From 19f2e53562cf8b4f07a609b0c5b30deb84a68429 Mon Sep 17 00:00:00 2001 From: developer Date: Tue, 22 Nov 2022 09:59:14 +0800 Subject: [PATCH] [Description] Fix panic issue for mtk_pending_work. If without this patch, mtk_pending_work might cause kernel panic in the one gmac system. [Release-log] N/A Change-Id: I9d2940645d738bac8888a7410c5ad5586a08c115 Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6814894 --- .../net/ethernet/mediatek/mtk_eth_soc.c | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 6291c2b6ef..a0caa7dae5 100644 --- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -3081,10 +3081,15 @@ static void mtk_pending_work(struct work_struct *work) mtk_prepare_reset_fe(eth); /* Trigger Wifi SER reset */ - call_netdevice_notifiers(MTK_FE_START_RESET, eth->netdev[0]); - rtnl_unlock(); - wait_for_completion_timeout(&wait_ser_done, 5000); - rtnl_lock(); + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!eth->netdev[i]) + continue; + call_netdevice_notifiers(MTK_FE_START_RESET, eth->netdev[i]); + rtnl_unlock(); + wait_for_completion_timeout(&wait_ser_done, 5000); + rtnl_lock(); + break; + } while (test_and_set_bit_lock(MTK_RESETTING, ð->state)) cpu_relax(); @@ -3111,7 +3116,7 @@ static void mtk_pending_work(struct work_struct *work) /* restart DMA and enable IRQs */ for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!test_bit(i, &restart)) + if (!test_bit(i, &restart) || !eth->netdev[i]) continue; err = mtk_open(eth->netdev[i]); if (err) { @@ -3135,6 +3140,8 @@ static void mtk_pending_work(struct work_struct *work) /* Power up sgmii */ for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!eth->netdev[i]) + continue; mac = netdev_priv(eth->netdev[i]); phy_node = of_parse_phandle(mac->of_node, "phy-handle", 0); if (!phy_node && eth->sgmii->regmap[i]) { @@ -3143,11 +3150,15 @@ static void mtk_pending_work(struct work_struct *work) } } - call_netdevice_notifiers(MTK_FE_RESET_NAT_DONE, eth->netdev[0]); - pr_info("[%s] HNAT reset done !\n", __func__); - - call_netdevice_notifiers(MTK_FE_RESET_DONE, eth->netdev[0]); - pr_info("[%s] WiFi SER reset done !\n", __func__); + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!eth->netdev[i]) + continue; + call_netdevice_notifiers(MTK_FE_RESET_NAT_DONE, eth->netdev[i]); + pr_info("[%s] HNAT reset done !\n", __func__); + call_netdevice_notifiers(MTK_FE_RESET_DONE, eth->netdev[i]); + pr_info("[%s] WiFi SER reset done !\n", __func__); + break; + } atomic_dec(&reset_lock); if (atomic_read(&force) > 0)