wifi: iwlwifi: support link_id in SESSION_PROTECTION cmd
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Tue, 17 Oct 2023 09:16:37 +0000 (12:16 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 23 Oct 2023 10:48:27 +0000 (12:48 +0200)
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>
drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c

index f0d4056199a774530b5b1c193bec17b0e7c199c2..701b2929c3a4965ac79e8c7f8bb4e0c7b864d666 100644 (file)
@@ -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
index 54e57c7ecfc8f2da2b8ed9f267b9e11b26aff3cd..ecbebef80791a34b8de9e73787013cb6ff05a546 100644 (file)
@@ -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);
 }