Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Minor Fix
[palacios.git] / palacios / src / devices / ne2k.c
1 /*
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu> 
11  * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Lei Xia <lxia@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19  
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>
30
31 #ifndef CONFIG_DEBUG_NE2K
32 #undef PrintDebug
33 #define PrintDebug(fmts, args...)
34 #endif
35
36
37 #define NE2K_DEFAULT_IRQ        11
38
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
44
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 */
48
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 */
78
79 /* Page 1 registers */
80 #define EN1_PHYS                0x01
81 #define EN1_CURPAG              0x07
82 #define EN1_MULT                0x08
83
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 */
98
99 /* Page 3 registers */
100 #define EN3_CONFIG0             0x03
101 #define EN3_CONFIG1             0x04
102 #define EN3_CONFIG2             0x05
103 #define EN3_CONFIG3             0x06
104
105
106 struct cmd_reg {
107     union {
108         uint8_t val;
109         struct {
110             uint8_t stop        : 1;
111             uint8_t start       : 1;
112             uint8_t tx_pkt      : 1;
113             uint8_t rem_dma_cmd : 3;    /* 0=Not allowed, 1=Read, 2=Write, 3=Send Pkt, 4=Abort/Complete DMA */
114             uint8_t pg_sel      : 2;
115         } __attribute__((packed));
116     } __attribute__((packed));
117 } __attribute__((packed));
118
119
120 struct intr_status_reg {
121     union {
122         uint8_t val;
123         struct {
124             uint8_t pkt_rx          : 1;
125             uint8_t pkt_tx          : 1;
126             uint8_t rx_err          : 1;
127             uint8_t tx_err          : 1;
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));
135
136
137 struct intr_mask_reg {
138     union {
139         uint8_t val;
140         struct {
141             uint8_t pkt_rx          : 1;
142             uint8_t pkt_tx          : 1;
143             uint8_t rx_err          : 1;
144             uint8_t tx_err          : 1;
145             uint8_t overwrite_warn  : 1;
146             uint8_t cnt_overflow    : 1;
147             uint8_t rem_dma_done    : 1;
148             uint8_t rsvd            : 1;
149         } __attribute__((packed));
150     } __attribute__((packed));
151 } __attribute__((packed));
152
153
154 struct data_cfg_reg {
155     union {
156         uint8_t val;
157         struct {
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;
164             uint8_t rsvd             : 1;
165         } __attribute__((packed));
166     } __attribute__((packed));
167 } __attribute__((packed));
168
169
170 struct tx_cfg_reg { 
171     union {
172         uint8_t val;
173         struct {
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;
178             uint8_t rsvd            : 3;
179         } __attribute__((packed));
180     } __attribute__((packed));
181 } __attribute__((packed));
182
183 struct tx_status_reg { 
184     union {
185         uint8_t val;
186         struct {
187             uint8_t pkt_tx_ok       : 1;
188             uint8_t rsvd            : 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));
198
199 struct rx_cfg_reg { 
200     union {
201         uint8_t val;
202         struct {
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;
209             uint8_t rsvd             : 2;
210         } __attribute__((packed));
211     } __attribute__((packed));
212 } __attribute__((packed));
213
214
215 struct rx_status_reg { 
216     union {
217         uint8_t val;
218         struct {
219             uint8_t pkt_rx_ok        : 1;
220             uint8_t crc_err          : 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));
230
231
232 struct ne2k_registers {
233     struct cmd_reg cmd;
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;  
241
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... */
248
249     uint8_t      curpag;       /* current page */
250     uint8_t      rnpp;         /* rem next pkt ptr */
251     uint8_t      lnpp;         /* local next pkt ptr */
252
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) */
256
257     union {                    /* current local DMA Addr */
258         uint16_t     clda;
259         struct {
260             uint8_t clda0;
261             uint8_t clda1;
262         } __attribute__((packed));
263     } __attribute__((packed));
264
265
266     union {                    /* current remote DMA addr */
267         uint16_t     crda;
268         struct {
269             uint8_t crda0;
270             uint8_t crda1;
271         } __attribute__((packed));
272     } __attribute__((packed));
273
274
275     union {                    /* Remote Start Addr Reg */
276         uint16_t     rsar;
277         struct {
278             uint8_t rsar0;
279             uint8_t rsar1;
280         } __attribute__((packed));
281     } __attribute__((packed));
282
283
284     union {                    /* TX Byte count Reg */
285         uint16_t     tbcr;
286         struct {
287             uint8_t tbcr0;
288             uint8_t tbcr1;
289         } __attribute__((packed));
290     } __attribute__((packed));
291
292     union {                    /* Remote Byte count Reg */
293         uint16_t     rbcr;
294         struct {
295             uint8_t rbcr0;
296             uint8_t rbcr1;
297         } __attribute__((packed));
298     } __attribute__((packed));
299
300     union {                    /* Address counter? */
301         uint16_t     addcnt;
302         struct {
303             uint8_t addcnt0;
304             uint8_t addcnt1;
305         } __attribute__((packed));
306     } __attribute__((packed));
307 };
308
309
310 struct ne2k_state {
311     struct v3_vm_info * vm;
312     struct pci_device * pci_dev;
313     struct vm_device * pci_bus;
314     struct vm_device * dev;
315
316     struct ne2k_registers context;
317     uint8_t mem[NE2K_MEM_SIZE];
318
319     uint8_t mcast_addr[8];
320     uint8_t mac[ETH_ALEN];
321
322     struct nic_statistics statistics;
323
324     struct v3_dev_net_ops *net_ops;
325     void * backend_data;
326 };
327
328 static int ne2k_update_irq(struct ne2k_state * nic_state) {
329     struct pci_device * pci_dev = nic_state->pci_dev;
330
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);
334        } else {     
335             v3_pci_raise_irq(nic_state->pci_bus, 0, nic_state->pci_dev);
336        }
337
338        nic_state->statistics.interrupts ++;
339
340        PrintDebug("NE2000: Raise IRQ\n");
341     }
342
343     return 0;
344 }
345
346 static int tx_one_pkt(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
347         
348 #ifdef CONFIG_DEBUG_NE2K
349     PrintDebug("NE2000: Send Packet:\n");
350     v3_hexdump(pkt, length, NULL, 0);
351 #endif    
352
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;
356
357         return 0;
358     }
359         
360     nic_state->statistics.tx_dropped ++;
361
362     return -1;
363 }
364
365 static int ne2k_rxbuf_full(struct ne2k_registers * regs) {
366     int empty;
367     int index;
368     int boundary;
369
370     index = regs->curpag << 8;
371     boundary = regs->boundary << 8;
372
373     if (index < boundary) {
374         empty = boundary - index;
375     } else {
376         empty = ((regs->pgstop - regs->pgstart) << 8) - (index - boundary);
377     }
378
379     if (empty < (ETHERNET_PACKET_LEN + 4)) {
380         return 1;
381     }
382
383     return 0;
384 }
385
386 #define MIN_BUF_SIZE 60
387
388
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);
392     uchar_t * p;
393     uint32_t total_len;
394     uint32_t next;
395     uint32_t len;
396     uint32_t index;
397     uint32_t empty;
398     uint32_t start;
399     uint32_t stop;
400
401     start = regs->pgstart << 8;
402     stop = regs->pgstop << 8;
403    
404     if (regs->cmd.stop) {
405         return -1;
406     }
407
408     if (ne2k_rxbuf_full(regs)) {
409         PrintError("Ne2k: received buffer overflow\n");
410         return -1;
411     }
412
413     //packet too small, expand it
414     if (length < MIN_BUF_SIZE) {
415         uchar_t buf[MIN_BUF_SIZE];
416
417         memcpy(buf, pkt, length);
418         memset(buf + length, 0, MIN_BUF_SIZE - length);
419         pkt = buf;
420         length = MIN_BUF_SIZE;
421     }
422
423     index = regs->curpag << 8;
424
425     //header, 4 bytes
426     total_len = length + 4;
427
428     //address for next packet (4 bytes for CRC)
429     next = index + ((total_len + 4 + 255) & ~0xff);
430
431     if (next >= stop) {
432         next -= (stop - start);
433     }
434
435     p = nic_state->mem + index;
436     regs->rsr.val = 0;
437     regs->rsr.pkt_rx_ok = 1;
438
439     if (pkt[0] & 0x01) {
440         regs->rsr.phy_match = 1; /* TODO: Check this back */
441     }
442
443     p[0] = regs->rsr.val;
444     p[1] = next >> 8;
445     p[2] = total_len;
446     p[3] = total_len >> 8;
447     index += 4;
448
449     while (length > 0) {
450         if (index <= stop) {
451             empty = stop - index;
452         } else {
453             empty = 0;
454         }
455
456         len = length;
457
458         if (len > empty) {
459             len = empty;
460         }
461
462         memcpy(nic_state->mem + index, pkt, len);
463         pkt += len;
464         index += len;
465
466         if (index == stop) {
467             index = start;
468         }
469
470         length -= len;
471     }
472
473     regs->curpag = next >> 8;
474
475     regs->isr.pkt_rx = 1;
476     ne2k_update_irq(nic_state);
477
478     return 0;
479 }
480
481
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;
484   
485 #ifdef CONFIG_DEBUG_NE2K
486     PrintDebug("\nNe2k: Packet Received:\n");
487     v3_hexdump(buf, size, NULL, 0);
488 #endif    
489
490     if(!rx_one_pkt(nic_state, buf, size)){
491         nic_state->statistics.rx_pkts ++;
492         nic_state->statistics.rx_bytes += size;
493         
494         return 0;
495     }
496
497     nic_state->statistics.rx_dropped ++;
498         
499     return -1;
500 }
501
502
503 static inline void mem_writeb(struct ne2k_state * nic_state, 
504                         uint32_t addr, 
505                         uint32_t val) {
506     uchar_t tmp = (uchar_t) (val & 0x000000ff);
507
508     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
509         nic_state->mem[addr] = tmp;
510     }
511 }
512
513 static inline void mem_writew(struct ne2k_state * nic_state, 
514                             uint32_t addr,
515                             uint32_t val) {
516     addr &= ~1;
517
518     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
519         *(uint16_t *)(nic_state->mem + addr) = val;
520     }
521 }
522
523 static inline void mem_writel(struct ne2k_state * nic_state,
524                             uint32_t addr,
525                             uint32_t val) {
526     addr &= ~1;
527
528     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
529         *(uint32_t *)(nic_state->mem + addr) = val;
530     }
531 }
532
533 static inline uint8_t  mem_readb(struct ne2k_state * nic_state, uint32_t addr) {
534         
535     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
536         return nic_state->mem[addr];
537     } else {
538         return 0xff;
539     }
540 }
541
542 static inline uint16_t mem_readw(struct ne2k_state * nic_state, uint32_t addr) {
543     addr &= ~1;
544
545     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
546         return *(uint16_t *)(nic_state->mem + addr);
547     } else {
548         return 0xffff;
549     }
550 }
551
552 static uint32_t mem_readl(struct ne2k_state * nic_state, uint32_t addr) {
553     addr &= ~1;
554
555     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
556         return *(uint32_t *)(nic_state->mem + addr);
557     } else {
558         return 0xffffffff;
559     }
560 }
561
562
563 static void dma_update( struct ne2k_state * nic_state, int len) {                       
564     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
565
566     regs->rsar += len;
567
568     // wrap
569     if (regs->rsar == regs->pgstop) {
570         regs->rsar = regs->pgstart;
571     }
572
573     if (regs->rbcr <= len) {
574         regs->rbcr = 0;
575         regs->isr.rem_dma_done = 1;
576         ne2k_update_irq(nic_state);
577     } else {
578         regs->rbcr -= len;
579     }
580 }
581
582 static int ne2k_data_read(struct guest_info * core, 
583                           uint16_t port, 
584                           void * dst, 
585                           uint_t length, 
586                           void * private_data) {
587     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
588     uint32_t val;
589     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
590
591     // current dma address
592     uint32_t addr = regs->rsar;
593
594     switch (length){
595         case 1:
596             val = mem_readb(nic_state, addr);
597             break;
598         case 2:
599             val = mem_readw(nic_state, addr);
600             break;
601         case 4:
602             val = mem_readl(nic_state, addr);
603             break;
604         default:
605             PrintError("ne2k_data_read error: invalid length %d\n", length);
606             val = 0x0;
607     }
608     
609     dma_update(nic_state, length);
610     memcpy(dst, &val, length);
611
612     PrintDebug("NE2000 read: port:0x%x (%u bytes): 0x%x", port & 0x1f, length, val);
613
614     return length;
615 }
616
617 static int ne2k_data_write(struct guest_info * core, 
618                            uint16_t port, 
619                            void * src, 
620                            uint_t length, 
621                            void * private_data) {
622     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
623     uint32_t val;
624     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
625         
626     uint32_t addr = regs->rsar;
627         
628     if (regs->rbcr == 0) {
629         return length;
630     }
631
632     memcpy(&val, src, length);
633
634     switch (length) {
635         case 1:
636             mem_writeb(nic_state, addr, val);
637             break;
638         case 2:
639             mem_writew(nic_state, addr, val);
640             break;
641         case 4:
642             mem_writel(nic_state, addr, val);
643             break;
644         default:
645             PrintError("NE2000 port write error: invalid length %d\n", length);
646     }
647     
648     dma_update(nic_state, length);
649
650     PrintDebug("NE2000: Write port:0x%x (%u bytes): 0x%x\n", port & 0x1f, length, val);
651     
652     return length;
653 }
654
655
656 static void ne2k_init_state(struct ne2k_state * nic_state) {
657
658
659     /* Not sure what this is about....  */
660     memset(nic_state->mem, 0xff, 32); 
661         
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;
666
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;
671 }
672
673 static int reset_device(struct ne2k_state * nic_state) {  
674     ne2k_init_state(nic_state);
675
676     PrintDebug("NE2000: Reset device\n");
677
678     return 0;
679 }
680
681 //for 0xc11f port
682 static int ne2k_reset_port_read(struct guest_info * core, 
683                                 uint16_t port, 
684                                 void * dst, 
685                                 uint_t length, 
686                                 void * private_data) {
687     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
688
689     memset(dst, 0, length);
690     reset_device(nic_state);
691
692     return length;
693 }
694
695 static int ne2k_reset_port_write(struct guest_info * core, 
696                                  uint16_t port, 
697                                  void * src, 
698                                  uint_t length, 
699                                  void * private_data) {
700
701     return length;
702 }
703
704
705
706 static int ne2k_cmd_write(struct guest_info * core, 
707                           uint16_t port, 
708                           void * src, 
709                           uint_t length, 
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);
713
714     if (length != 1) {
715         PrintError("Invalid write length to NE2000 Command register\n");
716         return -1;
717     }
718
719     regs->cmd.val = *(uint8_t *)src;
720
721     if (!(regs->cmd.stop)) {
722         regs->isr.reset_status = 0;
723         
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);
728         }
729         
730         if (regs->cmd.tx_pkt) {
731             int offset = (regs->tpsr << 8);
732             
733             if (offset >= NE2K_PMEM_END) {
734                 offset -= NE2K_PMEM_SIZE;
735             }
736
737             if (offset + regs->tbcr <= NE2K_PMEM_END) {
738                 tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr);
739             }
740
741             regs->tsr.val = 0;        /* clear the tx status reg */
742             regs->tsr.pkt_tx_ok = 1;  /* indicate successful tx */
743
744             regs->isr.pkt_tx = 1;     /* irq due to pkt tx */
745             regs->cmd.tx_pkt = 0;     /* reset cmd bit  */
746             
747             ne2k_update_irq(nic_state);
748         }
749     } else {
750         /* stop the controller */
751     }
752
753     return length;
754 }
755
756 static int ne2k_cmd_read(struct guest_info * core, 
757                          uint16_t port, 
758                          void * dst, 
759                          uint_t length, 
760                          void * private_data) {
761     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
762
763     if (length != 1) {
764         PrintError("Invalid read length to NE2000 Command register\n");
765         return -1;
766     }
767
768     *(uint8_t *)dst = nic_state->context.cmd.val;
769
770     PrintDebug("ne2k_read: port:0x%x  val: 0x%x\n", port, *(uint8_t *)dst);
771     return length;
772 }
773
774 static int ne2k_std_write(struct guest_info * core, 
775                           uint16_t port, 
776                           void * src, 
777                           uint_t length, 
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;
783
784     if (length != 1){
785         PrintError("NE2000 port write error: length %d port 0x%xnot equal to 1\n", length, port);  
786         return -1;
787     }
788
789     uint8_t val = *(uint8_t *)src;
790         
791     PrintDebug("NE2000: write port:0x%x val: 0x%x\n", port, (uint8_t)val);
792     
793     if (page == 0) {
794         switch (idx) {
795             case EN0_STARTPG:
796                 regs->pgstart = val;
797                 break;
798             case EN0_STOPPG:
799                 regs->pgstop = val;
800                 break;
801             case EN0_BOUNDARY:
802                 regs->boundary = val;
803                 break;
804             case EN0_TPSR:
805                 regs->tpsr = val;
806                 break;
807             case EN0_TCNTLO:
808                 regs->tbcr0 = val;
809                 break;
810             case EN0_TCNTHI:
811                 regs->tbcr1 = val;
812                 break;
813             case EN0_ISR:
814                 regs->isr.val &= ~(val & 0x7f);
815                 ne2k_update_irq(nic_state);
816                 break;
817             case EN0_RSARLO:
818                 regs->rsar0 = val;
819                 break;
820             case EN0_RSARHI:
821                 regs->rsar1 = val;
822                 break;
823             case EN0_RCNTLO:
824                 regs->rbcr0 = val;
825                 break;
826             case EN0_RCNTHI:
827                 regs->rbcr1 = val;
828                 break;
829             case EN0_RXCR:
830                 regs->rcr.val = val;
831                 break;
832             case EN0_TXCR:
833                 regs->tcr.val = val;
834                 break;
835             case EN0_DCFG:
836                 regs->dcr.val = val;
837                 break;  
838             case EN0_IMR:
839                 regs->imr.val = val;
840                 ne2k_update_irq(nic_state);
841                 break;
842
843             default:
844                 PrintError("NE2000 port write error: invalid port:0x%x\n", port);
845                 return -1;
846         }
847     } else if (page == 1) {
848         switch (idx) {
849             case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
850                 nic_state->mac[port - EN1_PHYS] = val;
851                 break;
852             case EN1_CURPAG:
853                 regs->curpag = val;
854                 break;
855             case EN1_MULT ... EN1_MULT + 7:
856                 nic_state->mcast_addr[port - EN1_MULT] = val;
857                 break;
858                 
859             default:
860                 PrintError("NE2000 write port error: invalid port:0x%x\n", port);
861                 return -1;
862         }
863     } else if (page == 2) {
864         switch (idx) {
865             case EN2_LDMA0:
866                 regs->clda0 = val;
867                 break;
868             case EN2_LDMA1:
869                 regs->clda1 = val;
870                 break;
871             case EN2_RNPR:
872                 regs->rnpp = val;
873                 break;
874             case EN2_LNRP:
875                 regs->lnpp = val;
876                 break;
877             case EN2_ACNT0:
878                 regs->addcnt0 = val;
879                 break;
880             case EN2_ACNT1: 
881                 regs->addcnt1 = val;
882                 break;
883                 
884             default:
885                 PrintError("NE2000 write port error: invalid port:0x%x\n", port);
886                 return -1;
887         }
888     } else {
889         PrintError("NE2000: Invalid Register Page Value\n");
890         return -1;
891     }
892
893
894     return length;
895         
896 }
897
898 static int ne2k_std_read(struct guest_info * core, 
899                          uint16_t port, 
900                          void * dst, 
901                          uint_t length, 
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;
907
908     if (length > 1) {
909         PrintError("ne2k_read error: length %d\n", length);
910         return length;
911     }
912
913     if (page == 0) {
914         switch (index) {                
915             case EN0_CLDALO:
916                 *(uint8_t *)dst = regs->clda0;
917                 break;
918             case EN0_CLDAHI:
919                 *(uint8_t *)dst = regs->clda1;
920                 break;
921             case EN0_BOUNDARY:
922                 *(uint8_t *)dst = regs->boundary;
923                 break;
924             case EN0_TSR:
925                 *(uint8_t *)dst = regs->tsr.val;
926                 break;
927             case EN0_NCR:
928                 *(uint8_t *)dst = regs->ncr;
929                 break;
930             case EN0_FIFO:
931                 *(uint8_t *)dst = regs->fifo;
932                 break;
933             case EN0_ISR:
934                 *(uint8_t *)dst = regs->isr.val;
935                 ne2k_update_irq(nic_state);
936                 break;
937             case EN0_CRDALO:
938                 *(uint8_t *)dst = regs->crda0;
939                 break;
940             case EN0_CRDAHI:
941                 *(uint8_t *)dst = regs->crda1;
942                 break;
943             case EN0_RSR:
944                 *(uint8_t *)dst = regs->rsr.val;
945                 break;
946             case EN0_COUNTER0:
947                 *(uint8_t *)dst = regs->cntr0;
948                 break;
949             case EN0_COUNTER1:
950                 *(uint8_t *)dst = regs->cntr1;
951                 break;  
952             case EN0_COUNTER2:
953                 *(uint8_t *)dst = regs->cntr2;
954                 break;
955                 
956             default:
957                 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
958                 return -1;
959         }
960     } else if (page == 1) {
961         switch (index) {
962             case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
963                 *(uint8_t *)dst = nic_state->mac[index - EN1_PHYS];
964                 break;
965             case EN1_CURPAG:
966                 *(uint8_t *)dst = regs->curpag;
967                 break;
968             case EN1_MULT ... EN1_MULT + 7:
969                 *(uint8_t *)dst = nic_state->mcast_addr[index - EN1_MULT];
970                 break;
971                 
972             default:
973                 PrintError("ne2k_read error: invalid port:0x%x\n", port);
974                 return -1;
975         }
976     } else if (page == 2) {
977         switch (index) {
978             case EN2_STARTPG:
979                 *(uint8_t *)dst = regs->pgstart;
980                 break;
981             case EN2_STOPPG:
982                 *(uint8_t *)dst = regs->pgstop;
983                 break;
984             case EN2_RNPR:
985                 *(uint8_t *)dst = regs->rnpp;
986                 break;
987             case EN2_LNRP:
988                 *(uint8_t *)dst = regs->lnpp;
989                 break;
990             case EN2_TPSR:
991                 *(uint8_t *)dst = regs->tpsr;
992                 break;
993             case EN2_ACNT0:
994                 *(uint8_t *)dst = regs->addcnt0;
995                 break;
996             case EN2_ACNT1: 
997                 *(uint8_t *)dst = regs->addcnt1;
998                 break;
999             case EN2_RCR:
1000                 *(uint8_t *)dst = regs->rcr.val;
1001                 break;
1002             case EN2_TCR:
1003                 *(uint8_t *)dst = regs->tcr.val;
1004                 break;
1005             case EN2_DCR:
1006                 *(uint8_t *)dst = regs->dcr.val;
1007                 break;
1008             case EN2_IMR:
1009                 *(uint8_t *)dst = regs->imr.val;
1010                 break;
1011             default:
1012                 PrintError("NE2000 port read error: invalid port:0x%x\n", port);
1013                 return -1;
1014         }
1015     } else {
1016         PrintError("NE2000 port read: Invalid Register Page Value\n");
1017         return -1;
1018     }
1019
1020     PrintDebug("NE2000 port read: port:0x%x  val: 0x%x\n", port, *(uint8_t *)dst);
1021
1022     return length;
1023 }
1024
1025
1026
1027 static int ne2k_pci_write(struct guest_info * core, 
1028                           uint16_t port, 
1029                           void * src, 
1030                           uint_t length, 
1031                           void * private_data) {
1032     uint16_t idx = port & 0x1f;
1033     int ret;
1034
1035     switch (idx) {
1036         case NIC_REG_BASE_PORT:
1037             ret =  ne2k_cmd_write(core, port, src, length, private_data);
1038             break;
1039         case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15:
1040             ret = ne2k_std_write(core, port, src, length, private_data);
1041             break;
1042         case NIC_DATA_PORT:
1043             ret = ne2k_data_write(core, port, src, length, private_data);
1044             break;
1045         case NIC_RESET_PORT:
1046             ret = ne2k_reset_port_write(core, port, src, length, private_data);
1047             break;
1048
1049         default:
1050             PrintError("NE2000 port write error: invalid port:0x%x\n", port);
1051             return -1;
1052     }
1053
1054     return ret;
1055 }
1056
1057 static int ne2k_pci_read(struct guest_info * core, 
1058                          uint16_t port, 
1059                          void * dst, 
1060                          uint_t length, 
1061                          void * private_data) {
1062     uint16_t idx = port & 0x1f;
1063     int ret;
1064
1065     switch (idx) {
1066         case NIC_REG_BASE_PORT:
1067             ret =  ne2k_cmd_read(core, port, dst, length, private_data);
1068             break;
1069         case NIC_REG_BASE_PORT+1 ... NIC_REG_BASE_PORT+15:
1070             ret = ne2k_std_read(core, port, dst, length, private_data);
1071             break;
1072         case NIC_DATA_PORT:
1073             ret = ne2k_data_read(core, port, dst, length, private_data);
1074             break;
1075         case NIC_RESET_PORT:
1076             ret = ne2k_reset_port_read(core, port, dst, length, private_data);
1077             break;
1078
1079         default:
1080             PrintError("NE2000 port read error: invalid port:0x%x\n", port);
1081             return -1;
1082     }
1083
1084     return ret;
1085
1086
1087 }
1088
1089 static int pci_config_update(uint_t reg_num, 
1090                              void * src, 
1091                              uint_t length,
1092                              void * private_data) {
1093     PrintDebug("PCI Config Update\n");
1094
1095     /* Do we need this? */
1096
1097     return 0;
1098 }
1099
1100
1101 static int register_dev(struct ne2k_state * nic_state) 
1102 {
1103     int i;
1104
1105     if (nic_state->pci_bus != NULL) {
1106         struct v3_pci_bar bars[6];
1107         struct pci_device * pci_dev = NULL;
1108
1109         PrintDebug("NE2000: PCI Enabled\n");
1110
1111         for (i = 0; i < 6; i++) {
1112             bars[i].type = PCI_BAR_NONE;
1113         }
1114
1115         bars[0].type = PCI_BAR_IO;
1116         bars[0].default_base_port = NIC_REG_BASE_PORT;
1117         bars[0].num_ports = 256;
1118
1119         bars[0].io_read = ne2k_pci_read;
1120         bars[0].io_write = ne2k_pci_write;
1121        bars[0].private_data = nic_state;
1122
1123         pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0, 
1124                                          "NE2000", bars,
1125                                          pci_config_update, NULL, NULL, nic_state);
1126
1127
1128         if (pci_dev == NULL) {
1129             PrintError("NE2000: Could not register PCI Device\n");
1130             return -1;
1131         }
1132         
1133         pci_dev->config_header.vendor_id = 0x10ec;
1134         pci_dev->config_header.device_id = 0x8029;
1135         pci_dev->config_header.revision = 0x00;
1136
1137         pci_dev->config_header.subclass = 0x00;
1138         pci_dev->config_header.class = 0x02;
1139         pci_dev->config_header.header_type = 0x00;
1140
1141         pci_dev->config_header.intr_line = 11;
1142         pci_dev->config_header.intr_pin = 1;
1143
1144         nic_state->pci_dev = pci_dev;
1145     }else {
1146         PrintDebug("NE2000: Not attached to PCI\n");
1147
1148         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT , &ne2k_cmd_read, &ne2k_cmd_write);
1149
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);
1152         }
1153
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);
1156     }
1157
1158
1159     return 0;
1160 }
1161
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;
1168
1169     ne2k_init_state(nic_state);
1170     register_dev(nic_state);
1171
1172     nic_state->net_ops = ops;
1173     nic_state->backend_data = private_data;     
1174
1175     ops->recv = ne2k_rx;
1176     ops->poll = NULL;
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);
1181
1182     return 0;
1183 }
1184
1185
1186 static int ne2k_free(struct ne2k_state * nic_state) {
1187     int i;
1188
1189     /* dettached from backend */
1190
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);
1194         }
1195     
1196        v3_dev_unhook_io(nic_state->dev, NIC_DATA_PORT);
1197        v3_dev_unhook_io(nic_state->dev, NIC_RESET_PORT);
1198     }else {
1199        /* unregistered from PCI? */
1200     }
1201
1202     V3_Free(nic_state);
1203         
1204     return 0;
1205 }
1206
1207
1208 static struct v3_device_ops dev_ops = {
1209     .free = (int (*)(void *))ne2k_free,
1210 };
1211
1212
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");
1218
1219     nic_state  = (struct ne2k_state *)V3_Malloc(sizeof(struct ne2k_state));
1220     memset(nic_state, 0, sizeof(struct ne2k_state));
1221
1222     nic_state->pci_bus = pci_bus;
1223     nic_state->vm = vm;
1224
1225     if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1226         PrintDebug("NE2000: Mac specified %s\n", macstr);
1227     }else {
1228         PrintDebug("NE2000: MAC not specified\n");
1229         random_ethaddr(nic_state->mac);
1230     }
1231
1232     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1233
1234     if (dev == NULL) {
1235         PrintError("NE2000: Could not attach device %s\n", dev_id);
1236         V3_Free(nic_state);
1237         return -1;
1238     }
1239
1240     nic_state->dev = dev;
1241
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);
1245         V3_Free(nic_state);
1246         return -1;
1247     }
1248             
1249     return 0;
1250 }
1251
1252 device_register("NE2000", ne2k_init)