Commit 687db6ff authored by Shahar S Matityahu's avatar Shahar S Matityahu Committed by Kalle Valo
Browse files

iwlwifi: scan: make new scan req versioning flow



Implement a new versioning handling flow supported from version 11
onwards.

Signed-off-by: default avatarShahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent c5aaa8be
Loading
Loading
Loading
Loading
+58 −55
Original line number Diff line number Diff line
@@ -644,7 +644,10 @@ enum iwl_umac_scan_general_flags2 {
};

/**
 * enum iwl_umac_scan_general_flags_v22 - UMAC scan general flags ver 2
 * enum iwl_umac_scan_general_flags_v2 - UMAC scan general flags version 2
 *
 * The FW flags were reordered and hence the driver introduce version 2
 *
 * @IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC: periodic or scheduled
 * @IWL_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL: pass all probe responses and beacons
 *                                       during scan iterations
@@ -871,7 +874,7 @@ struct iwl_scan_req_umac {
#define IWL_SCAN_REQ_UMAC_SIZE_V1 36

/**
 * struct iwl_scan_probe_params
 * struct iwl_scan_probe_params_v3
 * @preq: scan probe request params
 * @ssid_num: number of valid SSIDs in direct scan array
 * @short_ssid_num: number of valid short SSIDs in short ssid array
@@ -881,7 +884,7 @@ struct iwl_scan_req_umac {
 * @short_ssid: array of short ssids
 * @bssid_array: array of bssids
 */
