1 From c7706b1173c77185a2ef40c7d1811021566563f3 Mon Sep 17 00:00:00 2001
2 From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
3 Date: Wed, 23 Oct 2024 17:10:32 +0300
4 Subject: [PATCH] wifi: rtw88: Enable data rate fallback for older chips
6 RTL8811AU fails to perform the 4-way handshake when the AP is too far
7 because it transmits the EAPOL frames at MCS9 and when that doesn't
8 work it retries 48 times with the same rate, to no avail.
10 Retrying 48 times with the same rate seems pointless. Set the
11 appropriate field in the TX descriptor to allow it to use lower rates
14 Set it for RTL8723D and RTL8703B because they interpret this field the
17 The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in
18 the TX descriptor differently, so leave it alone for those chips.
20 Tested with RTL8811AU and RTL8723DU.
22 Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
23 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
24 Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com
26 drivers/net/wireless/realtek/rtw88/fw.c | 2 +-
27 drivers/net/wireless/realtek/rtw88/main.h | 1 +
28 drivers/net/wireless/realtek/rtw88/pci.c | 2 +-
29 drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 +
30 drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 +
31 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 +
32 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
33 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
34 drivers/net/wireless/realtek/rtw88/sdio.c | 2 +-
35 drivers/net/wireless/realtek/rtw88/tx.c | 6 +++++-
36 drivers/net/wireless/realtek/rtw88/tx.h | 4 +++-
37 drivers/net/wireless/realtek/rtw88/usb.c | 4 ++--
38 12 files changed, 19 insertions(+), 7 deletions(-)
40 --- a/drivers/net/wireless/realtek/rtw88/fw.c
41 +++ b/drivers/net/wireless/realtek/rtw88/fw.c
42 @@ -1290,7 +1290,7 @@ static void rtw_fill_rsvd_page_desc(stru
43 rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
44 pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
45 memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
46 - rtw_tx_fill_tx_desc(&pkt_info, skb);
47 + rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb);
50 static inline u8 rtw_len_to_page(unsigned int len, u8 page_size)
51 --- a/drivers/net/wireless/realtek/rtw88/main.h
52 +++ b/drivers/net/wireless/realtek/rtw88/main.h
53 @@ -1204,6 +1204,7 @@ struct rtw_chip_info {
54 u8 usb_tx_agg_desc_num;
55 bool hw_feature_report;
56 u8 c2h_ra_report_size;
57 + bool old_datarate_fb_limit;
59 u8 default_1ss_tx_path;
61 --- a/drivers/net/wireless/realtek/rtw88/pci.c
62 +++ b/drivers/net/wireless/realtek/rtw88/pci.c
63 @@ -824,7 +824,7 @@ static int rtw_pci_tx_write_data(struct
64 pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
65 memset(pkt_desc, 0, tx_pkt_desc_sz);
66 pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue);
67 - rtw_tx_fill_tx_desc(pkt_info, skb);
68 + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
69 dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len,
71 if (dma_mapping_error(&rtwpci->pdev->dev, dma))
72 --- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c
73 +++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c
74 @@ -1964,6 +1964,7 @@ const struct rtw_chip_info rtw8703b_hw_s
75 .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */
76 .hw_feature_report = true,
77 .c2h_ra_report_size = 7,
78 + .old_datarate_fb_limit = true,
80 .path_div_supported = false,
82 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
83 +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
84 @@ -2135,6 +2135,7 @@ const struct rtw_chip_info rtw8723d_hw_s
85 .usb_tx_agg_desc_num = 1,
86 .hw_feature_report = true,
87 .c2h_ra_report_size = 7,
88 + .old_datarate_fb_limit = true,
90 .vht_supported = false,
91 .lps_deep_mode_supported = 0,
92 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
93 +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
94 @@ -1972,6 +1972,7 @@ const struct rtw_chip_info rtw8821c_hw_s
95 .usb_tx_agg_desc_num = 3,
96 .hw_feature_report = true,
97 .c2h_ra_report_size = 7,
98 + .old_datarate_fb_limit = false,
100 .vht_supported = true,
101 .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
102 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
103 +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
104 @@ -2513,6 +2513,7 @@ const struct rtw_chip_info rtw8822b_hw_s
105 .usb_tx_agg_desc_num = 3,
106 .hw_feature_report = true,
107 .c2h_ra_report_size = 7,
108 + .old_datarate_fb_limit = false,
109 .ht_supported = true,
110 .vht_supported = true,
111 .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
112 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
113 +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
114 @@ -5333,6 +5333,7 @@ const struct rtw_chip_info rtw8822c_hw_s
115 .usb_tx_agg_desc_num = 3,
116 .hw_feature_report = true,
117 .c2h_ra_report_size = 7,
118 + .old_datarate_fb_limit = false,
119 .default_1ss_tx_path = BB_PATH_A,
120 .path_div_supported = true,
121 .ht_supported = true,
122 --- a/drivers/net/wireless/realtek/rtw88/sdio.c
123 +++ b/drivers/net/wireless/realtek/rtw88/sdio.c
124 @@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(stru
126 pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
128 - rtw_tx_fill_tx_desc(pkt_info, skb);
129 + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
130 rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
133 --- a/drivers/net/wireless/realtek/rtw88/tx.c
134 +++ b/drivers/net/wireless/realtek/rtw88/tx.c
135 @@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev
139 -void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
140 +void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
141 + struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
143 struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
144 bool more_data = false;
145 @@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p
147 tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE);
149 + if (rtwdev->chip->old_datarate_fb_limit)
150 + tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT);
152 tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) |
153 le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) |
154 le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) |
155 --- a/drivers/net/wireless/realtek/rtw88/tx.h
156 +++ b/drivers/net/wireless/realtek/rtw88/tx.h
157 @@ -44,6 +44,7 @@ struct rtw_tx_desc {
158 #define RTW_TX_DESC_W3_NAVUSEHDR BIT(15)
159 #define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17)
160 #define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0)
161 +#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8)
162 #define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24)
163 #define RTW_TX_DESC_W5_DATA_SHORT BIT(4)
164 #define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5)
165 @@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_d
166 struct rtw_tx_pkt_info *pkt_info,
167 struct ieee80211_sta *sta,
168 struct sk_buff *skb);
169 -void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
170 +void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
171 + struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
172 void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
173 void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
174 void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
175 --- a/drivers/net/wireless/realtek/rtw88/usb.c
176 +++ b/drivers/net/wireless/realtek/rtw88/usb.c
177 @@ -457,7 +457,7 @@ static int rtw_usb_write_data(struct rtw
178 skb_put_data(skb, buf, size);
179 skb_push(skb, chip->tx_pkt_desc_sz);
180 memset(skb->data, 0, chip->tx_pkt_desc_sz);
181 - rtw_tx_fill_tx_desc(pkt_info, skb);
182 + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
183 rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
185 ret = rtw_usb_write_port(rtwdev, qsel, skb,
186 @@ -524,7 +524,7 @@ static int rtw_usb_tx_write(struct rtw_d
187 pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
188 memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
189 ep = qsel_to_ep(rtwusb, pkt_info->qsel);
190 - rtw_tx_fill_tx_desc(pkt_info, skb);
191 + rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
192 rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
193 tx_data = rtw_usb_get_tx_data(skb);
194 tx_data->sn = pkt_info->sn;