[processor-sdk/performance-audio-sr.git] / pdk_k2g_1_0_1_0_eng / packages / ti / board / src / skAM335x / device / enet_phy.c
1 /**
2 * enet_phy.c
3 */
5 /*
6 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
19 * distribution.
20 *
21 * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
39 #include <stdio.h>
40 #include <ti/csl/cslr_mdio.h>
41 #include <ti/csl/src/ip/mdio/V2/cslr_mdio.h>
42 #include <ti/csl/csl_mdio.h>
43 #include <ti/csl/src/ip/mdio/V2/csl_mdio.h>
44 #include <ti/csl/csl_mdioAux.h>
45 #include <ti/csl/src/ip/mdio/V2/csl_mdioAux.h>
46 #include <ti/board/src/skAM335x/device/enet_phy.h>
48 /* UART Header files */
49 #include <ti/drv/uart/UART.h>
50 #include <ti/drv/uart/src/UART_osal.h>
51 #include <ti/drv/uart/UART_stdio.h>
53 /* R A N D O M N U M B E R S U P P O R T */
54 #define COMMON_RANDOM_MAX 0xFFFFu
56 /* Enable the below macro to have prints on the IO Console */
57 //#define IO_CONSOLE
59 #ifndef IO_CONSOLE
60 #define ENET_PHY_log UART_printf
61 #else
62 #define ENET_PHY_log printf
63 #endif
65 static Uint32 RandomSeed = 1u;
67 static Uint32 cpswRandom(void)
68 {
69 RandomSeed = (RandomSeed * (1103515245u)) + (12345u);
70 return ((Uint32) (RandomSeed/(65536u)) % (COMMON_RANDOM_MAX + 1u));
71 }
74 static Uint32 cpswRandomRange(Uint32 min, Uint32 max)
75 {
76 Uint32 iTmp;
78 iTmp = cpswRandom();
79 iTmp %= ((max - min) + 1u);
80 iTmp += min;
81 return(iTmp);
82 }
84 static void _ENETPHY_DisablePhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum);
85 static void _ENETPHY_PhyTimeOut(ENETPHY_Handle hPhyDev);
86 static void _ENETPHY_ResetPhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum);
89 static void _ENETPHY_DefaultState (ENETPHY_Handle hPhyDev);
90 static void _ENETPHY_FindingState (ENETPHY_Handle hPhyDev);
91 static void _ENETPHY_FoundState (ENETPHY_Handle hPhyDev);
92 static void _ENETPHY_InitState (ENETPHY_Handle hPhyDev);
93 static void _ENETPHY_LinkedState (ENETPHY_Handle hPhyDev);
94 static void _ENETPHY_LinkWaitState (ENETPHY_Handle hPhyDev);
95 static void _ENETPHY_LoopbackState (ENETPHY_Handle hPhyDev);
96 static void _ENETPHY_NwayStartState(ENETPHY_Handle hPhyDev);
97 static void _ENETPHY_NwayWaitState (ENETPHY_Handle hPhyDev);
99 #define _cpswIsGigPhy(hPhyDev) (TRUE)
101 #define ENETPHY_NOT_FOUND 0xFFFFu /* Used in Phy Detection */
103 /*CHECK:: PhyState field breakup */
104 #define ENETPHY_DEV_OFFSET (0u)
105 #define ENETPHY_DEV_SIZE (5u)
106 #define ENETPHY_DEV_MASK (0x1f<<ENETPHY_DEV_OFFSET)
108 #define ENETPHY_STATE_OFFSET (ENETPHY_DEV_SIZE+ENETPHY_DEV_OFFSET)
109 #define ENETPHY_STATE_SIZE (5u)
110 #define ENETPHY_STATE_MASK (0x1fu<<ENETPHY_STATE_OFFSET)
111 #define INIT (1u<<ENETPHY_STATE_OFFSET)
112 #define FINDING (2u<<ENETPHY_STATE_OFFSET)
113 #define FOUND (3u<<ENETPHY_STATE_OFFSET)
114 #define NWAY_START (4u<<ENETPHY_STATE_OFFSET)
115 #define NWAY_WAIT (5u<<ENETPHY_STATE_OFFSET)
116 #define LINK_WAIT (6u<<ENETPHY_STATE_OFFSET)
117 #define LINKED (7u<<ENETPHY_STATE_OFFSET)
118 #define LOOPBACK (8u<<ENETPHY_STATE_OFFSET)
120 #define ENETPHY_SPEED_OFFSET (ENETPHY_STATE_OFFSET+ENETPHY_STATE_SIZE)
121 #define ENETPHY_SPEED_SIZE (1u)
122 #define ENETPHY_SPEED_MASK_NDK (1u<<ENETPHY_SPEED_OFFSET)
124 #define ENETPHY_DUPLEX_OFFSET (ENETPHY_SPEED_OFFSET+ENETPHY_SPEED_SIZE)
125 #define ENETPHY_DUPLEX_SIZE (1u)
126 #define ENETPHY_DUPLEX_MASK (1u<<ENETPHY_DUPLEX_OFFSET)
128 #define ENETPHY_TIM_OFFSET (ENETPHY_DUPLEX_OFFSET+ENETPHY_DUPLEX_SIZE)
129 #define ENETPHY_TIM_SIZE (10u)
130 #define ENETPHY_TIM_MASK (0x3ffu<<ENETPHY_TIM_OFFSET)
132 /* we are working with 100ms ticks here */
133 #define ENETPHY_FIND_TO ( 1u<<ENETPHY_TIM_OFFSET)
134 #define ENETPHY_RECK_TO (20u<<ENETPHY_TIM_OFFSET)
135 #define ENETPHY_LINK_TO (50u<<ENETPHY_TIM_OFFSET)
136 #define ENETPHY_NWST_TO (50u<<ENETPHY_TIM_OFFSET)
137 #define ENETPHY_NWDN_TO (80u<<ENETPHY_TIM_OFFSET)
138 #define ENETPHY_MDIX_TO (27u<<ENETPHY_TIM_OFFSET) /* 2.74 Seconds <--Spec and empirical */
140 #define ENETPHY_SMODE_OFFSET (ENETPHY_TIM_OFFSET+ENETPHY_TIM_SIZE)
141 #define ENETPHY_SMODE_SIZE (7u)
142 #define ENETPHY_SMODE_MASK (0x7fu<<ENETPHY_SMODE_OFFSET)
143 #define SMODE_LPBK (0x40u<<ENETPHY_SMODE_OFFSET)
144 #define SMODE_AUTO (0x20u<<ENETPHY_SMODE_OFFSET)
145 #define SMODE_FD1000 (0x10u<<ENETPHY_SMODE_OFFSET)
146 #define SMODE_FD100 (0x08u<<ENETPHY_SMODE_OFFSET)
147 #define SMODE_HD100 (0x04u<<ENETPHY_SMODE_OFFSET)
148 #define SMODE_FD10 (0x02u<<ENETPHY_SMODE_OFFSET)
149 #define SMODE_HD10 (0x01u<<ENETPHY_SMODE_OFFSET)
150 #define SMODE_ALL (0x1fu<<ENETPHY_SMODE_OFFSET)
152 #define ENETPHY_CHNG_OFFSET (ENETPHY_SMODE_OFFSET+ENETPHY_SMODE_SIZE)
153 #define ENETPHY_CHNG_SIZE (1u)
154 #define ENETPHY_CHNG_MASK (1u<<ENETPHY_CHNG_OFFSET)
155 #define ENETPHY_CHANGE (1u<<ENETPHY_CHNG_OFFSET)
157 #define ENETPHY_TIMEDOUT_OFFSET (ENETPHY_CHNG_OFFSET+ENETPHY_CHNG_SIZE)
158 #define ENETPHY_TIMEDOUT_SIZE (1u) /* 30 Bits used */
159 #define ENETPHY_TIMEDOUT_MASK ((Uint32)(1u<<ENETPHY_TIMEDOUT_OFFSET))
160 #define ENETPHY_MDIX_SWITCH ((Uint32)(1u<<ENETPHY_TIMEDOUT_OFFSET))
162 #define ENETPHY_MDIX_OFFSET (ENETPHY_TIMEDOUT_OFFSET+ENETPHY_TIMEDOUT_SIZE)
163 #define ENETPHY_MDIX_SIZE (1u) /* 31 Bits used */
164 #define ENETPHY_MDIX_MASK ((Uint32)(1u<<ENETPHY_MDIX_OFFSET))
165 #define ENETPHY_MDIX ((Uint32)(1u<<ENETPHY_MDIX_OFFSET))
168 #ifndef VOLATILE32
169 #define VOLATILE32(addr) (*((volatile Uint32 *)(addr)))
170 #endif
172 Int32 cpsw_g_speed_set = 0;
173 Int32 cpsw_g_soft_reset_status = 0;
175 /*User Calls********************************************************* */
177 /* Updates book-keeping with info provided, programs ControlReg
178 * with clkdiv,enable bits*/
179 int ENETPHY_Init(ENETPHY_Handle hPhyDev, Uint32 miibase, Uint32 inst, Uint32 PhyMask, Uint32 MLinkMask, Uint32 MdixMask, Uint32 PhyAddr, Uint32 ResetBit, Uint32 MdioBusFreq, Uint32 MdioClockFreq,int verbose)
180 {
181 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
183 Int32 ret =0 ;
184 Uint32 phy;
186 ((ENETPHY_DEVICE *) hPhyDev)->miibase = miibase;
187 ((ENETPHY_DEVICE *) hPhyDev)->inst = inst;
188 ((ENETPHY_DEVICE *) hPhyDev)->PhyMask = PhyMask;
189 ((ENETPHY_DEVICE *) hPhyDev)->MLinkMask = MLinkMask;
190 ((ENETPHY_DEVICE *) hPhyDev)->MdixMask = MdixMask;
192 (void)verbose;/* remove if not required */
194 *PhyState &= ~ENETPHY_MDIX_MASK; /* Set initial State to MDI */
196 CSL_MDIO_setClkDivVal((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, (MdioBusFreq/MdioClockFreq - 1));
197 CSL_MDIO_enableFaultDetect((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
198 CSL_MDIO_disablePreamble((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
199 CSL_MDIO_enableStateMachine((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
201 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_CNTRL_REG, PhyAddr, &phy);
202 phy |= NWAY_AUTOMDIX_ENABLE;
203 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_CNTRL_REG,PhyAddr,phy);
205 (void)ResetBit; /* suppress warning */
207 *PhyState=INIT;
209 ret = 0;
211 return ret;
212 }/* end of function ENETPHY_Init*/
214 void ENETPHY_SetPhyMode(ENETPHY_Handle hPhyDev,Uint32 PhyMode)
215 {
216 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
217 Uint32 CurrentState;
219 ((ENETPHY_DEVICE *) hPhyDev)->PhyMode = PhyMode; /* used for AUTOMIDX, planned to replace PhyState fields */
220 *PhyState &= (~ENETPHY_SMODE_MASK);
222 if (0u != (PhyMode & NWAY_LPBK))
223 {
224 *PhyState |= SMODE_LPBK;
225 }
226 if (0u != (PhyMode & NWAY_AUTO))
227 {
228 *PhyState |= SMODE_AUTO;
229 }
230 if (0u != (PhyMode & NWAY_FD1000) )
231 {
232 *PhyState |= SMODE_FD1000;
233 }
234 if (0u!= (PhyMode & NWAY_FD100))
235 {
236 *PhyState |= SMODE_FD100;
237 }
238 if (0u != (PhyMode & NWAY_HD100))
239 {
240 *PhyState |= SMODE_HD100;
241 }
242 if (0u != (PhyMode & NWAY_FD10))
243 {
244 *PhyState |= SMODE_FD10;
245 }
246 if (0u != (PhyMode & NWAY_HD10))
247 {
248 *PhyState |= SMODE_HD10;
249 }
251 CurrentState = (*PhyState) & ENETPHY_STATE_MASK;
252 if ( ((CurrentState == NWAY_START)|| (CurrentState == NWAY_WAIT)) ||
253 ( ((CurrentState == LINK_WAIT) || (CurrentState == LINKED) ) || (CurrentState == LOOPBACK)) )
254 {
255 *PhyState = ( (*PhyState)&(~ENETPHY_STATE_MASK)) | (FOUND | ENETPHY_CHANGE);
256 }
258 ENET_PHY_log("SetPhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d, FD1000:%d LPBK:%d\n", PhyMode,
259 (PhyMode & NWAY_AUTO), (PhyMode & MII_NWAY_FD10),(PhyMode & MII_NWAY_HD10),(PhyMode & MII_NWAY_FD100),
260 (PhyMode & MII_NWAY_HD100), (PhyMode & NWAY_FD1000),
261 (PhyMode & NWAY_LPBK) );
263 }
265 Uint32 ENETPHY_GetPhyMode(ENETPHY_Handle hPhyDev)
266 {
267 Uint32 PhyMode =0;
268 Uint32 status_reg = 0,control_reg = 0,advertize_reg;
269 Uint32 PhyNum,j;
270 Uint32 PhyMask = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
272 PhyNum = 0;
273 for(j = 1;PhyNum < 32;PhyNum++)
274 {
275 if( 0u != ( j & PhyMask))
276 {
277 break;
278 }
279 j = j<<1;
280 }
282 if(0u != _cpswIsGigPhy(hPhyDev))
283 {
284 /* read gig status */
285 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, &control_reg);
286 /* read gig status */
287 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_STATUS, PhyNum, &status_reg);
288 }
289 /* figure out if gig connected at FD 1000 or not first */
290 if ((0u != (control_reg & MII_NWAY_MY_FD1000)) && (0u != (status_reg & MII_NWAY_REM_FD1000)) )
291 {
292 PhyMode |= NWAY_FD1000;
293 }
295 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &control_reg);
296 if(0u != (control_reg & MII_AUTO_NEGOTIATE_EN) )
297 {
298 PhyMode |= NWAY_AUTO;
299 }
300 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &status_reg);
301 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, &advertize_reg);
303 /* Check for 10/100 capabilities of PHYs */
304 if((0u != (control_reg & MII_ENETPHY_100))|| (0u != (PhyMode & NWAY_AUTO)) )
305 {
306 if(0u != (advertize_reg & MII_NWAY_FD100))
307 {
308 PhyMode |= NWAY_FD100;
309 }
310 if(0u != (advertize_reg & MII_NWAY_HD100))
311 {
312 PhyMode |= NWAY_HD100;
313 }
315 }
317 if(((control_reg & MII_ENETPHY_100) == 0) || (0u != (PhyMode & NWAY_AUTO)) )
318 {
319 if(0u != (advertize_reg & MII_NWAY_FD10))
320 {
321 PhyMode |= NWAY_FD10;
322 }
323 if(0u != (advertize_reg & MII_NWAY_HD10))
324 {
325 PhyMode |= NWAY_HD10;
326 }
328 }
329 return PhyMode;
330 }
331 /* ENETPHY_Tic is called every 10 mili seconds to process Phy states */
333 int ENETPHY_Tic(ENETPHY_Handle hPhyDev,Uint32* mdioStatus)
334 {
335 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
336 Uint32 CurrentState;
337 Int32 ret = 0;
339 *mdioStatus = MDIO_EVENT_NOCHANGE;
341 /*Act on current state of the Phy */
342 CurrentState=*PhyState;
343 switch(CurrentState&ENETPHY_STATE_MASK)
344 {
345 case INIT: _ENETPHY_InitState(hPhyDev); break;
346 case FINDING: _ENETPHY_FindingState(hPhyDev); break;
347 case FOUND: _ENETPHY_FoundState(hPhyDev); break;
348 case NWAY_START: _ENETPHY_NwayStartState(hPhyDev); break;
349 case NWAY_WAIT: _ENETPHY_NwayWaitState(hPhyDev); break;
350 case LINK_WAIT: _ENETPHY_LinkWaitState(hPhyDev); break;
351 case LINKED: _ENETPHY_LinkedState(hPhyDev); break;
352 case LOOPBACK: _ENETPHY_LoopbackState(hPhyDev); break;
353 default: _ENETPHY_DefaultState(hPhyDev); break;
354 }
356 /* Check is MDI/MDIX mode switch is needed */
358 if(0u != ((*PhyState) & ENETPHY_MDIX_SWITCH) )
359 {
361 Uint32 Mdix;
363 *PhyState &= (~ENETPHY_MDIX_SWITCH); /* Clear Mdix Flip indicator */
365 if(0u != ((*PhyState) & ENETPHY_MDIX))
366 {
367 Mdix = 1;
368 }
369 else
370 {
371 Mdix = 0;
372 }
373 ret = (Int32)(_MIIMDIO_MDIXFLIP | Mdix);
375 }
376 else
377 {
379 /*Return state change to user */
380 /** CHECK : report MDIO_LINKEVENTS as MDIO_EVENT_NOCHANGE, MDIO_EVENT_LINKDOWN,
381 * MDIO_EVENT_PHYERROR,MDIO_EVENT_LINKUP
382 * Currently ENETPHY_CHNG_MASK set for any state transition*/
384 if (0u != ((*PhyState) & ENETPHY_CHNG_MASK))
385 {
386 if( ( ((*PhyState) & ENETPHY_STATE_MASK) == LINKED) && ((CurrentState & ENETPHY_STATE_MASK) != LINKED) )
387 {
388 /* we have just entered LInked state */
389 *mdioStatus = MDIO_EVENT_LINKUP;
390 }
391 if( ((CurrentState & ENETPHY_STATE_MASK) == LINKED) && ( ( (*PhyState) & ENETPHY_STATE_MASK) != LINKED))
392 {
393 /* we started in Linked state and we have a state change */
394 *mdioStatus = MDIO_EVENT_LINKDOWN;
395 }
396 *PhyState &= (~ENETPHY_CHNG_MASK);
397 ret = (Int32)(TRUE);
398 }
399 else
400 {
401 ret = (Int32)(FALSE);
402 }
403 }
405 return ret;
407 }
410 void ENETPHY_LinkChange(ENETPHY_Handle hPhyDev)
411 {
412 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
413 Uint32 PhyNum,PhyStatus;
415 PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
417 ENET_PHY_log("ENETPHY_LinkChange: PhyNum = %d\n", PhyNum);
419 if (0u != (ENETPHY_GetLinked(hPhyDev)) )
420 {
421 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
423 if ((PhyStatus & MII_ENETPHY_LINKED) == 0u)
424 {
425 *PhyState &= (~(ENETPHY_TIM_MASK | ENETPHY_STATE_MASK));
426 if (0u!=((*PhyState) & SMODE_AUTO))
427 {
428 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN|MII_RENEGOTIATE);
429 *PhyState |= ((ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
430 }
431 else
432 {
433 *PhyState|= ((ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
434 }
435 }
436 }
437 }
439 /* returns 0 if current Phy has AutoMdix support, otherwise 0 */
440 static int _ENETPHY_MdixSupported(ENETPHY_Handle hPhyDev)
441 {
442 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
443 Uint32 PhyNum;
444 Int32 ret;
446 if((((ENETPHY_DEVICE *) hPhyDev)->PhyMode & NWAY_AUTOMDIX) == 0)
447 {
448 ret = (0); /* AutoMdix not turned on */
449 }
450 else
451 {
452 PhyNum = ((*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
453 if( ((1<<PhyNum) & ((ENETPHY_DEVICE *) hPhyDev)->MdixMask) == 0)
454 {
455 ret = 0; /* Phy does not support AutoMdix*/
456 }
458 ret = 1;
459 }
460 return ret;
461 }
463 /* If current Phy has AutoMdix support add Mdix Delay to the Timer State Value */
464 static void _ENETPHY_MdixDelay(ENETPHY_Handle hPhyDev)
465 {
466 Uint32 Delay;
467 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
470 if(_ENETPHY_MdixSupported(hPhyDev) != 0)
471 {
472 /* Get the Delay value in milli-seconds and convert to ten-milli second value */
473 Delay = cpswRandomRange(_AUTOMDIX_DELAY_MIN, _AUTOMDIX_DELAY_MAX);
474 Delay /= 10;
476 /* Add AutoMidx Random Switch Delay to AutoMdix Link Delay */
478 Delay += (ENETPHY_MDIX_TO>>ENETPHY_TIM_OFFSET);
480 /* Change Timeout value to AutoMdix standard */
481 *PhyState &= (~(ENETPHY_TIM_MASK)); /* Clear current Time out value */
482 *PhyState |= (Delay<<ENETPHY_TIM_OFFSET); /* Set new value */
483 }
484 return;
486 }
488 void _ENETPHY_DisablePhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum)
489 {
490 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, (MII_ENETPHY_ISOLATE | MII_ENETPHY_PDOWN) );
492 ENET_PHY_log("ENETPHY_DisablePhy(%d)\n",PhyNum);
494 }
496 void _ENETPHY_InitState(ENETPHY_Handle hPhyDev)
497 {
498 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
499 Uint32 CurrentState;
501 CurrentState=*PhyState;
502 CurrentState = (CurrentState & (~ENETPHY_TIM_MASK)) | (ENETPHY_FIND_TO);
503 CurrentState=(CurrentState & (~ENETPHY_STATE_MASK)) | (FINDING);
504 CurrentState=(CurrentState & (~ENETPHY_SPEED_MASK_NDK));
505 CurrentState=(CurrentState & (~ENETPHY_DUPLEX_MASK));
506 CurrentState|=ENETPHY_CHANGE;
508 *PhyState=CurrentState;
510 }
512 void _ENETPHY_FindingState(ENETPHY_Handle hPhyDev)
513 {
514 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
515 Uint32 PhyMask = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
516 Uint32 PhyNum,i,j;
518 PhyNum=ENETPHY_NOT_FOUND;
520 if (0u!= ((*PhyState) & ENETPHY_TIM_MASK))
521 {
522 *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK) ) | (( (*PhyState) & ENETPHY_TIM_MASK) - (1 << ENETPHY_TIM_OFFSET));
523 }
524 else
525 {
526 j =1;
527 for(i=0; i<32; i++)
528 {
529 if( PhyMask & j)
530 {
531 if( CSL_MDIO_isPhyAlive((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, i))
532 {
533 PhyNum=i;
534 break;
535 }
536 }
537 j = j << 1;
538 }
539 if (PhyNum!=ENETPHY_NOT_FOUND)
540 {
541 /* Phy Found! */
542 *PhyState = ((*PhyState) & (~ENETPHY_DEV_MASK) ) | ((PhyNum & ENETPHY_DEV_MASK) << ENETPHY_DEV_OFFSET);
543 *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK) ) | (FOUND);
544 *PhyState|=ENETPHY_CHANGE;
546 ENET_PHY_log("ENETPHY_FindingState: PhyNum: %d\n",PhyNum);
548 }
549 else
550 {
552 ENET_PHY_log("ENETPHY_FindingState: Timed Out looking for a Phy!\n");
553 *PhyState|=ENETPHY_RECK_TO; /* Set Timer */
554 }
555 }
556 }
558 void _ENETPHY_FoundState(ENETPHY_Handle hPhyDev)
559 {
560 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
561 Uint32 PhyMask = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
562 Uint32 MLinkMask = ((ENETPHY_DEVICE *) hPhyDev)->MLinkMask;
563 Uint32 PhyNum,PhyStatus,NWAYadvertise,NWAY1000advertise=0,m,phynum,i,j;
564 Uint32 PhyDummy;
566 static Uint32 auto_neg1 = 0xFFFFFFFF,auto_neg2= 0xFFFFFFFF;
569 if (( (*PhyState) & ENETPHY_SMODE_MASK) == 0)
570 {
571 return;
572 }
574 PhyNum = ((*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
575 j =1;
576 for(phynum=0; phynum<32; phynum++)
577 {
578 if(0u!= (PhyMask & j))
579 {
580 if( CSL_MDIO_isPhyAlive((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, phynum))
581 {
582 _ENETPHY_DisablePhy(hPhyDev,phynum);
583 }
584 }
585 j = j << 1;
586 }
587 /* If Aries SWR2 reset then don't reset phy*/
588 /* Reset the Phy and proceed with auto-negotiation */
589 if(( 0u != cpsw_g_speed_set) || ((0u ==cpsw_g_soft_reset_status) || ((auto_neg1 & (1 << PhyNum)) == 0) ) )
590 {
591 _ENETPHY_ResetPhy(hPhyDev,PhyNum);
592 }
594 /* Set the way Link will be Monitored */
595 /* Check the Link Selection Method */
596 if (0u != ((1 << PhyNum) & MLinkMask) )
597 {
598 CSL_MDIO_enableLinkStatusChangeInterrupt((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, ((ENETPHY_DEVICE *) hPhyDev)->inst, PhyNum);
599 }
600 else
601 {
602 CSL_MDIO_disableLinkStatusChangeInterrupt((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, ((ENETPHY_DEVICE *) hPhyDev)->inst, PhyNum);
603 }
604 /* Get the Phy Status */
605 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
608 /* For Phy Internal loopback test, need to wait until Phy
609 found, then set Loopback */
610 if (0u != ((*PhyState) & SMODE_LPBK))
611 {
612 /* Set Phy in Loopback */
614 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_ENETPHY_LOOP|MII_ENETPHY_FD);
615 /* Do a read to ensure ENETPHY_LOOP has completed */
616 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyDummy);
617 *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK) ) | (LOOPBACK);
618 *PhyState|=ENETPHY_CHANGE;
619 return;
620 }
622 ENET_PHY_log("Enable Phy to negotiate external connection\n");
625 NWAYadvertise=MII_NWAY_SEL;
626 if (0u != ((*PhyState) & SMODE_FD100))
627 {
628 NWAYadvertise |= MII_NWAY_FD100;
629 }
630 if (0u != ((*PhyState) & SMODE_HD100))
631 {
632 NWAYadvertise |= MII_NWAY_HD100;
633 }
634 if (0u != ((*PhyState) & SMODE_FD10))
635 {
636 NWAYadvertise |= MII_NWAY_FD10;
637 }
638 if (0u != ((*PhyState) & SMODE_HD10))
639 {
640 NWAYadvertise |= MII_NWAY_HD10;
641 }
642 if (0u != ((*PhyState) & SMODE_FD1000))
643 {
644 NWAY1000advertise= ENETPHY_1000BT_FD;
645 }
647 *PhyState &= ( ~(ENETPHY_TIM_MASK | ENETPHY_STATE_MASK));
648 if ((0u != (PhyStatus & MII_NWAY_CAPABLE)) && (0u != ( (*PhyState) & SMODE_AUTO)) ) /*NWAY Phy Detected*/
649 {
650 if(( 0u != cpsw_g_speed_set) || ((0u ==cpsw_g_soft_reset_status) || ((auto_neg1 & (1 << PhyNum)) == 0) ) )
651 {
652 /*For NWAY compliant Phys */
653 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, NWAYadvertise);
654 /* for gig negotiation */
655 if(0u != _cpswIsGigPhy(hPhyDev))
656 {
657 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, NWAY1000advertise);
658 }
660 ENET_PHY_log("NWAY Advertising: ");
661 if (0u != ((*PhyState) & SMODE_FD1000))
662 {
663 ENET_PHY_log("FullDuplex-1000 ");
664 }
665 if (0u != (NWAYadvertise & MII_NWAY_FD100))
666 {
667 ENET_PHY_log("FullDuplex-100 ");
668 }
669 if (0u != (NWAYadvertise & MII_NWAY_HD100))
670 {
671 ENET_PHY_log("HalfDuplex-100 ");
672 }
673 if (0u != (NWAYadvertise & MII_NWAY_FD10))
674 {
675 ENET_PHY_log("FullDuplex-10 ");
676 }
677 if (0u != (NWAYadvertise & MII_NWAY_HD10))
678 {
679 ENET_PHY_log("HalfDuplex-10 ");
680 }
682 ENET_PHY_log("\n");
684 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN );
685 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN|MII_RENEGOTIATE|MII_ENETPHY_FD);
686 *PhyState|= ( (ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
687 }
688 else
689 {
690 *PhyState |= ( (ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
691 auto_neg1 = auto_neg1 & (~(1 << PhyNum));
692 }
693 }
694 else
695 {
696 *PhyState &= (~SMODE_AUTO); /*The Phy is not capable of auto negotiation! */
697 m=NWAYadvertise;
698 j = 0x8000u;
700 for(i=0;(i<16);i++)
701 {
702 if(0u != (j & m))
703 {
704 break;
705 }
706 j = j >> 1 ;
708 }
709 m=j;
710 j=0;
712 /* figure out if gig connected at FD 1000 or not first */
713 if ((NWAY1000advertise & MII_NWAY_MY_FD1000)== MII_NWAY_MY_FD1000)
714 {
715 j = MII_ENETPHY_1000;
716 j |= MII_ENETPHY_FD;
717 }
718 else
719 {
720 if (0u != (m & (MII_NWAY_FD100 | MII_NWAY_HD100)) )
721 {
722 j=MII_ENETPHY_100;
723 m&=(MII_NWAY_FD100|MII_NWAY_HD100);
724 }
725 if (0u != (m & (MII_NWAY_FD100 | MII_NWAY_FD10)) )
726 {
727 j |= MII_ENETPHY_FD;
728 }
729 }
731 ENET_PHY_log("Requested PHY mode %s Duplex %s Mbps\n",(j & MII_ENETPHY_FD) ? "Full":"Half",
732 (j & MII_ENETPHY_1000) ? "1000":((j & MII_ENETPHY_100) ? "100":"10"));
734 if((0u != cpsw_g_speed_set) || ( (0u == cpsw_g_soft_reset_status) || ((auto_neg2 & (1 << PhyNum)) == 0) ))
735 {
736 if(0u != (j & MII_ENETPHY_1000))
737 {
738 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, j);
739 }
740 else
741 {
742 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, j);
743 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, NWAYadvertise);
744 }
745 cpsw_g_speed_set = 0;
746 }
747 else
748 {
749 auto_neg2 = auto_neg2 & (~(1 << PhyNum));
750 }
751 *PhyState &= (~ENETPHY_SPEED_MASK_NDK);
752 if(0u != (j & MII_ENETPHY_1000) )
753 {
754 *PhyState|=(1<<ENETPHY_DUPLEX_OFFSET);
755 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 1;
756 }
757 else
758 {
759 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 0;
760 }
761 if (0u != (j & MII_ENETPHY_100) )
762 {
763 *PhyState|=(1<<ENETPHY_SPEED_OFFSET);
764 }
765 *PhyState &= (~ENETPHY_DUPLEX_MASK);
766 if (0u != (j & MII_ENETPHY_FD) )
767 {
768 *PhyState|=(1<<ENETPHY_DUPLEX_OFFSET);
769 }
770 *PhyState |= ((ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
771 }
772 _ENETPHY_MdixDelay(hPhyDev); /* If AutoMdix add delay */
774 }
776 void _ENETPHY_ResetPhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum)
777 {
778 Uint32 data;
780 data = MII_ENETPHY_RESET;
782 /* Reset the phy */
783 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, data);
785 /* wait till the reset bit is auto cleared */
786 while(data & MII_ENETPHY_RESET)
787 {
788 /* Read the reset */
789 if(_ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &data) != TRUE)
790 {
791 break;
792 }
793 }
795 }
797 void _ENETPHY_NwayStartState(ENETPHY_Handle hPhyDev)
798 {
799 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
800 Uint32 PhyNum,PhyMode,PhyDummy;
802 PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
804 /*Wait for Negotiation to start */
806 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &PhyMode);
808 if((PhyMode&MII_RENEGOTIATE)==0)
809 {
810 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum,&PhyDummy); /*Flush pending latch bits*/
811 *PhyState &= (~(ENETPHY_STATE_MASK|ENETPHY_TIM_MASK));
812 *PhyState |= ((ENETPHY_CHANGE | NWAY_WAIT) |ENETPHY_NWDN_TO);
813 _ENETPHY_MdixDelay(hPhyDev); /* If AutoMdix add delay */
814 }
815 else
816 {
817 if (0u != ((*PhyState) & ENETPHY_TIM_MASK) )
818 {
819 *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK)) | ( ( (*PhyState) & ENETPHY_TIM_MASK)-(1 << ENETPHY_TIM_OFFSET));
820 }
821 else
822 {
823 _ENETPHY_PhyTimeOut(hPhyDev);
824 }
825 }
826 }
828 void _ENETPHY_NwayWaitState(ENETPHY_Handle hPhyDev)
829 {
830 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
831 Uint32 PhyNum,PhyStatus,NWAYadvertise = 0,NWAYREadvertise = 0,NegMode,i,j;
832 Uint32 NWAY1000advertise = 0, NWAY1000REMadvertise = 0;
834 PhyNum=( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
836 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
838 if (0u != (PhyStatus & MII_NWAY_COMPLETE))
839 {
840 *PhyState|=ENETPHY_CHANGE;
841 *PhyState &= (~ENETPHY_SPEED_MASK_NDK);
842 *PhyState &= (~ENETPHY_DUPLEX_MASK);
844 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, &NWAYadvertise);
845 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_LINK_PARTNER_ABLTY, PhyNum, &NWAYREadvertise);
846 /* read gig status */
847 if(0u != _cpswIsGigPhy(hPhyDev))
848 {
849 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, &NWAY1000advertise);
850 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_STATUS, PhyNum, &NWAY1000REMadvertise);
851 }
853 /* figure out if gig connected at FD 1000 or not first */
854 if ((0u !=(NWAY1000advertise & MII_NWAY_MY_FD1000)) && (0u!=(NWAY1000REMadvertise & MII_NWAY_REM_FD1000)) )
855 {
856 NegMode = MII_NWAY_MY_FD1000;
857 }
858 else
859 {
860 NegMode = 0u;
861 }
863 if (NegMode == 0u)
864 {
865 /* continue checking for 100 and 10 connection */
867 /* Negotiated mode is we and the remote have in common */
868 NegMode = NWAYadvertise & NWAYREadvertise;
870 ENET_PHY_log("Phy: %d, ",( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET);
871 ENET_PHY_log("NegMode %04X, NWAYadvertise %04X, NWAYREadvertise %04X\n",
872 NegMode, NWAYadvertise, NWAYREadvertise);
874 /* Limit negotiation to fields below */
875 NegMode &= ( (MII_NWAY_FD100|MII_NWAY_HD100) | (MII_NWAY_FD10|MII_NWAY_HD10));
877 if (NegMode == 0u)
878 {
879 NegMode=(MII_NWAY_HD100|MII_NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/
880 }
882 j = 0x8000u;
883 for(i = 0; i <16 ; i++)
884 {
885 if (0u != (j & NegMode))
886 {
887 break;
888 }
889 j = j >> 1;
890 }
892 NegMode=j;
895 ENET_PHY_log("Negotiated connection: ");
898 if (0u != (NegMode & MII_NWAY_FD100))
899 {
900 ENET_PHY_log("FullDuplex 100 Mbs\n");
901 }
902 if (0u != (NegMode & MII_NWAY_HD100))
903 {
904 ENET_PHY_log("HalfDuplex 100 Mbs\n");
905 }
906 if (0u != (NegMode & MII_NWAY_FD10))
907 {
908 ENET_PHY_log("FullDuplex 10 Mbs\n");
909 }
910 if (0u != (NegMode & MII_NWAY_HD10))
911 {
912 ENET_PHY_log("HalfDuplex 10 Mbs\n");
913 }
915 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 0u;
916 }
917 else
918 {
920 /* found 1000 negotiated connection! */
921 ENET_PHY_log("Negotiated connection: ");
922 ENET_PHY_log("FullDuplex 1000 Mbs\n");
924 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 1u;
925 }
927 if (NegMode != 0u)
928 {
929 if (0u != (PhyStatus & MII_ENETPHY_LINKED))
930 {
931 *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK)) | LINKED;
932 }
933 else
934 {
935 *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK)) | LINK_WAIT;
936 }
937 if (0u != (NegMode & (MII_NWAY_FD100 | MII_NWAY_HD100)) )
938 {
939 *PhyState=( (*PhyState) & (~ENETPHY_SPEED_MASK_NDK)) | (1 << ENETPHY_SPEED_OFFSET);
940 }
941 if (0u != (NegMode & (MII_NWAY_FD100 | MII_NWAY_FD10 | MII_NWAY_MY_FD1000)))
942 {
943 *PhyState=( (*PhyState) & (~ENETPHY_DUPLEX_MASK)) | (1 << ENETPHY_DUPLEX_OFFSET);
944 }
945 }
946 }
947 else
948 {
949 if ( 0u != ( (*PhyState) & ENETPHY_TIM_MASK) )
950 {
951 *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK)) | (( (*PhyState) & ENETPHY_TIM_MASK)-(1 << ENETPHY_TIM_OFFSET));
952 }
953 else
954 {
955 _ENETPHY_PhyTimeOut(hPhyDev);
956 }
957 }
959 }
961 void _ENETPHY_LinkWaitState(ENETPHY_Handle hPhyDev)
962 {
963 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
964 Uint32 PhyStatus;
965 Uint32 PhyNum;
967 PhyNum=( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
969 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
971 if (0u != (PhyStatus & MII_ENETPHY_LINKED) )
972 {
973 *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK) ) | LINKED;
974 *PhyState|=ENETPHY_CHANGE;
975 }
976 else
977 {
978 if (0u != ( (*PhyState) & ENETPHY_TIM_MASK) )
979 {
980 *PhyState=(*PhyState&~ENETPHY_TIM_MASK)|((*PhyState&ENETPHY_TIM_MASK)-(1<<ENETPHY_TIM_OFFSET));
981 }
982 else
983 {
984 _ENETPHY_PhyTimeOut(hPhyDev);
985 }
986 }
987 }
989 void _ENETPHY_PhyTimeOut(ENETPHY_Handle hPhyDev)
990 {
991 Uint32 *PhyState;
992 if(_ENETPHY_MdixSupported(hPhyDev) == 0)
993 {
994 return; /* AutoMdix not supported */
995 }
996 PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
998 /* Indicate MDI/MDIX mode switch is needed */
999 *PhyState|=ENETPHY_MDIX_SWITCH;
1001 /* Toggle the MDIX mode indicatir */
1002 if(0u != ( (*PhyState) & ENETPHY_MDIX) )
1003 {
1004 *PhyState &= (~ENETPHY_MDIX_MASK); /* Current State is MDIX, set to MDI */
1005 }
1006 else
1007 {
1008 *PhyState |= ENETPHY_MDIX_MASK; /* Current State is MDI, set to MDIX */
1009 }
1010 /* Reset state machine to FOUND */
1011 *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK)) | (FOUND);
1012 }
1014 void _ENETPHY_LoopbackState(ENETPHY_Handle hPhyDev)
1015 {
1016 (void)((ENETPHY_DEVICE *) hPhyDev); /* remove if not needed, to avoid warning */
1017 return;
1018 }
1020 void _ENETPHY_LinkedState(ENETPHY_Handle hPhyDev)
1021 {
1022 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1023 Uint32 PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
1025 if (CSL_MDIO_isPhyLinked((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, PhyNum))
1026 {
1027 return; /* if still Linked, exit*/
1028 }
1030 /* Not Linked */
1031 *PhyState &= (~(ENETPHY_STATE_MASK | ENETPHY_TIM_MASK));
1032 if (0u != ( (*PhyState) & SMODE_AUTO) )
1033 {
1034 *PhyState |= ( (ENETPHY_CHANGE | NWAY_WAIT) | ENETPHY_NWDN_TO);
1035 }
1036 else
1037 {
1038 *PhyState |= ( (ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
1039 }
1040 _ENETPHY_MdixDelay(hPhyDev); /* If AutoMdix add delay */
1042 }
1044 void _ENETPHY_DefaultState(ENETPHY_Handle hPhyDev)
1045 {
1046 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1047 /*Awaiting a ENETPHY_Init call */
1048 *PhyState|=ENETPHY_CHANGE;
1049 }
1051 /* Simple Query Functions for reporting speed,duplex */
1052 /* ENETPHY_GetDuplex is called to retrieve the Duplex info */
1053 int ENETPHY_GetDuplex(ENETPHY_Handle hPhyDev)
1054 {
1055 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1056 return(( (*PhyState) & ENETPHY_DUPLEX_MASK) ? 1:0); /* return 0 or a 1 */
1057 }
1059 /* ENETPHY_GetSpeed is called to retreive the Speed info */
1060 int ENETPHY_GetSpeed(ENETPHY_Handle hPhyDev)
1061 {
1062 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1063 Int32 ret = 0 ;
1065 if (((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 == 1)
1066 {
1067 ret = 2; /* if we are linked at 1000, we return a value of 2 */
1068 }
1069 else
1070 {
1071 ret = ( (*PhyState) & ENETPHY_SPEED_MASK_NDK);
1072 }
1074 return ret;
1075 }
1077 /* ENETPHY_GetPhyNum is called to retreive the Phy Device Adr info*/
1078 int ENETPHY_GetPhyNum(ENETPHY_Handle hPhyDev)
1079 {
1080 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1081 return((Int32)(( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET));
1082 }
1084 /* ENETPHY_GetLoopback is called to Determine if the LOOPBACK state has been reached*/
1085 int ENETPHY_GetLoopback(ENETPHY_Handle hPhyDev)
1086 {
1087 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1088 return(( (*PhyState) & ENETPHY_STATE_MASK) == LOOPBACK);
1089 }
1091 /* ENETPHY_GetLinked is called to Determine if the LINKED state has been reached*/
1092 int ENETPHY_GetLinked(ENETPHY_Handle hPhyDev)
1093 {
1094 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1095 return (( (*PhyState) & ENETPHY_STATE_MASK) == LINKED);
1096 }
1098 /************************************
1099 ***
1100 *** Waits for MDIO_USERACCESS to be ready and reads data
1101 *** If 'WaitForData' set, waits for read to complete and returns Data,
1102 *** otherwise returns 0
1103 *** Note: 'data' is 16 bits but we use 32 bits
1104 *** to be consistent with rest of the code.
1105 ***
1106 **************************************/
1107 Uint32 _ENETPHY_UserAccessRead(ENETPHY_Handle hPhyDev, Uint32 regadr, Uint32 phyadr, Uint32 *data)
1108 {
1109 CSL_MDIO_USERACCESS user_access_reg;
1111 /* Wait till transaction completion if any */
1112 do
1113 {
1114 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1115 }
1116 while(user_access_reg.go);
1118 user_access_reg.phyAddr = phyadr;
1119 user_access_reg.regAddr = regadr;
1120 user_access_reg.write = 0U;
1121 user_access_reg.go = 1U;
1123 CSL_MDIO_setUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0U, &user_access_reg);
1125 /* wait for command completion */
1126 do
1127 {
1128 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1129 }
1130 while(user_access_reg.go);
1132 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1133 /* Store the data if the read is acknowledged */
1134 if(user_access_reg.ack)
1135 {
1136 *data = user_access_reg.data & MDIO_USERACCESS_DATA;
1137 return 1u;
1138 }
1140 return 0u;
1141 }
1144 /************************************
1145 ***
1146 *** Waits for MDIO_USERACCESS to be ready and writes data
1147 ***
1148 **************************************/
1149 void _ENETPHY_UserAccessWrite(ENETPHY_Handle hPhyDev, Uint32 regadr, Uint32 phyadr, Uint32 data)
1150 {
1151 CSL_MDIO_USERACCESS user_access_reg;
1153 /* Wait till transaction completion if any */
1154 do
1155 {
1156 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1157 }
1158 while(user_access_reg.go);
1160 user_access_reg.phyAddr = phyadr;
1161 user_access_reg.regAddr = regadr;
1162 user_access_reg.write = 1U;
1163 user_access_reg.go = 1U;
1164 user_access_reg.data = data;
1166 CSL_MDIO_setUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0U, &user_access_reg);
1168 /* wait for command completion */
1169 do
1170 {
1171 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1172 }
1173 while(user_access_reg.go);
1174 }