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