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