From: Avraham Stern <avraham.stern@xxxxxxxxx> When a PASN station is added, set the HLTK to FW. Signed-off-by: Avraham Stern <avraham.stern@xxxxxxxxx> Signed-off-by: Luca Coelho <luciano.coelho@xxxxxxxxx> --- .../intel/iwlwifi/mvm/ftm-responder.c | 43 ++++++++++++++----- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 15 +++++++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c index e24e5bc7b40c..e940ef138f55 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c @@ -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) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ba1b74d10577..40e102f2017f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -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__ */ -- 2.28.0