[9610] wlbt: Create and register Wlan sable file clients
authorAlbert Cano <a.canocamps@samsung.com>
Thu, 12 Jul 2018 18:29:26 +0000 (19:29 +0100)
committerhskang <hs1218.kang@samsung.com>
Fri, 17 Aug 2018 00:32:55 +0000 (20:32 -0400)
Create and register wlan sable file client to collect hip4 samples and
hcf a sbl file.

Add UDI as a mxlogger observer

Change-Id: I69d14126920ffc01d07b976847318ebeed2789fb
SCSC-Bug-Id: SSB-41876
Signed-off-by: Cristian Marussi <c.marussi@samsung.com>
Signed-off-by: Albert Cano <a.canocamps@samsung.com>
drivers/net/wireless/scsc/cm_if.c
drivers/net/wireless/scsc/dev.h
drivers/net/wireless/scsc/hip4.c
drivers/net/wireless/scsc/hip4.h
drivers/net/wireless/scsc/hip4_sampler.c
drivers/net/wireless/scsc/procfs.c
drivers/net/wireless/scsc/udi.c

index b166f20c9d044c679abbe7a9541486fe64ec94f0..7f59f52481a380177105d5cec2c215be0c0a6bdb 100755 (executable)
@@ -16,6 +16,9 @@
 
 #include "../scsc/scsc_mx_impl.h" /* TODO */
 #include <scsc/scsc_mx.h>
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+#include <scsc/scsc_log_collector.h>
+#endif
 
 static bool EnableTestMode;
 module_param(EnableTestMode, bool, S_IRUGO | S_IWUSR);
