Description
Source
Call Graph
Start Line: 319
unsigned char DM9161_AutoNegotiate(Dm9161 *pDm)
{
unsigned int retryMax;
unsigned int value;
unsigned int phyAnar;
unsigned int phyAnalpar;
unsigned int retryCount= 0;
unsigned char phyAddress;
unsigned char rc = 1;
ASSERT(pDm, "-F- DM9161_AutoNegotiate\n\r");
phyAddress = pDm->phyAddress;
retryMax = pDm->retryMax;
EMAC_EnableMdio();
if (!EMAC_ReadPhy(phyAddress, DM9161_PHYID1, &value, retryMax)) {
TRACE_ERROR("Pb EMAC_ReadPhy Id1\n\r");
rc = 0;
goto AutoNegotiateExit;
}
TRACE_DEBUG("ReadPhy Id1 0x%X, addresse: %d\n\r", value, phyAddress);
if (!EMAC_ReadPhy(phyAddress, DM9161_PHYID2, &phyAnar, retryMax)) {
TRACE_ERROR("Pb EMAC_ReadPhy Id2\n\r");
rc = 0;
goto AutoNegotiateExit;
}
TRACE_DEBUG("ReadPhy Id2 0x%X\n\r", phyAnar);
if( ( value == DM9161_OUI_MSB )
&& ( ((phyAnar>>10)&DM9161_LSB_MASK) == DM9161_OUI_LSB ) ) {
TRACE_DEBUG("Vendor Number Model = 0x%X\n\r", ((phyAnar>>4)&0x3F));
TRACE_DEBUG("Model Revision Number = 0x%X\n\r", (phyAnar&0x7));
}
else {
TRACE_ERROR("Problem OUI value\n\r");
}
// Setup control register
rc = EMAC_ReadPhy(phyAddress, DM9161_BMCR, &value, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
value &= ~DM9161_AUTONEG; // Remove autonegotiation enable
value &= ~(DM9161_LOOPBACK|DM9161_POWER_DOWN);
value |= DM9161_ISOLATE; // Electrically isolate PHY
rc = EMAC_WritePhy(phyAddress, DM9161_BMCR, value, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
// Set the Auto_negotiation Advertisement Register
// MII advertising for Next page
// 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3
phyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
rc = EMAC_WritePhy(phyAddress, DM9161_ANAR, phyAnar, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
// Read & modify control register
rc = EMAC_ReadPhy(phyAddress, DM9161_BMCR, &value, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
rc = EMAC_WritePhy(phyAddress, DM9161_BMCR, value, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
// Restart Auto_negotiation
value |= DM9161_RESTART_AUTONEG;
value &= ~DM9161_ISOLATE;
rc = EMAC_WritePhy(phyAddress, DM9161_BMCR, value, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
TRACE_DEBUG(" _BMCR: 0x%X\n\r", value);
// Check AutoNegotiate complete
while (1) {
rc = EMAC_ReadPhy(phyAddress, DM9161_BMSR, &value, retryMax);
if (rc == 0) {
TRACE_ERROR("rc==0\n\r");
goto AutoNegotiateExit;
}
// Done successfully
if (value & DM9161_AUTONEG_COMP) {
TRACE_INFO("AutoNegotiate complete\n\r");
break;
}
// Timeout check
if (retryMax) {
if (++ retryCount >= retryMax) {
DM9161_DumpRegisters(pDm);
TRACE_FATAL("TimeOut\n\r");
goto AutoNegotiateExit;
}
}
}
// Get the AutoNeg Link partner base page
rc = EMAC_ReadPhy(phyAddress, DM9161_ANLPAR, &phyAnalpar, retryMax);
if (rc == 0) {
goto AutoNegotiateExit;
}
// Setup the EMAC link speed
if ((phyAnar & phyAnalpar) & DM9161_TX_FDX) {
// set MII for 100BaseTX and Full Duplex
EMAC_SetLinkSpeed(1, 1);
}
else if ((phyAnar & phyAnalpar) & DM9161_10_FDX) {
// set MII for 10BaseT and Full Duplex
EMAC_SetLinkSpeed(0, 1);
}
else if ((phyAnar & phyAnalpar) & DM9161_TX_HDX) {
// set MII for 100BaseTX and half Duplex
EMAC_SetLinkSpeed(1, 0);
}
else if ((phyAnar & phyAnalpar) & DM9161_10_HDX) {
// set MII for 10BaseT and half Duplex
EMAC_SetLinkSpeed(0, 0);
}
// Setup EMAC mode
#if BOARD_EMAC_MODE_RMII != 1
EMAC_EnableMII();
#else
EMAC_EnableRMII();
#endif
AutoNegotiateExit:
EMAC_DisableMdio();
return rc;
}