1/* 2 * Copyright (c) 2004-2005 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 * Authors: Nathan Binkert 29 * Lisa Hsu 30 */ 31 32/** @file 33 * Device module for modelling the National Semiconductor 34 * DP83820 ethernet controller. Does not support priority queueing 35 */ 36 37#include "dev/net/ns_gige.hh" 38 39#include <deque> 40#include <memory> 41#include <string> 42 43#include "base/debug.hh" 44#include "base/inet.hh" 45#include "base/types.hh" 46#include "config/the_isa.hh" 47#include "debug/EthernetAll.hh" 48#include "dev/net/etherlink.hh" 49#include "mem/packet.hh" 50#include "mem/packet_access.hh" 51#include "params/NSGigE.hh" 52#include "sim/system.hh" 53 54// clang complains about std::set being overloaded with Packet::set if 55// we open up the entire namespace std 56using std::make_shared; 57using std::min; 58using std::ostream; 59using std::string; 60 61const char *NsRxStateStrings[] = 62{ 63 "rxIdle", 64 "rxDescRefr", 65 "rxDescRead", 66 "rxFifoBlock", 67 "rxFragWrite", 68 "rxDescWrite", 69 "rxAdvance" 70}; 71 72const char *NsTxStateStrings[] = 73{ 74 "txIdle", 75 "txDescRefr", 76 "txDescRead", 77 "txFifoBlock", 78 "txFragRead", 79 "txDescWrite", 80 "txAdvance" 81}; 82 83const char *NsDmaState[] = 84{ 85 "dmaIdle", 86 "dmaReading", 87 "dmaWriting", 88 "dmaReadWaiting", 89 "dmaWriteWaiting" 90}; 91 92using namespace Net; 93using namespace TheISA; 94 95/////////////////////////////////////////////////////////////////////// 96// 97// NSGigE PCI Device 98// 99NSGigE::NSGigE(Params *p) 100 : EtherDevBase(p), ioEnable(false), 101 txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), 102 txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), 103 txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false), 104 txState(txIdle), txEnable(false), CTDD(false), txHalt(false), 105 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), 106 rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false), 107 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), 108 eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0), 109 eepromOpcode(0), eepromAddress(0), eepromData(0), 110 dmaReadDelay(p->dma_read_delay), dmaWriteDelay(p->dma_write_delay), 111 dmaReadFactor(p->dma_read_factor), dmaWriteFactor(p->dma_write_factor), 112 rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0), 113 txDmaData(NULL), txDmaAddr(0), txDmaLen(0), 114 rxDmaReadEvent(this), rxDmaWriteEvent(this), 115 txDmaReadEvent(this), txDmaWriteEvent(this), 116 dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free), 117 txDelay(p->tx_delay), rxDelay(p->rx_delay), 118 rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this), 119 txEvent(this), rxFilterEnable(p->rx_filter), 120 acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false), 121 acceptPerfect(false), acceptArp(false), multicastHashEnable(false), 122 intrDelay(p->intr_delay), intrTick(0), cpuPendingIntr(false), 123 intrEvent(0), interface(0) 124{ 125 126 127 interface = new NSGigEInt(name() + ".int0", this); 128 129 regsReset(); 130 memcpy(&rom.perfectMatch, p->hardware_address.bytes(), ETH_ADDR_LEN); 131 132 memset(&rxDesc32, 0, sizeof(rxDesc32)); 133 memset(&txDesc32, 0, sizeof(txDesc32)); 134 memset(&rxDesc64, 0, sizeof(rxDesc64)); 135 memset(&txDesc64, 0, sizeof(txDesc64)); 136} 137 138NSGigE::~NSGigE() 139{ 140 delete interface; 141} 142 143/** 144 * This is to write to the PCI general configuration registers 145 */ 146Tick 147NSGigE::writeConfig(PacketPtr pkt) 148{ 149 int offset = pkt->getAddr() & PCI_CONFIG_SIZE; 150 if (offset < PCI_DEVICE_SPECIFIC) 151 PciDevice::writeConfig(pkt); 152 else 153 panic("Device specific PCI config space not implemented!\n"); 154 155 switch (offset) { 156 // seems to work fine without all these PCI settings, but i 157 // put in the IO to double check, an assertion will fail if we 158 // need to properly implement it 159 case PCI_COMMAND: 160 if (config.data[offset] & PCI_CMD_IOSE) 161 ioEnable = true; 162 else 163 ioEnable = false; 164 break; 165 } 166 167 return configDelay; 168} 169 170EtherInt* 171NSGigE::getEthPort(const std::string &if_name, int idx) 172{ 173 if (if_name == "interface") { 174 if (interface->getPeer()) 175 panic("interface already connected to\n"); 176 return interface; 177 } 178 return NULL; 179} 180 181/** 182 * This reads the device registers, which are detailed in the NS83820 183 * spec sheet 184 */ 185Tick 186NSGigE::read(PacketPtr pkt) 187{ 188 assert(ioEnable); 189 190 //The mask is to give you only the offset into the device register file 191 Addr daddr = pkt->getAddr() & 0xfff; 192 DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n", 193 daddr, pkt->getAddr(), pkt->getSize()); 194 195 196 // there are some reserved registers, you can see ns_gige_reg.h and 197 // the spec sheet for details 198 if (daddr > LAST && daddr <= RESERVED) { 199 panic("Accessing reserved register"); 200 } else if (daddr > RESERVED && daddr <= 0x3FC) { 201 return readConfig(pkt); 202 } else if (daddr >= MIB_START && daddr <= MIB_END) { 203 // don't implement all the MIB's. hopefully the kernel 204 // doesn't actually DEPEND upon their values 205 // MIB are just hardware stats keepers 206 pkt->set<uint32_t>(0); 207 pkt->makeAtomicResponse(); 208 return pioDelay; 209 } else if (daddr > 0x3FC) 210 panic("Something is messed up!\n"); 211 212 assert(pkt->getSize() == sizeof(uint32_t)); 213 uint32_t ® = *pkt->getPtr<uint32_t>(); 214 uint16_t rfaddr; 215 216 switch (daddr) { 217 case CR: 218 reg = regs.command; 219 //these are supposed to be cleared on a read 220 reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); 221 break; 222 223 case CFGR: 224 reg = regs.config; 225 break; 226 227 case MEAR: 228 reg = regs.mear; 229 break; 230 231 case PTSCR: 232 reg = regs.ptscr; 233 break; 234 235 case ISR: 236 reg = regs.isr; 237 devIntrClear(ISR_ALL); 238 break; 239 240 case IMR: 241 reg = regs.imr; 242 break; 243 244 case IER: 245 reg = regs.ier; 246 break; 247 248 case IHR: 249 reg = regs.ihr; 250 break; 251 252 case TXDP: 253 reg = regs.txdp; 254 break; 255 256 case TXDP_HI: 257 reg = regs.txdp_hi; 258 break; 259 260 case TX_CFG: 261 reg = regs.txcfg; 262 break; 263 264 case GPIOR: 265 reg = regs.gpior; 266 break; 267 268 case RXDP: 269 reg = regs.rxdp; 270 break; 271 272 case RXDP_HI: 273 reg = regs.rxdp_hi; 274 break; 275 276 case RX_CFG: 277 reg = regs.rxcfg; 278 break; 279 280 case PQCR: 281 reg = regs.pqcr; 282 break; 283 284 case WCSR: 285 reg = regs.wcsr; 286 break; 287 288 case PCR: 289 reg = regs.pcr; 290 break; 291 292 // see the spec sheet for how RFCR and RFDR work 293 // basically, you write to RFCR to tell the machine 294 // what you want to do next, then you act upon RFDR, 295 // and the device will be prepared b/c of what you 296 // wrote to RFCR 297 case RFCR: 298 reg = regs.rfcr; 299 break; 300 301 case RFDR: 302 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 303 switch (rfaddr) { 304 // Read from perfect match ROM octets 305 case 0x000: 306 reg = rom.perfectMatch[1]; 307 reg = reg << 8; 308 reg += rom.perfectMatch[0]; 309 break; 310 case 0x002: 311 reg = rom.perfectMatch[3] << 8; 312 reg += rom.perfectMatch[2]; 313 break; 314 case 0x004: 315 reg = rom.perfectMatch[5] << 8; 316 reg += rom.perfectMatch[4]; 317 break; 318 default: 319 // Read filter hash table 320 if (rfaddr >= FHASH_ADDR && 321 rfaddr < FHASH_ADDR + FHASH_SIZE) { 322 323 // Only word-aligned reads supported 324 if (rfaddr % 2) 325 panic("unaligned read from filter hash table!"); 326 327 reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; 328 reg += rom.filterHash[rfaddr - FHASH_ADDR]; 329 break; 330 } 331 332 panic("reading RFDR for something other than pattern" 333 " matching or hashing! %#x\n", rfaddr); 334 } 335 break; 336 337 case SRR: 338 reg = regs.srr; 339 break; 340 341 case MIBC: 342 reg = regs.mibc; 343 reg &= ~(MIBC_MIBS | MIBC_ACLR); 344 break; 345 346 case VRCR: 347 reg = regs.vrcr; 348 break; 349 350 case VTCR: 351 reg = regs.vtcr; 352 break; 353 354 case VDR: 355 reg = regs.vdr; 356 break; 357 358 case CCSR: 359 reg = regs.ccsr; 360 break; 361 362 case TBICR: 363 reg = regs.tbicr; 364 break; 365 366 case TBISR: 367 reg = regs.tbisr; 368 break; 369 370 case TANAR: 371 reg = regs.tanar; 372 break; 373 374 case TANLPAR: 375 reg = regs.tanlpar; 376 break; 377 378 case TANER: 379 reg = regs.taner; 380 break; 381 382 case TESR: 383 reg = regs.tesr; 384 break; 385 386 case M5REG: 387 reg = 0; 388 if (params()->rx_thread) 389 reg |= M5REG_RX_THREAD; 390 if (params()->tx_thread) 391 reg |= M5REG_TX_THREAD; 392 if (params()->rss) 393 reg |= M5REG_RSS; 394 break; 395 396 default: 397 panic("reading unimplemented register: addr=%#x", daddr); 398 } 399 400 DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", 401 daddr, reg, reg); 402 403 pkt->makeAtomicResponse(); 404 return pioDelay; 405} 406 407Tick 408NSGigE::write(PacketPtr pkt) 409{ 410 assert(ioEnable); 411 412 Addr daddr = pkt->getAddr() & 0xfff; 413 DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", 414 daddr, pkt->getAddr(), pkt->getSize()); 415 416 if (daddr > LAST && daddr <= RESERVED) { 417 panic("Accessing reserved register"); 418 } else if (daddr > RESERVED && daddr <= 0x3FC) { 419 return writeConfig(pkt); 420 } else if (daddr > 0x3FC) 421 panic("Something is messed up!\n"); 422 423 if (pkt->getSize() == sizeof(uint32_t)) { 424 uint32_t reg = pkt->get<uint32_t>(); 425 uint16_t rfaddr; 426 427 DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg); 428 429 switch (daddr) { 430 case CR: 431 regs.command = reg; 432 if (reg & CR_TXD) { 433 txEnable = false; 434 } else if (reg & CR_TXE) { 435 txEnable = true; 436 437 // the kernel is enabling the transmit machine 438 if (txState == txIdle) 439 txKick(); 440 } 441 442 if (reg & CR_RXD) { 443 rxEnable = false; 444 } else if (reg & CR_RXE) { 445 rxEnable = true; 446 447 if (rxState == rxIdle) 448 rxKick(); 449 } 450 451 if (reg & CR_TXR) 452 txReset(); 453 454 if (reg & CR_RXR) 455 rxReset(); 456 457 if (reg & CR_SWI) 458 devIntrPost(ISR_SWI); 459 460 if (reg & CR_RST) { 461 txReset(); 462 rxReset(); 463 464 regsReset(); 465 } 466 break; 467 468 case CFGR: 469 if (reg & CFGR_LNKSTS || 470 reg & CFGR_SPDSTS || 471 reg & CFGR_DUPSTS || 472 reg & CFGR_RESERVED || 473 reg & CFGR_T64ADDR || 474 reg & CFGR_PCI64_DET) { 475 // First clear all writable bits 476 regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | 477 CFGR_RESERVED | CFGR_T64ADDR | 478 CFGR_PCI64_DET; 479 // Now set the appropriate writable bits 480 regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | 481 CFGR_RESERVED | CFGR_T64ADDR | 482 CFGR_PCI64_DET); 483 } 484 485// all these #if 0's are because i don't THINK the kernel needs to 486// have these implemented. if there is a problem relating to one of 487// these, you may need to add functionality in. 488 489// grouped together and #if 0'ed to avoid empty if body and make clang happy 490#if 0 491 if (reg & CFGR_TBI_EN) ; 492 if (reg & CFGR_MODE_1000) ; 493 494 if (reg & CFGR_PINT_DUPSTS || 495 reg & CFGR_PINT_LNKSTS || 496 reg & CFGR_PINT_SPDSTS) 497 ; 498 499 if (reg & CFGR_TMRTEST) ; 500 if (reg & CFGR_MRM_DIS) ; 501 if (reg & CFGR_MWI_DIS) ; 502 503 if (reg & CFGR_DATA64_EN) ; 504 if (reg & CFGR_M64ADDR) ; 505 if (reg & CFGR_PHY_RST) ; 506 if (reg & CFGR_PHY_DIS) ; 507 508 if (reg & CFGR_REQALG) ; 509 if (reg & CFGR_SB) ; 510 if (reg & CFGR_POW) ; 511 if (reg & CFGR_EXD) ; 512 if (reg & CFGR_PESEL) ; 513 if (reg & CFGR_BROM_DIS) ; 514 if (reg & CFGR_EXT_125) ; 515 if (reg & CFGR_BEM) ; 516 517 if (reg & CFGR_T64ADDR) ; 518 // panic("CFGR_T64ADDR is read only register!\n"); 519#endif 520 if (reg & CFGR_AUTO_1000) 521 panic("CFGR_AUTO_1000 not implemented!\n"); 522 523 if (reg & CFGR_PCI64_DET) 524 panic("CFGR_PCI64_DET is read only register!\n"); 525 526 if (reg & CFGR_EXTSTS_EN) 527 extstsEnable = true; 528 else 529 extstsEnable = false; 530 break; 531 532 case MEAR: 533 // Clear writable bits 534 regs.mear &= MEAR_EEDO; 535 // Set appropriate writable bits 536 regs.mear |= reg & ~MEAR_EEDO; 537 538 // FreeBSD uses the EEPROM to read PMATCH (for the MAC address) 539 // even though it could get it through RFDR 540 if (reg & MEAR_EESEL) { 541 // Rising edge of clock 542 if (reg & MEAR_EECLK && !eepromClk) 543 eepromKick(); 544 } 545 else { 546 eepromState = eepromStart; 547 regs.mear &= ~MEAR_EEDI; 548 } 549 550 eepromClk = reg & MEAR_EECLK; 551 552 // since phy is completely faked, MEAR_MD* don't matter 553 554// grouped together and #if 0'ed to avoid empty if body and make clang happy 555#if 0 556 if (reg & MEAR_MDIO) ; 557 if (reg & MEAR_MDDIR) ; 558 if (reg & MEAR_MDC) ; 559#endif 560 break; 561 562 case PTSCR: 563 regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY); 564 // these control BISTs for various parts of chip - we 565 // don't care or do just fake that the BIST is done 566 if (reg & PTSCR_RBIST_EN) 567 regs.ptscr |= PTSCR_RBIST_DONE; 568 if (reg & PTSCR_EEBIST_EN) 569 regs.ptscr &= ~PTSCR_EEBIST_EN; 570 if (reg & PTSCR_EELOAD_EN) 571 regs.ptscr &= ~PTSCR_EELOAD_EN; 572 break; 573 574 case ISR: /* writing to the ISR has no effect */ 575 panic("ISR is a read only register!\n"); 576 577 case IMR: 578 regs.imr = reg; 579 devIntrChangeMask(); 580 break; 581 582 case IER: 583 regs.ier = reg; 584 break; 585 586 case IHR: 587 regs.ihr = reg; 588 /* not going to implement real interrupt holdoff */ 589 break; 590 591 case TXDP: 592 regs.txdp = (reg & 0xFFFFFFFC); 593 assert(txState == txIdle); 594 CTDD = false; 595 break; 596 597 case TXDP_HI: 598 regs.txdp_hi = reg; 599 break; 600 601 case TX_CFG: 602 regs.txcfg = reg; 603#if 0 604 if (reg & TX_CFG_CSI) ; 605 if (reg & TX_CFG_HBI) ; 606 if (reg & TX_CFG_MLB) ; 607 if (reg & TX_CFG_ATP) ; 608 if (reg & TX_CFG_ECRETRY) { 609 /* 610 * this could easily be implemented, but considering 611 * the network is just a fake pipe, wouldn't make 612 * sense to do this 613 */ 614 } 615 616 if (reg & TX_CFG_BRST_DIS) ; 617#endif 618 619#if 0 620 /* we handle our own DMA, ignore the kernel's exhortations */ 621 if (reg & TX_CFG_MXDMA) ; 622#endif 623 624 // also, we currently don't care about fill/drain 625 // thresholds though this may change in the future with 626 // more realistic networks or a driver which changes it 627 // according to feedback 628 629 break; 630 631 case GPIOR: 632 // Only write writable bits 633 regs.gpior &= GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN 634 | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN; 635 regs.gpior |= reg & ~(GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN 636 | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN); 637 /* these just control general purpose i/o pins, don't matter */ 638 break; 639 640 case RXDP: 641 regs.rxdp = reg; 642 CRDD = false; 643 break; 644 645 case RXDP_HI: 646 regs.rxdp_hi = reg; 647 break; 648 649 case RX_CFG: 650 regs.rxcfg = reg; 651#if 0 652 if (reg & RX_CFG_AEP) ; 653 if (reg & RX_CFG_ARP) ; 654 if (reg & RX_CFG_STRIPCRC) ; 655 if (reg & RX_CFG_RX_RD) ; 656 if (reg & RX_CFG_ALP) ; 657 if (reg & RX_CFG_AIRL) ; 658 659 /* we handle our own DMA, ignore what kernel says about it */ 660 if (reg & RX_CFG_MXDMA) ; 661 662 //also, we currently don't care about fill/drain thresholds 663 //though this may change in the future with more realistic 664 //networks or a driver which changes it according to feedback 665 if (reg & (RX_CFG_DRTH | RX_CFG_DRTH0)) ; 666#endif 667 break; 668 669 case PQCR: 670 /* there is no priority queueing used in the linux 2.6 driver */ 671 regs.pqcr = reg; 672 break; 673 674 case WCSR: 675 /* not going to implement wake on LAN */ 676 regs.wcsr = reg; 677 break; 678 679 case PCR: 680 /* not going to implement pause control */ 681 regs.pcr = reg; 682 break; 683 684 case RFCR: 685 regs.rfcr = reg; 686 687 rxFilterEnable = (reg & RFCR_RFEN) ? true : false; 688 acceptBroadcast = (reg & RFCR_AAB) ? true : false; 689 acceptMulticast = (reg & RFCR_AAM) ? true : false; 690 acceptUnicast = (reg & RFCR_AAU) ? true : false; 691 acceptPerfect = (reg & RFCR_APM) ? true : false; 692 acceptArp = (reg & RFCR_AARP) ? true : false; 693 multicastHashEnable = (reg & RFCR_MHEN) ? true : false; 694 695#if 0 696 if (reg & RFCR_APAT) 697 panic("RFCR_APAT not implemented!\n"); 698#endif 699 if (reg & RFCR_UHEN) 700 panic("Unicast hash filtering not used by drivers!\n"); 701 702 if (reg & RFCR_ULM) 703 panic("RFCR_ULM not implemented!\n"); 704 705 break; 706 707 case RFDR: 708 rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); 709 switch (rfaddr) { 710 case 0x000: 711 rom.perfectMatch[0] = (uint8_t)reg; 712 rom.perfectMatch[1] = (uint8_t)(reg >> 8); 713 break; 714 case 0x002: 715 rom.perfectMatch[2] = (uint8_t)reg; 716 rom.perfectMatch[3] = (uint8_t)(reg >> 8); 717 break; 718 case 0x004: 719 rom.perfectMatch[4] = (uint8_t)reg; 720 rom.perfectMatch[5] = (uint8_t)(reg >> 8); 721 break; 722 default: 723 724 if (rfaddr >= FHASH_ADDR && 725 rfaddr < FHASH_ADDR + FHASH_SIZE) { 726 727 // Only word-aligned writes supported 728 if (rfaddr % 2) 729 panic("unaligned write to filter hash table!"); 730 731 rom.filterHash[rfaddr - FHASH_ADDR] = (uint8_t)reg; 732 rom.filterHash[rfaddr - FHASH_ADDR + 1] 733 = (uint8_t)(reg >> 8); 734 break; 735 } 736 panic("writing RFDR for something other than pattern matching " 737 "or hashing! %#x\n", rfaddr); 738 } 739 740 case BRAR: 741 regs.brar = reg; 742 break; 743 744 case BRDR: 745 panic("the driver never uses BRDR, something is wrong!\n"); 746 747 case SRR: 748 panic("SRR is read only register!\n"); 749 750 case MIBC: 751 panic("the driver never uses MIBC, something is wrong!\n"); 752 753 case VRCR: 754 regs.vrcr = reg; 755 break; 756 757 case VTCR: 758 regs.vtcr = reg; 759 break; 760 761 case VDR: 762 panic("the driver never uses VDR, something is wrong!\n"); 763 764 case CCSR: 765 /* not going to implement clockrun stuff */ 766 regs.ccsr = reg; 767 break; 768 769 case TBICR: 770 regs.tbicr = reg; 771 if (reg & TBICR_MR_LOOPBACK) 772 panic("TBICR_MR_LOOPBACK never used, something wrong!\n"); 773 774 if (reg & TBICR_MR_AN_ENABLE) { 775 regs.tanlpar = regs.tanar; 776 regs.tbisr |= (TBISR_MR_AN_COMPLETE | TBISR_MR_LINK_STATUS); 777 } 778 779#if 0 780 if (reg & TBICR_MR_RESTART_AN) ; 781#endif 782 783 break; 784 785 case TBISR: 786 panic("TBISR is read only register!\n"); 787 788 case TANAR: 789 // Only write the writable bits 790 regs.tanar &= TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED; 791 regs.tanar |= reg & ~(TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED); 792 793 // Pause capability unimplemented 794#if 0 795 if (reg & TANAR_PS2) ; 796 if (reg & TANAR_PS1) ; 797#endif 798 799 break; 800 801 case TANLPAR: 802 panic("this should only be written to by the fake phy!\n"); 803 804 case TANER: 805 panic("TANER is read only register!\n"); 806 807 case TESR: 808 regs.tesr = reg; 809 break; 810 811 default: 812 panic("invalid register access daddr=%#x", daddr); 813 } 814 } else { 815 panic("Invalid Request Size"); 816 } 817 pkt->makeAtomicResponse(); 818 return pioDelay; 819} 820 821void 822NSGigE::devIntrPost(uint32_t interrupts) 823{ 824 if (interrupts & ISR_RESERVE) 825 panic("Cannot set a reserved interrupt"); 826 827 if (interrupts & ISR_NOIMPL) 828 warn("interrupt not implemented %#x\n", interrupts); 829 830 interrupts &= ISR_IMPL; 831 regs.isr |= interrupts; 832 833 if (interrupts & regs.imr) { 834 if (interrupts & ISR_SWI) { 835 totalSwi++; 836 } 837 if (interrupts & ISR_RXIDLE) { 838 totalRxIdle++; 839 } 840 if (interrupts & ISR_RXOK) { 841 totalRxOk++; 842 } 843 if (interrupts & ISR_RXDESC) { 844 totalRxDesc++; 845 } 846 if (interrupts & ISR_TXOK) { 847 totalTxOk++; 848 } 849 if (interrupts & ISR_TXIDLE) { 850 totalTxIdle++; 851 } 852 if (interrupts & ISR_TXDESC) { 853 totalTxDesc++; 854 } 855 if (interrupts & ISR_RXORN) { 856 totalRxOrn++; 857 } 858 } 859 860 DPRINTF(EthernetIntr, 861 "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n", 862 interrupts, regs.isr, regs.imr); 863 864 if ((regs.isr & regs.imr)) { 865 Tick when = curTick(); 866 if ((regs.isr & regs.imr & ISR_NODELAY) == 0) 867 when += intrDelay; 868 postedInterrupts++; 869 cpuIntrPost(when); 870 } 871} 872 873/* writing this interrupt counting stats inside this means that this function 874 is now limited to being used to clear all interrupts upon the kernel 875 reading isr and servicing. just telling you in case you were thinking 876 of expanding use. 877*/ 878void 879NSGigE::devIntrClear(uint32_t interrupts) 880{ 881 if (interrupts & ISR_RESERVE) 882 panic("Cannot clear a reserved interrupt"); 883 884 if (regs.isr & regs.imr & ISR_SWI) { 885 postedSwi++; 886 } 887 if (regs.isr & regs.imr & ISR_RXIDLE) { 888 postedRxIdle++; 889 } 890 if (regs.isr & regs.imr & ISR_RXOK) { 891 postedRxOk++; 892 } 893 if (regs.isr & regs.imr & ISR_RXDESC) { 894 postedRxDesc++; 895 } 896 if (regs.isr & regs.imr & ISR_TXOK) { 897 postedTxOk++; 898 } 899 if (regs.isr & regs.imr & ISR_TXIDLE) { 900 postedTxIdle++; 901 } 902 if (regs.isr & regs.imr & ISR_TXDESC) { 903 postedTxDesc++; 904 } 905 if (regs.isr & regs.imr & ISR_RXORN) { 906 postedRxOrn++; 907 } 908 909 interrupts &= ~ISR_NOIMPL; 910 regs.isr &= ~interrupts; 911 912 DPRINTF(EthernetIntr, 913 "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n", 914 interrupts, regs.isr, regs.imr); 915 916 if (!(regs.isr & regs.imr)) 917 cpuIntrClear(); 918} 919 920void 921NSGigE::devIntrChangeMask() 922{ 923 DPRINTF(EthernetIntr, "interrupt mask changed: isr=%x imr=%x masked=%x\n", 924 regs.isr, regs.imr, regs.isr & regs.imr); 925 926 if (regs.isr & regs.imr) 927 cpuIntrPost(curTick()); 928 else 929 cpuIntrClear(); 930} 931 932void 933NSGigE::cpuIntrPost(Tick when) 934{ 935 // If the interrupt you want to post is later than an interrupt 936 // already scheduled, just let it post in the coming one and don't 937 // schedule another. 938 // HOWEVER, must be sure that the scheduled intrTick is in the 939 // future (this was formerly the source of a bug) 940 /** 941 * @todo this warning should be removed and the intrTick code should 942 * be fixed. 943 */ 944 assert(when >= curTick()); 945 assert(intrTick >= curTick() || intrTick == 0); 946 if (when > intrTick && intrTick != 0) { 947 DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n", 948 intrTick); 949 return; 950 } 951 952 intrTick = when; 953 if (intrTick < curTick()) { 954 intrTick = curTick(); 955 } 956 957 DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n", 958 intrTick); 959 960 if (intrEvent) 961 intrEvent->squash(); 962 intrEvent = new IntrEvent(this, true); 963 schedule(intrEvent, intrTick); 964} 965 966void 967NSGigE::cpuInterrupt() 968{ 969 assert(intrTick == curTick()); 970 971 // Whether or not there's a pending interrupt, we don't care about 972 // it anymore 973 intrEvent = 0; 974 intrTick = 0; 975 976 // Don't send an interrupt if there's already one 977 if (cpuPendingIntr) { 978 DPRINTF(EthernetIntr, 979 "would send an interrupt now, but there's already pending\n"); 980 } else { 981 // Send interrupt 982 cpuPendingIntr = true; 983 984 DPRINTF(EthernetIntr, "posting interrupt\n"); 985 intrPost(); 986 } 987} 988 989void 990NSGigE::cpuIntrClear() 991{ 992 if (!cpuPendingIntr) 993 return; 994 995 if (intrEvent) { 996 intrEvent->squash(); 997 intrEvent = 0; 998 } 999 1000 intrTick = 0; 1001 1002 cpuPendingIntr = false; 1003 1004 DPRINTF(EthernetIntr, "clearing interrupt\n"); 1005 intrClear(); 1006} 1007 1008bool 1009NSGigE::cpuIntrPending() const 1010{ return cpuPendingIntr; } 1011 1012void 1013NSGigE::txReset() 1014{ 1015 1016 DPRINTF(Ethernet, "transmit reset\n"); 1017 1018 CTDD = false; 1019 txEnable = false;; 1020 txFragPtr = 0; 1021 assert(txDescCnt == 0); 1022 txFifo.clear(); 1023 txState = txIdle; 1024 assert(txDmaState == dmaIdle); 1025} 1026 1027void 1028NSGigE::rxReset() 1029{ 1030 DPRINTF(Ethernet, "receive reset\n"); 1031 1032 CRDD = false; 1033 assert(rxPktBytes == 0); 1034 rxEnable = false; 1035 rxFragPtr = 0; 1036 assert(rxDescCnt == 0); 1037 assert(rxDmaState == dmaIdle); 1038 rxFifo.clear(); 1039 rxState = rxIdle; 1040} 1041 1042void 1043NSGigE::regsReset() 1044{ 1045 memset(®s, 0, sizeof(regs)); 1046 regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000); 1047 regs.mear = 0x12; 1048 regs.txcfg = 0x120; // set drain threshold to 1024 bytes and 1049 // fill threshold to 32 bytes 1050 regs.rxcfg = 0x4; // set drain threshold to 16 bytes 1051 regs.srr = 0x0103; // set the silicon revision to rev B or 0x103 1052 regs.mibc = MIBC_FRZ; 1053 regs.vdr = 0x81; // set the vlan tag type to 802.1q 1054 regs.tesr = 0xc000; // TBI capable of both full and half duplex 1055 regs.brar = 0xffffffff; 1056 1057 extstsEnable = false; 1058 acceptBroadcast = false; 1059 acceptMulticast = false; 1060 acceptUnicast = false; 1061 acceptPerfect = false; 1062 acceptArp = false; 1063} 1064 1065bool 1066NSGigE::doRxDmaRead() 1067{ 1068 assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); 1069 rxDmaState = dmaReading; 1070 1071 if (dmaPending() || drainState() != DrainState::Running) 1072 rxDmaState = dmaReadWaiting; 1073 else 1074 dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData); 1075 1076 return true; 1077} 1078 1079void 1080NSGigE::rxDmaReadDone() 1081{ 1082 assert(rxDmaState == dmaReading); 1083 rxDmaState = dmaIdle; 1084 1085 DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", 1086 rxDmaAddr, rxDmaLen); 1087 DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 1088 1089 // If the transmit state machine has a pending DMA, let it go first 1090 if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 1091 txKick(); 1092 1093 rxKick(); 1094} 1095 1096bool 1097NSGigE::doRxDmaWrite() 1098{ 1099 assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); 1100 rxDmaState = dmaWriting; 1101 1102 if (dmaPending() || drainState() != DrainState::Running) 1103 rxDmaState = dmaWriteWaiting; 1104 else 1105 dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData); 1106 return true; 1107} 1108 1109void 1110NSGigE::rxDmaWriteDone() 1111{ 1112 assert(rxDmaState == dmaWriting); 1113 rxDmaState = dmaIdle; 1114 1115 DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", 1116 rxDmaAddr, rxDmaLen); 1117 DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 1118 1119 // If the transmit state machine has a pending DMA, let it go first 1120 if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 1121 txKick(); 1122 1123 rxKick(); 1124} 1125 1126void 1127NSGigE::rxKick() 1128{ 1129 bool is64bit = (bool)(regs.config & CFGR_M64ADDR); 1130 1131 DPRINTF(EthernetSM, 1132 "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n", 1133 NsRxStateStrings[rxState], rxFifo.size(), is64bit ? 64 : 32); 1134 1135 Addr link, bufptr; 1136 uint32_t &cmdsts = is64bit ? rxDesc64.cmdsts : rxDesc32.cmdsts; 1137 uint32_t &extsts = is64bit ? rxDesc64.extsts : rxDesc32.extsts; 1138 1139 next: 1140 if (rxKickTick > curTick()) { 1141 DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n", 1142 rxKickTick); 1143 1144 goto exit; 1145 } 1146 1147 // Go to the next state machine clock tick. 1148 rxKickTick = clockEdge(Cycles(1)); 1149 1150 switch(rxDmaState) { 1151 case dmaReadWaiting: 1152 if (doRxDmaRead()) 1153 goto exit; 1154 break; 1155 case dmaWriteWaiting: 1156 if (doRxDmaWrite()) 1157 goto exit; 1158 break; 1159 default: 1160 break; 1161 } 1162 1163 link = is64bit ? (Addr)rxDesc64.link : (Addr)rxDesc32.link; 1164 bufptr = is64bit ? (Addr)rxDesc64.bufptr : (Addr)rxDesc32.bufptr; 1165 1166 // see state machine from spec for details 1167 // the way this works is, if you finish work on one state and can 1168 // go directly to another, you do that through jumping to the 1169 // label "next". however, if you have intermediate work, like DMA 1170 // so that you can't go to the next state yet, you go to exit and 1171 // exit the loop. however, when the DMA is done it will trigger 1172 // an event and come back to this loop. 1173 switch (rxState) { 1174 case rxIdle: 1175 if (!rxEnable) { 1176 DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n"); 1177 goto exit; 1178 } 1179 1180 if (CRDD) { 1181 rxState = rxDescRefr; 1182 1183 rxDmaAddr = regs.rxdp & 0x3fffffff; 1184 rxDmaData = 1185 is64bit ? (void *)&rxDesc64.link : (void *)&rxDesc32.link; 1186 rxDmaLen = is64bit ? sizeof(rxDesc64.link) : sizeof(rxDesc32.link); 1187 rxDmaFree = dmaDescFree; 1188 1189 descDmaReads++; 1190 descDmaRdBytes += rxDmaLen; 1191 1192 if (doRxDmaRead()) 1193 goto exit; 1194 } else { 1195 rxState = rxDescRead; 1196 1197 rxDmaAddr = regs.rxdp & 0x3fffffff; 1198 rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32; 1199 rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32); 1200 rxDmaFree = dmaDescFree; 1201 1202 descDmaReads++; 1203 descDmaRdBytes += rxDmaLen; 1204 1205 if (doRxDmaRead()) 1206 goto exit; 1207 } 1208 break; 1209 1210 case rxDescRefr: 1211 if (rxDmaState != dmaIdle) 1212 goto exit; 1213 1214 rxState = rxAdvance; 1215 break; 1216 1217 case rxDescRead: 1218 if (rxDmaState != dmaIdle) 1219 goto exit; 1220 1221 DPRINTF(EthernetDesc, "rxDesc: addr=%08x read descriptor\n", 1222 regs.rxdp & 0x3fffffff); 1223 DPRINTF(EthernetDesc, 1224 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n", 1225 link, bufptr, cmdsts, extsts); 1226 1227 if (cmdsts & CMDSTS_OWN) { 1228 devIntrPost(ISR_RXIDLE); 1229 rxState = rxIdle; 1230 goto exit; 1231 } else { 1232 rxState = rxFifoBlock; 1233 rxFragPtr = bufptr; 1234 rxDescCnt = cmdsts & CMDSTS_LEN_MASK; 1235 } 1236 break; 1237 1238 case rxFifoBlock: 1239 if (!rxPacket) { 1240 /** 1241 * @todo in reality, we should be able to start processing 1242 * the packet as it arrives, and not have to wait for the 1243 * full packet ot be in the receive fifo. 1244 */ 1245 if (rxFifo.empty()) 1246 goto exit; 1247 1248 DPRINTF(EthernetSM, "****processing receive of new packet****\n"); 1249 1250 // If we don't have a packet, grab a new one from the fifo. 1251 rxPacket = rxFifo.front(); 1252 rxPktBytes = rxPacket->length; 1253 rxPacketBufPtr = rxPacket->data; 1254 1255#if TRACING_ON 1256 if (DTRACE(Ethernet)) { 1257 IpPtr ip(rxPacket); 1258 if (ip) { 1259 DPRINTF(Ethernet, "ID is %d\n", ip->id()); 1260 TcpPtr tcp(ip); 1261 if (tcp) { 1262 DPRINTF(Ethernet, 1263 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", 1264 tcp->sport(), tcp->dport(), tcp->seq(), 1265 tcp->ack()); 1266 } 1267 } 1268 } 1269#endif 1270 1271 // sanity check - i think the driver behaves like this 1272 assert(rxDescCnt >= rxPktBytes); 1273 rxFifo.pop(); 1274 } 1275 1276 1277 // dont' need the && rxDescCnt > 0 if driver sanity check 1278 // above holds 1279 if (rxPktBytes > 0) { 1280 rxState = rxFragWrite; 1281 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity 1282 // check holds 1283 rxXferLen = rxPktBytes; 1284 1285 rxDmaAddr = rxFragPtr & 0x3fffffff; 1286 rxDmaData = rxPacketBufPtr; 1287 rxDmaLen = rxXferLen; 1288 rxDmaFree = dmaDataFree; 1289 1290 if (doRxDmaWrite()) 1291 goto exit; 1292 1293 } else { 1294 rxState = rxDescWrite; 1295 1296 //if (rxPktBytes == 0) { /* packet is done */ 1297 assert(rxPktBytes == 0); 1298 DPRINTF(EthernetSM, "done with receiving packet\n"); 1299 1300 cmdsts |= CMDSTS_OWN; 1301 cmdsts &= ~CMDSTS_MORE; 1302 cmdsts |= CMDSTS_OK; 1303 cmdsts &= 0xffff0000; 1304 cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE 1305 1306#if 0 1307 /* 1308 * all the driver uses these are for its own stats keeping 1309 * which we don't care about, aren't necessary for 1310 * functionality and doing this would just slow us down. 1311 * if they end up using this in a later version for 1312 * functional purposes, just undef 1313 */ 1314 if (rxFilterEnable) { 1315 cmdsts &= ~CMDSTS_DEST_MASK; 1316 const EthAddr &dst = rxFifoFront()->dst(); 1317 if (dst->unicast()) 1318 cmdsts |= CMDSTS_DEST_SELF; 1319 if (dst->multicast()) 1320 cmdsts |= CMDSTS_DEST_MULTI; 1321 if (dst->broadcast()) 1322 cmdsts |= CMDSTS_DEST_MASK; 1323 } 1324#endif 1325 1326 IpPtr ip(rxPacket); 1327 if (extstsEnable && ip) { 1328 extsts |= EXTSTS_IPPKT; 1329 rxIpChecksums++; 1330 if (cksum(ip) != 0) { 1331 DPRINTF(EthernetCksum, "Rx IP Checksum Error\n"); 1332 extsts |= EXTSTS_IPERR; 1333 } 1334 TcpPtr tcp(ip); 1335 UdpPtr udp(ip); 1336 if (tcp) { 1337 extsts |= EXTSTS_TCPPKT; 1338 rxTcpChecksums++; 1339 if (cksum(tcp) != 0) { 1340 DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n"); 1341 extsts |= EXTSTS_TCPERR; 1342 1343 } 1344 } else if (udp) { 1345 extsts |= EXTSTS_UDPPKT; 1346 rxUdpChecksums++; 1347 if (cksum(udp) != 0) { 1348 DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n"); 1349 extsts |= EXTSTS_UDPERR; 1350 } 1351 } 1352 } 1353 rxPacket = 0; 1354 1355 /* 1356 * the driver seems to always receive into desc buffers 1357 * of size 1514, so you never have a pkt that is split 1358 * into multiple descriptors on the receive side, so 1359 * i don't implement that case, hence the assert above. 1360 */ 1361 1362 DPRINTF(EthernetDesc, 1363 "rxDesc: addr=%08x writeback cmdsts extsts\n", 1364 regs.rxdp & 0x3fffffff); 1365 DPRINTF(EthernetDesc, 1366 "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n", 1367 link, bufptr, cmdsts, extsts); 1368 1369 rxDmaAddr = regs.rxdp & 0x3fffffff; 1370 rxDmaData = &cmdsts; 1371 if (is64bit) { 1372 rxDmaAddr += offsetof(ns_desc64, cmdsts); 1373 rxDmaLen = sizeof(rxDesc64.cmdsts) + sizeof(rxDesc64.extsts); 1374 } else { 1375 rxDmaAddr += offsetof(ns_desc32, cmdsts); 1376 rxDmaLen = sizeof(rxDesc32.cmdsts) + sizeof(rxDesc32.extsts); 1377 } 1378 rxDmaFree = dmaDescFree; 1379 1380 descDmaWrites++; 1381 descDmaWrBytes += rxDmaLen; 1382 1383 if (doRxDmaWrite()) 1384 goto exit; 1385 } 1386 break; 1387 1388 case rxFragWrite: 1389 if (rxDmaState != dmaIdle) 1390 goto exit; 1391 1392 rxPacketBufPtr += rxXferLen; 1393 rxFragPtr += rxXferLen; 1394 rxPktBytes -= rxXferLen; 1395 1396 rxState = rxFifoBlock; 1397 break; 1398 1399 case rxDescWrite: 1400 if (rxDmaState != dmaIdle) 1401 goto exit; 1402 1403 assert(cmdsts & CMDSTS_OWN); 1404 1405 assert(rxPacket == 0); 1406 devIntrPost(ISR_RXOK); 1407 1408 if (cmdsts & CMDSTS_INTR) 1409 devIntrPost(ISR_RXDESC); 1410 1411 if (!rxEnable) { 1412 DPRINTF(EthernetSM, "Halting the RX state machine\n"); 1413 rxState = rxIdle; 1414 goto exit; 1415 } else 1416 rxState = rxAdvance; 1417 break; 1418 1419 case rxAdvance: 1420 if (link == 0) { 1421 devIntrPost(ISR_RXIDLE); 1422 rxState = rxIdle; 1423 CRDD = true; 1424 goto exit; 1425 } else { 1426 if (rxDmaState != dmaIdle) 1427 goto exit; 1428 rxState = rxDescRead; 1429 regs.rxdp = link; 1430 CRDD = false; 1431 1432 rxDmaAddr = regs.rxdp & 0x3fffffff; 1433 rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32; 1434 rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32); 1435 rxDmaFree = dmaDescFree; 1436 1437 if (doRxDmaRead()) 1438 goto exit; 1439 } 1440 break; 1441 1442 default: 1443 panic("Invalid rxState!"); 1444 } 1445 1446 DPRINTF(EthernetSM, "entering next rxState=%s\n", 1447 NsRxStateStrings[rxState]); 1448 goto next; 1449 1450 exit: 1451 /** 1452 * @todo do we want to schedule a future kick? 1453 */ 1454 DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n", 1455 NsRxStateStrings[rxState]); 1456 1457 if (!rxKickEvent.scheduled()) 1458 schedule(rxKickEvent, rxKickTick); 1459} 1460 1461void 1462NSGigE::transmit() 1463{ 1464 if (txFifo.empty()) { 1465 DPRINTF(Ethernet, "nothing to transmit\n"); 1466 return; 1467 } 1468 1469 DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n", 1470 txFifo.size()); 1471 if (interface->sendPacket(txFifo.front())) { 1472#if TRACING_ON 1473 if (DTRACE(Ethernet)) { 1474 IpPtr ip(txFifo.front()); 1475 if (ip) { 1476 DPRINTF(Ethernet, "ID is %d\n", ip->id()); 1477 TcpPtr tcp(ip); 1478 if (tcp) { 1479 DPRINTF(Ethernet, 1480 "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", 1481 tcp->sport(), tcp->dport(), tcp->seq(), 1482 tcp->ack()); 1483 } 1484 } 1485 } 1486#endif 1487 1488 DDUMP(EthernetData, txFifo.front()->data, txFifo.front()->length); 1489 txBytes += txFifo.front()->length; 1490 txPackets++; 1491 1492 DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", 1493 txFifo.avail()); 1494 txFifo.pop(); 1495 1496 /* 1497 * normally do a writeback of the descriptor here, and ONLY 1498 * after that is done, send this interrupt. but since our 1499 * stuff never actually fails, just do this interrupt here, 1500 * otherwise the code has to stray from this nice format. 1501 * besides, it's functionally the same. 1502 */ 1503 devIntrPost(ISR_TXOK); 1504 } 1505 1506 if (!txFifo.empty() && !txEvent.scheduled()) { 1507 DPRINTF(Ethernet, "reschedule transmit\n"); 1508 schedule(txEvent, curTick() + retryTime); 1509 } 1510} 1511 1512bool 1513NSGigE::doTxDmaRead() 1514{ 1515 assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); 1516 txDmaState = dmaReading; 1517 1518 if (dmaPending() || drainState() != DrainState::Running) 1519 txDmaState = dmaReadWaiting; 1520 else 1521 dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData); 1522 1523 return true; 1524} 1525 1526void 1527NSGigE::txDmaReadDone() 1528{ 1529 assert(txDmaState == dmaReading); 1530 txDmaState = dmaIdle; 1531 1532 DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", 1533 txDmaAddr, txDmaLen); 1534 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1535 1536 // If the receive state machine has a pending DMA, let it go first 1537 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1538 rxKick(); 1539 1540 txKick(); 1541} 1542 1543bool 1544NSGigE::doTxDmaWrite() 1545{ 1546 assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); 1547 txDmaState = dmaWriting; 1548 1549 if (dmaPending() || drainState() != DrainState::Running) 1550 txDmaState = dmaWriteWaiting; 1551 else 1552 dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData); 1553 return true; 1554} 1555 1556void 1557NSGigE::txDmaWriteDone() 1558{ 1559 assert(txDmaState == dmaWriting); 1560 txDmaState = dmaIdle; 1561 1562 DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", 1563 txDmaAddr, txDmaLen); 1564 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1565 1566 // If the receive state machine has a pending DMA, let it go first 1567 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1568 rxKick(); 1569 1570 txKick(); 1571} 1572 1573void 1574NSGigE::txKick() 1575{ 1576 bool is64bit = (bool)(regs.config & CFGR_M64ADDR); 1577 1578 DPRINTF(EthernetSM, "transmit kick txState=%s %d-bit\n", 1579 NsTxStateStrings[txState], is64bit ? 64 : 32); 1580 1581 Addr link, bufptr; 1582 uint32_t &cmdsts = is64bit ? txDesc64.cmdsts : txDesc32.cmdsts; 1583 uint32_t &extsts = is64bit ? txDesc64.extsts : txDesc32.extsts; 1584 1585 next: 1586 if (txKickTick > curTick()) { 1587 DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n", 1588 txKickTick); 1589 goto exit; 1590 } 1591 1592 // Go to the next state machine clock tick. 1593 txKickTick = clockEdge(Cycles(1)); 1594 1595 switch(txDmaState) { 1596 case dmaReadWaiting: 1597 if (doTxDmaRead()) 1598 goto exit; 1599 break; 1600 case dmaWriteWaiting: 1601 if (doTxDmaWrite()) 1602 goto exit; 1603 break; 1604 default: 1605 break; 1606 } 1607 1608 link = is64bit ? (Addr)txDesc64.link : (Addr)txDesc32.link; 1609 bufptr = is64bit ? (Addr)txDesc64.bufptr : (Addr)txDesc32.bufptr; 1610 switch (txState) { 1611 case txIdle: 1612 if (!txEnable) { 1613 DPRINTF(EthernetSM, "Transmit disabled. Nothing to do.\n"); 1614 goto exit; 1615 } 1616 1617 if (CTDD) { 1618 txState = txDescRefr; 1619 1620 txDmaAddr = regs.txdp & 0x3fffffff; 1621 txDmaData = 1622 is64bit ? (void *)&txDesc64.link : (void *)&txDesc32.link; 1623 txDmaLen = is64bit ? sizeof(txDesc64.link) : sizeof(txDesc32.link); 1624 txDmaFree = dmaDescFree; 1625 1626 descDmaReads++; 1627 descDmaRdBytes += txDmaLen; 1628 1629 if (doTxDmaRead()) 1630 goto exit; 1631 1632 } else { 1633 txState = txDescRead; 1634 1635 txDmaAddr = regs.txdp & 0x3fffffff; 1636 txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32; 1637 txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32); 1638 txDmaFree = dmaDescFree; 1639 1640 descDmaReads++; 1641 descDmaRdBytes += txDmaLen; 1642 1643 if (doTxDmaRead()) 1644 goto exit; 1645 } 1646 break; 1647 1648 case txDescRefr: 1649 if (txDmaState != dmaIdle) 1650 goto exit; 1651 1652 txState = txAdvance; 1653 break; 1654 1655 case txDescRead: 1656 if (txDmaState != dmaIdle) 1657 goto exit; 1658 1659 DPRINTF(EthernetDesc, "txDesc: addr=%08x read descriptor\n", 1660 regs.txdp & 0x3fffffff); 1661 DPRINTF(EthernetDesc, 1662 "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n", 1663 link, bufptr, cmdsts, extsts); 1664 1665 if (cmdsts & CMDSTS_OWN) { 1666 txState = txFifoBlock; 1667 txFragPtr = bufptr; 1668 txDescCnt = cmdsts & CMDSTS_LEN_MASK; 1669 } else { 1670 devIntrPost(ISR_TXIDLE); 1671 txState = txIdle; 1672 goto exit; 1673 } 1674 break; 1675 1676 case txFifoBlock: 1677 if (!txPacket) { 1678 DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); 1679 txPacket = make_shared<EthPacketData>(16384); 1680 txPacketBufPtr = txPacket->data; 1681 } 1682 1683 if (txDescCnt == 0) { 1684 DPRINTF(EthernetSM, "the txDescCnt == 0, done with descriptor\n"); 1685 if (cmdsts & CMDSTS_MORE) { 1686 DPRINTF(EthernetSM, "there are more descriptors to come\n"); 1687 txState = txDescWrite; 1688 1689 cmdsts &= ~CMDSTS_OWN; 1690 1691 txDmaAddr = regs.txdp & 0x3fffffff; 1692 txDmaData = &cmdsts; 1693 if (is64bit) { 1694 txDmaAddr += offsetof(ns_desc64, cmdsts); 1695 txDmaLen = sizeof(txDesc64.cmdsts); 1696 } else { 1697 txDmaAddr += offsetof(ns_desc32, cmdsts); 1698 txDmaLen = sizeof(txDesc32.cmdsts); 1699 } 1700 txDmaFree = dmaDescFree; 1701 1702 if (doTxDmaWrite()) 1703 goto exit; 1704 1705 } else { /* this packet is totally done */ 1706 DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n"); 1707 /* deal with the the packet that just finished */ 1708 if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) { 1709 IpPtr ip(txPacket); 1710 if (extsts & EXTSTS_UDPPKT) { 1711 UdpPtr udp(ip); 1712 if (udp) { 1713 udp->sum(0); 1714 udp->sum(cksum(udp)); 1715 txUdpChecksums++; 1716 } else { 1717 Debug::breakpoint(); 1718 warn_once("UDPPKT set, but not UDP!\n"); 1719 } 1720 } else if (extsts & EXTSTS_TCPPKT) { 1721 TcpPtr tcp(ip); 1722 if (tcp) { 1723 tcp->sum(0); 1724 tcp->sum(cksum(tcp)); 1725 txTcpChecksums++; 1726 } else { 1727 warn_once("TCPPKT set, but not UDP!\n"); 1728 } 1729 } 1730 if (extsts & EXTSTS_IPPKT) { 1731 if (ip) { 1732 ip->sum(0); 1733 ip->sum(cksum(ip)); 1734 txIpChecksums++; 1735 } else { 1736 warn_once("IPPKT set, but not UDP!\n"); 1737 } 1738 } 1739 } 1740
|