struct iwl_scan_probe_params {
struct iwl_scan_probe_params_v3 {
	struct iwl_scan_probe_req preq;
	u8 ssid_num;
	u8 short_ssid_num;
@@ -895,29 +898,29 @@ struct iwl_scan_probe_params {
#define SCAN_MAX_NUM_CHANS_V3 67

/**
 * struct iwl_scan_channel_params
 * struct iwl_scan_channel_params_v3
 * @flags: channel flags &enum iwl_scan_channel_flags
 * @count: num of channels in scan request
 * @reserved: for future use and alignment
 * @channel_config: array of explicit channel configurations
 *                  for 2.4Ghz and 5.2Ghz bands
 */
struct iwl_scan_channel_params {
struct iwl_scan_channel_params_v3 {
	u8 flags;
	u8 count;
	__le16 reserved;
	struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V3];
} __packed;
} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_3 */

/**
  * struct iwl_scan_general_params
 * struct iwl_scan_general_params_v10
 * @flags: &enum iwl_umac_scan_flags
 * @reserved: reserved for future
 * @scan_start_mac_id: report the scan start TSF time according to this mac TSF
 * @active_dwell: dwell time for active scan per LMAC
 * @adwell_default_2g: adaptive dwell default number of APs
 *                        for 2.4GHz channel
  * @ddwell_default_5g: adaptive dwell default number of APs
 * @adwell_default_5g: adaptive dwell default number of APs
 *                        for 5GHz channels
 * @adwell_default_social_chn: adaptive dwell default number of
 *                             APs per social channel
@@ -931,8 +934,8 @@ struct iwl_scan_channel_params {
 *                 (without adaptive dwell)
 * @num_of_fragments: number of fragments needed for full fragmented
 *                    scan coverage.
  * */
struct iwl_scan_general_params {
 */
struct iwl_scan_general_params_v10 {
	__le16 flags;
	u8 reserved;
	u8 scan_start_mac_id;
@@ -947,45 +950,45 @@ struct iwl_scan_general_params {
	__le32 scan_priority;
	u8 passive_dwell[SCAN_TWO_LMACS];
	u8 num_of_fragments[SCAN_TWO_LMACS];
} __packed;
} __packed; /* SCAN_GENERAL_PARAMS_API_S_VER_10 */

/**
  * struct iwl_scan_periodic_parms
 * struct iwl_scan_periodic_parms_v1
 * @schedule: can scheduling parameter
 * @delay: initial delay of the periodic scan in seconds
 * @reserved: reserved for future
  * */
struct iwl_scan_periodic_parms {
 */
struct iwl_scan_periodic_parms_v1 {
	struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
	__le16 delay;
	__le16 reserved;
} __packed;
} __packed; /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */

/**
  * struct iwl_scan_req_params
  * @general_params: &struct iwl_scan_general_params
  * @channel_params: &struct iwl_scan_channel_params
  * @periodic_params: &struct iwl_scan_periodic_parms
  * @probe_params: &struct iwl_scan_probe_params
  * */
struct iwl_scan_req_params {
	struct iwl_scan_general_params general_params;
	struct iwl_scan_channel_params channel_params;
	struct iwl_scan_periodic_parms periodic_params;
	struct iwl_scan_probe_params probe_params;
} __packed;
 * struct iwl_scan_req_params_v11
 * @general_params: &struct iwl_scan_general_params_v10
 * @channel_params: &struct iwl_scan_channel_params_v3
 * @periodic_params: &struct iwl_scan_periodic_parms_v1
 * @probe_params: &struct iwl_scan_probe_params_v3
 */
struct iwl_scan_req_params_v11 {
	struct iwl_scan_general_params_v10 general_params;
	struct iwl_scan_channel_params_v3 channel_params;
	struct iwl_scan_periodic_parms_v1 periodic_params;
	struct iwl_scan_probe_params_v3 probe_params;
} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_11 */

/**
 * struct iwl_scan_req_umac_v2
 * struct iwl_scan_req_umac_v11
 * @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_umac_req_v2 {
struct iwl_scan_req_umac_v11 {
	__le32 uid;
	__le32 ooc_priority;
	struct iwl_scan_req_params scan_params;
} __packed;
	struct iwl_scan_req_params_v11 scan_params;
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_11 */

/**
 * struct iwl_umac_scan_abort
+0 −9
Original line number Diff line number Diff line
@@ -1422,15 +1422,6 @@ static inline bool iwl_mvm_is_band_in_rx_supported(struct iwl_mvm *mvm)
			   IWL_UCODE_TLV_API_BAND_IN_RX_DATA);
}

static inline bool iwl_mvm_is_scan_ext_band_supported(struct iwl_mvm *mvm)
{
	u8 cmd_ver = iwl_mvm_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
					    SCAN_REQ_UMAC);
	if (cmd_ver == IWL_FW_CMD_VER_UNKNOWN)
		return false;
	return (cmd_ver >= 11);
}

static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
{
	return fw_has_api(&mvm->fw->ucode_capa,
+150 −98
Original line number Diff line number Diff line
@@ -974,10 +974,6 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	int i;
	u8 band;

	lockdep_assert_held(&mvm->mutex);

	memset(cmd, 0, ksize(cmd));

	if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
		return -EINVAL;

@@ -1407,8 +1403,16 @@ static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm,
		cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
}

static void iwl_mvm_scan_umac_dwell_v2(struct iwl_mvm *mvm,
				       struct iwl_scan_umac_req_v2 *cmd,
static u32 iwl_mvm_scan_umac_ooc_priority(struct iwl_mvm_scan_params *params)
{
	return iwl_mvm_is_regular_scan(params) ?
		IWL_SCAN_PRIORITY_EXT_6 :
		IWL_SCAN_PRIORITY_EXT_2;
}

static void
iwl_mvm_scan_umac_dwell_v10(struct iwl_mvm *mvm,
			    struct iwl_scan_general_params_v10 *general_params,
			    struct iwl_mvm_scan_params *params)
{
	struct iwl_mvm_scan_timing_params *timing, *hb_timing;
@@ -1420,51 +1424,39 @@ static void iwl_mvm_scan_umac_dwell_v2(struct iwl_mvm *mvm,
	passive_dwell = params->measurement_dwell ?
		params->measurement_dwell : IWL_SCAN_DWELL_PASSIVE;

	cmd->scan_params.general_params.adwell_default_social_chn =
	general_params->adwell_default_social_chn =
		IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
	cmd->scan_params.general_params.adwell_default_2g =
		IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
	cmd->scan_params.general_params.adwell_default_5g =
			IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;
	general_params->adwell_default_2g = IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
	general_params->adwell_default_5g = IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;

	/* if custom max budget was configured with debugfs */
	if (IWL_MVM_ADWELL_MAX_BUDGET)
		cmd->scan_params.general_params.adwell_max_budget =
		general_params->adwell_max_budget =
			cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET);
	else if (params->ssids && params->ssids[0].ssid_len)
		cmd->scan_params.general_params.adwell_max_budget =
		general_params->adwell_max_budget =
			cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
	else
		cmd->scan_params.general_params.adwell_max_budget =
		general_params->adwell_max_budget =
			cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);

