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