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.


Cleanup and sanity-checking of OOB accesses and pointer-to-local issues (Coverity...
[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 V3_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
47 #define NE2K_CMD_OFFSET 0x00
48 #define NE2K_DATA_OFFSET        0x10
49 #define NE2K_RESET_OFFSET       0x1f
50
51 /* Page 0 registers */
52 #define EN0_CLDALO              0x01    /* Low byte of current local dma addr  RD */
53 #define EN0_STARTPG             0x01    /* Starting page of ring bfr WR  */
54 #define EN0_CLDAHI              0x02    /* High byte of current local dma addr  RD  */
55 #define EN0_STOPPG              0x02    /* Ending page +1 of ring bfr WR */
56 #define EN0_BOUNDARY            0x03    /* Boundary page of ring bfr RD WR */
57 #define EN0_TSR                 0x04    /* Transmit status reg RD */
58 #define EN0_TPSR                0x04    /* Transmit starting page WR */
59 #define EN0_NCR                 0x05    /* Number of collision reg RD */
60 #define EN0_TCNTLO              0x05    /* Low  byte of tx byte count WR */
61 #define EN0_FIFO                0x06    /* FIFO RD */
62 #define EN0_TCNTHI              0x06    /* High byte of tx byte count WR */
63 #define EN0_ISR                 0x07    /* Interrupt status reg RD WR */
64 #define EN0_CRDALO              0x08    /* low byte of current remote dma address RD */
65 #define EN0_RSARLO              0x08    /* Remote start address reg 0 */
66 #define EN0_CRDAHI              0x09    /* high byte, current remote dma address RD */
67 #define EN0_RSARHI              0x09    /* Remote start address reg 1 */
68 #define EN0_RCNTLO              0x0a    /* Remote byte count reg WR */
69 #define EN0_RTL8029ID0          0x0a    /* Realtek ID byte #1 RD */
70 #define EN0_RCNTHI              0x0b    /* Remote byte count reg WR */
71 #define EN0_RTL8029ID1          0x0b    /* Realtek ID byte #2 RD */
72 #define EN0_RSR                 0x0c    /* rx status reg RD */
73 #define EN0_RXCR                0x0c    /* RX configuration reg WR */
74 #define EN0_TXCR                0x0d    /* TX configuration reg WR */
75 #define EN0_COUNTER0            0x0d    /* Rcv alignment error counter RD */
76 #define EN0_DCFG                0x0e    /* Data configuration reg WR */
77 #define EN0_COUNTER1            0x0e    /* Rcv CRC error counter RD */
78 #define EN0_IMR                 0x0f    /* Interrupt mask reg WR */
79 #define EN0_COUNTER2            0x0f    /* Rcv missed frame error counter RD */
80
81 /* Page 1 registers */
82 #define EN1_PHYS                0x01
83 #define EN1_CURPAG              0x07
84 #define EN1_MULT                0x08
85
86 /* Page 2 registers */
87 #define EN2_STARTPG             0x01    /* Starting page of ring bfr RD */
88 #define EN2_STOPPG              0x02    /* Ending page +1 of ring bfr RD */
89 #define EN2_LDMA0               0x01    /* Current Local DMA Address 0 WR */
90 #define EN2_LDMA1               0x02    /* Current Local DMA Address 1 WR */
91 #define EN2_RNPR                0x03    /* Remote Next Packet Pointer RD WR */
92 #define EN2_TPSR                0x04            /* Transmit Page Start Address RD */
93 #define EN2_LNRP                0x05    /* Local Next Packet Pointer RD WR */
94 #define EN2_ACNT0               0x06    /* Address Counter Upper WR */
95 #define EN2_ACNT1               0x07    /* Address Counter Lower WR */
96 #define EN2_RCR                 0x0c    /* Receive Configuration Register RD */
97 #define EN2_TCR                 0x0d    /* Transmit Configuration Register RD */
98 #define EN2_DCR                 0x0e    /* Data Configuration Register RD */
99 #define EN2_IMR                 0x0f    /* Interrupt Mask Register RD */
100
101 /* Page 3 registers */
102 #define EN3_CONFIG0             0x03
103 #define EN3_CONFIG1             0x04
104 #define EN3_CONFIG2             0x05
105 #define EN3_CONFIG3             0x06
106
107
108 struct cmd_reg {
109     union {
110         uint8_t val;
111         struct {
112             uint8_t stop        : 1;
113             uint8_t start       : 1;
114             uint8_t tx_pkt      : 1;
115             uint8_t rem_dma_cmd : 3;    /* 0=Not allowed, 1=Read, 2=Write, 3=Send Pkt, 4=Abort/Complete DMA */
116             uint8_t pg_sel      : 2;
117         } __attribute__((packed));
118     } __attribute__((packed));
119 } __attribute__((packed));
120
121
122 struct intr_status_reg {
123     union {
124         uint8_t val;
125         struct {
126             uint8_t pkt_rx          : 1;
127             uint8_t pkt_tx          : 1;
128             uint8_t rx_err          : 1;
129             uint8_t tx_err          : 1;
130             uint8_t overwrite_warn  : 1;
131             uint8_t cnt_overflow    : 1;
132             uint8_t rem_dma_done    : 1;
133             uint8_t reset_status    : 1;
134         } __attribute__((packed));
135     } __attribute__((packed));
136 } __attribute__((packed));
137
138
139 struct intr_mask_reg {
140     union {
141         uint8_t val;
142         struct {
143             uint8_t pkt_rx          : 1;
144             uint8_t pkt_tx          : 1;
145             uint8_t rx_err          : 1;
146             uint8_t tx_err          : 1;
147             uint8_t overwrite_warn  : 1;
148             uint8_t cnt_overflow    : 1;
149             uint8_t rem_dma_done    : 1;
150             uint8_t rsvd            : 1;
151         } __attribute__((packed));
152     } __attribute__((packed));
153 } __attribute__((packed));
154
155
156 struct data_cfg_reg {
157     union {
158         uint8_t val;
159         struct {
160             uint8_t word_trans_sel   : 1;
161             uint8_t byte_order_sel   : 1;
162             uint8_t long_addr_sel    : 1;
163             uint8_t loopback_sel     : 1;
164             uint8_t auto_init_rem    : 1;
165             uint8_t fifo_thresh_sel  : 2;
166             uint8_t rsvd             : 1;
167         } __attribute__((packed));
168     } __attribute__((packed));
169 } __attribute__((packed));
170
171
172 struct tx_cfg_reg { 
173     union {
174         uint8_t val;
175         struct {
176             uint8_t inhibit_crc     : 1;
177             uint8_t enc_loop_ctrl   : 2;
178             uint8_t auto_tx_disable : 1;
179             uint8_t coll_offset_en  : 1;
180             uint8_t rsvd            : 3;
181         } __attribute__((packed));
182     } __attribute__((packed));
183 } __attribute__((packed));
184
185 struct tx_status_reg { 
186     union {
187         uint8_t val;
188         struct {
189             uint8_t pkt_tx_ok       : 1;
190             uint8_t rsvd            : 1;
191             uint8_t tx_collision    : 1;
192             uint8_t tx_aborted      : 1;
193             uint8_t carrier_lost    : 1;
194             uint8_t fifo_underrun   : 1;
195             uint8_t cd_heartbeat    : 1;
196             uint8_t oow_collision   : 1;
197         } __attribute__((packed));
198     } __attribute__((packed));
199 } __attribute__((packed));
200
201 struct rx_cfg_reg { 
202     union {
203         uint8_t val;
204         struct {
205             uint8_t save_pkt_errs    : 1;
206             uint8_t runt_pkt_ok      : 1;
207             uint8_t bcast_ok         : 1;
208             uint8_t mcast_ok         : 1;
209             uint8_t prom_phys_enable : 1;
210             uint8_t mon_mode         : 1;
211             uint8_t rsvd             : 2;
212         } __attribute__((packed));
213     } __attribute__((packed));
214 } __attribute__((packed));
215
216
217 struct rx_status_reg { 
218     union {
219         uint8_t val;
220         struct {
221             uint8_t pkt_rx_ok        : 1;
222             uint8_t crc_err          : 1;
223             uint8_t frame_align_err  : 1;
224             uint8_t fifo_overrun     : 1;
225             uint8_t missed_pkt       : 1;
226             uint8_t phy_match        : 1;   /* 0=Physical Addr Match, 1=MCAST/BCAST Addr Match */
227             uint8_t rx_disabled      : 1;
228             uint8_t deferring        : 1;
229         } __attribute__((packed));
230     } __attribute__((packed));
231 } __attribute__((packed));
232
233
234 struct ne2k_registers {
235     struct cmd_reg cmd;
236     struct intr_status_reg isr;
237     struct intr_mask_reg imr;
238     struct data_cfg_reg dcr;
239     struct tx_cfg_reg tcr;
240     struct tx_status_reg tsr;
241     struct rx_cfg_reg rcr;
242     struct rx_status_reg rsr;  
243
244     uint8_t      pgstart;      /* page start reg */
245     uint8_t      pgstop;       /* page stop reg */
246     uint8_t      boundary;     /* boundary ptr */
247     uint8_t      tpsr;         /* tx page start addr */
248     uint8_t      ncr;          /* number of collisions */
249     uint8_t      fifo;         /* FIFO... */
250
251     uint8_t      curpag;       /* current page */
252     uint8_t      rnpp;         /* rem next pkt ptr */
253     uint8_t      lnpp;         /* local next pkt ptr */
254
255     uint8_t      cntr0;        /* counter 0 (frame alignment errors) */
256     uint8_t      cntr1;        /* counter 1 (CRC Errors) */
257     uint8_t      cntr2;        /* counter 2 (missed pkt errors) */
258
259     union {                    /* current local DMA Addr */
260         uint16_t     clda;
261         struct {
262             uint8_t clda0;
263             uint8_t clda1;
264         } __attribute__((packed));
265     } __attribute__((packed));
266
267
268     union {                    /* current remote DMA addr */
269         uint16_t     crda;
270         struct {
271             uint8_t crda0;
272             uint8_t crda1;
273         } __attribute__((packed));
274     } __attribute__((packed));
275
276
277     union {                    /* Remote Start Addr Reg */
278         uint16_t     rsar;
279         struct {
280             uint8_t rsar0;
281             uint8_t rsar1;
282         } __attribute__((packed));
283     } __attribute__((packed));
284
285
286     union {                    /* TX Byte count Reg */
287         uint16_t     tbcr;
288         struct {
289             uint8_t tbcr0;
290             uint8_t tbcr1;
291         } __attribute__((packed));
292     } __attribute__((packed));
293
294     union {                    /* Remote Byte count Reg */
295         uint16_t     rbcr;
296         struct {
297             uint8_t rbcr0;
298             uint8_t rbcr1;
299         } __attribute__((packed));
300     } __attribute__((packed));
301
302     union {                    /* Address counter? */
303         uint16_t     addcnt;
304         struct {
305             uint8_t addcnt0;
306             uint8_t addcnt1;
307         } __attribute__((packed));
308     } __attribute__((packed));
309 };
310
311
312 struct ne2k_state {
313     struct v3_vm_info * vm;
314     struct pci_device * pci_dev;
315     struct vm_device * pci_bus;
316     struct vm_device * dev;
317
318     struct ne2k_registers context;
319     uint8_t mem[NE2K_MEM_SIZE];
320
321     uint8_t mcast_addr[8];
322     uint8_t mac[ETH_ALEN];
323
324     struct nic_statistics statistics;
325
326     struct v3_dev_net_ops *net_ops;
327     void * backend_data;
328 };
329
330 static int ne2k_update_irq(struct ne2k_state * nic_state) {
331     struct pci_device * pci_dev = nic_state->pci_dev;
332
333     if ((nic_state->context.isr.val & nic_state->context.imr.val) & 0x7f) {
334        if (pci_dev == NULL){
335             v3_raise_virq(&(nic_state->vm->cores[0]), NE2K_DEFAULT_IRQ);
336        } else {     
337            v3_pci_raise_irq(nic_state->pci_bus, nic_state->pci_dev, 0);
338        }
339
340        nic_state->statistics.rx_interrupts ++;
341
342        PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Raise IRQ\n");
343     }
344
345     return 0;
346 }
347
348 static int tx_one_pkt(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
349         
350 #ifdef V3_CONFIG_DEBUG_NE2K
351     PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Send Packet:\n");
352     v3_hexdump(pkt, length, NULL, 0);
353 #endif    
354
355     if(nic_state->net_ops->send(pkt, length, nic_state->backend_data) >= 0){
356         nic_state->statistics.tx_pkts ++;
357         nic_state->statistics.tx_bytes += length;
358
359         return 0;
360     }
361         
362     nic_state->statistics.tx_dropped ++;
363
364     return -1;
365 }
366
367 static int ne2k_rxbuf_full(struct ne2k_registers * regs) {
368     int empty;
369     int index;
370     int boundary;
371
372     index = regs->curpag << 8;
373     boundary = regs->boundary << 8;
374
375     if (index < boundary) {
376         empty = boundary - index;
377     } else {
378         empty = ((regs->pgstop - regs->pgstart) << 8) - (index - boundary);
379     }
380
381     if (empty < (ETHERNET_PACKET_LEN + 4)) {
382         return 1;
383     }
384
385     return 0;
386 }
387
388 #define MIN_BUF_SIZE 60
389
390
391 // This needs to be completely redone...
392 static int rx_one_pkt(struct ne2k_state * nic_state, const uchar_t * pkt,  uint32_t length) {
393     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
394     uchar_t buf[MIN_BUF_SIZE];
395     uchar_t * p;
396     uint32_t total_len;
397     uint32_t next;
398     uint32_t len;
399     uint32_t index;
400     uint32_t empty;
401     uint32_t start;
402     uint32_t stop;
403
404     start = regs->pgstart << 8;
405     stop = regs->pgstop << 8;
406    
407     if (regs->cmd.stop) {
408         return -1;
409     }
410
411     if (ne2k_rxbuf_full(regs)) {
412         PrintError(VM_NONE, VCORE_NONE, "Ne2k: received buffer overflow\n");
413         return -1;
414     }
415
416     //packet too small, expand it
417     if (length < MIN_BUF_SIZE) {
418         memcpy(buf, pkt, length);
419         memset(buf + length, 0, MIN_BUF_SIZE - length);
420         pkt = buf;
421         length = MIN_BUF_SIZE;
422     }
423
424     index = regs->curpag << 8;
425
426     //header, 4 bytes
427     total_len = length + 4;
428
429     //address for next packet (4 bytes for CRC)
430     next = index + ((total_len + 4 + 255) & ~0xff);
431
432     if (next >= stop) {
433         next -= (stop - start);
434     }
435
436     p = nic_state->mem + index;
437     regs->rsr.val = 0;
438     regs->rsr.pkt_rx_ok = 1;
439
440     if (pkt[0] & 0x01) {
441         regs->rsr.phy_match = 1; /* TODO: Check this back */
442     }
443
444     p[0] = regs->rsr.val;
445     p[1] = next >> 8;
446     p[2] = total_len;
447     p[3] = total_len >> 8;
448     index += 4;
449
450     while (length > 0) {
451         if (index <= stop) {
452             empty = stop - index;
453         } else {
454             empty = 0;
455         }
456
457         len = length;
458
459         if (len > empty) {
460             len = empty;
461         }
462
463         memcpy(nic_state->mem + index, pkt, len);
464         pkt += len;
465         index += len;
466
467         if (index == stop) {
468             index = start;
469         }
470
471         length -= len;
472     }
473
474     regs->curpag = next >> 8;
475
476     regs->isr.pkt_rx = 1;
477     ne2k_update_irq(nic_state);
478
479     return 0;
480 }
481
482
483 static int ne2k_rx(uint8_t * buf, uint32_t size, void * private_data){
484     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
485   
486 #ifdef V3_CONFIG_DEBUG_NE2K
487     PrintDebug(VM_NONE, VCORE_NONE, "\nNe2k: Packet Received:\n");
488     v3_hexdump(buf, size, NULL, 0);
489 #endif    
490
491     if(!rx_one_pkt(nic_state, buf, size)){
492         nic_state->statistics.rx_pkts ++;
493         nic_state->statistics.rx_bytes += size;
494         
495         return 0;
496     }
497
498     nic_state->statistics.rx_dropped ++;
499         
500     return -1;
501 }
502
503
504 static inline void mem_writeb(struct ne2k_state * nic_state, 
505                         uint32_t addr, 
506                         uint32_t val) {
507     uchar_t tmp = (uchar_t) (val & 0x000000ff);
508
509     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
510         nic_state->mem[addr] = tmp;
511     }
512 }
513
514 static inline void mem_writew(struct ne2k_state * nic_state, 
515                             uint32_t addr,
516                             uint32_t val) {
517     addr &= ~1;
518
519     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
520         *(uint16_t *)(nic_state->mem + addr) = val;
521     }
522 }
523
524 static inline void mem_writel(struct ne2k_state * nic_state,
525                             uint32_t addr,
526                             uint32_t val) {
527     addr &= ~1;
528
529     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
530         *(uint32_t *)(nic_state->mem + addr) = val;
531     }
532 }
533
534 static inline uint8_t  mem_readb(struct ne2k_state * nic_state, uint32_t addr) {
535         
536     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
537         return nic_state->mem[addr];
538     } else {
539         return 0xff;
540     }
541 }
542
543 static inline uint16_t mem_readw(struct ne2k_state * nic_state, uint32_t addr) {
544     addr &= ~1;
545
546     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
547         return *(uint16_t *)(nic_state->mem + addr);
548     } else {
549         return 0xffff;
550     }
551 }
552
553 static uint32_t mem_readl(struct ne2k_state * nic_state, uint32_t addr) {
554     addr &= ~1;
555
556     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
557         return *(uint32_t *)(nic_state->mem + addr);
558     } else {
559         return 0xffffffff;
560     }
561 }
562
563
564 static void dma_update( struct ne2k_state * nic_state, int len) {                       
565     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
566
567     regs->rsar += len;
568
569     // wrap
570     if (regs->rsar == regs->pgstop) {
571         regs->rsar = regs->pgstart;
572     }
573
574     if (regs->rbcr <= len) {
575         regs->rbcr = 0;
576         regs->isr.rem_dma_done = 1;
577         ne2k_update_irq(nic_state);
578     } else {
579         regs->rbcr -= len;
580     }
581 }
582
583 static int ne2k_data_read(struct guest_info * core, 
584                           uint16_t port, 
585                           void * dst, 
586                           uint_t length, 
587                           void * private_data) {
588     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
589     uint32_t val;
590     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
591
592     // current dma address
593     uint32_t addr = regs->rsar;
594
595     switch (length){
596         case 1:
597             val = mem_readb(nic_state, addr);
598             break;
599         case 2:
600             val = mem_readw(nic_state, addr);
601             break;
602         case 4:
603             val = mem_readl(nic_state, addr);
604             break;
605         default:
606             PrintError(VM_NONE, VCORE_NONE, "ne2k_data_read error: invalid length %d\n", length);
607             val = 0x0;
608     }
609     
610     dma_update(nic_state, length);
611     memcpy(dst, &val, length);
612
613     PrintDebug(VM_NONE, VCORE_NONE, "NE2000 read: port:0x%x (%u bytes): 0x%x", port & 0x1f, length, val);
614
615     return length;
616 }
617
618 static int ne2k_data_write(struct guest_info * core, 
619                            uint16_t port, 
620                            void * src, 
621                            uint_t length, 
622                            void * private_data) {
623     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
624     uint32_t val;
625     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
626         
627     uint32_t addr = regs->rsar;
628         
629     if (regs->rbcr == 0) {
630         return length;
631     }
632
633     memcpy(&val, src, length);
634
635     switch (length) {
636         case 1:
637             mem_writeb(nic_state, addr, val);
638             break;
639         case 2:
640             mem_writew(nic_state, addr, val);
641             break;
642         case 4:
643             mem_writel(nic_state, addr, val);
644             break;
645         default:
646             PrintError(VM_NONE, VCORE_NONE, "NE2000 port write error: invalid length %d\n", length);
647     }
648     
649     dma_update(nic_state, length);
650
651     PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Write port:0x%x (%u bytes): 0x%x\n", port & 0x1f, length, val);
652     
653     return length;
654 }
655
656
657 static void ne2k_init_state(struct ne2k_state * nic_state) {
658
659
660     /* Not sure what this is about....  */
661     memset(nic_state->mem, 0xff, 32); 
662         
663     memcpy(nic_state->mem, nic_state->mac, ETH_ALEN);
664     memset(nic_state->mcast_addr, 0xff, sizeof(nic_state->mcast_addr));
665     nic_state->mem[14] = 0x57;
666     nic_state->mem[15] = 0x57;
667
668     /* initiate registers */
669     nic_state->context.isr.reset_status = 1;
670     nic_state->context.imr.val = 0x00;
671     nic_state->context.cmd.val = 0x22;
672 }
673
674 static int reset_device(struct ne2k_state * nic_state) {  
675     ne2k_init_state(nic_state);
676
677     PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Reset device\n");
678
679     return 0;
680 }
681
682 //for 0xc11f port
683 static int ne2k_reset_port_read(struct guest_info * core, 
684                                 uint16_t port, 
685                                 void * dst, 
686                                 uint_t length, 
687                                 void * private_data) {
688     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
689
690     memset(dst, 0, length);
691     reset_device(nic_state);
692
693     return length;
694 }
695
696 static int ne2k_reset_port_write(struct guest_info * core, 
697                                  uint16_t port, 
698                                  void * src, 
699                                  uint_t length, 
700                                  void * private_data) {
701
702     return length;
703 }
704
705
706
707 static int ne2k_cmd_write(struct guest_info * core, 
708                           uint16_t port, 
709                           void * src, 
710                           uint_t length, 
711                           void * private_data) {
712     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
713     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
714
715     if (length != 1) {
716         PrintError(core->vm_info, core, "Invalid write length to NE2000 Command register\n");
717         return -1;
718     }
719
720     regs->cmd.val = *(uint8_t *)src;
721
722     if (!(regs->cmd.stop)) {
723         regs->isr.reset_status = 0;
724         
725         // if ((send pkt) && (dma byte count == 0)) 
726         if ((regs->cmd.rem_dma_cmd & 0x3) && (regs->rbcr == 0)) {
727             regs->isr.rem_dma_done = 1;
728             ne2k_update_irq(nic_state);
729         }
730         
731         if (regs->cmd.tx_pkt) {
732             int offset = (regs->tpsr << 8);
733             
734             if (offset >= NE2K_PMEM_END) {
735                 offset -= NE2K_PMEM_SIZE;
736             }
737
738             if (offset + regs->tbcr <= NE2K_PMEM_END) {
739                 tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr);
740             }
741
742             regs->tsr.val = 0;        /* clear the tx status reg */
743             regs->tsr.pkt_tx_ok = 1;  /* indicate successful tx */
744
745             regs->isr.pkt_tx = 1;     /* irq due to pkt tx */
746             regs->cmd.tx_pkt = 0;     /* reset cmd bit  */
747             
748             ne2k_update_irq(nic_state);
749         }
750     } else {
751         /* stop the controller */
752     }
753
754     return length;
755 }
756
757 static int ne2k_cmd_read(struct guest_info * core, 
758                          uint16_t port, 
759                          void * dst, 
760                          uint_t length, 
761                          void * private_data) {
762     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
763
764     if (length != 1) {
765         PrintError(core->vm_info, core, "Invalid read length to NE2000 Command register\n");
766         return -1;
767     }
768
769     *(uint8_t *)dst = nic_state->context.cmd.val;
770
771     PrintDebug(core->vm_info, core, "ne2k_read: port:0x%x  val: 0x%x\n", port, *(uint8_t *)dst);
772     return length;
773 }
774
775 static int ne2k_std_write(struct guest_info * core, 
776                           uint16_t port, 
777                           void * src, 
778                           uint_t length, 
779                           void * private_data) {
780     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
781     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
782     int idx = port & 0x1f;
783     uint8_t page = regs->cmd.pg_sel;
784
785     if (length != 1){
786         PrintError(core->vm_info, core, "NE2000 port write error: length %d port 0x%xnot equal to 1\n", length, port);  
787         return -1;
788     }
789
790     uint8_t val = *(uint8_t *)src;
791         
792     PrintDebug(core->vm_info, core, "NE2000: write port:0x%x val: 0x%x\n", port, (uint8_t)val);
793     
794     if (page == 0) {
795         switch (idx) {
796             case EN0_STARTPG:
797                 regs->pgstart = val;
798                 break;
799             case EN0_STOPPG:
800                 regs->pgstop = val;
801                 break;
802             case EN0_BOUNDARY:
803                 regs->boundary = val;
804                 break;
805             case EN0_TPSR:
806                 regs->tpsr = val;
807                 break;
808             case EN0_TCNTLO:
809                 regs->tbcr0 = val;
810                 break;
811             case EN0_TCNTHI:
812                 regs->tbcr1 = val;
813                 break;
814             case EN0_ISR:
815                 regs->isr.val &= ~(val & 0x7f);
816                 ne2k_update_irq(nic_state);
817                 break;
818             case EN0_RSARLO:
819                 regs->rsar0 = val;
820                 break;
821             case EN0_RSARHI:
822                 regs->rsar1 = val;
823                 break;
824             case EN0_RCNTLO:
825                 regs->rbcr0 = val;
826                 break;
827             case EN0_RCNTHI:
828                 regs->rbcr1 = val;
829                 break;
830             case EN0_RXCR:
831                 regs->rcr.val = val;
832                 break;
833             case EN0_TXCR:
834                 regs->tcr.val = val;
835                 break;
836             case EN0_DCFG:
837                 regs->dcr.val = val;
838                 break;  
839             case EN0_IMR:
840                 regs->imr.val = val;
841                 ne2k_update_irq(nic_state);
842                 break;
843
844             default:
845                 PrintError(core->vm_info, core, "NE2000 port write error: invalid port:0x%x\n", port);
846                 return -1;
847         }
848     } else if (page == 1) {
849         switch (idx) {
850             case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
851                 nic_state->mac[port - EN1_PHYS] = val;
852                 break;
853             case EN1_CURPAG:
854                 regs->curpag = val;
855                 break;
856             case EN1_MULT ... EN1_MULT + 7:
857                 nic_state->mcast_addr[port - EN1_MULT] = val;
858                 break;
859                 
860             default:
861                 PrintError(core->vm_info, core, "NE2000 write port error: invalid port:0x%x\n", port);
862                 return -1;
863         }
864     } else if (page == 2) {
865         switch (idx) {
866             case EN2_LDMA0:
867                 regs->clda0 = val;
868                 break;
869             case EN2_LDMA1:
870                 regs->clda1 = val;
871                 break;
872             case EN2_RNPR:
873                 regs->rnpp = val;
874                 break;
875             case EN2_LNRP:
876                 regs->lnpp = val;
877                 break;
878             case EN2_ACNT0:
879                 regs->addcnt0 = val;
880                 break;
881             case EN2_ACNT1: 
882                 regs->addcnt1 = val;
883                 break;
884                 
885             default:
886                 PrintError(core->vm_info, core, "NE2000 write port error: invalid port:0x%x\n", port);
887                 return -1;
888         }
889     } else {
890         PrintError(core->vm_info, core, "NE2000: Invalid Register Page Value\n");
891         return -1;
892     }
893
894
895     return length;
896         
897 }
898
899 static int ne2k_std_read(struct guest_info * core, 
900                          uint16_t port, 
901                          void * dst, 
902                          uint_t length, 
903                          void * private_data) {
904     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
905     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
906     uint16_t index = port & 0x1f;
907     uint8_t page = regs->cmd.pg_sel;
908
909     if (length > 1) {
910         PrintError(core->vm_info, core, "ne2k_read error: length %d\n", length);
911         return length;
912     }
913
914     if (page == 0) {
915         switch (index) {                
916             case EN0_CLDALO:
917                 *(uint8_t *)dst = regs->clda0;
918                 break;
919             case EN0_CLDAHI:
920                 *(uint8_t *)dst = regs->clda1;
921                 break;
922             case EN0_BOUNDARY:
923                 *(uint8_t *)dst = regs->boundary;
924                 break;
925             case EN0_TSR:
926                 *(uint8_t *)dst = regs->tsr.val;
927                 break;
928             case EN0_NCR:
929                 *(uint8_t *)dst = regs->ncr;
930                 break;
931             case EN0_FIFO:
932                 *(uint8_t *)dst = regs->fifo;
933                 break;
934             case EN0_ISR:
935                 *(uint8_t *)dst = regs->isr.val;
936                 ne2k_update_irq(nic_state);
937                 break;
938             case EN0_CRDALO:
939                 *(uint8_t *)dst = regs->crda0;
940                 break;
941             case EN0_CRDAHI:
942                 *(uint8_t *)dst = regs->crda1;
943                 break;
944             case EN0_RSR:
945                 *(uint8_t *)dst = regs->rsr.val;
946                 break;
947             case EN0_COUNTER0:
948                 *(uint8_t *)dst = regs->cntr0;
949                 break;
950             case EN0_COUNTER1:
951                 *(uint8_t *)dst = regs->cntr1;
952                 break;  
953             case EN0_COUNTER2:
954                 *(uint8_t *)dst = regs->cntr2;
955                 break;
956                 
957             default:
958                 PrintError(core->vm_info, core, "NE2000 port read error: invalid port:0x%x\n", port);
959                 return -1;
960         }
961     } else if (page == 1) {
962         switch (index) {
963             case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
964                 *(uint8_t *)dst = nic_state->mac[index - EN1_PHYS];
965                 break;
966             case EN1_CURPAG:
967                 *(uint8_t *)dst = regs->curpag;
968                 break;
969             case EN1_MULT ... EN1_MULT + 7:
970                 *(uint8_t *)dst = nic_state->mcast_addr[index - EN1_MULT];
971                 break;
972                 
973             default:
974                 PrintError(core->vm_info, core, "ne2k_read error: invalid port:0x%x\n", port);
975                 return -1;
976         }
977     } else if (page == 2) {
978         switch (index) {
979             case EN2_STARTPG:
980                 *(uint8_t *)dst = regs->pgstart;
981                 break;
982             case EN2_STOPPG:
983                 *(uint8_t *)dst = regs->pgstop;
984                 break;
985             case EN2_RNPR:
986                 *(uint8_t *)dst = regs->rnpp;
987                 break;
988             case EN2_LNRP:
989                 *(uint8_t *)dst = regs->lnpp;
990                 break;
991             case EN2_TPSR:
992                 *(uint8_t *)dst = regs->tpsr;
993                 break;
994             case EN2_ACNT0:
995                 *(uint8_t *)dst = regs->addcnt0;
996                 break;
997             case EN2_ACNT1: 
998                 *(uint8_t *)dst = regs->addcnt1;
999                 break;
1000             case EN2_RCR:
1001                 *(uint8_t *)dst = regs->rcr.val;
1002                 break;
1003             case EN2_TCR:
1004                 *(uint8_t *)dst = regs->tcr.val;
1005                 break;
1006             case EN2_DCR:
1007                 *(uint8_t *)dst = regs->dcr.val;
1008                 break;
1009             case EN2_IMR:
1010                 *(uint8_t *)dst = regs->imr.val;
1011                 break;
1012             default:
1013                 PrintError(core->vm_info, core, "NE2000 port read error: invalid port:0x%x\n", port);
1014                 return -1;
1015         }
1016     } else {
1017         PrintError(core->vm_info, core, "NE2000 port read: Invalid Register Page Value\n");
1018         return -1;
1019     }
1020
1021     PrintDebug(core->vm_info, core, "NE2000 port read: port:0x%x  val: 0x%x\n", port, *(uint8_t *)dst);
1022
1023     return length;
1024 }
1025
1026
1027
1028 static int ne2k_pci_write(struct guest_info * core, 
1029                           uint16_t port, 
1030                           void * src, 
1031                           uint_t length, 
1032                           void * private_data) {
1033     uint16_t idx = port & 0x1f;
1034     int ret;
1035
1036     switch (idx) {
1037         case NE2K_CMD_OFFSET:
1038             ret =  ne2k_cmd_write(core, port, src, length, private_data);
1039             break;
1040         case NE2K_CMD_OFFSET+1 ... NE2K_CMD_OFFSET+15:
1041             ret = ne2k_std_write(core, port, src, length, private_data);
1042             break;
1043         case NE2K_DATA_OFFSET:
1044             ret = ne2k_data_write(core, port, src, length, private_data);
1045             break;
1046         case NE2K_RESET_OFFSET:
1047             ret = ne2k_reset_port_write(core, port, src, length, private_data);
1048             break;
1049
1050         default:
1051             PrintError(core->vm_info, core, "NE2000 port write error: invalid port:0x%x\n", port);
1052             return -1;
1053     }
1054
1055     return ret;
1056 }
1057
1058 static int ne2k_pci_read(struct guest_info * core, 
1059                          uint16_t port, 
1060                          void * dst, 
1061                          uint_t length, 
1062                          void * private_data) {
1063     uint16_t idx = port & 0x1f;
1064     int ret;
1065
1066     switch (idx) {
1067         case NE2K_CMD_OFFSET:
1068             ret =  ne2k_cmd_read(core, port, dst, length, private_data);
1069             break;
1070         case NE2K_CMD_OFFSET+1 ... NE2K_CMD_OFFSET+15:
1071             ret = ne2k_std_read(core, port, dst, length, private_data);
1072             break;
1073         case NE2K_DATA_OFFSET:
1074             ret = ne2k_data_read(core, port, dst, length, private_data);
1075             break;
1076         case NE2K_RESET_OFFSET:
1077             ret = ne2k_reset_port_read(core, port, dst, length, private_data);
1078             break;
1079
1080         default:
1081             PrintError(core->vm_info, core, "NE2000 port read error: invalid port:0x%x\n", port);
1082             return -1;
1083     }
1084
1085     return ret;
1086
1087
1088 }
1089
1090 static int pci_config_update(struct pci_device * pci_dev,
1091                         uint32_t reg_num,
1092                              void * src, 
1093                              uint_t length,
1094                              void * private_data) {
1095     PrintDebug(VM_NONE, VCORE_NONE, "PCI Config Update\n");
1096
1097     /* Do we need this? */
1098
1099     return 0;
1100 }
1101
1102
1103 static int register_dev(struct ne2k_state * nic_state) 
1104 {
1105     int i;
1106
1107     if (nic_state->pci_bus != NULL) {
1108         struct v3_pci_bar bars[6];
1109         struct pci_device * pci_dev = NULL;
1110
1111         PrintDebug(VM_NONE, VCORE_NONE, "NE2000: PCI Enabled\n");
1112
1113         for (i = 0; i < 6; i++) {
1114             bars[i].type = PCI_BAR_NONE;
1115         }
1116
1117         bars[0].type = PCI_BAR_IO;
1118         bars[0].default_base_port = -1;
1119         bars[0].num_ports = 256;
1120
1121         bars[0].io_read = ne2k_pci_read;
1122         bars[0].io_write = ne2k_pci_write;
1123        bars[0].private_data = nic_state;
1124
1125         pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0, 
1126                                          "NE2000", bars,
1127                                          pci_config_update, NULL, NULL, NULL, nic_state);
1128
1129
1130         if (pci_dev == NULL) {
1131             PrintError(VM_NONE, VCORE_NONE, "NE2000: Could not register PCI Device\n");
1132             return -1;
1133         }
1134         
1135         pci_dev->config_header.vendor_id = 0x10ec;
1136         pci_dev->config_header.device_id = 0x8029;
1137         pci_dev->config_header.revision = 0x00;
1138
1139         pci_dev->config_header.subclass = 0x00;
1140         pci_dev->config_header.class = 0x02;
1141         pci_dev->config_header.header_type = 0x00;
1142
1143         pci_dev->config_header.intr_line = 11;
1144         pci_dev->config_header.intr_pin = 1;
1145
1146         nic_state->pci_dev = pci_dev;
1147     }else {
1148         PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Not attached to PCI\n");
1149
1150         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT , &ne2k_cmd_read, &ne2k_cmd_write);
1151
1152         for (i = 1; i < 16; i++){       
1153             v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + i, &ne2k_std_read, &ne2k_std_write);
1154         }
1155
1156         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_DATA_OFFSET, &ne2k_data_read, &ne2k_data_write);
1157         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_RESET_OFFSET, &ne2k_reset_port_read, &ne2k_reset_port_write);
1158     }
1159
1160
1161     return 0;
1162 }
1163
1164 static int connect_fn(struct v3_vm_info * info, 
1165                       void * frontend_data, 
1166                       struct v3_dev_net_ops * ops, 
1167                       v3_cfg_tree_t * cfg, 
1168                       void * private_data) {
1169     struct ne2k_state * nic_state = (struct ne2k_state *)frontend_data;
1170
1171     ne2k_init_state(nic_state);
1172     register_dev(nic_state);
1173
1174     nic_state->net_ops = ops;
1175     nic_state->backend_data = private_data;     
1176
1177     ops->recv = ne2k_rx;
1178     ops->poll = NULL;   
1179     ops->config.frontend_data = nic_state;
1180     ops->config.fnt_mac = nic_state->mac;
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_REG_BASE_PORT + NE2K_DATA_OFFSET);
1197        v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_RESET_OFFSET);
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
1221     if (!nic_state) {
1222         PrintError(vm, VCORE_NONE, "Cannot allocate in init\n");
1223         return -1;
1224     }
1225
1226     memset(nic_state, 0, sizeof(struct ne2k_state));
1227
1228     nic_state->pci_bus = pci_bus;
1229     nic_state->vm = vm;
1230
1231     if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1232         PrintDebug(vm, VCORE_NONE, "NE2000: Mac specified %s\n", macstr);
1233     }else {
1234         PrintDebug(vm, VCORE_NONE, "NE2000: MAC not specified\n");
1235         random_ethaddr(nic_state->mac);
1236     }
1237
1238     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1239
1240     if (dev == NULL) {
1241         PrintError(vm, VCORE_NONE, "NE2000: Could not attach device %s\n", dev_id);
1242         V3_Free(nic_state);
1243         return -1;
1244     }
1245
1246     nic_state->dev = dev;
1247
1248     if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)nic_state) == -1) {
1249         PrintError(vm, VCORE_NONE, "NE2000: Could not register %s as net frontend\n", dev_id);
1250         v3_remove_device(dev);
1251         V3_Free(nic_state);
1252         return -1;
1253     }
1254             
1255     return 0;
1256 }
1257
1258 device_register("NE2000", ne2k_init)