Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35a000b7 authored by David Spinadel's avatar David Spinadel Committed by Johannes Berg
Browse files

iwlwifi: mvm: support sched scan if supported by the fw



Add support for scheduled scan according to firmware support.

Signed-off-by: default avatarDavid Spinadel <david.spinadel@intel.com>
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 20f1a5de
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@
 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
 * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
 * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
 *	offload profile config command.
 * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
 * @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
 * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
@@ -82,6 +84,7 @@
 * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
 * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
 *	from the probe request template.
 * @IWL_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan.
 * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
 */
enum iwl_ucode_tlv_flag {
@@ -91,11 +94,13 @@ enum iwl_ucode_tlv_flag {
	IWL_UCODE_TLV_FLAGS_P2P			= BIT(3),
	IWL_UCODE_TLV_FLAGS_DW_BC_TABLE		= BIT(4),
	IWL_UCODE_TLV_FLAGS_UAPSD		= BIT(6),
	IWL_UCODE_TLV_FLAGS_SHORT_BL		= BIT(7),
	IWL_UCODE_TLV_FLAGS_RX_ENERGY_API	= BIT(8),
	IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2	= BIT(9),
	IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS	= BIT(10),
	IWL_UCODE_TLV_FLAGS_BF_UPDATED		= BIT(11),
	IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID	= BIT(12),
	IWL_UCODE_TLV_FLAGS_SCHED_SCAN		= BIT(17),
	IWL_UCODE_TLV_FLAGS_STA_KEY_CMD		= BIT(19),
};

+30 −4
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ struct iwl_scan_complete_notif {
/* scan offload */
#define IWL_MAX_SCAN_CHANNELS		40
#define IWL_SCAN_MAX_BLACKLIST_LEN	64
#define IWL_SCAN_SHORT_BLACKLIST_LEN	16
#define IWL_SCAN_MAX_PROFILES		11
#define SCAN_OFFLOAD_PROBE_REQ_SIZE	512

@@ -368,6 +369,12 @@ struct iwl_scan_complete_notif {
#define IWL_FULL_SCAN_MULTIPLIER 5
#define IWL_FAST_SCHED_SCAN_ITERATIONS 3

enum scan_framework_client {
	SCAN_CLIENT_SCHED_SCAN		= BIT(0),
	SCAN_CLIENT_NETDETECT		= BIT(1),
	SCAN_CLIENT_ASSET_TRACKING	= BIT(2),
};

/**
 * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6
 * @scan_flags:		see enum iwl_scan_flags
@@ -449,11 +456,12 @@ struct iwl_scan_offload_cfg {
 * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S
 * @ssid:		MAC address to filter out
 * @reported_rssi:	AP rssi reported to the host
 * @client_bitmap: clients ignore this entry  - enum scan_framework_client
 */
struct iwl_scan_offload_blacklist {
	u8 ssid[ETH_ALEN];
	u8 reported_rssi;
	u8 reserved;
	u8 client_bitmap;
} __packed;

enum iwl_scan_offload_network_type {
@@ -475,6 +483,7 @@ enum iwl_scan_offload_band_selection {
 * @aut_alg:		authentication olgorithm to match - bitmap
 * @network_type:	enum iwl_scan_offload_network_type
 * @band_selection:	enum iwl_scan_offload_band_selection
 * @client_bitmap:	clients waiting for match - enum scan_framework_client
 */
struct iwl_scan_offload_profile {
	u8 ssid_index;
@@ -482,7 +491,8 @@ struct iwl_scan_offload_profile {
	u8 auth_alg;
	u8 network_type;
	u8 band_selection;
	u8 reserved[3];
	u8 client_bitmap;
	u8 reserved[2];
} __packed;

/**
@@ -491,13 +501,18 @@ struct iwl_scan_offload_profile {
 * @profiles:		profiles to search for match
 * @blacklist_len:	length of blacklist
 * @num_profiles:	num of profiles in the list
 * @match_notify:	clients waiting for match found notification
 * @pass_match:		clients waiting for the results
 * @active_clients:	active clients bitmap - enum scan_framework_client
 */
struct iwl_scan_offload_profile_cfg {
	struct iwl_scan_offload_blacklist blacklist[IWL_SCAN_MAX_BLACKLIST_LEN];
	struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
	u8 blacklist_len;
	u8 num_profiles;
	u8 reserved[2];
	u8 match_notify;
	u8 pass_match;
	u8 active_clients;
	u8 reserved[3];
} __packed;

/**
@@ -560,4 +575,15 @@ struct iwl_scan_offload_complete {
	u8 reserved;
} __packed;

/**
 * iwl_sched_scan_results - SCAN_OFFLOAD_MATCH_FOUND_NTF_API_S_VER_1
 * @ssid_bitmap:	SSIDs indexes found in this iteration
 * @client_bitmap:	clients that are active and wait for this notification
 */
struct iwl_sched_scan_results {
	__le16 ssid_bitmap;
	u8 client_bitmap;
	u8 reserved;
};

#endif
+1 −0
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ enum {
	SCAN_OFFLOAD_COMPLETE = 0x6D,
	SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
	SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
	MATCH_FOUND_NOTIFICATION = 0xd9,

	/* Phy */
	PHY_CONFIGURATION_CMD = 0x6a,
+58 −0
Original line number Diff line number Diff line
@@ -239,6 +239,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
	else
		hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;

	if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
		hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
		hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
		hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
		/* we create the 802.11 header and zero length SSID IE. */
		hw->wiphy->max_sched_scan_ie_len =
					SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
	}

	hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
			       NL80211_FEATURE_P2P_GO_OPPPS;

@@ -1202,6 +1211,53 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
	mutex_unlock(&mvm->mutex);
}

static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif,
					struct cfg80211_sched_scan_request *req,
					struct ieee80211_sched_scan_ies *ies)
{
	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
	int ret;

	mutex_lock(&mvm->mutex);

	if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
		IWL_DEBUG_SCAN(mvm,
			       "SCHED SCAN request during internal scan - abort\n");
		ret = -EBUSY;
		goto out;
	}

	mvm->scan_status = IWL_MVM_SCAN_SCHED;

	ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
	if (ret)
		goto err;

	ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
	if (ret)
		goto err;

	ret = iwl_mvm_sched_scan_start(mvm, req);
	if (!ret)
		goto out;
err:
	mvm->scan_status = IWL_MVM_SCAN_NONE;
out:
	mutex_unlock(&mvm->mutex);
	return ret;
}

static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif)
{
	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);

	mutex_lock(&mvm->mutex);
	iwl_mvm_sched_scan_stop(mvm);
	mutex_unlock(&mvm->mutex);
}

static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
			       enum set_key_cmd cmd,
			       struct ieee80211_vif *vif,
@@ -1671,6 +1727,8 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
	.set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
	.conf_tx = iwl_mvm_mac_conf_tx,
	.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
	.sched_scan_start = iwl_mvm_mac_sched_scan_start,
	.sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
	.set_key = iwl_mvm_mac_set_key,
	.update_tkip_key = iwl_mvm_mac_update_tkip_key,
	.remain_on_channel = iwl_mvm_roc,
+18 −0
Original line number Diff line number Diff line
@@ -339,6 +339,7 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
enum iwl_scan_status {
	IWL_MVM_SCAN_NONE,
	IWL_MVM_SCAN_OS,
	IWL_MVM_SCAN_SCHED,
};

/**
@@ -696,6 +697,23 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
			     struct iwl_device_cmd *cmd);
void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);

/* Scheduled scan */
int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
					   struct iwl_rx_cmd_buffer *rxb,
					   struct iwl_device_cmd *cmd);
int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
			      struct ieee80211_vif *vif,
			      struct cfg80211_sched_scan_request *req,
			      struct ieee80211_sched_scan_ies *ies);
int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
				       struct cfg80211_sched_scan_request *req);
int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
			     struct cfg80211_sched_scan_request *req);
void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm);
int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
				  struct iwl_rx_cmd_buffer *rxb,
				  struct iwl_device_cmd *cmd);

/* MVM debugfs */
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
Loading