uint32_t PHY_start_auto_negotiate(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr, unsigned short advVal) { volatile unsigned short regContent = 0; /* Enable Auto Negotiation */ if (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BMCR, ®Content) != TRUE) { return FALSE; } regContent |= PHY_AUTONEG_EN_m; MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BMCR, regContent); /* originally ...HY_BMCR, PHY_RESET_m | PHY_AUTONEG_EN_m); */ /* Write Auto Negotiation capabilities */ if (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_ANAR, ®Content) != TRUE) { return FALSE; } regContent |= advVal; MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_ANAR, regContent); /* Start Auto Negotiation */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BMCR, ®Content); regContent |= PHY_AUTONEG_REST; MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BMCR, regContent); return TRUE; /* request to PHY through EMAC for autonegotiation established */ }
/** * \brief This function ask the phy device to start auto negotiation. * * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * \param advVal Autonegotiation advertisement value * \param gigAdvVal Gigabit capability advertisement value * advVal can take the following any OR combination of the values \n * PHY_100BTX - 100BaseTX \n * PHY_100BTX_FD - Full duplex capabilty for 100BaseTX \n * PHY_10BT - 10BaseT \n * PHY_10BT_FD - Full duplex capability for 10BaseT \n * gigAdvVal can take one of the following values \n * PHY_NO_1000BT - No 1000Base-T capability\n * PHY_1000BT_FD - Full duplex capabilty for 1000 Base-T \n * PHY_1000BT_HD - Half duplex capabilty for 1000 Base-T \n * FALSE - It is passed as an argument if phy dosen't support * Giga bit capability * * \return status after autonegotiation \n * TRUE if autonegotiation started * FALSE if autonegotiation not started * **/ unsigned int PhyAutoNegotiate(unsigned int mdioBaseAddr, unsigned int phyAddr, unsigned short *advPtr, unsigned short *gigAdvPtr) { volatile unsigned short data; volatile unsigned short anar; if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BCR, &data) != TRUE ) { return FALSE; } data |= PHY_AUTONEG_ENABLE; if (*gigAdvPtr != 0) { /* Set phy for gigabit speed */ data &= PHY_SPEED_MASK; data |= PHY_SPEED_1000MBPS; } /* Enable Auto Negotiation */ MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BCR, data); if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BCR, &data) != TRUE ) { return FALSE; } /* Write Auto Negotiation capabilities */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_AUTONEG_ADV, &anar); anar &= ~PHY_ADV_VAL_MASK; MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_AUTONEG_ADV, (anar |(*advPtr))); /* Write Auto Negotiation Gigabyte capabilities */ anar = 0; MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_1000BT_CONTROL, &anar); anar &= ~PHY_GIG_ADV_VAL_MASK; MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_1000BT_CONTROL, (anar |(*gigAdvPtr))); data |= PHY_AUTONEG_RESTART; /* Start Auto Negotiation */ MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BCR, data); return TRUE; }
void PHY_reset(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr) { volatile unsigned short regContent; MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BMCR, PHY_RESET_m); while (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BMCR, ®Content) & PHY_RESET_m); }
void PHY_Power_Up(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr) { volatile unsigned short regContent; MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BMCR, ®Content); MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BMCR, regContent & ~PHY_POWERDOWN_m); }
/** * \brief Reads the Link Partner Ability register of the PHY. * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * \param ptnerAblty Pointer to which partner ability will be written. * \param gbpsPtnerAblty Pointer to which Giga bit capability will be written. * * gbpsPtnerAblty can take following Macros.\n * * TRUE - It is passed as argument if phy supports Giga bit capability.\n * FALSE - It is passed as argument if phy dosen't supports Giga bit * capability.\n * * \return status after reading \n * TRUE if reading successful * FALSE if reading failed **/ unsigned int PhyPartnerAbilityGet(unsigned int mdioBaseAddr, unsigned int phyAddr, unsigned short *ptnerAblty, unsigned short *gbpsPtnerAblty) { unsigned int status; status = MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_LINK_PARTNER_ABLTY, ptnerAblty); if (*gbpsPtnerAblty != 0) { status = status | MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_1000BT_STATUS, gbpsPtnerAblty); } return status; }
uint32_t PHY_RMII_mode_get(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr) { volatile unsigned short regContent; /* Read the RBR of the PHY */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_RBR, ®Content); return (regContent & PHY_RMII_MODE); }
/** * \brief Reads the PHY ID. * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * * \return 32 bit PHY ID (ID1:ID2) * **/ unsigned int PhyIDGet(unsigned int mdioBaseAddr, unsigned int phyAddr) { unsigned int id = 0; unsigned short data; /* read the ID1 register */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_ID1, &data); /* update the ID1 value */ id = data << PHY_ID_SHIFT; /* read the ID2 register */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_ID2, &data); /* update the ID2 value */ id |= data; /* return the ID in ID1:ID2 format */ return id; }
uint32_t PHY_is_done_auto_negotiate(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr) { volatile unsigned short regContent; if (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BMSR, ®Content) != TRUE) { return FALSE; } if ((regContent & PHY_A_NEG_COMPLETE_m) == 0) return FALSE; return TRUE; }
void PHY_MII_mode_set(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr, uint32_t mode) { volatile unsigned short regContent; /* Read the RBR of the PHY */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_RBR, ®Content); /* Write the RBR of the PHY */ regContent &= 0x1f; regContent |= ( mode << 5 ); MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_RBR, regContent); }
/** * \brief Returns the status of Auto Negotiation completion. * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * * \return Auto negotiation completion status \n * TRUE if auto negotiation is completed * FALSE if auto negotiation is not completed **/ unsigned int PhyAutoNegStatusGet(unsigned int mdioBaseAddr, unsigned int phyAddr) { volatile unsigned short data; MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BSR, &data); /* Auto negotiation completion status */ if(PHY_AUTONEG_COMPLETE == (data & (PHY_AUTONEG_STATUS))) { return TRUE; } return FALSE; }
/** * \brief Disables Loop Back mode * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * * \return status after enabling. \n * TRUE if loop back is disabled \n * FALSE if not able to disable * **/ unsigned int PhyLoopBackDisable(unsigned int mdioBaseAddr, unsigned int phyAddr) { unsigned short data; if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BCR, &data) != TRUE ) { return FALSE; } data &= ~(PHY_LPBK_ENABLE); /* Disable loop back */ MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BCR, data); return TRUE; }
uint32_t PHY_link_status_get(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr, volatile uint32_t retries) { volatile unsigned short linkStatus; volatile uint32_t retVal = TRUE; while (retVal == TRUE) { /* Read the BSR of the PHY */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BMSR, &linkStatus); if (linkStatus & PHY_LINK_STATUS_m) { break; } else { (retries != 0) ? retries-- : (retVal = FALSE); } } return retVal; }
/** * \brief Resets the PHY * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * \param speed Speed to be enabled * \param duplexMode Duplex Mode * * \return status after configuring \n * TRUE if configuration successful * FALSE if configuration failed * **/ unsigned int PhyReset(unsigned int mdioBaseAddr, unsigned int phyAddr) { unsigned short data; data = PHY_SOFTRESET; /* Reset the phy */ MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BCR, data); /* wait till the reset bit is auto cleared */ while(data & PHY_SOFTRESET) { /* Read the reset */ if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BCR, &data) != TRUE) { return FALSE; } } return TRUE; }
/** * \brief Reads the link status of the PHY. * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * \param retries The number of retries before indicating down status * * \return link status after reading \n * TRUE if link is up * FALSE if link is down \n * * \note This reads both the basic status register of the PHY and the * link register of MDIO for double check **/ unsigned int PhyLinkStatusGet(unsigned int mdioBaseAddr, unsigned int phyAddr, volatile unsigned int retries) { volatile unsigned short linkStatus; retries++; while (retries) { /* First read the BSR of the PHY */ MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BSR, &linkStatus); if(linkStatus & PHY_LINK_STATUS) { return TRUE; } retries--; } return FALSE; }
/** * \brief Reads a register from the the PHY * * \param mdioBaseAddr Base Address of the MDIO Module Registers. * \param phyAddr PHY Adress. * \param regIdx Index of the register to be read * \param regValAdr address where value of the register will be written * * \return status of the read * **/ unsigned int PhyRegRead(unsigned int mdioBaseAddr, unsigned int phyAddr, unsigned int regIdx, unsigned short *regValAdr) { return (MDIOPhyRegRead(mdioBaseAddr, phyAddr, regIdx, regValAdr)); }
uint32_t PHY_partner_ability_get(volatile tms570_mdio_t *mdioBaseAddr, uint32_t phyAddr, unsigned short *regContent) { return (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_ANLPAR, regContent)); }