1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
4 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
7 #include <linux/module.h>
10 #define MT76x02_CCK_RATE(_idx, _rate) { \
12 .flags = IEEE80211_RATE_SHORT_PREAMBLE, \
13 .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
14 .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + (_idx)), \
17 struct ieee80211_rate mt76x02_rates
[] = {
18 MT76x02_CCK_RATE(0, 10),
19 MT76x02_CCK_RATE(1, 20),
20 MT76x02_CCK_RATE(2, 55),
21 MT76x02_CCK_RATE(3, 110),
31 EXPORT_SYMBOL_GPL(mt76x02_rates
);
33 static const struct ieee80211_iface_limit mt76x02_if_limits
[] = {
36 .types
= BIT(NL80211_IFTYPE_ADHOC
)
39 .types
= BIT(NL80211_IFTYPE_STATION
) |
40 #ifdef CONFIG_MAC80211_MESH
41 BIT(NL80211_IFTYPE_MESH_POINT
) |
43 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
44 BIT(NL80211_IFTYPE_P2P_GO
) |
45 BIT(NL80211_IFTYPE_AP
)
49 static const struct ieee80211_iface_limit mt76x02u_if_limits
[] = {
52 .types
= BIT(NL80211_IFTYPE_ADHOC
)
55 .types
= BIT(NL80211_IFTYPE_STATION
) |
56 #ifdef CONFIG_MAC80211_MESH
57 BIT(NL80211_IFTYPE_MESH_POINT
) |
59 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
60 BIT(NL80211_IFTYPE_P2P_GO
) |
61 BIT(NL80211_IFTYPE_AP
)
65 static const struct ieee80211_iface_combination mt76x02_if_comb
[] = {
67 .limits
= mt76x02_if_limits
,
68 .n_limits
= ARRAY_SIZE(mt76x02_if_limits
),
70 .num_different_channels
= 1,
71 .beacon_int_infra_match
= true,
72 .radar_detect_widths
= BIT(NL80211_CHAN_WIDTH_20_NOHT
) |
73 BIT(NL80211_CHAN_WIDTH_20
) |
74 BIT(NL80211_CHAN_WIDTH_40
) |
75 BIT(NL80211_CHAN_WIDTH_80
),
79 static const struct ieee80211_iface_combination mt76x02u_if_comb
[] = {
81 .limits
= mt76x02u_if_limits
,
82 .n_limits
= ARRAY_SIZE(mt76x02u_if_limits
),
84 .num_different_channels
= 1,
85 .beacon_int_infra_match
= true,
90 mt76x02_led_set_config(struct mt76_phy
*mphy
, u8 delay_on
, u8 delay_off
)
92 struct mt76x02_dev
*dev
= container_of(mphy
->dev
, struct mt76x02_dev
,
96 val
= FIELD_PREP(MT_LED_STATUS_DURATION
, 0xff) |
97 FIELD_PREP(MT_LED_STATUS_OFF
, delay_off
) |
98 FIELD_PREP(MT_LED_STATUS_ON
, delay_on
);
100 mt76_wr(dev
, MT_LED_S0(mphy
->leds
.pin
), val
);
101 mt76_wr(dev
, MT_LED_S1(mphy
->leds
.pin
), val
);
103 val
= MT_LED_CTRL_REPLAY(mphy
->leds
.pin
) |
104 MT_LED_CTRL_KICK(mphy
->leds
.pin
);
106 val
|= MT_LED_CTRL_POLARITY(mphy
->leds
.pin
);
107 mt76_wr(dev
, MT_LED_CTRL
, val
);
111 mt76x02_led_set_blink(struct led_classdev
*led_cdev
,
112 unsigned long *delay_on
,
113 unsigned long *delay_off
)
115 struct mt76_phy
*mphy
= container_of(led_cdev
, struct mt76_phy
,
117 u8 delta_on
, delta_off
;
119 delta_off
= max_t(u8
, *delay_off
/ 10, 1);
120 delta_on
= max_t(u8
, *delay_on
/ 10, 1);
122 mt76x02_led_set_config(mphy
, delta_on
, delta_off
);
128 mt76x02_led_set_brightness(struct led_classdev
*led_cdev
,
129 enum led_brightness brightness
)
131 struct mt76_phy
*mphy
= container_of(led_cdev
, struct mt76_phy
,
135 mt76x02_led_set_config(mphy
, 0, 0xff);
137 mt76x02_led_set_config(mphy
, 0xff, 0);
140 int mt76x02_init_device(struct mt76x02_dev
*dev
)
142 struct ieee80211_hw
*hw
= mt76_hw(dev
);
143 struct wiphy
*wiphy
= hw
->wiphy
;
145 INIT_DELAYED_WORK(&dev
->mphy
.mac_work
, mt76x02_mac_work
);
149 hw
->max_report_rates
= 7;
150 hw
->max_rate_tries
= 1;
151 hw
->extra_tx_headroom
= 2;
153 if (mt76_is_usb(&dev
->mt76
)) {
154 hw
->extra_tx_headroom
+= sizeof(struct mt76x02_txwi
) +
156 wiphy
->iface_combinations
= mt76x02u_if_comb
;
157 wiphy
->n_iface_combinations
= ARRAY_SIZE(mt76x02u_if_comb
);
159 INIT_DELAYED_WORK(&dev
->wdt_work
, mt76x02_wdt_work
);
161 mt76x02_dfs_init_detector(dev
);
163 wiphy
->reg_notifier
= mt76x02_regd_notifier
;
164 wiphy
->iface_combinations
= mt76x02_if_comb
;
165 wiphy
->n_iface_combinations
= ARRAY_SIZE(mt76x02_if_comb
);
167 /* init led callbacks */
168 if (IS_ENABLED(CONFIG_MT76_LEDS
)) {
169 dev
->mphy
.leds
.cdev
.brightness_set
=
170 mt76x02_led_set_brightness
;
171 dev
->mphy
.leds
.cdev
.blink_set
= mt76x02_led_set_blink
;
175 wiphy_ext_feature_set(wiphy
, NL80211_EXT_FEATURE_VHT_IBSS
);
177 hw
->sta_data_size
= sizeof(struct mt76x02_sta
);
178 hw
->vif_data_size
= sizeof(struct mt76x02_vif
);
180 ieee80211_hw_set(hw
, SUPPORTS_HT_CCK_RATES
);
181 ieee80211_hw_set(hw
, HOST_BROADCAST_PS_BUFFERING
);
182 ieee80211_hw_set(hw
, NEEDS_UNIQUE_STA_ADDR
);
184 dev
->mt76
.global_wcid
.idx
= 255;
185 dev
->mt76
.global_wcid
.hw_key_idx
= -1;
188 if (is_mt76x2(dev
)) {
189 dev
->mphy
.sband_2g
.sband
.ht_cap
.cap
|=
190 IEEE80211_HT_CAP_LDPC_CODING
;
191 dev
->mphy
.sband_5g
.sband
.ht_cap
.cap
|=
192 IEEE80211_HT_CAP_LDPC_CODING
;
193 dev
->mphy
.chainmask
= 0x202;
194 dev
->mphy
.antenna_mask
= 3;
196 dev
->mphy
.chainmask
= 0x101;
197 dev
->mphy
.antenna_mask
= 1;
202 EXPORT_SYMBOL_GPL(mt76x02_init_device
);
204 void mt76x02_configure_filter(struct ieee80211_hw
*hw
,
205 unsigned int changed_flags
,
206 unsigned int *total_flags
, u64 multicast
)
208 struct mt76x02_dev
*dev
= hw
->priv
;
211 #define MT76_FILTER(_flag, _hw) do { \
212 flags |= *total_flags & FIF_##_flag; \
213 dev->mt76.rxfilter &= ~(_hw); \
214 dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw); \
217 mutex_lock(&dev
->mt76
.mutex
);
219 dev
->mt76
.rxfilter
&= ~MT_RX_FILTR_CFG_OTHER_BSS
;
221 MT76_FILTER(FCSFAIL
, MT_RX_FILTR_CFG_CRC_ERR
);
222 MT76_FILTER(PLCPFAIL
, MT_RX_FILTR_CFG_PHY_ERR
);
223 MT76_FILTER(CONTROL
, MT_RX_FILTR_CFG_ACK
|
224 MT_RX_FILTR_CFG_CTS
|
225 MT_RX_FILTR_CFG_CFEND
|
226 MT_RX_FILTR_CFG_CFACK
|
228 MT_RX_FILTR_CFG_CTRL_RSV
);
229 MT76_FILTER(PSPOLL
, MT_RX_FILTR_CFG_PSPOLL
);
231 *total_flags
= flags
;
232 mt76_wr(dev
, MT_RX_FILTR_CFG
, dev
->mt76
.rxfilter
);
234 mutex_unlock(&dev
->mt76
.mutex
);
236 EXPORT_SYMBOL_GPL(mt76x02_configure_filter
);
238 int mt76x02_sta_add(struct mt76_dev
*mdev
, struct ieee80211_vif
*vif
,
239 struct ieee80211_sta
*sta
)
241 struct mt76x02_dev
*dev
= container_of(mdev
, struct mt76x02_dev
, mt76
);
242 struct mt76x02_sta
*msta
= (struct mt76x02_sta
*)sta
->drv_priv
;
243 struct mt76x02_vif
*mvif
= (struct mt76x02_vif
*)vif
->drv_priv
;
246 memset(msta
, 0, sizeof(*msta
));
248 idx
= mt76_wcid_alloc(dev
->mt76
.wcid_mask
, MT76x02_N_WCIDS
);
254 msta
->wcid
.idx
= idx
;
255 msta
->wcid
.hw_key_idx
= -1;
256 mt76x02_mac_wcid_setup(dev
, idx
, mvif
->idx
, sta
->addr
);
257 mt76x02_mac_wcid_set_drop(dev
, idx
, false);
258 ewma_pktlen_init(&msta
->pktlen
);
260 if (vif
->type
== NL80211_IFTYPE_AP
)
261 set_bit(MT_WCID_FLAG_CHECK_PS
, &msta
->wcid
.flags
);
265 EXPORT_SYMBOL_GPL(mt76x02_sta_add
);
267 void mt76x02_sta_remove(struct mt76_dev
*mdev
, struct ieee80211_vif
*vif
,
268 struct ieee80211_sta
*sta
)
270 struct mt76x02_dev
*dev
= container_of(mdev
, struct mt76x02_dev
, mt76
);
271 struct mt76_wcid
*wcid
= (struct mt76_wcid
*)sta
->drv_priv
;
274 mt76x02_mac_wcid_set_drop(dev
, idx
, true);
275 mt76x02_mac_wcid_setup(dev
, idx
, 0, NULL
);
277 EXPORT_SYMBOL_GPL(mt76x02_sta_remove
);
280 mt76x02_vif_init(struct mt76x02_dev
*dev
, struct ieee80211_vif
*vif
,
283 struct mt76x02_vif
*mvif
= (struct mt76x02_vif
*)vif
->drv_priv
;
284 struct mt76_txq
*mtxq
;
286 memset(mvif
, 0, sizeof(*mvif
));
289 mvif
->group_wcid
.idx
= MT_VIF_WCID(idx
);
290 mvif
->group_wcid
.hw_key_idx
= -1;
291 mt76_wcid_init(&mvif
->group_wcid
);
293 mtxq
= (struct mt76_txq
*)vif
->txq
->drv_priv
;
294 rcu_assign_pointer(dev
->mt76
.wcid
[MT_VIF_WCID(idx
)], &mvif
->group_wcid
);
295 mtxq
->wcid
= MT_VIF_WCID(idx
);
299 mt76x02_add_interface(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
)
301 struct mt76x02_dev
*dev
= hw
->priv
;
302 unsigned int idx
= 0;
304 /* Allow to change address in HW if we create first interface. */
305 if (!dev
->mt76
.vif_mask
&&
306 (((vif
->addr
[0] ^ dev
->mphy
.macaddr
[0]) & ~GENMASK(4, 1)) ||
307 memcmp(vif
->addr
+ 1, dev
->mphy
.macaddr
+ 1, ETH_ALEN
- 1)))
308 mt76x02_mac_setaddr(dev
, vif
->addr
);
310 if (vif
->addr
[0] & BIT(1))
311 idx
= 1 + (((dev
->mphy
.macaddr
[0] ^ vif
->addr
[0]) >> 2) & 7);
314 * Client mode typically only has one configurable BSSID register,
315 * which is used for bssidx=0. This is linked to the MAC address.
316 * Since mac80211 allows changing interface types, and we cannot
317 * force the use of the primary MAC address for a station mode
318 * interface, we need some other way of configuring a per-interface
320 * The hardware provides an AP-Client feature, where bssidx 0-7 are
321 * used for AP mode and bssidx 8-15 for client mode.
322 * We shift the station interface bss index by 8 to force the
323 * hardware to recognize the BSSID.
324 * The resulting bssidx mismatch for unicast frames is ignored by hw.
326 if (vif
->type
== NL80211_IFTYPE_STATION
)
329 /* vif is already set or idx is 8 for AP/Mesh/... */
330 if (dev
->mt76
.vif_mask
& BIT_ULL(idx
) ||
331 (vif
->type
!= NL80211_IFTYPE_STATION
&& idx
> 7))
334 dev
->mt76
.vif_mask
|= BIT_ULL(idx
);
336 mt76x02_vif_init(dev
, vif
, idx
);
339 EXPORT_SYMBOL_GPL(mt76x02_add_interface
);
341 void mt76x02_remove_interface(struct ieee80211_hw
*hw
,
342 struct ieee80211_vif
*vif
)
344 struct mt76x02_dev
*dev
= hw
->priv
;
345 struct mt76x02_vif
*mvif
= (struct mt76x02_vif
*)vif
->drv_priv
;
347 dev
->mt76
.vif_mask
&= ~BIT_ULL(mvif
->idx
);
348 rcu_assign_pointer(dev
->mt76
.wcid
[mvif
->group_wcid
.idx
], NULL
);
349 mt76_wcid_cleanup(&dev
->mt76
, &mvif
->group_wcid
);
351 EXPORT_SYMBOL_GPL(mt76x02_remove_interface
);
353 int mt76x02_ampdu_action(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
354 struct ieee80211_ampdu_params
*params
)
356 enum ieee80211_ampdu_mlme_action action
= params
->action
;
357 struct ieee80211_sta
*sta
= params
->sta
;
358 struct mt76x02_dev
*dev
= hw
->priv
;
359 struct mt76x02_sta
*msta
= (struct mt76x02_sta
*)sta
->drv_priv
;
360 struct ieee80211_txq
*txq
= sta
->txq
[params
->tid
];
361 u16 tid
= params
->tid
;
362 u16 ssn
= params
->ssn
;
363 struct mt76_txq
*mtxq
;
369 mtxq
= (struct mt76_txq
*)txq
->drv_priv
;
371 mutex_lock(&dev
->mt76
.mutex
);
373 case IEEE80211_AMPDU_RX_START
:
374 mt76_rx_aggr_start(&dev
->mt76
, &msta
->wcid
, tid
,
375 ssn
, params
->buf_size
);
376 mt76_set(dev
, MT_WCID_ADDR(msta
->wcid
.idx
) + 4, BIT(16 + tid
));
378 case IEEE80211_AMPDU_RX_STOP
:
379 mt76_rx_aggr_stop(&dev
->mt76
, &msta
->wcid
, tid
);
380 mt76_clear(dev
, MT_WCID_ADDR(msta
->wcid
.idx
) + 4,
383 case IEEE80211_AMPDU_TX_OPERATIONAL
:
385 mtxq
->send_bar
= false;
386 ieee80211_send_bar(vif
, sta
->addr
, tid
, mtxq
->agg_ssn
);
388 case IEEE80211_AMPDU_TX_STOP_FLUSH
:
389 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
:
392 case IEEE80211_AMPDU_TX_START
:
393 mtxq
->agg_ssn
= IEEE80211_SN_TO_SEQ(ssn
);
394 ret
= IEEE80211_AMPDU_TX_START_IMMEDIATE
;
396 case IEEE80211_AMPDU_TX_STOP_CONT
:
398 ieee80211_stop_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
401 mutex_unlock(&dev
->mt76
.mutex
);
405 EXPORT_SYMBOL_GPL(mt76x02_ampdu_action
);
407 int mt76x02_set_key(struct ieee80211_hw
*hw
, enum set_key_cmd cmd
,
408 struct ieee80211_vif
*vif
, struct ieee80211_sta
*sta
,
409 struct ieee80211_key_conf
*key
)
411 struct mt76x02_dev
*dev
= hw
->priv
;
412 struct mt76x02_vif
*mvif
= (struct mt76x02_vif
*)vif
->drv_priv
;
413 struct mt76x02_sta
*msta
;
414 struct mt76_wcid
*wcid
;
415 int idx
= key
->keyidx
;
418 /* fall back to sw encryption for unsupported ciphers */
419 switch (key
->cipher
) {
420 case WLAN_CIPHER_SUITE_WEP40
:
421 case WLAN_CIPHER_SUITE_WEP104
:
422 case WLAN_CIPHER_SUITE_TKIP
:
423 case WLAN_CIPHER_SUITE_CCMP
:
430 * The hardware does not support per-STA RX GTK, fall back
431 * to software mode for these.
433 if ((vif
->type
== NL80211_IFTYPE_ADHOC
||
434 vif
->type
== NL80211_IFTYPE_MESH_POINT
) &&
435 (key
->cipher
== WLAN_CIPHER_SUITE_TKIP
||
436 key
->cipher
== WLAN_CIPHER_SUITE_CCMP
) &&
437 !(key
->flags
& IEEE80211_KEY_FLAG_PAIRWISE
))
441 * In USB AP mode, broadcast/multicast frames are setup in beacon
442 * data registers and sent via HW beacons engine, they require to
443 * be already encrypted.
445 if (mt76_is_usb(&dev
->mt76
) &&
446 vif
->type
== NL80211_IFTYPE_AP
&&
447 !(key
->flags
& IEEE80211_KEY_FLAG_PAIRWISE
))
450 /* MT76x0 GTK offloading does not work with more than one VIF */
451 if (is_mt76x0(dev
) && !(key
->flags
& IEEE80211_KEY_FLAG_PAIRWISE
))
454 msta
= sta
? (struct mt76x02_sta
*)sta
->drv_priv
: NULL
;
455 wcid
= msta
? &msta
->wcid
: &mvif
->group_wcid
;
457 if (cmd
!= SET_KEY
) {
458 if (idx
== wcid
->hw_key_idx
) {
459 wcid
->hw_key_idx
= -1;
466 key
->hw_key_idx
= wcid
->idx
;
467 wcid
->hw_key_idx
= idx
;
468 if (key
->flags
& IEEE80211_KEY_FLAG_RX_MGMT
) {
469 key
->flags
|= IEEE80211_KEY_FLAG_SW_MGMT_TX
;
472 mt76_wcid_key_setup(&dev
->mt76
, wcid
, key
);
475 if (key
|| wcid
->hw_key_idx
== idx
) {
476 ret
= mt76x02_mac_wcid_set_key(dev
, wcid
->idx
, key
);
481 return mt76x02_mac_shared_key_setup(dev
, mvif
->idx
, idx
, key
);
484 return mt76x02_mac_wcid_set_key(dev
, msta
->wcid
.idx
, key
);
486 EXPORT_SYMBOL_GPL(mt76x02_set_key
);
488 int mt76x02_conf_tx(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
489 unsigned int link_id
, u16 queue
,
490 const struct ieee80211_tx_queue_params
*params
)
492 struct mt76x02_dev
*dev
= hw
->priv
;
493 u8 cw_min
= 5, cw_max
= 10, qid
;
496 qid
= dev
->mphy
.q_tx
[queue
]->hw_idx
;
499 cw_min
= fls(params
->cw_min
);
501 cw_max
= fls(params
->cw_max
);
503 val
= FIELD_PREP(MT_EDCA_CFG_TXOP
, params
->txop
) |
504 FIELD_PREP(MT_EDCA_CFG_AIFSN
, params
->aifs
) |
505 FIELD_PREP(MT_EDCA_CFG_CWMIN
, cw_min
) |
506 FIELD_PREP(MT_EDCA_CFG_CWMAX
, cw_max
);
507 mt76_wr(dev
, MT_EDCA_CFG_AC(qid
), val
);
509 val
= mt76_rr(dev
, MT_WMM_TXOP(qid
));
510 val
&= ~(MT_WMM_TXOP_MASK
<< MT_WMM_TXOP_SHIFT(qid
));
511 val
|= params
->txop
<< MT_WMM_TXOP_SHIFT(qid
);
512 mt76_wr(dev
, MT_WMM_TXOP(qid
), val
);
514 val
= mt76_rr(dev
, MT_WMM_AIFSN
);
515 val
&= ~(MT_WMM_AIFSN_MASK
<< MT_WMM_AIFSN_SHIFT(qid
));
516 val
|= params
->aifs
<< MT_WMM_AIFSN_SHIFT(qid
);
517 mt76_wr(dev
, MT_WMM_AIFSN
, val
);
519 val
= mt76_rr(dev
, MT_WMM_CWMIN
);
520 val
&= ~(MT_WMM_CWMIN_MASK
<< MT_WMM_CWMIN_SHIFT(qid
));
521 val
|= cw_min
<< MT_WMM_CWMIN_SHIFT(qid
);
522 mt76_wr(dev
, MT_WMM_CWMIN
, val
);
524 val
= mt76_rr(dev
, MT_WMM_CWMAX
);
525 val
&= ~(MT_WMM_CWMAX_MASK
<< MT_WMM_CWMAX_SHIFT(qid
));
526 val
|= cw_max
<< MT_WMM_CWMAX_SHIFT(qid
);
527 mt76_wr(dev
, MT_WMM_CWMAX
, val
);
531 EXPORT_SYMBOL_GPL(mt76x02_conf_tx
);
533 void mt76x02_set_tx_ackto(struct mt76x02_dev
*dev
)
535 u8 ackto
, sifs
, slottime
= dev
->slottime
;
537 /* As defined by IEEE 802.11-2007 17.3.8.6 */
538 slottime
+= 3 * dev
->coverage_class
;
539 mt76_rmw_field(dev
, MT_BKOFF_SLOT_CFG
,
540 MT_BKOFF_SLOT_CFG_SLOTTIME
, slottime
);
542 sifs
= mt76_get_field(dev
, MT_XIFS_TIME_CFG
,
543 MT_XIFS_TIME_CFG_OFDM_SIFS
);
545 ackto
= slottime
+ sifs
;
546 mt76_rmw_field(dev
, MT_TX_TIMEOUT_CFG
,
547 MT_TX_TIMEOUT_CFG_ACKTO
, ackto
);
549 EXPORT_SYMBOL_GPL(mt76x02_set_tx_ackto
);
551 void mt76x02_set_coverage_class(struct ieee80211_hw
*hw
,
554 struct mt76x02_dev
*dev
= hw
->priv
;
556 mutex_lock(&dev
->mt76
.mutex
);
557 dev
->coverage_class
= max_t(s16
, coverage_class
, 0);
558 mt76x02_set_tx_ackto(dev
);
559 mutex_unlock(&dev
->mt76
.mutex
);
561 EXPORT_SYMBOL_GPL(mt76x02_set_coverage_class
);
563 int mt76x02_set_rts_threshold(struct ieee80211_hw
*hw
, u32 val
)
565 struct mt76x02_dev
*dev
= hw
->priv
;
567 if (val
!= ~0 && val
> 0xffff)
570 mutex_lock(&dev
->mt76
.mutex
);
571 mt76x02_mac_set_rts_thresh(dev
, val
);
572 mutex_unlock(&dev
->mt76
.mutex
);
576 EXPORT_SYMBOL_GPL(mt76x02_set_rts_threshold
);
578 void mt76x02_sta_rate_tbl_update(struct ieee80211_hw
*hw
,
579 struct ieee80211_vif
*vif
,
580 struct ieee80211_sta
*sta
)
582 struct mt76x02_dev
*dev
= hw
->priv
;
583 struct mt76x02_sta
*msta
= (struct mt76x02_sta
*)sta
->drv_priv
;
584 struct ieee80211_sta_rates
*rates
= rcu_dereference(sta
->rates
);
585 struct ieee80211_tx_rate rate
= {};
590 rate
.idx
= rates
->rate
[0].idx
;
591 rate
.flags
= rates
->rate
[0].flags
;
592 mt76x02_mac_wcid_set_rate(dev
, &msta
->wcid
, &rate
);
594 EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update
);
596 void mt76x02_remove_hdr_pad(struct sk_buff
*skb
, int len
)
603 hdrlen
= ieee80211_get_hdrlen_from_skb(skb
);
604 memmove(skb
->data
+ len
, skb
->data
, hdrlen
);
607 EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad
);
609 void mt76x02_sw_scan_complete(struct ieee80211_hw
*hw
,
610 struct ieee80211_vif
*vif
)
612 struct mt76x02_dev
*dev
= hw
->priv
;
614 clear_bit(MT76_SCANNING
, &dev
->mphy
.state
);
615 if (dev
->cal
.gain_init_done
) {
616 /* Restore AGC gain and resume calibration after scanning. */
617 dev
->cal
.low_gain
= -1;
618 ieee80211_queue_delayed_work(hw
, &dev
->cal_work
, 0);
621 EXPORT_SYMBOL_GPL(mt76x02_sw_scan_complete
);
623 void mt76x02_sta_ps(struct mt76_dev
*mdev
, struct ieee80211_sta
*sta
,
626 struct mt76x02_dev
*dev
= container_of(mdev
, struct mt76x02_dev
, mt76
);
627 struct mt76x02_sta
*msta
= (struct mt76x02_sta
*)sta
->drv_priv
;
628 int idx
= msta
->wcid
.idx
;
630 mt76_stop_tx_queues(&dev
->mphy
, sta
, true);
631 if (mt76_is_mmio(mdev
))
632 mt76x02_mac_wcid_set_drop(dev
, idx
, ps
);
634 EXPORT_SYMBOL_GPL(mt76x02_sta_ps
);
636 void mt76x02_bss_info_changed(struct ieee80211_hw
*hw
,
637 struct ieee80211_vif
*vif
,
638 struct ieee80211_bss_conf
*info
,
641 struct mt76x02_vif
*mvif
= (struct mt76x02_vif
*)vif
->drv_priv
;
642 struct mt76x02_dev
*dev
= hw
->priv
;
644 mutex_lock(&dev
->mt76
.mutex
);
646 if (changed
& BSS_CHANGED_BSSID
)
647 mt76x02_mac_set_bssid(dev
, mvif
->idx
, info
->bssid
);
649 if (changed
& BSS_CHANGED_HT
|| changed
& BSS_CHANGED_ERP_CTS_PROT
)
650 mt76x02_mac_set_tx_protection(dev
, info
->use_cts_prot
,
651 info
->ht_operation_mode
);
653 if (changed
& BSS_CHANGED_BEACON_INT
) {
654 mt76_rmw_field(dev
, MT_BEACON_TIME_CFG
,
655 MT_BEACON_TIME_CFG_INTVAL
,
656 info
->beacon_int
<< 4);
657 dev
->mt76
.beacon_int
= info
->beacon_int
;
660 if (changed
& BSS_CHANGED_BEACON_ENABLED
)
661 mt76x02_mac_set_beacon_enable(dev
, vif
, info
->enable_beacon
);
663 if (changed
& BSS_CHANGED_ERP_PREAMBLE
)
664 mt76x02_mac_set_short_preamble(dev
, info
->use_short_preamble
);
666 if (changed
& BSS_CHANGED_ERP_SLOT
) {
667 int slottime
= info
->use_short_slot
? 9 : 20;
669 dev
->slottime
= slottime
;
670 mt76x02_set_tx_ackto(dev
);
673 mutex_unlock(&dev
->mt76
.mutex
);
675 EXPORT_SYMBOL_GPL(mt76x02_bss_info_changed
);
677 void mt76x02_config_mac_addr_list(struct mt76x02_dev
*dev
)
679 struct ieee80211_hw
*hw
= mt76_hw(dev
);
680 struct wiphy
*wiphy
= hw
->wiphy
;
683 for (i
= 0; i
< ARRAY_SIZE(dev
->macaddr_list
); i
++) {
684 u8
*addr
= dev
->macaddr_list
[i
].addr
;
686 memcpy(addr
, dev
->mphy
.macaddr
, ETH_ALEN
);
692 addr
[0] ^= ((i
- 1) << 2);
694 wiphy
->addresses
= dev
->macaddr_list
;
695 wiphy
->n_addresses
= ARRAY_SIZE(dev
->macaddr_list
);
697 EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list
);
699 MODULE_DESCRIPTION("MediaTek MT76x02 helpers");
700 MODULE_LICENSE("Dual BSD/GPL");