2 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
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.
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.
19 #define CHAN2G(_idx, _freq) { \
20 .band = NL80211_BAND_2GHZ, \
21 .center_freq = (_freq), \
26 #define CHAN5G(_idx, _freq) { \
27 .band = NL80211_BAND_5GHZ, \
28 .center_freq = (_freq), \
33 static const struct ieee80211_channel mt76_channels_2ghz
[] = {
50 static const struct ieee80211_channel mt76_channels_5ghz
[] = {
80 static const struct ieee80211_tpt_blink mt76_tpt_blink
[] = {
81 { .throughput
= 0 * 1024, .blink_time
= 334 },
82 { .throughput
= 1 * 1024, .blink_time
= 260 },
83 { .throughput
= 5 * 1024, .blink_time
= 220 },
84 { .throughput
= 10 * 1024, .blink_time
= 190 },
85 { .throughput
= 20 * 1024, .blink_time
= 170 },
86 { .throughput
= 50 * 1024, .blink_time
= 150 },
87 { .throughput
= 70 * 1024, .blink_time
= 130 },
88 { .throughput
= 100 * 1024, .blink_time
= 110 },
89 { .throughput
= 200 * 1024, .blink_time
= 80 },
90 { .throughput
= 300 * 1024, .blink_time
= 50 },
93 static int mt76_led_init(struct mt76_dev
*dev
)
95 struct device_node
*np
= dev
->dev
->of_node
;
96 struct ieee80211_hw
*hw
= dev
->hw
;
99 if (!dev
->led_cdev
.brightness_set
&& !dev
->led_cdev
.blink_set
)
102 snprintf(dev
->led_name
, sizeof(dev
->led_name
),
103 "mt76-%s", wiphy_name(hw
->wiphy
));
105 dev
->led_cdev
.name
= dev
->led_name
;
106 dev
->led_cdev
.default_trigger
=
107 ieee80211_create_tpt_led_trigger(hw
,
108 IEEE80211_TPT_LEDTRIG_FL_RADIO
,
110 ARRAY_SIZE(mt76_tpt_blink
));
112 np
= of_get_child_by_name(np
, "led");
114 if (!of_property_read_u32(np
, "led-sources", &led_pin
))
115 dev
->led_pin
= led_pin
;
116 dev
->led_al
= of_property_read_bool(np
, "led-active-low");
119 return devm_led_classdev_register(dev
->dev
, &dev
->led_cdev
);
122 static void mt76_init_stream_cap(struct mt76_dev
*dev
,
123 struct ieee80211_supported_band
*sband
,
126 struct ieee80211_sta_ht_cap
*ht_cap
= &sband
->ht_cap
;
127 int i
, nstream
= __sw_hweight8(dev
->antenna_mask
);
128 struct ieee80211_sta_vht_cap
*vht_cap
;
132 ht_cap
->cap
|= IEEE80211_HT_CAP_TX_STBC
;
134 ht_cap
->cap
&= ~IEEE80211_HT_CAP_TX_STBC
;
136 for (i
= 0; i
< IEEE80211_HT_MCS_MASK_LEN
; i
++)
137 ht_cap
->mcs
.rx_mask
[i
] = i
< nstream
? 0xff : 0;
142 vht_cap
= &sband
->vht_cap
;
144 vht_cap
->cap
|= IEEE80211_VHT_CAP_TXSTBC
;
146 vht_cap
->cap
&= ~IEEE80211_VHT_CAP_TXSTBC
;
148 for (i
= 0; i
< 8; i
++) {
150 mcs_map
|= (IEEE80211_VHT_MCS_SUPPORT_0_9
<< (i
* 2));
153 (IEEE80211_VHT_MCS_NOT_SUPPORTED
<< (i
* 2));
155 vht_cap
->vht_mcs
.rx_mcs_map
= cpu_to_le16(mcs_map
);
156 vht_cap
->vht_mcs
.tx_mcs_map
= cpu_to_le16(mcs_map
);
159 void mt76_set_stream_caps(struct mt76_dev
*dev
, bool vht
)
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
);
166 EXPORT_SYMBOL_GPL(mt76_set_stream_caps
);
169 mt76_init_sband(struct mt76_dev
*dev
, struct mt76_sband
*msband
,
170 const struct ieee80211_channel
*chan
, int n_chan
,
171 struct ieee80211_rate
*rates
, int n_rates
, bool vht
)
173 struct ieee80211_supported_band
*sband
= &msband
->sband
;
174 struct ieee80211_sta_ht_cap
*ht_cap
;
175 struct ieee80211_sta_vht_cap
*vht_cap
;
179 size
= n_chan
* sizeof(*chan
);
180 chanlist
= devm_kmemdup(dev
->dev
, chan
, size
, GFP_KERNEL
);
184 msband
->chan
= devm_kcalloc(dev
->dev
, n_chan
, sizeof(*msband
->chan
),
189 sband
->channels
= chanlist
;
190 sband
->n_channels
= n_chan
;
191 sband
->bitrates
= rates
;
192 sband
->n_bitrates
= n_rates
;
193 dev
->chandef
.chan
= &sband
->channels
[0];
195 ht_cap
= &sband
->ht_cap
;
196 ht_cap
->ht_supported
= true;
197 ht_cap
->cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
198 IEEE80211_HT_CAP_GRN_FLD
|
199 IEEE80211_HT_CAP_SGI_20
|
200 IEEE80211_HT_CAP_SGI_40
|
201 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT
);
203 ht_cap
->mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
204 ht_cap
->ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
205 ht_cap
->ampdu_density
= IEEE80211_HT_MPDU_DENSITY_4
;
207 mt76_init_stream_cap(dev
, sband
, vht
);
212 vht_cap
= &sband
->vht_cap
;
213 vht_cap
->vht_supported
= true;
214 vht_cap
->cap
|= IEEE80211_VHT_CAP_RXLDPC
|
215 IEEE80211_VHT_CAP_RXSTBC_1
|
216 IEEE80211_VHT_CAP_SHORT_GI_80
|
217 (3 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT
);
223 mt76_init_sband_2g(struct mt76_dev
*dev
, struct ieee80211_rate
*rates
,
226 dev
->hw
->wiphy
->bands
[NL80211_BAND_2GHZ
] = &dev
->sband_2g
.sband
;
228 return mt76_init_sband(dev
, &dev
->sband_2g
,
230 ARRAY_SIZE(mt76_channels_2ghz
),
231 rates
, n_rates
, false);
235 mt76_init_sband_5g(struct mt76_dev
*dev
, struct ieee80211_rate
*rates
,
236 int n_rates
, bool vht
)
238 dev
->hw
->wiphy
->bands
[NL80211_BAND_5GHZ
] = &dev
->sband_5g
.sband
;
240 return mt76_init_sband(dev
, &dev
->sband_5g
,
242 ARRAY_SIZE(mt76_channels_5ghz
),
243 rates
, n_rates
, vht
);
247 mt76_check_sband(struct mt76_dev
*dev
, int band
)
249 struct ieee80211_supported_band
*sband
= dev
->hw
->wiphy
->bands
[band
];
256 for (i
= 0; i
< sband
->n_channels
; i
++) {
257 if (sband
->channels
[i
].flags
& IEEE80211_CHAN_DISABLED
)
267 sband
->n_channels
= 0;
268 dev
->hw
->wiphy
->bands
[band
] = NULL
;
272 mt76_alloc_device(unsigned int size
, const struct ieee80211_ops
*ops
)
274 struct ieee80211_hw
*hw
;
275 struct mt76_dev
*dev
;
277 hw
= ieee80211_alloc_hw(size
, ops
);
283 spin_lock_init(&dev
->rx_lock
);
284 spin_lock_init(&dev
->lock
);
285 spin_lock_init(&dev
->cc_lock
);
286 mutex_init(&dev
->mutex
);
287 init_waitqueue_head(&dev
->tx_wait
);
288 skb_queue_head_init(&dev
->status_list
);
292 EXPORT_SYMBOL_GPL(mt76_alloc_device
);
294 int mt76_register_device(struct mt76_dev
*dev
, bool vht
,
295 struct ieee80211_rate
*rates
, int n_rates
)
297 struct ieee80211_hw
*hw
= dev
->hw
;
298 struct wiphy
*wiphy
= hw
->wiphy
;
301 dev_set_drvdata(dev
->dev
, dev
);
303 INIT_LIST_HEAD(&dev
->txwi_cache
);
305 SET_IEEE80211_DEV(hw
, dev
->dev
);
306 SET_IEEE80211_PERM_ADDR(hw
, dev
->macaddr
);
308 wiphy
->features
|= NL80211_FEATURE_ACTIVE_MONITOR
;
310 wiphy_ext_feature_set(wiphy
, NL80211_EXT_FEATURE_CQM_RSSI_LIST
);
312 wiphy
->available_antennas_tx
= dev
->antenna_mask
;
313 wiphy
->available_antennas_rx
= dev
->antenna_mask
;
315 hw
->txq_data_size
= sizeof(struct mt76_txq
);
316 hw
->max_tx_fragments
= 16;
318 ieee80211_hw_set(hw
, SIGNAL_DBM
);
319 ieee80211_hw_set(hw
, PS_NULLFUNC_STACK
);
320 ieee80211_hw_set(hw
, HOST_BROADCAST_PS_BUFFERING
);
321 ieee80211_hw_set(hw
, AMPDU_AGGREGATION
);
322 ieee80211_hw_set(hw
, SUPPORTS_RC_TABLE
);
323 ieee80211_hw_set(hw
, SUPPORT_FAST_XMIT
);
324 ieee80211_hw_set(hw
, SUPPORTS_CLONED_SKBS
);
325 ieee80211_hw_set(hw
, SUPPORTS_AMSDU_IN_AMPDU
);
326 ieee80211_hw_set(hw
, TX_AMSDU
);
327 ieee80211_hw_set(hw
, TX_FRAG_LIST
);
328 ieee80211_hw_set(hw
, MFP_CAPABLE
);
329 ieee80211_hw_set(hw
, AP_LINK_PS
);
330 ieee80211_hw_set(hw
, REPORTS_TX_ACK_STATUS
);
331 ieee80211_hw_set(hw
, NEEDS_UNIQUE_STA_ADDR
);
333 wiphy
->flags
|= WIPHY_FLAG_IBSS_RSN
;
335 if (dev
->cap
.has_2ghz
) {
336 ret
= mt76_init_sband_2g(dev
, rates
, n_rates
);
341 if (dev
->cap
.has_5ghz
) {
342 ret
= mt76_init_sband_5g(dev
, rates
+ 4, n_rates
- 4, vht
);
347 wiphy_read_of_freq_limits(dev
->hw
->wiphy
);
348 mt76_check_sband(dev
, NL80211_BAND_2GHZ
);
349 mt76_check_sband(dev
, NL80211_BAND_5GHZ
);
351 if (IS_ENABLED(CONFIG_MT76_LEDS
)) {
352 ret
= mt76_led_init(dev
);
357 return ieee80211_register_hw(hw
);
359 EXPORT_SYMBOL_GPL(mt76_register_device
);
361 void mt76_unregister_device(struct mt76_dev
*dev
)
363 struct ieee80211_hw
*hw
= dev
->hw
;
365 mt76_tx_status_check(dev
, NULL
, true);
366 ieee80211_unregister_hw(hw
);
369 EXPORT_SYMBOL_GPL(mt76_unregister_device
);
371 void mt76_rx(struct mt76_dev
*dev
, enum mt76_rxq_id q
, struct sk_buff
*skb
)
373 if (!test_bit(MT76_STATE_RUNNING
, &dev
->state
)) {
378 __skb_queue_tail(&dev
->rx_skb
[q
], skb
);
380 EXPORT_SYMBOL_GPL(mt76_rx
);
382 static bool mt76_has_tx_pending(struct mt76_dev
*dev
)
386 for (i
= 0; i
< ARRAY_SIZE(dev
->q_tx
); i
++) {
387 if (dev
->q_tx
[i
].queued
)
394 void mt76_set_channel(struct mt76_dev
*dev
)
396 struct ieee80211_hw
*hw
= dev
->hw
;
397 struct cfg80211_chan_def
*chandef
= &hw
->conf
.chandef
;
398 struct mt76_channel_state
*state
;
399 bool offchannel
= hw
->conf
.flags
& IEEE80211_CONF_OFFCHANNEL
;
400 int timeout
= HZ
/ 5;
403 set_bit(MT76_OFFCHANNEL
, &dev
->state
);
405 clear_bit(MT76_OFFCHANNEL
, &dev
->state
);
407 wait_event_timeout(dev
->tx_wait
, !mt76_has_tx_pending(dev
), timeout
);
409 if (dev
->drv
->update_survey
)
410 dev
->drv
->update_survey(dev
);
412 dev
->chandef
= *chandef
;
415 dev
->main_chan
= chandef
->chan
;
417 if (chandef
->chan
!= dev
->main_chan
) {
418 state
= mt76_channel_state(dev
, chandef
->chan
);
419 memset(state
, 0, sizeof(*state
));
422 EXPORT_SYMBOL_GPL(mt76_set_channel
);
424 int mt76_get_survey(struct ieee80211_hw
*hw
, int idx
,
425 struct survey_info
*survey
)
427 struct mt76_dev
*dev
= hw
->priv
;
428 struct mt76_sband
*sband
;
429 struct ieee80211_channel
*chan
;
430 struct mt76_channel_state
*state
;
433 if (idx
== 0 && dev
->drv
->update_survey
)
434 dev
->drv
->update_survey(dev
);
436 sband
= &dev
->sband_2g
;
437 if (idx
>= sband
->sband
.n_channels
) {
438 idx
-= sband
->sband
.n_channels
;
439 sband
= &dev
->sband_5g
;
442 if (idx
>= sband
->sband
.n_channels
)
445 chan
= &sband
->sband
.channels
[idx
];
446 state
= mt76_channel_state(dev
, chan
);
448 memset(survey
, 0, sizeof(*survey
));
449 survey
->channel
= chan
;
450 survey
->filled
= SURVEY_INFO_TIME
| SURVEY_INFO_TIME_BUSY
;
451 if (chan
== dev
->main_chan
)
452 survey
->filled
|= SURVEY_INFO_IN_USE
;
454 spin_lock_bh(&dev
->cc_lock
);
455 survey
->time
= div_u64(state
->cc_active
, 1000);
456 survey
->time_busy
= div_u64(state
->cc_busy
, 1000);
457 spin_unlock_bh(&dev
->cc_lock
);
461 EXPORT_SYMBOL_GPL(mt76_get_survey
);
463 void mt76_wcid_key_setup(struct mt76_dev
*dev
, struct mt76_wcid
*wcid
,
464 struct ieee80211_key_conf
*key
)
466 struct ieee80211_key_seq seq
;
469 wcid
->rx_check_pn
= false;
474 if (key
->cipher
== WLAN_CIPHER_SUITE_CCMP
)
475 wcid
->rx_check_pn
= true;
477 for (i
= 0; i
< IEEE80211_NUM_TIDS
; i
++) {
478 ieee80211_get_key_rx_seq(key
, i
, &seq
);
479 memcpy(wcid
->rx_key_pn
[i
], seq
.ccmp
.pn
, sizeof(seq
.ccmp
.pn
));
482 EXPORT_SYMBOL(mt76_wcid_key_setup
);
484 struct ieee80211_sta
*mt76_rx_convert(struct sk_buff
*skb
)
486 struct ieee80211_rx_status
*status
= IEEE80211_SKB_RXCB(skb
);
487 struct mt76_rx_status mstat
;
489 mstat
= *((struct mt76_rx_status
*) skb
->cb
);
490 memset(status
, 0, sizeof(*status
));
492 status
->flag
= mstat
.flag
;
493 status
->freq
= mstat
.freq
;
494 status
->enc_flags
= mstat
.enc_flags
;
495 status
->encoding
= mstat
.encoding
;
496 status
->bw
= mstat
.bw
;
497 status
->rate_idx
= mstat
.rate_idx
;
498 status
->nss
= mstat
.nss
;
499 status
->band
= mstat
.band
;
500 status
->signal
= mstat
.signal
;
501 status
->chains
= mstat
.chains
;
503 BUILD_BUG_ON(sizeof(mstat
) > sizeof(skb
->cb
));
504 BUILD_BUG_ON(sizeof(status
->chain_signal
) != sizeof(mstat
.chain_signal
));
505 memcpy(status
->chain_signal
, mstat
.chain_signal
, sizeof(mstat
.chain_signal
));
507 return wcid_to_sta(mstat
.wcid
);
509 EXPORT_SYMBOL(mt76_rx_convert
);
512 mt76_check_ccmp_pn(struct sk_buff
*skb
)
514 struct mt76_rx_status
*status
= (struct mt76_rx_status
*) skb
->cb
;
515 struct mt76_wcid
*wcid
= status
->wcid
;
516 struct ieee80211_hdr
*hdr
;
519 if (!(status
->flag
& RX_FLAG_DECRYPTED
))
522 if (!wcid
|| !wcid
->rx_check_pn
)
525 if (!(status
->flag
& RX_FLAG_IV_STRIPPED
)) {
527 * Validate the first fragment both here and in mac80211
528 * All further fragments will be validated by mac80211 only.
530 hdr
= (struct ieee80211_hdr
*) skb
->data
;
531 if (ieee80211_is_frag(hdr
) &&
532 !ieee80211_is_first_frag(hdr
->frame_control
))
536 BUILD_BUG_ON(sizeof(status
->iv
) != sizeof(wcid
->rx_key_pn
[0]));
537 ret
= memcmp(status
->iv
, wcid
->rx_key_pn
[status
->tid
],
540 return -EINVAL
; /* replay */
542 memcpy(wcid
->rx_key_pn
[status
->tid
], status
->iv
, sizeof(status
->iv
));
544 if (status
->flag
& RX_FLAG_IV_STRIPPED
)
545 status
->flag
|= RX_FLAG_PN_VALIDATED
;
551 mt76_check_sta(struct mt76_dev
*dev
, struct sk_buff
*skb
)
553 struct mt76_rx_status
*status
= (struct mt76_rx_status
*) skb
->cb
;
554 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
555 struct ieee80211_sta
*sta
;
556 struct mt76_wcid
*wcid
= status
->wcid
;
559 if (ieee80211_is_pspoll(hdr
->frame_control
) && !wcid
) {
560 sta
= ieee80211_find_sta_by_ifaddr(dev
->hw
, hdr
->addr2
, NULL
);
562 wcid
= status
->wcid
= (struct mt76_wcid
*) sta
->drv_priv
;
565 if (!wcid
|| !wcid
->sta
)
568 sta
= container_of((void *) wcid
, struct ieee80211_sta
, drv_priv
);
570 if (status
->signal
<= 0)
571 ewma_signal_add(&wcid
->rssi
, -status
->signal
);
573 wcid
->inactive_count
= 0;
575 if (!test_bit(MT_WCID_FLAG_CHECK_PS
, &wcid
->flags
))
578 if (ieee80211_is_pspoll(hdr
->frame_control
)) {
579 ieee80211_sta_pspoll(sta
);
583 if (ieee80211_has_morefrags(hdr
->frame_control
) ||
584 !(ieee80211_is_mgmt(hdr
->frame_control
) ||
585 ieee80211_is_data(hdr
->frame_control
)))
588 ps
= ieee80211_has_pm(hdr
->frame_control
);
590 if (ps
&& (ieee80211_is_data_qos(hdr
->frame_control
) ||
591 ieee80211_is_qos_nullfunc(hdr
->frame_control
)))
592 ieee80211_sta_uapsd_trigger(sta
, status
->tid
);
594 if (!!test_bit(MT_WCID_FLAG_PS
, &wcid
->flags
) == ps
)
598 set_bit(MT_WCID_FLAG_PS
, &wcid
->flags
);
600 clear_bit(MT_WCID_FLAG_PS
, &wcid
->flags
);
602 dev
->drv
->sta_ps(dev
, sta
, ps
);
603 ieee80211_sta_ps_transition(sta
, ps
);
606 void mt76_rx_complete(struct mt76_dev
*dev
, struct sk_buff_head
*frames
,
607 struct napi_struct
*napi
)
609 struct ieee80211_sta
*sta
;
612 spin_lock(&dev
->rx_lock
);
613 while ((skb
= __skb_dequeue(frames
)) != NULL
) {
614 if (mt76_check_ccmp_pn(skb
)) {
619 sta
= mt76_rx_convert(skb
);
620 ieee80211_rx_napi(dev
->hw
, sta
, skb
, napi
);
622 spin_unlock(&dev
->rx_lock
);
625 void mt76_rx_poll_complete(struct mt76_dev
*dev
, enum mt76_rxq_id q
,
626 struct napi_struct
*napi
)
628 struct sk_buff_head frames
;
631 __skb_queue_head_init(&frames
);
633 while ((skb
= __skb_dequeue(&dev
->rx_skb
[q
])) != NULL
) {
634 mt76_check_sta(dev
, skb
);
635 mt76_rx_aggr_reorder(skb
, &frames
);
638 mt76_rx_complete(dev
, &frames
, napi
);
640 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete
);
643 mt76_sta_add(struct mt76_dev
*dev
, struct ieee80211_vif
*vif
,
644 struct ieee80211_sta
*sta
)
646 struct mt76_wcid
*wcid
= (struct mt76_wcid
*)sta
->drv_priv
;
650 mutex_lock(&dev
->mutex
);
652 ret
= dev
->drv
->sta_add(dev
, vif
, sta
);
656 for (i
= 0; i
< ARRAY_SIZE(sta
->txq
); i
++) {
657 struct mt76_txq
*mtxq
;
662 mtxq
= (struct mt76_txq
*)sta
->txq
[i
]->drv_priv
;
665 mt76_txq_init(dev
, sta
->txq
[i
]);
668 ewma_signal_init(&wcid
->rssi
);
669 rcu_assign_pointer(dev
->wcid
[wcid
->idx
], wcid
);
672 mutex_unlock(&dev
->mutex
);
678 mt76_sta_remove(struct mt76_dev
*dev
, struct ieee80211_vif
*vif
,
679 struct ieee80211_sta
*sta
)
681 struct mt76_wcid
*wcid
= (struct mt76_wcid
*)sta
->drv_priv
;
685 rcu_assign_pointer(dev
->wcid
[idx
], NULL
);
688 mutex_lock(&dev
->mutex
);
690 if (dev
->drv
->sta_remove
)
691 dev
->drv
->sta_remove(dev
, vif
, sta
);
693 mt76_tx_status_check(dev
, wcid
, true);
694 for (i
= 0; i
< ARRAY_SIZE(sta
->txq
); i
++)
695 mt76_txq_remove(dev
, sta
->txq
[i
]);
696 mt76_wcid_free(dev
->wcid_mask
, idx
);
698 mutex_unlock(&dev
->mutex
);
701 int mt76_sta_state(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
702 struct ieee80211_sta
*sta
,
703 enum ieee80211_sta_state old_state
,
704 enum ieee80211_sta_state new_state
)
706 struct mt76_dev
*dev
= hw
->priv
;
708 if (old_state
== IEEE80211_STA_NOTEXIST
&&
709 new_state
== IEEE80211_STA_NONE
)
710 return mt76_sta_add(dev
, vif
, sta
);
712 if (old_state
== IEEE80211_STA_NONE
&&
713 new_state
== IEEE80211_STA_NOTEXIST
)
714 mt76_sta_remove(dev
, vif
, sta
);
718 EXPORT_SYMBOL_GPL(mt76_sta_state
);
720 int mt76_get_txpower(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
723 struct mt76_dev
*dev
= hw
->priv
;
724 int n_chains
= __sw_hweight8(dev
->antenna_mask
);
726 *dbm
= dev
->txpower_cur
/ 2;
728 /* convert from per-chain power to combined
729 * output on 2x2 devices
736 EXPORT_SYMBOL_GPL(mt76_get_txpower
);
739 __mt76_csa_finish(void *priv
, u8
*mac
, struct ieee80211_vif
*vif
)
741 if (vif
->csa_active
&& ieee80211_csa_is_complete(vif
))
742 ieee80211_csa_finish(vif
);
745 void mt76_csa_finish(struct mt76_dev
*dev
)
747 if (!dev
->csa_complete
)
750 ieee80211_iterate_active_interfaces_atomic(dev
->hw
,
751 IEEE80211_IFACE_ITER_RESUME_ALL
,
752 __mt76_csa_finish
, dev
);
754 dev
->csa_complete
= 0;
756 EXPORT_SYMBOL_GPL(mt76_csa_finish
);
759 __mt76_csa_check(void *priv
, u8
*mac
, struct ieee80211_vif
*vif
)
761 struct mt76_dev
*dev
= priv
;
763 if (!vif
->csa_active
)
766 dev
->csa_complete
|= ieee80211_csa_is_complete(vif
);
769 void mt76_csa_check(struct mt76_dev
*dev
)
771 ieee80211_iterate_active_interfaces_atomic(dev
->hw
,
772 IEEE80211_IFACE_ITER_RESUME_ALL
,
773 __mt76_csa_check
, dev
);
775 EXPORT_SYMBOL_GPL(mt76_csa_check
);