summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFuyun Liang <liangfuyun1@huawei.com>2018-08-14 18:13:14 +0200
committerDavid S. Miller <davem@davemloft.net>2018-08-14 18:54:23 +0200
commitb01b7cf19bf4a677d5dd4e63b12d86a021db751d (patch)
tree75712ddad34f78dd404de4626d7cd103379b4b7d /drivers/net
parentnet: hns3: Fix for command format parsing error in hclge_is_all_function_id_zero (diff)
downloadlinux-b01b7cf19bf4a677d5dd4e63b12d86a021db751d.tar.xz
linux-b01b7cf19bf4a677d5dd4e63b12d86a021db751d.zip
net: hns3: Fix for information of phydev lost problem when down/up
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c24
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c25
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h4
3 files changed, 44 insertions, 9 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 5f30ea4c5142..2e9c8b9a75ce 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3782,7 +3782,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);
@@ -3796,9 +3796,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;
}
@@ -5417,6 +5415,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)
{
@@ -5436,6 +5444,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;
@@ -5498,6 +5513,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;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
index 2065ee2fd358..85a123d40e8b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
@@ -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;
@@ -213,11 +213,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;
@@ -227,5 +245,4 @@ void hclge_mac_stop_phy(struct hclge_dev *hdev)
return;
phy_stop(phydev);
- phy_disconnect(phydev);
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h
index bb3ce35e0d66..5fbf7dddb5d9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h
@@ -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