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