Annotation of kernel/bsd/dev/ppc/drvMaceEnet/MaceEnet.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) 1995-1996 NeXT Software, Inc.
                     27:  *
                     28:  * Hardware independent (relatively) code for the Mace Ethernet Controller 
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * dd-mmm-yy    
                     33:  *     Created.
                     34:  *
                     35:  */
                     36: 
                     37: #import "MaceEnetPrivate.h"
                     38: 
                     39: @implementation MaceEnet
                     40: 
                     41: /*
                     42:  * Public Factory Methods
                     43:  */
                     44:  
                     45: + (BOOL)probe:(IODeviceDescription *)devDesc
                     46: {
                     47:     MaceEnet           *MaceEnetInstance;
                     48:     extern int         kdp_flag;
                     49: 
                     50:     /*
                     51:      * If bootargs: kdp bit 0 using in-kernel mace driver for early debugging,
                     52:      *              Don't probe this driver.
                     53:      */
                     54:     if( kdp_flag & 1)
                     55:     {
                     56:         return nil;
                     57:     }  
                     58: 
                     59:     MaceEnetInstance = [self alloc];
                     60:     return [MaceEnetInstance initFromDeviceDescription:devDesc] != nil;
                     61: }
                     62: 
                     63: /*
                     64:  * Public Instance Methods
                     65:  */
                     66: 
                     67: /*-------------------------------------------------------------------------
                     68:  *
                     69:  *
                     70:  *
                     71:  *-------------------------------------------------------------------------*/
                     72: 
                     73: - initFromDeviceDescription:(IOTreeDevice *)devDesc
                     74: {
                     75:     IORange            *ioRangeMace;
                     76: 
                     77:     if ([super initFromDeviceDescription:devDesc] == nil)     
                     78:     {
                     79:       IOLog( "Ethernet(Mace): [super initFromDeviceDescription] failed\n");
                     80:       return nil;
                     81:     }
                     82: 
                     83:     if ( [devDesc numMemoryRanges] < 3 )
                     84:     {
                     85:       IOLog( "Ethernet(Mace): Incorrect deviceDescription - 1\n\r");
                     86:       return nil;
                     87:     }
                     88: 
                     89:     ioRangeMace = [devDesc memoryRangeList];
                     90: 
                     91:     ioBaseEnet      = (IOPPCAddress) ioRangeMace[0].start;
                     92:     ioBaseEnetTxDMA = (IOPPCAddress) ioRangeMace[1].start;
                     93:     ioBaseEnetRxDMA = (IOPPCAddress) ioRangeMace[2].start;
                     94: 
                     95:     ioBaseEnetROM   = (IOPPCAddress) (((unsigned int) ioBaseEnet & ~0xffff) | kControllerROMOffset);
                     96: 
                     97:     if ( ![self resetAndEnable:NO] ) 
                     98:     {
                     99:       [self free];
                    100:       return nil;
                    101:     }
                    102: 
                    103:     [self _getStationAddress:&myAddress];
                    104: 
                    105:     if ([self _allocateMemory] == NO) 
                    106:     {
                    107:       [self free];
                    108:       return nil;
                    109:     }
                    110: 
                    111:     if ( ![self resetAndEnable:YES] ) 
                    112:     {
                    113:       [self free];
                    114:       return nil;
                    115:     }
                    116: 
                    117:     isPromiscuous = NO;
                    118:     multicastEnabled = NO;
                    119: 
                    120:     networkInterface = [super attachToNetworkWithAddress:myAddress];
                    121: 
                    122:     return self;
                    123: }
                    124: 
                    125: 
                    126: /*-------------------------------------------------------------------------
                    127:  *
                    128:  *
                    129:  *
                    130:  *-------------------------------------------------------------------------*/
                    131: 
                    132: - free
                    133: {
                    134:     int                i;
                    135:     
                    136:     [self clearTimeout];
                    137:     
                    138:     [self _resetChip];
                    139:     
                    140:     if (networkInterface)
                    141:        [networkInterface free];
                    142: 
                    143:     for (i = 0; i < rxMaxCommand; i++)
                    144:        if (rxNetbuf[i])  nb_free(rxNetbuf[i]);
                    145: 
                    146:     for (i = 0; i < txMaxCommand; i++)
                    147:        if (txNetbuf[i]) nb_free(txNetbuf[i]);
                    148:     
                    149:     return [super free];
                    150: }
                    151: 
                    152: /*-------------------------------------------------------------------------
                    153:  *
                    154:  *
                    155:  *
                    156:  *-------------------------------------------------------------------------*/
                    157: - (void) interruptOccurredAt:(int)irqNum
                    158: {
                    159: 
                    160:     [self reserveDebuggerLock];
                    161:         
                    162: //    kprintf("IRQ = %d\n",irqNum );
                    163: 
                    164:     switch ( irqNum )
                    165:     {
                    166:       case kIRQEnetTxDMA:
                    167:         txWDInterrupts++;
                    168:         KERNEL_DEBUG(DBG_MACE_TXIRQ | DBG_FUNC_START, 0, 0, 0, 0, 0 );
                    169:         [self _transmitInterruptOccurred];
                    170:         KERNEL_DEBUG(DBG_MACE_TXIRQ | DBG_FUNC_END,   0, 0, 0, 0, 0 );
                    171:         [self enableInterrupt:kIRQEnetTxDMA];
                    172:         [self serviceTransmitQueue];
                    173:         break;
                    174:       case kIRQEnetRxDMA:
                    175:         KERNEL_DEBUG(DBG_MACE_RXIRQ | DBG_FUNC_START, 0, 0, 0, 0, 0 );
                    176:         [self _receiveInterruptOccurred];
                    177:         KERNEL_DEBUG(DBG_MACE_RXIRQ | DBG_FUNC_END,   0, 0, 0, 0, 0 );
                    178:         [self enableInterrupt:kIRQEnetRxDMA];
                    179:         break;
                    180:     }
                    181: 
                    182:     [self releaseDebuggerLock];
                    183: }
                    184: 
                    185: 
                    186: /*-------------------------------------------------------------------------
                    187:  *
                    188:  *
                    189:  *
                    190:  *-------------------------------------------------------------------------*/
                    191: 
                    192: - (void) serviceTransmitQueue
                    193: {
                    194:     netbuf_t                   packet;
                    195:     u_int32_t                  i;
                    196: 
                    197:     while ( 1 )
                    198:     {
                    199:       if ( ![transmitQueue count] )
                    200:       {
                    201:         break;
                    202:       }
                    203: 
                    204:       i = txCommandTail + 1;
                    205:       if ( i >= txMaxCommand ) i = 0;
                    206:       if ( i == txCommandHead )
                    207:       {
                    208:         break;
                    209:       }
                    210:       packet = [transmitQueue dequeue];
                    211:       [self _transmitPacket:packet];
                    212:     }
                    213: 
                    214: }
                    215: 
                    216: /*-------------------------------------------------------------------------
                    217:  *
                    218:  *
                    219:  *
                    220:  *-------------------------------------------------------------------------*/
                    221: 
                    222: - (void)transmit:(netbuf_t)pkt
                    223: {
                    224:     u_int32_t          i;
                    225:     u_int32_t           n;
                    226:     u_int8_t           regValue;
                    227: 
                    228:     KERNEL_DEBUG(DBG_MACE_TXQUEUE | DBG_FUNC_NONE, (int) pkt, (int) nb_size(pkt), 0, 0, 0 );
                    229: 
                    230:     /*
                    231:      * Hold the debugger lock so the debugger can't interrupt us
                    232:      */
                    233:     [self reserveDebuggerLock];
                    234: 
                    235:     do
                    236:     {
                    237:       /*
                    238:        * Someone is turning off the receiver before the first transmit.
                    239:        * Dont know who yet!
                    240:        */
                    241:       regValue = ReadMaceRegister( ioBaseEnet, kMacCC );
                    242:       regValue |= kMacCCEnRcv;
                    243:       WriteMaceRegister( ioBaseEnet, kMacCC, regValue );
                    244: 
                    245:       /* 
                    246:        * Preliminary sanity checks
                    247:        */
                    248:       if (!pkt) 
                    249:       {
                    250:         IOLog("EtherNet(Mace): transmit received NULL netbuf\n");
                    251:         continue;  
                    252:       }
                    253:       if ( ![self isRunning] ) 
                    254:       {
                    255:         nb_free(pkt);
                    256:         continue;
                    257:       }
                    258:     
                    259:       /*
                    260:        * Remove any completed packets from the Tx ring 
                    261:        */
                    262:       [self _transmitInterruptOccurred]; 
                    263:        
                    264:       /*
                    265:        * Refill the Tx ring from the Transmit waiting list
                    266:        */
                    267:       [self serviceTransmitQueue];
                    268: 
                    269:       /*
                    270:        * If the Transmit waiting list is not empty or the Tx ring is
                    271:        * full, add the new packet to the waiting list.
                    272:        */
                    273:       n = [transmitQueue count];
                    274:       if ( n > 0 )
                    275:       {
                    276:         if ( n >= [transmitQueue maxCount] )
                    277:         {
                    278:           IOLog("Ethernet(Mace) Transmit queue overflow\n");
                    279:         }
                    280: 
                    281:         [transmitQueue enqueue:pkt];
                    282:         continue;
                    283:       }
                    284:       i = txCommandTail + 1;
                    285:       if ( i >= txMaxCommand ) i = 0;
                    286:       if ( i == txCommandHead )
                    287:       {
                    288:         [transmitQueue enqueue:pkt];
                    289:         continue;
                    290:       }
                    291: 
                    292:       /*
                    293:        * If there is space on the Tx ring, add the packet directly to the
                    294:        * ring
                    295:        */
                    296:       [self _transmitPacket:pkt];
                    297:     }
                    298:     while( 0 );
                    299: 
                    300:     [self releaseDebuggerLock];
                    301: 
                    302: }
                    303: 
                    304: /*-------------------------------------------------------------------------
                    305:  *
                    306:  *
                    307:  *
                    308:  *-------------------------------------------------------------------------*/
                    309: 
                    310: - (int) transmitQueueSize
                    311: {
                    312:     return (TRANSMIT_QUEUE_SIZE);
                    313: }
                    314: 
                    315: - (int) transmitQueueCount
                    316: {
                    317:     return ([transmitQueue count]);
                    318: }
                    319: /*-------------------------------------------------------------------------
                    320:  *
                    321:  *
                    322:  *
                    323:  *-------------------------------------------------------------------------*/
                    324: 
                    325: - (BOOL)resetAndEnable:(BOOL)enable
                    326: {
                    327:     resetAndEnabled = NO;
                    328:     [self clearTimeout];
                    329:     [self disableAllInterrupts];
                    330:     [self _resetChip];
                    331:     
                    332:     if (enable) 
                    333:     {
                    334:       if ( ![self _initRxRing] || ![self _initTxRing] || ![self _initChip] ) 
                    335:       {
                    336:        [self setRunning:NO];
                    337:        return NO;
                    338:       }
                    339: 
                    340:       [self _startChip];
                    341: 
                    342:       [self setRelativeTimeout: WATCHDOG_TIMER_MS];
                    343: 
                    344:       [self enableInterrupt:kIRQEnetRxDMA];
                    345:       [self enableInterrupt:kIRQEnetTxDMA];
                    346:       [self _enableAdapterInterrupts];
                    347: 
                    348:       resetAndEnabled = YES;
                    349:     }
                    350: 
                    351:     [self setRunning:enable];
                    352: 
                    353:     return YES;
                    354: }
                    355: 
                    356: /*-------------------------------------------------------------------------
                    357:  *
                    358:  *
                    359:  *
                    360:  *-------------------------------------------------------------------------*/
                    361: 
                    362: - (void)timeoutOccurred
                    363: {
                    364:     u_int32_t          dmaStatus;
                    365: 
                    366:     if ( ![self isRunning] ) 
                    367:     {    
                    368:       return;
                    369:     }
                    370: 
                    371:     [self reserveDebuggerLock];
                    372: 
                    373:     /*
                    374:      * Check for DMA shutdown on receive channel
                    375:      */
                    376:     dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
                    377:     if ( !(dmaStatus & kdbdmaActive) )
                    378:     {
                    379:       IOLog( "Ethernet(Mace): Checking for timeout - RxHead = %d RxTail = %d\n\r", rxCommandHead, rxCommandTail);
                    380: #if 0
                    381:       IOLog( "Ethernet(Mace): Rx Commands = %08x(p) Rx DMA Ptr = %08x(p)\n\r", rxDMACommandsPhys, IOGetDBDMACommandPtr(ioBaseEnetRxDMA) ); 
                    382:       [self _dumpDesc:(void *)rxDMACommands Size:rxMaxCommand * sizeof(enet_dma_cmd_t)];
                    383: #endif 
                    384:       [self _receiveInterruptOccurred];
                    385:     } 
                    386: 
                    387:     /*
                    388:      * If there are pending entries on the Tx ring
                    389:      */
                    390:     if ( txCommandHead != txCommandTail )
                    391:     {
                    392:       /* 
                    393:        * If we did not service the Tx ring during the last timeout interval,
                    394:        * then force servicing of the Tx ring.
                    395:        * If we have more than one timeout interval without any transmit interrupts,
                    396:        * then force the transmitter to reset.
                    397:        */
                    398:       if ( txWDInterrupts == 0 )
                    399:       { 
                    400:         if ( ++txWDTimeouts > 1 ) txWDForceReset = YES;  
                    401:        
                    402:         IOLog( "Ethernet(Mace): Checking for timeout - TxHead = %d TxTail = %d\n\r", txCommandHead, txCommandTail); 
                    403:         [self _transmitInterruptOccurred];
                    404:       }
                    405:       else
                    406:       {
                    407:         txWDTimeouts     = 0;
                    408:         txWDInterrupts   = 0;
                    409:       }
                    410:     }
                    411:     else
                    412:     {
                    413:       txWDTimeouts     = 0;
                    414:       txWDInterrupts   = 0;
                    415:     }
                    416: 
                    417:     /*
                    418:      * Restart the watchdog timer
                    419:      */
                    420:     [self setRelativeTimeout: WATCHDOG_TIMER_MS];
                    421: 
                    422:     [self releaseDebuggerLock];
                    423: 
                    424: }
                    425: 
                    426: /*-------------------------------------------------------------------------
                    427:  *
                    428:  *
                    429:  *
                    430:  *-------------------------------------------------------------------------*/
                    431: 
                    432: - (netbuf_t)allocateNetbuf
                    433: {
                    434:     netbuf_t           packet;
                    435:        
                    436:     packet = nb_alloc(NETWORK_BUFSIZE);
                    437:     if (!packet) 
                    438:     {
                    439:       IOLog("nb_alloc() returned NULL\n");
                    440:     }
                    441:     
                    442:     return packet;
                    443: }
                    444: 
                    445: /*-------------------------------------------------------------------------
                    446:  *
                    447:  *
                    448:  *
                    449:  *-------------------------------------------------------------------------*/
                    450: 
                    451: - (BOOL)enablePromiscuousMode
                    452: {
                    453:     u_int8_t           regVal;
                    454:     
                    455:     isPromiscuous = YES;
                    456:     
                    457:     [self reserveDebuggerLock];
                    458: 
                    459:     regVal = ReadMaceRegister( ioBaseEnet, kMacCC );
                    460:     WriteMaceRegister( ioBaseEnet, kMacCC, regVal & ~kMacCCEnRcv );
                    461:     regVal |= kMacCCProm;      
                    462:     WriteMaceRegister( ioBaseEnet, kMacCC, regVal );   
                    463:        
                    464:     [self releaseDebuggerLock];
                    465: 
                    466:     return YES;
                    467: }
                    468: 
                    469: - (void)disablePromiscuousMode
                    470: {
                    471:     u_int8_t           regVal;
                    472:     
                    473:     isPromiscuous = NO;
                    474:     
                    475:     [self reserveDebuggerLock];
                    476: 
                    477:     regVal = ReadMaceRegister(ioBaseEnet, kMacCC);
                    478:     WriteMaceRegister( ioBaseEnet, kMacCC, regVal & ~kMacCCEnRcv );
                    479:     regVal &= ~kMacCCProm;     
                    480:     WriteMaceRegister( ioBaseEnet, kMacCC, regVal );   
                    481:        
                    482:     [self releaseDebuggerLock];
                    483: 
                    484: }
                    485: 
                    486: - (BOOL)enableMulticastMode
                    487: {
                    488:     multicastEnabled = YES;
                    489:     return YES;
                    490: }
                    491:         
                    492: - (void)disableMulticastMode
                    493: {
                    494:     multicastEnabled = NO;
                    495: }
                    496: 
                    497: - (void)addMulticastAddress:(enet_addr_t *)addr
                    498: {
                    499:     multicastEnabled = YES;
                    500:     [self reserveDebuggerLock];
                    501:     [self _addToHashTableMask:addr->ea_byte];
                    502:     [self _updateHashTableMask];
                    503:     [self releaseDebuggerLock];
                    504: }
                    505: 
                    506: - (void)removeMulticastAddress:(enet_addr_t *)addr
                    507: {
                    508:     [self reserveDebuggerLock];
                    509:     [self _removeFromHashTableMask:addr->ea_byte];
                    510:     [self _updateHashTableMask];
                    511:     [self releaseDebuggerLock];
                    512: }
                    513: 
                    514: /*
                    515:  * Kernel Debugger Support 
                    516:  */
                    517: - (void)sendPacket:(void *)pkt length:(unsigned int)pkt_len
                    518: {
                    519:     [self _sendPacket:(void *)pkt length:(unsigned int)pkt_len];
                    520: }
                    521: 
                    522: - (void)receivePacket:(void *)pkt length:(unsigned int *)pkt_len  timeout:(unsigned int)timeout
                    523: {
                    524:     [self _receivePacket:(void *)pkt length:(unsigned int *)pkt_len  timeout:(unsigned int)timeout];
                    525: }
                    526: 
                    527: /*
                    528:  * Power management methods. 
                    529:  */
                    530: - (IOReturn)getPowerState:(PMPowerState *)state_p
                    531: {
                    532:     return IO_R_UNSUPPORTED;
                    533: }
                    534: 
                    535: - (IOReturn)setPowerState:(PMPowerState)state
                    536: {
                    537:     if (state == PM_OFF) {
                    538:        resetAndEnabled = NO;
                    539:         [self _resetChip];
                    540:        return IO_R_SUCCESS;
                    541:     }
                    542:     return IO_R_UNSUPPORTED;
                    543: }
                    544: 
                    545: - (IOReturn)getPowerManagement:(PMPowerManagementState *)state_p
                    546: {
                    547:     return IO_R_UNSUPPORTED;
                    548: }
                    549: 
                    550: - (IOReturn)setPowerManagement:(PMPowerManagementState)state
                    551: {
                    552:     return IO_R_UNSUPPORTED;
                    553: }
                    554: 
                    555: @end
                    556: 
                    557: 
                    558: 
                    559: 
                    560: 
                    561: 
                    562: 
                    563: 
                    564: 
                    565: 
                    566: 
                    567: 
                    568: 
                    569: 
                    570: 

unix.superglobalmegacorp.com

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