mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-01-27 23:47:19 +01:00
realtek: mdio: enhance reading phy id
Reading the PHY ID to assign a PHY config is currently simple. For C45 two MDIO reads of a hardcoded MMD are done to get the standard PHY ID registers. MMD 31 (MMD_VEND2) is used for that purpose, assuming there will be a valid PHY ID stored in this MMD in all cases. However, with Aquantia AQR813 there's at least one example for which this isn't true. This PHY returns 0 for the PHY ID in MMD_VEND2, instead MMD_VEND1 would have the correct ID. Enhance reading the PHY by accessing a common set of MMDs of which most PHY at least implement one and have a valid PHY ID in. To keep overhead low, do not scan all MMDs. As soon as a valid PHY ID is found, exit and use that. This is similar to the kernel logic, jsut reduced to fewer MMDs. Also handle possible errors coming from MDIO reads to avoid reading garbage. While at it, move reading the PHY ID to a separate function to not pollute the poll fixup retrievel function. Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com> Link: https://github.com/openwrt/openwrt/pull/21515 Signed-off-by: Robert Marko <robert.marko@sartura.hr>
This commit is contained in:
parent
12fd85eb79
commit
322041ffeb
1 changed files with 50 additions and 6 deletions
|
|
@ -532,6 +532,52 @@ static int rtmdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rtmdio_read_phy_id(struct mii_bus *bus, u8 addr, unsigned int *phy_id)
|
||||
{
|
||||
static const int common_mmds[] = {
|
||||
MDIO_MMD_PMAPMD, MDIO_MMD_PCS, MDIO_MMD_AN,
|
||||
MDIO_MMD_VEND1, MDIO_MMD_VEND2
|
||||
};
|
||||
struct rtmdio_bus_priv *priv = bus->priv;
|
||||
int devid1 = 0, devid2 = 0;
|
||||
unsigned int id = 0;
|
||||
|
||||
/* Clause 22 */
|
||||
if (!priv->smi_bus_isc45[priv->smi_bus[addr]]) {
|
||||
devid1 = rtmdio_read(bus, addr, MDIO_DEVID1);
|
||||
devid2 = rtmdio_read(bus, addr, MDIO_DEVID2);
|
||||
if (devid1 < 0 || devid2 < 0)
|
||||
return -EIO;
|
||||
|
||||
id = (devid1 << 16) | devid2;
|
||||
if (!id || (id & 0x1fffffff) == 0x1fffffff)
|
||||
return -ENODEV;
|
||||
|
||||
*phy_id = id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Clause 45
|
||||
* only scan some MMDs which can be considered as common i.e.
|
||||
* implemented by most PHYs.
|
||||
*/
|
||||
for (int i = 0; i < ARRAY_SIZE(common_mmds); i++) {
|
||||
devid1 = rtmdio_read_c45(bus, addr, common_mmds[i], MDIO_DEVID1);
|
||||
devid2 = rtmdio_read_c45(bus, addr, common_mmds[i], MDIO_DEVID2);
|
||||
if (devid1 < 0 || devid2 < 0)
|
||||
continue;
|
||||
|
||||
id = (devid1 << 16) | devid2;
|
||||
if (id && id != 0xffffffff) {
|
||||
*phy_id = id;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void rtmdio_get_phy_info(struct mii_bus *bus, int addr, struct rtmdio_phy_info *phyinfo)
|
||||
{
|
||||
struct rtmdio_bus_priv *priv = bus->priv;
|
||||
|
|
@ -547,12 +593,10 @@ static void rtmdio_get_phy_info(struct mii_bus *bus, int addr, struct rtmdio_phy
|
|||
return;
|
||||
}
|
||||
|
||||
if (priv->smi_bus_isc45[priv->smi_bus[addr]])
|
||||
phyinfo->phy_id = (rtmdio_read_c45(bus, addr, 31, 2) << 16) +
|
||||
rtmdio_read_c45(bus, addr, 31, 3);
|
||||
else
|
||||
phyinfo->phy_id = (rtmdio_read(bus, addr, 2) << 16) +
|
||||
rtmdio_read(bus, addr, 3);
|
||||
if (rtmdio_read_phy_id(bus, addr, &phyinfo->phy_id) < 0) {
|
||||
phyinfo->phy_unknown = true;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(phyinfo->phy_id) {
|
||||
case RTMDIO_PHY_AQR113C:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue