]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mld: Introduce scan command version 18
authorIlan Peer <ilan.peer@intel.com>
Thu, 19 Mar 2026 09:09:20 +0000 (11:09 +0200)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Wed, 25 Mar 2026 09:31:55 +0000 (11:31 +0200)
The FW scan logic was extended to support new channels in the
7 GHz band, as such, the scan command was modified to support
scanning more PSC channels.

Introduce scan command version 18 handling, which is different
from scan command version 17 only in the number of supported
channel configurations.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260319110722.c995b4e8bbc5.Ie401d9cf02daaa5e6adf2b3c309643589e3ead71@changeid
drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
drivers/net/wireless/intel/iwlwifi/mld/scan.c

index 60f0a4924ddfb0e6cf006aee71ab499accf739d2..c2bb400c834cff69d84af9fe696c29c76714967f 100644 (file)
@@ -985,6 +985,7 @@ struct iwl_scan_probe_params_v4 {
 } __packed; /* SCAN_PROBE_PARAMS_API_S_VER_4 */
 
 #define SCAN_MAX_NUM_CHANS_V3 67
+#define SCAN_MAX_NUM_CHANS_V4 68
 
 /**
  * struct iwl_scan_channel_params_v4 - channel params
@@ -1027,6 +1028,24 @@ struct iwl_scan_channel_params_v7 {
        struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V3];
 } __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_6 */
 
+/**
+ * struct iwl_scan_channel_params_v8 - channel params
+ * @flags: channel flags &enum iwl_scan_channel_flags
+ * @count: num of channels in scan request
+ * @n_aps_override: override the number of APs the FW uses to calculate dwell
+ *     time when adaptive dwell is used.
+ *     Channel k will use n_aps_override[i] when BIT(20 + i) is set in
+ *     channel_config[k].flags
+ * @channel_config: array of explicit channel configurations
+ *      for 2.4Ghz and 5.2Ghz bands
+ */
+struct iwl_scan_channel_params_v8 {
+       u8 flags;
+       u8 count;
+       u8 n_aps_override[2];
+       struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V4];
+} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_8 */
+
 /**
  * struct iwl_scan_general_params_v11 - channel params
  * @flags: &enum iwl_umac_scan_general_flags_v2
@@ -1109,6 +1128,20 @@ struct iwl_scan_req_params_v17 {
        struct iwl_scan_probe_params_v4 probe_params;
 } __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_17 - 14 */
 
+/**
+ * struct iwl_scan_req_params_v18 - scan request parameters (v18)
+ * @general_params: &struct iwl_scan_general_params_v11
+ * @channel_params: &struct iwl_scan_channel_params_v8
+ * @periodic_params: &struct iwl_scan_periodic_parms_v1
+ * @probe_params: &struct iwl_scan_probe_params_v4
+ */
+struct iwl_scan_req_params_v18 {
+       struct iwl_scan_general_params_v11 general_params;
+       struct iwl_scan_channel_params_v8 channel_params;
+       struct iwl_scan_periodic_parms_v1 periodic_params;
+       struct iwl_scan_probe_params_v4 probe_params;
+} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_18 */
+
 /**
  * struct iwl_scan_req_umac_v12 - scan request command (v12)
  * @uid: scan id, &enum iwl_umac_scan_uid_offsets
@@ -1133,6 +1166,18 @@ struct iwl_scan_req_umac_v17 {
        struct iwl_scan_req_params_v17 scan_params;
 } __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_17 - 14 */
 
