mac80211: rtl8xxxu: sync with linux-next 20240229
[openwrt/staging/mans0n.git] / package / kernel / mac80211 / patches / rtl / 008-v6.9-wifi-rtl8xxxu-update-rate-mask-per-sta.patch
1 From 94dd7ce1885e530a7b10bbe50d5d68ba1bb99e6e Mon Sep 17 00:00:00 2001
2 From: Martin Kaistra <martin.kaistra@linutronix.de>
3 Date: Mon, 5 Feb 2024 10:30:40 +0100
4 Subject: [PATCH] wifi: rtl8xxxu: update rate mask per sta
5
6 Until now, rtl8xxxu_watchdog_callback() only fetches RSSI and updates
7 the rate mask in station mode. This means, in AP mode only the default
8 rate mask is used.
9
10 In order to have the rate mask reflect the actual connection quality,
11 extend rtl8xxxu_watchdog_callback() to iterate over every sta. Like in
12 the rtw88 driver, add a function to collect all currently present stas
13 and then iterate over a list of copies to ensure no RCU lock problems
14 for register access via USB. Remove the existing RCU lock in
15 rtl8xxxu_refresh_rate_mask().
16
17 Since the currently used ieee80211_ave_rssi() is only for 'vif', add
18 driver-level tracking of RSSI per sta.
19
20 Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
21 Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
22 Signed-off-by: Kalle Valo <kvalo@kernel.org>
23 Link: https://msgid.link/20240205093040.1941140-1-martin.kaistra@linutronix.de
24 ---
25 .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 8 +-
26 .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 188 ++++++++++++++----
27 2 files changed, 158 insertions(+), 38 deletions(-)
28
29 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
30 +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
31 @@ -6,6 +6,7 @@
32 */
33
34 #include <asm/byteorder.h>
35 +#include <linux/average.h>
36
37 #define RTL8XXXU_DEBUG_REG_WRITE 0x01
38 #define RTL8XXXU_DEBUG_REG_READ 0x02
39 @@ -1858,6 +1859,8 @@ struct rtl8xxxu_priv {
40 int next_mbox;
41 int nr_out_eps;
42
43 + /* Ensure no added or deleted stas while iterating */
44 + struct mutex sta_mutex;
45 struct mutex h2c_mutex;
46 /* Protect the indirect register accesses of RTL8710BU. */
47 struct mutex syson_indirect_access_mutex;
48 @@ -1892,7 +1895,6 @@ struct rtl8xxxu_priv {
49 u8 pi_enabled:1;
50 u8 no_pape:1;
51 u8 int_buf[USB_INTR_CONTENT_LENGTH];
52 - u8 rssi_level;
53 DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS);
54 DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS);
55
56 @@ -1913,11 +1915,15 @@ struct rtl8xxxu_priv {
57 DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM);
58 };
59
60 +DECLARE_EWMA(rssi, 10, 16);
61 +
62 struct rtl8xxxu_sta_info {
63 struct ieee80211_sta *sta;
64 struct ieee80211_vif *vif;
65
66 u8 macid;
67 + struct ewma_rssi avg_rssi;
68 + u8 rssi_level;
69 };
70
71 struct rtl8xxxu_vif {
72 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
73 +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
74 @@ -4991,10 +4991,11 @@ rtl8xxxu_bss_info_changed(struct ieee802
75 struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
76 struct rtl8xxxu_priv *priv = hw->priv;
77 struct device *dev = &priv->udev->dev;
78 + struct rtl8xxxu_sta_info *sta_info;
79 struct ieee80211_sta *sta;
80 struct rtl8xxxu_ra_report *rarpt;
81 + u8 val8, macid;
82 u32 val32;
83 - u8 val8;
84
85 rarpt = &priv->ra_report;
86
87 @@ -5017,6 +5018,7 @@ rtl8xxxu_bss_info_changed(struct ieee802
88 rcu_read_unlock();
89 goto error;
90 }
91 + macid = rtl8xxxu_get_macid(priv, sta);
92
93 if (sta->deflink.ht_cap.ht_supported)
94 dev_info(dev, "%s: HT supported\n", __func__);
95 @@ -5037,14 +5039,15 @@ rtl8xxxu_bss_info_changed(struct ieee802
96 bw = RATE_INFO_BW_40;
97 else
98 bw = RATE_INFO_BW_20;
99 +
100 + sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
101 + sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT;
102 rcu_read_unlock();
103
104 rtl8xxxu_update_ra_report(rarpt, highest_rate, sgi, bw);
105
106 - priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
107 -
108 priv->fops->update_rate_mask(priv, ramask, 0, sgi,
109 - bw == RATE_INFO_BW_40, 0);
110 + bw == RATE_INFO_BW_40, macid);
111
112 rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
113
114 @@ -6317,6 +6320,76 @@ static void rtl8188e_c2hcmd_callback(str
115 }
116 }
117
118 +#define rtl8xxxu_iterate_vifs_atomic(priv, iterator, data) \
119 + ieee80211_iterate_active_interfaces_atomic((priv)->hw, \
120 + IEEE80211_IFACE_ITER_NORMAL, iterator, data)
121 +
122 +struct rtl8xxxu_rx_update_rssi_data {
123 + struct rtl8xxxu_priv *priv;
124 + struct ieee80211_hdr *hdr;
125 + struct ieee80211_rx_status *rx_status;
126 + u8 *bssid;
127 +};
128 +
129 +static void rtl8xxxu_rx_update_rssi_iter(void *data, u8 *mac,
130 + struct ieee80211_vif *vif)
131 +{
132 + struct rtl8xxxu_rx_update_rssi_data *iter_data = data;
133 + struct ieee80211_sta *sta;
134 + struct ieee80211_hdr *hdr = iter_data->hdr;
135 + struct rtl8xxxu_priv *priv = iter_data->priv;
136 + struct rtl8xxxu_sta_info *sta_info;
137 + struct ieee80211_rx_status *rx_status = iter_data->rx_status;
138 + u8 *bssid = iter_data->bssid;
139 +
140 + if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
141 + return;
142 +
143 + if (!(ether_addr_equal(vif->addr, hdr->addr1) ||
144 + ieee80211_is_beacon(hdr->frame_control)))
145 + return;
146 +
147 + sta = ieee80211_find_sta_by_ifaddr(priv->hw, hdr->addr2,
148 + vif->addr);
149 + if (!sta)
150 + return;
151 +
152 + sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
153 + ewma_rssi_add(&sta_info->avg_rssi, -rx_status->signal);
154 +}
155 +
156 +static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
157 +{
158 + __le16 fc = hdr->frame_control;
159 + u8 *bssid;
160 +
161 + if (ieee80211_has_tods(fc))
162 + bssid = hdr->addr1;
163 + else if (ieee80211_has_fromds(fc))
164 + bssid = hdr->addr2;
165 + else
166 + bssid = hdr->addr3;
167 +
168 + return bssid;
169 +}
170 +
171 +static void rtl8xxxu_rx_update_rssi(struct rtl8xxxu_priv *priv,
172 + struct ieee80211_rx_status *rx_status,
173 + struct ieee80211_hdr *hdr)
174 +{
175 + struct rtl8xxxu_rx_update_rssi_data data = {};
176 +
177 + if (ieee80211_is_ctl(hdr->frame_control))
178 + return;
179 +
180 + data.priv = priv;
181 + data.hdr = hdr;
182 + data.rx_status = rx_status;
183 + data.bssid = get_hdr_bssid(hdr);
184 +
185 + rtl8xxxu_iterate_vifs_atomic(priv, rtl8xxxu_rx_update_rssi_iter, &data);
186 +}
187 +
188 int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
189 {
190 struct ieee80211_hw *hw = priv->hw;
191 @@ -6376,18 +6449,26 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8x
192 skb_queue_tail(&priv->c2hcmd_queue, skb);
193 schedule_work(&priv->c2hcmd_work);
194 } else {
195 + struct ieee80211_hdr *hdr;
196 +
197 phy_stats = (struct rtl8723au_phy_stats *)skb->data;
198
199 skb_pull(skb, drvinfo_sz + desc_shift);
200
201 skb_trim(skb, pkt_len);
202
203 - if (rx_desc->phy_stats)
204 + hdr = (struct ieee80211_hdr *)skb->data;
205 + if (rx_desc->phy_stats) {
206 priv->fops->parse_phystats(
207 priv, rx_status, phy_stats,
208 rx_desc->rxmcs,
209 - (struct ieee80211_hdr *)skb->data,
210 + hdr,
211 rx_desc->crc32 || rx_desc->icverr);
212 + if (!rx_desc->crc32 && !rx_desc->icverr)
213 + rtl8xxxu_rx_update_rssi(priv,
214 + rx_status,
215 + hdr);
216 + }
217
218 rx_status->mactime = rx_desc->tsfl;
219 rx_status->flag |= RX_FLAG_MACTIME_START;
220 @@ -6484,10 +6565,15 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8x
221 } else {
222 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
223
224 - if (rx_desc->phy_stats)
225 + if (rx_desc->phy_stats) {
226 priv->fops->parse_phystats(priv, rx_status, phy_stats,
227 rx_desc->rxmcs, hdr,
228 rx_desc->crc32 || rx_desc->icverr);
229 + if (!rx_desc->crc32 && !rx_desc->icverr)
230 + rtl8xxxu_rx_update_rssi(priv,
231 + rx_status,
232 + hdr);
233 + }
234
235 rx_status->mactime = rx_desc->tsfl;
236 rx_status->flag |= RX_FLAG_MACTIME_START;
237 @@ -7111,6 +7197,7 @@ static void rtl8xxxu_refresh_rate_mask(s
238 int signal, struct ieee80211_sta *sta,
239 bool force)
240 {
241 + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
242 struct ieee80211_hw *hw = priv->hw;
243 u16 wireless_mode;
244 u8 rssi_level, ratr_idx;
245 @@ -7119,7 +7206,7 @@ static void rtl8xxxu_refresh_rate_mask(s
246 u8 go_up_gap = 5;
247 u8 macid = rtl8xxxu_get_macid(priv, sta);
248
249 - rssi_level = priv->rssi_level;
250 + rssi_level = sta_info->rssi_level;
251 snr = rtl8xxxu_signal_to_snr(signal);
252 snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH;
253 snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW;
254 @@ -7144,18 +7231,16 @@ static void rtl8xxxu_refresh_rate_mask(s
255 else
256 rssi_level = RTL8XXXU_RATR_STA_LOW;
257
258 - if (rssi_level != priv->rssi_level || force) {
259 + if (rssi_level != sta_info->rssi_level || force) {
260 int sgi = 0;
261 u32 rate_bitmap = 0;
262
263 - rcu_read_lock();
264 rate_bitmap = (sta->deflink.supp_rates[0] & 0xfff) |
265 (sta->deflink.ht_cap.mcs.rx_mask[0] << 12) |
266 (sta->deflink.ht_cap.mcs.rx_mask[1] << 20);
267 if (sta->deflink.ht_cap.cap &
268 (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
269 sgi = 1;
270 - rcu_read_unlock();
271
272 wireless_mode = rtl8xxxu_wireless_mode(hw, sta);
273 switch (wireless_mode) {
274 @@ -7236,7 +7321,7 @@ static void rtl8xxxu_refresh_rate_mask(s
275 break;
276 }
277
278 - priv->rssi_level = rssi_level;
279 + sta_info->rssi_level = rssi_level;
280 priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz, macid);
281 }
282 }
283 @@ -7329,40 +7414,60 @@ static void rtl8xxxu_track_cfo(struct rt
284 rtl8xxxu_set_atc_status(priv, abs(cfo_average) >= CFO_TH_ATC);
285 }
286
287 -static void rtl8xxxu_watchdog_callback(struct work_struct *work)
288 +static void rtl8xxxu_ra_iter(void *data, struct ieee80211_sta *sta)
289 {
290 - struct ieee80211_vif *vif;
291 - struct rtl8xxxu_priv *priv;
292 - int i;
293 + struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
294 + struct rtl8xxxu_priv *priv = data;
295 + int signal = -ewma_rssi_read(&sta_info->avg_rssi);
296
297 - priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
298 - for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) {
299 - vif = priv->vifs[i];
300 + priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta),
301 + rtl8xxxu_signal_to_snr(signal));
302 + rtl8xxxu_refresh_rate_mask(priv, signal, sta, false);
303 +}
304 +
305 +struct rtl8xxxu_stas_entry {
306 + struct list_head list;
307 + struct ieee80211_sta *sta;
308 +};
309
310 - if (!vif || vif->type != NL80211_IFTYPE_STATION)
311 - continue;
312 +struct rtl8xxxu_iter_stas_data {
313 + struct rtl8xxxu_priv *priv;
314 + struct list_head list;
315 +};
316
317 - int signal;
318 - struct ieee80211_sta *sta;
319 +static void rtl8xxxu_collect_sta_iter(void *data, struct ieee80211_sta *sta)
320 +{
321 + struct rtl8xxxu_iter_stas_data *iter_stas = data;
322 + struct rtl8xxxu_stas_entry *stas_entry;
323
324 - rcu_read_lock();
325 - sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
326 - if (!sta) {
327 - struct device *dev = &priv->udev->dev;
328 + stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
329 + if (!stas_entry)
330 + return;
331
332 - dev_dbg(dev, "%s: no sta found\n", __func__);
333 - rcu_read_unlock();
334 - continue;
335 - }
336 - rcu_read_unlock();
337 + stas_entry->sta = sta;
338 + list_add_tail(&stas_entry->list, &iter_stas->list);
339 +}
340
341 - signal = ieee80211_ave_rssi(vif);
342 +static void rtl8xxxu_watchdog_callback(struct work_struct *work)
343 +{
344
345 - priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta),
346 - rtl8xxxu_signal_to_snr(signal));
347 + struct rtl8xxxu_iter_stas_data iter_data;
348 + struct rtl8xxxu_stas_entry *sta_entry, *tmp;
349 + struct rtl8xxxu_priv *priv;
350
351 - rtl8xxxu_refresh_rate_mask(priv, signal, sta, false);
352 + priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
353 + iter_data.priv = priv;
354 + INIT_LIST_HEAD(&iter_data.list);
355 +
356 + mutex_lock(&priv->sta_mutex);
357 + ieee80211_iterate_stations_atomic(priv->hw, rtl8xxxu_collect_sta_iter,
358 + &iter_data);
359 + list_for_each_entry_safe(sta_entry, tmp, &iter_data.list, list) {
360 + list_del_init(&sta_entry->list);
361 + rtl8xxxu_ra_iter(priv, sta_entry->sta);
362 + kfree(sta_entry);
363 }
364 + mutex_unlock(&priv->sta_mutex);
365
366 if (priv->fops->set_crystal_cap)
367 rtl8xxxu_track_cfo(priv);
368 @@ -7504,10 +7609,15 @@ static int rtl8xxxu_sta_add(struct ieee8
369 struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
370 struct rtl8xxxu_priv *priv = hw->priv;
371
372 + mutex_lock(&priv->sta_mutex);
373 + ewma_rssi_init(&sta_info->avg_rssi);
374 if (vif->type == NL80211_IFTYPE_AP) {
375 + sta_info->rssi_level = RTL8XXXU_RATR_STA_INIT;
376 sta_info->macid = rtl8xxxu_acquire_macid(priv);
377 - if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM)
378 + if (sta_info->macid >= RTL8XXXU_MAX_MAC_ID_NUM) {
379 + mutex_unlock(&priv->sta_mutex);
380 return -ENOSPC;
381 + }
382
383 rtl8xxxu_refresh_rate_mask(priv, 0, sta, true);
384 priv->fops->report_connect(priv, sta_info->macid, H2C_MACID_ROLE_STA, true);
385 @@ -7523,6 +7633,7 @@ static int rtl8xxxu_sta_add(struct ieee8
386 break;
387 }
388 }
389 + mutex_unlock(&priv->sta_mutex);
390
391 return 0;
392 }
393 @@ -7534,8 +7645,10 @@ static int rtl8xxxu_sta_remove(struct ie
394 struct rtl8xxxu_sta_info *sta_info = (struct rtl8xxxu_sta_info *)sta->drv_priv;
395 struct rtl8xxxu_priv *priv = hw->priv;
396
397 + mutex_lock(&priv->sta_mutex);
398 if (vif->type == NL80211_IFTYPE_AP)
399 rtl8xxxu_release_macid(priv, sta_info->macid);
400 + mutex_unlock(&priv->sta_mutex);
401
402 return 0;
403 }
404 @@ -7766,6 +7879,7 @@ static int rtl8xxxu_probe(struct usb_int
405 mutex_init(&priv->usb_buf_mutex);
406 mutex_init(&priv->syson_indirect_access_mutex);
407 mutex_init(&priv->h2c_mutex);
408 + mutex_init(&priv->sta_mutex);
409 INIT_LIST_HEAD(&priv->tx_urb_free_list);
410 spin_lock_init(&priv->tx_urb_lock);
411 INIT_LIST_HEAD(&priv->rx_urb_pending_list);