Annotation of kernel/bsd/dev/ppc/drvBMacEnet/BMacEnetPrivate.m, revision 1.1

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

unix.superglobalmegacorp.com

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