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.


made virtio nic an experimental feature
[palacios.git] / palacios / src / devices / ne2k.c
index e1f2ed6..9df0871 100644 (file)
@@ -29,7 +29,7 @@
 #include <palacios/vmm_debug.h>
 #include <palacios/vmm_string.h>
 
-#ifndef DEBUG_NE2K
+#ifndef CONFIG_DEBUG_NE2K
 #undef PrintDebug
 #define PrintDebug(fmts, args...)
 #endif
@@ -41,6 +41,8 @@
 
 #define MAX_ETH_FRAME_SIZE      1514
 
+
+// What the hell is this crap?
 #define NE2K_PMEM_SIZE          (32 * 1024)
 #define NE2K_PMEM_START         (16 * 1024)
 #define NE2K_PMEM_END           (NE2K_PMEM_SIZE + NE2K_PMEM_START)
@@ -117,7 +119,7 @@ struct cmd_reg {
            uint8_t stop        : 1;
            uint8_t start       : 1;
            uint8_t tx_pkt      : 1;
-           uint8_t rem_dma_cmd : 3;
+           uint8_t rem_dma_cmd : 3; // 0=Not allowed, 1=Read, 2=Write, 3=Send Pkt, 4=Abort/Complete DMA
            uint8_t pg_sel      : 2;
        } __attribute__((packed));
     } __attribute__((packed));
@@ -228,7 +230,7 @@ struct rx_status_reg {
            uint8_t frame_align_err  : 1;
            uint8_t fifo_overrun     : 1;
            uint8_t missed_pkt       : 1;
-           uint8_t mac_addr_match   : 1;
+           uint8_t phy_match        : 1;   // 0=Physical Addr Match, 1=MCAST/BCAST Addr Match
            uint8_t rx_disabled      : 1;
            uint8_t deferring        : 1;
        } __attribute__((packed));
