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