|
|
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.