* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
};
/**
+ * enum iwl_umac_scan_general_flags2 - UMAC scan general flags #2
+ * @IWL_UMAC_SCAN_GEN_FLAGS2_NOTIF_PER_CHNL: Whether to send a complete
+ * notification per channel or not.
+ */
+enum iwl_umac_scan_general_flags2 {
+ IWL_UMAC_SCAN_GEN_FLAGS2_NOTIF_PER_CHNL = BIT(0),
+};
+
+/**
* struct iwl_scan_channel_cfg_umac
* @flags: bitmap - 0-19: directed scan to i'th ssid.
* @channel_num: channel number 1-13 etc.
} __packed;
/**
+ * struct iwl_scan_umac_chan_param
+ * @flags: channel flags &enum iwl_scan_channel_flags
+ * @count: num of channels in scan request
+ * @reserved: for future use and alignment
+ */
+struct iwl_scan_umac_chan_param {
+ u8 flags;
+ u8 count;
+ __le16 reserved;
+} __packed; /*SCAN_CHANNEL_PARAMS_API_S_VER_1 */
+
+/**
* struct iwl_scan_req_umac
* @flags: &enum iwl_umac_scan_flags
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
* @general_flags: &enum iwl_umac_scan_general_flags
* @scan_start_mac_id: report the scan start TSF time according to this mac TSF
* @extended_dwell: dwell time for channels 1, 6 and 11
- * @active_dwell: dwell time for active scan
- * @passive_dwell: dwell time for passive scan
+ * @active_dwell: dwell time for active scan per LMAC
+ * @passive_dwell: dwell time for passive scan per LMAC
* @fragmented_dwell: dwell time for fragmented passive scan
* @adwell_default_n_aps: for adaptive dwell the default number of APs
* per channel
* @adwell_default_n_aps_social: for adaptive dwell the default
* number of APs per social (1,6,11) channel
+ * @general_flags2: &enum iwl_umac_scan_general_flags2
* @adwell_max_budget: for adaptive dwell the maximal budget of TU to be added
* to total scan time
* @max_out_time: max out of serving channel time, per LMAC - for CDB there
* are 2 LMACs
* @suspend_time: max suspend time, per LMAC - for CDB there are 2 LMACs
* @scan_priority: scan internal prioritization &enum iwl_scan_priority
- * @channel_flags: &enum iwl_scan_channel_flags
- * @n_channels: num of channels in scan request
+ * @num_of_fragments: Number of fragments needed for full coverage per band.
+ * Relevant only for fragmented scan.
+ * @channel: &struct iwl_scan_umac_chan_param
* @reserved: for future use and alignment
- * @reserved2: for future use and alignment
* @reserved3: for future use and alignment
* @data: &struct iwl_scan_channel_cfg_umac and
* &struct iwl_scan_req_umac_tail
__le32 max_out_time;
__le32 suspend_time;
__le32 scan_priority;
- /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */
- u8 channel_flags;
- u8 n_channels;
- __le16 reserved2;
+ struct iwl_scan_umac_chan_param channel;
u8 data[];
} v1; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */
struct {
__le32 max_out_time[SCAN_TWO_LMACS];
__le32 suspend_time[SCAN_TWO_LMACS];
__le32 scan_priority;
- /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */
- u8 channel_flags;
- u8 n_channels;
- __le16 reserved2;
+ struct iwl_scan_umac_chan_param channel;
u8 data[];
} v6; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_6 */
struct {
__le32 max_out_time[SCAN_TWO_LMACS];
__le32 suspend_time[SCAN_TWO_LMACS];
__le32 scan_priority;
- /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */
- u8 channel_flags;
- u8 n_channels;
- __le16 reserved2;
+ struct iwl_scan_umac_chan_param channel;
u8 data[];
} v7; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_7 */
+ struct {
+ u8 active_dwell[SCAN_TWO_LMACS];
+ u8 reserved2;
+ u8 adwell_default_n_aps;
+ u8 adwell_default_n_aps_social;
+ u8 general_flags2;
+ __le16 adwell_max_budget;
+ __le32 max_out_time[SCAN_TWO_LMACS];
+ __le32 suspend_time[SCAN_TWO_LMACS];
+ __le32 scan_priority;
+ u8 passive_dwell[SCAN_TWO_LMACS];
+ u8 num_of_fragments[SCAN_TWO_LMACS];
+ struct iwl_scan_umac_chan_param channel;
+ u8 data[];
+ } v8; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_8 */
};
} __packed;
-#define IWL_SCAN_REQ_UMAC_SIZE_V7 sizeof(struct iwl_scan_req_umac)
+#define IWL_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwl_scan_req_umac)
+#define IWL_SCAN_REQ_UMAC_SIZE_V7 (sizeof(struct iwl_scan_req_umac) - \
+ 4 * sizeof(u8))
#define IWL_SCAN_REQ_UMAC_SIZE_V6 (sizeof(struct iwl_scan_req_umac) - \
2 * sizeof(u8) - sizeof(__le16))
#define IWL_SCAN_REQ_UMAC_SIZE_V1 (sizeof(struct iwl_scan_req_umac) - \
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#define IWL_SCAN_DWELL_PASSIVE 110
#define IWL_SCAN_DWELL_FRAGMENTED 44
#define IWL_SCAN_DWELL_EXTENDED 90
+#define IWL_SCAN_NUM_OF_FRAGS 3
+
/* adaptive dwell max budget time [TU] for full scan */
#define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
{
struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
+ if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
+ return (void *)&cmd->v8.data;
+
if (iwl_mvm_is_adaptive_dwell_supported(mvm))
return (void *)&cmd->v7.data;
return (void *)&cmd->v1.data;
}
+static inline struct iwl_scan_umac_chan_param *
+iwl_mvm_get_scan_req_umac_channel(struct iwl_mvm *mvm)
+{
+ struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
+
+ if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
+ return &cmd->v8.channel;
+
+ if (iwl_mvm_is_adaptive_dwell_supported(mvm))
+ return &cmd->v7.channel;
+
+ if (iwl_mvm_has_new_tx_api(mvm))
+ return &cmd->v6.channel;
+
+ return &cmd->v1.channel;
+}
+
static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
{
if (mvm->scan_rx_ant != ANT_NONE)
struct iwl_scan_req_umac *cmd,
struct iwl_mvm_scan_params *params)
{
- struct iwl_mvm_scan_timing_params *timing = &scan_timing[params->type];
+ struct iwl_mvm_scan_timing_params *timing, *hb_timing;
+ u8 active_dwell, passive_dwell;
+
+ timing = &scan_timing[params->type];
+ active_dwell = params->measurement_dwell ?
+ params->measurement_dwell : IWL_SCAN_DWELL_ACTIVE;
+ passive_dwell = params->measurement_dwell ?
+ params->measurement_dwell : IWL_SCAN_DWELL_PASSIVE;
if (iwl_mvm_is_adaptive_dwell_supported(mvm)) {
- if (params->measurement_dwell) {
- cmd->v7.active_dwell = params->measurement_dwell;
- cmd->v7.passive_dwell = params->measurement_dwell;
- } else {
- cmd->v7.active_dwell = IWL_SCAN_DWELL_ACTIVE;
- cmd->v7.passive_dwell = IWL_SCAN_DWELL_PASSIVE;
- }
- cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
cmd->v7.adwell_default_n_aps_social =
IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
cmd->v7.adwell_default_n_aps =
cpu_to_le32(timing->max_out_time);
cmd->v7.suspend_time[SCAN_LB_LMAC_IDX] =
cpu_to_le32(timing->suspend_time);
+
if (iwl_mvm_is_cdb_supported(mvm)) {
- cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] =
- cpu_to_le32(timing->max_out_time);
- cmd->v6.suspend_time[SCAN_HB_LMAC_IDX] =
- cpu_to_le32(timing->suspend_time);
+ hb_timing = &scan_timing[params->type];
+
+ cmd->v7.max_out_time[SCAN_HB_LMAC_IDX] =
+ cpu_to_le32(hb_timing->max_out_time);
+ cmd->v7.suspend_time[SCAN_HB_LMAC_IDX] =
+ cpu_to_le32(hb_timing->suspend_time);
}
- } else {
- if (params->measurement_dwell) {
- cmd->v1.active_dwell = params->measurement_dwell;
- cmd->v1.passive_dwell = params->measurement_dwell;
- cmd->v1.extended_dwell = params->measurement_dwell;
+
+ if (!iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
+ cmd->v7.active_dwell = active_dwell;
+ cmd->v7.passive_dwell = passive_dwell;
+ cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
} else {
- cmd->v1.active_dwell = IWL_SCAN_DWELL_ACTIVE;
- cmd->v1.passive_dwell = IWL_SCAN_DWELL_PASSIVE;
- cmd->v1.extended_dwell = IWL_SCAN_DWELL_EXTENDED;
+ cmd->v8.active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
+ cmd->v8.passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
+ if (iwl_mvm_is_cdb_supported(mvm)) {
+ cmd->v8.active_dwell[SCAN_HB_LMAC_IDX] =
+ active_dwell;
+ cmd->v8.passive_dwell[SCAN_HB_LMAC_IDX] =
+ passive_dwell;
+ }
}
+ } else {
+ cmd->v1.extended_dwell = params->measurement_dwell ?
+ params->measurement_dwell : IWL_SCAN_DWELL_EXTENDED;
+ cmd->v1.active_dwell = active_dwell;
+ cmd->v1.passive_dwell = passive_dwell;
cmd->v1.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
+
if (iwl_mvm_is_cdb_supported(mvm)) {
- struct iwl_mvm_scan_timing_params *hb_timing =
- &scan_timing[params->type];
+ hb_timing = &scan_timing[params->type];
cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] =
cpu_to_le32(hb_timing->max_out_time);
int type)
{
struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
+ struct iwl_scan_umac_chan_param *chan_param;
void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
struct iwl_scan_req_umac_tail *sec_part = cmd_data +
sizeof(struct iwl_scan_channel_cfg_umac) *
int uid, i;
u32 ssid_bitmap = 0;
u8 channel_flags = 0;
+ u16 gen_flags;
struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif);
+ chan_param = iwl_mvm_get_scan_req_umac_channel(mvm);
+
lockdep_assert_held(&mvm->mutex);
if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
mvm->scan_uid_status[uid] = type;
cmd->uid = cpu_to_le32(uid);
- cmd->general_flags = cpu_to_le16(iwl_mvm_scan_umac_flags(mvm, params,
- vif));
+ gen_flags = iwl_mvm_scan_umac_flags(mvm, params, vif);
+ cmd->general_flags = cpu_to_le16(gen_flags);
+ if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
+ if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED)
+ cmd->v8.num_of_fragments[SCAN_LB_LMAC_IDX] =
+ IWL_SCAN_NUM_OF_FRAGS;
+ if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED)
+ cmd->v8.num_of_fragments[SCAN_HB_LMAC_IDX] =
+ IWL_SCAN_NUM_OF_FRAGS;
+ }
+
cmd->scan_start_mac_id = scan_vif->id;
if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT)
IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
- if (iwl_mvm_is_adaptive_dwell_supported(mvm)) {
- cmd->v7.channel_flags = channel_flags;
- cmd->v7.n_channels = params->n_channels;
- } else if (iwl_mvm_has_new_tx_api(mvm)) {
- cmd->v6.channel_flags = channel_flags;
- cmd->v6.n_channels = params->n_channels;
- } else {
- cmd->v1.channel_flags = channel_flags;
- cmd->v1.n_channels = params->n_channels;
- }
+ chan_param->flags = channel_flags;
+ chan_param->count = params->n_channels;
iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap);
{
int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
- if (iwl_mvm_is_adaptive_dwell_supported(mvm))
+ if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
+ base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
+ else if (iwl_mvm_is_adaptive_dwell_supported(mvm))
base_size = IWL_SCAN_REQ_UMAC_SIZE_V7;
else if (iwl_mvm_has_new_tx_api(mvm))
base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;