1 /* 2 * QEMU Intel i82596 (Apricot) emulation 3 * 4 * Copyright (c) 2019 Helge Deller <deller@gmx.de> 5 * This work is licensed under the GNU GPL license version 2 or later. 6 * 7 * This software was written to be compatible with the specification: 8 * https://parisc.docs.kernel.org/en/latest/_downloads/96672be0650d9fc046bbcea40b92482f/82596CA.pdf 9 */ 10 11 #include "qemu/osdep.h" 12 #include "qemu/timer.h" 13 #include "net/net.h" 14 #include "net/eth.h" 15 #include "hw/irq.h" 16 #include "hw/qdev-properties.h" 17 #include "migration/vmstate.h" 18 #include "system/address-spaces.h" 19 #include "qemu/module.h" 20 #include "trace.h" 21 #include "i82596.h" 22 #include <zlib.h> /* for crc32 */ 23 24 #if defined(ENABLE_DEBUG) 25 #define DBG(x) x 26 #else 27 #define DBG(x) do { } while (0) 28 #endif 29 30 #define USE_TIMER 0 31 32 #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m) 33 34 #define PKT_BUF_SZ 1536 35 #define MAX_MC_CNT 64 36 37 #define ISCP_BUSY 0x0001 38 39 #define I596_NULL ((uint32_t)0xffffffff) 40 41 #define SCB_STATUS_CX 0x8000 /* CU finished command with I bit */ 42 #define SCB_STATUS_FR 0x4000 /* RU finished receiving a frame */ 43 #define SCB_STATUS_CNA 0x2000 /* CU left active state */ 44 #define SCB_STATUS_RNR 0x1000 /* RU left active state */ 45 46 #define SCB_COMMAND_ACK_MASK \ 47 (SCB_STATUS_CX | SCB_STATUS_FR | SCB_STATUS_CNA | SCB_STATUS_RNR) 48 49 #define CU_IDLE 0 50 #define CU_SUSPENDED 1 51 #define CU_ACTIVE 2 52 53 #define RX_IDLE 0 54 #define RX_SUSPENDED 1 55 #define RX_READY 4 56 57 #define CMD_EOL 0x8000 /* The last command of the list, stop. */ 58 #define CMD_SUSP 0x4000 /* Suspend after doing cmd. */ 59 #define CMD_INTR 0x2000 /* Interrupt after doing cmd. */ 60 61 #define CMD_FLEX 0x0008 /* Enable flexible memory model */ 62 63 enum commands { 64 CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, 65 CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7 66 }; 67 68 #define STAT_C 0x8000 /* Set to 0 after execution */ 69 #define STAT_B 0x4000 /* Command being executed */ 70 #define STAT_OK 0x2000 /* Command executed ok */ 71 #define STAT_A 0x1000 /* Command aborted */ 72 73 #define I596_EOF 0x8000 74 #define SIZE_MASK 0x3fff 75 76 /* various flags in the chip config registers */ 77 #define I596_PREFETCH (s->config[0] & 0x80) 78 #define I596_PROMISC (s->config[8] & 0x01) 79 #define I596_BC_DISABLE (s->config[8] & 0x02) /* broadcast disable */ 80 #define I596_NOCRC_INS (s->config[8] & 0x08) 81 #define I596_CRCINM (s->config[11] & 0x04) /* CRC appended */ 82 #define I596_MC_ALL (s->config[11] & 0x20) 83 #define I596_MULTIIA (s->config[13] & 0x40) 84 85 86 static uint8_t get_byte(uint32_t addr) 87 { 88 return ldub_phys(&address_space_memory, addr); 89 } 90 91 static void set_byte(uint32_t addr, uint8_t c) 92 { 93 return stb_phys(&address_space_memory, addr, c); 94 } 95 96 static uint16_t get_uint16(uint32_t addr) 97 { 98 return lduw_be_phys(&address_space_memory, addr); 99 } 100 101 static void set_uint16(uint32_t addr, uint16_t w) 102 { 103 return stw_be_phys(&address_space_memory, addr, w); 104 } 105 106 static uint32_t get_uint32(uint32_t addr) 107 { 108 uint32_t lo = lduw_be_phys(&address_space_memory, addr); 109 uint32_t hi = lduw_be_phys(&address_space_memory, addr + 2); 110 return (hi << 16) | lo; 111 } 112 113 static void set_uint32(uint32_t addr, uint32_t val) 114 { 115 set_uint16(addr, (uint16_t) val); 116 set_uint16(addr + 2, val >> 16); 117 } 118 119 120 struct qemu_ether_header { 121 uint8_t ether_dhost[6]; 122 uint8_t ether_shost[6]; 123 uint16_t ether_type; 124 }; 125 126 #define PRINT_PKTHDR(txt, BUF) do { \ 127 struct qemu_ether_header *hdr = (void *)(BUF); \ 128 printf(txt ": packet dhost=" MAC_FMT ", shost=" MAC_FMT ", type=0x%04x\n",\ 129 MAC_ARG(hdr->ether_dhost), MAC_ARG(hdr->ether_shost), \ 130 be16_to_cpu(hdr->ether_type)); \ 131 } while (0) 132 133 static void i82596_transmit(I82596State *s, uint32_t addr) 134 { 135 uint32_t tdb_p; /* Transmit Buffer Descriptor */ 136 137 /* TODO: Check flexible mode */ 138 tdb_p = get_uint32(addr + 8); 139 while (tdb_p != I596_NULL) { 140 uint16_t size, len; 141 uint32_t tba; 142 143 size = get_uint16(tdb_p); 144 len = size & SIZE_MASK; 145 tba = get_uint32(tdb_p + 8); 146 trace_i82596_transmit(len, tba); 147 148 if (s->nic && len) { 149 assert(len <= sizeof(s->tx_buffer)); 150 address_space_read(&address_space_memory, tba, 151 MEMTXATTRS_UNSPECIFIED, s->tx_buffer, len); 152 DBG(PRINT_PKTHDR("Send", &s->tx_buffer)); 153 DBG(printf("Sending %d bytes\n", len)); 154 qemu_send_packet(qemu_get_queue(s->nic), s->tx_buffer, len); 155 } 156 157 /* was this the last package? */ 158 if (size & I596_EOF) { 159 break; 160 } 161 162 /* get next buffer pointer */ 163 tdb_p = get_uint32(tdb_p + 4); 164 } 165 } 166 167 static void set_individual_address(I82596State *s, uint32_t addr) 168 { 169 NetClientState *nc; 170 uint8_t *m; 171 172 nc = qemu_get_queue(s->nic); 173 m = s->conf.macaddr.a; 174 address_space_read(&address_space_memory, addr + 8, 175 MEMTXATTRS_UNSPECIFIED, m, ETH_ALEN); 176 qemu_format_nic_info_str(nc, m); 177 trace_i82596_new_mac(nc->info_str); 178 } 179 180 static void i82596_configure(I82596State *s, uint32_t addr) 181 { 182 uint8_t byte_cnt; 183 byte_cnt = get_byte(addr + 8) & 0x0f; 184 185 byte_cnt = MAX(byte_cnt, 4); 186 byte_cnt = MIN(byte_cnt, sizeof(s->config)); 187 /* copy byte_cnt max. */ 188 address_space_read(&address_space_memory, addr + 8, 189 MEMTXATTRS_UNSPECIFIED, s->config, byte_cnt); 190 /* config byte according to page 35ff */ 191 s->config[2] &= 0x82; /* mask valid bits */ 192 s->config[2] |= 0x40; 193 s->config[7] &= 0xf7; /* clear zero bit */ 194 assert(I596_NOCRC_INS == 0); /* do CRC insertion */ 195 s->config[10] = MAX(s->config[10], 5); /* min frame length */ 196 s->config[12] &= 0x40; /* only full duplex field valid */ 197 s->config[13] |= 0x3f; /* set ones in byte 13 */ 198 } 199 200 static void set_multicast_list(I82596State *s, uint32_t addr) 201 { 202 uint16_t mc_count, i; 203 204 memset(&s->mult[0], 0, sizeof(s->mult)); 205 mc_count = get_uint16(addr + 8) / ETH_ALEN; 206 addr += 10; 207 if (mc_count > MAX_MC_CNT) { 208 mc_count = MAX_MC_CNT; 209 } 210 for (i = 0; i < mc_count; i++) { 211 uint8_t multicast_addr[ETH_ALEN]; 212 address_space_read(&address_space_memory, addr + i * ETH_ALEN, 213 MEMTXATTRS_UNSPECIFIED, multicast_addr, ETH_ALEN); 214 DBG(printf("Add multicast entry " MAC_FMT "\n", 215 MAC_ARG(multicast_addr))); 216 unsigned mcast_idx = (net_crc32(multicast_addr, ETH_ALEN) & 217 BITS(7, 2)) >> 2; 218 assert(mcast_idx < 8 * sizeof(s->mult)); 219 s->mult[mcast_idx >> 3] |= (1 << (mcast_idx & 7)); 220 } 221 trace_i82596_set_multicast(mc_count); 222 } 223 224 void i82596_set_link_status(NetClientState *nc) 225 { 226 I82596State *d = qemu_get_nic_opaque(nc); 227 228 d->lnkst = nc->link_down ? 0 : 0x8000; 229 } 230 231 static void update_scb_status(I82596State *s) 232 { 233 s->scb_status = (s->scb_status & 0xf000) 234 | (s->cu_status << 8) | (s->rx_status << 4); 235 set_uint16(s->scb, s->scb_status); 236 } 237 238 239 static void i82596_s_reset(I82596State *s) 240 { 241 trace_i82596_s_reset(s); 242 s->scp = 0; 243 s->scb_status = 0; 244 s->cu_status = CU_IDLE; 245 s->rx_status = RX_SUSPENDED; 246 s->cmd_p = I596_NULL; 247 s->lnkst = 0x8000; /* initial link state: up */ 248 s->ca = s->ca_active = 0; 249 s->send_irq = 0; 250 } 251 252 253 static void command_loop(I82596State *s) 254 { 255 uint16_t cmd; 256 uint16_t status; 257 258 DBG(printf("STARTING COMMAND LOOP cmd_p=%08x\n", s->cmd_p)); 259 260 while (s->cmd_p != I596_NULL) { 261 /* set status */ 262 status = STAT_B; 263 set_uint16(s->cmd_p, status); 264 status = STAT_C | STAT_OK; /* update, but write later */ 265 266 cmd = get_uint16(s->cmd_p + 2); 267 DBG(printf("Running command %04x at %08x\n", cmd, s->cmd_p)); 268 269 switch (cmd & 0x07) { 270 case CmdNOp: 271 break; 272 case CmdSASetup: 273 set_individual_address(s, s->cmd_p); 274 break; 275 case CmdConfigure: 276 i82596_configure(s, s->cmd_p); 277 break; 278 case CmdTDR: 279 /* get signal LINK */ 280 set_uint32(s->cmd_p + 8, s->lnkst); 281 break; 282 case CmdTx: 283 i82596_transmit(s, s->cmd_p); 284 break; 285 case CmdMulticastList: 286 set_multicast_list(s, s->cmd_p); 287 break; 288 case CmdDump: 289 case CmdDiagnose: 290 printf("FIXME Command %d !!\n", cmd & 7); 291 g_assert_not_reached(); 292 } 293 294 /* update status */ 295 set_uint16(s->cmd_p, status); 296 297 s->cmd_p = get_uint32(s->cmd_p + 4); /* get link address */ 298 DBG(printf("NEXT addr would be %08x\n", s->cmd_p)); 299 if (s->cmd_p == 0) { 300 s->cmd_p = I596_NULL; 301 } 302 303 /* Stop when last command of the list. */ 304 if (cmd & CMD_EOL) { 305 s->cmd_p = I596_NULL; 306 } 307 /* Suspend after doing cmd? */ 308 if (cmd & CMD_SUSP) { 309 s->cu_status = CU_SUSPENDED; 310 printf("FIXME SUSPEND !!\n"); 311 } 312 /* Interrupt after doing cmd? */ 313 if (cmd & CMD_INTR) { 314 s->scb_status |= SCB_STATUS_CX; 315 } else { 316 s->scb_status &= ~SCB_STATUS_CX; 317 } 318 update_scb_status(s); 319 320 /* Interrupt after doing cmd? */ 321 if (cmd & CMD_INTR) { 322 s->send_irq = 1; 323 } 324 325 if (s->cu_status != CU_ACTIVE) { 326 break; 327 } 328 } 329 DBG(printf("FINISHED COMMAND LOOP\n")); 330 qemu_flush_queued_packets(qemu_get_queue(s->nic)); 331 } 332 333 static void i82596_flush_queue_timer(void *opaque) 334 { 335 I82596State *s = opaque; 336 if (0) { 337 timer_del(s->flush_queue_timer); 338 qemu_flush_queued_packets(qemu_get_queue(s->nic)); 339 timer_mod(s->flush_queue_timer, 340 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000); 341 } 342 } 343 344 static void examine_scb(I82596State *s) 345 { 346 uint16_t command, cuc, ruc; 347 348 /* get the scb command word */ 349 command = get_uint16(s->scb + 2); 350 cuc = (command >> 8) & 0x7; 351 ruc = (command >> 4) & 0x7; 352 DBG(printf("MAIN COMMAND %04x cuc %02x ruc %02x\n", command, cuc, ruc)); 353 /* and clear the scb command word */ 354 set_uint16(s->scb + 2, 0); 355 356 s->scb_status &= ~(command & SCB_COMMAND_ACK_MASK); 357 358 switch (cuc) { 359 case 0: /* no change */ 360 break; 361 case 1: /* CUC_START */ 362 s->cu_status = CU_ACTIVE; 363 break; 364 case 4: /* CUC_ABORT */ 365 s->cu_status = CU_SUSPENDED; 366 s->scb_status |= SCB_STATUS_CNA; /* CU left active state */ 367 break; 368 default: 369 printf("WARNING: Unknown CUC %d!\n", cuc); 370 } 371 372 switch (ruc) { 373 case 0: /* no change */ 374 break; 375 case 1: /* RX_START */ 376 case 2: /* RX_RESUME */ 377 s->rx_status = RX_IDLE; 378 if (USE_TIMER) { 379 timer_mod(s->flush_queue_timer, qemu_clock_get_ms( 380 QEMU_CLOCK_VIRTUAL) + 1000); 381 } 382 break; 383 case 3: /* RX_SUSPEND */ 384 case 4: /* RX_ABORT */ 385 s->rx_status = RX_SUSPENDED; 386 s->scb_status |= SCB_STATUS_RNR; /* RU left active state */ 387 break; 388 default: 389 printf("WARNING: Unknown RUC %d!\n", ruc); 390 } 391 392 if (command & 0x80) { /* reset bit set? */ 393 i82596_s_reset(s); 394 } 395 396 /* execute commands from SCBL */ 397 if (s->cu_status != CU_SUSPENDED) { 398 if (s->cmd_p == I596_NULL) { 399 s->cmd_p = get_uint32(s->scb + 4); 400 } 401 } 402 403 /* update scb status */ 404 update_scb_status(s); 405 406 command_loop(s); 407 } 408 409 static void signal_ca(I82596State *s) 410 { 411 uint32_t iscp = 0; 412 413 /* trace_i82596_channel_attention(s); */ 414 if (s->scp) { 415 /* CA after reset -> do init with new scp. */ 416 s->sysbus = get_byte(s->scp + 3); /* big endian */ 417 DBG(printf("SYSBUS = %08x\n", s->sysbus)); 418 if (((s->sysbus >> 1) & 0x03) != 2) { 419 printf("WARNING: NO LINEAR MODE !!\n"); 420 } 421 if ((s->sysbus >> 7)) { 422 printf("WARNING: 32BIT LINMODE IN B-STEPPING NOT SUPPORTED !!\n"); 423 } 424 iscp = get_uint32(s->scp + 8); 425 s->scb = get_uint32(iscp + 4); 426 set_byte(iscp + 1, 0); /* clear BUSY flag in iscp */ 427 s->scp = 0; 428 } 429 430 s->ca++; /* count ca() */ 431 if (!s->ca_active) { 432 s->ca_active = 1; 433 while (s->ca) { 434 examine_scb(s); 435 s->ca--; 436 } 437 s->ca_active = 0; 438 } 439 440 if (s->send_irq) { 441 s->send_irq = 0; 442 qemu_set_irq(s->irq, 1); 443 } 444 } 445 446 void i82596_ioport_writew(void *opaque, uint32_t addr, uint32_t val) 447 { 448 I82596State *s = opaque; 449 /* printf("i82596_ioport_writew addr=0x%08x val=0x%04x\n", addr, val); */ 450 switch (addr) { 451 case PORT_RESET: /* Reset */ 452 i82596_s_reset(s); 453 break; 454 case PORT_ALTSCP: 455 s->scp = val; 456 break; 457 case PORT_CA: 458 signal_ca(s); 459 break; 460 } 461 } 462 463 uint32_t i82596_ioport_readw(void *opaque, uint32_t addr) 464 { 465 return -1; 466 } 467 468 void i82596_h_reset(void *opaque) 469 { 470 I82596State *s = opaque; 471 472 i82596_s_reset(s); 473 } 474 475 bool i82596_can_receive(NetClientState *nc) 476 { 477 I82596State *s = qemu_get_nic_opaque(nc); 478 479 if (s->rx_status == RX_SUSPENDED) { 480 return false; 481 } 482 483 if (!s->lnkst) { 484 return false; 485 } 486 487 if (USE_TIMER && !timer_pending(s->flush_queue_timer)) { 488 return true; 489 } 490 491 return true; 492 } 493 494 ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz) 495 { 496 I82596State *s = qemu_get_nic_opaque(nc); 497 uint32_t rfd_p; 498 uint32_t rbd; 499 uint16_t is_broadcast = 0; 500 size_t len = sz; /* length of data for guest (including CRC) */ 501 size_t bufsz = sz; /* length of data in buf */ 502 uint32_t crc; 503 uint8_t *crc_ptr; 504 static const uint8_t broadcast_macaddr[6] = { 505 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 506 507 DBG(printf("i82596_receive() start\n")); 508 509 if (USE_TIMER && timer_pending(s->flush_queue_timer)) { 510 return 0; 511 } 512 513 /* first check if receiver is enabled */ 514 if (s->rx_status == RX_SUSPENDED) { 515 trace_i82596_receive_analysis(">>> Receiving suspended"); 516 return -1; 517 } 518 519 if (!s->lnkst) { 520 trace_i82596_receive_analysis(">>> Link down"); 521 return -1; 522 } 523 524 /* Received frame smaller than configured "min frame len"? */ 525 if (sz < s->config[10]) { 526 printf("Received frame too small, %zu vs. %u bytes\n", 527 sz, s->config[10]); 528 return -1; 529 } 530 531 DBG(printf("Received %lu bytes\n", sz)); 532 533 if (I596_PROMISC) { 534 535 /* promiscuous: receive all */ 536 trace_i82596_receive_analysis( 537 ">>> packet received in promiscuous mode"); 538 539 } else { 540 541 if (!memcmp(buf, broadcast_macaddr, 6)) { 542 /* broadcast address */ 543 if (I596_BC_DISABLE) { 544 trace_i82596_receive_analysis(">>> broadcast packet rejected"); 545 546 return len; 547 } 548 549 trace_i82596_receive_analysis(">>> broadcast packet received"); 550 is_broadcast = 1; 551 552 } else if (buf[0] & 0x01) { 553 /* multicast */ 554 if (!I596_MC_ALL) { 555 trace_i82596_receive_analysis(">>> multicast packet rejected"); 556 557 return len; 558 } 559 560 int mcast_idx = (net_crc32(buf, ETH_ALEN) & BITS(7, 2)) >> 2; 561 assert(mcast_idx < 8 * sizeof(s->mult)); 562 563 if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) { 564 trace_i82596_receive_analysis(">>> multicast address mismatch"); 565 566 return len; 567 } 568 569 trace_i82596_receive_analysis(">>> multicast packet received"); 570 is_broadcast = 1; 571 572 } else if (!memcmp(s->conf.macaddr.a, buf, 6)) { 573 574 /* match */ 575 trace_i82596_receive_analysis( 576 ">>> physical address matching packet received"); 577 578 } else { 579 580 trace_i82596_receive_analysis(">>> unknown packet"); 581 582 return len; 583 } 584 } 585 586 /* Calculate the ethernet checksum (4 bytes) */ 587 len += 4; 588 crc = cpu_to_be32(crc32(~0, buf, sz)); 589 crc_ptr = (uint8_t *) &crc; 590 591 rfd_p = get_uint32(s->scb + 8); /* get Receive Frame Descriptor */ 592 assert(rfd_p && rfd_p != I596_NULL); 593 594 /* get first Receive Buffer Descriptor Address */ 595 rbd = get_uint32(rfd_p + 8); 596 assert(rbd && rbd != I596_NULL); 597 598 trace_i82596_receive_packet(len); 599 /* PRINT_PKTHDR("Receive", buf); */ 600 601 while (len) { 602 uint16_t command, status; 603 uint32_t next_rfd; 604 605 command = get_uint16(rfd_p + 2); 606 assert(command & CMD_FLEX); /* assert Flex Mode */ 607 /* get first Receive Buffer Descriptor Address */ 608 rbd = get_uint32(rfd_p + 8); 609 assert(get_uint16(rfd_p + 14) == 0); 610 611 /* printf("Receive: rfd is %08x\n", rfd_p); */ 612 613 while (len) { 614 uint16_t buffer_size, num; 615 uint32_t rba; 616 size_t bufcount, crccount; 617 618 /* printf("Receive: rbd is %08x\n", rbd); */ 619 buffer_size = get_uint16(rbd + 12); 620 /* printf("buffer_size is 0x%x\n", buffer_size); */ 621 assert(buffer_size != 0); 622 623 num = buffer_size & SIZE_MASK; 624 if (num > len) { 625 num = len; 626 } 627 rba = get_uint32(rbd + 8); 628 /* printf("rba is 0x%x\n", rba); */ 629 /* 630 * Calculate how many bytes we want from buf[] and how many 631 * from the CRC. 632 */ 633 if ((len - num) >= 4) { 634 /* The whole guest buffer, we haven't hit the CRC yet */ 635 bufcount = num; 636 } else { 637 /* All that's left of buf[] */ 638 bufcount = len - 4; 639 } 640 crccount = num - bufcount; 641 642 if (bufcount > 0) { 643 /* Still some of the actual data buffer to transfer */ 644 assert(bufsz >= bufcount); 645 bufsz -= bufcount; 646 address_space_write(&address_space_memory, rba, 647 MEMTXATTRS_UNSPECIFIED, buf, bufcount); 648 rba += bufcount; 649 buf += bufcount; 650 len -= bufcount; 651 } 652 653 /* Write as much of the CRC as fits */ 654 if (crccount > 0) { 655 address_space_write(&address_space_memory, rba, 656 MEMTXATTRS_UNSPECIFIED, crc_ptr, crccount); 657 rba += crccount; 658 crc_ptr += crccount; 659 len -= crccount; 660 } 661 662 num |= 0x4000; /* set F BIT */ 663 if (len == 0) { 664 num |= I596_EOF; /* set EOF BIT */ 665 } 666 set_uint16(rbd + 0, num); /* write actual count with flags */ 667 668 /* get next rbd */ 669 rbd = get_uint32(rbd + 4); 670 /* printf("Next Receive: rbd is %08x\n", rbd); */ 671 672 if (buffer_size & I596_EOF) /* last entry */ 673 break; 674 } 675 676 /* Housekeeping, see pg. 18 */ 677 next_rfd = get_uint32(rfd_p + 4); 678 set_uint32(next_rfd + 8, rbd); 679 680 status = STAT_C | STAT_OK | is_broadcast; 681 set_uint16(rfd_p, status); 682 683 if (command & CMD_SUSP) { /* suspend after command? */ 684 s->rx_status = RX_SUSPENDED; 685 s->scb_status |= SCB_STATUS_RNR; /* RU left active state */ 686 break; 687 } 688 if (command & CMD_EOL) /* was it last Frame Descriptor? */ 689 break; 690 691 assert(len == 0); 692 } 693 694 assert(len == 0); 695 696 s->scb_status |= SCB_STATUS_FR; /* set "RU finished receiving frame" bit. */ 697 update_scb_status(s); 698 699 /* send IRQ that we received data */ 700 qemu_set_irq(s->irq, 1); 701 /* s->send_irq = 1; */ 702 703 if (0) { 704 DBG(printf("Checking:\n")); 705 rfd_p = get_uint32(s->scb + 8); /* get Receive Frame Descriptor */ 706 DBG(printf("Next Receive: rfd is %08x\n", rfd_p)); 707 rfd_p = get_uint32(rfd_p + 4); /* get Next Receive Frame Descriptor */ 708 DBG(printf("Next Receive: rfd is %08x\n", rfd_p)); 709 /* get first Receive Buffer Descriptor Address */ 710 rbd = get_uint32(rfd_p + 8); 711 DBG(printf("Next Receive: rbd is %08x\n", rbd)); 712 } 713 714 return sz; 715 } 716 717 718 const VMStateDescription vmstate_i82596 = { 719 .name = "i82596", 720 .version_id = 1, 721 .minimum_version_id = 1, 722 .fields = (const VMStateField[]) { 723 VMSTATE_UINT16(lnkst, I82596State), 724 VMSTATE_TIMER_PTR(flush_queue_timer, I82596State), 725 VMSTATE_END_OF_LIST() 726 } 727 }; 728 729 void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info) 730 { 731 if (s->conf.macaddr.a[0] == 0) { 732 qemu_macaddr_default_if_unset(&s->conf.macaddr); 733 } 734 s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), 735 dev->id, &dev->mem_reentrancy_guard, s); 736 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); 737 738 if (USE_TIMER) { 739 s->flush_queue_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 740 i82596_flush_queue_timer, s); 741 } 742 s->lnkst = 0x8000; /* initial link state: up */ 743 } 744