aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvraham Stern <avraham.stern@intel.com>2015-03-22 07:11:01 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-08-04 14:29:40 -0400
commit17564dde6024fcfe74cc0512e7837175aa5283d9 (patch)
tree07fee9e78addb630a0e32a010ce1a5b62b767e99
parent9d012d0dbee1dcc4f7491925de41b4249b2cfb31 (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.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h25
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
375static 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
144struct iwl_ucode_tlv { 145struct 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 */
310enum iwl_ucode_tlv_capa { 312enum 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 */
747struct 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 */
206struct 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
253static inline const char *get_fw_dbg_mode_string(int mode) 278static inline const char *get_fw_dbg_mode_string(int mode)