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

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