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