diff options
author | Karthikeyan Kathirvel <karthikeyan.kathirvel@oss.qualcomm.com> | 2025-06-04 15:46:20 +0530 |
---|---|---|
committer | Jeff Johnson <jeff.johnson@oss.qualcomm.com> | 2025-07-10 07:29:45 -0700 |
commit | 27ba973caaf85ff3a2a23eca33d6dc9b4fe405e8 (patch) | |
tree | b7326cc598587af3dfdbf329670d24bd946bad50 | |
parent | 0424cc3d70f6bd72e6501c730b1f95ba966e2ee9 (diff) |
wifi: ath12k: allow beacon protection keys to be installed in hardware
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>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250604101620.2948103-1-karthikeyan.kathirvel@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
-rw-r--r-- | drivers/net/wireless/ath/ath12k/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/mac.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/wmi.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/wmi.h | 5 |
4 files changed, 48 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index afc8329980c8..042d6bcd1c6e 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -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; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 42eb9e8e14d1..5333da9cac1b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1496,11 +1496,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; @@ -1518,6 +1520,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; @@ -1560,6 +1567,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)) { @@ -1608,11 +1628,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); @@ -1681,9 +1701,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) @@ -5305,6 +5325,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; @@ -5599,13 +5629,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; @@ -13809,6 +13835,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); diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index b34f2c183312..a6379f19be2c 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -2016,6 +2016,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); diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index ed9b4324a7b8..eeea9a22d93b 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2241,6 +2241,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, @@ -3755,6 +3756,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; @@ -4723,7 +4726,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 { |