@@ -154,6 +157,9 @@ void slsi_wlan_service_probe(struct scsc_mx_module_client *module_client, struct
        struct slsi_dev            *sdev;
        struct device              *dev;
        struct scsc_service_client mx_wlan_client;
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+       char buf[SCSC_LOG_FAPI_VERSION_SIZE];
+#endif
 
        SLSI_UNUSED_PARAMETER(module_client);
 
@@ -201,6 +207,20 @@ void slsi_wlan_service_probe(struct scsc_mx_module_client *module_client, struct
 
 #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING
                hip4_sampler_create(sdev, mx);
+#endif
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+               memset(buf, 0, SCSC_LOG_FAPI_VERSION_SIZE);
+               /* Write FAPI VERSION to collector header */
+               /* IMPORTANT - Do not change the formatting as User space tooling is parsing the string
+                * to read SAP fapi versions.
+                */
+               snprintf(buf, SCSC_LOG_FAPI_VERSION_SIZE, "ma:%u.%u, mlme:%u.%u, debug:%u.%u, test:%u.%u",
+                        FAPI_MAJOR_VERSION(FAPI_DATA_SAP_VERSION), FAPI_MINOR_VERSION(FAPI_DATA_SAP_VERSION),
+                        FAPI_MAJOR_VERSION(FAPI_CONTROL_SAP_VERSION), FAPI_MINOR_VERSION(FAPI_CONTROL_SAP_VERSION),
+                        FAPI_MAJOR_VERSION(FAPI_DEBUG_SAP_VERSION), FAPI_MINOR_VERSION(FAPI_DEBUG_SAP_VERSION),
+                        FAPI_MAJOR_VERSION(FAPI_TEST_SAP_VERSION), FAPI_MINOR_VERSION(FAPI_TEST_SAP_VERSION));
+
+               scsc_log_collector_write_fapi(buf, SCSC_LOG_FAPI_VERSION_SIZE);
 #endif
        }
 
index 2f04dfb648bdfab2102a72d149b17ea730515841..dbee1776c4dace1c7b03d47e6b2b60a2edd93a3a 100755 (executable)
@@ -47,6 +47,9 @@
 #include "nl80211_vendor.h"
 #include "traffic_monitor.h"
 
+#define FAPI_MAJOR_VERSION(v) (((v) >> 8) & 0xFF)
+#define FAPI_MINOR_VERSION(v) ((v) & 0xFF)
+
 #ifdef CONFIG_SCSC_WLAN_DEBUG
 /* the FAPI definition should be in fapi.h auto-generated file.
  * But until a new FAPI version is generated, the definition for
index 52efa5d985ba63c7a0ca413e23155a0cc7744458..34d7e81d92b7fa883606c2d99941feb5d2706461 100755 (executable)
@@ -13,6 +13,9 @@
 #include <linux/ktime.h>
 #include <linux/kthread.h>
 #include <scsc/scsc_logring.h>
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+#include <scsc/scsc_log_collector.h>
+#endif
 
 #include "hip4.h"
 #include "mbulk.h"
@@ -433,6 +436,41 @@ static const struct file_operations hip4_procfs_jitter_fops = {
 };
 #endif
 
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+static int hip4_collect(struct scsc_log_collector_client *collect_client, size_t size)
+{
+       struct slsi_hip4 *hip = (struct slsi_hip4 *)collect_client->prv;
+       struct hip4_priv *hip_priv;
+       int ret = 0;
+
+       if (!hip)
+               return 0;
+
+       hip_priv = hip->hip_priv;
+       if (!hip_priv)
+               return 0;
+
+       if (!hip_priv->mib_collect || !hip_priv->mib_sz)
+               return 0;
+
+       SLSI_INFO_NODEV("Hip4 collecting HCF\n");
+       mutex_lock(&hip_priv->in_collection);
+       ret = scsc_log_collector_write(hip_priv->mib_collect, hip_priv->mib_sz, 1);
+       mutex_unlock(&hip_priv->in_collection);
+       return ret;
+}
+
+/* Collect client registration for HCF file*/
+struct scsc_log_collector_client hip4_collect_hcf_client = {
+       .name = "wlan_hcf",
+       .type = SCSC_LOG_CHUNK_WLAN_HCF,
+       .collect_init = NULL,
+       .collect = hip4_collect,
+       .collect_end = NULL,
+       .prv = NULL,
+};
+#endif
+
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0))
 static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec)
 {
@@ -962,9 +1000,8 @@ static void hip4_wq(struct work_struct *data)
 #endif
                mem = scsc_mx_service_mif_addr_to_ptr(service, ref);
                m = (struct mbulk *)mem;
-
                if (!m) {
-                       SLSI_ERR_NODEV("FB: Mbulk is NULL\n");
+                       SLSI_ERR_NODEV("FB: Mbulk is NULL 0x%x\n", ref);
                        goto consume_fb_mbulk;
                }
                /* colour is defined as: */
@@ -1031,6 +1068,10 @@ consume_fb_mbulk:
 #endif
                mem = scsc_mx_service_mif_addr_to_ptr(service, ref);
                m = (struct mbulk *)(mem);
+               if (!m) {
+                       SLSI_ERR_NODEV("Ctrl: Mbulk is NULL 0x%x\n", ref);
+                       goto consume_ctl_mbulk;
+               }
                /* Process Control Signal */
 
                skb = hip4_mbulk_to_skb(service, m, to_free, false);
@@ -1142,6 +1183,11 @@ consume_ctl_mbulk:
 #endif
                mem = scsc_mx_service_mif_addr_to_ptr(service, ref);
                m = (struct mbulk *)(mem);
+               if (!m) {
+                       SLSI_ERR_NODEV("Dat: Mbulk is NULL 0x%x\n", ref);
+                       goto consume_dat_mbulk;
+               }
+
                skb = hip4_mbulk_to_skb(service, m, to_free, false);
                if (!skb) {
                        SLSI_ERR_NODEV("Dat: Error parsing skb\n");
@@ -1468,6 +1514,7 @@ int hip4_init(struct slsi_hip4 *hip)
                hip_control->config_v4.mib_sz       = 0;
                hip_control->config_v3.mib_loc      = 0;
                hip_control->config_v3.mib_sz       = 0;
+               total_mib_len = 0;
        } else if (total_mib_len) {
                SLSI_INFO_NODEV("Loading MIB into shared memory, size (%d)\n", total_mib_len);
                /* Load each MIB file into shared DRAM region */
@@ -1602,6 +1649,23 @@ int hip4_init(struct slsi_hip4 *hip)
                        SLSI_WARN(sdev, "failed to add PM QoS request\n");
                }
        }
+
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+       /* Register with log collector to collect wlan hcf file */
+       /* Make a copy for collection */
+       mutex_init(&hip->hip_priv->in_collection);
+       if (total_mib_len) {
+               hip->hip_priv->mib_collect = vmalloc(total_mib_len);
+               if (hip->hip_priv->mib_collect) {
+                       memcpy(hip->hip_priv->mib_collect, (u8 *)hip_ptr + HIP4_WLAN_MIB_OFFSET, total_mib_len);
+                       hip->hip_priv->mib_sz = total_mib_len;
+                       hip4_collect_hcf_client.prv = hip;
+                       scsc_log_collector_register_client(&hip4_collect_hcf_client);
+               } else {
+                       SLSI_WARN(sdev, "failed to allocate memory for hcf file backup\n");
+               }
+       }
+#endif
        return 0;
 }
 
