wlan: Enhance LLStats to Separate data between HDD and SME

This commit enhances LLStats implementation to ensure SME does a
separate copy of HDD data.Also , this commit checks for this feature
capability before functioning and returns failure if not enabled.

Change-Id: I4ec1ca0893ef82b991e1f1078a2ac8999f21d057
CRs-Fixed:  689686
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 2d14f63..f7323f0 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -1496,7 +1496,7 @@
 {
     int status;
     struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
-    tpSirLLStatsSetReq pLinkLayerStatsSetReq;
+    tSirLLStatsSetReq linkLayerStatsSetReq;
     struct net_device *dev = wdev->netdev;
     hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
     hdd_context_t *pHddCtx = wiphy_priv(wiphy);
@@ -1515,6 +1515,14 @@
                FL("HDD adapter is Null"));
         return -ENODEV;
     }
+    /* check the LLStats Capability */
+    if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
+         (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               FL("Link Layer Statistics not supported by Firmware"));
+        return -EINVAL;
+    }
 
     if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
            (struct nlattr *)data,
@@ -1535,21 +1543,14 @@
         hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
         return -EINVAL;
     }
-    pLinkLayerStatsSetReq = vos_mem_malloc(sizeof(tSirLLStatsSetReq));
-    if (NULL == pLinkLayerStatsSetReq)
-    {
-        hddLog(VOS_TRACE_LEVEL_ERROR,
-               FL(" Unable to allocate memory to pLinkLayerStatsSetReq") );
-        return -ENOMEM;
-    }
     // Shall take the request Id if the Upper layers pass. 1 For now.
-    pLinkLayerStatsSetReq->reqId = 1;
+    linkLayerStatsSetReq.reqId = 1;
 
-    pLinkLayerStatsSetReq->mpduSizeThreshold =
+    linkLayerStatsSetReq.mpduSizeThreshold =
         nla_get_u32(
             tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
 
-    pLinkLayerStatsSetReq->aggressiveStatisticsGathering =
+    linkLayerStatsSetReq.aggressiveStatisticsGathering =
         nla_get_u32(
             tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
 
@@ -1557,20 +1558,20 @@
      * Hence the interface staId start from 1. Hence the staId matching the
      * interface in the firmware is sessionId + 1.
      */
-    pLinkLayerStatsSetReq->staId = pAdapter->sessionId + 1;
+    linkLayerStatsSetReq.staId = pAdapter->sessionId + 1;
 
 
     hddLog(VOS_TRACE_LEVEL_INFO,
            "LL_STATS_SET reqId = %d",
-           pLinkLayerStatsSetReq->reqId);
+           linkLayerStatsSetReq.reqId);
     hddLog(VOS_TRACE_LEVEL_INFO,
-            "LL_STATS_SET staId = %d", pLinkLayerStatsSetReq->staId);
+            "LL_STATS_SET staId = %d", linkLayerStatsSetReq.staId);
     hddLog(VOS_TRACE_LEVEL_INFO,
             "LL_STATS_SET mpduSizeThreshold = %d",
-            pLinkLayerStatsSetReq->mpduSizeThreshold);
+            linkLayerStatsSetReq.mpduSizeThreshold);
     hddLog(VOS_TRACE_LEVEL_INFO,
             "LL_STATS_SET aggressive Statistics Gathering  = %d",
-            pLinkLayerStatsSetReq->aggressiveStatisticsGathering);
+            linkLayerStatsSetReq.aggressiveStatisticsGathering);
 
     if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
                                pHddCtx->hHal,
@@ -1580,16 +1581,14 @@
     {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
            "sme_SetLinkLayerStatsIndCB Failed", __func__);
-        vos_mem_free(pLinkLayerStatsSetReq);
         return -EINVAL;
 
     }
     if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
-                                            pLinkLayerStatsSetReq))
+                                            &linkLayerStatsSetReq))
     {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
            "sme_LLStatsSetReq Failed", __func__);
-        vos_mem_free(pLinkLayerStatsSetReq);
         return -EINVAL;
     }
 
@@ -1622,7 +1621,7 @@
 {
     hdd_context_t *pHddCtx = wiphy_priv(wiphy);
     struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
-    tpSirLLStatsGetReq pLinkLayerStatsGetReq;
+    tSirLLStatsGetReq linkLayerStatsGetReq;
     struct net_device *dev = wdev->netdev;
     hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
     int status;
@@ -1641,6 +1640,15 @@
                "%s: HDD adapter is Null", __func__);
         return -ENODEV;
     }
+    /* check the LLStats Capability */
+    if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
+         (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               FL("Link Layer Statistics not supported by Firmware"));
+        return -EINVAL;
+    }
+
 
     if (!pAdapter->isLinkLayerStatsSet)
     {
@@ -1672,19 +1680,11 @@
        return -EINVAL;
     }
 
-    pLinkLayerStatsGetReq = vos_mem_malloc(sizeof(tSirLLStatsGetReq));
 
