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