From c7a64ef56edcc32c18431ec7aba345b20eda5e8f Mon Sep 17 00:00:00 2001 From: Seevalamuthu Mariappan Date: Mon, 25 Jan 2021 10:10:30 +0530 Subject: [PATCH] ath11k: 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/ath11k//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/ath11k/qcn9000\ hw1.0_0000 \:01\:00.0/fw_dbglog_config Signed-off-by: Seevalamuthu Mariappan --- drivers/net/wireless/ath/ath11k/core.h | 2 + drivers/net/wireless/ath/ath11k/debugfs.c | 66 ++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/wmi.c | 48 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 16 ++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -967,6 +967,8 @@ struct ath11k_base { int userpd_id; struct ath11k_internal_pci ipci; bool enable_memory_stats; + u32 fw_dbglog_param; + u64 fw_dbglog_val; u32 rx_hash; bool stats_disable; --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1790,6 +1790,71 @@ static const struct file_operations fops .read = ath11k_read_ce_latency_stats, }; +static ssize_t ath11k_read_fw_dbglog(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k_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 ath11k_write_fw_dbglog(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath11k_base *ab = file->private_data; + struct ath11k *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 = ath11k_wmi_dbglog_cfg(ar, param, value); + if (ret) { + ath11k_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 = ath11k_read_fw_dbglog, + .write = ath11k_write_fw_dbglog, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath11k_debugfs_pdev_create(struct ath11k_base *ab) { if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) @@ -1809,6 +1874,9 @@ int ath11k_debugfs_pdev_create(struct at debugfs_create_file("ce_latency_stats", 0600, ab->debugfs_soc, ab, &fops_ce_latency_stats); + debugfs_create_file("fw_dbglog_config", 0600, ab->debugfs_soc, ab, + &fops_fw_dbglog); + debugfs_create_file("rx_hash", 0600, ab->debugfs_soc, ab, &fops_soc_rx_hash); @@ -3759,7 +3827,6 @@ int ath11k_debugfs_register(struct ath11 debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev, ar, &fops_dbr_debug); - return 0; } --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8683,6 +8683,55 @@ int ath11k_wmi_pdev_get_tpc_table_cmdid( return ret; } +int ath11k_wmi_dbglog_cfg(struct ath11k *ar, u32 param, u64 value) +{ + struct ath11k_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 = ath11k_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 = ath11k_wmi_cmd_send(wmi, skb, WMI_DBGLOG_CFG_CMDID); + if (ret) { + ath11k_warn(ar->ab, + "failed to send WMI_DBGLOG_CFG_CMDID\n"); + dev_kfree_skb(skb); + } + return ret; +} + static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base *ab, struct sk_buff *skb) { const char *status[] = { --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -6111,6 +6111,21 @@ struct wmi_qos_null_tx_cmd { u32 tx_params_valid; } __packed; +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 @@ -6496,4 +6511,5 @@ int ath11k_wmi_send_aggr_size_cmd(struct struct set_custom_aggr_size_params *params); int ath11k_wmi_send_wmi_ctrl_stats_cmd(struct ath11k *ar, struct wmi_ctrl_path_stats_cmd_param *param); +int ath11k_wmi_dbglog_cfg(struct ath11k *ar, u32 param, u64 value); #endif