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