@@ -249,70 +251,89 @@ struct ne2k_context {
     struct tx_cfg_reg tcr;
     struct tx_status_reg tsr;
     struct rx_cfg_reg rcr;
-    struct rx_status_reg rsr;
+    struct rx_status_reg rsr;  
 
-    uint8_t      pgstart;
-    uint8_t      pgstop;
-    uint8_t      boundary;
-    uint8_t      tpsr;
-    uint8_t      ncr;
-    uint8_t      fifo;
+    uint8_t      pgstart;      // page start reg
+    uint8_t      pgstop;       // page stop reg
+    uint8_t      boundary;     // boundary ptr
+    uint8_t      tpsr;         // tx page start addr
+    uint8_t      ncr;          // number of collisions
+    uint8_t      fifo;         // FIFO...
 
-    uint16_t     clda;
-    uint16_t     crda;
-    uint16_t     rsar;
+    uint8_t      curpag;       // current page
+    uint8_t      rnpp;         // rem next pkt ptr
+    uint8_t      lnpp;         // local next pkt ptr
 
-    union {
+    uint8_t      cntr0;        // counter 0 (frame alignment errors)
+    uint8_t      cntr1;        // counter 1 (CRC Errors)
+    uint8_t      cntr2;        // counter 2 (missed pkt errors)
+
+    union {                    // current local DMA Addr
+       uint16_t     clda;
+       struct {
+           uint8_t clda0;
+           uint8_t clda1;
+       } __attribute__((packed));
+    } __attribute__((packed));
+
+
+    union {                   // current remote DMA addr
+       uint16_t     crda;
+       struct {
+           uint8_t crda0;
+           uint8_t crda1;
+       } __attribute__((packed));
+    } __attribute__((packed));
+
+
+    union {                   // Remote Start Addr Reg
+       uint16_t     rsar;
+       struct {
+           uint8_t rsar0;
+           uint8_t rsar1;
+       } __attribute__((packed));
+    } __attribute__((packed));
+
+
+    union {                    // TX Byte count Reg
        uint16_t     tbcr;
        struct {
-           uint8_t tbcr_lo;
-           uint8_t tbcr_hi;
+           uint8_t tbcr0;
+           uint8_t tbcr1;
        } __attribute__((packed));
     } __attribute__((packed));
 
-    union {
+    union {                    // Remote Byte count Reg
        uint16_t     rbcr;
        struct {
-           uint8_t rbcr_lo;
-           uint8_t rbcr_hi;
+           uint8_t rbcr0;
+           uint8_t rbcr1;
        } __attribute__((packed));
     } __attribute__((packed));
 
-    uint_t       cntr;
 
-    uint8_t      curpag;
-    uint8_t      rnpp;
-    uint8_t      lnpp;
 
-    union {
+    union {                    // Address counter?
        uint16_t     addcnt;
        struct {
-           uint8_t addcnt_lo;
-           uint8_t addcnt_hi;
+           uint8_t addcnt0;
+           uint8_t addcnt1;
        } __attribute__((packed));
     } __attribute__((packed));
 
-    uint8_t      mcast_addr[8]; //multicast mask array 
-    uint8_t      mac_addr[6];
 
+    uint8_t      mcast_addr[8];  // multicast mask array 
+    uint8_t      mac_addr[6];    // MAC Addr
 
-    uchar_t mem[NE2K_MEM_SIZE];
+    uint8_t mem[NE2K_MEM_SIZE];
 
     struct pci_device * pci_dev;
     struct vm_device * pci_bus;
 };
 
-#define compare_mac(src, dst) ({ \
-           ((src[0] == dst[0]) &&              \
-            (src[1] == dst[1]) &&              \
-            (src[2] == dst[2]) &&              \
-            (src[3] == dst[3]) &&              \
-            (src[4] == dst[4]) &&              \
-            (src[5] == dst[5]))? 1 : 0;        \
-       })
+#define compare_mac(src, dst) !memcmp(src, dst, 6)
 
-
-#ifdef DEBUG_NE2K
+#ifdef CONFIG_DEBUG_NE2K
 static void dump_state(struct vm_device * dev) {
     struct ne2k_context *nic_state = (struct ne2k_context *)dev->private_data;
     int i;
@@ -337,32 +358,30 @@ static void dump_state(struct vm_device * dev) {
 
 
 static int ne2k_update_irq(struct vm_device *dev) {
-    int isr;
     struct ne2k_context * nic_state = (struct ne2k_context *)dev->private_data;
-    struct pci_device * pdev = nic_state->pci_dev;
-    int irqline = 0;
+    struct pci_device * pci_dev = nic_state->pci_dev;
+    int irq_line = 0;
 
-    if (pdev == NULL){
+    if (pci_dev == NULL){
        PrintDebug("Ne2k: Device %p is not attached to any PCI Bus\n", nic_state);
-       irqline = NE2K_DEFAULT_IRQ;
+       irq_line = NE2K_DEFAULT_IRQ;
     } else {
-       irqline = pdev->config_header.intr_line;
+       irq_line = pdev->config_header.intr_line;
     }
-       
-    // What the hell is this?
-    isr = ((nic_state->regs.isr & nic_state->regs.imr) & 0x7f);
-    
-    if (irqline == 0){
-       PrintError("Ne2k: IRQ_LINE: %d\n", irqline);
+           
+    if (irq_line == 0){
+       PrintError("Ne2k: IRQ_LINE: %d\n", irq_line);
        return -1;
     }
 
-    PrintDebug("Ne2k: RaiseIrq: isr: 0x%02x imr: 0x%02x\n", nic_state->regs.isr, nic_state->regs.imr);
-    PrintDebug("ne2k_update_irq: irq_line: %d\n", irqline);
+    PrintDebug("ne2k_update_irq: irq_line: %d\n", irq_line);
+
 
-    if ((isr & 0x7f) != 0x0) {
-       v3_raise_irq(nic_state->vm, irqline);
-       PrintDebug("Ne2k: RaiseIrq: isr: 0x%02x imr: 0x%02x\n", nic_state->regs.isr, nic_state->regs.imr);
+    // The top bit of the ISR/IMR is reserved and does not indicate and irq event
+    // We mask the bit out of the irq pending check
+    if ((nic_state->isr.val & nic_state->imr.val) & 0x7f) {
+       v3_raise_irq(nic_state->vm, irq_line);
+       PrintDebug("Ne2k: RaiseIrq: isr: 0x%02x imr: 0x%02x\n", nic_state->isr.val, nic_state->imr.val);
     }
 
     return 0;
@@ -377,29 +396,24 @@ static void ne2k_init_state(struct vm_device * dev) {
 
     nic_state->vm = dev->vm;
 
-    nic_state->regs.isr = ENISR_RESET;
-    nic_state->regs.imr = 0x00;
-    nic_state->regs.cmd = 0x22;
+    nic_state->isr.reset = 1;
+    nic_state->imr.val = 0x00;
+    nic_state->cmd.val = 0x22;
 
     for (i = 0; i < 5; i++) {
        nic_state->mac_addr[i] = mac[i];
     }
 
-    nic_state->mac_addr[5] = mac[5] + nic_no;
+    memset(nic_state->mcast_addr, 0xff, sizeof(nic_state->mcast_addr));
 
-    for (i = 0; i < 8; i++) {
-       nic_state->regs.mcast_addr[i] = 0xff;
-    }
-
-    for(i = 0; i < 32; i++) {
-        nic_state->mem[i] = 0xff;
-    }
+    // Not sure what this is about....
+    memset(nic_state->mem, 0xff, 32); 
 
     memcpy(nic_state->mem, nic_state->mac_addr, 6);
     nic_state->mem[14] = 0x57;
     nic_state->mem[15] = 0x57;
 
-#ifdef DEBUG_NE2K
+#ifdef CONFIG_DEBUG_NE2K
     dump_state(dev);
 #endif
 
@@ -416,20 +430,24 @@ static int ne2k_send_packet(struct vm_device *dev, uchar_t *pkt, int length) {
 
     PrintDebug("\n");
        
-    return V3_Send_pkt(pkt, length);
+    PrintError("Implement Send Packet interface\n");
+
+    return -1;
 }
 
 static int ne2k_rxbuf_full(struct vm_device *dev) {
-    int empty, index, boundary;
-    struct ne2k_context *nic_state = (struct ne2k_context *)dev->private_data;
+    int empty;
+    int index;
+    int boundary;
+    struct ne2k_context * nic_state = (struct ne2k_context *)dev->private_data;
 
-    index = nic_state->regs.curpag << 8;
-    boundary = nic_state->regs.boundary << 8;
+    index = nic_state->curpag << 8;
+    boundary = nic_state->boundary << 8;
 
     if (index < boundary) {
         empty = boundary - index;
     } else {
-        empty = ((nic_state->regs.pgstop - nic_state->regs.pgstart) << 8) - (index - boundary);
+        empty = ((nic_state->pgstop - nic_state->pgstart) << 8) - (index - boundary);
     }
 
     if (empty < (MAX_ETH_FRAME_SIZE + 4)) {
@@ -441,18 +459,24 @@ static int ne2k_rxbuf_full(struct vm_device *dev) {
 
 #define MIN_BUF_SIZE 60
 
-static void ne2k_receive(struct vm_device *dev, const uchar_t * pkt, int length) {
-    struct ne2k_context *nic_state = (struct ne2k_context *)dev->private_data;
-    struct ne2k_regs *nregs = &(nic_state->regs);
-    uchar_t *p;
-    uint32_t total_len, next, len, index, empty;
+
+// This needs to be completely redone...
+static void ne2k_receive(struct vm_device * dev, const uchar_t * pkt, int length) {
+    struct ne2k_context * nic_state = (struct ne2k_context *)dev->private_data;
+    uchar_t * p;
+    uint32_t total_len;
+    uint32_t next;
+    uint32_t len;
+    uint32_t index;
+    uint32_t empty;
     uchar_t buf[60];
-    uint32_t start, stop;
+    uint32_t start;
+    uint32_t stop;
 
-    start = nregs->pgstart << 8;
-    stop = nregs->pgstop << 8;
+    start = nic_state->pgstart << 8;
+    stop = nic_state->pgstop << 8;
    
-    if (nregs->cmd & NE2K_STOP) {
+    if (nic_state->cmd.stop) {
        return;
     }
 
@@ -461,6 +485,7 @@ static void ne2k_receive(struct vm_device *dev, const uchar_t * pkt, int length)
        return;
     }
 
+
     //packet too small, expand it
     if (length < MIN_BUF_SIZE) {
         memcpy(buf, pkt, length);
@@ -469,7 +494,7 @@ static void ne2k_receive(struct vm_device *dev, const uchar_t * pkt, int length)
         length = MIN_BUF_SIZE;
     }
 
-    index = nregs->curpag << 8;
+    index = nic_state->curpag << 8;
 
     //header, 4 bytes
     total_len = length + 4;
@@ -478,17 +503,18 @@ static void ne2k_receive(struct vm_device *dev, const uchar_t * pkt, int length)
     next = index + ((total_len + 4 + 255) & ~0xff);
 
     if (next >= stop) {
-        next -= stop - start;
+        next -= (stop - start);
     }
 
     p = nic_state->mem + index;
-    nregs->rsr = ENRSR_RXOK;
+    nic_state->rsr.val = 0;
+    nic_state->rsr.rx_pkt_ok = 1;
 
     if (pkt[0] & 0x01) {
-        nregs->rsr |= ENRSR_PHY;
+        nic_state->rsr.phy = 1;
     }
 
-    p[0] = nregs->rsr;
+    p[0] = nic_state->rsr.val;
     p[1] = next >> 8;
     p[2] = total_len;
     p[3] = total_len >> 8;
@@ -518,9 +544,9 @@ static void ne2k_receive(struct vm_device *dev, const uchar_t * pkt, int length)
         length -= len;
     }
 
-    nregs->curpag = next >> 8;
+    nic_state->curpag = next >> 8;
 
-    nregs->isr |= ENISR_RX;
+    nic_state->isr.pkt_rx = 1;
     ne2k_update_irq(dev);
 }
 
@@ -528,12 +554,11 @@ static void ne2k_receive(struct vm_device *dev, const uchar_t * pkt, int length)
 
 
 static int netif_input(uchar_t *pkt, uint_t size) {
-    struct ne2k_context *nic_state;
-    struct ne2k_regs *nregs;
+    struct ne2k_context * nic_state;
     static const uchar_t brocast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
     int i;
   
-#ifdef DEBUG_NE2K
+#ifdef CONFIG_DEBUG_NE2K
     PrintDebug("\nNe2k: Packet Received:\nSource:");
     for (i = 6; i < 12; i++) {
        PrintDebug("%x ", pkt[i]);
@@ -541,37 +566,27 @@ static int netif_input(uchar_t *pkt, uint_t size) {
 
     PrintDebug("\n");
 
-    for(i= 0; i<size; i++) {
+    for(i = 0; i < size; i++) {
        PrintDebug("%x ", pkt[i]);
     }    
+    PrintDebug("\n");
 #endif    
 
-    for (i = 0; i < NUM_NE2K; i++){
-       if (ne2ks[i] != NULL) {
-           nic_state = (struct ne2k_context *)ne2ks[i]->private_data;
-           nregs = &(nic_state->regs);
-           
-           if (nregs->rcr & 0x10) {
-               //promiscuous mode
-               ne2k_receive(ne2ks[i], pkt, size);
-           } else {
-               if (compare_mac(pkt,  brocast_mac) && (nregs->rcr & 0x04)) { 
-                   //broadcast packet
-                   ne2k_receive(ne2ks[i], pkt, size);
-               } else if (pkt[0] & 0x01) {
-                   //TODO: multicast packet
-                   if (nregs->rcr & 0x08)
-                       ne2k_receive(ne2ks[i], pkt, size);
-               } else if (compare_mac(pkt, nic_state->mac_addr)) {
-                   ne2k_receive(ne2ks[i], pkt, size);
-               } else {
-                   continue;
-               }
-           }
-       }
+
+    if (nic_state->rcr.prom_phys_enable == 1) {
+       //promiscuous mode
+       ne2k_receive(ne2ks[i], pkt, size);
+    } else if (compare_mac(pkt,  brocast_mac) && (nic_state->rcr.bcast_ok)) {
+       //broadcast packet
+       ne2k_receive(ne2ks[i], pkt, size);
+    } else if ((pkt[0] & 0x01) && (nic_state->rcr.mcast_ok)) {
+       //TODO: multicast packet
+       ne2k_receive(ne2ks[i], pkt, size);
+    } else if (compare_mac(pkt, nic_state->mac_addr)) {
+       ne2k_receive(ne2ks[i], pkt, size);
     }
     
-  return 0;
+    return 0;
 }
 
 
@@ -649,19 +664,19 @@ static uint32_t ne2k_mem_readl(struct ne2k_context *nic_state, uint32_t addr) {
 static void ne2k_dma_update(struct vm_device *dev, int len) {          
     struct ne2k_context * nic_state = (struct ne2k_context *)dev->private_data;
        
-    nic_state->regs.rsar += len;
+    nic_state->rsar += len;
 
     // wrap
-    if (nic_state->regs.rsar == nic_state->regs.pgstop) {
-        nic_state->regs.rsar = nic_state->regs.pgstart;
+    if (nic_state->rsar == nic_state->pgstop) {
+        nic_state->rsar = nic_state->pgstart;
     }
 
-    if (nic_state->regs.rbcr <= len) {
-        nic_state->regs.rbcr = 0;
-        nic_state->regs.isr |= ENISR_RDC;
+    if (nic_state->rbcr <= len) {
+        nic_state->rbcr = 0;
+        nic_state->isr.rem_dma_done = 1;
         ne2k_update_irq(dev);
     } else {
-        nic_state->regs.rbcr -= len;
+        nic_state->rbcr -= len;
     }
 }
 
@@ -669,10 +684,10 @@ static void ne2k_dma_update(struct vm_device *dev, int len) {
 //for data port read/write
 static int ne2k_data_read(ushort_t port, void * dst, uint_t length, struct vm_device *dev) {
     uint32_t val;
-    struct ne2k_context *nic_state = (struct ne2k_context *)dev->private_data;
+    struct ne2k_context * nic_state = (struct ne2k_context *)dev->private_data;
     
     // current dma address
-    uint32_t addr = nic_state->regs.rsar;
+    uint32_t addr = nic_state->rsar;
 
     switch (length){
        case 1:
@@ -700,10 +715,10 @@ static int ne2k_data_read(ushort_t port, void * dst, uint_t length, struct vm_de
 
 static int ne2k_data_write(ushort_t port, void * src, uint_t length, struct vm_device *dev) {
     uint32_t val;
-    struct ne2k_context *nic_state = (struct ne2k_context *)dev->private_data;
-    uint32_t addr = nic_state->regs.rsar;
+    struct ne2k_context * nic_state = (struct ne2k_context *)dev->private_data;
+    uint32_t addr = nic_state->rsar;
 
-    if (nic_state->regs.rbcr == 0) {
+    if (nic_state->rbcr == 0) {
        return length;
     }
 
@@ -769,7 +784,9 @@ static int ne2k_cmd_write(uint16_t port, void * src, uint_t length, struct vm_de
     if (!(nic_state->cmd.stop)) {
        nic_state->isr.reset = 0;
        
-       if ((val & (NE2K_DMAREAD | NE2K_DMAWRITE)) && (nic_state->rbcr == 0)) {
+
+       // if ((send pkt) && (dma byte count == 0)) 
+       if ((nic_state.rem_dma_cmd & 0x3) && (nic_state->rbcr == 0)) {
            nic_state->isr.rem_dma_done = 1;
            ne2k_update_irq(dev);
        }
@@ -823,49 +840,50 @@ static int ne2k_std_write(uint16_t port, void * src, uint_t length, struct vm_de
     if (page == 0) {
        switch (port) {
            case EN0_STARTPG:
-               nic_state->regs.pgstart = val;
+               nic_state->pgstart = val;
                break;
            case EN0_STOPPG:
-               nic_state->regs.pgstop = val;
+               nic_state->pgstop = val;
                break;
            case EN0_BOUNDARY:
-               nic_state->regs.boundary = val;
+               nic_state->boundary = val;
                break;
            case EN0_TPSR:
-               nic_state->regs.tpsr = val;
+               nic_state->tpsr = val;
                break;
            case EN0_TCNTLO:
-               nic_state->regs.tbcr = (nic_state->regs.tbcr & 0xff00) | val;
+               nic_state->tbcr0 = val;
                break;
            case EN0_TCNTHI:
-               nic_state->regs.tbcr = (nic_state->regs.tbcr & 0x00ff) | (val << 8);
+               nic_state->tbcr1 = val;
                break;
            case EN0_ISR:
-               nic_state->regs.isr &= ~(val & 0x7f);
+               nic_state->isr.val &= ~(val & 0x7f);
                ne2k_update_irq(dev);
                break;
            case EN0_RSARLO:
-               nic_state->regs.rsar = (nic_state->regs.rsar & 0xff00) | val;
+               nic_state->rsar0 = val;
                break;
            case EN0_RSARHI:
-               nic_state->regs.rsar = (nic_state->regs.rsar & 0x00ff) | (val << 8);
+               nic_state->rsar1 = val;
                break;
            case EN0_RCNTLO:
-               nic_state->regs.rbcr = (nic_state->regs.rbcr & 0xff00) | val;
+               nic_state->rbcr0 = val;
                break;
            case EN0_RCNTHI:
-               nic_state->regs.rbcr = (nic_state->regs.rbcr & 0x00ff) | (val << 8);
+               nic_state->rbcr1 = val;
                break;
            case EN0_RXCR:
-               nic_state->regs.rcr = val;
+               nic_state->rcr.val = val;
                break;
            case EN0_TXCR:
-               nic_state->regs.tcr = val;
+               nic_state->tcr.val = val;
+               break;
            case EN0_DCFG:
-               nic_state->regs.dcr = val;
+               nic_state->dcr.val = val;
                break;  
            case EN0_IMR:
-               nic_state->regs.imr = val;
+               nic_state->imr.val = val;
                //PrintError("ne2k_write error: write IMR:0x%x\n", (int)val);
                ne2k_update_irq(dev);
                break;
@@ -876,14 +894,14 @@ static int ne2k_std_write(uint16_t port, void * src, uint_t length, struct vm_de
     } else if (page == 1) {
        switch (port) {
            case EN1_PHYS ... EN1_PHYS + 5:
-               nic_state->regs.mac_addr[port - EN1_PHYS] = val;
+               nic_state->mac_addr[port - EN1_PHYS] = val;
                break;
            case EN1_CURPAG:
-               nic_state->regs.curpag = val;
+               nic_state->curpag = val;
                break;
            case EN1_MULT ... EN1_MULT + 7:
                // PrintError("ne2k_write error: write EN_MULT:0x%x\n", (int)val);
-               nic_state->regs.mcast_addr[port - EN1_MULT] = val;
+               nic_state->mcast_addr[port - EN1_MULT] = val;
                break;
            default:
                PrintError("ne2k_write error: invalid port:0x%x\n", port);
@@ -892,22 +910,22 @@ static int ne2k_std_write(uint16_t port, void * src, uint_t length, struct vm_de
     } else if (page == 2) {
        switch (port) {
            case EN2_LDMA0:
-               nic_state->regs.clda = (nic_state->regs.clda & 0xff00) | val;
+               nic_state->clda0 = val;
                break;
            case EN2_LDMA1:
-               nic_state->regs.clda = (nic_state->regs.clda & 0x00ff) | (val << 8);
+               nic_state->clda1 = val;
                break;
            case EN2_RNPR:
-               nic_state->regs.rnpp = val;
+               nic_state->rnpp = val;
                break;
            case EN2_LNRP:
-               nic_state->regs.lnpp = val;
+               nic_state->lnpp = val;
                break;
            case EN2_ACNT0:
-               nic_state->regs.addcnt = (nic_state->regs.addcnt & 0xff00) | val;
+               nic_state->addcnt0 = val;
                break;
            case EN2_ACNT1: 
-               nic_state->regs.addcnt = (nic_state->regs.addcnt & 0x00ff) | (val << 8);
+               nic_state->addcnt1 = val;
                break;
            default:
                PrintError("ne2k_write error: invalid port:0x%x\n", port);
@@ -933,23 +951,20 @@ static int ne2k_std_read(uint16_t port, void * dst, uint_t length, struct vm_dev
        return length;
     }
 
-
-
-
     if (page == 0) {
 
        switch (index) {                
            case EN0_CLDALO:
-               *(uint8_t *)dst = nic_state->clda & 0x00ff;
+               *(uint8_t *)dst = nic_state->clda0;
                break;
            case EN0_CLDAHI:
-               *(uint8_t *)dst = (nic_state->clda & 0xff00) >> 8;
+               *(uint8_t *)dst = nic_state->clda1;
                break;
            case EN0_BOUNDARY:
                *(uint8_t *)dst = nic_state->boundary;
                break;
            case EN0_TSR:
-               *(uint8_t *)dst = nic_state->tsr;
+               *(uint8_t *)dst = nic_state->tsr.val;
                break;
            case EN0_NCR:
                *(uint8_t *)dst = nic_state->ncr;
@@ -958,26 +973,26 @@ static int ne2k_std_read(uint16_t port, void * dst, uint_t length, struct vm_dev
                *(uint8_t *)dst = nic_state->fifo;
                break;
            case EN0_ISR:
-               *(uint8_t *)dst = nic_state->isr;
+               *(uint8_t *)dst = nic_state->isr.val;
                ne2k_update_irq(dev);
                break;
            case EN0_CRDALO:
-               *(uint8_t *)dst = nic_state->crda & 0x00ff;
+               *(uint8_t *)dst = nic_state->crda0;
                break;
            case EN0_CRDAHI:
-               *(uint8_t *)dst = (nic_state->crda & 0xff00) >> 8;
+               *(uint8_t *)dst = nic_state->crda1;
                break;
            case EN0_RSR:
-               *(uint8_t *)dst = nic_state->rsr;
+               *(uint8_t *)dst = nic_state->rsr.val;
                break;
            case EN0_COUNTER0:
-               *(uint8_t *)dst = nic_state->cntr & 0x000000ff;
+               *(uint8_t *)dst = nic_state->cntr0;
                break;
            case EN0_COUNTER1:
-               *(uint8_t *)dst = (nic_state->cntr & 0x0000ff00) >> 8;
+               *(uint8_t *)dst = nic_state->cntr1;
                break;  
            case EN0_COUNTER2:
-               *(uint8_t *)dst = (nic_state->cntr & 0x00ff0000) >> 16;
+               *(uint8_t *)dst = nic_state->cntr2;
                break;
            default:
                PrintError("ne2k_read error: invalid port:0x%x\n", port);
@@ -1020,22 +1035,22 @@ static int ne2k_std_read(uint16_t port, void * dst, uint_t length, struct vm_dev
                *(uint8_t *)dst = nic_state->tpsr;
                break;
            case EN2_ACNT0:
-               *(uint8_t *)dst = nic_state->addcnt & 0x00ff;
+               *(uint8_t *)dst = nic_state->addcnt0;
                break;
            case EN2_ACNT1: 
-               *(uint8_t *)dst = (nic_state->addcnt & 0xff00) >> 8;
+               *(uint8_t *)dst = nic_state->addcnt1;
                break;
            case EN2_RCR:
-               *(uint8_t *)dst = nic_state->rcr;
+               *(uint8_t *)dst = nic_state->rcr.val;
                break;
            case EN2_TCR:
-               *(uint8_t *)dst = nic_state->tcr;
+               *(uint8_t *)dst = nic_state->tcr.val;
                break;
            case EN2_DCR:
-               *(uint8_t *)dst = nic_state->dcr;
+               *(uint8_t *)dst = nic_state->dcr.val;
                break;
            case EN2_IMR:
-               *(uint8_t *)dst = nic_state->imr;
+               *(uint8_t *)dst = nic_state->imr.val;
                break;
            default:
                PrintError("ne2k_read error: invalid port:0x%x\n", port);
@@ -1131,7 +1146,7 @@ static int ne2k_init_device(struct vm_device * dev) {
     }
     
 
-#ifdef DEBUG_NE2K
+#ifdef CONFIG_DEBUG_NE2K
     dump_state(dev);
 #endif
 
@@ -1154,7 +1169,7 @@ static int ne2k_deinit_device(struct vm_device *dev) {
 }
 
 
-static struct vm_device_ops dev_ops = { 
+static struct v3_device_ops dev_ops = { 
     .init = ne2k_init_device, 
     .deinit = ne2k_deinit_device,
     .reset = ne2k_reset_device,