ath10k: add support to configure pktlog filter
authorRajkumar Manoharan <rmanohar@qti.qualcomm.com>
Fri, 3 Oct 2014 05:02:33 +0000 (08:02 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 7 Oct 2014 14:09:56 +0000 (17:09 +0300)
Add support to configure packet log filters (tx, rx, rate control)
via debugfs. To disable htt pktlog events set the filters to 0.

ex:

To enable pktlog for all filters

   echo 0x1f > /sys/kernel/debug/ieee80211/phy*/ath10k/pktlog_filter

To disable pktlog

   echo 0 > /sys/kernel/debug/ieee80211/phy*/ath10k/pktlog_filter

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

index 754ecc5..1ac2f14 100644 (file)
@@ -302,7 +302,9 @@ struct ath10k_debug {
        struct ath10k_dfs_stats dfs_stats;
        struct ath_dfs_pool_stats dfs_pool_stats;
 
+       /* protected by conf_mutex */
        u32 fw_dbglog_mask;
+       u32 pktlog_filter;
 
        u8 htt_max_amsdu;
        u8 htt_max_ampdu;
index 2bb894f..0d94feb 100644 (file)
@@ -1396,7 +1396,22 @@ int ath10k_debug_start(struct ath10k *ar)
                                    ret);
        }
 
-       return 0;
+       if (ar->debug.pktlog_filter) {
+               ret = ath10k_wmi_pdev_pktlog_enable(ar,
+                                                   ar->debug.pktlog_filter);
+               if (ret)
+                       /* not serious */
+                       ath10k_warn(ar,
+                                   "failed to enable pktlog filter %x: %d\n",
+                                   ar->debug.pktlog_filter, ret);
+       } else {
+               ret = ath10k_wmi_pdev_pktlog_disable(ar);
+               if (ret)
+                       /* not serious */
+                       ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
+       }
+
+       return ret;
 }
 
 void ath10k_debug_stop(struct ath10k *ar)
@@ -1411,6 +1426,8 @@ void ath10k_debug_stop(struct ath10k *ar)
 
        ar->debug.htt_max_amsdu = 0;
        ar->debug.htt_max_ampdu = 0;
+
+       ath10k_wmi_pdev_pktlog_disable(ar);
 }
 
 static ssize_t ath10k_write_simulate_radar(struct file *file,
@@ -1493,6 +1510,69 @@ static const struct file_operations fops_dfs_stats = {
        .llseek = default_llseek,
 };
 
+static ssize_t ath10k_write_pktlog_filter(struct file *file,
+                                         const char __user *ubuf,
+                                         size_t count, loff_t *ppos)
+{
+       struct ath10k *ar = file->private_data;
+       u32 filter;
+       int ret;
+
+       if (kstrtouint_from_user(ubuf, count, 0, &filter))
+               return -EINVAL;
+
+       mutex_lock(&ar->conf_mutex);
+
+       if (ar->state != ATH10K_STATE_ON) {
+               ar->debug.pktlog_filter = filter;
+               ret = count;
+               goto out;
+       }
+
+       if (filter && (filter != ar->debug.pktlog_filter)) {
+               ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
+               if (ret) {
+                       ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
+                                   ar->debug.pktlog_filter, ret);
+                       goto out;
+               }
+       } else {
+               ret = ath10k_wmi_pdev_pktlog_disable(ar);
+               if (ret) {
+                       ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
+                       goto out;
+               }
+       }
+
+       ar->debug.pktlog_filter = filter;
+       ret = count;
+
+out:
+       mutex_unlock(&ar->conf_mutex);
+       return ret;
+}
+
+static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf,
+                                        size_t count, loff_t *ppos)
+{
+       char buf[32];
+       struct ath10k *ar = file->private_data;
+       int len = 0;
+
+       mutex_lock(&ar->conf_mutex);
+       len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
+                       ar->debug.pktlog_filter);
+       mutex_unlock(&ar->conf_mutex);
+
+       return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_pktlog_filter = {
+       .read = ath10k_read_pktlog_filter,
+       .write = ath10k_write_pktlog_filter,
+       .open = simple_open
+};
+
 int ath10k_debug_create(struct ath10k *ar)
 {
        ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
@@ -1574,6 +1654,9 @@ int ath10k_debug_register(struct ath10k *ar)
                                    &fops_dfs_stats);
        }
 
+       debugfs_create_file("pktlog_filter", S_IRUGO | S_IWUSR,
+                           ar->debug.debugfs_phy, ar, &fops_pktlog_filter);
+
        return 0;
 }
 
index d6a565d..ce86ed2 100644 (file)
@@ -38,6 +38,15 @@ enum ath10k_debug_mask {
        ATH10K_DBG_ANY          = 0xffffffff,
 };
 
+enum ath10k_pktlog_filter {
+       ATH10K_PKTLOG_RX         = 0x000000001,
+       ATH10K_PKTLOG_TX         = 0x000000002,
+       ATH10K_PKTLOG_RCFIND     = 0x000000004,
+       ATH10K_PKTLOG_RCUPDATE   = 0x000000008,
+       ATH10K_PKTLOG_DBG_PRINT  = 0x000000010,
+       ATH10K_PKTLOG_ANY        = 0x00000001f,
+};
+
 extern unsigned int ath10k_debug_mask;
 
 __printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
index f65032f..c145b98 100644 (file)
@@ -4345,6 +4345,39 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
        return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
 }
 
+int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_bitmap)
+{
+       struct wmi_pdev_pktlog_enable_cmd *cmd;
+       struct sk_buff *skb;
+
+       skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       ev_bitmap &= ATH10K_PKTLOG_ANY;
+       ath10k_dbg(ar, ATH10K_DBG_WMI,
+                  "wmi enable pktlog filter:%x\n", ev_bitmap);
+
+       cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data;
+       cmd->ev_bitmap = __cpu_to_le32(ev_bitmap);
+       return ath10k_wmi_cmd_send(ar, skb,
+                                  ar->wmi.cmd->pdev_pktlog_enable_cmdid);
+}
+
+int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar)
+{
+       struct sk_buff *skb;
+
+       skb = ath10k_wmi_alloc_skb(ar, 0);
+       if (!skb)
+               return -ENOMEM;
+
+       ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n");
+
+       return ath10k_wmi_cmd_send(ar, skb,
+                                  ar->wmi.cmd->pdev_pktlog_disable_cmdid);
+}
+
 int ath10k_wmi_attach(struct ath10k *ar)
 {
        if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
index 6243dbe..a38d788 100644 (file)
@@ -2787,6 +2787,10 @@ struct wmi_pdev_set_channel_cmd {
        struct wmi_channel chan;
 } __packed;
 
+struct wmi_pdev_pktlog_enable_cmd {
+       __le32 ev_bitmap;
+} __packed;
+
 /* Customize the DSCP (bit) to TID (0-7) mapping for QOS */
 #define WMI_DSCP_MAP_MAX    (64)
 struct wmi_pdev_set_dscp_tid_map_cmd {
@@ -4647,5 +4651,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);
 int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable);
 int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
                             struct ath10k_fw_stats *stats);
+int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_list);
+int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar);
 
 #endif /* _WMI_H_ */