summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAyala Beker <ayala.beker@intel.com>2019-10-29 11:47:20 -0400
committerKalle Valo <kvalo@codeaurora.org>2019-10-30 11:00:26 -0400
commit3d206e6899a07fe853f703f7e68f84b48b919129 (patch)
tree8edadd5fa15a4a6f31078e921ad5b5af06882fbd
parent7bd0650be63cbb9e45e394d689c81365fe48e495 (diff)
iwlwifi: fw api: support new API for scan config cmd
The API was reduced to include only knowledge currently needed by the FW scan logic, the rest is legacy. Support the new, reduced version. Using the old API with newer firmwares (starting from iwlwifi-*-50.ucode, which implements and requires the new API version) causes an assertion failure similar to this one: [ 2.854505] iwlwifi 0000:00:14.3: 0x20000038 | BAD_COMMAND Signed-off-by: Ayala Beker <ayala.beker@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/scan.h22
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c40
4 files changed, 61 insertions, 10 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
index 39c64850cb6f..c0750ced5ac2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
@@ -520,7 +520,7 @@ struct iwl_scan_dwell {
520} __packed; 520} __packed;
521 521
522/** 522/**
523 * struct iwl_scan_config 523 * struct iwl_scan_config_v1
524 * @flags: enum scan_config_flags 524 * @flags: enum scan_config_flags
525 * @tx_chains: valid_tx antenna - ANT_* definitions 525 * @tx_chains: valid_tx antenna - ANT_* definitions
526 * @rx_chains: valid_rx antenna - ANT_* definitions 526 * @rx_chains: valid_rx antenna - ANT_* definitions
@@ -552,7 +552,7 @@ struct iwl_scan_config_v1 {
552#define SCAN_LB_LMAC_IDX 0 552#define SCAN_LB_LMAC_IDX 0
553#define SCAN_HB_LMAC_IDX 1 553#define SCAN_HB_LMAC_IDX 1
554 554
555struct iwl_scan_config { 555struct iwl_scan_config_v2 {
556 __le32 flags; 556 __le32 flags;
557 __le32 tx_chains; 557 __le32 tx_chains;
558 __le32 rx_chains; 558 __le32 rx_chains;
@@ -564,6 +564,24 @@ struct iwl_scan_config {
564 u8 bcast_sta_id; 564 u8 bcast_sta_id;
565 u8 channel_flags; 565 u8 channel_flags;
566 u8 channel_array[]; 566 u8 channel_array[];
567} __packed; /* SCAN_CONFIG_DB_CMD_API_S_2 */
568
569/**
570 * struct iwl_scan_config
571 * @enable_cam_mode: whether to enable CAM mode.
572 * @enable_promiscouos_mode: whether to enable promiscouos mode
573 * @bcast_sta_id: the index of the station in the fw
574 * @reserved: reserved
575 * @tx_chains: valid_tx antenna - ANT_* definitions
576 * @rx_chains: valid_rx antenna - ANT_* definitions
577 */
578struct iwl_scan_config {
579 u8 enable_cam_mode;
580 u8 enable_promiscouos_mode;
581 u8 bcast_sta_id;
582 u8 reserved;
583 __le32 tx_chains;
584 __le32 rx_chains;
567} __packed; /* SCAN_CONFIG_DB_CMD_API_S_3 */ 585} __packed; /* SCAN_CONFIG_DB_CMD_API_S_3 */
568 586
569/** 587/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 423cc0cf8e78..0d5bc4ce5c07 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -288,6 +288,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
288 * STA_CONTEXT_DOT11AX_API_S 288 * STA_CONTEXT_DOT11AX_API_S
289 * @IWL_UCODE_TLV_CAPA_SAR_TABLE_VER: This ucode supports different sar 289 * @IWL_UCODE_TLV_CAPA_SAR_TABLE_VER: This ucode supports different sar
290 * version tables. 290 * version tables.
291 * @IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG: This ucode supports v3 of
292 * SCAN_CONFIG_DB_CMD_API_S.
291 * 293 *
292 * @NUM_IWL_UCODE_TLV_API: number of bits used 294 * @NUM_IWL_UCODE_TLV_API: number of bits used
293 */ 295 */
@@ -321,6 +323,7 @@ enum iwl_ucode_tlv_api {
321 IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE = (__force iwl_ucode_tlv_api_t)53, 323 IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE = (__force iwl_ucode_tlv_api_t)53,
322 IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54, 324 IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54,
323 IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55, 325 IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55,
326 IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG = (__force iwl_ucode_tlv_api_t)56,
324 IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57, 327 IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57,
325 IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58, 328 IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58,
326 329
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 843d00bf2bd5..5ca50f39a023 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1405,6 +1405,12 @@ static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm)
1405 IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER); 1405 IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER);
1406} 1406}
1407 1407
1408static inline bool iwl_mvm_is_reduced_config_scan_supported(struct iwl_mvm *mvm)
1409{
1410 return fw_has_api(&mvm->fw->ucode_capa,
1411 IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG);
1412}
1413
1408static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) 1414static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
1409{ 1415{
1410 return fw_has_api(&mvm->fw->ucode_capa, 1416 return fw_has_api(&mvm->fw->ucode_capa,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index f6b3045badbd..fcafa22ec6ce 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1137,11 +1137,11 @@ static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
1137 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels); 1137 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1138} 1138}
1139 1139
1140static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config, 1140static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config,
1141 u32 flags, u8 channel_flags, 1141 u32 flags, u8 channel_flags,
1142 u32 max_channels) 1142 u32 max_channels)
1143{ 1143{
1144 struct iwl_scan_config *cfg = config; 1144 struct iwl_scan_config_v2 *cfg = config;
1145 1145
1146 cfg->flags = cpu_to_le32(flags); 1146 cfg->flags = cpu_to_le32(flags);
1147 cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); 1147 cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
@@ -1185,7 +1185,7 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
1185 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels); 1185 iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
1186} 1186}
1187 1187
1188int iwl_mvm_config_scan(struct iwl_mvm *mvm) 1188static int iwl_mvm_legacy_config_scan(struct iwl_mvm *mvm)
1189{ 1189{
1190 void *cfg; 1190 void *cfg;
1191 int ret, cmd_size; 1191 int ret, cmd_size;
@@ -1217,7 +1217,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1217 } 1217 }
1218 1218
1219 if (iwl_mvm_cdb_scan_api(mvm)) 1219 if (iwl_mvm_cdb_scan_api(mvm))
1220 cmd_size = sizeof(struct iwl_scan_config); 1220 cmd_size = sizeof(struct iwl_scan_config_v2);
1221 else 1221 else
1222 cmd_size = sizeof(struct iwl_scan_config_v1); 1222 cmd_size = sizeof(struct iwl_scan_config_v1);
1223 cmd_size += num_channels; 1223 cmd_size += num_channels;
@@ -1254,8 +1254,8 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1254 flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ? 1254 flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ?
1255 SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED : 1255 SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED :
1256 SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED; 1256 SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED;
1257 iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags, 1257 iwl_mvm_fill_scan_config_v2(mvm, cfg, flags, channel_flags,
1258 num_channels); 1258 num_channels);
1259 } else { 1259 } else {
1260 iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags, 1260 iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags,
1261 num_channels); 1261 num_channels);
@@ -1277,6 +1277,30 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1277 return ret; 1277 return ret;
1278} 1278}
1279 1279
1280int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1281{
1282 struct iwl_scan_config cfg;
1283 struct iwl_host_cmd cmd = {
1284 .id = iwl_cmd_id(SCAN_CFG_CMD, IWL_ALWAYS_LONG_GROUP, 0),
1285 .len[0] = sizeof(cfg),
1286 .data[0] = &cfg,
1287 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1288 };
1289
1290 if (!iwl_mvm_is_reduced_config_scan_supported(mvm))
1291 return iwl_mvm_legacy_config_scan(mvm);
1292
1293 memset(&cfg, 0, sizeof(cfg));
1294
1295 cfg.bcast_sta_id = mvm->aux_sta.sta_id;
1296 cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1297 cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1298
1299 IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
1300
1301 return iwl_mvm_send_cmd(mvm, &cmd);
1302}
1303
1280static int iwl_mvm_scan_uid_by_status(struct iwl_mvm *mvm, int status) 1304static int iwl_mvm_scan_uid_by_status(struct iwl_mvm *mvm, int status)
1281{ 1305{
1282 int i; 1306 int i;