Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v3] wifi: rtw88: usb: Further limit the TX aggregation
@ 2024-06-16 19:27 Bitterblue Smith
  2024-06-17  1:28 ` Ping-Ke Shih
  2024-06-21 12:45 ` Ping-Ke Shih
  0 siblings, 2 replies; 3+ messages in thread
From: Bitterblue Smith @ 2024-06-16 19:27 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org; +Cc: Ping-Ke Shih, Sascha Hauer

Currently the number of frames sent to the chip in a single USB Request
Block is limited only by the size of the TX buffer, which is 20 KiB.
Testing reveals that as many as 13 frames get aggregated. This is more
than what any of the chips would like to receive. RTL8822CU, RTL8822BU,
and RTL8821CU want at most 3 frames, and RTL8723DU wants only 1 frame
per URB.

RTL8723DU in particular reliably malfunctions during a speed test if it
receives more than 1 frame per URB. All traffic seems to stop. Pinging
the AP no longer works.

Fix this problem by limiting the number of frames sent to the chip in a
single URB according to what each chip likes.

Also configure RTL8822CU, RTL8822BU, and RTL8821CU to expect 3 frames
per URB.

RTL8703B may or may not be found in USB devices. Declare that it wants
only 1 frame per URB, just in case.

Tested with RTL8723DU and RTL8811CU.

Cc: stable@vger.kernel.org
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
v3:
 - Don't sort the members of rtw{8703b,8723d,8821c,8822b,8822c}_hw_spec.
 - Put usb_tx_agg_desc_num in rtw{8723d,8821c,8822b,8822c}_hw_spec
   in a better position.
 - Explicitly say that RTL8723DU malfunctions if it receives more than
   1 frame per URB.

v2:
 - Use rtw_write8_mask and GENMASK.
 - Initialise the members of rtw{8703b,8723d,8821c,8822b,8822c}_hw_spec
   in the same order they are declared.
---
 drivers/net/wireless/realtek/rtw88/mac.c      | 9 +++++++++
 drivers/net/wireless/realtek/rtw88/main.h     | 2 ++
 drivers/net/wireless/realtek/rtw88/reg.h      | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
 drivers/net/wireless/realtek/rtw88/usb.c      | 4 +++-
 9 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 0dba8aae7716..564f5988ee82 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -1201,6 +1201,15 @@ static int __priority_queue_cfg(struct rtw_dev *rtwdev,
 	rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary);
 	rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary);
 	rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1);
+
+	if (rtwdev->hci.type == RTW_HCI_TYPE_USB) {
+		rtw_write8_mask(rtwdev, REG_AUTO_LLT_V1, BIT_MASK_BLK_DESC_NUM,
+				chip->usb_tx_agg_desc_num);
+
+		rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, chip->usb_tx_agg_desc_num);
+		rtw_write8_set(rtwdev, REG_TXDMA_OFFSET_CHK + 1, BIT(1));
+	}
+
 	rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1);
 
 	if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0))
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 49894331f7b4..49a3fd4fb7dc 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1197,6 +1197,8 @@ struct rtw_chip_info {
 	u16 fw_fifo_addr[RTW_FW_FIFO_MAX];
 	const struct rtw_fwcd_segs *fwcd_segs;
 
+	u8 usb_tx_agg_desc_num;
+
 	u8 default_1ss_tx_path;
 
 	bool path_div_supported;
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index b122f226924b..02ef9a77316b 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -270,6 +270,7 @@
 #define BIT_MASK_BCN_HEAD_1_V1	0xfff
 #define REG_AUTO_LLT_V1		0x0208
 #define BIT_AUTO_INIT_LLT_V1	BIT(0)
+#define BIT_MASK_BLK_DESC_NUM	GENMASK(7, 4)
 #define REG_DWBCN0_CTRL		0x0208
 #define BIT_BCN_VALID		BIT(16)
 #define REG_TXDMA_OFFSET_CHK	0x020C
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
index 8919f9e11f03..222608de33cd 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
@@ -2013,6 +2013,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
 	.tx_stbc = false,
 	.max_power_index = 0x3f,
 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
+	.usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */
 
 	.path_div_supported = false,
 	.ht_supported = true,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index f8df4c84d39f..3fba4054d45f 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -2171,6 +2171,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
 	.band = RTW_BAND_2G,
 	.page_size = TX_PAGE_SIZE,
 	.dig_min = 0x20,
+	.usb_tx_agg_desc_num = 1,
 	.ht_supported = true,
 	.vht_supported = false,
 	.lps_deep_mode_supported = 0,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index fe5d8e188350..526e8de77b3e 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -2008,6 +2008,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
 	.band = RTW_BAND_2G | RTW_BAND_5G,
 	.page_size = TX_PAGE_SIZE,
 	.dig_min = 0x1c,
+	.usb_tx_agg_desc_num = 3,
 	.ht_supported = true,
 	.vht_supported = true,
 	.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 3017a9760da8..2456ff242818 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2548,6 +2548,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
 	.band = RTW_BAND_2G | RTW_BAND_5G,
 	.page_size = TX_PAGE_SIZE,
 	.dig_min = 0x1c,
+	.usb_tx_agg_desc_num = 3,
 	.ht_supported = true,
 	.vht_supported = true,
 	.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index cd965edc29ce..62376d1cca22 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -5366,6 +5366,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
 	.band = RTW_BAND_2G | RTW_BAND_5G,
 	.page_size = TX_PAGE_SIZE,
 	.dig_min = 0x20,
+	.usb_tx_agg_desc_num = 3,
 	.default_1ss_tx_path = BB_PATH_A,
 	.path_div_supported = true,
 	.ht_supported = true,
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index d204d138afe2..057c0ffbe944 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -379,7 +379,9 @@ static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list
 
 		skb_iter = skb_peek(list);
 
-		if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ)
+		if (skb_iter &&
+		    skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ &&
+		    agg_num < rtwdev->chip->usb_tx_agg_desc_num)
 			__skb_unlink(skb_iter, list);
 		else
 			skb_iter = NULL;
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [PATCH v3] wifi: rtw88: usb: Further limit the TX aggregation
  2024-06-16 19:27 [PATCH v3] wifi: rtw88: usb: Further limit the TX aggregation Bitterblue Smith
