]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
net: hns3: Fix for information of phydev lost problem when down/up
authorFuyun Liang <liangfuyun1@huawei.com>
Fri, 12 Oct 2018 23:13:55 +0000 (17:13 -0600)
committerKhalid Elmously <khalid.elmously@canonical.com>
Tue, 23 Oct 2018 06:45:58 +0000 (08:45 +0200)
BugLink: https://bugs.launchpad.net/bugs/1797654
Function call of phy_connect_direct will reinitialize phydev. Some
information like advertising will be lost. Phy_connect_direct only
needs to be called once. And driver can run well. This patch adds
some functions to ensure that phy_connect_direct is called only once
to solve the information of phydev lost problem occurring when we stop
the net and open it again.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support
Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit b01b7cf19bf4a677d5dd4e63b12d86a021db751d)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Souza <kleber.souza@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h

index 81c8efb9de4a17acdb1f98e0b256601e51188a10..226855ff5436ea924468e0d47813940a6bb59e26 100644 (file)
@@ -3827,7 +3827,7 @@ static int hclge_ae_start(struct hnae3_handle *handle)
 {
        struct hclge_vport *vport = hclge_get_vport(handle);
        struct hclge_dev *hdev = vport->back;
-       int i, ret;
+       int i;
 
        for (i = 0; i < vport->alloc_tqps; i++)
                hclge_tqp_enable(hdev, i, 0, true);
@@ -3841,9 +3841,7 @@ static int hclge_ae_start(struct hnae3_handle *handle)
        /* reset tqp stats */
        hclge_reset_tqp_stats(handle);
 
-       ret = hclge_mac_start_phy(hdev);
-       if (ret)
-               return ret;
+       hclge_mac_start_phy(hdev);
 
        return 0;
 }
@@ -5462,6 +5460,16 @@ static void hclge_get_mdix_mode(struct hnae3_handle *handle,
                *tp_mdix = ETH_TP_MDI;
 }
 
+static int hclge_init_instance_hw(struct hclge_dev *hdev)
+{
+       return hclge_mac_connect_phy(hdev);
+}
+
+static void hclge_uninit_instance_hw(struct hclge_dev *hdev)
+{
+       hclge_mac_disconnect_phy(hdev);
+}
+
 static int hclge_init_client_instance(struct hnae3_client *client,
                                      struct hnae3_ae_dev *ae_dev)
 {
@@ -5481,6 +5489,13 @@ static int hclge_init_client_instance(struct hnae3_client *client,
                        if (ret)
                                return ret;
 
+                       ret = hclge_init_instance_hw(hdev);
+                       if (ret) {
+                               client->ops->uninit_instance(&vport->nic,
+                                                            0);
+                               return ret;
+                       }
+
                        if (hdev->roce_client &&
                            hnae3_dev_roce_supported(hdev)) {
                                struct hnae3_client *rc = hdev->roce_client;
@@ -5543,6 +5558,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
                if (client->type == HNAE3_CLIENT_ROCE)
                        return;
                if (client->ops->uninit_instance) {
+                       hclge_uninit_instance_hw(hdev);
                        client->ops->uninit_instance(&vport->nic, 0);
                        hdev->nic_client = NULL;
                        vport->nic.client = NULL;
index ff6de4718ca31170701103c2059bb4038334c1b2..398971a062f475202887ca5cbccccae653052bde 100644 (file)
@@ -193,7 +193,7 @@ static void hclge_mac_adjust_link(struct net_device *netdev)
                netdev_err(netdev, "failed to configure flow control.\n");
 }
 
-int hclge_mac_start_phy(struct hclge_dev *hdev)
+int hclge_mac_connect_phy(struct hclge_dev *hdev)
 {
        struct net_device *netdev = hdev->vport[0].nic.netdev;
        struct phy_device *phydev = hdev->hw.mac.phydev;
@@ -215,11 +215,29 @@ int hclge_mac_start_phy(struct hclge_dev *hdev)
        phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES;
        phydev->advertising = phydev->supported;
 
-       phy_start(phydev);
-
        return 0;
 }
 
+void hclge_mac_disconnect_phy(struct hclge_dev *hdev)
+{
+       struct phy_device *phydev = hdev->hw.mac.phydev;
+
+       if (!phydev)
+               return;
+
+       phy_disconnect(phydev);
+}
+
+void hclge_mac_start_phy(struct hclge_dev *hdev)
+{
+       struct phy_device *phydev = hdev->hw.mac.phydev;
+
+       if (!phydev)
+               return;
+
+       phy_start(phydev);
+}
+
 void hclge_mac_stop_phy(struct hclge_dev *hdev)
 {
        struct net_device *netdev = hdev->vport[0].nic.netdev;
@@ -229,5 +247,4 @@ void hclge_mac_stop_phy(struct hclge_dev *hdev)
                return;
 
        phy_stop(phydev);
-       phy_disconnect(phydev);
 }
index bb3ce35e0d66544432e69951dcaccfd35a0f92ea..5fbf7dddb5d9ba9d7f4400738837c0c033c26e3e 100644 (file)
@@ -5,7 +5,9 @@
 #define __HCLGE_MDIO_H
 
 int hclge_mac_mdio_config(struct hclge_dev *hdev);
-int hclge_mac_start_phy(struct hclge_dev *hdev);
+int hclge_mac_connect_phy(struct hclge_dev *hdev);
+void hclge_mac_disconnect_phy(struct hclge_dev *hdev);
+void hclge_mac_start_phy(struct hclge_dev *hdev);
 void hclge_mac_stop_phy(struct hclge_dev *hdev);
 
 #endif