iwlwifi: scan: support FW APIs with variable number of profiles
The FW changed the maximum number of scan offload profiles to 8 in new APIs. Support it by changing the scan_offload_profile_cfg struct to be more dynamic, so we can reuse most of the code and only change size of the profiles array. Change-Id: I65210cf541af46e2675a8c764d5871f7f5b070d6 Signed-off-by: Tova Mussai <tova.mussai@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
e8b61560ef
commit
5d1234ba25
|
@ -95,6 +95,7 @@ struct iwl_ssid_ie {
|
||||||
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
|
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
|
||||||
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
|
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
|
||||||
#define IWL_SCAN_MAX_PROFILES 11
|
#define IWL_SCAN_MAX_PROFILES 11
|
||||||
|
#define IWL_SCAN_MAX_PROFILES_V2 8
|
||||||
#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
|
#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
|
||||||
#define SCAN_NUM_BAND_PROBE_DATA_V_1 2
|
#define SCAN_NUM_BAND_PROBE_DATA_V_1 2
|
||||||
#define SCAN_NUM_BAND_PROBE_DATA_V_2 3
|
#define SCAN_NUM_BAND_PROBE_DATA_V_2 3
|
||||||
|
@ -160,8 +161,7 @@ struct iwl_scan_offload_profile {
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_scan_offload_profile_cfg - SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1
|
* struct iwl_scan_offload_profile_cfg_data
|
||||||
* @profiles: profiles to search for match
|
|
||||||
* @blacklist_len: length of blacklist
|
* @blacklist_len: length of blacklist
|
||||||
* @num_profiles: num of profiles in the list
|
* @num_profiles: num of profiles in the list
|
||||||
* @match_notify: clients waiting for match found notification
|
* @match_notify: clients waiting for match found notification
|
||||||
|
@ -170,8 +170,7 @@ struct iwl_scan_offload_profile {
|
||||||
* @any_beacon_notify: clients waiting for match notification without match
|
* @any_beacon_notify: clients waiting for match notification without match
|
||||||
* @reserved: reserved
|
* @reserved: reserved
|
||||||
*/
|
*/
|
||||||
struct iwl_scan_offload_profile_cfg {
|
struct iwl_scan_offload_profile_cfg_data {
|
||||||
struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
|
|
||||||
u8 blacklist_len;
|
u8 blacklist_len;
|
||||||
u8 num_profiles;
|
u8 num_profiles;
|
||||||
u8 match_notify;
|
u8 match_notify;
|
||||||
|
@ -181,6 +180,26 @@ struct iwl_scan_offload_profile_cfg {
|
||||||
u8 reserved[2];
|
u8 reserved[2];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_scan_offload_profile_cfg
|
||||||
|
* @profiles: profiles to search for match
|
||||||
|
* @data: the rest of the data for profile_cfg
|
||||||
|
*/
|
||||||
|
struct iwl_scan_offload_profile_cfg_v1 {
|
||||||
|
struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
|
||||||
|
struct iwl_scan_offload_profile_cfg_data data;
|
||||||
|
} __packed; /* SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1-2*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_scan_offload_profile_cfg
|
||||||
|
* @profiles: profiles to search for match
|
||||||
|
* @data: the rest of the data for profile_cfg
|
||||||
|
*/
|
||||||
|
struct iwl_scan_offload_profile_cfg {
|
||||||
|
struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES_V2];
|
||||||
|
struct iwl_scan_offload_profile_cfg_data data;
|
||||||
|
} __packed; /* SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_3*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_scan_schedule_lmac - schedule of scan offload
|
* struct iwl_scan_schedule_lmac - schedule of scan offload
|
||||||
* @delay: delay between iterations, in seconds.
|
* @delay: delay between iterations, in seconds.
|
||||||
|
@ -1169,7 +1188,7 @@ struct iwl_scan_offload_profiles_query_v1 {
|
||||||
u8 resume_while_scanning;
|
u8 resume_while_scanning;
|
||||||
u8 self_recovery;
|
u8 self_recovery;
|
||||||
__le16 reserved;
|
__le16 reserved;
|
||||||
struct iwl_scan_offload_profile_match_v1 matches[IWL_SCAN_MAX_PROFILES];
|
struct iwl_scan_offload_profile_match_v1 matches[0];
|
||||||
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
|
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1213,7 +1232,7 @@ struct iwl_scan_offload_profiles_query {
|
||||||
u8 resume_while_scanning;
|
u8 resume_while_scanning;
|
||||||
u8 self_recovery;
|
u8 self_recovery;
|
||||||
__le16 reserved;
|
__le16 reserved;
|
||||||
struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
|
struct iwl_scan_offload_profile_match matches[0];
|
||||||
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 */
|
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1709,6 +1709,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
|
||||||
};
|
};
|
||||||
int ret, len;
|
int ret, len;
|
||||||
size_t query_len, matches_len;
|
size_t query_len, matches_len;
|
||||||
|
int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
|
||||||
|
|
||||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -1720,11 +1721,11 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
|
||||||
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
|
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
|
||||||
query_len = sizeof(struct iwl_scan_offload_profiles_query);
|
query_len = sizeof(struct iwl_scan_offload_profiles_query);
|
||||||
matches_len = sizeof(struct iwl_scan_offload_profile_match) *
|
matches_len = sizeof(struct iwl_scan_offload_profile_match) *
|
||||||
IWL_SCAN_MAX_PROFILES;
|
max_profiles;
|
||||||
} else {
|
} else {
|
||||||
query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
|
query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
|
||||||
matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
|
matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
|
||||||
IWL_SCAN_MAX_PROFILES;
|
max_profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
|
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
|
||||||
|
|
|
@ -617,7 +617,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||||
|
|
||||||
hw->wiphy->max_sched_scan_reqs = 1;
|
hw->wiphy->max_sched_scan_reqs = 1;
|
||||||
hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
|
hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
|
||||||
hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
|
hw->wiphy->max_match_sets = iwl_umac_scan_get_max_profiles(mvm->fw);
|
||||||
/* we create the 802.11 header and zero length SSID IE. */
|
/* we create the 802.11 header and zero length SSID IE. */
|
||||||
hw->wiphy->max_sched_scan_ie_len =
|
hw->wiphy->max_sched_scan_ie_len =
|
||||||
SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
|
SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
|
||||||
|
@ -705,7 +705,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||||
mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
|
mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
|
||||||
mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
|
mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
|
||||||
mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
|
mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
|
||||||
mvm->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES;
|
mvm->wowlan.max_nd_match_sets =
|
||||||
|
iwl_umac_scan_get_max_profiles(mvm->fw);
|
||||||
hw->wiphy->wowlan = &mvm->wowlan;
|
hw->wiphy->wowlan = &mvm->wowlan;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2147,4 +2147,11 @@ iwl_mvm_set_chan_info_chandef(struct iwl_mvm *mvm,
|
||||||
iwl_mvm_get_ctrl_pos(chandef));
|
iwl_mvm_get_ctrl_pos(chandef));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int iwl_umac_scan_get_max_profiles(const struct iwl_fw *fw)
|
||||||
|
{
|
||||||
|
u8 ver = iwl_mvm_lookup_cmd_ver(fw, IWL_ALWAYS_LONG_GROUP,
|
||||||
|
SCAN_OFFLOAD_UPDATE_PROFILES_CMD);
|
||||||
|
return (ver == IWL_FW_CMD_VER_UNKNOWN || ver < 3) ?
|
||||||
|
IWL_SCAN_MAX_PROFILES : IWL_SCAN_MAX_PROFILES_V2;
|
||||||
|
}
|
||||||
#endif /* __IWL_MVM_H__ */
|
#endif /* __IWL_MVM_H__ */
|
||||||
|
|
|
@ -594,11 +594,15 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
|
||||||
struct cfg80211_sched_scan_request *req)
|
struct cfg80211_sched_scan_request *req)
|
||||||
{
|
{
|
||||||
struct iwl_scan_offload_profile *profile;
|
struct iwl_scan_offload_profile *profile;
|
||||||
struct iwl_scan_offload_profile_cfg *profile_cfg;
|
struct iwl_scan_offload_profile_cfg_v1 *profile_cfg_v1;
|
||||||
struct iwl_scan_offload_blacklist *blacklist;
|
struct iwl_scan_offload_blacklist *blacklist;
|
||||||
|
struct iwl_scan_offload_profile_cfg_data *data;
|
||||||
|
int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
|
||||||
|
int profile_cfg_size = sizeof(*data) +
|
||||||
|
sizeof(*profile) * max_profiles;
|
||||||
struct iwl_host_cmd cmd = {
|
struct iwl_host_cmd cmd = {
|
||||||
.id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD,
|
.id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD,
|
||||||
.len[1] = sizeof(*profile_cfg),
|
.len[1] = profile_cfg_size,
|
||||||
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
||||||
.dataflags[1] = IWL_HCMD_DFL_NOCOPY,
|
.dataflags[1] = IWL_HCMD_DFL_NOCOPY,
|
||||||
};
|
};
|
||||||
|
@ -606,7 +610,7 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES))
|
if (WARN_ON(req->n_match_sets > max_profiles))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
|
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
|
||||||
|
@ -618,27 +622,37 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
|
||||||
if (!blacklist)
|
if (!blacklist)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
profile_cfg = kzalloc(sizeof(*profile_cfg), GFP_KERNEL);
|
profile_cfg_v1 = kzalloc(profile_cfg_size, GFP_KERNEL);
|
||||||
if (!profile_cfg) {
|
if (!profile_cfg_v1) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto free_blacklist;
|
goto free_blacklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.data[0] = blacklist;
|
cmd.data[0] = blacklist;
|
||||||
cmd.len[0] = sizeof(*blacklist) * blacklist_len;
|
cmd.len[0] = sizeof(*blacklist) * blacklist_len;
|
||||||
cmd.data[1] = profile_cfg;
|
cmd.data[1] = profile_cfg_v1;
|
||||||
|
|
||||||
|
/* if max_profile is MAX_PROFILES_V2, we have the new API */
|
||||||
|
if (max_profiles == IWL_SCAN_MAX_PROFILES_V2) {
|
||||||
|
struct iwl_scan_offload_profile_cfg *profile_cfg =
|
||||||
|
(struct iwl_scan_offload_profile_cfg *)profile_cfg_v1;
|
||||||
|
|
||||||
|
data = &profile_cfg->data;
|
||||||
|
} else {
|
||||||
|
data = &profile_cfg_v1->data;
|
||||||
|
}
|
||||||
|
|
||||||
/* No blacklist configuration */
|
/* No blacklist configuration */
|
||||||
|
data->num_profiles = req->n_match_sets;
|
||||||
|
data->active_clients = SCAN_CLIENT_SCHED_SCAN;
|
||||||
|
data->pass_match = SCAN_CLIENT_SCHED_SCAN;
|
||||||
|
data->match_notify = SCAN_CLIENT_SCHED_SCAN;
|
||||||
|
|
||||||
profile_cfg->num_profiles = req->n_match_sets;
|
|
||||||
profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN;
|
|
||||||
profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN;
|
|
||||||
profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN;
|
|
||||||
if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
|
if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
|
||||||
profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
|
data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
|
||||||
|
|
||||||
for (i = 0; i < req->n_match_sets; i++) {
|
for (i = 0; i < req->n_match_sets; i++) {
|
||||||
profile = &profile_cfg->profiles[i];
|
profile = &profile_cfg_v1->profiles[i];
|
||||||
profile->ssid_index = i;
|
profile->ssid_index = i;
|
||||||
/* Support any cipher and auth algorithm */
|
/* Support any cipher and auth algorithm */
|
||||||
profile->unicast_cipher = 0xff;
|
profile->unicast_cipher = 0xff;
|
||||||
|
@ -651,7 +665,7 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
|
||||||
IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n");
|
IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n");
|
||||||
|
|
||||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||||
kfree(profile_cfg);
|
kfree(profile_cfg_v1);
|
||||||
free_blacklist:
|
free_blacklist:
|
||||||
kfree(blacklist);
|
kfree(blacklist);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue