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