iwlwifi: mvm: location: set the HLTK when PASN station is added
authorAvraham Stern <avraham.stern@intel.com>
Wed, 30 Sep 2020 13:31:13 +0000 (16:31 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 1 Oct 2020 19:00:56 +0000 (22:00 +0300)
When a PASN station is added, set the HLTK to FW.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200930161256.1c7a59fd3164.I68005f0015ad04e53d0239e2d2ee85d5ffdeaa37@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

index e24e5bc7b40cfcba90bc06ae04f0ffcc87219ced..e940ef138f554e9c490141e4d44f452a5eaf6add 100644 (file)
@@ -306,6 +306,16 @@ iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm,
        return ret;
 }
 
+static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm,
+                                     struct ieee80211_vif *vif,
+                                     struct iwl_mvm_pasn_sta *sta)
+{
+       list_del(&sta->list);
+       iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id);
+       iwl_mvm_dealloc_int_sta(mvm, &sta->int_sta);
+       kfree(sta);
+}
+
 int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
                                      struct ieee80211_vif *vif,
                                      u8 *addr, u32 cipher, u8 *tk, u32 tk_len,
@@ -313,9 +323,26 @@ int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
 {
        int ret;
        struct iwl_mvm_pasn_sta *sta;
+       struct iwl_mvm_pasn_hltk_data hltk_data = {
+               .addr = addr,
+               .hltk = hltk,
+       };
+       u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP,
+                                          TOF_RESPONDER_DYN_CONFIG_CMD, 2);
 
        lockdep_assert_held(&mvm->mutex);
 
+       if (cmd_ver < 3) {
+               IWL_ERR(mvm, "Adding PASN station not supported by FW\n");
+               return -ENOTSUPP;
+       }
+
+       hltk_data.cipher = iwl_mvm_cipher_to_location_cipher(cipher);
+       if (hltk_data.cipher == IWL_LOCATION_CIPHER_INVALID) {
+               IWL_ERR(mvm, "invalid cipher: %u\n", cipher);
+               return -EINVAL;
+       }
+
        sta = kmalloc(sizeof(*sta), GFP_KERNEL);
        if (!sta)
                return -ENOBUFS;
@@ -327,23 +354,17 @@ int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
                return ret;
        }
 
-       // TODO: set the HLTK to fw
+       ret = iwl_mvm_ftm_responder_dyn_cfg_v3(mvm, vif, NULL, &hltk_data);
+       if (ret) {
+               iwl_mvm_resp_del_pasn_sta(mvm, vif, sta);
+               return ret;
+       }
 
        memcpy(sta->addr, addr, ETH_ALEN);
        list_add_tail(&sta->list, &mvm->resp_pasn_list);
        return 0;
 }
 
-static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm,
-                                     struct ieee80211_vif *vif,
-                                     struct iwl_mvm_pasn_sta *sta)
-{
-       list_del(&sta->list);
-       iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id);
-       iwl_mvm_dealloc_int_sta(mvm, &sta->int_sta);
-       kfree(sta);
-}
-
 int iwl_mvm_ftm_resp_remove_pasn_sta(struct iwl_mvm *mvm,
                                     struct ieee80211_vif *vif, u8 *addr)
 {
index ba1b74d105775770e69efffc25e86b300b4413d6..40e102f2017f256820baa37da4bc1704d76c1592 100644 (file)
@@ -2161,4 +2161,19 @@ static inline int iwl_umac_scan_get_max_profiles(const struct iwl_fw *fw)
        return (ver == IWL_FW_CMD_VER_UNKNOWN || ver < 3) ?
                IWL_SCAN_MAX_PROFILES : IWL_SCAN_MAX_PROFILES_V2;
 }
+
+static inline
+enum iwl_location_cipher iwl_mvm_cipher_to_location_cipher(u32 cipher)
+{
+       switch (cipher) {
+       case WLAN_CIPHER_SUITE_CCMP:
+               return IWL_LOCATION_CIPHER_CCMP_128;
+       case WLAN_CIPHER_SUITE_GCMP:
+               return IWL_LOCATION_CIPHER_GCMP_128;
+       case WLAN_CIPHER_SUITE_GCMP_256:
+               return IWL_LOCATION_CIPHER_GCMP_256;
+       default:
+               return IWL_LOCATION_CIPHER_INVALID;
+       }
+}
 #endif /* __IWL_MVM_H__ */