]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/macb.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / AtmelFiles / libboard_sama5d3x-ek / source / macb.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /** \file */\r
31 \r
32 /*---------------------------------------------------------------------------\r
33  *         Headers\r
34  *---------------------------------------------------------------------------*/\r
35 \r
36 #include <board.h>\r
37 \r
38 /*---------------------------------------------------------------------------\r
39  *         Definitions\r
40  *---------------------------------------------------------------------------*/\r
41 \r
42 /** Default max retry count */\r
43 #define MACB_RETRY_MAX            1000000\r
44 \r
45 /*---------------------------------------------------------------------------\r
46  *         Local functions\r
47  *---------------------------------------------------------------------------*/\r
48 \r
49 /**\r
50  * Wait PHY operation complete.\r
51  * Return 1 if the operation completed successfully.\r
52  * May be need to re-implemented to reduce CPU load.\r
53  * \param retry: the retry times, 0 to wait forever until complete.\r
54  */\r
55 static uint8_t EMAC_WaitPhy( Emac *pHw, uint32_t retry )\r
56 {\r
57     volatile uint32_t retry_count = 0;\r
58 \r
59     while (!EMAC_IsIdle(pHw))\r
60     {\r
61         if(retry == 0) continue;\r
62         retry_count ++;\r
63         if (retry_count >= retry)\r
64         {\r
65             return 0;\r
66         }\r
67     }\r
68     return 1;\r
69 }\r
70 \r
71 /**\r
72  * Read PHY register.\r
73  * Return 1 if successfully, 0 if timeout.\r
74  * \param pHw HW controller address\r
75  * \param PhyAddress PHY Address\r
76  * \param Address Register Address\r
77  * \param pValue Pointer to a 32 bit location to store read data\r
78  * \param retry The retry times, 0 to wait forever until complete.\r
79  */\r
80 static uint8_t EMAC_ReadPhy(Emac *pHw,\r
81                             uint8_t PhyAddress,\r
82                             uint8_t Address,\r
83                             uint32_t *pValue,\r
84                             uint32_t retry)\r
85 {\r
86     EMAC_PHYMaintain(pHw, PhyAddress, Address, 1, 0);\r
87     if ( EMAC_WaitPhy(pHw, retry) == 0 )\r
88     {\r
89         TRACE_ERROR("TimeOut EMAC_ReadPhy\n\r");\r
90         return 0;\r
91     }\r
92     *pValue = EMAC_PHYData(pHw);\r
93     return 1;\r
94 }\r
95 \r
96 /**\r
97  * Write PHY register\r
98  * Return 1 if successfully, 0 if timeout.\r
99  * \param pHw HW controller address\r
100  * \param PhyAddress PHY Address\r
101  * \param Address Register Address\r
102  * \param Value Data to write ( Actually 16 bit data )\r
103  * \param retry The retry times, 0 to wait forever until complete.\r
104  */\r
105 static uint8_t EMAC_WritePhy(Emac *pHw,\r
106                              uint8_t PhyAddress,\r
107                              uint8_t Address,\r
108                              uint32_t  Value,\r
109                              uint32_t  retry)\r
110 {\r
111     EMAC_PHYMaintain(pHw, PhyAddress, Address, 0, Value);\r
112     if ( EMAC_WaitPhy(pHw, retry) == 0 )\r
113     {\r
114         TRACE_ERROR("TimeOut EMAC_WritePhy\n\r");\r
115         return 0;\r
116     }\r
117     return 1;\r
118 }\r
119 \r
120 /*---------------------------------------------------------------------------\r
121  *         Exported functions\r
122  *---------------------------------------------------------------------------*/\r
123 \r
124 /**\r
125  * Find a valid PHY Address ( from addrStart to 31 ).\r
126  * Check BMSR register ( not 0 nor 0xFFFF )\r
127  * Return 0xFF when no valid PHY Address found.\r
128  * \param pMacb Pointer to the MACB instance\r
129  */\r
130 uint8_t MACB_FindValidPhy(Macb *pMacb, uint8_t addrStart)\r
131 {\r
132     sEmacd *pDrv = pMacb->pEmacd;\r
133     Emac *pHw = pDrv->pHw;\r
134 \r
135     uint32_t  retryMax;\r
136     uint32_t  value=0;\r
137     uint8_t rc;\r
138     uint8_t phyAddress;\r
139     uint8_t cnt;\r
140 \r
141     TRACE_DEBUG("MACB_FindValidPhy\n\r");\r
142 \r
143     EMAC_ManagementEnable(pHw, 1);\r
144 \r
145     phyAddress = pMacb->phyAddress;\r
146     retryMax = pMacb->retryMax;\r
147 \r
148     /* Check current phyAddress */\r
149     rc = phyAddress;\r
150     if( EMAC_ReadPhy(pHw, phyAddress, MII_PHYID1, &value, retryMax) == 0 )\r
151     {\r
152         TRACE_ERROR("MACB PROBLEM\n\r");\r
153     }\r
154     TRACE_DEBUG("_PHYID1  : 0x%X, addr: %d\n\r", value, phyAddress);\r
155 \r
156     /* Find another one */\r
157     if (value != MII_OUI_MSB)\r
158     {\r
159         rc = 0xFF;\r
160         for(cnt = 0; cnt < 32; cnt ++)\r
161         {\r
162             phyAddress = (phyAddress + 1) & 0x1F;\r
163             if( EMAC_ReadPhy(pHw, phyAddress, MII_PHYID1, &value, retryMax) == 0 )\r
164             {\r
165                 TRACE_ERROR("MACB PROBLEM\n\r");\r
166             }\r
167             TRACE_DEBUG("_PHYID1  : 0x%X, addr: %d\n\r", value, phyAddress);\r
168             if (value == MII_OUI_MSB)\r
169             {\r
170                 rc = phyAddress;\r
171                 break;\r
172             }\r
173         }\r
174     }\r
175 \r
176     EMAC_ManagementEnable(pHw, 0);\r
177 \r
178     if (rc != 0xFF)\r
179     {\r
180 \r
181         printf("** Valid PHY Found: %d\n\r", rc);\r
182         EMAC_ReadPhy(pHw, phyAddress, MII_DSCSR, &value, retryMax);\r
183         TRACE_DEBUG("_DSCSR  : 0x%X, addr: %d\n\r", value, phyAddress);\r
184 \r
185     }\r
186     return rc;\r
187 }\r
188 \r
189 /**\r
190  * Dump all the useful registers\r
191  * \param pMacb          Pointer to the MACB instance\r
192  */\r
193 void MACB_DumpRegisters(Macb *pMacb)\r
194 {\r
195     sEmacd *pDrv = pMacb->pEmacd;\r
196     Emac *pHw = pDrv->pHw;\r
197 \r
198     uint8_t phyAddress;\r
199     uint32_t retryMax;\r
200     uint32_t value;\r
201 \r
202     TRACE_INFO("MACB_DumpRegisters\n\r");\r
203 \r
204     EMAC_ManagementEnable(pHw, 1);\r
205 \r
206     phyAddress = pMacb->phyAddress;\r
207     retryMax = pMacb->retryMax;\r
208 \r
209     TRACE_INFO("%cMII MACB (@%d) Registers:\n\r",\r
210         pMacb->RMII ? 'R' : ' ',\r
211         phyAddress);\r
212 \r
213     EMAC_ReadPhy(pHw, phyAddress, MII_BMCR, &value, retryMax);\r
214     TRACE_INFO(" _BMCR   : 0x%X\n\r", value);\r
215     EMAC_ReadPhy(pHw, phyAddress, MII_BMSR, &value, retryMax);\r
216     TRACE_INFO(" _BMSR   : 0x%X\n\r", value);\r
217     EMAC_ReadPhy(pHw, phyAddress, MII_ANAR, &value, retryMax);\r
218     TRACE_INFO(" _ANAR   : 0x%X\n\r", value);\r
219     EMAC_ReadPhy(pHw, phyAddress, MII_ANLPAR, &value, retryMax);\r
220     TRACE_INFO(" _ANLPAR : 0x%X\n\r", value);\r
221     EMAC_ReadPhy(pHw, phyAddress, MII_ANER, &value, retryMax);\r
222     TRACE_INFO(" _ANER   : 0x%X\n\r", value);\r
223     EMAC_ReadPhy(pHw, phyAddress, MII_DSCR, &value, retryMax);\r
224     TRACE_INFO(" _DSCR   : 0x%X\n\r", value);\r
225     EMAC_ReadPhy(pHw, phyAddress, MII_DSCSR, &value, retryMax);\r
226     TRACE_INFO(" _DSCSR  : 0x%X\n\r", value);\r
227     EMAC_ReadPhy(pHw, phyAddress, MII_10BTCSR, &value, retryMax);\r
228     TRACE_INFO(" _10BTCSR: 0x%X\n\r", value);\r
229     EMAC_ReadPhy(pHw, phyAddress, MII_PWDOR, &value, retryMax);\r
230     TRACE_INFO(" _PWDOR  : 0x%X\n\r", value);\r
231     EMAC_ReadPhy(pHw, phyAddress, MII_CONFIGR, &value, retryMax);\r
232     TRACE_INFO(" _CONFIGR: 0x%X\n\r", value);\r
233     EMAC_ReadPhy(pHw, phyAddress, MII_MDINTR, &value, retryMax);\r
234     TRACE_INFO(" _MDINTR : 0x%X\n\r", value);\r
235     EMAC_ReadPhy(pHw, phyAddress, MII_RECR, &value, retryMax);\r
236     TRACE_INFO(" _RECR   : 0x%X\n\r", value);\r
237     EMAC_ReadPhy(pHw, phyAddress, MII_DISCR, &value, retryMax);\r
238     TRACE_INFO(" _DISCR  : 0x%X\n\r", value);\r
239     EMAC_ReadPhy(pHw, phyAddress, MII_RLSR, &value, retryMax);\r
240     TRACE_INFO(" _RLSR   : 0x%X\n\r", value);\r
241 \r
242     EMAC_ManagementEnable(pHw, 0);\r
243 }\r
244 \r
245 /**\r
246  * Setup the maximum timeout count of the driver.\r
247  * \param pMacb   Pointer to the MACB instance\r
248  * \param toMax   Timeout maxmum count.\r
249  */\r
250 void MACB_SetupTimeout(Macb *pMacb, uint32_t toMax)\r
251 {\r
252     pMacb->retryMax = toMax;\r
253 }\r
254 \r
255 /**\r
256  * Initialize the MACB instance\r
257  * \param pMacb        Pointer to the MACB instance\r
258  * \param pEmac        Pointer to the Emac instance for the MACB\r
259  * \param phyAddress   The PHY address used to access the PHY\r
260  *                     ( pre-defined by pin status on PHY reset )\r
261  */\r
262 void MACB_Init(Macb *pMacb, sEmacd *pEmacd, uint8_t phyAddress)\r
263 {\r
264     pMacb->pEmacd = pEmacd;\r
265     pMacb->phyAddress = phyAddress;\r
266     /* Initialize timeout by default */\r
267     pMacb->retryMax = MACB_RETRY_MAX;\r
268 }\r
269 \r
270 /**\r
271  * Issue a SW reset to reset all registers of the PHY\r
272  * Return 1 if successfully, 0 if timeout.\r
273  * \param pMacb   Pointer to the MACB instance\r
274  */\r
275 uint8_t MACB_ResetPhy(Macb *pMacb)\r
276 {\r
277     sEmacd *pDrv = pMacb->pEmacd;\r
278     Emac *pHw = pDrv->pHw;\r
279 \r
280     uint32_t retryMax;\r
281     uint32_t bmcr = MII_RESET;\r
282     uint8_t phyAddress;\r
283     uint32_t timeout = 10;\r
284     uint8_t ret = 1;\r
285 \r
286     TRACE_INFO(" MACB_ResetPhy\n\r");\r
287 \r
288     phyAddress = pMacb->phyAddress;\r
289     retryMax = pMacb->retryMax;\r
290 \r
291     EMAC_ManagementEnable(pHw, 1);\r
292 \r
293     bmcr = MII_RESET;\r
294     EMAC_WritePhy(pHw, phyAddress, MII_BMCR, bmcr, retryMax);\r
295 \r
296     do\r
297     {\r
298         EMAC_ReadPhy(pHw, phyAddress, MII_BMCR, &bmcr, retryMax);\r
299         timeout--;\r
300     } while ((bmcr & MII_RESET) && timeout);\r
301 \r
302     EMAC_ManagementEnable(pHw, 0);\r
303 \r
304     if (!timeout)\r
305     {\r
306         ret = 0;\r
307     }\r
308 \r
309     return( ret );\r
310 }\r
311 \r
312 /**\r
313  * Do a HW initialize to the PHY ( via RSTC ) and setup clocks & PIOs\r
314  * This should be called only once to initialize the PHY pre-settings.\r
315  * The PHY address is reset status of CRS,RXD[3:0] (the emacPins' pullups).\r
316  * The COL pin is used to select MII mode on reset (pulled up for Reduced MII)\r
317  * The RXDV pin is used to select test mode on reset (pulled up for test mode)\r
318  * The above pins should be predefined for corresponding settings in resetPins\r
319  * The EMAC peripheral pins are configured after the reset done.\r
320  * Return 1 if RESET OK, 0 if timeout.\r
321  * \param pMacb         Pointer to the MACB instance\r
322  * \param mck         Main clock setting to initialize clock\r
323  * \param resetPins   Pointer to list of PIOs to configure before HW RESET\r
324  *                       (for PHY power on reset configuration latch)\r
325  * \param nbResetPins Number of PIO items that should be configured\r
326  * \param emacPins    Pointer to list of PIOs for the EMAC interface\r
327  * \param nbEmacPins  Number of PIO items that should be configured\r
328  */\r
329 \r
330 uint8_t MACB_InitPhy(Macb         *pMacb,\r
331                      uint32_t      mck,\r
332                      const Pin    *pResetPins,\r
333                      uint32_t      nbResetPins,\r
334                      const Pin    *pEmacPins,\r
335                      uint32_t      nbEmacPins)\r
336 {\r
337     sEmacd *pDrv = pMacb->pEmacd;\r
338     Emac *pHw = pDrv->pHw;\r
339 \r
340     uint8_t rc = 1;\r
341     uint8_t phy;\r
342 \r
343     /* Perform RESET */\r
344     TRACE_DEBUG("RESET PHY\n\r");\r
345     \r
346     if (pResetPins)\r
347     {\r
348         /* Configure PINS */\r
349         PIO_Configure(pResetPins, nbResetPins);\r
350         /* Execute reset */\r
351         RSTC_SetExtResetLength(MACB_RESET_LENGTH);\r
352         RSTC_ExtReset();\r
353         /* Get NRST level */\r
354         /* Wait for end hardware reset */\r
355         while (!RSTC_GetNrstLevel());\r
356     }\r
357     /* Configure EMAC runtime pins */\r
358     if (rc)\r
359     {\r
360         PIO_Configure(pEmacPins, nbEmacPins);\r
361         rc = EMAC_SetClock( pHw, mck );\r
362         if (!rc)\r
363         {\r
364             TRACE_ERROR("No Valid MDC clock\n\r");\r
365             return 0;\r
366         }\r
367 \r
368         /* Check PHY Address */\r
369         phy = MACB_FindValidPhy(pMacb, 0);\r
370         if (phy == 0xFF)\r
371         {\r
372             TRACE_ERROR("PHY Access fail\n\r");\r
373             return 0;\r
374         }\r
375         if(phy != pMacb->phyAddress)\r
376         {\r
377             pMacb->phyAddress = phy;\r
378             MACB_ResetPhy(pMacb);\r
379         }\r
380 \r
381     }\r
382     else\r
383     {\r
384         TRACE_ERROR("PHY Reset Timeout\n\r");\r
385     }\r
386 \r
387     return rc;\r
388 }\r
389 \r
390 /**\r
391  * Issue a Auto Negotiation of the PHY\r
392  * Return 1 if successfully, 0 if timeout.\r
393  * \param pMacb   Pointer to the MACB instance\r
394  */\r
395 uint8_t MACB_AutoNegotiate(Macb *pMacb, uint8_t rmiiMode)\r
396 {\r
397     sEmacd *pDrv = pMacb->pEmacd;\r
398     Emac *pHw = pDrv->pHw;\r
399 \r
400     uint32_t retryMax;\r
401     uint32_t value;\r
402     uint32_t phyAnar;\r
403     uint32_t phyAnalpar;\r
404     uint32_t retryCount= 0;\r
405     uint8_t phyAddress;\r
406     uint8_t bFD = 0;\r
407     uint8_t bSP = 0;\r
408     uint8_t rc = 1;\r
409 \r
410     pMacb->RMII = rmiiMode;\r
411 \r
412     phyAddress = pMacb->phyAddress;\r
413     retryMax = pMacb->retryMax;\r
414 \r
415     EMAC_ManagementEnable(pHw, 1);\r
416 \r
417     if (!EMAC_ReadPhy(pHw, phyAddress, MII_PHYID1, &value, retryMax))\r
418     {\r
419         TRACE_ERROR("Pb EMAC_ReadPhy Id1\n\r");\r
420         rc = 0;\r
421         goto AutoNegotiateExit;\r
422     }\r
423     TRACE_DEBUG("ReadPhy Id1 0x%X, addresse: %d\n\r", value, phyAddress);\r
424     if (!EMAC_ReadPhy(pHw, phyAddress, MII_PHYID2, &phyAnar, retryMax))\r
425     {\r
426         TRACE_ERROR("Pb EMAC_ReadPhy Id2\n\r");\r
427         rc = 0;\r
428         goto AutoNegotiateExit;\r
429     }\r
430     TRACE_DEBUG("ReadPhy Id2 0x%X\n\r", phyAnar);\r
431 \r
432     if( ( value == MII_OUI_MSB )\r
433      && ( ((phyAnar>>10)&MII_LSB_MASK) == MII_OUI_LSB ) )\r
434     {\r
435         TRACE_DEBUG("Vendor Number Model = 0x%X\n\r", ((phyAnar>>4)&0x3F));\r
436         TRACE_DEBUG("Model Revision Number = 0x%X\n\r", (phyAnar&0x7));\r
437     }\r
438     else\r
439     {\r
440         TRACE_ERROR("Problem OUI value\n\r");\r
441     }        \r
442 \r
443     /* Setup control register */\r
444     rc  = EMAC_ReadPhy(pHw, phyAddress, MII_BMCR, &value, retryMax);\r
445     if (rc == 0)\r
446     {\r
447         goto AutoNegotiateExit;\r
448     }\r
449 \r
450     value &= ~MII_AUTONEG;   /* Remove autonegotiation enable */\r
451     value &= ~(MII_LOOPBACK|MII_POWER_DOWN);\r
452     value |=  MII_ISOLATE;   /* Electrically isolate PHY */\r
453     rc = EMAC_WritePhy(pHw, phyAddress, MII_BMCR, value, retryMax);\r
454     if (rc == 0)\r
455     {\r
456         goto AutoNegotiateExit;\r
457     }\r
458 \r
459     /* Set the Auto_negotiation Advertisement Register\r
460        MII advertising for Next page\r
461        100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */\r
462     phyAnar = MII_TX_FDX | MII_TX_HDX |\r
463               MII_10_FDX | MII_10_HDX | MII_AN_IEEE_802_3;\r
464     rc = EMAC_WritePhy(pHw, phyAddress, MII_ANAR, phyAnar, retryMax);\r
465     if (rc == 0)\r
466     {\r
467         goto AutoNegotiateExit;\r
468     }\r
469 \r
470     /* Read & modify control register */\r
471     rc  = EMAC_ReadPhy(pHw, phyAddress, MII_BMCR, &value, retryMax);\r
472     if (rc == 0)\r
473     {\r
474         goto AutoNegotiateExit;\r
475     }\r
476 \r
477     value |= MII_SPEED_SELECT | MII_AUTONEG | MII_DUPLEX_MODE;\r
478     rc = EMAC_WritePhy(pHw, phyAddress, MII_BMCR, value, retryMax);\r
479     if (rc == 0)\r
480     {\r
481         goto AutoNegotiateExit;\r
482     }\r
483 \r
484     /* Restart Auto_negotiation */\r
485     value |=  MII_RESTART_AUTONEG;\r
486     value &= ~MII_ISOLATE;\r
487     rc = EMAC_WritePhy(pHw, phyAddress, MII_BMCR, value, retryMax);\r
488     if (rc == 0)\r
489     {\r
490         goto AutoNegotiateExit;\r
491     }\r
492     TRACE_DEBUG(" _BMCR: 0x%X\n\r", value);\r
493 \r
494     /* Check AutoNegotiate complete */\r
495     while (1)\r
496     {\r
497         rc  = EMAC_ReadPhy(pHw, phyAddress, MII_BMSR, &value, retryMax);\r
498         if (rc == 0)\r
499         {\r
500             TRACE_ERROR("_BMSR Rd err\n\r");\r
501             goto AutoNegotiateExit;\r
502         }\r
503         /* Done successfully */\r
504         if (value & MII_AUTONEG_COMP)\r
505         {\r
506             printf("AutoNegotiate complete\n\r");\r
507             break;\r
508         }\r
509 \r
510         /* Timeout check */\r
511         if (retryMax)\r
512         {\r
513             if (++ retryCount >= retryMax)\r
514             {\r
515                 MACB_DumpRegisters(pMacb);\r
516                 TRACE_ERROR("TimeOut\n\r");\r
517                 rc = 0;\r
518                 goto AutoNegotiateExit;\r
519             }\r
520         }\r
521     }\r
522 \r
523     /* Get the AutoNeg Link partner base page */\r
524     rc  = EMAC_ReadPhy(pHw, phyAddress, MII_ANLPAR, &phyAnalpar, retryMax);\r
525     if (rc == 0)\r
526     {\r
527         goto AutoNegotiateExit;\r
528     }\r
529 \r
530     /* Setup the EMAC link speed */\r
531     if ((phyAnar & phyAnalpar) & MII_TX_FDX)\r
532     {\r
533         /* set MII for 100BaseTX and Full Duplex */\r
534         bSP = 1; bFD = 1;\r
535     }\r
536     else if ((phyAnar & phyAnalpar) & MII_10_FDX)\r
537     {\r
538         /* set MII for 10BaseT and Full Duplex */\r
539         bSP = 0; bFD = 1;\r
540     }\r
541     else if ((phyAnar & phyAnalpar) & MII_TX_HDX)\r
542     {\r
543         // set MII for 100BaseTX and half Duplex\r
544         bSP = 1; bFD = 0;\r
545     }\r
546     else if ((phyAnar & phyAnalpar) & MII_10_HDX)\r
547     {\r
548         // set MII for 10BaseT and half Duplex\r
549         bSP = 0; bFD = 0;\r
550     }\r
551     EMAC_SetSpeed(pHw, bSP);\r
552     EMAC_FullDuplexEnable(pHw, bFD);\r
553 \r
554     EMAC_RMIIEnable(pHw, rmiiMode);\r
555     EMAC_TransceiverClockEnable(pHw, 1);\r
556 \r
557 AutoNegotiateExit:\r
558     EMAC_ManagementEnable(pHw, 0);\r
559     return rc;\r
560 }\r
561 \r
562 /**\r
563  * Get the Link & speed settings, and automatically setup the EMAC with the\r
564  * settings.\r
565  * Return 1 if link found, 0 if no ethernet link.\r
566  * \param pMacb          Pointer to the MACB instance\r
567  * \param applySetting Apply the settings to EMAC interface\r
568  */\r
569 uint8_t MACB_GetLinkSpeed(Macb *pMacb, uint8_t applySetting)\r
570 {\r
571     sEmacd *pDrv = pMacb->pEmacd;\r
572     Emac *pHw = pDrv->pHw;\r
573 \r
574     uint32_t retryMax;\r
575     uint32_t stat1;\r
576     uint32_t stat2;\r
577     uint8_t phyAddress, bSP, bFD;\r
578     uint8_t rc = 1;\r
579        \r
580     TRACE_DEBUG("MACB_GetLinkSpeed\n\r");\r
581     bSP = 0; bFD = 0;\r
582     EMAC_ManagementEnable(pHw, 1);\r
583 \r
584     phyAddress = pMacb->phyAddress;\r
585     retryMax = pMacb->retryMax;\r
586 \r
587     rc  = EMAC_ReadPhy(pHw, phyAddress, MII_BMSR, &stat1, retryMax);\r
588     if (rc == 0)\r
589     {\r
590         goto GetLinkSpeedExit;\r
591     }\r
592 \r
593     if ((stat1 & MII_LINK_STATUS) == 0)\r
594     {\r
595         TRACE_ERROR("Pb: LinkStat: 0x%x\n\r", (unsigned int)stat1);\r
596         rc = 0;\r
597         goto GetLinkSpeedExit;\r
598     }\r
599 \r
600     if (applySetting == 0)\r
601     {\r
602         TRACE_WARNING("Speed #%d not applied\n\r", applySetting);\r
603         bSP = 0; bFD = 0;\r
604         goto GetLinkSpeedExit;\r
605     }\r
606 \r
607     /* Re-configure Link speed */\r
608     rc  = EMAC_ReadPhy(pHw, phyAddress, MII_DSCSR, &stat2, retryMax);\r
609     if (rc == 0)\r
610     {\r
611         TRACE_ERROR("Pb _DSCSR: rc 0x%x\n\r", rc);\r
612         goto GetLinkSpeedExit;\r
613     }\r
614 \r
615     if ((stat1 & MII_100BASE_TX_FD) && (stat2 & MII_100FDX))\r
616     {\r
617         /* set Emac for 100BaseTX and Full Duplex */\r
618         bSP = 1; bFD = 1;\r
619     }\r
620 \r
621     if ((stat1 & MII_10BASE_T_FD) && (stat2 & MII_10FDX))\r
622     {\r
623         /* set MII for 10BaseT and Full Duplex */\r
624         bSP= 0; bFD = 1;\r
625     }\r
626 \r
627     if ((stat1 & MII_100BASE_T4_HD) && (stat2 & MII_100HDX))\r
628     {\r
629         /* set MII for 100BaseTX and Half Duplex */\r
630         bSP = 1; bFD = 0;\r
631     }\r
632 \r
633     if ((stat1 & MII_10BASE_T_HD) && (stat2 & MII_10HDX))\r
634     {\r
635         /* set MII for 10BaseT and Half Duplex */\r
636         bSP = 0; bFD = 0;\r
637     }\r
638     EMAC_SetSpeed(pHw, bSP);\r
639     EMAC_FullDuplexEnable(pHw, bFD);\r
640 \r
641     /* Start the EMAC transfers */\r
642     TRACE_DEBUG("MACB_GetLinkSpeed passed\n\r");\r
643 \r
644 GetLinkSpeedExit:\r
645     EMAC_ManagementEnable(pHw, 0);\r
646     return rc;\r
647 }\r
648 \r