X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fne2k.c;h=420bc79865ed72918c9b5aaab8fefe8769da1fc8;hb=d597d493eb303496f3bb32e2a73a094a8a20a022;hp=46594c31e8b105bf6a52a3b2789751f423b21fe7;hpb=22dbf90548cb2ea56a9057a706e3da411dc1b57b;p=palacios.git diff --git a/palacios/src/devices/ne2k.c b/palacios/src/devices/ne2k.c index 46594c3..420bc79 100644 --- a/palacios/src/devices/ne2k.c +++ b/palacios/src/devices/ne2k.c @@ -28,7 +28,7 @@ #include #include -#ifndef CONFIG_DEBUG_NE2K +#ifndef V3_CONFIG_DEBUG_NE2K #undef PrintDebug #define PrintDebug(fmts, args...) #endif @@ -43,8 +43,10 @@ #define NE2K_MEM_SIZE NE2K_PMEM_END #define NIC_REG_BASE_PORT 0xc100 /* Command register (for all pages) */ -#define NIC_DATA_PORT 0xc110 /* Data read/write port */ -#define NIC_RESET_PORT 0xc11f /* Reset port */ + +#define NE2K_CMD_OFFSET 0x00 +#define NE2K_DATA_OFFSET 0x10 +#define NE2K_RESET_OFFSET 0x1f /* Page 0 registers */ #define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */ @@ -319,6 +321,8 @@ struct ne2k_state { uint8_t mcast_addr[8]; uint8_t mac[ETH_ALEN]; + struct nic_statistics statistics; + struct v3_dev_net_ops *net_ops; void * backend_data; }; @@ -330,23 +334,34 @@ static int ne2k_update_irq(struct ne2k_state * nic_state) { if (pci_dev == NULL){ v3_raise_virq(&(nic_state->vm->cores[0]), NE2K_DEFAULT_IRQ); } else { - v3_pci_raise_irq(nic_state->pci_bus, 0, nic_state->pci_dev); + v3_pci_raise_irq(nic_state->pci_bus, nic_state->pci_dev, 0); } + nic_state->statistics.rx_interrupts ++; + PrintDebug("NE2000: Raise IRQ\n"); } return 0; } -static int ne2k_send_packet(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) { +static int tx_one_pkt(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) { -#ifdef CONFIG_DEBUG_NE2K +#ifdef V3_CONFIG_DEBUG_NE2K PrintDebug("NE2000: Send Packet:\n"); v3_hexdump(pkt, length, NULL, 0); #endif - return nic_state->net_ops->send(pkt, length, nic_state->backend_data); + if(nic_state->net_ops->send(pkt, length, nic_state->backend_data) >= 0){ + nic_state->statistics.tx_pkts ++; + nic_state->statistics.tx_bytes += length; + + return 0; + } + + nic_state->statistics.tx_dropped ++; + + return -1; } static int ne2k_rxbuf_full(struct ne2k_registers * regs) { @@ -469,15 +484,20 @@ static int rx_one_pkt(struct ne2k_state * nic_state, const uchar_t * pkt, uint3 static int ne2k_rx(uint8_t * buf, uint32_t size, void * private_data){ struct ne2k_state * nic_state = (struct ne2k_state *)private_data; -#ifdef CONFIG_DEBUG_NE2K +#ifdef V3_CONFIG_DEBUG_NE2K PrintDebug("\nNe2k: Packet Received:\n"); v3_hexdump(buf, size, NULL, 0); #endif if(!rx_one_pkt(nic_state, buf, size)){ + nic_state->statistics.rx_pkts ++; + nic_state->statistics.rx_bytes += size; + return 0; } - + + nic_state->statistics.rx_dropped ++; + return -1; } @@ -717,7 +737,7 @@ static int ne2k_cmd_write(struct guest_info * core, } if (offset + regs->tbcr <= NE2K_PMEM_END) { - ne2k_send_packet(nic_state, nic_state->mem + offset, regs->tbcr); + tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr); } regs->tsr.val = 0; /* clear the tx status reg */ @@ -1015,16 +1035,16 @@ static int ne2k_pci_write(struct guest_info * core, int ret; switch (idx) { - case NIC_REG_BASE_PORT: + case NE2K_CMD_OFFSET: ret = ne2k_cmd_write(core, port, src, length, private_data); break; - case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15: + case NE2K_CMD_OFFSET+1 ... NE2K_CMD_OFFSET+15: ret = ne2k_std_write(core, port, src, length, private_data); break; - case NIC_DATA_PORT: + case NE2K_DATA_OFFSET: ret = ne2k_data_write(core, port, src, length, private_data); break; - case NIC_RESET_PORT: + case NE2K_RESET_OFFSET: ret = ne2k_reset_port_write(core, port, src, length, private_data); break; @@ -1045,16 +1065,16 @@ static int ne2k_pci_read(struct guest_info * core, int ret; switch (idx) { - case NIC_REG_BASE_PORT: + case NE2K_CMD_OFFSET: ret = ne2k_cmd_read(core, port, dst, length, private_data); break; - case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15: + case NE2K_CMD_OFFSET+1 ... NE2K_CMD_OFFSET+15: ret = ne2k_std_read(core, port, dst, length, private_data); break; - case NIC_DATA_PORT: + case NE2K_DATA_OFFSET: ret = ne2k_data_read(core, port, dst, length, private_data); break; - case NIC_RESET_PORT: + case NE2K_RESET_OFFSET: ret = ne2k_reset_port_read(core, port, dst, length, private_data); break; @@ -1068,7 +1088,8 @@ static int ne2k_pci_read(struct guest_info * core, } -static int pci_config_update(uint_t reg_num, +static int pci_config_update(struct pci_device * pci_dev, + uint32_t reg_num, void * src, uint_t length, void * private_data) { @@ -1095,7 +1116,7 @@ static int register_dev(struct ne2k_state * nic_state) } bars[0].type = PCI_BAR_IO; - bars[0].default_base_port = NIC_REG_BASE_PORT; + bars[0].default_base_port = -1; bars[0].num_ports = 256; bars[0].io_read = ne2k_pci_read; @@ -1104,7 +1125,7 @@ static int register_dev(struct ne2k_state * nic_state) pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0, "NE2000", bars, - pci_config_update, NULL, NULL, nic_state); + pci_config_update, NULL, NULL, NULL, nic_state); if (pci_dev == NULL) { @@ -1133,8 +1154,8 @@ static int register_dev(struct ne2k_state * nic_state) v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + i, &ne2k_std_read, &ne2k_std_write); } - v3_dev_hook_io(nic_state->dev, NIC_DATA_PORT, &ne2k_data_read, &ne2k_data_write); - v3_dev_hook_io(nic_state->dev, NIC_RESET_PORT, &ne2k_reset_port_read, &ne2k_reset_port_write); + v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_DATA_OFFSET, &ne2k_data_read, &ne2k_data_write); + v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_RESET_OFFSET, &ne2k_reset_port_read, &ne2k_reset_port_write); } @@ -1155,11 +1176,9 @@ static int connect_fn(struct v3_vm_info * info, nic_state->backend_data = private_data; ops->recv = ne2k_rx; - ops->poll = NULL; - ops->start_tx = NULL; - ops->stop_tx = NULL; - ops->frontend_data = nic_state; - memcpy(ops->fnt_mac, nic_state->mac, ETH_ALEN); + ops->poll = NULL; + ops->config.frontend_data = nic_state; + ops->config.fnt_mac = nic_state->mac; return 0; } @@ -1175,13 +1194,11 @@ static int ne2k_free(struct ne2k_state * nic_state) { v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + i); } - v3_dev_unhook_io(nic_state->dev, NIC_DATA_PORT); - v3_dev_unhook_io(nic_state->dev, NIC_RESET_PORT); + v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_DATA_OFFSET); + v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_RESET_OFFSET); }else { /* unregistered from PCI? */ } - - return 0; V3_Free(nic_state); @@ -1201,6 +1218,12 @@ static int ne2k_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { char * macstr = v3_cfg_val(cfg, "mac"); nic_state = (struct ne2k_state *)V3_Malloc(sizeof(struct ne2k_state)); + + if (!nic_state) { + PrintError("Cannot allocate in init\n"); + return -1; + } + memset(nic_state, 0, sizeof(struct ne2k_state)); nic_state->pci_bus = pci_bus;