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