1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc. */
4 #include "mt76_connac_mcu.h"
6 int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
12 .option = cpu_to_le32(option),
13 .addr = cpu_to_le32(addr),
16 return mt76_mcu_send_msg(dev, MCU_CMD(FW_START_REQ), &req,
19 EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
21 int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
23 u32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;
27 .op = cpu_to_le32(op),
30 return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_SEM_CONTROL),
31 &req, sizeof(req), true);
33 EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
35 int mt76_connac_mcu_start_patch(struct mt76_dev *dev)
44 return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_FINISH_REQ),
45 &req, sizeof(req), true);
47 EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
49 #define MCU_PATCH_ADDRESS 0x200000
51 int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
59 .addr = cpu_to_le32(addr),
60 .len = cpu_to_le32(len),
61 .mode = cpu_to_le32(mode),
65 if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
66 (is_mt7921(dev) && addr == 0x900000))
67 cmd = MCU_CMD(PATCH_START_REQ);
69 cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
71 return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true);
73 EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
75 int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
77 int len, i, n_max_channels, n_2ch = 0, n_5ch = 0, n_6ch = 0;
78 struct mt76_connac_mcu_channel_domain {
79 u8 alpha2[4]; /* regulatory_request.alpha2 */
80 u8 bw_2g; /* BW_20_40M 0
95 .bw_5g = 3, /* BW_20_40_80_160M */
98 struct mt76_connac_mcu_chan {
103 struct mt76_dev *dev = phy->dev;
104 struct ieee80211_channel *chan;
107 n_max_channels = phy->sband_2g.sband.n_channels +
108 phy->sband_5g.sband.n_channels +
109 phy->sband_6g.sband.n_channels;
110 len = sizeof(hdr) + n_max_channels * sizeof(channel);
112 skb = mt76_mcu_msg_alloc(dev, NULL, len);
116 skb_reserve(skb, sizeof(hdr));
118 for (i = 0; i < phy->sband_2g.sband.n_channels; i++) {
119 chan = &phy->sband_2g.sband.channels[i];
120 if (chan->flags & IEEE80211_CHAN_DISABLED)
123 channel.hw_value = cpu_to_le16(chan->hw_value);
124 channel.flags = cpu_to_le32(chan->flags);
127 skb_put_data(skb, &channel, sizeof(channel));
130 for (i = 0; i < phy->sband_5g.sband.n_channels; i++) {
131 chan = &phy->sband_5g.sband.channels[i];
132 if (chan->flags & IEEE80211_CHAN_DISABLED)
135 channel.hw_value = cpu_to_le16(chan->hw_value);
136 channel.flags = cpu_to_le32(chan->flags);
139 skb_put_data(skb, &channel, sizeof(channel));
142 for (i = 0; i < phy->sband_6g.sband.n_channels; i++) {
143 chan = &phy->sband_6g.sband.channels[i];
144 if (chan->flags & IEEE80211_CHAN_DISABLED)
147 channel.hw_value = cpu_to_le16(chan->hw_value);
148 channel.flags = cpu_to_le32(chan->flags);
151 skb_put_data(skb, &channel, sizeof(channel));
155 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
156 memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
161 memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
163 return mt76_mcu_skb_send_msg(dev, skb, MCU_CE_CMD(SET_CHAN_DOMAIN),
166 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
168 int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
175 } __packed req_mac = {
180 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(MAC_INIT_CTRL), &req_mac,
181 sizeof(req_mac), true);
183 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
185 int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
187 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
190 u8 ps_state; /* 0: device awake
191 * 1: static power save
192 * 2: dynamic power saving
195 .bss_idx = mvif->idx,
196 .ps_state = vif->bss_conf.ps ? 2 : 0,
199 if (vif->type != NL80211_IFTYPE_STATION)
202 return mt76_mcu_send_msg(dev, MCU_CE_CMD(SET_PS_PROFILE),
203 &req, sizeof(req), false);
205 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
207 int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
218 .len_thresh = cpu_to_le32(val),
219 .pkt_thresh = cpu_to_le32(0x2),
222 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PROTECT_CTRL), &req,
225 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
227 void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
228 struct ieee80211_vif *vif)
230 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
231 struct mt76_connac_beacon_loss_event *event = priv;
233 if (mvif->idx != event->bss_idx)
236 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
239 ieee80211_beacon_loss(vif);
241 EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
244 mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
245 void *sta_ntlv, void *sta_wtbl)
247 struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv;
248 struct tlv *sta_hdr = sta_wtbl;
249 struct tlv *ptlv, tlv = {
250 .tag = cpu_to_le16(tag),
251 .len = cpu_to_le16(len),
255 ptlv = skb_put(skb, len);
256 memcpy(ptlv, &tlv, sizeof(tlv));
258 ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
259 ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
262 le16_add_cpu(&sta_hdr->len, len);
266 EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
269 __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
270 struct mt76_wcid *wcid, int len)
272 struct sta_req_hdr hdr = {
273 .bss_idx = mvif->idx,
274 .muar_idx = wcid ? mvif->omac_idx : 0,
279 mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
281 skb = mt76_mcu_msg_alloc(dev, NULL, len);
283 return ERR_PTR(-ENOMEM);
285 skb_put_data(skb, &hdr, sizeof(hdr));
289 EXPORT_SYMBOL_GPL(__mt76_connac_mcu_alloc_sta_req);
291 struct wtbl_req_hdr *
292 mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
293 int cmd, void *sta_wtbl, struct sk_buff **skb)
295 struct tlv *sta_hdr = sta_wtbl;
296 struct wtbl_req_hdr hdr = {
299 struct sk_buff *nskb = *skb;
301 mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
304 nskb = mt76_mcu_msg_alloc(dev, NULL,
305 MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
307 return ERR_PTR(-ENOMEM);
313 le16_add_cpu(&sta_hdr->len, sizeof(hdr));
315 return skb_put_data(nskb, &hdr, sizeof(hdr));
317 EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
319 void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb,
320 struct ieee80211_vif *vif)
322 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
323 u8 omac_idx = mvif->omac_idx;
324 struct bss_info_omac *omac;
329 case NL80211_IFTYPE_MONITOR:
330 case NL80211_IFTYPE_MESH_POINT:
331 case NL80211_IFTYPE_AP:
333 type = CONNECTION_P2P_GO;
335 type = CONNECTION_INFRA_AP;
337 case NL80211_IFTYPE_STATION:
339 type = CONNECTION_P2P_GC;
341 type = CONNECTION_INFRA_STA;
343 case NL80211_IFTYPE_ADHOC:
344 type = CONNECTION_IBSS_ADHOC;
351 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_OMAC, sizeof(*omac));
353 omac = (struct bss_info_omac *)tlv;
354 omac->conn_type = cpu_to_le32(type);
355 omac->omac_idx = mvif->omac_idx;
356 omac->band_idx = mvif->band_idx;
357 omac->hw_bss_idx = omac_idx > EXT_BSSID_START ? HW_BSSID_0 : omac_idx;
359 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_omac_tlv);
361 void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
362 struct ieee80211_vif *vif,
363 struct ieee80211_sta *sta,
364 bool enable, bool newly)
366 struct sta_rec_basic *basic;
370 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
372 basic = (struct sta_rec_basic *)tlv;
373 basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);
377 basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
378 basic->conn_state = CONN_STATE_PORT_SECURE;
380 basic->conn_state = CONN_STATE_DISCONNECT;
384 basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
385 eth_broadcast_addr(basic->peer_addr);
390 case NL80211_IFTYPE_MESH_POINT:
391 case NL80211_IFTYPE_AP:
393 conn_type = CONNECTION_P2P_GC;
395 conn_type = CONNECTION_INFRA_STA;
396 basic->conn_type = cpu_to_le32(conn_type);
397 basic->aid = cpu_to_le16(sta->aid);
399 case NL80211_IFTYPE_STATION:
401 conn_type = CONNECTION_P2P_GO;
403 conn_type = CONNECTION_INFRA_AP;
404 basic->conn_type = cpu_to_le32(conn_type);
405 basic->aid = cpu_to_le16(vif->bss_conf.aid);
407 case NL80211_IFTYPE_ADHOC:
408 basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
409 basic->aid = cpu_to_le16(sta->aid);
416 memcpy(basic->peer_addr, sta->addr, ETH_ALEN);
417 basic->qos = sta->wme;
419 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
421 void mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
422 struct ieee80211_sta *sta)
424 struct sta_rec_uapsd *uapsd;
427 if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
430 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
431 uapsd = (struct sta_rec_uapsd *)tlv;
433 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
434 uapsd->dac_map |= BIT(3);
435 uapsd->tac_map |= BIT(3);
437 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
438 uapsd->dac_map |= BIT(2);
439 uapsd->tac_map |= BIT(2);
441 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
442 uapsd->dac_map |= BIT(1);
443 uapsd->tac_map |= BIT(1);
445 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
446 uapsd->dac_map |= BIT(0);
447 uapsd->tac_map |= BIT(0);
449 uapsd->max_sp = sta->max_sp;
451 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_uapsd);
453 void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
454 struct ieee80211_vif *vif,
455 struct mt76_wcid *wcid,
456 void *sta_wtbl, void *wtbl_tlv)
458 struct wtbl_hdr_trans *htr;
461 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HDR_TRANS,
464 htr = (struct wtbl_hdr_trans *)tlv;
465 htr->no_rx_trans = true;
467 if (vif->type == NL80211_IFTYPE_STATION)
475 htr->no_rx_trans = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
476 if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
481 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv);
483 int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
484 struct ieee80211_vif *vif,
485 struct mt76_wcid *wcid, int cmd)
487 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
488 struct wtbl_req_hdr *wtbl_hdr;
489 struct tlv *sta_wtbl;
492 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
496 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
499 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
501 if (IS_ERR(wtbl_hdr))
502 return PTR_ERR(wtbl_hdr);
504 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, sta_wtbl, wtbl_hdr);
506 return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
508 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans);
510 int mt76_connac_mcu_wtbl_update_hdr_trans(struct mt76_dev *dev,
511 struct ieee80211_vif *vif,
512 struct ieee80211_sta *sta)
514 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
515 struct wtbl_req_hdr *wtbl_hdr;
516 struct sk_buff *skb = NULL;
518 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, NULL,
520 if (IS_ERR(wtbl_hdr))
521 return PTR_ERR(wtbl_hdr);
523 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, NULL, wtbl_hdr);
525 return mt76_mcu_skb_send_msg(dev, skb, MCU_EXT_CMD(WTBL_UPDATE), true);
527 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_update_hdr_trans);
529 void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
531 struct ieee80211_vif *vif,
532 struct ieee80211_sta *sta,
533 void *sta_wtbl, void *wtbl_tlv)
535 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
536 struct wtbl_generic *generic;
538 struct wtbl_spe *spe;
541 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC,
545 generic = (struct wtbl_generic *)tlv;
548 if (vif->type == NL80211_IFTYPE_STATION)
549 generic->partial_aid = cpu_to_le16(vif->bss_conf.aid);
551 generic->partial_aid = cpu_to_le16(sta->aid);
552 memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
553 generic->muar_idx = mvif->omac_idx;
554 generic->qos = sta->wme;
556 if (!is_connac_v1(dev) && vif->type == NL80211_IFTYPE_STATION)
557 memcpy(generic->peer_addr, vif->bss_conf.bssid,
560 eth_broadcast_addr(generic->peer_addr);
562 generic->muar_idx = 0xe;
565 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx),
568 rx = (struct wtbl_rx *)tlv;
569 rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1;
573 if (!is_connac_v1(dev))
576 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe),
578 spe = (struct wtbl_spe *)tlv;
581 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
584 mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
585 struct ieee80211_vif *vif)
587 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
588 struct sta_rec_amsdu *amsdu;
591 if (vif->type != NL80211_IFTYPE_AP &&
592 vif->type != NL80211_IFTYPE_STATION)
595 if (!sta->max_amsdu_len)
598 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
599 amsdu = (struct sta_rec_amsdu *)tlv;
600 amsdu->max_amsdu_num = 8;
601 amsdu->amsdu_en = true;
602 amsdu->max_mpdu_size = sta->max_amsdu_len >=
603 IEEE80211_MAX_MPDU_LEN_VHT_7991;
608 #define HE_PHY(p, c) u8_get_bits(c, IEEE80211_HE_PHY_##p)
609 #define HE_MAC(m, c) u8_get_bits(c, IEEE80211_HE_MAC_##m)
611 mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
613 struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
614 struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
615 struct sta_rec_he *he;
619 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
621 he = (struct sta_rec_he *)tlv;
623 if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
624 cap |= STA_REC_HE_CAP_HTC;
626 if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
627 cap |= STA_REC_HE_CAP_BSR;
629 if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
630 cap |= STA_REC_HE_CAP_OM;
632 if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
633 cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
635 if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
636 cap |= STA_REC_HE_CAP_BQR;
638 if (elem->phy_cap_info[0] &
639 (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G |
640 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
641 cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
643 if (elem->phy_cap_info[1] &
644 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
645 cap |= STA_REC_HE_CAP_LDPC;
647 if (elem->phy_cap_info[1] &
648 IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US)
649 cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI;
651 if (elem->phy_cap_info[2] &
652 IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US)
653 cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI;
655 if (elem->phy_cap_info[2] &
656 IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ)
657 cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC;
659 if (elem->phy_cap_info[2] &
660 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
661 cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC;
663 if (elem->phy_cap_info[6] &
664 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE)
665 cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE;
667 if (elem->phy_cap_info[7] &
668 IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
669 cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI;
671 if (elem->phy_cap_info[7] &
672 IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ)
673 cap |= STA_REC_HE_CAP_GT_80M_TX_STBC;
675 if (elem->phy_cap_info[7] &
676 IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
677 cap |= STA_REC_HE_CAP_GT_80M_RX_STBC;
679 if (elem->phy_cap_info[8] &
680 IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
681 cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI;
683 if (elem->phy_cap_info[8] &
684 IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI)
685 cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI;
687 if (elem->phy_cap_info[9] &
688 IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK)
689 cap |= STA_REC_HE_CAP_TRIG_CQI_FK;
691 if (elem->phy_cap_info[9] &
692 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU)
693 cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242;
695 if (elem->phy_cap_info[9] &
696 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU)
697 cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242;
699 he->he_cap = cpu_to_le32(cap);
701 switch (sta->bandwidth) {
702 case IEEE80211_STA_RX_BW_160:
703 if (elem->phy_cap_info[0] &
704 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
705 he->max_nss_mcs[CMD_HE_MCS_BW8080] =
706 he_cap->he_mcs_nss_supp.rx_mcs_80p80;
708 he->max_nss_mcs[CMD_HE_MCS_BW160] =
709 he_cap->he_mcs_nss_supp.rx_mcs_160;
712 he->max_nss_mcs[CMD_HE_MCS_BW80] =
713 he_cap->he_mcs_nss_supp.rx_mcs_80;
718 HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
720 HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]);
723 HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]);
725 HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]);
727 HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
730 HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]);
732 HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]);
734 HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]);
736 HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]);
738 HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]);
744 mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
745 enum nl80211_band band, struct ieee80211_sta *sta)
747 struct ieee80211_sta_ht_cap *ht_cap;
748 struct ieee80211_sta_vht_cap *vht_cap;
749 const struct ieee80211_sta_he_cap *he_cap;
753 ht_cap = &sta->ht_cap;
754 vht_cap = &sta->vht_cap;
755 he_cap = &sta->he_cap;
757 struct ieee80211_supported_band *sband;
759 sband = mphy->hw->wiphy->bands[band];
760 ht_cap = &sband->ht_cap;
761 vht_cap = &sband->vht_cap;
762 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
765 if (band == NL80211_BAND_2GHZ) {
766 mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP;
768 if (ht_cap->ht_supported)
769 mode |= PHY_TYPE_BIT_HT;
771 if (he_cap && he_cap->has_he)
772 mode |= PHY_TYPE_BIT_HE;
773 } else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
774 mode |= PHY_TYPE_BIT_OFDM;
776 if (ht_cap->ht_supported)
777 mode |= PHY_TYPE_BIT_HT;
779 if (vht_cap->vht_supported)
780 mode |= PHY_TYPE_BIT_VHT;
782 if (he_cap && he_cap->has_he)
783 mode |= PHY_TYPE_BIT_HE;
789 void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
790 struct ieee80211_sta *sta,
791 struct ieee80211_vif *vif,
792 u8 rcpi, u8 sta_state)
794 struct cfg80211_chan_def *chandef = &mphy->chandef;
795 enum nl80211_band band = chandef->chan->band;
796 struct mt76_dev *dev = mphy->dev;
797 struct sta_rec_ra_info *ra_info;
798 struct sta_rec_state *state;
799 struct sta_rec_phy *phy;
804 if (sta->ht_cap.ht_supported) {
805 struct sta_rec_ht *ht;
807 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
808 ht = (struct sta_rec_ht *)tlv;
809 ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
813 if (sta->vht_cap.vht_supported) {
814 struct sta_rec_vht *vht;
817 len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
818 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
819 vht = (struct sta_rec_vht *)tlv;
820 vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
821 vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
822 vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
826 mt76_connac_mcu_sta_uapsd(skb, vif, sta);
831 if (sta->ht_cap.ht_supported || sta->he_cap.has_he)
832 mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
835 if (sta->he_cap.has_he) {
836 mt76_connac_mcu_sta_he_tlv(skb, sta);
837 if (band == NL80211_BAND_6GHZ &&
838 sta_state == MT76_STA_INFO_STATE_ASSOC) {
839 struct sta_rec_he_6g_capa *he_6g_capa;
841 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G,
842 sizeof(*he_6g_capa));
843 he_6g_capa = (struct sta_rec_he_6g_capa *)tlv;
844 he_6g_capa->capa = sta->he_6ghz_capa.capa;
848 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
849 phy = (struct sta_rec_phy *)tlv;
850 phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
851 phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
853 phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
854 sta->ht_cap.ampdu_factor) |
855 FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY,
856 sta->ht_cap.ampdu_density);
858 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
859 ra_info = (struct sta_rec_ra_info *)tlv;
861 supp_rates = sta->supp_rates[band];
862 if (band == NL80211_BAND_2GHZ)
863 supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
864 FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf);
866 supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates);
868 ra_info->legacy = cpu_to_le16(supp_rates);
870 if (sta->ht_cap.ht_supported)
871 memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask,
874 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
875 state = (struct sta_rec_state *)tlv;
876 state->state = sta_state;
878 if (sta->vht_cap.vht_supported) {
879 state->vht_opmode = sta->bandwidth;
880 state->vht_opmode |= (sta->rx_nss - 1) <<
881 IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
884 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
886 void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb,
887 struct ieee80211_sta *sta,
888 void *sta_wtbl, void *wtbl_tlv)
890 struct wtbl_smps *smps;
893 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
895 smps = (struct wtbl_smps *)tlv;
896 smps->smps = (sta->smps_mode == IEEE80211_SMPS_DYNAMIC);
898 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv);
900 void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
901 struct ieee80211_sta *sta, void *sta_wtbl,
902 void *wtbl_tlv, bool ht_ldpc, bool vht_ldpc)
904 struct wtbl_ht *ht = NULL;
908 if (sta->ht_cap.ht_supported || sta->he_6ghz_capa.capa) {
909 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
911 ht = (struct wtbl_ht *)tlv;
912 ht->ldpc = ht_ldpc &&
913 !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
915 if (sta->ht_cap.ht_supported) {
916 ht->af = sta->ht_cap.ampdu_factor;
917 ht->mm = sta->ht_cap.ampdu_density;
919 ht->af = le16_get_bits(sta->he_6ghz_capa.capa,
920 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
921 ht->mm = le16_get_bits(sta->he_6ghz_capa.capa,
922 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
928 if (sta->vht_cap.vht_supported || sta->he_6ghz_capa.capa) {
929 struct wtbl_vht *vht;
932 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
933 sizeof(*vht), wtbl_tlv,
935 vht = (struct wtbl_vht *)tlv;
936 vht->ldpc = vht_ldpc &&
937 !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
940 af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
943 ht->af = max(ht->af, af);
946 mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
948 if (is_connac_v1(dev) && sta->ht_cap.ht_supported) {
950 u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
951 MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
952 struct wtbl_raw *raw;
954 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
955 sizeof(*raw), wtbl_tlv,
958 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
959 flags |= MT_WTBL_W5_SHORT_GI_20;
960 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
961 flags |= MT_WTBL_W5_SHORT_GI_40;
963 if (sta->vht_cap.vht_supported) {
964 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
965 flags |= MT_WTBL_W5_SHORT_GI_80;
966 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
967 flags |= MT_WTBL_W5_SHORT_GI_160;
969 raw = (struct wtbl_raw *)tlv;
970 raw->val = cpu_to_le32(flags);
971 raw->msk = cpu_to_le32(~msk);
976 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
978 int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
979 struct mt76_sta_cmd_info *info)
981 struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv;
982 struct mt76_dev *dev = phy->dev;
983 struct wtbl_req_hdr *wtbl_hdr;
984 struct tlv *sta_wtbl;
987 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid);
991 if (info->sta || !info->offload_fw)
992 mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
993 info->enable, info->newly);
994 if (info->sta && info->enable)
995 mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
996 info->vif, info->rcpi,
999 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1000 sizeof(struct tlv));
1002 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid,
1005 if (IS_ERR(wtbl_hdr))
1006 return PTR_ERR(wtbl_hdr);
1009 mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif,
1010 info->sta, sta_wtbl,
1012 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid,
1013 sta_wtbl, wtbl_hdr);
1015 mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta,
1020 return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
1022 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);
1024 void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
1025 struct ieee80211_ampdu_params *params,
1026 bool enable, bool tx, void *sta_wtbl,
1032 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
1033 wtbl_tlv, sta_wtbl);
1035 ba = (struct wtbl_ba *)tlv;
1036 ba->tid = params->tid;
1039 ba->ba_type = MT_BA_TYPE_ORIGINATOR;
1040 ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
1041 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
1044 memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
1045 ba->ba_type = MT_BA_TYPE_RECIPIENT;
1046 ba->rst_ba_tid = params->tid;
1047 ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
1051 if (!is_connac_v1(dev)) {
1052 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
1057 static const u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
1060 for (i = 7; i > 0; i--) {
1061 if (params->buf_size >= ba_range[i])
1064 ba->ba_winsize_idx = i;
1067 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
1069 int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
1070 struct ieee80211_vif *vif,
1071 struct mt76_wcid *wcid,
1074 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1075 struct mt76_dev *dev = phy->dev;
1087 u8 omac_addr[ETH_ALEN];
1091 .omac_idx = mvif->omac_idx,
1092 .band_idx = mvif->band_idx,
1095 .tag = cpu_to_le16(DEV_INFO_ACTIVE),
1096 .len = cpu_to_le16(sizeof(struct req_tlv)),
1105 struct mt76_connac_bss_basic_tlv basic;
1108 .bss_idx = mvif->idx,
1111 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1112 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1113 .omac_idx = mvif->omac_idx,
1114 .band_idx = mvif->band_idx,
1115 .wmm_idx = mvif->wmm_idx,
1117 .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
1118 .sta_idx = cpu_to_le16(wcid->idx),
1122 int err, idx, cmd, len;
1125 switch (vif->type) {
1126 case NL80211_IFTYPE_MESH_POINT:
1127 case NL80211_IFTYPE_MONITOR:
1128 case NL80211_IFTYPE_AP:
1129 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
1131 case NL80211_IFTYPE_STATION:
1132 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
1134 case NL80211_IFTYPE_ADHOC:
1135 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1142 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1143 basic_req.basic.hw_bss_idx = idx;
1145 memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
1147 cmd = enable ? MCU_UNI_CMD(DEV_INFO_UPDATE) : MCU_UNI_CMD(BSS_INFO_UPDATE);
1148 data = enable ? (void *)&dev_req : (void *)&basic_req;
1149 len = enable ? sizeof(dev_req) : sizeof(basic_req);
1151 err = mt76_mcu_send_msg(dev, cmd, data, len, true);
1155 cmd = enable ? MCU_UNI_CMD(BSS_INFO_UPDATE) : MCU_UNI_CMD(DEV_INFO_UPDATE);
1156 data = enable ? (void *)&basic_req : (void *)&dev_req;
1157 len = enable ? sizeof(basic_req) : sizeof(dev_req);
1159 return mt76_mcu_send_msg(dev, cmd, data, len, true);
1161 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
1163 void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
1164 struct ieee80211_ampdu_params *params,
1165 bool enable, bool tx)
1167 struct sta_rec_ba *ba;
1170 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
1172 ba = (struct sta_rec_ba *)tlv;
1173 ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
1174 ba->winsize = cpu_to_le16(params->buf_size);
1175 ba->ssn = cpu_to_le16(params->ssn);
1176 ba->ba_en = enable << params->tid;
1177 ba->amsdu = params->amsdu;
1178 ba->tid = params->tid;
1180 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
1182 int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
1183 struct ieee80211_ampdu_params *params,
1184 int cmd, bool enable, bool tx)
1186 struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
1187 struct wtbl_req_hdr *wtbl_hdr;
1188 struct tlv *sta_wtbl;
1189 struct sk_buff *skb;
1192 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1194 return PTR_ERR(skb);
1196 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1197 sizeof(struct tlv));
1199 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
1201 if (IS_ERR(wtbl_hdr))
1202 return PTR_ERR(wtbl_hdr);
1204 mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
1207 ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true);
1211 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1213 return PTR_ERR(skb);
1215 mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
1217 return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
1219 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
1221 u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
1222 enum nl80211_band band, struct ieee80211_sta *sta)
1224 struct mt76_dev *dev = phy->dev;
1225 const struct ieee80211_sta_he_cap *he_cap;
1226 struct ieee80211_sta_vht_cap *vht_cap;
1227 struct ieee80211_sta_ht_cap *ht_cap;
1230 if (is_connac_v1(dev))
1234 ht_cap = &sta->ht_cap;
1235 vht_cap = &sta->vht_cap;
1236 he_cap = &sta->he_cap;
1238 struct ieee80211_supported_band *sband;
1240 sband = phy->hw->wiphy->bands[band];
1241 ht_cap = &sband->ht_cap;
1242 vht_cap = &sband->vht_cap;
1243 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
1246 if (band == NL80211_BAND_2GHZ) {
1247 mode |= PHY_MODE_B | PHY_MODE_G;
1249 if (ht_cap->ht_supported)
1250 mode |= PHY_MODE_GN;
1252 if (he_cap && he_cap->has_he)
1253 mode |= PHY_MODE_AX_24G;
1254 } else if (band == NL80211_BAND_5GHZ) {
1257 if (ht_cap->ht_supported)
1258 mode |= PHY_MODE_AN;
1260 if (vht_cap->vht_supported)
1261 mode |= PHY_MODE_AC;
1263 if (he_cap && he_cap->has_he)
1264 mode |= PHY_MODE_AX_5G;
1265 } else if (band == NL80211_BAND_6GHZ) {
1266 mode |= PHY_MODE_A | PHY_MODE_AN |
1267 PHY_MODE_AC | PHY_MODE_AX_5G;
1272 EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
1274 const struct ieee80211_sta_he_cap *
1275 mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
1277 enum nl80211_band band = phy->chandef.chan->band;
1278 struct ieee80211_supported_band *sband;
1280 sband = phy->hw->wiphy->bands[band];
1282 return ieee80211_get_he_iftype_cap(sband, vif->type);
1284 EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap);
1286 #define DEFAULT_HE_PE_DURATION 4
1287 #define DEFAULT_HE_DURATION_RTS_THRES 1023
1289 mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
1292 const struct ieee80211_sta_he_cap *cap;
1293 struct bss_info_uni_he *he;
1295 cap = mt76_connac_get_he_phy_cap(phy, vif);
1297 he = (struct bss_info_uni_he *)tlv;
1298 he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
1299 if (!he->he_pe_duration)
1300 he->he_pe_duration = DEFAULT_HE_PE_DURATION;
1302 he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
1303 if (!he->he_rts_thres)
1304 he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
1306 he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
1307 he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
1308 he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
1311 int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
1312 struct ieee80211_vif *vif,
1313 struct mt76_wcid *wcid,
1316 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1317 struct cfg80211_chan_def *chandef = &phy->chandef;
1318 int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
1319 enum nl80211_band band = chandef->chan->band;
1320 struct mt76_dev *mdev = phy->dev;
1326 struct mt76_connac_bss_basic_tlv basic;
1327 struct mt76_connac_bss_qos_tlv qos;
1330 .bss_idx = mvif->idx,
1333 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1334 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1335 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1336 .dtim_period = vif->bss_conf.dtim_period,
1337 .omac_idx = mvif->omac_idx,
1338 .band_idx = mvif->band_idx,
1339 .wmm_idx = mvif->wmm_idx,
1340 .active = true, /* keep bss deactivated */
1341 .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
1344 .tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
1345 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
1346 .qos = vif->bss_conf.qos,
1369 } __packed rlm_req = {
1371 .bss_idx = mvif->idx,
1374 .tag = cpu_to_le16(UNI_BSS_INFO_RLM),
1375 .len = cpu_to_le16(sizeof(struct rlm_tlv)),
1376 .control_channel = chandef->chan->hw_value,
1377 .center_chan = ieee80211_frequency_to_channel(freq1),
1378 .center_chan2 = ieee80211_frequency_to_channel(freq2),
1379 .tx_streams = hweight8(phy->antenna_mask),
1380 .ht_op_info = 4, /* set HT 40M allowed */
1381 .rx_streams = phy->chainmask,
1389 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1390 basic_req.basic.hw_bss_idx = idx;
1391 if (band == NL80211_BAND_6GHZ)
1392 basic_req.basic.phymode_ext = PHY_MODE_AX_6G;
1394 basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL);
1395 basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy);
1397 switch (vif->type) {
1398 case NL80211_IFTYPE_MESH_POINT:
1399 case NL80211_IFTYPE_AP:
1401 conn_type = CONNECTION_P2P_GO;
1403 conn_type = CONNECTION_INFRA_AP;
1404 basic_req.basic.conn_type = cpu_to_le32(conn_type);
1406 case NL80211_IFTYPE_STATION:
1408 conn_type = CONNECTION_P2P_GC;
1410 conn_type = CONNECTION_INFRA_STA;
1411 basic_req.basic.conn_type = cpu_to_le32(conn_type);
1413 case NL80211_IFTYPE_ADHOC:
1414 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1421 memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
1422 basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
1423 basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
1424 basic_req.basic.conn_state = !enable;
1426 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &basic_req,
1427 sizeof(basic_req), true);
1431 if (vif->bss_conf.he_support) {
1437 struct bss_info_uni_he he;
1438 struct bss_info_uni_bss_color bss_color;
1441 .bss_idx = mvif->idx,
1444 .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
1445 .len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
1448 .tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR),
1449 .len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)),
1456 he_req.bss_color.enable =
1457 vif->bss_conf.he_bss_color.enabled;
1458 he_req.bss_color.bss_color =
1459 vif->bss_conf.he_bss_color.color;
1462 mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
1463 (struct tlv *)&he_req.he);
1464 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE),
1465 &he_req, sizeof(he_req), true);
1470 switch (chandef->width) {
1471 case NL80211_CHAN_WIDTH_40:
1472 rlm_req.rlm.bw = CMD_CBW_40MHZ;
1474 case NL80211_CHAN_WIDTH_80:
1475 rlm_req.rlm.bw = CMD_CBW_80MHZ;
1477 case NL80211_CHAN_WIDTH_80P80:
1478 rlm_req.rlm.bw = CMD_CBW_8080MHZ;
1480 case NL80211_CHAN_WIDTH_160:
1481 rlm_req.rlm.bw = CMD_CBW_160MHZ;
1483 case NL80211_CHAN_WIDTH_5:
1484 rlm_req.rlm.bw = CMD_CBW_5MHZ;
1486 case NL80211_CHAN_WIDTH_10:
1487 rlm_req.rlm.bw = CMD_CBW_10MHZ;
1489 case NL80211_CHAN_WIDTH_20_NOHT:
1490 case NL80211_CHAN_WIDTH_20:
1492 rlm_req.rlm.bw = CMD_CBW_20MHZ;
1493 rlm_req.rlm.ht_op_info = 0;
1497 if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
1498 rlm_req.rlm.sco = 1; /* SCA */
1499 else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
1500 rlm_req.rlm.sco = 3; /* SCB */
1502 return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req,
1503 sizeof(rlm_req), true);
1505 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
1507 #define MT76_CONNAC_SCAN_CHANNEL_TIME 60
1508 int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
1509 struct ieee80211_scan_request *scan_req)
1511 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1512 struct cfg80211_scan_request *sreq = &scan_req->req;
1513 int n_ssids = 0, err, i, duration;
1514 int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
1515 struct ieee80211_channel **scan_list = sreq->channels;
1516 struct mt76_dev *mdev = phy->dev;
1517 struct mt76_connac_mcu_scan_channel *chan;
1518 struct mt76_connac_hw_scan_req *req;
1519 struct sk_buff *skb;
1521 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
1525 set_bit(MT76_HW_SCANNING, &phy->state);
1526 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1528 req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
1530 req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
1531 req->bss_idx = mvif->idx;
1532 req->scan_type = sreq->n_ssids ? 1 : 0;
1533 req->probe_req_num = sreq->n_ssids ? 2 : 0;
1536 for (i = 0; i < sreq->n_ssids; i++) {
1537 if (!sreq->ssids[i].ssid_len)
1540 req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
1541 memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
1542 sreq->ssids[i].ssid_len);
1545 req->ssid_type = n_ssids ? BIT(2) : BIT(0);
1546 req->ssid_type_ext = n_ssids ? BIT(0) : 0;
1547 req->ssids_num = n_ssids;
1549 duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME;
1550 /* increase channel time for passive scan */
1553 req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
1554 req->channel_min_dwell_time = cpu_to_le16(duration);
1555 req->channel_dwell_time = cpu_to_le16(duration);
1557 req->channels_num = min_t(u8, sreq->n_channels, 32);
1558 req->ext_channels_num = min_t(u8, ext_channels_num, 32);
1559 for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
1561 chan = &req->ext_channels[i - 32];
1563 chan = &req->channels[i];
1565 switch (scan_list[i]->band) {
1566 case NL80211_BAND_2GHZ:
1569 case NL80211_BAND_6GHZ:
1576 chan->channel_num = scan_list[i]->hw_value;
1578 req->channel_type = sreq->n_channels ? 4 : 0;
1580 if (sreq->ie_len > 0) {
1581 memcpy(req->ies, sreq->ie, sreq->ie_len);
1582 req->ies_len = cpu_to_le16(sreq->ie_len);
1585 if (is_mt7921(phy->dev))
1586 req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
1588 memcpy(req->bssid, sreq->bssid, ETH_ALEN);
1589 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1590 get_random_mask_addr(req->random_mac, sreq->mac_addr,
1591 sreq->mac_addr_mask);
1592 req->scan_func |= SCAN_FUNC_RANDOM_MAC;
1595 err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(START_HW_SCAN),
1598 clear_bit(MT76_HW_SCANNING, &phy->state);
1602 EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
1604 int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
1605 struct ieee80211_vif *vif)
1607 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1613 .seq_num = mvif->scan_seq_num,
1616 if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
1617 struct cfg80211_scan_info info = {
1621 ieee80211_scan_completed(phy->hw, &info);
1624 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(CANCEL_HW_SCAN),
1625 &req, sizeof(req), false);
1627 EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
1629 int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
1630 struct ieee80211_vif *vif,
1631 struct cfg80211_sched_scan_request *sreq)
1633 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1634 struct ieee80211_channel **scan_list = sreq->channels;
1635 struct mt76_connac_mcu_scan_channel *chan;
1636 struct mt76_connac_sched_scan_req *req;
1637 struct mt76_dev *mdev = phy->dev;
1638 struct cfg80211_match_set *match;
1639 struct cfg80211_ssid *ssid;
1640 struct sk_buff *skb;
1643 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
1647 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1649 req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
1651 req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
1653 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1654 u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
1655 : req->mt7921.random_mac;
1658 get_random_mask_addr(addr, sreq->mac_addr,
1659 sreq->mac_addr_mask);
1661 if (is_mt7921(phy->dev)) {
1662 req->mt7921.bss_idx = mvif->idx;
1663 req->mt7921.delay = cpu_to_le32(sreq->delay);
1666 req->ssids_num = sreq->n_ssids;
1667 for (i = 0; i < req->ssids_num; i++) {
1668 ssid = &sreq->ssids[i];
1669 memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
1670 req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
1673 req->match_num = sreq->n_match_sets;
1674 for (i = 0; i < req->match_num; i++) {
1675 match = &sreq->match_sets[i];
1676 memcpy(req->match[i].ssid, match->ssid.ssid,
1677 match->ssid.ssid_len);
1678 req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
1679 req->match[i].ssid_len = match->ssid.ssid_len;
1682 req->channel_type = sreq->n_channels ? 4 : 0;
1683 req->channels_num = min_t(u8, sreq->n_channels, 64);
1684 for (i = 0; i < req->channels_num; i++) {
1685 chan = &req->channels[i];
1687 switch (scan_list[i]->band) {
1688 case NL80211_BAND_2GHZ:
1691 case NL80211_BAND_6GHZ:
1698 chan->channel_num = scan_list[i]->hw_value;
1701 req->intervals_num = sreq->n_scan_plans;
1702 for (i = 0; i < req->intervals_num; i++)
1703 req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
1705 if (sreq->ie_len > 0) {
1706 req->ie_len = cpu_to_le16(sreq->ie_len);
1707 memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
1710 return mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(SCHED_SCAN_REQ),
1713 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
1715 int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
1716 struct ieee80211_vif *vif,
1720 u8 active; /* 0: enabled 1: disabled */
1727 set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1729 clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1731 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SCHED_SCAN_ENABLE),
1732 &req, sizeof(req), false);
1734 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
1736 int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
1738 struct mt76_connac_config req = {
1742 memcpy(req.data, "assert", 7);
1744 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
1745 &req, sizeof(req), false);
1747 EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
1749 int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
1751 struct mt76_connac_config req = {
1755 snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
1757 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
1758 &req, sizeof(req), false);
1760 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
1762 int mt76_connac_sta_state_dp(struct mt76_dev *dev,
1763 enum ieee80211_sta_state old_state,
1764 enum ieee80211_sta_state new_state)
1766 if ((old_state == IEEE80211_STA_ASSOC &&
1767 new_state == IEEE80211_STA_AUTHORIZED) ||
1768 (old_state == IEEE80211_STA_NONE &&
1769 new_state == IEEE80211_STA_NOTEXIST))
1770 mt76_connac_mcu_set_deep_sleep(dev, true);
1772 if ((old_state == IEEE80211_STA_NOTEXIST &&
1773 new_state == IEEE80211_STA_NONE) ||
1774 (old_state == IEEE80211_STA_AUTHORIZED &&
1775 new_state == IEEE80211_STA_ASSOC))
1776 mt76_connac_mcu_set_deep_sleep(dev, false);
1780 EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
1782 void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
1783 struct mt76_connac_coredump *coredump)
1785 spin_lock_bh(&dev->lock);
1786 __skb_queue_tail(&coredump->msg_list, skb);
1787 spin_unlock_bh(&dev->lock);
1789 coredump->last_activity = jiffies;
1791 queue_delayed_work(dev->wq, &coredump->work,
1792 MT76_CONNAC_COREDUMP_TIMEOUT);
1794 EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
1796 static void mt76_connac_mcu_parse_tx_resource(struct mt76_dev *dev,
1797 struct sk_buff *skb)
1799 struct mt76_sdio *sdio = &dev->sdio;
1800 struct mt76_connac_tx_resource {
1802 __le32 pse_data_quota;
1803 __le32 pse_mcu_quota;
1804 __le32 ple_data_quota;
1805 __le32 ple_mcu_quota;
1806 __le16 pse_page_size;
1807 __le16 ple_page_size;
1810 } __packed * tx_res;
1812 tx_res = (struct mt76_connac_tx_resource *)skb->data;
1813 sdio->sched.pse_data_quota = le32_to_cpu(tx_res->pse_data_quota);
1814 sdio->sched.pse_mcu_quota = le32_to_cpu(tx_res->pse_mcu_quota);
1815 sdio->sched.ple_data_quota = le32_to_cpu(tx_res->ple_data_quota);
1816 sdio->sched.pse_page_size = le16_to_cpu(tx_res->pse_page_size);
1817 sdio->sched.deficit = tx_res->pp_padding;
1820 static void mt76_connac_mcu_parse_phy_cap(struct mt76_dev *dev,
1821 struct sk_buff *skb)
1823 struct mt76_connac_phy_cap {
1843 cap = (struct mt76_connac_phy_cap *)skb->data;
1845 dev->phy.antenna_mask = BIT(cap->nss) - 1;
1846 dev->phy.chainmask = dev->phy.antenna_mask;
1847 dev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G);
1848 dev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G);
1851 int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy)
1853 struct mt76_connac_cap_hdr {
1857 struct sk_buff *skb;
1860 ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CE_CMD(GET_NIC_CAPAB),
1861 NULL, 0, true, &skb);
1865 hdr = (struct mt76_connac_cap_hdr *)skb->data;
1866 if (skb->len < sizeof(*hdr)) {
1871 skb_pull(skb, sizeof(*hdr));
1873 for (i = 0; i < le16_to_cpu(hdr->n_element); i++) {
1877 } __packed * tlv = (struct tlv_hdr *)skb->data;
1880 if (skb->len < sizeof(*tlv))
1883 skb_pull(skb, sizeof(*tlv));
1885 len = le32_to_cpu(tlv->len);
1889 switch (le32_to_cpu(tlv->type)) {
1891 phy->cap.has_6ghz = skb->data[0];
1893 case MT_NIC_CAP_MAC_ADDR:
1894 memcpy(phy->macaddr, (void *)skb->data, ETH_ALEN);
1896 case MT_NIC_CAP_PHY:
1897 mt76_connac_mcu_parse_phy_cap(phy->dev, skb);
1899 case MT_NIC_CAP_TX_RESOURCE:
1900 if (mt76_is_sdio(phy->dev))
1901 mt76_connac_mcu_parse_tx_resource(phy->dev,
1914 EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability);
1917 mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
1918 struct mt76_power_limits *limits,
1919 enum nl80211_band band)
1921 int max_power = is_mt7921(dev) ? 127 : 63;
1922 int i, offset = sizeof(limits->cck);
1924 memset(sku, max_power, MT_SKU_POWER_LIMIT);
1926 if (band == NL80211_BAND_2GHZ) {
1928 memcpy(sku, limits->cck, sizeof(limits->cck));
1932 memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm));
1933 offset += sizeof(limits->ofdm);
1936 for (i = 0; i < 2; i++) {
1937 memcpy(&sku[offset], limits->mcs[i], 8);
1940 sku[offset++] = limits->mcs[0][0];
1943 for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) {
1944 memcpy(&sku[offset], limits->mcs[i],
1945 ARRAY_SIZE(limits->mcs[i]));
1949 if (!is_mt7921(dev))
1953 for (i = 0; i < ARRAY_SIZE(limits->ru); i++) {
1954 memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i]));
1955 offset += ARRAY_SIZE(limits->ru[i]);
1959 static s8 mt76_connac_get_ch_power(struct mt76_phy *phy,
1960 struct ieee80211_channel *chan,
1963 struct mt76_dev *dev = phy->dev;
1964 struct ieee80211_supported_band *sband;
1967 switch (chan->band) {
1968 case NL80211_BAND_2GHZ:
1969 sband = &phy->sband_2g.sband;
1971 case NL80211_BAND_5GHZ:
1972 sband = &phy->sband_5g.sband;
1974 case NL80211_BAND_6GHZ:
1975 sband = &phy->sband_6g.sband;
1978 return target_power;
1981 for (i = 0; i < sband->n_channels; i++) {
1982 struct ieee80211_channel *ch = &sband->channels[i];
1984 if (ch->hw_value == chan->hw_value) {
1985 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) {
1986 int power = 2 * ch->max_reg_power;
1988 if (is_mt7663(dev) && (power > 63 || power < -64))
1990 target_power = min_t(s8, power, target_power);
1996 return target_power;
2000 mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
2001 enum nl80211_band band)
2003 struct mt76_dev *dev = phy->dev;
2004 int sku_len, batch_len = is_mt7921(dev) ? 8 : 16;
2005 static const u8 chan_list_2ghz[] = {
2006 1, 2, 3, 4, 5, 6, 7,
2007 8, 9, 10, 11, 12, 13, 14
2009 static const u8 chan_list_5ghz[] = {
2010 36, 38, 40, 42, 44, 46, 48,
2011 50, 52, 54, 56, 58, 60, 62,
2012 64, 100, 102, 104, 106, 108, 110,
2013 112, 114, 116, 118, 120, 122, 124,
2014 126, 128, 132, 134, 136, 138, 140,
2015 142, 144, 149, 151, 153, 155, 157,
2018 static const u8 chan_list_6ghz[] = {
2019 1, 3, 5, 7, 9, 11, 13,
2020 15, 17, 19, 21, 23, 25, 27,
2021 29, 33, 35, 37, 39, 41, 43,
2022 45, 47, 49, 51, 53, 55, 57,
2023 59, 61, 65, 67, 69, 71, 73,
2024 75, 77, 79, 81, 83, 85, 87,
2025 89, 91, 93, 97, 99, 101, 103,
2026 105, 107, 109, 111, 113, 115, 117,
2027 119, 121, 123, 125, 129, 131, 133,
2028 135, 137, 139, 141, 143, 145, 147,
2029 149, 151, 153, 155, 157, 161, 163,
2030 165, 167, 169, 171, 173, 175, 177,
2031 179, 181, 183, 185, 187, 189, 193,
2032 195, 197, 199, 201, 203, 205, 207,
2033 209, 211, 213, 215, 217, 219, 221,
2036 int i, n_chan, batch_size, idx = 0, tx_power, last_ch;
2037 struct mt76_connac_sku_tlv sku_tlbv;
2038 struct mt76_power_limits limits;
2041 sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92;
2042 tx_power = 2 * phy->hw->conf.power_level;
2046 if (band == NL80211_BAND_2GHZ) {
2047 n_chan = ARRAY_SIZE(chan_list_2ghz);
2048 ch_list = chan_list_2ghz;
2049 } else if (band == NL80211_BAND_6GHZ) {
2050 n_chan = ARRAY_SIZE(chan_list_6ghz);
2051 ch_list = chan_list_6ghz;
2053 n_chan = ARRAY_SIZE(chan_list_5ghz);
2054 ch_list = chan_list_5ghz;
2056 batch_size = DIV_ROUND_UP(n_chan, batch_len);
2058 if (phy->cap.has_6ghz)
2059 last_ch = chan_list_6ghz[ARRAY_SIZE(chan_list_6ghz) - 1];
2060 else if (phy->cap.has_5ghz)
2061 last_ch = chan_list_5ghz[ARRAY_SIZE(chan_list_5ghz) - 1];
2063 last_ch = chan_list_2ghz[ARRAY_SIZE(chan_list_2ghz) - 1];
2065 for (i = 0; i < batch_size; i++) {
2066 struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {};
2067 int j, err, msg_len, num_ch;
2068 struct sk_buff *skb;
2070 num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len;
2071 msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv);
2072 skb = mt76_mcu_msg_alloc(dev, NULL, msg_len);
2076 skb_reserve(skb, sizeof(tx_power_tlv));
2078 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2));
2079 memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
2080 tx_power_tlv.n_chan = num_ch;
2083 case NL80211_BAND_2GHZ:
2084 tx_power_tlv.band = 1;
2086 case NL80211_BAND_6GHZ:
2087 tx_power_tlv.band = 3;
2090 tx_power_tlv.band = 2;
2094 for (j = 0; j < num_ch; j++, idx++) {
2095 struct ieee80211_channel chan = {
2096 .hw_value = ch_list[idx],
2099 s8 reg_power, sar_power;
2101 reg_power = mt76_connac_get_ch_power(phy, &chan,
2103 sar_power = mt76_get_sar_power(phy, &chan, reg_power);
2105 mt76_get_rate_power_limits(phy, &chan, &limits,
2108 tx_power_tlv.last_msg = ch_list[idx] == last_ch;
2109 sku_tlbv.channel = ch_list[idx];
2111 mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit,
2113 skb_put_data(skb, &sku_tlbv, sku_len);
2115 __skb_push(skb, sizeof(tx_power_tlv));
2116 memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
2118 err = mt76_mcu_skb_send_msg(dev, skb,
2119 MCU_CE_CMD(SET_RATE_TX_POWER),
2128 int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
2132 if (phy->cap.has_2ghz) {
2133 err = mt76_connac_mcu_rate_txpower_band(phy,
2138 if (phy->cap.has_5ghz) {
2139 err = mt76_connac_mcu_rate_txpower_band(phy,
2144 if (phy->cap.has_6ghz) {
2145 err = mt76_connac_mcu_rate_txpower_band(phy,
2153 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower);
2155 int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
2156 struct mt76_vif *vif,
2157 struct ieee80211_bss_conf *info)
2159 struct sk_buff *skb;
2160 int i, len = min_t(int, info->arp_addr_cnt,
2161 IEEE80211_BSS_ARP_ADDR_LIST_LEN);
2167 struct mt76_connac_arpns_tlv arp;
2170 .bss_idx = vif->idx,
2173 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2174 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2176 .mode = 2, /* update */
2181 skb = mt76_mcu_msg_alloc(dev, NULL,
2182 sizeof(req_hdr) + len * sizeof(__be32));
2186 skb_put_data(skb, &req_hdr, sizeof(req_hdr));
2187 for (i = 0; i < len; i++) {
2188 u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
2190 memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
2193 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true);
2195 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
2197 int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
2198 struct ieee80211_vif *vif)
2200 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2201 int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
2202 struct mt76_phy *phy = hw->priv;
2208 .ct_win = cpu_to_le32(ct_window),
2209 .bss_idx = mvif->idx,
2212 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS),
2213 &req, sizeof(req), false);
2215 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps);
2219 const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
2220 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
2221 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
2223 .pattern_min_len = 1,
2224 .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
2225 .max_nd_match_sets = 10,
2227 EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
2230 mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
2231 struct ieee80211_vif *vif,
2232 struct ieee80211_sta *sta,
2233 struct ieee80211_key_conf *key,
2236 struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
2239 if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
2240 key->cipher != WLAN_CIPHER_SUITE_CCMP &&
2241 key->cipher != WLAN_CIPHER_SUITE_TKIP)
2244 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
2249 /* we are assuming here to have a single pairwise key */
2250 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2251 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
2252 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
2254 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
2256 gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
2257 gtk_tlv->keyid = key->keyidx;
2259 gtk_tlv->group_cipher = cpu_to_le32(cipher);
2263 int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
2264 struct ieee80211_vif *vif,
2265 struct cfg80211_gtk_rekey_data *key)
2267 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2268 struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
2269 struct mt76_phy *phy = hw->priv;
2270 struct sk_buff *skb;
2275 .bss_idx = mvif->idx,
2278 skb = mt76_mcu_msg_alloc(phy->dev, NULL,
2279 sizeof(hdr) + sizeof(*gtk_tlv));
2283 skb_put_data(skb, &hdr, sizeof(hdr));
2284 gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb,
2286 gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
2287 gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
2288 gtk_tlv->rekey_mode = 2;
2289 gtk_tlv->option = 1;
2292 ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
2295 memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
2296 memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
2297 memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
2299 return mt76_mcu_skb_send_msg(phy->dev, skb,
2300 MCU_UNI_CMD(OFFLOAD), true);
2302 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
2305 mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
2308 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2314 struct mt76_connac_arpns_tlv arpns;
2317 .bss_idx = mvif->idx,
2320 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2321 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2326 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
2331 mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
2334 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2340 struct mt76_connac_gtk_rekey_tlv gtk_tlv;
2343 .bss_idx = mvif->idx,
2346 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
2347 .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
2348 .rekey_mode = !suspend,
2352 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
2357 mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
2358 struct ieee80211_vif *vif,
2359 bool enable, u8 mdtim,
2362 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2368 struct mt76_connac_suspend_tlv suspend_tlv;
2371 .bss_idx = mvif->idx,
2374 .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
2375 .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
2378 .wow_suspend = wow_suspend,
2382 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
2387 mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
2388 struct ieee80211_vif *vif,
2389 u8 index, bool enable,
2390 struct cfg80211_pkt_pattern *pattern)
2392 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2393 struct mt76_connac_wow_pattern_tlv *ptlv;
2394 struct sk_buff *skb;
2399 .bss_idx = mvif->idx,
2402 skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
2406 skb_put_data(skb, &hdr, sizeof(hdr));
2407 ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
2408 ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
2409 ptlv->len = cpu_to_le16(sizeof(*ptlv));
2410 ptlv->data_len = pattern->pattern_len;
2411 ptlv->enable = enable;
2412 ptlv->index = index;
2414 memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
2415 memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
2417 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true);
2421 mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
2422 bool suspend, struct cfg80211_wowlan *wowlan)
2424 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2425 struct mt76_dev *dev = phy->dev;
2431 struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
2432 struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
2435 .bss_idx = mvif->idx,
2438 .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
2439 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
2440 .cmd = suspend ? 1 : 2,
2443 .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
2444 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
2445 .gpio_pin = 0xff, /* follow fw about GPIO pin */
2449 if (wowlan->magic_pkt)
2450 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
2451 if (wowlan->disconnect)
2452 req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
2453 UNI_WOW_DETECT_TYPE_BCN_LOST);
2454 if (wowlan->nd_config) {
2455 mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
2456 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
2457 mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
2459 if (wowlan->n_patterns)
2460 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
2462 if (mt76_is_mmio(dev))
2463 req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
2464 else if (mt76_is_usb(dev))
2465 req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
2466 else if (mt76_is_sdio(dev))
2467 req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
2469 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
2473 int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
2477 u8 hif_type; /* 0x0: HIF_SDIO
2483 struct hif_suspend_tlv {
2487 } __packed hif_suspend;
2490 .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
2491 .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
2496 if (mt76_is_mmio(dev))
2497 req.hdr.hif_type = 2;
2498 else if (mt76_is_usb(dev))
2499 req.hdr.hif_type = 1;
2500 else if (mt76_is_sdio(dev))
2501 req.hdr.hif_type = 0;
2503 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req,
2506 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
2508 void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
2509 struct ieee80211_vif *vif)
2511 struct mt76_phy *phy = priv;
2512 bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state);
2513 struct ieee80211_hw *hw = phy->hw;
2514 struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
2517 mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
2518 mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
2520 mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
2522 for (i = 0; i < wowlan->n_patterns; i++)
2523 mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
2524 &wowlan->patterns[i]);
2525 mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
2527 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
2528 #endif /* CONFIG_PM */
2530 u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset)
2536 .addr = cpu_to_le32(offset),
2539 return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req,
2542 EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr);
2544 void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val)
2550 .addr = cpu_to_le32(offset),
2551 .val = cpu_to_le32(val),
2554 mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req,
2555 sizeof(req), false);
2557 EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr);
2560 mt76_connac_mcu_sta_key_tlv(struct mt76_connac_sta_key_conf *sta_key_conf,
2561 struct sk_buff *skb,
2562 struct ieee80211_key_conf *key,
2563 enum set_key_cmd cmd)
2565 struct sta_rec_sec *sec;
2566 u32 len = sizeof(*sec);
2569 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec));
2570 sec = (struct sta_rec_sec *)tlv;
2573 if (cmd == SET_KEY) {
2574 struct sec_key *sec_key;
2577 cipher = mt76_connac_mcu_get_cipher(key->cipher);
2578 if (cipher == MCU_CIPHER_NONE)
2581 sec_key = &sec->key[0];
2582 sec_key->cipher_len = sizeof(*sec_key);
2584 if (cipher == MCU_CIPHER_BIP_CMAC_128) {
2585 sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
2586 sec_key->key_id = sta_key_conf->keyidx;
2587 sec_key->key_len = 16;
2588 memcpy(sec_key->key, sta_key_conf->key, 16);
2590 sec_key = &sec->key[1];
2591 sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
2592 sec_key->cipher_len = sizeof(*sec_key);
2593 sec_key->key_len = 16;
2594 memcpy(sec_key->key, key->key, 16);
2597 sec_key->cipher_id = cipher;
2598 sec_key->key_id = key->keyidx;
2599 sec_key->key_len = key->keylen;
2600 memcpy(sec_key->key, key->key, key->keylen);
2602 if (cipher == MCU_CIPHER_TKIP) {
2603 /* Rx/Tx MIC keys are swapped */
2604 memcpy(sec_key->key + 16, key->key + 24, 8);
2605 memcpy(sec_key->key + 24, key->key + 16, 8);
2608 /* store key_conf for BIP batch update */
2609 if (cipher == MCU_CIPHER_AES_CCMP) {
2610 memcpy(sta_key_conf->key, key->key, key->keylen);
2611 sta_key_conf->keyidx = key->keyidx;
2614 len -= sizeof(*sec_key);
2618 len -= sizeof(sec->key);
2621 sec->len = cpu_to_le16(len);
2626 int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
2627 struct mt76_connac_sta_key_conf *sta_key_conf,
2628 struct ieee80211_key_conf *key, int mcu_cmd,
2629 struct mt76_wcid *wcid, enum set_key_cmd cmd)
2631 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2632 struct sk_buff *skb;
2635 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
2637 return PTR_ERR(skb);
2639 ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd);
2643 return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
2645 EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key);
2647 /* SIFS 20us + 512 byte beacon tranmitted by 1Mbps (3906us) */
2648 #define BCN_TX_ESTIMATE_TIME (4096 + 20)
2649 void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif)
2651 struct bss_info_ext_bss *ext;
2652 int ext_bss_idx, tsf_offset;
2655 ext_bss_idx = mvif->omac_idx - EXT_BSSID_START;
2656 if (ext_bss_idx < 0)
2659 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_EXT_BSS, sizeof(*ext));
2661 ext = (struct bss_info_ext_bss *)tlv;
2662 tsf_offset = ext_bss_idx * BCN_TX_ESTIMATE_TIME;
2663 ext->mbss_tsf_offset = cpu_to_le32(tsf_offset);
2665 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv);
2667 int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
2668 struct ieee80211_vif *vif,
2669 struct ieee80211_sta *sta,
2670 struct mt76_phy *phy, u16 wlan_idx,
2673 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2674 u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
2675 struct bss_info_basic *bss;
2678 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
2679 bss = (struct bss_info_basic *)tlv;
2681 switch (vif->type) {
2682 case NL80211_IFTYPE_MESH_POINT:
2683 case NL80211_IFTYPE_MONITOR:
2685 case NL80211_IFTYPE_AP:
2686 if (ieee80211_hw_check(phy->hw, SUPPORTS_MULTI_BSSID)) {
2687 u8 bssid_id = vif->bss_conf.bssid_indicator;
2689 bss->non_tx_bssid = vif->bss_conf.bssid_index;
2690 bss->max_bssid = bssid_id;
2693 case NL80211_IFTYPE_STATION:
2697 sta = ieee80211_find_sta(vif,
2698 vif->bss_conf.bssid);
2699 /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */
2701 struct mt76_wcid *wcid;
2703 wcid = (struct mt76_wcid *)sta->drv_priv;
2704 wlan_idx = wcid->idx;
2709 case NL80211_IFTYPE_ADHOC:
2710 type = NETWORK_IBSS;
2717 bss->network_type = cpu_to_le32(type);
2718 bss->bmc_wcid_lo = to_wcid_lo(wlan_idx);
2719 bss->bmc_wcid_hi = to_wcid_hi(wlan_idx);
2720 bss->wmm_idx = mvif->wmm_idx;
2721 bss->active = enable;
2722 bss->cipher = mvif->cipher;
2724 if (vif->type != NL80211_IFTYPE_MONITOR) {
2725 struct cfg80211_chan_def *chandef = &phy->chandef;
2727 memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);
2728 bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
2729 bss->dtim_period = vif->bss_conf.dtim_period;
2730 bss->phy_mode = mt76_connac_get_phy_mode(phy, vif,
2731 chandef->chan->band, NULL);
2733 memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
2738 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_basic_tlv);
2740 #define ENTER_PM_STATE 1
2741 #define EXIT_PM_STATE 2
2742 int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter)
2750 __le16 bcn_interval;
2763 .pm_state = enter ? ENTER_PM_STATE : EXIT_PM_STATE,
2767 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PM_STATE_CTRL), &req,
2770 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_pm);
2772 int mt76_connac_mcu_restart(struct mt76_dev *dev)
2781 return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req,
2782 sizeof(req), false);
2784 EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart);
2786 int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
2798 .rdd_rx_sel = rx_sel,
2802 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(SET_RDD_CTRL), &req,
2805 EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd);
2807 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
2808 MODULE_LICENSE("Dual BSD/GPL");