ns_gige.cc revision 11701:5e7599457b97
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->simLength = txPacketBufPtr - txPacket->data; 1742 txPacket->length = txPacketBufPtr - txPacket->data; 1743 // this is just because the receive can't handle a 1744 // packet bigger want to make sure 1745 if (txPacket->length > 1514) 1746 panic("transmit packet too large, %s > 1514\n", 1747 txPacket->length); 1748 1749#ifndef NDEBUG 1750 bool success = 1751#endif 1752 txFifo.push(txPacket); 1753 assert(success); 1754 1755 /* 1756 * this following section is not tqo spec, but 1757 * functionally shouldn't be any different. normally, 1758 * the chip will wait til the transmit has occurred 1759 * before writing back the descriptor because it has 1760 * to wait to see that it was successfully transmitted 1761 * to decide whether to set CMDSTS_OK or not. 1762 * however, in the simulator since it is always 1763 * successfully transmitted, and writing it exactly to 1764 * spec would complicate the code, we just do it here 1765 */ 1766 1767 cmdsts &= ~CMDSTS_OWN; 1768 cmdsts |= CMDSTS_OK; 1769 1770 DPRINTF(EthernetDesc, 1771 "txDesc writeback: cmdsts=%08x extsts=%08x\n", 1772 cmdsts, extsts); 1773 1774 txDmaFree = dmaDescFree; 1775 txDmaAddr = regs.txdp & 0x3fffffff; 1776 txDmaData = &cmdsts; 1777 if (is64bit) { 1778 txDmaAddr += offsetof(ns_desc64, cmdsts); 1779 txDmaLen = 1780 sizeof(txDesc64.cmdsts) + sizeof(txDesc64.extsts); 1781 } else { 1782 txDmaAddr += offsetof(ns_desc32, cmdsts); 1783 txDmaLen = 1784 sizeof(txDesc32.cmdsts) + sizeof(txDesc32.extsts); 1785 } 1786 1787 descDmaWrites++; 1788 descDmaWrBytes += txDmaLen; 1789 1790 transmit(); 1791 txPacket = 0; 1792 1793 if (!txEnable) { 1794 DPRINTF(EthernetSM, "halting TX state machine\n"); 1795 txState = txIdle; 1796 goto exit; 1797 } else 1798 txState = txAdvance; 1799 1800 if (doTxDmaWrite()) 1801 goto exit; 1802 } 1803 } else { 1804 DPRINTF(EthernetSM, "this descriptor isn't done yet\n"); 1805 if (!txFifo.full()) { 1806 txState = txFragRead; 1807 1808 /* 1809 * The number of bytes transferred is either whatever 1810 * is left in the descriptor (txDescCnt), or if there 1811 * is not enough room in the fifo, just whatever room 1812 * is left in the fifo 1813 */ 1814 txXferLen = min<uint32_t>(txDescCnt, txFifo.avail()); 1815 1816 txDmaAddr = txFragPtr & 0x3fffffff; 1817 txDmaData = txPacketBufPtr; 1818 txDmaLen = txXferLen; 1819 txDmaFree = dmaDataFree; 1820 1821 if (doTxDmaRead()) 1822 goto exit; 1823 } else { 1824 txState = txFifoBlock; 1825 transmit(); 1826 1827 goto exit; 1828 } 1829 1830 } 1831 break; 1832 1833 case txFragRead: 1834 if (txDmaState != dmaIdle) 1835 goto exit; 1836 1837 txPacketBufPtr += txXferLen; 1838 txFragPtr += txXferLen; 1839 txDescCnt -= txXferLen; 1840 txFifo.reserve(txXferLen); 1841 1842 txState = txFifoBlock; 1843 break; 1844 1845 case txDescWrite: 1846 if (txDmaState != dmaIdle) 1847 goto exit; 1848 1849 if (cmdsts & CMDSTS_INTR) 1850 devIntrPost(ISR_TXDESC); 1851 1852 if (!txEnable) { 1853 DPRINTF(EthernetSM, "halting TX state machine\n"); 1854 txState = txIdle; 1855 goto exit; 1856 } else 1857 txState = txAdvance; 1858 break; 1859 1860 case txAdvance: 1861 if (link == 0) { 1862 devIntrPost(ISR_TXIDLE); 1863 txState = txIdle; 1864 goto exit; 1865 } else { 1866 if (txDmaState != dmaIdle) 1867 goto exit; 1868 txState = txDescRead; 1869 regs.txdp = link; 1870 CTDD = false; 1871 1872 txDmaAddr = link & 0x3fffffff; 1873 txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32; 1874 txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32); 1875 txDmaFree = dmaDescFree; 1876 1877 if (doTxDmaRead()) 1878 goto exit; 1879 } 1880 break; 1881 1882 default: 1883 panic("invalid state"); 1884 } 1885 1886 DPRINTF(EthernetSM, "entering next txState=%s\n", 1887 NsTxStateStrings[txState]); 1888 goto next; 1889 1890 exit: 1891 /** 1892 * @todo do we want to schedule a future kick? 1893 */ 1894 DPRINTF(EthernetSM, "tx state machine exited txState=%s\n", 1895 NsTxStateStrings[txState]); 1896 1897 if (!txKickEvent.scheduled()) 1898 schedule(txKickEvent, txKickTick); 1899} 1900 1901/** 1902 * Advance the EEPROM state machine 1903 * Called on rising edge of EEPROM clock bit in MEAR 1904 */ 1905void 1906NSGigE::eepromKick() 1907{ 1908 switch (eepromState) { 1909 1910 case eepromStart: 1911 1912 // Wait for start bit 1913 if (regs.mear & MEAR_EEDI) { 1914 // Set up to get 2 opcode bits 1915 eepromState = eepromGetOpcode; 1916 eepromBitsToRx = 2; 1917 eepromOpcode = 0; 1918 } 1919 break; 1920 1921 case eepromGetOpcode: 1922 eepromOpcode <<= 1; 1923 eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0; 1924 --eepromBitsToRx; 1925 1926 // Done getting opcode 1927 if (eepromBitsToRx == 0) { 1928 if (eepromOpcode != EEPROM_READ) 1929 panic("only EEPROM reads are implemented!"); 1930 1931 // Set up to get address 1932 eepromState = eepromGetAddress; 1933 eepromBitsToRx = 6; 1934 eepromAddress = 0; 1935 } 1936 break; 1937 1938 case eepromGetAddress: 1939 eepromAddress <<= 1; 1940 eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0; 1941 --eepromBitsToRx; 1942 1943 // Done getting address 1944 if (eepromBitsToRx == 0) { 1945 1946 if (eepromAddress >= EEPROM_SIZE) 1947 panic("EEPROM read access out of range!"); 1948 1949 switch (eepromAddress) { 1950 1951 case EEPROM_PMATCH2_ADDR: 1952 eepromData = rom.perfectMatch[5]; 1953 eepromData <<= 8; 1954 eepromData += rom.perfectMatch[4]; 1955 break; 1956 1957 case EEPROM_PMATCH1_ADDR: 1958 eepromData = rom.perfectMatch[3]; 1959 eepromData <<= 8; 1960 eepromData += rom.perfectMatch[2]; 1961 break; 1962 1963 case EEPROM_PMATCH0_ADDR: 1964 eepromData = rom.perfectMatch[1]; 1965 eepromData <<= 8; 1966 eepromData += rom.perfectMatch[0]; 1967 break; 1968 1969 default: 1970 panic("FreeBSD driver only uses EEPROM to read PMATCH!"); 1971 } 1972 // Set up to read data 1973 eepromState = eepromRead; 1974 eepromBitsToRx = 16; 1975 1976 // Clear data in bit 1977 regs.mear &= ~MEAR_EEDI; 1978 } 1979 break; 1980 1981 case eepromRead: 1982 // Clear Data Out bit 1983 regs.mear &= ~MEAR_EEDO; 1984 // Set bit to value of current EEPROM bit 1985 regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0; 1986 1987 eepromData <<= 1; 1988 --eepromBitsToRx; 1989 1990 // All done 1991 if (eepromBitsToRx == 0) { 1992 eepromState = eepromStart; 1993 } 1994 break; 1995 1996 default: 1997 panic("invalid EEPROM state"); 1998 } 1999 2000} 2001 2002void 2003NSGigE::transferDone() 2004{ 2005 if (txFifo.empty()) { 2006 DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n"); 2007 return; 2008 } 2009 2010 DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n"); 2011 2012 reschedule(txEvent, clockEdge(Cycles(1)), true); 2013} 2014 2015bool 2016NSGigE::rxFilter(const EthPacketPtr &packet) 2017{ 2018 EthPtr eth = packet; 2019 bool drop = true; 2020 string type; 2021 2022 const EthAddr &dst = eth->dst(); 2023 if (dst.unicast()) { 2024 // If we're accepting all unicast addresses 2025 if (acceptUnicast) 2026 drop = false; 2027 2028 // If we make a perfect match 2029 if (acceptPerfect && dst == rom.perfectMatch) 2030 drop = false; 2031 2032 if (acceptArp && eth->type() == ETH_TYPE_ARP) 2033 drop = false; 2034 2035 } else if (dst.broadcast()) { 2036 // if we're accepting broadcasts 2037 if (acceptBroadcast) 2038 drop = false; 2039 2040 } else if (dst.multicast()) { 2041 // if we're accepting all multicasts 2042 if (acceptMulticast) 2043 drop = false; 2044 2045 // Multicast hashing faked - all packets accepted 2046 if (multicastHashEnable) 2047 drop = false; 2048 } 2049 2050 if (drop) { 2051 DPRINTF(Ethernet, "rxFilter drop\n"); 2052 DDUMP(EthernetData, packet->data, packet->length); 2053 } 2054 2055 return drop; 2056} 2057 2058bool 2059NSGigE::recvPacket(EthPacketPtr packet) 2060{ 2061 rxBytes += packet->length; 2062 rxPackets++; 2063 2064 DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n", 2065 rxFifo.avail()); 2066 2067 if (!rxEnable) { 2068 DPRINTF(Ethernet, "receive disabled...packet dropped\n"); 2069 return true; 2070 } 2071 2072 if (!rxFilterEnable) { 2073 DPRINTF(Ethernet, 2074 "receive packet filtering disabled . . . packet dropped\n"); 2075 return true; 2076 } 2077 2078 if (rxFilter(packet)) { 2079 DPRINTF(Ethernet, "packet filtered...dropped\n"); 2080 return true; 2081 } 2082 2083 if (rxFifo.avail() < packet->length) { 2084#if TRACING_ON 2085 IpPtr ip(packet); 2086 TcpPtr tcp(ip); 2087 if (ip) { 2088 DPRINTF(Ethernet, 2089 "packet won't fit in receive buffer...pkt ID %d dropped\n", 2090 ip->id()); 2091 if (tcp) { 2092 DPRINTF(Ethernet, "Seq=%d\n", tcp->seq()); 2093 } 2094 } 2095#endif 2096 droppedPackets++; 2097 devIntrPost(ISR_RXORN); 2098 return false; 2099 } 2100 2101 rxFifo.push(packet); 2102 2103 rxKick(); 2104 return true; 2105} 2106 2107 2108void 2109NSGigE::drainResume() 2110{ 2111 Drainable::drainResume(); 2112 2113 // During drain we could have left the state machines in a waiting state and 2114 // they wouldn't get out until some other event occured to kick them. 2115 // This way they'll get out immediately 2116 txKick(); 2117 rxKick(); 2118} 2119 2120 2121//===================================================================== 2122// 2123// 2124void 2125NSGigE::serialize(CheckpointOut &cp) const 2126{ 2127 // Serialize the PciDevice base class 2128 PciDevice::serialize(cp); 2129 2130 /* 2131 * Finalize any DMA events now. 2132 */ 2133 // @todo will mem system save pending dma? 2134 2135 /* 2136 * Serialize the device registers 2137 */ 2138 SERIALIZE_SCALAR(regs.command); 2139 SERIALIZE_SCALAR(regs.config); 2140 SERIALIZE_SCALAR(regs.mear); 2141 SERIALIZE_SCALAR(regs.ptscr); 2142 SERIALIZE_SCALAR(regs.isr); 2143 SERIALIZE_SCALAR(regs.imr); 2144 SERIALIZE_SCALAR(regs.ier); 2145 SERIALIZE_SCALAR(regs.ihr); 2146 SERIALIZE_SCALAR(regs.txdp); 2147 SERIALIZE_SCALAR(regs.txdp_hi); 2148 SERIALIZE_SCALAR(regs.txcfg); 2149 SERIALIZE_SCALAR(regs.gpior); 2150 SERIALIZE_SCALAR(regs.rxdp); 2151 SERIALIZE_SCALAR(regs.rxdp_hi); 2152 SERIALIZE_SCALAR(regs.rxcfg); 2153 SERIALIZE_SCALAR(regs.pqcr); 2154 SERIALIZE_SCALAR(regs.wcsr); 2155 SERIALIZE_SCALAR(regs.pcr); 2156 SERIALIZE_SCALAR(regs.rfcr); 2157 SERIALIZE_SCALAR(regs.rfdr); 2158 SERIALIZE_SCALAR(regs.brar); 2159 SERIALIZE_SCALAR(regs.brdr); 2160 SERIALIZE_SCALAR(regs.srr); 2161 SERIALIZE_SCALAR(regs.mibc); 2162 SERIALIZE_SCALAR(regs.vrcr); 2163 SERIALIZE_SCALAR(regs.vtcr); 2164 SERIALIZE_SCALAR(regs.vdr); 2165 SERIALIZE_SCALAR(regs.ccsr); 2166 SERIALIZE_SCALAR(regs.tbicr); 2167 SERIALIZE_SCALAR(regs.tbisr); 2168 SERIALIZE_SCALAR(regs.tanar); 2169 SERIALIZE_SCALAR(regs.tanlpar); 2170 SERIALIZE_SCALAR(regs.taner); 2171 SERIALIZE_SCALAR(regs.tesr); 2172 2173 SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); 2174 SERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); 2175 2176 SERIALIZE_SCALAR(ioEnable); 2177 2178 /* 2179 * Serialize the data Fifos 2180 */ 2181 rxFifo.serialize("rxFifo", cp); 2182 txFifo.serialize("txFifo", cp); 2183 2184 /* 2185 * Serialize the various helper variables 2186 */ 2187 bool txPacketExists = txPacket != nullptr; 2188 SERIALIZE_SCALAR(txPacketExists); 2189 if (txPacketExists) { 2190 txPacket->simLength = txPacketBufPtr - txPacket->data; 2191 txPacket->length = txPacketBufPtr - txPacket->data; 2192 txPacket->serialize("txPacket", cp); 2193 uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); 2194 SERIALIZE_SCALAR(txPktBufPtr); 2195 } 2196 2197 bool rxPacketExists = rxPacket != nullptr; 2198 SERIALIZE_SCALAR(rxPacketExists); 2199 if (rxPacketExists) { 2200 rxPacket->serialize("rxPacket", cp); 2201 uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data); 2202 SERIALIZE_SCALAR(rxPktBufPtr); 2203 } 2204 2205 SERIALIZE_SCALAR(txXferLen); 2206 SERIALIZE_SCALAR(rxXferLen); 2207 2208 /* 2209 * Serialize Cached Descriptors 2210 */ 2211 SERIALIZE_SCALAR(rxDesc64.link); 2212 SERIALIZE_SCALAR(rxDesc64.bufptr); 2213 SERIALIZE_SCALAR(rxDesc64.cmdsts); 2214 SERIALIZE_SCALAR(rxDesc64.extsts); 2215 SERIALIZE_SCALAR(txDesc64.link); 2216 SERIALIZE_SCALAR(txDesc64.bufptr); 2217 SERIALIZE_SCALAR(txDesc64.cmdsts); 2218 SERIALIZE_SCALAR(txDesc64.extsts); 2219 SERIALIZE_SCALAR(rxDesc32.link); 2220 SERIALIZE_SCALAR(rxDesc32.bufptr); 2221 SERIALIZE_SCALAR(rxDesc32.cmdsts); 2222 SERIALIZE_SCALAR(rxDesc32.extsts); 2223 SERIALIZE_SCALAR(txDesc32.link); 2224 SERIALIZE_SCALAR(txDesc32.bufptr); 2225 SERIALIZE_SCALAR(txDesc32.cmdsts); 2226 SERIALIZE_SCALAR(txDesc32.extsts); 2227 SERIALIZE_SCALAR(extstsEnable); 2228 2229 /* 2230 * Serialize tx state machine 2231 */ 2232 int txState = this->txState; 2233 SERIALIZE_SCALAR(txState); 2234 SERIALIZE_SCALAR(txEnable); 2235 SERIALIZE_SCALAR(CTDD); 2236 SERIALIZE_SCALAR(txFragPtr); 2237 SERIALIZE_SCALAR(txDescCnt); 2238 int txDmaState = this->txDmaState; 2239 SERIALIZE_SCALAR(txDmaState); 2240 SERIALIZE_SCALAR(txKickTick); 2241 2242 /* 2243 * Serialize rx state machine 2244 */ 2245 int rxState = this->rxState; 2246 SERIALIZE_SCALAR(rxState); 2247 SERIALIZE_SCALAR(rxEnable); 2248 SERIALIZE_SCALAR(CRDD); 2249 SERIALIZE_SCALAR(rxPktBytes); 2250 SERIALIZE_SCALAR(rxFragPtr); 2251 SERIALIZE_SCALAR(rxDescCnt); 2252 int rxDmaState = this->rxDmaState; 2253 SERIALIZE_SCALAR(rxDmaState); 2254 SERIALIZE_SCALAR(rxKickTick); 2255 2256 /* 2257 * Serialize EEPROM state machine 2258 */ 2259 int eepromState = this->eepromState; 2260 SERIALIZE_SCALAR(eepromState); 2261 SERIALIZE_SCALAR(eepromClk); 2262 SERIALIZE_SCALAR(eepromBitsToRx); 2263 SERIALIZE_SCALAR(eepromOpcode); 2264 SERIALIZE_SCALAR(eepromAddress); 2265 SERIALIZE_SCALAR(eepromData); 2266 2267 /* 2268 * If there's a pending transmit, store the time so we can 2269 * reschedule it later 2270 */ 2271 Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick() : 0; 2272 SERIALIZE_SCALAR(transmitTick); 2273 2274 /* 2275 * receive address filter settings 2276 */ 2277 SERIALIZE_SCALAR(rxFilterEnable); 2278 SERIALIZE_SCALAR(acceptBroadcast); 2279 SERIALIZE_SCALAR(acceptMulticast); 2280 SERIALIZE_SCALAR(acceptUnicast); 2281 SERIALIZE_SCALAR(acceptPerfect); 2282 SERIALIZE_SCALAR(acceptArp); 2283 SERIALIZE_SCALAR(multicastHashEnable); 2284 2285 /* 2286 * Keep track of pending interrupt status. 2287 */ 2288 SERIALIZE_SCALAR(intrTick); 2289 SERIALIZE_SCALAR(cpuPendingIntr); 2290 Tick intrEventTick = 0; 2291 if (intrEvent) 2292 intrEventTick = intrEvent->when(); 2293 SERIALIZE_SCALAR(intrEventTick); 2294 2295} 2296 2297void 2298NSGigE::unserialize(CheckpointIn &cp) 2299{ 2300 // Unserialize the PciDevice base class 2301 PciDevice::unserialize(cp); 2302 2303 UNSERIALIZE_SCALAR(regs.command); 2304 UNSERIALIZE_SCALAR(regs.config); 2305 UNSERIALIZE_SCALAR(regs.mear); 2306 UNSERIALIZE_SCALAR(regs.ptscr); 2307 UNSERIALIZE_SCALAR(regs.isr); 2308 UNSERIALIZE_SCALAR(regs.imr); 2309 UNSERIALIZE_SCALAR(regs.ier); 2310 UNSERIALIZE_SCALAR(regs.ihr); 2311 UNSERIALIZE_SCALAR(regs.txdp); 2312 UNSERIALIZE_SCALAR(regs.txdp_hi); 2313 UNSERIALIZE_SCALAR(regs.txcfg); 2314 UNSERIALIZE_SCALAR(regs.gpior); 2315 UNSERIALIZE_SCALAR(regs.rxdp); 2316 UNSERIALIZE_SCALAR(regs.rxdp_hi); 2317 UNSERIALIZE_SCALAR(regs.rxcfg); 2318 UNSERIALIZE_SCALAR(regs.pqcr); 2319 UNSERIALIZE_SCALAR(regs.wcsr); 2320 UNSERIALIZE_SCALAR(regs.pcr); 2321 UNSERIALIZE_SCALAR(regs.rfcr); 2322 UNSERIALIZE_SCALAR(regs.rfdr); 2323 UNSERIALIZE_SCALAR(regs.brar); 2324 UNSERIALIZE_SCALAR(regs.brdr); 2325 UNSERIALIZE_SCALAR(regs.srr); 2326 UNSERIALIZE_SCALAR(regs.mibc); 2327 UNSERIALIZE_SCALAR(regs.vrcr); 2328 UNSERIALIZE_SCALAR(regs.vtcr); 2329 UNSERIALIZE_SCALAR(regs.vdr); 2330 UNSERIALIZE_SCALAR(regs.ccsr); 2331 UNSERIALIZE_SCALAR(regs.tbicr); 2332 UNSERIALIZE_SCALAR(regs.tbisr); 2333 UNSERIALIZE_SCALAR(regs.tanar); 2334 UNSERIALIZE_SCALAR(regs.tanlpar); 2335 UNSERIALIZE_SCALAR(regs.taner); 2336 UNSERIALIZE_SCALAR(regs.tesr); 2337 2338 UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); 2339 UNSERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); 2340 2341 UNSERIALIZE_SCALAR(ioEnable); 2342 2343 /* 2344 * unserialize the data fifos 2345 */ 2346 rxFifo.unserialize("rxFifo", cp); 2347 txFifo.unserialize("txFifo", cp); 2348 2349 /* 2350 * unserialize the various helper variables 2351 */ 2352 bool txPacketExists; 2353 UNSERIALIZE_SCALAR(txPacketExists); 2354 if (txPacketExists) { 2355 txPacket = make_shared<EthPacketData>(); 2356 txPacket->unserialize("txPacket", cp); 2357 uint32_t txPktBufPtr; 2358 UNSERIALIZE_SCALAR(txPktBufPtr); 2359 txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr; 2360 } else 2361 txPacket = 0; 2362 2363 bool rxPacketExists; 2364 UNSERIALIZE_SCALAR(rxPacketExists); 2365 rxPacket = 0; 2366 if (rxPacketExists) { 2367 rxPacket = make_shared<EthPacketData>(); 2368 rxPacket->unserialize("rxPacket", cp); 2369 uint32_t rxPktBufPtr; 2370 UNSERIALIZE_SCALAR(rxPktBufPtr); 2371 rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr; 2372 } else 2373 rxPacket = 0; 2374 2375 UNSERIALIZE_SCALAR(txXferLen); 2376 UNSERIALIZE_SCALAR(rxXferLen); 2377 2378 /* 2379 * Unserialize Cached Descriptors 2380 */ 2381 UNSERIALIZE_SCALAR(rxDesc64.link); 2382 UNSERIALIZE_SCALAR(rxDesc64.bufptr); 2383 UNSERIALIZE_SCALAR(rxDesc64.cmdsts); 2384 UNSERIALIZE_SCALAR(rxDesc64.extsts); 2385 UNSERIALIZE_SCALAR(txDesc64.link); 2386 UNSERIALIZE_SCALAR(txDesc64.bufptr); 2387 UNSERIALIZE_SCALAR(txDesc64.cmdsts); 2388 UNSERIALIZE_SCALAR(txDesc64.extsts); 2389 UNSERIALIZE_SCALAR(rxDesc32.link); 2390 UNSERIALIZE_SCALAR(rxDesc32.bufptr); 2391 UNSERIALIZE_SCALAR(rxDesc32.cmdsts); 2392 UNSERIALIZE_SCALAR(rxDesc32.extsts); 2393 UNSERIALIZE_SCALAR(txDesc32.link); 2394 UNSERIALIZE_SCALAR(txDesc32.bufptr); 2395 UNSERIALIZE_SCALAR(txDesc32.cmdsts); 2396 UNSERIALIZE_SCALAR(txDesc32.extsts); 2397 UNSERIALIZE_SCALAR(extstsEnable); 2398 2399 /* 2400 * unserialize tx state machine 2401 */ 2402 int txState; 2403 UNSERIALIZE_SCALAR(txState); 2404 this->txState = (TxState) txState; 2405 UNSERIALIZE_SCALAR(txEnable); 2406 UNSERIALIZE_SCALAR(CTDD); 2407 UNSERIALIZE_SCALAR(txFragPtr); 2408 UNSERIALIZE_SCALAR(txDescCnt); 2409 int txDmaState; 2410 UNSERIALIZE_SCALAR(txDmaState); 2411 this->txDmaState = (DmaState) txDmaState; 2412 UNSERIALIZE_SCALAR(txKickTick); 2413 if (txKickTick) 2414 schedule(txKickEvent, txKickTick); 2415 2416 /* 2417 * unserialize rx state machine 2418 */ 2419 int rxState; 2420 UNSERIALIZE_SCALAR(rxState); 2421 this->rxState = (RxState) rxState; 2422 UNSERIALIZE_SCALAR(rxEnable); 2423 UNSERIALIZE_SCALAR(CRDD); 2424 UNSERIALIZE_SCALAR(rxPktBytes); 2425 UNSERIALIZE_SCALAR(rxFragPtr); 2426 UNSERIALIZE_SCALAR(rxDescCnt); 2427 int rxDmaState; 2428 UNSERIALIZE_SCALAR(rxDmaState); 2429 this->rxDmaState = (DmaState) rxDmaState; 2430 UNSERIALIZE_SCALAR(rxKickTick); 2431 if (rxKickTick) 2432 schedule(rxKickEvent, rxKickTick); 2433 2434 /* 2435 * Unserialize EEPROM state machine 2436 */ 2437 int eepromState; 2438 UNSERIALIZE_SCALAR(eepromState); 2439 this->eepromState = (EEPROMState) eepromState; 2440 UNSERIALIZE_SCALAR(eepromClk); 2441 UNSERIALIZE_SCALAR(eepromBitsToRx); 2442 UNSERIALIZE_SCALAR(eepromOpcode); 2443 UNSERIALIZE_SCALAR(eepromAddress); 2444 UNSERIALIZE_SCALAR(eepromData); 2445 2446 /* 2447 * If there's a pending transmit, reschedule it now 2448 */ 2449 Tick transmitTick; 2450 UNSERIALIZE_SCALAR(transmitTick); 2451 if (transmitTick) 2452 schedule(txEvent, curTick() + transmitTick); 2453 2454 /* 2455 * unserialize receive address filter settings 2456 */ 2457 UNSERIALIZE_SCALAR(rxFilterEnable); 2458 UNSERIALIZE_SCALAR(acceptBroadcast); 2459 UNSERIALIZE_SCALAR(acceptMulticast); 2460 UNSERIALIZE_SCALAR(acceptUnicast); 2461 UNSERIALIZE_SCALAR(acceptPerfect); 2462 UNSERIALIZE_SCALAR(acceptArp); 2463 UNSERIALIZE_SCALAR(multicastHashEnable); 2464 2465 /* 2466 * Keep track of pending interrupt status. 2467 */ 2468 UNSERIALIZE_SCALAR(intrTick); 2469 UNSERIALIZE_SCALAR(cpuPendingIntr); 2470 Tick intrEventTick; 2471 UNSERIALIZE_SCALAR(intrEventTick); 2472 if (intrEventTick) { 2473 intrEvent = new IntrEvent(this, true); 2474 schedule(intrEvent, intrEventTick); 2475 } 2476} 2477 2478NSGigE * 2479NSGigEParams::create() 2480{ 2481 return new NSGigE(this); 2482} 2483