diff options
author | David S. Miller <davem@davemloft.net> | 2022-07-13 14:18:39 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-07-13 14:18:39 +0100 |
commit | cfc6c2fcb686afdaea5bbca6f3dbb27815a23878 (patch) | |
tree | fff910cdd083ca5b1214b5dbdfd0a9ada174b7c0 | |
parent | d7c31cbde4bc6756d1a11747d2b99bc627001c86 (diff) | |
parent | d523f2eb1dadb74d365365eb3bd921ad8b6b2abb (diff) |
Merge branch 'phy-mxl-gpy-version-fix-and-improvements'
Michael Walle says:
====================
net: phy: mxl-gpy: version fix and improvements
Fix the version reporting which was introduced earlier. The version will
not change during runtime, so cache it and save a PHY read on every auto
negotiation. Also print the version in a human readable form.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/mxl-gpy.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c index 5b99acf44337..24bae27eedef 100644 --- a/drivers/net/phy/mxl-gpy.c +++ b/drivers/net/phy/mxl-gpy.c @@ -56,7 +56,7 @@ PHY_IMASK_ANC) #define PHY_FWV_REL_MASK BIT(15) -#define PHY_FWV_TYPE_MASK GENMASK(11, 8) +#define PHY_FWV_MAJOR_MASK GENMASK(11, 8) #define PHY_FWV_MINOR_MASK GENMASK(7, 0) /* SGMII */ @@ -77,8 +77,13 @@ #define VPSPEC2_WOL_AD45 0x0E0A #define WOL_EN BIT(0) +struct gpy_priv { + u8 fw_major; + u8 fw_minor; +}; + static const struct { - int type; + int major; int minor; } ver_need_sgmii_reaneg[] = { {7, 0x6D}, @@ -198,6 +203,9 @@ static int gpy_config_init(struct phy_device *phydev) static int gpy_probe(struct phy_device *phydev) { + struct device *dev = &phydev->mdio.dev; + struct gpy_priv *priv; + int fw_version; int ret; if (!phydev->is_c45) { @@ -206,37 +214,38 @@ static int gpy_probe(struct phy_device *phydev) return ret; } - /* Show GPY PHY FW version in dmesg */ - ret = phy_read(phydev, PHY_FWV); - if (ret < 0) - return ret; + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + phydev->priv = priv; + + fw_version = phy_read(phydev, PHY_FWV); + if (fw_version < 0) + return fw_version; + priv->fw_major = FIELD_GET(PHY_FWV_MAJOR_MASK, fw_version); + priv->fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_version); ret = gpy_hwmon_register(phydev); if (ret) return ret; - phydev_info(phydev, "Firmware Version: 0x%04X (%s)\n", ret, - (ret & PHY_FWV_REL_MASK) ? "release" : "test"); + /* Show GPY PHY FW version in dmesg */ + phydev_info(phydev, "Firmware Version: %d.%d (0x%04X%s)\n", + priv->fw_major, priv->fw_minor, fw_version, + fw_version & PHY_FWV_REL_MASK ? "" : " test version"); return 0; } static bool gpy_sgmii_need_reaneg(struct phy_device *phydev) { - int fw_ver, fw_type, fw_minor; + struct gpy_priv *priv = phydev->priv; size_t i; - fw_ver = phy_read(phydev, PHY_FWV); - if (fw_ver < 0) - return true; - - fw_type = FIELD_GET(PHY_FWV_TYPE_MASK, fw_ver); - fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_ver); - for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) { - if (fw_type != ver_need_sgmii_reaneg[i].type) + if (priv->fw_major != ver_need_sgmii_reaneg[i].major) continue; - if (fw_minor < ver_need_sgmii_reaneg[i].minor) + if (priv->fw_minor < ver_need_sgmii_reaneg[i].minor) return true; break; } @@ -604,18 +613,12 @@ static int gpy_loopback(struct phy_device *phydev, bool enable) static int gpy115_loopback(struct phy_device *phydev, bool enable) { - int ret; - int fw_minor; + struct gpy_priv *priv = phydev->priv; if (enable) return gpy_loopback(phydev, enable); - ret = phy_read(phydev, PHY_FWV); - if (ret < 0) - return ret; - - fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, ret); - if (fw_minor > 0x0076) + if (priv->fw_minor > 0x76) return gpy_loopback(phydev, 0); return genphy_soft_reset(phydev); |