Annotation of kernel/bsd/dev/ppc/drvBMacEnet/BMacEnetMII.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:  * MII/PHY (National Semiconductor DP83840/DP83840A) support methods.
                     29:  * It is general enough to work with most MII/PHYs.
                     30:  *
                     31:  * HISTORY
                     32:  *
                     33:  */
                     34: #import "BMacEnetPrivate.h"
                     35: 
                     36: @implementation BMacEnet(MII)
                     37: 
                     38: /*
                     39:  * Read from MII/PHY registers.
                     40:  */
                     41: - (BOOL)miiReadWord:(unsigned short *)dataPtr reg:(unsigned short)reg
                     42:        phy:(unsigned char)phy
                     43: {
                     44:     int                                        i;
                     45:     miiFrameUnion              frame;
                     46:     unsigned short             phyreg;
                     47:     BOOL                       ret = YES;
                     48: 
                     49:     do
                     50:     {
                     51:         // Write preamble
                     52:         //
                     53:         [self miiWrite:MII_FRAME_PREAMBLE size:MII_FRAME_SIZE];
                     54: 
                     55:        
                     56:         if ([self miiCheckZeroBit] == YES) 
                     57:         {
                     58: //          IOLog("Ethernet(BMac): MII not floating before read\n\r");
                     59:            ret = NO;
                     60:             break;
                     61:         }
                     62: 
                     63:         // Prepare command frame
                     64:         //
                     65:         frame.data = MII_FRAME_READ;
                     66:         frame.bit.regad = reg;
                     67:         frame.bit.phyad = phy;
                     68:        
                     69:         // write ST, OP, PHYAD, REGAD in the MII command frame
                     70:         //
                     71:         [self miiWrite:frame.data size:14];
                     72:        
                     73:         // Hi-Z state
                     74:         // Make sure the PHY generated a zero bit after the 2nd Hi-Z bit
                     75:         //
                     76: 
                     77:         [self miiOutThreeState];
                     78: 
                     79:         if ([self miiCheckZeroBit] == NO) 
                     80:         {
                     81: //          IOLog("Ethernet(BMac): MII not driven after turnaround\n\r");
                     82:            ret = NO;
                     83:             break;
                     84:         }
                     85: 
                     86:         // read 16-bit data
                     87:         //
                     88:         phyreg = 0;
                     89:         for (i = 0; i < 16; i++) 
                     90:         {
                     91:            phyreg = [self miiReadBit] | (phyreg << 1);
                     92:         }
                     93:         if (dataPtr)
                     94:            *dataPtr = phyreg;
                     95: 
                     96:         // Hi-Z state
                     97:         [self miiOutThreeState];
                     98:        
                     99:         if ([self miiCheckZeroBit] == YES) 
                    100:         {
                    101: //          IOLog("Ethernet(BMac): MII not floating after read\n\r");
                    102:            ret = NO;
                    103:             break;
                    104:         }
                    105:     }
                    106:     while ( 0 );
                    107: 
                    108:     return ret;
                    109: }
                    110: 
                    111: /*
                    112:  * Write to MII/PHY registers.
                    113:  */
                    114: - (BOOL)miiWriteWord:(unsigned short)data reg:(unsigned short)reg
                    115:        phy:(unsigned char)phy
                    116: {
                    117:     miiFrameUnion              frame;
                    118:     BOOL                       ret = YES;
                    119:        
                    120:     do
                    121:     {
                    122:         // Write preamble
                    123:         //
                    124:         [self miiWrite:MII_FRAME_PREAMBLE size:MII_FRAME_SIZE];
                    125: 
                    126:         if ([self miiCheckZeroBit] == YES) 
                    127:         {
                    128:            ret = NO;
                    129:             break;
                    130:         }
                    131: 
                    132:         // Prepare command frame
                    133:         //
                    134:         frame.data = MII_FRAME_WRITE;
                    135:         frame.bit.regad = reg;
                    136:         frame.bit.phyad = phy;
                    137:         frame.bit.data  = data;
                    138:        
                    139:         // Write command frame
                    140:         //
                    141:         [self miiWrite:frame.data size:MII_FRAME_SIZE];
                    142: 
                    143:         // Hi-Z state
                    144:         [self miiOutThreeState];
                    145: 
                    146:         if ([self miiCheckZeroBit] == YES) 
                    147:         {
                    148:            ret = NO;
                    149:             break;
                    150:         }
                    151:     }
                    152:     while ( 0 );
                    153: 
                    154:     return ret;
                    155: }
                    156: 
                    157: /* 
                    158:  * Write 'dataSize' number of bits to the MII management interface,
                    159:  * starting with the most significant bit of 'miiData'.
                    160:  *
                    161:  */
                    162: - (void)miiWrite:(unsigned int)miiData size:(unsigned int)dataSize
                    163: {
                    164:     int i;
                    165:     u_int16_t  regValue;
                    166:        
                    167:     regValue = kMIFCSR_DataOutEnable;
                    168:                
                    169:     for (i = dataSize; i > 0; i--) 
                    170:     {
                    171:         int bit = ((miiData & 0x80000000) ? kMIFCSR_DataOut : 0);
                    172:                
                    173:         regValue &= ~(kMIFCSR_Clock | kMIFCSR_DataOut) ;
                    174:         regValue |=  bit;
                    175:        WriteBigMacRegister(ioBaseEnet, kMIFCSR, regValue);
                    176:        IODelay(phyMIIDelay);
                    177:                
                    178:        regValue |= kMIFCSR_Clock;
                    179:        WriteBigMacRegister(ioBaseEnet, kMIFCSR, regValue );
                    180:        IODelay(phyMIIDelay);
                    181: 
                    182:        miiData = miiData << 1;
                    183:     }
                    184: }
                    185: 
                    186: /*
                    187:  * Read one bit from the MII management interface.
                    188:  */
                    189: - (int)miiReadBit
                    190: {
                    191:     u_int16_t          regValue;
                    192:     u_int16_t          regValueRead;
                    193: 
                    194:     regValue = 0;      
                    195: 
                    196:     WriteBigMacRegister(ioBaseEnet, kMIFCSR, regValue);
                    197:     IODelay(phyMIIDelay);
                    198: 
                    199:     regValue |= kMIFCSR_Clock;
                    200:     WriteBigMacRegister(ioBaseEnet, kMIFCSR, regValue);
                    201:     IODelay(phyMIIDelay);
                    202:        
                    203:     regValueRead = ReadBigMacRegister(ioBaseEnet, kMIFCSR);
                    204:     IODelay(phyMIIDelay);      // delay next invocation of this routine
                    205:        
                    206:     return ( (regValueRead & kMIFCSR_DataIn) ? 1 : 0 );
                    207: }
                    208: 
                    209: /*
                    210:  * Read the zero bit on the second clock of the turn-around (TA)
                    211:  * when reading a PHY register.
                    212:  */
                    213: - (BOOL)miiCheckZeroBit
                    214: {
                    215:     u_int16_t  regValue;
                    216:        
                    217:     regValue = ReadBigMacRegister(ioBaseEnet, kMIFCSR);
                    218:     
                    219:     return (((regValue & kMIFCSR_DataIn) == 0) ? YES : NO );
                    220: }
                    221: 
                    222: /*
                    223:  * Tri-state the STA's MDIO pin.
                    224:  */
                    225: - (void)miiOutThreeState
                    226: {
                    227:     u_int16_t          regValue;
                    228: 
                    229:     regValue = 0;      
                    230:     WriteBigMacRegister(ioBaseEnet, kMIFCSR, regValue);
                    231:     IODelay(phyMIIDelay);
                    232:        
                    233:     regValue |= kMIFCSR_Clock;
                    234:     WriteBigMacRegister(ioBaseEnet, kMIFCSR, regValue);
                    235:     IODelay(phyMIIDelay);
                    236: }
                    237: 
                    238: - (BOOL)miiResetPHY:(unsigned char)phy
                    239: {
                    240:     int i = MII_RESET_TIMEOUT;
                    241:     unsigned short mii_control;
                    242: 
                    243:     // Set the reset bit
                    244:     //
                    245:     [self miiWriteWord:MII_CONTROL_RESET reg:MII_CONTROL phy:phy];
                    246:        
                    247:     IOSleep(MII_RESET_DELAY);
                    248: 
                    249:     // Wait till reset process is complete (MII_CONTROL_RESET returns to zero)
                    250:     //
                    251:     while (i > 0) 
                    252:     {
                    253:        if ([self miiReadWord:&mii_control reg:MII_CONTROL phy:phy] == NO)
                    254:                return NO;
                    255: 
                    256:        if (!(mii_control & MII_CONTROL_RESET))
                    257:         {
                    258:             [self miiReadWord:&mii_control reg:MII_CONTROL phy:phy];
                    259:             mii_control &= ~MII_CONTROL_ISOLATE;
                    260:             [self miiWriteWord:mii_control reg:MII_CONTROL phy:phy];
                    261:             return YES;
                    262:         }
                    263: 
                    264:        IOSleep(MII_RESET_DELAY);
                    265:        i -= MII_RESET_DELAY;
                    266:     }
                    267:     return NO;
                    268: }
                    269: 
                    270: - (BOOL)miiWaitForLink:(unsigned char)phy
                    271: {
                    272:     int i = MII_LINK_TIMEOUT;
                    273:     unsigned short mii_status;
                    274:        
                    275:     while (i > 0) 
                    276:     {
                    277:        if ([self miiReadWord:&mii_status reg:MII_STATUS phy:phy] == NO)
                    278:                return NO;
                    279:                
                    280:        if (mii_status & MII_STATUS_LINK_STATUS)
                    281:                return YES;
                    282:                
                    283:        IOSleep(MII_LINK_DELAY);
                    284:        i -= MII_LINK_DELAY;
                    285:     }
                    286:     return NO;
                    287: }
                    288: 
                    289: - (BOOL)miiWaitForAutoNegotiation:(unsigned char)phy
                    290: {
                    291:     int i = MII_LINK_TIMEOUT;
                    292:     unsigned short mii_status;
                    293:        
                    294:     while (i > 0) 
                    295:     {
                    296:        if ([self miiReadWord:&mii_status reg:MII_STATUS phy:phy] == NO)
                    297:                return NO;
                    298:                
                    299:        if (mii_status & MII_STATUS_NEGOTIATION_COMPLETE)
                    300:                return YES;
                    301:                
                    302:        IOSleep(MII_LINK_DELAY);
                    303:        i -= MII_LINK_DELAY;
                    304:     }
                    305:     return NO;
                    306: }
                    307: 
                    308: - (void)miiRestartAutoNegotiation:(unsigned char)phy
                    309: {
                    310:     unsigned short mii_control;
                    311: 
                    312:     [self miiReadWord:&mii_control reg:MII_CONTROL phy:phy];
                    313:     mii_control |= MII_CONTROL_RESTART_NEGOTIATION;
                    314:     [self miiWriteWord:mii_control reg:MII_CONTROL phy:phy];
                    315: 
                    316:     /*
                    317:      * If the system is not connected to the network, then auto-negotiation
                    318:      * never completes and we hang in this loop!
                    319:      */
                    320: #if 0
                    321:     while (1) 
                    322:     {
                    323:        [self miiReadWord:&mii_control reg:MII_CONTROL phy:phy];
                    324:        if ((mii_control & MII_CONTROL_RESTART_NEGOTIATION) == 0)
                    325:                break;
                    326:     }
                    327: #endif
                    328: }
                    329: 
                    330: /*
                    331:  * Find the first PHY device on the MII interface.
                    332:  *
                    333:  * Return
                    334:  *     YES             PHY found 
                    335:  *     NO              PHY not found
                    336:  */
                    337: - (BOOL)miiFindPHY:(unsigned char *)phy
                    338: {
                    339:     int i;
                    340:        
                    341:     *phy = -1;
                    342: 
                    343:     // The first two PHY registers are required.
                    344:     //
                    345:     for (i = 0; i < MII_MAX_PHY; i++) 
                    346:     {
                    347:        if ([self miiReadWord:NULL reg:MII_STATUS phy:i] &&
                    348:                [self miiReadWord:NULL reg:MII_CONTROL phy:i])
                    349:                break;
                    350:     }
                    351:        
                    352:     if (i >= MII_MAX_PHY)
                    353:        return NO;
                    354: 
                    355:     *phy = i;
                    356: 
                    357:     return YES;
                    358: }
                    359: 
                    360: /*
                    361:  *
                    362:  *
                    363:  */
                    364: - (BOOL)miiInitializePHY:(unsigned char)phy
                    365: {
                    366:     u_int16_t          phyWord; 
                    367: 
                    368:     // Clear enable auto-negotiation bit
                    369:     //
                    370:     [self miiReadWord:&phyWord reg:MII_CONTROL phy:phy];
                    371:     phyWord &= ~MII_CONTROL_AUTONEGOTIATION;
                    372:     [self miiWriteWord:phyWord reg:MII_CONTROL phy:phy];
                    373: 
                    374:     // Advertise 10/100 Half/Full duplex capable to link partner
                    375:     //
                    376:     [self miiReadWord:&phyWord reg:MII_ADVERTISEMENT phy:phy];
                    377:     phyWord |= (MII_ANAR_100BASETX_FD | MII_ANAR_100BASETX |
                    378:                 MII_ANAR_10BASET_FD   | MII_ANAR_10BASET );
                    379:     [self miiWriteWord:phyWord reg:MII_ADVERTISEMENT phy:phy];
                    380: 
                    381:     // Set enable auto-negotiation bit
                    382:     //
                    383:     [self miiReadWord:&phyWord reg:MII_CONTROL phy:phy];
                    384:     phyWord |= MII_CONTROL_AUTONEGOTIATION;
                    385:     [self miiWriteWord:phyWord reg:MII_CONTROL phy:phy];
                    386: 
                    387:     [self miiRestartAutoNegotiation:phy];
                    388: 
                    389:     return YES;
                    390: }        
                    391: 
                    392: @end
                    393: 

unix.superglobalmegacorp.com

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