MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
}
+int mt7996_mcu_set_protection(struct mt7996_phy *phy, struct mt7996_vif_link *link,
+ u8 ht_mode, bool use_cts_prot)
+{
+ struct mt7996_dev *dev = phy->dev;
+ struct bss_prot_tlv *prot;
+ struct sk_buff *skb;
+ struct tlv *tlv;
+ enum {
+ PROT_NONMEMBER = BIT(1),
+ PROT_20MHZ = BIT(2),
+ PROT_NONHT_MIXED = BIT(3),
+ PROT_LEGACY_ERP = BIT(5),
+ PROT_NONGF_STA = BIT(7),
+ };
+
+ skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &link->mt76,
+ MT7996_BSS_UPDATE_MAX_SIZE);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_PROTECT_INFO,
+ sizeof(*prot));
+ prot = (struct bss_prot_tlv *)tlv;
+
+ switch (ht_mode & IEEE80211_HT_OP_MODE_PROTECTION) {
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+ prot->prot_mode = cpu_to_le32(PROT_NONMEMBER);
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+ prot->prot_mode = cpu_to_le32(PROT_20MHZ);
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+ prot->prot_mode = cpu_to_le32(PROT_NONHT_MIXED);
+ break;
+ }
+
+ if (ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
+ prot->prot_mode |= cpu_to_le32(PROT_NONGF_STA);
+
+ if (use_cts_prot)
+ prot->prot_mode |= cpu_to_le32(PROT_LEGACY_ERP);
+
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_WM_UNI_CMD(BSS_INFO_UPDATE), true);
+}
+
int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
{
const struct mt7996_dfs_pattern *pattern);
int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
+int mt7996_mcu_set_protection(struct mt7996_phy *phy, struct mt7996_vif_link *link,
+ u8 ht_mode, bool use_cts_prot);
int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf);
int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);