	cmd->scan_params.general_params.scan_priority =
		cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
	cmd->scan_params.general_params.max_out_of_time[SCAN_LB_LMAC_IDX] =
	general_params->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
	general_params->max_out_of_time[SCAN_LB_LMAC_IDX] =
		cpu_to_le32(timing->max_out_time);
	cmd->scan_params.general_params.suspend_time[SCAN_LB_LMAC_IDX] =
	general_params->suspend_time[SCAN_LB_LMAC_IDX] =
		cpu_to_le32(timing->suspend_time);

	hb_timing = &scan_timing[params->hb_type];

	cmd->scan_params.general_params.max_out_of_time[SCAN_HB_LMAC_IDX] =
	general_params->max_out_of_time[SCAN_HB_LMAC_IDX] =
		cpu_to_le32(hb_timing->max_out_time);
	cmd->scan_params.general_params.suspend_time[SCAN_HB_LMAC_IDX] =
	general_params->suspend_time[SCAN_HB_LMAC_IDX] =
		cpu_to_le32(hb_timing->suspend_time);

	cmd->scan_params.general_params.active_dwell[SCAN_LB_LMAC_IDX] =
		active_dwell;
	cmd->scan_params.general_params.passive_dwell[SCAN_LB_LMAC_IDX] =
		passive_dwell;
	cmd->scan_params.general_params.active_dwell[SCAN_HB_LMAC_IDX] =
		active_dwell;
	cmd->scan_params.general_params.passive_dwell[SCAN_HB_LMAC_IDX] =
		passive_dwell;

	if (iwl_mvm_is_regular_scan(params))
		cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
	else
		cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
	general_params->active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
	general_params->passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
	general_params->active_dwell[SCAN_HB_LMAC_IDX] = active_dwell;
	general_params->passive_dwell[SCAN_HB_LMAC_IDX] = passive_dwell;
}

static void
@@ -1664,7 +1656,7 @@ iwl_mvm_fill_scan_sched_params(struct iwl_mvm_scan_params *params,

static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			     struct iwl_mvm_scan_params *params,
			     int type)
			     int type, int uid)
{
	struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
	struct iwl_scan_umac_chan_param *chan_param;
@@ -1675,7 +1667,7 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
		(struct iwl_scan_req_umac_tail_v2 *)sec_part;
	struct iwl_scan_req_umac_tail_v1 *tail_v1;
	struct iwl_ssid_ie *direct_scan;
	int uid, ret = 0;
	int ret = 0;
	u32 ssid_bitmap = 0;
	u8 channel_flags = 0;
	u16 gen_flags;
@@ -1683,14 +1675,6 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,

	chan_param = iwl_mvm_get_scan_req_umac_channel(mvm);

	lockdep_assert_held(&mvm->mutex);

	uid = iwl_mvm_scan_uid_by_status(mvm, 0);
	if (uid < 0)
		return uid;

	memset(cmd, 0, ksize(cmd));

	iwl_mvm_scan_umac_dwell(mvm, cmd, params);

	mvm->scan_uid_status[uid] = type;
@@ -1754,68 +1738,79 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
	return 0;
}

