wlan: Update probe rsp template according to host and FW feature capability

Currently probe resp template length is more than 384 in P2P-GO interface
which can't accommodate in a fixed array of size BEACON_TEMPLATE_SIZE(384)

Add changes to update probe resp template to firmware according to host
and fw feature capability using variable length array.

Change-Id: I86c973f6ca21600adf50a9d26af4d682d79602b3
CRs-Fixed: 2043946
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 17be814..ecf6dc0 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -155,6 +155,9 @@
    MAKE_BEFORE_BREAK = 67,
 #endif
    NUD_DEBUG = 68,
+   /*69 reserved for FATAL_EVENT_LOGGING */
+   /*70 reserved for WIFI_DUAL_BAND_ENABLE */
+   PROBE_RSP_TEMPLATE_VER1 = 71,
    //MAX_FEATURE_SUPPORTED = 128
 } placeHolderInCapBitmap;
 
diff --git a/CORE/MAC/src/pe/sch/schApi.c b/CORE/MAC/src/pe/sch/schApi.c
index c9c8ef4..6357be7 100644
--- a/CORE/MAC/src/pe/sch/schApi.c
+++ b/CORE/MAC/src/pe/sch/schApi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -380,7 +380,10 @@
     tANI_U32             nPayload,nBytes,nStatus;
     tpSirMacMgmtHdr      pMacHdr;
     tANI_U32             addnIEPresent;
-    tANI_U32             addnIELen=0;
+    tANI_U32             addnIE1Len=0;
+    tANI_U32             addnIE2Len = 0;
+    tANI_U32             addnIE3Len = 0;
+    tANI_U32             totalAddnIeLen = 0;
     tSirRetStatus        nSirStatus;
     tANI_U8              *addIE = NULL;
 
@@ -411,45 +414,97 @@
 
     if (addnIEPresent)
     {
-        //Probe rsp IE available
-        addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
-        if ( NULL == addIE )
+        if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
+                                               &addnIE1Len) != eSIR_SUCCESS)
+        {
+            schLog(pMac, LOGE,
+                FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
+            return retCode;
+        }
+
+        if (addnIE1Len == WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN)
+        {
+            if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
+                                               &addnIE2Len) != eSIR_SUCCESS)
+            {
+                schLog(pMac, LOGE,
+                    FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 length"));
+                return retCode;
+            }
+        }
+
+        if (addnIE2Len == WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN)
+        {
+            if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
+                                               &addnIE3Len) != eSIR_SUCCESS)
+            {
+                schLog(pMac, LOGE,
+                    FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 length"));
+                return retCode;
+            }
+        }
+        schLog(pMac,LOG1, FL("addnIE1Len %d, addnIE2Len %d, addnIE3Len %d"),
+               addnIE1Len, addnIE2Len, addnIE3Len);
+        totalAddnIeLen = addnIE1Len + addnIE2Len + addnIE3Len;
+
+        addIE = vos_mem_malloc(totalAddnIeLen);
+        if (NULL == addIE)
         {
              schLog(pMac, LOGE,
                  FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
              return retCode;
         }
 
-        if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
-                                               &addnIELen) != eSIR_SUCCESS)
-        {
-            schLog(pMac, LOGE,
-                FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
-
-            vos_mem_free(addIE);
-            return retCode;
-        }
-
-        if (addnIELen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIELen &&
-                                 (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE)
+        if (addnIE1Len && addnIE1Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN &&
+                                 (nBytes + addnIE1Len) <= SIR_MAX_PACKET_SIZE)
         {
             if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac,
                                     WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &addIE[0],
-                                    &addnIELen) )
+                                    &addnIE1Len))
             {
                schLog(pMac, LOGE,
                    FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 String"));
-
                vos_mem_free(addIE);
                return retCode;
             }
         }
+
+        if (addnIE2Len && addnIE2Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN &&
+                     (nBytes + addnIE1Len + addnIE2Len) <= SIR_MAX_PACKET_SIZE)
+        {
+            if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac,
+                                     WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
+                                     &addIE[addnIE1Len],
+                                     &addnIE2Len) )
+            {
+                schLog(pMac, LOGE,
+                    FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 String"));
+                vos_mem_free(addIE);
+                return retCode;
+            }
+        }
+
+        if (addnIE3Len && addnIE3Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN &&
+                     (nBytes + totalAddnIeLen) <= SIR_MAX_PACKET_SIZE)
+        {
+            if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac,
+                                     WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
+                                     &addIE[addnIE1Len + addnIE2Len],
+                                     &addnIE3Len) )
+            {
+                schLog(pMac, LOGE,
+                    FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 String"));
+                vos_mem_free(addIE);
+                return retCode;
+            }
+        }
+
     }
 
     if (addnIEPresent)
     {
-        if ((nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE )
-            nBytes += addnIELen;
+        if ((nBytes + totalAddnIeLen) <= SIR_MAX_PACKET_SIZE )
+            nBytes += totalAddnIeLen;
         else
             addnIEPresent = false; //Dont include the IE.
     }
@@ -495,8 +550,8 @@
 
     if (addnIEPresent)
     {
-        vos_mem_copy ( &pFrame2Hal[nBytes - addnIELen],
-                             &addIE[0], addnIELen);
+        vos_mem_copy ( &pFrame2Hal[nBytes - totalAddnIeLen],
+                             &addIE[0], totalAddnIeLen);
     }
 
     /* free the allocated Memory */
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index a7ea56f..c141d63 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -8658,15 +8658,24 @@
                               pSendProbeRspParams->bssId, sizeof(tSirMacAddr));
    wdiSendProbeRspParam->wdiProbeRspTemplateInfo.uProbeRespTemplateLen =
                               pSendProbeRspParams->probeRespTemplateLen;
