Commit 1db85870 authored by Michael Walle's avatar Michael Walle Committed by David S. Miller

net: phy: mxl-gpy: cache PHY firmware version

Cache the firmware version during probe. There is no need to read the
firmware version on every autonegotiation.
Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fc3dd036
......@@ -77,6 +77,11 @@
#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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment