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>
This commit is contained in:
parent
9d012d0dbe
commit
17564dde60
|
@ -372,6 +372,30 @@ static int iwl_store_cscheme(struct iwl_fw *fw, const u8 *data, const u32 len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_store_gscan_capa(struct iwl_fw *fw, const u8 *data,
|
||||
const u32 len)
|
||||
{
|
||||
struct iwl_fw_gscan_capabilities *fw_capa = (void *)data;
|
||||
struct iwl_gscan_capabilities *capa = &fw->gscan_capa;
|
||||
|
||||
if (len < sizeof(*fw_capa))
|
||||
return -EINVAL;
|
||||
|
||||
capa->max_scan_cache_size = le32_to_cpu(fw_capa->max_scan_cache_size);
|
||||
capa->max_scan_buckets = le32_to_cpu(fw_capa->max_scan_buckets);
|
||||
capa->max_ap_cache_per_scan =
|
||||
le32_to_cpu(fw_capa->max_ap_cache_per_scan);
|
||||
capa->max_rssi_sample_size = le32_to_cpu(fw_capa->max_rssi_sample_size);
|
||||
capa->max_scan_reporting_threshold =
|
||||
le32_to_cpu(fw_capa->max_scan_reporting_threshold);
|
||||
capa->max_hotlist_aps = le32_to_cpu(fw_capa->max_hotlist_aps);
|
||||
capa->max_significant_change_aps =
|
||||
le32_to_cpu(fw_capa->max_significant_change_aps);
|
||||
capa->max_bssid_history_entries =
|
||||
le32_to_cpu(fw_capa->max_bssid_history_entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets uCode section from tlv.
|
||||
*/
|
||||
|
@ -581,6 +605,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
int num_of_cpus;
|
||||
bool usniffer_images = false;
|
||||
bool usniffer_req = false;
|
||||
bool gscan_capa = false;
|
||||
|
||||
if (len < sizeof(*ucode)) {
|
||||
IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
|
||||
|
@ -991,6 +1016,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
drv->fw.sdio_adma_addr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_FW_GSCAN_CAPA:
|
||||
if (iwl_store_gscan_capa(&drv->fw, tlv_data, tlv_len))
|
||||
goto invalid_tlv_len;
|
||||
gscan_capa = true;
|
||||
break;
|
||||
default:
|
||||
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
||||
break;
|
||||
|
@ -1009,6 +1039,16 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If ucode advertises that it supports GSCAN but GSCAN
|
||||
* capabilities TLV is not present, warn and continue without GSCAN.
|
||||
*/
|
||||
if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
|
||||
WARN(!gscan_capa,
|
||||
"GSCAN is supported but capabilities TLV is unavailable\n"))
|
||||
__clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT,
|
||||
capa->_capa);
|
||||
|
||||
return 0;
|
||||
|
||||
invalid_tlv_len:
|
||||
|
|
|
@ -139,6 +139,7 @@ enum iwl_ucode_tlv_type {
|
|||
IWL_UCODE_TLV_FW_DBG_DEST = 38,
|
||||
IWL_UCODE_TLV_FW_DBG_CONF = 39,
|
||||
IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
|
||||
IWL_UCODE_TLV_FW_GSCAN_CAPA = 50,
|
||||
};
|
||||
|
||||
struct iwl_ucode_tlv {
|
||||
|
@ -306,6 +307,7 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
|
|||
* IWL_UCODE_TLV_API_WIFI_MCC_UPDATE. When either is set, multi-source LAR
|
||||
* is supported.
|
||||
* @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
|
||||
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan
|
||||
*/
|
||||
enum iwl_ucode_tlv_capa {
|
||||
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0,
|
||||
|
@ -327,6 +329,7 @@ enum iwl_ucode_tlv_capa {
|
|||
IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = (__force iwl_ucode_tlv_capa_t)28,
|
||||
IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29,
|
||||
IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30,
|
||||
IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31,
|
||||
};
|
||||
|
||||
/* The default calibrate table size if not specified by firmware file */
|
||||
|
@ -728,4 +731,28 @@ struct iwl_fw_dbg_conf_tlv {
|
|||
struct iwl_fw_dbg_conf_hcmd hcmd;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_gscan_capabilities - gscan capabilities supported by FW
|
||||
* @max_scan_cache_size: total space allocated for scan results (in bytes).
|
||||
* @max_scan_buckets: maximum number of channel buckets.
|
||||
* @max_ap_cache_per_scan: maximum number of APs that can be stored per scan.
|
||||
* @max_rssi_sample_size: number of RSSI samples used for averaging RSSI.
|
||||
* @max_scan_reporting_threshold: max possible report threshold. in percentage.
|
||||
* @max_hotlist_aps: maximum number of entries for hotlist APs.
|
||||
* @max_significant_change_aps: maximum number of entries for significant
|
||||
* change APs.
|
||||
* @max_bssid_history_entries: number of BSSID/RSSI entries that the device can
|
||||
* hold.
|
||||
*/
|
||||
struct iwl_fw_gscan_capabilities {
|
||||
__le32 max_scan_cache_size;
|
||||
__le32 max_scan_buckets;
|
||||
__le32 max_ap_cache_per_scan;
|
||||
__le32 max_rssi_sample_size;
|
||||
__le32 max_scan_reporting_threshold;
|
||||
__le32 max_hotlist_aps;
|
||||
__le32 max_significant_change_aps;
|
||||
__le32 max_bssid_history_entries;
|
||||
} __packed;
|
||||
|
||||
#endif /* __iwl_fw_file_h__ */
|
||||
|
|
|
@ -190,6 +190,30 @@ struct iwl_fw_cscheme_list {
|
|||
struct iwl_fw_cipher_scheme cs[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_gscan_capabilities - gscan capabilities supported by FW
|
||||
* @max_scan_cache_size: total space allocated for scan results (in bytes).
|
||||
* @max_scan_buckets: maximum number of channel buckets.
|
||||
* @max_ap_cache_per_scan: maximum number of APs that can be stored per scan.
|
||||
* @max_rssi_sample_size: number of RSSI samples used for averaging RSSI.
|
||||
* @max_scan_reporting_threshold: max possible report threshold. in percentage.
|
||||
* @max_hotlist_aps: maximum number of entries for hotlist APs.
|
||||
* @max_significant_change_aps: maximum number of entries for significant
|
||||
* change APs.
|
||||
* @max_bssid_history_entries: number of BSSID/RSSI entries that the device can
|
||||
* hold.
|
||||
*/
|
||||
struct iwl_gscan_capabilities {
|
||||
u32 max_scan_cache_size;
|
||||
u32 max_scan_buckets;
|
||||
u32 max_ap_cache_per_scan;
|
||||
u32 max_rssi_sample_size;
|
||||
u32 max_scan_reporting_threshold;
|
||||
u32 max_hotlist_aps;
|
||||
u32 max_significant_change_aps;
|
||||
u32 max_bssid_history_entries;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw - variables associated with the firmware
|
||||
*
|
||||
|
@ -248,6 +272,7 @@ struct iwl_fw {
|
|||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||
u8 dbg_dest_reg_num;
|
||||
struct iwl_gscan_capabilities gscan_capa;
|
||||
};
|
||||
|
||||
static inline const char *get_fw_dbg_mode_string(int mode)
|
||||
|
|
Loading…
Reference in New Issue