Annotation of XNU/iokit/Drivers/network/drvMaceEnet/MaceEnet.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) 1995-1996 NeXT Software, Inc.
        !            24:  *
        !            25:  * Hardware independent (relatively) code for the Mace Ethernet Controller 
        !            26:  *
        !            27:  * HISTORY
        !            28:  *
        !            29:  * dd-mmm-yy    
        !            30:  *     Created.
        !            31:  *
        !            32:  */
        !            33: 
        !            34: #include <IOKit/assert.h>
        !            35: #include <IOKit/platform/AppleMacIODevice.h>
        !            36: #include "MaceEnetPrivate.h"
        !            37: 
        !            38: //------------------------------------------------------------------------
        !            39: 
        !            40: #define super IOEthernetController
        !            41: 
        !            42: OSDefineMetaClassAndStructors( MaceEnet, IOEthernetController )
        !            43: 
        !            44: //------------------------------------------------------------------------
        !            45: 
        !            46: #define        PROVIDER_DEV    0
        !            47: #define        PROVIDER_DMA_TX 1
        !            48: #define        PROVIDER_DMA_RX 2
        !            49: 
        !            50: /*
        !            51:  * Public Instance Methods
        !            52:  */
        !            53: 
        !            54: bool MaceEnet::init(OSDictionary * properties)
        !            55: {
        !            56:        if (!super::init(properties))
        !            57:                return false;
        !            58: 
        !            59:     isPromiscuous     = false;
        !            60:     multicastEnabled  = false;
        !            61:        ready             = false;
        !            62:        debugClient       = false;
        !            63:        debugTxPoll       = false;
        !            64:        netifClient       = false;
        !            65: 
        !            66:        return true;
        !            67: }
        !            68: 
        !            69: MaceEnet * MaceEnet::probe(IOService *    /*provider*/,
        !            70:                            unsigned int * /*score*/,
        !            71:                            unsigned int * /*specificity*/)
        !            72: {
        !            73: #ifdef OLD_CODE
        !            74:     extern int         kdp_flag;
        !            75: 
        !            76:     /*
        !            77:      * If bootargs: kdp bit 0 using in-kernel mace driver for early debugging,
        !            78:      *              Don't probe this driver.
        !            79:      */
        !            80:     if( kdp_flag & 1)
        !            81:        {
        !            82:                return 0;
        !            83:        }
        !            84: #endif
        !            85: 
        !            86:        return this;
        !            87: }
        !            88: 
        !            89: bool MaceEnet::start(IOService * provider)
        !            90: {
        !            91:        AppleMacIODevice *nub = OSDynamicCast(AppleMacIODevice, provider);
        !            92: 
        !            93:        if (!nub || !super::start(provider))
        !            94:                return false;
        !            95: 
        !            96:        transmitQueue = OSDynamicCast(IOOQGateFIFOQueue, getOutputQueue());
        !            97:        if (!transmitQueue)
        !            98:        {
        !            99:                IOLog("Mace: output queue initialization failed\n");
        !           100:                return false;
        !           101:        }
        !           102:        transmitQueue->retain();
        !           103: 
        !           104:        // Allocate debug queue. This stores packets retired from the TX ring
        !           105:        // by the polling routine. We cannot call freePacket() or m_free() within
        !           106:        // the debugger context.
        !           107:        //
        !           108:        // The capacity of the queue is set at maximum to prevent the queue from
        !           109:        // calling m_free() due to over-capacity. But we don't expect the size
        !           110:        // of the queue to grow too large.
        !           111:        //
        !           112:        debugQueue = IOPacketQueue::withCapacity((UInt) -1);
        !           113:        if (!debugQueue)
        !           114:                return false;
        !           115: 
        !           116:        // Allocate a IOMBufDBDMAMemoryCursor instance. Currently, the maximum
        !           117:        // number of segments is set to 2. The maximum length for each segment
        !           118:        // is set to the maximum ethernet frame size (plus padding).
        !           119: 
        !           120:        mbufCursor = IOMBufBigMemoryCursor::withSpecification(NETWORK_BUFSIZE, 2);
        !           121:        if (!mbufCursor)
        !           122:        {
        !           123:                IOLog("Mace: IOMBufMemoryCursor allocation failed\n");
        !           124:                return false;
        !           125:        }
        !           126: 
        !           127:        //
        !           128:        // Our provider is the nub representing the MaceEnet hardware
        !           129:        // controller. We will query it for our resource information.
        !           130:        //
        !           131: 
        !           132:        for (int i = 0; i < MEMORY_MAP_COUNT; i++) {
        !           133:                IOMemoryMap * map;
        !           134:                
        !           135:                map = provider->mapDeviceMemoryWithIndex(i);
        !           136:                if (!map)
        !           137:                        return false;
        !           138: 
        !           139: #ifdef DEBUG_XXX
        !           140:                IOLog("map %d: Phys:%08x Virt:%08x len:%d\n",
        !           141:                        i,
        !           142:                        (UInt) map->getPhysicalAddress(),
        !           143:                        (UInt) map->getVirtualAddress(),
        !           144:                        (UInt) map->getLength());
        !           145: #endif
        !           146: 
        !           147:                switch (i) {
        !           148:                        case MEMORY_MAP_ENET_INDEX:
        !           149:                                ioBaseEnet    = (IOPPCAddress) map->getVirtualAddress();
        !           150:                        ioBaseEnetROM = (IOPPCAddress) ((map->getPhysicalAddress() &
        !           151:                                        ~0xffff) | kControllerROMOffset);
        !           152:                                break;
        !           153:                        
        !           154:                        case MEMORY_MAP_TXDMA_INDEX:
        !           155:                                ioBaseEnetTxDMA = (IODBDMAChannelRegisters *)
        !           156:                                        map->getVirtualAddress();
        !           157:                                break;
        !           158:                        
        !           159:                        case MEMORY_MAP_RXDMA_INDEX:
        !           160:                                ioBaseEnetRxDMA = (IODBDMAChannelRegisters *)
        !           161:                                        map->getVirtualAddress();
        !           162:                                break;
        !           163:                }
        !           164:                
        !           165:                maps[i] = map;
        !           166:        }
        !           167: 
        !           168:        // Manually create an IODeviceMemory for the ROM memory
        !           169:        // range.
        !           170:        //
        !           171:        IODeviceMemory * romMemory = IODeviceMemory::withRange(
        !           172:                                        (UInt) ioBaseEnetROM, 0x1000);
        !           173:        if (!romMemory) {
        !           174:                IOLog("Mace: can't create ROM memory object\n");
        !           175:                return false;
        !           176:        }
        !           177:        
        !           178:        romMap = romMemory->map();      
        !           179:        romMemory->release();
        !           180: 
        !           181:        if (!romMap)
        !           182:                return false;
        !           183: 
        !           184:        ioBaseEnetROM = (IOPPCAddress) romMap->getVirtualAddress();
        !           185: 
        !           186: #ifdef DEBUG_XXX
        !           187:        IOLog("Mace: ioBaseEnet       : %08x\n", (UInt) ioBaseEnet);
        !           188:        IOLog("Mace: ioBaseEnetTxDMA  : %08x\n", (UInt) ioBaseEnetTxDMA);
        !           189:        IOLog("Mace: ioBaseEnetRxDMA  : %08x\n", (UInt) ioBaseEnetRxDMA);
        !           190:        IOLog("Mace: ioBaseEnetROM    : %08x\n", (UInt) ioBaseEnetROM);
        !           191: #endif
        !           192: 
        !           193:        //
        !           194:        // Get a reference to the IOWorkLoop in our superclass.
        !           195:        //
        !           196:        IOWorkLoop * myWorkLoop = (IOWorkLoop *) getWorkLoop();
        !           197:        assert(myWorkLoop);
        !           198: 
        !           199:        //
        !           200:        // Allocate two IOInterruptEventSources.
        !           201:        //
        !           202:        txIntSrc = IOInterruptEventSource::interruptEventSource
        !           203:             (this,
        !           204:              (IOInterruptEventAction) &MaceEnet::interruptOccurredForSource,
        !           205:              provider, PROVIDER_DMA_TX);
        !           206:         if (!txIntSrc
        !           207:         || (myWorkLoop->addEventSource(txIntSrc) != kIOReturnSuccess)) {
        !           208:                IOLog("Mace: txIntSrc init failure\n");
        !           209:                return false;
        !           210:        }
        !           211:        
        !           212:        rxIntSrc = IOInterruptEventSource::interruptEventSource
        !           213:             (this,
        !           214:              (IOInterruptEventAction) &MaceEnet::interruptOccurredForSource,
        !           215:              provider, PROVIDER_DMA_RX);
        !           216:         if (!rxIntSrc
        !           217:         || (myWorkLoop->addEventSource(rxIntSrc) != kIOReturnSuccess)) {
        !           218:                IOLog("Mace: rxIntSrc init failure\n");
        !           219:                return false;
        !           220:        }
        !           221: 
        !           222:        timerSrc = IOTimerEventSource::timerEventSource
        !           223:             (this, (IOTimerEventSource::Action) &MaceEnet::timeoutOccurred);
        !           224:        if (!timerSrc
        !           225:        || (myWorkLoop->addEventSource(timerSrc) != kIOReturnSuccess)) {
        !           226:                IOLog("Mace: timerSrc init failure\n");
        !           227:                return false;
        !           228:        }
        !           229: 
        !           230:        MGETHDR(txDebuggerPkt, M_DONTWAIT, MT_DATA);
        !           231:        if (!txDebuggerPkt)
        !           232:        {
        !           233:                IOLog("Mace: Can't allocate KDB buffer\n");
        !           234:                return false;
        !           235:        }
        !           236: 
        !           237: #if 0
        !           238:        // Do not enable interrupt sources until the hardware
        !           239:        // is enabled.
        !           240: 
        !           241:        // Enable the interrupt event sources.
        !           242:        myWorkLoop->enableAllInterrupts();
        !           243: #endif
        !           244: 
        !           245: #if 0
        !           246:        // Do not reset the hardware until we are ready to use it.
        !           247:        // Otherwise, we would have messed up kdp_mace driver's
        !           248:        // state. And we won't be able to break into the debugger
        !           249:        // until we attach our debugger client.
        !           250: 
        !           251:        //
        !           252:        // Perform a hardware reset.
        !           253:        //
        !           254:     if ( !resetAndEnable(false) ) 
        !           255:     {
        !           256:                return false;
        !           257:     }
        !           258: #endif
        !           259: 
        !           260:        // Cache my MAC address.
        !           261:        //
        !           262:        getHardwareAddress(&myAddress);
        !           263: 
        !           264:        //
        !           265:        // Allocate memory for ring buffers.
        !           266:        //
        !           267:     if (_allocateMemory() == false) 
        !           268:     {
        !           269:                return false;
        !           270:     }
        !           271: 
        !           272:        //
        !           273:        // Attach a kernel debugger client.
        !           274:        //
        !           275:        attachDebuggerClient(&debugger);
        !           276: 
        !           277:        //
        !           278:        // Allocate and initialize an IONetworkInterface object.
        !           279:        //
        !           280:        if (!attachNetworkInterface((IONetworkInterface **) &networkInterface))
        !           281:                return false;
        !           282: 
        !           283:     return true;
        !           284: }
        !           285: 
        !           286: /*-------------------------------------------------------------------------
        !           287:  *
        !           288:  *
        !           289:  *
        !           290:  *-------------------------------------------------------------------------*/
        !           291: 
        !           292: void MaceEnet::free()
        !           293: {
        !           294:     UInt               i;
        !           295:     
        !           296:     timerSrc->cancelTimeout();
        !           297:     
        !           298:     _resetChip();
        !           299: 
        !           300:        if (debugger)
        !           301:                debugger->release();
        !           302: 
        !           303:        if (timerSrc)
        !           304:                timerSrc->release();
        !           305: 
        !           306:        if (rxIntSrc)
        !           307:                rxIntSrc->release();
        !           308: 
        !           309:        if (txIntSrc)
        !           310:                txIntSrc->release();
        !           311: 
        !           312:        if (transmitQueue)
        !           313:                transmitQueue->release();
        !           314: 
        !           315:        if (debugQueue)
        !           316:                debugQueue->release();
        !           317: 
        !           318:     if (networkInterface)
        !           319:                networkInterface->release();
        !           320: 
        !           321:        if (mbufCursor)
        !           322:                mbufCursor->release();
        !           323: 
        !           324:        if (txDebuggerPkt)
        !           325:                freePacket(txDebuggerPkt);
        !           326: 
        !           327:     for (i = 0; i < rxMaxCommand; i++)
        !           328:        if (rxMbuf[i])  freePacket(rxMbuf[i]);
        !           329: 
        !           330:     for (i = 0; i < txMaxCommand; i++)
        !           331:        if (txMbuf[i]) freePacket(txMbuf[i]);
        !           332: 
        !           333:        if (romMap) romMap->release();
        !           334: 
        !           335:        for (i = 0; i < MEMORY_MAP_COUNT; i++)
        !           336:                if (maps[i]) maps[i]->release();
        !           337: 
        !           338:        if (dmaMemory.ptr)
        !           339:        {
        !           340:                IOFree(dmaMemory.ptrReal, dmaMemory.sizeReal);
        !           341:                dmaMemory.ptr = 0;
        !           342:        }
        !           343: 
        !           344:        super::free();
        !           345: }
        !           346: 
        !           347: /*-------------------------------------------------------------------------
        !           348:  *
        !           349:  *
        !           350:  *
        !           351:  *-------------------------------------------------------------------------*/
        !           352: 
        !           353: void MaceEnet::interruptOccurredForSource(IOInterruptEventSource *src,
        !           354:                 int /*count*/)
        !           355: {
        !           356:        bool doFlushQueue = false;
        !           357:        bool doService    = false;
        !           358: 
        !           359:        // IOLog("Mace: interrupt %08x %d\n", (UInt) src, count);
        !           360:        
        !           361:        if (!ready) {
        !           362:                // IOLog("Mace: unexpected interrupt\n");
        !           363:                return;
        !           364:        }
        !           365: 
        !           366:        reserveDebuggerLock();
        !           367: 
        !           368:        if (src == txIntSrc) {
        !           369:         txWDInterrupts++;
        !           370:         KERNEL_DEBUG(DBG_MACE_TXIRQ | DBG_FUNC_START, 0, 0, 0, 0, 0 );
        !           371:                doService = _transmitInterruptOccurred();
        !           372:         KERNEL_DEBUG(DBG_MACE_TXIRQ | DBG_FUNC_END,   0, 0, 0, 0, 0 );
        !           373:        }
        !           374:        else {
        !           375:         KERNEL_DEBUG(DBG_MACE_RXIRQ | DBG_FUNC_START, 0, 0, 0, 0, 0 );         
        !           376:                doFlushQueue = _receiveInterruptOccurred();
        !           377:         KERNEL_DEBUG(DBG_MACE_RXIRQ | DBG_FUNC_END,   0, 0, 0, 0, 0 ); 
        !           378:        }
        !           379: 
        !           380:        releaseDebuggerLock();
        !           381: 
        !           382:        /*
        !           383:         * Submit all received packets queued up by _receiveInterruptOccurred()
        !           384:         * to the network stack. The up call is performed without holding the
        !           385:         * debugger lock.
        !           386:         */
        !           387:        if (doFlushQueue)
        !           388:                networkInterface->flushInputQueue();
        !           389: 
        !           390:        /*
        !           391:         * Make sure the output queue is not stalled.
        !           392:         */
        !           393:        if (doService && netifClient)
        !           394:                transmitQueue->service();
        !           395: }
        !           396: 
        !           397: /*-------------------------------------------------------------------------
        !           398:  *
        !           399:  *
        !           400:  *
        !           401:  *-------------------------------------------------------------------------*/
        !           402: 
        !           403: UInt32 MaceEnet::outputPacket(struct mbuf *pkt)
        !           404: {
        !           405:     u_int32_t    i;
        !           406:     u_int8_t     regValue;
        !           407:     UInt32       ret = kIOOQReturnSuccess;
        !           408: 
        !           409:        // IOLog("Mace: outputPacket %d\n", pkt->m_pkthdr.len);
        !           410: 
        !           411:     KERNEL_DEBUG(DBG_MACE_TXQUEUE | DBG_FUNC_NONE, (int) pkt,
        !           412:                (int) pkt->m_pkthdr.len, 0, 0, 0 );
        !           413:        
        !           414:     /*
        !           415:      * Hold the debugger lock so the debugger can't interrupt us
        !           416:      */
        !           417:        reserveDebuggerLock();
        !           418:        
        !           419:     do
        !           420:     {
        !           421:                /*
        !           422:                 * Someone is turning off the receiver before the first transmit.
        !           423:                 * Dont know who yet!
        !           424:                 */
        !           425:                regValue = ReadMaceRegister( ioBaseEnet, kMacCC );
        !           426:                regValue |= kMacCCEnRcv;
        !           427:                WriteMaceRegister( ioBaseEnet, kMacCC, regValue );
        !           428:                
        !           429:                /* 
        !           430:                 * Preliminary sanity checks
        !           431:                 */
        !           432:                assert(pkt && netifClient);
        !           433: 
        !           434:                /*
        !           435:                 * Remove any completed packets from the Tx ring 
        !           436:                 */
        !           437:                _transmitInterruptOccurred();
        !           438:                
        !           439:                i = txCommandTail + 1;
        !           440:                if ( i >= txMaxCommand ) i = 0;
        !           441:                if ( i == txCommandHead )
        !           442:                {
        !           443:                        ret = kIOOQReturnStall;
        !           444:                        continue;
        !           445:                }
        !           446: 
        !           447:                /*
        !           448:                 * If there is space on the Tx ring, add the packet directly to the
        !           449:                 * ring
        !           450:                 */
        !           451:                _transmitPacket(pkt);
        !           452:     }
        !           453:     while ( 0 );
        !           454: 
        !           455:        releaseDebuggerLock();
        !           456:        
        !           457:        return ret;
        !           458: }
        !           459: 
        !           460: /*-------------------------------------------------------------------------
        !           461:  * Called by IOEthernetInterface client to enable the controller.
        !           462:  * This method is always called while running on the default workloop
        !           463:  * thread.
        !           464:  *-------------------------------------------------------------------------*/
        !           465: 
        !           466: IOReturn MaceEnet::enable(IONetworkInterface * netif)
        !           467: {
        !           468:        IONetworkParameter * param;
        !           469:        
        !           470:        // If an interface client has previously enabled us,
        !           471:        // and we know there can only be one interface client
        !           472:        // for this driver, then simply return true.
        !           473:        //
        !           474:        if (netifClient) {
        !           475:                IOLog("Mace: already enabled\n");
        !           476:                return kIOReturnSuccess;
        !           477:        }
        !           478: 
        !           479:        param = netif->getParameter(kIONetworkStatsKey);
        !           480:        if (!param || !(netStats = (IONetworkStats *) param->getBuffer()))
        !           481:        {
        !           482:                IOLog("Mace: invalid network statistics\n");
        !           483:                return kIOReturnError;
        !           484:        }
        !           485: 
        !           486:        if ((ready == false) && !resetAndEnable(true))
        !           487:                return kIOReturnIOError;
        !           488: 
        !           489:        // Record the interface as an active client.
        !           490:        //
        !           491:        netifClient = true;
        !           492: 
        !           493:        // Start our IOOutputQueue object.
        !           494:        //
        !           495:        transmitQueue->setCapacity(TRANSMIT_QUEUE_SIZE);
        !           496:        transmitQueue->start();
        !           497: 
        !           498:        return kIOReturnSuccess;
        !           499: }
        !           500: 
        !           501: /*-------------------------------------------------------------------------
        !           502:  * Called by IOEthernetInterface client to disable the controller.
        !           503:  * This method is always called while running on the default workloop
        !           504:  * thread.
        !           505:  *-------------------------------------------------------------------------*/
        !           506: 
        !           507: IOReturn MaceEnet::disable(IONetworkInterface * /*netif*/)
        !           508: {
        !           509:        // If we have no active clients, then disable the controller.
        !           510:        //
        !           511:        if (debugClient == false)
        !           512:                resetAndEnable(false);
        !           513:        
        !           514:        // Disable our IOOutputQueue object.
        !           515:        //
        !           516:        transmitQueue->stop();
        !           517: 
        !           518:        // Flush all packets currently in the output queue.
        !           519:        //
        !           520:        transmitQueue->setCapacity(0);
        !           521:        transmitQueue->flush();
        !           522: 
        !           523:        netifClient = false;
        !           524: 
        !           525:        return kIOReturnSuccess;
        !           526: }
        !           527: 
        !           528: /*-------------------------------------------------------------------------
        !           529:  * This method is called by our debugger client to bring up the controller
        !           530:  * just before the controller is registered as the debugger device. The
        !           531:  * debugger client is attached in response to the attachDebuggerClient()
        !           532:  * call.
        !           533:  *
        !           534:  * This method is always called while running on the default workloop
        !           535:  * thread.
        !           536:  *-------------------------------------------------------------------------*/
        !           537: 
        !           538: IOReturn MaceEnet::handleDebuggerOpen(IOKernelDebugger * /*debugger*/)
        !           539: {
        !           540:        // Enable hardware and make it ready to support the debugger client.
        !           541:        //
        !           542:        if ((ready == false) && !resetAndEnable(true))
        !           543:                return kIOReturnIOError;
        !           544: 
        !           545:        // Record the debugger as an active client of ours.
        !           546:        //
        !           547:        debugClient = true;
        !           548: 
        !           549:        // Returning true will allow the kdp registration to continue.
        !           550:        // If we return false, then we will not be registered as the
        !           551:        // debugger device, and the attachDebuggerClient() call will
        !           552:        // return NULL.
        !           553:        //
        !           554:        return kIOReturnSuccess;
        !           555: }
        !           556: 
        !           557: /*-------------------------------------------------------------------------
        !           558:  * This method is called by our debugger client to stop the controller.
        !           559:  * The debugger will call this method when we issue a detachDebuggerClient().
        !           560:  *
        !           561:  * This method is always called while running on the default workloop
        !           562:  * thread.
        !           563:  *-------------------------------------------------------------------------*/
        !           564: 
        !           565: IOReturn MaceEnet::handleDebuggerClose(IOKernelDebugger * /*debugger*/)
        !           566: {
        !           567:        debugClient = false;
        !           568: 
        !           569:        // If we have no active clients, then disable the controller.
        !           570:        //
        !           571:        if (netifClient == false)
        !           572:                resetAndEnable(false);
        !           573: 
        !           574:        return kIOReturnSuccess;
        !           575: }
        !           576: 
        !           577: /*-------------------------------------------------------------------------
        !           578:  *
        !           579:  *
        !           580:  *
        !           581:  *-------------------------------------------------------------------------*/
        !           582: 
        !           583: bool MaceEnet::resetAndEnable(bool enable)
        !           584: {
        !           585:        bool ret = true;
        !           586: 
        !           587:        if (timerSrc)
        !           588:                timerSrc->cancelTimeout();
        !           589: 
        !           590:        _disableAdapterInterrupts();
        !           591:        if (getWorkLoop()) getWorkLoop()->disableAllInterrupts();
        !           592: 
        !           593:        reserveDebuggerLock();
        !           594: 
        !           595:        ready = false;
        !           596: 
        !           597:        _resetChip();
        !           598: 
        !           599:     do {
        !           600:                if (!enable) break;
        !           601: 
        !           602:                if ( !_initRxRing() || !_initTxRing() || !_initChip() ) 
        !           603:                {
        !           604:                        ret = false;
        !           605:                        break;
        !           606:                }
        !           607: 
        !           608:                _startChip();
        !           609: 
        !           610:                ready = true;
        !           611: 
        !           612:                releaseDebuggerLock();
        !           613: 
        !           614:                timerSrc->setTimeoutMS(WATCHDOG_TIMER_MS);
        !           615:                
        !           616:                if (getWorkLoop()) getWorkLoop()->enableAllInterrupts();
        !           617:                _enableAdapterInterrupts();
        !           618: 
        !           619:                return true;
        !           620:     }
        !           621:        while (0);
        !           622: 
        !           623:        releaseDebuggerLock();
        !           624: 
        !           625:     return ret;
        !           626: }
        !           627: 
        !           628: /*-------------------------------------------------------------------------
        !           629:  *
        !           630:  *
        !           631:  *
        !           632:  *-------------------------------------------------------------------------*/
        !           633: 
        !           634: void MaceEnet::_sendTestPacket()
        !           635: {
        !           636: //     IOOutputPacketStatus ret;
        !           637:     unsigned char * buf;
        !           638:        const unsigned int size = 64;
        !           639:        
        !           640:        struct mbuf * m = allocatePacket(size);
        !           641:        if (!m) {
        !           642:                IOLog("Mace: _sendTestpacket:  allocatePacket() failed\n");
        !           643:                return;
        !           644:        }
        !           645: 
        !           646:        buf = mtod(m, unsigned char *);
        !           647: 
        !           648:        bcopy(&myAddress, buf, NUM_EN_ADDR_BYTES);
        !           649:        buf += NUM_EN_ADDR_BYTES;
        !           650:     bcopy(&myAddress, buf, NUM_EN_ADDR_BYTES);
        !           651:        buf += NUM_EN_ADDR_BYTES;
        !           652:        *buf++ = 0;
        !           653:        *buf++ = 0;
        !           654: 
        !           655:        outputPacket(m);
        !           656: }
        !           657: 
        !           658: /*-------------------------------------------------------------------------
        !           659:  *
        !           660:  *
        !           661:  *
        !           662:  *-------------------------------------------------------------------------*/
        !           663: 
        !           664: void MaceEnet::timeoutOccurred(IOTimerEventSource * /*timer*/)
        !           665: {
        !           666:     u_int32_t   dmaStatus;
        !           667:        bool        doFlushQueue = false;
        !           668:        bool        doService    = false;
        !           669: 
        !           670:        reserveDebuggerLock();
        !           671: 
        !           672:     /*
        !           673:      * Check for DMA shutdown on receive channel
        !           674:      */
        !           675:     dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
        !           676:     if ( !(dmaStatus & kdbdmaActive) )
        !           677:     {
        !           678: #if 0
        !           679:                IOLog("Mace: Timeout check - RxHead = %d RxTail = %d\n", 
        !           680:                        rxCommandHead, rxCommandTail);
        !           681: #endif
        !           682: 
        !           683: #if 0
        !           684:       IOLog( "Mace: Rx Commands = %08x(p) Rx DMA Ptr = %08x(p)\n\r", rxDMACommandsPhys, IOGetDBDMACommandPtr(ioBaseEnetRxDMA) ); 
        !           685:       [self _dumpDesc:(void *)rxDMACommands Size:rxMaxCommand * sizeof(enet_dma_cmd_t)];
        !           686: #endif 
        !           687: 
        !           688:                doFlushQueue = _receiveInterruptOccurred();
        !           689:     } 
        !           690: 
        !           691:     /*
        !           692:      * If there are pending entries on the Tx ring
        !           693:      */
        !           694:     if ( txCommandHead != txCommandTail )
        !           695:     {
        !           696:                /* 
        !           697:                 * If we did not service the Tx ring during the last timeout interval,
        !           698:                 * then force servicing of the Tx ring.
        !           699:                 * If we have more than one timeout interval without any transmit 
        !           700:                 * interrupts, then force the transmitter to reset.
        !           701:                 */
        !           702:                if ( txWDInterrupts == 0 )
        !           703:                { 
        !           704:                        if ( ++txWDTimeouts > 1 ) txWDForceReset = true;
        !           705: 
        !           706: #if 0
        !           707:                        IOLog( "Mace: Checking for timeout - TxHead = %d TxTail = %d\n", 
        !           708:                                txCommandHead, txCommandTail);
        !           709: #endif
        !           710:                        doService = _transmitInterruptOccurred();
        !           711:                }
        !           712:                else
        !           713:                {
        !           714:                        txWDTimeouts     = 0;
        !           715:                        txWDInterrupts   = 0;
        !           716:                }
        !           717:     }
        !           718:     else
        !           719:     {
        !           720:                txWDTimeouts     = 0;
        !           721:                txWDInterrupts   = 0;
        !           722:     }
        !           723: 
        !           724:        // Clean-up after the debugger if the debugger was active.
        !           725:        //
        !           726:        if (debugTxPoll)
        !           727:        {
        !           728:                debugQueue->flush();
        !           729:                debugTxPoll = false;
        !           730:                releaseDebuggerLock();
        !           731:                doService = true;
        !           732:        }
        !           733:        else
        !           734:        {
        !           735:                releaseDebuggerLock();
        !           736:        }
        !           737: 
        !           738:        /*
        !           739:         * Submit all received packets queued up by _receiveInterruptOccurred()
        !           740:         * to the network stack. The up call is performed without holding the
        !           741:         * debugger lock.
        !           742:         */
        !           743:        if (doFlushQueue)
        !           744:        {
        !           745:                networkInterface->flushInputQueue();
        !           746:        }
        !           747: 
        !           748:        /*
        !           749:         * Make sure the output queue is not stalled.
        !           750:         */
        !           751:        if (doService && netifClient)
        !           752:        {
        !           753:                transmitQueue->service();
        !           754:        }
        !           755: 
        !           756:     /*
        !           757:      * Restart the watchdog timer
        !           758:      */
        !           759:        timerSrc->setTimeoutMS(WATCHDOG_TIMER_MS);
        !           760: }
        !           761: 
        !           762: /*-------------------------------------------------------------------------
        !           763:  *
        !           764:  *
        !           765:  *
        !           766:  *-------------------------------------------------------------------------*/
        !           767: 
        !           768: const char * MaceEnet::getVendorString() const
        !           769: {
        !           770:        return ("Apple");
        !           771: }
        !           772: 
        !           773: const char * MaceEnet::getModelString() const
        !           774: {
        !           775:        return ("Mace");
        !           776: }
        !           777: 
        !           778: const char * MaceEnet::getRevisionString() const
        !           779: {
        !           780:        return ("");
        !           781: }
        !           782: 
        !           783: /*-------------------------------------------------------------------------
        !           784:  *
        !           785:  *
        !           786:  *
        !           787:  *-------------------------------------------------------------------------*/
        !           788: 
        !           789: IOReturn MaceEnet::_setPromiscuousMode(IOEnetPromiscuousMode mode)
        !           790: {
        !           791:     u_int8_t           regVal;
        !           792:        
        !           793:     regVal = ReadMaceRegister( ioBaseEnet, kMacCC );
        !           794:     WriteMaceRegister( ioBaseEnet, kMacCC, regVal & ~kMacCCEnRcv );
        !           795:        if (mode == kIOEnetPromiscuousModeOff) {
        !           796:                regVal &= ~kMacCCProm;
        !           797:                isPromiscuous = false;
        !           798:        }
        !           799:        else {
        !           800:                regVal |= kMacCCProm;
        !           801:                isPromiscuous = true;
        !           802:        }
        !           803:        WriteMaceRegister( ioBaseEnet, kMacCC, regVal );
        !           804:     
        !           805:     return kIOReturnSuccess;
        !           806: 
        !           807: }
        !           808: 
        !           809: IOReturn MaceEnet::setPromiscuousMode(IOEnetPromiscuousMode mode)
        !           810: {
        !           811:        IOReturn ret;
        !           812: 
        !           813:        reserveDebuggerLock();
        !           814:        ret = _setPromiscuousMode(mode);
        !           815:        releaseDebuggerLock();
        !           816: 
        !           817:     return ret;
        !           818: }
        !           819: 
        !           820: IOReturn MaceEnet::setMulticastMode(IOEnetMulticastMode mode)
        !           821: {
        !           822:        multicastEnabled = (mode == kIOEnetMulticastModeOff) ? false : true;
        !           823:        return kIOReturnSuccess;
        !           824: }
        !           825: 
        !           826: IOReturn MaceEnet::setMulticastList(enet_addr_t *addrs, UInt count)
        !           827: {
        !           828:        reserveDebuggerLock();
        !           829:        _resetHashTableMask();
        !           830:        for (UInt i = 0; i < count; i++) {
        !           831:                _addToHashTableMask(addrs->ea_byte);
        !           832:                addrs++;
        !           833:        }
        !           834:        _updateHashTableMask();
        !           835:        releaseDebuggerLock();
        !           836:        return kIOReturnSuccess;
        !           837: }
        !           838: 
        !           839: /*
        !           840:  * Allocate an IOOutputQueue object.
        !           841:  */
        !           842: IOOutputQueue * MaceEnet::allocateOutputQueue()
        !           843: {      
        !           844:        return IOOQGateFIFOQueue::withTarget( this, getWorkLoop() );
        !           845: }
        !           846: 
        !           847: /*
        !           848:  * Kernel Debugger Support 
        !           849:  */
        !           850: void MaceEnet::sendPacket(void *pkt, UInt pkt_len)
        !           851: {
        !           852:        _sendPacket(pkt, pkt_len);
        !           853: }
        !           854: 
        !           855: void MaceEnet::receivePacket(void *pkt, UInt *pkt_len, UInt timeout)
        !           856: {
        !           857:     _receivePacket(pkt, pkt_len, timeout);
        !           858: }
        !           859: 
        !           860: #if 0  // no power management stuff in IOKit yet.
        !           861: /*
        !           862:  * Power management methods. 
        !           863:  */
        !           864: - (IOReturn)getPowerState:(PMPowerState *)state_p
        !           865: {
        !           866:     return kIOReturnUnsupported;
        !           867: }
        !           868: 
        !           869: - (IOReturn)setPowerState:(PMPowerState)state
        !           870: {
        !           871:     if (state == PM_OFF) {
        !           872:        resetAndEnabled = NO;
        !           873:         [self _resetChip];
        !           874:        return kIOReturnSuccess;
        !           875:     }
        !           876:     return kIOReturnUnsupported;
        !           877: }
        !           878: 
        !           879: - (IOReturn)getPowerManagement:(PMPowerManagementState *)state_p
        !           880: {
        !           881:     return kIOReturnUnsupported;
        !           882: }
        !           883: 
        !           884: - (IOReturn)setPowerManagement:(PMPowerManagementState)state
        !           885: {
        !           886:     return kIOReturnUnsupported;
        !           887: }
        !           888: #endif /* 0 */

unix.superglobalmegacorp.com

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