summaryrefslogtreecommitdiffstats
path: root/target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch
diff options
context:
space:
mode:
authorRobert Marko <robimarko@gmail.com>2023-08-21 23:42:54 +0200
committerChristian Marangi <ansuelsmth@gmail.com>2023-09-17 21:00:24 +0200
commitcd9c7211241ea605e8713f5b9f0692ec0f7b765b (patch)
treedf5df11557ab88e8b5b51951dd7fa501c91540d4 /target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch
parent4c010932a5fa12b150dfcde773f291e6f906ec60 (diff)
downloadopenwrt-cd9c7211241ea605e8713f5b9f0692ec0f7b765b.tar.gz
openwrt-cd9c7211241ea605e8713f5b9f0692ec0f7b765b.tar.bz2
openwrt-cd9c7211241ea605e8713f5b9f0692ec0f7b765b.zip
ipq40xx: 6.1: use latest DSA and ethernet patches
This pulls-in the latest version of qca8k based IPQ4019 driver as well as the latest version of IPQESS that was sent upstream. Both qca8k and IPQESS have been improved and cleaned up compared to current version of patches. PSGMII PHY mode and missing reset have been upstreamed and will be in the kernel 6.6. Signed-off-by: Robert Marko <robimarko@gmail.com> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Diffstat (limited to 'target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch')
-rw-r--r--target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch64
1 files changed, 64 insertions, 0 deletions
diff --git a/target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch b/target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch
new file mode 100644
index 0000000000..149208aa69
--- /dev/null
+++ b/target/linux/ipq40xx/patches-6.1/711-net-qualcomm-ipqess-fix-TX-timeout-errors.patch
@@ -0,0 +1,64 @@
+From d0055b03d9c8d48ad2b971821989b09ba95c39f8 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 17 Sep 2023 20:18:31 +0200
+Subject: [PATCH] net: qualcomm: ipqess: fix TX timeout errors
+
+Currently logic to handle napi tx completion is flawed and on the long
+run on loaded condition cause TX timeout error with the queue not being
+able to handle any new packet.
+
+There are 2 main cause of this:
+- incrementing the packet done value wrongly
+- handling 2 times the tx_ring tail
+
+ipqess_tx_unmap_and_free may return 2 kind values:
+- 0: we are handling first and middle descriptor for the packet
+- packet len: we are at the last descriptor for the packet
+
+Done value was wrongly incremented also for first and intermediate
+descriptor for the packet resulting causing panic and TX timeouts by
+comunicating to the kernel an inconsistent value of packet handling not
+matching the expected ones.
+
+Tx_ring tail was handled twice for ipqess_tx_complete run resulting in
+again done value incremented wrongly and also problem with idx handling
+by actually skipping descriptor for some packets.
+
+Rework the loop logic to fix these 2 problem and also add some comments
+to make sure ipqess_tx_unmap_and_free ret value is better
+understandable.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/ethernet/qualcomm/ipqess/ipqess.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/qualcomm/ipqess/ipqess.c
++++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess.c
+@@ -453,13 +453,22 @@ static int ipqess_tx_complete(struct ipq
+ tail >>= IPQESS_TPD_CONS_IDX_SHIFT;
+ tail &= IPQESS_TPD_CONS_IDX_MASK;
+
+- do {
++ while ((tx_ring->tail != tail) && (done < budget)) {
+ ret = ipqess_tx_unmap_and_free(&tx_ring->ess->pdev->dev,
+ &tx_ring->buf[tx_ring->tail]);
+- tx_ring->tail = IPQESS_NEXT_IDX(tx_ring->tail, tx_ring->count);
++ /* ipqess_tx_unmap_and_free may return 2 kind values:
++ * - 0: we are handling first and middle descriptor for the packet
++ * - packet len: we are at the last descriptor for the packet
++ * Increment total bytes handled and packet done only if we are
++ * handling the last descriptor for the packet.
++ */
++ if (ret) {
++ total += ret;
++ done++;
++ }
+
+- total += ret;
+- } while ((++done < budget) && (tx_ring->tail != tail));
++ tx_ring->tail = IPQESS_NEXT_IDX(tx_ring->tail, tx_ring->count);
++ };
+
+ ipqess_w32(tx_ring->ess, IPQESS_REG_TX_SW_CONS_IDX_Q(tx_ring->idx),
+ tx_ring->tail);