net: phy: mxl-gpy: cache PHY firmware version
authorMichael Walle <michael@walle.cc>
Tue, 12 Jul 2022 13:15:52 +0000 (15:15 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 Jul 2022 13:18:39 +0000 (14:18 +0100)
Cache the firmware version during probe. There is no need to read the
firmware version on every autonegotiation.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/mxl-gpy.c

index 9728ef9..b630308 100644 (file)
 #define VPSPEC2_WOL_AD45       0x0E0A
 #define WOL_EN                 BIT(0)
 
+struct gpy_priv {
+       u8 fw_type;
+       u8 fw_minor;
+};
+
 static const struct {
        int type;
        int minor;
@@ -198,6 +203,8 @@ 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;
 
@@ -207,15 +214,22 @@ static int gpy_probe(struct phy_device *phydev)
                        return ret;
        }
 
-       /* Show GPY PHY FW version in dmesg */
+       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_type = FIELD_GET(PHY_FWV_TYPE_MASK, fw_version);
+       priv->fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_version);
 
        ret = gpy_hwmon_register(phydev);
        if (ret)
                return ret;
 
+       /* Show GPY PHY FW version in dmesg */
        phydev_info(phydev, "Firmware Version: 0x%04X (%s)\n", fw_version,
                    (fw_version & PHY_FWV_REL_MASK) ? "release" : "test");
 
@@ -224,20 +238,13 @@ static int gpy_probe(struct phy_device *phydev)
 
 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_type != ver_need_sgmii_reaneg[i].type)
                        continue;
-               if (fw_minor < ver_need_sgmii_reaneg[i].minor)
+               if (priv->fw_minor < ver_need_sgmii_reaneg[i].minor)
                        return true;
                break;
        }
@@ -605,18 +612,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);