Annotation of XNU/iokit/Drivers/network/drvPPCUniN/UniNEnetMII.cpp, 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:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: 
                     23: /*
                     24:  * Copyright (c) 1998-1999 by Apple Computer, Inc., All rights reserved.
                     25:  *
                     26:  * MII/PHY (National Semiconductor DP83840/DP83840A) support methods.
                     27:  * It is general enough to work with most MII/PHYs.
                     28:  *
                     29:  * HISTORY
                     30:  *
                     31:  */
                     32: #include "UniNEnetPrivate.h"
                     33: 
                     34: 
                     35: /*
                     36:  * Read from MII/PHY registers.
                     37:  */
                     38: bool UniNEnet::miiReadWord( UInt16 *dataPtr, UInt16 reg, UInt8 phy )
                     39: {
                     40:     UInt32              i;
                     41:     UInt32              miiReg;
                     42: 
                     43:     WriteUniNRegister( ioBaseEnet, kGEMMIFFrame, 0x01 * kGEMMIFFrame_StartFrameBit      |
                     44:                                                  0x02 * kGEMMIFFrame_OpcodeBit          |
                     45:                                                  phy  * kGEMMIFFrame_PhyAddrBit         |
                     46:                                                  reg  * kGEMMIFFrame_RegAddrBit         |
                     47:                                                         kGEMMIFFrame_TurnAroundMSB              );
                     48: 
                     49:     for (i=0; i < 20; i++ )
                     50:     {     
                     51:         miiReg = ReadUniNRegister( ioBaseEnet, kGEMMIFFrame );
                     52: 
                     53:         if ( miiReg & kGEMMIFFrame_TurnAroundLSB )
                     54:         {
                     55: //            IOLog("Phy = %d Reg = %d miiReg = %08x\n\r", phy, reg, miiReg );
                     56:             *dataPtr = (UInt16) miiReg;
                     57:             return true;
                     58:         }
                     59:         IODelay(10);
                     60:     }
                     61: 
                     62:     return false;
                     63: }
                     64: 
                     65: /*
                     66:  * Write to MII/PHY registers.
                     67:  */
                     68: bool UniNEnet::miiWriteWord( UInt16 data, UInt16 reg, UInt8 phy )
                     69: {
                     70:     UInt32              i;
                     71:     UInt32              miiReg;
                     72: 
                     73: 
                     74:     WriteUniNRegister( ioBaseEnet, kGEMMIFFrame, 0x01 * kGEMMIFFrame_StartFrameBit       |
                     75:                                                  0x01 * kGEMMIFFrame_OpcodeBit          |
                     76:                                                  phy  * kGEMMIFFrame_PhyAddrBit         |
                     77:                                                  reg  * kGEMMIFFrame_RegAddrBit         |
                     78:                                                         kGEMMIFFrame_TurnAroundMSB      |
                     79:                                                  data                                     );
                     80: 
                     81:     for ( i=0; i < 20; i++ )
                     82:     {     
                     83:         miiReg = ReadUniNRegister( ioBaseEnet, kGEMMIFFrame );
                     84:         
                     85:         if ( miiReg & kGEMMIFFrame_TurnAroundLSB )
                     86:         {
                     87:             return true;
                     88:         }
                     89:         IODelay(10);
                     90:     }
                     91: 
                     92:     return false;
                     93: }
                     94: 
                     95: 
                     96: bool UniNEnet::miiResetPHY( UInt8 phy )
                     97: {
                     98:     int                i = MII_RESET_TIMEOUT;
                     99:     UInt16             mii_control;
                    100: 
                    101:     // Set the reset bit
                    102:     //
                    103:     miiWriteWord( MII_CONTROL_RESET, MII_CONTROL, phy );
                    104:         
                    105:     IOSleep(MII_RESET_DELAY);
                    106: 
                    107:     // Wait till reset process is complete (MII_CONTROL_RESET returns to zero)
                    108:     //
                    109:     while ( i > 0 ) 
                    110:     {
                    111:         if ( miiReadWord( &mii_control, MII_CONTROL, phy) == false )
                    112:                 return false;
                    113: 
                    114:         if (!(mii_control & MII_CONTROL_RESET))
                    115:         {
                    116:             miiReadWord( &mii_control, MII_CONTROL, phy);
                    117:             mii_control &= ~MII_CONTROL_ISOLATE;
                    118:             miiWriteWord( mii_control, MII_CONTROL, phy );
                    119:             return true;
                    120:         }
                    121: 
                    122:         IOSleep(MII_RESET_DELAY);
                    123:         i -= MII_RESET_DELAY;
                    124:     }
                    125:     return false;
                    126: }
                    127: 
                    128: bool UniNEnet::miiWaitForLink( UInt8 phy )
                    129: {
                    130:     int i = MII_LINK_TIMEOUT;
                    131:     unsigned short mii_status;
                    132:         
                    133:     while (i > 0) 
                    134:     {
                    135:         if ( miiReadWord( &mii_status, MII_STATUS, phy ) == false)
                    136:                 return false;
                    137:                 
                    138:         if (mii_status & MII_STATUS_LINK_STATUS)
                    139:                 return true;
                    140:                 
                    141:         IOSleep(MII_LINK_DELAY);
                    142:         i -= MII_LINK_DELAY;
                    143:     }
                    144:     return false;
                    145: }
                    146: 
                    147: bool UniNEnet::miiWaitForAutoNegotiation( UInt8 phy )
                    148: {
                    149:     int i = MII_LINK_TIMEOUT;
                    150:     unsigned short mii_status;
                    151:         
                    152:     while (i > 0) 
                    153:     {
                    154:         if ( miiReadWord( &mii_status, MII_STATUS, phy ) == false)
                    155:                 return false;
                    156:                 
                    157:         if (mii_status & MII_STATUS_NEGOTIATION_COMPLETE)
                    158:                 return true;
                    159:                 
                    160:         IOSleep(MII_LINK_DELAY);
                    161:         i -= MII_LINK_DELAY;
                    162:     }
                    163:     return false;
                    164: }
                    165: 
                    166: void UniNEnet::miiRestartAutoNegotiation( UInt8 phy )
                    167: {
                    168:     unsigned short mii_control;
                    169: 
                    170:     miiReadWord( &mii_control, MII_CONTROL, phy);
                    171:     mii_control |= MII_CONTROL_RESTART_NEGOTIATION;
                    172:     miiWriteWord( mii_control, MII_CONTROL, phy);
                    173: 
                    174:     /*
                    175:      * If the system is not connected to the network, then auto-negotiation
                    176:      * never completes and we hang in this loop!
                    177:      */
                    178: #if 0
                    179:     while (1) 
                    180:     {
                    181:         miiReadWord( &mii_control, MII_CONTROL, phy );
                    182:         if ((mii_control & MII_CONTROL_RESTART_NEGOTIATION) == 0)
                    183:                 break;
                    184:     }
                    185: #endif
                    186: }
                    187: 
                    188: /*
                    189:  * Find the first PHY device on the MII interface.
                    190:  *
                    191:  * Return
                    192:  *      true             PHY found 
                    193:  *      false            PHY not found
                    194:  */
                    195: bool UniNEnet::miiFindPHY( UInt8 *phy )
                    196: {
                    197:     int         i;
                    198:     UInt16      phyWord[2];
                    199:         
                    200:     *phy = 0xff;
                    201: 
                    202:     // The first two PHY registers are required.
                    203:     //
                    204:     for (i = 0; i < MII_MAX_PHY; i++) 
                    205:     {        
                    206:         if ( miiReadWord( &phyWord[0], MII_STATUS, i ) == false )
                    207:         {
                    208:             continue;
                    209:         }
                    210:         if ( miiReadWord( &phyWord[1], MII_CONTROL, i ) == false )
                    211:         {
                    212:             continue;
                    213:         }
                    214:         if ( phyWord[0] == 0xffff && phyWord[1] == 0xffff )
                    215:         {
                    216:             continue;
                    217:         }
                    218:     
                    219:         if ( *phy == 0xff ) *phy = i;
                    220:     }
                    221:         
                    222:     return (*phy == 0xff) ? false : true;
                    223: }
                    224: 
                    225: /*
                    226:  *
                    227:  *
                    228:  */
                    229: bool UniNEnet::miiInitializePHY( UInt8 phy )
                    230: {
                    231:     UInt16           phyWord; 
                    232: 
                    233:    // Clear enable auto-negotiation bit
                    234:     //
                    235:     miiReadWord( &phyWord, MII_CONTROL, phy );
                    236:     phyWord &= ~MII_CONTROL_AUTONEGOTIATION;
                    237:     miiWriteWord( phyWord, MII_CONTROL, phy );
                    238: 
                    239:     // Advertise 10/100 Half/Full duplex capable to link partner
                    240:     //
                    241:     miiReadWord( &phyWord, MII_ADVERTISEMENT, phy );
                    242:     phyWord |= (MII_ANAR_100BASETX_FD | MII_ANAR_100BASETX |
                    243:                 MII_ANAR_10BASET_FD   | MII_ANAR_10BASET );
                    244:     miiWriteWord( phyWord, MII_ADVERTISEMENT, phy );
                    245: 
                    246:     // Set enable auto-negotiation bit
                    247:     //
                    248:     miiReadWord( &phyWord, MII_CONTROL, phy );
                    249:     phyWord |= MII_CONTROL_AUTONEGOTIATION;
                    250:     miiWriteWord( phyWord, MII_CONTROL, phy );
                    251: 
                    252:     miiRestartAutoNegotiation( phy );
                    253: 
                    254:     return true;
                    255: }        
                    256: 
                    257: 

unix.superglobalmegacorp.com

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