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