Commit 5167ff45 authored by Shahar S Matityahu's avatar Shahar S Matityahu Committed by Kalle Valo

iwlwifi: scan: support scan req cmd ver 12

Implement scan request command version 12.
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 687db6ff
......@@ -912,6 +912,28 @@ struct iwl_scan_channel_params_v3 {
struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V3];
} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_3 */
/**
* struct iwl_scan_channel_params_v4
* @flags: channel flags &enum iwl_scan_channel_flags
* @count: num of channels in scan request
* @num_of_aps_override: override the number of APs the FW uses to calculate
* dwell time when adaptive dwell is used
* @reserved: for future use and alignment
* @channel_config: array of explicit channel configurations
* for 2.4Ghz and 5.2Ghz bands
* @adwell_ch_override_bitmap: when using adaptive dwell, override the number
* of APs value with &num_of_aps_override for the channel.
* To cast channel to index, use &iwl_mvm_scan_ch_and_band_to_idx
*/
struct iwl_scan_channel_params_v4 {
u8 flags;
u8 count;
u8 num_of_aps_override;
u8 reserved;
struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V3];
u8 adwell_ch_override_bitmap[16];
} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_4 */
/**
* struct iwl_scan_general_params_v10
* @flags: &enum iwl_umac_scan_flags
......@@ -978,6 +1000,20 @@ struct iwl_scan_req_params_v11 {
struct iwl_scan_probe_params_v3 probe_params;
} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_11 */
/**
* struct iwl_scan_req_params_v12
* @general_params: &struct iwl_scan_general_params_v10
* @channel_params: &struct iwl_scan_channel_params_v4
* @periodic_params: &struct iwl_scan_periodic_parms_v1
* @probe_params: &struct iwl_scan_probe_params_v3
*/
struct iwl_scan_req_params_v12 {
struct iwl_scan_general_params_v10 general_params;
struct iwl_scan_channel_params_v4 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_12 */
/**
* struct iwl_scan_req_umac_v11
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
......@@ -990,6 +1026,18 @@ struct iwl_scan_req_umac_v11 {
struct iwl_scan_req_params_v11 scan_params;
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_11 */
/**
* struct iwl_scan_req_umac_v12
* @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_v12 {
__le32 uid;
__le32 ooc_priority;
struct iwl_scan_req_params_v12 scan_params;
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_12 */
/**
* struct iwl_umac_scan_abort
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
......
......@@ -89,6 +89,10 @@
#define IWL_SCAN_ADWELL_DEFAULT_LB_N_APS 2
/* adaptive dwell default APs number in social channels (1, 6, 11) */
#define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
/* number of scan channels */
#define IWL_SCAN_NUM_CHANNELS 112
/* adaptive dwell default number of APs override */
#define IWL_SCAN_ADWELL_DEFAULT_N_APS_OVERRIDE 10
struct iwl_mvm_scan_timing_params {
u32 suspend_time;
......@@ -1459,6 +1463,104 @@ iwl_mvm_scan_umac_dwell_v10(struct iwl_mvm *mvm,
general_params->passive_dwell[SCAN_HB_LMAC_IDX] = passive_dwell;
}
struct iwl_mvm_scan_channel_segment {
u8 start_idx;
u8 end_idx;
u8 first_channel_id;
u8 last_channel_id;
u8 channel_spacing_shift;
u8 band;
};
static const struct iwl_mvm_scan_channel_segment scan_channel_segments[] = {
{
.start_idx = 0,
.end_idx = 13,
.first_channel_id = 1,
.last_channel_id = 14,
.channel_spacing_shift = 0,
.band = PHY_BAND_24
},
{
.start_idx = 14,
.end_idx = 41,
.first_channel_id = 36,
.last_channel_id = 144,
.channel_spacing_shift = 2,
.band = PHY_BAND_5
},
{
.start_idx = 42,
.end_idx = 50,
.first_channel_id = 149,
.last_channel_id = 181,
.channel_spacing_shift = 2,
.band = PHY_BAND_5
},
};
static int iwl_mvm_scan_ch_and_band_to_idx(u8 channel_id, u8 band)
{
int i, index;
if (!channel_id)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(scan_channel_segments); i++) {
const struct iwl_mvm_scan_channel_segment *ch_segment =
&scan_channel_segments[i];
u32 ch_offset;
if (ch_segment->band != band ||
ch_segment->first_channel_id > channel_id ||
ch_segment->last_channel_id < channel_id)
continue;
ch_offset = (channel_id - ch_segment->first_channel_id) >>
ch_segment->channel_spacing_shift;
index = scan_channel_segments[i].start_idx + ch_offset;
if (index < IWL_SCAN_NUM_CHANNELS)
return index;
break;
}
return -EINVAL;
}
static void iwl_mvm_scan_ch_add_n_aps_override(enum nl80211_iftype vif_type,
u8 ch_id, u8 band, u8 *ch_bitmap,
size_t bitmap_n_entries)
{
int i;
static const u8 p2p_go_friendly_chs[] = {
36, 40, 44, 48, 149, 153, 157, 161, 165,
};
if (vif_type != NL80211_IFTYPE_P2P_DEVICE)
return;
for (i = 0; i < ARRAY_SIZE(p2p_go_friendly_chs); i++) {
if (p2p_go_friendly_chs[i] == ch_id) {
int ch_idx, bitmap_idx;
ch_idx = iwl_mvm_scan_ch_and_band_to_idx(ch_id, band);
if (ch_idx < 0)
return;
bitmap_idx = ch_idx / 8;
if (bitmap_idx >= bitmap_n_entries)
return;
ch_idx = ch_idx % 8;
ch_bitmap[bitmap_idx] |= BIT(ch_idx);
return;
}
}
}
static void
iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
struct ieee80211_channel **channels,
......@@ -1484,6 +1586,35 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
}
}
static void
iwl_mvm_umac_scan_cfg_channels_v4(struct iwl_mvm *mvm,
struct ieee80211_channel **channels,
struct iwl_scan_channel_params_v4 *cp,
int n_channels, u32 flags,
enum nl80211_iftype vif_type)
{
u8 *bitmap = cp->adwell_ch_override_bitmap;
size_t bitmap_n_entries = ARRAY_SIZE(cp->adwell_ch_override_bitmap);
int i;
for (i = 0; i < n_channels; i++) {
enum nl80211_band band = channels[i]->band;
struct iwl_scan_channel_cfg_umac *cfg =
&cp->channel_config[i];
cfg->flags = cpu_to_le32(flags);
cfg->v2.channel_num = channels[i]->hw_value;
cfg->v2.band = iwl_mvm_phy_band_from_nl80211(band);
cfg->v2.iter_count = 1;
cfg->v2.iter_interval = 0;
iwl_mvm_scan_ch_add_n_aps_override(vif_type,
cfg->v2.channel_num,
cfg->v2.band, bitmap,
bitmap_n_entries);
}
}
static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif)
......@@ -1782,6 +1913,20 @@ iwl_mvm_scan_umac_fill_ch_p_v3(struct iwl_mvm *mvm,
cp->channel_config);
}
static void
iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
struct ieee80211_vif *vif,
struct iwl_scan_channel_params_v4 *cp)
{
cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
cp->count = params->n_channels;
cp->num_of_aps_override = IWL_SCAN_ADWELL_DEFAULT_N_APS_OVERRIDE;
iwl_mvm_umac_scan_cfg_channels_v4(mvm, params->channels, cp,
params->n_channels, 0, vif->type);
}
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)
......@@ -1814,6 +1959,38 @@ static int iwl_mvm_scan_umac_v11(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return 0;
}
static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params, int type,
int uid)
{
struct iwl_scan_req_umac_v12 *cmd = mvm->scan_cmd;
struct iwl_scan_req_params_v12 *scan_p = &cmd->scan_params;
int ret;
u16 gen_flags;
mvm->scan_uid_status[uid] = type;
cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params));
cmd->uid = cpu_to_le32(uid);
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,
scan_p->periodic_params.schedule,
&scan_p->periodic_params.delay);
if (ret)
return ret;
iwl_mvm_scan_umac_fill_probe_p_v3(params, &scan_p->probe_params);
iwl_mvm_scan_umac_fill_ch_p_v4(mvm, params, vif,
&scan_p->channel_params);
return 0;
}
static int iwl_mvm_num_scans(struct iwl_mvm *mvm)
{
return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK);
......@@ -1928,6 +2105,8 @@ struct iwl_scan_umac_handler {
}
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(12),
IWL_SCAN_UMAC_HANDLER(11),
};
......@@ -2285,6 +2464,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
static int iwl_scan_req_umac_get_size(u8 scan_ver)
{
switch (scan_ver) {
IWL_SCAN_REQ_UMAC_HANDLE_SIZE(12);
IWL_SCAN_REQ_UMAC_HANDLE_SIZE(11);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment