mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix
@ 2017-06-23  7:54 Lin Yun Sheng
  2017-06-23  7:54 ` [PATCH NET v2 1/2] net: phy: Add phy loopback support in net phy framework Lin Yun Sheng
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Lin Yun Sheng @ 2017-06-23  7:54 UTC (permalink / raw)
  To: davem, andrew, f.fainelli
  Cc: huangdaode, xuwei5, liguozhu, Yisen.Zhuang, gabriele.paoloni,
	john.garry, linuxarm, yisen.zhuang, salil.mehta, lipeng321,
	tremyfr, netdev, linux-kernel

This Patch Set add set_loopback in phy_driver and use it to setup loopback
when doing ethtool phy self_test.

Patch V2:
	1. Add phy_loopback in phy_device.c.
	2. Do error checking and do the read and write once in genphy_loopback.
	3. Remove gen10g_loopback in phy_device.c.

Patch V1: Initial Submit

Lin Yun Sheng (2):
  net: phy: Add phy loopback support in net phy framework
  net: hns: Use phy_driver to setup Phy loopback

 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 68 +++++-------------------
 drivers/net/phy/marvell.c                        |  1 +
 drivers/net/phy/phy_device.c                     | 41 ++++++++++++++
 include/linux/phy.h                              |  5 ++
 4 files changed, 61 insertions(+), 54 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH NET v2 1/2] net: phy: Add phy loopback support in net phy framework
  2017-06-23  7:54 [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Lin Yun Sheng
@ 2017-06-23  7:54 ` Lin Yun Sheng
  2017-06-23  7:54 ` [PATCH NET v2 2/2] net: hns: Use phy_driver to setup Phy loopback Lin Yun Sheng
  2017-06-23  8:18 ` [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Yunsheng Lin
  2 siblings, 0 replies; 4+ messages in thread
From: Lin Yun Sheng @ 2017-06-23  7:54 UTC (permalink / raw)
  To: davem, andrew, f.fainelli
  Cc: huangdaode, xuwei5, liguozhu, Yisen.Zhuang, gabriele.paoloni,
	john.garry, linuxarm, yisen.zhuang, salil.mehta, lipeng321,
	tremyfr, netdev, linux-kernel

This patch add set_loopback in phy_driver, which is used by Mac
driver to enable or disable a phy. it also add a generic
genphy_loopback function, which use BMCR loopback bit to enable
or disable a phy.

Signed-off-by: Lin Yun Sheng <linyunsheng@huawei.com>
---
 drivers/net/phy/marvell.c    |  1 +
 drivers/net/phy/phy_device.c | 41 +++++++++++++++++++++++++++++++++++++++++
 include/linux/phy.h          |  5 +++++
 3 files changed, 47 insertions(+)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 57297ba..01a1586 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -2094,6 +2094,7 @@ static int m88e1510_probe(struct phy_device *phydev)
 		.get_sset_count = marvell_get_sset_count,
 		.get_strings = marvell_get_strings,
 		.get_stats = marvell_get_stats,
+		.set_loopback = genphy_loopback,
 	},
 	{
 		.phy_id = MARVELL_PHY_ID_88E1540,
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 1219eea..1e8f800 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1123,6 +1123,29 @@ int phy_resume(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_resume);
 
+int phy_loopback(struct phy_device *phydev, bool enable)
+{
+	struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
+	int ret = 0;
+
+	if (enable && phydev->loopback_enabled)
+		return -EBUSY;
+
+	if (!enable && !phydev->loopback_enabled)
+		return -EINVAL;
+
+	if (phydev->drv && phydrv->set_loopback)
+		ret = phydrv->set_loopback(phydev, enable);
+
+	if (ret)
+		return ret;
+
+	phydev->loopback_enabled = enable;
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_loopback);
+
 /* Generic PHY support and helper functions */
 
 /**
@@ -1628,6 +1651,23 @@ static int gen10g_resume(struct phy_device *phydev)
 	return 0;
 }
 
+int genphy_loopback(struct phy_device *phydev, bool enable)
+{
+	int value;
+
+	value = phy_read(phydev, MII_BMCR);
+	if (value < 0)
+		return value;
+
+	if (enable)
+		value |= BMCR_LOOPBACK;
+	else
+		value &= ~BMCR_LOOPBACK;
+
+	return phy_write(phydev, MII_BMCR, value);
+}
+EXPORT_SYMBOL(genphy_loopback);
+
 static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
 {
 	/* The default values for phydev->supported are provided by the PHY
@@ -1874,6 +1914,7 @@ void phy_drivers_unregister(struct phy_driver *drv, int n)
 	.read_status	= genphy_read_status,
 	.suspend	= genphy_suspend,
 	.resume		= genphy_resume,
+	.set_loopback	= genphy_loopback,
 }, {
 	.phy_id         = 0xffffffff,
 	.phy_id_mask    = 0xffffffff,
diff --git a/include/linux/phy.h b/include/linux/phy.h
index e76e4ad..49c903dc 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -364,6 +364,7 @@ struct phy_c45_device_ids {
  * is_pseudo_fixed_link: Set to true if this phy is an Ethernet switch, etc.
  * has_fixups: Set to true if this phy has fixups/quirks.
  * suspended: Set to true if this phy has been suspended successfully.
+ * loopback_enabled: Set true if this phy has been loopbacked successfully.
  * state: state of the PHY for management purposes
  * dev_flags: Device-specific flags used by the PHY driver.
  * link_timeout: The number of timer firings to wait before the
@@ -400,6 +401,7 @@ struct phy_device {
 	bool is_pseudo_fixed_link;
 	bool has_fixups;
 	bool suspended;
+	bool loopback_enabled;
 
 	enum phy_state state;
 
@@ -639,6 +641,7 @@ struct phy_driver {
 	int (*set_tunable)(struct phy_device *dev,
 			    struct ethtool_tunable *tuna,
 			    const void *data);
+	int (*set_loopback)(struct phy_device *dev, bool enable);
 };
 #define to_phy_driver(d) container_of(to_mdio_common_driver(d),		\
 				      struct phy_driver, mdiodrv)
@@ -774,6 +777,7 @@ static inline void phy_device_free(struct phy_device *phydev) { }
 int phy_init_hw(struct phy_device *phydev);
 int phy_suspend(struct phy_device *phydev);
 int phy_resume(struct phy_device *phydev);
+int phy_loopback(struct phy_device *phydev, bool enable);
 struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
 			      phy_interface_t interface);
 struct phy_device *phy_find_first(struct mii_bus *bus);
@@ -825,6 +829,7 @@ void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
 int genphy_read_status(struct phy_device *phydev);
 int genphy_suspend(struct phy_device *phydev);
 int genphy_resume(struct phy_device *phydev);
+int genphy_loopback(struct phy_device *phydev, bool enable);
 int genphy_soft_reset(struct phy_device *phydev);
 static inline int genphy_no_soft_reset(struct phy_device *phydev)
 {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH NET v2 2/2] net: hns: Use phy_driver to setup Phy loopback
  2017-06-23  7:54 [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Lin Yun Sheng
  2017-06-23  7:54 ` [PATCH NET v2 1/2] net: phy: Add phy loopback support in net phy framework Lin Yun Sheng
@ 2017-06-23  7:54 ` Lin Yun Sheng
  2017-06-23  8:18 ` [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Yunsheng Lin
  2 siblings, 0 replies; 4+ messages in thread
From: Lin Yun Sheng @ 2017-06-23  7:54 UTC (permalink / raw)
  To: davem, andrew, f.fainelli
  Cc: huangdaode, xuwei5, liguozhu, Yisen.Zhuang, gabriele.paoloni,
	john.garry, linuxarm, yisen.zhuang, salil.mehta, lipeng321,
	tremyfr, netdev, linux-kernel

Use function set_loopback in phy_driver to setup phy loopback
when doing ethtool self test.

Signed-off-by: Lin Yun Sheng <linyunsheng@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 68 +++++-------------------
 1 file changed, 14 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index e95795b..1cd5161 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -259,67 +259,27 @@ static int hns_nic_set_link_ksettings(struct net_device *net_dev,
 
 static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
 {
-#define COPPER_CONTROL_REG 0
-#define PHY_POWER_DOWN BIT(11)
-#define PHY_LOOP_BACK BIT(14)
-	u16 val = 0;
+	int err;
 
 	if (phy_dev->is_c45) /* c45 branch adding for XGE PHY */
 		return -ENOTSUPP;
 
 	if (en) {
-		/* speed : 1000M */
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 2);
-		phy_write(phy_dev, 21, 0x1046);
-
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
-		/* Force Master */
-		phy_write(phy_dev, 9, 0x1F00);
-
-		/* Soft-reset */
-		phy_write(phy_dev, 0, 0x9140);
-		/* If autoneg disabled,two soft-reset operations */
-		phy_write(phy_dev, 0, 0x9140);
-
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA);
-
-		/* Default is 0x0400 */
-		phy_write(phy_dev, 1, 0x418);
-
-		/* Force 1000M Link, Default is 0x0200 */
-		phy_write(phy_dev, 7, 0x20C);
-
-		/* Powerup Fiber */
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 1);
-		val = phy_read(phy_dev, COPPER_CONTROL_REG);
-		val &= ~PHY_POWER_DOWN;
-		phy_write(phy_dev, COPPER_CONTROL_REG, val);
-
-		/* Enable Phy Loopback */
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
-		val = phy_read(phy_dev, COPPER_CONTROL_REG);
-		val |= PHY_LOOP_BACK;
-		val &= ~PHY_POWER_DOWN;
-		phy_write(phy_dev, COPPER_CONTROL_REG, val);
+		err = phy_resume(phy_dev);
+		if (err)
+			goto out;
+
+		err = phy_loopback(phy_dev, true);
 	} else {
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA);
-		phy_write(phy_dev, 1, 0x400);
-		phy_write(phy_dev, 7, 0x200);
-
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 1);
-		val = phy_read(phy_dev, COPPER_CONTROL_REG);
-		val |= PHY_POWER_DOWN;
-		phy_write(phy_dev, COPPER_CONTROL_REG, val);
-
-		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
-		phy_write(phy_dev, 9, 0xF00);
-
-		val = phy_read(phy_dev, COPPER_CONTROL_REG);
-		val &= ~PHY_LOOP_BACK;
-		val |= PHY_POWER_DOWN;
-		phy_write(phy_dev, COPPER_CONTROL_REG, val);
+		err = phy_loopback(phy_dev, false);
+		if (err)
+			goto out;
+
+		err = phy_suspend(phy_dev);
 	}
