Re: [PATCH v4] wifi: ath10k: Store WLAN firmware version in SMEM image table

From: Nathan Chancellor
Date: Tue Nov 29 2022 - 11:04:07 EST


On Thu, Nov 17, 2022 at 11:35:34PM +0530, Youghandhar Chintala wrote:
> In a SoC based solution, it would be useful to know the versions of the
> various binary firmware blobs the system is running on. On a QCOM based
> SoC, this info can be obtained from socinfo debugfs infrastructure. For
> this to work, respective subsystem drivers have to export the firmware
> version information to an SMEM based version information table.
>
> Having firmware version information at one place will help quickly
> figure out the firmware versions of various subsystems on the device
> instead of going through builds/logs in an event of a system crash.
>
> Fill WLAN firmware version information in SMEM version table to be
> printed as part of socinfo debugfs infrastructure on a Qualcomm based
> SoC.
>
> This change is applicable only for SNOC/QMI based targets.
>
> Example:
> cat /sys/kernel/debug/qcom_socinfo/cnss/name
> QC_IMAGE_VERSION_STRING=WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
>
> Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
>
> Signed-off-by: Youghandhar Chintala <quic_youghand@xxxxxxxxxxx>
> ---
> Changes from v3:
> - Changed patch title
> - Changed naming conventions
> - Removed MAX_BUILD_ID_LEN usuage
> - Added condition to call API
> - Changed depends on QCOM_SMEM to select QCOM_SMEM

You cannot blindly select user configurable symbols that have
dependencies, otherwise you end up with Kconfig warnings. I see the
following warning in -next when CONFIG_HWSPINLOCK is disabled:

WARNING: unmet direct dependencies detected for QCOM_SMEM
Depends on [n]: (ARCH_QCOM [=y] || COMPILE_TEST [=n]) && HWSPINLOCK [=n]
Selected by [m]:
- ATH10K_SNOC [=m] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_ATH [=y] && ATH10K [=m] && (ARCH_QCOM [=y] || COMPILE_TEST [=n])

That should likely be changed back to 'depends on'. The reason the other
QCOM symbols are selected is because they are not user-selectable, so
they have to be selected by the configurations that need them.

>> --- drivers/net/wireless/ath/ath10k/Kconfig | 1 +
> drivers/net/wireless/ath/ath10k/qmi.c | 35 +++++++++++++++++++++++++
> 2 files changed, 36 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
> index ca007b800f75..e0a51dad8e42 100644
> --- a/drivers/net/wireless/ath/ath10k/Kconfig
> +++ b/drivers/net/wireless/ath/ath10k/Kconfig
> @@ -44,6 +44,7 @@ config ATH10K_SNOC
> tristate "Qualcomm ath10k SNOC support"
> depends on ATH10K
> depends on ARCH_QCOM || COMPILE_TEST
> + select QCOM_SMEM
> select QCOM_SCM
> select QCOM_QMI_HELPERS
> help
> diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c
> index 66cb7a1e628a..cdcb162f93c2 100644
> --- a/drivers/net/wireless/ath/ath10k/qmi.c
> +++ b/drivers/net/wireless/ath/ath10k/qmi.c
> @@ -14,6 +14,7 @@
> #include <linux/net.h>
> #include <linux/platform_device.h>
> #include <linux/qcom_scm.h>
> +#include <linux/soc/qcom/smem.h>
> #include <linux/string.h>
> #include <net/sock.h>
>
> @@ -22,6 +23,10 @@
>
> #define ATH10K_QMI_CLIENT_ID 0x4b4e454c
> #define ATH10K_QMI_TIMEOUT 30
> +#define SMEM_IMAGE_VERSION_TABLE 469
> +#define SMEM_IMAGE_TABLE_CNSS_INDEX 13
> +#define SMEM_IMAGE_VERSION_ENTRY_SIZE 128
> +#define SMEM_IMAGE_VERSION_NAME_SIZE 75
>
> static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi,
> struct ath10k_msa_mem_info *mem_info)
> @@ -536,6 +541,33 @@ int ath10k_qmi_wlan_disable(struct ath10k *ar)
> return ath10k_qmi_mode_send_sync_msg(ar, QMI_WLFW_OFF_V01);
> }
>
> +static void ath10k_qmi_add_wlan_ver_smem(struct ath10k *ar, const char *fw_build_id)
> +{
> + u8 *table_ptr;
> + size_t smem_item_size;
> + const u32 smem_img_idx_wlan = SMEM_IMAGE_TABLE_CNSS_INDEX *
> + SMEM_IMAGE_VERSION_ENTRY_SIZE;
> +
> + table_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY,
> + SMEM_IMAGE_VERSION_TABLE,
> + &smem_item_size);
> +
> + if (IS_ERR(table_ptr)) {
> + ath10k_err(ar, "smem image version table not found\n");
> + return;
> + }
> +
> + if (smem_img_idx_wlan + SMEM_IMAGE_VERSION_ENTRY_SIZE >
> + smem_item_size) {
> + ath10k_err(ar, "smem block size too small: %zu\n",
> + smem_item_size);
> + return;
> + }
> +
> + strscpy(table_ptr + smem_img_idx_wlan, fw_build_id,
> + SMEM_IMAGE_VERSION_NAME_SIZE);
> +}
> +
> static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi)
> {
> struct wlfw_cap_resp_msg_v01 *resp;
> @@ -606,6 +638,9 @@ static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi)
> qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id);
> }
>
> + if (resp->fw_build_id_valid)
> + ath10k_qmi_add_wlan_ver_smem(ar, qmi->fw_build_id);
> +
> kfree(resp);
> return 0;
>
> --
> 2.38.0
>
>