@@ -316,6 +316,7 @@ struct ath12k_link_vif {
int bank_id;
u8 vdev_id_check_en;
+ bool beacon_prot;
struct wmi_wmm_params_all_arg wmm_params;
struct list_head list;
@@ -1454,11 +1454,13 @@ static int ath12k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
return 0;
}
-static void ath12k_mac_set_arvif_ies(struct ath12k_link_vif *arvif, struct sk_buff *bcn,
+static void ath12k_mac_set_arvif_ies(struct ath12k_link_vif *arvif,
+ struct ath12k_link_vif *tx_arvif,
+ struct sk_buff *bcn,
u8 bssid_index, bool *nontx_profile_found)
{
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)bcn->data;
- const struct element *elem, *nontx, *index, *nie;
+ const struct element *elem, *nontx, *index, *nie, *ext_cap_ie;
const u8 *start, *tail;
u16 rem_len;
u8 i;
@@ -1476,6 +1478,11 @@ static void ath12k_mac_set_arvif_ies(struct ath12k_link_vif *arvif, struct sk_bu
start, rem_len))
arvif->wpaie_present = true;
+ ext_cap_ie = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, start, rem_len);
+ if (ext_cap_ie && ext_cap_ie->datalen >= 11 &&
+ (ext_cap_ie->data[10] & WLAN_EXT_CAPA11_BCN_PROTECT))
+ tx_arvif->beacon_prot = true;
+
/* Return from here for the transmitted profile */
if (!bssid_index)
return;
@@ -1518,6 +1525,19 @@ static void ath12k_mac_set_arvif_ies(struct ath12k_link_vif *arvif, struct sk_bu
if (index->data[0] == bssid_index) {
*nontx_profile_found = true;
+
+ /* Check if nontx BSS has beacon protection enabled */
+ if (!tx_arvif->beacon_prot) {
+ ext_cap_ie =
+ cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
+ nontx->data,
+ nontx->datalen);
+ if (ext_cap_ie && ext_cap_ie->datalen >= 11 &&
+ (ext_cap_ie->data[10] &
+ WLAN_EXT_CAPA11_BCN_PROTECT))
+ tx_arvif->beacon_prot = true;
+ }
+
if (cfg80211_find_ie(WLAN_EID_RSN,
nontx->data,
nontx->datalen)) {
@@ -1566,11 +1586,11 @@ static int ath12k_mac_setup_bcn_tmpl_ema(struct ath12k_link_vif *arvif,
}
if (tx_arvif == arvif)
- ath12k_mac_set_arvif_ies(arvif, beacons->bcn[0].skb, 0, NULL);
+ ath12k_mac_set_arvif_ies(arvif, tx_arvif, beacons->bcn[0].skb, 0, NULL);
for (i = 0; i < beacons->cnt; i++) {
if (tx_arvif != arvif && !nontx_profile_found)
- ath12k_mac_set_arvif_ies(arvif, beacons->bcn[i].skb,
+ ath12k_mac_set_arvif_ies(arvif, tx_arvif, beacons->bcn[i].skb,
bssid_index,
&nontx_profile_found);
@@ -1639,9 +1659,9 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_link_vif *arvif)
}
if (tx_arvif == arvif) {
- ath12k_mac_set_arvif_ies(arvif, bcn, 0, NULL);
+ ath12k_mac_set_arvif_ies(arvif, tx_arvif, bcn, 0, NULL);
} else {
- ath12k_mac_set_arvif_ies(arvif, bcn,
+ ath12k_mac_set_arvif_ies(arvif, tx_arvif, bcn,
link_conf->bssid_index,
&nontx_profile_found);
if (!nontx_profile_found)
@@ -4766,6 +4786,16 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
arg.key_cipher = WMI_CIPHER_AES_GCM;
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ arg.key_cipher = WMI_CIPHER_AES_CMAC;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ arg.key_cipher = WMI_CIPHER_AES_GMAC;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ arg.key_cipher = WMI_CIPHER_AES_CMAC;
+ break;
default:
ath12k_warn(ar->ab, "cipher %d is not supported\n", key->cipher);
return -EOPNOTSUPP;
@@ -4997,13 +5027,9 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
lockdep_assert_wiphy(hw->wiphy);
- /* BIP needs to be done in software */
- if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
- key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
- key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
- key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) {
+ /* IGTK needs to be done in host software */
+ if (key->keyidx == 4 || key->keyidx == 5)
return 1;
- }
if (key->keyidx > WMI_MAX_KEY_INDEX)
return -ENOSPC;
@@ -12089,6 +12115,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
}
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PUNCT);
+ if (test_bit(WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT, ab->wmi_ab.svc_map))
+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
ath12k_reg_init(hw);
@@ -2008,6 +2008,9 @@ int ath12k_wmi_bcn_tmpl(struct ath12k_link_vif *arvif,
u32p_replace_bits(&ema_params, 1, WMI_EMA_BEACON_LAST);
cmd->ema_params = cpu_to_le32(ema_params);
}
+ cmd->feature_enable_bitmap =
+ cpu_to_le32(u32_encode_bits(arvif->beacon_prot,
+ WMI_BEACON_PROTECTION_EN_BIT));
ptr = skb->data + sizeof(*cmd);
@@ -2216,6 +2216,7 @@ enum wmi_tlv_service {
WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET = 213,
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
WMI_TLV_SERVICE_EXT2_MSG = 220,
+ WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT = 244,
WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253,
WMI_MAX_EXT_SERVICE = 256,
@@ -3689,6 +3690,8 @@ struct ath12k_wmi_ftm_event {
#define WMI_EMA_BEACON_FIRST GENMASK(23, 16)
#define WMI_EMA_BEACON_LAST GENMASK(31, 24)
+#define WMI_BEACON_PROTECTION_EN_BIT BIT(0)
+
struct ath12k_wmi_bcn_tmpl_ema_arg {
u8 bcn_cnt;
u8 bcn_index;
@@ -4656,7 +4659,7 @@ enum wmi_ap_ps_peer_param {
#define DISABLE_SIFS_RESPONSE_TRIGGER 0
-#define WMI_MAX_KEY_INDEX 3
+#define WMI_MAX_KEY_INDEX 7
#define WMI_MAX_KEY_LEN 32
enum wmi_key_type {
Install beacon protection keys in hardware for AP modes only if hardware supports it, as indicated by the WMI service bit WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT. Allow keyidx up to 7, since beacon protection uses keyidx 6 and 7. Control this feature by setting bit 0 of feature_enable_bitmap when sending the WMI_BCN_TMPL_CMDID command to firmware. Check for the beacon protection enabled bit in both tx and non-tx profiles for MBSSID cases. If set in either profile, enable the beacon protection feature in firmware for transmitted vif. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Kathirvel <karthikeyan.kathirvel@oss.qualcomm.com> --- v2: - IGTK hardware offload is not working because a firmware bug that gets triggered during IGTK key installation, which leads to corruption of the GTK keys in firmware. So as of now relying on software crypto till firmware fixes available in uptream - Made alignment fix --- drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/mac.c | 52 ++++++++++++++++++++------ drivers/net/wireless/ath/ath12k/wmi.c | 3 ++ drivers/net/wireless/ath/ath12k/wmi.h | 5 ++- 4 files changed, 48 insertions(+), 13 deletions(-) base-commit: c3910de7bab78afbc106206aed5ec8e79458fbee