Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17564dde authored by Avraham Stern's avatar Avraham Stern Committed by Emmanuel Grumbach
Browse files

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: default avatarAvraham Stern <avraham.stern@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 9d012d0d
Loading
Loading
Loading
Loading
+40 −0
Original line number Original line Diff line number Diff line
@@ -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:
+27 −0
Original line number Original line Diff line number Diff line
@@ -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__ */
+25 −0
Original line number Original line Diff line number Diff line
@@ -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)