Annotation of XNU/iokit/Drivers/network/drvIntel82557/i82557.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.