]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/gmacb.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / AtmelFiles / libboard_sama5d3x-ek / source / gmacb.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2012, 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 GMACB_RETRY_MAX            300000\r
44 \r
45 /** Default max retry count */\r
46 #define GACB_RETRY_MAX            1000000\r
47 \r
48 /*---------------------------------------------------------------------------\r
49  *         Local functions\r
50  *---------------------------------------------------------------------------*/\r
51 \r
52 \r
53 /**\r
54  * Wait PHY operation complete.\r
55  * Return 1 if the operation completed successfully.\r
56  * May be need to re-implemented to reduce CPU load.\r
57  * \param retry: the retry times, 0 to wait forever until complete.\r
58  */\r
59 static uint8_t GMACB_WaitPhy( Gmac *pHw, uint32_t retry )\r
60 {\r
61     volatile uint32_t retry_count = 0;\r
62 \r
63     while (!GMAC_IsIdle(pHw))\r
64     {\r
65         if(retry == 0) continue;\r
66         retry_count ++;\r
67         if (retry_count >= retry)\r
68         {\r
69             return 0;\r
70         }\r
71     }\r
72     return 1;\r
73 }\r
74 \r
75 /**\r
76  * Read PHY register.\r
77  * Return 1 if successfully, 0 if timeout.\r
78  * \param pHw HW controller address\r
79  * \param PhyAddress PHY Address\r
80  * \param Address Register Address\r
81  * \param pValue Pointer to a 32 bit location to store read data\r
82  * \param retry The retry times, 0 to wait forever until complete.\r
83  */\r
84 static uint8_t GMACB_ReadPhy(Gmac *pHw,\r
85                              uint8_t PhyAddress,\r
86                              uint8_t Address,\r
87                              uint32_t *pValue,\r
88                              uint32_t retry)\r
89 {\r
90     GMAC_PHYMaintain(pHw, PhyAddress, Address, 1, 0);\r
91     if ( GMACB_WaitPhy(pHw, retry) == 0 )\r
92     {\r
93         TRACE_ERROR("TimeOut GMACB_ReadPhy\n\r");\r
94         return 0;\r
95     }\r
96     *pValue = GMAC_PHYData(pHw);\r
97     return 1;\r
98 }\r
99 \r
100 /**\r
101  * Write PHY register\r
102  * Return 1 if successfully, 0 if timeout.\r
103  * \param pHw HW controller address\r
104  * \param PhyAddress PHY Address\r
105  * \param Address Register Address\r
106  * \param Value Data to write ( Actually 16 bit data )\r
107  * \param retry The retry times, 0 to wait forever until complete.\r
108  */\r
109 static uint8_t GMACB_WritePhy(Gmac *pHw,\r
110                               uint8_t PhyAddress,\r
111                               uint8_t Address,\r
112                               uint32_t Value,\r
113                               uint32_t retry)\r
114 {\r
115     GMAC_PHYMaintain(pHw, PhyAddress, Address, 0, Value);\r
116     if ( GMACB_WaitPhy(pHw, retry) == 0 )\r
117     {\r
118         TRACE_ERROR("TimeOut GMACB_WritePhy\n\r");\r
119         return 0;\r
120     }\r
121     return 1;\r
122 }\r
123 \r
124 \r
125 /*---------------------------------------------------------------------------\r
126  *         Exported functions\r
127  *---------------------------------------------------------------------------*/\r
128 \r
129 /**\r
130  * \brief Find a valid PHY Address ( from 0 to 31 ).\r
131  * \param pMacb Pointer to the MACB instance\r
132  * \return 0xFF when no valid PHY Address found.\r
133  */\r
134 static uint8_t GMACB_FindValidPhy(GMacb *pMacb)\r
135 {\r
136     sGmacd *pDrv = pMacb->pGmacd;\r
137     Gmac *pHw = pDrv->pHw;\r
138 \r
139     uint32_t  retryMax;\r
140     uint32_t  value=0;\r
141     uint8_t rc;\r
142     uint8_t phyAddress;\r
143     uint8_t cnt;\r
144 \r
145     TRACE_DEBUG("GMACB_FindValidPhy\n\r");\r
146 \r
147     GMAC_EnableMdio(pHw);\r
148     phyAddress = pMacb->phyAddress;\r
149     retryMax = pMacb->retryMax;\r
150 \r
151     /* Check current phyAddress */\r
152     rc = phyAddress;\r
153     if( GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1, &value, retryMax) == 0 ) {\r
154         TRACE_ERROR("GMACB PROBLEM\n\r");\r
155     }\r
156     TRACE_DEBUG("_PHYID1  : 0x%X, addr: %d\n\r", value, phyAddress);\r
157 \r
158     /* Find another one */\r
159     if (value != GMII_OUI_MSB) {\r
160 \r
161         rc = 0xFF;\r
162         for(cnt = 0; cnt < 32; cnt ++) {\r
163 \r
164             phyAddress = (phyAddress + 1) & 0x1F;\r
165             if( GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1, &value, retryMax) == 0 ) {\r
166                 TRACE_ERROR("MACB PROBLEM\n\r");\r
167             }\r
168             TRACE_DEBUG("_PHYID1  : 0x%X, addr: %d\n\r", value, phyAddress);\r
169             if (value == GMII_OUI_MSB) {\r
170 \r
171                 rc = phyAddress;\r
172                 break;\r
173             }\r
174         }\r
175     }\r
176     GMAC_DisableMdio(pHw);\r
177     if (rc != 0xFF) {\r
178         TRACE_INFO("** Valid PHY Found: %d\n\r", rc);\r
179         GMACB_ReadPhy(pHw, phyAddress, GMII_BMSR, &value, retryMax);\r
180         TRACE_DEBUG("_BMSR  : 0x%X, addr: %d\n\r", value, phyAddress);\r
181         GMACB_ReadPhy(pHw, phyAddress, GMII_1000BTSR, &value, retryMax);\r
182         TRACE_DEBUG("_1000BTSR  : 0x%X, addr: %d\n\r", value, phyAddress);\r
183         GMACB_ReadPhy(pHw, phyAddress, GMII_EMSR, &value, retryMax);\r
184         TRACE_DEBUG("_EMSR  : 0x%X, addr: %d\n\r", value, phyAddress);\r
185     }\r
186     return rc;\r
187 }\r
188 \r
189 \r
190 /*----------------------------------------------------------------------------\r
191  *        Exported functions\r
192  *----------------------------------------------------------------------------*/\r
193 \r
194 \r
195 /**\r
196  * \brief Dump all the useful registers.\r
197  * \param pMacb          Pointer to the MACB instance\r
198  */\r
199 void GMACB_DumpRegisters(GMacb *pMacb)\r
200 {\r
201     sGmacd *pDrv = pMacb->pGmacd;\r
202     Gmac *pHw = pDrv->pHw;\r
203 \r
204     uint8_t phyAddress;\r
205     uint32_t retryMax;\r
206     uint32_t value;\r
207 \r
208     TRACE_INFO("GMACB_DumpRegisters\n\r");\r
209 \r
210     GMAC_EnableMdio(pHw);\r
211     phyAddress = pMacb->phyAddress;\r
212     retryMax = pMacb->retryMax;\r
213 \r
214     TRACE_INFO("GMII MACB @%d) Registers:\n\r", phyAddress);\r
215 \r
216     GMACB_ReadPhy(pHw, phyAddress, GMII_BMCR, &value, retryMax);\r
217     TRACE_INFO(" _BMCR     : 0x%X\n\r", value);\r
218     GMACB_ReadPhy(pHw, phyAddress, GMII_BMSR, &value, retryMax);\r
219     TRACE_INFO(" _BMSR     : 0x%X\n\r", value);\r
220     GMACB_ReadPhy(pHw, phyAddress, GMII_ANAR, &value, retryMax);\r
221     TRACE_INFO(" _ANAR     : 0x%X\n\r", value);\r
222     GMACB_ReadPhy(pHw, phyAddress, GMII_ANLPAR, &value, retryMax);\r
223     TRACE_INFO(" _ANLPAR   : 0x%X\n\r", value);\r
224     GMACB_ReadPhy(pHw, phyAddress, GMII_ANER, &value, retryMax);\r
225     TRACE_INFO(" _ANER     : 0x%X\n\r", value);\r
226     GMACB_ReadPhy(pHw, phyAddress, GMII_ANNPR, &value, retryMax);\r
227     TRACE_INFO(" _ANNPR    : 0x%X\n\r", value);\r
228     GMACB_ReadPhy(pHw, phyAddress, GMII_ANLPNPAR, &value, retryMax);\r
229     TRACE_INFO(" _ANLPNPAR : 0x%X\n\r", value);\r
230     GMACB_ReadPhy(pHw, phyAddress, GMII_1000BTCR, &value, retryMax);\r
231     TRACE_INFO(" _1000BTCR : 0x%X\n\r", value);\r
232     GMACB_ReadPhy(pHw, phyAddress, GMII_1000BTSR, &value, retryMax);\r
233     TRACE_INFO(" _1000BTSR : 0x%X\n\r", value);\r
234   \r
235     GMACB_ReadPhy(pHw, phyAddress, GMII_EMSR, &value, retryMax);\r
236     TRACE_INFO(" _EMSR     : 0x%X\n\r", value);\r
237     TRACE_INFO(" \n\r");\r
238     \r
239     GMACB_ReadPhy(pHw, phyAddress, GMII_RLLMR, &value, retryMax);\r
240     TRACE_INFO(" _RLLMR    : 0x%X\n\r", value);\r
241     GMACB_ReadPhy(pHw, phyAddress, GMII_LMDCDR, &value, retryMax);\r
242     TRACE_INFO(" _LMDCDR   : 0x%X\n\r", value);\r
243     GMACB_ReadPhy(pHw, phyAddress, GMII_DPPSR, &value, retryMax);\r
244     TRACE_INFO(" _DPPSR    : 0x%X\n\r", value);\r
245     GMACB_ReadPhy(pHw, phyAddress, GMII_RXERCR, &value, retryMax);\r
246     TRACE_INFO(" _RXERCR   : 0x%X\n\r", value);\r
247     GMACB_ReadPhy(pHw, phyAddress, GMII_ICSR, &value, retryMax);\r
248     TRACE_INFO(" _ICSR     : 0x%X\n\r", value);\r
249     GMACB_ReadPhy(pHw, phyAddress, GMII_DDC1R, &value, retryMax);\r
250     TRACE_INFO(" _DDC1R    : 0x%X\n\r", value);\r
251     GMACB_ReadPhy(pHw, phyAddress, GMII_PHYCR, &value, retryMax);\r
252     TRACE_INFO(" _PHYCR    : 0x%X\n\r", value);  \r
253     TRACE_INFO(" \n\r");\r
254    \r
255     value = GMII_CCR;\r
256     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
257     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
258     TRACE_INFO(" _CCR      : 0x%X\n\r", value);\r
259     value = GMII_SSR;\r
260     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
261     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
262     TRACE_INFO(" _SSR      : 0x%X\n\r", value);\r
263     value = GMII_OMSOR;\r
264     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
265     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
266     TRACE_INFO(" _OMSOR    : 0x%X\n\r", value);\r
267     value = GMII_OMSSR;\r
268     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
269     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
270     TRACE_INFO(" _OMSSR    : 0x%X\n\r", value);\r
271     value = GMII_RCCPSR;\r
272     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
273     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
274     TRACE_INFO(" _RCCPSR   : 0x%X\n\r", value);\r
275     value = GMII_RRDPSR;\r
276     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
277     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
278     TRACE_INFO(" _RCCPSR   : 0x%X\n\r", value);\r
279     value = GMII_ATR;   \r
280     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
281     GMACB_ReadPhy(pHw, phyAddress, GMII_ERDRR, &value, retryMax);\r
282     TRACE_INFO(" _ATR      : 0x%X\n\r", value);\r
283     \r
284     GMAC_DisableMdio(pHw);\r
285 }\r
286 \r
287 /**\r
288  * \brief Setup the maximum timeout count of the driver.\r
289  * \param pMacb Pointer to the MACB instance\r
290  * \param toMax Timeout maxmum count.\r
291  */\r
292 void GMACB_SetupTimeout(GMacb *pMacb, uint32_t toMax)\r
293 {\r
294     pMacb->retryMax = toMax;\r
295 }\r
296 \r
297 /**\r
298  * \brief Initialize the MACB instance.\r
299  * \param pMacb Pointer to the MACB instance\r
300  * \param phyAddress   The PHY address used to access the PHY\r
301  */\r
302 void GMACB_Init(GMacb *pMacb, sGmacd *pGmacd, uint8_t phyAddress)\r
303 {\r
304     pMacb->pGmacd = pGmacd;\r
305     pMacb->phyAddress = phyAddress;\r
306     /* Initialize timeout by default */\r
307     pMacb->retryMax = GMACB_RETRY_MAX;\r
308 }\r
309 \r
310 \r
311 /**\r
312  * \brief Issue a SW reset to reset all registers of the PHY.\r
313  * \param pMacb Pointer to the MACB instance\r
314  * \return 1 if successfully, 0 if timeout.\r
315  */\r
316 uint8_t GMACB_ResetPhy(GMacb *pMacb)\r
317 {\r
318     sGmacd *pDrv = pMacb->pGmacd;\r
319     Gmac *pHw = pDrv->pHw;\r
320     uint32_t retryMax;\r
321     uint32_t bmcr = GMII_RESET;\r
322     uint8_t phyAddress;\r
323     uint32_t timeout = 10;\r
324     uint8_t ret = 1;\r
325 \r
326     TRACE_INFO(" GMACB_ResetPhy\n\r");\r
327 \r
328     phyAddress = pMacb->phyAddress;\r
329     retryMax = pMacb->retryMax;\r
330 \r
331     GMAC_EnableMdio(pHw);\r
332     bmcr = GMII_RESET;\r
333     GMACB_WritePhy(pHw, phyAddress, GMII_BMCR, bmcr, retryMax);\r
334 \r
335     do {\r
336         GMACB_ReadPhy(pHw, phyAddress, GMII_BMCR, &bmcr, retryMax);\r
337         timeout--;\r
338     } while ((bmcr & GMII_RESET) && timeout);\r
339 \r
340     GMAC_DisableMdio(pHw);\r
341 \r
342     if (!timeout) {\r
343         ret = 0;\r
344     }\r
345 \r
346     return( ret );\r
347 }\r
348 \r
349 /**\r
350  * \brief Do a HW initialize to the PHY ( via RSTC ) and setup clocks & PIOs\r
351  * This should be called only once to initialize the PHY pre-settings.\r
352  * The PHY address is reset status of CRS,RXD[3:0] (the emacPins' pullups).\r
353  * The COL pin is used to select MII mode on reset (pulled up for Reduced MII)\r
354  * The RXDV pin is used to select test mode on reset (pulled up for test mode)\r
355  * The above pins should be predefined for corresponding settings in resetPins\r
356  * The GMAC peripheral pins are configured after the reset done.\r
357  * \param pMacb Pointer to the MACB instance\r
358  * \param mck         Main clock setting to initialize clock\r
359  * \param resetPins   Pointer to list of PIOs to configure before HW RESET\r
360  *                       (for PHY power on reset configuration latch)\r
361  * \param nbResetPins Number of PIO items that should be configured\r
362  * \param emacPins    Pointer to list of PIOs for the EMAC interface\r
363  * \param nbEmacPins  Number of PIO items that should be configured\r
364  * \return 1 if RESET OK, 0 if timeout.\r
365  */\r
366 uint8_t GMACB_InitPhy(GMacb *pMacb,\r
367                             uint32_t mck,\r
368                             const Pin *pResetPins,\r
369                             uint32_t nbResetPins,\r
370                             const Pin *pEmacPins,\r
371                             uint32_t nbEmacPins)\r
372 {\r
373     sGmacd *pDrv = pMacb->pGmacd;\r
374     Gmac *pHw = pDrv->pHw;\r
375     uint8_t rc = 1;\r
376     uint8_t phy;\r
377 \r
378     /* Perform RESET */\r
379     TRACE_DEBUG("RESET PHY\n\r");\r
380     \r
381     if (pResetPins) {\r
382         /* Configure PINS */\r
383         PIO_Configure(pResetPins, nbResetPins);\r
384     }\r
385     /* Configure EMAC runtime pins */\r
386     if (rc) {\r
387 \r
388         PIO_Configure(pEmacPins, nbEmacPins);\r
389         rc = GMAC_SetMdcClock(pHw, mck );\r
390         if (!rc) {\r
391             TRACE_ERROR("No Valid MDC clock\n\r");\r
392             return 0;\r
393         }\r
394 \r
395         /* Check PHY Address */\r
396         phy = GMACB_FindValidPhy(pMacb);\r
397         if (phy == 0xFF) {\r
398             TRACE_ERROR("PHY Access fail\n\r");\r
399             return 0;\r
400         }\r
401         if(phy != pMacb->phyAddress) {\r
402             pMacb->phyAddress = phy;\r
403             GMACB_ResetPhy(pMacb);\r
404         }\r
405     }\r
406     else {\r
407         TRACE_ERROR("PHY Reset Timeout\n\r");\r
408     }\r
409     return rc;\r
410 }\r
411 \r
412 /**\r
413  * \brief Issue a Auto Negotiation of the PHY\r
414  * \param pMacb Pointer to the MACB instance\r
415  * \return 1 if successfully, 0 if timeout.\r
416  */\r
417 uint8_t GMACB_AutoNegotiate(GMacb *pMacb)\r
418 {\r
419     sGmacd *pDrv = pMacb->pGmacd;\r
420     Gmac *pHw = pDrv->pHw;\r
421     uint32_t retryMax;\r
422     uint32_t value;\r
423     uint32_t phyAnar;\r
424     uint32_t phyAnalpar;\r
425     uint32_t gbaseTC;\r
426     uint32_t gbaseTS;\r
427     uint32_t retryCount= 0;\r
428     uint8_t phyAddress;\r
429     uint8_t rc = 1;\r
430     uint32_t duplex, speed;\r
431     phyAddress = pMacb->phyAddress;\r
432     retryMax = pMacb->retryMax;\r
433 \r
434     GMAC_EnableMdio(pHw);\r
435 \r
436     if (!GMACB_ReadPhy(pHw,phyAddress, GMII_PHYID1, &value, retryMax)) \r
437     {\r
438         TRACE_ERROR("Pb GEMAC_ReadPhy Id1\n\r");\r
439         rc = 0;\r
440         goto AutoNegotiateExit;\r
441     }\r
442     TRACE_DEBUG("ReadPhy Id1 0x%X, addresse: %d\n\r", value, phyAddress);\r
443     if (!GMACB_ReadPhy(pHw,phyAddress, GMII_PHYID2, &phyAnar, retryMax)) \r
444     {\r
445         TRACE_ERROR("Pb GMACB_ReadPhy Id2\n\r");\r
446         rc = 0;\r
447         goto AutoNegotiateExit;\r
448     }\r
449     TRACE_DEBUG("ReadPhy Id2 0x%X\n\r", phyAnar);\r
450 \r
451     if( ( value == GMII_OUI_MSB )\r
452      && ( ((phyAnar>>10)&GMII_LSB_MASK) == GMII_OUI_LSB ) )\r
453     {\r
454         TRACE_DEBUG("Vendor Number Model = 0x%X\n\r", ((phyAnar>>4)&0x3F));\r
455         TRACE_DEBUG("Model Revision Number = 0x%X\n\r", (phyAnar&0x7));\r
456     }\r
457     else \r
458     {\r
459         TRACE_ERROR("Problem OUI value\n\r");\r
460     }\r
461 \r
462     value = GMII_RCCPSR | 0x8000;\r
463     GMACB_WritePhy(pHw,phyAddress, GMII_ERCR, value, retryMax);\r
464     //value = 0xF0F4;\r
465     value = 0xF2F4;\r
466     GMACB_WritePhy(pHw,phyAddress, GMII_ERDWR, value, retryMax);\r
467     value = GMII_RRDPSR | 0x8000;\r
468     GMACB_WritePhy(pHw, phyAddress, GMII_ERCR, value, retryMax);\r
469     //value = 0x3028;\r
470     value = 0x2222;\r
471     GMACB_WritePhy(pHw,phyAddress, GMII_ERDWR, value, retryMax);\r
472     \r
473     value = 0xFF00;\r
474     rc = GMACB_WritePhy(pHw,phyAddress, GMII_ICSR, value, retryMax);\r
475  \r
476     /* Set the Auto_negotiation Advertisement Register, MII advertising for Next page\r
477        100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */\r
478     rc  = GMACB_ReadPhy(pHw, phyAddress, GMII_ANAR, &phyAnar, retryMax);\r
479     if (rc == 0) \r
480     {\r
481         goto AutoNegotiateExit;\r
482     }\r
483     phyAnar = GMII_TX_FDX | GMII_TX_HDX |\r
484               GMII_10_FDX | GMII_10_HDX | GMII_AN_IEEE_802_3;\r
485     rc = GMACB_WritePhy(pHw,phyAddress, GMII_ANAR, phyAnar, retryMax);\r
486     if (rc == 0) \r
487     {\r
488         goto AutoNegotiateExit;\r
489     }\r
490 \r
491     /* Read & modify 1000Base-T control register  */\r
492     rc  = GMACB_ReadPhy(pHw, phyAddress, GMII_1000BTCR, &gbaseTC, retryMax);\r
493     if (rc == 0) \r
494     {\r
495         goto AutoNegotiateExit;\r
496     }\r
497     gbaseTC |= GMII_1000BaseT_HALF_DUPLEX |GMII_1000BaseT_FULL_DUPLEX;\r
498     rc = GMACB_WritePhy(pHw, phyAddress, GMII_1000BTCR, gbaseTC, retryMax);\r
499     if (rc == 0) \r
500     {\r
501         goto AutoNegotiateExit;\r
502     }\r
503     \r
504     /* Read & modify control register */\r
505     rc  = GMACB_ReadPhy(pHw, phyAddress, GMII_BMCR, &value, retryMax);\r
506     if (rc == 0) \r
507     {\r
508         goto AutoNegotiateExit;\r
509     }\r
510 \r
511     /* Restart Auto_negotiation */\r
512     value |=  GMII_RESTART_AUTONEG;\r
513     rc = GMACB_WritePhy(pHw, phyAddress, GMII_BMCR, value, retryMax);\r
514     if (rc == 0) \r
515     {\r
516         goto AutoNegotiateExit;\r
517     }\r
518     TRACE_DEBUG(" _BMCR: 0x%X\n\r", value);\r
519 \r
520     /* Check AutoNegotiate complete */\r
521     while (1) \r
522     {\r
523         rc  = GMACB_ReadPhy(pHw, phyAddress, GMII_BMSR, &value, retryMax);\r
524         if (rc == 0)\r
525         {\r
526             TRACE_ERROR("rc==0\n\r");\r
527             goto AutoNegotiateExit;\r
528         }\r
529         /* Done successfully */\r
530         if (value & GMII_AUTONEG_COMP) \r
531         {\r
532             printf("AutoNegotiate complete\n\r");\r
533             break;\r
534         }\r
535         /* Timeout check */\r
536         if (retryMax)\r
537         {\r
538             if (++ retryCount >= retryMax)\r
539             {\r
540                 GMACB_DumpRegisters(pMacb);\r
541                 TRACE_ERROR("TimeOut\n\r");\r
542                 rc = 0;\r
543                 goto AutoNegotiateExit; \r
544             }\r
545         }\r
546     }\r
547 \r
548     /*Set local link mode */\r
549     while(1)\r
550     {\r
551         rc  = GMACB_ReadPhy(pHw, phyAddress, GMII_1000BTSR, &gbaseTS, retryMax);\r
552         if (rc == 0) \r
553         {\r
554             goto AutoNegotiateExit;\r
555         }\r
556         /* Setup the EMAC link speed */\r
557         if ((gbaseTS & GMII_LINKP_1000BaseT_FULL_DUPLEX) &&\r
558           (gbaseTC & GMII_1000BaseT_FULL_DUPLEX))\r
559         {\r
560             /* set RGMII for 1000BaseTX and Full Duplex */\r
561             duplex = GMAC_DUPLEX_FULL;\r
562             speed = GMAC_SPEED_1000M;\r
563             break;\r
564         }\r
565         else if ((gbaseTS & GMII_LINKP_1000BaseT_HALF_DUPLEX) &&\r
566           (gbaseTC & GMII_1000BaseT_HALF_DUPLEX))\r
567         {\r
568             /* set RGMII for 1000BaseT and Half Duplex*/\r
569             duplex = GMAC_DUPLEX_HALF;\r
570             speed = GMAC_SPEED_1000M;\r
571             break;\r
572         }\r
573 \r
574         /* Get the AutoNeg Link partner base page */\r
575         rc  = GMACB_ReadPhy(pHw, phyAddress, GMII_ANLPAR, &phyAnalpar, retryMax);\r
576         if (rc == 0) \r
577         {\r
578             goto AutoNegotiateExit;\r
579         }\r
580 \r
581         /* Setup the EMAC link speed */\r
582         if ((phyAnar & phyAnalpar) & GMII_TX_FDX) \r
583         {\r
584             /* set RGMII for 100BaseTX and Full Duplex */\r
585             duplex = GMAC_DUPLEX_FULL;\r
586             speed = GMAC_SPEED_100M;\r
587             break;\r
588         }\r
589         else if ((phyAnar & phyAnalpar) & GMII_10_FDX) \r
590         {\r
591             /* set RGMII for 10BaseT and Full Duplex */\r
592             duplex = GMAC_DUPLEX_FULL;\r
593             speed = GMAC_SPEED_10M;\r
594             break;\r
595         }\r
596         else if ((phyAnar & phyAnalpar) & GMII_TX_HDX) \r
597         {\r
598             /* set RGMII for 100BaseTX and half Duplex */\r
599             duplex = GMAC_DUPLEX_HALF;\r
600             speed = GMAC_SPEED_100M;\r
601             break;\r
602         }\r
603         else if ((phyAnar & phyAnalpar) & GMII_10_HDX) \r
604         {\r
605             /* set RGMII for 10BaseT and half Duplex */\r
606             duplex = GMAC_DUPLEX_HALF;\r
607             speed = GMAC_SPEED_10M;\r
608             break;\r
609         }\r
610     }\r
611 \r
612     /* Setup GMAC mode  */\r
613     GMAC_EnableRGMII(pHw, duplex, speed);\r
614 \r
615 AutoNegotiateExit:\r
616     GMAC_DisableMdio(pHw);\r
617     return rc;\r
618 }\r