ath6kl: implement support to set firmware log parameters
authorKalle Valo <kvalo@qca.qualcomm.com>
Fri, 2 Sep 2011 07:32:04 +0000 (10:32 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Fri, 2 Sep 2011 07:32:04 +0000 (10:32 +0300)
Firmware log parameters can be controlled now with help of fwlog_mask
debugfs file.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/debug.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h

index 319e768d9ad600da457fdc5930797f97132aca32..58c810acdbf2a5ad769dda2062d3a7a666a9f846 100644 (file)
@@ -474,6 +474,7 @@ struct ath6kl {
                struct circ_buf fwlog_buf;
                spinlock_t fwlog_lock;
                void *fwlog_tmp;
+               u32 fwlog_mask;
        } debug;
 #endif /* CONFIG_ATH6KL_DEBUG */
 };
index b2706da581492e35e61fdde346cf977df393317c..239c092d3e11ecf058b6de46af489e4e19c64235 100644 (file)
@@ -17,6 +17,7 @@
 #include "core.h"
 
 #include <linux/circ_buf.h>
+#include <linux/fs.h>
 
 #include "debug.h"
 #include "target.h"
@@ -32,6 +33,7 @@ struct ath6kl_fwlog_slot {
 #define ATH6KL_FWLOG_SIZE 32768
 #define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \
                                ATH6KL_FWLOG_PAYLOAD_SIZE)
+#define ATH6KL_FWLOG_VALID_MASK 0x1ffff
 
 int ath6kl_printk(const char *level, const char *fmt, ...)
 {
@@ -280,6 +282,46 @@ static const struct file_operations fops_fwlog = {
        .llseek = default_llseek,
 };
 
+static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf,
+                                     size_t count, loff_t *ppos)
+{
+       struct ath6kl *ar = file->private_data;
+       char buf[16];
+       int len;
+
+       len = snprintf(buf, sizeof(buf), "0x%x\n", ar->debug.fwlog_mask);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath6kl_fwlog_mask_write(struct file *file,
+                                      const char __user *user_buf,
+                                      size_t count, loff_t *ppos)
+{
+       struct ath6kl *ar = file->private_data;
+       int ret;
+
+       ret = kstrtou32_from_user(user_buf, count, 0, &ar->debug.fwlog_mask);
+       if (ret)
+               return ret;
+
+       ret = ath6kl_wmi_config_debug_module_cmd(ar->wmi,
+                                                ATH6KL_FWLOG_VALID_MASK,
+                                                ar->debug.fwlog_mask);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static const struct file_operations fops_fwlog_mask = {
+       .open = ath6kl_debugfs_open,
+       .read = ath6kl_fwlog_mask_read,
+       .write = ath6kl_fwlog_mask_write,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
 static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
@@ -497,6 +539,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
 
        spin_lock_init(&ar->debug.fwlog_lock);
 
+       /*
+        * Actually we are lying here but don't know how to read the mask
+        * value from the firmware.
+        */
+       ar->debug.fwlog_mask = 0;
+
        ar->debugfs_phy = debugfs_create_dir("ath6kl",
                                             ar->wdev->wiphy->debugfsdir);
        if (!ar->debugfs_phy) {
@@ -514,6 +562,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
        debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
                            &fops_fwlog);
 
+       debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy,
+                           ar, &fops_fwlog_mask);
+
        return 0;
 }
 
index 954d5e18e888b0dd2859d8cab9620486b4fed163..7201a72ac1b852605c98939ca232702c1826e7b1 100644 (file)
@@ -2412,6 +2412,25 @@ int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
        return ret;
 }
 
+int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config)
+{
+       struct ath6kl_wmix_dbglog_cfg_module_cmd *cmd;
+       struct sk_buff *skb;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct ath6kl_wmix_dbglog_cfg_module_cmd *) skb->data;
+       cmd->valid = cpu_to_le32(valid);
+       cmd->config = cpu_to_le32(config);
+
+       ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_DBGLOG_CFG_MODULE_CMDID,
+                                      NO_SYNC_WMIFLAG);
+       return ret;
+}
+
 int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
 {
        return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
index 5d68d8f2032cfc45474ba779355dcaae3cea9d19..1c565816f622b26325bc1b5e547fb4d587b1f61f 100644 (file)
@@ -2083,6 +2083,11 @@ struct wmix_hb_challenge_resp_cmd {
        __le32 source;
 } __packed;
 
+struct ath6kl_wmix_dbglog_cfg_module_cmd {
+       __le32 valid;
+       __le32 config;
+} __packed;
+
 /* End of Extended WMI (WMIX) */
 
 enum wmi_sync_flag {
@@ -2162,6 +2167,7 @@ int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
                                 u8 preamble_policy);
 
 int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
+int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config);
 
 int ath6kl_wmi_get_stats_cmd(struct wmi *wmi);
 int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,