net: hns: Use phy_driver to setup Phy loopback
authorLin Yun Sheng <linyunsheng@huawei.com>
Fri, 30 Jun 2017 09:44:16 +0000 (17:44 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Jul 2017 09:01:15 +0000 (02:01 -0700)
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns/hnae.h
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c

index 04211ac73b36a3152b6642a4c797f738076bd601..7ba653af19cb980a5e28a59ab2844cac1d7813c5 100644 (file)
@@ -360,6 +360,7 @@ enum hnae_loop {
        MAC_INTERNALLOOP_MAC = 0,
        MAC_INTERNALLOOP_SERDES,
        MAC_INTERNALLOOP_PHY,
+       MAC_LOOP_PHY_NONE,
        MAC_LOOP_NONE,
 };
 
index 00e57bbaf122775c20b11d5fd9eaedf80e2cd40f..a8db27e86a112cde0ba71dfe9cc3d39a2ae1d270 100644 (file)
@@ -259,67 +259,27 @@ static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = {
 
 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;
-
-       if (phy_dev->is_c45) /* c45 branch adding for XGE PHY */
-               return -ENOTSUPP;
+       int err;
 
        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);
+               /* Doing phy loopback in offline state, phy resuming is
+                * needed to power up the device.
+                */
+               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,
@@ -332,10 +292,9 @@ static int __lb_setup(struct net_device *ndev,
 
        switch (loop) {
        case MAC_INTERNALLOOP_PHY:
-               if ((phy_dev) && (!phy_dev->is_c45)) {
-                       ret = hns_nic_config_phy_loopback(phy_dev, 0x1);
-                       ret |= h->dev->ops->set_loopback(h, loop, 0x1);
-               }
+               ret = hns_nic_config_phy_loopback(phy_dev, 0x1);
+               if (!ret)
+                       ret = h->dev->ops->set_loopback(h, loop, 0x1);
                break;
        case MAC_INTERNALLOOP_MAC:
                if ((h->dev->ops->set_loopback) &&
@@ -346,17 +305,17 @@ static int __lb_setup(struct net_device *ndev,
                if (h->dev->ops->set_loopback)
                        ret = h->dev->ops->set_loopback(h, loop, 0x1);
                break;
+       case MAC_LOOP_PHY_NONE:
+               ret = hns_nic_config_phy_loopback(phy_dev, 0x0);
        case MAC_LOOP_NONE:
-               if ((phy_dev) && (!phy_dev->is_c45))
-                       ret |= hns_nic_config_phy_loopback(phy_dev, 0x0);
-
-               if (h->dev->ops->set_loopback) {
+               if (!ret && h->dev->ops->set_loopback) {
                        if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
-                               ret |= h->dev->ops->set_loopback(h,
+                               ret = h->dev->ops->set_loopback(h,
                                        MAC_INTERNALLOOP_MAC, 0x0);
 
-                       ret |= h->dev->ops->set_loopback(h,
-                               MAC_INTERNALLOOP_SERDES, 0x0);
+                       if (!ret)
+                               ret = h->dev->ops->set_loopback(h,
+                                       MAC_INTERNALLOOP_SERDES, 0x0);
                }
                break;
        default:
@@ -582,13 +541,16 @@ static int __lb_run_test(struct net_device *ndev,
        return ret_val;
 }
 
-static int __lb_down(struct net_device *ndev)
+static int __lb_down(struct net_device *ndev, enum hnae_loop loop)
 {
        struct hns_nic_priv *priv = netdev_priv(ndev);
        struct hnae_handle *h = priv->ae_handle;
        int ret;
 
-       ret = __lb_setup(ndev, MAC_LOOP_NONE);
+       if (loop == MAC_INTERNALLOOP_PHY)
+               ret = __lb_setup(ndev, MAC_LOOP_PHY_NONE);
+       else
+               ret = __lb_setup(ndev, MAC_LOOP_NONE);
        if (ret)
                netdev_err(ndev, "%s: __lb_setup return error(%d)!\n",
                           __func__,
@@ -644,7 +606,8 @@ static void hns_nic_self_test(struct net_device *ndev,
                        if (!data[test_index]) {
                                data[test_index] = __lb_run_test(
                                        ndev, (enum hnae_loop)st_param[i][0]);
-                               (void)__lb_down(ndev);
+                               (void)__lb_down(ndev,
+                                               (enum hnae_loop)st_param[i][0]);
                        }
 
                        if (data[test_index])