ns_gige.cc revision 2760
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 * Lisa Hsu 30 */ 31 32/** @file 33 * Device module for modelling the National Semiconductor 34 * DP83820 ethernet controller. Does not support priority queueing 35 */ 36#include <deque> 37#include <string> 38 39#include "arch/alpha/ev5.hh" 40#include "base/inet.hh" 41#include "cpu/thread_context.hh" 42#include "dev/etherlink.hh" 43#include "dev/ns_gige.hh" 44#include "dev/pciconfigall.hh" 45#include "mem/packet.hh" 46#include "sim/builder.hh" 47#include "sim/debug.hh" 48#include "sim/host.hh" 49#include "sim/stats.hh" 50#include "sim/system.hh" 51 52const char *NsRxStateStrings[] = 53{ 54 "rxIdle", 55 "rxDescRefr", 56 "rxDescRead", 57 "rxFifoBlock", 58 "rxFragWrite", 59 "rxDescWrite", 60 "rxAdvance" 61}; 62 63const char *NsTxStateStrings[] = 64{ 65 "txIdle", 66 "txDescRefr", 67 "txDescRead", 68 "txFifoBlock", 69 "txFragRead", 70 "txDescWrite", 71 "txAdvance" 72}; 73 74const char *NsDmaState[] = 75{ 76 "dmaIdle", 77 "dmaReading", 78 "dmaWriting", 79 "dmaReadWaiting", 80 "dmaWriteWaiting" 81}; 82 83using namespace std; 84using namespace Net; 85using namespace TheISA; 86 87/////////////////////////////////////////////////////////////////////// 88// 89// NSGigE PCI Device 90// 91NSGigE::NSGigE(Params *p) 92 : PciDev(p), ioEnable(false), 93 txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), 94 txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), 95 txXferLen(0), rxXferLen(0), clock(p->clock), 96 txState(txIdle), txEnable(false), CTDD(false), 97 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), 98 rxEnable(false), CRDD(false), rxPktBytes(0), 99 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), 100 eepromState(eepromStart), rxDmaReadEvent(this), rxDmaWriteEvent(this), 101 txDmaReadEvent(this), txDmaWriteEvent(this), 102 dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free), 103 txDelay(p->tx_delay), rxDelay(p->rx_delay), 104 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this), 105 txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false), 106 acceptMulticast(false), acceptUnicast(false), 107 acceptPerfect(false), acceptArp(false), multicastHashEnable(false), 108 intrTick(0), cpuPendingIntr(false), 109 intrEvent(0), interface(0) 110{ 111 112 intrDelay = p->intr_delay; 113 dmaReadDelay = p->dma_read_delay; 114 dmaWriteDelay = p->dma_write_delay; 115 dmaReadFactor = p->dma_read_factor; 116 dmaWriteFactor = p->dma_write_factor; 117 118 regsReset(); 119 memcpy(&rom.perfectMatch, p->eaddr.bytes(), ETH_ADDR_LEN); 120 121 memset(&rxDesc32, 0, sizeof(rxDesc32)); 122 memset(&txDesc32, 0, sizeof(txDesc32)); 123 memset(&rxDesc64, 0, sizeof(rxDesc64)); 124 memset(&txDesc64, 0, sizeof(txDesc64)); 125} 126 127NSGigE::~NSGigE() 128{} 129 130void 131NSGigE::regStats() 132{ 133 txBytes 134 .name(name() + ".txBytes") 135 .desc("Bytes Transmitted") 136 .prereq(txBytes) 137 ; 138 139 rxBytes 140 .name(name() + ".rxBytes") 141 .desc("Bytes Received") 142 .prereq(rxBytes) 143 ; 144 145 txPackets 146 .name(name() + ".txPackets") 147 .desc("Number of Packets Transmitted") 148 .prereq(txBytes) 149 ; 150 151 rxPackets 152 .name(name() + ".rxPackets") 153 .desc("Number of Packets Received") 154 .prereq(rxBytes) 155 ; 156 157 txIpChecksums 158 .name(name() + ".txIpChecksums") 159 .desc("Number of tx IP Checksums done by device") 160 .precision(0) 161 .prereq(txBytes) 162 ; 163 164 rxIpChecksums 165 .name(name() + ".rxIpChecksums") 166 .desc("Number of rx IP Checksums done by device") 167 .precision(0) 168 .prereq(rxBytes) 169 ; 170 171 txTcpChecksums 172 .name(name() + ".txTcpChecksums") 173 .desc("Number of tx TCP Checksums done by device") 174 .precision(0) 175 .prereq(txBytes) 176 ; 177 178 rxTcpChecksums 179 .name(name() + ".rxTcpChecksums") 180 .desc("Number of rx TCP Checksums done by device") 181 .precision(0) 182 .prereq(rxBytes) 183 ; 184 185 txUdpChecksums 186 .name(name() + ".txUdpChecksums") 187 .desc("Number of tx UDP Checksums done by device") 188 .precision(0) 189 .prereq(txBytes) 190 ; 191 192 rxUdpChecksums 193 .name(name() + ".rxUdpChecksums") 194 .desc("Number of rx UDP Checksums done by device") 195 .precision(0) 196 .prereq(rxBytes) 197 ; 198 199 descDmaReads 200 .name(name() + ".descDMAReads") 201 .desc("Number of descriptors the device read w/ DMA") 202 .precision(0) 203 ; 204 205 descDmaWrites 206 .name(name() + ".descDMAWrites") 207 .desc("Number of descriptors the device wrote w/ DMA") 208 .precision(0) 209 ; 210 211 descDmaRdBytes 212 .name(name() + ".descDmaReadBytes") 213 .desc("number of descriptor bytes read w/ DMA") 214 .precision(0) 215 ; 216 217 descDmaWrBytes 218 .name(name() + ".descDmaWriteBytes") 219 .desc("number of descriptor bytes write w/ DMA") 220 .precision(0) 221 ; 222 223 txBandwidth 224 .name(name() + ".txBandwidth") 225 .desc("Transmit Bandwidth (bits/s)") 226 .precision(0) 227 .prereq(txBytes) 228 ; 229 230 rxBandwidth 231 .name(name() + ".rxBandwidth") 232 .desc("Receive Bandwidth (bits/s)") 233 .precision(0) 234 .prereq(rxBytes) 235 ; 236 237 totBandwidth 238 .name(name() + ".totBandwidth") 239 .desc("Total Bandwidth (bits/s)") 240 .precision(0) 241 .prereq(totBytes) 242 ; 243 244 totPackets 245 .name(name() + ".totPackets") 246 .desc("Total Packets") 247 .precision(0) 248 .prereq(totBytes) 249 ; 250 251 totBytes 252 .name(name() + ".totBytes") 253 .desc("Total Bytes") 254 .precision(0) 255 .prereq(totBytes) 256 ; 257 258 totPacketRate 259 .name(name() + ".totPPS") 260 .desc("Total Tranmission Rate (packets/s)") 261 .precision(0) 262 .prereq(totBytes) 263 ; 264 265 txPacketRate 266 .name(name() + ".txPPS") 267 .desc("Packet Tranmission Rate (packets/s)") 268 .precision(0) 269 .prereq(txBytes) 270 ; 271 272 rxPacketRate 273 .name(name() + ".rxPPS") 274 .desc("Packet Reception Rate (packets/s)") 275 .precision(0) 276 .prereq(rxBytes) 277 ; 278 279 postedSwi 280 .name(name() + ".postedSwi") 281 .desc("number of software interrupts posted to CPU") 282 .precision(0) 283 ; 284 285 totalSwi 286 .name(name() + ".totalSwi") 287 .desc("total number of Swi written to ISR") 288 .precision(0) 289 ; 290 291 coalescedSwi 292 .name(name() + ".coalescedSwi") 293 .desc("average number of Swi's coalesced into each post") 294 .precision(0) 295 ; 296 297 postedRxIdle 298 .name(name() + ".postedRxIdle") 299 .desc("number of rxIdle interrupts posted to CPU") 300 .precision(0) 301 ; 302 303 totalRxIdle 304 .name(name() + ".totalRxIdle") 305 .desc("total number of RxIdle written to ISR") 306 .precision(0) 307 ; 308 309 coalescedRxIdle 310 .name(name() + ".coalescedRxIdle") 311 .desc("average number of RxIdle's coalesced into each post") 312 .precision(0) 313 ; 314 315 postedRxOk 316 .name(name() + ".postedRxOk") 317 .desc("number of RxOk interrupts posted to CPU") 318 .precision(0) 319 ; 320 321 totalRxOk 322 .name(name() + ".totalRxOk") 323 .desc("total number of RxOk written to ISR") 324 .precision(0) 325 ; 326 327 coalescedRxOk 328 .name(name() + ".coalescedRxOk") 329 .desc("average number of RxOk's coalesced into each post") 330 .precision(0) 331 ; 332 333 postedRxDesc 334 .name(name() + ".postedRxDesc") 335 .desc("number of RxDesc interrupts posted to CPU") 336 .precision(0) 337 ; 338 339 totalRxDesc 340 .name(name() + ".totalRxDesc") 341 .desc("total number of RxDesc written to ISR") 342 .precision(0) 343 ; 344 345 coalescedRxDesc 346 .name(name() + ".coalescedRxDesc") 347 .desc("average number of RxDesc's coalesced into each post") 348 .precision(0) 349 ; 350 351 postedTxOk 352 .name(name() + ".postedTxOk") 353 .desc("number of TxOk interrupts posted to CPU") 354 .precision(0) 355 ; 356 357 totalTxOk 358 .name(name() + ".totalTxOk") 359 .desc("total number of TxOk written to ISR") 360 .precision(0) 361 ; 362 363 coalescedTxOk 364 .name(name() + ".coalescedTxOk") 365 .desc("average number of TxOk's coalesced into each post") 366 .precision(0) 367 ; 368 369 postedTxIdle 370 .name(name() + ".postedTxIdle") 371 .desc("number of TxIdle interrupts posted to CPU") 372 .precision(0) 373 ; 374 375 totalTxIdle 376 .name(name() + ".totalTxIdle") 377 .desc("total number of TxIdle written to ISR") 378 .precision(0) 379 ; 380 381 coalescedTxIdle 382 .name(name() + ".coalescedTxIdle") 383 .desc("average number of TxIdle's coalesced into each post") 384 .precision(0) 385 ; 386 387 postedTxDesc 388 .name(name() + ".postedTxDesc") 389 .desc("number of TxDesc interrupts posted to CPU") 390 .precision(0) 391 ; 392 393 totalTxDesc 394 .name(name() + ".totalTxDesc") 395 .desc("total number of TxDesc written to ISR") 396 .precision(0) 397 ; 398 399 coalescedTxDesc 400 .name(name() + ".coalescedTxDesc") 401 .desc("average number of TxDesc's coalesced into each post") 402 .precision(0) 403 ; 404 405 postedRxOrn 406 .name(name() + ".postedRxOrn") 407 .desc("number of RxOrn posted to CPU") 408 .precision(0) 409 ; 410 411 totalRxOrn 412 .name(name() + ".totalRxOrn") 413 .desc("total number of RxOrn written to ISR") 414 .precision(0) 415 ; 416 417 coalescedRxOrn 418 .name(name() + ".coalescedRxOrn") 419 .desc("average number of RxOrn's coalesced into each post") 420 .precision(0) 421 ; 422 423 coalescedTotal 424 .name(name() + ".coalescedTotal") 425 .desc("average number of interrupts coalesced into each post") 426 .precision(0) 427 ; 428 429 postedInterrupts 430 .name(name() + ".postedInterrupts") 431 .desc("number of posts to CPU") 432 .precision(0) 433 ; 434 435 droppedPackets 436 .name(name() + ".droppedPackets") 437 .desc("number of packets dropped") 438 .precision(0) 439 ; 440 441 coalescedSwi = totalSwi / postedInterrupts; 442 coalescedRxIdle = totalRxIdle / postedInterrupts; 443 coalescedRxOk = totalRxOk / postedInterrupts; 444 coalescedRxDesc = totalRxDesc / postedInterrupts; 445 coalescedTxOk = totalTxOk / postedInterrupts; 446 coalescedTxIdle = totalTxIdle / postedInterrupts; 447 coalescedTxDesc = totalTxDesc / postedInterrupts; 448 coalescedRxOrn = totalRxOrn / postedInterrupts; 449 450 coalescedTotal = (totalSwi + totalRxIdle + totalRxOk + totalRxDesc + 451 totalTxOk + totalTxIdle + totalTxDesc + 452 totalRxOrn) / postedInterrupts; 453 454 txBandwidth = txBytes * Stats::constant(8) / simSeconds; 455 rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; 456 totBandwidth = txBandwidth + rxBandwidth; 457 totBytes = txBytes + rxBytes; 458 totPackets = txPackets + rxPackets; 459 460 txPacketRate = txPackets / simSeconds; 461 rxPacketRate = rxPackets / simSeconds; 462} 463 464 465/** 466 * This is to write to the PCI general configuration registers 467 */ 468void 469NSGigE::writeConfig(int offset, const uint16_t data) 470{ 471 if (offset < PCI_DEVICE_SPECIFIC) 472 PciDev::writeConfig(offset, data); 473 else 474 panic("Device specific PCI config space not implemented!\n"); 475 476 switch (offset) { 477 // seems to work fine without all these PCI settings, but i 478 // put in the IO to double check, an assertion will fail if we 479 // need to properly implement it 480 case PCI_COMMAND: 481 if (config.data[offset] & PCI_CMD_IOSE) 482 ioEnable = true; 483 else 484 ioEnable = false; 485 break; 486 } 487} 488 489/** 490 * This reads the device registers, which are detailed in the NS83820 491 * spec sheet 492 */ 493Tick 494NSGigE::read(Packet *pkt) 495{ 496 assert(ioEnable); 497 498 pkt->allocate(); 499 500 //The mask is to give you only the offset into the device register file 501 Addr daddr = pkt->getAddr() & 0xfff; 502 DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n", 503 daddr, pkt->getAddr(), pkt->getSize()); 504 505 506 // there are some reserved registers, you can see ns_gige_reg.h and 507 // the spec sheet for details 508 if (daddr > LAST && daddr <= RESERVED) { 509 panic("Accessing reserved register"); 510 } else if (daddr > RESERVED && daddr <= 0x3FC) { 511 if (pkt->getSize() == sizeof(uint8_t)) 512 readConfig(daddr & 0xff, pkt->getPtr<uint8_t>()); 513 if (pkt->getSize() == sizeof(uint16_t)) 514 readConfig(daddr & 0xff, pkt->getPtr<uint16_t>()); 515 if (pkt->getSize() == sizeof(uint32_t)) 516 readConfig(daddr & 0xff, pkt->getPtr<uint32_t>()); 517 pkt->result = Packet::Success; 518 return pioDelay; 519 } else if (daddr >= MIB_START && daddr <= MIB_END) { 520 // don't implement all the MIB's. hopefully the kernel 521 // doesn't actually DEPEND upon their values 522 // MIB are just hardware stats keepers 523 pkt->set<uint32_t>(0); 524 pkt->result = Packet::Success; 525 return pioDelay; 526 } else if (daddr > 0x3FC) 527 panic("Something is messed up!\n"); 528 529 assert(pkt->getSize() == sizeof(uint32_t)); 530 uint32_t ® = *pkt->getPtr<uint32_t>(); 531 uint16_t rfaddr; 532 533 switch (daddr) { 534 case CR: 535 reg = regs.command; 536 //these are supposed to be cleared on a read 537 reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); 538 break; 539 540 case CFGR: 541 reg = regs.config; 542 break; 543 544 case MEAR: 545 reg = regs.mear; 546 break; 547 548 case PTSCR: 549 reg = regs.ptscr; 550 break; 551 552 case ISR: 553 reg = regs.isr; 554 devIntrClear(ISR_ALL); 555 break; 556 557 case IMR: 558 reg = regs.imr; 559 break; 560 561 case IER: 562 reg = regs.ier; 563 break; 564 565 case IHR: 566 reg = regs.ihr; 567 break; 568 569 case TXDP: 570 reg = regs.txdp; 571 break; 572 573 case TXDP_HI: 574 reg = regs.txdp_hi; 575 break; 576 577 case TX_CFG: 578 reg = regs.txcfg; 579 break; 580 581 case GPIOR: 582 reg = regs.gpior; 583 break; 584 585 case RXDP: 586 reg = regs.rxdp; 587 break; 588 589 case RXDP_HI: 590 reg = regs.rxdp_hi; 591 break; 592 593 case RX_CFG: 594 reg = regs.rxcfg; 595 break; 596 597 case PQCR: 598 reg = regs.pqcr; 599 break; 600 601 case WCSR: 602 reg = regs.wcsr; 603 break; 604 605 case PCR: 606 reg = regs.pcr; 607 break; 608 609 // see the spec sheet for how RFCR and RFDR work 610 // basically, you write to RFCR to tell the machine 611 // what you want to do next, then you act upon RFDR, 612 // and the device will be prepared b/c of what you 613 // wrote to RFCR 614 case RFCR: 615 reg = regs.rfcr; 616 break; 617 618 case RFDR: 619 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 620 switch (rfaddr) { 621 // Read from perfect match ROM octets 622 case 0x000: 623 reg = rom.perfectMatch[1]; 624 reg = reg << 8; 625 reg += rom.perfectMatch[0]; 626 break; 627 case 0x002: 628 reg = rom.perfectMatch[3] << 8; 629 reg += rom.perfectMatch[2]; 630 break; 631 case 0x004: 632 reg = rom.perfectMatch[5] << 8; 633 reg += rom.perfectMatch[4]; 634 break; 635 default: 636 // Read filter hash table 637 if (rfaddr >= FHASH_ADDR && 638 rfaddr < FHASH_ADDR + FHASH_SIZE) { 639 640 // Only word-aligned reads supported 641 if (rfaddr % 2) 642 panic("unaligned read from filter hash table!"); 643 644 reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; 645 reg += rom.filterHash[rfaddr - FHASH_ADDR]; 646 break; 647 } 648 649 panic("reading RFDR for something other than pattern" 650 " matching or hashing! %#x\n", rfaddr); 651 } 652 break; 653 654 case SRR: 655 reg = regs.srr; 656 break; 657 658 case MIBC: 659 reg = regs.mibc; 660 reg &= ~(MIBC_MIBS | MIBC_ACLR); 661 break; 662 663 case VRCR: 664 reg = regs.vrcr; 665 break; 666 667 case VTCR: 668 reg = regs.vtcr; 669 break; 670 671 case VDR: 672 reg = regs.vdr; 673 break; 674 675 case CCSR: 676 reg = regs.ccsr; 677 break; 678 679 case TBICR: 680 reg = regs.tbicr; 681 break; 682 683 case TBISR: 684 reg = regs.tbisr; 685 break; 686 687 case TANAR: 688 reg = regs.tanar; 689 break; 690 691 case TANLPAR: 692 reg = regs.tanlpar; 693 break; 694 695 case TANER: 696 reg = regs.taner; 697 break; 698 699 case TESR: 700 reg = regs.tesr; 701 break; 702 703 case M5REG: 704 reg = 0; 705 if (params()->rx_thread) 706 reg |= M5REG_RX_THREAD; 707 if (params()->tx_thread) 708 reg |= M5REG_TX_THREAD; 709 if (params()->rss) 710 reg |= M5REG_RSS; 711 break; 712 713 default: 714 panic("reading unimplemented register: addr=%#x", daddr); 715 } 716 717 DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", 718 daddr, reg, reg); 719 720 pkt->result = Packet::Success; 721 return pioDelay; 722} 723 724Tick 725NSGigE::write(Packet *pkt) 726{ 727 assert(ioEnable); 728 729 Addr daddr = pkt->getAddr() & 0xfff; 730 DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", 731 daddr, pkt->getAddr(), pkt->getSize()); 732 733 if (daddr > LAST && daddr <= RESERVED) { 734 panic("Accessing reserved register"); 735 } else if (daddr > RESERVED && daddr <= 0x3FC) { 736 if (pkt->getSize() == sizeof(uint8_t)) 737 writeConfig(daddr & 0xff, pkt->get<uint8_t>()); 738 if (pkt->getSize() == sizeof(uint16_t)) 739 writeConfig(daddr & 0xff, pkt->get<uint16_t>()); 740 if (pkt->getSize() == sizeof(uint32_t)) 741 writeConfig(daddr & 0xff, pkt->get<uint32_t>()); 742 pkt->result = Packet::Success; 743 return pioDelay; 744 } else if (daddr > 0x3FC) 745 panic("Something is messed up!\n"); 746 747 if (pkt->getSize() == 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 = Packet::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