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