wl18xx: add dynamic fw traces
authorGuy Mishol <guym@ti.com>
Mon, 27 Jul 2015 06:46:02 +0000 (09:46 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 6 Aug 2015 07:18:14 +0000 (10:18 +0300)
add option to dynamically configure the fw
which debug traces to open

Signed-off-by: Guy Mishol <guym@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ti/wl18xx/acx.c
drivers/net/wireless/ti/wl18xx/acx.h
drivers/net/wireless/ti/wl18xx/debugfs.c
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wlcore/wlcore.h

index 67f2a0eec8542190ea6d8c374240492d9b95ed73..4be0409308cb6f2a9d315b7ed77d2150f65ad6f0 100644 (file)
@@ -282,3 +282,30 @@ out:
        kfree(acx);
        return ret;
 }
+
+int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl)
+{
+       struct acx_dynamic_fw_traces_cfg *acx;
+       int ret;
+
+       wl1271_debug(DEBUG_ACX, "acx dynamic fw traces config %d",
+                    wl->dynamic_fw_traces);
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->dynamic_fw_traces = cpu_to_le32(wl->dynamic_fw_traces);
+
+       ret = wl1271_cmd_configure(wl, ACX_DYNAMIC_TRACES_CFG,
+                                  acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1271_warning("acx config dynamic fw traces failed: %d", ret);
+               goto out;
+       }
+out:
+       kfree(acx);
+       return ret;
+}
index 4afccd4b946752b6312bc2301ab13e02c14944da..c8a33f43916ef2dffe116229e661985a152ecc47 100644 (file)
@@ -35,7 +35,8 @@ enum {
        ACX_PEER_CAP                     = 0x0056,
        ACX_INTERRUPT_NOTIFY             = 0x0057,
        ACX_RX_BA_FILTER                 = 0x0058,
-       ACX_AP_SLEEP_CFG                 = 0x0059
+       ACX_AP_SLEEP_CFG                 = 0x0059,
+       ACX_DYNAMIC_TRACES_CFG           = 0x005A,
 };
 
 /* numbers of bits the length field takes (add 1 for the actual number) */
@@ -367,6 +368,15 @@ struct acx_ap_sleep_cfg {
        u8 idle_conn_thresh;
 } __packed;
 
+/*
+ * ACX_DYNAMIC_TRACES_CFG
+ * configure the FW dynamic traces
+ */
+struct acx_dynamic_fw_traces_cfg {
+       struct acx_header header;
+       __le32 dynamic_fw_traces;
+} __packed;
+
 int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
                                  u32 sdio_blk_size, u32 extra_mem_blks,
                                  u32 len_field_size);
@@ -380,5 +390,6 @@ int wl18xx_acx_set_peer_cap(struct wl1271 *wl,
 int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl, bool action);
 int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action);
 int wl18xx_acx_ap_sleep(struct wl1271 *wl);
+int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl);
 
 #endif /* __WL18XX_ACX_H__ */
index 5fbd2230f372f2a17d763be90efa3228bca5bdbd..8c6a1c86f526981ba3f947f0948fd3acb46d9e6f 100644 (file)
@@ -281,6 +281,55 @@ static const struct file_operations radar_detection_ops = {
        .llseek = default_llseek,
 };
 
+static ssize_t dynamic_fw_traces_write(struct file *file,
+                                       const char __user *user_buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       unsigned long value;
+       int ret;
+
+       ret = kstrtoul_from_user(user_buf, count, 0, &value);
+       if (ret < 0)
+               return ret;
+
+       mutex_lock(&wl->mutex);
+
+       wl->dynamic_fw_traces = value;
+
+       if (unlikely(wl->state != WLCORE_STATE_ON))
+               goto out;
+
+       ret = wl1271_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl18xx_acx_dynamic_fw_traces(wl);
+       if (ret < 0)
+               count = ret;
+
+       wl1271_ps_elp_sleep(wl);
+out:
+       mutex_unlock(&wl->mutex);
+       return count;
+}
+
+static ssize_t dynamic_fw_traces_read(struct file *file,
+                                       char __user *userbuf,
+                                       size_t count, loff_t *ppos)
+{
+       struct wl1271 *wl = file->private_data;
+       return wl1271_format_buffer(userbuf, count, ppos,
+                                   "%d\n", wl->dynamic_fw_traces);
+}
+
+static const struct file_operations dynamic_fw_traces_ops = {
+       .read = dynamic_fw_traces_read,
+       .write = dynamic_fw_traces_write,
+       .open = simple_open,
+       .llseek = default_llseek,
+};
+
 int wl18xx_debugfs_add_files(struct wl1271 *wl,
                             struct dentry *rootdir)
 {
@@ -433,6 +482,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl,
 
        DEBUGFS_ADD(conf, moddir);
        DEBUGFS_ADD(radar_detection, moddir);
+       DEBUGFS_ADD(dynamic_fw_traces, moddir);
 
        return 0;
 
index 49aca2cf76050200771705ecb6c535ba1eee804e..8ce9825ee57762c26ae3b220876f7ae1aa0571f1 100644 (file)
@@ -1159,6 +1159,11 @@ static int wl18xx_hw_init(struct wl1271 *wl)
        if (ret < 0)
                return ret;
 
+       /* set the dynamic fw traces bitmap */
+       ret = wl18xx_acx_dynamic_fw_traces(wl);
+       if (ret < 0)
+               return ret;
+
        if (checksum_param) {
                ret = wl18xx_acx_set_checksum_state(wl);
                if (ret != 0)
index 7f363fa566a3478b24e354abd3dadacb19275e6a..a1b6040e6491219544be4054343ff00f6c555db1 100644 (file)
@@ -500,6 +500,9 @@ struct wl1271 {
        /* interface combinations supported by the hw */
        const struct ieee80211_iface_combination *iface_combinations;
        u8 n_iface_combinations;
+
+       /* dynamic fw traces */
+       u32 dynamic_fw_traces;
 };
 
 int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);