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