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