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.


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