-    if (NULL == pLinkLayerStatsGetReq)
-    {
-        hddLog(VOS_TRACE_LEVEL_ERROR,
-               FL("Unable to allocate memory to pLinkLayerStatsGetReq"));
-        return -ENOMEM;
-    }
-
-    pLinkLayerStatsGetReq->reqId =
+    linkLayerStatsGetReq.reqId =
         nla_get_u32( tb_vendor[
             QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
-    pLinkLayerStatsGetReq->paramIdMask =
+    linkLayerStatsGetReq.paramIdMask =
         nla_get_u32( tb_vendor[
             QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
 
@@ -1692,22 +1692,21 @@
      * Hence the interface staId start from 1. Hence the staId matching the
      * interface in the firmware is sessionId + 1.
      */
-    pLinkLayerStatsGetReq->staId = pAdapter->sessionId + 1;
+    linkLayerStatsGetReq.staId = pAdapter->sessionId + 1;
 
     hddLog(VOS_TRACE_LEVEL_INFO,
-           "LL_STATS_GET reqId = %d", pLinkLayerStatsGetReq->reqId);
+           "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
     hddLog(VOS_TRACE_LEVEL_INFO,
-           "LL_STATS_GET staId = %d", pLinkLayerStatsGetReq->staId);
+           "LL_STATS_GET staId = %d", linkLayerStatsGetReq.staId);
     hddLog(VOS_TRACE_LEVEL_INFO,
            "LL_STATS_GET paramIdMask = %d",
-           pLinkLayerStatsGetReq->paramIdMask);
+           linkLayerStatsGetReq.paramIdMask);
 
     if (eHAL_STATUS_SUCCESS  != sme_LLStatsGetReq( pHddCtx->hHal,
-                                                pLinkLayerStatsGetReq))
+                                                &linkLayerStatsGetReq))
     {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
                "sme_LLStatsGetReq Failed", __func__);
-        vos_mem_free(pLinkLayerStatsGetReq);
         return -EINVAL;
     }
     return 0;
@@ -1730,7 +1729,7 @@
 {
     hdd_context_t *pHddCtx = wiphy_priv(wiphy);
     struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
-    tpSirLLStatsClearReq pLinkLayerStatsClearReq;
+    tSirLLStatsClearReq linkLayerStatsClearReq;
     struct net_device *dev = wdev->netdev;
     hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
     u32 statsClearReqMask;
@@ -1751,6 +1750,14 @@
                    "%s: HDD adapter is Null", __func__);
         return -ENODEV;
     }
+    /* check the LLStats Capability */
+    if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
+         (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               FL("Enable LLStats Capability"));
+        return -EINVAL;
+    }
 
     if (!pAdapter->isLinkLayerStatsSet)
     {
@@ -1777,44 +1784,37 @@
 
     }
 
-    pLinkLayerStatsClearReq = vos_mem_malloc(sizeof(tSirLLStatsClearReq));
-    if (NULL == pLinkLayerStatsClearReq)
-    {
-        hddLog(VOS_TRACE_LEVEL_ERROR,
-               FL("Unable to allocate memory to pLinkLayerStatsClearReq"));
-        return -ENOMEM;
-    }
 
-    statsClearReqMask = pLinkLayerStatsClearReq->statsClearReqMask =
+    statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
         nla_get_u32(
             tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
 
-    stopReq = pLinkLayerStatsClearReq->stopReq =
+    stopReq = linkLayerStatsClearReq.stopReq =
         nla_get_u8(
             tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
 
     // Shall take the request Id if the Upper layers pass. 1 For now.
-    pLinkLayerStatsClearReq->reqId = 1;
+    linkLayerStatsClearReq.reqId = 1;
 
     /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
      * Hence the interface staId start from 1. Hence the staId matching the
      * interface in the firmware is sessionId + 1.
      */
-    pLinkLayerStatsClearReq->staId = pAdapter->sessionId + 1;
+    linkLayerStatsClearReq.staId = pAdapter->sessionId + 1;
 
     hddLog(VOS_TRACE_LEVEL_INFO,
-            "LL_STATS_CLEAR reqId = %d", pLinkLayerStatsClearReq->reqId);
+            "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
     hddLog(VOS_TRACE_LEVEL_INFO,
-            "LL_STATS_CLEAR staId = %d", pLinkLayerStatsClearReq->staId);
+            "LL_STATS_CLEAR staId = %d", linkLayerStatsClearReq.staId);
     hddLog(VOS_TRACE_LEVEL_INFO,
             "LL_STATS_CLEAR statsClearReqMask = 0x%X",
-            pLinkLayerStatsClearReq->statsClearReqMask);
+            linkLayerStatsClearReq.statsClearReqMask);
     hddLog(VOS_TRACE_LEVEL_INFO,
             "LL_STATS_CLEAR stopReq  = %d",
-            pLinkLayerStatsClearReq->stopReq);
+            linkLayerStatsClearReq.stopReq);
 
     if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
-                                                     pLinkLayerStatsClearReq))
+                                                     &linkLayerStatsClearReq))
     {
         struct sk_buff *temp_skbuff;
         temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
@@ -1839,16 +1839,15 @@
              * (stopReq = 1) , ensure that no further requests of get
              * go to the firmware by having isLinkLayerStatsSet set to 0.
              * However it the stopReq as part of the clear request is 0 ,
-             * the request to get the statistics are ehonoured as in this
+             * the request to get the statistics are honoured as in this
              * case the firmware is just asked to clear the statistics.
              */
-            if (pLinkLayerStatsClearReq->stopReq == 1)
+            if (linkLayerStatsClearReq.stopReq == 1)
                 pAdapter->isLinkLayerStatsSet = 0;
             return cfg80211_vendor_cmd_reply(temp_skbuff);
         }
         return -ENOMEM;
     }
-    vos_mem_free(pLinkLayerStatsClearReq);
     return -EINVAL;
 }
 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */