wlan: Add support to start/stop specific logging features

Add support to start and stop the logging of specific
logging features such as logging of wakelocks, per packet
statistics and connectivity events.

Change-Id: I94155e04c01757620be8686eec2c689166f22f3a
CRs-Fixed: 915570
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 4cb9e0d..d9b3646 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -5738,17 +5738,127 @@
 wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
                                               struct wireless_dev *wdev,
                                          const void *data, int data_len)
+{
+    int ret = 0;
+    vos_ssr_protect(__func__);
+    ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
+                                        data_len);
+    vos_ssr_unprotect(__func__);
+    return ret;
+}
 
+static const struct
+nla_policy
+qca_wlan_vendor_wifi_logger_start_policy
+[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
+   [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
+     = {.type = NLA_U32 },
+     [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
+        = {.type = NLA_U32 },
+     [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
+          = {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
+ * or disable the collection of packet statistics from the firmware
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to enable or disable the collection of packet
+ * statistics from the firmware
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
+                       struct wireless_dev *wdev,
+                        const void *data,
+                                int data_len)
+{
+    eHalStatus status;
+    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+    struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
+    tAniWifiStartLog start_log;
+
+    status = wlan_hdd_validate_context(hdd_ctx);
+    if (0 != status) {
+        return -EINVAL;
+    }
+
+     if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
+             data, data_len,
+            qca_wlan_vendor_wifi_logger_start_policy)) {
+        hddLog(LOGE, FL("Invalid attribute"));
+        return -EINVAL;
+    }
+
+    /* Parse and fetch ring id */
+    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
+        hddLog(LOGE, FL("attr ATTR failed"));
+        return -EINVAL;
+    }
+    start_log.ringId = nla_get_u32(
+           tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
+    hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
+
+    /* Parse and fetch verbose level */
+    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
+        hddLog(LOGE, FL("attr verbose_level failed"));
+        return -EINVAL;
+    }
+    start_log.verboseLevel = nla_get_u32(
+         tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
+    hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
+
+    /* Parse and fetch flag */
+    if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
+        hddLog(LOGE, FL("attr flag failed"));
+        return -EINVAL;
+    }
+    start_log.flag = nla_get_u32(
+        tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
+    hddLog(LOG1, FL("flag=%d"), start_log.flag);
+
+    if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
+                 !hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable)
+    {
+       hddLog(LOGE, FL("per pkt stats not enabled"));
+       return -EINVAL;
+    }
+    vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
+
+    return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
+ * or disable the collection of packet statistics from the firmware
+ * @wiphy:    WIPHY structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function is used to enable or disable the collection of packet
+ * statistics from the firmware
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
+                        struct wireless_dev *wdev,
+                        const void *data,
+                        int data_len)
 {
     int ret = 0;
 
     vos_ssr_protect(__func__);
-    ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
-                                              data_len);
+
+    ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
+          wdev, data, data_len);
     vos_ssr_unprotect(__func__);
 
     return ret;
-
 }
 
 
@@ -6155,7 +6265,14 @@
             WIPHY_VENDOR_CMD_NEED_NETDEV |
             WIPHY_VENDOR_CMD_NEED_RUNNING,
         .doit = wlan_hdd_cfg80211_setband
-    }
+    },
+    {
+         .info.vendor_id = QCA_NL80211_VENDOR_ID,
+         .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
+         .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+                  WIPHY_VENDOR_CMD_NEED_NETDEV,
+         .doit = wlan_hdd_cfg80211_wifi_logger_start
+    },
 };
 
 /* vendor specific events */