Commit 13506583 authored by Miri Korenblit's avatar Miri Korenblit Committed by Johannes Berg

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: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20231017115047.a3cb29ed0617.I85b8a85b0d9186d3dd4d704254e46775b0ccf7de@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 23673041
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* 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) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH
*/ */
...@@ -432,8 +432,8 @@ enum iwl_mvm_session_prot_conf_id { ...@@ -432,8 +432,8 @@ enum iwl_mvm_session_prot_conf_id {
/** /**
* struct iwl_mvm_session_prot_cmd - configure a session protection * 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 * @id_and_color: the id and color of the link (or mac, for command version 1)
* is sent * for which this session protection is sent
* @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE, * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE,
* see &enum iwl_ctxt_action * see &enum iwl_ctxt_action
* @conf_id: see &enum iwl_mvm_session_prot_conf_id * @conf_id: see &enum iwl_mvm_session_prot_conf_id
...@@ -454,7 +454,10 @@ struct iwl_mvm_session_prot_cmd { ...@@ -454,7 +454,10 @@ struct iwl_mvm_session_prot_cmd {
__le32 duration_tu; __le32 duration_tu;
__le32 repetition_count; __le32 repetition_count;
__le32 interval; __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 * struct iwl_mvm_session_prot_notif - session protection started / ended
......
...@@ -689,19 +689,46 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, ...@@ -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, static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
struct iwl_mvm_vif *mvmvif, struct ieee80211_vif *vif,
u32 id) 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 = { struct iwl_mvm_session_prot_cmd cmd = {
.id_and_color = .id_and_color = cpu_to_le32(mac_link_id),
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color)),
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE), .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
.conf_id = cpu_to_le32(id), .conf_id = cpu_to_le32(id),
}; };
int ret; int ret;
if (mac_link_id < 0)
return;
ret = iwl_mvm_send_cmd_pdu(mvm, ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD), WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
0, sizeof(cmd), &cmd); 0, sizeof(cmd), &cmd);
...@@ -715,10 +742,12 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, ...@@ -715,10 +742,12 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
u32 *uid) u32 *uid)
{ {
u32 id; u32 id;
struct ieee80211_vif *vif = te_data->vif;
struct iwl_mvm_vif *mvmvif; struct iwl_mvm_vif *mvmvif;
enum nl80211_iftype iftype; enum nl80211_iftype iftype;
unsigned int link_id;
if (!te_data->vif) if (!vif)
return false; return false;
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
...@@ -733,6 +762,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, ...@@ -733,6 +762,7 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
/* Save time event uid before clearing its data */ /* Save time event uid before clearing its data */
*uid = te_data->uid; *uid = te_data->uid;
id = te_data->id; id = te_data->id;
link_id = te_data->link_id;
/* /*
* The clear_data function handles time events that were already removed * 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, ...@@ -750,7 +780,8 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
id != HOT_SPOT_CMD) { id != HOT_SPOT_CMD) {
if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) { if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
/* Session protection is still ongoing. Cancel it */ /* 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) { if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_p2p_roc_finished(mvm); iwl_mvm_p2p_roc_finished(mvm);
} }
...@@ -941,8 +972,7 @@ iwl_mvm_start_p2p_roc_session_protection(struct iwl_mvm *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_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_session_prot_cmd cmd = { struct iwl_mvm_session_prot_cmd cmd = {
.id_and_color = .id_and_color =
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, cpu_to_le32(iwl_mvm_get_session_prot_id(mvm, vif, 0)),
mvmvif->color)),
.action = cpu_to_le32(FW_CTXT_ACTION_ADD), .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)), .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) ...@@ -1112,8 +1142,9 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
mvmvif = iwl_mvm_vif_from_mac80211(vif); mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_cancel_session_protection(mvm, mvmvif, iwl_mvm_cancel_session_protection(mvm, vif,
mvmvif->time_event_data.id); mvmvif->time_event_data.id,
mvmvif->time_event_data.link_id);
iwl_mvm_p2p_roc_finished(mvm); iwl_mvm_p2p_roc_finished(mvm);
} else { } else {
iwl_mvm_roc_station_remove(mvm, mvmvif); iwl_mvm_roc_station_remove(mvm, mvmvif);
...@@ -1242,15 +1273,17 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, ...@@ -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; struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
const u16 notif[] = { WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_NOTIF) }; const u16 notif[] = { WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_NOTIF) };
struct iwl_notification_wait wait_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 = { struct iwl_mvm_session_prot_cmd cmd = {
.id_and_color = .id_and_color = cpu_to_le32(mac_link_id),
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color)),
.action = cpu_to_le32(FW_CTXT_ACTION_ADD), .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC), .conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
.duration_tu = cpu_to_le32(MSEC_TO_TU(duration)), .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
}; };
if (mac_link_id < 0)
return;
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
spin_lock_bh(&mvm->time_event_lock); spin_lock_bh(&mvm->time_event_lock);
...@@ -1281,11 +1314,7 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, ...@@ -1281,11 +1314,7 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
if (iwl_mvm_send_cmd_pdu(mvm, if (iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD), WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
0, sizeof(cmd), &cmd)) { 0, sizeof(cmd), &cmd)) {
IWL_ERR(mvm, goto send_cmd_err;
"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);
} }
return; return;
...@@ -1298,12 +1327,19 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, ...@@ -1298,12 +1327,19 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
if (iwl_mvm_send_cmd_pdu(mvm, if (iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD), WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
0, sizeof(cmd), &cmd)) { 0, sizeof(cmd), &cmd)) {
IWL_ERR(mvm,
"Couldn't send the SESSION_PROTECTION_CMD\n");
iwl_remove_notification(&mvm->notif_wait, &wait_notif); iwl_remove_notification(&mvm->notif_wait, &wait_notif);
goto send_cmd_err;
} else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif, } else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
TU_TO_JIFFIES(100))) { TU_TO_JIFFIES(100))) {
IWL_ERR(mvm, IWL_ERR(mvm,
"Failed to protect session until session protection\n"); "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);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment