Skip to content

Commit

Permalink
wifi: iwlwifi: support link_id in SESSION_PROTECTION cmd
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Miri Korenblit authored and Johannes Berg committed Oct 23, 2023
1 parent 2367304 commit 1350658
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 25 deletions.
11 changes: 7 additions & 4 deletions drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
78 changes: 57 additions & 21 deletions drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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);
}
Expand Down Expand Up @@ -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)),
};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}

0 comments on commit 1350658

Please sign in to comment.