2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
11 * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Lei Xia <lxia@northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <devices/pci.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_io.h>
23 #include <palacios/vmm_debug.h>
24 #include <palacios/vmm_string.h>
25 #include <palacios/vmm_dev_mgr.h>
26 #include <palacios/vmm_intr.h>
27 #include <palacios/vmm_ethernet.h>
28 #include <palacios/vm_guest.h>
29 #include <palacios/vmm_sprintf.h>
31 #ifndef CONFIG_DEBUG_NE2K
33 #define PrintDebug(fmts, args...)
37 #define NE2K_DEFAULT_IRQ 11
39 // What the hell is this crap?
40 #define NE2K_PMEM_SIZE (32 * 1024)
41 #define NE2K_PMEM_START (16 * 1024)
42 #define NE2K_PMEM_END (NE2K_PMEM_SIZE + NE2K_PMEM_START)
43 #define NE2K_MEM_SIZE NE2K_PMEM_END
45 #define NIC_REG_BASE_PORT 0xc100 /* Command register (for all pages) */
46 #define NIC_DATA_PORT 0xc110 /* Data read/write port */
47 #define NIC_RESET_PORT 0xc11f /* Reset port */
49 /* Page 0 registers */
50 #define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
51 #define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
52 #define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
53 #define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
54 #define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
55 #define EN0_TSR 0x04 /* Transmit status reg RD */
56 #define EN0_TPSR 0x04 /* Transmit starting page WR */
57 #define EN0_NCR 0x05 /* Number of collision reg RD */
58 #define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
59 #define EN0_FIFO 0x06 /* FIFO RD */
60 #define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
61 #define EN0_ISR 0x07 /* Interrupt status reg RD WR */
62 #define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
63 #define EN0_RSARLO 0x08 /* Remote start address reg 0 */
64 #define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
65 #define EN0_RSARHI 0x09 /* Remote start address reg 1 */
66 #define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
67 #define EN0_RTL8029ID0 0x0a /* Realtek ID byte #1 RD */
68 #define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
69 #define EN0_RTL8029ID1 0x0b /* Realtek ID byte #2 RD */
70 #define EN0_RSR 0x0c /* rx status reg RD */
71 #define EN0_RXCR 0x0c /* RX configuration reg WR */
72 #define EN0_TXCR 0x0d /* TX configuration reg WR */
73 #define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
74 #define EN0_DCFG 0x0e /* Data configuration reg WR */
75 #define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
76 #define EN0_IMR 0x0f /* Interrupt mask reg WR */
77 #define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
79 /* Page 1 registers */
81 #define EN1_CURPAG 0x07
84 /* Page 2 registers */
85 #define EN2_STARTPG 0x01 /* Starting page of ring bfr RD */
86 #define EN2_STOPPG 0x02 /* Ending page +1 of ring bfr RD */
87 #define EN2_LDMA0 0x01 /* Current Local DMA Address 0 WR */
88 #define EN2_LDMA1 0x02 /* Current Local DMA Address 1 WR */
89 #define EN2_RNPR 0x03 /* Remote Next Packet Pointer RD WR */
90 #define EN2_TPSR 0x04 /* Transmit Page Start Address RD */
91 #define EN2_LNRP 0x05 /* Local Next Packet Pointer RD WR */
92 #define EN2_ACNT0 0x06 /* Address Counter Upper WR */
93 #define EN2_ACNT1 0x07 /* Address Counter Lower WR */
94 #define EN2_RCR 0x0c /* Receive Configuration Register RD */
95 #define EN2_TCR 0x0d /* Transmit Configuration Register RD */
96 #define EN2_DCR 0x0e /* Data Configuration Register RD */
97 #define EN2_IMR 0x0f /* Interrupt Mask Register RD */
99 /* Page 3 registers */
100 #define EN3_CONFIG0 0x03
101 #define EN3_CONFIG1 0x04
102 #define EN3_CONFIG2 0x05
103 #define EN3_CONFIG3 0x06
113 uint8_t rem_dma_cmd : 3; /* 0=Not allowed, 1=Read, 2=Write, 3=Send Pkt, 4=Abort/Complete DMA */
115 } __attribute__((packed));
116 } __attribute__((packed));
117 } __attribute__((packed));
120 struct intr_status_reg {
128 uint8_t overwrite_warn : 1;
129 uint8_t cnt_overflow : 1;
130 uint8_t rem_dma_done : 1;
131 uint8_t reset_status : 1;
132 } __attribute__((packed));
133 } __attribute__((packed));
134 } __attribute__((packed));
137 struct intr_mask_reg {
145 uint8_t overwrite_warn : 1;
146 uint8_t cnt_overflow : 1;
147 uint8_t rem_dma_done : 1;
149 } __attribute__((packed));
150 } __attribute__((packed));
151 } __attribute__((packed));
154 struct data_cfg_reg {
158 uint8_t word_trans_sel : 1;
159 uint8_t byte_order_sel : 1;
160 uint8_t long_addr_sel : 1;
161 uint8_t loopback_sel : 1;
162 uint8_t auto_init_rem : 1;
163 uint8_t fifo_thresh_sel : 2;
165 } __attribute__((packed));
166 } __attribute__((packed));
167 } __attribute__((packed));
174 uint8_t inhibit_crc : 1;
175 uint8_t enc_loop_ctrl : 2;
176 uint8_t auto_tx_disable : 1;
177 uint8_t coll_offset_en : 1;
179 } __attribute__((packed));
180 } __attribute__((packed));
181 } __attribute__((packed));
183 struct tx_status_reg {
187 uint8_t pkt_tx_ok : 1;
189 uint8_t tx_collision : 1;
190 uint8_t tx_aborted : 1;
191 uint8_t carrier_lost : 1;
192 uint8_t fifo_underrun : 1;
193 uint8_t cd_heartbeat : 1;
194 uint8_t oow_collision : 1;
195 } __attribute__((packed));
196 } __attribute__((packed));
197 } __attribute__((packed));
203 uint8_t save_pkt_errs : 1;
204 uint8_t runt_pkt_ok : 1;
205 uint8_t bcast_ok : 1;
206 uint8_t mcast_ok : 1;
207 uint8_t prom_phys_enable : 1;
208 uint8_t mon_mode : 1;
210 } __attribute__((packed));
211 } __attribute__((packed));
212 } __attribute__((packed));
215 struct rx_status_reg {
219 uint8_t pkt_rx_ok : 1;
221 uint8_t frame_align_err : 1;
222 uint8_t fifo_overrun : 1;
223 uint8_t missed_pkt : 1;
224 uint8_t phy_match : 1; /* 0=Physical Addr Match, 1=MCAST/BCAST Addr Match */
225 uint8_t rx_disabled : 1;
226 uint8_t deferring : 1;
227 } __attribute__((packed));
228 } __attribute__((packed));
229 } __attribute__((packed));
232 struct ne2k_registers {
234 struct intr_status_reg isr;
235 struct intr_mask_reg imr;
236 struct data_cfg_reg dcr;
237 struct tx_cfg_reg tcr;
238 struct tx_status_reg tsr;
239 struct rx_cfg_reg rcr;
240 struct rx_status_reg rsr;
242 uint8_t pgstart; /* page start reg */
243 uint8_t pgstop; /* page stop reg */
244 uint8_t boundary; /* boundary ptr */
245 uint8_t tpsr; /* tx page start addr */
246 uint8_t ncr; /* number of collisions */
247 uint8_t fifo; /* FIFO... */
249 uint8_t curpag; /* current page */
250 uint8_t rnpp; /* rem next pkt ptr */
251 uint8_t lnpp; /* local next pkt ptr */
253 uint8_t cntr0; /* counter 0 (frame alignment errors) */
254 uint8_t cntr1; /* counter 1 (CRC Errors) */
255 uint8_t cntr2; /* counter 2 (missed pkt errors) */
257 union { /* current local DMA Addr */
262 } __attribute__((packed));
263 } __attribute__((packed));
266 union { /* current remote DMA addr */
271 } __attribute__((packed));
272 } __attribute__((packed));
275 union { /* Remote Start Addr Reg */
280 } __attribute__((packed));
281 } __attribute__((packed));
284 union { /* TX Byte count Reg */
289 } __attribute__((packed));
290 } __attribute__((packed));
292 union { /* Remote Byte count Reg */
297 } __attribute__((packed));
298 } __attribute__((packed));
300 union { /* Address counter? */
305 } __attribute__((packed));
306 } __attribute__((packed));
311 struct v3_vm_info * vm;
312 struct pci_device * pci_dev;
313 struct vm_device * pci_bus;
314 struct vm_device * dev;
316 struct ne2k_registers context;
317 uint8_t mem[NE2K_MEM_SIZE];
319 uint8_t mcast_addr[8];
320 uint8_t mac[ETH_ALEN];
322 struct nic_statistics statistics;
324 struct v3_dev_net_ops *net_ops;
328 static int ne2k_update_irq(struct ne2k_state * nic_state) {
329 struct pci_device * pci_dev = nic_state->pci_dev;
331 if ((nic_state->context.isr.val & nic_state->context.imr.val) & 0x7f) {
332 if (pci_dev == NULL){
333 v3_raise_virq(&(nic_state->vm->cores[0]), NE2K_DEFAULT_IRQ);
335 v3_pci_raise_irq(nic_state->pci_bus, 0, nic_state->pci_dev);
338 nic_state->statistics.interrupts ++;
340 PrintDebug("NE2000: Raise IRQ\n");
346 static int tx_one_pkt(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
348 #ifdef CONFIG_DEBUG_NE2K
349 PrintDebug("NE2000: Send Packet:\n");
350 v3_hexdump(pkt, length, NULL, 0);
353 if(nic_state->net_ops->send(pkt, length, nic_state->backend_data) >= 0){
354 nic_state->statistics.tx_pkts ++;
355 nic_state->statistics.tx_bytes += length;
360 nic_state->statistics.tx_dropped ++;
365 static int ne2k_rxbuf_full(struct ne2k_registers * regs) {
370 index = regs->curpag << 8;
371 boundary = regs->boundary << 8;
373 if (index < boundary) {
374 empty = boundary - index;
376 empty = ((regs->pgstop - regs->pgstart) << 8) - (index - boundary);
379 if (empty < (ETHERNET_PACKET_LEN + 4)) {
386 #define MIN_BUF_SIZE 60
389 // This needs to be completely redone...
390 static int rx_one_pkt(struct ne2k_state * nic_state, const uchar_t * pkt, uint32_t length) {
391 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
401 start = regs->pgstart << 8;
402 stop = regs->pgstop << 8;
404 if (regs->cmd.stop) {
408 if (ne2k_rxbuf_full(regs)) {
409 PrintError("Ne2k: received buffer overflow\n");
413 //packet too small, expand it
414 if (length < MIN_BUF_SIZE) {
415 uchar_t buf[MIN_BUF_SIZE];
417 memcpy(buf, pkt, length);
418 memset(buf + length, 0, MIN_BUF_SIZE - length);
420 length = MIN_BUF_SIZE;
423 index = regs->curpag << 8;
426 total_len = length + 4;
428 //address for next packet (4 bytes for CRC)
429 next = index + ((total_len + 4 + 255) & ~0xff);
432 next -= (stop - start);
435 p = nic_state->mem + index;
437 regs->rsr.pkt_rx_ok = 1;
440 regs->rsr.phy_match = 1; /* TODO: Check this back */
443 p[0] = regs->rsr.val;
446 p[3] = total_len >> 8;
451 empty = stop - index;
462 memcpy(nic_state->mem + index, pkt, len);
473 regs->curpag = next >> 8;
475 regs->isr.pkt_rx = 1;
476 ne2k_update_irq(nic_state);
482 static int ne2k_rx(uint8_t * buf, uint32_t size, void * private_data){
483 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
485 #ifdef CONFIG_DEBUG_NE2K
486 PrintDebug("\nNe2k: Packet Received:\n");
487 v3_hexdump(buf, size, NULL, 0);
490 if(!rx_one_pkt(nic_state, buf, size)){
491 nic_state->statistics.rx_pkts ++;
492 nic_state->statistics.rx_bytes += size;
497 nic_state->statistics.rx_dropped ++;
503 static inline void mem_writeb(struct ne2k_state * nic_state,
506 uchar_t tmp = (uchar_t) (val & 0x000000ff);
508 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
509 nic_state->mem[addr] = tmp;
513 static inline void mem_writew(struct ne2k_state * nic_state,
518 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
519 *(uint16_t *)(nic_state->mem + addr) = val;
523 static inline void mem_writel(struct ne2k_state * nic_state,
528 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
529 *(uint32_t *)(nic_state->mem + addr) = val;
533 static inline uint8_t mem_readb(struct ne2k_state * nic_state, uint32_t addr) {
535 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
536 return nic_state->mem[addr];
542 static inline uint16_t mem_readw(struct ne2k_state * nic_state, uint32_t addr) {
545 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
546 return *(uint16_t *)(nic_state->mem + addr);
552 static uint32_t mem_readl(struct ne2k_state * nic_state, uint32_t addr) {
555 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
556 return *(uint32_t *)(nic_state->mem + addr);
563 static void dma_update( struct ne2k_state * nic_state, int len) {
564 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
569 if (regs->rsar == regs->pgstop) {
570 regs->rsar = regs->pgstart;
573 if (regs->rbcr <= len) {
575 regs->isr.rem_dma_done = 1;
576 ne2k_update_irq(nic_state);
582 static int ne2k_data_read(struct guest_info * core,
586 void * private_data) {
587 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
589 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
591 // current dma address
592 uint32_t addr = regs->rsar;
596 val = mem_readb(nic_state, addr);
599 val = mem_readw(nic_state, addr);
602 val = mem_readl(nic_state, addr);
605 PrintError("ne2k_data_read error: invalid length %d\n", length);
609 dma_update(nic_state, length);
610 memcpy(dst, &val, length);
612 PrintDebug("NE2000 read: port:0x%x (%u bytes): 0x%x", port & 0x1f, length, val);
617 static int ne2k_data_write(struct guest_info * core,
621 void * private_data) {
622 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
624 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
626 uint32_t addr = regs->rsar;
628 if (regs->rbcr == 0) {
632 memcpy(&val, src, length);
636 mem_writeb(nic_state, addr, val);
639 mem_writew(nic_state, addr, val);
642 mem_writel(nic_state, addr, val);
645 PrintError("NE2000 port write error: invalid length %d\n", length);
648 dma_update(nic_state, length);
650 PrintDebug("NE2000: Write port:0x%x (%u bytes): 0x%x\n", port & 0x1f, length, val);
656 static void ne2k_init_state(struct ne2k_state * nic_state) {
659 /* Not sure what this is about.... */
660 memset(nic_state->mem, 0xff, 32);
662 memcpy(nic_state->mem, nic_state->mac, ETH_ALEN);
663 memset(nic_state->mcast_addr, 0xff, sizeof(nic_state->mcast_addr));
664 nic_state->mem[14] = 0x57;
665 nic_state->mem[15] = 0x57;
667 /* initiate registers */
668 nic_state->context.isr.reset_status = 1;
669 nic_state->context.imr.val = 0x00;
670 nic_state->context.cmd.val = 0x22;
673 static int reset_device(struct ne2k_state * nic_state) {
674 ne2k_init_state(nic_state);
676 PrintDebug("NE2000: Reset device\n");
682 static int ne2k_reset_port_read(struct guest_info * core,
686 void * private_data) {
687 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
689 memset(dst, 0, length);
690 reset_device(nic_state);
695 static int ne2k_reset_port_write(struct guest_info * core,
699 void * private_data) {
706 static int ne2k_cmd_write(struct guest_info * core,
710 void * private_data) {
711 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
712 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
715 PrintError("Invalid write length to NE2000 Command register\n");
719 regs->cmd.val = *(uint8_t *)src;
721 if (!(regs->cmd.stop)) {
722 regs->isr.reset_status = 0;
724 // if ((send pkt) && (dma byte count == 0))
725 if ((regs->cmd.rem_dma_cmd & 0x3) && (regs->rbcr == 0)) {
726 regs->isr.rem_dma_done = 1;
727 ne2k_update_irq(nic_state);
730 if (regs->cmd.tx_pkt) {
731 int offset = (regs->tpsr << 8);
733 if (offset >= NE2K_PMEM_END) {
734 offset -= NE2K_PMEM_SIZE;
737 if (offset + regs->tbcr <= NE2K_PMEM_END) {
738 tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr);
741 regs->tsr.val = 0; /* clear the tx status reg */
742 regs->tsr.pkt_tx_ok = 1; /* indicate successful tx */
744 regs->isr.pkt_tx = 1; /* irq due to pkt tx */
745 regs->cmd.tx_pkt = 0; /* reset cmd bit */
747 ne2k_update_irq(nic_state);
750 /* stop the controller */
756 static int ne2k_cmd_read(struct guest_info * core,
760 void * private_data) {
761 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
764 PrintError("Invalid read length to NE2000 Command register\n");
768 *(uint8_t *)dst = nic_state->context.cmd.val;
770 PrintDebug("ne2k_read: port:0x%x val: 0x%x\n", port, *(uint8_t *)dst);
774 static int ne2k_std_write(struct guest_info * core,
778 void * private_data) {
779 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
780 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
781 int idx = port & 0x1f;
782 uint8_t page = regs->cmd.pg_sel;
785 PrintError("NE2000 port write error: length %d port 0x%xnot equal to 1\n", length, port);
789 uint8_t val = *(uint8_t *)src;
791 PrintDebug("NE2000: write port:0x%x val: 0x%x\n", port, (uint8_t)val);
802 regs->boundary = val;
814 regs->isr.val &= ~(val & 0x7f);
815 ne2k_update_irq(nic_state);
840 ne2k_update_irq(nic_state);
844 PrintError("NE2000 port write error: invalid port:0x%x\n", port);
847 } else if (page == 1) {
849 case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
850 nic_state->mac[port - EN1_PHYS] = val;
855 case EN1_MULT ... EN1_MULT + 7:
856 nic_state->mcast_addr[port - EN1_MULT] = val;
860 PrintError("NE2000 write port error: invalid port:0x%x\n", port);
863 } else if (page == 2) {
885 PrintError("NE2000 write port error: invalid port:0x%x\n", port);
889 PrintError("NE2000: Invalid Register Page Value\n");
898 static int ne2k_std_read(struct guest_info * core,
902 void * private_data) {
903 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
904 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
905 uint16_t index = port & 0x1f;
906 uint8_t page = regs->cmd.pg_sel;
909 PrintError("ne2k_read error: length %d\n", length);
916 *(uint8_t *)dst = regs->clda0;
919 *(uint8_t *)dst = regs->clda1;
922 *(uint8_t *)dst = regs->boundary;
925 *(uint8_t *)dst = regs->tsr.val;
928 *(uint8_t *)dst = regs->ncr;
931 *(uint8_t *)dst = regs->fifo;
934 *(uint8_t *)dst = regs->isr.val;
935 ne2k_update_irq(nic_state);
938 *(uint8_t *)dst = regs->crda0;
941 *(uint8_t *)dst = regs->crda1;
944 *(uint8_t *)dst = regs->rsr.val;
947 *(uint8_t *)dst = regs->cntr0;
950 *(uint8_t *)dst = regs->cntr1;
953 *(uint8_t *)dst = regs->cntr2;
957 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
960 } else if (page == 1) {
962 case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
963 *(uint8_t *)dst = nic_state->mac[index - EN1_PHYS];
966 *(uint8_t *)dst = regs->curpag;
968 case EN1_MULT ... EN1_MULT + 7:
969 *(uint8_t *)dst = nic_state->mcast_addr[index - EN1_MULT];
973 PrintError("ne2k_read error: invalid port:0x%x\n", port);
976 } else if (page == 2) {
979 *(uint8_t *)dst = regs->pgstart;
982 *(uint8_t *)dst = regs->pgstop;
985 *(uint8_t *)dst = regs->rnpp;
988 *(uint8_t *)dst = regs->lnpp;
991 *(uint8_t *)dst = regs->tpsr;
994 *(uint8_t *)dst = regs->addcnt0;
997 *(uint8_t *)dst = regs->addcnt1;
1000 *(uint8_t *)dst = regs->rcr.val;
1003 *(uint8_t *)dst = regs->tcr.val;
1006 *(uint8_t *)dst = regs->dcr.val;
1009 *(uint8_t *)dst = regs->imr.val;
1012 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
1016 PrintError("NE2000 port read: Invalid Register Page Value\n");
1020 PrintDebug("NE2000 port read: port:0x%x val: 0x%x\n", port, *(uint8_t *)dst);
1027 static int ne2k_pci_write(struct guest_info * core,
1031 void * private_data) {
1032 uint16_t idx = port & 0x1f;
1036 case NIC_REG_BASE_PORT:
1037 ret = ne2k_cmd_write(core, port, src, length, private_data);
1039 case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15:
1040 ret = ne2k_std_write(core, port, src, length, private_data);
1043 ret = ne2k_data_write(core, port, src, length, private_data);
1045 case NIC_RESET_PORT:
1046 ret = ne2k_reset_port_write(core, port, src, length, private_data);
1050 PrintError("NE2000 port write error: invalid port:0x%x\n", port);
1057 static int ne2k_pci_read(struct guest_info * core,
1061 void * private_data) {
1062 uint16_t idx = port & 0x1f;
1066 case NIC_REG_BASE_PORT:
1067 ret = ne2k_cmd_read(core, port, dst, length, private_data);
1069 case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15:
1070 ret = ne2k_std_read(core, port, dst, length, private_data);
1073 ret = ne2k_data_read(core, port, dst, length, private_data);
1075 case NIC_RESET_PORT:
1076 ret = ne2k_reset_port_read(core, port, dst, length, private_data);
1080 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
1089 static int pci_config_update(uint_t reg_num,
1092 void * private_data) {
1093 PrintDebug("PCI Config Update\n");
1095 /* Do we need this? */
1101 static int register_dev(struct ne2k_state * nic_state)
1105 if (nic_state->pci_bus != NULL) {
1106 struct v3_pci_bar bars[6];
1107 struct pci_device * pci_dev = NULL;
1109 PrintDebug("NE2000: PCI Enabled\n");
1111 for (i = 0; i < 6; i++) {
1112 bars[i].type = PCI_BAR_NONE;
1115 bars[0].type = PCI_BAR_IO;
1116 bars[0].default_base_port = NIC_REG_BASE_PORT;
1117 bars[0].num_ports = 256;
1119 bars[0].io_read = ne2k_pci_read;
1120 bars[0].io_write = ne2k_pci_write;
1121 bars[0].private_data = nic_state;
1123 pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0,
1125 pci_config_update, NULL, NULL, nic_state);
1128 if (pci_dev == NULL) {
1129 PrintError("NE2000: Could not register PCI Device\n");
1133 pci_dev->config_header.vendor_id = 0x10ec;
1134 pci_dev->config_header.device_id = 0x8029;
1135 pci_dev->config_header.revision = 0x00;
1137 pci_dev->config_header.subclass = 0x00;
1138 pci_dev->config_header.class = 0x02;
1139 pci_dev->config_header.header_type = 0x00;
1141 pci_dev->config_header.intr_line = 11;
1142 pci_dev->config_header.intr_pin = 1;
1144 nic_state->pci_dev = pci_dev;
1146 PrintDebug("NE2000: Not attached to PCI\n");
1148 v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT , &ne2k_cmd_read, &ne2k_cmd_write);
1150 for (i = 1; i < 16; i++){
1151 v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + i, &ne2k_std_read, &ne2k_std_write);
1154 v3_dev_hook_io(nic_state->dev, NIC_DATA_PORT, &ne2k_data_read, &ne2k_data_write);
1155 v3_dev_hook_io(nic_state->dev, NIC_RESET_PORT, &ne2k_reset_port_read, &ne2k_reset_port_write);
1162 static int connect_fn(struct v3_vm_info * info,
1163 void * frontend_data,
1164 struct v3_dev_net_ops * ops,
1165 v3_cfg_tree_t * cfg,
1166 void * private_data) {
1167 struct ne2k_state * nic_state = (struct ne2k_state *)frontend_data;
1169 ne2k_init_state(nic_state);
1170 register_dev(nic_state);
1172 nic_state->net_ops = ops;
1173 nic_state->backend_data = private_data;
1175 ops->recv = ne2k_rx;
1177 ops->start_tx = NULL;
1178 ops->stop_tx = NULL;
1179 ops->frontend_data = nic_state;
1180 memcpy(ops->fnt_mac, nic_state->mac, ETH_ALEN);
1186 static int ne2k_free(struct ne2k_state * nic_state) {
1189 /* dettached from backend */
1191 if(nic_state->pci_bus == NULL){
1192 for (i = 0; i < 16; i++){
1193 v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + i);
1196 v3_dev_unhook_io(nic_state->dev, NIC_DATA_PORT);
1197 v3_dev_unhook_io(nic_state->dev, NIC_RESET_PORT);
1199 /* unregistered from PCI? */
1208 static struct v3_device_ops dev_ops = {
1209 .free = (int (*)(void *))ne2k_free,
1213 static int ne2k_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1214 struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
1215 struct ne2k_state * nic_state = NULL;
1216 char * dev_id = v3_cfg_val(cfg, "ID");
1217 char * macstr = v3_cfg_val(cfg, "mac");
1219 nic_state = (struct ne2k_state *)V3_Malloc(sizeof(struct ne2k_state));
1220 memset(nic_state, 0, sizeof(struct ne2k_state));
1222 nic_state->pci_bus = pci_bus;
1225 if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1226 PrintDebug("NE2000: Mac specified %s\n", macstr);
1228 PrintDebug("NE2000: MAC not specified\n");
1229 random_ethaddr(nic_state->mac);
1232 struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1235 PrintError("NE2000: Could not attach device %s\n", dev_id);
1240 nic_state->dev = dev;
1242 if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)nic_state) == -1) {
1243 PrintError("NE2000: Could not register %s as net frontend\n", dev_id);
1244 v3_remove_device(dev);
1252 device_register("NE2000", ne2k_init)