1 From 002a5db9a52a0e7af0fa9a450d31049748435748 Mon Sep 17 00:00:00 2001
2 From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
3 Date: Thu, 8 Aug 2024 01:23:06 +0300
4 Subject: [PATCH] wifi: rtw88: Enable USB RX aggregation for 8822c/8822b/8821c
6 Enable USB RX aggregation when there is at least 1 Mbps RX or TX
7 traffic, otherwise disable it.
9 USB RX aggregation improves the RX speed of RTL8811CU on certain ARM
10 systems, like the NanoPi NEO Core2. Before: 28 Mbps, after: 231 Mbps.
12 It also improves the RX speed of RTL8822CU on some x86_64 systems.
13 Before: ~200 Mbps, after: ~300 Mbps.
15 The official drivers for these chips use the same logic for SDIO, but
16 for some reason the SDIO driver in rtw88 always enables RX aggregation,
17 so this patch only toggles aggregation for USB devices.
19 RTL8703B is likely not found in USB devices, and RTL8723DU doesn't like
22 Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
23 Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
24 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
25 Link: https://patch.msgid.link/b4c0d54c-6755-4b0f-9dd7-f9196fd74b68@gmail.com
27 drivers/net/wireless/realtek/rtw88/hci.h | 7 ++++
28 drivers/net/wireless/realtek/rtw88/main.c | 13 +++++---
29 drivers/net/wireless/realtek/rtw88/pci.c | 1 +
30 drivers/net/wireless/realtek/rtw88/sdio.c | 1 +
31 drivers/net/wireless/realtek/rtw88/usb.c | 40 +++++++++++++++++++++++
32 5 files changed, 58 insertions(+), 4 deletions(-)
34 --- a/drivers/net/wireless/realtek/rtw88/hci.h
35 +++ b/drivers/net/wireless/realtek/rtw88/hci.h
36 @@ -18,6 +18,7 @@ struct rtw_hci_ops {
37 void (*deep_ps)(struct rtw_dev *rtwdev, bool enter);
38 void (*link_ps)(struct rtw_dev *rtwdev, bool enter);
39 void (*interface_cfg)(struct rtw_dev *rtwdev);
40 + void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable);
42 int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
43 int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
44 @@ -72,6 +73,12 @@ static inline void rtw_hci_interface_cfg
45 rtwdev->hci.ops->interface_cfg(rtwdev);
48 +static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
50 + if (rtwdev->hci.ops->dynamic_rx_agg)
51 + rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable);
55 rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
57 --- a/drivers/net/wireless/realtek/rtw88/main.c
58 +++ b/drivers/net/wireless/realtek/rtw88/main.c
59 @@ -212,6 +212,7 @@ static void rtw_watch_dog_work(struct wo
60 struct rtw_traffic_stats *stats = &rtwdev->stats;
61 struct rtw_watch_dog_iter_data data = {};
62 bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
63 + u32 tx_unicast_mbps, rx_unicast_mbps;
66 mutex_lock(&rtwdev->mutex);
67 @@ -236,10 +237,11 @@ static void rtw_watch_dog_work(struct wo
71 - ewma_tp_add(&stats->tx_ewma_tp,
72 - (u32)(stats->tx_unicast >> RTW_TP_SHIFT));
73 - ewma_tp_add(&stats->rx_ewma_tp,
74 - (u32)(stats->rx_unicast >> RTW_TP_SHIFT));
75 + tx_unicast_mbps = stats->tx_unicast >> RTW_TP_SHIFT;
76 + rx_unicast_mbps = stats->rx_unicast >> RTW_TP_SHIFT;
78 + ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_mbps);
79 + ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_mbps);
80 stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp);
81 stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp);
83 @@ -259,6 +261,9 @@ static void rtw_watch_dog_work(struct wo
85 rtw_phy_dynamic_mechanism(rtwdev);
87 + rtw_hci_dynamic_rx_agg(rtwdev,
88 + tx_unicast_mbps >= 1 || rx_unicast_mbps >= 1);
91 /* rtw_iterate_vifs internally uses an atomic iterator which is needed
92 * to avoid taking local->iflist_mtx mutex
93 --- a/drivers/net/wireless/realtek/rtw88/pci.c
94 +++ b/drivers/net/wireless/realtek/rtw88/pci.c
95 @@ -1601,6 +1601,7 @@ static struct rtw_hci_ops rtw_pci_ops =
96 .deep_ps = rtw_pci_deep_ps,
97 .link_ps = rtw_pci_link_ps,
98 .interface_cfg = rtw_pci_interface_cfg,
99 + .dynamic_rx_agg = NULL,
101 .read8 = rtw_pci_read8,
102 .read16 = rtw_pci_read16,
103 --- a/drivers/net/wireless/realtek/rtw88/sdio.c
104 +++ b/drivers/net/wireless/realtek/rtw88/sdio.c
105 @@ -1157,6 +1157,7 @@ static struct rtw_hci_ops rtw_sdio_ops =
106 .deep_ps = rtw_sdio_deep_ps,
107 .link_ps = rtw_sdio_link_ps,
108 .interface_cfg = rtw_sdio_interface_cfg,
109 + .dynamic_rx_agg = NULL,
111 .read8 = rtw_sdio_read8,
112 .read16 = rtw_sdio_read16,
113 --- a/drivers/net/wireless/realtek/rtw88/usb.c
114 +++ b/drivers/net/wireless/realtek/rtw88/usb.c
115 @@ -766,6 +766,45 @@ static void rtw_usb_interface_cfg(struct
116 rtw_usb_init_burst_pkt_len(rtwdev);
119 +static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable)
124 + rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC);
125 + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
126 + rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
135 + val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) |
136 + u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1);
138 + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16);
141 +static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
143 + switch (rtwdev->chip->id) {
144 + case RTW_CHIP_TYPE_8822C:
145 + case RTW_CHIP_TYPE_8822B:
146 + case RTW_CHIP_TYPE_8821C:
147 + rtw_usb_dynamic_rx_agg_v1(rtwdev, enable);
149 + case RTW_CHIP_TYPE_8723D:
150 + /* Doesn't like aggregation. */
152 + case RTW_CHIP_TYPE_8703B:
153 + /* Likely not found in USB devices. */
158 static struct rtw_hci_ops rtw_usb_ops = {
159 .tx_write = rtw_usb_tx_write,
160 .tx_kick_off = rtw_usb_tx_kick_off,
161 @@ -775,6 +814,7 @@ static struct rtw_hci_ops rtw_usb_ops =
162 .deep_ps = rtw_usb_deep_ps,
163 .link_ps = rtw_usb_link_ps,
164 .interface_cfg = rtw_usb_interface_cfg,
165 + .dynamic_rx_agg = rtw_usb_dynamic_rx_agg,
167 .write8 = rtw_usb_write8,
168 .write16 = rtw_usb_write16,