-   /* Copy the Probe Response template to local buffer */
-   vos_mem_copy(
-           wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate,
-           pSendProbeRspParams->pProbeRespTemplate, 
-           pSendProbeRspParams->probeRespTemplateLen);
    vos_mem_copy(
      wdiSendProbeRspParam->wdiProbeRspTemplateInfo.uaProxyProbeReqValidIEBmap,
      pSendProbeRspParams->ucProxyProbeReqValidIEBmap,
      WDI_PROBE_REQ_BITMAP_IE_LEN);
+   /* Copy the Probe Response template to local buffer */
+   wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate =
+      vos_mem_malloc(wdiSendProbeRspParam->wdiProbeRspTemplateInfo.
+      uProbeRespTemplateLen);
+   if(!wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate)
+   {
+      status = WDI_STATUS_MEM_FAILURE;
+      goto free_mem;
+   }
+
+   vos_mem_copy(
+           wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate,
+           pSendProbeRspParams->pProbeRespTemplate,
+           pSendProbeRspParams->probeRespTemplateLen);
    
    wdiSendProbeRspParam->wdiReqStatusCB = NULL ;
    
@@ -8676,7 +8685,10 @@
    {
       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
           "Failure in SEND Probe RSP Params WDI API" );
+      vos_mem_free(wdiSendProbeRspParam->wdiProbeRspTemplateInfo.
+      pProbeRespTemplate);
    }
+free_mem:
    vos_mem_free(pSendProbeRspParams);
    vos_mem_free(wdiSendProbeRspParam);
    return CONVERT_WDI2VOS_STATUS(status);
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 8c745d9..c591795 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -3570,15 +3570,15 @@
   /*BSSID for which the Probe Template is to be used*/
   wpt_macAddr     macBSSID;
 
-  /*Probe response template*/
-  wpt_uint8      *pProbeRespTemplate[WDI_PROBE_RSP_TEMPLATE_SIZE];
-
   /*Template Len*/
   wpt_uint32      uProbeRespTemplateLen;
 
   /*Bitmap for the IEs that are to be handled at SLM level*/
   wpt_uint32      uaProxyProbeReqValidIEBmap[WDI_PROBE_REQ_BITMAP_IE_LEN];
 
+  /*Probe response template*/
+  wpt_uint8      *pProbeRespTemplate;
+
 }WDI_UpdateProbeRspTemplateInfoType;
 
 /*---------------------------------------------------------------------------
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index d8c2dd4..c6d6e3c 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -226,6 +226,9 @@
    ,SAP_BUFF_ALLOC                 //66
    ,MAKE_BEFORE_BREAK              //67
    ,NUD_DEBUG                      //68
+   ,FEATURE_NOT_SUPPORTED          //69 reserved for FATAL_EVENT_LOGGING
+   ,FEATURE_NOT_SUPPORTED          //70 reserved for WIFI_DUAL_BAND_ENABLE
+   ,PROBE_RSP_TEMPLATE_VER1        //71
 };
 
 /*-------------------------------------------------------------------------- 
@@ -2026,6 +2029,11 @@
                                          "%s", "NUD_DEBUG");
                           pCapStr += strlen("NUD_DEEBUG");
                           break;
+                     case PROBE_RSP_TEMPLATE_VER1:
+                          snprintf(pCapStr, sizeof("PROBE_RSP_TEMPLATE_VER1"),
+                                         "%s", "PROBE_RSP_TEMPLATE_VER1");
+                          pCapStr += strlen("PROBE_RSP_TEMPLATE_VER1");
+                          break;
                  }
                  *pCapStr++ = ',';
                  *pCapStr++ = ' ';
@@ -14086,7 +14094,9 @@
   wpt_uint8*                             pSendBuffer         = NULL;
   wpt_uint16                             usDataOffset        = 0;
   wpt_uint16                             usSendSize          = 0;
-  tSendProbeRespReqParams                halUpdateProbeRspTmplParams;
+  wpt_uint16                             uMsgSize            = 0;
+  tSendProbeRespReqParams                *halProbeRespTmplParams = NULL;
+  tSendProbeRespReqParams_V1             *halProbeRespTmplParams_V1 = NULL;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
   /*-------------------------------------------------------------------------
@@ -14106,13 +14116,22 @@
     (WDI_UpdateProbeRspTemplateParamsType*)pEventData->pEventData;
   wdiUpdateProbeRespTmplRspCb =
     (WDI_UpdateProbeRspTemplateRspCb)pEventData->pCBfnc;
+
+  if (WDI_getFwWlanFeatCaps(PROBE_RSP_TEMPLATE_VER1))
+     uMsgSize = sizeof(tSendProbeRespReqParams_V1) +
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+        uProbeRespTemplateLen -
+        sizeof(halProbeRespTmplParams_V1->pProbeRespTemplate);
+  else
+     uMsgSize = sizeof(tSendProbeRespReqParams);
+
   /*-----------------------------------------------------------------------
     Get message buffer
   -----------------------------------------------------------------------*/
   if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_PROBE_RSP_TEMPLATE_REQ,
