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