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