Loading drivers/net/wireless/cnss2/debug.c +110 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include <linux/err.h> #include <linux/seq_file.h> Loading @@ -10,10 +10,28 @@ #include "pci.h" #define MMIO_REG_ACCESS_MEM_TYPE 0xFF #define HEX_DUMP_ROW_SIZE 16 void *cnss_ipc_log_context; void *cnss_ipc_log_long_context; static void cnss_print_hex_dump(const void *buf, int len) { const u8 *ptr = buf; int i, linelen, remaining = len, rowsize = HEX_DUMP_ROW_SIZE; unsigned char linebuf[HEX_DUMP_ROW_SIZE * 3 + 1]; for (i = 0; i < len; i += rowsize) { linelen = min(remaining, rowsize); remaining -= rowsize; hex_dump_to_buffer(ptr + i, linelen, rowsize, 1, linebuf, sizeof(linebuf), false); cnss_pr_dbg("%.8x: %s\n", i, linebuf); } } static int cnss_pin_connect_show(struct seq_file *s, void *data) { struct cnss_plat_data *cnss_priv = s->private; Loading Loading @@ -750,6 +768,95 @@ static const struct file_operations cnss_dynamic_feature_fops = { .llseek = seq_lseek, }; static int cnss_wfc_call_status_debug_show(struct seq_file *s, void *data) { seq_puts(s, "\nUsage: echo <data_len> <hex data> > <debugfs_path>/cnss/wfc_call_status\n"); seq_puts(s, "e.g. Send 4 bytes of hex data for WFC call status using QMI message:\n"); seq_puts(s, "echo '0x4 0xA 0xB 0xC 0xD' > /d/cnss/wfc_call_status\n"); return 0; } static ssize_t cnss_wfc_call_status_debug_write(struct file *fp, const char __user *user_buf, size_t count, loff_t *off) { struct cnss_plat_data *plat_priv = ((struct seq_file *)fp->private_data)->private; char buf[(QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 + 1) * 5]; char *sptr, *token; unsigned int len = 0; const char *delim = " "; u32 data_len; u8 data[QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01] = {0}, data_byte; int ret = 0, i; if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) { cnss_pr_err("Firmware is not ready yet\n"); return -EINVAL; } len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; sptr = buf; token = strsep(&sptr, delim); if (!token || !sptr) return -EINVAL; if (kstrtou32(token, 0, &data_len)) return -EINVAL; cnss_pr_dbg("Parsing 0x%x bytes data for WFC call status\n", data_len); if (data_len > QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 || data_len == 0) { cnss_pr_err("Invalid data length 0x%x\n", data_len); return -EINVAL; } for (i = 0; i < data_len; i++) { token = strsep(&sptr, delim); if (!token || (!sptr && i < data_len - 1)) { cnss_pr_err("Input data is less than length\n"); return -EINVAL; } if (kstrtou8(token, 0, &data_byte)) { cnss_pr_err("Data format is incorrect\n"); return -EINVAL; } data[i] = data_byte; } cnss_print_hex_dump(data, data_len); ret = cnss_wlfw_wfc_call_status_send_sync(plat_priv, data_len, data); if (ret) return ret; return count; } static int cnss_wfc_call_status_debug_open(struct inode *inode, struct file *file) { return single_open(file, cnss_wfc_call_status_debug_show, inode->i_private); } static const struct file_operations cnss_wfc_call_status_debug_fops = { .read = seq_read, .write = cnss_wfc_call_status_debug_write, .open = cnss_wfc_call_status_debug_open, .owner = THIS_MODULE, .llseek = seq_lseek, }; #ifdef CONFIG_CNSS2_DEBUG static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) { Loading @@ -767,6 +874,8 @@ static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) &cnss_control_params_debug_fops); debugfs_create_file("dynamic_feature", 0600, root_dentry, plat_priv, &cnss_dynamic_feature_fops); debugfs_create_file("wfc_call_status", 0600, root_dentry, plat_priv, &cnss_wfc_call_status_debug_fops); return 0; } Loading drivers/net/wireless/cnss2/qmi.c +2 −2 Original line number Diff line number Diff line Loading @@ -1469,7 +1469,7 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv) return ret; } static int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data) { struct wlfw_wfc_call_status_req_msg_v01 *req; Loading drivers/net/wireless/cnss2/qmi.h +17 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _CNSS_QMI_H #define _CNSS_QMI_H Loading Loading @@ -61,6 +61,8 @@ int cnss_wlfw_antenna_grant_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_get_info_send_sync(struct cnss_plat_data *plat_priv, int type, void *cmd, int cmd_len); int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data); int cnss_register_coex_service(struct cnss_plat_data *plat_priv); void cnss_unregister_coex_service(struct cnss_plat_data *plat_priv); int coex_antenna_switch_to_wlan_send_sync_msg(struct cnss_plat_data *plat_priv); Loading Loading @@ -175,6 +177,20 @@ int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv) return 0; } static inline int cnss_wlfw_get_info_send_sync(struct cnss_plat_data *plat_priv, int type, void *cmd, int cmd_len) { return 0; } static inline int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data); { return 0; } static inline int cnss_register_coex_service(struct cnss_plat_data *plat_priv) { Loading Loading
drivers/net/wireless/cnss2/debug.c +110 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include <linux/err.h> #include <linux/seq_file.h> Loading @@ -10,10 +10,28 @@ #include "pci.h" #define MMIO_REG_ACCESS_MEM_TYPE 0xFF #define HEX_DUMP_ROW_SIZE 16 void *cnss_ipc_log_context; void *cnss_ipc_log_long_context; static void cnss_print_hex_dump(const void *buf, int len) { const u8 *ptr = buf; int i, linelen, remaining = len, rowsize = HEX_DUMP_ROW_SIZE; unsigned char linebuf[HEX_DUMP_ROW_SIZE * 3 + 1]; for (i = 0; i < len; i += rowsize) { linelen = min(remaining, rowsize); remaining -= rowsize; hex_dump_to_buffer(ptr + i, linelen, rowsize, 1, linebuf, sizeof(linebuf), false); cnss_pr_dbg("%.8x: %s\n", i, linebuf); } } static int cnss_pin_connect_show(struct seq_file *s, void *data) { struct cnss_plat_data *cnss_priv = s->private; Loading Loading @@ -750,6 +768,95 @@ static const struct file_operations cnss_dynamic_feature_fops = { .llseek = seq_lseek, }; static int cnss_wfc_call_status_debug_show(struct seq_file *s, void *data) { seq_puts(s, "\nUsage: echo <data_len> <hex data> > <debugfs_path>/cnss/wfc_call_status\n"); seq_puts(s, "e.g. Send 4 bytes of hex data for WFC call status using QMI message:\n"); seq_puts(s, "echo '0x4 0xA 0xB 0xC 0xD' > /d/cnss/wfc_call_status\n"); return 0; } static ssize_t cnss_wfc_call_status_debug_write(struct file *fp, const char __user *user_buf, size_t count, loff_t *off) { struct cnss_plat_data *plat_priv = ((struct seq_file *)fp->private_data)->private; char buf[(QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 + 1) * 5]; char *sptr, *token; unsigned int len = 0; const char *delim = " "; u32 data_len; u8 data[QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01] = {0}, data_byte; int ret = 0, i; if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) { cnss_pr_err("Firmware is not ready yet\n"); return -EINVAL; } len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; sptr = buf; token = strsep(&sptr, delim); if (!token || !sptr) return -EINVAL; if (kstrtou32(token, 0, &data_len)) return -EINVAL; cnss_pr_dbg("Parsing 0x%x bytes data for WFC call status\n", data_len); if (data_len > QMI_WLFW_MAX_WFC_CALL_STATUS_DATA_SIZE_V01 || data_len == 0) { cnss_pr_err("Invalid data length 0x%x\n", data_len); return -EINVAL; } for (i = 0; i < data_len; i++) { token = strsep(&sptr, delim); if (!token || (!sptr && i < data_len - 1)) { cnss_pr_err("Input data is less than length\n"); return -EINVAL; } if (kstrtou8(token, 0, &data_byte)) { cnss_pr_err("Data format is incorrect\n"); return -EINVAL; } data[i] = data_byte; } cnss_print_hex_dump(data, data_len); ret = cnss_wlfw_wfc_call_status_send_sync(plat_priv, data_len, data); if (ret) return ret; return count; } static int cnss_wfc_call_status_debug_open(struct inode *inode, struct file *file) { return single_open(file, cnss_wfc_call_status_debug_show, inode->i_private); } static const struct file_operations cnss_wfc_call_status_debug_fops = { .read = seq_read, .write = cnss_wfc_call_status_debug_write, .open = cnss_wfc_call_status_debug_open, .owner = THIS_MODULE, .llseek = seq_lseek, }; #ifdef CONFIG_CNSS2_DEBUG static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) { Loading @@ -767,6 +874,8 @@ static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv) &cnss_control_params_debug_fops); debugfs_create_file("dynamic_feature", 0600, root_dentry, plat_priv, &cnss_dynamic_feature_fops); debugfs_create_file("wfc_call_status", 0600, root_dentry, plat_priv, &cnss_wfc_call_status_debug_fops); return 0; } Loading
drivers/net/wireless/cnss2/qmi.c +2 −2 Original line number Diff line number Diff line Loading @@ -1469,7 +1469,7 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv) return ret; } static int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data) { struct wlfw_wfc_call_status_req_msg_v01 *req; Loading
drivers/net/wireless/cnss2/qmi.h +17 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _CNSS_QMI_H #define _CNSS_QMI_H Loading Loading @@ -61,6 +61,8 @@ int cnss_wlfw_antenna_grant_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_get_info_send_sync(struct cnss_plat_data *plat_priv, int type, void *cmd, int cmd_len); int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data); int cnss_register_coex_service(struct cnss_plat_data *plat_priv); void cnss_unregister_coex_service(struct cnss_plat_data *plat_priv); int coex_antenna_switch_to_wlan_send_sync_msg(struct cnss_plat_data *plat_priv); Loading Loading @@ -175,6 +177,20 @@ int cnss_wlfw_dynamic_feature_mask_send_sync(struct cnss_plat_data *plat_priv) return 0; } static inline int cnss_wlfw_get_info_send_sync(struct cnss_plat_data *plat_priv, int type, void *cmd, int cmd_len) { return 0; } static inline int cnss_wlfw_wfc_call_status_send_sync(struct cnss_plat_data *plat_priv, u32 data_len, const void *data); { return 0; } static inline int cnss_register_coex_service(struct cnss_plat_data *plat_priv) { Loading