forked from Minki/linux
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;
|
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.
|
* Gets uCode section from tlv.
|
||||||
*/
|
*/
|
||||||
@ -581,6 +605,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||||||
int num_of_cpus;
|
int num_of_cpus;
|
||||||
bool usniffer_images = false;
|
bool usniffer_images = false;
|
||||||
bool usniffer_req = false;
|
bool usniffer_req = false;
|
||||||
|
bool gscan_capa = false;
|
||||||
|
|
||||||
if (len < sizeof(*ucode)) {
|
if (len < sizeof(*ucode)) {
|
||||||
IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
|
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 =
|
drv->fw.sdio_adma_addr =
|
||||||
le32_to_cpup((__le32 *)tlv_data);
|
le32_to_cpup((__le32 *)tlv_data);
|
||||||
break;
|
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:
|
default:
|
||||||
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
||||||
break;
|
break;
|
||||||
@ -1009,6 +1039,16 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||||||
return -EINVAL;
|
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;
|
return 0;
|
||||||
|
|
||||||
invalid_tlv_len:
|
invalid_tlv_len:
|
||||||
|
@ -139,6 +139,7 @@ enum iwl_ucode_tlv_type {
|
|||||||
IWL_UCODE_TLV_FW_DBG_DEST = 38,
|
IWL_UCODE_TLV_FW_DBG_DEST = 38,
|
||||||
IWL_UCODE_TLV_FW_DBG_CONF = 39,
|
IWL_UCODE_TLV_FW_DBG_CONF = 39,
|
||||||
IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
|
IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
|
||||||
|
IWL_UCODE_TLV_FW_GSCAN_CAPA = 50,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iwl_ucode_tlv {
|
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
|
* IWL_UCODE_TLV_API_WIFI_MCC_UPDATE. When either is set, multi-source LAR
|
||||||
* is supported.
|
* is supported.
|
||||||
* @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
|
* @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
|
||||||
|
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan
|
||||||
*/
|
*/
|
||||||
enum iwl_ucode_tlv_capa {
|
enum iwl_ucode_tlv_capa {
|
||||||
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0,
|
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_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_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_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 */
|
/* 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;
|
struct iwl_fw_dbg_conf_hcmd hcmd;
|
||||||
} __packed;
|
} __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__ */
|
#endif /* __iwl_fw_file_h__ */
|
||||||
|
@ -190,6 +190,30 @@ struct iwl_fw_cscheme_list {
|
|||||||
struct iwl_fw_cipher_scheme cs[];
|
struct iwl_fw_cipher_scheme cs[];
|
||||||
} __packed;
|
} __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
|
* 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];
|
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||||
u8 dbg_dest_reg_num;
|
u8 dbg_dest_reg_num;
|
||||||
|
struct iwl_gscan_capabilities gscan_capa;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline const char *get_fw_dbg_mode_string(int mode)
|
static inline const char *get_fw_dbg_mode_string(int mode)
|
||||||
|
Loading…
Reference in New Issue
Block a user