-	return 0;
+
+out:
+	return err;
 }
 
 static int __lb_setup(struct net_device *ndev,
-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix
  2017-06-23  7:54 [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Lin Yun Sheng
  2017-06-23  7:54 ` [PATCH NET v2 1/2] net: phy: Add phy loopback support in net phy framework Lin Yun Sheng
  2017-06-23  7:54 ` [PATCH NET v2 2/2] net: hns: Use phy_driver to setup Phy loopback Lin Yun Sheng
@ 2017-06-23  8:18 ` Yunsheng Lin
  2 siblings, 0 replies; 4+ messages in thread
From: Yunsheng Lin @ 2017-06-23  8:18 UTC (permalink / raw)
  To: davem, andrew, f.fainelli
  Cc: liguozhu, linuxarm, linux-kernel, netdev, tremyfr

My apology, this patch set have a bug in hns mac driver which is not
calling phy_loopback enable and disable in pair, I will send a v3 to
fix it. Please ignore this patch set.

Best Regards
Yunsheng Lin

On 2017/6/23 15:54, Lin Yun Sheng wrote:
> This Patch Set add set_loopback in phy_driver and use it to setup loopback
> when doing ethtool phy self_test.
> 
> Patch V2:
> 	1. Add phy_loopback in phy_device.c.
> 	2. Do error checking and do the read and write once in genphy_loopback.
> 	3. Remove gen10g_loopback in phy_device.c.
> 
> Patch V1: Initial Submit
> 
> Lin Yun Sheng (2):
>   net: phy: Add phy loopback support in net phy framework
>   net: hns: Use phy_driver to setup Phy loopback
> 
>  drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 68 +++++-------------------
>  drivers/net/phy/marvell.c                        |  1 +
>  drivers/net/phy/phy_device.c                     | 41 ++++++++++++++
>  include/linux/phy.h                              |  5 ++
>  4 files changed, 61 insertions(+), 54 deletions(-)
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-06-23  8:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-23  7:54 [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Lin Yun Sheng
2017-06-23  7:54 ` [PATCH NET v2 1/2] net: phy: Add phy loopback support in net phy framework Lin Yun Sheng
2017-06-23  7:54 ` [PATCH NET v2 2/2] net: hns: Use phy_driver to setup Phy loopback Lin Yun Sheng
2017-06-23  8:18 ` [PATCH NET v2 0/2] Add loopback support in phy_driver and hns ethtool fix Yunsheng Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®