kernel: backport phylink changes from mainline Linux
[openwrt/staging/jow.git] / target / linux / generic / backport-6.1 / 729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch
1 From: Lorenzo Bianconi <lorenzo@kernel.org>
2 Date: Sat, 14 Jan 2023 18:01:32 +0100
3 Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks
4
5 Introduce reset and reset_complete wlan callback to schedule WLAN driver
6 reset when ethernet/wed driver is resetting.
7
8 Tested-by: Daniel Golle <daniel@makrotopia.org>
9 Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
10 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
11 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
12 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
13 ---
14
15 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
16 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
17 @@ -3688,6 +3688,11 @@ static void mtk_pending_work(struct work
18 set_bit(MTK_RESETTING, &eth->state);
19
20 mtk_prepare_for_reset(eth);
21 + mtk_wed_fe_reset();
22 + /* Run again reset preliminary configuration in order to avoid any
23 + * possible race during FE reset since it can run releasing RTNL lock.
24 + */
25 + mtk_prepare_for_reset(eth);
26
27 /* stop all devices to make sure that dma is properly shut down */
28 for (i = 0; i < MTK_MAC_COUNT; i++) {
29 @@ -3725,6 +3730,8 @@ static void mtk_pending_work(struct work
30
31 clear_bit(MTK_RESETTING, &eth->state);
32
33 + mtk_wed_fe_reset_complete();
34 +
35 rtnl_unlock();
36 }
37
38 --- a/drivers/net/ethernet/mediatek/mtk_wed.c
39 +++ b/drivers/net/ethernet/mediatek/mtk_wed.c
40 @@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device *
41 iounmap(reg);
42 }
43
44 +void mtk_wed_fe_reset(void)
45 +{
46 + int i;
47 +
48 + mutex_lock(&hw_lock);
49 +
50 + for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
51 + struct mtk_wed_hw *hw = hw_list[i];
52 + struct mtk_wed_device *dev = hw->wed_dev;
53 + int err;
54 +
55 + if (!dev || !dev->wlan.reset)
56 + continue;
57 +
58 + /* reset callback blocks until WLAN reset is completed */
59 + err = dev->wlan.reset(dev);
60 + if (err)
61 + dev_err(dev->dev, "wlan reset failed: %d\n", err);
62 + }
63 +
64 + mutex_unlock(&hw_lock);
65 +}
66 +
67 +void mtk_wed_fe_reset_complete(void)
68 +{
69 + int i;
70 +
71 + mutex_lock(&hw_lock);
72 +
73 + for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
74 + struct mtk_wed_hw *hw = hw_list[i];
75 + struct mtk_wed_device *dev = hw->wed_dev;
76 +
77 + if (!dev || !dev->wlan.reset_complete)
78 + continue;
79 +
80 + dev->wlan.reset_complete(dev);
81 + }
82 +
83 + mutex_unlock(&hw_lock);
84 +}
85 +
86 static struct mtk_wed_hw *
87 mtk_wed_assign(struct mtk_wed_device *dev)
88 {
89 --- a/drivers/net/ethernet/mediatek/mtk_wed.h
90 +++ b/drivers/net/ethernet/mediatek/mtk_wed.h
91 @@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node *
92 void mtk_wed_exit(void);
93 int mtk_wed_flow_add(int index);
94 void mtk_wed_flow_remove(int index);
95 +void mtk_wed_fe_reset(void);
96 +void mtk_wed_fe_reset_complete(void);
97 #else
98 static inline void
99 mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
100 @@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i
101 {
102 }
103
104 +static inline void mtk_wed_fe_reset(void)
105 +{
106 +}
107 +
108 +static inline void mtk_wed_fe_reset_complete(void)
109 +{
110 +}
111 #endif
112
113 #ifdef CONFIG_DEBUG_FS
114 --- a/include/linux/soc/mediatek/mtk_wed.h
115 +++ b/include/linux/soc/mediatek/mtk_wed.h
116 @@ -151,6 +151,8 @@ struct mtk_wed_device {
117 void (*release_rx_buf)(struct mtk_wed_device *wed);
118 void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
119 struct mtk_wed_wo_rx_stats *stats);
120 + int (*reset)(struct mtk_wed_device *wed);
121 + void (*reset_complete)(struct mtk_wed_device *wed);
122 } wlan;
123 #endif
124 };