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