diff options
author | Yonglong Liu <liuyonglong@huawei.com> | 2018-12-15 06:53:21 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-01-13 12:00:59 +0300 |
commit | 649171175b35f9f36f58bbe886718ebc2e788e0b (patch) | |
tree | 7c45b510dae226b0cdaca95c8a32bd08b8f71560 /drivers/net/ethernet/hisilicon | |
parent | 9c97aac00f9d6b01d45f3731b7f14f9d34a167c1 (diff) | |
download | linux-649171175b35f9f36f58bbe886718ebc2e788e0b.tar.xz |
net: hns: All ports can not work when insmod hns ko after rmmod.
[ Upstream commit 308c6cafde0147616da45e3a928adae55c428deb ]
There are two test cases:
1. Remove the 4 modules:hns_enet_drv/hns_dsaf/hnae/hns_mdio,
and install them again, must use "ifconfig down/ifconfig up"
command pair to bring port to work.
This patch calls phy_stop function when init phy to fix this bug.
2. Remove the 2 modules:hns_enet_drv/hns_dsaf, and install them again,
all ports can not use anymore, because of the phy devices register
failed(phy devices already exists).
Phy devices are registered when hns_dsaf installed, this patch
removes them when hns_dsaf removed.
The two cases are sometimes related, fixing the second case also requires
fixing the first case, so fix them together.
Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/hisilicon')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_enet.c | 3 |
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index 5a8dbd72fe45..07e117deeb0f 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -783,6 +783,17 @@ static int hns_mac_register_phy(struct hns_mac_cb *mac_cb) return rc; } +static void hns_mac_remove_phydev(struct hns_mac_cb *mac_cb) +{ + if (!to_acpi_device_node(mac_cb->fw_port) || !mac_cb->phy_dev) + return; + + phy_device_remove(mac_cb->phy_dev); + phy_device_free(mac_cb->phy_dev); + + mac_cb->phy_dev = NULL; +} + #define MAC_MEDIA_TYPE_MAX_LEN 16 static const struct { @@ -1120,7 +1131,11 @@ void hns_mac_uninit(struct dsaf_device *dsaf_dev) int max_port_num = hns_mac_get_max_port_num(dsaf_dev); for (i = 0; i < max_port_num; i++) { + if (!dsaf_dev->mac_cb[i]) + continue; + dsaf_dev->misc_op->cpld_reset_led(dsaf_dev->mac_cb[i]); + hns_mac_remove_phydev(dsaf_dev->mac_cb[i]); dsaf_dev->mac_cb[i] = NULL; } } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index 4faadc3ffe8c..2758c4bb9208 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -1286,6 +1286,9 @@ int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h) if (h->phy_if == PHY_INTERFACE_MODE_XGMII) phy_dev->autoneg = false; + if (h->phy_if == PHY_INTERFACE_MODE_SGMII) + phy_stop(phy_dev); + return 0; } |