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.


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