-                        sizeof(halUpdateProbeRspTmplParams),
+                        uMsgSize,
                         &pSendBuffer, &usDataOffset, &usSendSize))||
-      ( usSendSize < (usDataOffset + sizeof(halUpdateProbeRspTmplParams) )))
+      ( usSendSize < (usDataOffset + uMsgSize)))
   {
      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
               "Unable to get send buffer in set bss key req %p %p %p",
@@ -14121,29 +14140,62 @@
      return WDI_STATUS_E_FAILURE;
   }
 
-  wpalMemoryCopy(halUpdateProbeRspTmplParams.bssId,
-                 pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.macBSSID,
-                 WDI_MAC_ADDR_LEN);
+  if (WDI_getFwWlanFeatCaps(PROBE_RSP_TEMPLATE_VER1))
+  {
+     halProbeRespTmplParams_V1 =
+        (tSendProbeRespReqParams_V1 *)(pSendBuffer + usDataOffset);
 
-  halUpdateProbeRspTmplParams.probeRespTemplateLen =
-    pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.uProbeRespTemplateLen;
+     wpalMemoryCopy(halProbeRespTmplParams_V1->bssId,
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.macBSSID,
+        WDI_MAC_ADDR_LEN);
 
-  wpalMemoryCopy(halUpdateProbeRspTmplParams.pProbeRespTemplate,
-    pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.pProbeRespTemplate,
-                 BEACON_TEMPLATE_SIZE);
+     halProbeRespTmplParams_V1->probeRespTemplateLen =
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+        uProbeRespTemplateLen;
 
+     wpalMemoryCopy(halProbeRespTmplParams_V1->ucProxyProbeReqValidIEBmap,
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+        uaProxyProbeReqValidIEBmap,
+        WDI_PROBE_REQ_BITMAP_IE_LEN);
 
-  wpalMemoryCopy(halUpdateProbeRspTmplParams.ucProxyProbeReqValidIEBmap,
-           pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.uaProxyProbeReqValidIEBmap,
-                 WDI_PROBE_REQ_BITMAP_IE_LEN);
+     wpalMemoryCopy(halProbeRespTmplParams_V1->pProbeRespTemplate,
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+        pProbeRespTemplate,
+        halProbeRespTmplParams_V1->probeRespTemplateLen);
+  }
+  else
+  {
+     halProbeRespTmplParams =
+       (tSendProbeRespReqParams *)(pSendBuffer + usDataOffset);
 
-  wpalMemoryCopy( pSendBuffer+usDataOffset,
-                  &halUpdateProbeRspTmplParams,
-                  sizeof(halUpdateProbeRspTmplParams));
+     wpalMemoryCopy(halProbeRespTmplParams->bssId,
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.macBSSID,
+        WDI_MAC_ADDR_LEN);
+
+     if (BEACON_TEMPLATE_SIZE <
+       pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+       uProbeRespTemplateLen)
+        halProbeRespTmplParams->probeRespTemplateLen = BEACON_TEMPLATE_SIZE;
+     else
+        halProbeRespTmplParams->probeRespTemplateLen =
+            pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+            uProbeRespTemplateLen;
+
+     wpalMemoryCopy(halProbeRespTmplParams->ucProxyProbeReqValidIEBmap,
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+        uaProxyProbeReqValidIEBmap,
+        WDI_PROBE_REQ_BITMAP_IE_LEN);
+     wpalMemoryCopy(halProbeRespTmplParams->pProbeRespTemplate,
+        pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+        pProbeRespTemplate,
+        BEACON_TEMPLATE_SIZE);
+  }
 
   pWDICtx->wdiReqStatusCB     = pwdiUpdateProbeRespTmplParams->wdiReqStatusCB;
   pWDICtx->pReqStatusUserData = pwdiUpdateProbeRespTmplParams->pUserData;
 
+  vos_mem_free(pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.
+       pProbeRespTemplate);
   /*-------------------------------------------------------------------------
     Send Update Probe Resp Template Request to HAL
   -------------------------------------------------------------------------*/