mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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: Michael Walle <michael@walle.cc> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
fc3dd0367e
commit
1db8587078
1 changed files with 20 additions and 19 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue