]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/board/src/skAM437x/device/enet_phy.c
board-rtos: add to PDK
[processor-sdk/pdk.git] / packages / ti / board / src / skAM437x / device / enet_phy.c
1 /**
2  * enet_phy.c
3  *
4  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the
16  * distribution.
17  *
18  * Neither the name of Texas Instruments Incorporated nor the names of
19  * its contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  */
36 #include <stdio.h>
37 #include <ti/csl/cslr_mdio.h>
38 #include <ti/csl/src/ip/mdio/V2/cslr_mdio.h>
39 #include <ti/csl/csl_mdio.h>
40 #include <ti/csl/src/ip/mdio/V2/csl_mdio.h>
41 #include <ti/csl/csl_mdioAux.h>
42 #include <ti/csl/src/ip/mdio/V2/csl_mdioAux.h>
43 #include <ti/board/src/skAM437x/device/enet_phy.h>
45 /* UART Header files */
46 #include <ti/drv/uart/UART.h>
47 #include <ti/drv/uart/src/UART_osal.h>
48 #include <ti/drv/uart/UART_stdio.h>
50 /* R A N D O M  N U M B E R  S U P P O R T */
51 #define COMMON_RANDOM_MAX        0xFFFFu
53 /* Enable the below macro to have prints on the IO Console */
54 //#define IO_CONSOLE
56 #ifndef IO_CONSOLE
57 #define ENET_PHY_log                UART_printf
58 #else
59 #define ENET_PHY_log                printf
60 #endif
62 static uint32_t RandomSeed = 1u;
64 static uint32_t cpswRandom(void)
65 {
66   RandomSeed = (RandomSeed * (1103515245u)) + (12345u);
67   return ((uint32_t) (RandomSeed/(65536u)) % (COMMON_RANDOM_MAX + 1u));
68 }
71 static uint32_t cpswRandomRange(uint32_t min, uint32_t max)
72 {
73   uint32_t iTmp;
75   iTmp =  cpswRandom();
76   iTmp %= ((max - min) + 1u);
77   iTmp += min;
78   return(iTmp);
79 }
81 static void ENETPHY_DisablePhy(ENETPHY_Handle hPhyDev,uint32_t PhyNum);
82 static void ENETPHY_PhyTimeOut(ENETPHY_Handle hPhyDev);
83 static void ENETPHY_ResetPhy(ENETPHY_Handle hPhyDev,uint32_t PhyNum);
86 static void ENETPHY_DefaultState  (ENETPHY_Handle hPhyDev);
87 static void ENETPHY_FindingState  (ENETPHY_Handle hPhyDev);
88 static void ENETPHY_FoundState    (ENETPHY_Handle hPhyDev);
89 static void ENETPHY_InitState     (ENETPHY_Handle hPhyDev);
90 static void ENETPHY_LinkedState   (ENETPHY_Handle hPhyDev);
91 static void ENETPHY_LinkWaitState (ENETPHY_Handle hPhyDev);
92 static void ENETPHY_LoopbackState (ENETPHY_Handle hPhyDev);
93 static void ENETPHY_NwayStartState(ENETPHY_Handle hPhyDev);
94 static void ENETPHY_NwayWaitState (ENETPHY_Handle hPhyDev);
96 #define   _cpswIsGigPhy(hPhyDev)        (TRUE)
98 #define ENETPHY_NOT_FOUND  0xFFFFu    /*  Used in Phy Detection */
100 /*CHECK:: PhyState field breakup  */
101 #define ENETPHY_DEV_OFFSET      (0u)
102 #define ENETPHY_DEV_SIZE        (5u)
103 #define ENETPHY_DEV_MASK        (0x1f<<ENETPHY_DEV_OFFSET)
105 #define ENETPHY_STATE_OFFSET    (ENETPHY_DEV_SIZE+ENETPHY_DEV_OFFSET)
106 #define ENETPHY_STATE_SIZE      (5u)
107 #define ENETPHY_STATE_MASK      (0x1fu<<ENETPHY_STATE_OFFSET)
108     #define INIT       (1u<<ENETPHY_STATE_OFFSET)
109     #define FINDING    (2u<<ENETPHY_STATE_OFFSET)
110     #define FOUND      (3u<<ENETPHY_STATE_OFFSET)
111     #define NWAY_START (4u<<ENETPHY_STATE_OFFSET)
112     #define NWAY_WAIT  (5u<<ENETPHY_STATE_OFFSET)
113     #define LINK_WAIT  (6u<<ENETPHY_STATE_OFFSET)
114     #define LINKED     (7u<<ENETPHY_STATE_OFFSET)
115     #define LOOPBACK   (8u<<ENETPHY_STATE_OFFSET)
117 #define ENETPHY_SPEED_OFFSET    (ENETPHY_STATE_OFFSET+ENETPHY_STATE_SIZE)
118 #define ENETPHY_SPEED_SIZE      (1u)
119 #define ENETPHY_SPEED_MASK_NDK      (1u<<ENETPHY_SPEED_OFFSET)
121 #define ENETPHY_DUPLEX_OFFSET   (ENETPHY_SPEED_OFFSET+ENETPHY_SPEED_SIZE)
122 #define ENETPHY_DUPLEX_SIZE     (1u)
123 #define ENETPHY_DUPLEX_MASK     (1u<<ENETPHY_DUPLEX_OFFSET)
125 #define ENETPHY_TIM_OFFSET      (ENETPHY_DUPLEX_OFFSET+ENETPHY_DUPLEX_SIZE)
126 #define ENETPHY_TIM_SIZE        (10u)
127 #define ENETPHY_TIM_MASK        (0x3ffu<<ENETPHY_TIM_OFFSET)
129 /* we are working with 100ms ticks here */
130   #define ENETPHY_FIND_TO (  1u<<ENETPHY_TIM_OFFSET)
131     #define ENETPHY_RECK_TO (20u<<ENETPHY_TIM_OFFSET)
132     #define ENETPHY_LINK_TO (50u<<ENETPHY_TIM_OFFSET)
133     #define ENETPHY_NWST_TO (50u<<ENETPHY_TIM_OFFSET)
134     #define ENETPHY_NWDN_TO (80u<<ENETPHY_TIM_OFFSET)
135     #define ENETPHY_MDIX_TO (27u<<ENETPHY_TIM_OFFSET) /* 2.74 Seconds <--Spec and empirical */
137 #define ENETPHY_SMODE_OFFSET    (ENETPHY_TIM_OFFSET+ENETPHY_TIM_SIZE)
138 #define ENETPHY_SMODE_SIZE      (7u)
139 #define ENETPHY_SMODE_MASK      (0x7fu<<ENETPHY_SMODE_OFFSET)
140     #define SMODE_LPBK   (0x40u<<ENETPHY_SMODE_OFFSET)
141     #define SMODE_AUTO   (0x20u<<ENETPHY_SMODE_OFFSET)
142     #define SMODE_FD1000 (0x10u<<ENETPHY_SMODE_OFFSET)
143     #define SMODE_FD100  (0x08u<<ENETPHY_SMODE_OFFSET)
144     #define SMODE_HD100  (0x04u<<ENETPHY_SMODE_OFFSET)
145     #define SMODE_FD10   (0x02u<<ENETPHY_SMODE_OFFSET)
146     #define SMODE_HD10   (0x01u<<ENETPHY_SMODE_OFFSET)
147     #define SMODE_ALL    (0x1fu<<ENETPHY_SMODE_OFFSET)
149 #define ENETPHY_CHNG_OFFSET    (ENETPHY_SMODE_OFFSET+ENETPHY_SMODE_SIZE)
150 #define ENETPHY_CHNG_SIZE      (1u)
151 #define ENETPHY_CHNG_MASK      (1u<<ENETPHY_CHNG_OFFSET)
152     #define ENETPHY_CHANGE (1u<<ENETPHY_CHNG_OFFSET)
154 #define ENETPHY_TIMEDOUT_OFFSET    (ENETPHY_CHNG_OFFSET+ENETPHY_CHNG_SIZE)
155 #define ENETPHY_TIMEDOUT_SIZE      (1u)     /*  30 Bits used */
156 #define ENETPHY_TIMEDOUT_MASK   ((uint32_t)(1u<<ENETPHY_TIMEDOUT_OFFSET))
157 #define ENETPHY_MDIX_SWITCH     ((uint32_t)(1u<<ENETPHY_TIMEDOUT_OFFSET))
159 #define ENETPHY_MDIX_OFFSET    (ENETPHY_TIMEDOUT_OFFSET+ENETPHY_TIMEDOUT_SIZE)
160 #define ENETPHY_MDIX_SIZE      (1u)     /*  31 Bits used */
161 #define ENETPHY_MDIX_MASK      ((uint32_t)(1u<<ENETPHY_MDIX_OFFSET))
162 #define ENETPHY_MDIX           ((uint32_t)(1u<<ENETPHY_MDIX_OFFSET))
165 #ifndef VOLATILE32
166 #define VOLATILE32(addr) (*((volatile uint32_t *)(addr)))
167 #endif
169 int32_t cpsw_g_speed_set = 0;
170 int32_t cpsw_g_soft_reset_status = 0;
172 /*User Calls*********************************************************       */
174 /* Updates book-keeping with info provided, programs ControlReg
175  * with clkdiv,enable bits*/
176 int32_t ENETPHY_Init(ENETPHY_Handle hPhyDev, uint32_t miibase, uint32_t inst, uint32_t PhyMask, uint32_t MLinkMask, uint32_t MdixMask, uint32_t PhyAddr, uint32_t ResetBit, uint32_t MdioBusFreq, uint32_t MdioClockFreq,int32_t verbose)
178   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
180   int32_t  ret =0 ;
181   uint32_t phy;
183   ((ENETPHY_DEVICE *) hPhyDev)->miibase   = miibase;
184   ((ENETPHY_DEVICE *) hPhyDev)->inst      = inst;
185   ((ENETPHY_DEVICE *) hPhyDev)->PhyMask   = PhyMask;
186   ((ENETPHY_DEVICE *) hPhyDev)->MLinkMask = MLinkMask;
187   ((ENETPHY_DEVICE *) hPhyDev)->MdixMask  = MdixMask;
189   (void)verbose;/* remove if not required */
191   *PhyState &= ~ENETPHY_MDIX_MASK;   /* Set initial State to MDI */
193   CSL_MDIO_setClkDivVal((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, (MdioBusFreq/MdioClockFreq - 1));
194   CSL_MDIO_enableFaultDetect((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
195   CSL_MDIO_disablePreamble((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
196   CSL_MDIO_enableStateMachine((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase);
198   ENETPHY_UserAccessRead(hPhyDev, ENETPHY_CNTRL_REG, PhyAddr, &phy);
199   phy |= NWAY_AUTOMDIX_ENABLE;
200   ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_CNTRL_REG,PhyAddr,phy);
202         (void)ResetBit; /* suppress warning */
204         *PhyState=INIT;
206     ret = 0;
208   return ret;
209 }/* end of function ENETPHY_Init*/
211 void ENETPHY_SetPhyMode(ENETPHY_Handle hPhyDev,uint32_t PhyMode)
212   {
213   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
214   uint32_t CurrentState;
216   ((ENETPHY_DEVICE *) hPhyDev)->PhyMode = PhyMode;   /* used for AUTOMIDX, planned to replace PhyState fields */
217   *PhyState &= (~ENETPHY_SMODE_MASK);
219   if (0u != (PhyMode & NWAY_LPBK))
220     {
221     *PhyState |= SMODE_LPBK;
222     }
223   if (0u != (PhyMode & NWAY_AUTO))
224     {
225      *PhyState |= SMODE_AUTO;
226     }
227   if (0u != (PhyMode & NWAY_FD1000) )
228     {
229     *PhyState |= SMODE_FD1000;
230     }
231   if (0u!= (PhyMode & NWAY_FD100))
232     {
233     *PhyState |= SMODE_FD100;
234     }
235   if (0u != (PhyMode & NWAY_HD100))
236     {
237     *PhyState |= SMODE_HD100;
238     }
239   if (0u != (PhyMode & NWAY_FD10))
240     {
241     *PhyState |= SMODE_FD10;
242     }
243   if (0u != (PhyMode & NWAY_HD10))
244     {
245     *PhyState |= SMODE_HD10;
246     }
248   CurrentState = (*PhyState) & ENETPHY_STATE_MASK;
249   if ( ((CurrentState == NWAY_START)|| (CurrentState == NWAY_WAIT)) ||
250        ( ((CurrentState == LINK_WAIT) || (CurrentState == LINKED) ) || (CurrentState == LOOPBACK)) )
251     {
252     *PhyState = ( (*PhyState)&(~ENETPHY_STATE_MASK)) | (FOUND | ENETPHY_CHANGE);
253     }
255      ENET_PHY_log("SetPhyMode:%08x Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d, FD1000:%d LPBK:%d\n", (unsigned int)PhyMode,
256      (unsigned int)(PhyMode & NWAY_AUTO), (unsigned int)(PhyMode & MII_NWAY_FD10),(unsigned int)(PhyMode & MII_NWAY_HD10),(unsigned int)(PhyMode & MII_NWAY_FD100),
257      (unsigned int)(PhyMode & MII_NWAY_HD100), (unsigned int)(PhyMode & NWAY_FD1000),
258      (unsigned int)(PhyMode & NWAY_LPBK)  );
260           }
262 uint32_t ENETPHY_GetPhyMode(ENETPHY_Handle hPhyDev)
264     uint32_t  PhyMode =0;
265     uint32_t  status_reg = 0,control_reg = 0,advertize_reg;
266     uint32_t  PhyNum,j;
267     uint32_t  PhyMask   = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
269     PhyNum = 0;
270     for(j = 1;PhyNum < 32;PhyNum++)
271     {
272       if( 0u != ( j & PhyMask))
273         {
274         break;
275         }
276       j = j<<1;
277     }
279     if(0u != _cpswIsGigPhy(hPhyDev))
280     {
281        /* read gig status */
282        ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, &control_reg);
283        /* read gig status */
284        ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_STATUS, PhyNum, &status_reg);
285     }
286     /* figure out if gig connected at FD 1000 or not first */
287     if ((0u != (control_reg & MII_NWAY_MY_FD1000)) && (0u != (status_reg & MII_NWAY_REM_FD1000)) )
288     {
289         PhyMode |= NWAY_FD1000;
290     }
292     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &control_reg);
293     if(0u != (control_reg & MII_AUTO_NEGOTIATE_EN)  )
294     {
295        PhyMode |= NWAY_AUTO;
296     }
297     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &status_reg);
298     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, &advertize_reg);
300     /* Check for 10/100 capabilities of PHYs */
301     if((0u != (control_reg & MII_ENETPHY_100))|| (0u != (PhyMode & NWAY_AUTO)) )
302     {
303        if(0u != (advertize_reg & MII_NWAY_FD100))
304             {
305             PhyMode |= NWAY_FD100;
306             }
307        if(0u != (advertize_reg & MII_NWAY_HD100))
308             {
309             PhyMode |= NWAY_HD100;
310             }
312     }
314     if(((control_reg & MII_ENETPHY_100) == 0) || (0u != (PhyMode & NWAY_AUTO)) )
315     {
316        if(0u != (advertize_reg & MII_NWAY_FD10))
317             {
318             PhyMode |= NWAY_FD10;
319             }
320        if(0u != (advertize_reg & MII_NWAY_HD10))
321             {
322             PhyMode |= NWAY_HD10;
323             }
325     }
326     return PhyMode;
328 /* ENETPHY_Tic is called every 10 mili seconds to process Phy states         */
330 int32_t ENETPHY_Tic(ENETPHY_Handle hPhyDev,uint32_t* mdioStatus)
332   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
333   uint32_t  CurrentState;
334   int32_t   ret = 0;
336   *mdioStatus = MDIO_EVENT_NOCHANGE;
338   /*Act on current state of the Phy */
339   CurrentState=*PhyState;
340   switch(CurrentState&ENETPHY_STATE_MASK)
341     {
342     case INIT:         ENETPHY_InitState(hPhyDev);      break;
343     case FINDING:      ENETPHY_FindingState(hPhyDev);   break;
344     case FOUND:        ENETPHY_FoundState(hPhyDev);     break;
345     case NWAY_START:   ENETPHY_NwayStartState(hPhyDev); break;
346     case NWAY_WAIT:    ENETPHY_NwayWaitState(hPhyDev);  break;
347     case LINK_WAIT:    ENETPHY_LinkWaitState(hPhyDev);  break;
348     case LINKED:       ENETPHY_LinkedState(hPhyDev);    break;
349     case LOOPBACK:     ENETPHY_LoopbackState(hPhyDev);  break;
350     default:           ENETPHY_DefaultState(hPhyDev);   break;
351     }
353   /*  Check is MDI/MDIX mode switch is needed */
355   if(0u != ((*PhyState) & ENETPHY_MDIX_SWITCH) )
356     {
358     uint32_t Mdix;
360     *PhyState &= (~ENETPHY_MDIX_SWITCH);  /* Clear Mdix Flip indicator */
362     if(0u != ((*PhyState) & ENETPHY_MDIX))
363         {
364       Mdix = 1;
365         }
366     else
367         {
368       Mdix = 0;
369     }
370     ret = (int32_t)(_MIIMDIO_MDIXFLIP | Mdix);
372     }
373   else
374     {
376   /*Return state change to user */
377   /** CHECK : report MDIO_LINKEVENTS as MDIO_EVENT_NOCHANGE, MDIO_EVENT_LINKDOWN,
378    * MDIO_EVENT_PHYERROR,MDIO_EVENT_LINKUP
379    * Currently ENETPHY_CHNG_MASK set for any state transition*/
381     if (0u != ((*PhyState) & ENETPHY_CHNG_MASK))
382    {
383         if(  ( ((*PhyState) & ENETPHY_STATE_MASK) == LINKED) && ((CurrentState & ENETPHY_STATE_MASK) != LINKED) )
384                 {
385                 /* we have just entered LInked state */
386                 *mdioStatus = MDIO_EVENT_LINKUP;
387                 }
388         if(  ((CurrentState & ENETPHY_STATE_MASK) == LINKED) && ( ( (*PhyState) & ENETPHY_STATE_MASK) != LINKED))
389                 {
390                 /* we started in Linked state and we have a state change */
391                 *mdioStatus = MDIO_EVENT_LINKDOWN;
392                 }
393         *PhyState &= (~ENETPHY_CHNG_MASK);
394         ret = (int32_t)(TRUE);
395     }
396    else
397    {
398         ret = (int32_t)(FALSE);
399         }
400     }
402   return ret;
407 void ENETPHY_LinkChange(ENETPHY_Handle hPhyDev)
408   {
409   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
410   uint32_t  PhyNum,PhyStatus;
412   PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
414   ENET_PHY_log("ENETPHY_LinkChange: PhyNum = %d\n", (unsigned int)PhyNum);
416   if (0u != (ENETPHY_GetLinked(hPhyDev)) )
417     {
418     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
420     if ((PhyStatus & MII_ENETPHY_LINKED) == 0u)
421       {
422       *PhyState &= (~(ENETPHY_TIM_MASK | ENETPHY_STATE_MASK));
423       if (0u!=((*PhyState) & SMODE_AUTO))
424         {
425         ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN|MII_RENEGOTIATE);
426         *PhyState |= ((ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
427         }
428        else
429         {
430         *PhyState|= ((ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
431         }
432       }
433     }
434   }
436   /* returns 0 if current Phy has AutoMdix support, otherwise 0 */
437 static int32_t ENETPHY_MdixSupported(ENETPHY_Handle hPhyDev)
438   {
439   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
440   uint32_t PhyNum;
441   int32_t ret;
443   if((((ENETPHY_DEVICE *) hPhyDev)->PhyMode & NWAY_AUTOMDIX) == 0)
444   {
445     ret = (0);  /* AutoMdix not turned on */
446   }
447   else
448   {
449     PhyNum = ((*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
450   if( ((1<<PhyNum) & ((ENETPHY_DEVICE *) hPhyDev)->MdixMask) == 0)
451     {
452         ret = 0;  /*  Phy does not support AutoMdix*/
453     }
455     ret = 1;
456   }
457   return ret;
458   }
460 /* If current Phy has AutoMdix support add Mdix Delay to the Timer State Value */
461 static void ENETPHY_MdixDelay(ENETPHY_Handle hPhyDev)
462   {
463   uint32_t Delay;
464   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
467   if(ENETPHY_MdixSupported(hPhyDev) != 0)
468     {
469   /* Get the Delay value in milli-seconds and convert to ten-milli second value */
470   Delay = cpswRandomRange(_AUTOMDIX_DELAY_MIN, _AUTOMDIX_DELAY_MAX);
471   Delay /= 10;
473   /*  Add AutoMidx Random Switch Delay to AutoMdix Link Delay */
475   Delay += (ENETPHY_MDIX_TO>>ENETPHY_TIM_OFFSET);
477   /* Change Timeout value to AutoMdix standard */
478     *PhyState &= (~(ENETPHY_TIM_MASK));  /* Clear current Time out value */
479   *PhyState |=  (Delay<<ENETPHY_TIM_OFFSET);     /* Set new value */
480     }
481   return;
483   }
485 void ENETPHY_DisablePhy(ENETPHY_Handle hPhyDev,uint32_t PhyNum)
486   {
487   ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, (MII_ENETPHY_ISOLATE | MII_ENETPHY_PDOWN) );
489   ENET_PHY_log("ENETPHY_DisablePhy(%d)\n",(unsigned int)PhyNum);
491   }
493 void ENETPHY_InitState(ENETPHY_Handle hPhyDev)
494   {
495   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
496   uint32_t CurrentState;
498   CurrentState=*PhyState;
499   CurrentState = (CurrentState & (~ENETPHY_TIM_MASK)) | (ENETPHY_FIND_TO);
500   CurrentState=(CurrentState & (~ENETPHY_STATE_MASK)) | (FINDING);
501   CurrentState=(CurrentState & (~ENETPHY_SPEED_MASK_NDK));
502   CurrentState=(CurrentState & (~ENETPHY_DUPLEX_MASK));
503   CurrentState|=ENETPHY_CHANGE;
505   *PhyState=CurrentState;
507   }
509 void ENETPHY_FindingState(ENETPHY_Handle hPhyDev)
510   {
511   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
512   uint32_t  PhyMask  = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
513   uint32_t  PhyNum,i,j;
515   PhyNum=ENETPHY_NOT_FOUND;
517   if (0u!= ((*PhyState) & ENETPHY_TIM_MASK))
518     {
519     *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK) ) | (( (*PhyState) & ENETPHY_TIM_MASK) - (1 << ENETPHY_TIM_OFFSET));
520     }
521    else
522     {
523     j =1;
524     for(i=0; i<32; i++)
525         {
526         if( PhyMask & j)
527             {
528             if( CSL_MDIO_isPhyAlive((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, i))
529                 {
530                     PhyNum=i;
531                     break;
532                 }
533             }
534         j = j << 1;
535         }
536     if (PhyNum!=ENETPHY_NOT_FOUND)
537       {
538       /*  Phy Found! */
539       *PhyState = ((*PhyState) & (~ENETPHY_DEV_MASK) ) | ((PhyNum & ENETPHY_DEV_MASK) << ENETPHY_DEV_OFFSET);
540       *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK) ) | (FOUND);
541       *PhyState|=ENETPHY_CHANGE;
543       ENET_PHY_log("ENETPHY_FindingState: PhyNum: %d\n",(unsigned int)PhyNum);
545       }
546      else
547       {
549       ENET_PHY_log("ENETPHY_FindingState: Timed Out looking for a Phy!\n");
550       *PhyState|=ENETPHY_RECK_TO;  /* Set Timer */
551       }
552     }
553   }
555 void ENETPHY_FoundState(ENETPHY_Handle hPhyDev)
556  {
557   uint32_t *PhyState  = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
558   uint32_t  PhyMask   = ((ENETPHY_DEVICE *) hPhyDev)->PhyMask;
559   uint32_t  MLinkMask = ((ENETPHY_DEVICE *) hPhyDev)->MLinkMask;
560   uint32_t  PhyNum,PhyStatus,NWAYadvertise,NWAY1000advertise=0,m,phynum,i,j;
561   uint32_t PhyDummy;
563   static  uint32_t auto_neg1 = 0xFFFFFFFF,auto_neg2= 0xFFFFFFFF;
566   if (( (*PhyState) & ENETPHY_SMODE_MASK) == 0)
567     {
568     return;
569     }
571   PhyNum = ((*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
572     j =1;
573     for(phynum=0; phynum<32; phynum++)
574         {
575         if(0u!= (PhyMask & j))
576             {
577             if( CSL_MDIO_isPhyAlive((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, phynum))
578                 {
579                     ENETPHY_DisablePhy(hPhyDev,phynum);
580                 }
581             }
582         j = j << 1;
583         }
584   /* If Aries SWR2 reset then don't reset phy*/
585   /*  Reset the Phy and proceed with auto-negotiation */
586   if(( 0u != cpsw_g_speed_set) || ((0u ==cpsw_g_soft_reset_status) || ((auto_neg1 & (1 << PhyNum)) == 0) )  )
587   {
588       ENETPHY_ResetPhy(hPhyDev,PhyNum);
589   }
591   /*  Set the way Link will be Monitored */
592   /* Check the Link Selection Method */
593   if (0u != ((1 << PhyNum) & MLinkMask) )
594     {
595   CSL_MDIO_enableLinkStatusChangeInterrupt((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase,  ((ENETPHY_DEVICE *) hPhyDev)->inst, PhyNum);
596     }
597     else
598     {
599   CSL_MDIO_disableLinkStatusChangeInterrupt((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase,  ((ENETPHY_DEVICE *) hPhyDev)->inst, PhyNum);
600     }
601   /* Get the Phy Status */
602   ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
605  /*  For Phy Internal loopback test, need to wait until Phy
606       found, then set Loopback */
607   if (0u != ((*PhyState) & SMODE_LPBK))
608     {
609     /* Set Phy in Loopback */
611     ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_ENETPHY_LOOP|MII_ENETPHY_FD);
612     /* Do a read to ensure ENETPHY_LOOP has completed */
613     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyDummy);
614     *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK) ) | (LOOPBACK);
615     *PhyState|=ENETPHY_CHANGE;
616     return;
617     }
619   ENET_PHY_log("Enable Phy to negotiate external connection\n");
622   NWAYadvertise=MII_NWAY_SEL;
623   if (0u != ((*PhyState) & SMODE_FD100))
624   {
625     NWAYadvertise |= MII_NWAY_FD100;
626     }
627   if (0u != ((*PhyState) & SMODE_HD100))
628     {
629     NWAYadvertise |= MII_NWAY_HD100;
630     }
631   if (0u != ((*PhyState) & SMODE_FD10))
632     {
633     NWAYadvertise |= MII_NWAY_FD10;
634     }
635   if (0u != ((*PhyState) & SMODE_HD10))
636     {
637     NWAYadvertise |= MII_NWAY_HD10;
638     }
639   if (0u != ((*PhyState) & SMODE_FD1000))
640     {
641           NWAY1000advertise= ENETPHY_1000BT_FD;
642     }
644   *PhyState &= ( ~(ENETPHY_TIM_MASK | ENETPHY_STATE_MASK));
645   if ((0u != (PhyStatus & MII_NWAY_CAPABLE)) && (0u != ( (*PhyState) & SMODE_AUTO)) )   /*NWAY Phy Detected*/
646   {
647     if(( 0u != cpsw_g_speed_set) || ((0u ==cpsw_g_soft_reset_status) || ((auto_neg1 & (1 << PhyNum)) == 0) )  )
648     {
649        /*For NWAY compliant Phys                                                */
650         ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, NWAYadvertise);
651        /* for gig negotiation */
652       if(0u != _cpswIsGigPhy(hPhyDev))
653       {
654           ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, NWAY1000advertise);
655       }
657       ENET_PHY_log("NWAY Advertising: ");
658       if (0u != ((*PhyState) & SMODE_FD1000))
659         {
660         ENET_PHY_log("FullDuplex-1000 ");
661         }
662       if (0u != (NWAYadvertise & MII_NWAY_FD100))
663         {
664         ENET_PHY_log("FullDuplex-100 ");
665         }
666       if (0u != (NWAYadvertise & MII_NWAY_HD100))
667         {
668         ENET_PHY_log("HalfDuplex-100 ");
669         }
670       if (0u != (NWAYadvertise & MII_NWAY_FD10))
671         {
672         ENET_PHY_log("FullDuplex-10 ");
673         }
674       if (0u != (NWAYadvertise & MII_NWAY_HD10))
675         {
676         ENET_PHY_log("HalfDuplex-10 ");
677         }
679       ENET_PHY_log("\n");
681       ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN );
682       ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, MII_AUTO_NEGOTIATE_EN|MII_RENEGOTIATE|MII_ENETPHY_FD);
683      *PhyState|= ( (ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
684     }
685     else
686     {
687       *PhyState |= ( (ENETPHY_CHANGE | ENETPHY_NWST_TO) | NWAY_START);
688       auto_neg1 = auto_neg1 & (~(1 << PhyNum));
689     }
690   }
691   else
692   {
693     *PhyState &= (~SMODE_AUTO);   /*The Phy is not capable of auto negotiation!  */
694     m=NWAYadvertise;
695     j = 0x8000u;
697     for(i=0;(i<16);i++)
698     {
699         if(0u != (j & m))
700         {
701             break;
702         }
703         j = j >> 1 ;
705     }
706     m=j;
707     j=0;
709     /* figure out if gig connected at FD 1000 or not first */
710     if ((NWAY1000advertise & MII_NWAY_MY_FD1000)== MII_NWAY_MY_FD1000)
711     {
712          j = MII_ENETPHY_1000;
713          j |= MII_ENETPHY_FD;
714     }
715     else
716     {
717         if (0u != (m & (MII_NWAY_FD100 | MII_NWAY_HD100)) )
718         {
719            j=MII_ENETPHY_100;
720            m&=(MII_NWAY_FD100|MII_NWAY_HD100);
721         }
722         if (0u != (m & (MII_NWAY_FD100 | MII_NWAY_FD10)) )
723             {
724            j |= MII_ENETPHY_FD;
725     }
726     }
728     ENET_PHY_log("Requested PHY mode %s Duplex %s Mbps\n",(j & MII_ENETPHY_FD) ? "Full":"Half",
729                         (j & MII_ENETPHY_1000) ? "1000":((j & MII_ENETPHY_100) ? "100":"10"));
731     if((0u != cpsw_g_speed_set) || ( (0u == cpsw_g_soft_reset_status) || ((auto_neg2 & (1 << PhyNum)) == 0) ))
732     {
733        if(0u != (j & MII_ENETPHY_1000))
734        {
735           ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, j);
736        }
737        else
738        {
739            ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, j);
740            ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, NWAYadvertise);
741        }
742        cpsw_g_speed_set = 0;
743     }
744     else
745     {
746        auto_neg2 = auto_neg2 & (~(1 << PhyNum));
747     }
748     *PhyState &= (~ENETPHY_SPEED_MASK_NDK);
749     if(0u != (j & MII_ENETPHY_1000) )
750     {
751         *PhyState|=(1<<ENETPHY_DUPLEX_OFFSET);
752         ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 1;
753     }
754     else
755     {
756         ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 0;
757     }
758     if (0u != (j & MII_ENETPHY_100) )
759     {
760        *PhyState|=(1<<ENETPHY_SPEED_OFFSET);
761     }
762     *PhyState &= (~ENETPHY_DUPLEX_MASK);
763     if (0u != (j & MII_ENETPHY_FD) )
764     {
765        *PhyState|=(1<<ENETPHY_DUPLEX_OFFSET);
766     }
767     *PhyState |= ((ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
768   }
769     ENETPHY_MdixDelay(hPhyDev);  /* If AutoMdix add delay */
771   }
773 void ENETPHY_ResetPhy(ENETPHY_Handle hPhyDev,uint32_t PhyNum)
774   {
775     uint32_t data;
777     data = MII_ENETPHY_RESET;
779     /* Reset the phy */
780     ENETPHY_UserAccessWrite(hPhyDev, ENETPHY_BCR, PhyNum, data);
782     /* wait till the reset bit is auto cleared */
783     while(data & MII_ENETPHY_RESET)
784     {
785         /* Read the reset */
786         if(ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &data) != TRUE)
787         {
788             break;
789         }
790     }
792   }
794 void ENETPHY_NwayStartState(ENETPHY_Handle hPhyDev)
795   {
796   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
797   uint32_t PhyNum,PhyMode,PhyDummy;
799   PhyNum = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
801   /*Wait for Negotiation to start                                            */
803   ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BCR, PhyNum, &PhyMode);
805   if((PhyMode&MII_RENEGOTIATE)==0)
806     {
807     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum,&PhyDummy); /*Flush pending latch bits*/
808     *PhyState &= (~(ENETPHY_STATE_MASK|ENETPHY_TIM_MASK));
809     *PhyState |= ((ENETPHY_CHANGE | NWAY_WAIT) |ENETPHY_NWDN_TO);
810     ENETPHY_MdixDelay(hPhyDev);  /* If AutoMdix add delay */
811     }
812    else
813     {
814     if (0u != ((*PhyState) & ENETPHY_TIM_MASK) )
815         {
816         *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK)) | ( ( (*PhyState) & ENETPHY_TIM_MASK)-(1 << ENETPHY_TIM_OFFSET));
817         }
818      else
819         {
820       ENETPHY_PhyTimeOut(hPhyDev);
821     }
822   }
823   }
825 void ENETPHY_NwayWaitState(ENETPHY_Handle hPhyDev)
826   {
827   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
828   uint32_t  PhyNum,PhyStatus,NWAYadvertise = 0,NWAYREadvertise = 0,NegMode,i,j;
829   uint32_t NWAY1000advertise = 0, NWAY1000REMadvertise = 0;
831   PhyNum=( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
833   ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
835   if (0u != (PhyStatus & MII_NWAY_COMPLETE))
836     {
837     *PhyState|=ENETPHY_CHANGE;
838     *PhyState &= (~ENETPHY_SPEED_MASK_NDK);
839     *PhyState &= (~ENETPHY_DUPLEX_MASK);
841     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_AUTONEG_ADV, PhyNum, &NWAYadvertise);
842     ENETPHY_UserAccessRead(hPhyDev, ENETPHY_LINK_PARTNER_ABLTY, PhyNum, &NWAYREadvertise);
843     /* read gig status */
844     if(0u != _cpswIsGigPhy(hPhyDev))
845     {
846         ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_CONTROL, PhyNum, &NWAY1000advertise);
847         ENETPHY_UserAccessRead(hPhyDev, ENETPHY_1000BT_STATUS, PhyNum, &NWAY1000REMadvertise);
848     }
850     /* figure out if gig connected at FD 1000 or not first */
851     if ((0u !=(NWAY1000advertise & MII_NWAY_MY_FD1000)) && (0u!=(NWAY1000REMadvertise & MII_NWAY_REM_FD1000)) )
852         {
853       NegMode = MII_NWAY_MY_FD1000;
854         }
855     else
856         {
857         NegMode = 0u;
858         }
860     if (NegMode == 0u)
861       {
862         /* continue checking for 100 and 10 connection */
864         /* Negotiated mode is we and the remote have in common */
865         NegMode = NWAYadvertise & NWAYREadvertise;
867         ENET_PHY_log("Phy: %d, ",(unsigned int)( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET);
868         ENET_PHY_log("NegMode %04X, NWAYadvertise %04X, NWAYREadvertise %04X\n",
869                    (unsigned int)NegMode,  (unsigned int)NWAYadvertise, (unsigned int)NWAYREadvertise);
871         /* Limit negotiation to fields below */
872         NegMode &= ( (MII_NWAY_FD100|MII_NWAY_HD100) | (MII_NWAY_FD10|MII_NWAY_HD10));
874         if (NegMode == 0u)
875           {
876             NegMode=(MII_NWAY_HD100|MII_NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/
877           }
879         j = 0x8000u;
880         for(i = 0; i <16 ; i++)
881         {
882             if (0u != (j & NegMode))
883             {
884                 break;
885             }
886             j = j >> 1;
887         }
889         NegMode=j;
892         ENET_PHY_log("Negotiated connection: ");
895         if (0u != (NegMode & MII_NWAY_FD100))
896             {
897                 ENET_PHY_log("FullDuplex 100 Mbs\n");
898             }
899         if (0u != (NegMode & MII_NWAY_HD100))
900             {
901             ENET_PHY_log("HalfDuplex 100 Mbs\n");
902             }
903         if (0u != (NegMode & MII_NWAY_FD10))
904             {
905             ENET_PHY_log("FullDuplex 10 Mbs\n");
906             }
907         if (0u != (NegMode & MII_NWAY_HD10))
908             {
909             ENET_PHY_log("HalfDuplex 10 Mbs\n");
910             }
912         ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 0u;
913       }
914     else
915       {
917         /* found 1000 negotiated connection! */
918         ENET_PHY_log("Negotiated connection: ");
919         ENET_PHY_log("FullDuplex 1000 Mbs\n");
921         ((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 = 1u;
922       }
924     if (NegMode != 0u)
925       {
926       if (0u != (PhyStatus & MII_ENETPHY_LINKED))
927         {
928         *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK)) | LINKED;
929         }
930        else
931         {
932         *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK)) | LINK_WAIT;
933         }
934       if (0u != (NegMode & (MII_NWAY_FD100 | MII_NWAY_HD100)) )
935         {
936         *PhyState=( (*PhyState) & (~ENETPHY_SPEED_MASK_NDK)) | (1 << ENETPHY_SPEED_OFFSET);
937         }
938       if (0u != (NegMode & (MII_NWAY_FD100 | MII_NWAY_FD10 | MII_NWAY_MY_FD1000)))
939         {
940         *PhyState=( (*PhyState) & (~ENETPHY_DUPLEX_MASK)) | (1 << ENETPHY_DUPLEX_OFFSET);
941         }
942       }
943     }
944    else
945     {
946     if ( 0u != ( (*PhyState) & ENETPHY_TIM_MASK) )
947         {
948         *PhyState=( (*PhyState) & (~ENETPHY_TIM_MASK)) | (( (*PhyState) & ENETPHY_TIM_MASK)-(1 << ENETPHY_TIM_OFFSET));
949         }
950      else
951         {
952       ENETPHY_PhyTimeOut(hPhyDev);
953     }
954   }
956   }
958 void ENETPHY_LinkWaitState(ENETPHY_Handle hPhyDev)
959   {
960   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
961   uint32_t  PhyStatus;
962   uint32_t  PhyNum;
964   PhyNum=( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
966   ENETPHY_UserAccessRead(hPhyDev, ENETPHY_BSR, PhyNum, &PhyStatus);
968   if (0u != (PhyStatus & MII_ENETPHY_LINKED) )
969     {
970     *PhyState=( (*PhyState) & (~ENETPHY_STATE_MASK) ) | LINKED;
971     *PhyState|=ENETPHY_CHANGE;
972     }
973    else
974     {
975     if (0u != ( (*PhyState) & ENETPHY_TIM_MASK)  )
976         {
977       *PhyState=(*PhyState&~ENETPHY_TIM_MASK)|((*PhyState&ENETPHY_TIM_MASK)-(1<<ENETPHY_TIM_OFFSET));
978         }
979      else
980         {
981       ENETPHY_PhyTimeOut(hPhyDev);
982     }
983   }
984   }
986 void ENETPHY_PhyTimeOut(ENETPHY_Handle hPhyDev)
987   {
988   uint32_t *PhyState;
989   if(ENETPHY_MdixSupported(hPhyDev) == 0)
990     {
991     return;  /* AutoMdix not supported */
992     }
993   PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
995   /*  Indicate MDI/MDIX mode switch is needed */
996   *PhyState|=ENETPHY_MDIX_SWITCH;
998   /* Toggle the MDIX mode indicatir */
999   if(0u != ( (*PhyState) & ENETPHY_MDIX) )
1000     {
1001     *PhyState &= (~ENETPHY_MDIX_MASK);       /* Current State is MDIX, set to MDI */
1002     }
1003   else
1004     {
1005     *PhyState |=  ENETPHY_MDIX_MASK;      /* Current State is MDI, set to MDIX */
1006     }
1007   /* Reset state machine to FOUND */
1008   *PhyState = ( (*PhyState) & (~ENETPHY_STATE_MASK)) | (FOUND);
1009   }
1011 void ENETPHY_LoopbackState(ENETPHY_Handle hPhyDev)
1013     (void)((ENETPHY_DEVICE *) hPhyDev); /* remove if not needed, to avoid warning */
1014   return;
1017 void ENETPHY_LinkedState(ENETPHY_Handle hPhyDev)
1018   {
1019   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1020   uint32_t  PhyNum   = ( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET;
1022   if (CSL_MDIO_isPhyLinked((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, PhyNum))
1023     {
1024      return;  /* if still Linked, exit*/
1025     }
1027   /* Not Linked */
1028   *PhyState &= (~(ENETPHY_STATE_MASK | ENETPHY_TIM_MASK));
1029   if (0u != ( (*PhyState) & SMODE_AUTO) )
1030   {
1031     *PhyState |= ( (ENETPHY_CHANGE | NWAY_WAIT) | ENETPHY_NWDN_TO);
1032   }
1033    else
1034     {
1035     *PhyState |= ( (ENETPHY_CHANGE | ENETPHY_LINK_TO) | LINK_WAIT);
1036     }
1037   ENETPHY_MdixDelay(hPhyDev);  /* If AutoMdix add delay */
1039   }
1041 void ENETPHY_DefaultState(ENETPHY_Handle hPhyDev)
1042   {
1043   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1044   /*Awaiting a ENETPHY_Init call                                             */
1045   *PhyState|=ENETPHY_CHANGE;
1046   }
1048 /* Simple Query Functions for reporting speed,duplex */
1049 /* ENETPHY_GetDuplex is called to retrieve the Duplex info */
1050 int32_t ENETPHY_GetDuplex(ENETPHY_Handle hPhyDev)
1051   {
1052   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1053   return(( (*PhyState) & ENETPHY_DUPLEX_MASK) ? 1:0);  /* return 0 or a 1  */
1054   }
1056 /* ENETPHY_GetSpeed is called to retreive the Speed info */
1057 int32_t ENETPHY_GetSpeed(ENETPHY_Handle hPhyDev)
1058   {
1059   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1060   int32_t ret = 0 ;
1062   if (((ENETPHY_DEVICE *) hPhyDev)->SPEED_1000 == 1)
1063     {
1064     ret = 2; /* if we are linked at 1000, we return a value of 2 */
1065     }
1066   else
1067     {
1068     ret = ( (*PhyState) & ENETPHY_SPEED_MASK_NDK);
1069     }
1071   return ret;
1072   }
1074 /* ENETPHY_GetPhyNum is called to retreive the Phy Device Adr info*/
1075 int32_t ENETPHY_GetPhyNum(ENETPHY_Handle hPhyDev)
1076   {
1077   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1078   return((int32_t)(( (*PhyState) & ENETPHY_DEV_MASK) >> ENETPHY_DEV_OFFSET));
1079   }
1081 /* ENETPHY_GetLoopback is called to Determine if the LOOPBACK state has been reached*/
1082 int32_t ENETPHY_GetLoopback(ENETPHY_Handle hPhyDev)
1083   {
1084   uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1085   return(( (*PhyState) & ENETPHY_STATE_MASK) == LOOPBACK);
1086   }
1088 /* ENETPHY_GetLinked is called to Determine if the LINKED state has been reached*/
1089 int32_t ENETPHY_GetLinked(ENETPHY_Handle hPhyDev)
1090   {
1091     uint32_t *PhyState = &((ENETPHY_DEVICE *) hPhyDev)->PhyState;
1092     return (( (*PhyState) & ENETPHY_STATE_MASK) == LINKED);
1093   }
1095 /************************************
1096 ***
1097 *** Waits for MDIO_USERACCESS to be ready and reads data
1098 *** If 'WaitForData' set, waits for read to complete and returns Data,
1099 *** otherwise returns 0
1100 *** Note: 'data' is 16 bits but we use 32 bits
1101 ***        to be consistent with rest of the code.
1102 ***
1103 **************************************/
1104 uint32_t ENETPHY_UserAccessRead(ENETPHY_Handle hPhyDev, uint32_t regadr, uint32_t phyadr, uint32_t *data)
1105   {
1106     CSL_MDIO_USERACCESS    user_access_reg;
1108     /* Wait till transaction completion if any */
1109     do
1110     {
1111         CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1112     }
1113     while(user_access_reg.go);
1115     user_access_reg.phyAddr = phyadr;
1116     user_access_reg.regAddr = regadr;
1117     user_access_reg.write = 0U;
1118     user_access_reg.go = 1U;
1120     CSL_MDIO_setUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0U, &user_access_reg);
1122     /* wait for command completion */
1123     do
1124     {
1125         CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1126     }
1127     while(user_access_reg.go);
1129     CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1130     /* Store the data if the read is acknowledged */
1131     if(user_access_reg.ack)
1132     {
1133         *data = user_access_reg.data & MDIO_USERACCESS_DATA;
1134         return 1u;
1135     }
1137     return 0u;
1138   }
1141 /************************************
1142 ***
1143 *** Waits for MDIO_USERACCESS to be ready and writes data
1144 ***
1145 **************************************/
1146 void ENETPHY_UserAccessWrite(ENETPHY_Handle hPhyDev, uint32_t regadr, uint32_t phyadr, uint32_t data)
1147   {
1148     CSL_MDIO_USERACCESS    user_access_reg;
1150     /* Wait till transaction completion if any */
1151     do
1152     {
1153         CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1154     }
1155     while(user_access_reg.go);
1157     user_access_reg.phyAddr = phyadr;
1158     user_access_reg.regAddr = regadr;
1159     user_access_reg.write = 1U;
1160     user_access_reg.go = 1U;
1161     user_access_reg.data = data;
1163     CSL_MDIO_setUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0U, &user_access_reg);
1165     /* wait for command completion */
1166     do
1167     {
1168         CSL_MDIO_getUserAccessRegister((CSL_mdioHandle) ((ENETPHY_DEVICE *) hPhyDev)->miibase, 0, &user_access_reg);
1169     }
1170     while(user_access_reg.go);
1171   }