@@ -1849,6 +1913,17 @@ void hip4_deinit(struct slsi_hip4 *hip)
 
        service = sdev->service;
 
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+       mutex_lock(&hip->hip_priv->in_collection);
+       hip4_collect_hcf_client.prv = NULL;
+       scsc_log_collector_unregister_client(&hip4_collect_hcf_client);
+       if (hip->hip_priv->mib_collect) {
+               hip->hip_priv->mib_sz = 0;
+               vfree(hip->hip_priv->mib_collect);
+       }
+       mutex_unlock(&hip->hip_priv->in_collection);
+#endif
+
        /* de-register with traffic monitor */
        slsi_traffic_mon_client_unregister(sdev, hip);
        scsc_service_pm_qos_remove_request(service);
index e14d1f8079bac853d86057d0d45f1327d926c5dc..346452966693f5d53506968d2819bacbbc793917 100755 (executable)
@@ -324,8 +324,14 @@ struct hip4_priv {
        /* PM QoS control */
        struct work_struct           pm_qos_work;
        /* PM QoS control spinlock */
-       spinlock_t                                       pm_qos_lock;
+       spinlock_t                   pm_qos_lock;
        u8                           pm_qos_state;
+
+       /* Collection artificats */
+       void                         *mib_collect;
+       u16                          mib_sz;
+       /* Mutex to protect hcf file collection if a tear down is triggered */
+       struct mutex                 in_collection;
 };
 
 struct scsc_service;
