Commit cfc6c2fc authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents d7c31cbd d523f2eb
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
PHY_IMASK_ANC) PHY_IMASK_ANC)
#define PHY_FWV_REL_MASK BIT(15) #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) #define PHY_FWV_MINOR_MASK GENMASK(7, 0)
/* SGMII */ /* SGMII */
...@@ -77,8 +77,13 @@ ...@@ -77,8 +77,13 @@
#define VPSPEC2_WOL_AD45 0x0E0A #define VPSPEC2_WOL_AD45 0x0E0A
#define WOL_EN BIT(0) #define WOL_EN BIT(0)
struct gpy_priv {
u8 fw_major;
u8 fw_minor;
};
static const struct { static const struct {
int type; int major;
int minor; int minor;
} ver_need_sgmii_reaneg[] = { } ver_need_sgmii_reaneg[] = {
{7, 0x6D}, {7, 0x6D},
...@@ -198,6 +203,9 @@ static int gpy_config_init(struct phy_device *phydev) ...@@ -198,6 +203,9 @@ static int gpy_config_init(struct phy_device *phydev)
static int gpy_probe(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; int ret;
if (!phydev->is_c45) { if (!phydev->is_c45) {
...@@ -206,37 +214,38 @@ static int gpy_probe(struct phy_device *phydev) ...@@ -206,37 +214,38 @@ static int gpy_probe(struct phy_device *phydev)
return ret; return ret;
} }
/* Show GPY PHY FW version in dmesg */ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
ret = phy_read(phydev, PHY_FWV); if (!priv)
if (ret < 0) return -ENOMEM;
return ret; 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); ret = gpy_hwmon_register(phydev);
if (ret) if (ret)
return ret; return ret;
phydev_info(phydev, "Firmware Version: 0x%04X (%s)\n", ret, /* Show GPY PHY FW version in dmesg */
(ret & PHY_FWV_REL_MASK) ? "release" : "test"); 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; return 0;
} }
static bool gpy_sgmii_need_reaneg(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; 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++) { 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; continue;
if (fw_minor < ver_need_sgmii_reaneg[i].minor) if (priv->fw_minor < ver_need_sgmii_reaneg[i].minor)
return true; return true;
break; break;
} }
...@@ -604,18 +613,12 @@ static int gpy_loopback(struct phy_device *phydev, bool enable) ...@@ -604,18 +613,12 @@ static int gpy_loopback(struct phy_device *phydev, bool enable)
static int gpy115_loopback(struct phy_device *phydev, bool enable) static int gpy115_loopback(struct phy_device *phydev, bool enable)
{ {
int ret; struct gpy_priv *priv = phydev->priv;
int fw_minor;
if (enable) if (enable)
return gpy_loopback(phydev, enable); return gpy_loopback(phydev, enable);
ret = phy_read(phydev, PHY_FWV); if (priv->fw_minor > 0x76)
if (ret < 0)
return ret;
fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, ret);
if (fw_minor > 0x0076)
return gpy_loopback(phydev, 0); return gpy_loopback(phydev, 0);
return genphy_soft_reset(phydev); 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