|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1996 NeXT Software, Inc. All rights reserved. ! 24: * ! 25: * i82557.cpp ! 26: * ! 27: * HISTORY ! 28: * ! 29: * 22-Jan-96 Dieter Siegmund (dieter) at NeXT ! 30: * Created. ! 31: * ! 32: * 03-May-96 Dieter Siegmund (dieter) at NeXT ! 33: * Added a real ISR to improve performance. ! 34: * ! 35: * 10-June-96 Dieter Siegmund (dieter) at NeXT ! 36: * Added support for Splash 3 (10 Base-T only card). ! 37: * ! 38: * 18-June-96 Dieter Siegmund (dieter) at NeXT ! 39: * Keep the transmit queue draining by interrupting every ! 40: * N / 2 transmits (where N is the size of the hardware queue). ! 41: * ! 42: * 15-Dec-97 Joe Liu (jliu) at Apple ! 43: * Updated PHY programming to be 82558 aware. ! 44: * Misc changes to conform to new 82558 register flags. ! 45: * Changed RNR interrupt handler to restart RU instead of a reset. ! 46: * Interrupt handler now does a thread_call_func() to do most of its work. ! 47: * Interrupts are disabled until the thread callout finishes its work. ! 48: * Increased the size of TX/RX rings. ! 49: * buffer object removed, we use cluster mbufs to back up the receive ring. ! 50: * ! 51: * 29-May-98 Joe Liu (jliu) at Apple ! 52: * Updated _setupPhy method to take advantage of parallel detection whenever ! 53: * possible in order to detect the proper link speed. ! 54: * ! 55: * 17-Aug-98 Joe Liu (jliu) at Apple ! 56: * Re-enabled the setting of txready_sel PHY (PCS) bit for DP83840. ! 57: * Simplified interrupt handling, resulting in RCV performance improvements. ! 58: * Receive packets are sent upstream via a cached function pointer. ! 59: */ ! 60: ! 61: #include "i82557.h" ! 62: ! 63: #define ONE_SECOND_TICKS 1000 ! 64: #define LOAD_STATISTICS_INTERVAL (4 * ONE_SECOND_TICKS) ! 65: ! 66: #define super IOEthernetController ! 67: OSDefineMetaClassAndStructors( Intel82557, IOEthernetController ) ! 68: ! 69: //--------------------------------------------------------------------------- ! 70: // Function: init <IORegistryEntry> ! 71: // ! 72: // Initialize the driver instance and prepare it for a probe() call. ! 73: ! 74: bool Intel82557::init(OSDictionary * properties) ! 75: { ! 76: return super::init(properties); ! 77: } ! 78: ! 79: //--------------------------------------------------------------------------- ! 80: // Function: probe <IOService> ! 81: // ! 82: // Probe for the presence of Intel82557 by reading the PCI vendor ID ! 83: // from the PCI nub. ! 84: ! 85: IOService * Intel82557::probe(IOService * provider, ! 86: SInt32 * score) ! 87: { ! 88: IOPCIDevice * pciNub = OSDynamicCast(IOPCIDevice, provider); ! 89: UInt32 pciID; ! 90: ! 91: if (!pciNub) return 0; ! 92: ! 93: // Check PCI device ID. ! 94: // ! 95: pciID = pciNub->configRead32(PCI_CFID_OFFSET); ! 96: switch (pciID) { ! 97: case PCI_CFID_INTEL82557: ! 98: break; ! 99: default: ! 100: // IOLog("%s: Unknown device ID %08lx\n", getName(), pciID); ! 101: return 0; ! 102: } ! 103: ! 104: return super::probe(provider, score); ! 105: } ! 106: ! 107: //--------------------------------------------------------------------------- ! 108: // Function: pciConfigInit ! 109: // ! 110: // Update PCI command register to enable the memory-mapped range, ! 111: // and bus-master interface. ! 112: ! 113: bool Intel82557::pciConfigInit(IOPCIDevice * provider) ! 114: { ! 115: UInt32 reg; ! 116: ! 117: reg = provider->configRead32(PCI_CFCS_OFFSET); ! 118: reg |= (0x04 | 0x02 | 0x10); // Master, Memory, PCI-MWI ! 119: reg &= ~0x01; // disable I/O space ! 120: provider->configWrite32(PCI_CFCS_OFFSET, reg); ! 121: ! 122: return true; ! 123: } ! 124: ! 125: //--------------------------------------------------------------------------- ! 126: // Function: initDriver ! 127: // ! 128: // Create and initialize the driver objects before the hardware is ! 129: // enabled. ! 130: // ! 131: // Returns true on sucess, and false if initialization failed. ! 132: ! 133: bool Intel82557::initDriver(IOService * provider) ! 134: { ! 135: currentMediumType = MEDIUM_TYPE_INVALID; ! 136: ! 137: // This driver will allocate and use an IOOQGateFIFOQueue. ! 138: // ! 139: transmitQueue = OSDynamicCast(IOOQGateFIFOQueue, getOutputQueue()); ! 140: if (!transmitQueue) ! 141: return false; ! 142: transmitQueue->retain(); ! 143: ! 144: // Allocate two IOMBufLittleMemoryCursor instances. One for transmit and ! 145: // the other for receive. ! 146: // ! 147: rxMbufCursor = IOMBufLittleMemoryCursor::withSpecification(MAX_BUF_SIZE,1); ! 148: txMbufCursor = IOMBufLittleMemoryCursor::withSpecification(MAX_BUF_SIZE, ! 149: TBDS_PER_TCB); ! 150: if (!rxMbufCursor || !txMbufCursor) ! 151: return false; ! 152: ! 153: // Get a handle to our superclass' workloop. ! 154: // ! 155: IOWorkLoop * myWorkLoop = (IOWorkLoop *) getWorkLoop(); ! 156: if (!myWorkLoop) ! 157: return false; ! 158: ! 159: // Create and register an interrupt event source. The provider will ! 160: // take care of the low-level interrupt registration stuff. ! 161: // ! 162: #if USE_FILTER_INTERRUPT_EVENT_SRC ! 163: interruptSrc = ! 164: IOFilterInterruptEventSource::filterInterruptEventSource(this, ! 165: (IOInterruptEventAction) &Intel82557::interruptOccurred, ! 166: (IOFilterInterruptAction) &Intel82557::checkForInterrupt, ! 167: provider); ! 168: #else ! 169: interruptSrc = ! 170: IOInterruptEventSource::interruptEventSource(this, ! 171: (IOInterruptEventAction) &Intel82557::interruptOccurred, ! 172: provider); ! 173: #endif ! 174: if (!interruptSrc || ! 175: (myWorkLoop->addEventSource(interruptSrc) != kIOReturnSuccess)) ! 176: return false; ! 177: ! 178: // Register a timer event source. This is used as a watchdog timer. ! 179: // ! 180: timerSrc = IOTimerEventSource::timerEventSource(this, ! 181: (IOTimerEventSource::Action) &Intel82557::timeoutOccurred); ! 182: if (!timerSrc || ! 183: (myWorkLoop->addEventSource(timerSrc) != kIOReturnSuccess)) ! 184: return false; ! 185: ! 186: // Create a dictionary to hold IONetworkMedium objects. ! 187: // ! 188: mediumDict = OSDictionary::withCapacity(5); ! 189: if (!mediumDict) ! 190: return false; ! 191: ! 192: return true; ! 193: } ! 194: ! 195: //--------------------------------------------------------------------------- ! 196: // Function: getDefaultSettings ! 197: // ! 198: // Get the default driver settings chosen by the user. The properties ! 199: // are all stored in our property table (an OSDictionary). ! 200: // For convenience, all properties are OSNumbers. ! 201: ! 202: bool Intel82557::getDefaultSettings() ! 203: { ! 204: OSNumber * offset; ! 205: ! 206: // Check for PHY address override. ! 207: // ! 208: phyAddr = PHY_ADDRESS_DEFAULT; ! 209: offset = OSDynamicCast(OSNumber, getProperty("PHY Address")); ! 210: if (offset) { ! 211: phyAddr = offset->unsigned32BitValue(); ! 212: } ! 213: ! 214: // Check for Verbose flag. ! 215: // ! 216: verbose = false; ! 217: offset = OSDynamicCast(OSNumber, getProperty("Verbose")); ! 218: if (offset && offset->unsigned32BitValue()) { ! 219: IOLog("%s: verbose mode enabled\n", getName()); ! 220: verbose = true; ! 221: } ! 222: ! 223: // Check for Flow-Control enable flag. ! 224: // ! 225: flowControl = false; ! 226: offset = OSDynamicCast(OSNumber, getProperty("Flow Control")); ! 227: if (offset && offset->unsigned32BitValue()) { ! 228: IOLog("%s: 802.3x flow control enabled\n", getName()); ! 229: flowControl = true; ! 230: } ! 231: ! 232: return true; ! 233: } ! 234: ! 235: //--------------------------------------------------------------------------- ! 236: // Function: start <IOService> ! 237: // ! 238: // Hardware was detected and initialized, start the driver. ! 239: ! 240: bool Intel82557::start(IOService * provider) ! 241: { ! 242: IOPCIDevice * pciNub = OSDynamicCast(IOPCIDevice, provider); ! 243: ! 244: // Start our superclass first. ! 245: // ! 246: if (!pciNub || !super::start(provider)) ! 247: return false; ! 248: ! 249: // Initialize the driver's event sources and other support objects. ! 250: // ! 251: if (!initDriver(provider)) ! 252: return false; ! 253: ! 254: // Get the virtual address mapping of CSR registers located at ! 255: // Base Address Range 0 (0x10). The size of this range is 4K. ! 256: // ! 257: csrMap = pciNub->mapDeviceMemoryWithRegister(PCI_BAR0_OFFSET); ! 258: if (!csrMap) ! 259: return false; ! 260: CSR_p = (CSR_t *) csrMap->getVirtualAddress(); ! 261: ! 262: // Enables the bus-master and turns on memory space decoding. ! 263: // ! 264: if (!pciConfigInit(pciNub)) ! 265: return false; ! 266: ! 267: // Create the EEPROM object. ! 268: // ! 269: eeprom = i82557eeprom::withAddress(&CSR_p->eepromControl); ! 270: if (!eeprom) { ! 271: IOLog("%s: couldn't allocate eeprom object", getName()); ! 272: return false; ! 273: } ! 274: ! 275: // Get default driver settings. ! 276: // ! 277: if (!getDefaultSettings()) ! 278: return false; ! 279: ! 280: if (verbose) ! 281: eeprom->dumpContents(); ! 282: ! 283: // Execute one-time initialization code. ! 284: // ! 285: if (!coldInit()) { ! 286: IOLog("%s: coldInit failed\n", getName()); ! 287: return false; ! 288: } ! 289: ! 290: if (!hwInit()) { ! 291: IOLog("%s: hwInit failed\n", getName()); ! 292: return false; ! 293: } ! 294: ! 295: // Publish our media capabilities. ! 296: // ! 297: _phyPublishMedia(); ! 298: if (!publishMediumDictionary(mediumDict)) { ! 299: IOLog("%s: publishMediumDictionary failed\n", getName()); ! 300: return false; ! 301: } ! 302: ! 303: // Announce the basic hardware configuration info. ! 304: // ! 305: IOLog("%s: Memory 0x%lx irq %d\n", ! 306: getName(), csrMap->getPhysicalAddress(), 0); ! 307: ! 308: // Allocate and attach an IOEthernetInterface instance to this driver ! 309: // object. ! 310: // ! 311: if (!attachInterface((IONetworkInterface **) &netif, false)) ! 312: return false; ! 313: ! 314: // Attach a kernel debugger client. ! 315: // ! 316: attachDebuggerClient(&debugger); ! 317: ! 318: netif->registerService(); ! 319: ! 320: return true; ! 321: } ! 322: ! 323: //--------------------------------------------------------------------------- ! 324: // Function: stop <IOService> ! 325: // ! 326: // Stop all activities and prepare for termination. ! 327: ! 328: void Intel82557::stop(IOService * provider) ! 329: { ! 330: #if 0 // This belongs in stop()? ! 331: if (resetAndEnabled == YES) { /* shut down the hardware */ ! 332: [self disableAdapterInterrupts]; ! 333: resetAndEnabled = NO; ! 334: } ! 335: #endif ! 336: } ! 337: ! 338: bool Intel82557::configureInterface(IONetworkInterface * netif) ! 339: { ! 340: IONetworkData * param; ! 341: ! 342: if (super::configureInterface(netif) == false) ! 343: return false; ! 344: ! 345: // Get the generic network statistics structure. ! 346: // ! 347: param = netif->getParameter(kIONetworkStatsKey); ! 348: if (!param || !(netStats = (IONetworkStats *) param->getBuffer())) { ! 349: return false; ! 350: } ! 351: ! 352: // Get the Ethernet statistics structure. ! 353: // ! 354: param = netif->getParameter(kIOEthernetStatsKey); ! 355: if (!param || !(etherStats = (IOEthernetStats *) param->getBuffer())) { ! 356: return false; ! 357: } ! 358: ! 359: return true; ! 360: } ! 361: ! 362: //--------------------------------------------------------------------------- ! 363: // Function: free <IOService> ! 364: // ! 365: // Deallocate all resources and destroy the instance. ! 366: ! 367: void Intel82557::free() ! 368: { ! 369: if (debugger) debugger->release(); ! 370: if (netif) netif->release(); ! 371: if (transmitQueue) transmitQueue->release(); ! 372: if (interruptSrc) interruptSrc->release(); ! 373: if (timerSrc) timerSrc->release(); ! 374: if (rxMbufCursor) rxMbufCursor->release(); ! 375: if (txMbufCursor) txMbufCursor->release(); ! 376: if (csrMap) csrMap->release(); ! 377: if (eeprom) eeprom->release(); ! 378: if (mediumDict) mediumDict->release(); ! 379: ! 380: _freeMemPage(&shared); ! 381: _freeMemPage(&txRing); ! 382: _freeMemPage(&rxRing); ! 383: ! 384: super::free(); // pass it to our superclass ! 385: } ! 386: ! 387: //--------------------------------------------------------------------------- ! 388: // Function: enableAdapter ! 389: // ! 390: // Enables the adapter & driver to the given level of support. ! 391: ! 392: bool Intel82557::enableAdapter(UInt32 level) ! 393: { ! 394: bool ret = false; ! 395: ! 396: // IOLog("%s::%s enabling level %ld\n", getName(), __FUNCTION__, level); ! 397: ! 398: switch (level) { ! 399: case kAdapterLevel1: ! 400: if (!_initRingBuffers()) ! 401: break; ! 402: ! 403: if (!_startReceive()) { ! 404: _clearRingBuffers(); ! 405: break; ! 406: } ! 407: ! 408: // Set current medium. ! 409: // ! 410: if (setMedium(getCurrentMedium()) != kIOReturnSuccess) ! 411: IOLog("%s: setMedium error\n", getName()); ! 412: ! 413: // Start the watchdog timer. ! 414: // ! 415: timerSrc->setTimeoutMS(LOAD_STATISTICS_INTERVAL); ! 416: ! 417: // Enable interrupt event sources and hardware interrupts. ! 418: // ! 419: if (getWorkLoop()) ! 420: getWorkLoop()->enableAllInterrupts(); ! 421: enableAdapterInterrupts(); ! 422: ! 423: ret = true; ! 424: break; ! 425: ! 426: case kAdapterLevel2: ! 427: // Issue a dump statistics command. ! 428: // ! 429: _dumpStatistics(); ! 430: ! 431: // Start our IOOutputQueue object. ! 432: // ! 433: transmitQueue->setCapacity(TRANSMIT_QUEUE_SIZE); ! 434: transmitQueue->start(); ! 435: ! 436: ret = true; ! 437: break; ! 438: } ! 439: ! 440: if (!ret) ! 441: IOLog("%s::%s error in level %ld\n", getName(), __FUNCTION__, level); ! 442: ! 443: return ret; ! 444: } ! 445: ! 446: //--------------------------------------------------------------------------- ! 447: // Function: disableAdapter ! 448: // ! 449: // Disables the adapter & driver to the given level of support. ! 450: ! 451: bool Intel82557::disableAdapter(UInt32 level) ! 452: { ! 453: bool ret = false; ! 454: ! 455: // IOLog("%s::%s disabling level %ld\n", getName(), __FUNCTION__, level); ! 456: ! 457: switch (level) { ! 458: case kAdapterLevel1: ! 459: // Disable interrupt handling and hardware interrupt sources. ! 460: // ! 461: disableAdapterInterrupts(); ! 462: if (getWorkLoop()) ! 463: getWorkLoop()->disableAllInterrupts(); ! 464: ! 465: // Stop the timer event source, and initialize the watchdog state. ! 466: // ! 467: timerSrc->cancelTimeout(); ! 468: packetsReceived = true; // assume we're getting packets ! 469: packetsTransmitted = false; ! 470: txCount = 0; ! 471: ! 472: // Reset the hardware engine. ! 473: // ! 474: ret = hwInit(); ! 475: ! 476: // Clear the descriptor rings after the hardware is idle. ! 477: // ! 478: _clearRingBuffers(); ! 479: ! 480: // Report no link. ! 481: // ! 482: setLinkStatus(kIONetworkLinkValid, 0, 0); ! 483: ! 484: // Flush all packets held in the queue and prevent it ! 485: // from accumulating any additional packets. ! 486: // ! 487: transmitQueue->setCapacity(0); ! 488: transmitQueue->flush(); ! 489: ! 490: break; ! 491: ! 492: case kAdapterLevel2: ! 493: // Stop the transmit queue. outputPacket() will not get called ! 494: // after this. ! 495: // ! 496: transmitQueue->stop(); ! 497: ! 498: ret = true; ! 499: break; ! 500: } ! 501: ! 502: if (!ret) ! 503: IOLog("%s::%s error in level %ld\n", getName(), __FUNCTION__, level); ! 504: ! 505: return ret; ! 506: } ! 507: ! 508: //--------------------------------------------------------------------------- ! 509: // Function: setAdapterLevel ! 510: // ! 511: // Sets the adapter's run level depending on the type of client present. ! 512: // ! 513: // kAdapterLevel0 - Adapter is disabled. ! 514: // kAdapterLevel1 - Adapter is brought up just enough to support debugging. ! 515: // kAdapterLevel2 - Adapter is completely up. ! 516: ! 517: bool Intel82557::setAdapterLevel(UInt32 newLevel) ! 518: { ! 519: bool ret = false; ! 520: UInt32 nextLevel; ! 521: ! 522: // IOLog("---> DESIRED LEVEL : %d\n", newLevel); ! 523: ! 524: if (currentLevel == newLevel) ! 525: return true; ! 526: ! 527: for ( ; currentLevel > newLevel; currentLevel--) ! 528: { ! 529: if ((ret = disableAdapter(currentLevel)) == false) ! 530: break; ! 531: } ! 532: ! 533: for (nextLevel = currentLevel + 1; currentLevel < newLevel; ! 534: currentLevel++, nextLevel++) ! 535: { ! 536: if ((ret = enableAdapter(nextLevel)) == false) ! 537: break; ! 538: } ! 539: ! 540: // IOLog("---> PRESENT LEVEL : %d\n\n", currentLevel); ! 541: ! 542: return ret; ! 543: } ! 544: ! 545: //--------------------------------------------------------------------------- ! 546: // Function: enable <IONetworkController> ! 547: // ! 548: // A request from our interface client to enable the adapter. ! 549: ! 550: IOReturn Intel82557::enable(IONetworkInterface * /*netif*/) ! 551: { ! 552: if (enabledForNetif) ! 553: return kIOReturnSuccess; ! 554: ! 555: enabledForNetif = setAdapterLevel(kAdapterLevel2); ! 556: ! 557: return (enabledForNetif ? kIOReturnSuccess : kIOReturnIOError); ! 558: } ! 559: ! 560: //--------------------------------------------------------------------------- ! 561: // Function: disable <IONetworkController> ! 562: // ! 563: // A request from our interface client to disable the adapter. ! 564: ! 565: IOReturn Intel82557::disable(IONetworkInterface * /*netif*/) ! 566: { ! 567: enabledForNetif = false; ! 568: ! 569: if (enabledForDebugger) ! 570: setAdapterLevel(kAdapterLevel1); ! 571: else ! 572: setAdapterLevel(kAdapterLevel0); ! 573: ! 574: return kIOReturnSuccess; ! 575: } ! 576: ! 577: //--------------------------------------------------------------------------- ! 578: // Function: enable <IONetworkController> ! 579: // ! 580: // A request from our debugger client to enable the adapter. ! 581: ! 582: IOReturn Intel82557::enable(IOKernelDebugger * /*debugger*/) ! 583: { ! 584: if (enabledForDebugger || enabledForNetif) { ! 585: enabledForDebugger = true; ! 586: return kIOReturnSuccess; ! 587: } ! 588: ! 589: enabledForDebugger = setAdapterLevel(kAdapterLevel1); ! 590: ! 591: return (enabledForDebugger ? kIOReturnSuccess : kIOReturnIOError); ! 592: } ! 593: ! 594: //--------------------------------------------------------------------------- ! 595: // Function: disable <IONetworkController> ! 596: // ! 597: // A request from our debugger client to disable the adapter. ! 598: ! 599: IOReturn Intel82557::disable(IOKernelDebugger * /*debugger*/) ! 600: { ! 601: enabledForDebugger = false; ! 602: ! 603: if (!enabledForNetif) ! 604: setAdapterLevel(kAdapterLevel0); ! 605: ! 606: return kIOReturnSuccess; ! 607: } ! 608: ! 609: //--------------------------------------------------------------------------- ! 610: // Function: timeoutOccurred ! 611: // ! 612: // Periodic timer that monitors the receiver status, updates error ! 613: // and collision statistics, and update the current link status. ! 614: ! 615: void Intel82557::timeoutOccurred(IOTimerEventSource * /*timer*/) ! 616: { ! 617: if ((packetsReceived == false) && (packetsTransmitted == true)) { ! 618: /* ! 619: * The B-step of the i82557 requires that an mcsetup command be ! 620: * issued if the receiver stops receiving. This is a documented ! 621: * errata. ! 622: */ ! 623: mcSetup(0, 0, true); ! 624: } ! 625: packetsReceived = packetsTransmitted = false; ! 626: ! 627: _updateStatistics(); ! 628: ! 629: updateLinkStatus(); ! 630: ! 631: timerSrc->setTimeoutMS(LOAD_STATISTICS_INTERVAL); ! 632: } ! 633: ! 634: //--------------------------------------------------------------------------- ! 635: // Function: setPromiscuousMode <IOEthernetController> ! 636: ! 637: IOReturn Intel82557::setPromiscuousMode(IOEnetPromiscuousMode mode) ! 638: { ! 639: bool rv; ! 640: promiscuousEnabled = (mode == kIOEnetPromiscuousModeOff) ? false : true; ! 641: reserveDebuggerLock(); ! 642: rv = config(); ! 643: releaseDebuggerLock(); ! 644: return (rv ? kIOReturnSuccess : kIOReturnIOError); ! 645: } ! 646: ! 647: //--------------------------------------------------------------------------- ! 648: // Function: setMulticastMode <IOEthernetController> ! 649: ! 650: IOReturn Intel82557::setMulticastMode(IOEnetMulticastMode mode) ! 651: { ! 652: multicastEnabled = (mode == kIOEnetMulticastModeOff) ? false : true; ! 653: return kIOReturnSuccess; ! 654: } ! 655: ! 656: //--------------------------------------------------------------------------- ! 657: // Function: setMulticastList <IOEthernetController> ! 658: ! 659: IOReturn Intel82557::setMulticastList(enet_addr_t * addrs, UInt count) ! 660: { ! 661: IOReturn ret = kIOReturnSuccess; ! 662: ! 663: if (!mcSetup(addrs, count)) { ! 664: IOLog("%s: set multicast list failed\n", getName()); ! 665: ret = kIOReturnIOError; ! 666: } ! 667: return ret; ! 668: } ! 669: ! 670: //--------------------------------------------------------------------------- ! 671: // Function: getPacketBufferConstraints <IONetworkController> ! 672: // ! 673: // Return our driver's packet alignment requirements. ! 674: ! 675: void ! 676: Intel82557::getPacketBufferConstraints(IOPacketBufferConstraints * constraints) const ! 677: { ! 678: constraints->alignStart = kIOPacketBufferAlign2; // even word aligned. ! 679: constraints->alignLength = kIOPacketBufferAlign1; // no restriction. ! 680: } ! 681: ! 682: //--------------------------------------------------------------------------- ! 683: // Function: getHardwareAddress <IOEthernetController> ! 684: // ! 685: // Return the adapter's hardware address. ! 686: ! 687: IOReturn Intel82557::getHardwareAddress(enet_addr_t * addrs) ! 688: { ! 689: bcopy(&myAddress, addrs, sizeof(*addrs)); ! 690: return kIOReturnSuccess; ! 691: } ! 692: ! 693: //--------------------------------------------------------------------------- ! 694: // Function: allocateOutputQueue <IONetworkController> ! 695: // ! 696: // Allocate an IOOQGateFIFOQueue instance. ! 697: ! 698: IOOutputQueue * Intel82557::createOutputQueue() ! 699: { ! 700: return IOOQGateFIFOQueue::withTarget(this, getWorkLoop()); ! 701: } ! 702: ! 703: //--------------------------------------------------------------------------- ! 704: // Function: updateLinkStatus ! 705: // ! 706: // Get the current link status and call the inherited setLinkStatus() ! 707: // function to update the status. This function is called periodically ! 708: // by timeoutOccurred() to poll the current link status. ! 709: ! 710: void Intel82557::updateLinkStatus() ! 711: { ! 712: bool linkUp; ! 713: IONetworkMedium * activeMedium = 0; ! 714: UInt32 linkStatus = kIONetworkLinkValid; ! 715: UInt64 linkSpeed = 0; ! 716: mediumType_t activeMediumType; ! 717: ! 718: // Query the hardware for the current active medium, and the link ! 719: // status flag. ! 720: // ! 721: if (_phyGetLinkStatus(&linkUp, ! 722: &activeMediumType, ! 723: currentMediumType) == false) { ! 724: return; ! 725: } ! 726: ! 727: if (linkUp) { ! 728: linkStatus |= kIONetworkLinkActive; ! 729: ! 730: // Link speeds are fixed per medium. Get the speed from the active ! 731: // medium. ! 732: // ! 733: activeMedium = _phyGetMediumWithCode(activeMediumType); ! 734: if (activeMedium) ! 735: linkSpeed = activeMedium->getSpeed(); ! 736: } ! 737: ! 738: // Update the link status properties. ! 739: // ! 740: if (!setLinkStatus(linkStatus, linkSpeed, activeMedium)) ! 741: IOLog("%s: setLinkStatus error\n", getName()); ! 742: } ! 743: ! 744: //--------------------------------------------------------------------------- ! 745: // Function: setMedium <IONetworkController> ! 746: // ! 747: // Transition the controller/PHY to use a new medium. Note that ! 748: // this function can be called my the driver, or by our client. ! 749: ! 750: IOReturn Intel82557::setMedium(const IONetworkMedium * medium) ! 751: { ! 752: bool r; ! 753: ! 754: if (!OSDynamicCast(IONetworkMedium, medium)) ! 755: return kIOReturnBadArgument; ! 756: ! 757: #if 0 ! 758: IOLog("%s: setMedium -> %s\n", getName(), ! 759: medium->getName()->getCStringNoCopy()); ! 760: #endif ! 761: ! 762: // Program PHY. ! 763: // ! 764: r = _phySetMedium((mediumType_t) medium->getIndex()); ! 765: ! 766: // Update the current medium property. ! 767: // ! 768: if (r && !setCurrentMedium(medium)) ! 769: IOLog("%s: setCurrentMedium error\n", getName()); ! 770: ! 771: return (r ? kIOReturnSuccess : kIOReturnIOError); ! 772: } ! 773: ! 774: //--------------------------------------------------------------------------- ! 775: // Function: getVendorString(), getModelString(), getRevisionString() ! 776: // <IONetworkController> ! 777: // ! 778: // Report human readable hardware information strings. ! 779: ! 780: const char * Intel82557::getVendorString() const ! 781: { ! 782: return ("Intel"); ! 783: } ! 784: ! 785: const char * Intel82557::getModelString() const ! 786: { ! 787: const char * model = 0; ! 788: ! 789: assert(eeprom && eeprom->getContents()); ! 790: ! 791: switch(eeprom->getContents()->controllerType) { ! 792: case I82558_CONTROLLER_TYPE: ! 793: model = "82558"; ! 794: break; ! 795: case I82557_CONTROLLER_TYPE: ! 796: default: ! 797: model = "82557"; ! 798: break; ! 799: } ! 800: return model; ! 801: } ! 802: ! 803: const char * Intel82557::getRevisionString() const ! 804: { ! 805: return NULL; ! 806: } ! 807: ! 808: //--------------------------------------------------------------------------- ! 809: // Kernel debugger entry points. ! 810: // ! 811: // KDP driven polling routines to send and transmit a frame. ! 812: // Remember, no memory allocation! Not even mbufs are safe. ! 813: ! 814: void Intel82557::sendPacket(void * pkt, UInt pkt_len) ! 815: { ! 816: _sendPacket(pkt, pkt_len); ! 817: } ! 818: ! 819: void Intel82557::receivePacket(void * pkt, UInt * pkt_len, UInt timeout) ! 820: { ! 821: _receivePacket(pkt, pkt_len, timeout); ! 822: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.