]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: allow beacon protection keys to be installed in hardware
authorKarthikeyan Kathirvel <karthikeyan.kathirvel@oss.qualcomm.com>
Wed, 4 Jun 2025 10:16:20 +0000 (15:46 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 10 Jul 2025 14:29:45 +0000 (07:29 -0700)
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>
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/wmi.c
drivers/net/wireless/ath/ath12k/wmi.h

index afc8329980c8cc9a684787c2121c74d5e1146d39..042d6bcd1c6ea84f3bb74328266514b10a41a7d2 100644 (file)
@@ -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;
index 42eb9e8e14d1361c7bf0148467b78d65128496a6..5333da9cac1b2cae4a71c975bf927de8182c357b 100644 (file)
@@ -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);
 
index b34f2c1833126cc37d4125eed793aa9efc3e4460..a6379f19be2caba707862fb367e922c7aeb22c22 100644 (file)
@@ -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);
 
index ed9b4324a7b87ad31a79b2decebbe7c164496692..eeea9a22d93bba9d0ab55e1aaf9ed7b4ba48e0f7 100644 (file)
@@ -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 {