00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "board.h"
00037
00038
00039
00040
00041
00042
00043 #define GMACB_RETRY_MAX 300000
00044
00045
00046 #define GACB_RETRY_MAX 1000000
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 static uint8_t GMACB_WaitPhy(Gmac *pHw, uint32_t retry)
00060 {
00061 volatile uint32_t retry_count = 0;
00062
00063 while (!GMAC_IsIdle(pHw)) {
00064 if (retry == 0) continue;
00065
00066 retry_count ++;
00067
00068 if (retry_count >= retry)
00069 return 0;
00070 }
00071
00072 return 1;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 static uint8_t GMACB_ReadPhy(Gmac *pHw,
00085 uint8_t PhyAddress,
00086 uint8_t Address,
00087 uint32_t *pValue,
00088 uint32_t retry)
00089 {
00090 GMAC_PHYMaintain(pHw, PhyAddress, Address, 1, 0);
00091
00092 if (GMACB_WaitPhy(pHw, retry) == 0) {
00093 TRACE_ERROR("TimeOut GMACB_ReadPhy\n\r");
00094 return 0;
00095 }
00096
00097 *pValue = GMAC_PHYData(pHw);
00098 return 1;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 static uint8_t GMACB_WritePhy(Gmac *pHw,
00111 uint8_t PhyAddress,
00112 uint8_t Address,
00113 uint32_t Value,
00114 uint32_t retry)
00115 {
00116 GMAC_PHYMaintain(pHw, PhyAddress, Address, 0, Value);
00117
00118 if (GMACB_WaitPhy(pHw, retry) == 0) {
00119 TRACE_ERROR("TimeOut GMACB_WritePhy\n\r");
00120 return 0;
00121 }
00122
00123 return 1;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static uint8_t GMACB_FindValidPhy(GMacb *pMacb)
00136 {
00137 sGmacd *pDrv = pMacb->pGmacd;
00138 Gmac *pHw = pDrv->pHw;
00139
00140 uint32_t retryMax;
00141 uint32_t value = 0;
00142 uint8_t rc;
00143 uint8_t phyAddress;
00144 uint8_t cnt;
00145
00146 TRACE_DEBUG("GMACB_FindValidPhy\n\r");
00147
00148 GMAC_EnableMdio(pHw);
00149 phyAddress = pMacb->phyAddress;
00150 retryMax = pMacb->retryMax;
00151
00152
00153 rc = phyAddress;
00154
00155 if (GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1R, &value, retryMax) == 0)
00156 TRACE_ERROR("GMACB PROBLEM\n\r");
00157
00158 TRACE_DEBUG("_PHYID1 : 0x%X, addr: %d\n\r", value, phyAddress);
00159
00160
00161 if (value != GMII_OUI_MSB) {
00162 rc = 0xFF;
00163
00164 for (cnt = 0; cnt < 32; cnt ++) {
00165 phyAddress = (phyAddress + 1) & 0x1F;
00166
00167 if (GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1R, &value, retryMax)
00168 == 0)
00169 TRACE_ERROR("MACB PROBLEM\n\r");
00170
00171 TRACE_DEBUG("_PHYID1 : 0x%X, addr: %d\n\r", value, phyAddress);
00172
00173 if (value == GMII_OUI_MSB) {
00174
00175 rc = phyAddress;
00176 break;
00177 }
00178 }
00179 }
00180
00181 if (rc != 0xFF) {
00182 TRACE_INFO("** Valid PHY Found: %d\n\r", rc);
00183 GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1R, &value, retryMax);
00184 TRACE_DEBUG("_PHYID1R : 0x%X, addr: %d\n\r", value, phyAddress);
00185 GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID2R, &value, retryMax);
00186 TRACE_DEBUG("_EMSR : 0x%X, addr: %d\n\r", value, phyAddress);
00187 }
00188
00189 GMAC_DisableMdio(pHw);
00190 return rc;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 void GMACB_DumpRegisters(GMacb *pMacb)
00204 {
00205 sGmacd *pDrv = pMacb->pGmacd;
00206 Gmac *pHw = pDrv->pHw;
00207
00208 uint8_t phyAddress;
00209 uint32_t retryMax;
00210 uint32_t value;
00211
00212 TRACE_INFO("GMACB_DumpRegisters\n\r");
00213
00214 GMAC_EnableMdio(pHw);
00215 phyAddress = pMacb->phyAddress;
00216 retryMax = pMacb->retryMax;
00217
00218 TRACE_INFO("GMII MACB @ %d) Registers:\n\r", phyAddress);
00219
00220 GMACB_ReadPhy(pHw, phyAddress, GMII_BMCR, &value, retryMax);
00221 TRACE_INFO(" _BMCR : 0x%X\n\r", (unsigned)value);
00222 GMACB_ReadPhy(pHw, phyAddress, GMII_BMSR, &value, retryMax);
00223 TRACE_INFO(" _BMSR : 0x%X\n\r", (unsigned)value);
00224 GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1R, &value, retryMax);
00225 TRACE_INFO(" _PHYID1 : 0x%X\n\r", (unsigned)value);
00226 GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID2R, &value, retryMax);
00227 TRACE_INFO(" _PHYID2 : 0x%X\n\r", (unsigned)value);
00228 GMACB_ReadPhy(pHw, phyAddress, GMII_ANAR, &value, retryMax);
00229 TRACE_INFO(" _ANAR : 0x%X\n\r", (unsigned)value);
00230 GMACB_ReadPhy(pHw, phyAddress, GMII_ANLPAR, &value, retryMax);
00231 TRACE_INFO(" _ANLPAR : 0x%X\n\r", (unsigned)value);
00232 GMACB_ReadPhy(pHw, phyAddress, GMII_ANER, &value, retryMax);
00233 TRACE_INFO(" _ANER : 0x%X\n\r", (unsigned)value);
00234 GMACB_ReadPhy(pHw, phyAddress, GMII_ANNPR, &value, retryMax);
00235 TRACE_INFO(" _ANNPR : 0x%X\n\r", (unsigned)value);
00236 GMACB_ReadPhy(pHw, phyAddress, GMII_ANLPNPAR, &value, retryMax);
00237 TRACE_INFO(" _ANLPNPAR : 0x%X\n\r", (unsigned)value);
00238
00239 TRACE_INFO(" \n\r");
00240
00241 GMACB_ReadPhy(pHw, phyAddress, GMII_RXERCR, &value, retryMax);
00242 TRACE_INFO(" _RXERCR : 0x%X\n\r", (unsigned)value);
00243 GMACB_ReadPhy(pHw, phyAddress, GMII_ICSR, &value, retryMax);
00244 TRACE_INFO(" _ICSR : 0x%X\n\r", (unsigned)value);
00245 TRACE_INFO(" \n\r");
00246
00247 GMAC_DisableMdio(pHw);
00248 }
00249
00250
00251
00252
00253
00254
00255 void GMACB_SetupTimeout(GMacb *pMacb, uint32_t toMax)
00256 {
00257 pMacb->retryMax = toMax;
00258 }
00259
00260
00261
00262
00263
00264
00265 void GMACB_Init(GMacb *pMacb, sGmacd *pGmacd, uint8_t phyAddress)
00266 {
00267 pMacb->pGmacd = pGmacd;
00268 pMacb->phyAddress = phyAddress;
00269
00270 pMacb->retryMax = GMACB_RETRY_MAX;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 uint8_t GMACB_ResetPhy(GMacb *pMacb)
00280 {
00281 sGmacd *pDrv = pMacb->pGmacd;
00282 Gmac *pHw = pDrv->pHw;
00283 uint32_t retryMax;
00284 uint32_t bmcr = GMII_RESET;
00285 uint8_t phyAddress;
00286 uint32_t timeout = 10;
00287 uint8_t ret = 1;
00288
00289 TRACE_INFO(" GMACB_ResetPhy\n\r");
00290
00291 phyAddress = pMacb->phyAddress;
00292 retryMax = pMacb->retryMax;
00293
00294 GMAC_EnableMdio(pHw);
00295 bmcr = GMII_RESET;
00296 GMACB_WritePhy(pHw, phyAddress, GMII_BMCR, bmcr, retryMax);
00297
00298 do {
00299 GMACB_ReadPhy(pHw, phyAddress, GMII_BMCR, &bmcr, retryMax);
00300 timeout--;
00301 } while ((bmcr & GMII_RESET) && timeout);
00302
00303 GMAC_DisableMdio(pHw);
00304
00305 if (!timeout)
00306 ret = 0;
00307
00308 return (ret);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 uint8_t GMACB_InitPhy(GMacb *pMacb,
00329 uint32_t mck,
00330 const Pin *pResetPins,
00331 uint32_t nbResetPins,
00332 const Pin *pGmacPins,
00333 uint32_t nbGmacPins)
00334 {
00335 sGmacd *pDrv = pMacb->pGmacd;
00336 Gmac *pHw = pDrv->pHw;
00337 uint8_t rc = 1;
00338 uint8_t phy;
00339
00340
00341 TRACE_DEBUG("RESET PHY\n\r");
00342
00343 if (pResetPins) {
00344
00345 PIO_Configure(pResetPins, nbResetPins);
00346 TRACE_INFO(" Hard Reset of GMACD Phy\n\r");
00347 PIO_Clear(pResetPins);
00348 Wait(100);
00349 PIO_Set(pResetPins);
00350 }
00351
00352
00353 if (rc) {
00354
00355 PIO_Configure(pGmacPins, nbGmacPins);
00356 rc = GMAC_SetMdcClock(pHw, mck);
00357
00358 if (!rc) {
00359 TRACE_ERROR("No Valid MDC clock\n\r");
00360 return 0;
00361 }
00362
00363
00364 phy = GMACB_FindValidPhy(pMacb);
00365
00366 if (phy == 0xFF) {
00367 TRACE_ERROR("PHY Access fail\n\r");
00368 return 0;
00369 }
00370
00371 if (phy != pMacb->phyAddress) {
00372 pMacb->phyAddress = phy;
00373 GMACB_ResetPhy(pMacb);
00374 }
00375 } else
00376 TRACE_ERROR("PHY Reset Timeout\n\r");
00377
00378 return rc;
00379 }
00380
00381
00382
00383
00384
00385
00386 uint8_t GMACB_AutoNegotiate(GMacb *pMacb)
00387 {
00388 sGmacd *pDrv = pMacb->pGmacd;
00389 Gmac *pHw = pDrv->pHw;
00390 uint32_t retryMax;
00391 uint32_t value;
00392 uint32_t phyAnar;
00393 uint32_t phyAnalpar;
00394 uint32_t retryCount = 0;
00395 uint8_t phyAddress;
00396 uint8_t rc = 1;
00397 uint32_t duplex, speed;
00398 phyAddress = pMacb->phyAddress;
00399 retryMax = pMacb->retryMax;
00400
00401 GMAC_EnableMdio(pHw);
00402
00403 if (!GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID1R, &value, retryMax)) {
00404 TRACE_ERROR("Pb GEMAC_ReadPhy Id1\n\r");
00405 rc = 0;
00406 goto AutoNegotiateExit;
00407 }
00408
00409 TRACE_DEBUG("ReadPhy Id1 0x%X, address: %d\n\r", value, phyAddress);
00410
00411 if (!GMACB_ReadPhy(pHw, phyAddress, GMII_PHYID2R, &phyAnar, retryMax)) {
00412 TRACE_ERROR("Pb GMACB_ReadPhy Id2\n\r");
00413 rc = 0;
00414 goto AutoNegotiateExit;
00415 }
00416
00417 TRACE_DEBUG("ReadPhy Id2 0x%X\n\r", phyAnar);
00418
00419 if ((value == GMII_OUI_MSB)
00420 && (((phyAnar) & (~GMII_LSB_MASK)) == GMII_OUI_LSB)) {
00421 TRACE_DEBUG("Vendor Number Model = 0x%X\n\r", ((phyAnar >> 4) & 0x3F));
00422 TRACE_DEBUG("Model Revision Number = 0x%X\n\r", (phyAnar & 0xF));
00423 } else
00424 TRACE_ERROR("Problem OUI value\n\r");
00425
00426
00427
00428 rc = GMACB_ReadPhy(pHw, phyAddress, GMII_ANAR, &phyAnar, retryMax);
00429
00430 if (rc == 0)
00431 goto AutoNegotiateExit;
00432
00433 phyAnar = GMII_TX_FDX | GMII_TX_HDX |
00434 GMII_10_FDX | GMII_10_HDX | GMII_AN_IEEE_802_3;
00435 rc = GMACB_WritePhy(pHw, phyAddress, GMII_ANAR, phyAnar, retryMax);
00436
00437 if (rc == 0)
00438 goto AutoNegotiateExit;
00439
00440
00441 rc = GMACB_ReadPhy(pHw, phyAddress, GMII_BMCR, &value, retryMax);
00442
00443 if (rc == 0)
00444 goto AutoNegotiateExit;
00445
00446
00447 value |= GMII_AUTONEG | GMII_RESTART_AUTONEG;
00448 rc = GMACB_WritePhy(pHw, phyAddress, GMII_BMCR, value, retryMax);
00449
00450 if (rc == 0)
00451 goto AutoNegotiateExit;
00452
00453 TRACE_DEBUG(" _BMCR: 0x%X\n\r", value);
00454
00455
00456 while (1) {
00457 rc = GMACB_ReadPhy(pHw, phyAddress, GMII_BMSR, &value, retryMax);
00458
00459 if (rc == 0) {
00460 TRACE_ERROR("rc==0\n\r");
00461 goto AutoNegotiateExit;
00462 }
00463
00464
00465 if (value & GMII_AUTONEG_COMP) {
00466 printf("AutoNegotiate complete\n\r");
00467 break;
00468 }
00469
00470
00471 if (retryMax) {
00472 if (++ retryCount >= retryMax) {
00473 GMACB_DumpRegisters(pMacb);
00474 TRACE_ERROR("TimeOut\n\r");
00475 rc = 0;
00476 goto AutoNegotiateExit;
00477 }
00478 }
00479 }
00480
00481
00482 while (1) {
00483 rc = GMACB_ReadPhy(pHw, phyAddress, GMII_ANLPAR, &phyAnalpar, retryMax);
00484
00485 if (rc == 0)
00486 goto AutoNegotiateExit;
00487
00488
00489 if ((phyAnar & phyAnalpar) & GMII_TX_FDX) {
00490
00491 duplex = GMAC_DUPLEX_FULL;
00492 speed = GMAC_SPEED_100M;
00493 break;
00494 } else if ((phyAnar & phyAnalpar) & GMII_10_FDX) {
00495
00496 duplex = GMAC_DUPLEX_FULL;
00497 speed = GMAC_SPEED_10M;
00498 break;
00499 } else if ((phyAnar & phyAnalpar) & GMII_TX_HDX) {
00500
00501 duplex = GMAC_DUPLEX_HALF;
00502 speed = GMAC_SPEED_100M;
00503 break;
00504 } else if ((phyAnar & phyAnalpar) & GMII_10_HDX) {
00505
00506 duplex = GMAC_DUPLEX_HALF;
00507 speed = GMAC_SPEED_10M;
00508 break;
00509 }
00510 }
00511
00512 TRACE_INFO("GMAC_EnableRGMII duplex %u, speed %u\n\r", (unsigned)duplex,
00513 (unsigned)speed);
00514
00515 GMACB_ReadPhy(pHw, phyAddress, GMII_PC1R, &value, retryMax);
00516 GMACB_ReadPhy(pHw, phyAddress, GMII_PC2R, &value, retryMax);
00517 GMACB_ReadPhy(pHw, phyAddress, GMII_ICSR, &value, retryMax);
00518
00519 GMAC_EnableRGMII(pHw, duplex, speed);
00520
00521 AutoNegotiateExit:
00522 GMAC_DisableMdio(pHw);
00523 return rc;
00524 }