static int iwl_mvm_scan_umac_v2(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
static void
iwl_mvm_scan_umac_fill_general_p_v10(struct iwl_mvm *mvm,
				     struct iwl_mvm_scan_params *params,
				int type)
				     struct ieee80211_vif *vif,
				     struct iwl_scan_general_params_v10 *gp,
				     u16 gen_flags)
{
	struct iwl_scan_umac_req_v2 *cmd = mvm->scan_cmd;
	int uid, ret = 0;
	u8 channel_flags = 0;
	u16 gen_flags;
	struct iwl_scan_req_params *scan_params;
	struct iwl_scan_periodic_parms *periodic_params;
	struct iwl_scan_channel_params *channel_params;

	struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif);

	scan_params = &cmd->scan_params;
	periodic_params = &scan_params->periodic_params;
	channel_params = &scan_params->channel_params;
	lockdep_assert_held(&mvm->mutex);
	iwl_mvm_scan_umac_dwell_v10(mvm, gp, params);

	uid = iwl_mvm_scan_uid_by_status(mvm, 0);
	if (uid < 0)
		return uid;
	gp->flags = cpu_to_le16(gen_flags);

	memset(cmd, 0, ksize(cmd));
	if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
		gp->num_of_fragments[SCAN_LB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
	if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
		gp->num_of_fragments[SCAN_HB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;

	iwl_mvm_scan_umac_dwell_v2(mvm, cmd, params);
	gp->scan_start_mac_id = scan_vif->id;
}

	mvm->scan_uid_status[uid] = type;
static void
iwl_mvm_scan_umac_fill_probe_p_v3(struct iwl_mvm_scan_params *params,
				  struct iwl_scan_probe_params_v3 *pp)
{
	pp->preq = params->preq;
	pp->ssid_num = params->n_ssids;
	iwl_scan_build_ssids(params, pp->direct_scan, NULL);
}

	cmd->uid = cpu_to_le32(uid);
static void
iwl_mvm_scan_umac_fill_ch_p_v3(struct iwl_mvm *mvm,
			       struct iwl_mvm_scan_params *params,
			       struct ieee80211_vif *vif,
			       struct iwl_scan_channel_params_v3 *cp)
{
	cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
	cp->count = params->n_channels;

	gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
	scan_params->general_params.flags = cpu_to_le16(gen_flags);
	iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
				       params->n_channels, 0,
				       cp->channel_config);
}

	if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
		scan_params->general_params.num_of_fragments[SCAN_LB_LMAC_IDX] =
			IWL_SCAN_NUM_OF_FRAGS;
	if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
		scan_params->general_params.num_of_fragments[SCAN_HB_LMAC_IDX] =
			IWL_SCAN_NUM_OF_FRAGS;
static int iwl_mvm_scan_umac_v11(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
				 struct iwl_mvm_scan_params *params, int type,
				 int uid)
{
	struct iwl_scan_req_umac_v11 *cmd = mvm->scan_cmd;
	struct iwl_scan_req_params_v11 *scan_p = &cmd->scan_params;
	int ret;
	u16 gen_flags;

	scan_params->general_params.scan_start_mac_id = scan_vif->id;
	mvm->scan_uid_status[uid] = type;

	channel_flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
	channel_params->flags = channel_flags;
	cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params));
	cmd->uid = cpu_to_le32(uid);

	channel_params->count = params->n_channels;
	gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
	iwl_mvm_scan_umac_fill_general_p_v10(mvm, params, vif,
					     &scan_p->general_params,
					     gen_flags);

	 ret = iwl_mvm_fill_scan_sched_params(params,
					      periodic_params->schedule,
					      &periodic_params->delay);
					      scan_p->periodic_params.schedule,
					      &scan_p->periodic_params.delay);
	if (ret)
		return ret;

	scan_params->probe_params.preq = params->preq;
	scan_params->probe_params.ssid_num = params->n_ssids;
	iwl_scan_build_ssids(params, scan_params->probe_params.direct_scan,
			     NULL);
	iwl_mvm_scan_umac_fill_probe_p_v3(params, &scan_p->probe_params);
	iwl_mvm_scan_umac_fill_ch_p_v3(mvm, params, vif,
				       &scan_p->channel_params);

	iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
				       params->n_channels, 0,
				       channel_params->channel_config);
	return 0;
}

