Annotation of XNU/iokit/Drivers/network/drvPPCBMac/BMacEnetPrivate.cpp, revision 1.1.1.1

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