+/**
+ * struct iwl_scan_req_umac_v18 - scan request command (v18)
+ * @uid: scan id, &enum iwl_umac_scan_uid_offsets
+ * @ooc_priority: out of channel priority - &enum iwl_scan_priority
+ * @scan_params: scan parameters
+ */
+struct iwl_scan_req_umac_v18 {
+       __le32 uid;
+       __le32 ooc_priority;
+       struct iwl_scan_req_params_v18 scan_params;
+} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_18 */
+
 /**
  * struct iwl_umac_scan_abort - scan abort command
  * @uid: scan id, &enum iwl_umac_scan_uid_offsets
index 7f4679134defc4815caf30c3dd1eff4ec613dc3b..96cd970cceb4c83fc47fb743cc59c53321079c7f 100644 (file)
@@ -118,7 +118,7 @@ struct iwl_mld_scan_params {
 
 struct iwl_scan_req_params_ptrs {
        struct iwl_scan_general_params_v11 *general_params;
-       struct iwl_scan_channel_params_v7 *channel_params;
+       struct iwl_scan_channel_params_v8 *channel_params;
        struct iwl_scan_periodic_parms_v1 *periodic_params;
        struct iwl_scan_probe_params_v4 *probe_params;
 };
@@ -840,7 +840,7 @@ iwl_mld_scan_cmd_set_channels(struct iwl_mld *mld,
                              int n_channels, u32 flags,
                              enum nl80211_iftype vif_type)
 {
-       struct iwl_scan_channel_params_v7 *cp = scan_ptrs->channel_params;
+       struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
 
        for (int i = 0; i < n_channels; i++) {
                enum nl80211_band band = channels[i]->band;
@@ -883,7 +883,7 @@ iwl_mld_scan_cfg_channels_6g(struct iwl_mld *mld,
                             enum nl80211_iftype vif_type)
 {
        struct iwl_scan_probe_params_v4 *pp = scan_ptrs->probe_params;
-       struct iwl_scan_channel_params_v7 *cp = scan_ptrs->channel_params;
+       struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
        struct cfg80211_scan_6ghz_params *scan_6ghz_params =
                params->scan_6ghz_params;
        u32 i;
@@ -1083,7 +1083,7 @@ iwl_mld_scan_cmd_set_6ghz_chan_params(struct iwl_mld *mld,
                                      struct ieee80211_vif *vif,
                                      struct iwl_scan_req_params_ptrs *scan_ptrs)
 {
-       struct iwl_scan_channel_params_v7 *cp = scan_ptrs->channel_params;
+       struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
 
        /* Explicitly clear the flags since most of them are not
         * relevant for 6 GHz scan.
@@ -1111,7 +1111,7 @@ iwl_mld_scan_cmd_set_chan_params(struct iwl_mld *mld,
                                 enum iwl_mld_scan_status scan_status,
                                 u32 channel_cfg_flags)
 {
-       struct iwl_scan_channel_params_v7 *cp = scan_ptrs->channel_params;
+       struct iwl_scan_channel_params_v8 *cp = scan_ptrs->channel_params;
        struct ieee80211_supported_band *sband =
                &mld->nvm_data->bands[NL80211_BAND_6GHZ];
 
@@ -1173,39 +1173,89 @@ struct iwl_scan_umac_handler {
        .handler = iwl_mld_scan_umac_v##_ver,   \
 }
 
-static int iwl_mld_scan_umac_v17(struct iwl_mld *mld, struct ieee80211_vif *vif,
+static int iwl_mld_scan_umac_common(struct iwl_mld *mld,
+                                   struct ieee80211_vif *vif,
+                                   struct iwl_mld_scan_params *params,
+                                   struct iwl_scan_req_params_ptrs *scan_ptrs,
+                                   enum iwl_mld_scan_status scan_status,
+                                   bool low_latency)
+{
+       u32 bitmap_ssid = 0;
+       int ret;
+
+       iwl_mld_scan_cmd_set_gen_params(mld, params, vif, scan_ptrs,
+                                       scan_status);
+
+       ret = iwl_mld_scan_cmd_set_sched_params(params, scan_ptrs);
+       if (ret)
+               return ret;
+
+       iwl_mld_scan_cmd_set_probe_params(params, scan_ptrs, &bitmap_ssid);
+
+       return iwl_mld_scan_cmd_set_chan_params(mld, params, vif, scan_ptrs,
+                                               low_latency, scan_status,
+                                               bitmap_ssid);
+}
+
+static int iwl_mld_scan_umac_v18(struct iwl_mld *mld, struct ieee80211_vif *vif,
                                 struct iwl_mld_scan_params *params,
                                 enum iwl_mld_scan_status scan_status,
                                 int uid, u32 ooc_priority, bool low_latency)
 {
-       struct iwl_scan_req_umac_v17 *cmd = mld->scan.cmd;
+       struct iwl_scan_req_umac_v18 *cmd = mld->scan.cmd;
        struct iwl_scan_req_params_ptrs scan_ptrs = {
                .general_params = &cmd->scan_params.general_params,
                .probe_params = &cmd->scan_params.probe_params,
                .channel_params = &cmd->scan_params.channel_params,
                .periodic_params = &cmd->scan_params.periodic_params
        };
-       u32 bitmap_ssid = 0;
        int ret;
 
-       if (WARN_ON(params->n_channels > SCAN_MAX_NUM_CHANS_V3))
+       if (WARN_ON(params->n_channels > SCAN_MAX_NUM_CHANS_V4))
                return -EINVAL;
 
        cmd->uid = cpu_to_le32(uid);
        cmd->ooc_priority = cpu_to_le32(ooc_priority);
 
-       iwl_mld_scan_cmd_set_gen_params(mld, params, vif, &scan_ptrs,
-                                       scan_status);
-
-       ret = iwl_mld_scan_cmd_set_sched_params(params, &scan_ptrs);
+       ret = iwl_mld_scan_umac_common(mld, vif, params, &scan_ptrs,
+                                      scan_status, low_latency);
        if (ret)
                return ret;
 
-       iwl_mld_scan_cmd_set_probe_params(params, &scan_ptrs, &bitmap_ssid);
+       return uid;
+}
+
+static int iwl_mld_scan_umac_v17(struct iwl_mld *mld, struct ieee80211_vif *vif,
+                                struct iwl_mld_scan_params *params,
+                                enum iwl_mld_scan_status scan_status,
+                                int uid, u32 ooc_priority, bool low_latency)
+{
+       struct iwl_scan_req_umac_v17 *cmd = mld->scan.cmd;
+       struct iwl_scan_req_params_ptrs scan_ptrs = {
+               .general_params = &cmd->scan_params.general_params,
+               .probe_params = &cmd->scan_params.probe_params,
+
+               /* struct iwl_scan_channel_params_v8 and struct
+                * iwl_scan_channel_params_v7 are almost identical. The only
+                * difference is that the newer version allows configuration of
+                * more channels. So casting here is ok as long as we ensure
+                * that we don't exceed the max number of channels supported by
+                * the older version (see the WARN_ON below).
+                */
+               .channel_params = (struct iwl_scan_channel_params_v8 *)
+                       &cmd->scan_params.channel_params,
+               .periodic_params = &cmd->scan_params.periodic_params
+       };
+       int ret;
+
+       if (WARN_ON(params->n_channels > SCAN_MAX_NUM_CHANS_V3))
+               return -EINVAL;
+
+       cmd->uid = cpu_to_le32(uid);
+       cmd->ooc_priority = cpu_to_le32(ooc_priority);
 
-       ret = iwl_mld_scan_cmd_set_chan_params(mld, params, vif, &scan_ptrs,
-                                              low_latency, scan_status,
-                                              bitmap_ssid);
+       ret = iwl_mld_scan_umac_common(mld, vif, params, &scan_ptrs,
+                                      scan_status, low_latency);
        if (ret)
                return ret;
 
@@ -1214,6 +1264,7 @@ static int iwl_mld_scan_umac_v17(struct iwl_mld *mld, struct ieee80211_vif *vif,
 
 static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = {
        /* set the newest version first to shorten the list traverse time */
+       IWL_SCAN_UMAC_HANDLER(18),
        IWL_SCAN_UMAC_HANDLER(17),
 };
 
@@ -2095,6 +2146,8 @@ int iwl_mld_alloc_scan_cmd(struct iwl_mld *mld)
 
        if (scan_cmd_ver == 17) {
                scan_cmd_size = sizeof(struct iwl_scan_req_umac_v17);
+       } else if (scan_cmd_ver == 18) {
+               scan_cmd_size = sizeof(struct iwl_scan_req_umac_v18);
        } else {
                IWL_ERR(mld, "Unexpected scan cmd version %d\n", scan_cmd_ver);
                return -EINVAL;