Annotation of XNU/iokit/Drivers/network/drvIntel82557/i82557.cpp, revision 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.