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