1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
2 | /* Copyright(c) 2019-2020 Realtek Corporation |
3 | */ |
4 | #include <linux/ip.h> |
5 | #include <linux/udp.h> |
6 | |
7 | #include "cam.h" |
8 | #include "chan.h" |
9 | #include "coex.h" |
10 | #include "core.h" |
11 | #include "efuse.h" |
12 | #include "fw.h" |
13 | #include "mac.h" |
14 | #include "phy.h" |
15 | #include "ps.h" |
16 | #include "reg.h" |
17 | #include "sar.h" |
18 | #include "ser.h" |
19 | #include "txrx.h" |
20 | #include "util.h" |
21 | |
22 | static bool rtw89_disable_ps_mode; |
23 | module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644); |
24 | MODULE_PARM_DESC(disable_ps_mode, "Set Y to disable low power mode" ); |
25 | |
26 | #define RTW89_DEF_CHAN(_freq, _hw_val, _flags, _band) \ |
27 | { .center_freq = _freq, .hw_value = _hw_val, .flags = _flags, .band = _band, } |
28 | #define RTW89_DEF_CHAN_2G(_freq, _hw_val) \ |
29 | RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_2GHZ) |
30 | #define RTW89_DEF_CHAN_5G(_freq, _hw_val) \ |
31 | RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_5GHZ) |
32 | #define RTW89_DEF_CHAN_5G_NO_HT40MINUS(_freq, _hw_val) \ |
33 | RTW89_DEF_CHAN(_freq, _hw_val, IEEE80211_CHAN_NO_HT40MINUS, NL80211_BAND_5GHZ) |
34 | #define RTW89_DEF_CHAN_6G(_freq, _hw_val) \ |
35 | RTW89_DEF_CHAN(_freq, _hw_val, 0, NL80211_BAND_6GHZ) |
36 | |
37 | static struct ieee80211_channel rtw89_channels_2ghz[] = { |
38 | RTW89_DEF_CHAN_2G(2412, 1), |
39 | RTW89_DEF_CHAN_2G(2417, 2), |
40 | RTW89_DEF_CHAN_2G(2422, 3), |
41 | RTW89_DEF_CHAN_2G(2427, 4), |
42 | RTW89_DEF_CHAN_2G(2432, 5), |
43 | RTW89_DEF_CHAN_2G(2437, 6), |
44 | RTW89_DEF_CHAN_2G(2442, 7), |
45 | RTW89_DEF_CHAN_2G(2447, 8), |
46 | RTW89_DEF_CHAN_2G(2452, 9), |
47 | RTW89_DEF_CHAN_2G(2457, 10), |
48 | RTW89_DEF_CHAN_2G(2462, 11), |
49 | RTW89_DEF_CHAN_2G(2467, 12), |
50 | RTW89_DEF_CHAN_2G(2472, 13), |
51 | RTW89_DEF_CHAN_2G(2484, 14), |
52 | }; |
53 | |
54 | static struct ieee80211_channel rtw89_channels_5ghz[] = { |
55 | RTW89_DEF_CHAN_5G(5180, 36), |
56 | RTW89_DEF_CHAN_5G(5200, 40), |
57 | RTW89_DEF_CHAN_5G(5220, 44), |
58 | RTW89_DEF_CHAN_5G(5240, 48), |
59 | RTW89_DEF_CHAN_5G(5260, 52), |
60 | RTW89_DEF_CHAN_5G(5280, 56), |
61 | RTW89_DEF_CHAN_5G(5300, 60), |
62 | RTW89_DEF_CHAN_5G(5320, 64), |
63 | RTW89_DEF_CHAN_5G(5500, 100), |
64 | RTW89_DEF_CHAN_5G(5520, 104), |
65 | RTW89_DEF_CHAN_5G(5540, 108), |
66 | RTW89_DEF_CHAN_5G(5560, 112), |
67 | RTW89_DEF_CHAN_5G(5580, 116), |
68 | RTW89_DEF_CHAN_5G(5600, 120), |
69 | RTW89_DEF_CHAN_5G(5620, 124), |
70 | RTW89_DEF_CHAN_5G(5640, 128), |
71 | RTW89_DEF_CHAN_5G(5660, 132), |
72 | RTW89_DEF_CHAN_5G(5680, 136), |
73 | RTW89_DEF_CHAN_5G(5700, 140), |
74 | RTW89_DEF_CHAN_5G(5720, 144), |
75 | RTW89_DEF_CHAN_5G(5745, 149), |
76 | RTW89_DEF_CHAN_5G(5765, 153), |
77 | RTW89_DEF_CHAN_5G(5785, 157), |
78 | RTW89_DEF_CHAN_5G(5805, 161), |
79 | RTW89_DEF_CHAN_5G_NO_HT40MINUS(5825, 165), |
80 | RTW89_DEF_CHAN_5G(5845, 169), |
81 | RTW89_DEF_CHAN_5G(5865, 173), |
82 | RTW89_DEF_CHAN_5G(5885, 177), |
83 | }; |
84 | |
85 | static struct ieee80211_channel rtw89_channels_6ghz[] = { |
86 | RTW89_DEF_CHAN_6G(5955, 1), |
87 | RTW89_DEF_CHAN_6G(5975, 5), |
88 | RTW89_DEF_CHAN_6G(5995, 9), |
89 | RTW89_DEF_CHAN_6G(6015, 13), |
90 | RTW89_DEF_CHAN_6G(6035, 17), |
91 | RTW89_DEF_CHAN_6G(6055, 21), |
92 | RTW89_DEF_CHAN_6G(6075, 25), |
93 | RTW89_DEF_CHAN_6G(6095, 29), |
94 | RTW89_DEF_CHAN_6G(6115, 33), |
95 | RTW89_DEF_CHAN_6G(6135, 37), |
96 | RTW89_DEF_CHAN_6G(6155, 41), |
97 | RTW89_DEF_CHAN_6G(6175, 45), |
98 | RTW89_DEF_CHAN_6G(6195, 49), |
99 | RTW89_DEF_CHAN_6G(6215, 53), |
100 | RTW89_DEF_CHAN_6G(6235, 57), |
101 | RTW89_DEF_CHAN_6G(6255, 61), |
102 | RTW89_DEF_CHAN_6G(6275, 65), |
103 | RTW89_DEF_CHAN_6G(6295, 69), |
104 | RTW89_DEF_CHAN_6G(6315, 73), |
105 | RTW89_DEF_CHAN_6G(6335, 77), |
106 | RTW89_DEF_CHAN_6G(6355, 81), |
107 | RTW89_DEF_CHAN_6G(6375, 85), |
108 | RTW89_DEF_CHAN_6G(6395, 89), |
109 | RTW89_DEF_CHAN_6G(6415, 93), |
110 | RTW89_DEF_CHAN_6G(6435, 97), |
111 | RTW89_DEF_CHAN_6G(6455, 101), |
112 | RTW89_DEF_CHAN_6G(6475, 105), |
113 | RTW89_DEF_CHAN_6G(6495, 109), |
114 | RTW89_DEF_CHAN_6G(6515, 113), |
115 | RTW89_DEF_CHAN_6G(6535, 117), |
116 | RTW89_DEF_CHAN_6G(6555, 121), |
117 | RTW89_DEF_CHAN_6G(6575, 125), |
118 | RTW89_DEF_CHAN_6G(6595, 129), |
119 | RTW89_DEF_CHAN_6G(6615, 133), |
120 | RTW89_DEF_CHAN_6G(6635, 137), |
121 | RTW89_DEF_CHAN_6G(6655, 141), |
122 | RTW89_DEF_CHAN_6G(6675, 145), |
123 | RTW89_DEF_CHAN_6G(6695, 149), |
124 | RTW89_DEF_CHAN_6G(6715, 153), |
125 | RTW89_DEF_CHAN_6G(6735, 157), |
126 | RTW89_DEF_CHAN_6G(6755, 161), |
127 | RTW89_DEF_CHAN_6G(6775, 165), |
128 | RTW89_DEF_CHAN_6G(6795, 169), |
129 | RTW89_DEF_CHAN_6G(6815, 173), |
130 | RTW89_DEF_CHAN_6G(6835, 177), |
131 | RTW89_DEF_CHAN_6G(6855, 181), |
132 | RTW89_DEF_CHAN_6G(6875, 185), |
133 | RTW89_DEF_CHAN_6G(6895, 189), |
134 | RTW89_DEF_CHAN_6G(6915, 193), |
135 | RTW89_DEF_CHAN_6G(6935, 197), |
136 | RTW89_DEF_CHAN_6G(6955, 201), |
137 | RTW89_DEF_CHAN_6G(6975, 205), |
138 | RTW89_DEF_CHAN_6G(6995, 209), |
139 | RTW89_DEF_CHAN_6G(7015, 213), |
140 | RTW89_DEF_CHAN_6G(7035, 217), |
141 | RTW89_DEF_CHAN_6G(7055, 221), |
142 | RTW89_DEF_CHAN_6G(7075, 225), |
143 | RTW89_DEF_CHAN_6G(7095, 229), |
144 | RTW89_DEF_CHAN_6G(7115, 233), |
145 | }; |
146 | |
147 | static struct ieee80211_rate rtw89_bitrates[] = { |
148 | { .bitrate = 10, .hw_value = 0x00, }, |
149 | { .bitrate = 20, .hw_value = 0x01, }, |
150 | { .bitrate = 55, .hw_value = 0x02, }, |
151 | { .bitrate = 110, .hw_value = 0x03, }, |
152 | { .bitrate = 60, .hw_value = 0x04, }, |
153 | { .bitrate = 90, .hw_value = 0x05, }, |
154 | { .bitrate = 120, .hw_value = 0x06, }, |
155 | { .bitrate = 180, .hw_value = 0x07, }, |
156 | { .bitrate = 240, .hw_value = 0x08, }, |
157 | { .bitrate = 360, .hw_value = 0x09, }, |
158 | { .bitrate = 480, .hw_value = 0x0a, }, |
159 | { .bitrate = 540, .hw_value = 0x0b, }, |
160 | }; |
161 | |
162 | static const struct ieee80211_iface_limit rtw89_iface_limits[] = { |
163 | { |
164 | .max = 1, |
165 | .types = BIT(NL80211_IFTYPE_STATION), |
166 | }, |
167 | { |
168 | .max = 1, |
169 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | |
170 | BIT(NL80211_IFTYPE_P2P_GO) | |
171 | BIT(NL80211_IFTYPE_AP), |
172 | }, |
173 | }; |
174 | |
175 | static const struct ieee80211_iface_limit rtw89_iface_limits_mcc[] = { |
176 | { |
177 | .max = 1, |
178 | .types = BIT(NL80211_IFTYPE_STATION), |
179 | }, |
180 | { |
181 | .max = 1, |
182 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | |
183 | BIT(NL80211_IFTYPE_P2P_GO), |
184 | }, |
185 | }; |
186 | |
187 | static const struct ieee80211_iface_combination rtw89_iface_combs[] = { |
188 | { |
189 | .limits = rtw89_iface_limits, |
190 | .n_limits = ARRAY_SIZE(rtw89_iface_limits), |
191 | .max_interfaces = 2, |
192 | .num_different_channels = 1, |
193 | }, |
194 | { |
195 | .limits = rtw89_iface_limits_mcc, |
196 | .n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc), |
197 | .max_interfaces = 2, |
198 | .num_different_channels = 2, |
199 | }, |
200 | }; |
201 | |
202 | bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate) |
203 | { |
204 | struct ieee80211_rate rate; |
205 | |
206 | if (unlikely(rpt_rate >= ARRAY_SIZE(rtw89_bitrates))) { |
207 | rtw89_debug(rtwdev, mask: RTW89_DBG_UNEXP, fmt: "invalid rpt rate %d\n" , rpt_rate); |
208 | return false; |
209 | } |
210 | |
211 | rate = rtw89_bitrates[rpt_rate]; |
212 | *bitrate = rate.bitrate; |
213 | |
214 | return true; |
215 | } |
216 | |
217 | static const struct ieee80211_supported_band rtw89_sband_2ghz = { |
218 | .band = NL80211_BAND_2GHZ, |
219 | .channels = rtw89_channels_2ghz, |
220 | .n_channels = ARRAY_SIZE(rtw89_channels_2ghz), |
221 | .bitrates = rtw89_bitrates, |
222 | .n_bitrates = ARRAY_SIZE(rtw89_bitrates), |
223 | .ht_cap = {0}, |
224 | .vht_cap = {0}, |
225 | }; |
226 | |
227 | static const struct ieee80211_supported_band rtw89_sband_5ghz = { |
228 | .band = NL80211_BAND_5GHZ, |
229 | .channels = rtw89_channels_5ghz, |
230 | .n_channels = ARRAY_SIZE(rtw89_channels_5ghz), |
231 | |
232 | /* 5G has no CCK rates, 1M/2M/5.5M/11M */ |
233 | .bitrates = rtw89_bitrates + 4, |
234 | .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, |
235 | .ht_cap = {0}, |
236 | .vht_cap = {0}, |
237 | }; |
238 | |
239 | static const struct ieee80211_supported_band rtw89_sband_6ghz = { |
240 | .band = NL80211_BAND_6GHZ, |
241 | .channels = rtw89_channels_6ghz, |
242 | .n_channels = ARRAY_SIZE(rtw89_channels_6ghz), |
243 | |
244 | /* 6G has no CCK rates, 1M/2M/5.5M/11M */ |
245 | .bitrates = rtw89_bitrates + 4, |
246 | .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, |
247 | }; |
248 | |
249 | static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev, |
250 | struct rtw89_traffic_stats *stats, |
251 | struct sk_buff *skb, bool tx) |
252 | { |
253 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
254 | |
255 | if (!ieee80211_is_data(fc: hdr->frame_control)) |
256 | return; |
257 | |
258 | if (is_broadcast_ether_addr(addr: hdr->addr1) || |
259 | is_multicast_ether_addr(addr: hdr->addr1)) |
260 | return; |
261 | |
262 | if (tx) { |
263 | stats->tx_cnt++; |
264 | stats->tx_unicast += skb->len; |
265 | } else { |
266 | stats->rx_cnt++; |
267 | stats->rx_unicast += skb->len; |
268 | } |
269 | } |
270 | |
271 | void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef) |
272 | { |
273 | cfg80211_chandef_create(chandef, channel: &rtw89_channels_2ghz[0], |
274 | chantype: NL80211_CHAN_NO_HT); |
275 | } |
276 | |
277 | void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef, |
278 | struct rtw89_chan *chan) |
279 | { |
280 | struct ieee80211_channel *channel = chandef->chan; |
281 | enum nl80211_chan_width width = chandef->width; |
282 | u32 primary_freq, center_freq; |
283 | u8 center_chan; |
284 | u8 bandwidth = RTW89_CHANNEL_WIDTH_20; |
285 | u32 offset; |
286 | u8 band; |
287 | |
288 | center_chan = channel->hw_value; |
289 | primary_freq = channel->center_freq; |
290 | center_freq = chandef->center_freq1; |
291 | |
292 | switch (width) { |
293 | case NL80211_CHAN_WIDTH_20_NOHT: |
294 | case NL80211_CHAN_WIDTH_20: |
295 | bandwidth = RTW89_CHANNEL_WIDTH_20; |
296 | break; |
297 | case NL80211_CHAN_WIDTH_40: |
298 | bandwidth = RTW89_CHANNEL_WIDTH_40; |
299 | if (primary_freq > center_freq) { |
300 | center_chan -= 2; |
301 | } else { |
302 | center_chan += 2; |
303 | } |
304 | break; |
305 | case NL80211_CHAN_WIDTH_80: |
306 | case NL80211_CHAN_WIDTH_160: |
307 | bandwidth = nl_to_rtw89_bandwidth(width); |
308 | if (primary_freq > center_freq) { |
309 | offset = (primary_freq - center_freq - 10) / 20; |
310 | center_chan -= 2 + offset * 4; |
311 | } else { |
312 | offset = (center_freq - primary_freq - 10) / 20; |
313 | center_chan += 2 + offset * 4; |
314 | } |
315 | break; |
316 | default: |
317 | center_chan = 0; |
318 | break; |
319 | } |
320 | |
321 | switch (channel->band) { |
322 | default: |
323 | case NL80211_BAND_2GHZ: |
324 | band = RTW89_BAND_2G; |
325 | break; |
326 | case NL80211_BAND_5GHZ: |
327 | band = RTW89_BAND_5G; |
328 | break; |
329 | case NL80211_BAND_6GHZ: |
330 | band = RTW89_BAND_6G; |
331 | break; |
332 | } |
333 | |
334 | rtw89_chan_create(chan, center_chan, primary_chan: channel->hw_value, band, bandwidth); |
335 | } |
336 | |
337 | void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev) |
338 | { |
339 | struct rtw89_hal *hal = &rtwdev->hal; |
340 | const struct rtw89_chip_info *chip = rtwdev->chip; |
341 | const struct rtw89_chan *chan; |
342 | enum rtw89_sub_entity_idx sub_entity_idx; |
343 | enum rtw89_sub_entity_idx roc_idx; |
344 | enum rtw89_phy_idx phy_idx; |
345 | enum rtw89_entity_mode mode; |
346 | bool entity_active; |
347 | |
348 | entity_active = rtw89_get_entity_state(rtwdev); |
349 | if (!entity_active) |
350 | return; |
351 | |
352 | mode = rtw89_get_entity_mode(rtwdev); |
353 | switch (mode) { |
354 | case RTW89_ENTITY_MODE_SCC: |
355 | case RTW89_ENTITY_MODE_MCC: |
356 | sub_entity_idx = RTW89_SUB_ENTITY_0; |
357 | break; |
358 | case RTW89_ENTITY_MODE_MCC_PREPARE: |
359 | sub_entity_idx = RTW89_SUB_ENTITY_1; |
360 | break; |
361 | default: |
362 | WARN(1, "Invalid ent mode: %d\n" , mode); |
363 | return; |
364 | } |
365 | |
366 | roc_idx = atomic_read(v: &hal->roc_entity_idx); |
367 | if (roc_idx != RTW89_SUB_ENTITY_IDLE) |
368 | sub_entity_idx = roc_idx; |
369 | |
370 | phy_idx = RTW89_PHY_0; |
371 | chan = rtw89_chan_get(rtwdev, idx: sub_entity_idx); |
372 | chip->ops->set_txpwr(rtwdev, chan, phy_idx); |
373 | } |
374 | |
375 | int rtw89_set_channel(struct rtw89_dev *rtwdev) |
376 | { |
377 | struct rtw89_hal *hal = &rtwdev->hal; |
378 | const struct rtw89_chip_info *chip = rtwdev->chip; |
379 | const struct rtw89_chan_rcd *chan_rcd; |
380 | const struct rtw89_chan *chan; |
381 | enum rtw89_sub_entity_idx sub_entity_idx; |
382 | enum rtw89_sub_entity_idx roc_idx; |
383 | enum rtw89_mac_idx mac_idx; |
384 | enum rtw89_phy_idx phy_idx; |
385 | struct rtw89_channel_help_params bak; |
386 | enum rtw89_entity_mode mode; |
387 | bool entity_active; |
388 | |
389 | entity_active = rtw89_get_entity_state(rtwdev); |
390 | |
391 | mode = rtw89_entity_recalc(rtwdev); |
392 | switch (mode) { |
393 | case RTW89_ENTITY_MODE_SCC: |
394 | case RTW89_ENTITY_MODE_MCC: |
395 | sub_entity_idx = RTW89_SUB_ENTITY_0; |
396 | break; |
397 | case RTW89_ENTITY_MODE_MCC_PREPARE: |
398 | sub_entity_idx = RTW89_SUB_ENTITY_1; |
399 | break; |
400 | default: |
401 | WARN(1, "Invalid ent mode: %d\n" , mode); |
402 | return -EINVAL; |
403 | } |
404 | |
405 | roc_idx = atomic_read(v: &hal->roc_entity_idx); |
406 | if (roc_idx != RTW89_SUB_ENTITY_IDLE) |
407 | sub_entity_idx = roc_idx; |
408 | |
409 | mac_idx = RTW89_MAC_0; |
410 | phy_idx = RTW89_PHY_0; |
411 | |
412 | chan = rtw89_chan_get(rtwdev, idx: sub_entity_idx); |
413 | chan_rcd = rtw89_chan_rcd_get(rtwdev, idx: sub_entity_idx); |
414 | |
415 | rtw89_chip_set_channel_prepare(rtwdev, p: &bak, chan, mac_idx, phy_idx); |
416 | |
417 | chip->ops->set_channel(rtwdev, chan, mac_idx, phy_idx); |
418 | |
419 | chip->ops->set_txpwr(rtwdev, chan, phy_idx); |
420 | |
421 | rtw89_chip_set_channel_done(rtwdev, p: &bak, chan, mac_idx, phy_idx); |
422 | |
423 | if (!entity_active || chan_rcd->band_changed) { |
424 | rtw89_btc_ntfy_switch_band(rtwdev, phy_idx, band: chan->band_type); |
425 | rtw89_chip_rfk_band_changed(rtwdev, phy_idx); |
426 | } |
427 | |
428 | rtw89_set_entity_state(rtwdev, active: true); |
429 | return 0; |
430 | } |
431 | |
432 | void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, |
433 | struct rtw89_chan *chan) |
434 | { |
435 | const struct cfg80211_chan_def *chandef; |
436 | |
437 | chandef = rtw89_chandef_get(rtwdev, idx: rtwvif->sub_entity_idx); |
438 | rtw89_get_channel_params(chandef, chan); |
439 | } |
440 | |
441 | static enum rtw89_core_tx_type |
442 | rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, |
443 | struct sk_buff *skb) |
444 | { |
445 | struct ieee80211_hdr *hdr = (void *)skb->data; |
446 | __le16 fc = hdr->frame_control; |
447 | |
448 | if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc)) |
449 | return RTW89_CORE_TX_TYPE_MGMT; |
450 | |
451 | return RTW89_CORE_TX_TYPE_DATA; |
452 | } |
453 | |
454 | static void |
455 | rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, |
456 | struct rtw89_core_tx_request *tx_req, |
457 | enum btc_pkt_type pkt_type) |
458 | { |
459 | struct ieee80211_sta *sta = tx_req->sta; |
460 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
461 | struct sk_buff *skb = tx_req->skb; |
462 | struct rtw89_sta *rtwsta; |
463 | u8 ampdu_num; |
464 | u8 tid; |
465 | |
466 | if (pkt_type == PACKET_EAPOL) { |
467 | desc_info->bk = true; |
468 | return; |
469 | } |
470 | |
471 | if (!(IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU)) |
472 | return; |
473 | |
474 | if (!sta) { |
475 | rtw89_warn(rtwdev, "cannot set ampdu info without sta\n" ); |
476 | return; |
477 | } |
478 | |
479 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
480 | rtwsta = (struct rtw89_sta *)sta->drv_priv; |
481 | |
482 | ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? |
483 | rtwsta->ampdu_params[tid].agg_num : |
484 | 4 << sta->deflink.ht_cap.ampdu_factor) - 1); |
485 | |
486 | desc_info->agg_en = true; |
487 | desc_info->ampdu_density = sta->deflink.ht_cap.ampdu_density; |
488 | desc_info->ampdu_num = ampdu_num; |
489 | } |
490 | |
491 | static void |
492 | rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, |
493 | struct rtw89_core_tx_request *tx_req) |
494 | { |
495 | const struct rtw89_chip_info *chip = rtwdev->chip; |
496 | struct ieee80211_vif *vif = tx_req->vif; |
497 | struct ieee80211_sta *sta = tx_req->sta; |
498 | struct ieee80211_tx_info *info; |
499 | struct ieee80211_key_conf *key; |
500 | struct rtw89_vif *rtwvif; |
501 | struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); |
502 | struct rtw89_addr_cam_entry *addr_cam; |
503 | struct rtw89_sec_cam_entry *sec_cam; |
504 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
505 | struct sk_buff *skb = tx_req->skb; |
506 | u8 sec_type = RTW89_SEC_KEY_TYPE_NONE; |
507 | u64 pn64; |
508 | |
509 | if (!vif) { |
510 | rtw89_warn(rtwdev, "cannot set sec key without vif\n" ); |
511 | return; |
512 | } |
513 | |
514 | rtwvif = (struct rtw89_vif *)vif->drv_priv; |
515 | addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta); |
516 | |
517 | info = IEEE80211_SKB_CB(skb); |
518 | key = info->control.hw_key; |
519 | sec_cam = addr_cam->sec_entries[key->hw_key_idx]; |
520 | if (!sec_cam) { |
521 | rtw89_warn(rtwdev, "sec cam entry is empty\n" ); |
522 | return; |
523 | } |
524 | |
525 | switch (key->cipher) { |
526 | case WLAN_CIPHER_SUITE_WEP40: |
527 | sec_type = RTW89_SEC_KEY_TYPE_WEP40; |
528 | break; |
529 | case WLAN_CIPHER_SUITE_WEP104: |
530 | sec_type = RTW89_SEC_KEY_TYPE_WEP104; |
531 | break; |
532 | case WLAN_CIPHER_SUITE_TKIP: |
533 | sec_type = RTW89_SEC_KEY_TYPE_TKIP; |
534 | break; |
535 | case WLAN_CIPHER_SUITE_CCMP: |
536 | sec_type = RTW89_SEC_KEY_TYPE_CCMP128; |
537 | break; |
538 | case WLAN_CIPHER_SUITE_CCMP_256: |
539 | sec_type = RTW89_SEC_KEY_TYPE_CCMP256; |
540 | break; |
541 | case WLAN_CIPHER_SUITE_GCMP: |
542 | sec_type = RTW89_SEC_KEY_TYPE_GCMP128; |
543 | break; |
544 | case WLAN_CIPHER_SUITE_GCMP_256: |
545 | sec_type = RTW89_SEC_KEY_TYPE_GCMP256; |
546 | break; |
547 | default: |
548 | rtw89_warn(rtwdev, "key cipher not supported %d\n" , key->cipher); |
549 | return; |
550 | } |
551 | |
552 | desc_info->sec_en = true; |
553 | desc_info->sec_keyid = key->keyidx; |
554 | desc_info->sec_type = sec_type; |
555 | desc_info->sec_cam_idx = sec_cam->sec_cam_idx; |
556 | |
557 | if (!chip->hw_sec_hdr) |
558 | return; |
559 | |
560 | pn64 = atomic64_inc_return(v: &key->tx_pn); |
561 | desc_info->sec_seq[0] = pn64; |
562 | desc_info->sec_seq[1] = pn64 >> 8; |
563 | desc_info->sec_seq[2] = pn64 >> 16; |
564 | desc_info->sec_seq[3] = pn64 >> 24; |
565 | desc_info->sec_seq[4] = pn64 >> 32; |
566 | desc_info->sec_seq[5] = pn64 >> 40; |
567 | desc_info->wp_offset = 1; /* in unit of 8 bytes for security header */ |
568 | } |
569 | |
570 | static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, |
571 | struct rtw89_core_tx_request *tx_req, |
572 | const struct rtw89_chan *chan) |
573 | { |
574 | struct sk_buff *skb = tx_req->skb; |
575 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
576 | struct ieee80211_vif *vif = tx_info->control.vif; |
577 | u16 lowest_rate; |
578 | |
579 | if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || |
580 | (vif && vif->p2p)) |
581 | lowest_rate = RTW89_HW_RATE_OFDM6; |
582 | else if (chan->band_type == RTW89_BAND_2G) |
583 | lowest_rate = RTW89_HW_RATE_CCK1; |
584 | else |
585 | lowest_rate = RTW89_HW_RATE_OFDM6; |
586 | |
587 | if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta) |
588 | return lowest_rate; |
589 | |
590 | return __ffs(vif->bss_conf.basic_rates) + lowest_rate; |
591 | } |
592 | |
593 | static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, |
594 | struct rtw89_core_tx_request *tx_req) |
595 | { |
596 | struct ieee80211_vif *vif = tx_req->vif; |
597 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
598 | struct ieee80211_sta *sta = tx_req->sta; |
599 | struct rtw89_sta *rtwsta; |
600 | |
601 | if (!sta) |
602 | return rtwvif->mac_id; |
603 | |
604 | rtwsta = (struct rtw89_sta *)sta->drv_priv; |
605 | return rtwsta->mac_id; |
606 | } |
607 | |
608 | static void |
609 | rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, |
610 | struct rtw89_core_tx_request *tx_req) |
611 | { |
612 | struct ieee80211_vif *vif = tx_req->vif; |
613 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
614 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
615 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, |
616 | idx: rtwvif->sub_entity_idx); |
617 | u8 qsel, ch_dma; |
618 | |
619 | qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT; |
620 | ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
621 | |
622 | desc_info->qsel = qsel; |
623 | desc_info->ch_dma = ch_dma; |
624 | desc_info->port = desc_info->hiq ? rtwvif->port : 0; |
625 | desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); |
626 | desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL; |
627 | desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE; |
628 | |
629 | /* fixed data rate for mgmt frames */ |
630 | desc_info->en_wd_info = true; |
631 | desc_info->use_rate = true; |
632 | desc_info->dis_data_fb = true; |
633 | desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req, chan); |
634 | |
635 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
636 | fmt: "tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n" , |
637 | desc_info->data_rate, chan->channel, chan->band_type, |
638 | chan->band_width); |
639 | } |
640 | |
641 | static void |
642 | rtw89_core_tx_update_h2c_info(struct rtw89_dev *rtwdev, |
643 | struct rtw89_core_tx_request *tx_req) |
644 | { |
645 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
646 | |
647 | desc_info->is_bmc = false; |
648 | desc_info->wd_page = false; |
649 | desc_info->ch_dma = RTW89_DMA_H2C; |
650 | } |
651 | |
652 | static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc, |
653 | const struct rtw89_chan *chan) |
654 | { |
655 | static const u8 rtw89_bandwidth_to_om[] = { |
656 | [RTW89_CHANNEL_WIDTH_20] = HTC_OM_CHANNEL_WIDTH_20, |
657 | [RTW89_CHANNEL_WIDTH_40] = HTC_OM_CHANNEL_WIDTH_40, |
658 | [RTW89_CHANNEL_WIDTH_80] = HTC_OM_CHANNEL_WIDTH_80, |
659 | [RTW89_CHANNEL_WIDTH_160] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, |
660 | [RTW89_CHANNEL_WIDTH_80_80] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, |
661 | }; |
662 | const struct rtw89_chip_info *chip = rtwdev->chip; |
663 | struct rtw89_hal *hal = &rtwdev->hal; |
664 | u8 om_bandwidth; |
665 | |
666 | if (!chip->dis_2g_40m_ul_ofdma || |
667 | chan->band_type != RTW89_BAND_2G || |
668 | chan->band_width != RTW89_CHANNEL_WIDTH_40) |
669 | return; |
670 | |
671 | om_bandwidth = chan->band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ? |
672 | rtw89_bandwidth_to_om[chan->band_width] : 0; |
673 | *htc = le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | |
674 | le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_OM, RTW89_HTC_MASK_CTL_ID) | |
675 | le32_encode_bits(v: hal->rx_nss - 1, RTW89_HTC_MASK_HTC_OM_RX_NSS) | |
676 | le32_encode_bits(v: om_bandwidth, RTW89_HTC_MASK_HTC_OM_CH_WIDTH) | |
677 | le32_encode_bits(v: 1, RTW89_HTC_MASK_HTC_OM_UL_MU_DIS) | |
678 | le32_encode_bits(v: hal->tx_nss - 1, RTW89_HTC_MASK_HTC_OM_TX_NSTS) | |
679 | le32_encode_bits(v: 0, RTW89_HTC_MASK_HTC_OM_ER_SU_DIS) | |
680 | le32_encode_bits(v: 0, RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR) | |
681 | le32_encode_bits(v: 0, RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS); |
682 | } |
683 | |
684 | static bool |
685 | __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, |
686 | struct rtw89_core_tx_request *tx_req, |
687 | enum btc_pkt_type pkt_type) |
688 | { |
689 | struct ieee80211_sta *sta = tx_req->sta; |
690 | struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); |
691 | struct sk_buff *skb = tx_req->skb; |
692 | struct ieee80211_hdr *hdr = (void *)skb->data; |
693 | __le16 fc = hdr->frame_control; |
694 | |
695 | /* AP IOT issue with EAPoL, ARP and DHCP */ |
696 | if (pkt_type < PACKET_MAX) |
697 | return false; |
698 | |
699 | if (!sta || !sta->deflink.he_cap.has_he) |
700 | return false; |
701 | |
702 | if (!ieee80211_is_data_qos(fc)) |
703 | return false; |
704 | |
705 | if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN) |
706 | return false; |
707 | |
708 | if (rtwsta && rtwsta->ra_report.might_fallback_legacy) |
709 | return false; |
710 | |
711 | return true; |
712 | } |
713 | |
714 | static void |
715 | __rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, |
716 | struct rtw89_core_tx_request *tx_req) |
717 | { |
718 | struct ieee80211_sta *sta = tx_req->sta; |
719 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
720 | struct sk_buff *skb = tx_req->skb; |
721 | struct ieee80211_hdr *hdr = (void *)skb->data; |
722 | __le16 fc = hdr->frame_control; |
723 | void *data; |
724 | __le32 *htc; |
725 | u8 *qc; |
726 | int hdr_len; |
727 | |
728 | hdr_len = ieee80211_has_a4(fc) ? 32 : 26; |
729 | data = skb_push(skb, IEEE80211_HT_CTL_LEN); |
730 | memmove(data, data + IEEE80211_HT_CTL_LEN, hdr_len); |
731 | |
732 | hdr = data; |
733 | htc = data + hdr_len; |
734 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER); |
735 | *htc = rtwsta->htc_template ? rtwsta->htc_template : |
736 | le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | |
737 | le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID); |
738 | |
739 | qc = data + hdr_len - IEEE80211_QOS_CTL_LEN; |
740 | qc[0] |= IEEE80211_QOS_CTL_EOSP; |
741 | } |
742 | |
743 | static void |
744 | rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, |
745 | struct rtw89_core_tx_request *tx_req, |
746 | enum btc_pkt_type pkt_type) |
747 | { |
748 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
749 | struct ieee80211_vif *vif = tx_req->vif; |
750 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
751 | |
752 | if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type)) |
753 | goto desc_bk; |
754 | |
755 | __rtw89_core_tx_adjust_he_qos_htc(rtwdev, tx_req); |
756 | |
757 | desc_info->pkt_size += IEEE80211_HT_CTL_LEN; |
758 | desc_info->a_ctrl_bsr = true; |
759 | |
760 | desc_bk: |
761 | if (!rtwvif || rtwvif->last_a_ctrl == desc_info->a_ctrl_bsr) |
762 | return; |
763 | |
764 | rtwvif->last_a_ctrl = desc_info->a_ctrl_bsr; |
765 | desc_info->bk = true; |
766 | } |
767 | |
768 | static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, |
769 | struct rtw89_core_tx_request *tx_req) |
770 | { |
771 | struct ieee80211_vif *vif = tx_req->vif; |
772 | struct ieee80211_sta *sta = tx_req->sta; |
773 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
774 | struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; |
775 | enum rtw89_sub_entity_idx idx = rtwvif->sub_entity_idx; |
776 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); |
777 | u16 lowest_rate; |
778 | |
779 | if (rate_pattern->enable) |
780 | return rate_pattern->rate; |
781 | |
782 | if (vif->p2p) |
783 | lowest_rate = RTW89_HW_RATE_OFDM6; |
784 | else if (chan->band_type == RTW89_BAND_2G) |
785 | lowest_rate = RTW89_HW_RATE_CCK1; |
786 | else |
787 | lowest_rate = RTW89_HW_RATE_OFDM6; |
788 | |
789 | if (!sta || !sta->deflink.supp_rates[chan->band_type]) |
790 | return lowest_rate; |
791 | |
792 | return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate; |
793 | } |
794 | |
795 | static void |
796 | rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, |
797 | struct rtw89_core_tx_request *tx_req) |
798 | { |
799 | struct ieee80211_vif *vif = tx_req->vif; |
800 | struct ieee80211_sta *sta = tx_req->sta; |
801 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
802 | struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); |
803 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
804 | struct sk_buff *skb = tx_req->skb; |
805 | u8 tid, tid_indicate; |
806 | u8 qsel, ch_dma; |
807 | |
808 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
809 | tid_indicate = rtw89_core_get_tid_indicate(rtwdev, tid); |
810 | qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : rtw89_core_get_qsel(rtwdev, tid); |
811 | ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
812 | |
813 | desc_info->ch_dma = ch_dma; |
814 | desc_info->tid_indicate = tid_indicate; |
815 | desc_info->qsel = qsel; |
816 | desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); |
817 | desc_info->port = desc_info->hiq ? rtwvif->port : 0; |
818 | desc_info->er_cap = rtwsta ? rtwsta->er_cap : false; |
819 | |
820 | /* enable wd_info for AMPDU */ |
821 | desc_info->en_wd_info = true; |
822 | |
823 | if (IEEE80211_SKB_CB(skb)->control.hw_key) |
824 | rtw89_core_tx_update_sec_key(rtwdev, tx_req); |
825 | |
826 | desc_info->data_retry_lowest_rate = rtw89_core_get_data_rate(rtwdev, tx_req); |
827 | } |
828 | |
829 | static enum btc_pkt_type |
830 | rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, |
831 | struct rtw89_core_tx_request *tx_req) |
832 | { |
833 | struct sk_buff *skb = tx_req->skb; |
834 | struct udphdr *udphdr; |
835 | |
836 | if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) { |
837 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->btc.eapol_notify_work); |
838 | return PACKET_EAPOL; |
839 | } |
840 | |
841 | if (skb->protocol == htons(ETH_P_ARP)) { |
842 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->btc.arp_notify_work); |
843 | return PACKET_ARP; |
844 | } |
845 | |
846 | if (skb->protocol == htons(ETH_P_IP) && |
847 | ip_hdr(skb)->protocol == IPPROTO_UDP) { |
848 | udphdr = udp_hdr(skb); |
849 | if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) || |
850 | (udphdr->source == htons(68) && udphdr->dest == htons(67))) && |
851 | skb->len > 282) { |
852 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->btc.dhcp_notify_work); |
853 | return PACKET_DHCP; |
854 | } |
855 | } |
856 | |
857 | if (skb->protocol == htons(ETH_P_IP) && |
858 | ip_hdr(skb)->protocol == IPPROTO_ICMP) { |
859 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->btc.icmp_notify_work); |
860 | return PACKET_ICMP; |
861 | } |
862 | |
863 | return PACKET_MAX; |
864 | } |
865 | |
866 | static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev, |
867 | struct rtw89_tx_desc_info *desc_info, |
868 | struct sk_buff *skb) |
869 | { |
870 | struct ieee80211_hdr *hdr = (void *)skb->data; |
871 | __le16 fc = hdr->frame_control; |
872 | |
873 | desc_info->hdr_llc_len = ieee80211_hdrlen(fc); |
874 | desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */ |
875 | } |
876 | |
877 | static void |
878 | rtw89_core_tx_wake(struct rtw89_dev *rtwdev, |
879 | struct rtw89_core_tx_request *tx_req) |
880 | { |
881 | const struct rtw89_chip_info *chip = rtwdev->chip; |
882 | |
883 | if (!RTW89_CHK_FW_FEATURE(TX_WAKE, &rtwdev->fw)) |
884 | return; |
885 | |
886 | if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) |
887 | return; |
888 | |
889 | if (chip->chip_id != RTL8852C && |
890 | tx_req->tx_type != RTW89_CORE_TX_TYPE_MGMT) |
891 | return; |
892 | |
893 | rtw89_mac_notify_wake(rtwdev); |
894 | } |
895 | |
896 | static void |
897 | rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, |
898 | struct rtw89_core_tx_request *tx_req) |
899 | { |
900 | struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; |
901 | struct sk_buff *skb = tx_req->skb; |
902 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
903 | struct ieee80211_hdr *hdr = (void *)skb->data; |
904 | enum rtw89_core_tx_type tx_type; |
905 | enum btc_pkt_type pkt_type; |
906 | bool is_bmc; |
907 | u16 seq; |
908 | |
909 | seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
910 | if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) { |
911 | tx_type = rtw89_core_get_tx_type(rtwdev, skb); |
912 | tx_req->tx_type = tx_type; |
913 | } |
914 | is_bmc = (is_broadcast_ether_addr(addr: hdr->addr1) || |
915 | is_multicast_ether_addr(addr: hdr->addr1)); |
916 | |
917 | desc_info->seq = seq; |
918 | desc_info->pkt_size = skb->len; |
919 | desc_info->is_bmc = is_bmc; |
920 | desc_info->wd_page = true; |
921 | desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
922 | |
923 | switch (tx_req->tx_type) { |
924 | case RTW89_CORE_TX_TYPE_MGMT: |
925 | rtw89_core_tx_update_mgmt_info(rtwdev, tx_req); |
926 | break; |
927 | case RTW89_CORE_TX_TYPE_DATA: |
928 | rtw89_core_tx_update_data_info(rtwdev, tx_req); |
929 | pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req); |
930 | rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type); |
931 | rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, pkt_type); |
932 | rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb); |
933 | break; |
934 | case RTW89_CORE_TX_TYPE_FWCMD: |
935 | rtw89_core_tx_update_h2c_info(rtwdev, tx_req); |
936 | break; |
937 | } |
938 | } |
939 | |
940 | void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel) |
941 | { |
942 | u8 ch_dma; |
943 | |
944 | ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
945 | |
946 | rtw89_hci_tx_kick_off(rtwdev, txch: ch_dma); |
947 | } |
948 | |
949 | int rtw89_core_tx_kick_off_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, |
950 | int qsel, unsigned int timeout) |
951 | { |
952 | struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); |
953 | struct rtw89_tx_wait_info *wait; |
954 | unsigned long time_left; |
955 | int ret = 0; |
956 | |
957 | wait = kzalloc(size: sizeof(*wait), GFP_KERNEL); |
958 | if (!wait) { |
959 | rtw89_core_tx_kick_off(rtwdev, qsel); |
960 | return 0; |
961 | } |
962 | |
963 | init_completion(x: &wait->completion); |
964 | rcu_assign_pointer(skb_data->wait, wait); |
965 | |
966 | rtw89_core_tx_kick_off(rtwdev, qsel); |
967 | time_left = wait_for_completion_timeout(x: &wait->completion, |
968 | timeout: msecs_to_jiffies(m: timeout)); |
969 | if (time_left == 0) |
970 | ret = -ETIMEDOUT; |
971 | else if (!wait->tx_done) |
972 | ret = -EAGAIN; |
973 | |
974 | rcu_assign_pointer(skb_data->wait, NULL); |
975 | kfree_rcu(wait, rcu_head); |
976 | |
977 | return ret; |
978 | } |
979 | |
980 | int rtw89_h2c_tx(struct rtw89_dev *rtwdev, |
981 | struct sk_buff *skb, bool fwdl) |
982 | { |
983 | struct rtw89_core_tx_request tx_req = {0}; |
984 | u32 cnt; |
985 | int ret; |
986 | |
987 | if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { |
988 | rtw89_debug(rtwdev, mask: RTW89_DBG_FW, |
989 | fmt: "ignore h2c due to power is off with firmware state=%d\n" , |
990 | test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)); |
991 | dev_kfree_skb(skb); |
992 | return 0; |
993 | } |
994 | |
995 | tx_req.skb = skb; |
996 | tx_req.tx_type = RTW89_CORE_TX_TYPE_FWCMD; |
997 | if (fwdl) |
998 | tx_req.desc_info.fw_dl = true; |
999 | |
1000 | rtw89_core_tx_update_desc_info(rtwdev, tx_req: &tx_req); |
1001 | |
1002 | if (!fwdl) |
1003 | rtw89_hex_dump(rtwdev, mask: RTW89_DBG_FW, prefix_str: "H2C: " , buf: skb->data, len: skb->len); |
1004 | |
1005 | cnt = rtw89_hci_check_and_reclaim_tx_resource(rtwdev, txch: RTW89_TXCH_CH12); |
1006 | if (cnt == 0) { |
1007 | rtw89_err(rtwdev, "no tx fwcmd resource\n" ); |
1008 | return -ENOSPC; |
1009 | } |
1010 | |
1011 | ret = rtw89_hci_tx_write(rtwdev, tx_req: &tx_req); |
1012 | if (ret) { |
1013 | rtw89_err(rtwdev, "failed to transmit skb to HCI\n" ); |
1014 | return ret; |
1015 | } |
1016 | rtw89_hci_tx_kick_off(rtwdev, txch: RTW89_TXCH_CH12); |
1017 | |
1018 | return 0; |
1019 | } |
1020 | |
1021 | int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, |
1022 | struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel) |
1023 | { |
1024 | struct rtw89_core_tx_request tx_req = {0}; |
1025 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1026 | int ret; |
1027 | |
1028 | tx_req.skb = skb; |
1029 | tx_req.sta = sta; |
1030 | tx_req.vif = vif; |
1031 | |
1032 | rtw89_traffic_stats_accu(rtwdev, stats: &rtwdev->stats, skb, tx: true); |
1033 | rtw89_traffic_stats_accu(rtwdev, stats: &rtwvif->stats, skb, tx: true); |
1034 | rtw89_core_tx_update_desc_info(rtwdev, tx_req: &tx_req); |
1035 | rtw89_core_tx_wake(rtwdev, tx_req: &tx_req); |
1036 | |
1037 | ret = rtw89_hci_tx_write(rtwdev, tx_req: &tx_req); |
1038 | if (ret) { |
1039 | rtw89_err(rtwdev, "failed to transmit skb to HCI\n" ); |
1040 | return ret; |
1041 | } |
1042 | |
1043 | if (qsel) |
1044 | *qsel = tx_req.desc_info.qsel; |
1045 | |
1046 | return 0; |
1047 | } |
1048 | |
1049 | static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info) |
1050 | { |
1051 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET, desc_info->wp_offset) | |
1052 | FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | |
1053 | FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | |
1054 | FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | |
1055 | FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | |
1056 | FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl) | |
1057 | FIELD_PREP(RTW89_TXWD_BODY0_HW_SSN_SEL, desc_info->hw_ssn_sel) | |
1058 | FIELD_PREP(RTW89_TXWD_BODY0_HW_SSN_MODE, desc_info->hw_seq_mode); |
1059 | |
1060 | return cpu_to_le32(dword); |
1061 | } |
1062 | |
1063 | static __le32 rtw89_build_txwd_body0_v1(struct rtw89_tx_desc_info *desc_info) |
1064 | { |
1065 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET_V1, desc_info->wp_offset) | |
1066 | FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | |
1067 | FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | |
1068 | FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | |
1069 | FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | |
1070 | FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl); |
1071 | |
1072 | return cpu_to_le32(dword); |
1073 | } |
1074 | |
1075 | static __le32 rtw89_build_txwd_body1_v1(struct rtw89_tx_desc_info *desc_info) |
1076 | { |
1077 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | |
1078 | FIELD_PREP(RTW89_TXWD_BODY1_SEC_KEYID, desc_info->sec_keyid) | |
1079 | FIELD_PREP(RTW89_TXWD_BODY1_SEC_TYPE, desc_info->sec_type); |
1080 | |
1081 | return cpu_to_le32(dword); |
1082 | } |
1083 | |
1084 | static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info) |
1085 | { |
1086 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY2_TID_INDICATE, desc_info->tid_indicate) | |
1087 | FIELD_PREP(RTW89_TXWD_BODY2_QSEL, desc_info->qsel) | |
1088 | FIELD_PREP(RTW89_TXWD_BODY2_TXPKT_SIZE, desc_info->pkt_size) | |
1089 | FIELD_PREP(RTW89_TXWD_BODY2_MACID, desc_info->mac_id); |
1090 | |
1091 | return cpu_to_le32(dword); |
1092 | } |
1093 | |
1094 | static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) |
1095 | { |
1096 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY3_SW_SEQ, desc_info->seq) | |
1097 | FIELD_PREP(RTW89_TXWD_BODY3_AGG_EN, desc_info->agg_en) | |
1098 | FIELD_PREP(RTW89_TXWD_BODY3_BK, desc_info->bk); |
1099 | |
1100 | return cpu_to_le32(dword); |
1101 | } |
1102 | |
1103 | static __le32 rtw89_build_txwd_body4(struct rtw89_tx_desc_info *desc_info) |
1104 | { |
1105 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) | |
1106 | FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L1, desc_info->sec_seq[1]); |
1107 | |
1108 | return cpu_to_le32(dword); |
1109 | } |
1110 | |
1111 | static __le32 rtw89_build_txwd_body5(struct rtw89_tx_desc_info *desc_info) |
1112 | { |
1113 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H2, desc_info->sec_seq[2]) | |
1114 | FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H3, desc_info->sec_seq[3]) | |
1115 | FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H4, desc_info->sec_seq[4]) | |
1116 | FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H5, desc_info->sec_seq[5]); |
1117 | |
1118 | return cpu_to_le32(dword); |
1119 | } |
1120 | |
1121 | static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info) |
1122 | { |
1123 | u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) | |
1124 | FIELD_PREP(RTW89_TXWD_BODY7_DATA_RATE, desc_info->data_rate); |
1125 | |
1126 | return cpu_to_le32(dword); |
1127 | } |
1128 | |
1129 | static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) |
1130 | { |
1131 | u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) | |
1132 | FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) | |
1133 | FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) | |
1134 | FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port); |
1135 | |
1136 | return cpu_to_le32(dword); |
1137 | } |
1138 | |
1139 | static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info) |
1140 | { |
1141 | u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) | |
1142 | FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port) | |
1143 | FIELD_PREP(RTW89_TXWD_INFO0_DATA_ER, desc_info->er_cap) | |
1144 | FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW_ER, 0); |
1145 | |
1146 | return cpu_to_le32(dword); |
1147 | } |
1148 | |
1149 | static __le32 rtw89_build_txwd_info1(struct rtw89_tx_desc_info *desc_info) |
1150 | { |
1151 | u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) | |
1152 | FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | |
1153 | FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE, |
1154 | desc_info->data_retry_lowest_rate); |
1155 | |
1156 | return cpu_to_le32(dword); |
1157 | } |
1158 | |
1159 | static __le32 rtw89_build_txwd_info2(struct rtw89_tx_desc_info *desc_info) |
1160 | { |
1161 | u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | |
1162 | FIELD_PREP(RTW89_TXWD_INFO2_SEC_TYPE, desc_info->sec_type) | |
1163 | FIELD_PREP(RTW89_TXWD_INFO2_SEC_HW_ENC, desc_info->sec_en) | |
1164 | FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); |
1165 | |
1166 | return cpu_to_le32(dword); |
1167 | } |
1168 | |
1169 | static __le32 rtw89_build_txwd_info2_v1(struct rtw89_tx_desc_info *desc_info) |
1170 | { |
1171 | u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | |
1172 | FIELD_PREP(RTW89_TXWD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | |
1173 | FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); |
1174 | |
1175 | return cpu_to_le32(dword); |
1176 | } |
1177 | |
1178 | static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) |
1179 | { |
1180 | bool rts_en = !desc_info->is_bmc; |
1181 | u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, rts_en) | |
1182 | FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1); |
1183 | |
1184 | return cpu_to_le32(dword); |
1185 | } |
1186 | |
1187 | void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, |
1188 | struct rtw89_tx_desc_info *desc_info, |
1189 | void *txdesc) |
1190 | { |
1191 | struct rtw89_txwd_body *txwd_body = (struct rtw89_txwd_body *)txdesc; |
1192 | struct rtw89_txwd_info *txwd_info; |
1193 | |
1194 | txwd_body->dword0 = rtw89_build_txwd_body0(desc_info); |
1195 | txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); |
1196 | txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); |
1197 | |
1198 | if (!desc_info->en_wd_info) |
1199 | return; |
1200 | |
1201 | txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); |
1202 | txwd_info->dword0 = rtw89_build_txwd_info0(desc_info); |
1203 | txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); |
1204 | txwd_info->dword2 = rtw89_build_txwd_info2(desc_info); |
1205 | txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); |
1206 | |
1207 | } |
1208 | EXPORT_SYMBOL(rtw89_core_fill_txdesc); |
1209 | |
1210 | void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, |
1211 | struct rtw89_tx_desc_info *desc_info, |
1212 | void *txdesc) |
1213 | { |
1214 | struct rtw89_txwd_body_v1 *txwd_body = (struct rtw89_txwd_body_v1 *)txdesc; |
1215 | struct rtw89_txwd_info *txwd_info; |
1216 | |
1217 | txwd_body->dword0 = rtw89_build_txwd_body0_v1(desc_info); |
1218 | txwd_body->dword1 = rtw89_build_txwd_body1_v1(desc_info); |
1219 | txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); |
1220 | txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); |
1221 | if (desc_info->sec_en) { |
1222 | txwd_body->dword4 = rtw89_build_txwd_body4(desc_info); |
1223 | txwd_body->dword5 = rtw89_build_txwd_body5(desc_info); |
1224 | } |
1225 | txwd_body->dword7 = rtw89_build_txwd_body7_v1(desc_info); |
1226 | |
1227 | if (!desc_info->en_wd_info) |
1228 | return; |
1229 | |
1230 | txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); |
1231 | txwd_info->dword0 = rtw89_build_txwd_info0_v1(desc_info); |
1232 | txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); |
1233 | txwd_info->dword2 = rtw89_build_txwd_info2_v1(desc_info); |
1234 | txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); |
1235 | } |
1236 | EXPORT_SYMBOL(rtw89_core_fill_txdesc_v1); |
1237 | |
1238 | static __le32 rtw89_build_txwd_body0_v2(struct rtw89_tx_desc_info *desc_info) |
1239 | { |
1240 | u32 dword = FIELD_PREP(BE_TXD_BODY0_WP_OFFSET_V1, desc_info->wp_offset) | |
1241 | FIELD_PREP(BE_TXD_BODY0_WDINFO_EN, desc_info->en_wd_info) | |
1242 | FIELD_PREP(BE_TXD_BODY0_CH_DMA, desc_info->ch_dma) | |
1243 | FIELD_PREP(BE_TXD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | |
1244 | FIELD_PREP(BE_TXD_BODY0_WD_PAGE, desc_info->wd_page); |
1245 | |
1246 | return cpu_to_le32(dword); |
1247 | } |
1248 | |
1249 | static __le32 rtw89_build_txwd_body1_v2(struct rtw89_tx_desc_info *desc_info) |
1250 | { |
1251 | u32 dword = FIELD_PREP(BE_TXD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | |
1252 | FIELD_PREP(BE_TXD_BODY1_SEC_KEYID, desc_info->sec_keyid) | |
1253 | FIELD_PREP(BE_TXD_BODY1_SEC_TYPE, desc_info->sec_type); |
1254 | |
1255 | return cpu_to_le32(dword); |
1256 | } |
1257 | |
1258 | static __le32 rtw89_build_txwd_body2_v2(struct rtw89_tx_desc_info *desc_info) |
1259 | { |
1260 | u32 dword = FIELD_PREP(BE_TXD_BODY2_TID_IND, desc_info->tid_indicate) | |
1261 | FIELD_PREP(BE_TXD_BODY2_QSEL, desc_info->qsel) | |
1262 | FIELD_PREP(BE_TXD_BODY2_TXPKTSIZE, desc_info->pkt_size) | |
1263 | FIELD_PREP(BE_TXD_BODY2_AGG_EN, desc_info->agg_en) | |
1264 | FIELD_PREP(BE_TXD_BODY2_BK, desc_info->bk) | |
1265 | FIELD_PREP(BE_TXD_BODY2_MACID, desc_info->mac_id); |
1266 | |
1267 | return cpu_to_le32(dword); |
1268 | } |
1269 | |
1270 | static __le32 rtw89_build_txwd_body3_v2(struct rtw89_tx_desc_info *desc_info) |
1271 | { |
1272 | u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq); |
1273 | |
1274 | return cpu_to_le32(dword); |
1275 | } |
1276 | |
1277 | static __le32 rtw89_build_txwd_body4_v2(struct rtw89_tx_desc_info *desc_info) |
1278 | { |
1279 | u32 dword = FIELD_PREP(BE_TXD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) | |
1280 | FIELD_PREP(BE_TXD_BODY4_SEC_IV_L1, desc_info->sec_seq[1]); |
1281 | |
1282 | return cpu_to_le32(dword); |
1283 | } |
1284 | |
1285 | static __le32 rtw89_build_txwd_body5_v2(struct rtw89_tx_desc_info *desc_info) |
1286 | { |
1287 | u32 dword = FIELD_PREP(BE_TXD_BODY5_SEC_IV_H2, desc_info->sec_seq[2]) | |
1288 | FIELD_PREP(BE_TXD_BODY5_SEC_IV_H3, desc_info->sec_seq[3]) | |
1289 | FIELD_PREP(BE_TXD_BODY5_SEC_IV_H4, desc_info->sec_seq[4]) | |
1290 | FIELD_PREP(BE_TXD_BODY5_SEC_IV_H5, desc_info->sec_seq[5]); |
1291 | |
1292 | return cpu_to_le32(dword); |
1293 | } |
1294 | |
1295 | static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info) |
1296 | { |
1297 | u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) | |
1298 | FIELD_PREP(BE_TXD_BODY7_DATA_ER, desc_info->er_cap) | |
1299 | FIELD_PREP(BE_TXD_BODY7_DATA_BW_ER, 0) | |
1300 | FIELD_PREP(BE_TXD_BODY7_DATARATE, desc_info->data_rate); |
1301 | |
1302 | return cpu_to_le32(dword); |
1303 | } |
1304 | |
1305 | static __le32 rtw89_build_txwd_info0_v2(struct rtw89_tx_desc_info *desc_info) |
1306 | { |
1307 | u32 dword = FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) | |
1308 | FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port); |
1309 | |
1310 | return cpu_to_le32(dword); |
1311 | } |
1312 | |
1313 | static __le32 rtw89_build_txwd_info1_v2(struct rtw89_tx_desc_info *desc_info) |
1314 | { |
1315 | u32 dword = FIELD_PREP(BE_TXD_INFO1_MAX_AGG_NUM, desc_info->ampdu_num) | |
1316 | FIELD_PREP(BE_TXD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | |
1317 | FIELD_PREP(BE_TXD_INFO1_DATA_RTY_LOWEST_RATE, |
1318 | desc_info->data_retry_lowest_rate); |
1319 | |
1320 | return cpu_to_le32(dword); |
1321 | } |
1322 | |
1323 | static __le32 rtw89_build_txwd_info2_v2(struct rtw89_tx_desc_info *desc_info) |
1324 | { |
1325 | u32 dword = FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | |
1326 | FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | |
1327 | FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); |
1328 | |
1329 | return cpu_to_le32(dword); |
1330 | } |
1331 | |
1332 | static __le32 rtw89_build_txwd_info4_v2(struct rtw89_tx_desc_info *desc_info) |
1333 | { |
1334 | bool rts_en = !desc_info->is_bmc; |
1335 | u32 dword = FIELD_PREP(BE_TXD_INFO4_RTS_EN, rts_en) | |
1336 | FIELD_PREP(BE_TXD_INFO4_HW_RTS_EN, 1); |
1337 | |
1338 | return cpu_to_le32(dword); |
1339 | } |
1340 | |
1341 | void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev, |
1342 | struct rtw89_tx_desc_info *desc_info, |
1343 | void *txdesc) |
1344 | { |
1345 | struct rtw89_txwd_body_v2 *txwd_body = txdesc; |
1346 | struct rtw89_txwd_info_v2 *txwd_info; |
1347 | |
1348 | txwd_body->dword0 = rtw89_build_txwd_body0_v2(desc_info); |
1349 | txwd_body->dword1 = rtw89_build_txwd_body1_v2(desc_info); |
1350 | txwd_body->dword2 = rtw89_build_txwd_body2_v2(desc_info); |
1351 | txwd_body->dword3 = rtw89_build_txwd_body3_v2(desc_info); |
1352 | if (desc_info->sec_en) { |
1353 | txwd_body->dword4 = rtw89_build_txwd_body4_v2(desc_info); |
1354 | txwd_body->dword5 = rtw89_build_txwd_body5_v2(desc_info); |
1355 | } |
1356 | txwd_body->dword7 = rtw89_build_txwd_body7_v2(desc_info); |
1357 | |
1358 | if (!desc_info->en_wd_info) |
1359 | return; |
1360 | |
1361 | txwd_info = (struct rtw89_txwd_info_v2 *)(txwd_body + 1); |
1362 | txwd_info->dword0 = rtw89_build_txwd_info0_v2(desc_info); |
1363 | txwd_info->dword1 = rtw89_build_txwd_info1_v2(desc_info); |
1364 | txwd_info->dword2 = rtw89_build_txwd_info2_v2(desc_info); |
1365 | txwd_info->dword4 = rtw89_build_txwd_info4_v2(desc_info); |
1366 | } |
1367 | EXPORT_SYMBOL(rtw89_core_fill_txdesc_v2); |
1368 | |
1369 | static __le32 rtw89_build_txwd_fwcmd0_v1(struct rtw89_tx_desc_info *desc_info) |
1370 | { |
1371 | u32 dword = FIELD_PREP(AX_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | |
1372 | FIELD_PREP(AX_RXD_RPKT_TYPE_MASK, desc_info->fw_dl ? |
1373 | RTW89_CORE_RX_TYPE_FWDL : |
1374 | RTW89_CORE_RX_TYPE_H2C); |
1375 | |
1376 | return cpu_to_le32(dword); |
1377 | } |
1378 | |
1379 | void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, |
1380 | struct rtw89_tx_desc_info *desc_info, |
1381 | void *txdesc) |
1382 | { |
1383 | struct rtw89_rxdesc_short *txwd_v1 = (struct rtw89_rxdesc_short *)txdesc; |
1384 | |
1385 | txwd_v1->dword0 = rtw89_build_txwd_fwcmd0_v1(desc_info); |
1386 | } |
1387 | EXPORT_SYMBOL(rtw89_core_fill_txdesc_fwcmd_v1); |
1388 | |
1389 | static __le32 rtw89_build_txwd_fwcmd0_v2(struct rtw89_tx_desc_info *desc_info) |
1390 | { |
1391 | u32 dword = FIELD_PREP(BE_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | |
1392 | FIELD_PREP(BE_RXD_RPKT_TYPE_MASK, desc_info->fw_dl ? |
1393 | RTW89_CORE_RX_TYPE_FWDL : |
1394 | RTW89_CORE_RX_TYPE_H2C); |
1395 | |
1396 | return cpu_to_le32(dword); |
1397 | } |
1398 | |
1399 | void rtw89_core_fill_txdesc_fwcmd_v2(struct rtw89_dev *rtwdev, |
1400 | struct rtw89_tx_desc_info *desc_info, |
1401 | void *txdesc) |
1402 | { |
1403 | struct rtw89_rxdesc_short_v2 *txwd_v2 = (struct rtw89_rxdesc_short_v2 *)txdesc; |
1404 | |
1405 | txwd_v2->dword0 = rtw89_build_txwd_fwcmd0_v2(desc_info); |
1406 | } |
1407 | EXPORT_SYMBOL(rtw89_core_fill_txdesc_fwcmd_v2); |
1408 | |
1409 | static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev, |
1410 | struct sk_buff *skb, |
1411 | struct rtw89_rx_phy_ppdu *phy_ppdu) |
1412 | { |
1413 | const struct rtw89_chip_info *chip = rtwdev->chip; |
1414 | const struct rtw89_rxinfo *rxinfo = (const struct rtw89_rxinfo *)skb->data; |
1415 | const struct rtw89_rxinfo_user *user; |
1416 | enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; |
1417 | int rx_cnt_size = RTW89_PPDU_MAC_RX_CNT_SIZE; |
1418 | bool rx_cnt_valid = false; |
1419 | bool invalid = false; |
1420 | u8 plcp_size = 0; |
1421 | u8 *phy_sts; |
1422 | u8 usr_num; |
1423 | int i; |
1424 | |
1425 | if (chip_gen == RTW89_CHIP_BE) { |
1426 | invalid = le32_get_bits(v: rxinfo->w0, RTW89_RXINFO_W0_INVALID_V1); |
1427 | rx_cnt_size = RTW89_PPDU_MAC_RX_CNT_SIZE_V1; |
1428 | } |
1429 | |
1430 | if (invalid) |
1431 | return -EINVAL; |
1432 | |
1433 | rx_cnt_valid = le32_get_bits(v: rxinfo->w0, RTW89_RXINFO_W0_RX_CNT_VLD); |
1434 | if (chip_gen == RTW89_CHIP_BE) { |
1435 | plcp_size = le32_get_bits(v: rxinfo->w0, RTW89_RXINFO_W0_PLCP_LEN_V1) << 3; |
1436 | usr_num = le32_get_bits(v: rxinfo->w0, RTW89_RXINFO_W0_USR_NUM_V1); |
1437 | } else { |
1438 | plcp_size = le32_get_bits(v: rxinfo->w1, RTW89_RXINFO_W1_PLCP_LEN) << 3; |
1439 | usr_num = le32_get_bits(v: rxinfo->w0, RTW89_RXINFO_W0_USR_NUM); |
1440 | } |
1441 | if (usr_num > chip->ppdu_max_usr) { |
1442 | rtw89_warn(rtwdev, "Invalid user number (%d) in mac info\n" , |
1443 | usr_num); |
1444 | return -EINVAL; |
1445 | } |
1446 | |
1447 | /* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set by hardware, |
1448 | * so update mac_id by rxinfo_user[].mac_id. |
1449 | */ |
1450 | for (i = 0; i < usr_num && chip_gen == RTW89_CHIP_BE; i++) { |
1451 | user = &rxinfo->user[i]; |
1452 | if (!le32_get_bits(v: user->w0, RTW89_RXINFO_USER_MAC_ID_VALID)) |
1453 | continue; |
1454 | |
1455 | phy_ppdu->mac_id = |
1456 | le32_get_bits(v: user->w0, RTW89_RXINFO_USER_MACID); |
1457 | break; |
1458 | } |
1459 | |
1460 | phy_sts = skb->data + RTW89_PPDU_MAC_INFO_SIZE; |
1461 | phy_sts += usr_num * RTW89_PPDU_MAC_INFO_USR_SIZE; |
1462 | /* 8-byte alignment */ |
1463 | if (usr_num & BIT(0)) |
1464 | phy_sts += RTW89_PPDU_MAC_INFO_USR_SIZE; |
1465 | if (rx_cnt_valid) |
1466 | phy_sts += rx_cnt_size; |
1467 | phy_sts += plcp_size; |
1468 | |
1469 | if (phy_sts > skb->data + skb->len) |
1470 | return -EINVAL; |
1471 | |
1472 | phy_ppdu->buf = phy_sts; |
1473 | phy_ppdu->len = skb->data + skb->len - phy_sts; |
1474 | |
1475 | return 0; |
1476 | } |
1477 | |
1478 | static void rtw89_core_rx_process_phy_ppdu_iter(void *data, |
1479 | struct ieee80211_sta *sta) |
1480 | { |
1481 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
1482 | struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; |
1483 | struct rtw89_dev *rtwdev = rtwsta->rtwdev; |
1484 | struct rtw89_hal *hal = &rtwdev->hal; |
1485 | u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; |
1486 | u8 ant_pos = U8_MAX; |
1487 | u8 evm_pos = 0; |
1488 | int i; |
1489 | |
1490 | if (rtwsta->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self) |
1491 | return; |
1492 | |
1493 | if (hal->ant_diversity && hal->antenna_rx) { |
1494 | ant_pos = __ffs(hal->antenna_rx); |
1495 | evm_pos = ant_pos; |
1496 | } |
1497 | |
1498 | ewma_rssi_add(e: &rtwsta->avg_rssi, val: phy_ppdu->rssi_avg); |
1499 | |
1500 | if (ant_pos < ant_num) { |
1501 | ewma_rssi_add(e: &rtwsta->rssi[ant_pos], val: phy_ppdu->rssi[0]); |
1502 | } else { |
1503 | for (i = 0; i < rtwdev->chip->rf_path_num; i++) |
1504 | ewma_rssi_add(e: &rtwsta->rssi[i], val: phy_ppdu->rssi[i]); |
1505 | } |
1506 | |
1507 | if (phy_ppdu->ofdm.has) { |
1508 | ewma_snr_add(e: &rtwsta->avg_snr, val: phy_ppdu->ofdm.avg_snr); |
1509 | ewma_evm_add(e: &rtwsta->evm_min[evm_pos], val: phy_ppdu->ofdm.evm_min); |
1510 | ewma_evm_add(e: &rtwsta->evm_max[evm_pos], val: phy_ppdu->ofdm.evm_max); |
1511 | } |
1512 | } |
1513 | |
1514 | #define VAR_LEN 0xff |
1515 | #define VAR_LEN_UNIT 8 |
1516 | static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev, |
1517 | const struct rtw89_phy_sts_iehdr *iehdr) |
1518 | { |
1519 | static const u8 physts_ie_len_tabs[RTW89_CHIP_GEN_NUM][32] = { |
1520 | [RTW89_CHIP_AX] = { |
1521 | 16, 32, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, |
1522 | VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN, |
1523 | VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32 |
1524 | }, |
1525 | [RTW89_CHIP_BE] = { |
1526 | 32, 40, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, |
1527 | VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN, |
1528 | VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32 |
1529 | }, |
1530 | }; |
1531 | const u8 *physts_ie_len_tab; |
1532 | u16 ie_len; |
1533 | u8 ie; |
1534 | |
1535 | physts_ie_len_tab = physts_ie_len_tabs[rtwdev->chip->chip_gen]; |
1536 | |
1537 | ie = le32_get_bits(v: iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE); |
1538 | if (physts_ie_len_tab[ie] != VAR_LEN) |
1539 | ie_len = physts_ie_len_tab[ie]; |
1540 | else |
1541 | ie_len = le32_get_bits(v: iehdr->w0, RTW89_PHY_STS_IEHDR_LEN) * VAR_LEN_UNIT; |
1542 | |
1543 | return ie_len; |
1544 | } |
1545 | |
1546 | static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, |
1547 | const struct rtw89_phy_sts_iehdr *iehdr, |
1548 | struct rtw89_rx_phy_ppdu *phy_ppdu) |
1549 | { |
1550 | const struct rtw89_phy_sts_ie0 *ie = (const struct rtw89_phy_sts_ie0 *)iehdr; |
1551 | s16 cfo; |
1552 | u32 t; |
1553 | |
1554 | phy_ppdu->chan_idx = le32_get_bits(v: ie->w0, RTW89_PHY_STS_IE01_W0_CH_IDX); |
1555 | if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) |
1556 | return; |
1557 | |
1558 | if (!phy_ppdu->to_self) |
1559 | return; |
1560 | |
1561 | phy_ppdu->ofdm.avg_snr = le32_get_bits(v: ie->w2, RTW89_PHY_STS_IE01_W2_AVG_SNR); |
1562 | phy_ppdu->ofdm.evm_max = le32_get_bits(v: ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MAX); |
1563 | phy_ppdu->ofdm.evm_min = le32_get_bits(v: ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MIN); |
1564 | phy_ppdu->ofdm.has = true; |
1565 | |
1566 | /* sign conversion for S(12,2) */ |
1567 | if (rtwdev->chip->cfo_src_fd) { |
1568 | t = le32_get_bits(v: ie->w1, RTW89_PHY_STS_IE01_W1_FD_CFO); |
1569 | cfo = sign_extend32(value: t, index: 11); |
1570 | } else { |
1571 | t = le32_get_bits(v: ie->w1, RTW89_PHY_STS_IE01_W1_PREMB_CFO); |
1572 | cfo = sign_extend32(value: t, index: 11); |
1573 | } |
1574 | |
1575 | rtw89_phy_cfo_parse(rtwdev, cfo_val: cfo, phy_ppdu); |
1576 | } |
1577 | |
1578 | static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev, |
1579 | const struct rtw89_phy_sts_iehdr *iehdr, |
1580 | struct rtw89_rx_phy_ppdu *phy_ppdu) |
1581 | { |
1582 | u8 ie; |
1583 | |
1584 | ie = le32_get_bits(v: iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE); |
1585 | |
1586 | switch (ie) { |
1587 | case RTW89_PHYSTS_IE01_CMN_OFDM: |
1588 | rtw89_core_parse_phy_status_ie01(rtwdev, iehdr, phy_ppdu); |
1589 | break; |
1590 | default: |
1591 | break; |
1592 | } |
1593 | |
1594 | return 0; |
1595 | } |
1596 | |
1597 | static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu) |
1598 | { |
1599 | const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf; |
1600 | u8 * = phy_ppdu->rssi; |
1601 | |
1602 | phy_ppdu->ie = le32_get_bits(v: hdr->w0, RTW89_PHY_STS_HDR_W0_IE_MAP); |
1603 | phy_ppdu->rssi_avg = le32_get_bits(v: hdr->w0, RTW89_PHY_STS_HDR_W0_RSSI_AVG); |
1604 | rssi[RF_PATH_A] = le32_get_bits(v: hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_A); |
1605 | rssi[RF_PATH_B] = le32_get_bits(v: hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_B); |
1606 | rssi[RF_PATH_C] = le32_get_bits(v: hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_C); |
1607 | rssi[RF_PATH_D] = le32_get_bits(v: hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_D); |
1608 | } |
1609 | |
1610 | static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev, |
1611 | struct rtw89_rx_phy_ppdu *phy_ppdu) |
1612 | { |
1613 | const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf; |
1614 | u32 ; |
1615 | bool physts_valid; |
1616 | |
1617 | physts_valid = le32_get_bits(v: hdr->w0, RTW89_PHY_STS_HDR_W0_VALID); |
1618 | if (!physts_valid) |
1619 | return -EINVAL; |
1620 | |
1621 | len_from_header = le32_get_bits(v: hdr->w0, RTW89_PHY_STS_HDR_W0_LEN) << 3; |
1622 | |
1623 | if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) |
1624 | len_from_header += PHY_STS_HDR_LEN; |
1625 | |
1626 | if (len_from_header != phy_ppdu->len) { |
1627 | rtw89_debug(rtwdev, mask: RTW89_DBG_UNEXP, fmt: "phy ppdu len mismatch\n" ); |
1628 | return -EINVAL; |
1629 | } |
1630 | rtw89_core_update_phy_ppdu(phy_ppdu); |
1631 | |
1632 | return 0; |
1633 | } |
1634 | |
1635 | static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev, |
1636 | struct rtw89_rx_phy_ppdu *phy_ppdu) |
1637 | { |
1638 | u16 ie_len; |
1639 | void *pos, *end; |
1640 | |
1641 | /* mark invalid reports and bypass them */ |
1642 | if (phy_ppdu->ie < RTW89_CCK_PKT) |
1643 | return -EINVAL; |
1644 | |
1645 | pos = phy_ppdu->buf + PHY_STS_HDR_LEN; |
1646 | end = phy_ppdu->buf + phy_ppdu->len; |
1647 | while (pos < end) { |
1648 | const struct rtw89_phy_sts_iehdr *iehdr = pos; |
1649 | |
1650 | ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, iehdr); |
1651 | rtw89_core_process_phy_status_ie(rtwdev, iehdr, phy_ppdu); |
1652 | pos += ie_len; |
1653 | if (pos > end || ie_len == 0) { |
1654 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
1655 | fmt: "phy status parse failed\n" ); |
1656 | return -EINVAL; |
1657 | } |
1658 | } |
1659 | |
1660 | rtw89_phy_antdiv_parse(rtwdev, phy_ppdu); |
1661 | |
1662 | return 0; |
1663 | } |
1664 | |
1665 | static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev, |
1666 | struct rtw89_rx_phy_ppdu *phy_ppdu) |
1667 | { |
1668 | int ret; |
1669 | |
1670 | ret = rtw89_core_rx_parse_phy_sts(rtwdev, phy_ppdu); |
1671 | if (ret) |
1672 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, fmt: "parse phy sts failed\n" ); |
1673 | else |
1674 | phy_ppdu->valid = true; |
1675 | |
1676 | ieee80211_iterate_stations_atomic(hw: rtwdev->hw, |
1677 | iterator: rtw89_core_rx_process_phy_ppdu_iter, |
1678 | data: phy_ppdu); |
1679 | } |
1680 | |
1681 | static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev, |
1682 | u8 desc_info_gi, |
1683 | bool rx_status, bool eht) |
1684 | { |
1685 | switch (desc_info_gi) { |
1686 | case RTW89_GILTF_SGI_4XHE08: |
1687 | case RTW89_GILTF_2XHE08: |
1688 | case RTW89_GILTF_1XHE08: |
1689 | return eht ? NL80211_RATE_INFO_EHT_GI_0_8 : |
1690 | NL80211_RATE_INFO_HE_GI_0_8; |
1691 | case RTW89_GILTF_2XHE16: |
1692 | case RTW89_GILTF_1XHE16: |
1693 | return eht ? NL80211_RATE_INFO_EHT_GI_1_6 : |
1694 | NL80211_RATE_INFO_HE_GI_1_6; |
1695 | case RTW89_GILTF_LGI_4XHE32: |
1696 | return eht ? NL80211_RATE_INFO_EHT_GI_3_2 : |
1697 | NL80211_RATE_INFO_HE_GI_3_2; |
1698 | default: |
1699 | rtw89_warn(rtwdev, "invalid gi_ltf=%d" , desc_info_gi); |
1700 | if (rx_status) |
1701 | return eht ? NL80211_RATE_INFO_EHT_GI_3_2 : |
1702 | NL80211_RATE_INFO_HE_GI_3_2; |
1703 | return U8_MAX; |
1704 | } |
1705 | } |
1706 | |
1707 | static |
1708 | bool rtw89_check_rx_statu_gi_match(struct ieee80211_rx_status *status, u8 gi_ltf, |
1709 | bool eht) |
1710 | { |
1711 | if (eht) |
1712 | return status->eht.gi == gi_ltf; |
1713 | |
1714 | return status->he_gi == gi_ltf; |
1715 | } |
1716 | |
1717 | static bool rtw89_core_rx_ppdu_match(struct rtw89_dev *rtwdev, |
1718 | struct rtw89_rx_desc_info *desc_info, |
1719 | struct ieee80211_rx_status *status) |
1720 | { |
1721 | u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
1722 | u8 data_rate_mode, bw, rate_idx = MASKBYTE0, gi_ltf; |
1723 | bool eht = false; |
1724 | u16 data_rate; |
1725 | bool ret; |
1726 | |
1727 | data_rate = desc_info->data_rate; |
1728 | data_rate_mode = rtw89_get_data_rate_mode(rtwdev, hw_rate: data_rate); |
1729 | if (data_rate_mode == DATA_RATE_MODE_NON_HT) { |
1730 | rate_idx = rtw89_get_data_not_ht_idx(rtwdev, hw_rate: data_rate); |
1731 | /* rate_idx is still hardware value here */ |
1732 | } else if (data_rate_mode == DATA_RATE_MODE_HT) { |
1733 | rate_idx = rtw89_get_data_ht_mcs(rtwdev, hw_rate: data_rate); |
1734 | } else if (data_rate_mode == DATA_RATE_MODE_VHT || |
1735 | data_rate_mode == DATA_RATE_MODE_HE || |
1736 | data_rate_mode == DATA_RATE_MODE_EHT) { |
1737 | rate_idx = rtw89_get_data_mcs(rtwdev, hw_rate: data_rate); |
1738 | } else { |
1739 | rtw89_warn(rtwdev, "invalid RX rate mode %d\n" , data_rate_mode); |
1740 | } |
1741 | |
1742 | eht = data_rate_mode == DATA_RATE_MODE_EHT; |
1743 | bw = rtw89_hw_to_rate_info_bw(hw_bw: desc_info->bw); |
1744 | gi_ltf = rtw89_rxdesc_to_nl_he_eht_gi(rtwdev, desc_info_gi: desc_info->gi_ltf, rx_status: false, eht); |
1745 | ret = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band] == desc_info->ppdu_cnt && |
1746 | status->rate_idx == rate_idx && |
1747 | rtw89_check_rx_statu_gi_match(status, gi_ltf, eht) && |
1748 | status->bw == bw; |
1749 | |
1750 | return ret; |
1751 | } |
1752 | |
1753 | struct rtw89_vif_rx_stats_iter_data { |
1754 | struct rtw89_dev *rtwdev; |
1755 | struct rtw89_rx_phy_ppdu *phy_ppdu; |
1756 | struct rtw89_rx_desc_info *desc_info; |
1757 | struct sk_buff *skb; |
1758 | const u8 *bssid; |
1759 | }; |
1760 | |
1761 | static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, |
1762 | struct ieee80211_vif *vif, |
1763 | struct sk_buff *skb) |
1764 | { |
1765 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1766 | struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data; |
1767 | u8 *pos, *end, type, tf_bw; |
1768 | u16 aid, tf_rua; |
1769 | |
1770 | if (!ether_addr_equal(addr1: vif->bss_conf.bssid, addr2: tf->ta) || |
1771 | rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION || |
1772 | rtwvif->net_type == RTW89_NET_TYPE_NO_LINK) |
1773 | return; |
1774 | |
1775 | type = le64_get_bits(v: tf->common_info, IEEE80211_TRIGGER_TYPE_MASK); |
1776 | if (type != IEEE80211_TRIGGER_TYPE_BASIC && type != IEEE80211_TRIGGER_TYPE_MU_BAR) |
1777 | return; |
1778 | |
1779 | end = (u8 *)tf + skb->len; |
1780 | pos = tf->variable; |
1781 | |
1782 | while (end - pos >= RTW89_TF_BASIC_USER_INFO_SZ) { |
1783 | aid = RTW89_GET_TF_USER_INFO_AID12(pos); |
1784 | tf_rua = RTW89_GET_TF_USER_INFO_RUA(pos); |
1785 | tf_bw = le64_get_bits(v: tf->common_info, IEEE80211_TRIGGER_ULBW_MASK); |
1786 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
1787 | fmt: "[TF] aid: %d, ul_mcs: %d, rua: %d, bw: %d\n" , |
1788 | aid, RTW89_GET_TF_USER_INFO_UL_MCS(pos), |
1789 | tf_rua, tf_bw); |
1790 | |
1791 | if (aid == RTW89_TF_PAD) |
1792 | break; |
1793 | |
1794 | if (aid == vif->cfg.aid) { |
1795 | enum nl80211_he_ru_alloc rua = rtw89_he_rua_to_ru_alloc(rua: tf_rua >> 1); |
1796 | |
1797 | rtwvif->stats.rx_tf_acc++; |
1798 | rtwdev->stats.rx_tf_acc++; |
1799 | if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ && |
1800 | rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106) |
1801 | rtwvif->pwr_diff_en = true; |
1802 | break; |
1803 | } |
1804 | |
1805 | pos += RTW89_TF_BASIC_USER_INFO_SZ; |
1806 | } |
1807 | } |
1808 | |
1809 | static void rtw89_cancel_6ghz_probe_work(struct work_struct *work) |
1810 | { |
1811 | struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, |
1812 | cancel_6ghz_probe_work); |
1813 | struct list_head *pkt_list = rtwdev->scan_info.pkt_list; |
1814 | struct rtw89_pktofld_info *info; |
1815 | |
1816 | mutex_lock(&rtwdev->mutex); |
1817 | |
1818 | if (!rtwdev->scanning) |
1819 | goto out; |
1820 | |
1821 | list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { |
1822 | if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload)) |
1823 | continue; |
1824 | |
1825 | rtw89_fw_h2c_del_pkt_offload(rtwdev, id: info->id); |
1826 | |
1827 | /* Don't delete/free info from pkt_list at this moment. Let it |
1828 | * be deleted/freed in rtw89_release_pkt_list() after scanning, |
1829 | * since if during scanning, pkt_list is accessed in bottom half. |
1830 | */ |
1831 | } |
1832 | |
1833 | out: |
1834 | mutex_unlock(lock: &rtwdev->mutex); |
1835 | } |
1836 | |
1837 | static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, |
1838 | struct sk_buff *skb) |
1839 | { |
1840 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); |
1841 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1842 | struct list_head *pkt_list = rtwdev->scan_info.pkt_list; |
1843 | struct rtw89_pktofld_info *info; |
1844 | const u8 *ies = mgmt->u.beacon.variable, *ssid_ie; |
1845 | bool queue_work = false; |
1846 | |
1847 | if (rx_status->band != NL80211_BAND_6GHZ) |
1848 | return; |
1849 | |
1850 | ssid_ie = cfg80211_find_ie(eid: WLAN_EID_SSID, ies, len: skb->len); |
1851 | |
1852 | list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { |
1853 | if (ether_addr_equal(addr1: info->bssid, addr2: mgmt->bssid)) { |
1854 | info->cancel = true; |
1855 | queue_work = true; |
1856 | continue; |
1857 | } |
1858 | |
1859 | if (!ssid_ie || ssid_ie[1] != info->ssid_len || info->ssid_len == 0) |
1860 | continue; |
1861 | |
1862 | if (memcmp(p: &ssid_ie[2], q: info->ssid, size: info->ssid_len) == 0) { |
1863 | info->cancel = true; |
1864 | queue_work = true; |
1865 | } |
1866 | } |
1867 | |
1868 | if (queue_work) |
1869 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->cancel_6ghz_probe_work); |
1870 | } |
1871 | |
1872 | static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif, |
1873 | struct ieee80211_hdr *hdr, size_t len) |
1874 | { |
1875 | struct ieee80211_mgmt *mgmt = (typeof(mgmt))hdr; |
1876 | |
1877 | if (len < offsetof(typeof(*mgmt), u.beacon.variable)) |
1878 | return; |
1879 | |
1880 | WRITE_ONCE(rtwvif->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp)); |
1881 | } |
1882 | |
1883 | static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, |
1884 | struct ieee80211_vif *vif) |
1885 | { |
1886 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
1887 | struct rtw89_vif_rx_stats_iter_data *iter_data = data; |
1888 | struct rtw89_dev *rtwdev = iter_data->rtwdev; |
1889 | struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; |
1890 | struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; |
1891 | struct sk_buff *skb = iter_data->skb; |
1892 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1893 | struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu; |
1894 | const u8 *bssid = iter_data->bssid; |
1895 | |
1896 | if (rtwdev->scanning && |
1897 | (ieee80211_is_beacon(fc: hdr->frame_control) || |
1898 | ieee80211_is_probe_resp(fc: hdr->frame_control))) |
1899 | rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb); |
1900 | |
1901 | if (!vif->bss_conf.bssid) |
1902 | return; |
1903 | |
1904 | if (ieee80211_is_trigger(fc: hdr->frame_control)) { |
1905 | rtw89_stats_trigger_frame(rtwdev, vif, skb); |
1906 | return; |
1907 | } |
1908 | |
1909 | if (!ether_addr_equal(addr1: vif->bss_conf.bssid, addr2: bssid)) |
1910 | return; |
1911 | |
1912 | if (ieee80211_is_beacon(fc: hdr->frame_control)) { |
1913 | if (vif->type == NL80211_IFTYPE_STATION) { |
1914 | rtw89_vif_sync_bcn_tsf(rtwvif, hdr, len: skb->len); |
1915 | rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu); |
1916 | } |
1917 | pkt_stat->beacon_nr++; |
1918 | } |
1919 | |
1920 | if (!ether_addr_equal(addr1: vif->addr, addr2: hdr->addr1)) |
1921 | return; |
1922 | |
1923 | if (desc_info->data_rate < RTW89_HW_RATE_NR) |
1924 | pkt_stat->rx_rate_cnt[desc_info->data_rate]++; |
1925 | |
1926 | rtw89_traffic_stats_accu(rtwdev, stats: &rtwvif->stats, skb, tx: false); |
1927 | } |
1928 | |
1929 | static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev, |
1930 | struct rtw89_rx_phy_ppdu *phy_ppdu, |
1931 | struct rtw89_rx_desc_info *desc_info, |
1932 | struct sk_buff *skb) |
1933 | { |
1934 | struct rtw89_vif_rx_stats_iter_data iter_data; |
1935 | |
1936 | rtw89_traffic_stats_accu(rtwdev, stats: &rtwdev->stats, skb, tx: false); |
1937 | |
1938 | iter_data.rtwdev = rtwdev; |
1939 | iter_data.phy_ppdu = phy_ppdu; |
1940 | iter_data.desc_info = desc_info; |
1941 | iter_data.skb = skb; |
1942 | iter_data.bssid = get_hdr_bssid(hdr: (struct ieee80211_hdr *)skb->data); |
1943 | rtw89_iterate_vifs_bh(rtwdev, rtw89_vif_rx_stats_iter, &iter_data); |
1944 | } |
1945 | |
1946 | static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev, |
1947 | struct ieee80211_rx_status *status) |
1948 | { |
1949 | const struct rtw89_chan_rcd *rcd = |
1950 | rtw89_chan_rcd_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
1951 | u16 chan = rcd->prev_primary_channel; |
1952 | u8 band = rtw89_hw_to_nl80211_band(hw_band: rcd->prev_band_type); |
1953 | |
1954 | if (status->band != NL80211_BAND_2GHZ && |
1955 | status->encoding == RX_ENC_LEGACY && |
1956 | status->rate_idx < RTW89_HW_RATE_OFDM6) { |
1957 | status->freq = ieee80211_channel_to_frequency(chan, band); |
1958 | status->band = band; |
1959 | } |
1960 | } |
1961 | |
1962 | static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status) |
1963 | { |
1964 | if (rx_status->band == NL80211_BAND_2GHZ || |
1965 | rx_status->encoding != RX_ENC_LEGACY) |
1966 | return; |
1967 | |
1968 | /* Some control frames' freq(ACKs in this case) are reported wrong due |
1969 | * to FW notify timing, set to lowest rate to prevent overflow. |
1970 | */ |
1971 | if (rx_status->rate_idx < RTW89_HW_RATE_OFDM6) { |
1972 | rx_status->rate_idx = 0; |
1973 | return; |
1974 | } |
1975 | |
1976 | /* No 4 CCK rates for non-2G */ |
1977 | rx_status->rate_idx -= 4; |
1978 | } |
1979 | |
1980 | static const u8 rx_status_bw_to_radiotap_eht_usig[] = { |
1981 | [RATE_INFO_BW_20] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_20MHZ, |
1982 | [RATE_INFO_BW_5] = U8_MAX, |
1983 | [RATE_INFO_BW_10] = U8_MAX, |
1984 | [RATE_INFO_BW_40] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_40MHZ, |
1985 | [RATE_INFO_BW_80] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_80MHZ, |
1986 | [RATE_INFO_BW_160] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_160MHZ, |
1987 | [RATE_INFO_BW_HE_RU] = U8_MAX, |
1988 | [RATE_INFO_BW_320] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_320MHZ_1, |
1989 | [RATE_INFO_BW_EHT_RU] = U8_MAX, |
1990 | }; |
1991 | |
1992 | static void rtw89_core_update_radiotap_eht(struct rtw89_dev *rtwdev, |
1993 | struct sk_buff *skb, |
1994 | struct ieee80211_rx_status *rx_status) |
1995 | { |
1996 | struct ieee80211_radiotap_eht_usig *usig; |
1997 | struct ieee80211_radiotap_eht *eht; |
1998 | struct ieee80211_radiotap_tlv *tlv; |
1999 | int eht_len = struct_size(eht, user_info, 1); |
2000 | int usig_len = sizeof(*usig); |
2001 | int len; |
2002 | u8 bw; |
2003 | |
2004 | len = sizeof(*tlv) + ALIGN(eht_len, 4) + |
2005 | sizeof(*tlv) + ALIGN(usig_len, 4); |
2006 | |
2007 | rx_status->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; |
2008 | skb_reset_mac_header(skb); |
2009 | |
2010 | /* EHT */ |
2011 | tlv = skb_push(skb, len); |
2012 | memset(tlv, 0, len); |
2013 | tlv->type = cpu_to_le16(IEEE80211_RADIOTAP_EHT); |
2014 | tlv->len = cpu_to_le16(eht_len); |
2015 | |
2016 | eht = (struct ieee80211_radiotap_eht *)tlv->data; |
2017 | eht->known = cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_GI); |
2018 | eht->data[0] = |
2019 | le32_encode_bits(v: rx_status->eht.gi, field: IEEE80211_RADIOTAP_EHT_DATA0_GI); |
2020 | |
2021 | eht->user_info[0] = |
2022 | cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | |
2023 | IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O); |
2024 | eht->user_info[0] |= |
2025 | le32_encode_bits(v: rx_status->rate_idx, field: IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | |
2026 | le32_encode_bits(v: rx_status->nss, field: IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O); |
2027 | |
2028 | /* U-SIG */ |
2029 | tlv = (void *)tlv + sizeof(*tlv) + ALIGN(eht_len, 4); |
2030 | tlv->type = cpu_to_le16(IEEE80211_RADIOTAP_EHT_USIG); |
2031 | tlv->len = cpu_to_le16(usig_len); |
2032 | |
2033 | if (rx_status->bw >= ARRAY_SIZE(rx_status_bw_to_radiotap_eht_usig)) |
2034 | return; |
2035 | |
2036 | bw = rx_status_bw_to_radiotap_eht_usig[rx_status->bw]; |
2037 | if (bw == U8_MAX) |
2038 | return; |
2039 | |
2040 | usig = (struct ieee80211_radiotap_eht_usig *)tlv->data; |
2041 | usig->common = |
2042 | le32_encode_bits(v: 1, field: IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN) | |
2043 | le32_encode_bits(v: bw, field: IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW); |
2044 | } |
2045 | |
2046 | static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev, |
2047 | struct sk_buff *skb, |
2048 | struct ieee80211_rx_status *rx_status) |
2049 | { |
2050 | static const struct ieee80211_radiotap_he known_he = { |
2051 | .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | |
2052 | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), |
2053 | .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), |
2054 | }; |
2055 | struct ieee80211_radiotap_he *he; |
2056 | |
2057 | if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)) |
2058 | return; |
2059 | |
2060 | if (rx_status->encoding == RX_ENC_HE) { |
2061 | rx_status->flag |= RX_FLAG_RADIOTAP_HE; |
2062 | he = skb_push(skb, len: sizeof(*he)); |
2063 | *he = known_he; |
2064 | } else if (rx_status->encoding == RX_ENC_EHT) { |
2065 | rtw89_core_update_radiotap_eht(rtwdev, skb, rx_status); |
2066 | } |
2067 | } |
2068 | |
2069 | static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev, |
2070 | struct rtw89_rx_phy_ppdu *phy_ppdu, |
2071 | struct rtw89_rx_desc_info *desc_info, |
2072 | struct sk_buff *skb_ppdu, |
2073 | struct ieee80211_rx_status *rx_status) |
2074 | { |
2075 | struct napi_struct *napi = &rtwdev->napi; |
2076 | |
2077 | /* In low power mode, napi isn't scheduled. Receive it to netif. */ |
2078 | if (unlikely(!napi_is_scheduled(napi))) |
2079 | napi = NULL; |
2080 | |
2081 | rtw89_core_hw_to_sband_rate(rx_status); |
2082 | rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb: skb_ppdu); |
2083 | rtw89_core_update_radiotap(rtwdev, skb: skb_ppdu, rx_status); |
2084 | /* In low power mode, it does RX in thread context. */ |
2085 | local_bh_disable(); |
2086 | ieee80211_rx_napi(hw: rtwdev->hw, NULL, skb: skb_ppdu, napi); |
2087 | local_bh_enable(); |
2088 | rtwdev->napi_budget_countdown--; |
2089 | } |
2090 | |
2091 | static void rtw89_core_rx_pending_skb(struct rtw89_dev *rtwdev, |
2092 | struct rtw89_rx_phy_ppdu *phy_ppdu, |
2093 | struct rtw89_rx_desc_info *desc_info, |
2094 | struct sk_buff *skb) |
2095 | { |
2096 | u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
2097 | int curr = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band]; |
2098 | struct sk_buff *skb_ppdu = NULL, *tmp; |
2099 | struct ieee80211_rx_status *rx_status; |
2100 | |
2101 | if (curr > RTW89_MAX_PPDU_CNT) |
2102 | return; |
2103 | |
2104 | skb_queue_walk_safe(&rtwdev->ppdu_sts.rx_queue[band], skb_ppdu, tmp) { |
2105 | skb_unlink(skb: skb_ppdu, list: &rtwdev->ppdu_sts.rx_queue[band]); |
2106 | rx_status = IEEE80211_SKB_RXCB(skb: skb_ppdu); |
2107 | if (rtw89_core_rx_ppdu_match(rtwdev, desc_info, status: rx_status)) |
2108 | rtw89_chip_query_ppdu(rtwdev, phy_ppdu, status: rx_status); |
2109 | rtw89_correct_cck_chan(rtwdev, status: rx_status); |
2110 | rtw89_core_rx_to_mac80211(rtwdev, phy_ppdu, desc_info, skb_ppdu, rx_status); |
2111 | } |
2112 | } |
2113 | |
2114 | static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev, |
2115 | struct rtw89_rx_desc_info *desc_info, |
2116 | struct sk_buff *skb) |
2117 | { |
2118 | struct rtw89_rx_phy_ppdu phy_ppdu = {.buf = skb->data, .valid = false, |
2119 | .len = skb->len, |
2120 | .to_self = desc_info->addr1_match, |
2121 | .rate = desc_info->data_rate, |
2122 | .mac_id = desc_info->mac_id}; |
2123 | int ret; |
2124 | |
2125 | if (desc_info->mac_info_valid) { |
2126 | ret = rtw89_core_rx_process_mac_ppdu(rtwdev, skb, phy_ppdu: &phy_ppdu); |
2127 | if (ret) |
2128 | goto out; |
2129 | } |
2130 | |
2131 | ret = rtw89_core_rx_process_phy_ppdu(rtwdev, phy_ppdu: &phy_ppdu); |
2132 | if (ret) |
2133 | goto out; |
2134 | |
2135 | rtw89_core_rx_process_phy_sts(rtwdev, phy_ppdu: &phy_ppdu); |
2136 | |
2137 | out: |
2138 | rtw89_core_rx_pending_skb(rtwdev, phy_ppdu: &phy_ppdu, desc_info, skb); |
2139 | dev_kfree_skb_any(skb); |
2140 | } |
2141 | |
2142 | static void rtw89_core_rx_process_report(struct rtw89_dev *rtwdev, |
2143 | struct rtw89_rx_desc_info *desc_info, |
2144 | struct sk_buff *skb) |
2145 | { |
2146 | switch (desc_info->pkt_type) { |
2147 | case RTW89_CORE_RX_TYPE_C2H: |
2148 | rtw89_fw_c2h_irqsafe(rtwdev, c2h: skb); |
2149 | break; |
2150 | case RTW89_CORE_RX_TYPE_PPDU_STAT: |
2151 | rtw89_core_rx_process_ppdu_sts(rtwdev, desc_info, skb); |
2152 | break; |
2153 | default: |
2154 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, fmt: "unhandled pkt_type=%d\n" , |
2155 | desc_info->pkt_type); |
2156 | dev_kfree_skb_any(skb); |
2157 | break; |
2158 | } |
2159 | } |
2160 | |
2161 | void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, |
2162 | struct rtw89_rx_desc_info *desc_info, |
2163 | u8 *data, u32 data_offset) |
2164 | { |
2165 | const struct rtw89_chip_info *chip = rtwdev->chip; |
2166 | struct rtw89_rxdesc_short *rxd_s; |
2167 | struct rtw89_rxdesc_long *rxd_l; |
2168 | u8 shift_len, drv_info_len; |
2169 | |
2170 | rxd_s = (struct rtw89_rxdesc_short *)(data + data_offset); |
2171 | desc_info->pkt_size = le32_get_bits(v: rxd_s->dword0, AX_RXD_RPKT_LEN_MASK); |
2172 | desc_info->drv_info_size = le32_get_bits(v: rxd_s->dword0, AX_RXD_DRV_INFO_SIZE_MASK); |
2173 | desc_info->long_rxdesc = le32_get_bits(v: rxd_s->dword0, AX_RXD_LONG_RXD); |
2174 | desc_info->pkt_type = le32_get_bits(v: rxd_s->dword0, AX_RXD_RPKT_TYPE_MASK); |
2175 | desc_info->mac_info_valid = le32_get_bits(v: rxd_s->dword0, AX_RXD_MAC_INFO_VLD); |
2176 | if (chip->chip_id == RTL8852C) |
2177 | desc_info->bw = le32_get_bits(v: rxd_s->dword1, AX_RXD_BW_v1_MASK); |
2178 | else |
2179 | desc_info->bw = le32_get_bits(v: rxd_s->dword1, AX_RXD_BW_MASK); |
2180 | desc_info->data_rate = le32_get_bits(v: rxd_s->dword1, AX_RXD_RX_DATARATE_MASK); |
2181 | desc_info->gi_ltf = le32_get_bits(v: rxd_s->dword1, AX_RXD_RX_GI_LTF_MASK); |
2182 | desc_info->user_id = le32_get_bits(v: rxd_s->dword1, AX_RXD_USER_ID_MASK); |
2183 | desc_info->sr_en = le32_get_bits(v: rxd_s->dword1, AX_RXD_SR_EN); |
2184 | desc_info->ppdu_cnt = le32_get_bits(v: rxd_s->dword1, AX_RXD_PPDU_CNT_MASK); |
2185 | desc_info->ppdu_type = le32_get_bits(v: rxd_s->dword1, AX_RXD_PPDU_TYPE_MASK); |
2186 | desc_info->free_run_cnt = le32_get_bits(v: rxd_s->dword2, AX_RXD_FREERUN_CNT_MASK); |
2187 | desc_info->icv_err = le32_get_bits(v: rxd_s->dword3, AX_RXD_ICV_ERR); |
2188 | desc_info->crc32_err = le32_get_bits(v: rxd_s->dword3, AX_RXD_CRC32_ERR); |
2189 | desc_info->hw_dec = le32_get_bits(v: rxd_s->dword3, AX_RXD_HW_DEC); |
2190 | desc_info->sw_dec = le32_get_bits(v: rxd_s->dword3, AX_RXD_SW_DEC); |
2191 | desc_info->addr1_match = le32_get_bits(v: rxd_s->dword3, AX_RXD_A1_MATCH); |
2192 | |
2193 | shift_len = desc_info->shift << 1; /* 2-byte unit */ |
2194 | drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ |
2195 | desc_info->offset = data_offset + shift_len + drv_info_len; |
2196 | if (desc_info->long_rxdesc) |
2197 | desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long); |
2198 | else |
2199 | desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short); |
2200 | desc_info->ready = true; |
2201 | |
2202 | if (!desc_info->long_rxdesc) |
2203 | return; |
2204 | |
2205 | rxd_l = (struct rtw89_rxdesc_long *)(data + data_offset); |
2206 | desc_info->frame_type = le32_get_bits(v: rxd_l->dword4, AX_RXD_TYPE_MASK); |
2207 | desc_info->addr_cam_valid = le32_get_bits(v: rxd_l->dword5, AX_RXD_ADDR_CAM_VLD); |
2208 | desc_info->addr_cam_id = le32_get_bits(v: rxd_l->dword5, AX_RXD_ADDR_CAM_MASK); |
2209 | desc_info->sec_cam_id = le32_get_bits(v: rxd_l->dword5, AX_RXD_SEC_CAM_IDX_MASK); |
2210 | desc_info->mac_id = le32_get_bits(v: rxd_l->dword5, AX_RXD_MAC_ID_MASK); |
2211 | desc_info->rx_pl_id = le32_get_bits(v: rxd_l->dword5, AX_RXD_RX_PL_ID_MASK); |
2212 | } |
2213 | EXPORT_SYMBOL(rtw89_core_query_rxdesc); |
2214 | |
2215 | void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev, |
2216 | struct rtw89_rx_desc_info *desc_info, |
2217 | u8 *data, u32 data_offset) |
2218 | { |
2219 | struct rtw89_rxdesc_short_v2 *rxd_s; |
2220 | struct rtw89_rxdesc_long_v2 *rxd_l; |
2221 | u16 shift_len, drv_info_len, phy_rtp_len, hdr_cnv_len; |
2222 | |
2223 | rxd_s = (struct rtw89_rxdesc_short_v2 *)(data + data_offset); |
2224 | |
2225 | desc_info->pkt_size = le32_get_bits(v: rxd_s->dword0, BE_RXD_RPKT_LEN_MASK); |
2226 | desc_info->drv_info_size = le32_get_bits(v: rxd_s->dword0, BE_RXD_DRV_INFO_SZ_MASK); |
2227 | desc_info->phy_rpt_size = le32_get_bits(v: rxd_s->dword0, BE_RXD_PHY_RPT_SZ_MASK); |
2228 | desc_info->hdr_cnv_size = le32_get_bits(v: rxd_s->dword0, BE_RXD_HDR_CNV_SZ_MASK); |
2229 | desc_info->shift = le32_get_bits(v: rxd_s->dword0, BE_RXD_SHIFT_MASK); |
2230 | desc_info->long_rxdesc = le32_get_bits(v: rxd_s->dword0, BE_RXD_LONG_RXD); |
2231 | desc_info->pkt_type = le32_get_bits(v: rxd_s->dword0, BE_RXD_RPKT_TYPE_MASK); |
2232 | if (desc_info->pkt_type == RTW89_CORE_RX_TYPE_PPDU_STAT) |
2233 | desc_info->mac_info_valid = true; |
2234 | |
2235 | desc_info->frame_type = le32_get_bits(v: rxd_s->dword2, BE_RXD_TYPE_MASK); |
2236 | desc_info->mac_id = le32_get_bits(v: rxd_s->dword2, BE_RXD_MAC_ID_MASK); |
2237 | desc_info->addr_cam_valid = le32_get_bits(v: rxd_s->dword2, BE_RXD_ADDR_CAM_VLD); |
2238 | |
2239 | desc_info->icv_err = le32_get_bits(v: rxd_s->dword3, BE_RXD_ICV_ERR); |
2240 | desc_info->crc32_err = le32_get_bits(v: rxd_s->dword3, BE_RXD_CRC32_ERR); |
2241 | desc_info->hw_dec = le32_get_bits(v: rxd_s->dword3, BE_RXD_HW_DEC); |
2242 | desc_info->sw_dec = le32_get_bits(v: rxd_s->dword3, BE_RXD_SW_DEC); |
2243 | desc_info->addr1_match = le32_get_bits(v: rxd_s->dword3, BE_RXD_A1_MATCH); |
2244 | |
2245 | desc_info->bw = le32_get_bits(v: rxd_s->dword4, BE_RXD_BW_MASK); |
2246 | desc_info->data_rate = le32_get_bits(v: rxd_s->dword4, BE_RXD_RX_DATARATE_MASK); |
2247 | desc_info->gi_ltf = le32_get_bits(v: rxd_s->dword4, BE_RXD_RX_GI_LTF_MASK); |
2248 | desc_info->ppdu_cnt = le32_get_bits(v: rxd_s->dword4, BE_RXD_PPDU_CNT_MASK); |
2249 | desc_info->ppdu_type = le32_get_bits(v: rxd_s->dword4, BE_RXD_PPDU_TYPE_MASK); |
2250 | |
2251 | desc_info->free_run_cnt = le32_to_cpu(rxd_s->dword5); |
2252 | |
2253 | shift_len = desc_info->shift << 1; /* 2-byte unit */ |
2254 | drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ |
2255 | phy_rtp_len = desc_info->phy_rpt_size << 3; /* 8-byte unit */ |
2256 | hdr_cnv_len = desc_info->hdr_cnv_size << 4; /* 16-byte unit */ |
2257 | desc_info->offset = data_offset + shift_len + drv_info_len + |
2258 | phy_rtp_len + hdr_cnv_len; |
2259 | |
2260 | if (desc_info->long_rxdesc) |
2261 | desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long_v2); |
2262 | else |
2263 | desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short_v2); |
2264 | desc_info->ready = true; |
2265 | |
2266 | if (!desc_info->long_rxdesc) |
2267 | return; |
2268 | |
2269 | rxd_l = (struct rtw89_rxdesc_long_v2 *)(data + data_offset); |
2270 | |
2271 | desc_info->sr_en = le32_get_bits(v: rxd_l->dword6, BE_RXD_SR_EN); |
2272 | desc_info->user_id = le32_get_bits(v: rxd_l->dword6, BE_RXD_USER_ID_MASK); |
2273 | desc_info->addr_cam_id = le32_get_bits(v: rxd_l->dword6, BE_RXD_ADDR_CAM_MASK); |
2274 | desc_info->sec_cam_id = le32_get_bits(v: rxd_l->dword6, BE_RXD_SEC_CAM_IDX_MASK); |
2275 | |
2276 | desc_info->rx_pl_id = le32_get_bits(v: rxd_l->dword7, BE_RXD_RX_PL_ID_MASK); |
2277 | } |
2278 | EXPORT_SYMBOL(rtw89_core_query_rxdesc_v2); |
2279 | |
2280 | struct rtw89_core_iter_rx_status { |
2281 | struct rtw89_dev *rtwdev; |
2282 | struct ieee80211_rx_status *rx_status; |
2283 | struct rtw89_rx_desc_info *desc_info; |
2284 | u8 mac_id; |
2285 | }; |
2286 | |
2287 | static |
2288 | void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta) |
2289 | { |
2290 | struct rtw89_core_iter_rx_status *iter_data = |
2291 | (struct rtw89_core_iter_rx_status *)data; |
2292 | struct ieee80211_rx_status *rx_status = iter_data->rx_status; |
2293 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
2294 | struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; |
2295 | u8 mac_id = iter_data->mac_id; |
2296 | |
2297 | if (mac_id != rtwsta->mac_id) |
2298 | return; |
2299 | |
2300 | rtwsta->rx_status = *rx_status; |
2301 | rtwsta->rx_hw_rate = desc_info->data_rate; |
2302 | } |
2303 | |
2304 | static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev, |
2305 | struct rtw89_rx_desc_info *desc_info, |
2306 | struct ieee80211_rx_status *rx_status) |
2307 | { |
2308 | struct rtw89_core_iter_rx_status iter_data; |
2309 | |
2310 | if (!desc_info->addr1_match || !desc_info->long_rxdesc) |
2311 | return; |
2312 | |
2313 | if (desc_info->frame_type != RTW89_RX_TYPE_DATA) |
2314 | return; |
2315 | |
2316 | iter_data.rtwdev = rtwdev; |
2317 | iter_data.rx_status = rx_status; |
2318 | iter_data.desc_info = desc_info; |
2319 | iter_data.mac_id = desc_info->mac_id; |
2320 | ieee80211_iterate_stations_atomic(hw: rtwdev->hw, |
2321 | iterator: rtw89_core_stats_sta_rx_status_iter, |
2322 | data: &iter_data); |
2323 | } |
2324 | |
2325 | static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, |
2326 | struct rtw89_rx_desc_info *desc_info, |
2327 | struct ieee80211_rx_status *rx_status) |
2328 | { |
2329 | const struct cfg80211_chan_def *chandef = |
2330 | rtw89_chandef_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
2331 | u16 data_rate; |
2332 | u8 data_rate_mode; |
2333 | bool eht = false; |
2334 | u8 gi; |
2335 | |
2336 | /* currently using single PHY */ |
2337 | rx_status->freq = chandef->chan->center_freq; |
2338 | rx_status->band = chandef->chan->band; |
2339 | |
2340 | if (rtwdev->scanning && |
2341 | RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) { |
2342 | const struct rtw89_chan *cur = rtw89_scan_chan_get(rtwdev); |
2343 | u8 chan = cur->primary_channel; |
2344 | u8 band = cur->band_type; |
2345 | enum nl80211_band nl_band; |
2346 | |
2347 | nl_band = rtw89_hw_to_nl80211_band(hw_band: band); |
2348 | rx_status->freq = ieee80211_channel_to_frequency(chan, band: nl_band); |
2349 | rx_status->band = nl_band; |
2350 | } |
2351 | |
2352 | if (desc_info->icv_err || desc_info->crc32_err) |
2353 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
2354 | |
2355 | if (desc_info->hw_dec && |
2356 | !(desc_info->sw_dec || desc_info->icv_err)) |
2357 | rx_status->flag |= RX_FLAG_DECRYPTED; |
2358 | |
2359 | rx_status->bw = rtw89_hw_to_rate_info_bw(hw_bw: desc_info->bw); |
2360 | |
2361 | data_rate = desc_info->data_rate; |
2362 | data_rate_mode = rtw89_get_data_rate_mode(rtwdev, hw_rate: data_rate); |
2363 | if (data_rate_mode == DATA_RATE_MODE_NON_HT) { |
2364 | rx_status->encoding = RX_ENC_LEGACY; |
2365 | rx_status->rate_idx = rtw89_get_data_not_ht_idx(rtwdev, hw_rate: data_rate); |
2366 | /* convert rate_idx after we get the correct band */ |
2367 | } else if (data_rate_mode == DATA_RATE_MODE_HT) { |
2368 | rx_status->encoding = RX_ENC_HT; |
2369 | rx_status->rate_idx = rtw89_get_data_ht_mcs(rtwdev, hw_rate: data_rate); |
2370 | if (desc_info->gi_ltf) |
2371 | rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; |
2372 | } else if (data_rate_mode == DATA_RATE_MODE_VHT) { |
2373 | rx_status->encoding = RX_ENC_VHT; |
2374 | rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, hw_rate: data_rate); |
2375 | rx_status->nss = rtw89_get_data_nss(rtwdev, hw_rate: data_rate) + 1; |
2376 | if (desc_info->gi_ltf) |
2377 | rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; |
2378 | } else if (data_rate_mode == DATA_RATE_MODE_HE) { |
2379 | rx_status->encoding = RX_ENC_HE; |
2380 | rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, hw_rate: data_rate); |
2381 | rx_status->nss = rtw89_get_data_nss(rtwdev, hw_rate: data_rate) + 1; |
2382 | } else if (data_rate_mode == DATA_RATE_MODE_EHT) { |
2383 | rx_status->encoding = RX_ENC_EHT; |
2384 | rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, hw_rate: data_rate); |
2385 | rx_status->nss = rtw89_get_data_nss(rtwdev, hw_rate: data_rate) + 1; |
2386 | eht = true; |
2387 | } else { |
2388 | rtw89_warn(rtwdev, "invalid RX rate mode %d\n" , data_rate_mode); |
2389 | } |
2390 | |
2391 | /* he_gi is used to match ppdu, so we always fill it. */ |
2392 | gi = rtw89_rxdesc_to_nl_he_eht_gi(rtwdev, desc_info_gi: desc_info->gi_ltf, rx_status: true, eht); |
2393 | if (eht) |
2394 | rx_status->eht.gi = gi; |
2395 | else |
2396 | rx_status->he_gi = gi; |
2397 | rx_status->flag |= RX_FLAG_MACTIME_START; |
2398 | rx_status->mactime = desc_info->free_run_cnt; |
2399 | |
2400 | rtw89_core_stats_sta_rx_status(rtwdev, desc_info, rx_status); |
2401 | } |
2402 | |
2403 | static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) |
2404 | { |
2405 | const struct rtw89_chip_info *chip = rtwdev->chip; |
2406 | |
2407 | if (rtw89_disable_ps_mode || !chip->ps_mode_supported || |
2408 | RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw)) |
2409 | return RTW89_PS_MODE_NONE; |
2410 | |
2411 | if ((chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) && |
2412 | !RTW89_CHK_FW_FEATURE(NO_LPS_PG, &rtwdev->fw)) |
2413 | return RTW89_PS_MODE_PWR_GATED; |
2414 | |
2415 | if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_CLK_GATED)) |
2416 | return RTW89_PS_MODE_CLK_GATED; |
2417 | |
2418 | if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_RFOFF)) |
2419 | return RTW89_PS_MODE_RFOFF; |
2420 | |
2421 | return RTW89_PS_MODE_NONE; |
2422 | } |
2423 | |
2424 | static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev, |
2425 | struct rtw89_rx_desc_info *desc_info) |
2426 | { |
2427 | struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; |
2428 | u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
2429 | struct ieee80211_rx_status *rx_status; |
2430 | struct sk_buff *skb_ppdu, *tmp; |
2431 | |
2432 | skb_queue_walk_safe(&ppdu_sts->rx_queue[band], skb_ppdu, tmp) { |
2433 | skb_unlink(skb: skb_ppdu, list: &ppdu_sts->rx_queue[band]); |
2434 | rx_status = IEEE80211_SKB_RXCB(skb: skb_ppdu); |
2435 | rtw89_core_rx_to_mac80211(rtwdev, NULL, desc_info, skb_ppdu, rx_status); |
2436 | } |
2437 | } |
2438 | |
2439 | void rtw89_core_rx(struct rtw89_dev *rtwdev, |
2440 | struct rtw89_rx_desc_info *desc_info, |
2441 | struct sk_buff *skb) |
2442 | { |
2443 | struct ieee80211_rx_status *rx_status; |
2444 | struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; |
2445 | u8 ppdu_cnt = desc_info->ppdu_cnt; |
2446 | u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; |
2447 | |
2448 | if (desc_info->pkt_type != RTW89_CORE_RX_TYPE_WIFI) { |
2449 | rtw89_core_rx_process_report(rtwdev, desc_info, skb); |
2450 | return; |
2451 | } |
2452 | |
2453 | if (ppdu_sts->curr_rx_ppdu_cnt[band] != ppdu_cnt) { |
2454 | rtw89_core_flush_ppdu_rx_queue(rtwdev, desc_info); |
2455 | ppdu_sts->curr_rx_ppdu_cnt[band] = ppdu_cnt; |
2456 | } |
2457 | |
2458 | rx_status = IEEE80211_SKB_RXCB(skb); |
2459 | memset(rx_status, 0, sizeof(*rx_status)); |
2460 | rtw89_core_update_rx_status(rtwdev, desc_info, rx_status); |
2461 | if (desc_info->long_rxdesc && |
2462 | BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP) |
2463 | skb_queue_tail(list: &ppdu_sts->rx_queue[band], newsk: skb); |
2464 | else |
2465 | rtw89_core_rx_to_mac80211(rtwdev, NULL, desc_info, skb_ppdu: skb, rx_status); |
2466 | } |
2467 | EXPORT_SYMBOL(rtw89_core_rx); |
2468 | |
2469 | void rtw89_core_napi_start(struct rtw89_dev *rtwdev) |
2470 | { |
2471 | if (test_and_set_bit(nr: RTW89_FLAG_NAPI_RUNNING, addr: rtwdev->flags)) |
2472 | return; |
2473 | |
2474 | napi_enable(n: &rtwdev->napi); |
2475 | } |
2476 | EXPORT_SYMBOL(rtw89_core_napi_start); |
2477 | |
2478 | void rtw89_core_napi_stop(struct rtw89_dev *rtwdev) |
2479 | { |
2480 | if (!test_and_clear_bit(nr: RTW89_FLAG_NAPI_RUNNING, addr: rtwdev->flags)) |
2481 | return; |
2482 | |
2483 | napi_synchronize(n: &rtwdev->napi); |
2484 | napi_disable(n: &rtwdev->napi); |
2485 | } |
2486 | EXPORT_SYMBOL(rtw89_core_napi_stop); |
2487 | |
2488 | void rtw89_core_napi_init(struct rtw89_dev *rtwdev) |
2489 | { |
2490 | init_dummy_netdev(dev: &rtwdev->netdev); |
2491 | netif_napi_add(dev: &rtwdev->netdev, napi: &rtwdev->napi, |
2492 | poll: rtwdev->hci.ops->napi_poll); |
2493 | } |
2494 | EXPORT_SYMBOL(rtw89_core_napi_init); |
2495 | |
2496 | void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev) |
2497 | { |
2498 | rtw89_core_napi_stop(rtwdev); |
2499 | netif_napi_del(napi: &rtwdev->napi); |
2500 | } |
2501 | EXPORT_SYMBOL(rtw89_core_napi_deinit); |
2502 | |
2503 | static void rtw89_core_ba_work(struct work_struct *work) |
2504 | { |
2505 | struct rtw89_dev *rtwdev = |
2506 | container_of(work, struct rtw89_dev, ba_work); |
2507 | struct rtw89_txq *rtwtxq, *tmp; |
2508 | int ret; |
2509 | |
2510 | spin_lock_bh(lock: &rtwdev->ba_lock); |
2511 | list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { |
2512 | struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
2513 | struct ieee80211_sta *sta = txq->sta; |
2514 | struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; |
2515 | u8 tid = txq->tid; |
2516 | |
2517 | if (!sta) { |
2518 | rtw89_warn(rtwdev, "cannot start BA without sta\n" ); |
2519 | goto skip_ba_work; |
2520 | } |
2521 | |
2522 | if (rtwsta->disassoc) { |
2523 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
2524 | fmt: "cannot start BA with disassoc sta\n" ); |
2525 | goto skip_ba_work; |
2526 | } |
2527 | |
2528 | ret = ieee80211_start_tx_ba_session(sta, tid, timeout: 0); |
2529 | if (ret) { |
2530 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
2531 | fmt: "failed to setup BA session for %pM:%2d: %d\n" , |
2532 | sta->addr, tid, ret); |
2533 | if (ret == -EINVAL) |
2534 | set_bit(nr: RTW89_TXQ_F_BLOCK_BA, addr: &rtwtxq->flags); |
2535 | } |
2536 | skip_ba_work: |
2537 | list_del_init(entry: &rtwtxq->list); |
2538 | } |
2539 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
2540 | } |
2541 | |
2542 | static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, |
2543 | struct ieee80211_sta *sta) |
2544 | { |
2545 | struct rtw89_txq *rtwtxq, *tmp; |
2546 | |
2547 | spin_lock_bh(lock: &rtwdev->ba_lock); |
2548 | list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { |
2549 | struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
2550 | |
2551 | if (sta == txq->sta) |
2552 | list_del_init(entry: &rtwtxq->list); |
2553 | } |
2554 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
2555 | } |
2556 | |
2557 | static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev, |
2558 | struct ieee80211_sta *sta) |
2559 | { |
2560 | struct rtw89_txq *rtwtxq, *tmp; |
2561 | |
2562 | spin_lock_bh(lock: &rtwdev->ba_lock); |
2563 | list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->forbid_ba_list, list) { |
2564 | struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
2565 | |
2566 | if (sta == txq->sta) { |
2567 | clear_bit(nr: RTW89_TXQ_F_FORBID_BA, addr: &rtwtxq->flags); |
2568 | list_del_init(entry: &rtwtxq->list); |
2569 | } |
2570 | } |
2571 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
2572 | } |
2573 | |
2574 | static void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev, |
2575 | struct ieee80211_sta *sta) |
2576 | { |
2577 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
2578 | struct sk_buff *skb, *tmp; |
2579 | |
2580 | skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { |
2581 | skb_unlink(skb, list: &rtwsta->roc_queue); |
2582 | dev_kfree_skb_any(skb); |
2583 | } |
2584 | } |
2585 | |
2586 | static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev, |
2587 | struct rtw89_txq *rtwtxq) |
2588 | { |
2589 | struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
2590 | struct ieee80211_sta *sta = txq->sta; |
2591 | struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); |
2592 | |
2593 | if (unlikely(!rtwsta) || unlikely(rtwsta->disassoc)) |
2594 | return; |
2595 | |
2596 | if (!test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags) || |
2597 | test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) |
2598 | return; |
2599 | |
2600 | spin_lock_bh(lock: &rtwdev->ba_lock); |
2601 | if (!test_and_set_bit(nr: RTW89_TXQ_F_FORBID_BA, addr: &rtwtxq->flags)) |
2602 | list_add_tail(new: &rtwtxq->list, head: &rtwdev->forbid_ba_list); |
2603 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
2604 | |
2605 | ieee80211_stop_tx_ba_session(sta, tid: txq->tid); |
2606 | cancel_delayed_work(dwork: &rtwdev->forbid_ba_work); |
2607 | ieee80211_queue_delayed_work(hw: rtwdev->hw, dwork: &rtwdev->forbid_ba_work, |
2608 | RTW89_FORBID_BA_TIMER); |
2609 | } |
2610 | |
2611 | static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, |
2612 | struct rtw89_txq *rtwtxq, |
2613 | struct sk_buff *skb) |
2614 | { |
2615 | struct ieee80211_hw *hw = rtwdev->hw; |
2616 | struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
2617 | struct ieee80211_sta *sta = txq->sta; |
2618 | struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; |
2619 | |
2620 | if (test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags)) |
2621 | return; |
2622 | |
2623 | if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
2624 | rtw89_core_stop_tx_ba_session(rtwdev, rtwtxq); |
2625 | return; |
2626 | } |
2627 | |
2628 | if (unlikely(!sta)) |
2629 | return; |
2630 | |
2631 | if (unlikely(test_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags))) |
2632 | return; |
2633 | |
2634 | if (test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags)) { |
2635 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_AMPDU; |
2636 | return; |
2637 | } |
2638 | |
2639 | spin_lock_bh(lock: &rtwdev->ba_lock); |
2640 | if (!rtwsta->disassoc && list_empty(head: &rtwtxq->list)) { |
2641 | list_add_tail(new: &rtwtxq->list, head: &rtwdev->ba_list); |
2642 | ieee80211_queue_work(hw, work: &rtwdev->ba_work); |
2643 | } |
2644 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
2645 | } |
2646 | |
2647 | static void rtw89_core_txq_push(struct rtw89_dev *rtwdev, |
2648 | struct rtw89_txq *rtwtxq, |
2649 | unsigned long frame_cnt, |
2650 | unsigned long byte_cnt) |
2651 | { |
2652 | struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); |
2653 | struct ieee80211_vif *vif = txq->vif; |
2654 | struct ieee80211_sta *sta = txq->sta; |
2655 | struct sk_buff *skb; |
2656 | unsigned long i; |
2657 | int ret; |
2658 | |
2659 | rcu_read_lock(); |
2660 | for (i = 0; i < frame_cnt; i++) { |
2661 | skb = ieee80211_tx_dequeue_ni(hw: rtwdev->hw, txq); |
2662 | if (!skb) { |
2663 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, fmt: "dequeue a NULL skb\n" ); |
2664 | goto out; |
2665 | } |
2666 | rtw89_core_txq_check_agg(rtwdev, rtwtxq, skb); |
2667 | ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, NULL); |
2668 | if (ret) { |
2669 | rtw89_err(rtwdev, "failed to push txq: %d\n" , ret); |
2670 | ieee80211_free_txskb(hw: rtwdev->hw, skb); |
2671 | break; |
2672 | } |
2673 | } |
2674 | out: |
2675 | rcu_read_unlock(); |
2676 | } |
2677 | |
2678 | static u32 rtw89_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 tid) |
2679 | { |
2680 | u8 qsel, ch_dma; |
2681 | |
2682 | qsel = rtw89_core_get_qsel(rtwdev, tid); |
2683 | ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); |
2684 | |
2685 | return rtw89_hci_check_and_reclaim_tx_resource(rtwdev, txch: ch_dma); |
2686 | } |
2687 | |
2688 | static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, |
2689 | struct ieee80211_txq *txq, |
2690 | unsigned long *frame_cnt, |
2691 | bool *sched_txq, bool *reinvoke) |
2692 | { |
2693 | struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; |
2694 | struct ieee80211_sta *sta = txq->sta; |
2695 | struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; |
2696 | |
2697 | if (!sta || rtwsta->max_agg_wait <= 0) |
2698 | return false; |
2699 | |
2700 | if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID) |
2701 | return false; |
2702 | |
2703 | if (*frame_cnt > 1) { |
2704 | *frame_cnt -= 1; |
2705 | *sched_txq = true; |
2706 | *reinvoke = true; |
2707 | rtwtxq->wait_cnt = 1; |
2708 | return false; |
2709 | } |
2710 | |
2711 | if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta->max_agg_wait) { |
2712 | *reinvoke = true; |
2713 | rtwtxq->wait_cnt++; |
2714 | return true; |
2715 | } |
2716 | |
2717 | rtwtxq->wait_cnt = 0; |
2718 | return false; |
2719 | } |
2720 | |
2721 | static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinvoke) |
2722 | { |
2723 | struct ieee80211_hw *hw = rtwdev->hw; |
2724 | struct ieee80211_txq *txq; |
2725 | struct rtw89_vif *rtwvif; |
2726 | struct rtw89_txq *rtwtxq; |
2727 | unsigned long frame_cnt; |
2728 | unsigned long byte_cnt; |
2729 | u32 tx_resource; |
2730 | bool sched_txq; |
2731 | |
2732 | ieee80211_txq_schedule_start(hw, ac); |
2733 | while ((txq = ieee80211_next_txq(hw, ac))) { |
2734 | rtwtxq = (struct rtw89_txq *)txq->drv_priv; |
2735 | rtwvif = (struct rtw89_vif *)txq->vif->drv_priv; |
2736 | |
2737 | if (rtwvif->offchan) { |
2738 | ieee80211_return_txq(hw, txq, force: true); |
2739 | continue; |
2740 | } |
2741 | tx_resource = rtw89_check_and_reclaim_tx_resource(rtwdev, tid: txq->tid); |
2742 | sched_txq = false; |
2743 | |
2744 | ieee80211_txq_get_depth(txq, frame_cnt: &frame_cnt, byte_cnt: &byte_cnt); |
2745 | if (rtw89_core_txq_agg_wait(rtwdev, txq, frame_cnt: &frame_cnt, sched_txq: &sched_txq, reinvoke)) { |
2746 | ieee80211_return_txq(hw, txq, force: true); |
2747 | continue; |
2748 | } |
2749 | frame_cnt = min_t(unsigned long, frame_cnt, tx_resource); |
2750 | rtw89_core_txq_push(rtwdev, rtwtxq, frame_cnt, byte_cnt); |
2751 | ieee80211_return_txq(hw, txq, force: sched_txq); |
2752 | if (frame_cnt != 0) |
2753 | rtw89_core_tx_kick_off(rtwdev, qsel: rtw89_core_get_qsel(rtwdev, tid: txq->tid)); |
2754 | |
2755 | /* bound of tx_resource could get stuck due to burst traffic */ |
2756 | if (frame_cnt == tx_resource) |
2757 | *reinvoke = true; |
2758 | } |
2759 | ieee80211_txq_schedule_end(hw, ac); |
2760 | } |
2761 | |
2762 | static void rtw89_ips_work(struct work_struct *work) |
2763 | { |
2764 | struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, |
2765 | ips_work); |
2766 | mutex_lock(&rtwdev->mutex); |
2767 | rtw89_enter_ips_by_hwflags(rtwdev); |
2768 | mutex_unlock(lock: &rtwdev->mutex); |
2769 | } |
2770 | |
2771 | static void rtw89_core_txq_work(struct work_struct *w) |
2772 | { |
2773 | struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, txq_work); |
2774 | bool reinvoke = false; |
2775 | u8 ac; |
2776 | |
2777 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
2778 | rtw89_core_txq_schedule(rtwdev, ac, reinvoke: &reinvoke); |
2779 | |
2780 | if (reinvoke) { |
2781 | /* reinvoke to process the last frame */ |
2782 | mod_delayed_work(wq: rtwdev->txq_wq, dwork: &rtwdev->txq_reinvoke_work, delay: 1); |
2783 | } |
2784 | } |
2785 | |
2786 | static void rtw89_core_txq_reinvoke_work(struct work_struct *w) |
2787 | { |
2788 | struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, |
2789 | txq_reinvoke_work.work); |
2790 | |
2791 | queue_work(wq: rtwdev->txq_wq, work: &rtwdev->txq_work); |
2792 | } |
2793 | |
2794 | static void rtw89_forbid_ba_work(struct work_struct *w) |
2795 | { |
2796 | struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, |
2797 | forbid_ba_work.work); |
2798 | struct rtw89_txq *rtwtxq, *tmp; |
2799 | |
2800 | spin_lock_bh(lock: &rtwdev->ba_lock); |
2801 | list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->forbid_ba_list, list) { |
2802 | clear_bit(nr: RTW89_TXQ_F_FORBID_BA, addr: &rtwtxq->flags); |
2803 | list_del_init(entry: &rtwtxq->list); |
2804 | } |
2805 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
2806 | } |
2807 | |
2808 | static void rtw89_core_sta_pending_tx_iter(void *data, |
2809 | struct ieee80211_sta *sta) |
2810 | { |
2811 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
2812 | struct rtw89_vif *rtwvif_target = data, *rtwvif = rtwsta->rtwvif; |
2813 | struct rtw89_dev *rtwdev = rtwvif->rtwdev; |
2814 | struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); |
2815 | struct sk_buff *skb, *tmp; |
2816 | int qsel, ret; |
2817 | |
2818 | if (rtwvif->sub_entity_idx != rtwvif_target->sub_entity_idx) |
2819 | return; |
2820 | |
2821 | if (skb_queue_len(list_: &rtwsta->roc_queue) == 0) |
2822 | return; |
2823 | |
2824 | skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { |
2825 | skb_unlink(skb, list: &rtwsta->roc_queue); |
2826 | |
2827 | ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, qsel: &qsel); |
2828 | if (ret) { |
2829 | rtw89_warn(rtwdev, "pending tx failed with %d\n" , ret); |
2830 | dev_kfree_skb_any(skb); |
2831 | } else { |
2832 | rtw89_core_tx_kick_off(rtwdev, qsel); |
2833 | } |
2834 | } |
2835 | } |
2836 | |
2837 | static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev, |
2838 | struct rtw89_vif *rtwvif) |
2839 | { |
2840 | ieee80211_iterate_stations_atomic(hw: rtwdev->hw, |
2841 | iterator: rtw89_core_sta_pending_tx_iter, |
2842 | data: rtwvif); |
2843 | } |
2844 | |
2845 | static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, |
2846 | struct rtw89_vif *rtwvif, bool qos, bool ps) |
2847 | { |
2848 | struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); |
2849 | struct ieee80211_sta *sta; |
2850 | struct ieee80211_hdr *hdr; |
2851 | struct sk_buff *skb; |
2852 | int ret, qsel; |
2853 | |
2854 | if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) |
2855 | return 0; |
2856 | |
2857 | rcu_read_lock(); |
2858 | sta = ieee80211_find_sta(vif, addr: vif->bss_conf.bssid); |
2859 | if (!sta) { |
2860 | ret = -EINVAL; |
2861 | goto out; |
2862 | } |
2863 | |
2864 | skb = ieee80211_nullfunc_get(hw: rtwdev->hw, vif, link_id: -1, qos_ok: qos); |
2865 | if (!skb) { |
2866 | ret = -ENOMEM; |
2867 | goto out; |
2868 | } |
2869 | |
2870 | hdr = (struct ieee80211_hdr *)skb->data; |
2871 | if (ps) |
2872 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
2873 | |
2874 | ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, qsel: &qsel); |
2875 | if (ret) { |
2876 | rtw89_warn(rtwdev, "nullfunc transmit failed: %d\n" , ret); |
2877 | dev_kfree_skb_any(skb); |
2878 | goto out; |
2879 | } |
2880 | |
2881 | rcu_read_unlock(); |
2882 | |
2883 | return rtw89_core_tx_kick_off_and_wait(rtwdev, skb, qsel, |
2884 | RTW89_ROC_TX_TIMEOUT); |
2885 | out: |
2886 | rcu_read_unlock(); |
2887 | |
2888 | return ret; |
2889 | } |
2890 | |
2891 | void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) |
2892 | { |
2893 | const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; |
2894 | struct ieee80211_hw *hw = rtwdev->hw; |
2895 | struct rtw89_roc *roc = &rtwvif->roc; |
2896 | struct cfg80211_chan_def roc_chan; |
2897 | struct rtw89_vif *tmp; |
2898 | int ret; |
2899 | |
2900 | lockdep_assert_held(&rtwdev->mutex); |
2901 | |
2902 | rtw89_leave_ips_by_hwflags(rtwdev); |
2903 | rtw89_leave_lps(rtwdev); |
2904 | rtw89_chanctx_pause(rtwdev, rsn: RTW89_CHANCTX_PAUSE_REASON_ROC); |
2905 | |
2906 | ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, qos: true, ps: true); |
2907 | if (ret) |
2908 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
2909 | fmt: "roc send null-1 failed: %d\n" , ret); |
2910 | |
2911 | rtw89_for_each_rtwvif(rtwdev, tmp) |
2912 | if (tmp->sub_entity_idx == rtwvif->sub_entity_idx) |
2913 | tmp->offchan = true; |
2914 | |
2915 | cfg80211_chandef_create(chandef: &roc_chan, channel: &roc->chan, chantype: NL80211_CHAN_NO_HT); |
2916 | rtw89_config_roc_chandef(rtwdev, idx: rtwvif->sub_entity_idx, chandef: &roc_chan); |
2917 | rtw89_set_channel(rtwdev); |
2918 | rtw89_write32_clr(rtwdev, |
2919 | addr: rtw89_mac_reg_by_idx(rtwdev, reg_base: mac->rx_fltr, band: RTW89_MAC_0), |
2920 | B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH); |
2921 | |
2922 | ieee80211_ready_on_channel(hw); |
2923 | cancel_delayed_work(dwork: &rtwvif->roc.roc_work); |
2924 | ieee80211_queue_delayed_work(hw, dwork: &rtwvif->roc.roc_work, |
2925 | delay: msecs_to_jiffies(m: rtwvif->roc.duration)); |
2926 | } |
2927 | |
2928 | void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) |
2929 | { |
2930 | const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; |
2931 | struct ieee80211_hw *hw = rtwdev->hw; |
2932 | struct rtw89_roc *roc = &rtwvif->roc; |
2933 | struct rtw89_vif *tmp; |
2934 | int ret; |
2935 | |
2936 | lockdep_assert_held(&rtwdev->mutex); |
2937 | |
2938 | ieee80211_remain_on_channel_expired(hw); |
2939 | |
2940 | rtw89_leave_ips_by_hwflags(rtwdev); |
2941 | rtw89_leave_lps(rtwdev); |
2942 | |
2943 | rtw89_write32_mask(rtwdev, |
2944 | addr: rtw89_mac_reg_by_idx(rtwdev, reg_base: mac->rx_fltr, band: RTW89_MAC_0), |
2945 | B_AX_RX_FLTR_CFG_MASK, |
2946 | data: rtwdev->hal.rx_fltr); |
2947 | |
2948 | roc->state = RTW89_ROC_IDLE; |
2949 | rtw89_config_roc_chandef(rtwdev, idx: rtwvif->sub_entity_idx, NULL); |
2950 | rtw89_chanctx_proceed(rtwdev); |
2951 | ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, qos: true, ps: false); |
2952 | if (ret) |
2953 | rtw89_debug(rtwdev, mask: RTW89_DBG_TXRX, |
2954 | fmt: "roc send null-0 failed: %d\n" , ret); |
2955 | |
2956 | rtw89_for_each_rtwvif(rtwdev, tmp) |
2957 | if (tmp->sub_entity_idx == rtwvif->sub_entity_idx) |
2958 | tmp->offchan = false; |
2959 | |
2960 | rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif); |
2961 | queue_work(wq: rtwdev->txq_wq, work: &rtwdev->txq_work); |
2962 | |
2963 | if (hw->conf.flags & IEEE80211_CONF_IDLE) |
2964 | ieee80211_queue_delayed_work(hw, dwork: &roc->roc_work, |
2965 | delay: msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT)); |
2966 | } |
2967 | |
2968 | void rtw89_roc_work(struct work_struct *work) |
2969 | { |
2970 | struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, |
2971 | roc.roc_work.work); |
2972 | struct rtw89_dev *rtwdev = rtwvif->rtwdev; |
2973 | struct rtw89_roc *roc = &rtwvif->roc; |
2974 | |
2975 | mutex_lock(&rtwdev->mutex); |
2976 | |
2977 | switch (roc->state) { |
2978 | case RTW89_ROC_IDLE: |
2979 | rtw89_enter_ips_by_hwflags(rtwdev); |
2980 | break; |
2981 | case RTW89_ROC_MGMT: |
2982 | case RTW89_ROC_NORMAL: |
2983 | rtw89_roc_end(rtwdev, rtwvif); |
2984 | break; |
2985 | default: |
2986 | break; |
2987 | } |
2988 | |
2989 | mutex_unlock(lock: &rtwdev->mutex); |
2990 | } |
2991 | |
2992 | static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev, |
2993 | u32 throughput, u64 cnt) |
2994 | { |
2995 | if (cnt < 100) |
2996 | return RTW89_TFC_IDLE; |
2997 | if (throughput > 50) |
2998 | return RTW89_TFC_HIGH; |
2999 | if (throughput > 10) |
3000 | return RTW89_TFC_MID; |
3001 | if (throughput > 2) |
3002 | return RTW89_TFC_LOW; |
3003 | return RTW89_TFC_ULTRA_LOW; |
3004 | } |
3005 | |
3006 | static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev, |
3007 | struct rtw89_traffic_stats *stats) |
3008 | { |
3009 | enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; |
3010 | enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; |
3011 | |
3012 | stats->tx_throughput_raw = (u32)(stats->tx_unicast >> RTW89_TP_SHIFT); |
3013 | stats->rx_throughput_raw = (u32)(stats->rx_unicast >> RTW89_TP_SHIFT); |
3014 | |
3015 | ewma_tp_add(e: &stats->tx_ewma_tp, val: stats->tx_throughput_raw); |
3016 | ewma_tp_add(e: &stats->rx_ewma_tp, val: stats->rx_throughput_raw); |
3017 | |
3018 | stats->tx_throughput = ewma_tp_read(e: &stats->tx_ewma_tp); |
3019 | stats->rx_throughput = ewma_tp_read(e: &stats->rx_ewma_tp); |
3020 | stats->tx_tfc_lv = rtw89_get_traffic_level(rtwdev, throughput: stats->tx_throughput, |
3021 | cnt: stats->tx_cnt); |
3022 | stats->rx_tfc_lv = rtw89_get_traffic_level(rtwdev, throughput: stats->rx_throughput, |
3023 | cnt: stats->rx_cnt); |
3024 | stats->tx_avg_len = stats->tx_cnt ? |
3025 | DIV_ROUND_DOWN_ULL(stats->tx_unicast, stats->tx_cnt) : 0; |
3026 | stats->rx_avg_len = stats->rx_cnt ? |
3027 | DIV_ROUND_DOWN_ULL(stats->rx_unicast, stats->rx_cnt) : 0; |
3028 | |
3029 | stats->tx_unicast = 0; |
3030 | stats->rx_unicast = 0; |
3031 | stats->tx_cnt = 0; |
3032 | stats->rx_cnt = 0; |
3033 | stats->rx_tf_periodic = stats->rx_tf_acc; |
3034 | stats->rx_tf_acc = 0; |
3035 | |
3036 | if (tx_tfc_lv != stats->tx_tfc_lv || rx_tfc_lv != stats->rx_tfc_lv) |
3037 | return true; |
3038 | |
3039 | return false; |
3040 | } |
3041 | |
3042 | static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) |
3043 | { |
3044 | struct rtw89_vif *rtwvif; |
3045 | bool tfc_changed; |
3046 | |
3047 | tfc_changed = rtw89_traffic_stats_calc(rtwdev, stats: &rtwdev->stats); |
3048 | rtw89_for_each_rtwvif(rtwdev, rtwvif) { |
3049 | rtw89_traffic_stats_calc(rtwdev, stats: &rtwvif->stats); |
3050 | rtw89_fw_h2c_tp_offload(rtwdev, rtwvif); |
3051 | } |
3052 | |
3053 | return tfc_changed; |
3054 | } |
3055 | |
3056 | static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) |
3057 | { |
3058 | if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && |
3059 | rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || |
3060 | rtwvif->tdls_peer) |
3061 | return; |
3062 | |
3063 | if (rtwvif->offchan) |
3064 | return; |
3065 | |
3066 | if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && |
3067 | rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE) |
3068 | rtw89_enter_lps(rtwdev, rtwvif, ps_mode: true); |
3069 | } |
3070 | |
3071 | static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev) |
3072 | { |
3073 | struct rtw89_vif *rtwvif; |
3074 | |
3075 | rtw89_for_each_rtwvif(rtwdev, rtwvif) |
3076 | rtw89_vif_enter_lps(rtwdev, rtwvif); |
3077 | } |
3078 | |
3079 | static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev) |
3080 | { |
3081 | enum rtw89_entity_mode mode; |
3082 | |
3083 | mode = rtw89_get_entity_mode(rtwdev); |
3084 | if (mode == RTW89_ENTITY_MODE_MCC) |
3085 | return; |
3086 | |
3087 | rtw89_chip_rfk_track(rtwdev); |
3088 | } |
3089 | |
3090 | void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) |
3091 | { |
3092 | enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); |
3093 | |
3094 | if (mode == RTW89_ENTITY_MODE_MCC) |
3095 | rtw89_queue_chanctx_change(rtwdev, change: RTW89_CHANCTX_P2P_PS_CHANGE); |
3096 | else |
3097 | rtw89_process_p2p_ps(rtwdev, vif); |
3098 | } |
3099 | |
3100 | void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, |
3101 | struct rtw89_traffic_stats *stats) |
3102 | { |
3103 | stats->tx_unicast = 0; |
3104 | stats->rx_unicast = 0; |
3105 | stats->tx_cnt = 0; |
3106 | stats->rx_cnt = 0; |
3107 | ewma_tp_init(e: &stats->tx_ewma_tp); |
3108 | ewma_tp_init(e: &stats->rx_ewma_tp); |
3109 | } |
3110 | |
3111 | static void rtw89_track_work(struct work_struct *work) |
3112 | { |
3113 | struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, |
3114 | track_work.work); |
3115 | bool tfc_changed; |
3116 | |
3117 | if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags)) |
3118 | return; |
3119 | |
3120 | mutex_lock(&rtwdev->mutex); |
3121 | |
3122 | if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) |
3123 | goto out; |
3124 | |
3125 | ieee80211_queue_delayed_work(hw: rtwdev->hw, dwork: &rtwdev->track_work, |
3126 | RTW89_TRACK_WORK_PERIOD); |
3127 | |
3128 | tfc_changed = rtw89_traffic_stats_track(rtwdev); |
3129 | if (rtwdev->scanning) |
3130 | goto out; |
3131 | |
3132 | rtw89_leave_lps(rtwdev); |
3133 | |
3134 | if (tfc_changed) { |
3135 | rtw89_hci_recalc_int_mit(rtwdev); |
3136 | rtw89_btc_ntfy_wl_sta(rtwdev); |
3137 | } |
3138 | rtw89_mac_bf_monitor_track(rtwdev); |
3139 | rtw89_phy_stat_track(rtwdev); |
3140 | rtw89_phy_env_monitor_track(rtwdev); |
3141 | rtw89_phy_dig(rtwdev); |
3142 | rtw89_core_rfk_track(rtwdev); |
3143 | rtw89_phy_ra_update(rtwdev); |
3144 | rtw89_phy_cfo_track(rtwdev); |
3145 | rtw89_phy_tx_path_div_track(rtwdev); |
3146 | rtw89_phy_antdiv_track(rtwdev); |
3147 | rtw89_phy_ul_tb_ctrl_track(rtwdev); |
3148 | rtw89_phy_edcca_track(rtwdev); |
3149 | rtw89_tas_track(rtwdev); |
3150 | rtw89_chanctx_track(rtwdev); |
3151 | |
3152 | if (rtwdev->lps_enabled && !rtwdev->btc.lps) |
3153 | rtw89_enter_lps_track(rtwdev); |
3154 | |
3155 | out: |
3156 | mutex_unlock(lock: &rtwdev->mutex); |
3157 | } |
3158 | |
3159 | u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size) |
3160 | { |
3161 | unsigned long bit; |
3162 | |
3163 | bit = find_first_zero_bit(addr, size); |
3164 | if (bit < size) |
3165 | set_bit(nr: bit, addr); |
3166 | |
3167 | return bit; |
3168 | } |
3169 | |
3170 | void rtw89_core_release_bit_map(unsigned long *addr, u8 bit) |
3171 | { |
3172 | clear_bit(nr: bit, addr); |
3173 | } |
3174 | |
3175 | void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits) |
3176 | { |
3177 | bitmap_zero(dst: addr, nbits); |
3178 | } |
3179 | |
3180 | int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, |
3181 | struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx) |
3182 | { |
3183 | const struct rtw89_chip_info *chip = rtwdev->chip; |
3184 | struct rtw89_cam_info *cam_info = &rtwdev->cam_info; |
3185 | struct rtw89_ba_cam_entry *entry = NULL, *tmp; |
3186 | u8 idx; |
3187 | int i; |
3188 | |
3189 | lockdep_assert_held(&rtwdev->mutex); |
3190 | |
3191 | idx = rtw89_core_acquire_bit_map(addr: cam_info->ba_cam_map, size: chip->bacam_num); |
3192 | if (idx == chip->bacam_num) { |
3193 | /* allocate a static BA CAM to tid=0/5, so replace the existing |
3194 | * one if BA CAM is full. Hardware will process the original tid |
3195 | * automatically. |
3196 | */ |
3197 | if (tid != 0 && tid != 5) |
3198 | return -ENOSPC; |
3199 | |
3200 | for_each_set_bit(i, cam_info->ba_cam_map, chip->bacam_num) { |
3201 | tmp = &cam_info->ba_cam_entry[i]; |
3202 | if (tmp->tid == 0 || tmp->tid == 5) |
3203 | continue; |
3204 | |
3205 | idx = i; |
3206 | entry = tmp; |
3207 | list_del(entry: &entry->list); |
3208 | break; |
3209 | } |
3210 | |
3211 | if (!entry) |
3212 | return -ENOSPC; |
3213 | } else { |
3214 | entry = &cam_info->ba_cam_entry[idx]; |
3215 | } |
3216 | |
3217 | entry->tid = tid; |
3218 | list_add_tail(new: &entry->list, head: &rtwsta->ba_cam_list); |
3219 | |
3220 | *cam_idx = idx; |
3221 | |
3222 | return 0; |
3223 | } |
3224 | |
3225 | int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev, |
3226 | struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx) |
3227 | { |
3228 | struct rtw89_cam_info *cam_info = &rtwdev->cam_info; |
3229 | struct rtw89_ba_cam_entry *entry = NULL, *tmp; |
3230 | u8 idx; |
3231 | |
3232 | lockdep_assert_held(&rtwdev->mutex); |
3233 | |
3234 | list_for_each_entry_safe(entry, tmp, &rtwsta->ba_cam_list, list) { |
3235 | if (entry->tid != tid) |
3236 | continue; |
3237 | |
3238 | idx = entry - cam_info->ba_cam_entry; |
3239 | list_del(entry: &entry->list); |
3240 | |
3241 | rtw89_core_release_bit_map(addr: cam_info->ba_cam_map, bit: idx); |
3242 | *cam_idx = idx; |
3243 | return 0; |
3244 | } |
3245 | |
3246 | return -ENOENT; |
3247 | } |
3248 | |
3249 | #define RTW89_TYPE_MAPPING(_type) \ |
3250 | case NL80211_IFTYPE_ ## _type: \ |
3251 | rtwvif->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ |
3252 | break |
3253 | void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) |
3254 | { |
3255 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
3256 | |
3257 | switch (vif->type) { |
3258 | case NL80211_IFTYPE_STATION: |
3259 | if (vif->p2p) |
3260 | rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT; |
3261 | else |
3262 | rtwvif->wifi_role = RTW89_WIFI_ROLE_STATION; |
3263 | break; |
3264 | case NL80211_IFTYPE_AP: |
3265 | if (vif->p2p) |
3266 | rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_GO; |
3267 | else |
3268 | rtwvif->wifi_role = RTW89_WIFI_ROLE_AP; |
3269 | break; |
3270 | RTW89_TYPE_MAPPING(ADHOC); |
3271 | RTW89_TYPE_MAPPING(MONITOR); |
3272 | RTW89_TYPE_MAPPING(MESH_POINT); |
3273 | default: |
3274 | WARN_ON(1); |
3275 | break; |
3276 | } |
3277 | |
3278 | switch (vif->type) { |
3279 | case NL80211_IFTYPE_AP: |
3280 | case NL80211_IFTYPE_MESH_POINT: |
3281 | rtwvif->net_type = RTW89_NET_TYPE_AP_MODE; |
3282 | rtwvif->self_role = RTW89_SELF_ROLE_AP; |
3283 | break; |
3284 | case NL80211_IFTYPE_ADHOC: |
3285 | rtwvif->net_type = RTW89_NET_TYPE_AD_HOC; |
3286 | rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; |
3287 | break; |
3288 | case NL80211_IFTYPE_STATION: |
3289 | if (assoc) { |
3290 | rtwvif->net_type = RTW89_NET_TYPE_INFRA; |
3291 | rtwvif->trigger = vif->bss_conf.he_support; |
3292 | } else { |
3293 | rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; |
3294 | rtwvif->trigger = false; |
3295 | } |
3296 | rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; |
3297 | rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; |
3298 | break; |
3299 | case NL80211_IFTYPE_MONITOR: |
3300 | break; |
3301 | default: |
3302 | WARN_ON(1); |
3303 | break; |
3304 | } |
3305 | } |
3306 | |
3307 | int rtw89_core_sta_add(struct rtw89_dev *rtwdev, |
3308 | struct ieee80211_vif *vif, |
3309 | struct ieee80211_sta *sta) |
3310 | { |
3311 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
3312 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
3313 | struct rtw89_hal *hal = &rtwdev->hal; |
3314 | u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num; |
3315 | int i; |
3316 | int ret; |
3317 | |
3318 | rtwsta->rtwdev = rtwdev; |
3319 | rtwsta->rtwvif = rtwvif; |
3320 | rtwsta->prev_rssi = 0; |
3321 | INIT_LIST_HEAD(list: &rtwsta->ba_cam_list); |
3322 | skb_queue_head_init(list: &rtwsta->roc_queue); |
3323 | |
3324 | for (i = 0; i < ARRAY_SIZE(sta->txq); i++) |
3325 | rtw89_core_txq_init(rtwdev, txq: sta->txq[i]); |
3326 | |
3327 | ewma_rssi_init(e: &rtwsta->avg_rssi); |
3328 | ewma_snr_init(e: &rtwsta->avg_snr); |
3329 | for (i = 0; i < ant_num; i++) { |
3330 | ewma_rssi_init(e: &rtwsta->rssi[i]); |
3331 | ewma_evm_init(e: &rtwsta->evm_min[i]); |
3332 | ewma_evm_init(e: &rtwsta->evm_max[i]); |
3333 | } |
3334 | |
3335 | if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { |
3336 | /* for station mode, assign the mac_id from itself */ |
3337 | rtwsta->mac_id = rtwvif->mac_id; |
3338 | /* must do rtw89_reg_6ghz_power_recalc() before rfk channel */ |
3339 | rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, active: true); |
3340 | rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, |
3341 | state: BTC_ROLE_MSTS_STA_CONN_START); |
3342 | rtw89_chip_rfk_channel(rtwdev); |
3343 | } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { |
3344 | rtwsta->mac_id = rtw89_core_acquire_bit_map(addr: rtwdev->mac_id_map, |
3345 | RTW89_MAX_MAC_ID_NUM); |
3346 | if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) |
3347 | return -ENOSPC; |
3348 | |
3349 | ret = rtw89_mac_set_macid_pause(rtwdev, macid: rtwsta->mac_id, pause: false); |
3350 | if (ret) { |
3351 | rtw89_core_release_bit_map(addr: rtwdev->mac_id_map, bit: rtwsta->mac_id); |
3352 | rtw89_warn(rtwdev, "failed to send h2c macid pause\n" ); |
3353 | return ret; |
3354 | } |
3355 | |
3356 | ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, |
3357 | upd_mode: RTW89_ROLE_CREATE); |
3358 | if (ret) { |
3359 | rtw89_core_release_bit_map(addr: rtwdev->mac_id_map, bit: rtwsta->mac_id); |
3360 | rtw89_warn(rtwdev, "failed to send h2c role info\n" ); |
3361 | return ret; |
3362 | } |
3363 | |
3364 | ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta); |
3365 | if (ret) |
3366 | return ret; |
3367 | |
3368 | ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta); |
3369 | if (ret) |
3370 | return ret; |
3371 | |
3372 | rtw89_queue_chanctx_change(rtwdev, change: RTW89_CHANCTX_REMOTE_STA_CHANGE); |
3373 | } |
3374 | |
3375 | return 0; |
3376 | } |
3377 | |
3378 | int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, |
3379 | struct ieee80211_vif *vif, |
3380 | struct ieee80211_sta *sta) |
3381 | { |
3382 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
3383 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
3384 | |
3385 | if (vif->type == NL80211_IFTYPE_STATION) |
3386 | rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, connect: false); |
3387 | |
3388 | rtwdev->total_sta_assoc--; |
3389 | if (sta->tdls) |
3390 | rtwvif->tdls_peer--; |
3391 | rtwsta->disassoc = true; |
3392 | |
3393 | return 0; |
3394 | } |
3395 | |
3396 | int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, |
3397 | struct ieee80211_vif *vif, |
3398 | struct ieee80211_sta *sta) |
3399 | { |
3400 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
3401 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
3402 | int ret; |
3403 | |
3404 | rtw89_mac_bf_monitor_calc(rtwdev, sta, disconnect: true); |
3405 | rtw89_mac_bf_disassoc(rtwdev, vif, sta); |
3406 | rtw89_core_free_sta_pending_ba(rtwdev, sta); |
3407 | rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta); |
3408 | rtw89_core_free_sta_pending_roc_tx(rtwdev, sta); |
3409 | |
3410 | if (vif->type == NL80211_IFTYPE_AP || sta->tdls) |
3411 | rtw89_cam_deinit_addr_cam(rtwdev, addr_cam: &rtwsta->addr_cam); |
3412 | if (sta->tdls) |
3413 | rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam: &rtwsta->bssid_cam); |
3414 | |
3415 | if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { |
3416 | rtw89_vif_type_mapping(vif, assoc: false); |
3417 | rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw: true); |
3418 | } |
3419 | |
3420 | ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta); |
3421 | if (ret) { |
3422 | rtw89_warn(rtwdev, "failed to send h2c cmac table\n" ); |
3423 | return ret; |
3424 | } |
3425 | |
3426 | ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, dis_conn: true); |
3427 | if (ret) { |
3428 | rtw89_warn(rtwdev, "failed to send h2c join info\n" ); |
3429 | return ret; |
3430 | } |
3431 | |
3432 | /* update cam aid mac_id net_type */ |
3433 | ret = rtw89_fw_h2c_cam(rtwdev, vif: rtwvif, rtwsta, NULL); |
3434 | if (ret) { |
3435 | rtw89_warn(rtwdev, "failed to send h2c cam\n" ); |
3436 | return ret; |
3437 | } |
3438 | |
3439 | return ret; |
3440 | } |
3441 | |
3442 | int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, |
3443 | struct ieee80211_vif *vif, |
3444 | struct ieee80211_sta *sta) |
3445 | { |
3446 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
3447 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
3448 | struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta); |
3449 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, |
3450 | idx: rtwvif->sub_entity_idx); |
3451 | int ret; |
3452 | |
3453 | if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { |
3454 | if (sta->tdls) { |
3455 | ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, bssid: sta->addr); |
3456 | if (ret) { |
3457 | rtw89_warn(rtwdev, "failed to send h2c init bssid cam for TDLS\n" ); |
3458 | return ret; |
3459 | } |
3460 | } |
3461 | |
3462 | ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam: &rtwsta->addr_cam, bssid_cam); |
3463 | if (ret) { |
3464 | rtw89_warn(rtwdev, "failed to send h2c init addr cam\n" ); |
3465 | return ret; |
3466 | } |
3467 | } |
3468 | |
3469 | ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta); |
3470 | if (ret) { |
3471 | rtw89_warn(rtwdev, "failed to send h2c cmac table\n" ); |
3472 | return ret; |
3473 | } |
3474 | |
3475 | ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, dis_conn: false); |
3476 | if (ret) { |
3477 | rtw89_warn(rtwdev, "failed to send h2c join info\n" ); |
3478 | return ret; |
3479 | } |
3480 | |
3481 | /* update cam aid mac_id net_type */ |
3482 | ret = rtw89_fw_h2c_cam(rtwdev, vif: rtwvif, rtwsta, NULL); |
3483 | if (ret) { |
3484 | rtw89_warn(rtwdev, "failed to send h2c cam\n" ); |
3485 | return ret; |
3486 | } |
3487 | |
3488 | rtwdev->total_sta_assoc++; |
3489 | if (sta->tdls) |
3490 | rtwvif->tdls_peer++; |
3491 | rtw89_phy_ra_assoc(rtwdev, sta); |
3492 | rtw89_mac_bf_assoc(rtwdev, vif, sta); |
3493 | rtw89_mac_bf_monitor_calc(rtwdev, sta, disconnect: false); |
3494 | |
3495 | if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { |
3496 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
3497 | |
3498 | if (bss_conf->he_support && |
3499 | !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)) |
3500 | rtwsta->er_cap = true; |
3501 | |
3502 | rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, |
3503 | state: BTC_ROLE_MSTS_STA_CONN_END); |
3504 | rtw89_core_get_no_ul_ofdma_htc(rtwdev, htc: &rtwsta->htc_template, chan); |
3505 | rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); |
3506 | |
3507 | ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, macid: rtwsta->mac_id); |
3508 | if (ret) { |
3509 | rtw89_warn(rtwdev, "failed to send h2c general packet\n" ); |
3510 | return ret; |
3511 | } |
3512 | |
3513 | rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, connect: true); |
3514 | } |
3515 | |
3516 | return ret; |
3517 | } |
3518 | |
3519 | int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, |
3520 | struct ieee80211_vif *vif, |
3521 | struct ieee80211_sta *sta) |
3522 | { |
3523 | struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; |
3524 | struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; |
3525 | int ret; |
3526 | |
3527 | if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { |
3528 | rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, active: false); |
3529 | rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, |
3530 | state: BTC_ROLE_MSTS_STA_DIS_CONN); |
3531 | } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { |
3532 | rtw89_core_release_bit_map(addr: rtwdev->mac_id_map, bit: rtwsta->mac_id); |
3533 | |
3534 | ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, |
3535 | upd_mode: RTW89_ROLE_REMOVE); |
3536 | if (ret) { |
3537 | rtw89_warn(rtwdev, "failed to send h2c role info\n" ); |
3538 | return ret; |
3539 | } |
3540 | |
3541 | rtw89_queue_chanctx_change(rtwdev, change: RTW89_CHANCTX_REMOTE_STA_CHANGE); |
3542 | } |
3543 | |
3544 | return 0; |
3545 | } |
3546 | |
3547 | static void _rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, |
3548 | struct ieee80211_sta *sta, |
3549 | struct cfg80211_tid_cfg *tid_conf) |
3550 | { |
3551 | struct ieee80211_txq *txq; |
3552 | struct rtw89_txq *rtwtxq; |
3553 | u32 mask = tid_conf->mask; |
3554 | u8 tids = tid_conf->tids; |
3555 | int tids_nbit = BITS_PER_BYTE; |
3556 | int i; |
3557 | |
3558 | for (i = 0; i < tids_nbit; i++, tids >>= 1) { |
3559 | if (!tids) |
3560 | break; |
3561 | |
3562 | if (!(tids & BIT(0))) |
3563 | continue; |
3564 | |
3565 | txq = sta->txq[i]; |
3566 | rtwtxq = (struct rtw89_txq *)txq->drv_priv; |
3567 | |
3568 | if (mask & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) { |
3569 | if (tid_conf->ampdu == NL80211_TID_CONFIG_ENABLE) { |
3570 | clear_bit(nr: RTW89_TXQ_F_FORBID_BA, addr: &rtwtxq->flags); |
3571 | } else { |
3572 | if (test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags)) |
3573 | ieee80211_stop_tx_ba_session(sta, tid: txq->tid); |
3574 | spin_lock_bh(lock: &rtwdev->ba_lock); |
3575 | list_del_init(entry: &rtwtxq->list); |
3576 | set_bit(nr: RTW89_TXQ_F_FORBID_BA, addr: &rtwtxq->flags); |
3577 | spin_unlock_bh(lock: &rtwdev->ba_lock); |
3578 | } |
3579 | } |
3580 | |
3581 | if (mask & BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL) && tids == 0xff) { |
3582 | if (tid_conf->amsdu == NL80211_TID_CONFIG_ENABLE) |
3583 | sta->max_amsdu_subframes = 0; |
3584 | else |
3585 | sta->max_amsdu_subframes = 1; |
3586 | } |
3587 | } |
3588 | } |
3589 | |
3590 | void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, |
3591 | struct ieee80211_sta *sta, |
3592 | struct cfg80211_tid_config *tid_config) |
3593 | { |
3594 | int i; |
3595 | |
3596 | for (i = 0; i < tid_config->n_tid_conf; i++) |
3597 | _rtw89_core_set_tid_config(rtwdev, sta, |
3598 | tid_conf: &tid_config->tid_conf[i]); |
3599 | } |
3600 | |
3601 | static void rtw89_init_ht_cap(struct rtw89_dev *rtwdev, |
3602 | struct ieee80211_sta_ht_cap *ht_cap) |
3603 | { |
3604 | static const __le16 highest[RF_PATH_MAX] = { |
3605 | cpu_to_le16(150), cpu_to_le16(300), cpu_to_le16(450), cpu_to_le16(600), |
3606 | }; |
3607 | struct rtw89_hal *hal = &rtwdev->hal; |
3608 | u8 nss = hal->rx_nss; |
3609 | int i; |
3610 | |
3611 | ht_cap->ht_supported = true; |
3612 | ht_cap->cap = 0; |
3613 | ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | |
3614 | IEEE80211_HT_CAP_MAX_AMSDU | |
3615 | IEEE80211_HT_CAP_TX_STBC | |
3616 | (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); |
3617 | ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; |
3618 | ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
3619 | IEEE80211_HT_CAP_DSSSCCK40 | |
3620 | IEEE80211_HT_CAP_SGI_40; |
3621 | ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
3622 | ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; |
3623 | ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
3624 | for (i = 0; i < nss; i++) |
3625 | ht_cap->mcs.rx_mask[i] = 0xFF; |
3626 | ht_cap->mcs.rx_mask[4] = 0x01; |
3627 | ht_cap->mcs.rx_highest = highest[nss - 1]; |
3628 | } |
3629 | |
3630 | static void rtw89_init_vht_cap(struct rtw89_dev *rtwdev, |
3631 | struct ieee80211_sta_vht_cap *vht_cap) |
3632 | { |
3633 | static const __le16 highest_bw80[RF_PATH_MAX] = { |
3634 | cpu_to_le16(433), cpu_to_le16(867), cpu_to_le16(1300), cpu_to_le16(1733), |
3635 | }; |
3636 | static const __le16 highest_bw160[RF_PATH_MAX] = { |
3637 | cpu_to_le16(867), cpu_to_le16(1733), cpu_to_le16(2600), cpu_to_le16(3467), |
3638 | }; |
3639 | const struct rtw89_chip_info *chip = rtwdev->chip; |
3640 | const __le16 *highest = chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160) ? |
3641 | highest_bw160 : highest_bw80; |
3642 | struct rtw89_hal *hal = &rtwdev->hal; |
3643 | u16 tx_mcs_map = 0, rx_mcs_map = 0; |
3644 | u8 sts_cap = 3; |
3645 | int i; |
3646 | |
3647 | for (i = 0; i < 8; i++) { |
3648 | if (i < hal->tx_nss) |
3649 | tx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); |
3650 | else |
3651 | tx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); |
3652 | if (i < hal->rx_nss) |
3653 | rx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); |
3654 | else |
3655 | rx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); |
3656 | } |
3657 | |
3658 | vht_cap->vht_supported = true; |
3659 | vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | |
3660 | IEEE80211_VHT_CAP_SHORT_GI_80 | |
3661 | IEEE80211_VHT_CAP_RXSTBC_1 | |
3662 | IEEE80211_VHT_CAP_HTC_VHT | |
3663 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | |
3664 | 0; |
3665 | vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; |
3666 | vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; |
3667 | vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | |
3668 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; |
3669 | vht_cap->cap |= sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; |
3670 | if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) |
3671 | vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ | |
3672 | IEEE80211_VHT_CAP_SHORT_GI_160; |
3673 | vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(rx_mcs_map); |
3674 | vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(tx_mcs_map); |
3675 | vht_cap->vht_mcs.rx_highest = highest[hal->rx_nss - 1]; |
3676 | vht_cap->vht_mcs.tx_highest = highest[hal->tx_nss - 1]; |
3677 | |
3678 | if (ieee80211_hw_check(rtwdev->hw, SUPPORTS_VHT_EXT_NSS_BW)) |
3679 | vht_cap->vht_mcs.tx_highest |= |
3680 | cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE); |
3681 | } |
3682 | |
3683 | static void rtw89_init_he_cap(struct rtw89_dev *rtwdev, |
3684 | enum nl80211_band band, |
3685 | enum nl80211_iftype iftype, |
3686 | struct ieee80211_sband_iftype_data *iftype_data) |
3687 | { |
3688 | const struct rtw89_chip_info *chip = rtwdev->chip; |
3689 | struct rtw89_hal *hal = &rtwdev->hal; |
3690 | bool no_ng16 = (chip->chip_id == RTL8852A && hal->cv == CHIP_CBV) || |
3691 | (chip->chip_id == RTL8852B && hal->cv == CHIP_CAV); |
3692 | struct ieee80211_sta_he_cap *he_cap; |
3693 | int nss = hal->rx_nss; |
3694 | u8 *mac_cap_info; |
3695 | u8 *phy_cap_info; |
3696 | u16 mcs_map = 0; |
3697 | int i; |
3698 | |
3699 | for (i = 0; i < 8; i++) { |
3700 | if (i < nss) |
3701 | mcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); |
3702 | else |
3703 | mcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); |
3704 | } |
3705 | |
3706 | he_cap = &iftype_data->he_cap; |
3707 | mac_cap_info = he_cap->he_cap_elem.mac_cap_info; |
3708 | phy_cap_info = he_cap->he_cap_elem.phy_cap_info; |
3709 | |
3710 | he_cap->has_he = true; |
3711 | mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE; |
3712 | if (iftype == NL80211_IFTYPE_STATION) |
3713 | mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; |
3714 | mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_ALL_ACK | |
3715 | IEEE80211_HE_MAC_CAP2_BSR; |
3716 | mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2; |
3717 | if (iftype == NL80211_IFTYPE_AP) |
3718 | mac_cap_info[3] |= IEEE80211_HE_MAC_CAP3_OMI_CONTROL; |
3719 | mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_OPS | |
3720 | IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; |
3721 | if (iftype == NL80211_IFTYPE_STATION) |
3722 | mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX; |
3723 | if (band == NL80211_BAND_2GHZ) { |
3724 | phy_cap_info[0] = |
3725 | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; |
3726 | } else { |
3727 | phy_cap_info[0] = |
3728 | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; |
3729 | if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) |
3730 | phy_cap_info[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; |
3731 | } |
3732 | phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | |
3733 | IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD | |
3734 | IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; |
3735 | phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | |
3736 | IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | |
3737 | IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ | |
3738 | IEEE80211_HE_PHY_CAP2_DOPPLER_TX; |
3739 | phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM; |
3740 | if (iftype == NL80211_IFTYPE_STATION) |
3741 | phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM | |
3742 | IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2; |
3743 | if (iftype == NL80211_IFTYPE_AP) |
3744 | phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; |
3745 | phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | |
3746 | IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; |
3747 | if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) |
3748 | phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; |
3749 | phy_cap_info[5] = no_ng16 ? 0 : |
3750 | IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | |
3751 | IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; |
3752 | phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | |
3753 | IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | |
3754 | IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | |
3755 | IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE; |
3756 | phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | |
3757 | IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | |
3758 | IEEE80211_HE_PHY_CAP7_MAX_NC_1; |
3759 | phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | |
3760 | IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI | |
3761 | IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996; |
3762 | if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) |
3763 | phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | |
3764 | IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU; |
3765 | phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM | |
3766 | IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | |
3767 | IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | |
3768 | IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB | |
3769 | u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US, |
3770 | IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK); |
3771 | if (iftype == NL80211_IFTYPE_STATION) |
3772 | phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; |
3773 | he_cap->he_mcs_nss_supp.rx_mcs_80 = cpu_to_le16(mcs_map); |
3774 | he_cap->he_mcs_nss_supp.tx_mcs_80 = cpu_to_le16(mcs_map); |
3775 | if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) { |
3776 | he_cap->he_mcs_nss_supp.rx_mcs_160 = cpu_to_le16(mcs_map); |
3777 | he_cap->he_mcs_nss_supp.tx_mcs_160 = cpu_to_le16(mcs_map); |
3778 | } |
3779 | |
3780 | if (band == NL80211_BAND_6GHZ) { |
3781 | __le16 capa; |
3782 | |
3783 | capa = le16_encode_bits(v: IEEE80211_HT_MPDU_DENSITY_NONE, |
3784 | IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) | |
3785 | le16_encode_bits(v: IEEE80211_VHT_MAX_AMPDU_1024K, |
3786 | IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) | |
3787 | le16_encode_bits(IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, |
3788 | IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN); |
3789 | iftype_data->he_6ghz_capa.capa = capa; |
3790 | } |
3791 | } |
3792 | |
3793 | static void rtw89_init_eht_cap(struct rtw89_dev *rtwdev, |
3794 | enum nl80211_band band, |
3795 | enum nl80211_iftype iftype, |
3796 | struct ieee80211_sband_iftype_data *iftype_data) |
3797 | { |
3798 | const struct rtw89_chip_info *chip = rtwdev->chip; |
3799 | struct ieee80211_eht_cap_elem_fixed *eht_cap_elem; |
3800 | struct ieee80211_eht_mcs_nss_supp *eht_nss; |
3801 | struct ieee80211_sta_eht_cap *eht_cap; |
3802 | struct rtw89_hal *hal = &rtwdev->hal; |
3803 | bool support_320mhz = false; |
3804 | int sts = 8; |
3805 | u8 val; |
3806 | |
3807 | if (chip->chip_gen == RTW89_CHIP_AX) |
3808 | return; |
3809 | |
3810 | if (band == NL80211_BAND_6GHZ && |
3811 | chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_320)) |
3812 | support_320mhz = true; |
3813 | |
3814 | eht_cap = &iftype_data->eht_cap; |
3815 | eht_cap_elem = &eht_cap->eht_cap_elem; |
3816 | eht_nss = &eht_cap->eht_mcs_nss_supp; |
3817 | |
3818 | eht_cap->has_eht = true; |
3819 | |
3820 | eht_cap_elem->mac_cap_info[0] = |
3821 | u8_encode_bits(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991, |
3822 | IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); |
3823 | eht_cap_elem->mac_cap_info[1] = 0; |
3824 | |
3825 | eht_cap_elem->phy_cap_info[0] = |
3826 | IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | |
3827 | IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE; |
3828 | if (support_320mhz) |
3829 | eht_cap_elem->phy_cap_info[0] |= |
3830 | IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; |
3831 | |
3832 | eht_cap_elem->phy_cap_info[0] |= |
3833 | u8_encode_bits(v: u8_get_bits(v: sts - 1, BIT(0)), |
3834 | IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK); |
3835 | eht_cap_elem->phy_cap_info[1] = |
3836 | u8_encode_bits(v: u8_get_bits(v: sts - 1, GENMASK(2, 1)), |
3837 | IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) | |
3838 | u8_encode_bits(v: sts - 1, |
3839 | IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK); |
3840 | if (support_320mhz) |
3841 | eht_cap_elem->phy_cap_info[1] |= |
3842 | u8_encode_bits(v: sts - 1, |
3843 | IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK); |
3844 | |
3845 | eht_cap_elem->phy_cap_info[2] = 0; |
3846 | |
3847 | eht_cap_elem->phy_cap_info[3] = |
3848 | IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK | |
3849 | IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | |
3850 | IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK | |
3851 | IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK; |
3852 | |
3853 | eht_cap_elem->phy_cap_info[4] = |
3854 | IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP | |
3855 | u8_encode_bits(v: 1, IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK); |
3856 | |
3857 | eht_cap_elem->phy_cap_info[5] = |
3858 | u8_encode_bits(IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US, |
3859 | IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK); |
3860 | |
3861 | eht_cap_elem->phy_cap_info[6] = 0; |
3862 | eht_cap_elem->phy_cap_info[7] = 0; |
3863 | eht_cap_elem->phy_cap_info[8] = 0; |
3864 | |
3865 | val = u8_encode_bits(v: hal->rx_nss, IEEE80211_EHT_MCS_NSS_RX) | |
3866 | u8_encode_bits(v: hal->tx_nss, IEEE80211_EHT_MCS_NSS_TX); |
3867 | eht_nss->bw._80.rx_tx_mcs9_max_nss = val; |
3868 | eht_nss->bw._80.rx_tx_mcs11_max_nss = val; |
3869 | eht_nss->bw._80.rx_tx_mcs13_max_nss = val; |
3870 | eht_nss->bw._160.rx_tx_mcs9_max_nss = val; |
3871 | eht_nss->bw._160.rx_tx_mcs11_max_nss = val; |
3872 | eht_nss->bw._160.rx_tx_mcs13_max_nss = val; |
3873 | if (support_320mhz) { |
3874 | eht_nss->bw._320.rx_tx_mcs9_max_nss = val; |
3875 | eht_nss->bw._320.rx_tx_mcs11_max_nss = val; |
3876 | eht_nss->bw._320.rx_tx_mcs13_max_nss = val; |
3877 | } |
3878 | } |
3879 | |
3880 | #define RTW89_SBAND_IFTYPES_NR 2 |
3881 | |
3882 | static void rtw89_init_he_eht_cap(struct rtw89_dev *rtwdev, |
3883 | enum nl80211_band band, |
3884 | struct ieee80211_supported_band *sband) |
3885 | { |
3886 | struct ieee80211_sband_iftype_data *iftype_data; |
3887 | enum nl80211_iftype iftype; |
3888 | int idx = 0; |
3889 | |
3890 | iftype_data = kcalloc(RTW89_SBAND_IFTYPES_NR, size: sizeof(*iftype_data), GFP_KERNEL); |
3891 | if (!iftype_data) |
3892 | return; |
3893 | |
3894 | for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { |
3895 | switch (iftype) { |
3896 | case NL80211_IFTYPE_STATION: |
3897 | case NL80211_IFTYPE_AP: |
3898 | break; |
3899 | default: |
3900 | continue; |
3901 | } |
3902 | |
3903 | if (idx >= RTW89_SBAND_IFTYPES_NR) { |
3904 | rtw89_warn(rtwdev, "run out of iftype_data\n" ); |
3905 | break; |
3906 | } |
3907 | |
3908 | iftype_data[idx].types_mask = BIT(iftype); |
3909 | |
3910 | rtw89_init_he_cap(rtwdev, band, iftype, iftype_data: &iftype_data[idx]); |
3911 | rtw89_init_eht_cap(rtwdev, band, iftype, iftype_data: &iftype_data[idx]); |
3912 | |
3913 | idx++; |
3914 | } |
3915 | |
3916 | _ieee80211_set_sband_iftype_data(sband, iftd: iftype_data, n_iftd: idx); |
3917 | } |
3918 | |
3919 | static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) |
3920 | { |
3921 | struct ieee80211_hw *hw = rtwdev->hw; |
3922 | struct ieee80211_supported_band *sband_2ghz = NULL, *sband_5ghz = NULL; |
3923 | struct ieee80211_supported_band *sband_6ghz = NULL; |
3924 | u32 size = sizeof(struct ieee80211_supported_band); |
3925 | u8 support_bands = rtwdev->chip->support_bands; |
3926 | |
3927 | if (support_bands & BIT(NL80211_BAND_2GHZ)) { |
3928 | sband_2ghz = kmemdup(p: &rtw89_sband_2ghz, size, GFP_KERNEL); |
3929 | if (!sband_2ghz) |
3930 | goto err; |
3931 | rtw89_init_ht_cap(rtwdev, ht_cap: &sband_2ghz->ht_cap); |
3932 | rtw89_init_he_eht_cap(rtwdev, band: NL80211_BAND_2GHZ, sband: sband_2ghz); |
3933 | hw->wiphy->bands[NL80211_BAND_2GHZ] = sband_2ghz; |
3934 | } |
3935 | |
3936 | if (support_bands & BIT(NL80211_BAND_5GHZ)) { |
3937 | sband_5ghz = kmemdup(p: &rtw89_sband_5ghz, size, GFP_KERNEL); |
3938 | if (!sband_5ghz) |
3939 | goto err; |
3940 | rtw89_init_ht_cap(rtwdev, ht_cap: &sband_5ghz->ht_cap); |
3941 | rtw89_init_vht_cap(rtwdev, vht_cap: &sband_5ghz->vht_cap); |
3942 | rtw89_init_he_eht_cap(rtwdev, band: NL80211_BAND_5GHZ, sband: sband_5ghz); |
3943 | hw->wiphy->bands[NL80211_BAND_5GHZ] = sband_5ghz; |
3944 | } |
3945 | |
3946 | if (support_bands & BIT(NL80211_BAND_6GHZ)) { |
3947 | sband_6ghz = kmemdup(p: &rtw89_sband_6ghz, size, GFP_KERNEL); |
3948 | if (!sband_6ghz) |
3949 | goto err; |
3950 | rtw89_init_he_eht_cap(rtwdev, band: NL80211_BAND_6GHZ, sband: sband_6ghz); |
3951 | hw->wiphy->bands[NL80211_BAND_6GHZ] = sband_6ghz; |
3952 | } |
3953 | |
3954 | return 0; |
3955 | |
3956 | err: |
3957 | hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; |
3958 | hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; |
3959 | hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL; |
3960 | if (sband_2ghz) |
3961 | kfree(objp: (__force void *)sband_2ghz->iftype_data); |
3962 | if (sband_5ghz) |
3963 | kfree(objp: (__force void *)sband_5ghz->iftype_data); |
3964 | if (sband_6ghz) |
3965 | kfree(objp: (__force void *)sband_6ghz->iftype_data); |
3966 | kfree(objp: sband_2ghz); |
3967 | kfree(objp: sband_5ghz); |
3968 | kfree(objp: sband_6ghz); |
3969 | return -ENOMEM; |
3970 | } |
3971 | |
3972 | static void rtw89_core_clr_supported_band(struct rtw89_dev *rtwdev) |
3973 | { |
3974 | struct ieee80211_hw *hw = rtwdev->hw; |
3975 | |
3976 | if (hw->wiphy->bands[NL80211_BAND_2GHZ]) |
3977 | kfree(objp: (__force void *)hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data); |
3978 | if (hw->wiphy->bands[NL80211_BAND_5GHZ]) |
3979 | kfree(objp: (__force void *)hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data); |
3980 | if (hw->wiphy->bands[NL80211_BAND_6GHZ]) |
3981 | kfree(objp: (__force void *)hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data); |
3982 | kfree(objp: hw->wiphy->bands[NL80211_BAND_2GHZ]); |
3983 | kfree(objp: hw->wiphy->bands[NL80211_BAND_5GHZ]); |
3984 | kfree(objp: hw->wiphy->bands[NL80211_BAND_6GHZ]); |
3985 | hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; |
3986 | hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; |
3987 | hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL; |
3988 | } |
3989 | |
3990 | static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) |
3991 | { |
3992 | int i; |
3993 | |
3994 | for (i = 0; i < RTW89_PHY_MAX; i++) |
3995 | skb_queue_head_init(list: &rtwdev->ppdu_sts.rx_queue[i]); |
3996 | for (i = 0; i < RTW89_PHY_MAX; i++) |
3997 | rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX; |
3998 | } |
3999 | |
4000 | void rtw89_core_update_beacon_work(struct work_struct *work) |
4001 | { |
4002 | struct rtw89_dev *rtwdev; |
4003 | struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, |
4004 | update_beacon_work); |
4005 | |
4006 | if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE) |
4007 | return; |
4008 | |
4009 | rtwdev = rtwvif->rtwdev; |
4010 | mutex_lock(&rtwdev->mutex); |
4011 | rtw89_chip_h2c_update_beacon(rtwdev, rtwvif); |
4012 | mutex_unlock(lock: &rtwdev->mutex); |
4013 | } |
4014 | |
4015 | int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond) |
4016 | { |
4017 | struct completion *cmpl = &wait->completion; |
4018 | unsigned long timeout; |
4019 | unsigned int cur; |
4020 | |
4021 | cur = atomic_cmpxchg(v: &wait->cond, RTW89_WAIT_COND_IDLE, new: cond); |
4022 | if (cur != RTW89_WAIT_COND_IDLE) |
4023 | return -EBUSY; |
4024 | |
4025 | timeout = wait_for_completion_timeout(x: cmpl, RTW89_WAIT_FOR_COND_TIMEOUT); |
4026 | if (timeout == 0) { |
4027 | atomic_set(v: &wait->cond, RTW89_WAIT_COND_IDLE); |
4028 | return -ETIMEDOUT; |
4029 | } |
4030 | |
4031 | if (wait->data.err) |
4032 | return -EFAULT; |
4033 | |
4034 | return 0; |
4035 | } |
4036 | |
4037 | void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, |
4038 | const struct rtw89_completion_data *data) |
4039 | { |
4040 | unsigned int cur; |
4041 | |
4042 | cur = atomic_cmpxchg(v: &wait->cond, old: cond, RTW89_WAIT_COND_IDLE); |
4043 | if (cur != cond) |
4044 | return; |
4045 | |
4046 | wait->data = *data; |
4047 | complete(&wait->completion); |
4048 | } |
4049 | |
4050 | void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event) |
4051 | { |
4052 | u16 bt_req_len; |
4053 | |
4054 | switch (event) { |
4055 | case RTW89_BTC_HMSG_SET_BT_REQ_SLOT: |
4056 | bt_req_len = rtw89_coex_query_bt_req_len(rtwdev, phy_idx: RTW89_PHY_0); |
4057 | rtw89_debug(rtwdev, mask: RTW89_DBG_BTC, |
4058 | fmt: "coex updates BT req len to %d TU\n" , bt_req_len); |
4059 | rtw89_queue_chanctx_change(rtwdev, change: RTW89_CHANCTX_BT_SLOT_CHANGE); |
4060 | break; |
4061 | default: |
4062 | if (event < NUM_OF_RTW89_BTC_HMSG) |
4063 | rtw89_debug(rtwdev, mask: RTW89_DBG_BTC, |
4064 | fmt: "unhandled BTC HMSG event: %d\n" , event); |
4065 | else |
4066 | rtw89_warn(rtwdev, |
4067 | "unrecognized BTC HMSG event: %d\n" , event); |
4068 | break; |
4069 | } |
4070 | } |
4071 | |
4072 | int rtw89_core_start(struct rtw89_dev *rtwdev) |
4073 | { |
4074 | int ret; |
4075 | |
4076 | ret = rtw89_mac_init(rtwdev); |
4077 | if (ret) { |
4078 | rtw89_err(rtwdev, "mac init fail, ret:%d\n" , ret); |
4079 | return ret; |
4080 | } |
4081 | |
4082 | rtw89_btc_ntfy_poweron(rtwdev); |
4083 | |
4084 | /* efuse process */ |
4085 | |
4086 | /* pre-config BB/RF, BB reset/RFC reset */ |
4087 | ret = rtw89_chip_reset_bb_rf(rtwdev); |
4088 | if (ret) |
4089 | return ret; |
4090 | |
4091 | rtw89_phy_init_bb_reg(rtwdev); |
4092 | rtw89_chip_bb_postinit(rtwdev); |
4093 | rtw89_phy_init_rf_reg(rtwdev, noio: false); |
4094 | |
4095 | rtw89_btc_ntfy_init(rtwdev, mode: BTC_MODE_NORMAL); |
4096 | |
4097 | rtw89_phy_dm_init(rtwdev); |
4098 | |
4099 | rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx: RTW89_MAC_0, enable: true); |
4100 | rtw89_mac_update_rts_threshold(rtwdev, mac_idx: RTW89_MAC_0); |
4101 | |
4102 | rtw89_tas_reset(rtwdev); |
4103 | |
4104 | ret = rtw89_hci_start(rtwdev); |
4105 | if (ret) { |
4106 | rtw89_err(rtwdev, "failed to start hci\n" ); |
4107 | return ret; |
4108 | } |
4109 | |
4110 | ieee80211_queue_delayed_work(hw: rtwdev->hw, dwork: &rtwdev->track_work, |
4111 | RTW89_TRACK_WORK_PERIOD); |
4112 | |
4113 | set_bit(nr: RTW89_FLAG_RUNNING, addr: rtwdev->flags); |
4114 | |
4115 | rtw89_chip_rfk_init_late(rtwdev); |
4116 | rtw89_btc_ntfy_radio_state(rtwdev, rf_state: BTC_RFCTRL_WL_ON); |
4117 | rtw89_fw_h2c_fw_log(rtwdev, enable: rtwdev->fw.log.enable); |
4118 | rtw89_fw_h2c_init_ba_cam(rtwdev); |
4119 | |
4120 | return 0; |
4121 | } |
4122 | |
4123 | void rtw89_core_stop(struct rtw89_dev *rtwdev) |
4124 | { |
4125 | struct rtw89_btc *btc = &rtwdev->btc; |
4126 | |
4127 | /* Prvent to stop twice; enter_ips and ops_stop */ |
4128 | if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) |
4129 | return; |
4130 | |
4131 | rtw89_btc_ntfy_radio_state(rtwdev, rf_state: BTC_RFCTRL_WL_OFF); |
4132 | |
4133 | clear_bit(nr: RTW89_FLAG_RUNNING, addr: rtwdev->flags); |
4134 | |
4135 | mutex_unlock(lock: &rtwdev->mutex); |
4136 | |
4137 | cancel_work_sync(work: &rtwdev->c2h_work); |
4138 | cancel_work_sync(work: &rtwdev->cancel_6ghz_probe_work); |
4139 | cancel_work_sync(work: &btc->eapol_notify_work); |
4140 | cancel_work_sync(work: &btc->arp_notify_work); |
4141 | cancel_work_sync(work: &btc->dhcp_notify_work); |
4142 | cancel_work_sync(work: &btc->icmp_notify_work); |
4143 | cancel_delayed_work_sync(dwork: &rtwdev->txq_reinvoke_work); |
4144 | cancel_delayed_work_sync(dwork: &rtwdev->track_work); |
4145 | cancel_delayed_work_sync(dwork: &rtwdev->chanctx_work); |
4146 | cancel_delayed_work_sync(dwork: &rtwdev->coex_act1_work); |
4147 | cancel_delayed_work_sync(dwork: &rtwdev->coex_bt_devinfo_work); |
4148 | cancel_delayed_work_sync(dwork: &rtwdev->coex_rfk_chk_work); |
4149 | cancel_delayed_work_sync(dwork: &rtwdev->cfo_track_work); |
4150 | cancel_delayed_work_sync(dwork: &rtwdev->forbid_ba_work); |
4151 | cancel_delayed_work_sync(dwork: &rtwdev->antdiv_work); |
4152 | |
4153 | mutex_lock(&rtwdev->mutex); |
4154 | |
4155 | rtw89_btc_ntfy_poweroff(rtwdev); |
4156 | rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, drop: true); |
4157 | rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, drop: true); |
4158 | rtw89_hci_stop(rtwdev); |
4159 | rtw89_hci_deinit(rtwdev); |
4160 | rtw89_mac_pwr_off(rtwdev); |
4161 | rtw89_hci_reset(rtwdev); |
4162 | } |
4163 | |
4164 | int rtw89_core_init(struct rtw89_dev *rtwdev) |
4165 | { |
4166 | struct rtw89_btc *btc = &rtwdev->btc; |
4167 | u8 band; |
4168 | |
4169 | INIT_LIST_HEAD(list: &rtwdev->ba_list); |
4170 | INIT_LIST_HEAD(list: &rtwdev->forbid_ba_list); |
4171 | INIT_LIST_HEAD(list: &rtwdev->rtwvifs_list); |
4172 | INIT_LIST_HEAD(list: &rtwdev->early_h2c_list); |
4173 | for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { |
4174 | if (!(rtwdev->chip->support_bands & BIT(band))) |
4175 | continue; |
4176 | INIT_LIST_HEAD(list: &rtwdev->scan_info.pkt_list[band]); |
4177 | } |
4178 | INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); |
4179 | INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); |
4180 | INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); |
4181 | INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work); |
4182 | INIT_DELAYED_WORK(&rtwdev->chanctx_work, rtw89_chanctx_work); |
4183 | INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work); |
4184 | INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); |
4185 | INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); |
4186 | INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); |
4187 | INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work); |
4188 | INIT_DELAYED_WORK(&rtwdev->antdiv_work, rtw89_phy_antdiv_work); |
4189 | rtwdev->txq_wq = alloc_workqueue(fmt: "rtw89_tx_wq" , flags: WQ_UNBOUND | WQ_HIGHPRI, max_active: 0); |
4190 | if (!rtwdev->txq_wq) |
4191 | return -ENOMEM; |
4192 | spin_lock_init(&rtwdev->ba_lock); |
4193 | spin_lock_init(&rtwdev->rpwm_lock); |
4194 | mutex_init(&rtwdev->mutex); |
4195 | mutex_init(&rtwdev->rf_mutex); |
4196 | rtwdev->total_sta_assoc = 0; |
4197 | |
4198 | rtw89_init_wait(wait: &rtwdev->mcc.wait); |
4199 | rtw89_init_wait(wait: &rtwdev->mac.fw_ofld_wait); |
4200 | |
4201 | INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); |
4202 | INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); |
4203 | INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); |
4204 | INIT_WORK(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); |
4205 | |
4206 | skb_queue_head_init(list: &rtwdev->c2h_queue); |
4207 | rtw89_core_ppdu_sts_init(rtwdev); |
4208 | rtw89_traffic_stats_init(rtwdev, stats: &rtwdev->stats); |
4209 | |
4210 | rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR; |
4211 | rtwdev->dbcc_en = false; |
4212 | rtwdev->mlo_dbcc_mode = MLO_DBCC_NOT_SUPPORT; |
4213 | rtwdev->mac.qta_mode = RTW89_QTA_SCC; |
4214 | |
4215 | if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { |
4216 | rtwdev->dbcc_en = true; |
4217 | rtwdev->mac.qta_mode = RTW89_QTA_DBCC; |
4218 | rtwdev->mlo_dbcc_mode = MLO_2_PLUS_0_1RF; |
4219 | } |
4220 | |
4221 | INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); |
4222 | INIT_WORK(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work); |
4223 | INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); |
4224 | INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); |
4225 | |
4226 | init_completion(x: &rtwdev->fw.req.completion); |
4227 | init_completion(x: &rtwdev->rfk_wait.completion); |
4228 | |
4229 | schedule_work(work: &rtwdev->load_firmware_work); |
4230 | |
4231 | rtw89_ser_init(rtwdev); |
4232 | rtw89_entity_init(rtwdev); |
4233 | rtw89_tas_init(rtwdev); |
4234 | |
4235 | return 0; |
4236 | } |
4237 | EXPORT_SYMBOL(rtw89_core_init); |
4238 | |
4239 | void rtw89_core_deinit(struct rtw89_dev *rtwdev) |
4240 | { |
4241 | rtw89_ser_deinit(rtwdev); |
4242 | rtw89_unload_firmware(rtwdev); |
4243 | rtw89_fw_free_all_early_h2c(rtwdev); |
4244 | |
4245 | destroy_workqueue(wq: rtwdev->txq_wq); |
4246 | mutex_destroy(lock: &rtwdev->rf_mutex); |
4247 | mutex_destroy(lock: &rtwdev->mutex); |
4248 | } |
4249 | EXPORT_SYMBOL(rtw89_core_deinit); |
4250 | |
4251 | void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, |
4252 | const u8 *mac_addr, bool hw_scan) |
4253 | { |
4254 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, |
4255 | idx: rtwvif->sub_entity_idx); |
4256 | |
4257 | rtwdev->scanning = true; |
4258 | rtw89_leave_lps(rtwdev); |
4259 | if (hw_scan) |
4260 | rtw89_leave_ips_by_hwflags(rtwdev); |
4261 | |
4262 | ether_addr_copy(dst: rtwvif->mac_addr, src: mac_addr); |
4263 | rtw89_btc_ntfy_scan_start(rtwdev, phy_idx: RTW89_PHY_0, band: chan->band_type); |
4264 | rtw89_chip_rfk_scan(rtwdev, start: true); |
4265 | rtw89_hci_recalc_int_mit(rtwdev); |
4266 | rtw89_phy_config_edcca(rtwdev, scan: true); |
4267 | |
4268 | rtw89_fw_h2c_cam(rtwdev, vif: rtwvif, NULL, scan_mac_addr: mac_addr); |
4269 | } |
4270 | |
4271 | void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, |
4272 | struct ieee80211_vif *vif, bool hw_scan) |
4273 | { |
4274 | struct rtw89_vif *rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL; |
4275 | |
4276 | if (!rtwvif) |
4277 | return; |
4278 | |
4279 | ether_addr_copy(dst: rtwvif->mac_addr, src: vif->addr); |
4280 | rtw89_fw_h2c_cam(rtwdev, vif: rtwvif, NULL, NULL); |
4281 | |
4282 | rtw89_chip_rfk_scan(rtwdev, start: false); |
4283 | rtw89_btc_ntfy_scan_finish(rtwdev, phy_idx: RTW89_PHY_0); |
4284 | rtw89_phy_config_edcca(rtwdev, scan: false); |
4285 | |
4286 | rtwdev->scanning = false; |
4287 | rtwdev->dig.bypass_dig = true; |
4288 | if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) |
4289 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->ips_work); |
4290 | } |
4291 | |
4292 | static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) |
4293 | { |
4294 | const struct rtw89_chip_info *chip = rtwdev->chip; |
4295 | int ret; |
4296 | u8 val; |
4297 | u8 cv; |
4298 | |
4299 | cv = rtw89_read32_mask(rtwdev, R_AX_SYS_CFG1, B_AX_CHIP_VER_MASK); |
4300 | if (chip->chip_id == RTL8852A && cv <= CHIP_CBV) { |
4301 | if (rtw89_read32(rtwdev, R_AX_GPIO0_7_FUNC_SEL) == RTW89_R32_DEAD) |
4302 | cv = CHIP_CAV; |
4303 | else |
4304 | cv = CHIP_CBV; |
4305 | } |
4306 | |
4307 | rtwdev->hal.cv = cv; |
4308 | |
4309 | if (chip->chip_id == RTL8852B || chip->chip_id == RTL8851B) { |
4310 | ret = rtw89_mac_read_xtal_si(rtwdev, offset: XTAL_SI_CV, val: &val); |
4311 | if (ret) |
4312 | return; |
4313 | |
4314 | rtwdev->hal.acv = u8_get_bits(v: val, XTAL_SI_ACV_MASK); |
4315 | } |
4316 | } |
4317 | |
4318 | static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev) |
4319 | { |
4320 | rtwdev->hal.support_cckpd = |
4321 | !(rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV) && |
4322 | !(rtwdev->chip->chip_id == RTL8852B && rtwdev->hal.cv <= CHIP_CAV); |
4323 | rtwdev->hal.support_igi = |
4324 | rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV; |
4325 | } |
4326 | |
4327 | static void rtw89_core_setup_rfe_parms(struct rtw89_dev *rtwdev) |
4328 | { |
4329 | const struct rtw89_chip_info *chip = rtwdev->chip; |
4330 | const struct rtw89_rfe_parms_conf *conf = chip->rfe_parms_conf; |
4331 | struct rtw89_efuse *efuse = &rtwdev->efuse; |
4332 | const struct rtw89_rfe_parms *sel; |
4333 | u8 rfe_type = efuse->rfe_type; |
4334 | |
4335 | if (!conf) { |
4336 | sel = chip->dflt_parms; |
4337 | goto out; |
4338 | } |
4339 | |
4340 | while (conf->rfe_parms) { |
4341 | if (rfe_type == conf->rfe_type) { |
4342 | sel = conf->rfe_parms; |
4343 | goto out; |
4344 | } |
4345 | conf++; |
4346 | } |
4347 | |
4348 | sel = chip->dflt_parms; |
4349 | |
4350 | out: |
4351 | rtwdev->rfe_parms = rtw89_load_rfe_data_from_fw(rtwdev, init: sel); |
4352 | rtw89_load_txpwr_table(rtwdev, tbl: rtwdev->rfe_parms->byr_tbl); |
4353 | } |
4354 | |
4355 | static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) |
4356 | { |
4357 | const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; |
4358 | int ret; |
4359 | |
4360 | ret = rtw89_mac_partial_init(rtwdev, include_bb: false); |
4361 | if (ret) |
4362 | return ret; |
4363 | |
4364 | ret = mac->parse_efuse_map(rtwdev); |
4365 | if (ret) |
4366 | return ret; |
4367 | |
4368 | ret = mac->parse_phycap_map(rtwdev); |
4369 | if (ret) |
4370 | return ret; |
4371 | |
4372 | ret = rtw89_mac_setup_phycap(rtwdev); |
4373 | if (ret) |
4374 | return ret; |
4375 | |
4376 | rtw89_core_setup_phycap(rtwdev); |
4377 | |
4378 | rtw89_hci_mac_pre_deinit(rtwdev); |
4379 | |
4380 | rtw89_mac_pwr_off(rtwdev); |
4381 | |
4382 | return 0; |
4383 | } |
4384 | |
4385 | static int rtw89_chip_board_info_setup(struct rtw89_dev *rtwdev) |
4386 | { |
4387 | rtw89_chip_fem_setup(rtwdev); |
4388 | |
4389 | return 0; |
4390 | } |
4391 | |
4392 | int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) |
4393 | { |
4394 | int ret; |
4395 | |
4396 | rtw89_read_chip_ver(rtwdev); |
4397 | |
4398 | ret = rtw89_wait_firmware_completion(rtwdev); |
4399 | if (ret) { |
4400 | rtw89_err(rtwdev, "failed to wait firmware completion\n" ); |
4401 | return ret; |
4402 | } |
4403 | |
4404 | ret = rtw89_fw_recognize(rtwdev); |
4405 | if (ret) { |
4406 | rtw89_err(rtwdev, "failed to recognize firmware\n" ); |
4407 | return ret; |
4408 | } |
4409 | |
4410 | ret = rtw89_chip_efuse_info_setup(rtwdev); |
4411 | if (ret) |
4412 | return ret; |
4413 | |
4414 | ret = rtw89_fw_recognize_elements(rtwdev); |
4415 | if (ret) { |
4416 | rtw89_err(rtwdev, "failed to recognize firmware elements\n" ); |
4417 | return ret; |
4418 | } |
4419 | |
4420 | ret = rtw89_chip_board_info_setup(rtwdev); |
4421 | if (ret) |
4422 | return ret; |
4423 | |
4424 | rtw89_core_setup_rfe_parms(rtwdev); |
4425 | rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); |
4426 | |
4427 | return 0; |
4428 | } |
4429 | EXPORT_SYMBOL(rtw89_chip_info_setup); |
4430 | |
4431 | static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) |
4432 | { |
4433 | const struct rtw89_chip_info *chip = rtwdev->chip; |
4434 | struct ieee80211_hw *hw = rtwdev->hw; |
4435 | struct rtw89_efuse *efuse = &rtwdev->efuse; |
4436 | struct rtw89_hal *hal = &rtwdev->hal; |
4437 | int ret; |
4438 | int tx_headroom = IEEE80211_HT_CTL_LEN; |
4439 | |
4440 | hw->vif_data_size = sizeof(struct rtw89_vif); |
4441 | hw->sta_data_size = sizeof(struct rtw89_sta); |
4442 | hw->txq_data_size = sizeof(struct rtw89_txq); |
4443 | hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg); |
4444 | |
4445 | SET_IEEE80211_PERM_ADDR(hw, addr: efuse->addr); |
4446 | |
4447 | hw->extra_tx_headroom = tx_headroom; |
4448 | hw->queues = IEEE80211_NUM_ACS; |
4449 | hw->max_rx_aggregation_subframes = RTW89_MAX_RX_AGG_NUM; |
4450 | hw->max_tx_aggregation_subframes = RTW89_MAX_TX_AGG_NUM; |
4451 | hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; |
4452 | |
4453 | ieee80211_hw_set(hw, SIGNAL_DBM); |
4454 | ieee80211_hw_set(hw, HAS_RATE_CONTROL); |
4455 | ieee80211_hw_set(hw, MFP_CAPABLE); |
4456 | ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); |
4457 | ieee80211_hw_set(hw, AMPDU_AGGREGATION); |
4458 | ieee80211_hw_set(hw, RX_INCLUDES_FCS); |
4459 | ieee80211_hw_set(hw, TX_AMSDU); |
4460 | ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); |
4461 | ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); |
4462 | ieee80211_hw_set(hw, SUPPORTS_PS); |
4463 | ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); |
4464 | ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); |
4465 | ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); |
4466 | ieee80211_hw_set(hw, WANT_MONITOR_VIF); |
4467 | |
4468 | if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160)) |
4469 | ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); |
4470 | |
4471 | if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw)) |
4472 | ieee80211_hw_set(hw, CONNECTION_MONITOR); |
4473 | |
4474 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
4475 | BIT(NL80211_IFTYPE_AP) | |
4476 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
4477 | BIT(NL80211_IFTYPE_P2P_GO); |
4478 | |
4479 | if (hal->ant_diversity) { |
4480 | hw->wiphy->available_antennas_tx = 0x3; |
4481 | hw->wiphy->available_antennas_rx = 0x3; |
4482 | } else { |
4483 | hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; |
4484 | hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; |
4485 | } |
4486 | |
4487 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | |
4488 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP | |
4489 | WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_SPLIT_SCAN_6GHZ; |
4490 | hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; |
4491 | |
4492 | hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID; |
4493 | hw->wiphy->max_scan_ie_len = RTW89_SCANOFLD_MAX_IE_LEN; |
4494 | |
4495 | #ifdef CONFIG_PM |
4496 | hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; |
4497 | #endif |
4498 | |
4499 | hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); |
4500 | hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL); |
4501 | hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); |
4502 | hw->wiphy->tid_config_support.peer |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); |
4503 | hw->wiphy->max_remain_on_channel_duration = 1000; |
4504 | |
4505 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); |
4506 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_SCAN_RANDOM_SN); |
4507 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_SET_SCAN_DWELL); |
4508 | |
4509 | ret = rtw89_core_set_supported_band(rtwdev); |
4510 | if (ret) { |
4511 | rtw89_err(rtwdev, "failed to set supported band\n" ); |
4512 | return ret; |
4513 | } |
4514 | |
4515 | ret = rtw89_regd_setup(rtwdev); |
4516 | if (ret) { |
4517 | rtw89_err(rtwdev, "failed to set up regd\n" ); |
4518 | goto err_free_supported_band; |
4519 | } |
4520 | |
4521 | hw->wiphy->sar_capa = &rtw89_sar_capa; |
4522 | |
4523 | ret = ieee80211_register_hw(hw); |
4524 | if (ret) { |
4525 | rtw89_err(rtwdev, "failed to register hw\n" ); |
4526 | goto err_free_supported_band; |
4527 | } |
4528 | |
4529 | ret = rtw89_regd_init(rtwdev, reg_notifier: rtw89_regd_notifier); |
4530 | if (ret) { |
4531 | rtw89_err(rtwdev, "failed to init regd\n" ); |
4532 | goto err_unregister_hw; |
4533 | } |
4534 | |
4535 | return 0; |
4536 | |
4537 | err_unregister_hw: |
4538 | ieee80211_unregister_hw(hw); |
4539 | err_free_supported_band: |
4540 | rtw89_core_clr_supported_band(rtwdev); |
4541 | |
4542 | return ret; |
4543 | } |
4544 | |
4545 | static void rtw89_core_unregister_hw(struct rtw89_dev *rtwdev) |
4546 | { |
4547 | struct ieee80211_hw *hw = rtwdev->hw; |
4548 | |
4549 | ieee80211_unregister_hw(hw); |
4550 | rtw89_core_clr_supported_band(rtwdev); |
4551 | } |
4552 | |
4553 | int rtw89_core_register(struct rtw89_dev *rtwdev) |
4554 | { |
4555 | int ret; |
4556 | |
4557 | ret = rtw89_core_register_hw(rtwdev); |
4558 | if (ret) { |
4559 | rtw89_err(rtwdev, "failed to register core hw\n" ); |
4560 | return ret; |
4561 | } |
4562 | |
4563 | rtw89_debugfs_init(rtwdev); |
4564 | |
4565 | return 0; |
4566 | } |
4567 | EXPORT_SYMBOL(rtw89_core_register); |
4568 | |
4569 | void rtw89_core_unregister(struct rtw89_dev *rtwdev) |
4570 | { |
4571 | rtw89_core_unregister_hw(rtwdev); |
4572 | } |
4573 | EXPORT_SYMBOL(rtw89_core_unregister); |
4574 | |
4575 | struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, |
4576 | u32 bus_data_size, |
4577 | const struct rtw89_chip_info *chip) |
4578 | { |
4579 | struct rtw89_fw_info early_fw = {}; |
4580 | const struct firmware *firmware; |
4581 | struct ieee80211_hw *hw; |
4582 | struct rtw89_dev *rtwdev; |
4583 | struct ieee80211_ops *ops; |
4584 | u32 driver_data_size; |
4585 | int fw_format = -1; |
4586 | bool no_chanctx; |
4587 | |
4588 | firmware = rtw89_early_fw_feature_recognize(device, chip, early_fw: &early_fw, used_fw_format: &fw_format); |
4589 | |
4590 | ops = kmemdup(p: &rtw89_ops, size: sizeof(rtw89_ops), GFP_KERNEL); |
4591 | if (!ops) |
4592 | goto err; |
4593 | |
4594 | no_chanctx = chip->support_chanctx_num == 0 || |
4595 | !RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &early_fw) || |
4596 | !RTW89_CHK_FW_FEATURE(BEACON_FILTER, &early_fw); |
4597 | |
4598 | if (no_chanctx) { |
4599 | ops->add_chanctx = ieee80211_emulate_add_chanctx; |
4600 | ops->remove_chanctx = ieee80211_emulate_remove_chanctx; |
4601 | ops->change_chanctx = ieee80211_emulate_change_chanctx; |
4602 | ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx; |
4603 | ops->assign_vif_chanctx = NULL; |
4604 | ops->unassign_vif_chanctx = NULL; |
4605 | ops->remain_on_channel = NULL; |
4606 | ops->cancel_remain_on_channel = NULL; |
4607 | } |
4608 | |
4609 | driver_data_size = sizeof(struct rtw89_dev) + bus_data_size; |
4610 | hw = ieee80211_alloc_hw(priv_data_len: driver_data_size, ops); |
4611 | if (!hw) |
4612 | goto err; |
4613 | |
4614 | hw->wiphy->iface_combinations = rtw89_iface_combs; |
4615 | |
4616 | if (no_chanctx || chip->support_chanctx_num == 1) |
4617 | hw->wiphy->n_iface_combinations = 1; |
4618 | else |
4619 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw89_iface_combs); |
4620 | |
4621 | rtwdev = hw->priv; |
4622 | rtwdev->hw = hw; |
4623 | rtwdev->dev = device; |
4624 | rtwdev->ops = ops; |
4625 | rtwdev->chip = chip; |
4626 | rtwdev->fw.req.firmware = firmware; |
4627 | rtwdev->fw.fw_format = fw_format; |
4628 | |
4629 | rtw89_debug(rtwdev, mask: RTW89_DBG_FW, fmt: "probe driver %s chanctx\n" , |
4630 | no_chanctx ? "without" : "with" ); |
4631 | |
4632 | return rtwdev; |
4633 | |
4634 | err: |
4635 | kfree(objp: ops); |
4636 | release_firmware(fw: firmware); |
4637 | return NULL; |
4638 | } |
4639 | EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); |
4640 | |
4641 | void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev) |
4642 | { |
4643 | kfree(objp: rtwdev->ops); |
4644 | kfree(objp: rtwdev->rfe_data); |
4645 | release_firmware(fw: rtwdev->fw.req.firmware); |
4646 | ieee80211_free_hw(hw: rtwdev->hw); |
4647 | } |
4648 | EXPORT_SYMBOL(rtw89_free_ieee80211_hw); |
4649 | |
4650 | MODULE_AUTHOR("Realtek Corporation" ); |
4651 | MODULE_DESCRIPTION("Realtek 802.11ax wireless core module" ); |
4652 | MODULE_LICENSE("Dual BSD/GPL" ); |
4653 | |