@@ -1921,22 +1916,61 @@ static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
	}
}

struct iwl_scan_umac_handler {
	u8 version;
	int (*handler)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
		       struct iwl_mvm_scan_params *params, int type, int uid);
};

#define IWL_SCAN_UMAC_HANDLER(_ver) {		\
	.version = _ver,			\
	.handler = iwl_mvm_scan_umac_v##_ver,	\
}

static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = {
	IWL_SCAN_UMAC_HANDLER(11),
};

static int iwl_mvm_build_scan_cmd(struct iwl_mvm *mvm,
				  struct ieee80211_vif *vif,
				  struct iwl_host_cmd *hcmd,
				  struct iwl_mvm_scan_params *params,
				  int type)
{
	if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
		hcmd->id = iwl_cmd_id(SCAN_REQ_UMAC, IWL_ALWAYS_LONG_GROUP, 0);
		if (iwl_mvm_is_scan_ext_band_supported(mvm))
			return iwl_mvm_scan_umac_v2(mvm, vif, params, type);
		return iwl_mvm_scan_umac(mvm, vif, params, type);
	}
	int uid, i;
	u8 scan_ver;

	lockdep_assert_held(&mvm->mutex);
	memset(mvm->scan_cmd, 0, ksize(mvm->scan_cmd));

	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
		hcmd->id = SCAN_OFFLOAD_REQUEST_CMD;

		return iwl_mvm_scan_lmac(mvm, vif, params);
	}

	uid = iwl_mvm_scan_uid_by_status(mvm, 0);
	if (uid < 0)
		return uid;

	hcmd->id = iwl_cmd_id(SCAN_REQ_UMAC, IWL_ALWAYS_LONG_GROUP, 0);

	scan_ver = iwl_mvm_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
					  SCAN_REQ_UMAC);

	for (i = 0; i < ARRAY_SIZE(iwl_scan_umac_handlers); i++) {
		const struct iwl_scan_umac_handler *ver_handler =
			&iwl_scan_umac_handlers[i];

		if (ver_handler->version != scan_ver)
			continue;

		return ver_handler->handler(mvm, vif, params, type, uid);
	}

	return iwl_mvm_scan_umac(mvm, vif, params, type, uid);
}

int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			   struct cfg80211_scan_request *req,
			   struct ieee80211_scan_ies *ies)
@@ -2244,13 +2278,29 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
				     1 * HZ);
}

#define IWL_SCAN_REQ_UMAC_HANDLE_SIZE(_ver) {				\
	case (_ver): return sizeof(struct iwl_scan_req_umac_v##_ver);	\
}

static int iwl_scan_req_umac_get_size(u8 scan_ver)
{
	switch (scan_ver) {
		IWL_SCAN_REQ_UMAC_HANDLE_SIZE(11);
	}

	return 0;
}

int iwl_mvm_scan_size(struct iwl_mvm *mvm)
{
	int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
	int tail_size;
	int base_size, tail_size;
	u8 scan_ver = iwl_mvm_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
					     SCAN_REQ_UMAC);

	base_size = iwl_scan_req_umac_get_size(scan_ver);
	if (base_size)
		return base_size;

	if (iwl_mvm_is_scan_ext_band_supported(mvm))
		return sizeof(struct iwl_scan_umac_req_v2);

	if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
		base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
@@ -2258,6 +2308,8 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
		base_size = IWL_SCAN_REQ_UMAC_SIZE_V7;
	else if (iwl_mvm_cdb_scan_api(mvm))
		base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;
	else
		base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;

	if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
		if (iwl_mvm_is_scan_ext_chan_supported(mvm))