ns_gige.cc revision 11299:72046b9b3323
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 * Lisa Hsu 30 */ 31 32/** @file 33 * Device module for modelling the National Semiconductor 34 * DP83820 ethernet controller. Does not support priority queueing 35 */ 36 37#include "dev/net/ns_gige.hh" 38 39#include <deque> 40#include <memory> 41#include <string> 42 43#include "base/debug.hh" 44#include "base/inet.hh" 45#include "base/types.hh" 46#include "config/the_isa.hh" 47#include "debug/EthernetAll.hh" 48#include "dev/net/etherlink.hh" 49#include "mem/packet.hh" 50#include "mem/packet_access.hh" 51#include "params/NSGigE.hh" 52#include "sim/system.hh" 53 54// clang complains about std::set being overloaded with Packet::set if 55// we open up the entire namespace std 56using std::make_shared; 57using std::min; 58using std::ostream; 59using std::string; 60 61const char *NsRxStateStrings[] = 62{ 63 "rxIdle", 64 "rxDescRefr", 65 "rxDescRead", 66 "rxFifoBlock", 67 "rxFragWrite", 68 "rxDescWrite", 69 "rxAdvance" 70}; 71 72const char *NsTxStateStrings[] = 73{ 74 "txIdle", 75 "txDescRefr", 76 "txDescRead", 77 "txFifoBlock", 78 "txFragRead", 79 "txDescWrite", 80 "txAdvance" 81}; 82 83const char *NsDmaState[] = 84{ 85 "dmaIdle", 86 "dmaReading", 87 "dmaWriting", 88 "dmaReadWaiting", 89 "dmaWriteWaiting" 90}; 91 92using namespace Net; 93using namespace TheISA; 94 95/////////////////////////////////////////////////////////////////////// 96// 97// NSGigE PCI Device 98// 99NSGigE::NSGigE(Params *p) 100 : EtherDevBase(p), ioEnable(false), 101 txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), 102 txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), 103 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false), 104 txState(txIdle), txEnable(false), CTDD(false), txHalt(false), 105 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), 106 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false), 107 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), 108 eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0), 109 eepromOpcode(0), eepromAddress(0), eepromData(0), 110 dmaReadDelay(p->dma_read_delay), dmaWriteDelay(p->dma_write_delay), 111 dmaReadFactor(p->dma_read_factor), dmaWriteFactor(p->dma_write_factor), 112 rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0), 113 txDmaData(NULL), txDmaAddr(0), txDmaLen(0), 114 rxDmaReadEvent(this), rxDmaWriteEvent(this), 115 txDmaReadEvent(this), txDmaWriteEvent(this), 116 dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free), 117 txDelay(p->tx_delay), rxDelay(p->rx_delay), 118 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this), 119 txEvent(this), rxFilterEnable(p->rx_filter), 120 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false), 121 acceptPerfect(false), acceptArp(false), multicastHashEnable(false), 122 intrDelay(p->intr_delay), intrTick(0), cpuPendingIntr(false), 123 intrEvent(0), interface(0) 124{ 125 126 127 interface = new NSGigEInt(name() + ".int0", this); 128 129 regsReset(); 130 memcpy(&rom.perfectMatch, p->hardware_address.bytes(), ETH_ADDR_LEN); 131 132 memset(&rxDesc32, 0, sizeof(rxDesc32)); 133 memset(&txDesc32, 0, sizeof(txDesc32)); 134 memset(&rxDesc64, 0, sizeof(rxDesc64)); 135 memset(&txDesc64, 0, sizeof(txDesc64)); 136} 137 138NSGigE::~NSGigE() 139{ 140 delete interface; 141} 142 143/** 144 * This is to write to the PCI general configuration registers 145 */ 146Tick 147NSGigE::writeConfig(PacketPtr pkt) 148{ 149 int offset = pkt->getAddr() & PCI_CONFIG_SIZE; 150 if (offset < PCI_DEVICE_SPECIFIC) 151 PciDevice::writeConfig(pkt); 152 else 153 panic("Device specific PCI config space not implemented!\n"); 154 155 switch (offset) { 156 // seems to work fine without all these PCI settings, but i 157 // put in the IO to double check, an assertion will fail if we 158 // need to properly implement it 159 case PCI_COMMAND: 160 if (config.data[offset] & PCI_CMD_IOSE) 161 ioEnable = true; 162 else 163 ioEnable = false; 164 break; 165 } 166 167 return configDelay; 168} 169 170EtherInt* 171NSGigE::getEthPort(const std::string &if_name, int idx) 172{ 173 if (if_name == "interface") { 174 if (interface->getPeer()) 175 panic("interface already connected to\n"); 176 return interface; 177 } 178 return NULL; 179} 180 181/** 182 * This reads the device registers, which are detailed in the NS83820 183 * spec sheet 184 */ 185Tick 186NSGigE::read(PacketPtr pkt) 187{ 188 assert(ioEnable); 189 190 //The mask is to give you only the offset into the device register file 191 Addr daddr = pkt->getAddr() & 0xfff; 192 DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n", 193 daddr, pkt->getAddr(), pkt->getSize()); 194 195 196 // there are some reserved registers, you can see ns_gige_reg.h and 197 // the spec sheet for details 198 if (daddr > LAST && daddr <= RESERVED) { 199 panic("Accessing reserved register"); 200 } else if (daddr > RESERVED && daddr <= 0x3FC) { 201 return readConfig(pkt); 202 } else if (daddr >= MIB_START && daddr <= MIB_END) { 203 // don't implement all the MIB's. hopefully the kernel 204 // doesn't actually DEPEND upon their values 205 // MIB are just hardware stats keepers 206 pkt->set<uint32_t>(0); 207 pkt->makeAtomicResponse(); 208 return pioDelay; 209 } else if (daddr > 0x3FC) 210 panic("Something is messed up!\n"); 211 212 assert(pkt->getSize() == sizeof(uint32_t)); 213 uint32_t ® = *pkt->getPtr<uint32_t>(); 214 uint16_t rfaddr; 215 216 switch (daddr) { 217 case CR: 218 reg = regs.command; 219 //these are supposed to be cleared on a read 220 reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); 221 break; 222 223 case CFGR: 224 reg = regs.config; 225 break; 226 227 case MEAR: 228 reg = regs.mear; 229 break; 230 231 case PTSCR: 232 reg = regs.ptscr; 233 break; 234 235 case ISR: 236 reg = regs.isr; 237 devIntrClear(ISR_ALL); 238 break; 239 240 case IMR: 241 reg = regs.imr; 242 break; 243 244 case IER: 245 reg = regs.ier; 246 break; 247 248 case IHR: 249 reg = regs.ihr; 250 break; 251 252 case TXDP: 253 reg = regs.txdp; 254 break; 255 256 case TXDP_HI: 257 reg = regs.txdp_hi; 258 break; 259 260 case TX_CFG: 261 reg = regs.txcfg; 262 break; 263 264 case GPIOR: 265 reg = regs.gpior; 266 break; 267 268 case RXDP: 269 reg = regs.rxdp; 270 break; 271 272 case RXDP_HI: 273 reg = regs.rxdp_hi; 274 break; 275 276 case RX_CFG: 277 reg = regs.rxcfg; 278 break; 279 280 case PQCR: 281 reg = regs.pqcr; 282 break; 283 284 case WCSR: 285 reg = regs.wcsr; 286 break; 287 288 case PCR: 289 reg = regs.pcr; 290 break; 291 292 // see the spec sheet for how RFCR and RFDR work 293 // basically, you write to RFCR to tell the machine 294 // what you want to do next, then you act upon RFDR, 295 // and the device will be prepared b/c of what you 296 // wrote to RFCR 297 case RFCR: 298 reg = regs.rfcr; 299 break; 300 301 case RFDR: 302 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 303 switch (rfaddr) { 304 // Read from perfect match ROM octets 305 case 0x000: 306 reg = rom.perfectMatch[1]; 307 reg = reg << 8; 308 reg += rom.perfectMatch[0]; 309 break; 310 case 0x002: 311 reg = rom.perfectMatch[3] << 8; 312 reg += rom.perfectMatch[2]; 313 break; 314 case 0x004: 315 reg = rom.perfectMatch[5] << 8; 316 reg += rom.perfectMatch[4]; 317 break; 318 default: 319 // Read filter hash table 320 if (rfaddr >= FHASH_ADDR && 321 rfaddr < FHASH_ADDR + FHASH_SIZE) { 322 323 // Only word-aligned reads supported 324 if (rfaddr % 2) 325 panic("unaligned read from filter hash table!"); 326 327 reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; 328 reg += rom.filterHash[rfaddr - FHASH_ADDR]; 329 break; 330 } 331 332 panic("reading RFDR for something other than pattern" 333 " matching or hashing! %#x\n", rfaddr); 334 } 335 break; 336 337 case SRR: 338 reg = regs.srr; 339 break; 340 341 case MIBC: 342 reg = regs.mibc; 343 reg &= ~(MIBC_MIBS | MIBC_ACLR); 344 break; 345 346 case VRCR: 347 reg = regs.vrcr; 348 break; 349 350 case VTCR: 351 reg = regs.vtcr; 352 break; 353 354 case VDR: 355 reg = regs.vdr; 356 break; 357 358 case CCSR: 359 reg = regs.ccsr; 360 break; 361 362 case TBICR: 363 reg = regs.tbicr; 364 break; 365 366 case TBISR: 367 reg = regs.tbisr; 368 break; 369 370 case TANAR: 371 reg = regs.tanar; 372 break; 373 374 case TANLPAR: 375 reg = regs.tanlpar; 376 break; 377 378 case TANER: 379 reg = regs.taner; 380 break; 381 382 case TESR: 383 reg = regs.tesr; 384 break; 385 386 case M5REG: 387 reg = 0; 388 if (params()->rx_thread) 389 reg |= M5REG_RX_THREAD; 390 if (params()->tx_thread) 391 reg |= M5REG_TX_THREAD; 392 if (params()->rss) 393 reg |= M5REG_RSS; 394 break; 395 396 default: 397 panic("reading unimplemented register: addr=%#x", daddr); 398 } 399 400 DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", 401 daddr, reg, reg); 402 403 pkt->makeAtomicResponse(); 404 return pioDelay; 405} 406 407Tick 408NSGigE::write(PacketPtr pkt) 409{ 410 assert(ioEnable); 411 412 Addr daddr = pkt->getAddr() & 0xfff; 413 DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", 414 daddr, pkt->getAddr(), pkt->getSize()); 415 416 if (daddr > LAST && daddr <= RESERVED) { 417 panic("Accessing reserved register"); 418 } else if (daddr > RESERVED && daddr <= 0x3FC) { 419 return writeConfig(pkt); 420 } else if (daddr > 0x3FC) 421 panic("Something is messed up!\n"); 422 423 if (pkt->getSize() == sizeof(uint32_t)) { 424 uint32_t reg = pkt->get<uint32_t>(); 425 uint16_t rfaddr; 426 427 DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg); 428 429 switch (daddr) { 430 case CR: 431 regs.command = reg; 432 if (reg & CR_TXD) { 433 txEnable = false; 434 } else if (reg & CR_TXE) { 435 txEnable = true; 436 437 // the kernel is enabling the transmit machine 438 if (txState == txIdle) 439 txKick(); 440 } 441 442 if (reg & CR_RXD) { 443 rxEnable = false; 444 } else if (reg & CR_RXE) { 445 rxEnable = true; 446 447 if (rxState == rxIdle) 448 rxKick(); 449 } 450 451 if (reg & CR_TXR) 452 txReset(); 453 454 if (reg & CR_RXR) 455 rxReset(); 456 457 if (reg & CR_SWI) 458 devIntrPost(ISR_SWI); 459 460 if (reg & CR_RST) { 461 txReset(); 462 rxReset(); 463 464 regsReset(); 465 } 466 break; 467 468 case CFGR: 469 if (reg & CFGR_LNKSTS || 470 reg & CFGR_SPDSTS || 471 reg & CFGR_DUPSTS || 472 reg & CFGR_RESERVED || 473 reg & CFGR_T64ADDR || 474 reg & CFGR_PCI64_DET) { 475 // First clear all writable bits 476 regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | 477 CFGR_RESERVED | CFGR_T64ADDR | 478 CFGR_PCI64_DET; 479 // Now set the appropriate writable bits 480 regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | 481 CFGR_RESERVED | CFGR_T64ADDR | 482 CFGR_PCI64_DET); 483 } 484 485// all these #if 0's are because i don't THINK the kernel needs to 486// have these implemented. if there is a problem relating to one of 487// these, you may need to add functionality in. 488 489// grouped together and #if 0'ed to avoid empty if body and make clang happy 490#if 0 491 if (reg & CFGR_TBI_EN) ; 492 if (reg & CFGR_MODE_1000) ; 493 494 if (reg & CFGR_PINT_DUPSTS || 495 reg & CFGR_PINT_LNKSTS || 496 reg & CFGR_PINT_SPDSTS) 497 ; 498 499 if (reg & CFGR_TMRTEST) ; 500 if (reg & CFGR_MRM_DIS) ; 501 if (reg & CFGR_MWI_DIS) ; 502 503 if (reg & CFGR_DATA64_EN) ; 504 if (reg & CFGR_M64ADDR) ; 505 if (reg & CFGR_PHY_RST) ; 506 if (reg & CFGR_PHY_DIS) ; 507 508 if (reg & CFGR_REQALG) ; 509 if (reg & CFGR_SB) ; 510 if (reg & CFGR_POW) ; 511 if (reg & CFGR_EXD) ; 512 if (reg & CFGR_PESEL) ; 513 if (reg & CFGR_BROM_DIS) ; 514 if (reg & CFGR_EXT_125) ; 515 if (reg & CFGR_BEM) ; 516 517 if (reg & CFGR_T64ADDR) ; 518 // panic("CFGR_T64ADDR is read only register!\n"); 519#endif 520 if (reg & CFGR_AUTO_1000) 521 panic("CFGR_AUTO_1000 not implemented!\n"); 522 523 if (reg & CFGR_PCI64_DET) 524 panic("CFGR_PCI64_DET is read only register!\n"); 525 526 if (reg & CFGR_EXTSTS_EN) 527 extstsEnable = true; 528 else 529 extstsEnable = false; 530 break; 531 532 case MEAR: 533 // Clear writable bits 534 regs.mear &= MEAR_EEDO; 535 // Set appropriate writable bits 536 regs.mear |= reg & ~MEAR_EEDO; 537 538 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address) 539 // even though it could get it through RFDR 540 if (reg & MEAR_EESEL) { 541 // Rising edge of clock 542 if (reg & MEAR_EECLK && !eepromClk) 543 eepromKick(); 544 } 545 else { 546 eepromState = eepromStart; 547 regs.mear &= ~MEAR_EEDI; 548 } 549 550 eepromClk = reg & MEAR_EECLK; 551 552 // since phy is completely faked, MEAR_MD* don't matter 553 554// grouped together and #if 0'ed to avoid empty if body and make clang happy 555#if 0 556 if (reg & MEAR_MDIO) ; 557 if (reg & MEAR_MDDIR) ; 558 if (reg & MEAR_MDC) ; 559#endif 560 break; 561 562 case PTSCR: 563 regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY); 564 // these control BISTs for various parts of chip - we 565 // don't care or do just fake that the BIST is done 566 if (reg & PTSCR_RBIST_EN) 567 regs.ptscr |= PTSCR_RBIST_DONE; 568 if (reg & PTSCR_EEBIST_EN) 569 regs.ptscr &= ~PTSCR_EEBIST_EN; 570 if (reg & PTSCR_EELOAD_EN) 571 regs.ptscr &= ~PTSCR_EELOAD_EN; 572 break; 573 574 case ISR: /* writing to the ISR has no effect */ 575 panic("ISR is a read only register!\n"); 576 577 case IMR: 578 regs.imr = reg; 579 devIntrChangeMask(); 580 break; 581 582 case IER: 583 regs.ier = reg; 584 break; 585 586 case IHR: 587 regs.ihr = reg; 588 /* not going to implement real interrupt holdoff */ 589 break; 590 591 case TXDP: 592 regs.txdp = (reg & 0xFFFFFFFC); 593 assert(txState == txIdle); 594 CTDD = false; 595 break; 596 597 case TXDP_HI: 598 regs.txdp_hi = reg; 599 break; 600 601 case TX_CFG: 602 regs.txcfg = reg; 603#if 0 604 if (reg & TX_CFG_CSI) ; 605 if (reg & TX_CFG_HBI) ; 606 if (reg & TX_CFG_MLB) ; 607 if (reg & TX_CFG_ATP) ; 608 if (reg & TX_CFG_ECRETRY) { 609 /* 610 * this could easily be implemented, but considering 611 * the network is just a fake pipe, wouldn't make 612 * sense to do this 613 */ 614 } 615 616 if (reg & TX_CFG_BRST_DIS) ; 617#endif 618 619#if 0 620 /* we handle our own DMA, ignore the kernel's exhortations */ 621 if (reg & TX_CFG_MXDMA) ; 622#endif 623 624 // also, we currently don't care about fill/drain 625 // thresholds though this may change in the future with 626 // more realistic networks or a driver which changes it 627 // according to feedback 628 629 break; 630 631 case GPIOR: 632 // Only write writable bits 633 regs.gpior &= GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN 634 | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN; 635 regs.gpior |= reg & ~(GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN 636 | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN); 637 /* these just control general purpose i/o pins, don't matter */ 638 break; 639 640 case RXDP: 641 regs.rxdp = reg; 642 CRDD = false; 643 break; 644 645 case RXDP_HI: 646 regs.rxdp_hi = reg; 647 break; 648 649 case RX_CFG: 650 regs.rxcfg = reg; 651#if 0 652 if (reg & RX_CFG_AEP) ; 653 if (reg & RX_CFG_ARP) ; 654 if (reg & RX_CFG_STRIPCRC) ; 655 if (reg & RX_CFG_RX_RD) ; 656 if (reg & RX_CFG_ALP) ; 657 if (reg & RX_CFG_AIRL) ; 658 659 /* we handle our own DMA, ignore what kernel says about it */ 660 if (reg & RX_CFG_MXDMA) ; 661 662 //also, we currently don't care about fill/drain thresholds 663 //though this may change in the future with more realistic 664 //networks or a driver which changes it according to feedback 665 if (reg & (RX_CFG_DRTH | RX_CFG_DRTH0)) ; 666#endif 667 break; 668 669 case PQCR: 670 /* there is no priority queueing used in the linux 2.6 driver */ 671 regs.pqcr = reg; 672 break; 673 674 case WCSR: 675 /* not going to implement wake on LAN */ 676 regs.wcsr = reg; 677 break; 678 679 case PCR: 680 /* not going to implement pause control */ 681 regs.pcr = reg; 682 break; 683 684 case RFCR: 685 regs.rfcr = reg; 686 687 rxFilterEnable = (reg & RFCR_RFEN) ? true : false; 688 acceptBroadcast = (reg & RFCR_AAB) ? true : false; 689 acceptMulticast = (reg & RFCR_AAM) ? true : false; 690 acceptUnicast = (reg & RFCR_AAU) ? true : false; 691 acceptPerfect = (reg & RFCR_APM) ? true : false; 692 acceptArp = (reg & RFCR_AARP) ? true : false; 693 multicastHashEnable = (reg & RFCR_MHEN) ? true : false; 694 695#if 0 696 if (reg & RFCR_APAT) 697 panic("RFCR_APAT not implemented!\n"); 698#endif 699 if (reg & RFCR_UHEN) 700 panic("Unicast hash filtering not used by drivers!\n"); 701 702 if (reg & RFCR_ULM) 703 panic("RFCR_ULM not implemented!\n"); 704 705 break; 706 707 case RFDR: 708 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 709 switch (rfaddr) { 710 case 0x000: 711 rom.perfectMatch[0] = (uint8_t)reg; 712 rom.perfectMatch[1] = (uint8_t)(reg >> 8); 713 break; 714 case 0x002: 715 rom.perfectMatch[2] = (uint8_t)reg; 716 rom.perfectMatch[3] = (uint8_t)(reg >> 8); 717 break; 718 case 0x004: 719 rom.perfectMatch[4] = (uint8_t)reg; 720 rom.perfectMatch[5] = (uint8_t)(reg >> 8); 721 break; 722 default: 723 724 if (rfaddr >= FHASH_ADDR && 725 rfaddr < FHASH_ADDR + FHASH_SIZE) { 726 727 // Only word-aligned writes supported 728 if (rfaddr % 2) 729 panic("unaligned write to filter hash table!"); 730 731 rom.filterHash[rfaddr - FHASH_ADDR] = (uint8_t)reg; 732 rom.filterHash[rfaddr - FHASH_ADDR + 1] 733 = (uint8_t)(reg >> 8); 734 break; 735 } 736 panic("writing RFDR for something other than pattern matching " 737 "or hashing! %#x\n", rfaddr); 738 } 739 740 case BRAR: 741 regs.brar = reg; 742 break; 743 744 case BRDR: 745 panic("the driver never uses BRDR, something is wrong!\n"); 746 747 case SRR: 748 panic("SRR is read only register!\n"); 749 750 case MIBC: 751 panic("the driver never uses MIBC, something is wrong!\n"); 752 753 case VRCR: 754 regs.vrcr = reg; 755 break; 756 757 case VTCR: 758 regs.vtcr = reg; 759 break; 760 761 case VDR: 762 panic("the driver never uses VDR, something is wrong!\n"); 763 764 case CCSR: 765 /* not going to implement clockrun stuff */ 766 regs.ccsr = reg; 767 break; 768 769 case TBICR: 770 regs.tbicr = reg; 771 if (reg & TBICR_MR_LOOPBACK) 772 panic("TBICR_MR_LOOPBACK never used, something wrong!\n"); 773 774 if (reg & TBICR_MR_AN_ENABLE) { 775 regs.tanlpar = regs.tanar; 776 regs.tbisr |= (TBISR_MR_AN_COMPLETE | TBISR_MR_LINK_STATUS); 777 } 778 779#if 0 780 if (reg & TBICR_MR_RESTART_AN) ; 781#endif 782 783 break; 784 785 case TBISR: 786 panic("TBISR is read only register!\n"); 787 788 case TANAR: 789 // Only write the writable bits 790 regs.tanar &= TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED; 791 regs.tanar |= reg & ~(TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED); 792 793 // Pause capability unimplemented 794#if 0 795 if (reg & TANAR_PS2) ; 796 if (reg & TANAR_PS1) ; 797#endif 798 799 break; 800 801 case TANLPAR: 802 panic("this should only be written to by the fake phy!\n"); 803 804 case TANER: 805 panic("TANER is read only register!\n"); 806 807 case TESR: 808 regs.tesr = reg; 809 break; 810 811 default: 812 panic("invalid register access daddr=%#x", daddr); 813 } 814 } else { 815 panic("Invalid Request Size"); 816 } 817 pkt->makeAtomicResponse(); 818 return pioDelay; 819} 820 821void 822NSGigE::devIntrPost(uint32_t interrupts) 823{ 824 if (interrupts & ISR_RESERVE) 825 panic("Cannot set a reserved interrupt"); 826 827 if (interrupts & ISR_NOIMPL) 828 warn("interrupt not implemented %#x\n", interrupts); 829 830 interrupts &= ISR_IMPL; 831 regs.isr |= interrupts; 832 833 if (interrupts & regs.imr) { 834 if (interrupts & ISR_SWI) { 835 totalSwi++; 836 } 837 if (interrupts & ISR_RXIDLE) { 838 totalRxIdle++; 839 } 840 if (interrupts & ISR_RXOK) { 841 totalRxOk++; 842 } 843 if (interrupts & ISR_RXDESC) { 844 totalRxDesc++; 845 } 846 if (interrupts & ISR_TXOK) { 847 totalTxOk++; 848 } 849 if (interrupts & ISR_TXIDLE) { 850 totalTxIdle++; 851 } 852 if (interrupts & ISR_TXDESC) { 853 totalTxDesc++; 854 } 855 if (interrupts & ISR_RXORN) { 856 totalRxOrn++; 857 } 858 } 859 860 DPRINTF(EthernetIntr, 861 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n", 862 interrupts, regs.isr, regs.imr); 863 864 if ((regs.isr & regs.imr)) { 865 Tick when = curTick(); 866 if ((regs.isr & regs.imr & ISR_NODELAY) == 0) 867 when += intrDelay; 868 postedInterrupts++; 869 cpuIntrPost(when); 870 } 871} 872 873/* writing this interrupt counting stats inside this means that this function 874 is now limited to being used to clear all interrupts upon the kernel 875 reading isr and servicing. just telling you in case you were thinking 876 of expanding use. 877*/ 878void 879NSGigE::devIntrClear(uint32_t interrupts) 880{ 881 if (interrupts & ISR_RESERVE) 882 panic("Cannot clear a reserved interrupt"); 883 884 if (regs.isr & regs.imr & ISR_SWI) { 885 postedSwi++; 886 } 887 if (regs.isr & regs.imr & ISR_RXIDLE) { 888 postedRxIdle++; 889 } 890 if (regs.isr & regs.imr & ISR_RXOK) { 891 postedRxOk++; 892 } 893 if (regs.isr & regs.imr & ISR_RXDESC) { 894 postedRxDesc++; 895 } 896 if (regs.isr & regs.imr & ISR_TXOK) { 897 postedTxOk++; 898 } 899 if (regs.isr & regs.imr & ISR_TXIDLE) { 900 postedTxIdle++; 901 } 902 if (regs.isr & regs.imr & ISR_TXDESC) { 903 postedTxDesc++; 904 } 905 if (regs.isr & regs.imr & ISR_RXORN) { 906 postedRxOrn++; 907 } 908 909 interrupts &= ~ISR_NOIMPL; 910 regs.isr &= ~interrupts; 911 912 DPRINTF(EthernetIntr, 913 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n", 914 interrupts, regs.isr, regs.imr); 915 916 if (!(regs.isr & regs.imr)) 917 cpuIntrClear(); 918} 919 920void 921NSGigE::devIntrChangeMask() 922{ 923 DPRINTF(EthernetIntr, "interrupt mask changed: isr=%x imr=%x masked=%x\n", 924 regs.isr, regs.imr, regs.isr & regs.imr); 925 926 if (regs.isr & regs.imr) 927 cpuIntrPost(curTick()); 928 else 929 cpuIntrClear(); 930} 931 932void 933NSGigE::cpuIntrPost(Tick when) 934{ 935 // If the interrupt you want to post is later than an interrupt 936 // already scheduled, just let it post in the coming one and don't 937 // schedule another. 938 // HOWEVER, must be sure that the scheduled intrTick is in the 939 // future (this was formerly the source of a bug) 940 /** 941 * @todo this warning should be removed and the intrTick code should 942 * be fixed. 943 */ 944 assert(when >= curTick()); 945 assert(intrTick >= curTick() || intrTick == 0); 946 if (when > intrTick && intrTick != 0) { 947 DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n", 948 intrTick); 949 return; 950 } 951 952 intrTick = when; 953 if (intrTick < curTick()) { 954 intrTick = curTick(); 955 } 956 957 DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n", 958 intrTick); 959 960 if (intrEvent) 961 intrEvent->squash(); 962 intrEvent = new IntrEvent(this, true); 963 schedule(intrEvent, intrTick); 964} 965 966void 967NSGigE::cpuInterrupt() 968{ 969 assert(intrTick == curTick()); 970 971 // Whether or not there's a pending interrupt, we don't care about 972 // it anymore 973 intrEvent = 0; 974 intrTick = 0; 975 976 // Don't send an interrupt if there's already one 977 if (cpuPendingIntr) { 978 DPRINTF(EthernetIntr, 979 "would send an interrupt now, but there's already pending\n"); 980 } else { 981 // Send interrupt 982 cpuPendingIntr = true; 983 984 DPRINTF(EthernetIntr, "posting interrupt\n"); 985 intrPost(); 986 } 987} 988 989void 990NSGigE::cpuIntrClear() 991{ 992 if (!cpuPendingIntr) 993 return; 994 995 if (intrEvent) { 996 intrEvent->squash(); 997 intrEvent = 0; 998 } 999 1000 intrTick = 0; 1001 1002 cpuPendingIntr = false; 1003 1004 DPRINTF(EthernetIntr, "clearing interrupt\n"); 1005 intrClear(); 1006} 1007 1008bool 1009NSGigE::cpuIntrPending() const 1010{ return cpuPendingIntr; } 1011 1012void 1013NSGigE::txReset() 1014{ 1015 1016 DPRINTF(Ethernet, "transmit reset\n"); 1017 1018 CTDD = false; 1019 txEnable = false;; 1020 txFragPtr = 0; 1021 assert(txDescCnt == 0); 1022 txFifo.clear(); 1023 txState = txIdle; 1024 assert(txDmaState == dmaIdle); 1025} 1026 1027void 1028NSGigE::rxReset() 1029{ 1030 DPRINTF(Ethernet, "receive reset\n"); 1031 1032 CRDD = false; 1033 assert(rxPktBytes == 0); 1034 rxEnable = false; 1035 rxFragPtr = 0; 1036 assert(rxDescCnt == 0); 1037 assert(rxDmaState == dmaIdle); 1038 rxFifo.clear(); 1039 rxState = rxIdle; 1040} 1041 1042void 1043NSGigE::regsReset() 1044{ 1045 memset(®s, 0, sizeof(regs)); 1046 regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000); 1047 regs.mear = 0x12; 1048 regs.txcfg = 0x120; // set drain threshold to 1024 bytes and 1049 // fill threshold to 32 bytes 1050 regs.rxcfg = 0x4; // set drain threshold to 16 bytes 1051 regs.srr = 0x0103; // set the silicon revision to rev B or 0x103 1052 regs.mibc = MIBC_FRZ; 1053 regs.vdr = 0x81; // set the vlan tag type to 802.1q 1054 regs.tesr = 0xc000; // TBI capable of both full and half duplex 1055 regs.brar = 0xffffffff; 1056 1057 extstsEnable = false; 1058 acceptBroadcast = false; 1059 acceptMulticast = false; 1060 acceptUnicast = false; 1061 acceptPerfect = false; 1062 acceptArp = false; 1063} 1064 1065bool 1066NSGigE::doRxDmaRead() 1067{ 1068 assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); 1069 rxDmaState = dmaReading; 1070 1071 if (dmaPending() || drainState() != DrainState::Running) 1072 rxDmaState = dmaReadWaiting; 1073 else 1074 dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData); 1075 1076 return true; 1077} 1078 1079void 1080NSGigE::rxDmaReadDone() 1081{ 1082 assert(rxDmaState == dmaReading); 1083 rxDmaState = dmaIdle; 1084 1085 DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", 1086 rxDmaAddr, rxDmaLen); 1087 DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 1088 1089 // If the transmit state machine has a pending DMA, let it go first 1090 if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 1091 txKick(); 1092 1093 rxKick(); 1094} 1095 1096bool 1097NSGigE::doRxDmaWrite() 1098{ 1099 assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); 1100 rxDmaState = dmaWriting; 1101 1102 if (dmaPending() || drainState() != DrainState::Running) 1103 rxDmaState = dmaWriteWaiting; 1104 else 1105 dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData); 1106 return true; 1107} 1108 1109void 1110NSGigE::rxDmaWriteDone() 1111{ 1112 assert(rxDmaState == dmaWriting); 1113 rxDmaState = dmaIdle; 1114 1115 DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", 1116 rxDmaAddr, rxDmaLen); 1117 DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 1118 1119 // If the transmit state machine has a pending DMA, let it go first 1120 if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 1121 txKick(); 1122 1123 rxKick(); 1124} 1125 1126void 1127NSGigE::rxKick() 1128{ 1129 bool is64bit = (bool)(regs.config & CFGR_M64ADDR); 1130 1131 DPRINTF(EthernetSM, 1132 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n", 1133 NsRxStateStrings[rxState], rxFifo.size(), is64bit ? 64 : 32); 1134 1135 Addr link, bufptr; 1136 uint32_t &cmdsts = is64bit ? rxDesc64.cmdsts : rxDesc32.cmdsts; 1137 uint32_t &extsts = is64bit ? rxDesc64.extsts : rxDesc32.extsts; 1138 1139 next: 1140 if (rxKickTick > curTick()) { 1141 DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n", 1142 rxKickTick); 1143 1144 goto exit; 1145 } 1146 1147 // Go to the next state machine clock tick. 1148 rxKickTick = clockEdge(Cycles(1)); 1149 1150 switch(rxDmaState) { 1151 case dmaReadWaiting: 1152 if (doRxDmaRead()) 1153 goto exit; 1154 break; 1155 case dmaWriteWaiting: 1156 if (doRxDmaWrite()) 1157 goto exit; 1158 break; 1159 default: 1160 break; 1161 } 1162 1163 link = is64bit ? (Addr)rxDesc64.link : (Addr)rxDesc32.link; 1164 bufptr = is64bit ? (Addr)rxDesc64.bufptr : (Addr)rxDesc32.bufptr; 1165 1166 // see state machine from spec for details 1167 // the way this works is, if you finish work on one state and can 1168 // go directly to another, you do that through jumping to the 1169 // label "next". however, if you have intermediate work, like DMA 1170 // so that you can't go to the next state yet, you go to exit and 1171 // exit the loop. however, when the DMA is done it will trigger 1172 // an event and come back to this loop. 1173 switch (rxState) { 1174 case rxIdle: 1175 if (!rxEnable) { 1176 DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n"); 1177 goto exit; 1178 } 1179 1180 if (CRDD) { 1181 rxState = rxDescRefr; 1182 1183 rxDmaAddr = regs.rxdp & 0x3fffffff; 1184 rxDmaData = 1185 is64bit ? (void *)&rxDesc64.link : (void *)&rxDesc32.link; 1186 rxDmaLen = is64bit ? sizeof(rxDesc64.link) : sizeof(rxDesc32.link); 1187 rxDmaFree = dmaDescFree; 1188 1189 descDmaReads++; 1190 descDmaRdBytes += rxDmaLen; 1191 1192 if (doRxDmaRead()) 1193 goto exit; 1194 } else { 1195 rxState = rxDescRead; 1196 1197 rxDmaAddr = regs.rxdp & 0x3fffffff; 1198 rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32; 1199 rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32); 1200 rxDmaFree = dmaDescFree; 1201 1202 descDmaReads++; 1203 descDmaRdBytes += rxDmaLen; 1204 1205 if (doRxDmaRead()) 1206 goto exit; 1207 } 1208 break; 1209 1210 case rxDescRefr: 1211 if (rxDmaState != dmaIdle) 1212 goto exit; 1213 1214 rxState = rxAdvance; 1215 break; 1216 1217 case rxDescRead: 1218 if (rxDmaState != dmaIdle) 1219 goto exit; 1220 1221 DPRINTF(EthernetDesc, "rxDesc: addr=%08x read descriptor\n", 1222 regs.rxdp & 0x3fffffff); 1223 DPRINTF(EthernetDesc, 1224 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n", 1225 link, bufptr, cmdsts, extsts); 1226 1227 if (cmdsts & CMDSTS_OWN) { 1228 devIntrPost(ISR_RXIDLE); 1229 rxState = rxIdle; 1230 goto exit; 1231 } else { 1232 rxState = rxFifoBlock; 1233 rxFragPtr = bufptr; 1234 rxDescCnt = cmdsts & CMDSTS_LEN_MASK; 1235 } 1236 break; 1237 1238 case rxFifoBlock: 1239 if (!rxPacket) { 1240 /** 1241 * @todo in reality, we should be able to start processing 1242 * the packet as it arrives, and not have to wait for the 1243 * full packet ot be in the receive fifo. 1244 */ 1245 if (rxFifo.empty()) 1246 goto exit; 1247 1248 DPRINTF(EthernetSM, "****processing receive of new packet****\n"); 1249 1250 // If we don't have a packet, grab a new one from the fifo. 1251 rxPacket = rxFifo.front(); 1252 rxPktBytes = rxPacket->length; 1253 rxPacketBufPtr = rxPacket->data; 1254 1255#if TRACING_ON 1256 if (DTRACE(Ethernet)) { 1257 IpPtr ip(rxPacket); 1258 if (ip) { 1259 DPRINTF(Ethernet, "ID is %d\n", ip->id()); 1260 TcpPtr tcp(ip); 1261 if (tcp) { 1262 DPRINTF(Ethernet, 1263 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", 1264 tcp->sport(), tcp->dport(), tcp->seq(), 1265 tcp->ack()); 1266 } 1267 } 1268 } 1269#endif 1270 1271 // sanity check - i think the driver behaves like this 1272 assert(rxDescCnt >= rxPktBytes); 1273 rxFifo.pop(); 1274 } 1275 1276 1277 // dont' need the && rxDescCnt > 0 if driver sanity check 1278 // above holds 1279 if (rxPktBytes > 0) { 1280 rxState = rxFragWrite; 1281 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity 1282 // check holds 1283 rxXferLen = rxPktBytes; 1284 1285 rxDmaAddr = rxFragPtr & 0x3fffffff; 1286 rxDmaData = rxPacketBufPtr; 1287 rxDmaLen = rxXferLen; 1288 rxDmaFree = dmaDataFree; 1289 1290 if (doRxDmaWrite()) 1291 goto exit; 1292 1293 } else { 1294 rxState = rxDescWrite; 1295 1296 //if (rxPktBytes == 0) { /* packet is done */ 1297 assert(rxPktBytes == 0); 1298 DPRINTF(EthernetSM, "done with receiving packet\n"); 1299 1300 cmdsts |= CMDSTS_OWN; 1301 cmdsts &= ~CMDSTS_MORE; 1302 cmdsts |= CMDSTS_OK; 1303 cmdsts &= 0xffff0000; 1304 cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE 1305 1306#if 0 1307 /* 1308 * all the driver uses these are for its own stats keeping 1309 * which we don't care about, aren't necessary for 1310 * functionality and doing this would just slow us down. 1311 * if they end up using this in a later version for 1312 * functional purposes, just undef 1313 */ 1314 if (rxFilterEnable) { 1315 cmdsts &= ~CMDSTS_DEST_MASK; 1316 const EthAddr &dst = rxFifoFront()->dst(); 1317 if (dst->unicast()) 1318 cmdsts |= CMDSTS_DEST_SELF; 1319 if (dst->multicast()) 1320 cmdsts |= CMDSTS_DEST_MULTI; 1321 if (dst->broadcast()) 1322 cmdsts |= CMDSTS_DEST_MASK; 1323 } 1324#endif 1325 1326 IpPtr ip(rxPacket); 1327 if (extstsEnable && ip) { 1328 extsts |= EXTSTS_IPPKT; 1329 rxIpChecksums++; 1330 if (cksum(ip) != 0) { 1331 DPRINTF(EthernetCksum, "Rx IP Checksum Error\n"); 1332 extsts |= EXTSTS_IPERR; 1333 } 1334 TcpPtr tcp(ip); 1335 UdpPtr udp(ip); 1336 if (tcp) { 1337 extsts |= EXTSTS_TCPPKT; 1338 rxTcpChecksums++; 1339 if (cksum(tcp) != 0) { 1340 DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n"); 1341 extsts |= EXTSTS_TCPERR; 1342 1343 } 1344 } else if (udp) { 1345 extsts |= EXTSTS_UDPPKT; 1346 rxUdpChecksums++; 1347 if (cksum(udp) != 0) { 1348 DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n"); 1349 extsts |= EXTSTS_UDPERR; 1350 } 1351 } 1352 } 1353 rxPacket = 0; 1354 1355 /* 1356 * the driver seems to always receive into desc buffers 1357 * of size 1514, so you never have a pkt that is split 1358 * into multiple descriptors on the receive side, so 1359 * i don't implement that case, hence the assert above. 1360 */ 1361 1362 DPRINTF(EthernetDesc, 1363 "rxDesc: addr=%08x writeback cmdsts extsts\n", 1364 regs.rxdp & 0x3fffffff); 1365 DPRINTF(EthernetDesc, 1366 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n", 1367 link, bufptr, cmdsts, extsts); 1368 1369 rxDmaAddr = regs.rxdp & 0x3fffffff; 1370 rxDmaData = &cmdsts; 1371 if (is64bit) { 1372 rxDmaAddr += offsetof(ns_desc64, cmdsts); 1373 rxDmaLen = sizeof(rxDesc64.cmdsts) + sizeof(rxDesc64.extsts); 1374 } else { 1375 rxDmaAddr += offsetof(ns_desc32, cmdsts); 1376 rxDmaLen = sizeof(rxDesc32.cmdsts) + sizeof(rxDesc32.extsts); 1377 } 1378 rxDmaFree = dmaDescFree; 1379 1380 descDmaWrites++; 1381 descDmaWrBytes += rxDmaLen; 1382 1383 if (doRxDmaWrite()) 1384 goto exit; 1385 } 1386 break; 1387 1388 case rxFragWrite: 1389 if (rxDmaState != dmaIdle) 1390 goto exit; 1391 1392 rxPacketBufPtr += rxXferLen; 1393 rxFragPtr += rxXferLen; 1394 rxPktBytes -= rxXferLen; 1395 1396 rxState = rxFifoBlock; 1397 break; 1398 1399 case rxDescWrite: 1400 if (rxDmaState != dmaIdle) 1401 goto exit; 1402 1403 assert(cmdsts & CMDSTS_OWN); 1404 1405 assert(rxPacket == 0); 1406 devIntrPost(ISR_RXOK); 1407 1408 if (cmdsts & CMDSTS_INTR) 1409 devIntrPost(ISR_RXDESC); 1410 1411 if (!rxEnable) { 1412 DPRINTF(EthernetSM, "Halting the RX state machine\n"); 1413 rxState = rxIdle; 1414 goto exit; 1415 } else 1416 rxState = rxAdvance; 1417 break; 1418 1419 case rxAdvance: 1420 if (link == 0) { 1421 devIntrPost(ISR_RXIDLE); 1422 rxState = rxIdle; 1423 CRDD = true; 1424 goto exit; 1425 } else { 1426 if (rxDmaState != dmaIdle) 1427 goto exit; 1428 rxState = rxDescRead; 1429 regs.rxdp = link; 1430 CRDD = false; 1431 1432 rxDmaAddr = regs.rxdp & 0x3fffffff; 1433 rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32; 1434 rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32); 1435 rxDmaFree = dmaDescFree; 1436 1437 if (doRxDmaRead()) 1438 goto exit; 1439 } 1440 break; 1441 1442 default: 1443 panic("Invalid rxState!"); 1444 } 1445 1446 DPRINTF(EthernetSM, "entering next rxState=%s\n", 1447 NsRxStateStrings[rxState]); 1448 goto next; 1449 1450 exit: 1451 /** 1452 * @todo do we want to schedule a future kick? 1453 */ 1454 DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n", 1455 NsRxStateStrings[rxState]); 1456 1457 if (!rxKickEvent.scheduled()) 1458 schedule(rxKickEvent, rxKickTick); 1459} 1460 1461void 1462NSGigE::transmit() 1463{ 1464 if (txFifo.empty()) { 1465 DPRINTF(Ethernet, "nothing to transmit\n"); 1466 return; 1467 } 1468 1469 DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n", 1470 txFifo.size()); 1471 if (interface->sendPacket(txFifo.front())) { 1472#if TRACING_ON 1473 if (DTRACE(Ethernet)) { 1474 IpPtr ip(txFifo.front()); 1475 if (ip) { 1476 DPRINTF(Ethernet, "ID is %d\n", ip->id()); 1477 TcpPtr tcp(ip); 1478 if (tcp) { 1479 DPRINTF(Ethernet, 1480 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", 1481 tcp->sport(), tcp->dport(), tcp->seq(), 1482 tcp->ack()); 1483 } 1484 } 1485 } 1486#endif 1487 1488 DDUMP(EthernetData, txFifo.front()->data, txFifo.front()->length); 1489 txBytes += txFifo.front()->length; 1490 txPackets++; 1491 1492 DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", 1493 txFifo.avail()); 1494 txFifo.pop(); 1495 1496 /* 1497 * normally do a writeback of the descriptor here, and ONLY 1498 * after that is done, send this interrupt. but since our 1499 * stuff never actually fails, just do this interrupt here, 1500 * otherwise the code has to stray from this nice format. 1501 * besides, it's functionally the same. 1502 */ 1503 devIntrPost(ISR_TXOK); 1504 } 1505 1506 if (!txFifo.empty() && !txEvent.scheduled()) { 1507 DPRINTF(Ethernet, "reschedule transmit\n"); 1508 schedule(txEvent, curTick() + retryTime); 1509 } 1510} 1511 1512bool 1513NSGigE::doTxDmaRead() 1514{ 1515 assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); 1516 txDmaState = dmaReading; 1517 1518 if (dmaPending() || drainState() != DrainState::Running) 1519 txDmaState = dmaReadWaiting; 1520 else 1521 dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData); 1522 1523 return true; 1524} 1525 1526void 1527NSGigE::txDmaReadDone() 1528{ 1529 assert(txDmaState == dmaReading); 1530 txDmaState = dmaIdle; 1531 1532 DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", 1533 txDmaAddr, txDmaLen); 1534 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1535 1536 // If the receive state machine has a pending DMA, let it go first 1537 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1538 rxKick(); 1539 1540 txKick(); 1541} 1542 1543bool 1544NSGigE::doTxDmaWrite() 1545{ 1546 assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); 1547 txDmaState = dmaWriting; 1548 1549 if (dmaPending() || drainState() != DrainState::Running) 1550 txDmaState = dmaWriteWaiting; 1551 else 1552 dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData); 1553 return true; 1554} 1555 1556void 1557NSGigE::txDmaWriteDone() 1558{ 1559 assert(txDmaState == dmaWriting); 1560 txDmaState = dmaIdle; 1561 1562 DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", 1563 txDmaAddr, txDmaLen); 1564 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1565 1566 // If the receive state machine has a pending DMA, let it go first 1567 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1568 rxKick(); 1569 1570 txKick(); 1571} 1572 1573void 1574NSGigE::txKick() 1575{ 1576 bool is64bit = (bool)(regs.config & CFGR_M64ADDR); 1577 1578 DPRINTF(EthernetSM, "transmit kick txState=%s %d-bit\n", 1579 NsTxStateStrings[txState], is64bit ? 64 : 32); 1580 1581 Addr link, bufptr; 1582 uint32_t &cmdsts = is64bit ? txDesc64.cmdsts : txDesc32.cmdsts; 1583 uint32_t &extsts = is64bit ? txDesc64.extsts : txDesc32.extsts; 1584 1585 next: 1586 if (txKickTick > curTick()) { 1587 DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n", 1588 txKickTick); 1589 goto exit; 1590 } 1591 1592 // Go to the next state machine clock tick. 1593 txKickTick = clockEdge(Cycles(1)); 1594 1595 switch(txDmaState) { 1596 case dmaReadWaiting: 1597 if (doTxDmaRead()) 1598 goto exit; 1599 break; 1600 case dmaWriteWaiting: 1601 if (doTxDmaWrite()) 1602 goto exit; 1603 break; 1604 default: 1605 break; 1606 } 1607 1608 link = is64bit ? (Addr)txDesc64.link : (Addr)txDesc32.link; 1609 bufptr = is64bit ? (Addr)txDesc64.bufptr : (Addr)txDesc32.bufptr; 1610 switch (txState) { 1611 case txIdle: 1612 if (!txEnable) { 1613 DPRINTF(EthernetSM, "Transmit disabled. Nothing to do.\n"); 1614 goto exit; 1615 } 1616 1617 if (CTDD) { 1618 txState = txDescRefr; 1619 1620 txDmaAddr = regs.txdp & 0x3fffffff; 1621 txDmaData = 1622 is64bit ? (void *)&txDesc64.link : (void *)&txDesc32.link; 1623 txDmaLen = is64bit ? sizeof(txDesc64.link) : sizeof(txDesc32.link); 1624 txDmaFree = dmaDescFree; 1625 1626 descDmaReads++; 1627 descDmaRdBytes += txDmaLen; 1628 1629 if (doTxDmaRead()) 1630 goto exit; 1631 1632 } else { 1633 txState = txDescRead; 1634 1635 txDmaAddr = regs.txdp & 0x3fffffff; 1636 txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32; 1637 txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32); 1638 txDmaFree = dmaDescFree; 1639 1640 descDmaReads++; 1641 descDmaRdBytes += txDmaLen; 1642 1643 if (doTxDmaRead()) 1644 goto exit; 1645 } 1646 break; 1647 1648 case txDescRefr: 1649 if (txDmaState != dmaIdle) 1650 goto exit; 1651 1652 txState = txAdvance; 1653 break; 1654 1655 case txDescRead: 1656 if (txDmaState != dmaIdle) 1657 goto exit; 1658 1659 DPRINTF(EthernetDesc, "txDesc: addr=%08x read descriptor\n", 1660 regs.txdp & 0x3fffffff); 1661 DPRINTF(EthernetDesc, 1662 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n", 1663 link, bufptr, cmdsts, extsts); 1664 1665 if (cmdsts & CMDSTS_OWN) { 1666 txState = txFifoBlock; 1667 txFragPtr = bufptr; 1668 txDescCnt = cmdsts & CMDSTS_LEN_MASK; 1669 } else { 1670 devIntrPost(ISR_TXIDLE); 1671 txState = txIdle; 1672 goto exit; 1673 } 1674 break; 1675 1676 case txFifoBlock: 1677 if (!txPacket) { 1678 DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); 1679 txPacket = make_shared<EthPacketData>(16384); 1680 txPacketBufPtr = txPacket->data; 1681 } 1682 1683 if (txDescCnt == 0) { 1684 DPRINTF(EthernetSM, "the txDescCnt == 0, done with descriptor\n"); 1685 if (cmdsts & CMDSTS_MORE) { 1686 DPRINTF(EthernetSM, "there are more descriptors to come\n"); 1687 txState = txDescWrite; 1688 1689 cmdsts &= ~CMDSTS_OWN; 1690 1691 txDmaAddr = regs.txdp & 0x3fffffff; 1692 txDmaData = &cmdsts; 1693 if (is64bit) { 1694 txDmaAddr += offsetof(ns_desc64, cmdsts); 1695 txDmaLen = sizeof(txDesc64.cmdsts); 1696 } else { 1697 txDmaAddr += offsetof(ns_desc32, cmdsts); 1698 txDmaLen = sizeof(txDesc32.cmdsts); 1699 } 1700 txDmaFree = dmaDescFree; 1701 1702 if (doTxDmaWrite()) 1703 goto exit; 1704 1705 } else { /* this packet is totally done */ 1706 DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n"); 1707 /* deal with the the packet that just finished */ 1708 if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) { 1709 IpPtr ip(txPacket); 1710 if (extsts & EXTSTS_UDPPKT) { 1711 UdpPtr udp(ip); 1712 if (udp) { 1713 udp->sum(0); 1714 udp->sum(cksum(udp)); 1715 txUdpChecksums++; 1716 } else { 1717 Debug::breakpoint(); 1718 warn_once("UDPPKT set, but not UDP!\n"); 1719 } 1720 } else if (extsts & EXTSTS_TCPPKT) { 1721 TcpPtr tcp(ip); 1722 if (tcp) { 1723 tcp->sum(0); 1724 tcp->sum(cksum(tcp)); 1725 txTcpChecksums++; 1726 } else { 1727 warn_once("TCPPKT set, but not UDP!\n"); 1728 } 1729 } 1730 if (extsts & EXTSTS_IPPKT) { 1731 if (ip) { 1732 ip->sum(0); 1733 ip->sum(cksum(ip)); 1734 txIpChecksums++; 1735 } else { 1736 warn_once("IPPKT set, but not UDP!\n"); 1737 } 1738 } 1739 } 1740 1741 txPacket->length = txPacketBufPtr - txPacket->data; 1742 // this is just because the receive can't handle a 1743 // packet bigger want to make sure 1744 if (txPacket->length > 1514) 1745 panic("transmit packet too large, %s > 1514\n", 1746 txPacket->length); 1747 1748#ifndef NDEBUG 1749 bool success = 1750#endif 1751 txFifo.push(txPacket); 1752 assert(success); 1753 1754 /* 1755 * this following section is not tqo spec, but 1756 * functionally shouldn't be any different. normally, 1757 * the chip will wait til the transmit has occurred 1758 * before writing back the descriptor because it has 1759 * to wait to see that it was successfully transmitted 1760 * to decide whether to set CMDSTS_OK or not. 1761 * however, in the simulator since it is always 1762 * successfully transmitted, and writing it exactly to 1763 * spec would complicate the code, we just do it here 1764 */ 1765 1766 cmdsts &= ~CMDSTS_OWN; 1767 cmdsts |= CMDSTS_OK; 1768 1769 DPRINTF(EthernetDesc, 1770 "txDesc writeback: cmdsts=%08x extsts=%08x\n", 1771 cmdsts, extsts); 1772 1773 txDmaFree = dmaDescFree; 1774 txDmaAddr = regs.txdp & 0x3fffffff; 1775 txDmaData = &cmdsts; 1776 if (is64bit) { 1777 txDmaAddr += offsetof(ns_desc64, cmdsts); 1778 txDmaLen = 1779 sizeof(txDesc64.cmdsts) + sizeof(txDesc64.extsts); 1780 } else { 1781 txDmaAddr += offsetof(ns_desc32, cmdsts); 1782 txDmaLen = 1783 sizeof(txDesc32.cmdsts) + sizeof(txDesc32.extsts); 1784 } 1785 1786 descDmaWrites++; 1787 descDmaWrBytes += txDmaLen; 1788 1789 transmit(); 1790 txPacket = 0; 1791 1792 if (!txEnable) { 1793 DPRINTF(EthernetSM, "halting TX state machine\n"); 1794 txState = txIdle; 1795 goto exit; 1796 } else 1797 txState = txAdvance; 1798 1799 if (doTxDmaWrite()) 1800 goto exit; 1801 } 1802 } else { 1803 DPRINTF(EthernetSM, "this descriptor isn't done yet\n"); 1804 if (!txFifo.full()) { 1805 txState = txFragRead; 1806 1807 /* 1808 * The number of bytes transferred is either whatever 1809 * is left in the descriptor (txDescCnt), or if there 1810 * is not enough room in the fifo, just whatever room 1811 * is left in the fifo 1812 */ 1813 txXferLen = min<uint32_t>(txDescCnt, txFifo.avail()); 1814 1815 txDmaAddr = txFragPtr & 0x3fffffff; 1816 txDmaData = txPacketBufPtr; 1817 txDmaLen = txXferLen; 1818 txDmaFree = dmaDataFree; 1819 1820 if (doTxDmaRead()) 1821 goto exit; 1822 } else { 1823 txState = txFifoBlock; 1824 transmit(); 1825 1826 goto exit; 1827 } 1828 1829 } 1830 break; 1831 1832 case txFragRead: 1833 if (txDmaState != dmaIdle) 1834 goto exit; 1835 1836 txPacketBufPtr += txXferLen; 1837 txFragPtr += txXferLen; 1838 txDescCnt -= txXferLen; 1839 txFifo.reserve(txXferLen); 1840 1841 txState = txFifoBlock; 1842 break; 1843 1844 case txDescWrite: 1845 if (txDmaState != dmaIdle) 1846 goto exit; 1847 1848 if (cmdsts & CMDSTS_INTR) 1849 devIntrPost(ISR_TXDESC); 1850 1851 if (!txEnable) { 1852 DPRINTF(EthernetSM, "halting TX state machine\n"); 1853 txState = txIdle; 1854 goto exit; 1855 } else 1856 txState = txAdvance; 1857 break; 1858 1859 case txAdvance: 1860 if (link == 0) { 1861 devIntrPost(ISR_TXIDLE); 1862 txState = txIdle; 1863 goto exit; 1864 } else { 1865 if (txDmaState != dmaIdle) 1866 goto exit; 1867 txState = txDescRead; 1868 regs.txdp = link; 1869 CTDD = false; 1870 1871 txDmaAddr = link & 0x3fffffff; 1872 txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32; 1873 txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32); 1874 txDmaFree = dmaDescFree; 1875 1876 if (doTxDmaRead()) 1877 goto exit; 1878 } 1879 break; 1880 1881 default: 1882 panic("invalid state"); 1883 } 1884 1885 DPRINTF(EthernetSM, "entering next txState=%s\n", 1886 NsTxStateStrings[txState]); 1887 goto next; 1888 1889 exit: 1890 /** 1891 * @todo do we want to schedule a future kick? 1892 */ 1893 DPRINTF(EthernetSM, "tx state machine exited txState=%s\n", 1894 NsTxStateStrings[txState]); 1895 1896 if (!txKickEvent.scheduled()) 1897 schedule(txKickEvent, txKickTick); 1898} 1899 1900/** 1901 * Advance the EEPROM state machine 1902 * Called on rising edge of EEPROM clock bit in MEAR 1903 */ 1904void 1905NSGigE::eepromKick() 1906{ 1907 switch (eepromState) { 1908 1909 case eepromStart: 1910 1911 // Wait for start bit 1912 if (regs.mear & MEAR_EEDI) { 1913 // Set up to get 2 opcode bits 1914 eepromState = eepromGetOpcode; 1915 eepromBitsToRx = 2; 1916 eepromOpcode = 0; 1917 } 1918 break; 1919 1920 case eepromGetOpcode: 1921 eepromOpcode <<= 1; 1922 eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0; 1923 --eepromBitsToRx; 1924 1925 // Done getting opcode 1926 if (eepromBitsToRx == 0) { 1927 if (eepromOpcode != EEPROM_READ) 1928 panic("only EEPROM reads are implemented!"); 1929 1930 // Set up to get address 1931 eepromState = eepromGetAddress; 1932 eepromBitsToRx = 6; 1933 eepromAddress = 0; 1934 } 1935 break; 1936 1937 case eepromGetAddress: 1938 eepromAddress <<= 1; 1939 eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0; 1940 --eepromBitsToRx; 1941 1942 // Done getting address 1943 if (eepromBitsToRx == 0) { 1944 1945 if (eepromAddress >= EEPROM_SIZE) 1946 panic("EEPROM read access out of range!"); 1947 1948 switch (eepromAddress) { 1949 1950 case EEPROM_PMATCH2_ADDR: 1951 eepromData = rom.perfectMatch[5]; 1952 eepromData <<= 8; 1953 eepromData += rom.perfectMatch[4]; 1954 break; 1955 1956 case EEPROM_PMATCH1_ADDR: 1957 eepromData = rom.perfectMatch[3]; 1958 eepromData <<= 8; 1959 eepromData += rom.perfectMatch[2]; 1960 break; 1961 1962 case EEPROM_PMATCH0_ADDR: 1963 eepromData = rom.perfectMatch[1]; 1964 eepromData <<= 8; 1965 eepromData += rom.perfectMatch[0]; 1966 break; 1967 1968 default: 1969 panic("FreeBSD driver only uses EEPROM to read PMATCH!"); 1970 } 1971 // Set up to read data 1972 eepromState = eepromRead; 1973 eepromBitsToRx = 16; 1974 1975 // Clear data in bit 1976 regs.mear &= ~MEAR_EEDI; 1977 } 1978 break; 1979 1980 case eepromRead: 1981 // Clear Data Out bit 1982 regs.mear &= ~MEAR_EEDO; 1983 // Set bit to value of current EEPROM bit 1984 regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0; 1985 1986 eepromData <<= 1; 1987 --eepromBitsToRx; 1988 1989 // All done 1990 if (eepromBitsToRx == 0) { 1991 eepromState = eepromStart; 1992 } 1993 break; 1994 1995 default: 1996 panic("invalid EEPROM state"); 1997 } 1998 1999} 2000 2001void 2002NSGigE::transferDone() 2003{ 2004 if (txFifo.empty()) { 2005 DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n"); 2006 return; 2007 } 2008 2009 DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n"); 2010 2011 reschedule(txEvent, clockEdge(Cycles(1)), true); 2012} 2013 2014bool 2015NSGigE::rxFilter(const EthPacketPtr &packet) 2016{ 2017 EthPtr eth = packet; 2018 bool drop = true; 2019 string type; 2020 2021 const EthAddr &dst = eth->dst(); 2022 if (dst.unicast()) { 2023 // If we're accepting all unicast addresses 2024 if (acceptUnicast) 2025 drop = false; 2026 2027 // If we make a perfect match 2028 if (acceptPerfect && dst == rom.perfectMatch) 2029 drop = false; 2030 2031 if (acceptArp && eth->type() == ETH_TYPE_ARP) 2032 drop = false; 2033 2034 } else if (dst.broadcast()) { 2035 // if we're accepting broadcasts 2036 if (acceptBroadcast) 2037 drop = false; 2038 2039 } else if (dst.multicast()) { 2040 // if we're accepting all multicasts 2041 if (acceptMulticast) 2042 drop = false; 2043 2044 // Multicast hashing faked - all packets accepted 2045 if (multicastHashEnable) 2046 drop = false; 2047 } 2048 2049 if (drop) { 2050 DPRINTF(Ethernet, "rxFilter drop\n"); 2051 DDUMP(EthernetData, packet->data, packet->length); 2052 } 2053 2054 return drop; 2055} 2056 2057bool 2058NSGigE::recvPacket(EthPacketPtr packet) 2059{ 2060 rxBytes += packet->length; 2061 rxPackets++; 2062 2063 DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n", 2064 rxFifo.avail()); 2065 2066 if (!rxEnable) { 2067 DPRINTF(Ethernet, "receive disabled...packet dropped\n"); 2068 return true; 2069 } 2070 2071 if (!rxFilterEnable) { 2072 DPRINTF(Ethernet, 2073 "receive packet filtering disabled . . . packet dropped\n"); 2074 return true; 2075 } 2076 2077 if (rxFilter(packet)) { 2078 DPRINTF(Ethernet, "packet filtered...dropped\n"); 2079 return true; 2080 } 2081 2082 if (rxFifo.avail() < packet->length) { 2083#if TRACING_ON 2084 IpPtr ip(packet); 2085 TcpPtr tcp(ip); 2086 if (ip) { 2087 DPRINTF(Ethernet, 2088 "packet won't fit in receive buffer...pkt ID %d dropped\n", 2089 ip->id()); 2090 if (tcp) { 2091 DPRINTF(Ethernet, "Seq=%d\n", tcp->seq()); 2092 } 2093 } 2094#endif 2095 droppedPackets++; 2096 devIntrPost(ISR_RXORN); 2097 return false; 2098 } 2099 2100 rxFifo.push(packet); 2101 2102 rxKick(); 2103 return true; 2104} 2105 2106 2107void 2108NSGigE::drainResume() 2109{ 2110 Drainable::drainResume(); 2111 2112 // During drain we could have left the state machines in a waiting state and 2113 // they wouldn't get out until some other event occured to kick them. 2114 // This way they'll get out immediately 2115 txKick(); 2116 rxKick(); 2117} 2118 2119 2120//===================================================================== 2121// 2122// 2123void 2124NSGigE::serialize(CheckpointOut &cp) const 2125{ 2126 // Serialize the PciDevice base class 2127 PciDevice::serialize(cp); 2128 2129 /* 2130 * Finalize any DMA events now. 2131 */ 2132 // @todo will mem system save pending dma? 2133 2134 /* 2135 * Serialize the device registers 2136 */ 2137 SERIALIZE_SCALAR(regs.command); 2138 SERIALIZE_SCALAR(regs.config); 2139 SERIALIZE_SCALAR(regs.mear); 2140 SERIALIZE_SCALAR(regs.ptscr); 2141 SERIALIZE_SCALAR(regs.isr); 2142 SERIALIZE_SCALAR(regs.imr); 2143 SERIALIZE_SCALAR(regs.ier); 2144 SERIALIZE_SCALAR(regs.ihr); 2145 SERIALIZE_SCALAR(regs.txdp); 2146 SERIALIZE_SCALAR(regs.txdp_hi); 2147 SERIALIZE_SCALAR(regs.txcfg); 2148 SERIALIZE_SCALAR(regs.gpior); 2149 SERIALIZE_SCALAR(regs.rxdp); 2150 SERIALIZE_SCALAR(regs.rxdp_hi); 2151 SERIALIZE_SCALAR(regs.rxcfg); 2152 SERIALIZE_SCALAR(regs.pqcr); 2153 SERIALIZE_SCALAR(regs.wcsr); 2154 SERIALIZE_SCALAR(regs.pcr); 2155 SERIALIZE_SCALAR(regs.rfcr); 2156 SERIALIZE_SCALAR(regs.rfdr); 2157 SERIALIZE_SCALAR(regs.brar); 2158 SERIALIZE_SCALAR(regs.brdr); 2159 SERIALIZE_SCALAR(regs.srr); 2160 SERIALIZE_SCALAR(regs.mibc); 2161 SERIALIZE_SCALAR(regs.vrcr); 2162 SERIALIZE_SCALAR(regs.vtcr); 2163 SERIALIZE_SCALAR(regs.vdr); 2164 SERIALIZE_SCALAR(regs.ccsr); 2165 SERIALIZE_SCALAR(regs.tbicr); 2166 SERIALIZE_SCALAR(regs.tbisr); 2167 SERIALIZE_SCALAR(regs.tanar); 2168 SERIALIZE_SCALAR(regs.tanlpar); 2169 SERIALIZE_SCALAR(regs.taner); 2170 SERIALIZE_SCALAR(regs.tesr); 2171 2172 SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); 2173 SERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); 2174 2175 SERIALIZE_SCALAR(ioEnable); 2176 2177 /* 2178 * Serialize the data Fifos 2179 */ 2180 rxFifo.serialize("rxFifo", cp); 2181 txFifo.serialize("txFifo", cp); 2182 2183 /* 2184 * Serialize the various helper variables 2185 */ 2186 bool txPacketExists = txPacket != nullptr; 2187 SERIALIZE_SCALAR(txPacketExists); 2188 if (txPacketExists) { 2189 txPacket->length = txPacketBufPtr - txPacket->data; 2190 txPacket->serialize("txPacket", cp); 2191 uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); 2192 SERIALIZE_SCALAR(txPktBufPtr); 2193 } 2194 2195 bool rxPacketExists = rxPacket != nullptr; 2196 SERIALIZE_SCALAR(rxPacketExists); 2197 if (rxPacketExists) { 2198 rxPacket->serialize("rxPacket", cp); 2199 uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data); 2200 SERIALIZE_SCALAR(rxPktBufPtr); 2201 } 2202 2203 SERIALIZE_SCALAR(txXferLen); 2204 SERIALIZE_SCALAR(rxXferLen); 2205 2206 /* 2207 * Serialize Cached Descriptors 2208 */ 2209 SERIALIZE_SCALAR(rxDesc64.link); 2210 SERIALIZE_SCALAR(rxDesc64.bufptr); 2211 SERIALIZE_SCALAR(rxDesc64.cmdsts); 2212 SERIALIZE_SCALAR(rxDesc64.extsts); 2213 SERIALIZE_SCALAR(txDesc64.link); 2214 SERIALIZE_SCALAR(txDesc64.bufptr); 2215 SERIALIZE_SCALAR(txDesc64.cmdsts); 2216 SERIALIZE_SCALAR(txDesc64.extsts); 2217 SERIALIZE_SCALAR(rxDesc32.link); 2218 SERIALIZE_SCALAR(rxDesc32.bufptr); 2219 SERIALIZE_SCALAR(rxDesc32.cmdsts); 2220 SERIALIZE_SCALAR(rxDesc32.extsts); 2221 SERIALIZE_SCALAR(txDesc32.link); 2222 SERIALIZE_SCALAR(txDesc32.bufptr); 2223 SERIALIZE_SCALAR(txDesc32.cmdsts); 2224 SERIALIZE_SCALAR(txDesc32.extsts); 2225 SERIALIZE_SCALAR(extstsEnable); 2226 2227 /* 2228 * Serialize tx state machine 2229 */ 2230 int txState = this->txState; 2231 SERIALIZE_SCALAR(txState); 2232 SERIALIZE_SCALAR(txEnable); 2233 SERIALIZE_SCALAR(CTDD); 2234 SERIALIZE_SCALAR(txFragPtr); 2235 SERIALIZE_SCALAR(txDescCnt); 2236 int txDmaState = this->txDmaState; 2237 SERIALIZE_SCALAR(txDmaState); 2238 SERIALIZE_SCALAR(txKickTick); 2239 2240 /* 2241 * Serialize rx state machine 2242 */ 2243 int rxState = this->rxState; 2244 SERIALIZE_SCALAR(rxState); 2245 SERIALIZE_SCALAR(rxEnable); 2246 SERIALIZE_SCALAR(CRDD); 2247 SERIALIZE_SCALAR(rxPktBytes); 2248 SERIALIZE_SCALAR(rxFragPtr); 2249 SERIALIZE_SCALAR(rxDescCnt); 2250 int rxDmaState = this->rxDmaState; 2251 SERIALIZE_SCALAR(rxDmaState); 2252 SERIALIZE_SCALAR(rxKickTick); 2253 2254 /* 2255 * Serialize EEPROM state machine 2256 */ 2257 int eepromState = this->eepromState; 2258 SERIALIZE_SCALAR(eepromState); 2259 SERIALIZE_SCALAR(eepromClk); 2260 SERIALIZE_SCALAR(eepromBitsToRx); 2261 SERIALIZE_SCALAR(eepromOpcode); 2262 SERIALIZE_SCALAR(eepromAddress); 2263 SERIALIZE_SCALAR(eepromData); 2264 2265 /* 2266 * If there's a pending transmit, store the time so we can 2267 * reschedule it later 2268 */ 2269 Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick() : 0; 2270 SERIALIZE_SCALAR(transmitTick); 2271 2272 /* 2273 * receive address filter settings 2274 */ 2275 SERIALIZE_SCALAR(rxFilterEnable); 2276 SERIALIZE_SCALAR(acceptBroadcast); 2277 SERIALIZE_SCALAR(acceptMulticast); 2278 SERIALIZE_SCALAR(acceptUnicast); 2279 SERIALIZE_SCALAR(acceptPerfect); 2280 SERIALIZE_SCALAR(acceptArp); 2281 SERIALIZE_SCALAR(multicastHashEnable); 2282 2283 /* 2284 * Keep track of pending interrupt status. 2285 */ 2286 SERIALIZE_SCALAR(intrTick); 2287 SERIALIZE_SCALAR(cpuPendingIntr); 2288 Tick intrEventTick = 0; 2289 if (intrEvent) 2290 intrEventTick = intrEvent->when(); 2291 SERIALIZE_SCALAR(intrEventTick); 2292 2293} 2294 2295void 2296NSGigE::unserialize(CheckpointIn &cp) 2297{ 2298 // Unserialize the PciDevice base class 2299 PciDevice::unserialize(cp); 2300 2301 UNSERIALIZE_SCALAR(regs.command); 2302 UNSERIALIZE_SCALAR(regs.config); 2303 UNSERIALIZE_SCALAR(regs.mear); 2304 UNSERIALIZE_SCALAR(regs.ptscr); 2305 UNSERIALIZE_SCALAR(regs.isr); 2306 UNSERIALIZE_SCALAR(regs.imr); 2307 UNSERIALIZE_SCALAR(regs.ier); 2308 UNSERIALIZE_SCALAR(regs.ihr); 2309 UNSERIALIZE_SCALAR(regs.txdp); 2310 UNSERIALIZE_SCALAR(regs.txdp_hi); 2311 UNSERIALIZE_SCALAR(regs.txcfg); 2312 UNSERIALIZE_SCALAR(regs.gpior); 2313 UNSERIALIZE_SCALAR(regs.rxdp); 2314 UNSERIALIZE_SCALAR(regs.rxdp_hi); 2315 UNSERIALIZE_SCALAR(regs.rxcfg); 2316 UNSERIALIZE_SCALAR(regs.pqcr); 2317 UNSERIALIZE_SCALAR(regs.wcsr); 2318 UNSERIALIZE_SCALAR(regs.pcr); 2319 UNSERIALIZE_SCALAR(regs.rfcr); 2320 UNSERIALIZE_SCALAR(regs.rfdr); 2321 UNSERIALIZE_SCALAR(regs.brar); 2322 UNSERIALIZE_SCALAR(regs.brdr); 2323 UNSERIALIZE_SCALAR(regs.srr); 2324 UNSERIALIZE_SCALAR(regs.mibc); 2325 UNSERIALIZE_SCALAR(regs.vrcr); 2326 UNSERIALIZE_SCALAR(regs.vtcr); 2327 UNSERIALIZE_SCALAR(regs.vdr); 2328 UNSERIALIZE_SCALAR(regs.ccsr); 2329 UNSERIALIZE_SCALAR(regs.tbicr); 2330 UNSERIALIZE_SCALAR(regs.tbisr); 2331 UNSERIALIZE_SCALAR(regs.tanar); 2332 UNSERIALIZE_SCALAR(regs.tanlpar); 2333 UNSERIALIZE_SCALAR(regs.taner); 2334 UNSERIALIZE_SCALAR(regs.tesr); 2335 2336 UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); 2337 UNSERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); 2338 2339 UNSERIALIZE_SCALAR(ioEnable); 2340 2341 /* 2342 * unserialize the data fifos 2343 */ 2344 rxFifo.unserialize("rxFifo", cp); 2345 txFifo.unserialize("txFifo", cp); 2346 2347 /* 2348 * unserialize the various helper variables 2349 */ 2350 bool txPacketExists; 2351 UNSERIALIZE_SCALAR(txPacketExists); 2352 if (txPacketExists) { 2353 txPacket = make_shared<EthPacketData>(16384); 2354 txPacket->unserialize("txPacket", cp); 2355 uint32_t txPktBufPtr; 2356 UNSERIALIZE_SCALAR(txPktBufPtr); 2357 txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr; 2358 } else 2359 txPacket = 0; 2360 2361 bool rxPacketExists; 2362 UNSERIALIZE_SCALAR(rxPacketExists); 2363 rxPacket = 0; 2364 if (rxPacketExists) { 2365 rxPacket = make_shared<EthPacketData>(16384); 2366 rxPacket->unserialize("rxPacket", cp); 2367 uint32_t rxPktBufPtr; 2368 UNSERIALIZE_SCALAR(rxPktBufPtr); 2369 rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr; 2370 } else 2371 rxPacket = 0; 2372 2373 UNSERIALIZE_SCALAR(txXferLen); 2374 UNSERIALIZE_SCALAR(rxXferLen); 2375 2376 /* 2377 * Unserialize Cached Descriptors 2378 */ 2379 UNSERIALIZE_SCALAR(rxDesc64.link); 2380 UNSERIALIZE_SCALAR(rxDesc64.bufptr); 2381 UNSERIALIZE_SCALAR(rxDesc64.cmdsts); 2382 UNSERIALIZE_SCALAR(rxDesc64.extsts); 2383 UNSERIALIZE_SCALAR(txDesc64.link); 2384 UNSERIALIZE_SCALAR(txDesc64.bufptr); 2385 UNSERIALIZE_SCALAR(txDesc64.cmdsts); 2386 UNSERIALIZE_SCALAR(txDesc64.extsts); 2387 UNSERIALIZE_SCALAR(rxDesc32.link); 2388 UNSERIALIZE_SCALAR(rxDesc32.bufptr); 2389 UNSERIALIZE_SCALAR(rxDesc32.cmdsts); 2390 UNSERIALIZE_SCALAR(rxDesc32.extsts); 2391 UNSERIALIZE_SCALAR(txDesc32.link); 2392 UNSERIALIZE_SCALAR(txDesc32.bufptr); 2393 UNSERIALIZE_SCALAR(txDesc32.cmdsts); 2394 UNSERIALIZE_SCALAR(txDesc32.extsts); 2395 UNSERIALIZE_SCALAR(extstsEnable); 2396 2397 /* 2398 * unserialize tx state machine 2399 */ 2400 int txState; 2401 UNSERIALIZE_SCALAR(txState); 2402 this->txState = (TxState) txState; 2403 UNSERIALIZE_SCALAR(txEnable); 2404 UNSERIALIZE_SCALAR(CTDD); 2405 UNSERIALIZE_SCALAR(txFragPtr); 2406 UNSERIALIZE_SCALAR(txDescCnt); 2407 int txDmaState; 2408 UNSERIALIZE_SCALAR(txDmaState); 2409 this->txDmaState = (DmaState) txDmaState; 2410 UNSERIALIZE_SCALAR(txKickTick); 2411 if (txKickTick) 2412 schedule(txKickEvent, txKickTick); 2413 2414 /* 2415 * unserialize rx state machine 2416 */ 2417 int rxState; 2418 UNSERIALIZE_SCALAR(rxState); 2419 this->rxState = (RxState) rxState; 2420 UNSERIALIZE_SCALAR(rxEnable); 2421 UNSERIALIZE_SCALAR(CRDD); 2422 UNSERIALIZE_SCALAR(rxPktBytes); 2423 UNSERIALIZE_SCALAR(rxFragPtr); 2424 UNSERIALIZE_SCALAR(rxDescCnt); 2425 int rxDmaState; 2426 UNSERIALIZE_SCALAR(rxDmaState); 2427 this->rxDmaState = (DmaState) rxDmaState; 2428 UNSERIALIZE_SCALAR(rxKickTick); 2429 if (rxKickTick) 2430 schedule(rxKickEvent, rxKickTick); 2431 2432 /* 2433 * Unserialize EEPROM state machine 2434 */ 2435 int eepromState; 2436 UNSERIALIZE_SCALAR(eepromState); 2437 this->eepromState = (EEPROMState) eepromState; 2438 UNSERIALIZE_SCALAR(eepromClk); 2439 UNSERIALIZE_SCALAR(eepromBitsToRx); 2440 UNSERIALIZE_SCALAR(eepromOpcode); 2441 UNSERIALIZE_SCALAR(eepromAddress); 2442 UNSERIALIZE_SCALAR(eepromData); 2443 2444 /* 2445 * If there's a pending transmit, reschedule it now 2446 */ 2447 Tick transmitTick; 2448 UNSERIALIZE_SCALAR(transmitTick); 2449 if (transmitTick) 2450 schedule(txEvent, curTick() + transmitTick); 2451 2452 /* 2453 * unserialize receive address filter settings 2454 */ 2455 UNSERIALIZE_SCALAR(rxFilterEnable); 2456 UNSERIALIZE_SCALAR(acceptBroadcast); 2457 UNSERIALIZE_SCALAR(acceptMulticast); 2458 UNSERIALIZE_SCALAR(acceptUnicast); 2459 UNSERIALIZE_SCALAR(acceptPerfect); 2460 UNSERIALIZE_SCALAR(acceptArp); 2461 UNSERIALIZE_SCALAR(multicastHashEnable); 2462 2463 /* 2464 * Keep track of pending interrupt status. 2465 */ 2466 UNSERIALIZE_SCALAR(intrTick); 2467 UNSERIALIZE_SCALAR(cpuPendingIntr); 2468 Tick intrEventTick; 2469 UNSERIALIZE_SCALAR(intrEventTick); 2470 if (intrEventTick) { 2471 intrEvent = new IntrEvent(this, true); 2472 schedule(intrEvent, intrEventTick); 2473 } 2474} 2475 2476NSGigE * 2477NSGigEParams::create() 2478{ 2479 return new NSGigE(this); 2480} 2481