} __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
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
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
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
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;
};
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;
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;
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.
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];
.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;
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),
};
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;