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 "sysbus.h" 11#include "net.h" 12#include "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 21typedef 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 53static 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 90static 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. */ 159static 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. */ 172static 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. */ 189static 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. */ 199static 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. */ 215static 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. */ 227static 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. */ 235static void smc91c111_do_tx(smc91c111_state *s) 236{ 237 int i; 238 int len; 239 int control; 240 int add_crc; 241 int packetnum; 242 uint8_t *p; 243 244 if ((s->tcr & TCR_TXEN) == 0) 245 return; 246 if (s->tx_fifo_len == 0) 247 return; 248 for (i = 0; i < s->tx_fifo_len; i++) { 249 packetnum = s->tx_fifo[i]; 250 p = &s->data[packetnum][0]; 251 /* Set status word. */ 252 *(p++) = 0x01; 253 *(p++) = 0x40; 254 len = *(p++); 255 len |= ((int)*(p++)) << 8; 256 len -= 6; 257 control = p[len + 1]; 258 if (control & 0x20) 259 len++; 260 /* ??? This overwrites the data following the buffer. 261 Don't know what real hardware does. */ 262 if (len < 64 && (s->tcr & TCR_PAD_EN)) { 263 memset(p + len, 0, 64 - len); 264 len = 64; 265 } 266#if 0 267 /* The card is supposed to append the CRC to the frame. However 268 none of the other network traffic has the CRC appended. 269 Suspect this is low level ethernet detail we don't need to worry 270 about. */ 271 add_crc = (control & 0x10) || (s->tcr & TCR_NOCRC) == 0; 272 if (add_crc) { 273 uint32_t crc; 274 275 crc = crc32(~0, p, len); 276 memcpy(p + len, &crc, 4); 277 len += 4; 278 } 279#else 280 add_crc = 0; 281#endif 282 if (s->ctr & CTR_AUTO_RELEASE) 283 /* Race? */ 284 smc91c111_release_packet(s, packetnum); 285 else if (s->tx_fifo_done_len < NUM_PACKETS) 286 s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum; 287 qemu_send_packet(s->vc, p, len); 288 } 289 s->tx_fifo_len = 0; 290 smc91c111_update(s); 291} 292 293/* Add a packet to the TX FIFO. */ 294static void smc91c111_queue_tx(smc91c111_state *s, int packet) 295{ 296 if (s->tx_fifo_len == NUM_PACKETS) 297 return; 298 s->tx_fifo[s->tx_fifo_len++] = packet; 299 smc91c111_do_tx(s); 300} 301 302static void smc91c111_reset(smc91c111_state *s) 303{ 304 s->bank = 0; 305 s->tx_fifo_len = 0; 306 s->tx_fifo_done_len = 0; 307 s->rx_fifo_len = 0; 308 s->allocated = 0; 309 s->packet_num = 0; 310 s->tx_alloc = 0; 311 s->tcr = 0; 312 s->rcr = 0; 313 s->cr = 0xa0b1; 314 s->ctr = 0x1210; 315 s->ptr = 0; 316 s->ercv = 0x1f; 317 s->int_level = INT_TX_EMPTY; 318 s->int_mask = 0; 319 smc91c111_update(s); 320} 321 322#define SET_LOW(name, val) s->name = (s->name & 0xff00) | val 323#define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8) 324 325static void smc91c111_writeb(void *opaque, target_phys_addr_t offset, 326 uint32_t value) 327{ 328 smc91c111_state *s = (smc91c111_state *)opaque; 329 330 if (offset == 14) { 331 s->bank = value; 332 return; 333 } 334 if (offset == 15) 335 return; 336 switch (s->bank) { 337 case 0: 338 switch (offset) { 339 case 0: /* TCR */ 340 SET_LOW(tcr, value); 341 return; 342 case 1: 343 SET_HIGH(tcr, value); 344 return; 345 case 4: /* RCR */ 346 SET_LOW(rcr, value); 347 return; 348 case 5: 349 SET_HIGH(rcr, value); 350 if (s->rcr & RCR_SOFT_RST) 351 smc91c111_reset(s); 352 return; 353 case 10: case 11: /* RPCR */ 354 /* Ignored */ 355 return; 356 } 357 break; 358 359 case 1: 360 switch (offset) { 361 case 0: /* CONFIG */ 362 SET_LOW(cr, value); 363 return; 364 case 1: 365 SET_HIGH(cr,value); 366 return; 367 case 2: case 3: /* BASE */ 368 case 4: case 5: case 6: case 7: case 8: case 9: /* IA */ 369 /* Not implemented. */ 370 return; 371 case 10: /* Genral Purpose */ 372 SET_LOW(gpr, value); 373 return; 374 case 11: 375 SET_HIGH(gpr, value); 376 return; 377 case 12: /* Control */ 378 if (value & 1) 379 fprintf(stderr, "smc91c111:EEPROM store not implemented\n"); 380 if (value & 2) 381 fprintf(stderr, "smc91c111:EEPROM reload not implemented\n"); 382 value &= ~3; 383 SET_LOW(ctr, value); 384 return; 385 case 13: 386 SET_HIGH(ctr, value); 387 return; 388 } 389 break; 390 391 case 2: 392 switch (offset) { 393 case 0: /* MMU Command */ 394 switch (value >> 5) { 395 case 0: /* no-op */ 396 break; 397 case 1: /* Allocate for TX. */ 398 s->tx_alloc = 0x80; 399 s->int_level &= ~INT_ALLOC; 400 smc91c111_update(s); 401 smc91c111_tx_alloc(s); 402 break; 403 case 2: /* Reset MMU. */ 404 s->allocated = 0; 405 s->tx_fifo_len = 0; 406 s->tx_fifo_done_len = 0; 407 s->rx_fifo_len = 0; 408 s->tx_alloc = 0; 409 break; 410 case 3: /* Remove from RX FIFO. */ 411 smc91c111_pop_rx_fifo(s); 412 break; 413 case 4: /* Remove from RX FIFO and release. */ 414 if (s->rx_fifo_len > 0) { 415 smc91c111_release_packet(s, s->rx_fifo[0]); 416 } 417 smc91c111_pop_rx_fifo(s); 418 break; 419 case 5: /* Release. */ 420 smc91c111_release_packet(s, s->packet_num); 421 break; 422 case 6: /* Add to TX FIFO. */ 423 smc91c111_queue_tx(s, s->packet_num); 424 break; 425 case 7: /* Reset TX FIFO. */ 426 s->tx_fifo_len = 0; 427 s->tx_fifo_done_len = 0; 428 break; 429 } 430 return; 431 case 1: 432 /* Ignore. */ 433 return; 434 case 2: /* Packet Number Register */ 435 s->packet_num = value; 436 return; 437 case 3: case 4: case 5: 438 /* Should be readonly, but linux writes to them anyway. Ignore. */ 439 return; 440 case 6: /* Pointer */ 441 SET_LOW(ptr, value); 442 return; 443 case 7: 444 SET_HIGH(ptr, value); 445 return; 446 case 8: case 9: case 10: case 11: /* Data */ 447 { 448 int p; 449 int n; 450 451 if (s->ptr & 0x8000) 452 n = s->rx_fifo[0]; 453 else 454 n = s->packet_num; 455 p = s->ptr & 0x07ff; 456 if (s->ptr & 0x4000) { 457 s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff); 458 } else { 459 p += (offset & 3); 460 } 461 s->data[n][p] = value; 462 } 463 return; 464 case 12: /* Interrupt ACK. */ 465 s->int_level &= ~(value & 0xd6); 466 if (value & INT_TX) 467 smc91c111_pop_tx_fifo_done(s); 468 smc91c111_update(s); 469 return; 470 case 13: /* Interrupt mask. */ 471 s->int_mask = value; 472 smc91c111_update(s); 473 return; 474 } 475 break;; 476 477 case 3: 478 switch (offset) { 479 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 480 /* Multicast table. */ 481 /* Not implemented. */ 482 return; 483 case 8: case 9: /* Management Interface. */ 484 /* Not implemented. */ 485 return; 486 case 12: /* Early receive. */ 487 s->ercv = value & 0x1f; 488 case 13: 489 /* Ignore. */ 490 return; 491 } 492 break; 493 } 494 hw_error("smc91c111_write: Bad reg %d:%x\n", s->bank, (int)offset); 495} 496 497static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset) 498{ 499 smc91c111_state *s = (smc91c111_state *)opaque; 500 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 } 542 break; 543 544 case 1: 545 switch (offset) { 546 case 0: /* CONFIG */ 547 return s->cr & 0xff; 548 case 1: 549 return s->cr >> 8; 550 case 2: case 3: /* BASE */ 551 /* Not implemented. */ 552 return 0; 553 case 4: case 5: case 6: case 7: case 8: case 9: /* IA */ 554 return s->macaddr[offset - 4]; 555 case 10: /* General Purpose */ 556 return s->gpr & 0xff; 557 case 11: 558 return s->gpr >> 8; 559 case 12: /* Control */ 560 return s->ctr & 0xff; 561 case 13: 562 return s->ctr >> 8; 563 } 564 break; 565 566 case 2: 567 switch (offset) { 568 case 0: case 1: /* MMUCR Busy bit. */ 569 return 0; 570 case 2: /* Packet Number. */ 571 return s->packet_num; 572 case 3: /* Allocation Result. */ 573 return s->tx_alloc; 574 case 4: /* TX FIFO */ 575 if (s->tx_fifo_done_len == 0) 576 return 0x80; 577 else 578 return s->tx_fifo_done[0]; 579 case 5: /* RX FIFO */ 580 if (s->rx_fifo_len == 0) 581 return 0x80; 582 else 583 return s->rx_fifo[0]; 584 case 6: /* Pointer */ 585 return s->ptr & 0xff; 586 case 7: 587 return (s->ptr >> 8) & 0xf7; 588 case 8: case 9: case 10: case 11: /* Data */ 589 { 590 int p; 591 int n; 592 593 if (s->ptr & 0x8000) 594 n = s->rx_fifo[0]; 595 else 596 n = s->packet_num; 597 p = s->ptr & 0x07ff; 598 if (s->ptr & 0x4000) { 599 s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff); 600 } else { 601 p += (offset & 3); 602 } 603 return s->data[n][p]; 604 } 605 case 12: /* Interrupt status. */ 606 return s->int_level; 607 case 13: /* Interrupt mask. */ 608 return s->int_mask; 609 } 610 break; 611 612 case 3: 613 switch (offset) { 614 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 615 /* Multicast table. */ 616 /* Not implemented. */ 617 return 0; 618 case 8: /* Management Interface. */ 619 /* Not implemented. */ 620 return 0x30; 621 case 9: 622 return 0x33; 623 case 10: /* Revision. */ 624 return 0x91; 625 case 11: 626 return 0x33; 627 case 12: 628 return s->ercv; 629 case 13: 630 return 0; 631 } 632 break; 633 } 634 hw_error("smc91c111_read: Bad reg %d:%x\n", s->bank, (int)offset); 635 return 0; 636} 637 638static void smc91c111_writew(void *opaque, target_phys_addr_t offset, 639 uint32_t value) 640{ 641 smc91c111_writeb(opaque, offset, value & 0xff); 642 smc91c111_writeb(opaque, offset + 1, value >> 8); 643} 644 645static void smc91c111_writel(void *opaque, target_phys_addr_t offset, 646 uint32_t value) 647{ 648 /* 32-bit writes to offset 0xc only actually write to the bank select 649 register (offset 0xe) */ 650 if (offset != 0xc) 651 smc91c111_writew(opaque, offset, value & 0xffff); 652 smc91c111_writew(opaque, offset + 2, value >> 16); 653} 654 655static uint32_t smc91c111_readw(void *opaque, target_phys_addr_t offset) 656{ 657 uint32_t val; 658 val = smc91c111_readb(opaque, offset); 659 val |= smc91c111_readb(opaque, offset + 1) << 8; 660 return val; 661} 662 663static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset) 664{ 665 uint32_t val; 666 val = smc91c111_readw(opaque, offset); 667 val |= smc91c111_readw(opaque, offset + 2) << 16; 668 return val; 669} 670 671static int smc91c111_can_receive(VLANClientState *vc) 672{ 673 smc91c111_state *s = vc->opaque; 674 675 if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) 676 return 1; 677 if (s->allocated == (1 << NUM_PACKETS) - 1) 678 return 0; 679 return 1; 680} 681 682static ssize_t smc91c111_receive(VLANClientState *vc, const uint8_t *buf, size_t size) 683{ 684 smc91c111_state *s = vc->opaque; 685 int status; 686 int packetsize; 687 uint32_t crc; 688 int packetnum; 689 uint8_t *p; 690 691 if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) 692 return -1; 693 /* Short packets are padded with zeros. Receiving a packet 694 < 64 bytes long is considered an error condition. */ 695 if (size < 64) 696 packetsize = 64; 697 else 698 packetsize = (size & ~1); 699 packetsize += 6; 700 crc = (s->rcr & RCR_STRIP_CRC) == 0; 701 if (crc) 702 packetsize += 4; 703 /* TODO: Flag overrun and receive errors. */ 704 if (packetsize > 2048) 705 return -1; 706 packetnum = smc91c111_allocate_packet(s); 707 if (packetnum == 0x80) 708 return -1; 709 s->rx_fifo[s->rx_fifo_len++] = packetnum; 710 711 p = &s->data[packetnum][0]; 712 /* ??? Multicast packets? */ 713 status = 0; 714 if (size > 1518) 715 status |= RS_TOOLONG; 716 if (size & 1) 717 status |= RS_ODDFRAME; 718 *(p++) = status & 0xff; 719 *(p++) = status >> 8; 720 *(p++) = packetsize & 0xff; 721 *(p++) = packetsize >> 8; 722 memcpy(p, buf, size & ~1); 723 p += (size & ~1); 724 /* Pad short packets. */ 725 if (size < 64) { 726 int pad; 727 728 if (size & 1) 729 *(p++) = buf[size - 1]; 730 pad = 64 - size; 731 memset(p, 0, pad); 732 p += pad; 733 size = 64; 734 } 735 /* It's not clear if the CRC should go before or after the last byte in 736 odd sized packets. Linux disables the CRC, so that's no help. 737 The pictures in the documentation show the CRC aligned on a 16-bit 738 boundary before the last odd byte, so that's what we do. */ 739 if (crc) { 740 crc = crc32(~0, buf, size); 741 *(p++) = crc & 0xff; crc >>= 8; 742 *(p++) = crc & 0xff; crc >>= 8; 743 *(p++) = crc & 0xff; crc >>= 8; 744 *(p++) = crc & 0xff; crc >>= 8; 745 } 746 if (size & 1) { 747 *(p++) = buf[size - 1]; 748 *(p++) = 0x60; 749 } else { 750 *(p++) = 0; 751 *(p++) = 0x40; 752 } 753 /* TODO: Raise early RX interrupt? */ 754 s->int_level |= INT_RCV; 755 smc91c111_update(s); 756 757 return size; 758} 759 760static CPUReadMemoryFunc *smc91c111_readfn[] = { 761 smc91c111_readb, 762 smc91c111_readw, 763 smc91c111_readl 764}; 765 766static CPUWriteMemoryFunc *smc91c111_writefn[] = { 767 smc91c111_writeb, 768 smc91c111_writew, 769 smc91c111_writel 770}; 771 772static void smc91c111_cleanup(VLANClientState *vc) 773{ 774 smc91c111_state *s = vc->opaque; 775 776 cpu_unregister_io_memory(s->mmio_index); 777 qemu_free(s); 778} 779 780static void smc91c111_init1(SysBusDevice *dev) 781{ 782 smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev); 783 784 s->mmio_index = cpu_register_io_memory(smc91c111_readfn, 785 smc91c111_writefn, s); 786 sysbus_init_mmio(dev, 16, s->mmio_index); 787 sysbus_init_irq(dev, &s->irq); 788 qdev_get_macaddr(&dev->qdev, s->macaddr); 789 790 smc91c111_reset(s); 791 792 s->vc = qdev_get_vlan_client(&dev->qdev, 793 smc91c111_can_receive, smc91c111_receive, NULL, 794 smc91c111_cleanup, s); 795 qemu_format_nic_info_str(s->vc, s->macaddr); 796 797 register_savevm( "smc91c111", 0, SMC91C111_SAVE_VERSION, 798 smc91c111_save, smc91c111_load, s); 799} 800 801static void smc91c111_register_devices(void) 802{ 803 sysbus_register_dev("smc91c111", sizeof(smc91c111_state), smc91c111_init1); 804} 805 806/* Legacy helper function. Should go away when machine config files are 807 implemented. */ 808void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq) 809{ 810 DeviceState *dev; 811 SysBusDevice *s; 812 813 qemu_check_nic_model(nd, "smc91c111"); 814 dev = qdev_create(NULL, "smc91c111"); 815 qdev_set_netdev(dev, nd); 816 qdev_init(dev); 817 s = sysbus_from_qdev(dev); 818 sysbus_mmio_map(s, 0, base); 819 sysbus_connect_irq(s, 0, irq); 820} 821 822device_init(smc91c111_register_devices) 823