|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.