summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/sta.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 5469d634e289..ff1ce990a9d8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2015, 2018-2022 Intel Corporation
+ * Copyright (C) 2012-2015, 2018-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -281,7 +281,7 @@ static void iwl_mvm_rx_agg_session_expired(struct timer_list *t)
* A-MDPU and hence the timer continues to run. Then, the
* timer expires and sta is NULL.
*/
- if (!sta)
+ if (IS_ERR_OR_NULL(sta))
goto unlock;
mvm_sta = iwl_mvm_sta_from_mac80211(sta);
@@ -1679,7 +1679,7 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
memset(&cmd, 0, sizeof(cmd));
cmd.sta_id = sta->sta_id;
- if (iwl_fw_lookup_cmd_ver(mvm->fw, ADD_STA, 0) >= 12 &&
+ if (iwl_mvm_has_new_station_api(mvm->fw) &&
sta->type == IWL_STA_AUX_ACTIVITY)
cmd.mac_id_n_color = cpu_to_le32(mac_id);
else
@@ -1859,6 +1859,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
ret = iwl_mvm_sta_init(mvm, vif, sta, sta_id,
sta->tdls ? IWL_STA_TDLS_LINK : IWL_STA_LINK);
+ if (ret)
+ goto err;
update_fw:
ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags);
@@ -2070,13 +2072,6 @@ bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
cancel_delayed_work(&mvm->tdls_cs.dwork);
}
- /*
- * Make sure that the tx response code sees the station as -EBUSY and
- * calls the drain worker.
- */
- spin_lock_bh(&mvm_sta->lock);
- spin_unlock_bh(&mvm_sta->lock);
-
return false;
}
@@ -2089,9 +2084,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex);
- if (iwl_mvm_has_new_rx_api(mvm))
- kfree(mvm_sta->dup_data);
-
ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
if (ret)
return ret;
@@ -3785,6 +3777,9 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
u8 sta_id = mvmvif->deflink.ap_sta_id;
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
lockdep_is_held(&mvm->mutex));
+ if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
+ return NULL;
+
return sta->addr;
}
@@ -3822,6 +3817,11 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
if (keyconf->cipher == WLAN_CIPHER_SUITE_TKIP) {
addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
+ if (!addr) {
+ IWL_ERR(mvm, "Failed to find mac address\n");
+ return -EINVAL;
+ }
+
/* get phase 1 key from mac80211 */
ieee80211_get_key_rx_seq(keyconf, 0, &seq);
ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
@@ -4301,16 +4301,27 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
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);
+ u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK;
ret = iwl_mvm_allocate_int_sta(mvm, sta, 0,
- NL80211_IFTYPE_UNSPECIFIED,
- IWL_STA_LINK);
+ NL80211_IFTYPE_UNSPECIFIED, type);
if (ret)
return ret;
- ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, mvmvif->color,
- addr, sta, &queue,
- IWL_MVM_TX_FIFO_BE);
+ if (mld)
+ ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, sta, addr,
+ mvmvif->deflink.fw_link_id,
+ &queue,
+ IWL_MAX_TID_COUNT,
+ &wdg_timeout);
+ else
+ ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id,
+ mvmvif->color, addr, sta,
+ &queue,
+ IWL_MVM_TX_FIFO_BE);
if (ret)
goto out;
@@ -4323,9 +4334,23 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
keyconf->cipher = cipher;
memcpy(keyconf->key, key, key_len);
keyconf->keylen = key_len;
+ keyconf->flags = IEEE80211_KEY_FLAG_PAIRWISE;
+
+ if (mld) {
+ /* The MFP flag is set according to the station mfp field. Since
+ * we don't have a station, set it manually.
+ */
+ u32 key_flags =
+ iwl_mvm_get_sec_flags(mvm, vif, NULL, keyconf) |
+ IWL_SEC_KEY_FLAG_MFP;
+ u32 sta_mask = BIT(sta->sta_id);
+
+ ret = iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf);
+ } else {
+ ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
+ 0, NULL, 0, 0, true);
+ }
- ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
- 0, NULL, 0, 0, true);
kfree(keyconf);
return 0;
out:
@@ -4335,10 +4360,10 @@ out:
void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- u32 mac_id)
+ u32 id)
{
struct iwl_cancel_channel_switch_cmd cancel_channel_switch_cmd = {
- .mac_id = cpu_to_le32(mac_id),
+ .id = cpu_to_le32(id),
};
int ret;