mediatek: fix WED + wifi reset
authorFelix Fietkau <[email protected]>
Fri, 19 Jan 2024 13:48:05 +0000 (14:48 +0100)
committerFelix Fietkau <[email protected]>
Fri, 19 Jan 2024 13:48:22 +0000 (14:48 +0100)
The WLAN + WED reset sequence relies on being able to receive interrupts from
the card, in order to synchronize individual steps with the firmware.
When WED is stopped, leave interrupts running and rely on the driver turning
off unwanted ones.
WED DMA also needs to be disabled before resetting.

Signed-off-by: Felix Fietkau <[email protected]>
target/linux/mediatek/patches-5.15/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.1/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch [new file with mode: 0644]

diff --git a/target/linux/mediatek/patches-5.15/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch b/target/linux/mediatek/patches-5.15/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch
new file mode 100644 (file)
index 0000000..11b52d0
--- /dev/null
@@ -0,0 +1,49 @@
+From: Felix Fietkau <[email protected]>
+Date: Thu, 18 Jan 2024 12:51:32 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix WED + wifi reset
+
+The WLAN + WED reset sequence relies on being able to receive interrupts from
+the card, in order to synchronize individual steps with the firmware.
+When WED is stopped, leave interrupts running and rely on the driver turning
+off unwanted ones.
+WED DMA also needs to be disabled before resetting.
+
+Fixes: f78cd9c783e0 ("net: ethernet: mtk_wed: update mtk_wed_stop")
+Signed-off-by: Felix Fietkau <[email protected]>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -1071,13 +1071,13 @@ mtk_wed_dma_disable(struct mtk_wed_devic
+ static void
+ mtk_wed_stop(struct mtk_wed_device *dev)
+ {
++      mtk_wed_dma_disable(dev);
+       mtk_wed_set_ext_int(dev, false);
+       wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
+       wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
+       wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
+       wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
+-      wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
+       if (!mtk_wed_get_rx_capa(dev))
+               return;
+@@ -1090,7 +1090,6 @@ static void
+ mtk_wed_deinit(struct mtk_wed_device *dev)
+ {
+       mtk_wed_stop(dev);
+-      mtk_wed_dma_disable(dev);
+       wed_clr(dev, MTK_WED_CTRL,
+               MTK_WED_CTRL_WDMA_INT_AGENT_EN |
+@@ -2621,9 +2620,6 @@ mtk_wed_irq_get(struct mtk_wed_device *d
+ static void
+ mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask)
+ {
+-      if (!dev->running)
+-              return;
+-
+       mtk_wed_set_ext_int(dev, !!mask);
+       wed_w32(dev, MTK_WED_INT_MASK, mask);
+ }
diff --git a/target/linux/mediatek/patches-6.1/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch b/target/linux/mediatek/patches-6.1/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch
new file mode 100644 (file)
index 0000000..11b52d0
--- /dev/null
@@ -0,0 +1,49 @@
+From: Felix Fietkau <[email protected]>
+Date: Thu, 18 Jan 2024 12:51:32 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix WED + wifi reset
+
+The WLAN + WED reset sequence relies on being able to receive interrupts from
+the card, in order to synchronize individual steps with the firmware.
+When WED is stopped, leave interrupts running and rely on the driver turning
+off unwanted ones.
+WED DMA also needs to be disabled before resetting.
+
+Fixes: f78cd9c783e0 ("net: ethernet: mtk_wed: update mtk_wed_stop")
+Signed-off-by: Felix Fietkau <[email protected]>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -1071,13 +1071,13 @@ mtk_wed_dma_disable(struct mtk_wed_devic
+ static void
+ mtk_wed_stop(struct mtk_wed_device *dev)
+ {
++      mtk_wed_dma_disable(dev);
+       mtk_wed_set_ext_int(dev, false);
+       wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
+       wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
+       wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
+       wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
+-      wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
+       if (!mtk_wed_get_rx_capa(dev))
+               return;
+@@ -1090,7 +1090,6 @@ static void
+ mtk_wed_deinit(struct mtk_wed_device *dev)
+ {
+       mtk_wed_stop(dev);
+-      mtk_wed_dma_disable(dev);
+       wed_clr(dev, MTK_WED_CTRL,
+               MTK_WED_CTRL_WDMA_INT_AGENT_EN |
+@@ -2621,9 +2620,6 @@ mtk_wed_irq_get(struct mtk_wed_device *d
+ static void
+ mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask)
+ {
+-      if (!dev->running)
+-              return;
+-
+       mtk_wed_set_ext_int(dev, !!mask);
+       wed_w32(dev, MTK_WED_INT_MASK, mask);
+ }