Annotation of XNU/iokit/Drivers/network/drvMaceEnet/MaceEnet.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 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.