Home | History | Annotate | Download | only in hw
      1 /*
      2  * SMSC 91C111 Ethernet interface emulation
      3  *
      4  * Copyright (c) 2005 CodeSourcery, LLC.
      5  * Written by Paul Brook
      6  *
      7  * This code is licenced under the GPL
      8  */
      9 
     10 #include "sysbus.h"
     11 #include "net.h"
     12 #include "devices.h"
     13 #include "hw/hw.h"
     14 /* For crc32 */
     15 #include <zlib.h>
     16 
     17 /* Number of 2k memory pages available.  */
     18 #define NUM_PACKETS 4
     19 #define BUFFER_PER_PACKET 2048
     20 
     21 typedef struct {
     22     SysBusDevice busdev;
     23     VLANClientState *vc;
     24     uint16_t tcr;
     25     uint16_t rcr;
     26     uint16_t cr;
     27     uint16_t ctr;
     28     uint16_t gpr;
     29     uint16_t ptr;
     30     uint16_t ercv;
     31     qemu_irq irq;
     32     int bank;
     33     int packet_num;
     34     int tx_alloc;
     35     /* Bitmask of allocated packets.  */
     36     int allocated;
     37     int tx_fifo_len;
     38     int tx_fifo[NUM_PACKETS];
     39     int rx_fifo_len;
     40     int rx_fifo[NUM_PACKETS];
     41     int tx_fifo_done_len;
     42     int tx_fifo_done[NUM_PACKETS];
     43     /* Packet buffer memory.  */
     44     uint8_t data[NUM_PACKETS][BUFFER_PER_PACKET];
     45     uint8_t int_level;
     46     uint8_t int_mask;
     47     uint8_t macaddr[6];
     48     int mmio_index;
     49 } smc91c111_state;
     50 
     51 #define SMC91C111_SAVE_VERSION 1
     52 
     53 static void smc91c111_save(QEMUFile *f, void *opaque)
     54 {
     55     smc91c111_state *s = opaque;
     56 
     57     /* busdev, vc, macaddr and mmio_index are linked to the host state and
     58      * initialized when the emulator starts (in smc91c111_init1 below).
     59      * Saving/restoring those values is therefore useless and may even be
     60      * harmful, so they are omitted.
     61      */
     62     qemu_put_be16(f, s->tcr);
     63     qemu_put_be16(f, s->rcr);
     64     qemu_put_be16(f, s->cr);
     65     qemu_put_be16(f, s->ctr);
     66     qemu_put_be16(f, s->gpr);
     67     qemu_put_be16(f, s->ptr);
     68     qemu_put_be16(f, s->ercv);
     69 
     70     qemu_put_be32(f, s->bank);
     71     qemu_put_be32(f, s->packet_num);
     72 
     73     qemu_put_be32(f, s->tx_alloc);
     74     qemu_put_be32(f, s->allocated);
     75     qemu_put_be32(f, s->tx_fifo_len);
     76     qemu_put_buffer(f, (uint8_t*) s->tx_fifo, sizeof(s->tx_fifo));
     77     qemu_put_be32(f, s->rx_fifo_len);
     78     qemu_put_buffer(f, (uint8_t*) s->rx_fifo, sizeof(s->rx_fifo));
     79     qemu_put_be32(f, s->tx_fifo_done_len);
     80     qemu_put_buffer(f, (uint8_t*) s->tx_fifo_done, sizeof(s->tx_fifo_done));
     81 
     82     /* Packet buffer memory.  */
     83     qemu_put_buffer(f, (uint8_t*) s->data, sizeof(s->data));
     84     qemu_put_byte(f, s->int_level);
     85     qemu_put_byte(f, s->int_mask);
     86 
     87     /* macaddr, mmio_index omitted intentionally */
     88 }
     89 
     90 static int smc91c111_load(QEMUFile *f, void *opaque, int version_id)
     91 {
     92     smc91c111_state *s = opaque;
     93 
     94     if (version_id != SMC91C111_SAVE_VERSION) {
     95         return -1;
     96     }
     97 
     98     s->tcr = qemu_get_be16(f);
     99     s->rcr = qemu_get_be16(f);
    100     s->cr = qemu_get_be16(f);
    101     s->ctr = qemu_get_be16(f);
    102     s->gpr = qemu_get_be16(f);
    103     s->ptr = qemu_get_be16(f);
    104     s->ercv = qemu_get_be16(f);
    105 
    106     s->bank = qemu_get_be32(f);
    107     s->packet_num = qemu_get_be32(f);
    108 
    109     s->tx_alloc = qemu_get_be32(f);
    110     s->allocated = qemu_get_be32(f);
    111     s->tx_fifo_len = qemu_get_be32(f);
    112     qemu_get_buffer(f, (uint8_t*) s->tx_fifo, sizeof(s->tx_fifo));
    113     s->rx_fifo_len = qemu_get_be32(f);
    114     qemu_get_buffer(f, (uint8_t*) s->rx_fifo, sizeof(s->rx_fifo));
    115     s->tx_fifo_done_len = qemu_get_be32(f);
    116     qemu_get_buffer(f, (uint8_t*) s->tx_fifo_done, sizeof(s->tx_fifo_done));
    117 
    118     /* Packet buffer memory.  */
    119     qemu_get_buffer(f, (uint8_t*) s->data, sizeof(s->data));
    120     s->int_level = qemu_get_byte(f);
    121     s->int_mask = qemu_get_byte(f);
    122 
    123     return 0;
    124 }
    125 
    126 #define RCR_SOFT_RST  0x8000
    127 #define RCR_STRIP_CRC 0x0200
    128 #define RCR_RXEN      0x0100
    129 
    130 #define TCR_EPH_LOOP  0x2000
    131 #define TCR_NOCRC     0x0100
    132 #define TCR_PAD_EN    0x0080
    133 #define TCR_FORCOL    0x0004
    134 #define TCR_LOOP      0x0002
    135 #define TCR_TXEN      0x0001
    136 
    137 #define INT_MD        0x80
    138 #define INT_ERCV      0x40
    139 #define INT_EPH       0x20
    140 #define INT_RX_OVRN   0x10
    141 #define INT_ALLOC     0x08
    142 #define INT_TX_EMPTY  0x04
    143 #define INT_TX        0x02
    144 #define INT_RCV       0x01
    145 
    146 #define CTR_AUTO_RELEASE  0x0800
    147 #define CTR_RELOAD        0x0002
    148 #define CTR_STORE         0x0001
    149 
    150 #define RS_ALGNERR      0x8000
    151 #define RS_BRODCAST     0x4000
    152 #define RS_BADCRC       0x2000
    153 #define RS_ODDFRAME     0x1000
    154 #define RS_TOOLONG      0x0800
    155 #define RS_TOOSHORT     0x0400
    156 #define RS_MULTICAST    0x0001
    157 
    158 /* Update interrupt status.  */
    159 static void smc91c111_update(smc91c111_state *s)
    160 {
    161     int level;
    162 
    163     if (s->tx_fifo_len == 0)
    164         s->int_level |= INT_TX_EMPTY;
    165     if (s->tx_fifo_done_len != 0)
    166         s->int_level |= INT_TX;
    167     level = (s->int_level & s->int_mask) != 0;
    168     qemu_set_irq(s->irq, level);
    169 }
    170 
    171 /* Try to allocate a packet.  Returns 0x80 on failure.  */
    172 static int smc91c111_allocate_packet(smc91c111_state *s)
    173 {
    174     int i;
    175     if (s->allocated == (1 << NUM_PACKETS) - 1) {
    176         return 0x80;
    177     }
    178 
    179     for (i = 0; i < NUM_PACKETS; i++) {
    180         if ((s->allocated & (1 << i)) == 0)
    181             break;
    182     }
    183     s->allocated |= 1 << i;
    184     return i;
    185 }
    186 
    187 
    188 /* Process a pending TX allocate.  */
    189 static void smc91c111_tx_alloc(smc91c111_state *s)
    190 {
    191     s->tx_alloc = smc91c111_allocate_packet(s);
    192     if (s->tx_alloc == 0x80)
    193         return;
    194     s->int_level |= INT_ALLOC;
    195     smc91c111_update(s);
    196 }
    197 
    198 /* Remove and item from the RX FIFO.  */
    199 static void smc91c111_pop_rx_fifo(smc91c111_state *s)
    200 {
    201     int i;
    202 
    203     s->rx_fifo_len--;
    204     if (s->rx_fifo_len) {
    205         for (i = 0; i < s->rx_fifo_len; i++)
    206             s->rx_fifo[i] = s->rx_fifo[i + 1];
    207         s->int_level |= INT_RCV;
    208     } else {
    209         s->int_level &= ~INT_RCV;
    210     }
    211     smc91c111_update(s);
    212 }
    213 
    214 /* Remove an item from the TX completion FIFO.  */
    215 static void smc91c111_pop_tx_fifo_done(smc91c111_state *s)
    216 {
    217     int i;
    218 
    219     if (s->tx_fifo_done_len == 0)
    220         return;
    221     s->tx_fifo_done_len--;
    222     for (i = 0; i < s->tx_fifo_done_len; i++)
    223         s->tx_fifo_done[i] = s->tx_fifo_done[i + 1];
    224 }
    225 
    226 /* Release the memory allocated to a packet.  */
    227 static void smc91c111_release_packet(smc91c111_state *s, int packet)
    228 {
    229     s->allocated &= ~(1 << packet);
    230     if (s->tx_alloc == 0x80)
    231         smc91c111_tx_alloc(s);
    232 }
    233 
    234 /* Flush the TX FIFO.  */
    235 static void smc91c111_do_tx(smc91c111_state *s)
    236 {
    237     int i;
    238     int len;
    239     int control;
    240     int add_crc;
    241     int packetnum;
    242     uint8_t *p;
    243 
    244     if ((s->tcr & TCR_TXEN) == 0)
    245         return;
    246     if (s->tx_fifo_len == 0)
    247         return;
    248     for (i = 0; i < s->tx_fifo_len; i++) {
    249         packetnum = s->tx_fifo[i];
    250         p = &s->data[packetnum][0];
    251         /* Set status word.  */
    252         *(p++) = 0x01;
    253         *(p++) = 0x40;
    254         len = *(p++);
    255         len |= ((int)*(p++)) << 8;
    256         len -= 6;
    257         control = p[len + 1];
    258         if (control & 0x20)
    259             len++;
    260         /* ??? This overwrites the data following the buffer.
    261            Don't know what real hardware does.  */
    262         if (len < 64 && (s->tcr & TCR_PAD_EN)) {
    263             memset(p + len, 0, 64 - len);
    264             len = 64;
    265         }
    266 #if 0
    267         /* The card is supposed to append the CRC to the frame.  However
    268            none of the other network traffic has the CRC appended.
    269            Suspect this is low level ethernet detail we don't need to worry
    270            about.  */
    271         add_crc = (control & 0x10) || (s->tcr & TCR_NOCRC) == 0;
    272         if (add_crc) {
    273             uint32_t crc;
    274 
    275             crc = crc32(~0, p, len);
    276             memcpy(p + len, &crc, 4);
    277             len += 4;
    278         }
    279 #else
    280         add_crc = 0;
    281 #endif
    282         if (s->ctr & CTR_AUTO_RELEASE)
    283             /* Race?  */
    284             smc91c111_release_packet(s, packetnum);
    285         else if (s->tx_fifo_done_len < NUM_PACKETS)
    286             s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
    287         qemu_send_packet(s->vc, p, len);
    288     }
    289     s->tx_fifo_len = 0;
    290     smc91c111_update(s);
    291 }
    292 
    293 /* Add a packet to the TX FIFO.  */
    294 static void smc91c111_queue_tx(smc91c111_state *s, int packet)
    295 {
    296     if (s->tx_fifo_len == NUM_PACKETS)
    297         return;
    298     s->tx_fifo[s->tx_fifo_len++] = packet;
    299     smc91c111_do_tx(s);
    300 }
    301 
    302 static void smc91c111_reset(smc91c111_state *s)
    303 {
    304     s->bank = 0;
    305     s->tx_fifo_len = 0;
    306     s->tx_fifo_done_len = 0;
    307     s->rx_fifo_len = 0;
    308     s->allocated = 0;
    309     s->packet_num = 0;
    310     s->tx_alloc = 0;
    311     s->tcr = 0;
    312     s->rcr = 0;
    313     s->cr = 0xa0b1;
    314     s->ctr = 0x1210;
    315     s->ptr = 0;
    316     s->ercv = 0x1f;
    317     s->int_level = INT_TX_EMPTY;
    318     s->int_mask = 0;
    319     smc91c111_update(s);
    320 }
    321 
    322 #define SET_LOW(name, val) s->name = (s->name & 0xff00) | val
    323 #define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8)
    324 
    325 static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
    326                              uint32_t value)
    327 {
    328     smc91c111_state *s = (smc91c111_state *)opaque;
    329 
    330     if (offset == 14) {
    331         s->bank = value;
    332         return;
    333     }
    334     if (offset == 15)
    335         return;
    336     switch (s->bank) {
    337     case 0:
    338         switch (offset) {
    339         case 0: /* TCR */
    340             SET_LOW(tcr, value);
    341             return;
    342         case 1:
    343             SET_HIGH(tcr, value);
    344             return;
    345         case 4: /* RCR */
    346             SET_LOW(rcr, value);
    347             return;
    348         case 5:
    349             SET_HIGH(rcr, value);
    350             if (s->rcr & RCR_SOFT_RST)
    351                 smc91c111_reset(s);
    352             return;
    353         case 10: case 11: /* RPCR */
    354             /* Ignored */
    355             return;
    356         }
    357         break;
    358 
    359     case 1:
    360         switch (offset) {
    361         case 0: /* CONFIG */
    362             SET_LOW(cr, value);
    363             return;
    364         case 1:
    365             SET_HIGH(cr,value);
    366             return;
    367         case 2: case 3: /* BASE */
    368         case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
    369             /* Not implemented.  */
    370             return;
    371         case 10: /* Genral Purpose */
    372             SET_LOW(gpr, value);
    373             return;
    374         case 11:
    375             SET_HIGH(gpr, value);
    376             return;
    377         case 12: /* Control */
    378             if (value & 1)
    379                 fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
    380             if (value & 2)
    381                 fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
    382             value &= ~3;
    383             SET_LOW(ctr, value);
    384             return;
    385         case 13:
    386             SET_HIGH(ctr, value);
    387             return;
    388         }
    389         break;
    390 
    391     case 2:
    392         switch (offset) {
    393         case 0: /* MMU Command */
    394             switch (value >> 5) {
    395             case 0: /* no-op */
    396                 break;
    397             case 1: /* Allocate for TX.  */
    398                 s->tx_alloc = 0x80;
    399                 s->int_level &= ~INT_ALLOC;
    400                 smc91c111_update(s);
    401                 smc91c111_tx_alloc(s);
    402                 break;
    403             case 2: /* Reset MMU.  */
    404                 s->allocated = 0;
    405                 s->tx_fifo_len = 0;
    406                 s->tx_fifo_done_len = 0;
    407                 s->rx_fifo_len = 0;
    408                 s->tx_alloc = 0;
    409                 break;
    410             case 3: /* Remove from RX FIFO.  */
    411                 smc91c111_pop_rx_fifo(s);
    412                 break;
    413             case 4: /* Remove from RX FIFO and release.  */
    414                 if (s->rx_fifo_len > 0) {
    415                     smc91c111_release_packet(s, s->rx_fifo[0]);
    416                 }
    417                 smc91c111_pop_rx_fifo(s);
    418                 break;
    419             case 5: /* Release.  */
    420                 smc91c111_release_packet(s, s->packet_num);
    421                 break;
    422             case 6: /* Add to TX FIFO.  */
    423                 smc91c111_queue_tx(s, s->packet_num);
    424                 break;
    425             case 7: /* Reset TX FIFO.  */
    426                 s->tx_fifo_len = 0;
    427                 s->tx_fifo_done_len = 0;
    428                 break;
    429             }
    430             return;
    431         case 1:
    432             /* Ignore.  */
    433             return;
    434         case 2: /* Packet Number Register */
    435             s->packet_num = value;
    436             return;
    437         case 3: case 4: case 5:
    438             /* Should be readonly, but linux writes to them anyway. Ignore.  */
    439             return;
    440         case 6: /* Pointer */
    441             SET_LOW(ptr, value);
    442             return;
    443         case 7:
    444             SET_HIGH(ptr, value);
    445             return;
    446         case 8: case 9: case 10: case 11: /* Data */
    447             {
    448                 int p;
    449                 int n;
    450 
    451                 if (s->ptr & 0x8000)
    452                     n = s->rx_fifo[0];
    453                 else
    454                     n = s->packet_num;
    455                 p = s->ptr & 0x07ff;
    456                 if (s->ptr & 0x4000) {
    457                     s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff);
    458                 } else {
    459                     p += (offset & 3);
    460                 }
    461                 s->data[n][p] = value;
    462             }
    463             return;
    464         case 12: /* Interrupt ACK.  */
    465             s->int_level &= ~(value & 0xd6);
    466             if (value & INT_TX)
    467                 smc91c111_pop_tx_fifo_done(s);
    468             smc91c111_update(s);
    469             return;
    470         case 13: /* Interrupt mask.  */
    471             s->int_mask = value;
    472             smc91c111_update(s);
    473             return;
    474         }
    475         break;;
    476 
    477     case 3:
    478         switch (offset) {
    479         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
    480             /* Multicast table.  */
    481             /* Not implemented.  */
    482             return;
    483         case 8: case 9: /* Management Interface.  */
    484             /* Not implemented.  */
    485             return;
    486         case 12: /* Early receive.  */
    487             s->ercv = value & 0x1f;
    488         case 13:
    489             /* Ignore.  */
    490             return;
    491         }
    492         break;
    493     }
    494     hw_error("smc91c111_write: Bad reg %d:%x\n", s->bank, (int)offset);
    495 }
    496 
    497 static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
    498 {
    499     smc91c111_state *s = (smc91c111_state *)opaque;
    500 
    501     if (offset == 14) {
    502         return s->bank;
    503     }
    504     if (offset == 15)
    505         return 0x33;
    506     switch (s->bank) {
    507     case 0:
    508         switch (offset) {
    509         case 0: /* TCR */
    510             return s->tcr & 0xff;
    511         case 1:
    512             return s->tcr >> 8;
    513         case 2: /* EPH Status */
    514             return 0;
    515         case 3:
    516             return 0x40;
    517         case 4: /* RCR */
    518             return s->rcr & 0xff;
    519         case 5:
    520             return s->rcr >> 8;
    521         case 6: /* Counter */
    522         case 7:
    523             /* Not implemented.  */
    524             return 0;
    525         case 8: /* Memory size.  */
    526             return NUM_PACKETS;
    527         case 9: /* Free memory available.  */
    528             {
    529                 int i;
    530                 int n;
    531                 n = 0;
    532                 for (i = 0; i < NUM_PACKETS; i++) {
    533                     if (s->allocated & (1 << i))
    534                         n++;
    535                 }
    536                 return n;
    537             }
    538         case 10: case 11: /* RPCR */
    539             /* Not implemented.  */
    540             return 0;
    541         }
    542         break;
    543 
    544     case 1:
    545         switch (offset) {
    546         case 0: /* CONFIG */
    547             return s->cr & 0xff;
    548         case 1:
    549             return s->cr >> 8;
    550         case 2: case 3: /* BASE */
    551             /* Not implemented.  */
    552             return 0;
    553         case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
    554             return s->macaddr[offset - 4];
    555         case 10: /* General Purpose */
    556             return s->gpr & 0xff;
    557         case 11:
    558             return s->gpr >> 8;
    559         case 12: /* Control */
    560             return s->ctr & 0xff;
    561         case 13:
    562             return s->ctr >> 8;
    563         }
    564         break;
    565 
    566     case 2:
    567         switch (offset) {
    568         case 0: case 1: /* MMUCR Busy bit.  */
    569             return 0;
    570         case 2: /* Packet Number.  */
    571             return s->packet_num;
    572         case 3: /* Allocation Result.  */
    573             return s->tx_alloc;
    574         case 4: /* TX FIFO */
    575             if (s->tx_fifo_done_len == 0)
    576                 return 0x80;
    577             else
    578                 return s->tx_fifo_done[0];
    579         case 5: /* RX FIFO */
    580             if (s->rx_fifo_len == 0)
    581                 return 0x80;
    582             else
    583                 return s->rx_fifo[0];
    584         case 6: /* Pointer */
    585             return s->ptr & 0xff;
    586         case 7:
    587             return (s->ptr >> 8) & 0xf7;
    588         case 8: case 9: case 10: case 11: /* Data */
    589             {
    590                 int p;
    591                 int n;
    592 
    593                 if (s->ptr & 0x8000)
    594                     n = s->rx_fifo[0];
    595                 else
    596                     n = s->packet_num;
    597                 p = s->ptr & 0x07ff;
    598                 if (s->ptr & 0x4000) {
    599                     s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff);
    600                 } else {
    601                     p += (offset & 3);
    602                 }
    603                 return s->data[n][p];
    604             }
    605         case 12: /* Interrupt status.  */
    606             return s->int_level;
    607         case 13: /* Interrupt mask.  */
    608             return s->int_mask;
    609         }
    610         break;
    611 
    612     case 3:
    613         switch (offset) {
    614         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
    615             /* Multicast table.  */
    616             /* Not implemented.  */
    617             return 0;
    618         case 8: /* Management Interface.  */
    619             /* Not implemented.  */
    620             return 0x30;
    621         case 9:
    622             return 0x33;
    623         case 10: /* Revision.  */
    624             return 0x91;
    625         case 11:
    626             return 0x33;
    627         case 12:
    628             return s->ercv;
    629         case 13:
    630             return 0;
    631         }
    632         break;
    633     }
    634     hw_error("smc91c111_read: Bad reg %d:%x\n", s->bank, (int)offset);
    635     return 0;
    636 }
    637 
    638 static void smc91c111_writew(void *opaque, target_phys_addr_t offset,
    639                              uint32_t value)
    640 {
    641     smc91c111_writeb(opaque, offset, value & 0xff);
    642     smc91c111_writeb(opaque, offset + 1, value >> 8);
    643 }
    644 
    645 static void smc91c111_writel(void *opaque, target_phys_addr_t offset,
    646                              uint32_t value)
    647 {
    648     /* 32-bit writes to offset 0xc only actually write to the bank select
    649        register (offset 0xe)  */
    650     if (offset != 0xc)
    651         smc91c111_writew(opaque, offset, value & 0xffff);
    652     smc91c111_writew(opaque, offset + 2, value >> 16);
    653 }
    654 
    655 static uint32_t smc91c111_readw(void *opaque, target_phys_addr_t offset)
    656 {
    657     uint32_t val;
    658     val = smc91c111_readb(opaque, offset);
    659     val |= smc91c111_readb(opaque, offset + 1) << 8;
    660     return val;
    661 }
    662 
    663 static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
    664 {
    665     uint32_t val;
    666     val = smc91c111_readw(opaque, offset);
    667     val |= smc91c111_readw(opaque, offset + 2) << 16;
    668     return val;
    669 }
    670 
    671 static int smc91c111_can_receive(VLANClientState *vc)
    672 {
    673     smc91c111_state *s = vc->opaque;
    674 
    675     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
    676         return 1;
    677     if (s->allocated == (1 << NUM_PACKETS) - 1)
    678         return 0;
    679     return 1;
    680 }
    681 
    682 static ssize_t smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
    683 {
    684     smc91c111_state *s = vc->opaque;
    685     int status;
    686     int packetsize;
    687     uint32_t crc;
    688     int packetnum;
    689     uint8_t *p;
    690 
    691     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
    692         return -1;
    693     /* Short packets are padded with zeros.  Receiving a packet
    694        < 64 bytes long is considered an error condition.  */
    695     if (size < 64)
    696         packetsize = 64;
    697     else
    698         packetsize = (size & ~1);
    699     packetsize += 6;
    700     crc = (s->rcr & RCR_STRIP_CRC) == 0;
    701     if (crc)
    702         packetsize += 4;
    703     /* TODO: Flag overrun and receive errors.  */
    704     if (packetsize > 2048)
    705         return -1;
    706     packetnum = smc91c111_allocate_packet(s);
    707     if (packetnum == 0x80)
    708         return -1;
    709     s->rx_fifo[s->rx_fifo_len++] = packetnum;
    710 
    711     p = &s->data[packetnum][0];
    712     /* ??? Multicast packets?  */
    713     status = 0;
    714     if (size > 1518)
    715         status |= RS_TOOLONG;
    716     if (size & 1)
    717         status |= RS_ODDFRAME;
    718     *(p++) = status & 0xff;
    719     *(p++) = status >> 8;
    720     *(p++) = packetsize & 0xff;
    721     *(p++) = packetsize >> 8;
    722     memcpy(p, buf, size & ~1);
    723     p += (size & ~1);
    724     /* Pad short packets.  */
    725     if (size < 64) {
    726         int pad;
    727 
    728         if (size & 1)
    729             *(p++) = buf[size - 1];
    730         pad = 64 - size;
    731         memset(p, 0, pad);
    732         p += pad;
    733         size = 64;
    734     }
    735     /* It's not clear if the CRC should go before or after the last byte in
    736        odd sized packets.  Linux disables the CRC, so that's no help.
    737        The pictures in the documentation show the CRC aligned on a 16-bit
    738        boundary before the last odd byte, so that's what we do.  */
    739     if (crc) {
    740         crc = crc32(~0, buf, size);
    741         *(p++) = crc & 0xff; crc >>= 8;
    742         *(p++) = crc & 0xff; crc >>= 8;
    743         *(p++) = crc & 0xff; crc >>= 8;
    744         *(p++) = crc & 0xff; crc >>= 8;
    745     }
    746     if (size & 1) {
    747         *(p++) = buf[size - 1];
    748         *(p++) = 0x60;
    749     } else {
    750         *(p++) = 0;
    751         *(p++) = 0x40;
    752     }
    753     /* TODO: Raise early RX interrupt?  */
    754     s->int_level |= INT_RCV;
    755     smc91c111_update(s);
    756 
    757     return size;
    758 }
    759 
    760 static CPUReadMemoryFunc *smc91c111_readfn[] = {
    761     smc91c111_readb,
    762     smc91c111_readw,
    763     smc91c111_readl
    764 };
    765 
    766 static CPUWriteMemoryFunc *smc91c111_writefn[] = {
    767     smc91c111_writeb,
    768     smc91c111_writew,
    769     smc91c111_writel
    770 };
    771 
    772 static void smc91c111_cleanup(VLANClientState *vc)
    773 {
    774     smc91c111_state *s = vc->opaque;
    775 
    776     cpu_unregister_io_memory(s->mmio_index);
    777     qemu_free(s);
    778 }
    779 
    780 static void smc91c111_init1(SysBusDevice *dev)
    781 {
    782     smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev);
    783 
    784     s->mmio_index = cpu_register_io_memory(smc91c111_readfn,
    785                                            smc91c111_writefn, s);
    786     sysbus_init_mmio(dev, 16, s->mmio_index);
    787     sysbus_init_irq(dev, &s->irq);
    788     qdev_get_macaddr(&dev->qdev, s->macaddr);
    789 
    790     smc91c111_reset(s);
    791 
    792     s->vc = qdev_get_vlan_client(&dev->qdev,
    793                                  smc91c111_can_receive, smc91c111_receive, NULL,
    794                                  smc91c111_cleanup, s);
    795     qemu_format_nic_info_str(s->vc, s->macaddr);
    796 
    797     register_savevm( "smc91c111", 0, SMC91C111_SAVE_VERSION,
    798                      smc91c111_save, smc91c111_load, s);
    799 }
    800 
    801 static void smc91c111_register_devices(void)
    802 {
    803     sysbus_register_dev("smc91c111", sizeof(smc91c111_state), smc91c111_init1);
    804 }
    805 
    806 /* Legacy helper function.  Should go away when machine config files are
    807    implemented.  */
    808 void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
    809 {
    810     DeviceState *dev;
    811     SysBusDevice *s;
    812 
    813     qemu_check_nic_model(nd, "smc91c111");
    814     dev = qdev_create(NULL, "smc91c111");
    815     qdev_set_netdev(dev, nd);
    816     qdev_init(dev);
    817     s = sysbus_from_qdev(dev);
    818     sysbus_mmio_map(s, 0, base);
    819     sysbus_connect_irq(s, 0, irq);
    820 }
    821 
    822 device_init(smc91c111_register_devices)
    823