]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.93/net-hns-all-ports-can-not-work-when-insmod-hns-ko-af.patch
Linux 4.19.15
[thirdparty/kernel/stable-queue.git] / releases / 4.14.93 / net-hns-all-ports-can-not-work-when-insmod-hns-ko-af.patch
1 From 278324072c756e9ba42e9c8a470eeaadfdd2408a Mon Sep 17 00:00:00 2001
2 From: Yonglong Liu <liuyonglong@huawei.com>
3 Date: Sat, 15 Dec 2018 11:53:21 +0800
4 Subject: net: hns: All ports can not work when insmod hns ko after rmmod.
5
6 [ Upstream commit 308c6cafde0147616da45e3a928adae55c428deb ]
7
8 There are two test cases:
9 1. Remove the 4 modules:hns_enet_drv/hns_dsaf/hnae/hns_mdio,
10 and install them again, must use "ifconfig down/ifconfig up"
11 command pair to bring port to work.
12
13 This patch calls phy_stop function when init phy to fix this bug.
14
15 2. Remove the 2 modules:hns_enet_drv/hns_dsaf, and install them again,
16 all ports can not use anymore, because of the phy devices register
17 failed(phy devices already exists).
18
19 Phy devices are registered when hns_dsaf installed, this patch
20 removes them when hns_dsaf removed.
21
22 The two cases are sometimes related, fixing the second case also requires
23 fixing the first case, so fix them together.
24
25 Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
26 Signed-off-by: Peng Li <lipeng321@huawei.com>
27 Signed-off-by: David S. Miller <davem@davemloft.net>
28 Signed-off-by: Sasha Levin <sashal@kernel.org>
29 ---
30 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 15 +++++++++++++++
31 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 3 +++
32 2 files changed, 18 insertions(+)
33
34 diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
35 index 5a8dbd72fe45..07e117deeb0f 100644
36 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
37 +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
38 @@ -783,6 +783,17 @@ static int hns_mac_register_phy(struct hns_mac_cb *mac_cb)
39 return rc;
40 }
41
42 +static void hns_mac_remove_phydev(struct hns_mac_cb *mac_cb)
43 +{
44 + if (!to_acpi_device_node(mac_cb->fw_port) || !mac_cb->phy_dev)
45 + return;
46 +
47 + phy_device_remove(mac_cb->phy_dev);
48 + phy_device_free(mac_cb->phy_dev);
49 +
50 + mac_cb->phy_dev = NULL;
51 +}
52 +
53 #define MAC_MEDIA_TYPE_MAX_LEN 16
54
55 static const struct {
56 @@ -1120,7 +1131,11 @@ void hns_mac_uninit(struct dsaf_device *dsaf_dev)
57 int max_port_num = hns_mac_get_max_port_num(dsaf_dev);
58
59 for (i = 0; i < max_port_num; i++) {
60 + if (!dsaf_dev->mac_cb[i])
61 + continue;
62 +
63 dsaf_dev->misc_op->cpld_reset_led(dsaf_dev->mac_cb[i]);
64 + hns_mac_remove_phydev(dsaf_dev->mac_cb[i]);
65 dsaf_dev->mac_cb[i] = NULL;
66 }
67 }
68 diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
69 index 4faadc3ffe8c..2758c4bb9208 100644
70 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
71 +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
72 @@ -1286,6 +1286,9 @@ int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
73 if (h->phy_if == PHY_INTERFACE_MODE_XGMII)
74 phy_dev->autoneg = false;
75
76 + if (h->phy_if == PHY_INTERFACE_MODE_SGMII)
77 + phy_stop(phy_dev);
78 +
79 return 0;
80 }
81
82 --
83 2.19.1
84