From 819288798dc50e5b15b87873da7270e3fe40f261 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Tue, 24 Dec 2024 08:43:42 +0800 Subject: [PATCH] mac80211: rt2x00: fix various EDCA parameters This patch fixes AIFSN, CWMAX, CWMIN and TXOP parameters by correcting the rt2x00 register queue index. Signed-off-by: Shiji Yang --- ...parameters-caused-by-the-incorrect-q.patch | 280 ++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 package/kernel/mac80211/patches/rt2x00/622-rt2x00-fix-EDCA-parameters-caused-by-the-incorrect-q.patch diff --git a/package/kernel/mac80211/patches/rt2x00/622-rt2x00-fix-EDCA-parameters-caused-by-the-incorrect-q.patch b/package/kernel/mac80211/patches/rt2x00/622-rt2x00-fix-EDCA-parameters-caused-by-the-incorrect-q.patch new file mode 100644 index 00000000000000..77610f4956360f --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/622-rt2x00-fix-EDCA-parameters-caused-by-the-incorrect-q.patch @@ -0,0 +1,280 @@ +From ca11181381ac5bb4fa2d3b59ba84ab63b139a47f Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Tue, 24 Dec 2024 08:36:32 +0800 +Subject: [PATCH] rt2x00: fix EDCA parameters caused by the incorrect queue + index + +The Ralink TX queue register index is different from the Linux +IEEE80211 queue id definition. Their conversion table is as follows: + +Queue IEEE80211 Ralink +AC_VO 0 3 +AC_VI 1 2 +AC_BE 2 0 +AC_BK 3 1 + +In .conf_tx(), we use the wrong queue index to calculate the +register offset and mask, which resulted in writing incorrect +AIFSN, CWMAX, CWMIN and TXOP parameters for all TX queues. This +patch introduces a index conversion table to correct these TX +queue parameters. + +Signed-off-by: Shiji Yang +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 24 +++++++++---------- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 9 +++---- + .../net/wireless/ralink/rt2x00/rt2x00queue.h | 20 ++++++++++++++++ + drivers/net/wireless/ralink/rt2x00/rt61pci.c | 7 +++--- + drivers/net/wireless/ralink/rt2x00/rt61pci.h | 24 +++++++++---------- + drivers/net/wireless/ralink/rt2x00/rt73usb.c | 7 +++--- + drivers/net/wireless/ralink/rt2x00/rt73usb.h | 24 +++++++++---------- + 7 files changed, 69 insertions(+), 46 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -379,10 +379,10 @@ + + /* + * WMM_AIFSN_CFG: Aifsn for each EDCA AC +- * AIFSN0: AC_VO +- * AIFSN1: AC_VI +- * AIFSN2: AC_BE +- * AIFSN3: AC_BK ++ * AIFSN0: AC_BE ++ * AIFSN1: AC_BK ++ * AIFSN2: AC_VI ++ * AIFSN3: AC_VO + */ + #define WMM_AIFSN_CFG 0x0214 + #define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f) +@@ -392,10 +392,10 @@ + + /* + * WMM_CWMIN_CSR: CWmin for each EDCA AC +- * CWMIN0: AC_VO +- * CWMIN1: AC_VI +- * CWMIN2: AC_BE +- * CWMIN3: AC_BK ++ * CWMIN0: AC_BE ++ * CWMIN1: AC_BK ++ * CWMIN2: AC_VI ++ * CWMIN3: AC_VO + */ + #define WMM_CWMIN_CFG 0x0218 + #define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f) +@@ -405,10 +405,10 @@ + + /* + * WMM_CWMAX_CSR: CWmax for each EDCA AC +- * CWMAX0: AC_VO +- * CWMAX1: AC_VI +- * CWMAX2: AC_BE +- * CWMAX3: AC_BK ++ * CWMAX0: AC_BE ++ * CWMAX1: AC_BK ++ * CWMAX2: AC_VI ++ * CWMAX3: AC_VO + */ + #define WMM_CWMAX_CFG 0x021c + #define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -12207,8 +12207,9 @@ int rt2800_conf_tx(struct ieee80211_hw * + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); + + /* Update WMM TXOP register */ +- offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); +- field.bit_offset = (queue_idx & 1) * 16; ++ offset = WMM_TXOP0_CFG + ++ (sizeof(u32) * (!!(rt2x00_ac_to_hwq(queue_idx) & 2))); ++ field.bit_offset = (rt2x00_ac_to_hwq(queue_idx) & 1) * 16; + field.bit_mask = 0xffff << field.bit_offset; + + reg = rt2800_register_read(rt2x00dev, offset); +@@ -12216,7 +12217,7 @@ int rt2800_conf_tx(struct ieee80211_hw * + rt2800_register_write(rt2x00dev, offset, reg); + + /* Update WMM registers */ +- field.bit_offset = queue_idx * 4; ++ field.bit_offset = rt2x00_ac_to_hwq(queue_idx) * 4; + field.bit_mask = 0xf << field.bit_offset; + + reg = rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG); +@@ -12232,7 +12233,7 @@ int rt2800_conf_tx(struct ieee80211_hw * + rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg); + + /* Update EDCA registers */ +- offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx); ++ offset = EDCA_AC0_CFG + (sizeof(u32) * rt2x00_ac_to_hwq(queue_idx)); + + reg = rt2800_register_read(rt2x00dev, offset); + rt2x00_set_field32(®, EDCA_AC0_CFG_TX_OP, queue->txop); +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +@@ -57,6 +57,26 @@ enum data_queue_qid { + }; + + /** ++ * rt2x00_ac_to_hwq - Convert IEEE80211 queue id to Ralink hardware ++ * queue register index. ++ * @ac: TX queue id. ++ */ ++static inline u8 rt2x00_ac_to_hwq(enum data_queue_qid ac) ++{ ++ static const u8 ralink_queue_map[] = { ++ [IEEE80211_AC_BE] = 0, ++ [IEEE80211_AC_BK] = 1, ++ [IEEE80211_AC_VI] = 2, ++ [IEEE80211_AC_VO] = 3, ++ }; ++ ++ if (unlikely(ac >= IEEE80211_NUM_ACS)) ++ return ac; ++ ++ return ralink_queue_map[ac]; ++} ++ ++/** + * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc + * + * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX +--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +@@ -2830,8 +2830,9 @@ static int rt61pci_conf_tx(struct ieee80 + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); + + /* Update WMM TXOP register */ +- offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); +- field.bit_offset = (queue_idx & 1) * 16; ++ offset = AC_TXOP_CSR0 + ++ (sizeof(u32) * (!!(rt2x00_ac_to_hwq(queue_idx) & 2))); ++ field.bit_offset = (rt2x00_ac_to_hwq(queue_idx) & 1) * 16; + field.bit_mask = 0xffff << field.bit_offset; + + reg = rt2x00mmio_register_read(rt2x00dev, offset); +@@ -2839,7 +2840,7 @@ static int rt61pci_conf_tx(struct ieee80 + rt2x00mmio_register_write(rt2x00dev, offset, reg); + + /* Update WMM registers */ +- field.bit_offset = queue_idx * 4; ++ field.bit_offset = rt2x00_ac_to_hwq(queue_idx) * 4; + field.bit_mask = 0xf << field.bit_offset; + + reg = rt2x00mmio_register_read(rt2x00dev, AIFSN_CSR); +--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.h +@@ -821,10 +821,10 @@ struct hw_pairwise_ta_entry { + + /* + * AIFSN_CSR: AIFSN for each EDCA AC. +- * AIFSN0: For AC_VO. +- * AIFSN1: For AC_VI. +- * AIFSN2: For AC_BE. +- * AIFSN3: For AC_BK. ++ * AIFSN0: For AC_BE. ++ * AIFSN1: For AC_BK. ++ * AIFSN2: For AC_VI. ++ * AIFSN3: For AC_VO. + */ + #define AIFSN_CSR 0x3420 + #define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) +@@ -834,10 +834,10 @@ struct hw_pairwise_ta_entry { + + /* + * CWMIN_CSR: CWmin for each EDCA AC. +- * CWMIN0: For AC_VO. +- * CWMIN1: For AC_VI. +- * CWMIN2: For AC_BE. +- * CWMIN3: For AC_BK. ++ * CWMIN0: For AC_BE. ++ * CWMIN1: For AC_BK. ++ * CWMIN2: For AC_VI. ++ * CWMIN3: For AC_VO. + */ + #define CWMIN_CSR 0x3424 + #define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) +@@ -847,10 +847,10 @@ struct hw_pairwise_ta_entry { + + /* + * CWMAX_CSR: CWmax for each EDCA AC. +- * CWMAX0: For AC_VO. +- * CWMAX1: For AC_VI. +- * CWMAX2: For AC_BE. +- * CWMAX3: For AC_BK. ++ * CWMAX0: For AC_BE. ++ * CWMAX1: For AC_BK. ++ * CWMAX2: For AC_VI. ++ * CWMAX3: For AC_VO. + */ + #define CWMAX_CSR 0x3428 + #define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) +--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c +@@ -2249,8 +2249,9 @@ static int rt73usb_conf_tx(struct ieee80 + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); + + /* Update WMM TXOP register */ +- offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); +- field.bit_offset = (queue_idx & 1) * 16; ++ offset = AC_TXOP_CSR0 + ++ (sizeof(u32) * (!!(rt2x00_ac_to_hwq(queue_idx) & 2))); ++ field.bit_offset = (rt2x00_ac_to_hwq(queue_idx) & 1) * 16; + field.bit_mask = 0xffff << field.bit_offset; + + reg = rt2x00usb_register_read(rt2x00dev, offset); +@@ -2258,7 +2259,7 @@ static int rt73usb_conf_tx(struct ieee80 + rt2x00usb_register_write(rt2x00dev, offset, reg); + + /* Update WMM registers */ +- field.bit_offset = queue_idx * 4; ++ field.bit_offset = rt2x00_ac_to_hwq(queue_idx) * 4; + field.bit_mask = 0xf << field.bit_offset; + + reg = rt2x00usb_register_read(rt2x00dev, AIFSN_CSR); +--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.h +@@ -681,10 +681,10 @@ struct hw_pairwise_ta_entry { + + /* + * AIFSN_CSR: AIFSN for each EDCA AC. +- * AIFSN0: For AC_VO. +- * AIFSN1: For AC_VI. +- * AIFSN2: For AC_BE. +- * AIFSN3: For AC_BK. ++ * AIFSN0: For AC_BE. ++ * AIFSN1: For AC_BK. ++ * AIFSN2: For AC_VI. ++ * AIFSN3: For AC_VO. + */ + #define AIFSN_CSR 0x0400 + #define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) +@@ -694,10 +694,10 @@ struct hw_pairwise_ta_entry { + + /* + * CWMIN_CSR: CWmin for each EDCA AC. +- * CWMIN0: For AC_VO. +- * CWMIN1: For AC_VI. +- * CWMIN2: For AC_BE. +- * CWMIN3: For AC_BK. ++ * CWMIN0: For AC_BE. ++ * CWMIN1: For AC_BK. ++ * CWMIN2: For AC_VI. ++ * CWMIN3: For AC_VO. + */ + #define CWMIN_CSR 0x0404 + #define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) +@@ -707,10 +707,10 @@ struct hw_pairwise_ta_entry { + + /* + * CWMAX_CSR: CWmax for each EDCA AC. +- * CWMAX0: For AC_VO. +- * CWMAX1: For AC_VI. +- * CWMAX2: For AC_BE. +- * CWMAX3: For AC_BK. ++ * CWMAX0: For AC_BE. ++ * CWMAX1: For AC_BK. ++ * CWMAX2: For AC_VI. ++ * CWMAX3: For AC_VO. + */ + #define CWMAX_CSR 0x0408 + #define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)