Home | History | Annotate | Download | only in net
      1 /*
      2  * QEMU NE2000 emulation
      3  *
      4  * Copyright (c) 2003-2004 Fabrice Bellard
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22  * THE SOFTWARE.
     23  */
     24 #include "hw/hw.h"
     25 #include "hw/pci/pci.h"
     26 #include "hw/i386/pc.h"
     27 #include "net/net.h"
     28 
     29 /* debug NE2000 card */
     30 //#define DEBUG_NE2000
     31 
     32 #define MAX_ETH_FRAME_SIZE 1514
     33 
     34 #define E8390_CMD	0x00  /* The command register (for all pages) */
     35 /* Page 0 register offsets. */
     36 #define EN0_CLDALO	0x01	/* Low byte of current local dma addr  RD */
     37 #define EN0_STARTPG	0x01	/* Starting page of ring bfr WR */
     38 #define EN0_CLDAHI	0x02	/* High byte of current local dma addr  RD */
     39 #define EN0_STOPPG	0x02	/* Ending page +1 of ring bfr WR */
     40 #define EN0_BOUNDARY	0x03	/* Boundary page of ring bfr RD WR */
     41 #define EN0_TSR		0x04	/* Transmit status reg RD */
     42 #define EN0_TPSR	0x04	/* Transmit starting page WR */
     43 #define EN0_NCR		0x05	/* Number of collision reg RD */
     44 #define EN0_TCNTLO	0x05	/* Low  byte of tx byte count WR */
     45 #define EN0_FIFO	0x06	/* FIFO RD */
     46 #define EN0_TCNTHI	0x06	/* High byte of tx byte count WR */
     47 #define EN0_ISR		0x07	/* Interrupt status reg RD WR */
     48 #define EN0_CRDALO	0x08	/* low byte of current remote dma address RD */
     49 #define EN0_RSARLO	0x08	/* Remote start address reg 0 */
     50 #define EN0_CRDAHI	0x09	/* high byte, current remote dma address RD */
     51 #define EN0_RSARHI	0x09	/* Remote start address reg 1 */
     52 #define EN0_RCNTLO	0x0a	/* Remote byte count reg WR */
     53 #define EN0_RTL8029ID0	0x0a	/* Realtek ID byte #1 RD */
     54 #define EN0_RCNTHI	0x0b	/* Remote byte count reg WR */
     55 #define EN0_RTL8029ID1	0x0b	/* Realtek ID byte #2 RD */
     56 #define EN0_RSR		0x0c	/* rx status reg RD */
     57 #define EN0_RXCR	0x0c	/* RX configuration reg WR */
     58 #define EN0_TXCR	0x0d	/* TX configuration reg WR */
     59 #define EN0_COUNTER0	0x0d	/* Rcv alignment error counter RD */
     60 #define EN0_DCFG	0x0e	/* Data configuration reg WR */
     61 #define EN0_COUNTER1	0x0e	/* Rcv CRC error counter RD */
     62 #define EN0_IMR		0x0f	/* Interrupt mask reg WR */
     63 #define EN0_COUNTER2	0x0f	/* Rcv missed frame error counter RD */
     64 
     65 #define EN1_PHYS        0x11
     66 #define EN1_CURPAG      0x17
     67 #define EN1_MULT        0x18
     68 
     69 #define EN2_STARTPG	0x21	/* Starting page of ring bfr RD */
     70 #define EN2_STOPPG	0x22	/* Ending page +1 of ring bfr RD */
     71 
     72 #define EN3_CONFIG0	0x33
     73 #define EN3_CONFIG1	0x34
     74 #define EN3_CONFIG2	0x35
     75 #define EN3_CONFIG3	0x36
     76 
     77 /*  Register accessed at EN_CMD, the 8390 base addr.  */
     78 #define E8390_STOP	0x01	/* Stop and reset the chip */
     79 #define E8390_START	0x02	/* Start the chip, clear reset */
     80 #define E8390_TRANS	0x04	/* Transmit a frame */
     81 #define E8390_RREAD	0x08	/* Remote read */
     82 #define E8390_RWRITE	0x10	/* Remote write  */
     83 #define E8390_NODMA	0x20	/* Remote DMA */
     84 #define E8390_PAGE0	0x00	/* Select page chip registers */
     85 #define E8390_PAGE1	0x40	/* using the two high-order bits */
     86 #define E8390_PAGE2	0x80	/* Page 3 is invalid. */
     87 
     88 /* Bits in EN0_ISR - Interrupt status register */
     89 #define ENISR_RX	0x01	/* Receiver, no error */
     90 #define ENISR_TX	0x02	/* Transmitter, no error */
     91 #define ENISR_RX_ERR	0x04	/* Receiver, with error */
     92 #define ENISR_TX_ERR	0x08	/* Transmitter, with error */
     93 #define ENISR_OVER	0x10	/* Receiver overwrote the ring */
     94 #define ENISR_COUNTERS	0x20	/* Counters need emptying */
     95 #define ENISR_RDC	0x40	/* remote dma complete */
     96 #define ENISR_RESET	0x80	/* Reset completed */
     97 #define ENISR_ALL	0x3f	/* Interrupts we will enable */
     98 
     99 /* Bits in received packet status byte and EN0_RSR*/
    100 #define ENRSR_RXOK	0x01	/* Received a good packet */
    101 #define ENRSR_CRC	0x02	/* CRC error */
    102 #define ENRSR_FAE	0x04	/* frame alignment error */
    103 #define ENRSR_FO	0x08	/* FIFO overrun */
    104 #define ENRSR_MPA	0x10	/* missed pkt */
    105 #define ENRSR_PHY	0x20	/* physical/multicast address */
    106 #define ENRSR_DIS	0x40	/* receiver disable. set in monitor mode */
    107 #define ENRSR_DEF	0x80	/* deferring */
    108 
    109 /* Transmitted packet status, EN0_TSR. */
    110 #define ENTSR_PTX 0x01	/* Packet transmitted without error */
    111 #define ENTSR_ND  0x02	/* The transmit wasn't deferred. */
    112 #define ENTSR_COL 0x04	/* The transmit collided at least once. */
    113 #define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */
    114 #define ENTSR_CRS 0x10	/* The carrier sense was lost. */
    115 #define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */
    116 #define ENTSR_CDH 0x40	/* The collision detect "heartbeat" signal was lost. */
    117 #define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
    118 
    119 #define NE2000_PMEM_SIZE    (32*1024)
    120 #define NE2000_PMEM_START   (16*1024)
    121 #define NE2000_PMEM_END     (NE2000_PMEM_SIZE+NE2000_PMEM_START)
    122 #define NE2000_MEM_SIZE     NE2000_PMEM_END
    123 
    124 typedef struct NE2000State {
    125     uint8_t cmd;
    126     uint32_t start;
    127     uint32_t stop;
    128     uint8_t boundary;
    129     uint8_t tsr;
    130     uint8_t tpsr;
    131     uint16_t tcnt;
    132     uint16_t rcnt;
    133     uint32_t rsar;
    134     uint8_t rsr;
    135     uint8_t rxcr;
    136     uint8_t isr;
    137     uint8_t dcfg;
    138     uint8_t imr;
    139     uint8_t phys[6]; /* mac address */
    140     uint8_t curpag;
    141     uint8_t mult[8]; /* multicast mask array */
    142     qemu_irq irq;
    143     int isa_io_base;
    144     PCIDevice *pci_dev;
    145     VLANClientState *vc;
    146     uint8_t macaddr[6];
    147     uint8_t mem[NE2000_MEM_SIZE];
    148 } NE2000State;
    149 
    150 static void ne2000_reset(NE2000State *s)
    151 {
    152     int i;
    153 
    154     s->isr = ENISR_RESET;
    155     memcpy(s->mem, s->macaddr, 6);
    156     s->mem[14] = 0x57;
    157     s->mem[15] = 0x57;
    158 
    159     /* duplicate prom data */
    160     for(i = 15;i >= 0; i--) {
    161         s->mem[2 * i] = s->mem[i];
    162         s->mem[2 * i + 1] = s->mem[i];
    163     }
    164 }
    165 
    166 static void ne2000_update_irq(NE2000State *s)
    167 {
    168     int isr;
    169     isr = (s->isr & s->imr) & 0x7f;
    170 #if defined(DEBUG_NE2000)
    171     printf("NE2000: Set IRQ to %d (%02x %02x)\n",
    172 	   isr ? 1 : 0, s->isr, s->imr);
    173 #endif
    174     qemu_set_irq(s->irq, (isr != 0));
    175 }
    176 
    177 #define POLYNOMIAL 0x04c11db6
    178 
    179 /* From FreeBSD */
    180 /* XXX: optimize */
    181 static int compute_mcast_idx(const uint8_t *ep)
    182 {
    183     uint32_t crc;
    184     int carry, i, j;
    185     uint8_t b;
    186 
    187     crc = 0xffffffff;
    188     for (i = 0; i < 6; i++) {
    189         b = *ep++;
    190         for (j = 0; j < 8; j++) {
    191             carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
    192             crc <<= 1;
    193             b >>= 1;
    194             if (carry)
    195                 crc = ((crc ^ POLYNOMIAL) | carry);
    196         }
    197     }
    198     return (crc >> 26);
    199 }
    200 
    201 static int ne2000_buffer_full(NE2000State *s)
    202 {
    203     int avail, index, boundary;
    204 
    205     index = s->curpag << 8;
    206     boundary = s->boundary << 8;
    207     if (index < boundary)
    208         avail = boundary - index;
    209     else
    210         avail = (s->stop - s->start) - (index - boundary);
    211     if (avail < (MAX_ETH_FRAME_SIZE + 4))
    212         return 1;
    213     return 0;
    214 }
    215 
    216 static int ne2000_can_receive(VLANClientState *vc)
    217 {
    218     NE2000State *s = vc->opaque;
    219 
    220     if (s->cmd & E8390_STOP)
    221         return 1;
    222     return !ne2000_buffer_full(s);
    223 }
    224 
    225 #define MIN_BUF_SIZE 60
    226 
    227 static ssize_t ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size_)
    228 {
    229     NE2000State *s = vc->opaque;
    230     int size = size_;
    231     uint8_t *p;
    232     unsigned int total_len, next, avail, len, index, mcast_idx;
    233     uint8_t buf1[60];
    234     static const uint8_t broadcast_macaddr[6] =
    235         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    236 
    237 #if defined(DEBUG_NE2000)
    238     printf("NE2000: received len=%d\n", size);
    239 #endif
    240 
    241     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
    242         return -1;
    243 
    244     /* XXX: check this */
    245     if (s->rxcr & 0x10) {
    246         /* promiscuous: receive all */
    247     } else {
    248         if (!memcmp(buf,  broadcast_macaddr, 6)) {
    249             /* broadcast address */
    250             if (!(s->rxcr & 0x04))
    251                 return size;
    252         } else if (buf[0] & 0x01) {
    253             /* multicast */
    254             if (!(s->rxcr & 0x08))
    255                 return size;
    256             mcast_idx = compute_mcast_idx(buf);
    257             if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
    258                 return size;
    259         } else if (s->mem[0] == buf[0] &&
    260                    s->mem[2] == buf[1] &&
    261                    s->mem[4] == buf[2] &&
    262                    s->mem[6] == buf[3] &&
    263                    s->mem[8] == buf[4] &&
    264                    s->mem[10] == buf[5]) {
    265             /* match */
    266         } else {
    267             return size;
    268         }
    269     }
    270 
    271 
    272     /* if too small buffer, then expand it */
    273     if (size < MIN_BUF_SIZE) {
    274         memcpy(buf1, buf, size);
    275         memset(buf1 + size, 0, MIN_BUF_SIZE - size);
    276         buf = buf1;
    277         size = MIN_BUF_SIZE;
    278     }
    279 
    280     index = s->curpag << 8;
    281     /* 4 bytes for header */
    282     total_len = size + 4;
    283     /* address for next packet (4 bytes for CRC) */
    284     next = index + ((total_len + 4 + 255) & ~0xff);
    285     if (next >= s->stop)
    286         next -= (s->stop - s->start);
    287     /* prepare packet header */
    288     p = s->mem + index;
    289     s->rsr = ENRSR_RXOK; /* receive status */
    290     /* XXX: check this */
    291     if (buf[0] & 0x01)
    292         s->rsr |= ENRSR_PHY;
    293     p[0] = s->rsr;
    294     p[1] = next >> 8;
    295     p[2] = total_len;
    296     p[3] = total_len >> 8;
    297     index += 4;
    298 
    299     /* write packet data */
    300     while (size > 0) {
    301         if (index <= s->stop)
    302             avail = s->stop - index;
    303         else
    304             avail = 0;
    305         len = size;
    306         if (len > avail)
    307             len = avail;
    308         memcpy(s->mem + index, buf, len);
    309         buf += len;
    310         index += len;
    311         if (index == s->stop)
    312             index = s->start;
    313         size -= len;
    314     }
    315     s->curpag = next >> 8;
    316 
    317     /* now we can signal we have received something */
    318     s->isr |= ENISR_RX;
    319     ne2000_update_irq(s);
    320 
    321     return size_;
    322 }
    323 
    324 static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
    325 {
    326     NE2000State *s = opaque;
    327     int offset, page, index;
    328 
    329     addr &= 0xf;
    330 #ifdef DEBUG_NE2000
    331     printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
    332 #endif
    333     if (addr == E8390_CMD) {
    334         /* control register */
    335         s->cmd = val;
    336         if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
    337             s->isr &= ~ENISR_RESET;
    338             /* test specific case: zero length transfer */
    339             if ((val & (E8390_RREAD | E8390_RWRITE)) &&
    340                 s->rcnt == 0) {
    341                 s->isr |= ENISR_RDC;
    342                 ne2000_update_irq(s);
    343             }
    344             if (val & E8390_TRANS) {
    345                 index = (s->tpsr << 8);
    346                 /* XXX: next 2 lines are a hack to make netware 3.11 work */
    347                 if (index >= NE2000_PMEM_END)
    348                     index -= NE2000_PMEM_SIZE;
    349                 /* fail safe: check range on the transmitted length  */
    350                 if (index + s->tcnt <= NE2000_PMEM_END) {
    351                     qemu_send_packet(s->vc, s->mem + index, s->tcnt);
    352                 }
    353                 /* signal end of transfer */
    354                 s->tsr = ENTSR_PTX;
    355                 s->isr |= ENISR_TX;
    356                 s->cmd &= ~E8390_TRANS;
    357                 ne2000_update_irq(s);
    358             }
    359         }
    360     } else {
    361         page = s->cmd >> 6;
    362         offset = addr | (page << 4);
    363         switch(offset) {
    364         case EN0_STARTPG:
    365             s->start = val << 8;
    366             break;
    367         case EN0_STOPPG:
    368             s->stop = val << 8;
    369             break;
    370         case EN0_BOUNDARY:
    371             s->boundary = val;
    372             break;
    373         case EN0_IMR:
    374             s->imr = val;
    375             ne2000_update_irq(s);
    376             break;
    377         case EN0_TPSR:
    378             s->tpsr = val;
    379             break;
    380         case EN0_TCNTLO:
    381             s->tcnt = (s->tcnt & 0xff00) | val;
    382             break;
    383         case EN0_TCNTHI:
    384             s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
    385             break;
    386         case EN0_RSARLO:
    387             s->rsar = (s->rsar & 0xff00) | val;
    388             break;
    389         case EN0_RSARHI:
    390             s->rsar = (s->rsar & 0x00ff) | (val << 8);
    391             break;
    392         case EN0_RCNTLO:
    393             s->rcnt = (s->rcnt & 0xff00) | val;
    394             break;
    395         case EN0_RCNTHI:
    396             s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
    397             break;
    398         case EN0_RXCR:
    399             s->rxcr = val;
    400             break;
    401         case EN0_DCFG:
    402             s->dcfg = val;
    403             break;
    404         case EN0_ISR:
    405             s->isr &= ~(val & 0x7f);
    406             ne2000_update_irq(s);
    407             break;
    408         case EN1_PHYS ... EN1_PHYS + 5:
    409             s->phys[offset - EN1_PHYS] = val;
    410             break;
    411         case EN1_CURPAG:
    412             s->curpag = val;
    413             break;
    414         case EN1_MULT ... EN1_MULT + 7:
    415             s->mult[offset - EN1_MULT] = val;
    416             break;
    417         }
    418     }
    419 }
    420 
    421 static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
    422 {
    423     NE2000State *s = opaque;
    424     int offset, page, ret;
    425 
    426     addr &= 0xf;
    427     if (addr == E8390_CMD) {
    428         ret = s->cmd;
    429     } else {
    430         page = s->cmd >> 6;
    431         offset = addr | (page << 4);
    432         switch(offset) {
    433         case EN0_TSR:
    434             ret = s->tsr;
    435             break;
    436         case EN0_BOUNDARY:
    437             ret = s->boundary;
    438             break;
    439         case EN0_ISR:
    440             ret = s->isr;
    441             break;
    442 	case EN0_RSARLO:
    443 	    ret = s->rsar & 0x00ff;
    444 	    break;
    445 	case EN0_RSARHI:
    446 	    ret = s->rsar >> 8;
    447 	    break;
    448         case EN1_PHYS ... EN1_PHYS + 5:
    449             ret = s->phys[offset - EN1_PHYS];
    450             break;
    451         case EN1_CURPAG:
    452             ret = s->curpag;
    453             break;
    454         case EN1_MULT ... EN1_MULT + 7:
    455             ret = s->mult[offset - EN1_MULT];
    456             break;
    457         case EN0_RSR:
    458             ret = s->rsr;
    459             break;
    460         case EN2_STARTPG:
    461             ret = s->start >> 8;
    462             break;
    463         case EN2_STOPPG:
    464             ret = s->stop >> 8;
    465             break;
    466 	case EN0_RTL8029ID0:
    467 	    ret = 0x50;
    468 	    break;
    469 	case EN0_RTL8029ID1:
    470 	    ret = 0x43;
    471 	    break;
    472 	case EN3_CONFIG0:
    473 	    ret = 0;		/* 10baseT media */
    474 	    break;
    475 	case EN3_CONFIG2:
    476 	    ret = 0x40;		/* 10baseT active */
    477 	    break;
    478 	case EN3_CONFIG3:
    479 	    ret = 0x40;		/* Full duplex */
    480 	    break;
    481         default:
    482             ret = 0x00;
    483             break;
    484         }
    485     }
    486 #ifdef DEBUG_NE2000
    487     printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
    488 #endif
    489     return ret;
    490 }
    491 
    492 static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
    493                                      uint32_t val)
    494 {
    495     if (addr < 32 ||
    496         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
    497         s->mem[addr] = val;
    498     }
    499 }
    500 
    501 static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
    502                                      uint32_t val)
    503 {
    504     addr &= ~1; /* XXX: check exact behaviour if not even */
    505     if (addr < 32 ||
    506         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
    507         stw_le_p(s->mem + addr, val);
    508     }
    509 }
    510 
    511 static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
    512                                      uint32_t val)
    513 {
    514     addr &= ~1; /* XXX: check exact behaviour if not even */
    515     if (addr < 32 ||
    516         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
    517         stl_le_p(s->mem + addr, val);
    518     }
    519 }
    520 
    521 static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
    522 {
    523     if (addr < 32 ||
    524         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
    525         return s->mem[addr];
    526     } else {
    527         return 0xff;
    528     }
    529 }
    530 
    531 static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
    532 {
    533     addr &= ~1; /* XXX: check exact behaviour if not even */
    534     if (addr < 32 ||
    535         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
    536         return lduw_le_p(s->mem + addr);
    537     } else {
    538         return 0xffff;
    539     }
    540 }
    541 
    542 static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
    543 {
    544     addr &= ~1; /* XXX: check exact behaviour if not even */
    545     if (addr < 32 ||
    546         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
    547         return ldl_le_p(s->mem + addr);
    548     } else {
    549         return 0xffffffff;
    550     }
    551 }
    552 
    553 static inline void ne2000_dma_update(NE2000State *s, int len)
    554 {
    555     s->rsar += len;
    556     /* wrap */
    557     /* XXX: check what to do if rsar > stop */
    558     if (s->rsar == s->stop)
    559         s->rsar = s->start;
    560 
    561     if (s->rcnt <= len) {
    562         s->rcnt = 0;
    563         /* signal end of transfer */
    564         s->isr |= ENISR_RDC;
    565         ne2000_update_irq(s);
    566     } else {
    567         s->rcnt -= len;
    568     }
    569 }
    570 
    571 static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
    572 {
    573     NE2000State *s = opaque;
    574 
    575 #ifdef DEBUG_NE2000
    576     printf("NE2000: asic write val=0x%04x\n", val);
    577 #endif
    578     if (s->rcnt == 0)
    579         return;
    580     if (s->dcfg & 0x01) {
    581         /* 16 bit access */
    582         ne2000_mem_writew(s, s->rsar, val);
    583         ne2000_dma_update(s, 2);
    584     } else {
    585         /* 8 bit access */
    586         ne2000_mem_writeb(s, s->rsar, val);
    587         ne2000_dma_update(s, 1);
    588     }
    589 }
    590 
    591 static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
    592 {
    593     NE2000State *s = opaque;
    594     int ret;
    595 
    596     if (s->dcfg & 0x01) {
    597         /* 16 bit access */
    598         ret = ne2000_mem_readw(s, s->rsar);
    599         ne2000_dma_update(s, 2);
    600     } else {
    601         /* 8 bit access */
    602         ret = ne2000_mem_readb(s, s->rsar);
    603         ne2000_dma_update(s, 1);
    604     }
    605 #ifdef DEBUG_NE2000
    606     printf("NE2000: asic read val=0x%04x\n", ret);
    607 #endif
    608     return ret;
    609 }
    610 
    611 static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
    612 {
    613     NE2000State *s = opaque;
    614 
    615 #ifdef DEBUG_NE2000
    616     printf("NE2000: asic writel val=0x%04x\n", val);
    617 #endif
    618     if (s->rcnt == 0)
    619         return;
    620     /* 32 bit access */
    621     ne2000_mem_writel(s, s->rsar, val);
    622     ne2000_dma_update(s, 4);
    623 }
    624 
    625 static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
    626 {
    627     NE2000State *s = opaque;
    628     int ret;
    629 
    630     /* 32 bit access */
    631     ret = ne2000_mem_readl(s, s->rsar);
    632     ne2000_dma_update(s, 4);
    633 #ifdef DEBUG_NE2000
    634     printf("NE2000: asic readl val=0x%04x\n", ret);
    635 #endif
    636     return ret;
    637 }
    638 
    639 static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
    640 {
    641     /* nothing to do (end of reset pulse) */
    642 }
    643 
    644 static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
    645 {
    646     NE2000State *s = opaque;
    647     ne2000_reset(s);
    648     return 0;
    649 }
    650 
    651 static void ne2000_save(QEMUFile* f,void* opaque)
    652 {
    653 	NE2000State* s=(NE2000State*)opaque;
    654         uint32_t tmp;
    655 
    656         if (s->pci_dev)
    657             pci_device_save(s->pci_dev, f);
    658 
    659         qemu_put_8s(f, &s->rxcr);
    660 
    661 	qemu_put_8s(f, &s->cmd);
    662 	qemu_put_be32s(f, &s->start);
    663 	qemu_put_be32s(f, &s->stop);
    664 	qemu_put_8s(f, &s->boundary);
    665 	qemu_put_8s(f, &s->tsr);
    666 	qemu_put_8s(f, &s->tpsr);
    667 	qemu_put_be16s(f, &s->tcnt);
    668 	qemu_put_be16s(f, &s->rcnt);
    669 	qemu_put_be32s(f, &s->rsar);
    670 	qemu_put_8s(f, &s->rsr);
    671 	qemu_put_8s(f, &s->isr);
    672 	qemu_put_8s(f, &s->dcfg);
    673 	qemu_put_8s(f, &s->imr);
    674 	qemu_put_buffer(f, s->phys, 6);
    675 	qemu_put_8s(f, &s->curpag);
    676 	qemu_put_buffer(f, s->mult, 8);
    677         tmp = 0;
    678 	qemu_put_be32s(f, &tmp); /* ignored, was irq */
    679 	qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE);
    680 }
    681 
    682 static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
    683 {
    684 	NE2000State* s=(NE2000State*)opaque;
    685         int ret;
    686         uint32_t tmp;
    687 
    688         if (version_id > 3)
    689             return -EINVAL;
    690 
    691         if (s->pci_dev && version_id >= 3) {
    692             ret = pci_device_load(s->pci_dev, f);
    693             if (ret < 0)
    694                 return ret;
    695         }
    696 
    697         if (version_id >= 2) {
    698             qemu_get_8s(f, &s->rxcr);
    699         } else {
    700             s->rxcr = 0x0c;
    701         }
    702 
    703 	qemu_get_8s(f, &s->cmd);
    704 	qemu_get_be32s(f, &s->start);
    705 	qemu_get_be32s(f, &s->stop);
    706 	qemu_get_8s(f, &s->boundary);
    707 	qemu_get_8s(f, &s->tsr);
    708 	qemu_get_8s(f, &s->tpsr);
    709 	qemu_get_be16s(f, &s->tcnt);
    710 	qemu_get_be16s(f, &s->rcnt);
    711 	qemu_get_be32s(f, &s->rsar);
    712 	qemu_get_8s(f, &s->rsr);
    713 	qemu_get_8s(f, &s->isr);
    714 	qemu_get_8s(f, &s->dcfg);
    715 	qemu_get_8s(f, &s->imr);
    716 	qemu_get_buffer(f, s->phys, 6);
    717 	qemu_get_8s(f, &s->curpag);
    718 	qemu_get_buffer(f, s->mult, 8);
    719 	qemu_get_be32s(f, &tmp); /* ignored */
    720 	qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE);
    721 
    722 	return 0;
    723 }
    724 
    725 static void isa_ne2000_cleanup(VLANClientState *vc)
    726 {
    727     NE2000State *s = vc->opaque;
    728 
    729     unregister_savevm(NULL, "ne2000", s);
    730 
    731     isa_unassign_ioport(s->isa_io_base, 16);
    732     isa_unassign_ioport(s->isa_io_base + 0x10, 2);
    733     isa_unassign_ioport(s->isa_io_base + 0x1f, 1);
    734 
    735     g_free(s);
    736 }
    737 
    738 void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
    739 {
    740     NE2000State *s;
    741 
    742     qemu_check_nic_model(nd, "ne2k_isa");
    743 
    744     s = g_malloc0(sizeof(NE2000State));
    745 
    746     register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
    747     register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
    748 
    749     register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
    750     register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
    751     register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
    752     register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
    753 
    754     register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
    755     register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
    756     s->isa_io_base = base;
    757     s->irq = irq;
    758     memcpy(s->macaddr, nd->macaddr, 6);
    759 
    760     ne2000_reset(s);
    761 
    762     s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
    763                                  ne2000_can_receive, ne2000_receive, NULL,
    764                                  isa_ne2000_cleanup, s);
    765 
    766     qemu_format_nic_info_str(s->vc, s->macaddr);
    767 
    768     register_savevm(NULL, "ne2000", -1, 2, ne2000_save, ne2000_load, s);
    769 }
    770 
    771 /***********************************************************/
    772 /* PCI NE2000 definitions */
    773 
    774 typedef struct PCINE2000State {
    775     PCIDevice dev;
    776     NE2000State ne2000;
    777 } PCINE2000State;
    778 
    779 static void ne2000_map(PCIDevice *pci_dev, int region_num,
    780                        uint32_t addr, uint32_t size, int type)
    781 {
    782     PCINE2000State *d = (PCINE2000State *)pci_dev;
    783     NE2000State *s = &d->ne2000;
    784 
    785     register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
    786     register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
    787 
    788     register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
    789     register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
    790     register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
    791     register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
    792     register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
    793     register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
    794 
    795     register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
    796     register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
    797 }
    798 
    799 static void ne2000_cleanup(VLANClientState *vc)
    800 {
    801     NE2000State *s = vc->opaque;
    802 
    803     unregister_savevm(NULL, "ne2000", s);
    804 }
    805 
    806 static void pci_ne2000_init(PCIDevice *pci_dev)
    807 {
    808     PCINE2000State *d = (PCINE2000State *)pci_dev;
    809     NE2000State *s;
    810     uint8_t *pci_conf;
    811 
    812     pci_conf = d->dev.config;
    813     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
    814     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8029);
    815     pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
    816     pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
    817     pci_conf[0x3d] = 1; // interrupt pin 0
    818 
    819     pci_register_bar(&d->dev, 0, 0x100,
    820                            PCI_ADDRESS_SPACE_IO, ne2000_map);
    821     s = &d->ne2000;
    822     s->irq = d->dev.irq[0];
    823     s->pci_dev = (PCIDevice *)d;
    824     qdev_get_macaddr(&d->dev.qdev, s->macaddr);
    825     ne2000_reset(s);
    826     s->vc = qdev_get_vlan_client(&d->dev.qdev,
    827                                  ne2000_can_receive, ne2000_receive, NULL,
    828                                  ne2000_cleanup, s);
    829 
    830     qemu_format_nic_info_str(s->vc, s->macaddr);
    831 
    832     register_savevm(NULL, "ne2000", -1, 3, ne2000_save, ne2000_load, s);
    833 }
    834 
    835 static void ne2000_register_devices(void)
    836 {
    837     pci_qdev_register("ne2k_pci", sizeof(PCINE2000State), pci_ne2000_init);
    838 }
    839 
    840 device_init(ne2000_register_devices)
    841