forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/net/wireless/mediatek/mt76/mac80211.c
....@@ -1,18 +1,8 @@
1
+// SPDX-License-Identifier: ISC
12 /*
23 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
3
- *
4
- * Permission to use, copy, modify, and/or distribute this software for any
5
- * purpose with or without fee is hereby granted, provided that the above
6
- * copyright notice and this permission notice appear in all copies.
7
- *
8
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
154 */
5
+#include <linux/sched.h>
166 #include <linux/of.h>
177 #include "mt76.h"
188
....@@ -69,12 +59,15 @@
6959 CHAN5G(132, 5660),
7060 CHAN5G(136, 5680),
7161 CHAN5G(140, 5700),
62
+ CHAN5G(144, 5720),
7263
7364 CHAN5G(149, 5745),
7465 CHAN5G(153, 5765),
7566 CHAN5G(157, 5785),
7667 CHAN5G(161, 5805),
7768 CHAN5G(165, 5825),
69
+ CHAN5G(169, 5845),
70
+ CHAN5G(173, 5865),
7871 };
7972
8073 static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
....@@ -114,17 +107,26 @@
114107 if (!of_property_read_u32(np, "led-sources", &led_pin))
115108 dev->led_pin = led_pin;
116109 dev->led_al = of_property_read_bool(np, "led-active-low");
110
+ of_node_put(np);
117111 }
118112
119
- return devm_led_classdev_register(dev->dev, &dev->led_cdev);
113
+ return led_classdev_register(dev->dev, &dev->led_cdev);
120114 }
121115
122
-static void mt76_init_stream_cap(struct mt76_dev *dev,
116
+static void mt76_led_cleanup(struct mt76_dev *dev)
117
+{
118
+ if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set)
119
+ return;
120
+
121
+ led_classdev_unregister(&dev->led_cdev);
122
+}
123
+
124
+static void mt76_init_stream_cap(struct mt76_phy *phy,
123125 struct ieee80211_supported_band *sband,
124126 bool vht)
125127 {
126128 struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
127
- int i, nstream = __sw_hweight8(dev->antenna_mask);
129
+ int i, nstream = hweight8(phy->antenna_mask);
128130 struct ieee80211_sta_vht_cap *vht_cap;
129131 u16 mcs_map = 0;
130132
....@@ -156,12 +158,12 @@
156158 vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
157159 }
158160
159
-void mt76_set_stream_caps(struct mt76_dev *dev, bool vht)
161
+void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
160162 {
161
- if (dev->cap.has_2ghz)
162
- mt76_init_stream_cap(dev, &dev->sband_2g.sband, false);
163
- if (dev->cap.has_5ghz)
164
- mt76_init_stream_cap(dev, &dev->sband_5g.sband, vht);
163
+ if (phy->cap.has_2ghz)
164
+ mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
165
+ if (phy->cap.has_5ghz)
166
+ mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
165167 }
166168 EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
167169
....@@ -190,7 +192,6 @@
190192 sband->n_channels = n_chan;
191193 sband->bitrates = rates;
192194 sband->n_bitrates = n_rates;
193
- dev->chandef.chan = &sband->channels[0];
194195
195196 ht_cap = &sband->ht_cap;
196197 ht_cap->ht_supported = true;
....@@ -202,9 +203,8 @@
202203
203204 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
204205 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
205
- ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
206206
207
- mt76_init_stream_cap(dev, sband, vht);
207
+ mt76_init_stream_cap(&dev->phy, sband, vht);
208208
209209 if (!vht)
210210 return 0;
....@@ -214,6 +214,8 @@
214214 vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC |
215215 IEEE80211_VHT_CAP_RXSTBC_1 |
216216 IEEE80211_VHT_CAP_SHORT_GI_80 |
217
+ IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
218
+ IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |
217219 (3 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
218220
219221 return 0;
....@@ -223,9 +225,9 @@
223225 mt76_init_sband_2g(struct mt76_dev *dev, struct ieee80211_rate *rates,
224226 int n_rates)
225227 {
226
- dev->hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->sband_2g.sband;
228
+ dev->hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->phy.sband_2g.sband;
227229
228
- return mt76_init_sband(dev, &dev->sband_2g,
230
+ return mt76_init_sband(dev, &dev->phy.sband_2g,
229231 mt76_channels_2ghz,
230232 ARRAY_SIZE(mt76_channels_2ghz),
231233 rates, n_rates, false);
....@@ -235,18 +237,19 @@
235237 mt76_init_sband_5g(struct mt76_dev *dev, struct ieee80211_rate *rates,
236238 int n_rates, bool vht)
237239 {
238
- dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = &dev->sband_5g.sband;
240
+ dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = &dev->phy.sband_5g.sband;
239241
240
- return mt76_init_sband(dev, &dev->sband_5g,
242
+ return mt76_init_sband(dev, &dev->phy.sband_5g,
241243 mt76_channels_5ghz,
242244 ARRAY_SIZE(mt76_channels_5ghz),
243245 rates, n_rates, vht);
244246 }
245247
246248 static void
247
-mt76_check_sband(struct mt76_dev *dev, int band)
249
+mt76_check_sband(struct mt76_phy *phy, struct mt76_sband *msband,
250
+ enum nl80211_band band)
248251 {
249
- struct ieee80211_supported_band *sband = dev->hw->wiphy->bands[band];
252
+ struct ieee80211_supported_band *sband = &msband->sband;
250253 bool found = false;
251254 int i;
252255
....@@ -261,18 +264,154 @@
261264 break;
262265 }
263266
264
- if (found)
267
+ if (found) {
268
+ phy->chandef.chan = &sband->channels[0];
269
+ phy->chan_state = &msband->chan[0];
265270 return;
271
+ }
266272
267273 sband->n_channels = 0;
268
- dev->hw->wiphy->bands[band] = NULL;
274
+ phy->hw->wiphy->bands[band] = NULL;
269275 }
270276
271
-struct mt76_dev *
272
-mt76_alloc_device(unsigned int size, const struct ieee80211_ops *ops)
277
+static void
278
+mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
279
+{
280
+ struct wiphy *wiphy = hw->wiphy;
281
+
282
+ SET_IEEE80211_DEV(hw, dev->dev);
283
+ SET_IEEE80211_PERM_ADDR(hw, dev->macaddr);
284
+
285
+ wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
286
+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
287
+ WIPHY_FLAG_SUPPORTS_TDLS |
288
+ WIPHY_FLAG_AP_UAPSD;
289
+
290
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
291
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
292
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
293
+
294
+ wiphy->available_antennas_tx = dev->phy.antenna_mask;
295
+ wiphy->available_antennas_rx = dev->phy.antenna_mask;
296
+
297
+ hw->txq_data_size = sizeof(struct mt76_txq);
298
+ hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
299
+
300
+ if (!hw->max_tx_fragments)
301
+ hw->max_tx_fragments = 16;
302
+
303
+ ieee80211_hw_set(hw, SIGNAL_DBM);
304
+ ieee80211_hw_set(hw, AMPDU_AGGREGATION);
305
+ ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
306
+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
307
+ ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
308
+ ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
309
+ ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
310
+
311
+ if (!(dev->drv->drv_flags & MT_DRV_AMSDU_OFFLOAD)) {
312
+ ieee80211_hw_set(hw, TX_AMSDU);
313
+ ieee80211_hw_set(hw, TX_FRAG_LIST);
314
+ }
315
+
316
+ ieee80211_hw_set(hw, MFP_CAPABLE);
317
+ ieee80211_hw_set(hw, AP_LINK_PS);
318
+ ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
319
+ ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
320
+
321
+ wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
322
+ wiphy->interface_modes =
323
+ BIT(NL80211_IFTYPE_STATION) |
324
+ BIT(NL80211_IFTYPE_AP) |
325
+#ifdef CONFIG_MAC80211_MESH
326
+ BIT(NL80211_IFTYPE_MESH_POINT) |
327
+#endif
328
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
329
+ BIT(NL80211_IFTYPE_P2P_GO) |
330
+ BIT(NL80211_IFTYPE_ADHOC);
331
+}
332
+
333
+struct mt76_phy *
334
+mt76_alloc_phy(struct mt76_dev *dev, unsigned int size,
335
+ const struct ieee80211_ops *ops)
273336 {
274337 struct ieee80211_hw *hw;
338
+ struct mt76_phy *phy;
339
+ unsigned int phy_size, chan_size;
340
+ unsigned int size_2g, size_5g;
341
+ void *priv;
342
+
343
+ phy_size = ALIGN(sizeof(*phy), 8);
344
+ chan_size = sizeof(dev->phy.sband_2g.chan[0]);
345
+ size_2g = ALIGN(ARRAY_SIZE(mt76_channels_2ghz) * chan_size, 8);
346
+ size_5g = ALIGN(ARRAY_SIZE(mt76_channels_5ghz) * chan_size, 8);
347
+
348
+ size += phy_size + size_2g + size_5g;
349
+ hw = ieee80211_alloc_hw(size, ops);
350
+ if (!hw)
351
+ return NULL;
352
+
353
+ phy = hw->priv;
354
+ phy->dev = dev;
355
+ phy->hw = hw;
356
+
357
+ mt76_phy_init(dev, hw);
358
+
359
+ priv = hw->priv + phy_size;
360
+
361
+ phy->sband_2g = dev->phy.sband_2g;
362
+ phy->sband_2g.chan = priv;
363
+ priv += size_2g;
364
+
365
+ phy->sband_5g = dev->phy.sband_5g;
366
+ phy->sband_5g.chan = priv;
367
+ priv += size_5g;
368
+
369
+ phy->priv = priv;
370
+
371
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = &phy->sband_2g.sband;
372
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = &phy->sband_5g.sband;
373
+
374
+ mt76_check_sband(phy, &phy->sband_2g, NL80211_BAND_2GHZ);
375
+ mt76_check_sband(phy, &phy->sband_5g, NL80211_BAND_5GHZ);
376
+
377
+ return phy;
378
+}
379
+EXPORT_SYMBOL_GPL(mt76_alloc_phy);
380
+
381
+int
382
+mt76_register_phy(struct mt76_phy *phy)
383
+{
384
+ int ret;
385
+
386
+ ret = ieee80211_register_hw(phy->hw);
387
+ if (ret)
388
+ return ret;
389
+
390
+ phy->dev->phy2 = phy;
391
+ return 0;
392
+}
393
+EXPORT_SYMBOL_GPL(mt76_register_phy);
394
+
395
+void
396
+mt76_unregister_phy(struct mt76_phy *phy)
397
+{
398
+ struct mt76_dev *dev = phy->dev;
399
+
400
+ dev->phy2 = NULL;
401
+ mt76_tx_status_check(dev, NULL, true);
402
+ ieee80211_unregister_hw(phy->hw);
403
+}
404
+EXPORT_SYMBOL_GPL(mt76_unregister_phy);
405
+
406
+struct mt76_dev *
407
+mt76_alloc_device(struct device *pdev, unsigned int size,
408
+ const struct ieee80211_ops *ops,
409
+ const struct mt76_driver_ops *drv_ops)
410
+{
411
+ struct ieee80211_hw *hw;
412
+ struct mt76_phy *phy;
275413 struct mt76_dev *dev;
414
+ int i;
276415
277416 hw = ieee80211_alloc_hw(size, ops);
278417 if (!hw)
....@@ -280,10 +419,35 @@
280419
281420 dev = hw->priv;
282421 dev->hw = hw;
422
+ dev->dev = pdev;
423
+ dev->drv = drv_ops;
424
+
425
+ phy = &dev->phy;
426
+ phy->dev = dev;
427
+ phy->hw = hw;
428
+
283429 spin_lock_init(&dev->rx_lock);
284430 spin_lock_init(&dev->lock);
285431 spin_lock_init(&dev->cc_lock);
432
+ mutex_init(&dev->mutex);
286433 init_waitqueue_head(&dev->tx_wait);
434
+ skb_queue_head_init(&dev->status_list);
435
+
436
+ skb_queue_head_init(&dev->mcu.res_q);
437
+ init_waitqueue_head(&dev->mcu.wait);
438
+ mutex_init(&dev->mcu.mutex);
439
+ dev->tx_worker.fn = mt76_tx_worker;
440
+
441
+ INIT_LIST_HEAD(&dev->txwi_cache);
442
+
443
+ for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
444
+ skb_queue_head_init(&dev->rx_skb[i]);
445
+
446
+ dev->wq = alloc_ordered_workqueue("mt76", 0);
447
+ if (!dev->wq) {
448
+ ieee80211_free_hw(hw);
449
+ return NULL;
450
+ }
287451
288452 return dev;
289453 }
....@@ -293,54 +457,27 @@
293457 struct ieee80211_rate *rates, int n_rates)
294458 {
295459 struct ieee80211_hw *hw = dev->hw;
296
- struct wiphy *wiphy = hw->wiphy;
460
+ struct mt76_phy *phy = &dev->phy;
297461 int ret;
298462
299463 dev_set_drvdata(dev->dev, dev);
464
+ mt76_phy_init(dev, hw);
300465
301
- INIT_LIST_HEAD(&dev->txwi_cache);
302
-
303
- SET_IEEE80211_DEV(hw, dev->dev);
304
- SET_IEEE80211_PERM_ADDR(hw, dev->macaddr);
305
-
306
- wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
307
-
308
- wiphy->available_antennas_tx = dev->antenna_mask;
309
- wiphy->available_antennas_rx = dev->antenna_mask;
310
-
311
- hw->txq_data_size = sizeof(struct mt76_txq);
312
- hw->max_tx_fragments = 16;
313
-
314
- ieee80211_hw_set(hw, SIGNAL_DBM);
315
- ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
316
- ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
317
- ieee80211_hw_set(hw, AMPDU_AGGREGATION);
318
- ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
319
- ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
320
- ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
321
- ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
322
- ieee80211_hw_set(hw, TX_AMSDU);
323
- ieee80211_hw_set(hw, TX_FRAG_LIST);
324
- ieee80211_hw_set(hw, MFP_CAPABLE);
325
- ieee80211_hw_set(hw, AP_LINK_PS);
326
-
327
- wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
328
-
329
- if (dev->cap.has_2ghz) {
466
+ if (phy->cap.has_2ghz) {
330467 ret = mt76_init_sband_2g(dev, rates, n_rates);
331468 if (ret)
332469 return ret;
333470 }
334471
335
- if (dev->cap.has_5ghz) {
472
+ if (phy->cap.has_5ghz) {
336473 ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
337474 if (ret)
338475 return ret;
339476 }
340477
341
- wiphy_read_of_freq_limits(dev->hw->wiphy);
342
- mt76_check_sband(dev, NL80211_BAND_2GHZ);
343
- mt76_check_sband(dev, NL80211_BAND_5GHZ);
478
+ wiphy_read_of_freq_limits(hw->wiphy);
479
+ mt76_check_sband(&dev->phy, &phy->sband_2g, NL80211_BAND_2GHZ);
480
+ mt76_check_sband(&dev->phy, &phy->sband_5g, NL80211_BAND_5GHZ);
344481
345482 if (IS_ENABLED(CONFIG_MT76_LEDS)) {
346483 ret = mt76_led_init(dev);
....@@ -348,7 +485,14 @@
348485 return ret;
349486 }
350487
351
- return ieee80211_register_hw(hw);
488
+ ret = ieee80211_register_hw(hw);
489
+ if (ret)
490
+ return ret;
491
+
492
+ WARN_ON(mt76_worker_setup(hw, &dev->tx_worker, NULL, "tx"));
493
+ sched_set_fifo_low(dev->tx_worker.task);
494
+
495
+ return 0;
352496 }
353497 EXPORT_SYMBOL_GPL(mt76_register_device);
354498
....@@ -356,98 +500,187 @@
356500 {
357501 struct ieee80211_hw *hw = dev->hw;
358502
503
+ if (IS_ENABLED(CONFIG_MT76_LEDS))
504
+ mt76_led_cleanup(dev);
505
+ mt76_tx_status_check(dev, NULL, true);
359506 ieee80211_unregister_hw(hw);
360
- mt76_tx_free(dev);
361507 }
362508 EXPORT_SYMBOL_GPL(mt76_unregister_device);
363509
510
+void mt76_free_device(struct mt76_dev *dev)
511
+{
512
+ mt76_worker_teardown(&dev->tx_worker);
513
+ if (dev->wq) {
514
+ destroy_workqueue(dev->wq);
515
+ dev->wq = NULL;
516
+ }
517
+ ieee80211_free_hw(dev->hw);
518
+}
519
+EXPORT_SYMBOL_GPL(mt76_free_device);
520
+
364521 void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
365522 {
366
- if (!test_bit(MT76_STATE_RUNNING, &dev->state)) {
523
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
524
+ struct mt76_phy *phy = mt76_dev_phy(dev, status->ext_phy);
525
+
526
+ if (!test_bit(MT76_STATE_RUNNING, &phy->state)) {
367527 dev_kfree_skb(skb);
368528 return;
369529 }
370530
531
+#ifdef CONFIG_NL80211_TESTMODE
532
+ if (dev->test.state == MT76_TM_STATE_RX_FRAMES) {
533
+ dev->test.rx_stats.packets[q]++;
534
+ if (status->flag & RX_FLAG_FAILED_FCS_CRC)
535
+ dev->test.rx_stats.fcs_error[q]++;
536
+ }
537
+#endif
371538 __skb_queue_tail(&dev->rx_skb[q], skb);
372539 }
373540 EXPORT_SYMBOL_GPL(mt76_rx);
374541
375
-static bool mt76_has_tx_pending(struct mt76_dev *dev)
542
+bool mt76_has_tx_pending(struct mt76_phy *phy)
376543 {
377
- int i;
544
+ struct mt76_dev *dev = phy->dev;
545
+ struct mt76_queue *q;
546
+ int i, offset;
378547
379
- for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
380
- if (dev->q_tx[i].queued)
548
+ offset = __MT_TXQ_MAX * (phy != &dev->phy);
549
+
550
+ for (i = 0; i < __MT_TXQ_MAX; i++) {
551
+ q = dev->q_tx[offset + i];
552
+ if (q && q->queued)
381553 return true;
382554 }
383555
384556 return false;
385557 }
558
+EXPORT_SYMBOL_GPL(mt76_has_tx_pending);
386559
387
-void mt76_set_channel(struct mt76_dev *dev)
560
+static struct mt76_channel_state *
561
+mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
388562 {
389
- struct ieee80211_hw *hw = dev->hw;
390
- struct cfg80211_chan_def *chandef = &hw->conf.chandef;
391
- struct mt76_channel_state *state;
392
- bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
393
- int timeout = HZ / 5;
563
+ struct mt76_sband *msband;
564
+ int idx;
394565
395
- if (offchannel)
396
- set_bit(MT76_OFFCHANNEL, &dev->state);
566
+ if (c->band == NL80211_BAND_2GHZ)
567
+ msband = &phy->sband_2g;
397568 else
398
- clear_bit(MT76_OFFCHANNEL, &dev->state);
569
+ msband = &phy->sband_5g;
399570
400
- wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), timeout);
571
+ idx = c - &msband->sband.channels[0];
572
+ return &msband->chan[idx];
573
+}
574
+
575
+void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
576
+{
577
+ struct mt76_channel_state *state = phy->chan_state;
578
+
579
+ state->cc_active += ktime_to_us(ktime_sub(time,
580
+ phy->survey_time));
581
+ phy->survey_time = time;
582
+}
583
+EXPORT_SYMBOL_GPL(mt76_update_survey_active_time);
584
+
585
+void mt76_update_survey(struct mt76_dev *dev)
586
+{
587
+ ktime_t cur_time;
401588
402589 if (dev->drv->update_survey)
403590 dev->drv->update_survey(dev);
404591
405
- dev->chandef = *chandef;
592
+ cur_time = ktime_get_boottime();
593
+ mt76_update_survey_active_time(&dev->phy, cur_time);
594
+ if (dev->phy2)
595
+ mt76_update_survey_active_time(dev->phy2, cur_time);
596
+
597
+ if (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME) {
598
+ struct mt76_channel_state *state = dev->phy.chan_state;
599
+
600
+ spin_lock_bh(&dev->cc_lock);
601
+ state->cc_bss_rx += dev->cur_cc_bss_rx;
602
+ dev->cur_cc_bss_rx = 0;
603
+ spin_unlock_bh(&dev->cc_lock);
604
+ }
605
+}
606
+EXPORT_SYMBOL_GPL(mt76_update_survey);
607
+
608
+void mt76_set_channel(struct mt76_phy *phy)
609
+{
610
+ struct mt76_dev *dev = phy->dev;
611
+ struct ieee80211_hw *hw = phy->hw;
612
+ struct cfg80211_chan_def *chandef = &hw->conf.chandef;
613
+ bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
614
+ int timeout = HZ / 5;
615
+
616
+ wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
617
+ mt76_update_survey(dev);
618
+
619
+ phy->chandef = *chandef;
620
+ phy->chan_state = mt76_channel_state(phy, chandef->chan);
406621
407622 if (!offchannel)
408
- dev->main_chan = chandef->chan;
623
+ phy->main_chan = chandef->chan;
409624
410
- if (chandef->chan != dev->main_chan) {
411
- state = mt76_channel_state(dev, chandef->chan);
412
- memset(state, 0, sizeof(*state));
413
- }
625
+ if (chandef->chan != phy->main_chan)
626
+ memset(phy->chan_state, 0, sizeof(*phy->chan_state));
414627 }
415628 EXPORT_SYMBOL_GPL(mt76_set_channel);
416629
417630 int mt76_get_survey(struct ieee80211_hw *hw, int idx,
418631 struct survey_info *survey)
419632 {
420
- struct mt76_dev *dev = hw->priv;
633
+ struct mt76_phy *phy = hw->priv;
634
+ struct mt76_dev *dev = phy->dev;
421635 struct mt76_sband *sband;
422636 struct ieee80211_channel *chan;
423637 struct mt76_channel_state *state;
424638 int ret = 0;
425639
640
+ mutex_lock(&dev->mutex);
426641 if (idx == 0 && dev->drv->update_survey)
427
- dev->drv->update_survey(dev);
642
+ mt76_update_survey(dev);
428643
429
- sband = &dev->sband_2g;
644
+ sband = &phy->sband_2g;
430645 if (idx >= sband->sband.n_channels) {
431646 idx -= sband->sband.n_channels;
432
- sband = &dev->sband_5g;
647
+ sband = &phy->sband_5g;
433648 }
434649
435
- if (idx >= sband->sband.n_channels)
436
- return -ENOENT;
650
+ if (idx >= sband->sband.n_channels) {
651
+ ret = -ENOENT;
652
+ goto out;
653
+ }
437654
438655 chan = &sband->sband.channels[idx];
439
- state = mt76_channel_state(dev, chan);
656
+ state = mt76_channel_state(phy, chan);
440657
441658 memset(survey, 0, sizeof(*survey));
442659 survey->channel = chan;
443660 survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY;
444
- if (chan == dev->main_chan)
661
+ survey->filled |= dev->drv->survey_flags;
662
+ if (state->noise)
663
+ survey->filled |= SURVEY_INFO_NOISE_DBM;
664
+
665
+ if (chan == phy->main_chan) {
445666 survey->filled |= SURVEY_INFO_IN_USE;
446667
447
- spin_lock_bh(&dev->cc_lock);
448
- survey->time = div_u64(state->cc_active, 1000);
668
+ if (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME)
669
+ survey->filled |= SURVEY_INFO_TIME_BSS_RX;
670
+ }
671
+
449672 survey->time_busy = div_u64(state->cc_busy, 1000);
673
+ survey->time_rx = div_u64(state->cc_rx, 1000);
674
+ survey->time = div_u64(state->cc_active, 1000);
675
+ survey->noise = state->noise;
676
+
677
+ spin_lock_bh(&dev->cc_lock);
678
+ survey->time_bss_rx = div_u64(state->cc_bss_rx, 1000);
679
+ survey->time_tx = div_u64(state->cc_tx, 1000);
450680 spin_unlock_bh(&dev->cc_lock);
681
+
682
+out:
683
+ mutex_unlock(&dev->mutex);
451684
452685 return ret;
453686 }
....@@ -464,9 +697,10 @@
464697 if (!key)
465698 return;
466699
467
- if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
468
- wcid->rx_check_pn = true;
700
+ if (key->cipher != WLAN_CIPHER_SUITE_CCMP)
701
+ return;
469702
703
+ wcid->rx_check_pn = true;
470704 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
471705 ieee80211_get_key_rx_seq(key, i, &seq);
472706 memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
....@@ -474,12 +708,15 @@
474708 }
475709 EXPORT_SYMBOL(mt76_wcid_key_setup);
476710
477
-static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
711
+static void
712
+mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
713
+ struct ieee80211_hw **hw,
714
+ struct ieee80211_sta **sta)
478715 {
479716 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
480717 struct mt76_rx_status mstat;
481718
482
- mstat = *((struct mt76_rx_status *) skb->cb);
719
+ mstat = *((struct mt76_rx_status *)skb->cb);
483720 memset(status, 0, sizeof(*status));
484721
485722 status->flag = mstat.flag;
....@@ -487,23 +724,30 @@
487724 status->enc_flags = mstat.enc_flags;
488725 status->encoding = mstat.encoding;
489726 status->bw = mstat.bw;
727
+ status->he_ru = mstat.he_ru;
728
+ status->he_gi = mstat.he_gi;
729
+ status->he_dcm = mstat.he_dcm;
490730 status->rate_idx = mstat.rate_idx;
491731 status->nss = mstat.nss;
492732 status->band = mstat.band;
493733 status->signal = mstat.signal;
494734 status->chains = mstat.chains;
735
+ status->ampdu_reference = mstat.ampdu_ref;
495736
496737 BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
497
- BUILD_BUG_ON(sizeof(status->chain_signal) != sizeof(mstat.chain_signal));
498
- memcpy(status->chain_signal, mstat.chain_signal, sizeof(mstat.chain_signal));
738
+ BUILD_BUG_ON(sizeof(status->chain_signal) !=
739
+ sizeof(mstat.chain_signal));
740
+ memcpy(status->chain_signal, mstat.chain_signal,
741
+ sizeof(mstat.chain_signal));
499742
500
- return wcid_to_sta(mstat.wcid);
743
+ *sta = wcid_to_sta(mstat.wcid);
744
+ *hw = mt76_phy_hw(dev, mstat.ext_phy);
501745 }
502746
503747 static int
504748 mt76_check_ccmp_pn(struct sk_buff *skb)
505749 {
506
- struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
750
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
507751 struct mt76_wcid *wcid = status->wcid;
508752 struct ieee80211_hdr *hdr;
509753 int ret;
....@@ -519,7 +763,7 @@
519763 * Validate the first fragment both here and in mac80211
520764 * All further fragments will be validated by mac80211 only.
521765 */
522
- hdr = (struct ieee80211_hdr *) skb->data;
766
+ hdr = mt76_skb_get_hdr(skb);
523767 if (ieee80211_is_frag(hdr) &&
524768 !ieee80211_is_first_frag(hdr->frame_control))
525769 return 0;
....@@ -540,24 +784,119 @@
540784 }
541785
542786 static void
543
-mt76_check_ps(struct mt76_dev *dev, struct sk_buff *skb)
787
+mt76_airtime_report(struct mt76_dev *dev, struct mt76_rx_status *status,
788
+ int len)
544789 {
545
- struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
546
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
547
- struct ieee80211_sta *sta;
548790 struct mt76_wcid *wcid = status->wcid;
549
- bool ps;
791
+ struct ieee80211_rx_status info = {
792
+ .enc_flags = status->enc_flags,
793
+ .rate_idx = status->rate_idx,
794
+ .encoding = status->encoding,
795
+ .band = status->band,
796
+ .nss = status->nss,
797
+ .bw = status->bw,
798
+ };
799
+ struct ieee80211_sta *sta;
800
+ u32 airtime;
550801
551
- if (ieee80211_is_pspoll(hdr->frame_control) && !wcid) {
552
- sta = ieee80211_find_sta_by_ifaddr(dev->hw, hdr->addr2, NULL);
553
- if (sta)
554
- wcid = status->wcid = (struct mt76_wcid *) sta->drv_priv;
555
- }
802
+ airtime = ieee80211_calc_rx_airtime(dev->hw, &info, len);
803
+ spin_lock(&dev->cc_lock);
804
+ dev->cur_cc_bss_rx += airtime;
805
+ spin_unlock(&dev->cc_lock);
556806
557807 if (!wcid || !wcid->sta)
558808 return;
559809
560
- sta = container_of((void *) wcid, struct ieee80211_sta, drv_priv);
810
+ sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
811
+ ieee80211_sta_register_airtime(sta, status->tid, 0, airtime);
812
+}
813
+
814
+static void
815
+mt76_airtime_flush_ampdu(struct mt76_dev *dev)
816
+{
817
+ struct mt76_wcid *wcid;
818
+ int wcid_idx;
819
+
820
+ if (!dev->rx_ampdu_len)
821
+ return;
822
+
823
+ wcid_idx = dev->rx_ampdu_status.wcid_idx;
824
+ if (wcid_idx < ARRAY_SIZE(dev->wcid))
825
+ wcid = rcu_dereference(dev->wcid[wcid_idx]);
826
+ else
827
+ wcid = NULL;
828
+ dev->rx_ampdu_status.wcid = wcid;
829
+
830
+ mt76_airtime_report(dev, &dev->rx_ampdu_status, dev->rx_ampdu_len);
831
+
832
+ dev->rx_ampdu_len = 0;
833
+ dev->rx_ampdu_ref = 0;
834
+}
835
+
836
+static void
837
+mt76_airtime_check(struct mt76_dev *dev, struct sk_buff *skb)
838
+{
839
+ struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
840
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
841
+ struct mt76_wcid *wcid = status->wcid;
842
+
843
+ if (!(dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME))
844
+ return;
845
+
846
+ if (!wcid || !wcid->sta) {
847
+ if (!ether_addr_equal(hdr->addr1, dev->macaddr))
848
+ return;
849
+
850
+ wcid = NULL;
851
+ }
852
+
853
+ if (!(status->flag & RX_FLAG_AMPDU_DETAILS) ||
854
+ status->ampdu_ref != dev->rx_ampdu_ref)
855
+ mt76_airtime_flush_ampdu(dev);
856
+
857
+ if (status->flag & RX_FLAG_AMPDU_DETAILS) {
858
+ if (!dev->rx_ampdu_len ||
859
+ status->ampdu_ref != dev->rx_ampdu_ref) {
860
+ dev->rx_ampdu_status = *status;
861
+ dev->rx_ampdu_status.wcid_idx = wcid ? wcid->idx : 0xff;
862
+ dev->rx_ampdu_ref = status->ampdu_ref;
863
+ }
864
+
865
+ dev->rx_ampdu_len += skb->len;
866
+ return;
867
+ }
868
+
869
+ mt76_airtime_report(dev, status, skb->len);
870
+}
871
+
872
+static void
873
+mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
874
+{
875
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
876
+ struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
877
+ struct ieee80211_sta *sta;
878
+ struct ieee80211_hw *hw;
879
+ struct mt76_wcid *wcid = status->wcid;
880
+ bool ps;
881
+
882
+ hw = mt76_phy_hw(dev, status->ext_phy);
883
+ if (ieee80211_is_pspoll(hdr->frame_control) && !wcid) {
884
+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
885
+ if (sta)
886
+ wcid = status->wcid = (struct mt76_wcid *)sta->drv_priv;
887
+ }
888
+
889
+ mt76_airtime_check(dev, skb);
890
+
891
+ if (!wcid || !wcid->sta)
892
+ return;
893
+
894
+ sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
895
+
896
+ if (status->signal <= 0)
897
+ ewma_signal_add(&wcid->rssi, -status->signal);
898
+
899
+ wcid->inactive_count = 0;
561900
562901 if (!test_bit(MT_WCID_FLAG_CHECK_PS, &wcid->flags))
563902 return;
....@@ -568,8 +907,8 @@
568907 }
569908
570909 if (ieee80211_has_morefrags(hdr->frame_control) ||
571
- !(ieee80211_is_mgmt(hdr->frame_control) ||
572
- ieee80211_is_data(hdr->frame_control)))
910
+ !(ieee80211_is_mgmt(hdr->frame_control) ||
911
+ ieee80211_is_data(hdr->frame_control)))
573912 return;
574913
575914 ps = ieee80211_has_pm(hdr->frame_control);
....@@ -594,6 +933,7 @@
594933 struct napi_struct *napi)
595934 {
596935 struct ieee80211_sta *sta;
936
+ struct ieee80211_hw *hw;
597937 struct sk_buff *skb;
598938
599939 spin_lock(&dev->rx_lock);
....@@ -603,8 +943,8 @@
603943 continue;
604944 }
605945
606
- sta = mt76_rx_convert(skb);
607
- ieee80211_rx_napi(dev->hw, sta, skb, napi);
946
+ mt76_rx_convert(dev, skb, &hw, &sta);
947
+ ieee80211_rx_napi(hw, sta, skb, napi);
608948 }
609949 spin_unlock(&dev->rx_lock);
610950 }
....@@ -618,10 +958,249 @@
618958 __skb_queue_head_init(&frames);
619959
620960 while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
621
- mt76_check_ps(dev, skb);
961
+ mt76_check_sta(dev, skb);
622962 mt76_rx_aggr_reorder(skb, &frames);
623963 }
624964
625965 mt76_rx_complete(dev, &frames, napi);
626966 }
627967 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
968
+
969
+static int
970
+mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
971
+ struct ieee80211_sta *sta, bool ext_phy)
972
+{
973
+ struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
974
+ int ret;
975
+ int i;
976
+
977
+ mutex_lock(&dev->mutex);
978
+
979
+ ret = dev->drv->sta_add(dev, vif, sta);
980
+ if (ret)
981
+ goto out;
982
+
983
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
984
+ struct mt76_txq *mtxq;
985
+
986
+ if (!sta->txq[i])
987
+ continue;
988
+
989
+ mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
990
+ mtxq->wcid = wcid;
991
+ }
992
+
993
+ ewma_signal_init(&wcid->rssi);
994
+ if (ext_phy)
995
+ mt76_wcid_mask_set(dev->wcid_phy_mask, wcid->idx);
996
+ wcid->ext_phy = ext_phy;
997
+ rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
998
+
999
+out:
1000
+ mutex_unlock(&dev->mutex);
1001
+
1002
+ return ret;
1003
+}
1004
+
1005
+void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
1006
+ struct ieee80211_sta *sta)
1007
+{
1008
+ struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
1009
+ int i, idx = wcid->idx;
1010
+
1011
+ for (i = 0; i < ARRAY_SIZE(wcid->aggr); i++)
1012
+ mt76_rx_aggr_stop(dev, wcid, i);
1013
+
1014
+ if (dev->drv->sta_remove)
1015
+ dev->drv->sta_remove(dev, vif, sta);
1016
+
1017
+ mt76_tx_status_check(dev, wcid, true);
1018
+ mt76_wcid_mask_clear(dev->wcid_mask, idx);
1019
+ mt76_wcid_mask_clear(dev->wcid_phy_mask, idx);
1020
+}
1021
+EXPORT_SYMBOL_GPL(__mt76_sta_remove);
1022
+
1023
+static void
1024
+mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
1025
+ struct ieee80211_sta *sta)
1026
+{
1027
+ mutex_lock(&dev->mutex);
1028
+ __mt76_sta_remove(dev, vif, sta);
1029
+ mutex_unlock(&dev->mutex);
1030
+}
1031
+
1032
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1033
+ struct ieee80211_sta *sta,
1034
+ enum ieee80211_sta_state old_state,
1035
+ enum ieee80211_sta_state new_state)
1036
+{
1037
+ struct mt76_phy *phy = hw->priv;
1038
+ struct mt76_dev *dev = phy->dev;
1039
+ bool ext_phy = phy != &dev->phy;
1040
+
1041
+ if (old_state == IEEE80211_STA_NOTEXIST &&
1042
+ new_state == IEEE80211_STA_NONE)
1043
+ return mt76_sta_add(dev, vif, sta, ext_phy);
1044
+
1045
+ if (old_state == IEEE80211_STA_AUTH &&
1046
+ new_state == IEEE80211_STA_ASSOC &&
1047
+ dev->drv->sta_assoc)
1048
+ dev->drv->sta_assoc(dev, vif, sta);
1049
+
1050
+ if (old_state == IEEE80211_STA_NONE &&
1051
+ new_state == IEEE80211_STA_NOTEXIST)
1052
+ mt76_sta_remove(dev, vif, sta);
1053
+
1054
+ return 0;
1055
+}
1056
+EXPORT_SYMBOL_GPL(mt76_sta_state);
1057
+
1058
+void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1059
+ struct ieee80211_sta *sta)
1060
+{
1061
+ struct mt76_phy *phy = hw->priv;
1062
+ struct mt76_dev *dev = phy->dev;
1063
+ struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
1064
+
1065
+ mutex_lock(&dev->mutex);
1066
+ rcu_assign_pointer(dev->wcid[wcid->idx], NULL);
1067
+ mutex_unlock(&dev->mutex);
1068
+}
1069
+EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove);
1070
+
1071
+int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1072
+ int *dbm)
1073
+{
1074
+ struct mt76_phy *phy = hw->priv;
1075
+ int n_chains = hweight8(phy->antenna_mask);
1076
+ int delta = mt76_tx_power_nss_delta(n_chains);
1077
+
1078
+ *dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
1079
+
1080
+ return 0;
1081
+}
1082
+EXPORT_SYMBOL_GPL(mt76_get_txpower);
1083
+
1084
+static void
1085
+__mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
1086
+{
1087
+ if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
1088
+ ieee80211_csa_finish(vif);
1089
+}
1090
+
1091
+void mt76_csa_finish(struct mt76_dev *dev)
1092
+{
1093
+ if (!dev->csa_complete)
1094
+ return;
1095
+
1096
+ ieee80211_iterate_active_interfaces_atomic(dev->hw,
1097
+ IEEE80211_IFACE_ITER_RESUME_ALL,
1098
+ __mt76_csa_finish, dev);
1099
+
1100
+ dev->csa_complete = 0;
1101
+}
1102
+EXPORT_SYMBOL_GPL(mt76_csa_finish);
1103
+
1104
+static void
1105
+__mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
1106
+{
1107
+ struct mt76_dev *dev = priv;
1108
+
1109
+ if (!vif->csa_active)
1110
+ return;
1111
+
1112
+ dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif);
1113
+}
1114
+
1115
+void mt76_csa_check(struct mt76_dev *dev)
1116
+{
1117
+ ieee80211_iterate_active_interfaces_atomic(dev->hw,
1118
+ IEEE80211_IFACE_ITER_RESUME_ALL,
1119
+ __mt76_csa_check, dev);
1120
+}
1121
+EXPORT_SYMBOL_GPL(mt76_csa_check);
1122
+
1123
+int
1124
+mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
1125
+{
1126
+ return 0;
1127
+}
1128
+EXPORT_SYMBOL_GPL(mt76_set_tim);
1129
+
1130
+void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id)
1131
+{
1132
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
1133
+ int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
1134
+ u8 *hdr, *pn = status->iv;
1135
+
1136
+ __skb_push(skb, 8);
1137
+ memmove(skb->data, skb->data + 8, hdr_len);
1138
+ hdr = skb->data + hdr_len;
1139
+
1140
+ hdr[0] = pn[5];
1141
+ hdr[1] = pn[4];
1142
+ hdr[2] = 0;
1143
+ hdr[3] = 0x20 | (key_id << 6);
1144
+ hdr[4] = pn[3];
1145
+ hdr[5] = pn[2];
1146
+ hdr[6] = pn[1];
1147
+ hdr[7] = pn[0];
1148
+
1149
+ status->flag &= ~RX_FLAG_IV_STRIPPED;
1150
+}
1151
+EXPORT_SYMBOL_GPL(mt76_insert_ccmp_hdr);
1152
+
1153
+int mt76_get_rate(struct mt76_dev *dev,
1154
+ struct ieee80211_supported_band *sband,
1155
+ int idx, bool cck)
1156
+{
1157
+ int i, offset = 0, len = sband->n_bitrates;
1158
+
1159
+ if (cck) {
1160
+ if (sband == &dev->phy.sband_5g.sband)
1161
+ return 0;
1162
+
1163
+ idx &= ~BIT(2); /* short preamble */
1164
+ } else if (sband == &dev->phy.sband_2g.sband) {
1165
+ offset = 4;
1166
+ }
1167
+
1168
+ for (i = offset; i < len; i++) {
1169
+ if ((sband->bitrates[i].hw_value & GENMASK(7, 0)) == idx)
1170
+ return i;
1171
+ }
1172
+
1173
+ return 0;
1174
+}
1175
+EXPORT_SYMBOL_GPL(mt76_get_rate);
1176
+
1177
+void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1178
+ const u8 *mac)
1179
+{
1180
+ struct mt76_phy *phy = hw->priv;
1181
+
1182
+ set_bit(MT76_SCANNING, &phy->state);
1183
+}
1184
+EXPORT_SYMBOL_GPL(mt76_sw_scan);
1185
+
1186
+void mt76_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1187
+{
1188
+ struct mt76_phy *phy = hw->priv;
1189
+
1190
+ clear_bit(MT76_SCANNING, &phy->state);
1191
+}
1192
+EXPORT_SYMBOL_GPL(mt76_sw_scan_complete);
1193
+
1194
+int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
1195
+{
1196
+ struct mt76_phy *phy = hw->priv;
1197
+ struct mt76_dev *dev = phy->dev;
1198
+
1199
+ mutex_lock(&dev->mutex);
1200
+ *tx_ant = phy->antenna_mask;
1201
+ *rx_ant = phy->antenna_mask;
1202
+ mutex_unlock(&dev->mutex);
1203
+
1204
+ return 0;
1205
+}
1206
+EXPORT_SYMBOL_GPL(mt76_get_antenna);