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.


Fix for option processing
[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 * p;
395     uint32_t total_len;
396     uint32_t next;
397     uint32_t len;
398     uint32_t index;
399     uint32_t empty;
400     uint32_t start;
401     uint32_t stop;
402
403     start = regs->pgstart << 8;
404     stop = regs->pgstop << 8;
405    
406     if (regs->cmd.stop) {
407         return -1;
408     }
409
410     if (ne2k_rxbuf_full(regs)) {
411         PrintError(VM_NONE, VCORE_NONE, "Ne2k: received buffer overflow\n");
412         return -1;
413     }
414
415     //packet too small, expand it
416     if (length < MIN_BUF_SIZE) {
417         uchar_t buf[MIN_BUF_SIZE];
418
419         memcpy(buf, pkt, length);
420         memset(buf + length, 0, MIN_BUF_SIZE - length);
421         pkt = buf;
422         length = MIN_BUF_SIZE;
423     }
424
425     index = regs->curpag << 8;
426
427     //header, 4 bytes
428     total_len = length + 4;
429
430     //address for next packet (4 bytes for CRC)
431     next = index + ((total_len + 4 + 255) & ~0xff);
432
433     if (next >= stop) {
434         next -= (stop - start);
435     }
436
437     p = nic_state->mem + index;
438     regs->rsr.val = 0;
439     regs->rsr.pkt_rx_ok = 1;
440
441     if (pkt[0] & 0x01) {
442         regs->rsr.phy_match = 1; /* TODO: Check this back */
443     }
444
445     p[0] = regs->rsr.val;
446     p[1] = next >> 8;
447     p[2] = total_len;
448     p[3] = total_len >> 8;
449     index += 4;
450
451     while (length > 0) {
452         if (index <= stop) {
453             empty = stop - index;
454         } else {
455             empty = 0;
456         }
457
458         len = length;
459
460         if (len > empty) {
461             len = empty;
462         }
463
464         memcpy(nic_state->mem + index, pkt, len);
465         pkt += len;
466         index += len;
467
468         if (index == stop) {
469             index = start;
470         }
471
472         length -= len;
473     }
474
475     regs->curpag = next >> 8;
476
477     regs->isr.pkt_rx = 1;
478     ne2k_update_irq(nic_state);
479
480     return 0;
481 }
482
483
484 static int ne2k_rx(uint8_t * buf, uint32_t size, void * private_data){
485     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
486   
487 #ifdef V3_CONFIG_DEBUG_NE2K
488     PrintDebug(VM_NONE, VCORE_NONE, "\nNe2k: Packet Received:\n");
489     v3_hexdump(buf, size, NULL, 0);
490 #endif    
491
492     if(!rx_one_pkt(nic_state, buf, size)){
493         nic_state->statistics.rx_pkts ++;
494         nic_state->statistics.rx_bytes += size;
495         
496         return 0;
497     }
498
499     nic_state->statistics.rx_dropped ++;
500         
501     return -1;
502 }
503
504
505 static inline void mem_writeb(struct ne2k_state * nic_state, 
506                         uint32_t addr, 
507                         uint32_t val) {
508     uchar_t tmp = (uchar_t) (val & 0x000000ff);
509
510     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
511         nic_state->mem[addr] = tmp;
512     }
513 }
514
515 static inline void mem_writew(struct ne2k_state * nic_state, 
516                             uint32_t addr,
517                             uint32_t val) {
518     addr &= ~1;
519
520     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
521         *(uint16_t *)(nic_state->mem + addr) = val;
522     }
523 }
524
525 static inline void mem_writel(struct ne2k_state * nic_state,
526                             uint32_t addr,
527                             uint32_t val) {
528     addr &= ~1;
529
530     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
531         *(uint32_t *)(nic_state->mem + addr) = val;
532     }
533 }
534
535 static inline uint8_t  mem_readb(struct ne2k_state * nic_state, uint32_t addr) {
536         
537     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
538         return nic_state->mem[addr];
539     } else {
540         return 0xff;
541     }
542 }
543
544 static inline uint16_t mem_readw(struct ne2k_state * nic_state, uint32_t addr) {
545     addr &= ~1;
546
547     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
548         return *(uint16_t *)(nic_state->mem + addr);
549     } else {
550         return 0xffff;
551     }
552 }
553
554 static uint32_t mem_readl(struct ne2k_state * nic_state, uint32_t addr) {
555     addr &= ~1;
556
557     if ((addr < 32) || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
558         return *(uint32_t *)(nic_state->mem + addr);
559     } else {
560         return 0xffffffff;
561     }
562 }
563
564
565 static void dma_update( struct ne2k_state * nic_state, int len) {                       
566     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
567
568     regs->rsar += len;
569
570     // wrap
571     if (regs->rsar == regs->pgstop) {
572         regs->rsar = regs->pgstart;
573     }
574
575     if (regs->rbcr <= len) {
576         regs->rbcr = 0;
577         regs->isr.rem_dma_done = 1;
578         ne2k_update_irq(nic_state);
579     } else {
580         regs->rbcr -= len;
581     }
582 }
583
584 static int ne2k_data_read(struct guest_info * core, 
585                           uint16_t port, 
586                           void * dst, 
587                           uint_t length, 
588                           void * private_data) {
589     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
590     uint32_t val;
591     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
592
593     // current dma address
594     uint32_t addr = regs->rsar;
595
596     switch (length){
597         case 1:
598             val = mem_readb(nic_state, addr);
599             break;
600         case 2:
601             val = mem_readw(nic_state, addr);
602             break;
603         case 4:
604             val = mem_readl(nic_state, addr);
605             break;
606         default:
607             PrintError(VM_NONE, VCORE_NONE, "ne2k_data_read error: invalid length %d\n", length);
608             val = 0x0;
609     }
610     
611     dma_update(nic_state, length);
612     memcpy(dst, &val, length);
613
614     PrintDebug(VM_NONE, VCORE_NONE, "NE2000 read: port:0x%x (%u bytes): 0x%x", port & 0x1f, length, val);
615
616     return length;
617 }
618
619 static int ne2k_data_write(struct guest_info * core, 
620                            uint16_t port, 
621                            void * src, 
622                            uint_t length, 
623                            void * private_data) {
624     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
625     uint32_t val;
626     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
627         
628     uint32_t addr = regs->rsar;
629         
630     if (regs->rbcr == 0) {
631         return length;
632     }
633
634     memcpy(&val, src, length);
635
636     switch (length) {
637         case 1:
638             mem_writeb(nic_state, addr, val);
639             break;
640         case 2:
641             mem_writew(nic_state, addr, val);
642             break;
643         case 4:
644             mem_writel(nic_state, addr, val);
645             break;
646         default:
647             PrintError(VM_NONE, VCORE_NONE, "NE2000 port write error: invalid length %d\n", length);
648     }
649     
650     dma_update(nic_state, length);
651
652     PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Write port:0x%x (%u bytes): 0x%x\n", port & 0x1f, length, val);
653     
654     return length;
655 }
656
657
658 static void ne2k_init_state(struct ne2k_state * nic_state) {
659
660
661     /* Not sure what this is about....  */
662     memset(nic_state->mem, 0xff, 32); 
663         
664     memcpy(nic_state->mem, nic_state->mac, ETH_ALEN);
665     memset(nic_state->mcast_addr, 0xff, sizeof(nic_state->mcast_addr));
666     nic_state->mem[14] = 0x57;
667     nic_state->mem[15] = 0x57;
668
669     /* initiate registers */
670     nic_state->context.isr.reset_status = 1;
671     nic_state->context.imr.val = 0x00;
672     nic_state->context.cmd.val = 0x22;
673 }
674
675 static int reset_device(struct ne2k_state * nic_state) {  
676     ne2k_init_state(nic_state);
677
678     PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Reset device\n");
679
680     return 0;
681 }
682
683 //for 0xc11f port
684 static int ne2k_reset_port_read(struct guest_info * core, 
685                                 uint16_t port, 
686                                 void * dst, 
687                                 uint_t length, 
688                                 void * private_data) {
689     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
690
691     memset(dst, 0, length);
692     reset_device(nic_state);
693
694     return length;
695 }
696
697 static int ne2k_reset_port_write(struct guest_info * core, 
698                                  uint16_t port, 
699                                  void * src, 
700                                  uint_t length, 
701                                  void * private_data) {
702
703     return length;
704 }
705
706
707
708 static int ne2k_cmd_write(struct guest_info * core, 
709                           uint16_t port, 
710                           void * src, 
711                           uint_t length, 
712                           void * private_data) {
713     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
714     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
715
716     if (length != 1) {
717         PrintError(core->vm_info, core, "Invalid write length to NE2000 Command register\n");
718         return -1;
719     }
720
721     regs->cmd.val = *(uint8_t *)src;
722
723     if (!(regs->cmd.stop)) {
724         regs->isr.reset_status = 0;
725         
726         // if ((send pkt) && (dma byte count == 0)) 
727         if ((regs->cmd.rem_dma_cmd & 0x3) && (regs->rbcr == 0)) {
728             regs->isr.rem_dma_done = 1;
729             ne2k_update_irq(nic_state);
730         }
731         
732         if (regs->cmd.tx_pkt) {
733             int offset = (regs->tpsr << 8);
734             
735             if (offset >= NE2K_PMEM_END) {
736                 offset -= NE2K_PMEM_SIZE;
737             }
738
739             if (offset + regs->tbcr <= NE2K_PMEM_END) {
740                 tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr);
741             }
742
743             regs->tsr.val = 0;        /* clear the tx status reg */
744             regs->tsr.pkt_tx_ok = 1;  /* indicate successful tx */
745
746             regs->isr.pkt_tx = 1;     /* irq due to pkt tx */
747             regs->cmd.tx_pkt = 0;     /* reset cmd bit  */
748             
749             ne2k_update_irq(nic_state);
750         }
751     } else {
752         /* stop the controller */
753     }
754
755     return length;
756 }
757
758 static int ne2k_cmd_read(struct guest_info * core, 
759                          uint16_t port, 
760                          void * dst, 
761                          uint_t length, 
762                          void * private_data) {
763     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
764
765     if (length != 1) {
766         PrintError(core->vm_info, core, "Invalid read length to NE2000 Command register\n");
767         return -1;
768     }
769
770     *(uint8_t *)dst = nic_state->context.cmd.val;
771
772     PrintDebug(core->vm_info, core, "ne2k_read: port:0x%x  val: 0x%x\n", port, *(uint8_t *)dst);
773     return length;
774 }
775
776 static int ne2k_std_write(struct guest_info * core, 
777                           uint16_t port, 
778                           void * src, 
779                           uint_t length, 
780                           void * private_data) {
781     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
782     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
783     int idx = port & 0x1f;
784     uint8_t page = regs->cmd.pg_sel;
785
786     if (length != 1){
787         PrintError(core->vm_info, core, "NE2000 port write error: length %d port 0x%xnot equal to 1\n", length, port);  
788         return -1;
789     }
790
791     uint8_t val = *(uint8_t *)src;
792         
793     PrintDebug(core->vm_info, core, "NE2000: write port:0x%x val: 0x%x\n", port, (uint8_t)val);
794     
795     if (page == 0) {
796         switch (idx) {
797             case EN0_STARTPG:
798                 regs->pgstart = val;
799                 break;
800             case EN0_STOPPG:
801                 regs->pgstop = val;
802                 break;
803             case EN0_BOUNDARY:
804                 regs->boundary = val;
805                 break;
806             case EN0_TPSR:
807                 regs->tpsr = val;
808                 break;
809             case EN0_TCNTLO:
810                 regs->tbcr0 = val;
811                 break;
812             case EN0_TCNTHI:
813                 regs->tbcr1 = val;
814                 break;
815             case EN0_ISR:
816                 regs->isr.val &= ~(val & 0x7f);
817                 ne2k_update_irq(nic_state);
818                 break;
819             case EN0_RSARLO:
820                 regs->rsar0 = val;
821                 break;
822             case EN0_RSARHI:
823                 regs->rsar1 = val;
824                 break;
825             case EN0_RCNTLO:
826                 regs->rbcr0 = val;
827                 break;
828             case EN0_RCNTHI:
829                 regs->rbcr1 = val;
830                 break;
831             case EN0_RXCR:
832                 regs->rcr.val = val;
833                 break;
834             case EN0_TXCR:
835                 regs->tcr.val = val;
836                 break;
837             case EN0_DCFG:
838                 regs->dcr.val = val;
839                 break;  
840             case EN0_IMR:
841                 regs->imr.val = val;
842                 ne2k_update_irq(nic_state);
843                 break;
844
845             default:
846                 PrintError(core->vm_info, core, "NE2000 port write error: invalid port:0x%x\n", port);
847                 return -1;
848         }
849     } else if (page == 1) {
850         switch (idx) {
851             case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
852                 nic_state->mac[port - EN1_PHYS] = val;
853                 break;
854             case EN1_CURPAG:
855                 regs->curpag = val;
856                 break;
857             case EN1_MULT ... EN1_MULT + 7:
858                 nic_state->mcast_addr[port - EN1_MULT] = val;
859                 break;
860                 
861             default:
862                 PrintError(core->vm_info, core, "NE2000 write port error: invalid port:0x%x\n", port);
863                 return -1;
864         }
865     } else if (page == 2) {
866         switch (idx) {
867             case EN2_LDMA0:
868                 regs->clda0 = val;
869                 break;
870             case EN2_LDMA1:
871                 regs->clda1 = val;
872                 break;
873             case EN2_RNPR:
874                 regs->rnpp = val;
875                 break;
876             case EN2_LNRP:
877                 regs->lnpp = val;
878                 break;
879             case EN2_ACNT0:
880                 regs->addcnt0 = val;
881                 break;
882             case EN2_ACNT1: 
883                 regs->addcnt1 = val;
884                 break;
885                 
886             default:
887                 PrintError(core->vm_info, core, "NE2000 write port error: invalid port:0x%x\n", port);
888                 return -1;
889         }
890     } else {
891         PrintError(core->vm_info, core, "NE2000: Invalid Register Page Value\n");
892         return -1;
893     }
894
895
896     return length;
897         
898 }
899
900 static int ne2k_std_read(struct guest_info * core, 
901                          uint16_t port, 
902                          void * dst, 
903                          uint_t length, 
904                          void * private_data) {
905     struct ne2k_state * nic_state = (struct ne2k_state *)private_data;
906     struct ne2k_registers * regs = (struct ne2k_registers *)&(nic_state->context);
907     uint16_t index = port & 0x1f;
908     uint8_t page = regs->cmd.pg_sel;
909
910     if (length > 1) {
911         PrintError(core->vm_info, core, "ne2k_read error: length %d\n", length);
912         return length;
913     }
914
915     if (page == 0) {
916         switch (index) {                
917             case EN0_CLDALO:
918                 *(uint8_t *)dst = regs->clda0;
919                 break;
920             case EN0_CLDAHI:
921                 *(uint8_t *)dst = regs->clda1;
922                 break;
923             case EN0_BOUNDARY:
924                 *(uint8_t *)dst = regs->boundary;
925                 break;
926             case EN0_TSR:
927                 *(uint8_t *)dst = regs->tsr.val;
928                 break;
929             case EN0_NCR:
930                 *(uint8_t *)dst = regs->ncr;
931                 break;
932             case EN0_FIFO:
933                 *(uint8_t *)dst = regs->fifo;
934                 break;
935             case EN0_ISR:
936                 *(uint8_t *)dst = regs->isr.val;
937                 ne2k_update_irq(nic_state);
938                 break;
939             case EN0_CRDALO:
940                 *(uint8_t *)dst = regs->crda0;
941                 break;
942             case EN0_CRDAHI:
943                 *(uint8_t *)dst = regs->crda1;
944                 break;
945             case EN0_RSR:
946                 *(uint8_t *)dst = regs->rsr.val;
947                 break;
948             case EN0_COUNTER0:
949                 *(uint8_t *)dst = regs->cntr0;
950                 break;
951             case EN0_COUNTER1:
952                 *(uint8_t *)dst = regs->cntr1;
953                 break;  
954             case EN0_COUNTER2:
955                 *(uint8_t *)dst = regs->cntr2;
956                 break;
957                 
958             default:
959                 PrintError(core->vm_info, core, "NE2000 port read error: invalid port:0x%x\n", port);
960                 return -1;
961         }
962     } else if (page == 1) {
963         switch (index) {
964             case EN1_PHYS ... EN1_PHYS + ETH_ALEN -1:
965                 *(uint8_t *)dst = nic_state->mac[index - EN1_PHYS];
966                 break;
967             case EN1_CURPAG:
968                 *(uint8_t *)dst = regs->curpag;
969                 break;
970             case EN1_MULT ... EN1_MULT + 7:
971                 *(uint8_t *)dst = nic_state->mcast_addr[index - EN1_MULT];
972                 break;
973                 
974             default:
975                 PrintError(core->vm_info, core, "ne2k_read error: invalid port:0x%x\n", port);
976                 return -1;
977         }
978     } else if (page == 2) {
979         switch (index) {
980             case EN2_STARTPG:
981                 *(uint8_t *)dst = regs->pgstart;
982                 break;
983             case EN2_STOPPG:
984                 *(uint8_t *)dst = regs->pgstop;
985                 break;
986             case EN2_RNPR:
987                 *(uint8_t *)dst = regs->rnpp;
988                 break;
989             case EN2_LNRP:
990                 *(uint8_t *)dst = regs->lnpp;
991                 break;
992             case EN2_TPSR:
993                 *(uint8_t *)dst = regs->tpsr;
994                 break;
995             case EN2_ACNT0:
996                 *(uint8_t *)dst = regs->addcnt0;
997                 break;
998             case EN2_ACNT1: 
999                 *(uint8_t *)dst = regs->addcnt1;
1000                 break;
1001             case EN2_RCR:
1002                 *(uint8_t *)dst = regs->rcr.val;
1003                 break;
1004             case EN2_TCR:
1005                 *(uint8_t *)dst = regs->tcr.val;
1006                 break;
1007             case EN2_DCR:
1008                 *(uint8_t *)dst = regs->dcr.val;
1009                 break;
1010             case EN2_IMR:
1011                 *(uint8_t *)dst = regs->imr.val;
1012                 break;
1013             default:
1014                 PrintError(core->vm_info, core, "NE2000 port read error: invalid port:0x%x\n", port);
1015                 return -1;
1016         }
1017     } else {
1018         PrintError(core->vm_info, core, "NE2000 port read: Invalid Register Page Value\n");
1019         return -1;
1020     }
1021
1022     PrintDebug(core->vm_info, core, "NE2000 port read: port:0x%x  val: 0x%x\n", port, *(uint8_t *)dst);
1023
1024     return length;
1025 }
1026
1027
1028
1029 static int ne2k_pci_write(struct guest_info * core, 
1030                           uint16_t port, 
1031                           void * src, 
1032                           uint_t length, 
1033                           void * private_data) {
1034     uint16_t idx = port & 0x1f;
1035     int ret;
1036
1037     switch (idx) {
1038         case NE2K_CMD_OFFSET:
1039             ret =  ne2k_cmd_write(core, port, src, length, private_data);
1040             break;
1041         case NE2K_CMD_OFFSET+1 ... NE2K_CMD_OFFSET+15:
1042             ret = ne2k_std_write(core, port, src, length, private_data);
1043             break;
1044         case NE2K_DATA_OFFSET:
1045             ret = ne2k_data_write(core, port, src, length, private_data);
1046             break;
1047         case NE2K_RESET_OFFSET:
1048             ret = ne2k_reset_port_write(core, port, src, length, private_data);
1049             break;
1050
1051         default:
1052             PrintError(core->vm_info, core, "NE2000 port write error: invalid port:0x%x\n", port);
1053             return -1;
1054     }
1055
1056     return ret;
1057 }
1058
1059 static int ne2k_pci_read(struct guest_info * core, 
1060                          uint16_t port, 
1061                          void * dst, 
1062                          uint_t length, 
1063                          void * private_data) {
1064     uint16_t idx = port & 0x1f;
1065     int ret;
1066
1067     switch (idx) {
1068         case NE2K_CMD_OFFSET:
1069             ret =  ne2k_cmd_read(core, port, dst, length, private_data);
1070             break;
1071         case NE2K_CMD_OFFSET+1 ... NE2K_CMD_OFFSET+15:
1072             ret = ne2k_std_read(core, port, dst, length, private_data);
1073             break;
1074         case NE2K_DATA_OFFSET:
1075             ret = ne2k_data_read(core, port, dst, length, private_data);
1076             break;
1077         case NE2K_RESET_OFFSET:
1078             ret = ne2k_reset_port_read(core, port, dst, length, private_data);
1079             break;
1080
1081         default:
1082             PrintError(core->vm_info, core, "NE2000 port read error: invalid port:0x%x\n", port);
1083             return -1;
1084     }
1085
1086     return ret;
1087
1088
1089 }
1090
1091 static int pci_config_update(struct pci_device * pci_dev,
1092                         uint32_t reg_num,
1093                              void * src, 
1094                              uint_t length,
1095                              void * private_data) {
1096     PrintDebug(VM_NONE, VCORE_NONE, "PCI Config Update\n");
1097
1098     /* Do we need this? */
1099
1100     return 0;
1101 }
1102
1103
1104 static int register_dev(struct ne2k_state * nic_state) 
1105 {
1106     int i;
1107
1108     if (nic_state->pci_bus != NULL) {
1109         struct v3_pci_bar bars[6];
1110         struct pci_device * pci_dev = NULL;
1111
1112         PrintDebug(VM_NONE, VCORE_NONE, "NE2000: PCI Enabled\n");
1113
1114         for (i = 0; i < 6; i++) {
1115             bars[i].type = PCI_BAR_NONE;
1116         }
1117
1118         bars[0].type = PCI_BAR_IO;
1119         bars[0].default_base_port = -1;
1120         bars[0].num_ports = 256;
1121
1122         bars[0].io_read = ne2k_pci_read;
1123         bars[0].io_write = ne2k_pci_write;
1124        bars[0].private_data = nic_state;
1125
1126         pci_dev = v3_pci_register_device(nic_state->pci_bus, PCI_STD_DEVICE, 0, -1, 0, 
1127                                          "NE2000", bars,
1128                                          pci_config_update, NULL, NULL, NULL, nic_state);
1129
1130
1131         if (pci_dev == NULL) {
1132             PrintError(VM_NONE, VCORE_NONE, "NE2000: Could not register PCI Device\n");
1133             return -1;
1134         }
1135         
1136         pci_dev->config_header.vendor_id = 0x10ec;
1137         pci_dev->config_header.device_id = 0x8029;
1138         pci_dev->config_header.revision = 0x00;
1139
1140         pci_dev->config_header.subclass = 0x00;
1141         pci_dev->config_header.class = 0x02;
1142         pci_dev->config_header.header_type = 0x00;
1143
1144         pci_dev->config_header.intr_line = 11;
1145         pci_dev->config_header.intr_pin = 1;
1146
1147         nic_state->pci_dev = pci_dev;
1148     }else {
1149         PrintDebug(VM_NONE, VCORE_NONE, "NE2000: Not attached to PCI\n");
1150
1151         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT , &ne2k_cmd_read, &ne2k_cmd_write);
1152
1153         for (i = 1; i < 16; i++){       
1154             v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + i, &ne2k_std_read, &ne2k_std_write);
1155         }
1156
1157         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_DATA_OFFSET, &ne2k_data_read, &ne2k_data_write);
1158         v3_dev_hook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_RESET_OFFSET, &ne2k_reset_port_read, &ne2k_reset_port_write);
1159     }
1160
1161
1162     return 0;
1163 }
1164
1165 static int connect_fn(struct v3_vm_info * info, 
1166                       void * frontend_data, 
1167                       struct v3_dev_net_ops * ops, 
1168                       v3_cfg_tree_t * cfg, 
1169                       void * private_data) {
1170     struct ne2k_state * nic_state = (struct ne2k_state *)frontend_data;
1171
1172     ne2k_init_state(nic_state);
1173     register_dev(nic_state);
1174
1175     nic_state->net_ops = ops;
1176     nic_state->backend_data = private_data;     
1177
1178     ops->recv = ne2k_rx;
1179     ops->poll = NULL;   
1180     ops->config.frontend_data = nic_state;
1181     ops->config.fnt_mac = nic_state->mac;
1182
1183     return 0;
1184 }
1185
1186
1187 static int ne2k_free(struct ne2k_state * nic_state) {
1188     int i;
1189
1190     /* dettached from backend */
1191
1192     if(nic_state->pci_bus == NULL){
1193         for (i = 0; i < 16; i++){               
1194             v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + i);
1195         }
1196     
1197        v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_DATA_OFFSET);
1198        v3_dev_unhook_io(nic_state->dev, NIC_REG_BASE_PORT + NE2K_RESET_OFFSET);
1199     }else {
1200        /* unregistered from PCI? */
1201     }
1202
1203     V3_Free(nic_state);
1204         
1205     return 0;
1206 }
1207
1208
1209 static struct v3_device_ops dev_ops = {
1210     .free = (int (*)(void *))ne2k_free,
1211 };
1212
1213
1214 static int ne2k_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1215     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
1216     struct ne2k_state * nic_state = NULL;
1217     char * dev_id = v3_cfg_val(cfg, "ID");
1218     char * macstr = v3_cfg_val(cfg, "mac");
1219
1220     nic_state  = (struct ne2k_state *)V3_Malloc(sizeof(struct ne2k_state));
1221
1222     if (!nic_state) {
1223         PrintError(vm, VCORE_NONE, "Cannot allocate in init\n");
1224         return -1;
1225     }
1226
1227     memset(nic_state, 0, sizeof(struct ne2k_state));
1228
1229     nic_state->pci_bus = pci_bus;
1230     nic_state->vm = vm;
1231
1232     if (macstr != NULL && !str2mac(macstr, nic_state->mac)) {
1233         PrintDebug(vm, VCORE_NONE, "NE2000: Mac specified %s\n", macstr);
1234     }else {
1235         PrintDebug(vm, VCORE_NONE, "NE2000: MAC not specified\n");
1236         random_ethaddr(nic_state->mac);
1237     }
1238
1239     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nic_state);
1240
1241     if (dev == NULL) {
1242         PrintError(vm, VCORE_NONE, "NE2000: Could not attach device %s\n", dev_id);
1243         V3_Free(nic_state);
1244         return -1;
1245     }
1246
1247     nic_state->dev = dev;
1248
1249     if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)nic_state) == -1) {
1250         PrintError(vm, VCORE_NONE, "NE2000: Could not register %s as net frontend\n", dev_id);
1251         v3_remove_device(dev);
1252         V3_Free(nic_state);
1253         return -1;
1254     }
1255             
1256     return 0;
1257 }
1258
1259 device_register("NE2000", ne2k_init)