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