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