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