Skip to content

Commit

Permalink
mac80211: rt2x00: fix various EDCA parameters
Browse files Browse the repository at this point in the history
This patch fixes AIFSN, CWMAX, CWMIN and TXOP parameters by
correcting the rt2x00 register queue index.

Signed-off-by: Shiji Yang <[email protected]>
  • Loading branch information
DragonBluep authored and namiltd committed Dec 24, 2024
1 parent ab479fc commit 8192887
Showing 1 changed file with 280 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
From ca11181381ac5bb4fa2d3b59ba84ab63b139a47f Mon Sep 17 00:00:00 2001
From: Shiji Yang <[email protected]>
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 <[email protected]>
---
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(&reg, 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)

0 comments on commit 8192887

Please sign in to comment.