[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <b65cd0978587224eb1496ad60d224394525b8ba6.1540204183.git.joabreu@synopsys.com>
Date: Mon, 22 Oct 2018 11:32:48 +0100
From: Jose Abreu <jose.abreu@...opsys.com>
To: netdev@...r.kernel.org
Cc: Jose Abreu <jose.abreu@...opsys.com>, Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Joao Pinto <joao.pinto@...opsys.com>
Subject: [PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks
Implement the missing callbacks for Generic 10G PHY. Tested using XGMAC
with a C45 PHY working at 10G Link.
Signed-off-by: Jose Abreu <joabreu@...opsys.com>
Cc: Andrew Lunn <andrew@...n.ch>
Cc: Florian Fainelli <f.fainelli@...il.com>
Cc: "David S. Miller" <davem@...emloft.net>
Cc: Joao Pinto <joao.pinto@...opsys.com>
---
drivers/net/phy/phy-c45.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index c0135217b81f..7e62bd7795a3 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -1,6 +1,7 @@
/*
* Clause 45 PHY support
*/
+#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/export.h>
#include <linux/mdio.h>
@@ -294,6 +295,35 @@ int gen10g_read_status(struct phy_device *phydev)
}
EXPORT_SYMBOL_GPL(gen10g_read_status);
+static int gen10g_poll_reset(struct phy_device *phydev)
+{
+ /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
+ unsigned int retries = 12;
+ int ret;
+
+ do {
+ msleep(50);
+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
+ if (ret < 0)
+ return ret;
+ } while (ret & MDIO_CTRL1_RESET && --retries);
+ if (ret & MDIO_CTRL1_RESET)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int gen10g_soft_reset(struct phy_device *phydev)
+{
+ int val;
+
+ val = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, MDIO_CTRL1_RESET);
+ if (val < 0)
+ return val;
+
+ return gen10g_poll_reset(phydev);
+}
+
int gen10g_no_soft_reset(struct phy_device *phydev)
{
/* Do nothing for now */
@@ -313,12 +343,36 @@ EXPORT_SYMBOL_GPL(gen10g_config_init);
int gen10g_suspend(struct phy_device *phydev)
{
+ int val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
+ if (val < 0)
+ return val;
+
+ val |= MDIO_CTRL1_LPOWER;
+
+ val = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, val);
+ if (val < 0)
+ return val;
+
return 0;
}
EXPORT_SYMBOL_GPL(gen10g_suspend);
int gen10g_resume(struct phy_device *phydev)
{
+ int val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
+ if (val < 0)
+ return val;
+
+ val &= ~MDIO_CTRL1_LPOWER;
+
+ val = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, val);
+ if (val < 0)
+ return val;
+
return 0;
}
EXPORT_SYMBOL_GPL(gen10g_resume);
@@ -327,7 +381,7 @@ struct phy_driver genphy_10g_driver = {
.phy_id = 0xffffffff,
.phy_id_mask = 0xffffffff,
.name = "Generic 10G PHY",
- .soft_reset = gen10g_no_soft_reset,
+ .soft_reset = gen10g_soft_reset,
.config_init = gen10g_config_init,
.features = 0,
.aneg_done = genphy_c45_aneg_done,
--
2.7.4
Powered by blists - more mailing lists