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