]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - drivers/net/wireless/mediatek/mt76/mac80211.c
wifi: mt76: dynamic channel bandwidth changes in AP mode
[thirdparty/kernel/stable.git] / drivers / net / wireless / mediatek / mt76 / mac80211.c
CommitLineData
0e3d6777 1// SPDX-License-Identifier: ISC
17f1de56
FF
2/*
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
17f1de56 4 */
781eef5b 5#include <linux/sched.h>
17f1de56 6#include <linux/of.h>
2f5c3c77 7#include <net/page_pool.h>
17f1de56
FF
8#include "mt76.h"
9
10#define CHAN2G(_idx, _freq) { \
11 .band = NL80211_BAND_2GHZ, \
12 .center_freq = (_freq), \
13 .hw_value = (_idx), \
14 .max_power = 30, \
15}
16
17#define CHAN5G(_idx, _freq) { \
18 .band = NL80211_BAND_5GHZ, \
19 .center_freq = (_freq), \
20 .hw_value = (_idx), \
21 .max_power = 30, \
22}
23
edf9dab8
LB
24#define CHAN6G(_idx, _freq) { \
25 .band = NL80211_BAND_6GHZ, \
26 .center_freq = (_freq), \
27 .hw_value = (_idx), \
28 .max_power = 30, \
29}
30
17f1de56
FF
31static const struct ieee80211_channel mt76_channels_2ghz[] = {
32 CHAN2G(1, 2412),
33 CHAN2G(2, 2417),
34 CHAN2G(3, 2422),
35 CHAN2G(4, 2427),
36 CHAN2G(5, 2432),
37 CHAN2G(6, 2437),
38 CHAN2G(7, 2442),
39 CHAN2G(8, 2447),
40 CHAN2G(9, 2452),
41 CHAN2G(10, 2457),
42 CHAN2G(11, 2462),
43 CHAN2G(12, 2467),
44 CHAN2G(13, 2472),
45 CHAN2G(14, 2484),
46};
47
48static const struct ieee80211_channel mt76_channels_5ghz[] = {
49 CHAN5G(36, 5180),
50 CHAN5G(40, 5200),
51 CHAN5G(44, 5220),
52 CHAN5G(48, 5240),
53
54 CHAN5G(52, 5260),
55 CHAN5G(56, 5280),
56 CHAN5G(60, 5300),
57 CHAN5G(64, 5320),
58
59 CHAN5G(100, 5500),
60 CHAN5G(104, 5520),
61 CHAN5G(108, 5540),
62 CHAN5G(112, 5560),
63 CHAN5G(116, 5580),
64 CHAN5G(120, 5600),
65 CHAN5G(124, 5620),
66 CHAN5G(128, 5640),
67 CHAN5G(132, 5660),
68 CHAN5G(136, 5680),
69 CHAN5G(140, 5700),
9da82fb7 70 CHAN5G(144, 5720),
17f1de56
FF
71
72 CHAN5G(149, 5745),
73 CHAN5G(153, 5765),
74 CHAN5G(157, 5785),
75 CHAN5G(161, 5805),
76 CHAN5G(165, 5825),
9da82fb7
MT
77 CHAN5G(169, 5845),
78 CHAN5G(173, 5865),
17f1de56
FF
79};
80
edf9dab8
LB
81static const struct ieee80211_channel mt76_channels_6ghz[] = {
82 /* UNII-5 */
83 CHAN6G(1, 5955),
84 CHAN6G(5, 5975),
85 CHAN6G(9, 5995),
86 CHAN6G(13, 6015),
87 CHAN6G(17, 6035),
88 CHAN6G(21, 6055),
89 CHAN6G(25, 6075),
90 CHAN6G(29, 6095),
91 CHAN6G(33, 6115),
92 CHAN6G(37, 6135),
93 CHAN6G(41, 6155),
94 CHAN6G(45, 6175),
95 CHAN6G(49, 6195),
96 CHAN6G(53, 6215),
97 CHAN6G(57, 6235),
98 CHAN6G(61, 6255),
99 CHAN6G(65, 6275),
100 CHAN6G(69, 6295),
101 CHAN6G(73, 6315),
102 CHAN6G(77, 6335),
103 CHAN6G(81, 6355),
104 CHAN6G(85, 6375),
105 CHAN6G(89, 6395),
106 CHAN6G(93, 6415),
107 /* UNII-6 */
108 CHAN6G(97, 6435),
109 CHAN6G(101, 6455),
110 CHAN6G(105, 6475),
111 CHAN6G(109, 6495),
112 CHAN6G(113, 6515),
113 CHAN6G(117, 6535),
114 /* UNII-7 */
115 CHAN6G(121, 6555),
116 CHAN6G(125, 6575),
117 CHAN6G(129, 6595),
118 CHAN6G(133, 6615),
119 CHAN6G(137, 6635),
120 CHAN6G(141, 6655),
121 CHAN6G(145, 6675),
122 CHAN6G(149, 6695),
123 CHAN6G(153, 6715),
124 CHAN6G(157, 6735),
125 CHAN6G(161, 6755),
126 CHAN6G(165, 6775),
127 CHAN6G(169, 6795),
128 CHAN6G(173, 6815),
129 CHAN6G(177, 6835),
130 CHAN6G(181, 6855),
131 CHAN6G(185, 6875),
132 /* UNII-8 */
133 CHAN6G(189, 6895),
134 CHAN6G(193, 6915),
135 CHAN6G(197, 6935),
136 CHAN6G(201, 6955),
137 CHAN6G(205, 6975),
138 CHAN6G(209, 6995),
139 CHAN6G(213, 7015),
140 CHAN6G(217, 7035),
141 CHAN6G(221, 7055),
142 CHAN6G(225, 7075),
143 CHAN6G(229, 7095),
144 CHAN6G(233, 7115),
145};
146
17f1de56
FF
147static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
148 { .throughput = 0 * 1024, .blink_time = 334 },
149 { .throughput = 1 * 1024, .blink_time = 260 },
150 { .throughput = 5 * 1024, .blink_time = 220 },
151 { .throughput = 10 * 1024, .blink_time = 190 },
152 { .throughput = 20 * 1024, .blink_time = 170 },
153 { .throughput = 50 * 1024, .blink_time = 150 },
154 { .throughput = 70 * 1024, .blink_time = 130 },
155 { .throughput = 100 * 1024, .blink_time = 110 },
156 { .throughput = 200 * 1024, .blink_time = 80 },
157 { .throughput = 300 * 1024, .blink_time = 50 },
158};
159
54b8fdeb
LB
160struct ieee80211_rate mt76_rates[] = {
161 CCK_RATE(0, 10),
162 CCK_RATE(1, 20),
163 CCK_RATE(2, 55),
164 CCK_RATE(3, 110),
165 OFDM_RATE(11, 60),
166 OFDM_RATE(15, 90),
167 OFDM_RATE(10, 120),
168 OFDM_RATE(14, 180),
169 OFDM_RATE(9, 240),
170 OFDM_RATE(13, 360),
171 OFDM_RATE(8, 480),
172 OFDM_RATE(12, 540),
173};
174EXPORT_SYMBOL_GPL(mt76_rates);
175
502604f5
YC
176static const struct cfg80211_sar_freq_ranges mt76_sar_freq_ranges[] = {
177 { .start_freq = 2402, .end_freq = 2494, },
178 { .start_freq = 5150, .end_freq = 5350, },
179 { .start_freq = 5350, .end_freq = 5470, },
180 { .start_freq = 5470, .end_freq = 5725, },
181 { .start_freq = 5725, .end_freq = 5950, },
162d5c14
DW
182 { .start_freq = 5945, .end_freq = 6165, },
183 { .start_freq = 6165, .end_freq = 6405, },
184 { .start_freq = 6405, .end_freq = 6525, },
185 { .start_freq = 6525, .end_freq = 6705, },
186 { .start_freq = 6705, .end_freq = 6865, },
187 { .start_freq = 6865, .end_freq = 7125, },
502604f5
YC
188};
189
97f8e1ae 190static const struct cfg80211_sar_capa mt76_sar_capa = {
502604f5
YC
191 .type = NL80211_SAR_TYPE_POWER,
192 .num_freq_ranges = ARRAY_SIZE(mt76_sar_freq_ranges),
193 .freq_ranges = &mt76_sar_freq_ranges[0],
194};
502604f5 195
3abd46dd 196static int mt76_led_init(struct mt76_phy *phy)
17f1de56 197{
3abd46dd
LB
198 struct mt76_dev *dev = phy->dev;
199 struct ieee80211_hw *hw = phy->hw;
17f1de56 200
3abd46dd 201 if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
17f1de56
FF
202 return 0;
203
3abd46dd
LB
204 snprintf(phy->leds.name, sizeof(phy->leds.name), "mt76-%s",
205 wiphy_name(hw->wiphy));
17f1de56 206
3abd46dd
LB
207 phy->leds.cdev.name = phy->leds.name;
208 phy->leds.cdev.default_trigger =
17f1de56
FF
209 ieee80211_create_tpt_led_trigger(hw,
210 IEEE80211_TPT_LEDTRIG_FL_RADIO,
211 mt76_tpt_blink,
212 ARRAY_SIZE(mt76_tpt_blink));
213
3abd46dd
LB
214 if (phy == &dev->phy) {
215 struct device_node *np = dev->dev->of_node;
216
217 np = of_get_child_by_name(np, "led");
218 if (np) {
219 int led_pin;
220
221 if (!of_property_read_u32(np, "led-sources", &led_pin))
222 phy->leds.pin = led_pin;
223 phy->leds.al = of_property_read_bool(np,
224 "led-active-low");
225 of_node_put(np);
226 }
17f1de56
FF
227 }
228
3abd46dd 229 return led_classdev_register(dev->dev, &phy->leds.cdev);
36f7e2b2
FF
230}
231
3abd46dd 232static void mt76_led_cleanup(struct mt76_phy *phy)
36f7e2b2 233{
3abd46dd 234 if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set)
36f7e2b2
FF
235 return;
236
3abd46dd 237 led_classdev_unregister(&phy->leds.cdev);
17f1de56
FF
238}
239
bb3e3fec 240static void mt76_init_stream_cap(struct mt76_phy *phy,
551e1ef4
LB
241 struct ieee80211_supported_band *sband,
242 bool vht)
243{
244 struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
bb3e3fec 245 int i, nstream = hweight8(phy->antenna_mask);
551e1ef4
LB
246 struct ieee80211_sta_vht_cap *vht_cap;
247 u16 mcs_map = 0;
248
249 if (nstream > 1)
250 ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
251 else
252 ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC;
253
254 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
255 ht_cap->mcs.rx_mask[i] = i < nstream ? 0xff : 0;
256
257 if (!vht)
258 return;
259
260 vht_cap = &sband->vht_cap;
261 if (nstream > 1)
262 vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
263 else
264 vht_cap->cap &= ~IEEE80211_VHT_CAP_TXSTBC;
abba3453
DW
265 vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
266 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
551e1ef4
LB
267
268 for (i = 0; i < 8; i++) {
269 if (i < nstream)
270 mcs_map |= (IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2));
271 else
272 mcs_map |=
273 (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2));
274 }
275 vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
276 vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
781b80f4
FF
277 if (ieee80211_hw_check(phy->hw, SUPPORTS_VHT_EXT_NSS_BW))
278 vht_cap->vht_mcs.tx_highest |=
d9fcfc14 279 cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
551e1ef4
LB
280}
281
bb3e3fec 282void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
5ebdc3e0 283{
48dbce5c 284 if (phy->cap.has_2ghz)
bb3e3fec 285 mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
48dbce5c 286 if (phy->cap.has_5ghz)
bb3e3fec 287 mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
edf9dab8
LB
288 if (phy->cap.has_6ghz)
289 mt76_init_stream_cap(phy, &phy->sband_6g.sband, vht);
5ebdc3e0
LB
290}
291EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
292
17f1de56 293static int
77af762e 294mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
17f1de56 295 const struct ieee80211_channel *chan, int n_chan,
edf9dab8
LB
296 struct ieee80211_rate *rates, int n_rates,
297 bool ht, bool vht)
17f1de56
FF
298{
299 struct ieee80211_supported_band *sband = &msband->sband;
17f1de56 300 struct ieee80211_sta_vht_cap *vht_cap;
77af762e
LB
301 struct ieee80211_sta_ht_cap *ht_cap;
302 struct mt76_dev *dev = phy->dev;
17f1de56 303 void *chanlist;
17f1de56
FF
304 int size;
305
306 size = n_chan * sizeof(*chan);
307 chanlist = devm_kmemdup(dev->dev, chan, size, GFP_KERNEL);
308 if (!chanlist)
309 return -ENOMEM;
310
a86854d0 311 msband->chan = devm_kcalloc(dev->dev, n_chan, sizeof(*msband->chan),
17f1de56
FF
312 GFP_KERNEL);
313 if (!msband->chan)
314 return -ENOMEM;
315
316 sband->channels = chanlist;
317 sband->n_channels = n_chan;
318 sband->bitrates = rates;
319 sband->n_bitrates = n_rates;
17f1de56 320
edf9dab8
LB
321 if (!ht)
322 return 0;
323
17f1de56
FF
324 ht_cap = &sband->ht_cap;
325 ht_cap->ht_supported = true;
326 ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
327 IEEE80211_HT_CAP_GRN_FLD |
328 IEEE80211_HT_CAP_SGI_20 |
329 IEEE80211_HT_CAP_SGI_40 |
17f1de56
FF
330 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
331
17f1de56
FF
332 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
333 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
17f1de56 334
77af762e 335 mt76_init_stream_cap(phy, sband, vht);
551e1ef4 336
17f1de56
FF
337 if (!vht)
338 return 0;
339
340 vht_cap = &sband->vht_cap;
341 vht_cap->vht_supported = true;
17f1de56 342 vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC |
17f1de56 343 IEEE80211_VHT_CAP_RXSTBC_1 |
49149d3f
FF
344 IEEE80211_VHT_CAP_SHORT_GI_80 |
345 (3 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
17f1de56
FF
346
347 return 0;
348}
349
350static int
77af762e 351mt76_init_sband_2g(struct mt76_phy *phy, struct ieee80211_rate *rates,
17f1de56
FF
352 int n_rates)
353{
77af762e 354 phy->hw->wiphy->bands[NL80211_BAND_2GHZ] = &phy->sband_2g.sband;
17f1de56 355
77af762e
LB
356 return mt76_init_sband(phy, &phy->sband_2g, mt76_channels_2ghz,
357 ARRAY_SIZE(mt76_channels_2ghz), rates,
edf9dab8 358 n_rates, true, false);
17f1de56
FF
359}
360
361static int
77af762e 362mt76_init_sband_5g(struct mt76_phy *phy, struct ieee80211_rate *rates,
17f1de56
FF
363 int n_rates, bool vht)
364{
77af762e 365 phy->hw->wiphy->bands[NL80211_BAND_5GHZ] = &phy->sband_5g.sband;
17f1de56 366
77af762e
LB
367 return mt76_init_sband(phy, &phy->sband_5g, mt76_channels_5ghz,
368 ARRAY_SIZE(mt76_channels_5ghz), rates,
edf9dab8
LB
369 n_rates, true, vht);
370}
371
372static int
373mt76_init_sband_6g(struct mt76_phy *phy, struct ieee80211_rate *rates,
374 int n_rates)
375{
376 phy->hw->wiphy->bands[NL80211_BAND_6GHZ] = &phy->sband_6g.sband;
377
378 return mt76_init_sband(phy, &phy->sband_6g, mt76_channels_6ghz,
379 ARRAY_SIZE(mt76_channels_6ghz), rates,
380 n_rates, false, false);
17f1de56
FF
381}
382
383static void
c89d3625
FF
384mt76_check_sband(struct mt76_phy *phy, struct mt76_sband *msband,
385 enum nl80211_band band)
17f1de56 386{
c89d3625 387 struct ieee80211_supported_band *sband = &msband->sband;
17f1de56
FF
388 bool found = false;
389 int i;
390
391 if (!sband)
392 return;
393
394 for (i = 0; i < sband->n_channels; i++) {
395 if (sband->channels[i].flags & IEEE80211_CHAN_DISABLED)
396 continue;
397
398 found = true;
399 break;
400 }
401
c89d3625
FF
402 if (found) {
403 phy->chandef.chan = &sband->channels[0];
404 phy->chan_state = &msband->chan[0];
17f1de56 405 return;
c89d3625 406 }
17f1de56
FF
407
408 sband->n_channels = 0;
c89d3625 409 phy->hw->wiphy->bands[band] = NULL;
17f1de56
FF
410}
411
d43de9cf 412static int
98df2bae 413mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
c89d3625 414{
98df2bae 415 struct mt76_dev *dev = phy->dev;
c89d3625
FF
416 struct wiphy *wiphy = hw->wiphy;
417
418 SET_IEEE80211_DEV(hw, dev->dev);
98df2bae 419 SET_IEEE80211_PERM_ADDR(hw, phy->macaddr);
c89d3625 420
c278a64a
RL
421 wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
422 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
dd89a013 423 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
b807b368
LB
424 WIPHY_FLAG_SUPPORTS_TDLS |
425 WIPHY_FLAG_AP_UAPSD;
c89d3625
FF
426
427 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
428 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
d9c54264 429 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
c89d3625 430
0a57d636
BJ
431 wiphy->available_antennas_tx = phy->antenna_mask;
432 wiphy->available_antennas_rx = phy->antenna_mask;
c89d3625 433
d43de9cf
LB
434 wiphy->sar_capa = &mt76_sar_capa;
435 phy->frp = devm_kcalloc(dev->dev, wiphy->sar_capa->num_freq_ranges,
436 sizeof(struct mt76_freq_range_power),
437 GFP_KERNEL);
438 if (!phy->frp)
439 return -ENOMEM;
440
c89d3625 441 hw->txq_data_size = sizeof(struct mt76_txq);
b807b368 442 hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
c9619dfa
SC
443
444 if (!hw->max_tx_fragments)
445 hw->max_tx_fragments = 16;
c89d3625
FF
446
447 ieee80211_hw_set(hw, SIGNAL_DBM);
c89d3625
FF
448 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
449 ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
450 ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
451 ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
452 ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
ed89b893 453 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
5b0fb852
BG
454
455 if (!(dev->drv->drv_flags & MT_DRV_AMSDU_OFFLOAD)) {
456 ieee80211_hw_set(hw, TX_AMSDU);
457 ieee80211_hw_set(hw, TX_FRAG_LIST);
458 }
459
c89d3625
FF
460 ieee80211_hw_set(hw, MFP_CAPABLE);
461 ieee80211_hw_set(hw, AP_LINK_PS);
462 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
d43de9cf
LB
463
464 return 0;
c89d3625
FF
465}
466
467struct mt76_phy *
468mt76_alloc_phy(struct mt76_dev *dev, unsigned int size,
dc44c45c 469 const struct ieee80211_ops *ops, u8 band_idx)
c89d3625
FF
470{
471 struct ieee80211_hw *hw;
db78a791 472 unsigned int phy_size;
c89d3625 473 struct mt76_phy *phy;
c89d3625
FF
474
475 phy_size = ALIGN(sizeof(*phy), 8);
db78a791 476 hw = ieee80211_alloc_hw(size + phy_size, ops);
c89d3625
FF
477 if (!hw)
478 return NULL;
479
480 phy = hw->priv;
481 phy->dev = dev;
482 phy->hw = hw;
db78a791 483 phy->priv = hw->priv + phy_size;
dc44c45c 484 phy->band_idx = band_idx;
c89d3625 485
8af414e8
LB
486 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
487 hw->wiphy->interface_modes =
488 BIT(NL80211_IFTYPE_STATION) |
489 BIT(NL80211_IFTYPE_AP) |
490#ifdef CONFIG_MAC80211_MESH
491 BIT(NL80211_IFTYPE_MESH_POINT) |
492#endif
493 BIT(NL80211_IFTYPE_P2P_CLIENT) |
494 BIT(NL80211_IFTYPE_P2P_GO) |
495 BIT(NL80211_IFTYPE_ADHOC);
496
db78a791
LB
497 return phy;
498}
499EXPORT_SYMBOL_GPL(mt76_alloc_phy);
c89d3625 500
db78a791
LB
501int mt76_register_phy(struct mt76_phy *phy, bool vht,
502 struct ieee80211_rate *rates, int n_rates)
503{
504 int ret;
c89d3625 505
d43de9cf
LB
506 ret = mt76_phy_init(phy, phy->hw);
507 if (ret)
508 return ret;
c89d3625 509
db78a791
LB
510 if (phy->cap.has_2ghz) {
511 ret = mt76_init_sband_2g(phy, rates, n_rates);
512 if (ret)
513 return ret;
514 }
c89d3625 515
db78a791
LB
516 if (phy->cap.has_5ghz) {
517 ret = mt76_init_sband_5g(phy, rates + 4, n_rates - 4, vht);
518 if (ret)
519 return ret;
520 }
c89d3625 521
edf9dab8
LB
522 if (phy->cap.has_6ghz) {
523 ret = mt76_init_sband_6g(phy, rates + 4, n_rates - 4);
524 if (ret)
525 return ret;
526 }
527
9e81c2c7
LB
528 if (IS_ENABLED(CONFIG_MT76_LEDS)) {
529 ret = mt76_led_init(phy);
530 if (ret)
531 return ret;
532 }
533
db78a791 534 wiphy_read_of_freq_limits(phy->hw->wiphy);
c89d3625
FF
535 mt76_check_sband(phy, &phy->sband_2g, NL80211_BAND_2GHZ);
536 mt76_check_sband(phy, &phy->sband_5g, NL80211_BAND_5GHZ);
edf9dab8 537 mt76_check_sband(phy, &phy->sband_6g, NL80211_BAND_6GHZ);
c89d3625 538
c89d3625
FF
539 ret = ieee80211_register_hw(phy->hw);
540 if (ret)
541 return ret;
542
41130c32 543 set_bit(MT76_STATE_REGISTERED, &phy->state);
dc44c45c 544 phy->dev->phys[phy->band_idx] = phy;
db78a791 545
c89d3625
FF
546 return 0;
547}
548EXPORT_SYMBOL_GPL(mt76_register_phy);
549
db78a791 550void mt76_unregister_phy(struct mt76_phy *phy)
c89d3625
FF
551{
552 struct mt76_dev *dev = phy->dev;
553
41130c32
LB
554 if (!test_bit(MT76_STATE_REGISTERED, &phy->state))
555 return;
556
9e81c2c7
LB
557 if (IS_ENABLED(CONFIG_MT76_LEDS))
558 mt76_led_cleanup(phy);
c02f86ee 559 mt76_tx_status_check(dev, true);
c89d3625 560 ieee80211_unregister_hw(phy->hw);
dc44c45c 561 dev->phys[phy->band_idx] = NULL;
c89d3625
FF
562}
563EXPORT_SYMBOL_GPL(mt76_unregister_phy);
564
2f5c3c77
LB
565int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q)
566{
567 struct page_pool_params pp_params = {
568 .order = 0,
569 .flags = PP_FLAG_PAGE_FRAG,
570 .nid = NUMA_NO_NODE,
571 .dev = dev->dma_dev,
572 };
573 int idx = q - dev->q_rx;
574
575 switch (idx) {
576 case MT_RXQ_MAIN:
577 case MT_RXQ_BAND1:
578 case MT_RXQ_BAND2:
579 pp_params.pool_size = 256;
580 break;
581 default:
582 pp_params.pool_size = 16;
583 break;
584 }
585
586 if (mt76_is_mmio(dev)) {
587 /* rely on page_pool for DMA mapping */
588 pp_params.flags |= PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
589 pp_params.dma_dir = DMA_FROM_DEVICE;
590 pp_params.max_len = PAGE_SIZE;
591 pp_params.offset = 0;
592 }
593
594 q->page_pool = page_pool_create(&pp_params);
595 if (IS_ERR(q->page_pool)) {
596 int err = PTR_ERR(q->page_pool);
597
598 q->page_pool = NULL;
599 return err;
600 }
601
602 return 0;
603}
604EXPORT_SYMBOL_GPL(mt76_create_page_pool);
605
a85b590c 606struct mt76_dev *
c0f7b25a
LB
607mt76_alloc_device(struct device *pdev, unsigned int size,
608 const struct ieee80211_ops *ops,
609 const struct mt76_driver_ops *drv_ops)
a85b590c
FF
610{
611 struct ieee80211_hw *hw;
ac24dd35 612 struct mt76_phy *phy;
a85b590c 613 struct mt76_dev *dev;
e5443256 614 int i;
a85b590c
FF
615
616 hw = ieee80211_alloc_hw(size, ops);
617 if (!hw)
618 return NULL;
619
620 dev = hw->priv;
621 dev->hw = hw;
c0f7b25a
LB
622 dev->dev = pdev;
623 dev->drv = drv_ops;
d1ddc536 624 dev->dma_dev = pdev;
c0f7b25a 625
ac24dd35
FF
626 phy = &dev->phy;
627 phy->dev = dev;
628 phy->hw = hw;
dc44c45c
LB
629 phy->band_idx = MT_BAND0;
630 dev->phys[phy->band_idx] = phy;
ac24dd35 631
a85b590c
FF
632 spin_lock_init(&dev->rx_lock);
633 spin_lock_init(&dev->lock);
634 spin_lock_init(&dev->cc_lock);
c34f1005 635 spin_lock_init(&dev->status_lock);
2666bece 636 spin_lock_init(&dev->wed_lock);
108a4861 637 mutex_init(&dev->mutex);
26e40d4c 638 init_waitqueue_head(&dev->tx_wait);
a85b590c 639
09872957
LB
640 skb_queue_head_init(&dev->mcu.res_q);
641 init_waitqueue_head(&dev->mcu.wait);
642 mutex_init(&dev->mcu.mutex);
781eef5b 643 dev->tx_worker.fn = mt76_tx_worker;
09872957 644
8af414e8
LB
645 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
646 hw->wiphy->interface_modes =
647 BIT(NL80211_IFTYPE_STATION) |
648 BIT(NL80211_IFTYPE_AP) |
649#ifdef CONFIG_MAC80211_MESH
650 BIT(NL80211_IFTYPE_MESH_POINT) |
651#endif
652 BIT(NL80211_IFTYPE_P2P_CLIENT) |
653 BIT(NL80211_IFTYPE_P2P_GO) |
654 BIT(NL80211_IFTYPE_ADHOC);
655
51252cc5
LB
656 spin_lock_init(&dev->token_lock);
657 idr_init(&dev->token);
658
2666bece
SC
659 spin_lock_init(&dev->rx_token_lock);
660 idr_init(&dev->rx_token);
661
bd1e3e7b
LB
662 INIT_LIST_HEAD(&dev->wcid_list);
663
e5443256 664 INIT_LIST_HEAD(&dev->txwi_cache);
2666bece 665 INIT_LIST_HEAD(&dev->rxwi_cache);
61b5156b 666 dev->token_size = dev->drv->token_size;
e5443256
FF
667
668 for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
669 skb_queue_head_init(&dev->rx_skb[i]);
670
a86f1d01
LB
671 dev->wq = alloc_ordered_workqueue("mt76", 0);
672 if (!dev->wq) {
673 ieee80211_free_hw(hw);
674 return NULL;
675 }
676
a85b590c
FF
677 return dev;
678}
679EXPORT_SYMBOL_GPL(mt76_alloc_device);
680
17f1de56
FF
681int mt76_register_device(struct mt76_dev *dev, bool vht,
682 struct ieee80211_rate *rates, int n_rates)
683{
684 struct ieee80211_hw *hw = dev->hw;
c89d3625 685 struct mt76_phy *phy = &dev->phy;
17f1de56
FF
686 int ret;
687
688 dev_set_drvdata(dev->dev, dev);
d43de9cf
LB
689 ret = mt76_phy_init(phy, hw);
690 if (ret)
691 return ret;
17f1de56 692
48dbce5c 693 if (phy->cap.has_2ghz) {
77af762e 694 ret = mt76_init_sband_2g(phy, rates, n_rates);
17f1de56
FF
695 if (ret)
696 return ret;
697 }
698
48dbce5c 699 if (phy->cap.has_5ghz) {
77af762e 700 ret = mt76_init_sband_5g(phy, rates + 4, n_rates - 4, vht);
17f1de56
FF
701 if (ret)
702 return ret;
703 }
704
edf9dab8
LB
705 if (phy->cap.has_6ghz) {
706 ret = mt76_init_sband_6g(phy, rates + 4, n_rates - 4);
707 if (ret)
708 return ret;
709 }
710
c89d3625
FF
711 wiphy_read_of_freq_limits(hw->wiphy);
712 mt76_check_sband(&dev->phy, &phy->sband_2g, NL80211_BAND_2GHZ);
713 mt76_check_sband(&dev->phy, &phy->sband_5g, NL80211_BAND_5GHZ);
edf9dab8 714 mt76_check_sband(&dev->phy, &phy->sband_6g, NL80211_BAND_6GHZ);
17f1de56 715
b374e868 716 if (IS_ENABLED(CONFIG_MT76_LEDS)) {
3abd46dd 717 ret = mt76_led_init(phy);
b374e868
AB
718 if (ret)
719 return ret;
720 }
17f1de56 721
781eef5b
FF
722 ret = ieee80211_register_hw(hw);
723 if (ret)
724 return ret;
725
726 WARN_ON(mt76_worker_setup(hw, &dev->tx_worker, NULL, "tx"));
41130c32 727 set_bit(MT76_STATE_REGISTERED, &phy->state);
781eef5b
FF
728 sched_set_fifo_low(dev->tx_worker.task);
729
730 return 0;
17f1de56
FF
731}
732EXPORT_SYMBOL_GPL(mt76_register_device);
733
734void mt76_unregister_device(struct mt76_dev *dev)
735{
736 struct ieee80211_hw *hw = dev->hw;
737
41130c32
LB
738 if (!test_bit(MT76_STATE_REGISTERED, &dev->phy.state))
739 return;
740
d68f4e43 741 if (IS_ENABLED(CONFIG_MT76_LEDS))
3abd46dd 742 mt76_led_cleanup(&dev->phy);
c02f86ee 743 mt76_tx_status_check(dev, true);
17f1de56 744 ieee80211_unregister_hw(hw);
17f1de56
FF
745}
746EXPORT_SYMBOL_GPL(mt76_unregister_device);
747
def34a2f
LB
748void mt76_free_device(struct mt76_dev *dev)
749{
781eef5b 750 mt76_worker_teardown(&dev->tx_worker);
a86f1d01
LB
751 if (dev->wq) {
752 destroy_workqueue(dev->wq);
753 dev->wq = NULL;
754 }
def34a2f
LB
755 ieee80211_free_hw(dev->hw);
756}
757EXPORT_SYMBOL_GPL(mt76_free_device);
758
cc4b3c13
LB
759static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
760{
761 struct sk_buff *skb = phy->rx_amsdu[q].head;
2c2bdd23 762 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
cc4b3c13
LB
763 struct mt76_dev *dev = phy->dev;
764
765 phy->rx_amsdu[q].head = NULL;
766 phy->rx_amsdu[q].tail = NULL;
2c2bdd23
FF
767
768 /*
769 * Validate if the amsdu has a proper first subframe.
770 * A single MSDU can be parsed as A-MSDU when the unauthenticated A-MSDU
771 * flag of the QoS header gets flipped. In such cases, the first
772 * subframe has a LLC/SNAP header in the location of the destination
773 * address.
774 */
775 if (skb_shinfo(skb)->frag_list) {
776 int offset = 0;
777
778 if (!(status->flag & RX_FLAG_8023)) {
779 offset = ieee80211_get_hdrlen_from_skb(skb);
780
781 if ((status->flag &
782 (RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED)) ==
783 RX_FLAG_DECRYPTED)
784 offset += 8;
785 }
786
787 if (ether_addr_equal(skb->data + offset, rfc1042_header)) {
788 dev_kfree_skb(skb);
789 return;
790 }
791 }
cc4b3c13
LB
792 __skb_queue_tail(&dev->rx_skb[q], skb);
793}
794
795static void mt76_rx_release_burst(struct mt76_phy *phy, enum mt76_rxq_id q,
796 struct sk_buff *skb)
797{
798 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
799
800 if (phy->rx_amsdu[q].head &&
801 (!status->amsdu || status->first_amsdu ||
802 status->seqno != phy->rx_amsdu[q].seqno))
803 mt76_rx_release_amsdu(phy, q);
804
805 if (!phy->rx_amsdu[q].head) {
806 phy->rx_amsdu[q].tail = &skb_shinfo(skb)->frag_list;
807 phy->rx_amsdu[q].seqno = status->seqno;
808 phy->rx_amsdu[q].head = skb;
809 } else {
810 *phy->rx_amsdu[q].tail = skb;
811 phy->rx_amsdu[q].tail = &skb->next;
812 }
813
814 if (!status->amsdu || status->last_amsdu)
815 mt76_rx_release_amsdu(phy, q);
816}
817
17f1de56
FF
818void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
819{
011849e0 820 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
128c9b7d 821 struct mt76_phy *phy = mt76_dev_phy(dev, status->phy_idx);
011849e0
FF
822
823 if (!test_bit(MT76_STATE_RUNNING, &phy->state)) {
17f1de56
FF
824 dev_kfree_skb(skb);
825 return;
826 }
827
f0efa862 828#ifdef CONFIG_NL80211_TESTMODE
c918c74d
SC
829 if (phy->test.state == MT76_TM_STATE_RX_FRAMES) {
830 phy->test.rx_stats.packets[q]++;
f0efa862 831 if (status->flag & RX_FLAG_FAILED_FCS_CRC)
c918c74d 832 phy->test.rx_stats.fcs_error[q]++;
f0efa862
FF
833 }
834#endif
cc4b3c13
LB
835
836 mt76_rx_release_burst(phy, q, skb);
17f1de56
FF
837}
838EXPORT_SYMBOL_GPL(mt76_rx);
839
5a95ca41 840bool mt76_has_tx_pending(struct mt76_phy *phy)
26e40d4c 841{
af005f26 842 struct mt76_queue *q;
91990519 843 int i;
26e40d4c 844
5a95ca41 845 for (i = 0; i < __MT_TXQ_MAX; i++) {
91990519 846 q = phy->q_tx[i];
af005f26 847 if (q && q->queued)
26e40d4c
FF
848 return true;
849 }
850
851 return false;
852}
39d501d9 853EXPORT_SYMBOL_GPL(mt76_has_tx_pending);
26e40d4c 854
0fd0eb54 855static struct mt76_channel_state *
96747a51 856mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
0fd0eb54
FF
857{
858 struct mt76_sband *msband;
859 int idx;
860
861 if (c->band == NL80211_BAND_2GHZ)
96747a51 862 msband = &phy->sband_2g;
edf9dab8
LB
863 else if (c->band == NL80211_BAND_6GHZ)
864 msband = &phy->sband_6g;
0fd0eb54 865 else
96747a51 866 msband = &phy->sband_5g;
0fd0eb54
FF
867
868 idx = c - &msband->sband.channels[0];
869 return &msband->chan[idx];
870}
871
04414240 872void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
96747a51
FF
873{
874 struct mt76_channel_state *state = phy->chan_state;
875
876 state->cc_active += ktime_to_us(ktime_sub(time,
877 phy->survey_time));
878 phy->survey_time = time;
879}
04414240 880EXPORT_SYMBOL_GPL(mt76_update_survey_active_time);
96747a51 881
c560b137 882void mt76_update_survey(struct mt76_phy *phy)
5ce09c1a 883{
c560b137 884 struct mt76_dev *dev = phy->dev;
aec65e48
FF
885 ktime_t cur_time;
886
5ce09c1a 887 if (dev->drv->update_survey)
c560b137 888 dev->drv->update_survey(phy);
5ce09c1a 889
aec65e48 890 cur_time = ktime_get_boottime();
c560b137 891 mt76_update_survey_active_time(phy, cur_time);
aec65e48 892
5ce09c1a 893 if (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME) {
c560b137 894 struct mt76_channel_state *state = phy->chan_state;
96747a51 895
237312c5 896 spin_lock_bh(&dev->cc_lock);
5ce09c1a
FF
897 state->cc_bss_rx += dev->cur_cc_bss_rx;
898 dev->cur_cc_bss_rx = 0;
237312c5 899 spin_unlock_bh(&dev->cc_lock);
5ce09c1a
FF
900 }
901}
902EXPORT_SYMBOL_GPL(mt76_update_survey);
903
96747a51 904void mt76_set_channel(struct mt76_phy *phy)
17f1de56 905{
96747a51
FF
906 struct mt76_dev *dev = phy->dev;
907 struct ieee80211_hw *hw = phy->hw;
17f1de56 908 struct cfg80211_chan_def *chandef = &hw->conf.chandef;
17f1de56 909 bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
26e40d4c 910 int timeout = HZ / 5;
17f1de56 911
5a95ca41 912 wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
c560b137 913 mt76_update_survey(phy);
17f1de56 914
3f306448
FF
915 if (phy->chandef.chan->center_freq != chandef->chan->center_freq ||
916 phy->chandef.width != chandef->width)
917 phy->dfs_state = MT_DFS_STATE_UNKNOWN;
918
96747a51
FF
919 phy->chandef = *chandef;
920 phy->chan_state = mt76_channel_state(phy, chandef->chan);
17f1de56
FF
921
922 if (!offchannel)
96747a51 923 phy->main_chan = chandef->chan;
17f1de56 924
96747a51
FF
925 if (chandef->chan != phy->main_chan)
926 memset(phy->chan_state, 0, sizeof(*phy->chan_state));
17f1de56
FF
927}
928EXPORT_SYMBOL_GPL(mt76_set_channel);
929
930int mt76_get_survey(struct ieee80211_hw *hw, int idx,
931 struct survey_info *survey)
932{
96747a51
FF
933 struct mt76_phy *phy = hw->priv;
934 struct mt76_dev *dev = phy->dev;
17f1de56
FF
935 struct mt76_sband *sband;
936 struct ieee80211_channel *chan;
937 struct mt76_channel_state *state;
938 int ret = 0;
939
237312c5 940 mutex_lock(&dev->mutex);
17f1de56 941 if (idx == 0 && dev->drv->update_survey)
c560b137 942 mt76_update_survey(phy);
17f1de56 943
edf9dab8
LB
944 if (idx >= phy->sband_2g.sband.n_channels +
945 phy->sband_5g.sband.n_channels) {
946 idx -= (phy->sband_2g.sband.n_channels +
947 phy->sband_5g.sband.n_channels);
948 sband = &phy->sband_6g;
949 } else if (idx >= phy->sband_2g.sband.n_channels) {
950 idx -= phy->sband_2g.sband.n_channels;
96747a51 951 sband = &phy->sband_5g;
edf9dab8
LB
952 } else {
953 sband = &phy->sband_2g;
17f1de56
FF
954 }
955
237312c5
LB
956 if (idx >= sband->sband.n_channels) {
957 ret = -ENOENT;
958 goto out;
959 }
17f1de56
FF
960
961 chan = &sband->sband.channels[idx];
96747a51 962 state = mt76_channel_state(phy, chan);
17f1de56
FF
963
964 memset(survey, 0, sizeof(*survey));
965 survey->channel = chan;
966 survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY;
ea565833 967 survey->filled |= dev->drv->survey_flags;
e5051965
FF
968 if (state->noise)
969 survey->filled |= SURVEY_INFO_NOISE_DBM;
970
96747a51 971 if (chan == phy->main_chan) {
17f1de56
FF
972 survey->filled |= SURVEY_INFO_IN_USE;
973
5ce09c1a
FF
974 if (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME)
975 survey->filled |= SURVEY_INFO_TIME_BSS_RX;
976 }
977
17f1de56 978 survey->time_busy = div_u64(state->cc_busy, 1000);
6bfa6e38 979 survey->time_rx = div_u64(state->cc_rx, 1000);
237312c5 980 survey->time = div_u64(state->cc_active, 1000);
e5051965 981 survey->noise = state->noise;
237312c5
LB
982
983 spin_lock_bh(&dev->cc_lock);
984 survey->time_bss_rx = div_u64(state->cc_bss_rx, 1000);
ea565833 985 survey->time_tx = div_u64(state->cc_tx, 1000);
17f1de56
FF
986 spin_unlock_bh(&dev->cc_lock);
987
237312c5
LB
988out:
989 mutex_unlock(&dev->mutex);
990
17f1de56
FF
991 return ret;
992}
993EXPORT_SYMBOL_GPL(mt76_get_survey);
994
30ce7f44
FF
995void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
996 struct ieee80211_key_conf *key)
997{
998 struct ieee80211_key_seq seq;
999 int i;
1000
1001 wcid->rx_check_pn = false;
1002
1003 if (!key)
1004 return;
1005
01cfc1b4
LB
1006 if (key->cipher != WLAN_CIPHER_SUITE_CCMP)
1007 return;
30ce7f44 1008
01cfc1b4 1009 wcid->rx_check_pn = true;
a1b0bbd4
XS
1010
1011 /* data frame */
30ce7f44
FF
1012 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
1013 ieee80211_get_key_rx_seq(key, i, &seq);
1014 memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
1015 }
a1b0bbd4
XS
1016
1017 /* robust management frame */
1018 ieee80211_get_key_rx_seq(key, -1, &seq);
1019 memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
1020
30ce7f44
FF
1021}
1022EXPORT_SYMBOL(mt76_wcid_key_setup);
1023
a71b648e 1024int mt76_rx_signal(u8 chain_mask, s8 *chain_signal)
4550fb9e 1025{
4550fb9e
FF
1026 int signal = -128;
1027 u8 chains;
1028
a71b648e 1029 for (chains = chain_mask; chains; chains >>= 1, chain_signal++) {
4550fb9e
FF
1030 int cur, diff;
1031
6450b133
DW
1032 cur = *chain_signal;
1033 if (!(chains & BIT(0)) ||
1034 cur > 0)
4550fb9e
FF
1035 continue;
1036
4550fb9e
FF
1037 if (cur > signal)
1038 swap(cur, signal);
1039
1040 diff = signal - cur;
1041 if (diff == 0)
1042 signal += 3;
1043 else if (diff <= 2)
1044 signal += 2;
1045 else if (diff <= 6)
1046 signal += 1;
1047 }
1048
1049 return signal;
1050}
a71b648e 1051EXPORT_SYMBOL(mt76_rx_signal);
4550fb9e 1052
bfc394dd
FF
1053static void
1054mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
1055 struct ieee80211_hw **hw,
1056 struct ieee80211_sta **sta)
4e34249e
FF
1057{
1058 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
abe3f3da 1059 struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
4e34249e
FF
1060 struct mt76_rx_status mstat;
1061
13381dcd 1062 mstat = *((struct mt76_rx_status *)skb->cb);
4e34249e
FF
1063 memset(status, 0, sizeof(*status));
1064
1065 status->flag = mstat.flag;
1066 status->freq = mstat.freq;
1067 status->enc_flags = mstat.enc_flags;
1068 status->encoding = mstat.encoding;
1069 status->bw = mstat.bw;
af4a2f2f
RL
1070 status->he_ru = mstat.he_ru;
1071 status->he_gi = mstat.he_gi;
1072 status->he_dcm = mstat.he_dcm;
4e34249e
FF
1073 status->rate_idx = mstat.rate_idx;
1074 status->nss = mstat.nss;
1075 status->band = mstat.band;
1076 status->signal = mstat.signal;
1077 status->chains = mstat.chains;
d515fdca 1078 status->ampdu_reference = mstat.ampdu_ref;
0fda6d7b
RL
1079 status->device_timestamp = mstat.timestamp;
1080 status->mactime = mstat.timestamp;
a71b648e 1081 status->signal = mt76_rx_signal(mstat.chains, mstat.chain_signal);
4550fb9e
FF
1082 if (status->signal <= -128)
1083 status->flag |= RX_FLAG_NO_SIGNAL_VAL;
4e34249e 1084
abe3f3da
RL
1085 if (ieee80211_is_beacon(hdr->frame_control) ||
1086 ieee80211_is_probe_resp(hdr->frame_control))
1087 status->boottime_ns = ktime_get_boottime_ns();
1088
4e34249e 1089 BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
13381dcd
RL
1090 BUILD_BUG_ON(sizeof(status->chain_signal) !=
1091 sizeof(mstat.chain_signal));
1092 memcpy(status->chain_signal, mstat.chain_signal,
1093 sizeof(mstat.chain_signal));
9c68a57b 1094
bfc394dd 1095 *sta = wcid_to_sta(mstat.wcid);
128c9b7d 1096 *hw = mt76_phy_hw(dev, mstat.phy_idx);
4e34249e
FF
1097}
1098
3c1032e1 1099static void
30ce7f44
FF
1100mt76_check_ccmp_pn(struct sk_buff *skb)
1101{
13381dcd 1102 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
30ce7f44
FF
1103 struct mt76_wcid *wcid = status->wcid;
1104 struct ieee80211_hdr *hdr;
a1b0bbd4 1105 int security_idx;
30ce7f44
FF
1106 int ret;
1107
1108 if (!(status->flag & RX_FLAG_DECRYPTED))
3c1032e1 1109 return;
30ce7f44 1110
1858e4fc 1111 if (status->flag & RX_FLAG_ONLY_MONITOR)
3c1032e1 1112 return;
1858e4fc 1113
30ce7f44 1114 if (!wcid || !wcid->rx_check_pn)
3c1032e1 1115 return;
30ce7f44 1116
7360cdec
FF
1117 security_idx = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
1118 if (status->flag & RX_FLAG_8023)
1119 goto skip_hdr_check;
1120
a1b0bbd4 1121 hdr = mt76_skb_get_hdr(skb);
30ce7f44
FF
1122 if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
1123 /*
1124 * Validate the first fragment both here and in mac80211
1125 * All further fragments will be validated by mac80211 only.
1126 */
30ce7f44
FF
1127 if (ieee80211_is_frag(hdr) &&
1128 !ieee80211_is_first_frag(hdr->frame_control))
3c1032e1 1129 return;
30ce7f44
FF
1130 }
1131
a1b0bbd4
XS
1132 /* IEEE 802.11-2020, 12.5.3.4.4 "PN and replay detection" c):
1133 *
1134 * the recipient shall maintain a single replay counter for received
1135 * individually addressed robust Management frames that are received
1136 * with the To DS subfield equal to 0, [...]
1137 */
1138 if (ieee80211_is_mgmt(hdr->frame_control) &&
1139 !ieee80211_has_tods(hdr->frame_control))
1140 security_idx = IEEE80211_NUM_TIDS;
a1b0bbd4 1141
7360cdec 1142skip_hdr_check:
30ce7f44 1143 BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0]));
a1b0bbd4 1144 ret = memcmp(status->iv, wcid->rx_key_pn[security_idx],
30ce7f44 1145 sizeof(status->iv));
3c1032e1
FF
1146 if (ret <= 0) {
1147 status->flag |= RX_FLAG_ONLY_MONITOR;
1148 return;
1149 }
30ce7f44 1150
a1b0bbd4 1151 memcpy(wcid->rx_key_pn[security_idx], status->iv, sizeof(status->iv));
30ce7f44
FF
1152
1153 if (status->flag & RX_FLAG_IV_STRIPPED)
1154 status->flag |= RX_FLAG_PN_VALIDATED;
30ce7f44
FF
1155}
1156
5ce09c1a
FF
1157static void
1158mt76_airtime_report(struct mt76_dev *dev, struct mt76_rx_status *status,
1159 int len)
1160{
1161 struct mt76_wcid *wcid = status->wcid;
85b7a5d0
LB
1162 struct ieee80211_rx_status info = {
1163 .enc_flags = status->enc_flags,
1164 .rate_idx = status->rate_idx,
1165 .encoding = status->encoding,
1166 .band = status->band,
1167 .nss = status->nss,
1168 .bw = status->bw,
1169 };
5ce09c1a
FF
1170 struct ieee80211_sta *sta;
1171 u32 airtime;
e195dad1 1172 u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
5ce09c1a 1173
85b7a5d0 1174 airtime = ieee80211_calc_rx_airtime(dev->hw, &info, len);
237312c5 1175 spin_lock(&dev->cc_lock);
5ce09c1a 1176 dev->cur_cc_bss_rx += airtime;
237312c5 1177 spin_unlock(&dev->cc_lock);
5ce09c1a
FF
1178
1179 if (!wcid || !wcid->sta)
1180 return;
1181
1182 sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
e195dad1 1183 ieee80211_sta_register_airtime(sta, tidno, 0, airtime);
5ce09c1a
FF
1184}
1185
1186static void
1187mt76_airtime_flush_ampdu(struct mt76_dev *dev)
1188{
1189 struct mt76_wcid *wcid;
1190 int wcid_idx;
1191
1192 if (!dev->rx_ampdu_len)
1193 return;
1194
1195 wcid_idx = dev->rx_ampdu_status.wcid_idx;
bf5238b2 1196 if (wcid_idx < ARRAY_SIZE(dev->wcid))
5ce09c1a
FF
1197 wcid = rcu_dereference(dev->wcid[wcid_idx]);
1198 else
1199 wcid = NULL;
1200 dev->rx_ampdu_status.wcid = wcid;
1201
1202 mt76_airtime_report(dev, &dev->rx_ampdu_status, dev->rx_ampdu_len);
1203
1204 dev->rx_ampdu_len = 0;
1205 dev->rx_ampdu_ref = 0;
1206}
1207
1208static void
1209mt76_airtime_check(struct mt76_dev *dev, struct sk_buff *skb)
1210{
5ce09c1a
FF
1211 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
1212 struct mt76_wcid *wcid = status->wcid;
1213
1214 if (!(dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME))
1215 return;
1216
1217 if (!wcid || !wcid->sta) {
e195dad1
FF
1218 struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
1219
1220 if (status->flag & RX_FLAG_8023)
1221 return;
1222
98df2bae 1223 if (!ether_addr_equal(hdr->addr1, dev->phy.macaddr))
5ce09c1a
FF
1224 return;
1225
1226 wcid = NULL;
1227 }
1228
1229 if (!(status->flag & RX_FLAG_AMPDU_DETAILS) ||
1230 status->ampdu_ref != dev->rx_ampdu_ref)
1231 mt76_airtime_flush_ampdu(dev);
1232
1233 if (status->flag & RX_FLAG_AMPDU_DETAILS) {
1234 if (!dev->rx_ampdu_len ||
1235 status->ampdu_ref != dev->rx_ampdu_ref) {
1236 dev->rx_ampdu_status = *status;
1237 dev->rx_ampdu_status.wcid_idx = wcid ? wcid->idx : 0xff;
1238 dev->rx_ampdu_ref = status->ampdu_ref;
1239 }
1240
1241 dev->rx_ampdu_len += skb->len;
1242 return;
1243 }
1244
1245 mt76_airtime_report(dev, status, skb->len);
1246}
1247
d71ef286 1248static void
ef13edc0 1249mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
d71ef286 1250{
13381dcd 1251 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
77ae1d5e 1252 struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
d71ef286 1253 struct ieee80211_sta *sta;
bfc394dd 1254 struct ieee80211_hw *hw;
d71ef286 1255 struct mt76_wcid *wcid = status->wcid;
e195dad1 1256 u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
d71ef286
FF
1257 bool ps;
1258
128c9b7d 1259 hw = mt76_phy_hw(dev, status->phy_idx);
e195dad1
FF
1260 if (ieee80211_is_pspoll(hdr->frame_control) && !wcid &&
1261 !(status->flag & RX_FLAG_8023)) {
bfc394dd 1262 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
36d91096 1263 if (sta)
13381dcd 1264 wcid = status->wcid = (struct mt76_wcid *)sta->drv_priv;
36d91096
FF
1265 }
1266
5ce09c1a
FF
1267 mt76_airtime_check(dev, skb);
1268
d71ef286
FF
1269 if (!wcid || !wcid->sta)
1270 return;
1271
13381dcd 1272 sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
d71ef286 1273
02e5a769
FF
1274 if (status->signal <= 0)
1275 ewma_signal_add(&wcid->rssi, -status->signal);
1276
ef13edc0
FF
1277 wcid->inactive_count = 0;
1278
e195dad1
FF
1279 if (status->flag & RX_FLAG_8023)
1280 return;
1281
d71ef286
FF
1282 if (!test_bit(MT_WCID_FLAG_CHECK_PS, &wcid->flags))
1283 return;
1284
1285 if (ieee80211_is_pspoll(hdr->frame_control)) {
1286 ieee80211_sta_pspoll(sta);
1287 return;
1288 }
1289
1290 if (ieee80211_has_morefrags(hdr->frame_control) ||
13381dcd
RL
1291 !(ieee80211_is_mgmt(hdr->frame_control) ||
1292 ieee80211_is_data(hdr->frame_control)))
d71ef286
FF
1293 return;
1294
1295 ps = ieee80211_has_pm(hdr->frame_control);
1296
1297 if (ps && (ieee80211_is_data_qos(hdr->frame_control) ||
1298 ieee80211_is_qos_nullfunc(hdr->frame_control)))
e195dad1 1299 ieee80211_sta_uapsd_trigger(sta, tidno);
d71ef286
FF
1300
1301 if (!!test_bit(MT_WCID_FLAG_PS, &wcid->flags) == ps)
1302 return;
1303
11b2a25f 1304 if (ps)
d71ef286 1305 set_bit(MT_WCID_FLAG_PS, &wcid->flags);
d71ef286 1306
d71ef286 1307 dev->drv->sta_ps(dev, sta, ps);
608f7c47
FF
1308
1309 if (!ps)
1310 clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
1311
9f67c277 1312 ieee80211_sta_ps_transition(sta, ps);
d71ef286
FF
1313}
1314
9d9d738b 1315void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
81e850ef 1316 struct napi_struct *napi)
17f1de56 1317{
9c68a57b 1318 struct ieee80211_sta *sta;
bfc394dd 1319 struct ieee80211_hw *hw;
3298b1f8
FF
1320 struct sk_buff *skb, *tmp;
1321 LIST_HEAD(list);
9d9d738b 1322
c3d7c82a 1323 spin_lock(&dev->rx_lock);
9d9d738b 1324 while ((skb = __skb_dequeue(frames)) != NULL) {
cc4b3c13
LB
1325 struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
1326
3c1032e1 1327 mt76_check_ccmp_pn(skb);
cc4b3c13 1328 skb_shinfo(skb)->frag_list = NULL;
bfc394dd 1329 mt76_rx_convert(dev, skb, &hw, &sta);
3298b1f8 1330 ieee80211_rx_list(hw, sta, skb, &list);
cc4b3c13
LB
1331
1332 /* subsequent amsdu frames */
1333 while (nskb) {
1334 skb = nskb;
1335 nskb = nskb->next;
1336 skb->next = NULL;
1337
1338 mt76_rx_convert(dev, skb, &hw, &sta);
1339 ieee80211_rx_list(hw, sta, skb, &list);
1340 }
9d9d738b 1341 }
c3d7c82a 1342 spin_unlock(&dev->rx_lock);
3298b1f8
FF
1343
1344 if (!napi) {
1345 netif_receive_skb_list(&list);
1346 return;
1347 }
1348
1349 list_for_each_entry_safe(skb, tmp, &list, list) {
1350 skb_list_del_init(skb);
1351 napi_gro_receive(napi, skb);
1352 }
9d9d738b
FF
1353}
1354
81e850ef
LB
1355void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
1356 struct napi_struct *napi)
9d9d738b 1357{
aee5b8cf 1358 struct sk_buff_head frames;
17f1de56
FF
1359 struct sk_buff *skb;
1360
aee5b8cf
FF
1361 __skb_queue_head_init(&frames);
1362
d71ef286 1363 while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
ef13edc0 1364 mt76_check_sta(dev, skb);
4f831d18
LB
1365 if (mtk_wed_device_active(&dev->mmio.wed))
1366 __skb_queue_tail(&frames, skb);
1367 else
1368 mt76_rx_aggr_reorder(skb, &frames);
d71ef286 1369 }
aee5b8cf 1370
81e850ef 1371 mt76_rx_complete(dev, &frames, napi);
17f1de56 1372}
81e850ef 1373EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
723b90dc 1374
e28487ea 1375static int
a1a99d7b
LB
1376mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,
1377 struct ieee80211_sta *sta)
e28487ea
FF
1378{
1379 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
a1a99d7b 1380 struct mt76_dev *dev = phy->dev;
e28487ea
FF
1381 int ret;
1382 int i;
1383
1384 mutex_lock(&dev->mutex);
1385
1386 ret = dev->drv->sta_add(dev, vif, sta);
1387 if (ret)
1388 goto out;
1389
1390 for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
1391 struct mt76_txq *mtxq;
1392
1393 if (!sta->txq[i])
1394 continue;
1395
1396 mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
51fb1278 1397 mtxq->wcid = wcid->idx;
e28487ea
FF
1398 }
1399
ef13edc0 1400 ewma_signal_init(&wcid->rssi);
a1a99d7b 1401 if (phy->band_idx == MT_BAND1)
426e8e41 1402 mt76_wcid_mask_set(dev->wcid_phy_mask, wcid->idx);
a1a99d7b 1403 wcid->phy_idx = phy->band_idx;
e28487ea
FF
1404 rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
1405
bd1e3e7b 1406 mt76_packet_id_init(wcid);
e28487ea
FF
1407out:
1408 mutex_unlock(&dev->mutex);
1409
1410 return ret;
1411}
1412
13f61dfc
LB
1413void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
1414 struct ieee80211_sta *sta)
723b90dc
FF
1415{
1416 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
13f61dfc 1417 int i, idx = wcid->idx;
723b90dc 1418
58bab0d4
FF
1419 for (i = 0; i < ARRAY_SIZE(wcid->aggr); i++)
1420 mt76_rx_aggr_stop(dev, wcid, i);
1421
e28487ea
FF
1422 if (dev->drv->sta_remove)
1423 dev->drv->sta_remove(dev, vif, sta);
1424
bd1e3e7b
LB
1425 mt76_packet_id_flush(dev, wcid);
1426
426e8e41
FF
1427 mt76_wcid_mask_clear(dev->wcid_mask, idx);
1428 mt76_wcid_mask_clear(dev->wcid_phy_mask, idx);
13f61dfc
LB
1429}
1430EXPORT_SYMBOL_GPL(__mt76_sta_remove);
e28487ea 1431
13f61dfc
LB
1432static void
1433mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
1434 struct ieee80211_sta *sta)
1435{
1436 mutex_lock(&dev->mutex);
1437 __mt76_sta_remove(dev, vif, sta);
723b90dc
FF
1438 mutex_unlock(&dev->mutex);
1439}
e28487ea
FF
1440
1441int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1442 struct ieee80211_sta *sta,
1443 enum ieee80211_sta_state old_state,
1444 enum ieee80211_sta_state new_state)
1445{
426e8e41
FF
1446 struct mt76_phy *phy = hw->priv;
1447 struct mt76_dev *dev = phy->dev;
e28487ea
FF
1448
1449 if (old_state == IEEE80211_STA_NOTEXIST &&
1450 new_state == IEEE80211_STA_NONE)
a1a99d7b 1451 return mt76_sta_add(phy, vif, sta);
e28487ea 1452
9c193de5
FF
1453 if (old_state == IEEE80211_STA_AUTH &&
1454 new_state == IEEE80211_STA_ASSOC &&
1455 dev->drv->sta_assoc)
1456 dev->drv->sta_assoc(dev, vif, sta);
1457
e28487ea 1458 if (old_state == IEEE80211_STA_NONE &&
13381dcd 1459 new_state == IEEE80211_STA_NOTEXIST)
e28487ea
FF
1460 mt76_sta_remove(dev, vif, sta);
1461
1462 return 0;
1463}
1464EXPORT_SYMBOL_GPL(mt76_sta_state);
9313faac 1465
43ba1922
FF
1466void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1467 struct ieee80211_sta *sta)
1468{
1469 struct mt76_phy *phy = hw->priv;
1470 struct mt76_dev *dev = phy->dev;
1471 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
1472
1473 mutex_lock(&dev->mutex);
fcfe1b5e 1474 spin_lock_bh(&dev->status_lock);
43ba1922 1475 rcu_assign_pointer(dev->wcid[wcid->idx], NULL);
fcfe1b5e 1476 spin_unlock_bh(&dev->status_lock);
43ba1922
FF
1477 mutex_unlock(&dev->mutex);
1478}
1479EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove);
1480
9313faac
FF
1481int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1482 int *dbm)
1483{
beaaeb6b
FF
1484 struct mt76_phy *phy = hw->priv;
1485 int n_chains = hweight8(phy->antenna_mask);
07cda406 1486 int delta = mt76_tx_power_nss_delta(n_chains);
9313faac 1487
07cda406 1488 *dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
9313faac
FF
1489
1490 return 0;
1491}
1492EXPORT_SYMBOL_GPL(mt76_get_txpower);
e7173858 1493
b3cb885e
LB
1494int mt76_init_sar_power(struct ieee80211_hw *hw,
1495 const struct cfg80211_sar_specs *sar)
1496{
1497 struct mt76_phy *phy = hw->priv;
1498 const struct cfg80211_sar_capa *capa = hw->wiphy->sar_capa;
1499 int i;
1500
1501 if (sar->type != NL80211_SAR_TYPE_POWER || !sar->num_sub_specs)
1502 return -EINVAL;
1503
1504 for (i = 0; i < sar->num_sub_specs; i++) {
1505 u32 index = sar->sub_specs[i].freq_range_index;
1506 /* SAR specifies power limitaton in 0.25dbm */
1507 s32 power = sar->sub_specs[i].power >> 1;
1508
1509 if (power > 127 || power < -127)
1510 power = 127;
1511
1512 phy->frp[index].range = &capa->freq_ranges[index];
1513 phy->frp[index].power = power;
1514 }
1515
1516 return 0;
1517}
1518EXPORT_SYMBOL_GPL(mt76_init_sar_power);
1519
1520int mt76_get_sar_power(struct mt76_phy *phy,
1521 struct ieee80211_channel *chan,
1522 int power)
1523{
1524 const struct cfg80211_sar_capa *capa = phy->hw->wiphy->sar_capa;
1525 int freq, i;
1526
1527 if (!capa || !phy->frp)
1528 return power;
1529
1530 if (power > 127 || power < -127)
1531 power = 127;
1532
1533 freq = ieee80211_channel_to_frequency(chan->hw_value, chan->band);
1534 for (i = 0 ; i < capa->num_freq_ranges; i++) {
1535 if (phy->frp[i].range &&
1536 freq >= phy->frp[i].range->start_freq &&
1537 freq < phy->frp[i].range->end_freq) {
1538 power = min_t(int, phy->frp[i].power, power);
1539 break;
1540 }
1541 }
1542
1543 return power;
1544}
1545EXPORT_SYMBOL_GPL(mt76_get_sar_power);
1546
e7173858
FF
1547static void
1548__mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
1549{
d0a9123e 1550 if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
13381dcd 1551 ieee80211_csa_finish(vif);
e7173858
FF
1552}
1553
1554void mt76_csa_finish(struct mt76_dev *dev)
1555{
1556 if (!dev->csa_complete)
1557 return;
1558
1559 ieee80211_iterate_active_interfaces_atomic(dev->hw,
1560 IEEE80211_IFACE_ITER_RESUME_ALL,
1561 __mt76_csa_finish, dev);
1562
1563 dev->csa_complete = 0;
1564}
1565EXPORT_SYMBOL_GPL(mt76_csa_finish);
1566
1567static void
1568__mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
1569{
1570 struct mt76_dev *dev = priv;
1571
d0a9123e 1572 if (!vif->bss_conf.csa_active)
e7173858
FF
1573 return;
1574
8552a434 1575 dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif);
e7173858
FF
1576}
1577
1578void mt76_csa_check(struct mt76_dev *dev)
1579{
1580 ieee80211_iterate_active_interfaces_atomic(dev->hw,
1581 IEEE80211_IFACE_ITER_RESUME_ALL,
1582 __mt76_csa_check, dev);
1583}
1584EXPORT_SYMBOL_GPL(mt76_csa_check);
87d53103
SG
1585
1586int
1587mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
1588{
1589 return 0;
1590}
1591EXPORT_SYMBOL_GPL(mt76_set_tim);
eadfd98f
LB
1592
1593void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id)
1594{
1595 struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
1596 int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
1597 u8 *hdr, *pn = status->iv;
1598
1599 __skb_push(skb, 8);
1600 memmove(skb->data, skb->data + 8, hdr_len);
1601 hdr = skb->data + hdr_len;
1602
1603 hdr[0] = pn[5];
1604 hdr[1] = pn[4];
1605 hdr[2] = 0;
1606 hdr[3] = 0x20 | (key_id << 6);
1607 hdr[4] = pn[3];
1608 hdr[5] = pn[2];
1609 hdr[6] = pn[1];
1610 hdr[7] = pn[0];
1611
1612 status->flag &= ~RX_FLAG_IV_STRIPPED;
1613}
1614EXPORT_SYMBOL_GPL(mt76_insert_ccmp_hdr);
d2679d65
LB
1615
1616int mt76_get_rate(struct mt76_dev *dev,
1617 struct ieee80211_supported_band *sband,
1618 int idx, bool cck)
1619{
1620 int i, offset = 0, len = sband->n_bitrates;
1621
1622 if (cck) {
edf9dab8 1623 if (sband != &dev->phy.sband_2g.sband)
d2679d65
LB
1624 return 0;
1625
1626 idx &= ~BIT(2); /* short preamble */
96747a51 1627 } else if (sband == &dev->phy.sband_2g.sband) {
d2679d65
LB
1628 offset = 4;
1629 }
1630
1631 for (i = offset; i < len; i++) {
1632 if ((sband->bitrates[i].hw_value & GENMASK(7, 0)) == idx)
1633 return i;
1634 }
1635
1636 return 0;
1637}
1638EXPORT_SYMBOL_GPL(mt76_get_rate);
8b8ab5c2
LB
1639
1640void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1641 const u8 *mac)
1642{
011849e0 1643 struct mt76_phy *phy = hw->priv;
8b8ab5c2 1644
011849e0 1645 set_bit(MT76_SCANNING, &phy->state);
8b8ab5c2
LB
1646}
1647EXPORT_SYMBOL_GPL(mt76_sw_scan);
1648
1649void mt76_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1650{
011849e0 1651 struct mt76_phy *phy = hw->priv;
8b8ab5c2 1652
011849e0 1653 clear_bit(MT76_SCANNING, &phy->state);
8b8ab5c2
LB
1654}
1655EXPORT_SYMBOL_GPL(mt76_sw_scan_complete);
e49c76d4
LB
1656
1657int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
1658{
beaaeb6b
FF
1659 struct mt76_phy *phy = hw->priv;
1660 struct mt76_dev *dev = phy->dev;
e49c76d4
LB
1661
1662 mutex_lock(&dev->mutex);
beaaeb6b
FF
1663 *tx_ant = phy->antenna_mask;
1664 *rx_ant = phy->antenna_mask;
e49c76d4
LB
1665 mutex_unlock(&dev->mutex);
1666
1667 return 0;
1668}
1669EXPORT_SYMBOL_GPL(mt76_get_antenna);
b671da33 1670
b1cb42ad
LB
1671struct mt76_queue *
1672mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
f68d6762 1673 int ring_base, u32 flags)
b671da33
LB
1674{
1675 struct mt76_queue *hwq;
1676 int err;
1677
1678 hwq = devm_kzalloc(dev->dev, sizeof(*hwq), GFP_KERNEL);
1679 if (!hwq)
b1cb42ad 1680 return ERR_PTR(-ENOMEM);
b671da33 1681
f68d6762
FF
1682 hwq->flags = flags;
1683
b671da33
LB
1684 err = dev->queue_ops->alloc(dev, hwq, idx, n_desc, 0, ring_base);
1685 if (err < 0)
b1cb42ad 1686 return ERR_PTR(err);
b671da33 1687
b1cb42ad 1688 return hwq;
b671da33 1689}
b1cb42ad 1690EXPORT_SYMBOL_GPL(mt76_init_queue);
e4867225 1691
33920b2b 1692u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx)
e4867225 1693{
33920b2b 1694 int offset = 0;
e4867225 1695
edf9dab8 1696 if (phy->chandef.chan->band != NL80211_BAND_2GHZ)
e4867225
SW
1697 offset = 4;
1698
33920b2b
RL
1699 /* pick the lowest rate for hidden nodes */
1700 if (rateidx < 0)
1701 rateidx = 0;
1702
d4f3d1c4
LB
1703 rateidx += offset;
1704 if (rateidx >= ARRAY_SIZE(mt76_rates))
1705 rateidx = offset;
e4867225 1706
d4f3d1c4 1707 return mt76_rates[rateidx].hw_value;
e4867225 1708}
33920b2b 1709EXPORT_SYMBOL_GPL(mt76_calculate_default_rate);
54ae98ff
LB
1710
1711void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
731425f3 1712 struct mt76_sta_stats *stats, bool eht)
54ae98ff
LB
1713{
1714 int i, ei = wi->initial_stat_idx;
1715 u64 *data = wi->data;
1716
1717 wi->sta_count++;
1718
1719 data[ei++] += stats->tx_mode[MT_PHY_TYPE_CCK];
1720 data[ei++] += stats->tx_mode[MT_PHY_TYPE_OFDM];
1721 data[ei++] += stats->tx_mode[MT_PHY_TYPE_HT];
1722 data[ei++] += stats->tx_mode[MT_PHY_TYPE_HT_GF];
1723 data[ei++] += stats->tx_mode[MT_PHY_TYPE_VHT];
1724 data[ei++] += stats->tx_mode[MT_PHY_TYPE_HE_SU];
1725 data[ei++] += stats->tx_mode[MT_PHY_TYPE_HE_EXT_SU];
1726 data[ei++] += stats->tx_mode[MT_PHY_TYPE_HE_TB];
1727 data[ei++] += stats->tx_mode[MT_PHY_TYPE_HE_MU];
731425f3
SC
1728 if (eht) {
1729 data[ei++] += stats->tx_mode[MT_PHY_TYPE_EHT_SU];
1730 data[ei++] += stats->tx_mode[MT_PHY_TYPE_EHT_TRIG];
1731 data[ei++] += stats->tx_mode[MT_PHY_TYPE_EHT_MU];
1732 }
54ae98ff 1733
731425f3 1734 for (i = 0; i < (ARRAY_SIZE(stats->tx_bw) - !eht); i++)
54ae98ff
LB
1735 data[ei++] += stats->tx_bw[i];
1736
731425f3 1737 for (i = 0; i < (eht ? 14 : 12); i++)
54ae98ff
LB
1738 data[ei++] += stats->tx_mcs[i];
1739
1740 wi->worker_stat_count = ei - wi->initial_stat_idx;
1741}
1742EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
3f306448 1743
192ad406
LB
1744void mt76_ethtool_page_pool_stats(struct mt76_dev *dev, u64 *data, int *index)
1745{
1746#ifdef CONFIG_PAGE_POOL_STATS
1747 struct page_pool_stats stats = {};
1748 int i;
1749
1750 mt76_for_each_q_rx(dev, i)
1751 page_pool_get_stats(dev->q_rx[i].page_pool, &stats);
1752
1753 page_pool_ethtool_stats_get(data, &stats);
1754 *index += page_pool_ethtool_stats_get_count();
1755#endif
1756}
1757EXPORT_SYMBOL_GPL(mt76_ethtool_page_pool_stats);
1758
3f306448
FF
1759enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
1760{
1761 struct ieee80211_hw *hw = phy->hw;
1762 struct mt76_dev *dev = phy->dev;
1763
1764 if (dev->region == NL80211_DFS_UNSET ||
1765 test_bit(MT76_SCANNING, &phy->state))
1766 return MT_DFS_STATE_DISABLED;
1767
1768 if (!hw->conf.radar_enabled) {
1769 if ((hw->conf.flags & IEEE80211_CONF_MONITOR) &&
1770 (phy->chandef.chan->flags & IEEE80211_CHAN_RADAR))
1771 return MT_DFS_STATE_ACTIVE;
1772
1773 return MT_DFS_STATE_DISABLED;
1774 }
1775
00a883e6 1776 if (!cfg80211_reg_can_beacon(hw->wiphy, &phy->chandef, NL80211_IFTYPE_AP))
3f306448
FF
1777 return MT_DFS_STATE_CAC;
1778
1779 return MT_DFS_STATE_ACTIVE;
1780}
1781EXPORT_SYMBOL_GPL(mt76_phy_dfs_state);