wifi: iwlwifi: mvm: enable TX beacon protection
authorJohannes Berg <johannes.berg@intel.com>
Mon, 20 Mar 2023 10:33:06 +0000 (12:33 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 22 Mar 2023 12:16:35 +0000 (13:16 +0100)
Check hardware/firmware support and enable TX beacon protection
as well if supported, programming the key into the firmware as
usual.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230320122330.6a90a4f4f469.Ia028dea75f9a8eed40786d876d51f97fb3142688@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

index 1c47046e8f69e977a218495fe25d05fc9adb72d6..f2eefca6e260ba6fce942d22c8165a2ea735b884 100644 (file)
@@ -457,6 +457,7 @@ enum iwl_ucode_tlv_capa {
        IWL_UCODE_TLV_CAPA_DUMP_COMPLETE_SUPPORT        = (__force iwl_ucode_tlv_capa_t)105,
        IWL_UCODE_TLV_CAPA_SYNCED_TIME                  = (__force iwl_ucode_tlv_capa_t)106,
        IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM        = (__force iwl_ucode_tlv_capa_t)108,
+       IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT             = (__force iwl_ucode_tlv_capa_t)109,
 
 #ifdef __CHECKER__
        /* sparse says it cannot increment the previous enum member */
index 7ee8d24606a2bdc87aeb7a42d85eee5e83910b33..99a51d5192147261625a0fd2755fc64eb5905455 100644 (file)
@@ -280,6 +280,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
        bool unified = fw_has_capa(&mvm->fw->ucode_capa,
                                   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 #endif
+       u32 sec_key_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
+       u8 sec_key_ver = iwl_fw_lookup_cmd_ver(mvm->fw, sec_key_id, 0);
 
        /* Tell mac80211 our characteristics */
        ieee80211_hw_set(hw, SIGNAL_DBM);
@@ -404,8 +406,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                hw->wiphy->pmsr_capa = &iwl_mvm_pmsr_capa;
        }
 
-       if (fw_has_capa(&mvm->fw->ucode_capa,
-                       IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT))
+       if (sec_key_ver &&
+           fw_has_capa(&mvm->fw->ucode_capa,
+                       IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT))
+               wiphy_ext_feature_set(hw->wiphy,
+                                     NL80211_EXT_FEATURE_BEACON_PROTECTION);
+       else if (fw_has_capa(&mvm->fw->ucode_capa,
+                            IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT))
                wiphy_ext_feature_set(hw->wiphy,
                                      NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT);
 
@@ -3778,7 +3785,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
 
        switch (cmd) {
        case SET_KEY:
-               if (keyidx == 6 || keyidx == 7)
+               if (vif->type == NL80211_IFTYPE_STATION &&
+                   (keyidx == 6 || keyidx == 7))
                        rcu_assign_pointer(mvmvif->bcn_prot.keys[keyidx - 6],
                                           key);
 
@@ -3789,10 +3797,14 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
                         * on IBSS they're per-station and because we're lazy
                         * we don't support them for RX, so do the same.
                         * CMAC/GMAC in AP/IBSS modes must be done in software.
+                        *
+                        * Except, of course, beacon protection - it must be
+                        * offloaded since we just set a beacon template.
                         */
-                       if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
-                           key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
-                           key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) {
+                       if (keyidx < 6 &&
+                           (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+                            key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
+                            key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)) {
                                ret = -EOPNOTSUPP;
                                break;
                        }
@@ -3873,7 +3885,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
                if (mvmsta && key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
                        mvmsta->pairwise_cipher = key->cipher;
 
-               IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
+               IWL_DEBUG_MAC80211(mvm, "set hwcrypto key (sta:%pM, id:%d)\n",
+                                  sta ? sta->addr : NULL, key->keyidx);
 
                if (sec_key_ver)
                        ret = iwl_mvm_sec_key_add(mvm, vif, sta, key);
@@ -3897,7 +3910,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
 
                break;
        case DISABLE_KEY:
-               if (keyidx == 6 || keyidx == 7)
+               if (vif->type == NL80211_IFTYPE_STATION &&
+                   (keyidx == 6 || keyidx == 7))
                        RCU_INIT_POINTER(mvmvif->bcn_prot.keys[keyidx - 6],
                                         NULL);