diff options
author | Avraham Stern <avraham.stern@intel.com> | 2015-03-22 07:11:01 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-08-04 14:29:40 -0400 |
commit | 17564dde6024fcfe74cc0512e7837175aa5283d9 (patch) | |
tree | 07fee9e78addb630a0e32a010ce1a5b62b767e99 | |
parent | 9d012d0dbee1dcc4f7491925de41b4249b2cfb31 (diff) |
iwlwifi: add new TLV capability flag for gscan support
Gscan is a scan feature which is supported on certain devices only,
hence the need for a TLV flag for it. For devices that support gscan
store the gscan capabilities advertised by the FW so the driver can
report it to upper layers.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-drv.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw-file.h | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw.h | 25 |
3 files changed, 92 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 721d3cb94386..a86aa5bcee7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -372,6 +372,30 @@ static int iwl_store_cscheme(struct iwl_fw *fw, const u8 *data, const u32 len) | |||
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
374 | 374 | ||
375 | static int iwl_store_gscan_capa(struct iwl_fw *fw, const u8 *data, | ||
376 | const u32 len) | ||
377 | { | ||
378 | struct iwl_fw_gscan_capabilities *fw_capa = (void *)data; | ||
379 | struct iwl_gscan_capabilities *capa = &fw->gscan_capa; | ||
380 | |||
381 | if (len < sizeof(*fw_capa)) | ||
382 | return -EINVAL; | ||
383 | |||
384 | capa->max_scan_cache_size = le32_to_cpu(fw_capa->max_scan_cache_size); | ||
385 | capa->max_scan_buckets = le32_to_cpu(fw_capa->max_scan_buckets); | ||
386 | capa->max_ap_cache_per_scan = | ||
387 | le32_to_cpu(fw_capa->max_ap_cache_per_scan); | ||
388 | capa->max_rssi_sample_size = le32_to_cpu(fw_capa->max_rssi_sample_size); | ||
389 | capa->max_scan_reporting_threshold = | ||
390 | le32_to_cpu(fw_capa->max_scan_reporting_threshold); | ||
391 | capa->max_hotlist_aps = le32_to_cpu(fw_capa->max_hotlist_aps); | ||
392 | capa->max_significant_change_aps = | ||
393 | le32_to_cpu(fw_capa->max_significant_change_aps); | ||
394 | capa->max_bssid_history_entries = | ||
395 | le32_to_cpu(fw_capa->max_bssid_history_entries); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
375 | /* | 399 | /* |
376 | * Gets uCode section from tlv. | 400 | * Gets uCode section from tlv. |
377 | */ | 401 | */ |
@@ -581,6 +605,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
581 | int num_of_cpus; | 605 | int num_of_cpus; |
582 | bool usniffer_images = false; | 606 | bool usniffer_images = false; |
583 | bool usniffer_req = false; | 607 | bool usniffer_req = false; |
608 | bool gscan_capa = false; | ||
584 | 609 | ||
585 | if (len < sizeof(*ucode)) { | 610 | if (len < sizeof(*ucode)) { |
586 | IWL_ERR(drv, "uCode has invalid length: %zd\n", len); | 611 | IWL_ERR(drv, "uCode has invalid length: %zd\n", len); |
@@ -991,6 +1016,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
991 | drv->fw.sdio_adma_addr = | 1016 | drv->fw.sdio_adma_addr = |
992 | le32_to_cpup((__le32 *)tlv_data); | 1017 | le32_to_cpup((__le32 *)tlv_data); |
993 | break; | 1018 | break; |
1019 | case IWL_UCODE_TLV_FW_GSCAN_CAPA: | ||
1020 | if (iwl_store_gscan_capa(&drv->fw, tlv_data, tlv_len)) | ||
1021 | goto invalid_tlv_len; | ||
1022 | gscan_capa = true; | ||
1023 | break; | ||
994 | default: | 1024 | default: |
995 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); | 1025 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); |
996 | break; | 1026 | break; |
@@ -1009,6 +1039,16 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
1009 | return -EINVAL; | 1039 | return -EINVAL; |
1010 | } | 1040 | } |
1011 | 1041 | ||
1042 | /* | ||
1043 | * If ucode advertises that it supports GSCAN but GSCAN | ||
1044 | * capabilities TLV is not present, warn and continue without GSCAN. | ||
1045 | */ | ||
1046 | if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && | ||
1047 | WARN(!gscan_capa, | ||
1048 | "GSCAN is supported but capabilities TLV is unavailable\n")) | ||
1049 | __clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT, | ||
1050 | capa->_capa); | ||
1051 | |||
1012 | return 0; | 1052 | return 0; |
1013 | 1053 | ||
1014 | invalid_tlv_len: | 1054 | invalid_tlv_len: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 5d7f2d9cf180..d1c5b90eb6b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -139,6 +139,7 @@ enum iwl_ucode_tlv_type { | |||
139 | IWL_UCODE_TLV_FW_DBG_DEST = 38, | 139 | IWL_UCODE_TLV_FW_DBG_DEST = 38, |
140 | IWL_UCODE_TLV_FW_DBG_CONF = 39, | 140 | IWL_UCODE_TLV_FW_DBG_CONF = 39, |
141 | IWL_UCODE_TLV_FW_DBG_TRIGGER = 40, | 141 | IWL_UCODE_TLV_FW_DBG_TRIGGER = 40, |
142 | IWL_UCODE_TLV_FW_GSCAN_CAPA = 50, | ||
142 | }; | 143 | }; |
143 | 144 | ||
144 | struct iwl_ucode_tlv { | 145 | struct iwl_ucode_tlv { |
@@ -306,6 +307,7 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t; | |||
306 | * IWL_UCODE_TLV_API_WIFI_MCC_UPDATE. When either is set, multi-source LAR | 307 | * IWL_UCODE_TLV_API_WIFI_MCC_UPDATE. When either is set, multi-source LAR |
307 | * is supported. | 308 | * is supported. |
308 | * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC | 309 | * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC |
310 | * @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan | ||
309 | */ | 311 | */ |
310 | enum iwl_ucode_tlv_capa { | 312 | enum iwl_ucode_tlv_capa { |
311 | IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0, | 313 | IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0, |
@@ -327,6 +329,7 @@ enum iwl_ucode_tlv_capa { | |||
327 | IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = (__force iwl_ucode_tlv_capa_t)28, | 329 | IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = (__force iwl_ucode_tlv_capa_t)28, |
328 | IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29, | 330 | IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29, |
329 | IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30, | 331 | IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30, |
332 | IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31, | ||
330 | }; | 333 | }; |
331 | 334 | ||
332 | /* The default calibrate table size if not specified by firmware file */ | 335 | /* The default calibrate table size if not specified by firmware file */ |
@@ -728,4 +731,28 @@ struct iwl_fw_dbg_conf_tlv { | |||
728 | struct iwl_fw_dbg_conf_hcmd hcmd; | 731 | struct iwl_fw_dbg_conf_hcmd hcmd; |
729 | } __packed; | 732 | } __packed; |
730 | 733 | ||
734 | /** | ||
735 | * struct iwl_fw_gscan_capabilities - gscan capabilities supported by FW | ||
736 | * @max_scan_cache_size: total space allocated for scan results (in bytes). | ||
737 | * @max_scan_buckets: maximum number of channel buckets. | ||
738 | * @max_ap_cache_per_scan: maximum number of APs that can be stored per scan. | ||
739 | * @max_rssi_sample_size: number of RSSI samples used for averaging RSSI. | ||
740 | * @max_scan_reporting_threshold: max possible report threshold. in percentage. | ||
741 | * @max_hotlist_aps: maximum number of entries for hotlist APs. | ||
742 | * @max_significant_change_aps: maximum number of entries for significant | ||
743 | * change APs. | ||
744 | * @max_bssid_history_entries: number of BSSID/RSSI entries that the device can | ||
745 | * hold. | ||
746 | */ | ||
747 | struct iwl_fw_gscan_capabilities { | ||
748 | __le32 max_scan_cache_size; | ||
749 | __le32 max_scan_buckets; | ||
750 | __le32 max_ap_cache_per_scan; | ||
751 | __le32 max_rssi_sample_size; | ||
752 | __le32 max_scan_reporting_threshold; | ||
753 | __le32 max_hotlist_aps; | ||
754 | __le32 max_significant_change_aps; | ||
755 | __le32 max_bssid_history_entries; | ||
756 | } __packed; | ||
757 | |||
731 | #endif /* __iwl_fw_file_h__ */ | 758 | #endif /* __iwl_fw_file_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 224c7f45d2f1..0d9d6f51766e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -191,6 +191,30 @@ struct iwl_fw_cscheme_list { | |||
191 | } __packed; | 191 | } __packed; |
192 | 192 | ||
193 | /** | 193 | /** |
194 | * struct iwl_gscan_capabilities - gscan capabilities supported by FW | ||
195 | * @max_scan_cache_size: total space allocated for scan results (in bytes). | ||
196 | * @max_scan_buckets: maximum number of channel buckets. | ||
197 | * @max_ap_cache_per_scan: maximum number of APs that can be stored per scan. | ||
198 | * @max_rssi_sample_size: number of RSSI samples used for averaging RSSI. | ||
199 | * @max_scan_reporting_threshold: max possible report threshold. in percentage. | ||
200 | * @max_hotlist_aps: maximum number of entries for hotlist APs. | ||
201 | * @max_significant_change_aps: maximum number of entries for significant | ||
202 | * change APs. | ||
203 | * @max_bssid_history_entries: number of BSSID/RSSI entries that the device can | ||
204 | * hold. | ||
205 | */ | ||
206 | struct iwl_gscan_capabilities { | ||
207 | u32 max_scan_cache_size; | ||
208 | u32 max_scan_buckets; | ||
209 | u32 max_ap_cache_per_scan; | ||
210 | u32 max_rssi_sample_size; | ||
211 | u32 max_scan_reporting_threshold; | ||
212 | u32 max_hotlist_aps; | ||
213 | u32 max_significant_change_aps; | ||
214 | u32 max_bssid_history_entries; | ||
215 | }; | ||
216 | |||
217 | /** | ||
194 | * struct iwl_fw - variables associated with the firmware | 218 | * struct iwl_fw - variables associated with the firmware |
195 | * | 219 | * |
196 | * @ucode_ver: ucode version from the ucode file | 220 | * @ucode_ver: ucode version from the ucode file |
@@ -248,6 +272,7 @@ struct iwl_fw { | |||
248 | struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX]; | 272 | struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX]; |
249 | size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX]; | 273 | size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX]; |
250 | u8 dbg_dest_reg_num; | 274 | u8 dbg_dest_reg_num; |
275 | struct iwl_gscan_capabilities gscan_capa; | ||
251 | }; | 276 | }; |
252 | 277 | ||
253 | static inline const char *get_fw_dbg_mode_string(int mode) | 278 | static inline const char *get_fw_dbg_mode_string(int mode) |