Commit b01b7cf1 authored by Fuyun Liang's avatar Fuyun Liang Committed by David S. Miller

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: 46a3df9f ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support
Signed-off-by: default avatarFuyun Liang <liangfuyun1@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6c39d527
...@@ -3782,7 +3782,7 @@ static int hclge_ae_start(struct hnae3_handle *handle) ...@@ -3782,7 +3782,7 @@ static int hclge_ae_start(struct hnae3_handle *handle)
{ {
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
int i, ret; int i;
for (i = 0; i < vport->alloc_tqps; i++) for (i = 0; i < vport->alloc_tqps; i++)
hclge_tqp_enable(hdev, i, 0, true); hclge_tqp_enable(hdev, i, 0, true);
...@@ -3796,9 +3796,7 @@ static int hclge_ae_start(struct hnae3_handle *handle) ...@@ -3796,9 +3796,7 @@ static int hclge_ae_start(struct hnae3_handle *handle)
/* reset tqp stats */ /* reset tqp stats */
hclge_reset_tqp_stats(handle); hclge_reset_tqp_stats(handle);
ret = hclge_mac_start_phy(hdev); hclge_mac_start_phy(hdev);
if (ret)
return ret;
return 0; return 0;
} }
...@@ -5417,6 +5415,16 @@ static void hclge_get_mdix_mode(struct hnae3_handle *handle, ...@@ -5417,6 +5415,16 @@ static void hclge_get_mdix_mode(struct hnae3_handle *handle,
*tp_mdix = ETH_TP_MDI; *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, static int hclge_init_client_instance(struct hnae3_client *client,
struct hnae3_ae_dev *ae_dev) struct hnae3_ae_dev *ae_dev)
{ {
...@@ -5436,6 +5444,13 @@ static int hclge_init_client_instance(struct hnae3_client *client, ...@@ -5436,6 +5444,13 @@ static int hclge_init_client_instance(struct hnae3_client *client,
if (ret) if (ret)
return ret; return ret;
ret = hclge_init_instance_hw(hdev);
if (ret) {
client->ops->uninit_instance(&vport->nic,
0);
return ret;
}
if (hdev->roce_client && if (hdev->roce_client &&
hnae3_dev_roce_supported(hdev)) { hnae3_dev_roce_supported(hdev)) {
struct hnae3_client *rc = hdev->roce_client; struct hnae3_client *rc = hdev->roce_client;
...@@ -5498,6 +5513,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, ...@@ -5498,6 +5513,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
if (client->type == HNAE3_CLIENT_ROCE) if (client->type == HNAE3_CLIENT_ROCE)
return; return;
if (client->ops->uninit_instance) { if (client->ops->uninit_instance) {
hclge_uninit_instance_hw(hdev);
client->ops->uninit_instance(&vport->nic, 0); client->ops->uninit_instance(&vport->nic, 0);
hdev->nic_client = NULL; hdev->nic_client = NULL;
vport->nic.client = NULL; vport->nic.client = NULL;
......
...@@ -193,7 +193,7 @@ static void hclge_mac_adjust_link(struct net_device *netdev) ...@@ -193,7 +193,7 @@ static void hclge_mac_adjust_link(struct net_device *netdev)
netdev_err(netdev, "failed to configure flow control.\n"); 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 net_device *netdev = hdev->vport[0].nic.netdev;
struct phy_device *phydev = hdev->hw.mac.phydev; struct phy_device *phydev = hdev->hw.mac.phydev;
...@@ -213,11 +213,29 @@ int hclge_mac_start_phy(struct hclge_dev *hdev) ...@@ -213,11 +213,29 @@ int hclge_mac_start_phy(struct hclge_dev *hdev)
phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES; phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES;
phydev->advertising = phydev->supported; phydev->advertising = phydev->supported;
phy_start(phydev);
return 0; 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) void hclge_mac_stop_phy(struct hclge_dev *hdev)
{ {
struct net_device *netdev = hdev->vport[0].nic.netdev; struct net_device *netdev = hdev->vport[0].nic.netdev;
...@@ -227,5 +245,4 @@ void hclge_mac_stop_phy(struct hclge_dev *hdev) ...@@ -227,5 +245,4 @@ void hclge_mac_stop_phy(struct hclge_dev *hdev)
return; return;
phy_stop(phydev); phy_stop(phydev);
phy_disconnect(phydev);
} }
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#define __HCLGE_MDIO_H #define __HCLGE_MDIO_H
int hclge_mac_mdio_config(struct hclge_dev *hdev); 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); void hclge_mac_stop_phy(struct hclge_dev *hdev);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment