diff options
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 3 |
5 files changed, 34 insertions, 14 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c index 8f10590f9cdd..f72ca38d7c0e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c @@ -12,6 +12,9 @@ struct iwl_mvm_pasn_sta { struct list_head list; struct iwl_mvm_int_sta int_sta; u8 addr[ETH_ALEN]; + + /* must be last as it followed by buffer holding the key */ + struct ieee80211_key_conf keyconf; }; struct iwl_mvm_pasn_hltk_data { @@ -303,6 +306,10 @@ static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm, { list_del(&sta->list); + if (sta->keyconf.keylen) + iwl_mvm_sec_key_del_pasn(mvm, vif, BIT(sta->int_sta.sta_id), + &sta->keyconf); + if (iwl_mvm_has_mld_api(mvm->fw)) iwl_mvm_mld_rm_sta_id(mvm, sta->int_sta.sta_id); else @@ -352,12 +359,12 @@ int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm, } if (tk && tk_len) { - sta = kzalloc(sizeof(*sta), GFP_KERNEL); + sta = kzalloc(sizeof(*sta) + tk_len, GFP_KERNEL); if (!sta) return -ENOBUFS; ret = iwl_mvm_add_pasn_sta(mvm, vif, &sta->int_sta, addr, - cipher, tk, tk_len); + cipher, tk, tk_len, &sta->keyconf); if (ret) { kfree(sta); return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c index ea3e9e9c6e26..a1ce08a5527c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c @@ -335,6 +335,21 @@ static int _iwl_mvm_sec_key_del(struct iwl_mvm *mvm, return ret; } +int iwl_mvm_sec_key_del_pasn(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + u32 sta_mask, + struct ieee80211_key_conf *keyconf) +{ + u32 key_flags = iwl_mvm_get_sec_flags(mvm, vif, NULL, keyconf) | + IWL_SEC_KEY_FLAG_MFP; + + if (WARN_ON(!sta_mask)) + return -EINVAL; + + return __iwl_mvm_sec_key_del(mvm, sta_mask, key_flags, keyconf->keyidx, + 0); +} + int iwl_mvm_sec_key_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 9a89b91519db..e148ef02ff73 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2402,6 +2402,10 @@ int iwl_mvm_sec_key_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *keyconf); +int iwl_mvm_sec_key_del_pasn(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + u32 sta_mask, + struct ieee80211_key_conf *keyconf); void iwl_mvm_sec_key_remove_ap(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_vif_link_info *link, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 2a3ca9785974..d57fcbe4f8ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -4298,12 +4298,12 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data) int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_int_sta *sta, u8 *addr, u32 cipher, - u8 *key, u32 key_len) + u8 *key, u32 key_len, + struct ieee80211_key_conf *keyconf) { int ret; u16 queue; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct ieee80211_key_conf *keyconf; unsigned int wdg_timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false); bool mld = iwl_mvm_has_mld_api(mvm->fw); @@ -4328,12 +4328,6 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (ret) goto out; - keyconf = kzalloc(sizeof(*keyconf) + key_len, GFP_KERNEL); - if (!keyconf) { - ret = -ENOBUFS; - goto out; - } - keyconf->cipher = cipher; memcpy(keyconf->key, key, key_len); keyconf->keylen = key_len; @@ -4354,10 +4348,9 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 0, NULL, 0, 0, true); } - kfree(keyconf); - return 0; out: - iwl_mvm_dealloc_int_sta(mvm, sta); + if (ret) + iwl_mvm_dealloc_int_sta(mvm, sta); return ret; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index b33a0ce096d4..4668f413abd3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -574,7 +574,8 @@ void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk); int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_int_sta *sta, u8 *addr, u32 cipher, - u8 *key, u32 key_len); + u8 *key, u32 key_len, + struct ieee80211_key_conf *key_conf_out); void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 id); |