Commit de645c93 authored by Ayala Beker's avatar Ayala Beker Committed by Luca Coelho

iwlwifi: scan: add support for new scan request command version

Scan API was changed to support 6Ghz channels as well.
Support the new version.
Signed-off-by: default avatarAyala Beker <ayala.beker@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent aa43ae12
...@@ -93,6 +93,8 @@ struct iwl_ssid_ie { ...@@ -93,6 +93,8 @@ struct iwl_ssid_ie {
#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 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_2 3
/* Default watchdog (in MS) for scheduled scan iteration */ /* Default watchdog (in MS) for scheduled scan iteration */
#define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000) #define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000)
...@@ -251,9 +253,22 @@ struct iwl_scan_probe_segment { ...@@ -251,9 +253,22 @@ struct iwl_scan_probe_segment {
* @common_data: last (and common) part of the probe * @common_data: last (and common) part of the probe
* @buf: raw data block * @buf: raw data block
*/ */
struct iwl_scan_probe_req_v1 {
struct iwl_scan_probe_segment mac_header;
struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_1];
struct iwl_scan_probe_segment common_data;
u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
} __packed;
/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2
* @mac_header: first (and common) part of the probe
* @band_data: band specific data
* @common_data: last (and common) part of the probe
* @buf: raw data block
*/
struct iwl_scan_probe_req { struct iwl_scan_probe_req {
struct iwl_scan_probe_segment mac_header; struct iwl_scan_probe_segment mac_header;
struct iwl_scan_probe_segment band_data[2]; struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_2];
struct iwl_scan_probe_segment common_data; struct iwl_scan_probe_segment common_data;
u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE]; u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
} __packed; } __packed;
...@@ -608,15 +623,29 @@ enum iwl_umac_scan_general_flags2 { ...@@ -608,15 +623,29 @@ enum iwl_umac_scan_general_flags2 {
* struct iwl_scan_channel_cfg_umac * struct iwl_scan_channel_cfg_umac
* @flags: bitmap - 0-19: directed scan to i'th ssid. * @flags: bitmap - 0-19: directed scan to i'th ssid.
* @channel_num: channel number 1-13 etc. * @channel_num: channel number 1-13 etc.
* @band: band of channel: 0 for 2GHz, 1 for 5GHz
* @iter_count: repetition count for the channel. * @iter_count: repetition count for the channel.
* @iter_interval: interval between two scan iterations on one channel. * @iter_interval: interval between two scan iterations on one channel.
*/ */
struct iwl_scan_channel_cfg_umac { struct iwl_scan_channel_cfg_umac {
__le32 flags; __le32 flags;
u8 channel_num; /* Both versions are of the same size, so use a union without adjusting
u8 iter_count; * the command size later
__le16 iter_interval; */
} __packed; /* SCAN_CHANNEL_CFG_S_VER2 */ union {
struct {
u8 channel_num;
u8 iter_count;
__le16 iter_interval;
} v1; /* SCAN_CHANNEL_CFG_S_VER1 */
struct {
u8 channel_num;
u8 band;
u8 iter_count;
u8 iter_interval;
} v2; /* SCAN_CHANNEL_CFG_S_VER2 */
};
} __packed;
/** /**
* struct iwl_scan_umac_schedule * struct iwl_scan_umac_schedule
...@@ -630,6 +659,16 @@ struct iwl_scan_umac_schedule { ...@@ -630,6 +659,16 @@ struct iwl_scan_umac_schedule {
u8 reserved; u8 reserved;
} __packed; /* SCAN_SCHED_PARAM_API_S_VER_1 */ } __packed; /* SCAN_SCHED_PARAM_API_S_VER_1 */
struct iwl_scan_req_umac_tail_v1 {
/* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
__le16 delay;
__le16 reserved;
/* SCAN_PROBE_PARAMS_API_S_VER_1 */
struct iwl_scan_probe_req_v1 preq;
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
} __packed;
/** /**
* struct iwl_scan_req_umac_tail - the rest of the UMAC scan request command * struct iwl_scan_req_umac_tail - the rest of the UMAC scan request command
* parameters following channels configuration array. * parameters following channels configuration array.
...@@ -639,12 +678,12 @@ struct iwl_scan_umac_schedule { ...@@ -639,12 +678,12 @@ struct iwl_scan_umac_schedule {
* @preq: probe request with IEs blocks * @preq: probe request with IEs blocks
* @direct_scan: list of SSIDs for directed active scan * @direct_scan: list of SSIDs for directed active scan
*/ */
struct iwl_scan_req_umac_tail { struct iwl_scan_req_umac_tail_v2 {
/* SCAN_PERIODIC_PARAMS_API_S_VER_1 */ /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS]; struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
__le16 delay; __le16 delay;
__le16 reserved; __le16 reserved;
/* SCAN_PROBE_PARAMS_API_S_VER_1 */ /* SCAN_PROBE_PARAMS_API_S_VER_2 */
struct iwl_scan_probe_req preq; struct iwl_scan_probe_req preq;
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
} __packed; } __packed;
......
...@@ -323,6 +323,7 @@ enum iwl_ucode_tlv_api { ...@@ -323,6 +323,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54, IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54,
IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55, IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55,
IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57, IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57,
IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58,
NUM_IWL_UCODE_TLV_API NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__ #ifdef __CHECKER__
......
...@@ -1387,6 +1387,12 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm) ...@@ -1387,6 +1387,12 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm)
return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000; return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000;
} }
static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm)
{
return fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER);
}
static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
{ {
return fw_has_api(&mvm->fw->ucode_capa, return fw_has_api(&mvm->fw->ucode_capa,
......
...@@ -77,7 +77,10 @@ ...@@ -77,7 +77,10 @@
#define IWL_SCAN_DWELL_FRAGMENTED 44 #define IWL_SCAN_DWELL_FRAGMENTED 44
#define IWL_SCAN_DWELL_EXTENDED 90 #define IWL_SCAN_DWELL_EXTENDED 90
#define IWL_SCAN_NUM_OF_FRAGS 3 #define IWL_SCAN_NUM_OF_FRAGS 3
#define IWL_SCAN_LAST_2_4_CHN 14
#define IWL_SCAN_BAND_5_2 0
#define IWL_SCAN_BAND_2_4 1
/* adaptive dwell max budget time [TU] for full scan */ /* adaptive dwell max budget time [TU] for full scan */
#define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300 #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
...@@ -956,11 +959,24 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, ...@@ -956,11 +959,24 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
return flags; return flags;
} }
static void
iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req,
struct iwl_scan_probe_req src_p_req)
{
int i;
p_req->mac_header = src_p_req.mac_header;
for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++)
p_req->band_data[i] = src_p_req.band_data[i];
p_req->common_data = src_p_req.common_data;
memcpy(p_req->buf, src_p_req.buf, SCAN_OFFLOAD_PROBE_REQ_SIZE);
}
static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params) struct iwl_mvm_scan_params *params)
{ {
struct iwl_scan_req_lmac *cmd = mvm->scan_cmd; struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
struct iwl_scan_probe_req *preq = struct iwl_scan_probe_req_v1 *preq =
(void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) *
mvm->fw->ucode_capa.n_scan_channels); mvm->fw->ucode_capa.n_scan_channels);
u32 ssid_bitmap = 0; u32 ssid_bitmap = 0;
...@@ -1030,7 +1046,7 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1030,7 +1046,7 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels, iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
params->n_channels, ssid_bitmap, cmd); params->n_channels, ssid_bitmap, cmd);
*preq = params->preq; iwl_mvm_scan_set_legacy_probe_req(preq, params->preq);
return 0; return 0;
} }
...@@ -1384,9 +1400,17 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm, ...@@ -1384,9 +1400,17 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
for (i = 0; i < n_channels; i++) { for (i = 0; i < n_channels; i++) {
channel_cfg[i].flags = cpu_to_le32(ssid_bitmap); channel_cfg[i].flags = cpu_to_le32(ssid_bitmap);
channel_cfg[i].channel_num = channels[i]->hw_value; channel_cfg[i].v1.channel_num = channels[i]->hw_value;
channel_cfg[i].iter_count = 1; if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
channel_cfg[i].iter_interval = 0; channel_cfg[i].v2.band =
channels[i]->hw_value <= IWL_SCAN_LAST_2_4_CHN ?
IWL_SCAN_BAND_2_4 : IWL_SCAN_BAND_5_2;
channel_cfg[i].v2.iter_count = 1;
channel_cfg[i].v2.iter_interval = 0;
} else {
channel_cfg[i].v1.iter_count = 1;
channel_cfg[i].v1.iter_interval = 0;
}
} }
} }
...@@ -1476,9 +1500,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1476,9 +1500,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_scan_req_umac *cmd = mvm->scan_cmd; struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
struct iwl_scan_umac_chan_param *chan_param; struct iwl_scan_umac_chan_param *chan_param;
void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm); void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
struct iwl_scan_req_umac_tail *sec_part = cmd_data + void *sec_part = cmd_data + sizeof(struct iwl_scan_channel_cfg_umac) *
sizeof(struct iwl_scan_channel_cfg_umac) * mvm->fw->ucode_capa.n_scan_channels;
mvm->fw->ucode_capa.n_scan_channels; struct iwl_scan_req_umac_tail_v2 *tail_v2 =
(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, i; int uid, i;
u32 ssid_bitmap = 0; u32 ssid_bitmap = 0;
u8 channel_flags = 0; u8 channel_flags = 0;
...@@ -1540,18 +1567,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1540,18 +1567,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
chan_param->flags = channel_flags; chan_param->flags = channel_flags;
chan_param->count = params->n_channels; chan_param->count = params->n_channels;
iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap);
iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
params->n_channels, ssid_bitmap,
cmd_data);
for (i = 0; i < params->n_scan_plans; i++) { for (i = 0; i < params->n_scan_plans; i++) {
struct cfg80211_sched_scan_plan *scan_plan = struct cfg80211_sched_scan_plan *scan_plan =
&params->scan_plans[i]; &params->scan_plans[i];
sec_part->schedule[i].iter_count = scan_plan->iterations; tail_v2->schedule[i].iter_count = scan_plan->iterations;
sec_part->schedule[i].interval = tail_v2->schedule[i].interval =
cpu_to_le16(scan_plan->interval); cpu_to_le16(scan_plan->interval);
} }
...@@ -1561,12 +1582,23 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1561,12 +1582,23 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
* For example, when regular scan is requested the driver sets one scan * For example, when regular scan is requested the driver sets one scan
* plan with one iteration. * plan with one iteration.
*/ */
if (!sec_part->schedule[i - 1].iter_count) if (!tail_v2->schedule[i - 1].iter_count)
sec_part->schedule[i - 1].iter_count = 0xff; tail_v2->schedule[i - 1].iter_count = 0xff;
sec_part->delay = cpu_to_le16(params->delay); tail_v2->delay = cpu_to_le16(params->delay);
sec_part->preq = params->preq;
if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
tail_v2->preq = params->preq;
direct_scan = tail_v2->direct_scan;
} else {
tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part;
iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq, params->preq);
direct_scan = tail_v1->direct_scan;
}
iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap);
iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
params->n_channels, ssid_bitmap,
cmd_data);
return 0; return 0;
} }
...@@ -1996,6 +2028,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type) ...@@ -1996,6 +2028,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
int iwl_mvm_scan_size(struct iwl_mvm *mvm) int iwl_mvm_scan_size(struct iwl_mvm *mvm)
{ {
int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1; int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
int tail_size;
if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
base_size = IWL_SCAN_REQ_UMAC_SIZE_V8; base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
...@@ -2004,16 +2037,21 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) ...@@ -2004,16 +2037,21 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
else if (iwl_mvm_cdb_scan_api(mvm)) else if (iwl_mvm_cdb_scan_api(mvm))
base_size = IWL_SCAN_REQ_UMAC_SIZE_V6; base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
if (iwl_mvm_is_scan_ext_chan_supported(mvm))
tail_size = sizeof(struct iwl_scan_req_umac_tail_v2);
else
tail_size = sizeof(struct iwl_scan_req_umac_tail_v1);
return base_size + return base_size +
sizeof(struct iwl_scan_channel_cfg_umac) * sizeof(struct iwl_scan_channel_cfg_umac) *
mvm->fw->ucode_capa.n_scan_channels + mvm->fw->ucode_capa.n_scan_channels +
sizeof(struct iwl_scan_req_umac_tail); tail_size;
}
return sizeof(struct iwl_scan_req_lmac) + return sizeof(struct iwl_scan_req_lmac) +
sizeof(struct iwl_scan_channel_cfg_lmac) * sizeof(struct iwl_scan_channel_cfg_lmac) *
mvm->fw->ucode_capa.n_scan_channels + mvm->fw->ucode_capa.n_scan_channels +
sizeof(struct iwl_scan_probe_req); sizeof(struct iwl_scan_probe_req_v1);
} }
/* /*
......
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