Home | History | Annotate | Download | only in net
      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 "hw/sysbus.h"
     11 #include "net/net.h"
     12 #include "hw/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 packetnum;
    241     uint8_t *p;
    242 
    243     if ((s->tcr & TCR_TXEN) == 0)
    244         return;
    245     if (s->tx_fifo_len == 0)
    246         return;
    247     for (i = 0; i < s->tx_fifo_len; i++) {
    248         packetnum = s->tx_fifo[i];
    249         p = &s->data[packetnum][0];
    250         /* Set status word.  */
    251         *(p++) = 0x01;
    252         *(p++) = 0x40;
    253         len = *(p++);
    254         len |= ((int)*(p++)) << 8;
    255         len -= 6;
    256         control = p[len + 1];
    257         if (control & 0x20)
    258             len++;
    259         /* ??? This overwrites the data following the buffer.
    260            Don't know what real hardware does.  */
    261         if (len < 64 && (s->tcr & TCR_PAD_EN)) {
    262             memset(p + len, 0, 64 - len);
    263             len = 64;
    264         }
    265 #if 0
    266         /* The card is supposed to append the CRC to the frame.  However
    267            none of the other network traffic has the CRC appended.
    268            Suspect this is low level ethernet detail we don't need to worry
    269            about.  */
    270         add_crc = (control & 0x10) || (s->tcr & TCR_NOCRC) == 0;
    271         if (add_crc) {
    272             uint32_t crc;
    273 
    274             crc = crc32(~0, p, len);
    275             memcpy(p + len, &crc, 4);
    276             len += 4;
    277         }
    278 #endif
    279         if (s->ctr & CTR_AUTO_RELEASE)
    280             /* Race?  */
    281             smc91c111_release_packet(s, packetnum);
    282         else if (s->tx_fifo_done_len < NUM_PACKETS)
    283             s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
    284         qemu_send_packet(s->vc, p, len);
    285     }
    286     s->tx_fifo_len = 0;
    287     smc91c111_update(s);
    288 }
    289 
    290 /* Add a packet to the TX FIFO.  */
    291 static void smc91c111_queue_tx(smc91c111_state *s, int packet)
    292 {
    293     if (s->tx_fifo_len == NUM_PACKETS)
    294         return;
    295     s->tx_fifo[s->tx_fifo_len++] = packet;
    296     smc91c111_do_tx(s);
    297 }
    298 
    299 static void smc91c111_reset(smc91c111_state *s)
    300 {
    301     s->bank = 0;
    302     s->tx_fifo_len = 0;
    303     s->tx_fifo_done_len = 0;
    304     s->rx_fifo_len = 0;
    305     s->allocated = 0;
    306     s->packet_num = 0;
    307     s->tx_alloc = 0;
    308     s->tcr = 0;
    309     s->rcr = 0;
    310     s->cr = 0xa0b1;
    311     s->ctr = 0x1210;
    312     s->ptr = 0;
    313     s->ercv = 0x1f;
    314     s->int_level = INT_TX_EMPTY;
    315     s->int_mask = 0;
    316     smc91c111_update(s);
    317 }
    318 
    319 #define SET_LOW(name, val) s->name = (s->name & 0xff00) | val
    320 #define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8)
    321 
    322 static void smc91c111_writeb(void *opaque, hwaddr offset,
    323                              uint32_t value)
    324 {
    325     smc91c111_state *s = (smc91c111_state *)opaque;
    326 
    327     if (offset == 14) {
    328         s->bank = value;
    329         return;
    330     }
    331     if (offset == 15)
    332         return;
    333     switch (s->bank) {
    334     case 0:
    335         switch (offset) {
    336         case 0: /* TCR */
    337             SET_LOW(tcr, value);
    338             return;
    339         case 1:
    340             SET_HIGH(tcr, value);
    341             return;
    342         case 4: /* RCR */
    343             SET_LOW(rcr, value);
    344             return;
    345         case 5:
    346             SET_HIGH(rcr, value);
    347             if (s->rcr & RCR_SOFT_RST)
    348                 smc91c111_reset(s);
    349             return;
    350         case 10: case 11: /* RPCR */
    351             /* Ignored */
    352             return;
    353         }
    354         break;
    355 
    356     case 1:
    357         switch (offset) {
    358         case 0: /* CONFIG */
    359             SET_LOW(cr, value);
    360             return;
    361         case 1:
    362             SET_HIGH(cr,value);
    363             return;
    364         case 2: case 3: /* BASE */
    365         case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
    366             /* Not implemented.  */
    367             return;
    368         case 10: /* Genral Purpose */
    369             SET_LOW(gpr, value);
    370             return;
    371         case 11:
    372             SET_HIGH(gpr, value);
    373             return;
    374         case 12: /* Control */
    375             if (value & 1)
    376                 fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
    377             if (value & 2)
    378                 fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
    379             value &= ~3;
    380             SET_LOW(ctr, value);
    381             return;
    382         case 13:
    383             SET_HIGH(ctr, value);
    384             return;
    385         }
    386         break;
    387 
    388     case 2:
    389         switch (offset) {
    390         case 0: /* MMU Command */
    391             switch (value >> 5) {
    392             case 0: /* no-op */
    393                 break;
    394             case 1: /* Allocate for TX.  */
    395                 s->tx_alloc = 0x80;
    396                 s->int_level &= ~INT_ALLOC;
    397                 smc91c111_update(s);
    398                 smc91c111_tx_alloc(s);
    399                 break;
    400             case 2: /* Reset MMU.  */
    401                 s->allocated = 0;
    402                 s->tx_fifo_len = 0;
    403                 s->tx_fifo_done_len = 0;
    404                 s->rx_fifo_len = 0;
    405                 s->tx_alloc = 0;
    406                 break;
    407             case 3: /* Remove from RX FIFO.  */
    408                 smc91c111_pop_rx_fifo(s);
    409                 break;
    410             case 4: /* Remove from RX FIFO and release.  */
    411                 if (s->rx_fifo_len > 0) {
    412                     smc91c111_release_packet(s, s->rx_fifo[0]);
    413                 }
    414                 smc91c111_pop_rx_fifo(s);
    415                 break;
    416             case 5: /* Release.  */
    417                 smc91c111_release_packet(s, s->packet_num);
    418                 break;
    419             case 6: /* Add to TX FIFO.  */
    420                 smc91c111_queue_tx(s, s->packet_num);
    421                 break;
    422             case 7: /* Reset TX FIFO.  */
    423                 s->tx_fifo_len = 0;
    424                 s->tx_fifo_done_len = 0;
    425                 break;
    426             }
    427             return;
    428         case 1:
    429             /* Ignore.  */
    430             return;
    431         case 2: /* Packet Number Register */
    432             s->packet_num = value;
    433             return;
    434         case 3: case 4: case 5:
    435             /* Should be readonly, but linux writes to them anyway. Ignore.  */
    436             return;
    437         case 6: /* Pointer */
    438             SET_LOW(ptr, value);
    439             return;
    440         case 7:
    441             SET_HIGH(ptr, value);
    442             return;
    443         case 8: case 9: case 10: case 11: /* Data */
    444             {
    445                 int p;
    446                 int n;
    447 
    448                 if (s->ptr & 0x8000)
    449                     n = s->rx_fifo[0];
    450                 else
    451                     n = s->packet_num;
    452                 p = s->ptr & 0x07ff;
    453                 if (s->ptr & 0x4000) {
    454                     s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff);
    455                 } else {
    456                     p += (offset & 3);
    457                 }
    458                 s->data[n][p] = value;
    459             }
    460             return;
    461         case 12: /* Interrupt ACK.  */
    462             s->int_level &= ~(value & 0xd6);
    463             if (value & INT_TX)
    464                 smc91c111_pop_tx_fifo_done(s);
    465             smc91c111_update(s);
    466             return;
    467         case 13: /* Interrupt mask.  */
    468             s->int_mask = value;
    469             smc91c111_update(s);
    470             return;
    471         }
    472         break;;
    473 
    474     case 3:
    475         switch (offset) {
    476         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
    477             /* Multicast table.  */
    478             /* Not implemented.  */
    479             return;
    480         case 8: case 9: /* Management Interface.  */
    481             /* Not implemented.  */
    482             return;
    483         case 12: /* Early receive.  */
    484             s->ercv = value & 0x1f;
    485         case 13:
    486             /* Ignore.  */
    487             return;
    488         }
    489         break;
    490     }
    491     hw_error("smc91c111_write: Bad reg %d:%x\n", s->bank, (int)offset);
    492 }
    493 
    494 static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
    495 {
    496     smc91c111_state *s = (smc91c111_state *)opaque;
    497 
    498     if (offset == 14) {
    499         return s->bank;
    500     }
    501     if (offset == 15)
    502         return 0x33;
    503     switch (s->bank) {
    504     case 0:
    505         switch (offset) {
    506         case 0: /* TCR */
    507             return s->tcr & 0xff;
    508         case 1:
    509             return s->tcr >> 8;
    510         case 2: /* EPH Status */
    511             return 0;
    512         case 3:
    513             return 0x40;
    514         case 4: /* RCR */
    515             return s->rcr & 0xff;
    516         case 5:
    517             return s->rcr >> 8;
    518         case 6: /* Counter */
    519         case 7:
    520             /* Not implemented.  */
    521             return 0;
    522         case 8: /* Memory size.  */
    523             return NUM_PACKETS;
    524         case 9: /* Free memory available.  */
    525             {
    526                 int i;
    527                 int n;
    528                 n = 0;
    529                 for (i = 0; i < NUM_PACKETS; i++) {
    530                     if (s->allocated & (1 << i))
    531                         n++;
    532                 }
    533                 return n;
    534             }
    535         case 10: case 11: /* RPCR */
    536             /* Not implemented.  */
    537             return 0;
    538         }
    539         break;
    540 
    541     case 1:
    542         switch (offset) {
    543         case 0: /* CONFIG */
    544             return s->cr & 0xff;
    545         case 1:
    546             return s->cr >> 8;
    547         case 2: case 3: /* BASE */
    548             /* Not implemented.  */
    549             return 0;
    550         case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
    551             return s->macaddr[offset - 4];
    552         case 10: /* General Purpose */
    553             return s->gpr & 0xff;
    554         case 11:
    555             return s->gpr >> 8;
    556         case 12: /* Control */
    557             return s->ctr & 0xff;
    558         case 13:
    559             return s->ctr >> 8;
    560         }
    561         break;
    562 
    563     case 2:
    564         switch (offset) {
    565         case 0: case 1: /* MMUCR Busy bit.  */
    566             return 0;
    567         case 2: /* Packet Number.  */
    568             return s->packet_num;
    569         case 3: /* Allocation Result.  */
    570             return s->tx_alloc;
    571         case 4: /* TX FIFO */
    572             if (s->tx_fifo_done_len == 0)
    573                 return 0x80;
    574             else
    575                 return s->tx_fifo_done[0];
    576         case 5: /* RX FIFO */
    577             if (s->rx_fifo_len == 0)
    578                 return 0x80;
    579             else
    580                 return s->rx_fifo[0];
    581         case 6: /* Pointer */
    582             return s->ptr & 0xff;
    583         case 7:
    584             return (s->ptr >> 8) & 0xf7;
    585         case 8: case 9: case 10: case 11: /* Data */
    586             {
    587                 int p;
    588                 int n;
    589 
    590                 if (s->ptr & 0x8000)
    591                     n = s->rx_fifo[0];
    592                 else
    593                     n = s->packet_num;
    594                 p = s->ptr & 0x07ff;
    595                 if (s->ptr & 0x4000) {
    596                     s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff);
    597                 } else {
    598                     p += (offset & 3);
    599                 }
    600                 return s->data[n][p];
    601             }
    602         case 12: /* Interrupt status.  */
    603             return s->int_level;
    604         case 13: /* Interrupt mask.  */
    605             return s->int_mask;
    606         }
    607         break;
    608 
    609     case 3:
    610         switch (offset) {
    611         case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
    612             /* Multicast table.  */
    613             /* Not implemented.  */
    614             return 0;
    615         case 8: /* Management Interface.  */
    616             /* Not implemented.  */
    617             return 0x30;
    618         case 9:
    619             return 0x33;
    620         case 10: /* Revision.  */
    621             return 0x91;
    622         case 11:
    623             return 0x33;
    624         case 12:
    625             return s->ercv;
    626         case 13:
    627             return 0;
    628         }
    629         break;
    630     }
    631     hw_error("smc91c111_read: Bad reg %d:%x\n", s->bank, (int)offset);
    632     return 0;
    633 }
    634 
    635 static void smc91c111_writew(void *opaque, hwaddr offset,
    636                              uint32_t value)
    637 {
    638     smc91c111_writeb(opaque, offset, value & 0xff);
    639     smc91c111_writeb(opaque, offset + 1, value >> 8);
    640 }
    641 
    642 static void smc91c111_writel(void *opaque, hwaddr offset,
    643                              uint32_t value)
    644 {
    645     /* 32-bit writes to offset 0xc only actually write to the bank select
    646        register (offset 0xe)  */
    647     if (offset != 0xc)
    648         smc91c111_writew(opaque, offset, value & 0xffff);
    649     smc91c111_writew(opaque, offset + 2, value >> 16);
    650 }
    651 
    652 static uint32_t smc91c111_readw(void *opaque, hwaddr offset)
    653 {
    654     uint32_t val;
    655     val = smc91c111_readb(opaque, offset);
    656     val |= smc91c111_readb(opaque, offset + 1) << 8;
    657     return val;
    658 }
    659 
    660 static uint32_t smc91c111_readl(void *opaque, hwaddr offset)
    661 {
    662     uint32_t val;
    663     val = smc91c111_readw(opaque, offset);
    664     val |= smc91c111_readw(opaque, offset + 2) << 16;
    665     return val;
    666 }
    667 
    668 static int smc91c111_can_receive(VLANClientState *vc)
    669 {
    670     smc91c111_state *s = vc->opaque;
    671 
    672     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
    673         return 1;
    674     if (s->allocated == (1 << NUM_PACKETS) - 1)
    675         return 0;
    676     return 1;
    677 }
    678 
    679 static ssize_t smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
    680 {
    681     smc91c111_state *s = vc->opaque;
    682     int status;
    683     int packetsize;
    684     uint32_t crc;
    685     int packetnum;
    686     uint8_t *p;
    687 
    688     if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
    689         return -1;
    690     /* Short packets are padded with zeros.  Receiving a packet
    691        < 64 bytes long is considered an error condition.  */
    692     if (size < 64)
    693         packetsize = 64;
    694     else
    695         packetsize = (size & ~1);
    696     packetsize += 6;
    697     crc = (s->rcr & RCR_STRIP_CRC) == 0;
    698     if (crc)
    699         packetsize += 4;
    700     /* TODO: Flag overrun and receive errors.  */
    701     if (packetsize > 2048)
    702         return -1;
    703     packetnum = smc91c111_allocate_packet(s);
    704     if (packetnum == 0x80)
    705         return -1;
    706     s->rx_fifo[s->rx_fifo_len++] = packetnum;
    707 
    708     p = &s->data[packetnum][0];
    709     /* ??? Multicast packets?  */
    710     status = 0;
    711     if (size > 1518)
    712         status |= RS_TOOLONG;
    713     if (size & 1)
    714         status |= RS_ODDFRAME;
    715     *(p++) = status & 0xff;
    716     *(p++) = status >> 8;
    717     *(p++) = packetsize & 0xff;
    718     *(p++) = packetsize >> 8;
    719     memcpy(p, buf, size & ~1);
    720     p += (size & ~1);
    721     /* Pad short packets.  */
    722     if (size < 64) {
    723         int pad;
    724 
    725         if (size & 1)
    726             *(p++) = buf[size - 1];
    727         pad = 64 - size;
    728         memset(p, 0, pad);
    729         p += pad;
    730         size = 64;
    731     }
    732     /* It's not clear if the CRC should go before or after the last byte in
    733        odd sized packets.  Linux disables the CRC, so that's no help.
    734        The pictures in the documentation show the CRC aligned on a 16-bit
    735        boundary before the last odd byte, so that's what we do.  */
    736     if (crc) {
    737         crc = crc32(~0, buf, size);
    738         *(p++) = crc & 0xff; crc >>= 8;
    739         *(p++) = crc & 0xff; crc >>= 8;
    740         *(p++) = crc & 0xff; crc >>= 8;
    741         *(p++) = crc & 0xff; crc >>= 8;
    742     }
    743     if (size & 1) {
    744         *(p++) = buf[size - 1];
    745         *(p++) = 0x60;
    746     } else {
    747         *(p++) = 0;
    748         *(p++) = 0x40;
    749     }
    750     /* TODO: Raise early RX interrupt?  */
    751     s->int_level |= INT_RCV;
    752     smc91c111_update(s);
    753 
    754     return size;
    755 }
    756 
    757 static CPUReadMemoryFunc *smc91c111_readfn[] = {
    758     smc91c111_readb,
    759     smc91c111_readw,
    760     smc91c111_readl
    761 };
    762 
    763 static CPUWriteMemoryFunc *smc91c111_writefn[] = {
    764     smc91c111_writeb,
    765     smc91c111_writew,
    766     smc91c111_writel
    767 };
    768 
    769 static void smc91c111_cleanup(VLANClientState *vc)
    770 {
    771     smc91c111_state *s = vc->opaque;
    772 
    773     cpu_unregister_io_memory(s->mmio_index);
    774     g_free(s);
    775 }
    776 
    777 static void smc91c111_init1(SysBusDevice *dev)
    778 {
    779     smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev);
    780 
    781     s->mmio_index = cpu_register_io_memory(smc91c111_readfn,
    782                                            smc91c111_writefn, s);
    783     sysbus_init_mmio(dev, 16, s->mmio_index);
    784     sysbus_init_irq(dev, &s->irq);
    785     qdev_get_macaddr(&dev->qdev, s->macaddr);
    786 
    787     smc91c111_reset(s);
    788 
    789     s->vc = qdev_get_vlan_client(&dev->qdev,
    790                                  smc91c111_can_receive, smc91c111_receive, NULL,
    791                                  smc91c111_cleanup, s);
    792     qemu_format_nic_info_str(s->vc, s->macaddr);
    793 
    794     register_savevm(NULL, "smc91c111", 0, SMC91C111_SAVE_VERSION,
    795                     smc91c111_save, smc91c111_load, s);
    796 }
    797 
    798 static void smc91c111_register_devices(void)
    799 {
    800     sysbus_register_dev("smc91c111", sizeof(smc91c111_state), smc91c111_init1);
    801 }
    802 
    803 /* Legacy helper function.  Should go away when machine config files are
    804    implemented.  */
    805 void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
    806 {
    807     DeviceState *dev;
    808     SysBusDevice *s;
    809 
    810     qemu_check_nic_model(nd, "smc91c111");
    811     dev = qdev_create(NULL, "smc91c111");
    812     qdev_set_netdev(dev, nd);
    813     qdev_init(dev);
    814     s = sysbus_from_qdev(dev);
    815     sysbus_mmio_map(s, 0, base);
    816     sysbus_connect_irq(s, 0, irq);
    817 }
    818 
    819 device_init(smc91c111_register_devices)
    820