summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>2023-10-17 12:16:37 +0300
committerJohannes Berg <johannes.berg@intel.com>2023-10-23 13:48:27 +0300
commit1350658373106eace418eea673a058a0285f8334 (patch)
tree175b4bf92f4295f72a14676e34fa62d5ecf79f4f
parent236730413d5f71b6f224f1f6ca6ccba05a4d9107 (diff)
downloadlinux-1350658373106eace418eea673a058a0285f8334.tar.xz
wifi: iwlwifi: support link_id in SESSION_PROTECTION cmd
FW is introducing an API change in which link ID will be used for session protection cmd. Add support for it. Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20231017115047.a3cb29ed0617.I85b8a85b0d9186d3dd4d704254e46775b0ccf7de@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/time-event.c78
2 files changed, 64 insertions, 25 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
index f0d4056199a7..701b2929c3a4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018-2020, 2022 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2020, 2022-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -432,8 +432,8 @@ enum iwl_mvm_session_prot_conf_id {
/**
* struct iwl_mvm_session_prot_cmd - configure a session protection
- * @id_and_color: the id and color of the mac for which this session protection
- * is sent
+ * @id_and_color: the id and color of the link (or mac, for command version 1)
+ * for which this session protection is sent
* @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE,
* see &enum iwl_ctxt_action
* @conf_id: see &enum iwl_mvm_session_prot_conf_id
@@ -454,7 +454,10 @@ struct iwl_mvm_session_prot_cmd {
__le32 duration_tu;
__le32 repetition_count;
__le32 interval;
-} __packed; /* SESSION_PROTECTION_CMD_API_S_VER_1 */
+} __packed;
+/* SESSION_PROTECTION_CMD_API_S_VER_1 and
+ * SESSION_PROTECTION_CMD_API_S_VER_2
+ */
/**
* struct iwl_mvm_session_prot_notif - session protection started / ended
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index 54e57c7ecfc8..ecbebef80791 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -689,19 +689,46 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
}
}
+/* Determine whether mac or link id should be used, and validate the link id */
+static int iwl_mvm_get_session_prot_id(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ u32 link_id)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ int ver = iwl_fw_lookup_cmd_ver(mvm->fw,
+ WIDE_ID(MAC_CONF_GROUP,
+ SESSION_PROTECTION_CMD), 1);
+
+ if (ver < 2)
+ return mvmvif->id;
+
+ if (WARN(link_id < 0 || !mvmvif->link[link_id],
+ "Invalid link ID for session protection: %u\n", link_id))
+ return -EINVAL;
+
+ if (WARN(ieee80211_vif_is_mld(vif) &&
+ !(vif->active_links & BIT(link_id)),
+ "Session Protection on an inactive link: %u\n", link_id))
+ return -EINVAL;
+
+ return mvmvif->link[link_id]->fw_link_id;
+}
+
static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
- struct iwl_mvm_vif *mvmvif,
- u32 id)
+ struct ieee80211_vif *vif,
+ u32 id, u32 link_id)
{
+ int mac_link_id = iwl_mvm_get_session_prot_id(mvm, vif, link_id);
struct iwl_mvm_session_prot_cmd cmd = {
- .id_and_color =
- cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
- mvmvif->color)),
+ .id_and_color = cpu_to_le32(mac_link_id),
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
.conf_id = cpu_to_le32(id),
};
int ret;
+ if (mac_link_id < 0)
+ return;
+
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
0, sizeof(cmd), &cmd);
@@ -715,10 +742,12 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
u32 *uid)
{
u32 id;
+ struct ieee80211_vif *vif = te_data->vif;
struct iwl_mvm_vif *mvmvif;
enum nl80211_iftype iftype;
+ unsigned int link_id;
- if (!te_data->vif)
+ if (!vif)
return false;
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
@@ -733,6 +762,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
/* Save time event uid before clearing its data */
*uid = te_data->uid;
id = te_data->id;
+ link_id = te_data->link_id;
/*
* The clear_data function handles time events that were already removed
@@ -750,7 +780,8 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
id != HOT_SPOT_CMD) {
if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
/* Session protection is still ongoing. Cancel it */
- iwl_mvm_cancel_session_protection(mvm, mvmvif, id);
+ iwl_mvm_cancel_session_protection(mvm, vif, id,
+ link_id);
if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_p2p_roc_finished(mvm);
}
@@ -941,8 +972,7 @@ iwl_mvm_start_p2p_roc_session_protection(struct iwl_mvm *mvm,
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_session_prot_cmd cmd = {
.id_and_color =
- cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
- mvmvif->color)),
+ cpu_to_le32(iwl_mvm_get_session_prot_id(mvm, vif, 0)),
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
};
@@ -1112,8 +1142,9 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
- iwl_mvm_cancel_session_protection(mvm, mvmvif,
- mvmvif->time_event_data.id);
+ iwl_mvm_cancel_session_protection(mvm, vif,
+ mvmvif->time_event_data.id,
+ mvmvif->time_event_data.link_id);
iwl_mvm_p2p_roc_finished(mvm);
} else {
iwl_mvm_roc_station_remove(mvm, mvmvif);
@@ -1242,15 +1273,17 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
const u16 notif[] = { WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_NOTIF) };
struct iwl_notification_wait wait_notif;
+ int mac_link_id = iwl_mvm_get_session_prot_id(mvm, vif, link_id);
struct iwl_mvm_session_prot_cmd cmd = {
- .id_and_color =
- cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
- mvmvif->color)),
+ .id_and_color = cpu_to_le32(mac_link_id),
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
};
+ if (mac_link_id < 0)
+ return;
+
lockdep_assert_held(&mvm->mutex);
spin_lock_bh(&mvm->time_event_lock);
@@ -1281,11 +1314,7 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
if (iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
0, sizeof(cmd), &cmd)) {
- IWL_ERR(mvm,
- "Couldn't send the SESSION_PROTECTION_CMD\n");
- spin_lock_bh(&mvm->time_event_lock);
- iwl_mvm_te_clear_data(mvm, te_data);
- spin_unlock_bh(&mvm->time_event_lock);
+ goto send_cmd_err;
}
return;
@@ -1298,12 +1327,19 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
if (iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
0, sizeof(cmd), &cmd)) {
- IWL_ERR(mvm,
- "Couldn't send the SESSION_PROTECTION_CMD\n");
iwl_remove_notification(&mvm->notif_wait, &wait_notif);
+ goto send_cmd_err;
} else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
TU_TO_JIFFIES(100))) {
IWL_ERR(mvm,
"Failed to protect session until session protection\n");
}
+ return;
+
+send_cmd_err:
+ IWL_ERR(mvm,
+ "Couldn't send the SESSION_PROTECTION_CMD\n");
+ spin_lock_bh(&mvm->time_event_lock);
+ iwl_mvm_te_clear_data(mvm, te_data);
+ spin_unlock_bh(&mvm->time_event_lock);
}