Loading drivers/net/wireless/ath/ath10k/core.c +13 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,17 @@ static void ath10k_core_restart(struct work_struct *work) mutex_unlock(&ar->conf_mutex); } static void ath10k_core_init_max_sta_count(struct ath10k *ar) { if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { ar->max_num_peers = TARGET_10X_NUM_PEERS; ar->max_num_stations = TARGET_10X_NUM_STATIONS; } else { ar->max_num_peers = TARGET_NUM_PEERS; ar->max_num_stations = TARGET_NUM_STATIONS; } } int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) { int status; Loading Loading @@ -1035,6 +1046,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar) return ret; } ath10k_core_init_max_sta_count(ar); mutex_lock(&ar->conf_mutex); ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); Loading drivers/net/wireless/ath/ath10k/core.h +11 −2 Original line number Diff line number Diff line Loading @@ -79,10 +79,12 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus) struct ath10k_skb_cb { dma_addr_t paddr; u8 eid; u8 vdev_id; struct { u8 tid; u16 freq; bool is_offchan; struct ath10k_htt_txbuf *txbuf; u32 txbuf_paddr; Loading Loading @@ -122,6 +124,7 @@ struct ath10k_wmi { struct completion service_ready; struct completion unified_ready; wait_queue_head_t tx_credits_wq; DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX); struct wmi_cmd_map *cmd; struct wmi_vdev_param_map *vdev_param; struct wmi_pdev_param_map *pdev_param; Loading Loading @@ -218,6 +221,8 @@ struct ath10k_peer { int vdev_id; u8 addr[ETH_ALEN]; DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS); /* protected by ar->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; }; Loading Loading @@ -310,7 +315,6 @@ struct ath10k_debug { struct ath10k_fw_stats fw_stats; struct completion fw_stats_complete; bool fw_stats_done; DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX); unsigned long htt_stats_mask; struct delayed_work htt_stats_dwork; Loading @@ -320,6 +324,7 @@ struct ath10k_debug { /* protected by conf_mutex */ u32 fw_dbglog_mask; u32 pktlog_filter; u32 reg_addr; u8 htt_max_amsdu; u8 htt_max_ampdu; Loading Loading @@ -560,8 +565,12 @@ struct ath10k { struct list_head peers; wait_queue_head_t peer_mapping_wq; /* number of created peers; protected by data_lock */ /* protected by conf_mutex */ int num_peers; int num_stations; int max_num_peers; int max_num_stations; struct work_struct offchan_tx_work; struct sk_buff_head offchan_tx_queue; Loading drivers/net/wireless/ath/ath10k/debug.c +248 −14 Original line number Diff line number Diff line Loading @@ -17,9 +17,8 @@ #include <linux/module.h> #include <linux/debugfs.h> #include <linux/version.h> #include <linux/vermagic.h> #include <linux/vmalloc.h> #include <linux/utsname.h> #include "core.h" #include "debug.h" Loading Loading @@ -124,7 +123,7 @@ EXPORT_SYMBOL(ath10k_info); void ath10k_print_driver_info(struct ath10k *ar) { ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s\n", ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n", ar->hw_params.name, ar->target_version, ar->chip_id, Loading @@ -136,7 +135,8 @@ void ath10k_print_driver_info(struct ath10k *ar) ar->fw_version_minor, ar->fw_version_release, ar->fw_version_build, ath10k_cal_mode_str(ar->cal_mode)); ath10k_cal_mode_str(ar->cal_mode), ar->max_num_stations); ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", config_enabled(CONFIG_ATH10K_DEBUG), config_enabled(CONFIG_ATH10K_DEBUGFS), Loading Loading @@ -179,13 +179,6 @@ EXPORT_SYMBOL(ath10k_warn); #ifdef CONFIG_ATH10K_DEBUGFS void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size) { memcpy(ar->debug.wmi_service_bitmap, service_map, map_size); } static ssize_t ath10k_read_wmi_services(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) Loading @@ -207,8 +200,9 @@ static ssize_t ath10k_read_wmi_services(struct file *file, if (len > buf_len) len = buf_len; spin_lock_bh(&ar->data_lock); for (i = 0; i < WMI_SERVICE_MAX; i++) { enabled = test_bit(i, ar->debug.wmi_service_bitmap); enabled = test_bit(i, ar->wmi.svc_map); name = wmi_service_name(i); if (!name) { Loading @@ -224,6 +218,7 @@ static ssize_t ath10k_read_wmi_services(struct file *file, "%-40s %s\n", name, enabled ? "enabled" : "-"); } spin_unlock_bh(&ar->data_lock); ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); Loading Loading @@ -866,8 +861,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, sizeof(dump_data->fw_ver)); dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE); strlcpy(dump_data->kernel_ver, VERMAGIC_STRING, dump_data->kernel_ver_code = 0; strlcpy(dump_data->kernel_ver, init_utsname()->release, sizeof(dump_data->kernel_ver)); dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); Loading Loading @@ -929,6 +924,236 @@ static const struct file_operations fops_fw_crash_dump = { .llseek = default_llseek, }; static ssize_t ath10k_reg_addr_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 buf[32]; unsigned int len = 0; u32 reg_addr; mutex_lock(&ar->conf_mutex); reg_addr = ar->debug.reg_addr; mutex_unlock(&ar->conf_mutex); len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } static ssize_t ath10k_reg_addr_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u32 reg_addr; int ret; ret = kstrtou32_from_user(user_buf, count, 0, ®_addr); if (ret) return ret; if (!IS_ALIGNED(reg_addr, 4)) return -EFAULT; mutex_lock(&ar->conf_mutex); ar->debug.reg_addr = reg_addr; mutex_unlock(&ar->conf_mutex); return count; } static const struct file_operations fops_reg_addr = { .read = ath10k_reg_addr_read, .write = ath10k_reg_addr_write, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static ssize_t ath10k_reg_value_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 buf[48]; unsigned int len; u32 reg_addr, reg_val; int ret; mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } reg_addr = ar->debug.reg_addr; reg_val = ath10k_hif_read32(ar, reg_addr); len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val); ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); exit: mutex_unlock(&ar->conf_mutex); return ret; } static ssize_t ath10k_reg_value_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u32 reg_addr, reg_val; int ret; mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } reg_addr = ar->debug.reg_addr; ret = kstrtou32_from_user(user_buf, count, 0, ®_val); if (ret) goto exit; ath10k_hif_write32(ar, reg_addr, reg_val); ret = count; exit: mutex_unlock(&ar->conf_mutex); return ret; } static const struct file_operations fops_reg_value = { .read = ath10k_reg_value_read, .write = ath10k_reg_value_write, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static ssize_t ath10k_mem_value_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 *buf; int ret; if (*ppos < 0) return -EINVAL; if (!count) return 0; mutex_lock(&ar->conf_mutex); buf = vmalloc(count); if (!buf) { ret = -ENOMEM; goto exit; } if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } ret = ath10k_hif_diag_read(ar, *ppos, buf, count); if (ret) { ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", (u32)(*ppos), ret); goto exit; } ret = copy_to_user(user_buf, buf, count); if (ret) { ret = -EFAULT; goto exit; } count -= ret; *ppos += count; ret = count; exit: vfree(buf); mutex_unlock(&ar->conf_mutex); return ret; } static ssize_t ath10k_mem_value_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 *buf; int ret; if (*ppos < 0) return -EINVAL; if (!count) return 0; mutex_lock(&ar->conf_mutex); buf = vmalloc(count); if (!buf) { ret = -ENOMEM; goto exit; } if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } ret = copy_from_user(buf, user_buf, count); if (ret) { ret = -EFAULT; goto exit; } ret = ath10k_hif_diag_write(ar, *ppos, buf, count); if (ret) { ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", (u32)(*ppos), ret); goto exit; } *ppos += count; ret = count; exit: vfree(buf); mutex_unlock(&ar->conf_mutex); return ret; } static const struct file_operations fops_mem_value = { .read = ath10k_mem_value_read, .write = ath10k_mem_value_write, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static int ath10k_debug_htt_stats_req(struct ath10k *ar) { u64 cookie; Loading Loading @@ -1630,6 +1855,15 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_fw_crash_dump); debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_reg_addr); debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_reg_value); debugfs_create_file("mem_value", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_mem_value); debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_chip_id); Loading drivers/net/wireless/ath/ath10k/debug.h +1 −9 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ enum ath10k_debug_mask { ATH10K_DBG_BMI = 0x00000400, ATH10K_DBG_REGULATORY = 0x00000800, ATH10K_DBG_TESTMODE = 0x00001000, ATH10K_DBG_WMI_PRINT = 0x00002000, ATH10K_DBG_ANY = 0xffffffff, }; Loading @@ -61,9 +62,6 @@ int ath10k_debug_create(struct ath10k *ar); void ath10k_debug_destroy(struct ath10k *ar); int ath10k_debug_register(struct ath10k *ar); void ath10k_debug_unregister(struct ath10k *ar); void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size); void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); struct ath10k_fw_crash_data * ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); Loading Loading @@ -108,12 +106,6 @@ static inline void ath10k_debug_unregister(struct ath10k *ar) { } static inline void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size) { } static inline void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) { Loading drivers/net/wireless/ath/ath10k/hif.h +39 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include "core.h" #include "debug.h" struct ath10k_hif_sg_item { u16 transfer_id; Loading @@ -31,11 +32,9 @@ struct ath10k_hif_sg_item { struct ath10k_hif_cb { int (*tx_completion)(struct ath10k *ar, struct sk_buff *wbuf, unsigned transfer_id); struct sk_buff *wbuf); int (*rx_completion)(struct ath10k *ar, struct sk_buff *wbuf, u8 pipe_id); struct sk_buff *wbuf); }; struct ath10k_hif_ops { Loading @@ -47,6 +46,8 @@ struct ath10k_hif_ops { int (*diag_read)(struct ath10k *ar, u32 address, void *buf, size_t buf_len); int (*diag_write)(struct ath10k *ar, u32 address, const void *data, int nbytes); /* * API to handle HIF-specific BMI message exchanges, this API is * synchronous and only allowed to be called from a context that Loading Loading @@ -84,6 +85,10 @@ struct ath10k_hif_ops { u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id); u32 (*read32)(struct ath10k *ar, u32 address); void (*write32)(struct ath10k *ar, u32 address, u32 value); /* Power up the device and enter BMI transfer mode for FW download */ int (*power_up)(struct ath10k *ar); Loading @@ -108,6 +113,15 @@ static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf return ar->hif.ops->diag_read(ar, address, buf, buf_len); } static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address, const void *data, int nbytes) { if (!ar->hif.ops->diag_write) return -EOPNOTSUPP; return ar->hif.ops->diag_write(ar, address, data, nbytes); } static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, void *request, u32 request_len, void *response, u32 *response_len) Loading Loading @@ -187,4 +201,25 @@ static inline int ath10k_hif_resume(struct ath10k *ar) return ar->hif.ops->resume(ar); } static inline u32 ath10k_hif_read32(struct ath10k *ar, u32 address) { if (!ar->hif.ops->read32) { ath10k_warn(ar, "hif read32 not supported\n"); return 0xdeaddead; } return ar->hif.ops->read32(ar, address); } static inline void ath10k_hif_write32(struct ath10k *ar, u32 address, u32 data) { if (!ar->hif.ops->write32) { ath10k_warn(ar, "hif write32 not supported\n"); return; } ar->hif.ops->write32(ar, address, data); } #endif /* _HIF_H_ */ Loading
drivers/net/wireless/ath/ath10k/core.c +13 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,17 @@ static void ath10k_core_restart(struct work_struct *work) mutex_unlock(&ar->conf_mutex); } static void ath10k_core_init_max_sta_count(struct ath10k *ar) { if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { ar->max_num_peers = TARGET_10X_NUM_PEERS; ar->max_num_stations = TARGET_10X_NUM_STATIONS; } else { ar->max_num_peers = TARGET_NUM_PEERS; ar->max_num_stations = TARGET_NUM_STATIONS; } } int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) { int status; Loading Loading @@ -1035,6 +1046,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar) return ret; } ath10k_core_init_max_sta_count(ar); mutex_lock(&ar->conf_mutex); ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); Loading
drivers/net/wireless/ath/ath10k/core.h +11 −2 Original line number Diff line number Diff line Loading @@ -79,10 +79,12 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus) struct ath10k_skb_cb { dma_addr_t paddr; u8 eid; u8 vdev_id; struct { u8 tid; u16 freq; bool is_offchan; struct ath10k_htt_txbuf *txbuf; u32 txbuf_paddr; Loading Loading @@ -122,6 +124,7 @@ struct ath10k_wmi { struct completion service_ready; struct completion unified_ready; wait_queue_head_t tx_credits_wq; DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX); struct wmi_cmd_map *cmd; struct wmi_vdev_param_map *vdev_param; struct wmi_pdev_param_map *pdev_param; Loading Loading @@ -218,6 +221,8 @@ struct ath10k_peer { int vdev_id; u8 addr[ETH_ALEN]; DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS); /* protected by ar->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; }; Loading Loading @@ -310,7 +315,6 @@ struct ath10k_debug { struct ath10k_fw_stats fw_stats; struct completion fw_stats_complete; bool fw_stats_done; DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX); unsigned long htt_stats_mask; struct delayed_work htt_stats_dwork; Loading @@ -320,6 +324,7 @@ struct ath10k_debug { /* protected by conf_mutex */ u32 fw_dbglog_mask; u32 pktlog_filter; u32 reg_addr; u8 htt_max_amsdu; u8 htt_max_ampdu; Loading Loading @@ -560,8 +565,12 @@ struct ath10k { struct list_head peers; wait_queue_head_t peer_mapping_wq; /* number of created peers; protected by data_lock */ /* protected by conf_mutex */ int num_peers; int num_stations; int max_num_peers; int max_num_stations; struct work_struct offchan_tx_work; struct sk_buff_head offchan_tx_queue; Loading
drivers/net/wireless/ath/ath10k/debug.c +248 −14 Original line number Diff line number Diff line Loading @@ -17,9 +17,8 @@ #include <linux/module.h> #include <linux/debugfs.h> #include <linux/version.h> #include <linux/vermagic.h> #include <linux/vmalloc.h> #include <linux/utsname.h> #include "core.h" #include "debug.h" Loading Loading @@ -124,7 +123,7 @@ EXPORT_SYMBOL(ath10k_info); void ath10k_print_driver_info(struct ath10k *ar) { ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s\n", ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n", ar->hw_params.name, ar->target_version, ar->chip_id, Loading @@ -136,7 +135,8 @@ void ath10k_print_driver_info(struct ath10k *ar) ar->fw_version_minor, ar->fw_version_release, ar->fw_version_build, ath10k_cal_mode_str(ar->cal_mode)); ath10k_cal_mode_str(ar->cal_mode), ar->max_num_stations); ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", config_enabled(CONFIG_ATH10K_DEBUG), config_enabled(CONFIG_ATH10K_DEBUGFS), Loading Loading @@ -179,13 +179,6 @@ EXPORT_SYMBOL(ath10k_warn); #ifdef CONFIG_ATH10K_DEBUGFS void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size) { memcpy(ar->debug.wmi_service_bitmap, service_map, map_size); } static ssize_t ath10k_read_wmi_services(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) Loading @@ -207,8 +200,9 @@ static ssize_t ath10k_read_wmi_services(struct file *file, if (len > buf_len) len = buf_len; spin_lock_bh(&ar->data_lock); for (i = 0; i < WMI_SERVICE_MAX; i++) { enabled = test_bit(i, ar->debug.wmi_service_bitmap); enabled = test_bit(i, ar->wmi.svc_map); name = wmi_service_name(i); if (!name) { Loading @@ -224,6 +218,7 @@ static ssize_t ath10k_read_wmi_services(struct file *file, "%-40s %s\n", name, enabled ? "enabled" : "-"); } spin_unlock_bh(&ar->data_lock); ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); Loading Loading @@ -866,8 +861,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, sizeof(dump_data->fw_ver)); dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE); strlcpy(dump_data->kernel_ver, VERMAGIC_STRING, dump_data->kernel_ver_code = 0; strlcpy(dump_data->kernel_ver, init_utsname()->release, sizeof(dump_data->kernel_ver)); dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); Loading Loading @@ -929,6 +924,236 @@ static const struct file_operations fops_fw_crash_dump = { .llseek = default_llseek, }; static ssize_t ath10k_reg_addr_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 buf[32]; unsigned int len = 0; u32 reg_addr; mutex_lock(&ar->conf_mutex); reg_addr = ar->debug.reg_addr; mutex_unlock(&ar->conf_mutex); len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } static ssize_t ath10k_reg_addr_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u32 reg_addr; int ret; ret = kstrtou32_from_user(user_buf, count, 0, ®_addr); if (ret) return ret; if (!IS_ALIGNED(reg_addr, 4)) return -EFAULT; mutex_lock(&ar->conf_mutex); ar->debug.reg_addr = reg_addr; mutex_unlock(&ar->conf_mutex); return count; } static const struct file_operations fops_reg_addr = { .read = ath10k_reg_addr_read, .write = ath10k_reg_addr_write, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static ssize_t ath10k_reg_value_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 buf[48]; unsigned int len; u32 reg_addr, reg_val; int ret; mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } reg_addr = ar->debug.reg_addr; reg_val = ath10k_hif_read32(ar, reg_addr); len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val); ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); exit: mutex_unlock(&ar->conf_mutex); return ret; } static ssize_t ath10k_reg_value_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u32 reg_addr, reg_val; int ret; mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } reg_addr = ar->debug.reg_addr; ret = kstrtou32_from_user(user_buf, count, 0, ®_val); if (ret) goto exit; ath10k_hif_write32(ar, reg_addr, reg_val); ret = count; exit: mutex_unlock(&ar->conf_mutex); return ret; } static const struct file_operations fops_reg_value = { .read = ath10k_reg_value_read, .write = ath10k_reg_value_write, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static ssize_t ath10k_mem_value_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 *buf; int ret; if (*ppos < 0) return -EINVAL; if (!count) return 0; mutex_lock(&ar->conf_mutex); buf = vmalloc(count); if (!buf) { ret = -ENOMEM; goto exit; } if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } ret = ath10k_hif_diag_read(ar, *ppos, buf, count); if (ret) { ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", (u32)(*ppos), ret); goto exit; } ret = copy_to_user(user_buf, buf, count); if (ret) { ret = -EFAULT; goto exit; } count -= ret; *ppos += count; ret = count; exit: vfree(buf); mutex_unlock(&ar->conf_mutex); return ret; } static ssize_t ath10k_mem_value_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; u8 *buf; int ret; if (*ppos < 0) return -EINVAL; if (!count) return 0; mutex_lock(&ar->conf_mutex); buf = vmalloc(count); if (!buf) { ret = -ENOMEM; goto exit; } if (ar->state != ATH10K_STATE_ON && ar->state != ATH10K_STATE_UTF) { ret = -ENETDOWN; goto exit; } ret = copy_from_user(buf, user_buf, count); if (ret) { ret = -EFAULT; goto exit; } ret = ath10k_hif_diag_write(ar, *ppos, buf, count); if (ret) { ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", (u32)(*ppos), ret); goto exit; } *ppos += count; ret = count; exit: vfree(buf); mutex_unlock(&ar->conf_mutex); return ret; } static const struct file_operations fops_mem_value = { .read = ath10k_mem_value_read, .write = ath10k_mem_value_write, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static int ath10k_debug_htt_stats_req(struct ath10k *ar) { u64 cookie; Loading Loading @@ -1630,6 +1855,15 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_fw_crash_dump); debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_reg_addr); debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_reg_value); debugfs_create_file("mem_value", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_mem_value); debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_chip_id); Loading
drivers/net/wireless/ath/ath10k/debug.h +1 −9 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ enum ath10k_debug_mask { ATH10K_DBG_BMI = 0x00000400, ATH10K_DBG_REGULATORY = 0x00000800, ATH10K_DBG_TESTMODE = 0x00001000, ATH10K_DBG_WMI_PRINT = 0x00002000, ATH10K_DBG_ANY = 0xffffffff, }; Loading @@ -61,9 +62,6 @@ int ath10k_debug_create(struct ath10k *ar); void ath10k_debug_destroy(struct ath10k *ar); int ath10k_debug_register(struct ath10k *ar); void ath10k_debug_unregister(struct ath10k *ar); void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size); void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); struct ath10k_fw_crash_data * ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); Loading Loading @@ -108,12 +106,6 @@ static inline void ath10k_debug_unregister(struct ath10k *ar) { } static inline void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size) { } static inline void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) { Loading
drivers/net/wireless/ath/ath10k/hif.h +39 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include "core.h" #include "debug.h" struct ath10k_hif_sg_item { u16 transfer_id; Loading @@ -31,11 +32,9 @@ struct ath10k_hif_sg_item { struct ath10k_hif_cb { int (*tx_completion)(struct ath10k *ar, struct sk_buff *wbuf, unsigned transfer_id); struct sk_buff *wbuf); int (*rx_completion)(struct ath10k *ar, struct sk_buff *wbuf, u8 pipe_id); struct sk_buff *wbuf); }; struct ath10k_hif_ops { Loading @@ -47,6 +46,8 @@ struct ath10k_hif_ops { int (*diag_read)(struct ath10k *ar, u32 address, void *buf, size_t buf_len); int (*diag_write)(struct ath10k *ar, u32 address, const void *data, int nbytes); /* * API to handle HIF-specific BMI message exchanges, this API is * synchronous and only allowed to be called from a context that Loading Loading @@ -84,6 +85,10 @@ struct ath10k_hif_ops { u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id); u32 (*read32)(struct ath10k *ar, u32 address); void (*write32)(struct ath10k *ar, u32 address, u32 value); /* Power up the device and enter BMI transfer mode for FW download */ int (*power_up)(struct ath10k *ar); Loading @@ -108,6 +113,15 @@ static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf return ar->hif.ops->diag_read(ar, address, buf, buf_len); } static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address, const void *data, int nbytes) { if (!ar->hif.ops->diag_write) return -EOPNOTSUPP; return ar->hif.ops->diag_write(ar, address, data, nbytes); } static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, void *request, u32 request_len, void *response, u32 *response_len) Loading Loading @@ -187,4 +201,25 @@ static inline int ath10k_hif_resume(struct ath10k *ar) return ar->hif.ops->resume(ar); } static inline u32 ath10k_hif_read32(struct ath10k *ar, u32 address) { if (!ar->hif.ops->read32) { ath10k_warn(ar, "hif read32 not supported\n"); return 0xdeaddead; } return ar->hif.ops->read32(ar, address); } static inline void ath10k_hif_write32(struct ath10k *ar, u32 address, u32 data) { if (!ar->hif.ops->write32) { ath10k_warn(ar, "hif write32 not supported\n"); return; } ar->hif.ops->write32(ar, address, data); } #endif /* _HIF_H_ */