From e29de1b41ba065e8db3cff8ab0bf645ab39e0903 Mon Sep 17 00:00:00 2001 From: Sivashankari Madhavan Date: Tue, 19 Jul 2022 06:40:07 +0530 Subject: [PATCH] ath12k: Add debugfs interface to configure firmware dbg log level Added debugfs interface "fw_dbglog_config" to configure firmware log levels. Configuration is done via WMI command WMI_DBGLOG_CFG_CMDID. Command to configure, echo " " > /sys/kernel/debug/ath12k//fw_dbglog_config where dbglog_param can be, 1) WMI_DEBUG_LOG_PARAM_LOG_LEVEL - configure log level for a given module here, = <0xaaaa00bb>, 'aaaa' - module id and 'bb' - loglevel 2) WMI_DEBUG_LOG_PARAM_VDEV_ENABLE - enable the debug log for a given vdev here, = vdev_id 3) WMI_DEBUG_LOG_PARAM_VDEV_DISABLE - disable debug log for a given vdev except ERROR logs here, = vdev_id 4) WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP - set vdev enable bitmap here, = vdev_enable_bitmap 5) WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP - set a given log level to all the modules specified in the module bitmap here, = <0xaaaaaaaa000000bb>, 'aaaaaaaa' - module bitmap and 'bb' - loglevel 6) WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP - Wow mode specific logging enable here, = <0xaaaaaaaa000000bb>, 'aaaaaaaa' - module bitmap and 'bb' - loglevel Sample command usage, echo "1 0xffff0001" > /sys/kernel/debug/ath12k/qcn9000\ hw1.0_0000 \:01\:00.0/fw_dbglog_config Signed-off-by: Seevalamuthu Mariappan Signed-off-by: Sivashankari Madhavan --- drivers/net/wireless/ath/ath12k/core.h | 3 + drivers/net/wireless/ath/ath12k/debugfs.c | 68 +++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wmi.c | 49 ++++++++++++++++ drivers/net/wireless/ath/ath12k/wmi.h | 16 ++++++ 4 files changed, 136 insertions(+) --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -903,6 +903,9 @@ struct ath12k_base { struct completion htc_suspend; bool fw_recovery_support; + u32 fw_dbglog_param; + u64 fw_dbglog_val; + u64 fw_soc_drop_count; struct device_node *hremote_node; --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1003,11 +1003,79 @@ static const struct file_operations fops_fw_recovery = { .open = simple_open, }; +static ssize_t ath12k_read_fw_dbglog(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath12k_base *ab = file->private_data; + size_t len; + char buf[128]; + + len = scnprintf(buf, sizeof(buf), "%u 0x%016llx\n", + ab->fw_dbglog_param, ab->fw_dbglog_val); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t ath12k_write_fw_dbglog(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath12k_base *ab = file->private_data; + struct ath12k *ar = ab->pdevs[0].ar; + char buf[128] = {0}; + unsigned int param; + u64 value; + int ret; + + if (!ar) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, + user_buf, count); + if (ret <= 0) + goto out; + + ret = sscanf(buf, "%u %llx", ¶m, &value); + + if (ret != 2) { + ret = -EINVAL; + goto out; + } + + ab->fw_dbglog_param = param; + ab->fw_dbglog_val = value; + ret = ath12k_wmi_dbglog_cfg(ar, param, value); + if (ret) { + ath12k_warn(ar, "dbglog cfg failed from debugfs: %d\n", + ret); + goto out; + } + + ret = count; + +out: + mutex_unlock(&ar->conf_mutex); + return ret; +} + +static const struct file_operations fops_fw_dbglog = { + .read = ath12k_read_fw_dbglog, + .write = ath12k_write_fw_dbglog, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath12k_debugfs_pdev_create(struct ath12k_base *ab) { if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) return 0; + debugfs_create_file("fw_dbglog_config", 0600, ab->debugfs_soc, ab, + &fops_fw_dbglog); + debugfs_create_file("set_fw_recovery", 0600, ab->debugfs_soc, ab, &fops_fw_recovery); --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -8361,6 +8361,55 @@ static const char *ath12k_wmi_twt_add_di } } +int ath12k_wmi_dbglog_cfg(struct ath12k *ar, u32 param, u64 value) +{ + struct ath12k_pdev_wmi *wmi = ar->wmi; + struct wmi_dbglog_config_cmd_fixed_param *cmd; + struct sk_buff *skb; + struct wmi_tlv *tlv; + u32 module_id_bitmap; + int ret, len; + + len = sizeof(*cmd) + TLV_HDR_SIZE + sizeof(module_id_bitmap); + skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + cmd = (struct wmi_dbglog_config_cmd_fixed_param *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DEBUG_LOG_CONFIG_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + cmd->dbg_log_param = param; + + tlv = (u8 *) cmd + sizeof(*cmd); + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) | + FIELD_PREP(WMI_TLV_LEN, sizeof(u32)); + + switch (param) { + case WMI_DEBUG_LOG_PARAM_LOG_LEVEL: + case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE: + case WMI_DEBUG_LOG_PARAM_VDEV_DISABLE: + case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP: + cmd->value = value; + break; + case WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP: + case WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP: + cmd->value = value; + module_id_bitmap = value >> 32; + memcpy(tlv->value, &module_id_bitmap, sizeof(module_id_bitmap)); + break; + default: + dev_kfree_skb(skb); + return -EINVAL; + } + + ret = ath12k_wmi_cmd_send(wmi, skb, WMI_DBGLOG_CFG_CMDID); + if (ret) { + ath12k_warn(ar->ab, + "failed to send WMI_DBGLOG_CFG_CMDID\n"); + dev_kfree_skb(skb); + } + return ret; +} + static void ath12k_wmi_twt_add_dialog_event(struct ath12k_base *ab, struct sk_buff *skb) { --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -5669,6 +5669,21 @@ struct target_resource_config { u32 ema_max_profile_period; }; +enum wmi_dblog_param { + WMI_DEBUG_LOG_PARAM_LOG_LEVEL = 0x1, + WMI_DEBUG_LOG_PARAM_VDEV_ENABLE, + WMI_DEBUG_LOG_PARAM_VDEV_DISABLE, + WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP, + WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP, + WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP, +}; + +struct wmi_dbglog_config_cmd_fixed_param { + u32 tlv_header; + u32 dbg_log_param; + u32 value; +} __packed; + #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 @@ -6015,6 +6030,7 @@ int ath12k_wmi_probe_resp_tmpl(struct at int ath12k_wmi_set_hw_mode(struct ath12k_base *ab, enum wmi_host_hw_mode_config_type mode); int ath12k_wmi_pdev_ap_ps_cmd_send(struct ath12k *ar, u8 pdev_id, u32 value); +int ath12k_wmi_dbglog_cfg(struct ath12k *ar, u32 param, u64 value); int ath12k_wmi_wow_host_wakeup_ind(struct ath12k *ar); int ath12k_wmi_wow_enable(struct ath12k *ar); int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,