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