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 v3_dev_net_ops *net_ops;
326 static int ne2k_update_irq(struct ne2k_state * nic_state) {
327 struct pci_device * pci_dev = nic_state->pci_dev;
329 if ((nic_state->context.isr.val & nic_state->context.imr.val) & 0x7f) {
330 if (pci_dev == NULL){
331 v3_raise_virq(&(nic_state->vm->cores[0]), NE2K_DEFAULT_IRQ);
333 v3_pci_raise_irq(nic_state->pci_bus, 0, nic_state->pci_dev);
336 PrintDebug("NE2000: Raise IRQ\n");
342 static int ne2k_send_packet(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
344 #ifdef CONFIG_DEBUG_NE2K
345 PrintDebug("NE2000: Send Packet:\n");
346 v3_hexdump(pkt, length, NULL, 0);
349 return nic_state->net_ops->send(pkt, length, nic_state->backend_data);
352 static int ne2k_rxbuf_full(struct ne2k_registers * regs) {
357 index = regs->curpag << 8;
358 boundary = regs->boundary << 8;
360 if (index < boundary) {
361 empty = boundary - index;
363 empty = ((regs->pgstop - regs->pgstart) << 8) - (index - boundary);
366 if (empty < (ETHERNET_PACKET_LEN + 4)) {
373 #define MIN_BUF_SIZE 60
376 // This needs to be completely redone...
377 static int rx_one_pkt(struct ne2k_state * nic_state, const uchar_t * pkt, uint32_t length) {
378 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
388 start = regs->pgstart << 8;
389 stop = regs->pgstop << 8;
391 if (regs->cmd.stop) {
395 if (ne2k_rxbuf_full(regs)) {
396 PrintError("Ne2k: received buffer overflow\n");
400 //packet too small, expand it
401 if (length < MIN_BUF_SIZE) {
402 uchar_t buf[MIN_BUF_SIZE];
404 memcpy(buf, pkt, length);
405 memset(buf + length, 0, MIN_BUF_SIZE - length);
407 length = MIN_BUF_SIZE;
410 index = regs->curpag << 8;
413 total_len = length + 4;
415 //address for next packet (4 bytes for CRC)
416 next = index + ((total_len + 4 + 255) & ~0xff);
419 next -= (stop - start);
422 p = nic_state->mem + index;
424 regs->rsr.pkt_rx_ok = 1;
427 regs->rsr.phy_match = 1; /* TODO: Check this back */
430 p[0] = regs->rsr.val;
433 p[3] = total_len >> 8;
438 empty = stop - index;
449 memcpy(nic_state->mem + index, pkt, len);
460 regs->curpag = next >> 8;
462 regs->isr.pkt_rx = 1;
463 ne2k_update_irq(nic_state);
469 static int ne2k_rx(uint8_t * buf, uint32_t size, void * private_data){
470 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
472 #ifdef CONFIG_DEBUG_NE2K
473 PrintDebug("\nNe2k: Packet Received:\n");
474 v3_hexdump(buf, size, NULL, 0);
477 if(!rx_one_pkt(nic_state, buf, size)){
485 static inline void mem_writeb(struct ne2k_state * nic_state,
488 uchar_t tmp = (uchar_t) (val & 0x000000ff);
490 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
491 nic_state->mem[addr] = tmp;
495 static inline void mem_writew(struct ne2k_state * nic_state,
500 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
501 *(uint16_t *)(nic_state->mem + addr) = val;
505 static inline void mem_writel(struct ne2k_state * nic_state,
510 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
511 *(uint32_t *)(nic_state->mem + addr) = val;
515 static inline uint8_t mem_readb(struct ne2k_state * nic_state, uint32_t addr) {
517 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
518 return nic_state->mem[addr];
524 static inline uint16_t mem_readw(struct ne2k_state * nic_state, uint32_t addr) {
527 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
528 return *(uint16_t *)(nic_state->mem + addr);
534 static uint32_t mem_readl(struct ne2k_state * nic_state, uint32_t addr) {
537 if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
538 return *(uint32_t *)(nic_state->mem + addr);
545 static void dma_update( struct ne2k_state * nic_state, int len) {
546 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
551 if (regs->rsar == regs->pgstop) {
552 regs->rsar = regs->pgstart;
555 if (regs->rbcr <= len) {
557 regs->isr.rem_dma_done = 1;
558 ne2k_update_irq(nic_state);
564 static int ne2k_data_read(struct guest_info * core,
568 void * private_data) {
569 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
571 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
573 // current dma address
574 uint32_t addr = regs->rsar;
578 val = mem_readb(nic_state, addr);
581 val = mem_readw(nic_state, addr);
584 val = mem_readl(nic_state, addr);
587 PrintError("ne2k_data_read error: invalid length %d\n", length);
591 dma_update(nic_state, length);
592 memcpy(dst, &val, length);
594 PrintDebug("NE2000 read: port:0x%x (%u bytes): 0x%x", port & 0x1f, length, val);
599 static int ne2k_data_write(struct guest_info * core,
603 void * private_data) {
604 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
606 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
608 uint32_t addr = regs->rsar;
610 if (regs->rbcr == 0) {
614 memcpy(&val, src, length);
618 mem_writeb(nic_state, addr, val);
621 mem_writew(nic_state, addr, val);
624 mem_writel(nic_state, addr, val);
627 PrintError("NE2000 port write error: invalid length %d\n", length);
630 dma_update(nic_state, length);
632 PrintDebug("NE2000: Write port:0x%x (%u bytes): 0x%x\n", port & 0x1f, length, val);
638 static void ne2k_init_state(struct ne2k_state * nic_state) {
641 /* Not sure what this is about.... */
642 memset(nic_state->mem, 0xff, 32);
644 memcpy(nic_state->mem, nic_state->mac, ETH_ALEN);
645 memset(nic_state->mcast_addr, 0xff, sizeof(nic_state->mcast_addr));
646 nic_state->mem[14] = 0x57;
647 nic_state->mem[15] = 0x57;
649 /* initiate registers */
650 nic_state->context.isr.reset_status = 1;
651 nic_state->context.imr.val = 0x00;
652 nic_state->context.cmd.val = 0x22;
655 static int reset_device(struct ne2k_state * nic_state) {
656 ne2k_init_state(nic_state);
658 PrintDebug("NE2000: Reset device\n");
664 static int ne2k_reset_port_read(struct guest_info * core,
668 void * private_data) {
669 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
671 memset(dst, 0, length);
672 reset_device(nic_state);
677 static int ne2k_reset_port_write(struct guest_info * core,
681 void * private_data) {
688 static int ne2k_cmd_write(struct guest_info * core,
692 void * private_data) {
693 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
694 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
697 PrintError("Invalid write length to NE2000 Command register\n");
701 regs->cmd.val = *(uint8_t *)src;
703 if (!(regs->cmd.stop)) {
704 regs->isr.reset_status = 0;
706 // if ((send pkt) && (dma byte count == 0))
707 if ((regs->cmd.rem_dma_cmd & 0x3) && (regs->rbcr == 0)) {
708 regs->isr.rem_dma_done = 1;
709 ne2k_update_irq(nic_state);
712 if (regs->cmd.tx_pkt) {
713 int offset = (regs->tpsr << 8);
715 if (offset >= NE2K_PMEM_END) {
716 offset -= NE2K_PMEM_SIZE;
719 if (offset + regs->tbcr <= NE2K_PMEM_END) {
720 ne2k_send_packet(nic_state, nic_state->mem + offset, regs->tbcr);
723 regs->tsr.val = 0; /* clear the tx status reg */
724 regs->tsr.pkt_tx_ok = 1; /* indicate successful tx */
726 regs->isr.pkt_tx = 1; /* irq due to pkt tx */
727 regs->cmd.tx_pkt = 0; /* reset cmd bit */
729 ne2k_update_irq(nic_state);
732 /* stop the controller */
738 static int ne2k_cmd_read(struct guest_info * core,
742 void * private_data) {
743 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
746 PrintError("Invalid read length to NE2000 Command register\n");
750 *(uint8_t *)dst = nic_state->context.cmd.val;
752 PrintDebug("ne2k_read: port:0x%x val: 0x%x\n", port, *(uint8_t *)dst);
756 static int ne2k_std_write(struct guest_info * core,
760 void * private_data) {
761 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
762 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
763 int idx = port & 0x1f;
764 uint8_t page = regs->cmd.pg_sel;
767 PrintError("NE2000 port write error: length %d port 0x%xnot equal to 1\n", length, port);
771 uint8_t val = *(uint8_t *)src;
773 PrintDebug("NE2000: write port:0x%x val: 0x%x\n", port, (uint8_t)val);
784 regs->boundary = val;
796 regs->isr.val &= ~(val & 0x7f);
797 ne2k_update_irq(nic_state);
822 ne2k_update_irq(nic_state);
826 PrintError("NE2000 port write error: invalid port:0x%x\n", port);
829 } else if (page == 1) {
831 case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
832 nic_state->mac[port - EN1_PHYS] = val;
837 case EN1_MULT ... EN1_MULT + 7:
838 nic_state->mcast_addr[port - EN1_MULT] = val;
842 PrintError("NE2000 write port error: invalid port:0x%x\n", port);
845 } else if (page == 2) {
867 PrintError("NE2000 write port error: invalid port:0x%x\n", port);
871 PrintError("NE2000: Invalid Register Page Value\n");
880 static int ne2k_std_read(struct guest_info * core,
884 void * private_data) {
885 struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
886 struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
887 uint16_t index = port & 0x1f;
888 uint8_t page = regs->cmd.pg_sel;
891 PrintError("ne2k_read error: length %d\n", length);
898 *(uint8_t *)dst = regs->clda0;
901 *(uint8_t *)dst = regs->clda1;
904 *(uint8_t *)dst = regs->boundary;
907 *(uint8_t *)dst = regs->tsr.val;
910 *(uint8_t *)dst = regs->ncr;
913 *(uint8_t *)dst = regs->fifo;
916 *(uint8_t *)dst = regs->isr.val;
917 ne2k_update_irq(nic_state);
920 *(uint8_t *)dst = regs->crda0;
923 *(uint8_t *)dst = regs->crda1;
926 *(uint8_t *)dst = regs->rsr.val;
929 *(uint8_t *)dst = regs->cntr0;
932 *(uint8_t *)dst = regs->cntr1;
935 *(uint8_t *)dst = regs->cntr2;
939 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
942 } else if (page == 1) {
944 case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
945 *(uint8_t *)dst = nic_state->mac[index - EN1_PHYS];
948 *(uint8_t *)dst = regs->curpag;
950 case EN1_MULT ... EN1_MULT + 7:
951 *(uint8_t *)dst = nic_state->mcast_addr[index - EN1_MULT];
955 PrintError("ne2k_read error: invalid port:0x%x\n", port);
958 } else if (page == 2) {
961 *(uint8_t *)dst = regs->pgstart;
964 *(uint8_t *)dst = regs->pgstop;
967 *(uint8_t *)dst = regs->rnpp;
970 *(uint8_t *)dst = regs->lnpp;
973 *(uint8_t *)dst = regs->tpsr;
976 *(uint8_t *)dst = regs->addcnt0;
979 *(uint8_t *)dst = regs->addcnt1;
982 *(uint8_t *)dst = regs->rcr.val;
985 *(uint8_t *)dst = regs->tcr.val;
988 *(uint8_t *)dst = regs->dcr.val;
991 *(uint8_t *)dst = regs->imr.val;
994 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
998 PrintError("NE2000 port read: Invalid Register Page Value\n");
1002 PrintDebug("NE2000 port read: port:0x%x val: 0x%x\n", port, *(uint8_t *)dst);
1009 static int ne2k_pci_write(struct guest_info * core,
1013 void * private_data) {
1014 uint16_t idx = port & 0x1f;
1018 case NIC_REG_BASE_PORT:
1019 ret = ne2k_cmd_write(core, port, src, length, private_data);
1021 case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15:
1022 ret = ne2k_std_write(core, port, src, length, private_data);
1025 ret = ne2k_data_write(core, port, src, length, private_data);
1027 case NIC_RESET_PORT:
1028 ret = ne2k_reset_port_write(core, port, src, length, private_data);
1032 PrintError("NE2000 port write error: invalid port:0x%x\n", port);
1039 static int ne2k_pci_read(struct guest_info * core,
1043 void * private_data) {
1044 uint16_t idx = port & 0x1f;
1048 case NIC_REG_BASE_PORT:
1049 ret = ne2k_cmd_read(core, port, dst, length, private_data);
1051 case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15:
1052 ret = ne2k_std_read(core, port, dst, length, private_data);
1055 ret = ne2k_data_read(core, port, dst, length, private_data);
1057 case NIC_RESET_PORT:
1058 ret = ne2k_reset_port_read(core, port, dst, length, private_data);
1062 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
1071 static int pci_config_update(uint_t reg_num,
1074 void * private_data) {
1075 PrintDebug("PCI Config Update\n");
1077 /* Do we need this? */
1083 static int register_dev(struct ne2k_state * nic_state)
1087 if (nic_state->pci_bus != NULL) {
1088 struct v3_pci_bar bars[6];
1089 struct pci_device * pci_dev = NULL;
1091 PrintDebug("NE2000: PCI Enabled\n");
1093 for (i = 0; i < 6; i++) {
1094 bars[i].type = PCI_BAR_NONE;
1097 bars[0].type = PCI_BAR_IO;
1098 bars[0].default_base_port = NIC_REG_BASE_PORT;
1099 bars[0].num_ports = 256;
1101 bars[0].io_read = ne2k_pci_read;
1102 bars[0].io_write = ne2k_pci_write;
1103 bars[0].private_data = nic_state;
1105 pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0,
1107 pci_config_update, NULL, NULL, nic_state);
1110 if (pci_dev == NULL) {
1111 PrintError("NE2000: Could not register PCI Device\n");
1115 pci_dev->config_header.vendor_id = 0x10ec;
1116 pci_dev->config_header.device_id = 0x8029;
1117 pci_dev->config_header.revision = 0x00;
1119 pci_dev->config_header.subclass = 0x00;
1120 pci_dev->config_header.class = 0x02;
1121 pci_dev->config_header.header_type = 0x00;
1123 pci_dev->config_header.intr_line = 11;
1124 pci_dev->config_header.intr_pin = 1;
1126 nic_state->pci_dev = pci_dev;
1128 PrintDebug("NE2000: Not attached to PCI\n");
1130 v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT , &ne2k_cmd_read, &ne2k_cmd_write);
1132 for (i = 1; i < 16; i++){
1133 v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + i, &ne2k_std_read, &ne2k_std_write);
1136 v3_dev_hook_io(nic_state->dev, NIC_DATA_PORT, &ne2k_data_read, &ne2k_data_write);
1137 v3_dev_hook_io(nic_state->dev, NIC_RESET_PORT, &ne2k_reset_port_read, &ne2k_reset_port_write);
1144 static int connect_fn(struct v3_vm_info * info,
1145 void * frontend_data,
1146 struct v3_dev_net_ops * ops,
1147 v3_cfg_tree_t * cfg,
1148 void * private_data) {
1149 struct ne2k_state * nic_state = (struct ne2k_state *)frontend_data;
1151 ne2k_init_state(nic_state);
1152 register_dev(nic_state);
1154 nic_state->net_ops = ops;
1155 nic_state->backend_data = private_data;
1157 ops->recv = ne2k_rx;
1159 ops->start_tx = NULL;
1160 ops->stop_tx = NULL;
1161 ops->frontend_data = nic_state;
1162 memcpy(ops->fnt_mac, nic_state->mac, ETH_ALEN);
1168 static int ne2k_free(struct ne2k_state * nic_state) {
1171 /* dettached from backend */
1173 if(nic_state->pci_bus == NULL){
1174 for (i = 0; i < 16; i++){
1175 v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + i);
1178 v3_dev_unhook_io(nic_state->dev, NIC_DATA_PORT);
1179 v3_dev_unhook_io(nic_state->dev, NIC_RESET_PORT);
1181 /* unregistered from PCI? */
1192 static struct v3_device_ops dev_ops = {
1193 .free = (int (*)(void *))ne2k_free,
1197 static int ne2k_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1198 struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
1199 struct ne2k_state * nic_state = NULL;
1200 char * dev_id = v3_cfg_val(cfg, "ID");
1201 char * macstr = v3_cfg_val(cfg, "mac");
1203 nic_state = (struct ne2k_state *)V3_Malloc(sizeof(struct ne2k_state));
1204 memset(nic_state, 0, sizeof(struct ne2k_state));
1206 nic_state->pci_bus = pci_bus;
1209 if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1210 PrintDebug("NE2000: Mac specified %s\n", macstr);
1212 PrintDebug("NE2000: MAC not specified\n");
1213 random_ethaddr(nic_state->mac);
1216 struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1219 PrintError("NE2000: Could not attach device %s\n", dev_id);
1224 nic_state->dev = dev;
1226 if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)nic_state) == -1) {
1227 PrintError("NE2000: Could not register %s as net frontend\n", dev_id);
1228 v3_remove_device(dev);
1236 device_register("NE2000", ne2k_init)