index edf8d2973dc18eb4c095b30072e715f76973eedd..da03f8f6d42e06def2063bfba16bad5b1f819efe 100644 (file)
@@ -26,6 +26,9 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <scsc/scsc_mx.h>
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+#include <scsc/scsc_log_collector.h>
+#endif
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include "hip4_sampler.h"
@@ -41,9 +44,9 @@ struct hip4_record {
 
 static atomic_t in_read;
 
-static bool hip4_sampler_enable;
+static bool hip4_sampler_enable = true;
 module_param(hip4_sampler_enable, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(hip4_sampler_enable, "Enable hip4_sampler_enable. Run-time option - (default: N)");
+MODULE_PARM_DESC(hip4_sampler_enable, "Enable hip4_sampler_enable. Run-time option - (default: Y)");
 
 static bool hip4_sampler_dynamic = true;
 module_param(hip4_sampler_dynamic, bool, S_IRUGO | S_IWUSR);
@@ -489,6 +492,72 @@ void hip4_sampler_tcp_decode(struct slsi_dev *sdev, struct net_device *dev, u8 *
        }
 }
 
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+int hip4_collect_init(struct scsc_log_collector_client *collect_client)
+{
+       /* Stop Sampling */
+       atomic_set(&in_read, 1);
+       return 0;
+}
+
+int hip4_collect(struct scsc_log_collector_client *collect_client, size_t size)
+{
+       int i = SCSC_HIP4_DEBUG_INTERFACES;
+       int ret = 0;
+       unsigned long flags;
+       u32 num_samples;
+       struct hip4_sampler_dev *hip4_dev;
+       void *buf;
+
+       SLSI_INFO_NODEV("Triggered log collection in hip4_sampler\n");
+
+       if (!hip4_sampler_enable)
+               return 0;
+
+       while (i--)
+               if (hip4_sampler.devs[i].mx == collect_client->prv && hip4_sampler.devs[i].type == OFFLINE) {
+                       hip4_dev = &hip4_sampler.devs[i];
+                       num_samples = kfifo_len(&hip4_dev->fifo);
+                       if (!num_samples)
+                               continue;
+                       buf = vmalloc(num_samples * sizeof(struct hip4_record));
+                       if (!buf)
+                               continue;
+                       spin_lock_irqsave(&hip4_dev->spinlock, flags);
+                       ret = kfifo_out(&hip4_dev->fifo, buf, num_samples);
+                       spin_unlock_irqrestore(&hip4_dev->spinlock, flags);
+                       if (!ret)
+                               goto error;
+                       SLSI_DBG1_NODEV(SLSI_HIP, "num_samples %d ret %d size of hip4_record %zu\n", num_samples, ret, sizeof(struct hip4_record));
+                       ret = scsc_log_collector_write(buf, ret * sizeof(struct hip4_record), 1);
+                       if (ret)
+                               goto error;
+                       vfree(buf);
+               }
+       return 0;
+error:
+       vfree(buf);
+       return ret;
+}
+
+int hip4_collect_end(struct scsc_log_collector_client *collect_client)
+{
+       /* Restart sampling */
+       atomic_set(&in_read, 0);
+       return 0;
+}
+
+/* Collect client registration */
+struct scsc_log_collector_client hip4_collect_client = {
+       .name = "HIP4 Sampler",
+       .type = SCSC_LOG_CHUNK_HIP4_SAMPLER,
+       .collect_init = hip4_collect_init,
+       .collect = hip4_collect,
+       .collect_end = hip4_collect_end,
+       .prv = NULL,
+};
+#endif
+
 static int hip4_sampler_open(struct inode *inode, struct file *filp)
 {
        struct hip4_sampler_dev *hip4_dev;
@@ -691,6 +760,7 @@ void hip4_sampler_create(struct slsi_dev *sdev, struct scsc_mx *mx)
 
        SLSI_INFO_NODEV("hip4_sampler version: %d.%d\n", VER_MAJOR, VER_MINOR);
 
+       memset(&hip4_sampler, 0, sizeof(hip4_sampler));
        /* Check whether exists */
        if (!hip4_sampler.init) {
                ret = alloc_chrdev_region(&hip4_sampler.device, 0, SCSC_HIP4_DEBUG_INTERFACES, "hip4_sampler_char");
@@ -811,6 +881,10 @@ void hip4_sampler_create(struct slsi_dev *sdev, struct scsc_mx *mx)
                set_bit(minor, bitmap_hip4_sampler_minor);
        }
 
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+       hip4_collect_client.prv = mx;
+       scsc_log_collector_register_client(&hip4_collect_client);
+#endif
        hip4_sampler.init = true;
 
        SLSI_INFO_NODEV("%s: Ready to start sampling....\n", DRV_NAME);
@@ -851,6 +925,9 @@ void hip4_sampler_destroy(struct slsi_dev *sdev, struct scsc_mx *mx)
                        hip4_sampler.devs[i].mx = NULL;
                        clear_bit(i, bitmap_hip4_sampler_minor);
                }
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+       scsc_log_collector_unregister_client(&hip4_collect_client);
+#endif
        class_destroy(hip4_sampler.class_hip4_sampler);
        unregister_chrdev_region(hip4_sampler.device, SCSC_HIP4_DEBUG_INTERFACES);
        hip4_sampler.init = false;
index afafae56deac3a2942faf0c0e3c9d9e17da11d74..c74470c6a7768650fb2da5febdaafd06958248ce 100755 (executable)
@@ -17,9 +17,6 @@
 
 #include "mib.h"
 
-#define FAPI_MAJOR_VERSION(v) ((v >> 8) & 0xFF)
-#define FAPI_MINOR_VERSION(v) ((v) & 0xFF)
-
 int slsi_procfs_open_file_generic(struct inode *inode, struct file *file)
 {
        file->private_data = SLSI_PDE_DATA(inode);
index 571a03820cf29f2e4a216c274087a95324e0257f..8fb287cfc075e4205c0edc54434fe90625c0d6b3 100755 (executable)
@@ -207,6 +207,10 @@ static int slsi_cdev_open(struct inode *inode, struct file *file)
        file->private_data = client;
        slsi_procfs_inc_node();
 
+#ifdef CONFIG_SCSC_MXLOGGER
+       scsc_service_register_observer(NULL, "udi");
+#endif
+
        SLSI_DBG1_NODEV(SLSI_UDI, "Client:%d added\n", indx);
 
        return 0;
@@ -257,6 +261,10 @@ static int slsi_cdev_release(struct inode *inode, struct file *filp)
        kfree(client);
        slsi_procfs_dec_node();
 
+#ifdef CONFIG_SCSC_MXLOGGER
+       scsc_service_unregister_observer(NULL, "udi");
+#endif
+
        SLSI_DBG1_NODEV(SLSI_UDI, "Client:%d removed\n", indx);
 
        return 0;
@@ -280,7 +288,7 @@ static ssize_t slsi_cdev_read(struct file *filp, char *p, size_t len, loff_t *po
 
                /* wait until getting a signal */
                if (wait_event_interruptible(client->log_wq, skb_queue_len(&client->log_list))) {
-                       SLSI_ERR_NODEV("slsi_cdev_read: wait_event_interruptible failed.");
+                       SLSI_ERR_NODEV("slsi_cdev_read: wait_event_interruptible failed.\n");
                        return -ERESTARTSYS;
                }
        }