Annotation of kernel/bsd/dev/ppc/drvBMacEnet/BMacEnetPrivate.m, revision 1.1.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.