summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c138
1 files changed, 39 insertions, 99 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
index 1b6fb73ddfc7..83f6e508a094 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2024 Intel Corporation
*/
#include <net/cfg80211.h>
#include <linux/etherdevice.h>
@@ -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 {
@@ -39,7 +42,7 @@ static int iwl_mvm_ftm_responder_set_bw_v1(struct cfg80211_chan_def *chandef,
*ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef);
break;
default:
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
return 0;
@@ -77,7 +80,7 @@ static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef,
}
fallthrough;
default:
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
return 0;
@@ -85,7 +88,7 @@ static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef,
static void
iwl_mvm_ftm_responder_set_ndp(struct iwl_mvm *mvm,
- struct iwl_tof_responder_config_cmd_v9 *cmd)
+ struct iwl_tof_responder_config_cmd *cmd)
{
/* Up to 2 R2I STS are allowed on the responder */
u32 r2i_max_sts = IWL_MVM_FTM_R2I_MAX_STS < 2 ?
@@ -104,7 +107,8 @@ iwl_mvm_ftm_responder_set_ndp(struct iwl_mvm *mvm,
static int
iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- struct cfg80211_chan_def *chandef)
+ struct cfg80211_chan_def *chandef,
+ struct ieee80211_bss_conf *link_conf)
{
u32 cmd_id = WIDE_ID(LOCATION_GROUP, TOF_RESPONDER_CONFIG_CMD);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -113,13 +117,13 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
* field interpretation is different), so the same struct can be use
* for all cases.
*/
- struct iwl_tof_responder_config_cmd_v9 cmd = {
+ struct iwl_tof_responder_config_cmd cmd = {
.channel_num = chandef->chan->hw_value,
.cmd_valid_fields =
cpu_to_le32(IWL_TOF_RESPONDER_CMD_VALID_CHAN_INFO |
IWL_TOF_RESPONDER_CMD_VALID_BSSID |
IWL_TOF_RESPONDER_CMD_VALID_STA_ID),
- .sta_id = mvmvif->deflink.bcast_sta.sta_id,
+ .sta_id = mvmvif->link[link_conf->link_id]->bcast_sta.sta_id,
};
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 6);
int err;
@@ -127,8 +131,13 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex);
+ if (cmd_ver >= 10) {
+ cmd.band =
+ iwl_mvm_phy_band_from_nl80211(chandef->chan->band);
+ }
+
/* Use a default of bss_color=1 for now */
- if (cmd_ver == 9) {
+ if (cmd_ver >= 9) {
cmd.cmd_valid_fields |=
cpu_to_le32(IWL_TOF_RESPONDER_CMD_VALID_BSS_COLOR |
IWL_TOF_RESPONDER_CMD_VALID_MIN_MAX_TIME_BETWEEN_MSR);
@@ -144,7 +153,7 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
}
if (cmd_ver >= 8)
- iwl_mvm_ftm_responder_set_ndp(mvm, &cmd);
+ iwl_mvm_ftm_responder_set_ndp(mvm, (void *)&cmd);
if (cmd_ver >= 7)
err = iwl_mvm_ftm_responder_set_bw_v2(chandef, &cmd.format_bw,
@@ -290,7 +299,7 @@ iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm,
default:
IWL_ERR(mvm, "Unsupported DYN_CONFIG_CMD version %u\n",
cmd_ver);
- ret = -ENOTSUPP;
+ ret = -EOPNOTSUPP;
}
return ret;
@@ -301,92 +310,22 @@ static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm,
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,
- u8 *hltk, u32 hltk_len)
-{
- int ret;
- struct iwl_mvm_pasn_sta *sta = NULL;
- struct iwl_mvm_pasn_hltk_data hltk_data = {
- .addr = addr,
- .hltk = hltk,
- };
- struct iwl_mvm_pasn_hltk_data *hltk_data_ptr = NULL;
-
- u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
- WIDE_ID(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;
- }
-
- if ((!hltk || !hltk_len) && (!tk || !tk_len)) {
- IWL_ERR(mvm, "TK and HLTK not set\n");
- return -EINVAL;
- }
- if (hltk && hltk_len) {
- 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;
- }
+ if (sta->keyconf.keylen)
+ iwl_mvm_sec_key_del_pasn(mvm, vif, BIT(sta->int_sta.sta_id),
+ &sta->keyconf);
- hltk_data_ptr = &hltk_data;
- }
-
- if (tk && tk_len) {
- sta = kzalloc(sizeof(*sta), GFP_KERNEL);
- if (!sta)
- return -ENOBUFS;
-
- ret = iwl_mvm_add_pasn_sta(mvm, vif, &sta->int_sta, addr,
- cipher, tk, tk_len);
- if (ret) {
- kfree(sta);
- return ret;
- }
-
- memcpy(sta->addr, addr, ETH_ALEN);
- list_add_tail(&sta->list, &mvm->resp_pasn_list);
- }
-
- ret = iwl_mvm_ftm_responder_dyn_cfg_v3(mvm, vif, NULL, hltk_data_ptr);
- if (ret && sta)
- iwl_mvm_resp_del_pasn_sta(mvm, vif, sta);
-
- return ret;
-}
-
-int iwl_mvm_ftm_resp_remove_pasn_sta(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif, u8 *addr)
-{
- struct iwl_mvm_pasn_sta *sta, *prev;
-
- lockdep_assert_held(&mvm->mutex);
-
- list_for_each_entry_safe(sta, prev, &mvm->resp_pasn_list, list) {
- if (!memcmp(sta->addr, addr, ETH_ALEN)) {
- iwl_mvm_resp_del_pasn_sta(mvm, vif, sta);
- return 0;
- }
- }
+ if (iwl_mvm_has_mld_api(mvm->fw))
+ iwl_mvm_mld_rm_sta_id(mvm, sta->int_sta.sta_id);
+ else
+ iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id);
- IWL_ERR(mvm, "FTM: PASN station %pM not found\n", addr);
- return -EINVAL;
+ iwl_mvm_dealloc_int_sta(mvm, &sta->int_sta);
+ kfree(sta);
}
-int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_ftm_responder_params *params;
@@ -395,11 +334,11 @@ int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
struct iwl_mvm_phy_ctxt *phy_ctxt;
int ret;
- params = vif->bss_conf.ftmr_params;
+ params = bss_conf->ftmr_params;
lockdep_assert_held(&mvm->mutex);
- if (WARN_ON_ONCE(!vif->bss_conf.ftm_responder))
+ if (WARN_ON_ONCE(!bss_conf->ftm_responder))
return -EINVAL;
if (vif->p2p || vif->type != NL80211_IFTYPE_AP ||
@@ -409,7 +348,7 @@ int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
}
rcu_read_lock();
- pctx = rcu_dereference(vif->bss_conf.chanctx_conf);
+ pctx = rcu_dereference(bss_conf->chanctx_conf);
/* Copy the ctx to unlock the rcu and send the phy ctxt. We don't care
* about changes in the ctx after releasing the lock because the driver
* is still protected by the mutex. */
@@ -418,13 +357,13 @@ int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
rcu_read_unlock();
phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
- ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def,
+ ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def, &ctx.ap,
ctx.rx_chains_static,
ctx.rx_chains_dynamic);
if (ret)
return ret;
- ret = iwl_mvm_ftm_responder_cmd(mvm, vif, &ctx.def);
+ ret = iwl_mvm_ftm_responder_cmd(mvm, vif, &ctx.def, bss_conf);
if (ret)
return ret;
@@ -446,13 +385,14 @@ void iwl_mvm_ftm_responder_clear(struct iwl_mvm *mvm,
}
void iwl_mvm_ftm_restart_responder(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf)
{
- if (!vif->bss_conf.ftm_responder)
+ if (!bss_conf->ftm_responder)
return;
iwl_mvm_ftm_responder_clear(mvm, vif);
- iwl_mvm_ftm_start_responder(mvm, vif);
+ iwl_mvm_ftm_start_responder(mvm, vif, bss_conf);
}
void iwl_mvm_ftm_responder_stats(struct iwl_mvm *mvm,