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