[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_1_eng / packages / ti / board / src / evmAM437x / device / enet_phy.c
1 /**
2 * enet_phy.c
3 *
4 *
5 * Copyright (c) 2012 Texas Instruments Incorporated ALL RIGHTS RESERVED
6 *
7 */
9 #include <stdio.h>
10 #include <ti/csl/cslr_mdio.h>
11 #include <ti/csl/src/ip/mdio/V2/cslr_mdio.h>
12 #include <ti/csl/csl_mdio.h>
13 #include <ti/csl/src/ip/mdio/V2/csl_mdio.h>
14 #include <ti/csl/csl_mdioAux.h>
15 #include <ti/csl/src/ip/mdio/V2/csl_mdioAux.h>
16 #include <ti/board/src/evmAM437x/device/enet_phy.h>
18 /* UART Header files */
19 #include <ti/drv/uart/UART.h>
20 #include <ti/drv/uart/src/UART_osal.h>
21 #include <ti/drv/uart/UART_stdio.h>
23 /* R A N D O M N U M B E R S U P P O R T */
24 #define COMMON_RANDOM_MAX 0xFFFFu
26 /* Enable the below macro to have prints on the IO Console */
27 //#define IO_CONSOLE
29 #ifndef IO_CONSOLE
30 #define ENET_PHY_log UART_printf
31 #else
32 #define ENET_PHY_log printf
33 #endif
35 static Uint32 RandomSeed = 1u;
37 static Uint32 cpswRandom(void)
38 {
39 RandomSeed = (RandomSeed * (1103515245u)) + (12345u);
40 return ((Uint32) (RandomSeed/(65536u)) % (COMMON_RANDOM_MAX + 1u));
41 }
44 static Uint32 cpswRandomRange(Uint32 min, Uint32 max)
45 {
46 Uint32 iTmp;
48 iTmp = cpswRandom();
49 iTmp %= ((max - min) + 1u);
50 iTmp += min;
51 return(iTmp);
52 }
54 static void _ENETPHY_DisablePhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum);
55 static void _ENETPHY_PhyTimeOut(ENETPHY_Handle hPhyDev);
56 static void _ENETPHY_ResetPhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum);
59 static void _ENETPHY_DefaultState (ENETPHY_Handle hPhyDev);
60 static void _ENETPHY_FindingState (ENETPHY_Handle hPhyDev);
61 static void _ENETPHY_FoundState (ENETPHY_Handle hPhyDev);
62 static void _ENETPHY_InitState (ENETPHY_Handle hPhyDev);
63 static void _ENETPHY_LinkedState (ENETPHY_Handle hPhyDev);
64 static void _ENETPHY_LinkWaitState (ENETPHY_Handle hPhyDev);
65 static void _ENETPHY_LoopbackState (ENETPHY_Handle hPhyDev);
66 static void _ENETPHY_NwayStartState(ENETPHY_Handle hPhyDev);
67 static void _ENETPHY_NwayWaitState (ENETPHY_Handle hPhyDev);
69 #define _cpswIsGigPhy(hPhyDev) (TRUE)
71 #define ENETPHY_NOT_FOUND 0xFFFFu /* Used in Phy Detection */
73 /*CHECK:: PhyState field breakup */
74 #define ENETPHY_DEV_OFFSET (0u)
75 #define ENETPHY_DEV_SIZE (5u)
76 #define ENETPHY_DEV_MASK (0x1f<<ENETPHY_DEV_OFFSET)
78 #define ENETPHY_STATE_OFFSET (ENETPHY_DEV_SIZE+ENETPHY_DEV_OFFSET)
79 #define ENETPHY_STATE_SIZE (5u)
80 #define ENETPHY_STATE_MASK (0x1fu<<ENETPHY_STATE_OFFSET)
81 #define INIT (1u<<ENETPHY_STATE_OFFSET)
82 #define FINDING (2u<<ENETPHY_STATE_OFFSET)
83 #define FOUND (3u<<ENETPHY_STATE_OFFSET)
84 #define NWAY_START (4u<<ENETPHY_STATE_OFFSET)
85 #define NWAY_WAIT (5u<<ENETPHY_STATE_OFFSET)
86 #define LINK_WAIT (6u<<ENETPHY_STATE_OFFSET)
87 #define LINKED (7u<<ENETPHY_STATE_OFFSET)
88 #define LOOPBACK (8u<<ENETPHY_STATE_OFFSET)
90 #define ENETPHY_SPEED_OFFSET (ENETPHY_STATE_OFFSET+ENETPHY_STATE_SIZE)
91 #define ENETPHY_SPEED_SIZE (1u)
92 #define ENETPHY_SPEED_MASK_NDK (1u<<ENETPHY_SPEED_OFFSET)
94 #define ENETPHY_DUPLEX_OFFSET (ENETPHY_SPEED_OFFSET+ENETPHY_SPEED_SIZE)
95 #define ENETPHY_DUPLEX_SIZE (1u)
96 #define ENETPHY_DUPLEX_MASK (1u<<ENETPHY_DUPLEX_OFFSET)
98 #define ENETPHY_TIM_OFFSET (ENETPHY_DUPLEX_OFFSET+ENETPHY_DUPLEX_SIZE)
99 #define ENETPHY_TIM_SIZE (10u)
100 #define ENETPHY_TIM_MASK (0x3ffu<<ENETPHY_TIM_OFFSET)
102 /* we are working with 100ms ticks here */
103 #define ENETPHY_FIND_TO ( 1u<<ENETPHY_TIM_OFFSET)
104 #define ENETPHY_RECK_TO (20u<<ENETPHY_TIM_OFFSET)
105 #define ENETPHY_LINK_TO (50u<<ENETPHY_TIM_OFFSET)
106 #define ENETPHY_NWST_TO (50u<<ENETPHY_TIM_OFFSET)
107 #define ENETPHY_NWDN_TO (80u<<ENETPHY_TIM_OFFSET)
108 #define ENETPHY_MDIX_TO (27u<<ENETPHY_TIM_OFFSET) /* 2.74 Seconds <--Spec and empirical */
110 #define ENETPHY_SMODE_OFFSET (ENETPHY_TIM_OFFSET+ENETPHY_TIM_SIZE)
111 #define ENETPHY_SMODE_SIZE (7u)
112 #define ENETPHY_SMODE_MASK (0x7fu<<ENETPHY_SMODE_OFFSET)
113 #define SMODE_LPBK (0x40u<<ENETPHY_SMODE_OFFSET)
114 #define SMODE_AUTO (0x20u<<ENETPHY_SMODE_OFFSET)
115 #define SMODE_FD1000 (0x10u<<ENETPHY_SMODE_OFFSET)
116 #define SMODE_FD100 (0x08u<<ENETPHY_SMODE_OFFSET)
117 #define SMODE_HD100 (0x04u<<ENETPHY_SMODE_OFFSET)
118 #define SMODE_FD10 (0x02u<<ENETPHY_SMODE_OFFSET)
119 #define SMODE_HD10 (0x01u<<ENETPHY_SMODE_OFFSET)
120 #define SMODE_ALL (0x1fu<<ENETPHY_SMODE_OFFSET)
122 #define ENETPHY_CHNG_OFFSET (ENETPHY_SMODE_OFFSET+ENETPHY_SMODE_SIZE)
123 #define ENETPHY_CHNG_SIZE (1u)
124 #define ENETPHY_CHNG_MASK (1u<<ENETPHY_CHNG_OFFSET)
125 #define ENETPHY_CHANGE (1u<<ENETPHY_CHNG_OFFSET)
127 #define ENETPHY_TIMEDOUT_OFFSET (ENETPHY_CHNG_OFFSET+ENETPHY_CHNG_SIZE)
128 #define ENETPHY_TIMEDOUT_SIZE (1u) /* 30 Bits used */
129 #define ENETPHY_TIMEDOUT_MASK ((Uint32)(1u<<ENETPHY_TIMEDOUT_OFFSET))
130 #define ENETPHY_MDIX_SWITCH ((Uint32)(1u<<ENETPHY_TIMEDOUT_OFFSET))
132 #define ENETPHY_MDIX_OFFSET (ENETPHY_TIMEDOUT_OFFSET+ENETPHY_TIMEDOUT_SIZE)
133 #define ENETPHY_MDIX_SIZE (1u) /* 31 Bits used */
134 #define ENETPHY_MDIX_MASK ((Uint32)(1u<<ENETPHY_MDIX_OFFSET))
135 #define ENETPHY_MDIX ((Uint32)(1u<<ENETPHY_MDIX_OFFSET))
138 #ifndef VOLATILE32
139 #define VOLATILE32(addr) (*((volatile Uint32 *)(addr)))
140 #endif
142 Int32 cpsw_g_speed_set = 0;
143 Int32 cpsw_g_soft_reset_status = 0;
145 /*User Calls********************************************************* */
147 /* Updates book-keeping with info provided, programs ControlReg
148 * with clkdiv,enable bits*/
149 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)
150 {
151 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
153 Int32 ret =0 ;
154 Uint32 phy;
156 ((ENETPHY_DEVICE *) hPhyDev)->miibase = miibase;
157 ((ENETPHY_DEVICE *) hPhyDev)->inst = inst;
158 ((ENETPHY_DEVICE *) hPhyDev)->PhyMask = PhyMask;
159 ((ENETPHY_DEVICE *) hPhyDev)->MLinkMask = MLinkMask;
160 ((ENETPHY_DEVICE *) hPhyDev)->MdixMask = MdixMask;
162 (void)verbose;/* remove if not required */
164 *PhyState &= ~ENETPHY_MDIX_MASK; /* Set initial State to MDI */
166 CSL_MDIO_setClkDivVal((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, (MdioBusFreq/MdioClockFreq - 1));
167 CSL_MDIO_enableFaultDetect((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
168 CSL_MDIO_disablePreamble((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
169 CSL_MDIO_enableStateMachine((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
171 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_CNTRL_REG, PhyAddr, &phy);
172 phy |= NWAY_AUTOMDIX_ENABLE;
173 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_CNTRL_REG,PhyAddr,phy);
175 (void)ResetBit; /* suppress warning */
177 *PhyState=INIT;
179 ret = 0;
181 return ret;
182 }/* end of function ENETPHY_Init*/
184 void ENETPHY_SetPhyMode(ENETPHY_Handle hPhyDev,Uint32 PhyMode)
185 {
186 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
187 Uint32 CurrentState;
189 ((ENETPHY_DEVICE *) hPhyDev)->PhyMode = PhyMode; /* used for AUTOMIDX, planned to replace PhyState fields */
190 *PhyState &= (~ENETPHY_SMODE_MASK);
192 if (0u != (PhyMode & NWAY_LPBK))
193 {
194 *PhyState |= SMODE_LPBK;
195 }
196 if (0u != (PhyMode & NWAY_AUTO))
197 {
198 *PhyState |= SMODE_AUTO;
199 }
200 if (0u != (PhyMode & NWAY_FD1000) )
201 {
202 *PhyState |= SMODE_FD1000;
203 }
204 if (0u!= (PhyMode & NWAY_FD100))
205 {
206 *PhyState |= SMODE_FD100;
207 }
208 if (0u != (PhyMode & NWAY_HD100))
209 {
210 *PhyState |= SMODE_HD100;
211 }
212 if (0u != (PhyMode & NWAY_FD10))
213 {
214 *PhyState |= SMODE_FD10;
215 }
216 if (0u != (PhyMode & NWAY_HD10))
217 {
218 *PhyState |= SMODE_HD10;
219 }
221 CurrentState = (*PhyState) & ENETPHY_STATE_MASK;
222 if ( ((CurrentState == NWAY_START)|| (CurrentState == NWAY_WAIT)) ||
223 ( ((CurrentState == LINK_WAIT) || (CurrentState == LINKED) ) || (CurrentState == LOOPBACK)) )
224 {
225 *PhyState = ( (*PhyState)&(~ENETPHY_STATE_MASK)) | (FOUND | ENETPHY_CHANGE);
226 }
228 ENET_PHY_log("SetPhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d, FD1000:%d LPBK:%d\n", PhyMode,
229 (PhyMode & NWAY_AUTO), (PhyMode & MII_NWAY_FD10),(PhyMode & MII_NWAY_HD10),(PhyMode & MII_NWAY_FD100),
230 (PhyMode & MII_NWAY_HD100), (PhyMode & NWAY_FD1000),
231 (PhyMode & NWAY_LPBK) );
233 }
235 Uint32 ENETPHY_GetPhyMode(ENETPHY_Handle hPhyDev)
236 {
237 Uint32 PhyMode =0;
238 Uint32 status_reg = 0,control_reg = 0,advertize_reg;
239 Uint32 PhyNum,j;
240 Uint32 PhyMask = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
242 PhyNum = 0;
243 for(j = 1;PhyNum < 32;PhyNum++)
244 {
245 if( 0u != ( j & PhyMask))
246 {
247 break;
248 }
249 j = j<<1;
250 }
252 if(0u != _cpswIsGigPhy(hPhyDev))
253 {
254 /* read gig status */
255 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, &control_reg);
256 /* read gig status */
257 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_STATUS, PhyNum, &status_reg);
258 }
259 /* figure out if gig connected at FD 1000 or not first */
260 if ((0u != (control_reg & MII_NWAY_MY_FD1000)) && (0u != (status_reg & MII_NWAY_REM_FD1000)) )
261 {
262 PhyMode |= NWAY_FD1000;
263 }
265 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &control_reg);
266 if(0u != (control_reg & MII_AUTO_NEGOTIATE_EN) )
267 {
268 PhyMode |= NWAY_AUTO;
269 }
270 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &status_reg);
271 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, &advertize_reg);
273 /* Check for 10/100 capabilities of PHYs */
274 if((0u != (control_reg & MII_ENETPHY_100))|| (0u != (PhyMode & NWAY_AUTO)) )
275 {
276 if(0u != (advertize_reg & MII_NWAY_FD100))
277 {
278 PhyMode |= NWAY_FD100;
279 }
280 if(0u != (advertize_reg & MII_NWAY_HD100))
281 {
282 PhyMode |= NWAY_HD100;
283 }
285 }
287 if(((control_reg & MII_ENETPHY_100) == 0) || (0u != (PhyMode & NWAY_AUTO)) )
288 {
289 if(0u != (advertize_reg & MII_NWAY_FD10))
290 {
291 PhyMode |= NWAY_FD10;
292 }
293 if(0u != (advertize_reg & MII_NWAY_HD10))
294 {
295 PhyMode |= NWAY_HD10;
296 }
298 }
299 return PhyMode;
300 }
301 /* ENETPHY_Tic is called every 10 mili seconds to process Phy states */
303 int ENETPHY_Tic(ENETPHY_Handle hPhyDev,Uint32* mdioStatus)
304 {
305 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
306 Uint32 CurrentState;
307 Int32 ret = 0;
309 *mdioStatus = MDIO_EVENT_NOCHANGE;
311 /*Act on current state of the Phy */
312 CurrentState=*PhyState;
313 switch(CurrentState&ENETPHY_STATE_MASK)
314 {
315 case INIT: _ENETPHY_InitState(hPhyDev); break;
316 case FINDING: _ENETPHY_FindingState(hPhyDev); break;
317 case FOUND: _ENETPHY_FoundState(hPhyDev); break;
318 case NWAY_START: _ENETPHY_NwayStartState(hPhyDev); break;
319 case NWAY_WAIT: _ENETPHY_NwayWaitState(hPhyDev); break;
320 case LINK_WAIT: _ENETPHY_LinkWaitState(hPhyDev); break;
321 case LINKED: _ENETPHY_LinkedState(hPhyDev); break;
322 case LOOPBACK: _ENETPHY_LoopbackState(hPhyDev); break;
323 default: _ENETPHY_DefaultState(hPhyDev); break;
324 }
326 /* Check is MDI/MDIX mode switch is needed */
328 if(0u != ((*PhyState) & ENETPHY_MDIX_SWITCH) )
329 {
331 Uint32 Mdix;
333 *PhyState &= (~ENETPHY_MDIX_SWITCH); /* Clear Mdix Flip indicator */
335 if(0u != ((*PhyState) & ENETPHY_MDIX))
336 {
337 Mdix = 1;
338 }
339 else
340 {
341 Mdix = 0;
342 }
343 ret = (Int32)(_MIIMDIO_MDIXFLIP | Mdix);
345 }
346 else
347 {
349 /*Return state change to user */
350 /** CHECK : report MDIO_LINKEVENTS as MDIO_EVENT_NOCHANGE, MDIO_EVENT_LINKDOWN,
351 * MDIO_EVENT_PHYERROR,MDIO_EVENT_LINKUP
352 * Currently ENETPHY_CHNG_MASK set for any state transition*/
354 if (0u != ((*PhyState) & ENETPHY_CHNG_MASK))
355 {
356 if( ( ((*PhyState) & ENETPHY_STATE_MASK) == LINKED) && ((CurrentState & ENETPHY_STATE_MASK) != LINKED) )
357 {
358 /* we have just entered LInked state */
359 *mdioStatus = MDIO_EVENT_LINKUP;
360 }
361 if( ((CurrentState & ENETPHY_STATE_MASK) == LINKED) && ( ( (*PhyState) & ENETPHY_STATE_MASK) != LINKED))
362 {
363 /* we started in Linked state and we have a state change */
364 *mdioStatus = MDIO_EVENT_LINKDOWN;
365 }
366 *PhyState &= (~ENETPHY_CHNG_MASK);
367 ret = (Int32)(TRUE);
368 }
369 else
370 {
371 ret = (Int32)(FALSE);
372 }
373 }
375 return ret;
377 }
380 void ENETPHY_LinkChange(ENETPHY_Handle hPhyDev)
381 {
382 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
383 Uint32 PhyNum,PhyStatus;
385 PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
387 ENET_PHY_log("ENETPHY_LinkChange: PhyNum = %d\n", PhyNum);
389 if (0u != (ENETPHY_GetLinked(hPhyDev)) )
390 {
391 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
393 if ((PhyStatus & MII_ENETPHY_LINKED) == 0u)
394 {
395 *PhyState &= (~(ENETPHY_TIM_MASK | ENETPHY_STATE_MASK));
396 if (0u!=((*PhyState) & SMODE_AUTO))
397 {
398 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN|MII_RENEGOTIATE);
399 *PhyState |= ((ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
400 }
401 else
402 {
403 *PhyState|= ((ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
404 }
405 }
406 }
407 }
409 /* returns 0 if current Phy has AutoMdix support, otherwise 0 */
410 static int _ENETPHY_MdixSupported(ENETPHY_Handle hPhyDev)
411 {
412 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
413 Uint32 PhyNum;
414 Int32 ret;
416 if((((ENETPHY_DEVICE *) hPhyDev)->PhyMode & NWAY_AUTOMDIX) == 0)
417 {
418 ret = (0); /* AutoMdix not turned on */
419 }
420 else
421 {
422 PhyNum = ((*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
423 if( ((1<<PhyNum) & ((ENETPHY_DEVICE *) hPhyDev)->MdixMask) == 0)
424 {
425 ret = 0; /* Phy does not support AutoMdix*/
426 }
428 ret = 1;
429 }
430 return ret;
431 }
433 /* If current Phy has AutoMdix support add Mdix Delay to the Timer State Value */
434 static void _ENETPHY_MdixDelay(ENETPHY_Handle hPhyDev)
435 {
436 Uint32 Delay;
437 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
440 if(_ENETPHY_MdixSupported(hPhyDev) != 0)
441 {
442 /* Get the Delay value in milli-seconds and convert to ten-milli second value */
443 Delay = cpswRandomRange(_AUTOMDIX_DELAY_MIN, _AUTOMDIX_DELAY_MAX);
444 Delay /= 10;
446 /* Add AutoMidx Random Switch Delay to AutoMdix Link Delay */
448 Delay += (ENETPHY_MDIX_TO>>ENETPHY_TIM_OFFSET);
450 /* Change Timeout value to AutoMdix standard */
451 *PhyState &= (~(ENETPHY_TIM_MASK)); /* Clear current Time out value */
452 *PhyState |= (Delay<<ENETPHY_TIM_OFFSET); /* Set new value */
453 }
454 return;
456 }
458 void _ENETPHY_DisablePhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum)
459 {
460 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, (MII_ENETPHY_ISOLATE | MII_ENETPHY_PDOWN) );
462 ENET_PHY_log("ENETPHY_DisablePhy(%d)\n",PhyNum);
464 }
466 void _ENETPHY_InitState(ENETPHY_Handle hPhyDev)
467 {
468 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
469 Uint32 CurrentState;
471 CurrentState=*PhyState;
472 CurrentState = (CurrentState & (~ENETPHY_TIM_MASK)) | (ENETPHY_FIND_TO);
473 CurrentState=(CurrentState & (~ENETPHY_STATE_MASK)) | (FINDING);
474 CurrentState=(CurrentState & (~ENETPHY_SPEED_MASK_NDK));
475 CurrentState=(CurrentState & (~ENETPHY_DUPLEX_MASK));
476 CurrentState|=ENETPHY_CHANGE;
478 *PhyState=CurrentState;
480 }
482 void _ENETPHY_FindingState(ENETPHY_Handle hPhyDev)
483 {
484 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
485 Uint32 PhyMask = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
486 Uint32 PhyNum,i,j;
488 PhyNum=ENETPHY_NOT_FOUND;
490 if (0u!= ((*PhyState) & ENETPHY_TIM_MASK))
491 {
492 *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK) ) | (( (*PhyState) & ENETPHY_TIM_MASK) - (1 << ENETPHY_TIM_OFFSET));
493 }
494 else
495 {
496 j =1;
497 for(i=0; i<32; i++)
498 {
499 if( PhyMask & j)
500 {
501 if( CSL_MDIO_isPhyAlive((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, i))
502 {
503 PhyNum=i;
504 break;
505 }
506 }
507 j = j << 1;
508 }
509 if (PhyNum!=ENETPHY_NOT_FOUND)
510 {
511 /* Phy Found! */
512 *PhyState = ((*PhyState) & (~ENETPHY_DEV_MASK) ) | ((PhyNum & ENETPHY_DEV_MASK) << ENETPHY_DEV_OFFSET);
513 *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK) ) | (FOUND);
514 *PhyState|=ENETPHY_CHANGE;
516 ENET_PHY_log("ENETPHY_FindingState: PhyNum: %d\n",PhyNum);
518 }
519 else
520 {
522 ENET_PHY_log("ENETPHY_FindingState: Timed Out looking for a Phy!\n");
523 *PhyState|=ENETPHY_RECK_TO; /* Set Timer */
524 }
525 }
526 }
528 void _ENETPHY_FoundState(ENETPHY_Handle hPhyDev)
529 {
530 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
531 Uint32 PhyMask = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
532 Uint32 MLinkMask = ((ENETPHY_DEVICE *) hPhyDev)->MLinkMask;
533 Uint32 PhyNum,PhyStatus,NWAYadvertise,NWAY1000advertise=0,m,phynum,i,j;
534 Uint32 PhyDummy;
536 static Uint32 auto_neg1 = 0xFFFFFFFF,auto_neg2= 0xFFFFFFFF;
539 if (( (*PhyState) & ENETPHY_SMODE_MASK) == 0)
540 {
541 return;
542 }
544 PhyNum = ((*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
545 j =1;
546 for(phynum=0; phynum<32; phynum++)
547 {
548 if(0u!= (PhyMask & j))
549 {
550 if( CSL_MDIO_isPhyAlive((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, phynum))
551 {
552 _ENETPHY_DisablePhy(hPhyDev,phynum);
553 }
554 }
555 j = j << 1;
556 }
557 /* If Aries SWR2 reset then don't reset phy*/
558 /* Reset the Phy and proceed with auto-negotiation */
559 if(( 0u != cpsw_g_speed_set) || ((0u ==cpsw_g_soft_reset_status) || ((auto_neg1 & (1 << PhyNum)) == 0) ) )
560 {
561 _ENETPHY_ResetPhy(hPhyDev,PhyNum);
562 }
564 /* Set the way Link will be Monitored */
565 /* Check the Link Selection Method */
566 if (0u != ((1 << PhyNum) & MLinkMask) )
567 {
568 CSL_MDIO_enableLinkStatusChangeInterrupt((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, ((ENETPHY_DEVICE *) hPhyDev)->inst, PhyNum);
569 }
570 else
571 {
572 CSL_MDIO_disableLinkStatusChangeInterrupt((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, ((ENETPHY_DEVICE *) hPhyDev)->inst, PhyNum);
573 }
574 /* Get the Phy Status */
575 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
578 /* For Phy Internal loopback test, need to wait until Phy
579 found, then set Loopback */
580 if (0u != ((*PhyState) & SMODE_LPBK))
581 {
582 /* Set Phy in Loopback */
584 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_ENETPHY_LOOP|MII_ENETPHY_FD);
585 /* Do a read to ensure ENETPHY_LOOP has completed */
586 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyDummy);
587 *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK) ) | (LOOPBACK);
588 *PhyState|=ENETPHY_CHANGE;
589 return;
590 }
592 ENET_PHY_log("Enable Phy to negotiate external connection\n");
595 NWAYadvertise=MII_NWAY_SEL;
596 if (0u != ((*PhyState) & SMODE_FD100))
597 {
598 NWAYadvertise |= MII_NWAY_FD100;
599 }
600 if (0u != ((*PhyState) & SMODE_HD100))
601 {
602 NWAYadvertise |= MII_NWAY_HD100;
603 }
604 if (0u != ((*PhyState) & SMODE_FD10))
605 {
606 NWAYadvertise |= MII_NWAY_FD10;
607 }
608 if (0u != ((*PhyState) & SMODE_HD10))
609 {
610 NWAYadvertise |= MII_NWAY_HD10;
611 }
612 if (0u != ((*PhyState) & SMODE_FD1000))
613 {
614 NWAY1000advertise= ENETPHY_1000BT_FD;
615 }
617 *PhyState &= ( ~(ENETPHY_TIM_MASK | ENETPHY_STATE_MASK));
618 if ((0u != (PhyStatus & MII_NWAY_CAPABLE)) && (0u != ( (*PhyState) & SMODE_AUTO)) ) /*NWAY Phy Detected*/
619 {
620 if(( 0u != cpsw_g_speed_set) || ((0u ==cpsw_g_soft_reset_status) || ((auto_neg1 & (1 << PhyNum)) == 0) ) )
621 {
622 /*For NWAY compliant Phys */
623 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, NWAYadvertise);
624 /* for gig negotiation */
625 if(0u != _cpswIsGigPhy(hPhyDev))
626 {
627 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, NWAY1000advertise);
628 }
630 ENET_PHY_log("NWAY Advertising: ");
631 if (0u != ((*PhyState) & SMODE_FD1000))
632 {
633 ENET_PHY_log("FullDuplex-1000 ");
634 }
635 if (0u != (NWAYadvertise & MII_NWAY_FD100))
636 {
637 ENET_PHY_log("FullDuplex-100 ");
638 }
639 if (0u != (NWAYadvertise & MII_NWAY_HD100))
640 {
641 ENET_PHY_log("HalfDuplex-100 ");
642 }
643 if (0u != (NWAYadvertise & MII_NWAY_FD10))
644 {
645 ENET_PHY_log("FullDuplex-10 ");
646 }
647 if (0u != (NWAYadvertise & MII_NWAY_HD10))
648 {
649 ENET_PHY_log("HalfDuplex-10 ");
650 }
652 ENET_PHY_log("\n");
654 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN );
655 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN|MII_RENEGOTIATE|MII_ENETPHY_FD);
656 *PhyState|= ( (ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
657 }
658 else
659 {
660 *PhyState |= ( (ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
661 auto_neg1 = auto_neg1 & (~(1 << PhyNum));
662 }
663 }
664 else
665 {
666 *PhyState &= (~SMODE_AUTO); /*The Phy is not capable of auto negotiation! */
667 m=NWAYadvertise;
668 j = 0x8000u;
670 for(i=0;(i<16);i++)
671 {
672 if(0u != (j & m))
673 {
674 break;
675 }
676 j = j >> 1 ;
678 }
679 m=j;
680 j=0;
682 /* figure out if gig connected at FD 1000 or not first */
683 if ((NWAY1000advertise & MII_NWAY_MY_FD1000)== MII_NWAY_MY_FD1000)
684 {
685 j = MII_ENETPHY_1000;
686 j |= MII_ENETPHY_FD;
687 }
688 else
689 {
690 if (0u != (m & (MII_NWAY_FD100 | MII_NWAY_HD100)) )
691 {
692 j=MII_ENETPHY_100;
693 m&=(MII_NWAY_FD100|MII_NWAY_HD100);
694 }
695 if (0u != (m & (MII_NWAY_FD100 | MII_NWAY_FD10)) )
696 {
697 j |= MII_ENETPHY_FD;
698 }
699 }
701 ENET_PHY_log("Requested PHY mode %s Duplex %s Mbps\n",(j & MII_ENETPHY_FD) ? "Full":"Half",
702 (j & MII_ENETPHY_1000) ? "1000":((j & MII_ENETPHY_100) ? "100":"10"));
704 if((0u != cpsw_g_speed_set) || ( (0u == cpsw_g_soft_reset_status) || ((auto_neg2 & (1 << PhyNum)) == 0) ))
705 {
706 if(0u != (j & MII_ENETPHY_1000))
707 {
708 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, j);
709 }
710 else
711 {
712 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, j);
713 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, NWAYadvertise);
714 }
715 cpsw_g_speed_set = 0;
716 }
717 else
718 {
719 auto_neg2 = auto_neg2 & (~(1 << PhyNum));
720 }
721 *PhyState &= (~ENETPHY_SPEED_MASK_NDK);
722 if(0u != (j & MII_ENETPHY_1000) )
723 {
724 *PhyState|=(1<<ENETPHY_DUPLEX_OFFSET);
725 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 1;
726 }
727 else
728 {
729 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 0;
730 }
731 if (0u != (j & MII_ENETPHY_100) )
732 {
733 *PhyState|=(1<<ENETPHY_SPEED_OFFSET);
734 }
735 *PhyState &= (~ENETPHY_DUPLEX_MASK);
736 if (0u != (j & MII_ENETPHY_FD) )
737 {
738 *PhyState|=(1<<ENETPHY_DUPLEX_OFFSET);
739 }
740 *PhyState |= ((ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
741 }
742 _ENETPHY_MdixDelay(hPhyDev); /* If AutoMdix add delay */
744 }
746 void _ENETPHY_ResetPhy(ENETPHY_Handle hPhyDev,Uint32 PhyNum)
747 {
748 Uint32 data;
750 data = MII_ENETPHY_RESET;
752 /* Reset the phy */
753 _ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, data);
755 /* wait till the reset bit is auto cleared */
756 while(data & MII_ENETPHY_RESET)
757 {
758 /* Read the reset */
759 if(_ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &data) != TRUE)
760 {
761 break;
762 }
763 }
765 }
767 void _ENETPHY_NwayStartState(ENETPHY_Handle hPhyDev)
768 {
769 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
770 Uint32 PhyNum,PhyMode,PhyDummy;
772 PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
774 /*Wait for Negotiation to start */
776 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &PhyMode);
778 if((PhyMode&MII_RENEGOTIATE)==0)
779 {
780 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum,&PhyDummy); /*Flush pending latch bits*/
781 *PhyState &= (~(ENETPHY_STATE_MASK|ENETPHY_TIM_MASK));
782 *PhyState |= ((ENETPHY_CHANGE | NWAY_WAIT) |ENETPHY_NWDN_TO);
783 _ENETPHY_MdixDelay(hPhyDev); /* If AutoMdix add delay */
784 }
785 else
786 {
787 if (0u != ((*PhyState) & ENETPHY_TIM_MASK) )
788 {
789 *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK)) | ( ( (*PhyState) & ENETPHY_TIM_MASK)-(1 << ENETPHY_TIM_OFFSET));
790 }
791 else
792 {
793 _ENETPHY_PhyTimeOut(hPhyDev);
794 }
795 }
796 }
798 void _ENETPHY_NwayWaitState(ENETPHY_Handle hPhyDev)
799 {
800 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
801 Uint32 PhyNum,PhyStatus,NWAYadvertise = 0,NWAYREadvertise = 0,NegMode,i,j;
802 Uint32 NWAY1000advertise = 0, NWAY1000REMadvertise = 0;
804 PhyNum=( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
806 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
808 if (0u != (PhyStatus & MII_NWAY_COMPLETE))
809 {
810 *PhyState|=ENETPHY_CHANGE;
811 *PhyState &= (~ENETPHY_SPEED_MASK_NDK);
812 *PhyState &= (~ENETPHY_DUPLEX_MASK);
814 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, &NWAYadvertise);
815 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_LINK_PARTNER_ABLTY, PhyNum, &NWAYREadvertise);
816 /* read gig status */
817 if(0u != _cpswIsGigPhy(hPhyDev))
818 {
819 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, &NWAY1000advertise);
820 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_STATUS, PhyNum, &NWAY1000REMadvertise);
821 }
823 /* figure out if gig connected at FD 1000 or not first */
824 if ((0u !=(NWAY1000advertise & MII_NWAY_MY_FD1000)) && (0u!=(NWAY1000REMadvertise & MII_NWAY_REM_FD1000)) )
825 {
826 NegMode = MII_NWAY_MY_FD1000;
827 }
828 else
829 {
830 NegMode = 0u;
831 }
833 if (NegMode == 0u)
834 {
835 /* continue checking for 100 and 10 connection */
837 /* Negotiated mode is we and the remote have in common */
838 NegMode = NWAYadvertise & NWAYREadvertise;
840 ENET_PHY_log("Phy: %d, ",( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET);
841 ENET_PHY_log("NegMode %04X, NWAYadvertise %04X, NWAYREadvertise %04X\n",
842 NegMode, NWAYadvertise, NWAYREadvertise);
844 /* Limit negotiation to fields below */
845 NegMode &= ( (MII_NWAY_FD100|MII_NWAY_HD100) | (MII_NWAY_FD10|MII_NWAY_HD10));
847 if (NegMode == 0u)
848 {
849 NegMode=(MII_NWAY_HD100|MII_NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/
850 }
852 j = 0x8000u;
853 for(i = 0; i <16 ; i++)
854 {
855 if (0u != (j & NegMode))
856 {
857 break;
858 }
859 j = j >> 1;
860 }
862 NegMode=j;
865 ENET_PHY_log("Negotiated connection: ");
868 if (0u != (NegMode & MII_NWAY_FD100))
869 {
870 ENET_PHY_log("FullDuplex 100 Mbs\n");
871 }
872 if (0u != (NegMode & MII_NWAY_HD100))
873 {
874 ENET_PHY_log("HalfDuplex 100 Mbs\n");
875 }
876 if (0u != (NegMode & MII_NWAY_FD10))
877 {
878 ENET_PHY_log("FullDuplex 10 Mbs\n");
879 }
880 if (0u != (NegMode & MII_NWAY_HD10))
881 {
882 ENET_PHY_log("HalfDuplex 10 Mbs\n");
883 }
885 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 0u;
886 }
887 else
888 {
890 /* found 1000 negotiated connection! */
891 ENET_PHY_log("Negotiated connection: ");
892 ENET_PHY_log("FullDuplex 1000 Mbs\n");
894 ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 1u;
895 }
897 if (NegMode != 0u)
898 {
899 if (0u != (PhyStatus & MII_ENETPHY_LINKED))
900 {
901 *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK)) | LINKED;
902 }
903 else
904 {
905 *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK)) | LINK_WAIT;
906 }
907 if (0u != (NegMode & (MII_NWAY_FD100 | MII_NWAY_HD100)) )
908 {
909 *PhyState=( (*PhyState) & (~ENETPHY_SPEED_MASK_NDK)) | (1 << ENETPHY_SPEED_OFFSET);
910 }
911 if (0u != (NegMode & (MII_NWAY_FD100 | MII_NWAY_FD10 | MII_NWAY_MY_FD1000)))
912 {
913 *PhyState=( (*PhyState) & (~ENETPHY_DUPLEX_MASK)) | (1 << ENETPHY_DUPLEX_OFFSET);
914 }
915 }
916 }
917 else
918 {
919 if ( 0u != ( (*PhyState) & ENETPHY_TIM_MASK) )
920 {
921 *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK)) | (( (*PhyState) & ENETPHY_TIM_MASK)-(1 << ENETPHY_TIM_OFFSET));
922 }
923 else
924 {
925 _ENETPHY_PhyTimeOut(hPhyDev);
926 }
927 }
929 }
931 void _ENETPHY_LinkWaitState(ENETPHY_Handle hPhyDev)
932 {
933 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
934 Uint32 PhyStatus;
935 Uint32 PhyNum;
937 PhyNum=( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
939 _ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
941 if (0u != (PhyStatus & MII_ENETPHY_LINKED) )
942 {
943 *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK) ) | LINKED;
944 *PhyState|=ENETPHY_CHANGE;
945 }
946 else
947 {
948 if (0u != ( (*PhyState) & ENETPHY_TIM_MASK) )
949 {
950 *PhyState=(*PhyState&~ENETPHY_TIM_MASK)|((*PhyState&ENETPHY_TIM_MASK)-(1<<ENETPHY_TIM_OFFSET));
951 }
952 else
953 {
954 _ENETPHY_PhyTimeOut(hPhyDev);
955 }
956 }
957 }
959 void _ENETPHY_PhyTimeOut(ENETPHY_Handle hPhyDev)
960 {
961 Uint32 *PhyState;
962 if(_ENETPHY_MdixSupported(hPhyDev) == 0)
963 {
964 return; /* AutoMdix not supported */
965 }
966 PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
968 /* Indicate MDI/MDIX mode switch is needed */
969 *PhyState|=ENETPHY_MDIX_SWITCH;
971 /* Toggle the MDIX mode indicatir */
972 if(0u != ( (*PhyState) & ENETPHY_MDIX) )
973 {
974 *PhyState &= (~ENETPHY_MDIX_MASK); /* Current State is MDIX, set to MDI */
975 }
976 else
977 {
978 *PhyState |= ENETPHY_MDIX_MASK; /* Current State is MDI, set to MDIX */
979 }
980 /* Reset state machine to FOUND */
981 *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK)) | (FOUND);
982 }
984 void _ENETPHY_LoopbackState(ENETPHY_Handle hPhyDev)
985 {
986 (void)((ENETPHY_DEVICE *) hPhyDev); /* remove if not needed, to avoid warning */
987 return;
988 }
990 void _ENETPHY_LinkedState(ENETPHY_Handle hPhyDev)
991 {
992 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
993 Uint32 PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
995 if (CSL_MDIO_isPhyLinked((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, PhyNum))
996 {
997 return; /* if still Linked, exit*/
998 }
1000 /* Not Linked */
1001 *PhyState &= (~(ENETPHY_STATE_MASK | ENETPHY_TIM_MASK));
1002 if (0u != ( (*PhyState) & SMODE_AUTO) )
1003 {
1004 *PhyState |= ( (ENETPHY_CHANGE | NWAY_WAIT) | ENETPHY_NWDN_TO);
1005 }
1006 else
1007 {
1008 *PhyState |= ( (ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
1009 }
1010 _ENETPHY_MdixDelay(hPhyDev); /* If AutoMdix add delay */
1012 }
1014 void _ENETPHY_DefaultState(ENETPHY_Handle hPhyDev)
1015 {
1016 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1017 /*Awaiting a ENETPHY_Init call */
1018 *PhyState|=ENETPHY_CHANGE;
1019 }
1021 /* Simple Query Functions for reporting speed,duplex */
1022 /* ENETPHY_GetDuplex is called to retrieve the Duplex info */
1023 int ENETPHY_GetDuplex(ENETPHY_Handle hPhyDev)
1024 {
1025 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1026 return(( (*PhyState) & ENETPHY_DUPLEX_MASK) ? 1:0); /* return 0 or a 1 */
1027 }
1029 /* ENETPHY_GetSpeed is called to retreive the Speed info */
1030 int ENETPHY_GetSpeed(ENETPHY_Handle hPhyDev)
1031 {
1032 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1033 Int32 ret = 0 ;
1035 if (((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 == 1)
1036 {
1037 ret = 2; /* if we are linked at 1000, we return a value of 2 */
1038 }
1039 else
1040 {
1041 ret = ( (*PhyState) & ENETPHY_SPEED_MASK_NDK);
1042 }
1044 return ret;
1045 }
1047 /* ENETPHY_GetPhyNum is called to retreive the Phy Device Adr info*/
1048 int ENETPHY_GetPhyNum(ENETPHY_Handle hPhyDev)
1049 {
1050 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1051 return((Int32)(( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET));
1052 }
1054 /* ENETPHY_GetLoopback is called to Determine if the LOOPBACK state has been reached*/
1055 int ENETPHY_GetLoopback(ENETPHY_Handle hPhyDev)
1056 {
1057 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1058 return(( (*PhyState) & ENETPHY_STATE_MASK) == LOOPBACK);
1059 }
1061 /* ENETPHY_GetLinked is called to Determine if the LINKED state has been reached*/
1062 int ENETPHY_GetLinked(ENETPHY_Handle hPhyDev)
1063 {
1064 Uint32 *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1065 return (( (*PhyState) & ENETPHY_STATE_MASK) == LINKED);
1066 }
1068 /************************************
1069 ***
1070 *** Waits for MDIO_USERACCESS to be ready and reads data
1071 *** If 'WaitForData' set, waits for read to complete and returns Data,
1072 *** otherwise returns 0
1073 *** Note: 'data' is 16 bits but we use 32 bits
1074 *** to be consistent with rest of the code.
1075 ***
1076 **************************************/
1077 Uint32 _ENETPHY_UserAccessRead(ENETPHY_Handle hPhyDev, Uint32 regadr, Uint32 phyadr, Uint32 *data)
1078 {
1079 CSL_MDIO_USERACCESS user_access_reg;
1081 /* Wait till transaction completion if any */
1082 do
1083 {
1084 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1085 }
1086 while(user_access_reg.go);
1088 user_access_reg.phyAddr = phyadr;
1089 user_access_reg.regAddr = regadr;
1090 user_access_reg.write = 0U;
1091 user_access_reg.go = 1U;
1093 CSL_MDIO_setUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0U, &user_access_reg);
1095 /* wait for command completion */
1096 do
1097 {
1098 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1099 }
1100 while(user_access_reg.go);
1102 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1103 /* Store the data if the read is acknowledged */
1104 if(user_access_reg.ack)
1105 {
1106 *data = user_access_reg.data & MDIO_USERACCESS_DATA;
1107 return 1u;
1108 }
1110 return 0u;
1111 }
1114 /************************************
1115 ***
1116 *** Waits for MDIO_USERACCESS to be ready and writes data
1117 ***
1118 **************************************/
1119 void _ENETPHY_UserAccessWrite(ENETPHY_Handle hPhyDev, Uint32 regadr, Uint32 phyadr, Uint32 data)
1120 {
1121 CSL_MDIO_USERACCESS user_access_reg;
1123 /* Wait till transaction completion if any */
1124 do
1125 {
1126 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1127 }
1128 while(user_access_reg.go);
1130 user_access_reg.phyAddr = phyadr;
1131 user_access_reg.regAddr = regadr;
1132 user_access_reg.write = 1U;
1133 user_access_reg.go = 1U;
1134 user_access_reg.data = data;
1136 CSL_MDIO_setUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0U, &user_access_reg);
1138 /* wait for command completion */
1139 do
1140 {
1141 CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1142 }
1143 while(user_access_reg.go);
1144 }