Annotation of XNU/iokit/Drivers/network/drvPPCBMac/BMacEnetPrivate.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) 1998-1999 by Apple Computer, Inc., All rights reserved.
        !            24:  *
        !            25:  * Implementation for hardware dependent (relatively) code 
        !            26:  * for the BMac Ethernet controller. 
        !            27:  *
        !            28:  * HISTORY
        !            29:  *
        !            30:  */
        !            31: 
        !            32: #include <IOKit/assert.h>
        !            33: #include <IOKit/system.h>
        !            34: 
        !            35: #include "BMacEnetPrivate.h"
        !            36: #include <IOKit/IOLib.h>
        !            37: 
        !            38: /*****************************************************************************
        !            39:  *
        !            40:  * Hacks.
        !            41:  */
        !            42: 
        !            43: typedef        unsigned long long      ns_time_t;      /* nanoseconds! */
        !            44: 
        !            45: #define NSEC_PER_SEC   1000000000
        !            46: 
        !            47: static void
        !            48: _IOGetTimestamp(ns_time_t *nsp)
        !            49: {
        !            50:        mach_timespec_t         now;
        !            51: 
        !            52:        IOGetTime(&now);
        !            53:        *nsp = ((ns_time_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
        !            54: }
        !            55: 
        !            56: /*
        !            57:  * Find a physical address (if any) for the specified virtual address.
        !            58:  *
        !            59:  * Note: what about vm_offset_t kvtophys(vm_offset_t va) 
        !            60:  */
        !            61: static IOReturn _IOPhysicalFromVirtual(
        !            62:        vm_address_t virtualAddress,
        !            63:        unsigned *physicalAddress)
        !            64: {
        !            65:        *physicalAddress = pmap_extract(kernel_pmap, virtualAddress);
        !            66:        if(*physicalAddress == 0) {
        !            67:                return kIOReturnBadArgument;
        !            68:        }
        !            69:        else {
        !            70:                return kIOReturnSuccess;
        !            71:        }
        !            72: }
        !            73: 
        !            74: /****************************************************************************/
        !            75: 
        !            76:  
        !            77: extern kern_return_t           kmem_alloc_wired();
        !            78: 
        !            79: static IODBDMADescriptor       dbdmaCmd_Nop;
        !            80: static IODBDMADescriptor       dbdmaCmd_NopWInt;
        !            81: static IODBDMADescriptor       dbdmaCmd_LoadInt;                       
        !            82: static IODBDMADescriptor       dbdmaCmd_LoadIntWInt;
        !            83: static IODBDMADescriptor       dbdmaCmd_Stop;
        !            84: static IODBDMADescriptor       dbdmaCmd_Branch;
        !            85: 
        !            86: static u_int8_t reverseBitOrder(u_int8_t data )
        !            87: {
        !            88:        u_int8_t        val = 0;
        !            89:        int                     i;
        !            90: 
        !            91:        for ( i=0; i < 8; i++ )
        !            92:        {
        !            93:                val <<= 1;
        !            94:                if (data & 1) val |= 1;
        !            95:                data >>= 1;
        !            96:        }
        !            97:        return( val );
        !            98: }
        !            99: 
        !           100: /*
        !           101:  * Function: IOMallocPage
        !           102:  *
        !           103:  * Purpose:
        !           104:  *   Returns a pointer to a page-aligned memory block of size >= PAGE_SIZE
        !           105:  *
        !           106:  * Return:
        !           107:  *   Actual pointer and size of block returned in actual_ptr and actual_size.
        !           108:  *   Use these as arguments to kfree: kfree(*actual_ptr, *actual_size);
        !           109:  */
        !           110: static void *
        !           111: IOMallocPage(int request_size, void ** actual_ptr, u_int * actual_size)
        !           112: {
        !           113:     void * mem_ptr;
        !           114:     
        !           115:        *actual_size = round_page(request_size) + PAGE_SIZE;
        !           116:        mem_ptr = IOMalloc(*actual_size);
        !           117:        if (mem_ptr == NULL)
        !           118:                return NULL;
        !           119:        *actual_ptr = mem_ptr;
        !           120:        return ((void *)round_page(mem_ptr));
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * Private functions
        !           125:  */
        !           126: bool BMacEnet::_allocateMemory()
        !           127: {
        !           128:     u_int32_t                  i, n;
        !           129:     unsigned char *            virtAddr;
        !           130:     u_int32_t                  physBase;
        !           131:     u_int32_t                  physAddr;
        !           132:        u_int32_t                       dbdmaSize;
        !           133:  
        !           134:     /* 
        !           135:      * Calculate total space for DMA channel commands
        !           136:      */
        !           137:     dbdmaSize = round_page(
        !           138:                RX_RING_LENGTH * sizeof(enet_dma_cmd_t) + 
        !           139:                TX_RING_LENGTH * sizeof(enet_txdma_cmd_t) +
        !           140:                2 * sizeof(IODBDMADescriptor) );
        !           141: 
        !           142:     /*
        !           143:      * Allocate required memory
        !           144:      */
        !           145:        dmaMemory.size = dbdmaSize;
        !           146:        dmaMemory.ptr = (void *)IOMallocPage(
        !           147:                                 dmaMemory.size,
        !           148:                                 &dmaMemory.ptrReal,
        !           149:                                 &dmaMemory.sizeReal
        !           150:                                 );
        !           151: 
        !           152:        dmaCommands = (unsigned char *) dmaMemory.ptr;
        !           153:        if (dmaCommands == NULL) {
        !           154:                IOLog( "Ethernet(BMac): Cant allocate channel DBDMA commands\n\r" );
        !           155:                return false;
        !           156:        }
        !           157: 
        !           158:     /*
        !           159:      * If we needed more than one page, then make sure we received
        !           160:         * contiguous memory.
        !           161:      */
        !           162:     n = (dbdmaSize - PAGE_SIZE) / PAGE_SIZE;
        !           163:     _IOPhysicalFromVirtual( (vm_address_t) dmaCommands, &physBase );
        !           164: 
        !           165:     virtAddr = (unsigned char *) dmaCommands;
        !           166:     for( i=0; i < n; i++, virtAddr += PAGE_SIZE )
        !           167:        {
        !           168:                _IOPhysicalFromVirtual( (vm_address_t) virtAddr, &physAddr );
        !           169:                if (physAddr != (physBase + i * PAGE_SIZE) )
        !           170:                {
        !           171:                        IOLog( "Ethernet(BMac): Cannot allocate contiguous memory"
        !           172:                                " for DBDMA commands\n\r" );
        !           173:                        return false;
        !           174:                }
        !           175:        }           
        !           176: 
        !           177:     /* 
        !           178:      * Setup the receive ring pointers
        !           179:      */
        !           180:     rxDMACommands = (enet_dma_cmd_t *)dmaCommands;
        !           181:     rxMaxCommand  = RX_RING_LENGTH;
        !           182: 
        !           183:     /*
        !           184:      * Setup the transmit ring pointers
        !           185:      */
        !           186:     txDMACommands = (enet_txdma_cmd_t *)(dmaCommands +
        !           187:                RX_RING_LENGTH * sizeof(enet_dma_cmd_t) + sizeof(IODBDMADescriptor));
        !           188:     txMaxCommand  = TX_RING_LENGTH;
        !           189: 
        !           190:     /*
        !           191:      * Setup pre-initialized DBDMA commands 
        !           192:      */
        !           193:     IOMakeDBDMADescriptor( (&dbdmaCmd_Nop),
        !           194:                             kdbdmaNop,
        !           195:                                                        kdbdmaKeyStream0,
        !           196:                                                        kdbdmaIntNever,
        !           197:                                                        kdbdmaBranchNever,
        !           198:                                                        kdbdmaWaitNever,
        !           199:                             0,
        !           200:                             0);
        !           201: 
        !           202:     IOMakeDBDMADescriptor( (&dbdmaCmd_NopWInt),
        !           203:                             kdbdmaNop,
        !           204:                                                        kdbdmaKeyStream0,
        !           205:                                                        kdbdmaIntAlways,
        !           206:                                                        kdbdmaBranchNever,
        !           207:                                                        kdbdmaWaitNever,
        !           208:                             0,
        !           209:                             0);
        !           210: 
        !           211:        UInt32 ioBaseEnetPhys = maps[MEMORY_MAP_ENET_INDEX]->getPhysicalAddress();
        !           212: 
        !           213:     IOMakeDBDMADescriptor( (&dbdmaCmd_LoadInt),
        !           214:                             kdbdmaLoadQuad,
        !           215:                             kdbdmaKeySystem,
        !           216:                             kdbdmaIntNever,
        !           217:                             kdbdmaBranchNever,
        !           218:                             kdbdmaWaitNever,
        !           219:                             2,
        !           220:                             ((int)ioBaseEnetPhys +  kSTAT)   );
        !           221: 
        !           222:     IOMakeDBDMADescriptor( (&dbdmaCmd_LoadIntWInt),
        !           223:                             kdbdmaLoadQuad,
        !           224:                             kdbdmaKeySystem,
        !           225:                             kdbdmaIntAlways,
        !           226:                             kdbdmaBranchNever,
        !           227:                             kdbdmaWaitNever,
        !           228:                             2,
        !           229:                             ((int)ioBaseEnetPhys +  kSTAT)   );
        !           230: 
        !           231:     IOMakeDBDMADescriptor( (&dbdmaCmd_Stop),
        !           232:                             kdbdmaStop,
        !           233:                                                        kdbdmaKeyStream0,
        !           234:                                                        kdbdmaIntNever,
        !           235:                                                        kdbdmaBranchNever,
        !           236:                                                        kdbdmaWaitNever,
        !           237:                             0,
        !           238:                             0);
        !           239: 
        !           240:     IOMakeDBDMADescriptor( (&dbdmaCmd_Branch),
        !           241:                             kdbdmaNop,
        !           242:                                                        kdbdmaKeyStream0,
        !           243:                                                        kdbdmaIntNever,
        !           244:                                                        kdbdmaBranchAlways,
        !           245:                                                        kdbdmaWaitNever,
        !           246:                             0,
        !           247:                             0);
        !           248: 
        !           249:     return true;
        !           250: }
        !           251: 
        !           252: /*-------------------------------------------------------------------------
        !           253:  *
        !           254:  * Setup the Transmit Ring
        !           255:  * -----------------------
        !           256:  * Each transmit ring entry consists of two words to transmit data from buffer
        !           257:  * segments (possibly) spanning a page boundary. This is followed by two DMA 
        !           258:  * commands which read transmit frame status and interrupt status from the Bmac 
        !           259:  * chip. The last DMA command in each transmit ring entry generates a host 
        !           260:  * interrupt. The last entry in the ring is followed by a DMA branch to the 
        !           261:  * first entry.
        !           262:  *-------------------------------------------------------------------------*/
        !           263: 
        !           264: bool BMacEnet::_initTxRing()
        !           265: {
        !           266:     bool               kr;
        !           267:        u_int32_t       i;
        !           268:        IODBDMADescriptor       dbdmaCmd, dbdmaCmdInt;
        !           269: 
        !           270:     /*
        !           271:      * Clear the transmit DMA command memory
        !           272:      */  
        !           273:     bzero( (void *)txDMACommands, sizeof(enet_txdma_cmd_t) * txMaxCommand);
        !           274:     txCommandHead = 0;
        !           275:     txCommandTail = 0;
        !           276: 
        !           277:     /*
        !           278:      * DMA Channel commands 2 are the same for all DBDMA entries on transmit.
        !           279:      * Initialize them now.
        !           280:      */
        !           281:     
        !           282:     dbdmaCmd     = ( chipId >= kCHIPID_PaddingtonXmitStreaming ) ? dbdmaCmd_Nop     : dbdmaCmd_LoadInt;
        !           283:     dbdmaCmdInt  = ( chipId >= kCHIPID_PaddingtonXmitStreaming ) ? dbdmaCmd_NopWInt : dbdmaCmd_LoadIntWInt;
        !           284: 
        !           285:     for( i=0; i < txMaxCommand; i++ )
        !           286:     {
        !           287:       txDMACommands[i].desc_seg[2] = ( (i+1) % TX_PKTS_PER_INT ) ? dbdmaCmd : dbdmaCmdInt;
        !           288:     }
        !           289: 
        !           290:     /* 
        !           291:      * Put a DMA Branch command after the last entry in the transmit ring.
        !           292:         * Set the branch address to the physical address of the start of the 
        !           293:         * transmit ring.
        !           294:      */
        !           295:     txDMACommands[txMaxCommand].desc_seg[0] = dbdmaCmd_Branch; 
        !           296: 
        !           297:     kr = _IOPhysicalFromVirtual( (vm_address_t) txDMACommands,
        !           298:                (u_int32_t *)&txDMACommandsPhys );
        !           299:        if ( kr != kIOReturnSuccess )
        !           300:        {
        !           301:                IOLog( "Ethernet(BMac): Bad DBDMA command buf - %08x\n\r", 
        !           302:                        (u_int32_t)txDMACommands );
        !           303:     }
        !           304:        IOSetCCCmdDep( &txDMACommands[txMaxCommand].desc_seg[0],
        !           305:                txDMACommandsPhys );
        !           306:  
        !           307:     /* 
        !           308:      * Set the Transmit DMA Channel pointer to the first entry in the
        !           309:         * transmit ring.
        !           310:      */
        !           311:     IOSetDBDMACommandPtr( ioBaseEnetTxDMA, txDMACommandsPhys );
        !           312: 
        !           313:     return true;
        !           314: }
        !           315: 
        !           316: /*-------------------------------------------------------------------------
        !           317:  *
        !           318:  * Setup the Receive ring
        !           319:  * ----------------------
        !           320:  * Each receive ring entry consists of two DMA commands to receive data
        !           321:  * into a network buffer (possibly) spanning a page boundary. The second
        !           322:  * DMA command in each entry generates a host interrupt.
        !           323:  * The last entry in the ring is followed by a DMA branch to the first
        !           324:  * entry. 
        !           325:  *
        !           326:  *-------------------------------------------------------------------------*/
        !           327: 
        !           328: bool BMacEnet::_initRxRing()
        !           329: {
        !           330:     u_int32_t          i;
        !           331:     bool                       status;
        !           332:     IOReturn           kr;
        !           333:     
        !           334:     /*
        !           335:      * Clear the receive DMA command memory
        !           336:      */
        !           337:     bzero((void *)rxDMACommands, sizeof(enet_dma_cmd_t) * rxMaxCommand);
        !           338: 
        !           339:     kr = _IOPhysicalFromVirtual( (vm_address_t) rxDMACommands,
        !           340:                (u_int32_t *)&rxDMACommandsPhys );
        !           341:     if ( kr != kIOReturnSuccess )
        !           342:     {
        !           343:                IOLog( "Ethernet(BMac): Bad DBDMA command buf - %08x\n\r",
        !           344:                        (u_int32_t)rxDMACommands );
        !           345:                return false;
        !           346:     }
        !           347: 
        !           348:     /*
        !           349:      * Allocate a receive buffer for each entry in the Receive ring
        !           350:      */
        !           351:     for (i = 0; i < rxMaxCommand-1; i++) 
        !           352:        {       
        !           353:                if (rxMbuf[i] == NULL)  
        !           354:                {               
        !           355:                        rxMbuf[i] = allocatePacket(NETWORK_BUFSIZE);
        !           356:                        if (!rxMbuf[i])
        !           357:                        {
        !           358:                                IOLog("Ethernet(BMac): allocatePacket failed\n");
        !           359:                                return false;
        !           360:                        }
        !           361:                }
        !           362: 
        !           363:                /* 
        !           364:                 * Set the DMA commands for the ring entry to transfer data to the 
        !           365:                 * mbuf.
        !           366:                 */
        !           367:                status = _updateDescriptorFromMbuf(rxMbuf[i], &rxDMACommands[i], true);
        !           368:                if (status == false)
        !           369:                {    
        !           370:                        IOLog("Ethernet(BMac): cannot map mbuf to physical memory in"
        !           371:                                " _initRxRing\n\r");
        !           372:                        return false;
        !           373:                }
        !           374:        }
        !           375: 
        !           376:     /*
        !           377:      * Set the receive queue head to point to the first entry in the ring.
        !           378:         * Set the receive queue tail to point to a DMA Stop command after the
        !           379:         * last ring entry
        !           380:      */    
        !           381:     rxCommandHead = 0;
        !           382:     rxCommandTail = i;
        !           383: 
        !           384:     rxDMACommands[i].desc_seg[0] = dbdmaCmd_Stop; 
        !           385:     rxDMACommands[i].desc_seg[1] = dbdmaCmd_Nop;
        !           386: 
        !           387:     /*
        !           388:      * Setup a DMA branch command after the stop command
        !           389:      */
        !           390:     i++;
        !           391:     rxDMACommands[i].desc_seg[0] = dbdmaCmd_Branch; 
        !           392: 
        !           393:     IOSetCCCmdDep( &rxDMACommands[i].desc_seg[0], rxDMACommandsPhys );
        !           394: 
        !           395:     /*
        !           396:      * Set DMA command pointer to first receive entry
        !           397:      */ 
        !           398:     IOSetDBDMACommandPtr (ioBaseEnetRxDMA, rxDMACommandsPhys);
        !           399: 
        !           400:     return true;
        !           401: }
        !           402: 
        !           403: /*-------------------------------------------------------------------------
        !           404:  *
        !           405:  *
        !           406:  *
        !           407:  *-------------------------------------------------------------------------*/
        !           408: 
        !           409: void BMacEnet::_startChip()
        !           410: {
        !           411:     u_int16_t  oldConfig;
        !           412: 
        !           413:     IODBDMAContinue( ioBaseEnetRxDMA );
        !           414:   
        !           415:     // turn on rx plus any other bits already on (promiscuous possibly)
        !           416:     oldConfig = ReadBigMacRegister(ioBaseEnet, kRXCFG);                
        !           417:     WriteBigMacRegister(ioBaseEnet, kRXCFG, oldConfig | kRxMACEnable ); 
        !           418:  
        !           419:     oldConfig = ReadBigMacRegister(ioBaseEnet, kTXCFG);                
        !           420:     WriteBigMacRegister(ioBaseEnet, kTXCFG, oldConfig | kTxMACEnable ); 
        !           421: }
        !           422: 
        !           423: /*-------------------------------------------------------------------------
        !           424:  *
        !           425:  *
        !           426:  *
        !           427:  *-------------------------------------------------------------------------*/
        !           428: 
        !           429: void BMacEnet::_resetChip()
        !           430: {
        !           431:     volatile u_int32_t *heathrowFCR;
        !           432:     u_int32_t                  fcrValue;
        !           433:        u_int16_t                       *pPhyType;
        !           434:         
        !           435:     IODBDMAReset( ioBaseEnetRxDMA );  
        !           436:     IODBDMAReset( ioBaseEnetTxDMA );  
        !           437: 
        !           438:     IOSetDBDMAWaitSelect( ioBaseEnetTxDMA,
        !           439:                IOSetDBDMAChannelControlBits( kdbdmaS5 ) );
        !           440: 
        !           441:     IOSetDBDMABranchSelect( ioBaseEnetRxDMA,
        !           442:                IOSetDBDMAChannelControlBits( kdbdmaS6 ) );
        !           443: 
        !           444:     IOSetDBDMAInterruptSelect( ioBaseEnetRxDMA,
        !           445:                IOSetDBDMAChannelControlBits( kdbdmaS6 ) );
        !           446: 
        !           447:     heathrowFCR = (u_int32_t *)((u_int8_t *)ioBaseHeathrow + kHeathrowFCR);
        !           448: 
        !           449:     fcrValue = *heathrowFCR;
        !           450:     eieio();
        !           451: 
        !           452:     fcrValue = OSReadSwapInt32( &fcrValue, 0 );
        !           453: 
        !           454:     /*
        !           455:      * Enable the ethernet transceiver/clocks
        !           456:      */
        !           457:     fcrValue |= kEnetEnabledBits;
        !           458:     fcrValue &= ~kResetEnetCell;
        !           459:                                                
        !           460:     *heathrowFCR = OSReadSwapInt32( &fcrValue, 0 );
        !           461:     eieio();
        !           462:     IOSleep( 100 );
        !           463: 
        !           464:     /*
        !           465:      * Determine if PHY chip is configured. Reset and enable it (if present).
        !           466:      */
        !           467:     if ( phyId == 0xff )
        !           468:     {
        !           469:         phyMIIDelay = 20;
        !           470:         if ( miiFindPHY(&phyId) == true )
        !           471:         {
        !           472:                        miiResetPHY(phyId);
        !           473: 
        !           474:             pPhyType = (u_int16_t *)&phyType;
        !           475:             miiReadWord(pPhyType,   MII_ID0, phyId);
        !           476:                        miiReadWord(pPhyType+1, MII_ID1, phyId);
        !           477: 
        !           478:             if ( (phyType & MII_ST10040_MASK) == MII_ST10040_ID )
        !           479:             {
        !           480:                 phyMIIDelay = MII_ST10040_DELAY;
        !           481:             }
        !           482:             else if ( (phyType & MII_DP83843_MASK) == MII_DP83843_ID )
        !           483:             {
        !           484:                 phyMIIDelay = MII_DP83843_DELAY;
        !           485:             }
        !           486:         }
        !           487:     }
        !           488: 
        !           489:     /*
        !           490:      * Reset the reset the ethernet cell
        !           491:      */
        !           492:     fcrValue |= kResetEnetCell;
        !           493:     *heathrowFCR = OSReadSwapInt32( &fcrValue, 0 );
        !           494:     eieio();
        !           495:     IOSleep( 10 );
        !           496: 
        !           497:     fcrValue &= ~kResetEnetCell;
        !           498:     *heathrowFCR = OSReadSwapInt32( &fcrValue, 0 );
        !           499:     eieio();
        !           500:     IOSleep( 10 );
        !           501: 
        !           502:        chipId = ReadBigMacRegister(ioBaseEnet, kCHIPID) & 0xFF;
        !           503: }
        !           504: 
        !           505: /*-------------------------------------------------------------------------
        !           506:  *
        !           507:  *
        !           508:  *
        !           509:  *-------------------------------------------------------------------------*/
        !           510: 
        !           511: bool BMacEnet::_initChip()
        !           512: {
        !           513:     volatile u_int16_t         regValue;
        !           514:     ns_time_t                  timeStamp;         
        !           515:     u_int16_t                  *pWord16;
        !           516: 
        !           517:     WriteBigMacRegister(ioBaseEnet, kTXRST, kTxResetBit);
        !           518: 
        !           519:     do 
        !           520:     {
        !           521:                // wait for reset to clear..acknowledge
        !           522:                regValue = ReadBigMacRegister(ioBaseEnet, kTXRST);              
        !           523:     } 
        !           524:     while( regValue & kTxResetBit );
        !           525: 
        !           526:     WriteBigMacRegister(ioBaseEnet, kRXRST, kRxResetValue);
        !           527: 
        !           528:     if ( phyId == 0xff )
        !           529:     {
        !           530:                WriteBigMacRegister(ioBaseEnet, kXCVRIF,
        !           531:                        kClkBit | kSerialMode | kCOLActiveLow);
        !           532:     }  
        !           533: 
        !           534:     _IOGetTimestamp(&timeStamp);       
        !           535:     WriteBigMacRegister(ioBaseEnet, kRSEED, (u_int16_t) timeStamp );           
        !           536: 
        !           537:     regValue = ReadBigMacRegister(ioBaseEnet, kXIFC);
        !           538:     regValue |= kTxOutputEnable;
        !           539:     WriteBigMacRegister(ioBaseEnet, kXIFC, regValue);
        !           540: 
        !           541:     ReadBigMacRegister(ioBaseEnet, kPAREG);
        !           542: 
        !           543:     // set collision counters to 0
        !           544:     WriteBigMacRegister(ioBaseEnet, kNCCNT, 0);
        !           545:     WriteBigMacRegister(ioBaseEnet, kNTCNT, 0);
        !           546:     WriteBigMacRegister(ioBaseEnet, kEXCNT, 0);
        !           547:     WriteBigMacRegister(ioBaseEnet, kLTCNT, 0);
        !           548: 
        !           549:     // set rx counters to 0
        !           550:     WriteBigMacRegister(ioBaseEnet, kFRCNT, 0);
        !           551:     WriteBigMacRegister(ioBaseEnet, kLECNT, 0);
        !           552:     WriteBigMacRegister(ioBaseEnet, kAECNT, 0);
        !           553:     WriteBigMacRegister(ioBaseEnet, kFECNT, 0);
        !           554:     WriteBigMacRegister(ioBaseEnet, kRXCV, 0);
        !           555: 
        !           556:     // set tx fifo information
        !           557:        // 255 octets before tx starts
        !           558:     WriteBigMacRegister(ioBaseEnet, kTXTH, 0xff);
        !           559: 
        !           560:        // first disable txFIFO
        !           561:     WriteBigMacRegister(ioBaseEnet, kTXFIFOCSR, 0);
        !           562:     WriteBigMacRegister(ioBaseEnet, kTXFIFOCSR, kTxFIFOEnable );
        !           563: 
        !           564:     // set rx fifo information
        !           565:        // first disable rxFIFO
        !           566:     WriteBigMacRegister(ioBaseEnet, kRXFIFOCSR, 0);                            
        !           567:     WriteBigMacRegister(ioBaseEnet, kRXFIFOCSR, kRxFIFOEnable ); 
        !           568: 
        !           569:        // kTxNeverGiveUp maybe later
        !           570:     //WriteBigMacRegister(ioBaseEnet, kTXCFG, kTxMACEnable);
        !           571:     ReadBigMacRegister(ioBaseEnet, kSTAT);             // read it just to clear it
        !           572: 
        !           573:     // zero out the chip Hash Filter registers
        !           574:     WriteBigMacRegister(ioBaseEnet, kHASH3, hashTableMask[0]);         // bits 15 - 0
        !           575:     WriteBigMacRegister(ioBaseEnet, kHASH2, hashTableMask[1]);         // bits 31 - 16
        !           576:     WriteBigMacRegister(ioBaseEnet, kHASH1, hashTableMask[2]);         // bits 47 - 32
        !           577:     WriteBigMacRegister(ioBaseEnet, kHASH0, hashTableMask[3]);         // bits 63 - 48
        !           578:        
        !           579:     pWord16 = (u_int16_t *)&myAddress.ea_byte[0];
        !           580:     WriteBigMacRegister(ioBaseEnet, kMADD0, *pWord16++);
        !           581:     WriteBigMacRegister(ioBaseEnet, kMADD1, *pWord16++);
        !           582:     WriteBigMacRegister(ioBaseEnet, kMADD2, *pWord16);
        !           583:     
        !           584:     WriteBigMacRegister(ioBaseEnet, kRXCFG,
        !           585:                kRxCRCEnable | kRxHashFilterEnable | kRxRejectOwnPackets);
        !           586:     
        !           587:     return true;
        !           588: }
        !           589: 
        !           590: /*-------------------------------------------------------------------------
        !           591:  *
        !           592:  *
        !           593:  *
        !           594:  *-------------------------------------------------------------------------*/
        !           595: 
        !           596: void BMacEnet::_disableAdapterInterrupts()
        !           597: {
        !           598:        WriteBigMacRegister( ioBaseEnet, kINTDISABLE, kNoEventsMask );
        !           599: }
        !           600: 
        !           601: /*-------------------------------------------------------------------------
        !           602:  *
        !           603:  *
        !           604:  *
        !           605:  *-------------------------------------------------------------------------*/
        !           606: 
        !           607: void BMacEnet::_enableAdapterInterrupts()
        !           608: {
        !           609:     WriteBigMacRegister( ioBaseEnet, 
        !           610:                          kINTDISABLE, 
        !           611:                          ( chipId >= kCHIPID_PaddingtonXmitStreaming ) ?
        !           612:                                                        kNoEventsMask: kNormalIntEvents );
        !           613: }
        !           614: 
        !           615: /*-------------------------------------------------------------------------
        !           616:  *
        !           617:  *
        !           618:  *
        !           619:  *-------------------------------------------------------------------------*/
        !           620: 
        !           621: void BMacEnet::_setDuplexMode(bool duplexMode)
        !           622: {
        !           623:     u_int16_t          txCFGVal;
        !           624: 
        !           625:     isFullDuplex = duplexMode;
        !           626: 
        !           627:     txCFGVal = ReadBigMacRegister( ioBaseEnet, kTXCFG);
        !           628: 
        !           629:     WriteBigMacRegister( ioBaseEnet, kTXCFG, txCFGVal & ~kTxMACEnable );
        !           630:     while( ReadBigMacRegister(ioBaseEnet, kTXCFG) & kTxMACEnable )
        !           631:       ;
        !           632:  
        !           633:     if ( isFullDuplex )
        !           634:     {
        !           635:         txCFGVal |= (kTxIgnoreCollision | kTxFullDuplex);
        !           636:     }
        !           637:     else
        !           638:     {
        !           639:         txCFGVal &= ~(kTxIgnoreCollision | kTxFullDuplex);
        !           640:     }
        !           641:     
        !           642:     WriteBigMacRegister( ioBaseEnet, kTXCFG, txCFGVal );
        !           643: }    
        !           644: 
        !           645: /*-------------------------------------------------------------------------
        !           646:  *
        !           647:  *
        !           648:  *
        !           649:  *-------------------------------------------------------------------------*/
        !           650: 
        !           651: void BMacEnet::_restartTransmitter()
        !           652: {
        !           653:     u_int16_t  regValue;
        !           654: 
        !           655:     /*
        !           656:      * Shutdown DMA channel
        !           657:      */
        !           658:        _stopTransmitDMA();
        !           659: 
        !           660:     /*
        !           661:      * Get the silicon's attention
        !           662:      */
        !           663:     WriteBigMacRegister( ioBaseEnet, kTXFIFOCSR, 0 );
        !           664:     WriteBigMacRegister( ioBaseEnet, kTXFIFOCSR, kTxFIFOEnable);
        !           665: 
        !           666:        ReadBigMacRegister( ioBaseEnet, kSTAT );
        !           667: 
        !           668:     regValue = ReadBigMacRegister(ioBaseEnet, kTXCFG);         
        !           669:     WriteBigMacRegister(ioBaseEnet, kTXCFG, regValue | kTxMACEnable );  
        !           670: 
        !           671:     /*
        !           672:      * Restart transmit DMA
        !           673:      */
        !           674:     IODBDMAContinue( ioBaseEnetTxDMA );  
        !           675: }
        !           676: 
        !           677: /*-------------------------------------------------------------------------
        !           678:  *
        !           679:  *
        !           680:  *
        !           681:  *-------------------------------------------------------------------------*/
        !           682: 
        !           683: void BMacEnet::_restartReceiver()
        !           684: {
        !           685:     u_int16_t  oldConfig;
        !           686: 
        !           687:     /*
        !           688:      * Shutdown DMA channel
        !           689:      */
        !           690:        _stopReceiveDMA();
        !           691: 
        !           692:     /*
        !           693:      * Get the silicon's attention
        !           694:      */
        !           695:     WriteBigMacRegister( ioBaseEnet, kRXFIFOCSR, 0 );
        !           696:     WriteBigMacRegister( ioBaseEnet, kRXFIFOCSR, kRxFIFOEnable);
        !           697: 
        !           698:     oldConfig = ReadBigMacRegister(ioBaseEnet, kRXCFG);                
        !           699:     WriteBigMacRegister(ioBaseEnet, kRXCFG, oldConfig | kRxMACEnable ); 
        !           700:  
        !           701:     /*
        !           702:      * Restart receive DMA
        !           703:      */
        !           704:     IODBDMAContinue( ioBaseEnetRxDMA );  
        !           705: }
        !           706: 
        !           707: /*-------------------------------------------------------------------------
        !           708:  *
        !           709:  * Orderly stop of receive DMA.
        !           710:  *
        !           711:  *
        !           712:  *-------------------------------------------------------------------------*/
        !           713: 
        !           714: void BMacEnet::_stopReceiveDMA()
        !           715: {
        !           716:     u_int32_t          dmaCmdPtr;
        !           717:     u_int8_t           rxCFGVal;
        !           718: 
        !           719:     /* 
        !           720:      * Stop the receiver and allow any frame receive in progress to complete.
        !           721:      */
        !           722:     rxCFGVal = ReadBigMacRegister(ioBaseEnet, kRXCFG);
        !           723:     WriteBigMacRegister(ioBaseEnet, kRXCFG, rxCFGVal & ~kRxMACEnable );
        !           724:     IODelay( RECEIVE_QUIESCE_uS );
        !           725: 
        !           726:     IODBDMAReset( ioBaseEnetRxDMA );
        !           727: 
        !           728:     dmaCmdPtr = rxDMACommandsPhys + rxCommandHead * sizeof(enet_dma_cmd_t);
        !           729:     IOSetDBDMACommandPtr( ioBaseEnetRxDMA, dmaCmdPtr );
        !           730: }    
        !           731: 
        !           732: /*-------------------------------------------------------------------------
        !           733:  *
        !           734:  *
        !           735:  *
        !           736:  *-------------------------------------------------------------------------*/
        !           737: 
        !           738: void BMacEnet::_stopTransmitDMA()
        !           739: {
        !           740:     u_int32_t          dmaCmdPtr;
        !           741:     u_int8_t           txCFGVal;
        !           742: 
        !           743:     /* 
        !           744:      * Stop the transmitter and allow any frame transmit in progress to abort
        !           745:      */
        !           746:     txCFGVal = ReadBigMacRegister(ioBaseEnet, kTXCFG);
        !           747:     WriteBigMacRegister(ioBaseEnet, kTXCFG, txCFGVal & ~kTxMACEnable );
        !           748: 
        !           749:     IODelay( TRANSMIT_QUIESCE_uS );
        !           750: 
        !           751:     IODBDMAReset( ioBaseEnetTxDMA );
        !           752:     
        !           753:     dmaCmdPtr = txDMACommandsPhys + txCommandHead * sizeof(enet_txdma_cmd_t); 
        !           754:     IOSetDBDMACommandPtr( ioBaseEnetTxDMA, dmaCmdPtr );
        !           755: }
        !           756: 
        !           757: /*-------------------------------------------------------------------------
        !           758:  *
        !           759:  *
        !           760:  *
        !           761:  *-------------------------------------------------------------------------*/
        !           762: 
        !           763: bool BMacEnet::_transmitPacket(struct mbuf *packet)
        !           764: {
        !           765:     enet_dma_cmd_t     tmpCommand;
        !           766:     u_int32_t          i;
        !           767:        
        !           768:     /*
        !           769:      * Check for room on the transmit ring. There should always be space 
        !           770:         * since it is the responsibility of the caller to verify this before 
        !           771:         * calling _transmitPacket.
        !           772:      *
        !           773:      * Get a copy of the DMA transfer commands in a temporary buffer. 
        !           774:      * The new DMA command is written into the channel program so that the 
        !           775:         * command word for the old Stop command is overwritten last. This prevents 
        !           776:         * the DMA engine from executing a partially written channel command.
        !           777:      */
        !           778:     i = txCommandTail + 1;
        !           779:     if ( i >= txMaxCommand ) i = 0;
        !           780:     
        !           781:        if ( (i == txCommandHead) ||
        !           782:                !_updateDescriptorFromMbuf(packet, &tmpCommand, false) )
        !           783:     {
        !           784:                IOLog("Ethernet(BMac): Freeing transmit packet eh?\n\r");
        !           785:                if (packet != txDebuggerPkt)
        !           786:                        freePacket(packet);
        !           787:                return false;
        !           788:     }
        !           789: 
        !           790:     /*
        !           791:      * txCommandTail points to the current DMA Stop command for the channel.
        !           792:         * We are now creating a new DMA Stop command in the next slot in the 
        !           793:         * transmit ring. The previous DMA Stop command will be overwritten with 
        !           794:         * the DMA commands to transfer the new mbuf.
        !           795:      */
        !           796:     txDMACommands[i].desc_seg[0] = dbdmaCmd_Stop;
        !           797:     txDMACommands[i].desc_seg[1] = dbdmaCmd_Nop;
        !           798: 
        !           799:     bcopy( ((u_int32_t *)&tmpCommand)+1,
        !           800:            ((u_int32_t *)&txDMACommands[txCommandTail])+1,
        !           801:            sizeof(enet_dma_cmd_t)-sizeof(u_int32_t) );
        !           802: 
        !           803:        txMbuf[txCommandTail] = packet;
        !           804:     txDMACommands[txCommandTail].desc_seg[0].operation = 
        !           805:                tmpCommand.desc_seg[0].operation;
        !           806: 
        !           807:     /*
        !           808:      * Set the transmit tail to the new stop command.
        !           809:      */
        !           810:        txCommandTail = i;
        !           811: 
        !           812:     /*
        !           813:      * Tap the DMA channel to wake it up
        !           814:      */
        !           815:     IODBDMAContinue( ioBaseEnetTxDMA );
        !           816: 
        !           817:     return true;
        !           818: }      
        !           819: 
        !           820: /*-------------------------------------------------------------------------
        !           821:  * _receivePacket
        !           822:  * --------------
        !           823:  * This routine runs the receiver in polled-mode (yuk!) for the kernel debugger.
        !           824:  *
        !           825:  * The _receivePackets allocate NetBufs and pass them up the stack. The kernel
        !           826:  * debugger interface passes a buffer into us. To reconsile the two interfaces,
        !           827:  * we allow the receive routine to continue to allocate its own buffers and
        !           828:  * transfer any received data to the passed-in buffer. This is handled by 
        !           829:  * _receivePacket calling _packetToDebugger.
        !           830:  *-------------------------------------------------------------------------*/
        !           831: 
        !           832: void BMacEnet::_receivePacket(void *pkt, unsigned int *pkt_len,
        !           833:                unsigned int timeout)
        !           834: {
        !           835:     ns_time_t          startTime;
        !           836:     ns_time_t          currentTime;
        !           837:     u_int32_t          elapsedTimeMS;
        !           838: 
        !           839:     if (!ready || !pkt || !pkt_len)
        !           840:       return;
        !           841: 
        !           842:     *pkt_len = 0;
        !           843: 
        !           844:     debuggerPkt     = pkt;
        !           845:     debuggerPktSize = 0;
        !           846: 
        !           847:     _IOGetTimestamp(&startTime);
        !           848:     do
        !           849:     {
        !           850:                _receivePackets(true);
        !           851:                _IOGetTimestamp(&currentTime);
        !           852:                elapsedTimeMS = (currentTime - startTime) / (1000*1000);
        !           853:     } 
        !           854:     while ( (debuggerPktSize == 0) && (elapsedTimeMS < timeout) );
        !           855: 
        !           856:     *pkt_len = debuggerPktSize;
        !           857: }
        !           858: 
        !           859: /*-------------------------------------------------------------------------
        !           860:  * _packetToDebugger
        !           861:  * -----------------
        !           862:  * This is called by _receivePackets when we are polling for kernel debugger
        !           863:  * packets. It copies the NetBuf contents to the buffer passed by the debugger.
        !           864:  * It also sets the var debuggerPktSize which will break the polling loop.
        !           865:  *-------------------------------------------------------------------------*/
        !           866: 
        !           867: void BMacEnet::_packetToDebugger(struct mbuf * packet, u_int size)
        !           868: {
        !           869:     debuggerPktSize = size;
        !           870:     bcopy( mtod(packet, char *), debuggerPkt, size );
        !           871: }
        !           872: 
        !           873: /*-------------------------------------------------------------------------
        !           874:  * _sendPacket
        !           875:  * -----------
        !           876:  *
        !           877:  * This routine runs the transmitter in polled-mode (yuk!) for the kernel debugger.
        !           878:  *
        !           879:  *-------------------------------------------------------------------------*/
        !           880: 
        !           881: void BMacEnet::_sendPacket(void *pkt, unsigned int pkt_len)
        !           882: {
        !           883:     ns_time_t  startTime;
        !           884:     ns_time_t  currentTime;
        !           885:     u_int32_t  elapsedTimeMS;
        !           886: 
        !           887:     if (!ready || !pkt || (pkt_len > ETHERMAXPACKET))
        !           888:       return;
        !           889: 
        !           890:     /*
        !           891:      * Wait for the transmit ring to empty
        !           892:      */
        !           893:     _IOGetTimestamp(&startTime); 
        !           894:        do
        !           895:     {  
        !           896:                _debugTransmitInterruptOccurred();
        !           897:                _IOGetTimestamp(&currentTime);
        !           898:                elapsedTimeMS = (currentTime - startTime) / (1000*1000);
        !           899:     }
        !           900:     while ( (txCommandHead != txCommandTail) &&
        !           901:                        (elapsedTimeMS < TX_KDB_TIMEOUT) ); 
        !           902:        
        !           903:        if ( txCommandHead != txCommandTail )
        !           904:        {
        !           905:                IOLog( "Ethernet(BMac): Polled tranmit timeout - 1\n\r");
        !           906:                return;
        !           907:     }
        !           908: 
        !           909:     /*
        !           910:      * Allocate a NetBuf and copy the debugger transmit data into it.
        !           911:         *
        !           912:         * jliu - no allocation, just recycle the same buffer dedicated to
        !           913:         * KDB transmit.
        !           914:      */
        !           915:        txDebuggerPkt->m_next = 0;
        !           916:        txDebuggerPkt->m_data = (caddr_t) pkt;
        !           917:        txDebuggerPkt->m_pkthdr.len = txDebuggerPkt->m_len = pkt_len;
        !           918: 
        !           919:     /*
        !           920:      * Send the debugger packet. txDebuggerPkt must not be freed by
        !           921:         * the transmit routine.
        !           922:      */
        !           923:        _transmitPacket(txDebuggerPkt);
        !           924: 
        !           925:     /*
        !           926:      * Poll waiting for the transmit ring to empty again
        !           927:      */
        !           928:     do 
        !           929:     {
        !           930:                _debugTransmitInterruptOccurred();
        !           931:                _IOGetTimestamp(&currentTime);
        !           932:                elapsedTimeMS = (currentTime - startTime) / (1000*1000);
        !           933:     }
        !           934:     while ( (txCommandHead != txCommandTail) &&
        !           935:                        (elapsedTimeMS < TX_KDB_TIMEOUT) ); 
        !           936: 
        !           937:     if ( txCommandHead != txCommandTail )
        !           938:     {
        !           939:                IOLog( "Ethernet(BMac): Polled tranmit timeout - 2\n\r");
        !           940:     }
        !           941: 
        !           942:     return;
        !           943: }
        !           944: 
        !           945: /*-------------------------------------------------------------------------
        !           946:  * _sendDummyPacket
        !           947:  * ----------------
        !           948:  * The BMac receiver seems to be locked until we send our first packet.
        !           949:  *
        !           950:  *-------------------------------------------------------------------------*/
        !           951: void BMacEnet::_sendDummyPacket()
        !           952: {
        !           953:     union
        !           954:     {
        !           955:                u_int8_t                bytes[64];
        !           956:                enet_addr_t             enet_addr[2];
        !           957:     } dummyPacket;
        !           958:        
        !           959:        bzero( &dummyPacket, sizeof(dummyPacket) );
        !           960:     dummyPacket.enet_addr[0] = myAddress;   
        !           961:     dummyPacket.enet_addr[1] = myAddress;
        !           962:        _sendPacket((void *)dummyPacket.bytes, sizeof(dummyPacket));
        !           963:        IOSleep(50);
        !           964: }
        !           965: 
        !           966: /*-------------------------------------------------------------------------
        !           967:  *
        !           968:  *
        !           969:  *
        !           970:  *-------------------------------------------------------------------------*/
        !           971: 
        !           972: bool BMacEnet::_receiveInterruptOccurred()
        !           973: {
        !           974:        return _receivePackets(false);
        !           975: }
        !           976: 
        !           977: /*-------------------------------------------------------------------------
        !           978:  * Work around a hardware bug where the controller will receive
        !           979:  * unicast packets not directed to the station. The hardware is
        !           980:  * erroneously using the hash table to qualify the unicast address.
        !           981:  * This routine will check that the packet is unicast, and if so,
        !           982:  * makes sure that the unicast address matches the station's address.
        !           983:  * Thus function returns true if the packet should be rejected.
        !           984:  *-------------------------------------------------------------------------*/
        !           985: 
        !           986: bool BMacEnet::_rejectBadUnicastPacket(ether_header_t * etherHeader)
        !           987: {
        !           988:        bool rejectPacket = false;
        !           989: 
        !           990:        if ( useUnicastFilter &&
        !           991:                (etherHeader->ether_dhost[EA_GROUP_BYTE] & EA_GROUP_BIT) == 0) {
        !           992:                //
        !           993:                // Destination Ethernet address is not multicast nor broadcast.
        !           994:                // Then it must be addresses to the station MAC address,
        !           995:                // otherwise reject the packet.
        !           996:                //
        !           997:                if (bcmp(etherHeader->ether_dhost, &myAddress, NUM_EN_ADDR_BYTES) != 0)
        !           998:                        rejectPacket = true;
        !           999:        }
        !          1000: 
        !          1001:        return rejectPacket;
        !          1002: }
        !          1003: 
        !          1004: /*-------------------------------------------------------------------------
        !          1005:  *
        !          1006:  *
        !          1007:  *
        !          1008:  *-------------------------------------------------------------------------*/
        !          1009: 
        !          1010: bool BMacEnet::_receivePackets(bool fDebugger)
        !          1011: {
        !          1012:     enet_dma_cmd_t      tmpCommand;
        !          1013:     struct mbuf *              packet;
        !          1014:     u_int32_t           i, j, last;
        !          1015:     int                                        receivedFrameSize = 0;
        !          1016:     u_int32_t           dmaCount[2], dmaResid[2], dmaStatus[2];
        !          1017:     u_int32_t                  dmaChnlStatus;
        !          1018:     u_int16_t           rxPktStatus = 0;
        !          1019:     u_int32_t           badFrameCount;
        !          1020:     bool                               reusePkt;
        !          1021:     bool                               status;
        !          1022:        bool                            useNetif = !fDebugger && netifClient;
        !          1023:        bool                doFlushQueue = false;
        !          1024:     u_int32_t                  nextDesc;
        !          1025:        static const u_int32_t          lastResetValue = (u_int32_t)(-1);
        !          1026:        
        !          1027:     last         = lastResetValue;
        !          1028:     i            = rxCommandHead;
        !          1029: 
        !          1030:        while ( 1 )
        !          1031:        {
        !          1032:                reusePkt     = false;
        !          1033: 
        !          1034:                /*
        !          1035:                 * Collect the DMA residual counts/status for the two
        !          1036:                 * buffer segments.
        !          1037:                 */ 
        !          1038:                for ( j = 0; j < 2; j++ )
        !          1039:                {
        !          1040:                        dmaResid[j]  = IOGetCCResult( &rxDMACommands[i].desc_seg[j] );
        !          1041:                        dmaStatus[j] = dmaResid[j] >> 16;
        !          1042:                        dmaResid[j] &= 0x0000ffff;
        !          1043:                        dmaCount[j]  = IOGetCCOperation( &rxDMACommands[i].desc_seg[j] ) 
        !          1044:                                & kdbdmaReqCountMask;
        !          1045:                }
        !          1046: 
        !          1047: #if 0
        !          1048:       IOLog("Ethernet(BMac): Rx NetBuf[%2d] = %08x Resid[0] = %04x Status[0] = %04x Resid[1] = %04x Status[1] = %04x\n\r",
        !          1049:                 i, (int)nb_map(rxNetbuf[i]), dmaResid[0], dmaStatus[0], dmaResid[1], dmaStatus[1] );      
        !          1050: #endif 
        !          1051: 
        !          1052:                /* 
        !          1053:                 * If the current entry has not been written, then stop at this entry
        !          1054:                 */
        !          1055:                if (  !((dmaStatus[0] & kdbdmaBt) || (dmaStatus[1] & kdbdmaActive)) )
        !          1056:                {
        !          1057:                        break;
        !          1058:                }
        !          1059: 
        !          1060:                /*
        !          1061:                 * The BMac Ethernet controller appends two bytes to each receive
        !          1062:                 * buffer containing the buffer 
        !          1063:                 * size and receive frame status.
        !          1064:                 * We locate these bytes by using the DMA residual counts.
        !          1065:                 */ 
        !          1066:                receivedFrameSize = dmaCount[0] - dmaResid[0] + dmaCount[1] - 
        !          1067:                        ((dmaStatus[0] & kdbdmaBt) ? dmaCount[1] : dmaResid[1]);
        !          1068: 
        !          1069:                if ( ( receivedFrameSize >= 2 ) &&
        !          1070:                         ( receivedFrameSize <= NETWORK_BUFSIZE ) )
        !          1071:                {
        !          1072:                        /*
        !          1073:                         * Get the receive frame size as reported by the BMac controller
        !          1074:                         */
        !          1075:                        rxPktStatus =  *(u_int16_t *)(mtod(rxMbuf[i], u_int32_t) +
        !          1076:                                receivedFrameSize - 2);
        !          1077:                        receivedFrameSize = rxPktStatus & kRxLengthMask;
        !          1078:                }
        !          1079: 
        !          1080:                /*
        !          1081:                 * Reject packets that are runts or that have other mutations.
        !          1082:                 */
        !          1083:                if ( receivedFrameSize < (ETHERMINPACKET - ETHERCRC) || 
        !          1084:                         receivedFrameSize > (ETHERMAXPACKET + ETHERCRC) ||
        !          1085:                         rxPktStatus & kRxAbortBit ||
        !          1086:                         _rejectBadUnicastPacket(mtod(rxMbuf[i], ether_header_t *))
        !          1087:                         )
        !          1088:                {
        !          1089:                        if (useNetif) netStats->inputErrors++;
        !          1090:                        reusePkt = true;
        !          1091:                }
        !          1092:                else if ( useNetif == false )
        !          1093:                {
        !          1094:                        /*
        !          1095:                         * Always reuse packets in debugger mode. We also refuse to
        !          1096:                         * pass anything up the stack unless the driver is open. The
        !          1097:                         * hardware is enabled before the stack has opened us, to
        !          1098:                         * allow earlier debug interface registration. But we must
        !          1099:                         * not pass any packets up.
        !          1100:                         */
        !          1101:                        reusePkt = true;
        !          1102:                        if (fDebugger)
        !          1103:                                _packetToDebugger(rxMbuf[i], receivedFrameSize);
        !          1104:                }
        !          1105: 
        !          1106:                /*
        !          1107:                 * Before we pass this packet up the networking stack. Make sure we
        !          1108:                 * can get a replacement. Otherwise, hold on to the current packet and
        !          1109:                 * increment the input error count.
        !          1110:                 * Thanks Justin!
        !          1111:                 */
        !          1112: 
        !          1113:                packet = 0;
        !          1114: 
        !          1115:                if ( reusePkt == false )
        !          1116:                {
        !          1117:                        bool replaced;
        !          1118:                
        !          1119:                        packet = replaceOrCopyPacket(&rxMbuf[i], receivedFrameSize, 
        !          1120:                                &replaced);
        !          1121: 
        !          1122:                        reusePkt = true;
        !          1123: 
        !          1124:                        if (packet && replaced)
        !          1125:                        {
        !          1126:                                status = _updateDescriptorFromMbuf(rxMbuf[i], 
        !          1127:                                        &rxDMACommands[i], true);
        !          1128: 
        !          1129:                                if (status)
        !          1130:                                {
        !          1131:                                        reusePkt = false;
        !          1132:                                }
        !          1133:                                else
        !          1134:                                {
        !          1135:                                        // Assume descriptor has not been corrupted.
        !          1136:                                        freePacket(rxMbuf[i]);  // release new packet.
        !          1137:                                        rxMbuf[i] = packet;             // get the old packet back.
        !          1138:                                        packet = 0;                             // pass up nothing.
        !          1139:                                        IOLog("Ethernet(BMac): _updateDescriptorFromMbuf error\n");
        !          1140:                                }
        !          1141:                        }
        !          1142:                        
        !          1143:                        if (packet == 0)
        !          1144:                                netStats->inputErrors++;
        !          1145:                }
        !          1146: 
        !          1147:                /*
        !          1148:                 * If we are reusing the existing mbuf, then refurbish the existing 
        !          1149:                 * DMA command \ descriptors by clearing the status/residual count 
        !          1150:                 * fields.
        !          1151:                 */
        !          1152:                if ( reusePkt )
        !          1153:                {
        !          1154:                        for ( j=0; j < sizeof(enet_dma_cmd_t)/sizeof(IODBDMADescriptor); 
        !          1155:                                j++ )
        !          1156:                        {
        !          1157:                                IOSetCCResult( &rxDMACommands[i].desc_seg[j], 0 );
        !          1158:                        }
        !          1159:                }
        !          1160: 
        !          1161:                /*
        !          1162:                 * Keep track of the last receive descriptor processed
        !          1163:                 */            
        !          1164:                last = i;
        !          1165: 
        !          1166:                /*
        !          1167:                 * Implement ring wrap-around
        !          1168:                 */
        !          1169:                if (++i >= rxMaxCommand) i = 0;
        !          1170: 
        !          1171:                if (fDebugger)
        !          1172:                {
        !          1173:                        break;
        !          1174:                }
        !          1175: 
        !          1176:                /*
        !          1177:                 * Transfer received packet to network
        !          1178:                 */
        !          1179:                if (packet)
        !          1180:                {
        !          1181:                        KERNEL_DEBUG(DBG_BMAC_RXCOMPLETE | DBG_FUNC_NONE, (int) packet, 
        !          1182:                                (int)receivedFrameSize, 0, 0, 0 );
        !          1183: 
        !          1184:                        networkInterface->inputPacket(packet, receivedFrameSize, true);
        !          1185:                        doFlushQueue = true;
        !          1186:                        netStats->inputPackets++;
        !          1187:                }
        !          1188:        }
        !          1189: 
        !          1190:     /*
        !          1191:      * OK...this is a little messy
        !          1192:      *
        !          1193:      * We just processed a bunch of DMA receive descriptors. We are going to 
        !          1194:         * exchange the current DMA stop command (rxCommandTail) with the last 
        !          1195:         * receive descriptor we processed (last). This will make these list of 
        !          1196:         * descriptors we just processed available. If we processed no receive 
        !          1197:         * descriptors on this call then skip this exchange.
        !          1198:      */
        !          1199: 
        !          1200: #if 0
        !          1201:        IOLog( "Ethernet(BMac): Prev - Rx Head = %2d Rx Tail = %2d Rx Last = %2d\n\r", rxCommandHead, rxCommandTail, last );
        !          1202: #endif
        !          1203: 
        !          1204:        if ( last != lastResetValue )
        !          1205:        {
        !          1206:                /*
        !          1207:                 * Save the contents of the last receive descriptor processed.
        !          1208:                 */
        !          1209:                packet          = rxMbuf[last];
        !          1210:                tmpCommand      = rxDMACommands[last];
        !          1211: 
        !          1212:                /*
        !          1213:                 * Write a DMA stop command into this descriptor slot
        !          1214:                 */
        !          1215:                rxDMACommands[last].desc_seg[0] = dbdmaCmd_Stop;
        !          1216:                rxDMACommands[last].desc_seg[1] = dbdmaCmd_Nop;  
        !          1217:                rxMbuf[last] = 0;
        !          1218: 
        !          1219:                /*
        !          1220:                 * Replace the previous DMA stop command with the last receive 
        !          1221:                 * descriptor processed.
        !          1222:                 * 
        !          1223:                 * The new DMA command is written into the channel program so that the
        !          1224:                 * command word for the old Stop command is overwritten last. This 
        !          1225:                 * prevents the DMA engine from executing a partially written channel 
        !          1226:                 * command.
        !          1227:                 * 
        !          1228:                 * Note: When relocating the descriptor, we must update its branch 
        !          1229:                 * field to reflect its new location.
        !          1230:                 */
        !          1231:                nextDesc = rxDMACommandsPhys + 
        !          1232:                        (int) &rxDMACommands[rxCommandTail + 1] - (int)rxDMACommands;
        !          1233:                IOSetCCCmdDep( &tmpCommand.desc_seg[0], nextDesc );
        !          1234: 
        !          1235:                bcopy( (u_int32_t *) &tmpCommand + 1,
        !          1236:                (u_int32_t *) &rxDMACommands[rxCommandTail] + 1,
        !          1237:                sizeof(enet_dma_cmd_t) - sizeof(u_int32_t) );
        !          1238: 
        !          1239:                rxMbuf[rxCommandTail] = packet;
        !          1240: 
        !          1241:                rxDMACommands[rxCommandTail].desc_seg[0].operation = 
        !          1242:                        tmpCommand.desc_seg[0].operation;
        !          1243: 
        !          1244:                /*
        !          1245:                 * Update rxCommmandTail to point to the new Stop command. Update 
        !          1246:                 * rxCommandHead to point to the next slot in the ring past the Stop 
        !          1247:                 * command 
        !          1248:                 */
        !          1249:                rxCommandTail = last;
        !          1250:                rxCommandHead = i;
        !          1251:     }
        !          1252: 
        !          1253:     /*
        !          1254:      * Update receive error statistics
        !          1255:      */
        !          1256:     badFrameCount =  ReadBigMacRegister(ioBaseEnet, kFECNT) 
        !          1257:                        + ReadBigMacRegister(ioBaseEnet, kAECNT)
        !          1258:                            + ReadBigMacRegister(ioBaseEnet, kLECNT);
        !          1259: 
        !          1260:     /*
        !          1261:      * Clear Hardware counters
        !          1262:      */
        !          1263:     WriteBigMacRegister(ioBaseEnet, kFECNT, 0);
        !          1264:     WriteBigMacRegister(ioBaseEnet, kAECNT, 0);
        !          1265:     WriteBigMacRegister(ioBaseEnet, kLECNT, 0);
        !          1266: 
        !          1267:        if (badFrameCount && useNetif)
        !          1268:                netStats->inputErrors += badFrameCount;
        !          1269: 
        !          1270:     /*
        !          1271:      * Check for error conditions that may cause the receiver to stall
        !          1272:      */
        !          1273:     dmaChnlStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
        !          1274:  
        !          1275:     if ( dmaChnlStatus & kdbdmaDead )
        !          1276:        {
        !          1277:                if (useNetif) netStats->inputErrors++;
        !          1278:                IOLog( "Ethernet(BMac): Rx DMA Error - Status = %04x\n\r", 
        !          1279:                        dmaChnlStatus );
        !          1280:                _restartReceiver();
        !          1281:        }
        !          1282:        else
        !          1283:        {
        !          1284:                /*
        !          1285:                 * Tap the DMA to wake it up
        !          1286:                 */
        !          1287:                IODBDMAContinue( ioBaseEnetRxDMA );
        !          1288:     }
        !          1289: 
        !          1290: #if 0
        !          1291:     IOLog( "Ethernet(BMac): New  - Rx Head = %2d Rx Tail = %2d\n\r", rxCommandHead, rxCommandTail );
        !          1292: #endif
        !          1293: 
        !          1294:     return doFlushQueue;
        !          1295: }
        !          1296:  
        !          1297: /*-------------------------------------------------------------------------
        !          1298:  *
        !          1299:  *
        !          1300:  *
        !          1301:  *-------------------------------------------------------------------------*/
        !          1302: 
        !          1303: bool BMacEnet::_transmitInterruptOccurred()
        !          1304: {
        !          1305:     u_int32_t  dmaStatus;
        !          1306:     u_int32_t  collisionCount;
        !          1307:        u_int32_t       badFrameCount;
        !          1308:        bool            fServiced = false;
        !          1309: 
        !          1310:     while ( 1 )
        !          1311:     {
        !          1312:                /*
        !          1313:                 * Check the status of the last descriptor in this entry to see if
        !          1314:                 * the DMA engine completed this entry.
        !          1315:                 */
        !          1316:                dmaStatus = IOGetCCResult(
        !          1317:                        &(txDMACommands[txCommandHead].desc_seg[1])) >> 16;
        !          1318: 
        !          1319:                if ( !(dmaStatus & kdbdmaActive) )
        !          1320:                {
        !          1321:                        break;
        !          1322:                }
        !          1323: 
        !          1324:                if (netifClient) netStats->outputPackets++;
        !          1325: 
        !          1326:                fServiced = true;
        !          1327: 
        !          1328:        KERNEL_DEBUG(DBG_BMAC_TXCOMPLETE | DBG_FUNC_NONE,
        !          1329:                        (int)txMbuf[txCommandHead],
        !          1330:                        (int)txMbuf[txCommandHead]->m_pkthdr.len, 0, 0, 0 );
        !          1331: 
        !          1332:                /*
        !          1333:                 * Free the mbuf we just transmitted.
        !          1334:                 *
        !          1335:                 * If it is the debugger packet, just remove it from the ring.
        !          1336:                 * and reuse the same packet for the next sendPacket() request.
        !          1337:                 */
        !          1338:                if (txMbuf[txCommandHead] != txDebuggerPkt)
        !          1339:                {
        !          1340:                        freePacket( txMbuf[txCommandHead] );
        !          1341:                }
        !          1342:                txMbuf[txCommandHead] = NULL;
        !          1343: 
        !          1344:                if ( ++(txCommandHead) >= txMaxCommand )
        !          1345:                        txCommandHead = 0;
        !          1346:     }
        !          1347: 
        !          1348:     /* 
        !          1349:      * Increment transmit error statistics
        !          1350:      */
        !          1351:     collisionCount = ReadBigMacRegister(ioBaseEnet, kNCCNT ); 
        !          1352: 
        !          1353:     WriteBigMacRegister( ioBaseEnet, kNCCNT, 0 );
        !          1354: 
        !          1355:     badFrameCount = ReadBigMacRegister(ioBaseEnet, kEXCNT )
        !          1356:                       + ReadBigMacRegister(ioBaseEnet, kLTCNT );
        !          1357: 
        !          1358:     WriteBigMacRegister( ioBaseEnet, kEXCNT, 0 );
        !          1359:     WriteBigMacRegister( ioBaseEnet, kLTCNT, 0 );
        !          1360: 
        !          1361:        if (netifClient) {
        !          1362:                netStats->collisions += collisionCount;
        !          1363:                netStats->outputErrors += badFrameCount;
        !          1364:        }
        !          1365: 
        !          1366:     /*
        !          1367:      * Check for error conditions that may cause the transmitter to stall
        !          1368:      */
        !          1369:     dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetTxDMA );
        !          1370:  
        !          1371:     if ( dmaStatus & kdbdmaDead )
        !          1372:     {
        !          1373:                if (netifClient) netStats->outputErrors++;
        !          1374:                IOLog( "Ethernet(BMac): Tx DMA Error - Status = %04x\n\r", dmaStatus );
        !          1375:                _restartTransmitter();
        !          1376:                fServiced = true;
        !          1377:     }
        !          1378: 
        !          1379:     return fServiced;
        !          1380: }
        !          1381: 
        !          1382: /*-------------------------------------------------------------------------
        !          1383:  *
        !          1384:  *
        !          1385:  *
        !          1386:  *-------------------------------------------------------------------------*/
        !          1387: 
        !          1388: bool BMacEnet::_debugTransmitInterruptOccurred()
        !          1389: {
        !          1390:     u_int32_t  dmaStatus;
        !          1391:     u_int32_t  badFrameCount;
        !          1392:        bool        fServiced = false;
        !          1393: 
        !          1394:        // Set the debugTxPoll flag to indicate the debugger was active
        !          1395:        // and some cleanup may be needed when the driver returns to
        !          1396:        // normal operation.
        !          1397:        //
        !          1398:        debugTxPoll = true;
        !          1399: 
        !          1400:     while ( 1 )
        !          1401:     {
        !          1402:                /*
        !          1403:                 * Check the status of the last descriptor in this entry to see if
        !          1404:                 * the DMA engine completed this entry.
        !          1405:                 */
        !          1406:                dmaStatus = IOGetCCResult(
        !          1407:                        &(txDMACommands[txCommandHead].desc_seg[1])) >> 16;
        !          1408: 
        !          1409:                if ( !(dmaStatus & kdbdmaActive) )
        !          1410:                {
        !          1411:                        break;
        !          1412:                }
        !          1413: 
        !          1414:                fServiced = true;
        !          1415: 
        !          1416:        KERNEL_DEBUG(DBG_BMAC_TXCOMPLETE | DBG_FUNC_NONE,
        !          1417:                        (int)txMbuf[txCommandHead],
        !          1418:                        (int)txMbuf[txCommandHead]->m_pkthdr.len, 0, 0, 0 );
        !          1419: 
        !          1420:                /*
        !          1421:                 * Free the mbuf we just transmitted.
        !          1422:                 *
        !          1423:                 * If it is the debugger packet, just remove it from the ring.
        !          1424:                 * and reuse the same packet for the next sendPacket() request.
        !          1425:                 */
        !          1426:                if (txMbuf[txCommandHead] != txDebuggerPkt) {
        !          1427:                        //
        !          1428:                        // While in debugger mode, do not touch the mbuf pool.
        !          1429:                        // Queue any used mbufs to a local queue. This queue
        !          1430:                        // will get flushed after we exit from debugger mode.
        !          1431:                        //
        !          1432:                        // During continuous debugger transmission and
        !          1433:                        // interrupt polling, we expect only the txDebuggerPkt
        !          1434:                        // to show up on the transmit mbuf ring.
        !          1435:                        //
        !          1436:                        debugQueue->enqueue( txMbuf[txCommandHead] );
        !          1437:                }
        !          1438:                txMbuf[txCommandHead] = NULL;
        !          1439: 
        !          1440:                if ( ++(txCommandHead) >= txMaxCommand )
        !          1441:                        txCommandHead = 0;
        !          1442:     }
        !          1443: 
        !          1444:     /* 
        !          1445:      * Clear transmit error statistics
        !          1446:      */
        !          1447:     badFrameCount = ReadBigMacRegister(ioBaseEnet, kNCCNT ); 
        !          1448:     WriteBigMacRegister( ioBaseEnet, kNCCNT, 0 );
        !          1449:     
        !          1450:     badFrameCount = ReadBigMacRegister(ioBaseEnet, kEXCNT )
        !          1451:                       + ReadBigMacRegister(ioBaseEnet, kLTCNT );
        !          1452:     WriteBigMacRegister( ioBaseEnet, kEXCNT, 0 );
        !          1453:     WriteBigMacRegister( ioBaseEnet, kLTCNT, 0 );
        !          1454: 
        !          1455:     /*
        !          1456:      * Check for error conditions that may cause the transmitter to stall
        !          1457:      */
        !          1458:     dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetTxDMA );
        !          1459:  
        !          1460:     if ( dmaStatus & kdbdmaDead )
        !          1461:     {
        !          1462:                IOLog( "Ethernet(BMac): Tx DMA Error - Status = %04x\n\r", dmaStatus );
        !          1463:                _restartTransmitter();
        !          1464:                fServiced = true;
        !          1465:     }
        !          1466: 
        !          1467:     return fServiced;
        !          1468: }
        !          1469:        
        !          1470: /*-------------------------------------------------------------------------
        !          1471:  *
        !          1472:  *
        !          1473:  *
        !          1474:  *-------------------------------------------------------------------------*/
        !          1475: 
        !          1476: bool
        !          1477: BMacEnet::_updateDescriptorFromMbuf(struct mbuf * m,  enet_dma_cmd_t *desc,
        !          1478:                bool isReceive)
        !          1479: {
        !          1480:     u_int32_t          nextDesc = 0;
        !          1481:        u_int32_t               waitMask = 0;   
        !          1482:        int                     segments;
        !          1483:        struct IOPhysicalSegment segVector[2];
        !          1484: 
        !          1485:        segments = mbufCursor->getPhysicalSegmentsWithCoalesce(m, segVector);
        !          1486:        
        !          1487:        if ((!segments) || (segments > 2)) {
        !          1488:                IOLog("BMac: _updateDescriptorFromMbuf error, %d segments\n", 
        !          1489:                        segments);
        !          1490:                return false;
        !          1491:        }
        !          1492: 
        !          1493:        // IOLog("segments: %d\n", segments);
        !          1494: 
        !          1495:     if ( isReceive || chipId >= kCHIPID_PaddingtonXmitStreaming )
        !          1496:     {
        !          1497:         waitMask = kdbdmaWaitNever;
        !          1498:     }
        !          1499:     else
        !          1500:     {
        !          1501:         waitMask = kdbdmaWaitIfFalse;
        !          1502:     }
        !          1503:    
        !          1504:     if ( segments == 1 )
        !          1505:     {
        !          1506:                IOMakeDBDMADescriptor( (&desc->desc_seg[0]),
        !          1507:                                                        ((isReceive) ? kdbdmaInputLast : kdbdmaOutputLast), 
        !          1508:                                                        (kdbdmaKeyStream0),
        !          1509:                                                        (kdbdmaIntNever),
        !          1510:                                                        (kdbdmaBranchNever),
        !          1511:                                                        (waitMask),
        !          1512:                                                        (segVector[0].length),
        !          1513:                                                        (segVector[0].location)  );
        !          1514:   
        !          1515:                desc->desc_seg[1] = (isReceive) ? dbdmaCmd_NopWInt : dbdmaCmd_Nop;
        !          1516:     }
        !          1517:     else
        !          1518:        {
        !          1519:                if ( isReceive ) 
        !          1520:                {
        !          1521:                        nextDesc = rxDMACommandsPhys + (int)desc - (int)rxDMACommands + 
        !          1522:                                sizeof(enet_dma_cmd_t);
        !          1523:                }
        !          1524: 
        !          1525:                IOMakeDBDMADescriptorDep( (&desc->desc_seg[0]),
        !          1526:                                                        ((isReceive) ? kdbdmaInputMore : kdbdmaOutputMore), 
        !          1527:                                                        (kdbdmaKeyStream0),
        !          1528:                                                        ((isReceive) ? kdbdmaIntIfTrue : kdbdmaIntNever),
        !          1529:                                                        ((isReceive) ? kdbdmaBranchIfTrue : 
        !          1530:                                                                kdbdmaBranchNever),
        !          1531:                                                        (kdbdmaWaitNever),
        !          1532:                                                        (segVector[0].length),
        !          1533:                                                        (segVector[0].location),  
        !          1534:                                                        nextDesc   ); 
        !          1535: 
        !          1536:                IOMakeDBDMADescriptor( (&desc->desc_seg[1]),
        !          1537:                                                        ((isReceive) ? kdbdmaInputLast : kdbdmaOutputLast), 
        !          1538:                                                        (kdbdmaKeyStream0),
        !          1539:                                                        ((isReceive) ? kdbdmaIntAlways : kdbdmaIntNever),
        !          1540:                                                        (kdbdmaBranchNever),
        !          1541:                                                        (waitMask),
        !          1542:                                                        (segVector[1].length),
        !          1543:                                                        (segVector[1].location)  );
        !          1544:     }
        !          1545: 
        !          1546:     return true;
        !          1547: }
        !          1548: 
        !          1549: #ifdef DEBUG
        !          1550: /*
        !          1551:  * Useful for testing. 
        !          1552:  */
        !          1553: void BMacEnet::_dump_srom()
        !          1554: {
        !          1555:     unsigned short data;
        !          1556:     int i;
        !          1557:        
        !          1558:     for (i = 0; i < 128; i++)  
        !          1559:     {
        !          1560:                reset_and_select_srom(ioBaseEnet);
        !          1561:                data = read_srom(ioBaseEnet, i, sromAddressBits);
        !          1562:                IOLog("Ethernet(BMac): %x = %x ", i, data);
        !          1563:                if (i % 10 == 0) IOLog("\n");
        !          1564:     }
        !          1565: }
        !          1566: 
        !          1567: void BMacEnet::_dumpDesc(void * addr, u_int32_t size)
        !          1568: {
        !          1569:     u_int32_t          i;
        !          1570:     unsigned long      *p;
        !          1571:     vm_offset_t                paddr;
        !          1572: 
        !          1573:     _IOPhysicalFromVirtual( (vm_offset_t) addr, (vm_offset_t *)&paddr );
        !          1574: 
        !          1575:     p = (unsigned long *)addr;
        !          1576: 
        !          1577:     for ( i=0; i < size/sizeof(IODBDMADescriptor); i++, p+=4, 
        !          1578:                paddr+=sizeof(IODBDMADescriptor) )
        !          1579:     {
        !          1580:         IOLog("Ethernet(BMac): %08x(v) %08x(p):  %08x %08x %08x %08x\n\r",
        !          1581:               (int)p,
        !          1582:               (int)paddr,
        !          1583:               (int)OSReadSwapInt32(p, 0),   (int)OSReadSwapInt32(p, 4),
        !          1584:               (int)OSReadSwapInt32(p, 8),   (int)OSReadSwapInt32(p, 12) );
        !          1585:     }
        !          1586: }
        !          1587: 
        !          1588: void BMacEnet::_dumpRegisters()
        !          1589: {
        !          1590:     u_int16_t  dataValue;
        !          1591: 
        !          1592:     IOLog("\nEthernet(BMac): IO Address = %08x", (int)ioBaseEnet );
        !          1593: 
        !          1594:     dataValue = ReadBigMacRegister(ioBaseEnet, kXIFC);
        !          1595:     IOLog("\nEthernet(BMac): Read Register %04x Transceiver I/F = %04x", kXIFC, dataValue );
        !          1596: 
        !          1597:     dataValue = ReadBigMacRegister(ioBaseEnet, kSTAT);
        !          1598:     IOLog("\nEthernet(BMac): Read Register %04x Int Events      = %04x", kSTAT, dataValue );
        !          1599: 
        !          1600:     dataValue = ReadBigMacRegister(ioBaseEnet, kINTDISABLE);
        !          1601:     IOLog("\nEthernet(BMac): Read Register %04x Int Disable     = %04x", kINTDISABLE, dataValue );
        !          1602: 
        !          1603:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXRST);
        !          1604:     IOLog("\nEthernet(BMac): Read Register %04x Tx Reset        = %04x", kTXRST, dataValue );
        !          1605: 
        !          1606:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXCFG);
        !          1607:     IOLog("\nEthernet(BMac): Read Register %04x Tx Config       = %04x", kTXCFG, dataValue );
        !          1608:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1609: 
        !          1610:     dataValue = ReadBigMacRegister(ioBaseEnet, kIPG1);
        !          1611:     IOLog("\nEthernet(BMac): Read Register %04x IPG1            = %04x", kIPG1, dataValue );
        !          1612: 
        !          1613:     dataValue = ReadBigMacRegister(ioBaseEnet, kIPG2);
        !          1614:     IOLog("\nEthernet(BMac): Read Register %04x IPG2            = %04x", kIPG2, dataValue );
        !          1615: 
        !          1616:     dataValue = ReadBigMacRegister(ioBaseEnet, kALIMIT);
        !          1617:     IOLog("\nEthernet(BMac): Read Register %04x Attempt Limit   = %04x", kALIMIT, dataValue );
        !          1618: 
        !          1619:     dataValue = ReadBigMacRegister(ioBaseEnet, kSLOT);
        !          1620:     IOLog("\nEthernet(BMac): Read Register %04x Slot Time       = %04x", kSLOT, dataValue );
        !          1621: 
        !          1622:     dataValue = ReadBigMacRegister(ioBaseEnet, kPALEN);
        !          1623:     IOLog("\nEthernet(BMac): Read Register %04x Preamble Length = %04x", kPALEN, dataValue );
        !          1624: 
        !          1625:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1626:     dataValue = ReadBigMacRegister(ioBaseEnet, kPAPAT);
        !          1627:     IOLog("\nEthernet(BMac): Read Register %04x Preamble Pattern         = %04x", kPAPAT, dataValue );
        !          1628: 
        !          1629:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXSFD);
        !          1630:     IOLog("\nEthernet(BMac): Read Register %04x Tx Start Frame Delimeter = %04x", kTXSFD, dataValue );
        !          1631: 
        !          1632:     dataValue = ReadBigMacRegister(ioBaseEnet, kJAM);
        !          1633:     IOLog("\nEthernet(BMac): Read Register %04x Jam Size                 = %04x", kJAM, dataValue );
        !          1634: 
        !          1635:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXMAX);
        !          1636:     IOLog("\nEthernet(BMac): Read Register %04x Tx Max Size              = %04x", kTXMAX, dataValue );
        !          1637: 
        !          1638:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXMIN);
        !          1639:     IOLog("\nEthernet(BMac): Read Register %04x Tx Min Size              = %04x", kTXMIN, dataValue );
        !          1640:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1641: 
        !          1642:     dataValue = ReadBigMacRegister(ioBaseEnet, kPAREG);
        !          1643:     IOLog("\nEthernet(BMac): Read Register %04x Peak Attempts           = %04x", kPAREG, dataValue );
        !          1644: 
        !          1645:     dataValue = ReadBigMacRegister(ioBaseEnet, kDCNT);
        !          1646:     IOLog("\nEthernet(BMac): Read Register %04x Defer Timer             = %04x", kDCNT, dataValue );
        !          1647: 
        !          1648:     dataValue = ReadBigMacRegister(ioBaseEnet, kNCCNT);
        !          1649:     IOLog("\nEthernet(BMac): Read Register %04x Normal Collision Count  = %04x", kNCCNT, dataValue );
        !          1650: 
        !          1651:     dataValue = ReadBigMacRegister(ioBaseEnet, kNTCNT);
        !          1652:     IOLog("\nEthernet(BMac): Read Register %04x Network Collision Count = %04x", kNTCNT, dataValue );
        !          1653: 
        !          1654:     dataValue = ReadBigMacRegister(ioBaseEnet, kEXCNT);
        !          1655:     IOLog("\nEthernet(BMac): Read Register %04x Excessive Coll Count    = %04x", kEXCNT, dataValue );
        !          1656:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1657: 
        !          1658:     dataValue = ReadBigMacRegister(ioBaseEnet, kLTCNT);
        !          1659:     IOLog("\nEthernet(BMac): Read Register %04x Late Collision Count = %04x", kLTCNT, dataValue );
        !          1660: 
        !          1661:     dataValue = ReadBigMacRegister(ioBaseEnet, kRSEED);
        !          1662:     IOLog("\nEthernet(BMac): Read Register %04x Random Seed          = %04x", kRSEED, dataValue );
        !          1663: 
        !          1664:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXSM);
        !          1665:     IOLog("\nEthernet(BMac): Read Register %04x Tx State Machine     = %04x", kTXSM, dataValue );
        !          1666: 
        !          1667:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXRST);
        !          1668:     IOLog("\nEthernet(BMac): Read Register %04x Rx Reset             = %04x", kRXRST, dataValue );
        !          1669: 
        !          1670:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXCFG);
        !          1671:     IOLog("\nEthernet(BMac): Read Register %04x Rx Config            = %04x", kRXCFG, dataValue );
        !          1672:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1673: 
        !          1674:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXMAX);
        !          1675:     IOLog("\nEthernet(BMac): Read Register %04x Rx Max Size         = %04x", kRXMAX, dataValue );
        !          1676: 
        !          1677:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXMIN);
        !          1678:     IOLog("\nEthernet(BMac): Read Register %04x Rx Min Size         = %04x", kRXMIN, dataValue );
        !          1679: 
        !          1680:     dataValue = ReadBigMacRegister(ioBaseEnet, kMADD2);
        !          1681:     IOLog("\nEthernet(BMac): Read Register %04x Mac Address 2       = %04x", kMADD2, dataValue );
        !          1682: 
        !          1683:     dataValue = ReadBigMacRegister(ioBaseEnet, kMADD1);
        !          1684:     IOLog("\nEthernet(BMac): Read Register %04x Mac Address 1       = %04x", kMADD1, dataValue );
        !          1685: 
        !          1686:     dataValue = ReadBigMacRegister(ioBaseEnet, kMADD0);
        !          1687:     IOLog("\nEthernet(BMac): Read Register %04x Mac Address 0       = %04x", kMADD0, dataValue );
        !          1688:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1689: 
        !          1690:     dataValue = ReadBigMacRegister(ioBaseEnet, kFRCNT);
        !          1691:     IOLog("\nEthernet(BMac): Read Register %04x Rx Frame Counter    = %04x", kFRCNT, dataValue );
        !          1692: 
        !          1693:     dataValue = ReadBigMacRegister(ioBaseEnet, kLECNT);
        !          1694:     IOLog("\nEthernet(BMac): Read Register %04x Rx Length Error Cnt = %04x", kLECNT, dataValue );
        !          1695: 
        !          1696:     dataValue = ReadBigMacRegister(ioBaseEnet, kAECNT);
        !          1697:     IOLog("\nEthernet(BMac): Read Register %04x Alignment Error Cnt = %04x", kAECNT, dataValue );
        !          1698: 
        !          1699:     dataValue = ReadBigMacRegister(ioBaseEnet, kFECNT);
        !          1700:     IOLog("\nEthernet(BMac): Read Register %04x FCS Error Cnt       = %04x", kFECNT, dataValue );
        !          1701: 
        !          1702:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXSM);
        !          1703:     IOLog("\nEthernet(BMac): Read Register %04x Rx State Machine    = %04x", kRXSM, dataValue );
        !          1704:     IOLog("\nEthernet(BMac): -------------------------------------------------------" );
        !          1705: 
        !          1706:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXCV);
        !          1707:     IOLog("\nEthernet(BMac): Read Register %04x Rx Code Violation = %04x", kRXCV, dataValue );
        !          1708: 
        !          1709:     dataValue = ReadBigMacRegister(ioBaseEnet, kHASH3);
        !          1710:     IOLog("\nEthernet(BMac): Read Register %04x Hash 3            = %04x", kHASH3, dataValue );
        !          1711: 
        !          1712:     dataValue = ReadBigMacRegister(ioBaseEnet, kHASH2);
        !          1713:     IOLog("\nEthernet(BMac): Read Register %04x Hash 2            = %04x", kHASH2, dataValue );
        !          1714: 
        !          1715:     dataValue = ReadBigMacRegister(ioBaseEnet, kHASH1);
        !          1716:     IOLog("\nEthernet(BMac): Read Register %04x Hash 1            = %04x", kHASH1, dataValue );
        !          1717: 
        !          1718:     dataValue = ReadBigMacRegister(ioBaseEnet, kHASH0);
        !          1719:     IOLog("\nEthernet(BMac): Read Register %04x Hash 0            = %04x", kHASH0, dataValue );
        !          1720:     IOLog("\n-------------------------------------------------------" );
        !          1721: 
        !          1722:     dataValue = ReadBigMacRegister(ioBaseEnet, kAFR2);
        !          1723:     IOLog("\nEthernet(BMac): Read Register %04x Address Filter 2   = %04x", kAFR2, dataValue );
        !          1724: 
        !          1725:     dataValue = ReadBigMacRegister(ioBaseEnet, kAFR1);
        !          1726:     IOLog("\nEthernet(BMac): Read Register %04x Address Filter 1   = %04x", kAFR1, dataValue );
        !          1727: 
        !          1728:     dataValue = ReadBigMacRegister(ioBaseEnet, kAFR0);
        !          1729:     IOLog("\nEthernet(BMac): Read Register %04x Address Filter 0   = %04x", kAFR0, dataValue );
        !          1730: 
        !          1731:     dataValue = ReadBigMacRegister(ioBaseEnet, kAFCR);
        !          1732:     IOLog("\nEthernet(BMac): Read Register %04x Adress Filter Mask = %04x", kAFCR, dataValue );
        !          1733: 
        !          1734:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXFIFOCSR);
        !          1735:     IOLog("\nEthernet(BMac): Read Register %04x Tx FIFO CSR        = %04x", kTXFIFOCSR, dataValue );
        !          1736:     IOLog("\n-------------------------------------------------------" );
        !          1737: 
        !          1738:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXTH);
        !          1739:     IOLog("\nEthernet(BMac): Read Register %04x Tx Threshold  = %04x", kTXTH, dataValue );
        !          1740: 
        !          1741:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXFIFOCSR);
        !          1742:     IOLog("\nEthernet(BMac): Read Register %04x Rx FIFO CSR   = %04x", kRXFIFOCSR, dataValue );
        !          1743: 
        !          1744:     dataValue = ReadBigMacRegister(ioBaseEnet, kMEMADD);
        !          1745:     IOLog("\nEthernet(BMac): Read Register %04x Mem Addr      = %04x", kMEMADD, dataValue );
        !          1746: 
        !          1747:     dataValue = ReadBigMacRegister(ioBaseEnet, kMEMDATAHI);
        !          1748:     IOLog("\nEthernet(BMac): Read Register %04x Mem Data High = %04x", kMEMDATAHI, dataValue );
        !          1749: 
        !          1750:     dataValue = ReadBigMacRegister(ioBaseEnet, kMEMDATALO);
        !          1751:     IOLog("\nEthernet(BMac): Read Register %04x Mem Data Low  = %04x", kMEMDATALO, dataValue );
        !          1752:     IOLog("\n-------------------------------------------------------" );
        !          1753: 
        !          1754:     dataValue = ReadBigMacRegister(ioBaseEnet, kXCVRIF);
        !          1755:     IOLog("\nEthernet(BMac): Read Register %04x Transceiver IF Control = %04x", kXCVRIF, dataValue );
        !          1756: 
        !          1757:     dataValue = ReadBigMacRegister(ioBaseEnet, kCHIPID);
        !          1758:     IOLog("\nEthernet(BMac): Read Register %04x Chip ID                = %04x", kCHIPID, dataValue );
        !          1759: 
        !          1760:     dataValue = ReadBigMacRegister(ioBaseEnet, kMIFCSR);
        !          1761:     IOLog("\nEthernet(BMac): Read Register %04x MII CSR                = %04x", kMIFCSR, dataValue );
        !          1762: 
        !          1763:     dataValue = ReadBigMacRegister(ioBaseEnet, kSROMCSR);
        !          1764:     IOLog("\nEthernet(BMac): Read Register %04x SROM CSR               = %04x", kSROMCSR, dataValue );
        !          1765: 
        !          1766:     dataValue = ReadBigMacRegister(ioBaseEnet, kTXPNTR);
        !          1767:     IOLog("\nEthernet(BMac): Read Register %04x Tx Pointer             = %04x", kTXPNTR, dataValue );
        !          1768: 
        !          1769:     dataValue = ReadBigMacRegister(ioBaseEnet, kRXPNTR);
        !          1770:     IOLog("\nEthernet(BMac): Read Register %04x Rx Pointer             = %04x", kRXPNTR, dataValue );
        !          1771:     IOLog("\nEthernet(BMac): -------------------------------------------------------\n" );
        !          1772: }
        !          1773: #endif DEBUG
        !          1774: 
        !          1775: 
        !          1776: /*-------------------------------------------------------------------------
        !          1777:  *
        !          1778:  *
        !          1779:  *
        !          1780:  *-------------------------------------------------------------------------*/
        !          1781: 
        !          1782: IOReturn BMacEnet::getHardwareAddress(enet_addr_t *ea)
        !          1783: {
        !          1784:     int i;
        !          1785:     unsigned short data;
        !          1786: 
        !          1787:     for (i = 0; i < (unsigned short)sizeof(*ea)/2; i++)        
        !          1788:     {
        !          1789:                reset_and_select_srom(ioBaseEnet);
        !          1790:                data = read_srom(ioBaseEnet, i + enetAddressOffset/2, sromAddressBits);
        !          1791:                ea->ea_byte[2*i]   = reverseBitOrder(data & 0x0ff);
        !          1792:                ea->ea_byte[2*i+1] = reverseBitOrder((data >> 8) & 0x0ff);
        !          1793:     }
        !          1794:        
        !          1795:        return kIOReturnSuccess;
        !          1796: }
        !          1797: 
        !          1798: /*-------------------------------------------------------------------------
        !          1799:  *
        !          1800:  *
        !          1801:  *
        !          1802:  *-------------------------------------------------------------------------*/
        !          1803: 
        !          1804: #define ENET_CRCPOLY 0x04c11db7
        !          1805: 
        !          1806: /* Real fast bit-reversal algorithm, 6-bit values */
        !          1807: static int reverse6[] = 
        !          1808: {      0x0,0x20,0x10,0x30,0x8,0x28,0x18,0x38,
        !          1809:        0x4,0x24,0x14,0x34,0xc,0x2c,0x1c,0x3c,
        !          1810:        0x2,0x22,0x12,0x32,0xa,0x2a,0x1a,0x3a,
        !          1811:        0x6,0x26,0x16,0x36,0xe,0x2e,0x1e,0x3e,
        !          1812:        0x1,0x21,0x11,0x31,0x9,0x29,0x19,0x39,
        !          1813:        0x5,0x25,0x15,0x35,0xd,0x2d,0x1d,0x3d,
        !          1814:        0x3,0x23,0x13,0x33,0xb,0x2b,0x1b,0x3b,
        !          1815:        0x7,0x27,0x17,0x37,0xf,0x2f,0x1f,0x3f
        !          1816: };
        !          1817: 
        !          1818: static u_int32_t crc416(unsigned int current, unsigned short nxtval )
        !          1819: {
        !          1820:     register unsigned int counter;
        !          1821:     register int highCRCBitSet, lowDataBitSet;
        !          1822: 
        !          1823:     /* Swap bytes */
        !          1824:     nxtval = ((nxtval & 0x00FF) << 8) | (nxtval >> 8);
        !          1825: 
        !          1826:        /* Compute bit-by-bit */
        !          1827:        for (counter = 0; counter != 16; ++counter)
        !          1828:                {       /* is high CRC bit set? */
        !          1829:                if ((current & 0x80000000) == 0)        
        !          1830:                        highCRCBitSet = 0;
        !          1831:                else
        !          1832:                        highCRCBitSet = 1;
        !          1833:                
        !          1834:                current = current << 1;
        !          1835:        
        !          1836:                if ((nxtval & 0x0001) == 0)
        !          1837:                        lowDataBitSet = 0;
        !          1838:                else
        !          1839:                        lowDataBitSet = 1;
        !          1840: 
        !          1841:                nxtval = nxtval >> 1;
        !          1842:        
        !          1843:                /* do the XOR */
        !          1844:                if (highCRCBitSet ^ lowDataBitSet)
        !          1845:                        current = current ^ ENET_CRCPOLY;
        !          1846:     }
        !          1847: 
        !          1848:     return current;
        !          1849: }
        !          1850: 
        !          1851: /*-------------------------------------------------------------------------
        !          1852:  *
        !          1853:  *
        !          1854:  *
        !          1855:  *-------------------------------------------------------------------------*/
        !          1856: 
        !          1857: static u_int32_t mace_crc(unsigned short *address)
        !          1858: {      
        !          1859:     register u_int32_t newcrc;
        !          1860: 
        !          1861:     newcrc = crc416(0xffffffff, *address);     /* address bits 47 - 32 */
        !          1862:     newcrc = crc416(newcrc, address[1]);       /* address bits 31 - 16 */
        !          1863:     newcrc = crc416(newcrc, address[2]);       /* address bits 15 - 0  */
        !          1864: 
        !          1865:     return(newcrc);
        !          1866: }
        !          1867: 
        !          1868: /*
        !          1869:  * Clear the hash table filter.  
        !          1870:  *  
        !          1871:  */
        !          1872: void BMacEnet::_resetHashTableMask()
        !          1873: {
        !          1874:        bzero(hashTableUseCount, sizeof(hashTableUseCount));
        !          1875:        bzero(hashTableMask, sizeof(hashTableMask));
        !          1876: }
        !          1877: 
        !          1878: /*
        !          1879:  * Add requested mcast addr to BMac's hash table filter.  
        !          1880:  *  
        !          1881:  */
        !          1882: void BMacEnet::_addToHashTableMask(u_int8_t *addr)
        !          1883: {      
        !          1884:     u_int32_t   crc;
        !          1885:     u_int16_t   mask;
        !          1886: 
        !          1887:     crc = mace_crc((unsigned short *)addr)&0x3f; /* Big-endian alert! */
        !          1888:     crc = reverse6[crc];       /* Hyperfast bit-reversing algorithm */
        !          1889:     if (hashTableUseCount[crc]++)      
        !          1890:                return;                         /* This bit is already set */
        !          1891:     mask = crc % 16;
        !          1892:     mask = (unsigned short)1 << mask;
        !          1893:     hashTableMask[crc/16] |= mask;
        !          1894: }
        !          1895: 
        !          1896: /*-------------------------------------------------------------------------
        !          1897:  *
        !          1898:  *
        !          1899:  *
        !          1900:  *-------------------------------------------------------------------------*/
        !          1901: 
        !          1902: void BMacEnet::_removeFromHashTableMask(u_int8_t *addr)
        !          1903: {
        !          1904:     unsigned int       crc;
        !          1905:     u_int16_t  mask;
        !          1906: 
        !          1907:     /* Now, delete the address from the filter copy, as indicated */
        !          1908:     crc = mace_crc((unsigned short *)addr)&0x3f; /* Big-endian alert! */
        !          1909:     crc = reverse6[crc];       /* Hyperfast bit-reversing algorithm */
        !          1910:        if (hashTableUseCount[crc] == 0)
        !          1911:                return;                 /* That bit wasn't in use! */
        !          1912: 
        !          1913:        if (--hashTableUseCount[crc])
        !          1914:                return;                 /* That bit is still in use */
        !          1915: 
        !          1916:        mask = crc % 16;
        !          1917:     mask = (u_int16_t)1 << mask; /* To turn off bit */
        !          1918:     hashTableMask[crc/16] &= ~mask;
        !          1919: }
        !          1920: 
        !          1921: /*
        !          1922:  * Sync the adapter with the software copy of the multicast mask
        !          1923:  *  (logical address filter).
        !          1924:  */
        !          1925: void BMacEnet::_updateBMacHashTableMask()
        !          1926: {
        !          1927:     u_int16_t          rxCFGReg;
        !          1928: 
        !          1929:     rxCFGReg = ReadBigMacRegister(ioBaseEnet, kRXCFG);
        !          1930:     WriteBigMacRegister(ioBaseEnet, kRXCFG,
        !          1931:                rxCFGReg & ~(kRxMACEnable | kRxHashFilterEnable) );
        !          1932: 
        !          1933:     while ( ReadBigMacRegister(ioBaseEnet, kRXCFG) &
        !          1934:                (kRxMACEnable | kRxHashFilterEnable) )
        !          1935:                ;
        !          1936: 
        !          1937:     WriteBigMacRegister(ioBaseEnet, kHASH0, hashTableMask[0]);         // bits 15 - 0
        !          1938:     WriteBigMacRegister(ioBaseEnet, kHASH1, hashTableMask[1]);         // bits 31 - 16
        !          1939:     WriteBigMacRegister(ioBaseEnet, kHASH2, hashTableMask[2]);         // bits 47 - 32
        !          1940:     WriteBigMacRegister(ioBaseEnet, kHASH3, hashTableMask[3]);         // bits 63 - 48
        !          1941: 
        !          1942:     rxCFGReg |= kRxHashFilterEnable;
        !          1943:     WriteBigMacRegister(ioBaseEnet, kRXCFG, rxCFGReg );
        !          1944: }

unix.superglobalmegacorp.com

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