@ 2024-06-17  1:28 ` Ping-Ke Shih
  2024-06-21 12:45 ` Ping-Ke Shih
  1 sibling, 0 replies; 3+ messages in thread
From: Ping-Ke Shih @ 2024-06-17  1:28 UTC (permalink / raw)
  To: Bitterblue Smith, linux-wireless@vger.kernel.org; +Cc: Sascha Hauer

Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> Currently the number of frames sent to the chip in a single USB Request
> Block is limited only by the size of the TX buffer, which is 20 KiB.
> Testing reveals that as many as 13 frames get aggregated. This is more
> than what any of the chips would like to receive. RTL8822CU, RTL8822BU,
> and RTL8821CU want at most 3 frames, and RTL8723DU wants only 1 frame
> per URB.
> 
> RTL8723DU in particular reliably malfunctions during a speed test if it
> receives more than 1 frame per URB. All traffic seems to stop. Pinging
> the AP no longer works.
> 
> Fix this problem by limiting the number of frames sent to the chip in a
> single URB according to what each chip likes.
> 
> Also configure RTL8822CU, RTL8822BU, and RTL8821CU to expect 3 frames
> per URB.
> 
> RTL8703B may or may not be found in USB devices. Declare that it wants
> only 1 frame per URB, just in case.
> 
> Tested with RTL8723DU and RTL8811CU.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>

Acked-by: Ping-Ke Shih <pkshih@realtek.com>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] wifi: rtw88: usb: Further limit the TX aggregation
  2024-06-16 19:27 [PATCH v3] wifi: rtw88: usb: Further limit the TX aggregation Bitterblue Smith
  2024-06-17  1:28 ` Ping-Ke Shih
@ 2024-06-21 12:45 ` Ping-Ke Shih
  1 sibling, 0 replies; 3+ messages in thread
From: Ping-Ke Shih @ 2024-06-21 12:45 UTC (permalink / raw)
  To: Bitterblue Smith, linux-wireless@vger.kernel.org
  Cc: Ping-Ke Shih, Sascha Hauer

Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:

> Currently the number of frames sent to the chip in a single USB Request
> Block is limited only by the size of the TX buffer, which is 20 KiB.
> Testing reveals that as many as 13 frames get aggregated. This is more
> than what any of the chips would like to receive. RTL8822CU, RTL8822BU,
> and RTL8821CU want at most 3 frames, and RTL8723DU wants only 1 frame
> per URB.
> 
> RTL8723DU in particular reliably malfunctions during a speed test if it
> receives more than 1 frame per URB. All traffic seems to stop. Pinging
> the AP no longer works.
> 
> Fix this problem by limiting the number of frames sent to the chip in a
> single URB according to what each chip likes.
> 
> Also configure RTL8822CU, RTL8822BU, and RTL8821CU to expect 3 frames
> per URB.
> 
> RTL8703B may or may not be found in USB devices. Declare that it wants
> only 1 frame per URB, just in case.
> 
> Tested with RTL8723DU and RTL8811CU.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> Acked-by: Ping-Ke Shih <pkshih@realtek.com>

1 patch(es) applied to rtw-next branch of rtw.git, thanks.

d7dd13ea54af wifi: rtw88: usb: Further limit the TX aggregation

---
https://github.com/pkshih/rtw.git


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-06-21 12:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-16 19:27 [PATCH v3] wifi: rtw88: usb: Further limit the TX aggregation Bitterblue Smith
2024-06-17  1:28 ` Ping-Ke Shih
2024-06-21 12:45 ` Ping-Ke Shih

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox