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