feature: Implement embedded template in NV

This feature includes embedded template in NV and allows us to add
new parameters easily for customization. NV parser looks for a
magic number embedded in NV, to determine it is in new format.
Once it determines it is in new format, it parses the template and
compare the builtIn template, it copies the data only bulitIn
understands rest of the day is ignored.
If we do not see magic Number in the NV, then it parses as normal
processing as before for backward compatiblity. During cold-boot the
NV is send to the firmware without parsing, NV parse is done in
firmware during cold-boot as well as when we do WLAN/Wifi on.
Add new PTT api's to get NV.bin, set NV.bin, get dictionary for tools.

CRs-fixed: 474382
Change-Id: I5726852d30629a80ec1790eff11e73b8f7e0004f
diff --git a/CORE/HDD/inc/wlan_hdd_ftm.h b/CORE/HDD/inc/wlan_hdd_ftm.h
index b29b8cf..71a3d3c 100644
--- a/CORE/HDD/inc/wlan_hdd_ftm.h
+++ b/CORE/HDD/inc/wlan_hdd_ftm.h
@@ -107,7 +107,7 @@
 
 #define WE_FTM_MAX_STR_LEN 1024
 
-#define MAX_NV_TABLE_SIZE  30000
+#define MAX_NV_TABLE_SIZE  40000
 
 typedef enum {
     WLAN_FTM_CMD_START = 1,
diff --git a/CORE/HDD/src/wlan_hdd_ftm.c b/CORE/HDD/src/wlan_hdd_ftm.c
index 54e74d3..278696d 100644
--- a/CORE/HDD/src/wlan_hdd_ftm.c
+++ b/CORE/HDD/src/wlan_hdd_ftm.c
@@ -151,6 +151,7 @@
 /* To set 4MAC addresses from given first MAC address,
  * Last byte value within given MAC address must less than 0xFF - 3 */
 #define QWLAN_MAX_MAC_LAST_BYTE_VALUE       0xFC
+#define NV_EMBEDDED_VERSION                 0x80
 
 typedef struct {
    tANI_U32 tableSize;                      /* Whole NV Table Size */
@@ -163,15 +164,16 @@
    tANI_U32 tableSize;                      /* Whole NV Table Size */
    tANI_U32 chunkSize;                      /* Current Chunk Size < 2K */
    eNvTable nvTable;
-   tANI_U8  tableData; 
+   tANI_U8  tableData;
 } pttSetNvTable;
 
 
 extern const sHalNv nvDefaults;
 static int wlan_ftm_register_wext(hdd_adapter_t *pAdapter);
 static int wlan_ftm_stop(hdd_context_t *pHddCtx);
+VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len);
 
-/* for PRIMA: all the available frequency, channal pair i the table are defined for channel frequency @ RF center frequency 
+/* for PRIMA: all the available frequency, channal pair i the table are defined for channel frequency @ RF center frequency
    Since it is associated to agc.channel_freq register for mapping.
    For channel bonding, the channel number is +2 or -2 for CB with primary high, or with primary low respectively.
 */
@@ -397,7 +399,7 @@
       VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                 "%s: Unable to init wdaCompleteEvent",__func__);
       VOS_ASSERT(0);
-    
+
       goto err_probe_event;
    }
 
@@ -470,6 +472,15 @@
      goto err_wda_close;
    }
 
+   vStatus = vos_nv_get_dictionary_data();
+
+   if (!VOS_IS_STATUS_SUCCESS(vStatus))
+   {
+      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                "%s : failed to get dictionary data for NV", __func__);
+      goto err_wda_close;
+   }
+
    /* If we arrive here, both threads dispacthing messages correctly */
 
    /* Now proceed to open the MAC */
@@ -840,8 +851,8 @@
 
     lenRes = snprintf(buf, lenBuf, "\n chainSelect: %s\n rxmode: %s\n "
                                    "txpktgen: %s\n  txifs: %ld\n  txrate: ",
-                      chain[ftm_status.chainSelect], rx[ftm_status.rxmode], 
-                      tx[ftm_status.frameGenEnabled], 
+                      chain[ftm_status.chainSelect], rx[ftm_status.rxmode],
+                      tx[ftm_status.frameGenEnabled],
                       ftm_status.frameParams.interFrameSpace);
     if ((lenRes < 0) || (lenRes >= lenBuf))
     {
@@ -874,8 +885,8 @@
     lenBuf -= lenRes;
 
     lenRes = snprintf(buf, lenBuf, "\n  txpower: %d\n  txpktcnt: %ld\n  "
-                                   "txpktlen: %d\n", ftm_status.txpower, 
-                      ftm_status.frameParams.numTestPackets, 
+                                   "txpktlen: %d\n", ftm_status.txpower,
+                      ftm_status.frameParams.numTestPackets,
                       ftm_status.frameParams.payloadLength);
 
     if ((lenRes < 0) || (lenRes >= lenBuf))
@@ -928,7 +939,7 @@
 {
    VOS_STATUS vStatus          = VOS_STATUS_SUCCESS;
    pVosContextType pVosContext = (pVosContextType)vosContext;
-   
+
    VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
              "vos prestart");
 
@@ -948,8 +959,8 @@
    ccmStart(pVosContext->pMACContext);
 
    /* Reset wda wait event */
-   vos_event_reset(&pVosContext->wdaCompleteEvent);   
-    
+   vos_event_reset(&pVosContext->wdaCompleteEvent);
+
 
    /*call WDA pre start*/
    vStatus = WDA_preStart(pVosContext);
@@ -1001,7 +1012,7 @@
     VOS_STATUS vStatus       = VOS_STATUS_SUCCESS;
     pVosContextType pVosContext= NULL;
     hdd_adapter_t *pAdapter;
-    
+
     VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                "%s: Opening VOSS", __func__);
 
@@ -1092,7 +1103,7 @@
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  "%s: NV Table Buffer Alloc Fail", __func__);
       VOS_ASSERT(0);
-      goto err_nl_srv_init; 
+      goto err_nl_srv_init;
    }
    vos_mem_zero((v_VOID_t *)pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
 
@@ -1172,7 +1183,7 @@
 
     hdd_close_all_adapters( pHddCtx );
 #if 0
-    if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) 
+    if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags))
     {
         unregister_netdev(pAdapter->dev);
         clear_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
@@ -1270,9 +1281,9 @@
         goto err_status_failure;
     }
 
-   
+
     if (pVosContext->pMACContext == NULL)
-    {    
+    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                "%s: MAC NULL context",__func__);
         goto err_status_failure;
@@ -1314,7 +1325,7 @@
                     "%s: WDA_NVDownload_Start reporting  other error \n",__func__);
        }
        VOS_ASSERT(0);
-       goto err_wda_stop;   
+       goto err_wda_stop;
     }
 
     vStatus = WDA_start(pVosContext);
@@ -1324,7 +1335,7 @@
                  "%s: Failed to start WDA",__func__);
        goto err_status_failure;
     }
-    
+
 
     /* Start the MAC */
     vos_mem_zero((v_PVOID_t)&halStartParams, sizeof(tHalMacStartParameters));
@@ -1352,7 +1363,7 @@
 
     return VOS_STATUS_SUCCESS;
 
-err_wda_stop:   
+err_wda_stop:
    vos_event_reset(&(pVosContext->wdaCompleteEvent));
    WDA_stop(pVosContext, HAL_STOP_TYPE_RF_KILL);
    vStatus = vos_wait_single_event(&(pVosContext->wdaCompleteEvent), 1000);
@@ -1557,12 +1568,12 @@
       pHddCtx->ftm.targetNVTableSize    = 0;
       pHddCtx->ftm.processedNVTableSize = 0;
       vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
- 
+
       return -EINVAL;
    }
 
    /* Copy next chunk of NV table value into response buffer */
-   vos_mem_copy(&nvTable->tableData, 
+   vos_mem_copy(&nvTable->tableData,
                 pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize,
                 nvTable->chunkSize);
    /* Update processed pointer to prepare next chunk copy */
@@ -1712,7 +1723,7 @@
       return -EINVAL;
    }
    vos_mem_copy(pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize,
-                &nvTable->tableData, 
+                &nvTable->tableData,
                 nvTable->chunkSize);
 
    pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize;
@@ -2016,9 +2027,22 @@
          break;
 
       case NV_COMMON_NV_VERSION:
-         memcpy((void *)&nvField->fieldData,
-                &nvFieldDataBuffer.nvVersion,
-                sizeof(nvFieldDataBuffer.nvVersion));
+         {
+            VOS_STATUS nvEmbededStatus = VOS_STATUS_SUCCESS;
+            v_U8_t nvVersion = nvFieldDataBuffer.nvVersion;
+
+            nvEmbededStatus = vos_nv_isEmbeddedNV();
+
+            if ( nvEmbededStatus == VOS_STATUS_SUCCESS )
+            {
+                // High bit is set to indicate embedded NV..
+                nvVersion = nvVersion | NV_EMBEDDED_VERSION;
+            }
+
+            memcpy((void *)&nvField->fieldData,
+                   &nvVersion,
+                   sizeof(nvFieldDataBuffer.nvVersion));
+         }
          break;
 
       default:
@@ -2056,7 +2080,7 @@
    v_U8_t            *pNVMac;
    v_U8_t             lastByteMAC;
 
-   
+
    nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize);
    if((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents))
    {
@@ -2243,7 +2267,7 @@
          tablePtr     = (void *)&nvContents->tables.fwConfig;
          tableSize    = sizeof(nvContents->tables.fwConfig);
          tableVNVType = VNV_FW_CONFIG;
-         break;         
+         break;
 
       case NV_TABLE_ANTENNA_PATH_LOSS:
          tablePtr     = (void *)&nvContents->tables.antennaPathLoss[0];
@@ -2262,7 +2286,7 @@
                     "Not Supported Table Type %d", nvTable->nvTable);
          return -EIO;
          break;
-         
+
    }
 
    nvStatus = vos_nv_write(tableVNVType,
@@ -2276,6 +2300,241 @@
    return 1;
 }
 
+/* --------------------------------------------------------------------------
+  \brief wlan_hdd_ftm_get_nv_bin() -
+            Get NV bin read from Flash Memory, file
+
+  \param  - ftmCmd - Pointer FTM Commad Buffer
+
+  \return - int
+            -1, Process Host command fail, vail out
+             0, Process Host command success
+--------------------------------------------------------------------------*/
+
+static int wlan_hdd_ftm_get_nv_bin
+(
+   v_U16_t msgId,
+   hdd_context_t  *pHddCtx,
+   tPttMsgbuffer  *ftmCmd
+)
+{
+   VOS_STATUS          nvStatus = VOS_STATUS_SUCCESS;
+   pttGetNvTable      *nvTable = (pttGetNvTable *)&ftmCmd->msgBody.GetNvBin;
+   v_SIZE_t            nvSize;
+   v_U8_t             *nvContents;
+   v_U16_t offset = 0;
+
+
+   if ((NV_MAX_TABLE == pHddCtx->ftm.processingNVTable) ||
+      (0 == pHddCtx->ftm.processedNVTableSize))
+   {
+      if ( msgId == PTT_MSG_GET_NV_BIN )
+      {
+         nvStatus = vos_nv_getNVEncodedBuffer((void **)&nvContents, &nvSize);
+      }
+      else
+      {
+         nvStatus = vos_nv_getNVDictionary((void **)&nvContents, &nvSize);
+      }
+
+      if ((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents))
+      {
+         VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+                    "Fail to get cached NV value Status %d", nvStatus);
+         return -EIO;
+      }
+
+      switch (nvTable->nvTable)
+      {
+         case NV_BINARY_IMAGE:
+            pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)nvContents;
+            break;
+         default:
+            VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                       "Not Valid NV Table %d", nvTable->nvTable);
+            return -EIO;
+            break;
+      }
+
+      /* Set Current Processing NV table type */
+      pHddCtx->ftm.processingNVTable = nvTable->nvTable;
+      if ( msgId == PTT_MSG_GET_NV_BIN )
+      {
+         pHddCtx->ftm.targetNVTableSize = nvSize + sizeof(v_U32_t);
+         /* Validity Period */
+         pHddCtx->ftm.tempNVTableBuffer[0] = 0xFF;
+         pHddCtx->ftm.tempNVTableBuffer[1] = 0xFF;
+         pHddCtx->ftm.tempNVTableBuffer[2] = 0xFF;
+         pHddCtx->ftm.tempNVTableBuffer[3] = 0xFF;
+         offset = sizeof(v_U32_t);
+      }
+      else
+      {
+         pHddCtx->ftm.targetNVTableSize = nvSize;
+         offset = 0;
+      }
+
+      /* Copy target NV table value into temp context buffer */
+      vos_mem_copy(&pHddCtx->ftm.tempNVTableBuffer[offset],
+                   pHddCtx->ftm.targetNVTablePointer,
+                   pHddCtx->ftm.targetNVTableSize);
+   }
+
+
+   if (pHddCtx->ftm.processingNVTable != nvTable->nvTable)
+   {
+      /* Invalid table type */
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+                 "Invalid NV Table, now Processing %d, not %d",
+                  pHddCtx->ftm.processingNVTable, nvTable->nvTable);
+
+      pHddCtx->ftm.processingNVTable    = NV_MAX_TABLE;
+      pHddCtx->ftm.targetNVTableSize    = 0;
+      pHddCtx->ftm.processedNVTableSize = 0;
+      vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
+
+      return -EINVAL;
+   }
+
+   nvTable->tableSize = pHddCtx->ftm.targetNVTableSize;
+
+   /* Update processed pointer to prepare next chunk copy */
+   if ( (nvTable->chunkSize + pHddCtx->ftm.processedNVTableSize) >
+          pHddCtx->ftm.targetNVTableSize )
+   {
+      nvTable->chunkSize =
+          (pHddCtx->ftm.targetNVTableSize - pHddCtx->ftm.processedNVTableSize);
+   }
+
+   /* Copy next chunk of NV table value into response buffer */
+   vos_mem_copy(
+        &nvTable->tableData,
+        pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize,
+        nvTable->chunkSize);
+
+   pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize;
+
+   if (pHddCtx->ftm.targetNVTableSize == pHddCtx->ftm.processedNVTableSize)
+   {
+      /* Finished to process last chunk of data, initialize buffer */
+      pHddCtx->ftm.processingNVTable    = NV_MAX_TABLE;
+      pHddCtx->ftm.targetNVTableSize    = 0;
+      pHddCtx->ftm.processedNVTableSize = 0;
+      vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
+   }
+
+   return 1;
+}
+
+/**---------------------------------------------------------------------------
+
+  \brief wlan_hdd_ftm_set_nv_bin() -
+            Set NV bin to Flash Memory, file
+
+  \param  - ftmCmd - Pointer FTM Commad Buffer
+
+  \return - int
+            -1, Process Host command fail, vail out
+             0, Process Host command success
+
++----------------------------------------------------------------------------*/
+
+static int wlan_hdd_ftm_set_nv_bin
+(
+   hdd_context_t  *pHddCtx,
+   tPttMsgbuffer  *ftmCmd
+)
+{
+   VOS_STATUS          nvStatus = VOS_STATUS_SUCCESS;
+   pttSetNvTable      *nvTable = (pttSetNvTable *)&ftmCmd->msgBody.SetNvBin;
+
+   /* Test first chunk of NV table */
+   if ((NV_MAX_TABLE == pHddCtx->ftm.processingNVTable) ||
+       (0 == pHddCtx->ftm.processedNVTableSize))
+   {
+      switch (nvTable->nvTable)
+      {
+         case NV_BINARY_IMAGE:
+            pHddCtx->ftm.targetNVTableSize = nvTable->tableSize;
+            break;
+         default:
+            VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                       "Not Valid NV Table %d", nvTable->nvTable);
+            return -EIO;
+            break;
+      }
+
+      /* Set Current Processing NV table type */
+      pHddCtx->ftm.processingNVTable = nvTable->nvTable;
+      pHddCtx->ftm.processedNVTableSize = 0;
+
+      if (pHddCtx->ftm.targetNVTableSize != nvTable->tableSize)
+      {
+         VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+                    "Invalid Table Size %d", nvTable->tableSize);
+         pHddCtx->ftm.processingNVTable    = NV_MAX_TABLE;
+         pHddCtx->ftm.targetNVTableSize    = 0;
+         pHddCtx->ftm.processedNVTableSize = 0;
+         vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
+         return -EINVAL;
+      }
+   }
+
+   if (pHddCtx->ftm.processingNVTable != nvTable->nvTable)
+   {
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                 "Invalid NV Table, now Processing %d, not %d",
+                  pHddCtx->ftm.processingNVTable, nvTable->nvTable);
+      pHddCtx->ftm.processingNVTable    = NV_MAX_TABLE;
+      pHddCtx->ftm.targetNVTableSize    = 0;
+      pHddCtx->ftm.processedNVTableSize = 0;
+      vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
+      return -EINVAL;
+   }
+
+   vos_mem_copy(
+       pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize,
+       &nvTable->tableData,
+       nvTable->chunkSize);
+
+   pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize;
+
+   if (pHddCtx->ftm.targetNVTableSize == pHddCtx->ftm.processedNVTableSize)
+   {
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+         "Processing Done!! write encoded Buffer %d",
+          pHddCtx->ftm.targetNVTableSize);
+
+      nvStatus = wlan_write_to_efs ((v_U8_t*)pHddCtx->ftm.tempNVTableBuffer,
+                   (v_U16_t)pHddCtx->ftm.targetNVTableSize);
+
+      if ((VOS_STATUS_SUCCESS != nvStatus))
+      {
+         VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+                    "Fail to set NV Binary %d", nvStatus);
+         return -EIO;
+      }
+
+      nvStatus = vos_nv_setNVEncodedBuffer(
+            (v_U8_t*)pHddCtx->ftm.tempNVTableBuffer,
+            (v_SIZE_t)pHddCtx->ftm.targetNVTableSize);
+
+      if ((VOS_STATUS_SUCCESS != nvStatus))
+      {
+         VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+                    "Fail to set NV Binary %d", nvStatus);
+         return -EIO;
+      }
+
+      pHddCtx->ftm.processingNVTable    = NV_MAX_TABLE;
+      pHddCtx->ftm.targetNVTableSize    = 0;
+      pHddCtx->ftm.processedNVTableSize = 0;
+      vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE);
+   }
+
+   return 1;
+}
+
 /**---------------------------------------------------------------------------
 
   \brief wlan_hdd_ftm_temp_get_rel_num() -
@@ -2368,6 +2627,17 @@
          needToRouteHal = 0;
          break;
 
+      case PTT_MSG_GET_NV_BIN:
+      case PTT_MSG_GET_DICTIONARY:
+         hostState = wlan_hdd_ftm_get_nv_bin(pFTMCmd->msgId, pHddCtx, pFTMCmd);
+         needToRouteHal = 0;
+         break;
+
+      case PTT_MSG_SET_NV_BIN:
+         hostState = wlan_hdd_ftm_set_nv_bin(pHddCtx, pFTMCmd);
+         needToRouteHal = 0;
+         break;
+
       case PTT_MSG_DBG_READ_REGISTER:
          wpalReadRegister(pFTMCmd->msgBody.DbgReadRegister.regAddr,
                           &pFTMCmd->msgBody.DbgReadRegister.regValue);
@@ -2625,7 +2895,7 @@
     VOS_STATUS status;
     hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx;
 
-    if (start) 
+    if (start)
     {
         pHddCtx->ftm.cmd_iwpriv = TRUE;
         status = wlan_hdd_ftm_start(pHddCtx);
@@ -3219,7 +3489,7 @@
         goto done;
     }
 
-    *pChannel = freq_chan_tbl[indx].chan; 
+    *pChannel = freq_chan_tbl[indx].chan;
 
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Channel = %d  freq = %d\n",*pChannel, freq);
  done:
@@ -3382,7 +3652,7 @@
     lenBuf -= lenRes;
 
     /*Read the RevID*/
-    lenRes = snprintf(buf, lenBuf, "%x.%x-",(v_U8_t)(reg_val >> 8), (v_U8_t)(reg_val &0x000000FF)); 
+    lenRes = snprintf(buf, lenBuf, "%x.%x-",(v_U8_t)(reg_val >> 8), (v_U8_t)(reg_val &0x000000FF));
     if(lenRes < 0 || lenRes >= lenBuf)
     {
         status = VOS_STATUS_E_FAILURE;
@@ -3572,7 +3842,7 @@
     VOS_STATUS status;
     hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx;
    int ret;
-   
+
     if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED)
     {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__);
@@ -3607,15 +3877,15 @@
         goto done;
     }
 
-   ret = snprintf(buf, WE_FTM_MAX_STR_LEN, " R0:%d, R1:%d", 
-                      pMsgBody->GetRxRssi.rssi.rx[0], 
+   ret = snprintf(buf, WE_FTM_MAX_STR_LEN, " R0:%d, R1:%d",
+                      pMsgBody->GetRxRssi.rssi.rx[0],
                   pMsgBody->GetRxRssi.rssi.rx[1]);
 
    if( ret < 0 || ret >= WE_FTM_MAX_STR_LEN )
    {
       status = VOS_STATUS_E_FAILURE;
    }
-   
+
 done:
     vos_mem_free((v_VOID_t * )pMsgBuf);
 
@@ -3641,7 +3911,7 @@
     v_BOOL_t itemIsValid = VOS_FALSE;
     v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = {0, 0x0a, 0xf5, 4,5, 6};
     int ret;
-   
+
     hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx;
 
     if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED)
@@ -3652,12 +3922,12 @@
     /*Check the NV FIELD is valid or not*/
     if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) == VOS_STATUS_SUCCESS)
     {
-       if (itemIsValid == VOS_TRUE) 
+       if (itemIsValid == VOS_TRUE)
        {
             vos_nv_readMacAddress(macAddr);
 
-         ret = snprintf(buf, WE_FTM_MAX_STR_LEN, 
-                             "%02x:%02x:%02x:%02x:%02x:%02x", 
+         ret = snprintf(buf, WE_FTM_MAX_STR_LEN,
+                             "%02x:%02x:%02x:%02x:%02x:%02x",
                         MAC_ADDR_ARRAY(macAddr));
          if( ret < 0 || ret >= WE_FTM_MAX_STR_LEN )
          {
@@ -3665,11 +3935,11 @@
          }
        }
    }
-   else 
+   else
    {
          /*Return Hard coded mac address*/
-      ret = snprintf(buf, WE_FTM_MAX_STR_LEN, 
-                            "%02x:%02x:%02x:%02x:%02x:%02x", 
+      ret = snprintf(buf, WE_FTM_MAX_STR_LEN,
+                            "%02x:%02x:%02x:%02x:%02x:%02x",
                      MAC_ADDR_ARRAY(macAddr));
 
       if( ret < 0 || ret >= WE_FTM_MAX_STR_LEN )
@@ -4366,7 +4636,7 @@
 
     // Zero the memory.  This zeros the profile structure.
     //memset(pwextBuf, 0,sizeof(hdd_wext_state_t));
-   
+
     pAdapter->dev->wireless_handlers = (struct iw_handler_def *)&we_ftm_handler_def;
 
     return 0;
@@ -4409,7 +4679,7 @@
     pHddCtx->ftm.wnl->wmsg.length = FTM_SWAP16(pHddCtx->ftm.wnl->wmsg.length);
 
     /*Response expects the length to be in */
-    pHddCtx->ftm.pResponseBuf->ftm_hdr.data_len = pHddCtx->ftm.pRequestBuf->ftm_hdr.data_len - 
+    pHddCtx->ftm.pResponseBuf->ftm_hdr.data_len = pHddCtx->ftm.pRequestBuf->ftm_hdr.data_len -
                                            sizeof(pHddCtx->ftm.pRequestBuf->ftm_hdr.data_len);
 
     /*Copy the message*/
diff --git a/CORE/VOSS/inc/vos_getBin.h b/CORE/VOSS/inc/vos_getBin.h
index 39f89c8..cf3d65d 100644
--- a/CORE/VOSS/inc/vos_getBin.h
+++ b/CORE/VOSS/inc/vos_getBin.h
@@ -52,19 +52,6 @@
 
    These APIs allow components to retrieve binary contents (firmware, 
    configuration data, etc.) from a storage medium on the platform.
-<<<<<<< HEAD:CORE/VOSS/inc/vos_getBin.h
-  
-   Copyright 2008 (c) Qualcomm, Incorporated.  All Rights Reserved.
-   
-   Qualcomm Confidential and Proprietary.
-  
-=======
-
-   Copyright 2008 (c) Qualcomm Technologies, Inc.  All Rights Reserved.
-
-   Qualcomm Technologies Confidential and Proprietary.
-
->>>>>>> 1cc7c78... wlan: voss: remove obsolete "WLAN_SOFTAP_FEATURE" featurization:prima/CORE/VOSS/inc/vos_getBin.h
   ========================================================================*/
 
 /* $Header$ */
@@ -95,7 +82,10 @@
   VOS_BINARY_ID_COUNTRY_INFO,
 
   /// Binary ID for Handoff Configuration data
-  VOS_BINARY_ID_HO_CONFIG
+  VOS_BINARY_ID_HO_CONFIG,
+
+  /// Binary ID for Dictionary Configuration data
+  VOS_BINARY_ID_DICT_CONFIG
 
   
 } VOS_BINARY_ID;
diff --git a/CORE/VOSS/inc/vos_nvitem.h b/CORE/VOSS/inc/vos_nvitem.h
index b51a1a2..b0b514c 100644
--- a/CORE/VOSS/inc/vos_nvitem.h
+++ b/CORE/VOSS/inc/vos_nvitem.h
@@ -634,7 +634,53 @@
   \return status of the NV read operation
   \sa
   -------------------------------------------------------------------------*/
-VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer ,v_SIZE_t *pSize);
+VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer, v_SIZE_t *pSize);
+
+/**------------------------------------------------------------------------
+  \brief vos_nv_getNVEncodedBuffer -
+  \param pBuffer  - to return the buffer address
+         pSize    - buffer size.
+  \return status of the NV read operation
+  \sa
+  -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer, v_SIZE_t *pSize);
+
+
+/**------------------------------------------------------------------------
+  \brief vos_nv_getNVDictionary -
+  \param pBuffer  - to return the buffer address
+         pSize    - buffer size.
+  \return status of the NV read operation
+  \sa
+  -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer, v_SIZE_t *pSize);
+
+/**------------------------------------------------------------------------
+  \brief vos_nv_isEmbeddedNV() - NV.bin is embedded or not
+
+  \return VOS_STATUS_SUCCESS - if NV is embedded
+          otherwise  - NOT embedded
+  \sa
+  -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_isEmbeddedNV(void);
+
+/**------------------------------------------------------------------------
+  \brief vos_nv_setNVEncodedBuffer() - set Encode Buffer
+
+  \return VOS_STATUS_SUCCESS - if able to set encoded buffer successfully
+          otherwise  - NOT able to set encoded data
+  \sa
+  -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size);
+
+/**------------------------------------------------------------------------
+  \brief vos_nv_get_dictionary_data() - read dictionary data
+
+  \return VOS_STATUS_SUCCESS - if dictionary data is read successfully
+          otherwise  - NOT able to read dictionary data
+  \sa
+  -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_get_dictionary_data(void);
 
 /**------------------------------------------------------------------------
   \brief vos_nv_setRegDomain -
diff --git a/CORE/VOSS/inc/wlan_hdd_misc.h b/CORE/VOSS/inc/wlan_hdd_misc.h
index 570a96f..2e6ebe0 100644
--- a/CORE/VOSS/inc/wlan_hdd_misc.h
+++ b/CORE/VOSS/inc/wlan_hdd_misc.h
@@ -48,6 +48,7 @@
 #define WLAN_CFG_FILE              "wlan/prima/WCNSS_cfg.dat"
 #define WLAN_FW_FILE               ""
 #define WLAN_NV_FILE               "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+#define WLAN_DICT_FILE             "wlan/prima/WCNSS_qcom_wlan_dictionary.dat"
 #define WLAN_COUNTRY_INFO_FILE     "wlan/prima/WCNSS_wlan_country_info.dat"
 #define WLAN_HO_CFG_FILE           "wlan/prima/WCNSS_wlan_ho_config"
 #else
@@ -55,6 +56,7 @@
 #define WLAN_CFG_FILE              "wlan/volans/WCN1314_cfg.dat"
 #define WLAN_FW_FILE               "wlan/volans/WCN1314_qcom_fw.bin"
 #define WLAN_NV_FILE               "wlan/volans/WCN1314_qcom_wlan_nv.bin"
+#define WLAN_DICT_FILE             ""
 #define WLAN_COUNTRY_INFO_FILE     "wlan/volans/WCN1314_wlan_country_info.dat"
 #define WLAN_HO_CFG_FILE           "wlan/volans/WCN1314_wlan_ho_config"
 #endif // ANI_CHIPSET
@@ -63,6 +65,7 @@
 #define WLAN_CFG_FILE              "wlan/cfg.dat"
 #define WLAN_FW_FILE               "wlan/qcom_fw.bin"
 #define WLAN_NV_FILE               "wlan/qcom_wlan_nv.bin"
+#define WLAN_DICT_FILE             ""
 #define WLAN_COUNTRY_INFO_FILE     "wlan/wlan_country_info.dat"
 #define WLAN_HO_CFG_FILE           "wlan/wlan_ho_config"
 #endif // MSM_PLATFORM
diff --git a/CORE/VOSS/inc/wlan_nv_parser.h b/CORE/VOSS/inc/wlan_nv_parser.h
new file mode 100755
index 0000000..de41517
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_parser.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined __WLAN_NV_PARSER_H
+#define __WLAN_NV_PARSER_H
+
+#include <vos_status.h>
+
+VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize, sHalNv *);
+
+#endif
diff --git a/CORE/VOSS/inc/wlan_nv_parser_internal.h b/CORE/VOSS/inc/wlan_nv_parser_internal.h
new file mode 100755
index 0000000..c6791ab
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_parser_internal.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined _WLAN_NV_PARSER_INTERNAL_H
+#define  _WLAN_NV_PARSER_INTERNAL_H
+
+#include "wlan_nv_types.h"
+
+/*
+ * local prototypes
+ */
+static _NV_TEMPLATE_PROCESS_RC processNvTemplate(_NV_STREAM_BUF *pStream,
+   int len);
+static _NV_TEMPLATE_PROCESS_RC processNvTemplateTable(_NV_STREAM_BUF *pStream,
+   int len);
+static int constructATemplateTable(_NV_STREAM_BUF *pStream, int len,
+   char *tableStrName);
+static _NV_TEMPLATE_PROCESS_RC compareWithBuiltinTable(int idxFromBin,
+   char *tableNameFromBin);
+static _NV_TEMPLATE_PROCESS_RC compare2Tables(int idxFromBin, int idxBuiltin);
+static _NV_TEMPLATE_PROCESS_RC compare2FieldsAndCopyFromBin(
+   _NV_TEMPLATE_TABLE *pTableBuiltin, _NV_TEMPLATE_TABLE *pTableFromBin,
+   int idxBuiltin, int idxFromBin);
+static _NV_TEMPLATE_PROCESS_RC compare2FieldIDType(
+   _NV_TEMPLATE_TABLE *pTableBuiltIn, _NV_TEMPLATE_TABLE *pTableFromBin,
+   int idxBuiltin, int idxFromBin);
+static _NV_TEMPLATE_PROCESS_RC compare2FieldStorageTypeAndSizes(
+   _NV_TEMPLATE_TABLE *pTableBuiltIn, _NV_TEMPLATE_TABLE *pTableFromBin,
+   int idxBuiltin, int idxFromBin);
+static _NV_TEMPLATE_PROCESS_RC compare2StorageSize(int idxBuiltIn,
+   int idxFromBin, int sizeBuiltIn, int sizeFromBin,
+   tANI_U8 sizeBuiltInLowByte, tANI_U8 sizeFromBinLowByte);
+static _NV_TEMPLATE_PROCESS_RC processNvTemplateEnum(_NV_STREAM_BUF *pStream,
+   int len);
+static void compareEnumWithBuiltin(char *enumStr, int enumIdxFromBin);
+static _NV_TEMPLATE_PROCESS_RC compare2EnumEntriesAndCopy(int idxFromBin,
+   int idxBuiltin);
+static int constructATemplateEnum(_NV_STREAM_BUF *pStream, int len,
+   char *enumStr);
+static void processNvData(_NV_STREAM_BUF *pStream, int len);
+static int numElemSingular(_NV_TEMPLATE_TABLE *pTableEntry,int);
+static int numElemArray1(_NV_TEMPLATE_TABLE *pTableEntry,int);
+static int numElemArray2(_NV_TEMPLATE_TABLE *pTableEntry,int);
+static int numElemArray3(_NV_TEMPLATE_TABLE *pTableEntry,int);
+static void parseSubDataTable4Size(int tableIdx, int numElem);
+static void getBasicDataSize(_NV_TEMPLATE_TABLE *pTableEntry);
+static int getNumElemOutOfStorageSize(int fieldStorageSize,
+   tANI_U8 fieldStorageSizeLowByte,int);
+
+static int getFieldCount(int tableIdx, int fieldIdi, int numElem,
+   int nvBin);
+static void parseDataTable_new(_NV_STREAM_BUF *pStream, int* pos,
+   int tableIdx, int addOffset, int tableBaseOffset);
+static int getBuiltInFieldCount (int tblIdBin, char *tableNameFromBin,
+   int *tblIdBuiltIn, int *fieldIdBuitIn, int *numElem);
+static void parseSubDataTableAndCopy(int tableIdx, int numElem, int numElem2,
+   int numElem3, int fieldId, _NV_STREAM_BUF *pStream, int* pos,
+   int addOffset, int tableBaseOffset, int localAddOffset);
+
+/*
+ * typedef's
+ */
+
+typedef int (*pF_NumElemBasedOnStorageType)(_NV_TEMPLATE_TABLE *pTableEntry,
+    int nvBin);
+
+#endif
+
+
diff --git a/CORE/VOSS/inc/wlan_nv_stream.h b/CORE/VOSS/inc/wlan_nv_stream.h
new file mode 100755
index 0000000..8cbd043
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_stream.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined _WLAN_NV_STREAM_H
+#define _WLAN_NV_STREAM_H
+
+#include "wlan_nv_types.h"
+
+typedef tANI_U8 _NV_STREAM_BUF;
+
+typedef struct {
+   _NV_STREAM_BUF *dataBuf;
+   tANI_U32 currentIndex;
+   tANI_U32 totalLength;
+}_STREAM_BUF;
+
+extern _STREAM_BUF streamBuf;
+
+typedef enum {
+   RC_FAIL,
+   RC_SUCCESS,
+} _STREAM_RC;
+
+typedef enum {
+   STREAM_READ,
+   STREAM_WRITE,
+} _STREAM_OPERATION;
+
+_STREAM_RC nextStream (tANI_U32 *length, tANI_U8 *dataBuf);
+_STREAM_RC initReadStream ( tANI_U8 *readBuf, tANI_U32 length);
+
+#endif
diff --git a/CORE/VOSS/inc/wlan_nv_template_api.h b/CORE/VOSS/inc/wlan_nv_template_api.h
new file mode 100755
index 0000000..9c3750c
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_template_api.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined _WLAN_NV_TEMPLATE_API_H
+#define  _WLAN_NV_TEMPLATE_API_H
+
+#include "wlan_nv_types.h"
+
+/*
+* API Prototypes
+* These are meant to be exposed to outside applications
+*/
+//extern void writeNvData(void);
+//extern VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize, sHalNv *);
+
+/*
+* Parsing control bitmap
+*/
+#define _ABORT_WHEN_MISMATCH_MASK  0x00000001     /*set: abort when mismatch, clear: continue taking matched entries*/
+#define _IGNORE_THE_APPENDED_MASK  0x00000002     /*set: ignore, clear: take*/
+
+#define _FLAG_AND_ABORT(b)    (((b) & _ABORT_WHEN_MISMATCH_MASK) ? 1 : 0)
+
+#endif /*#if !defined(_WLAN_NV_TEMPLATE_API_H) */
diff --git a/CORE/VOSS/inc/wlan_nv_template_builtin.h b/CORE/VOSS/inc/wlan_nv_template_builtin.h
new file mode 100755
index 0000000..bc2b23e
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_template_builtin.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined _WLAN_NV_TEMPLATE_BUILTIN_H
+#define _WLAN_NV_TEMPLATE_BUILTIN_H
+
+
+/*===========================================================================
+                       EDIT HISTORY FOR FILE
+
+  This section contains comments describing changes made to the module.
+  Notice that changes are listed in reverse chronological order.
+
+  $Header:$ $DateTime: $ $Author: $
+
+  when        who        what, where, why
+  --------    ---        -----------------------------------------------
+  04/10/13    kumarpra   nv built in  creation
+===========================================================================*/
+
+
+/*
+  -----------------------------------------
+  This file is generated by nvTmplRun Parser
+  -----------------------------------------
+  To be auto-generated, or
+  This is the source file and the header file can be generated from this
+  template file.
+
+  Template constructs
+     1. TABLE_: struct
+     2. INDEX_ENUM: enums, e.g. {RATE_OFDM_6M,RATE_OFDM_54M}
+     3. INDEX_INT: int, e.g.{min, max, increment}
+     3. Basic data types: tANI_U8, tANI_S8, tANI_U32, tANI_S32
+     4. Storage types:
+        4.1 SINGULAR: one element of basic data type
+        4.2 ARRAY_1: one dimensional array, x-axis
+        4.3 ARRAY_2: two dimensional array, (x, y)
+        4.4 ARRAY_3: three dimensional array, (x, y, z)
+        4.5 ARRAY_4: four dimensional array, (x, y, z, t)
+
+  Implementation notes
+     1. Flow of changing NV data format: (TBD) Either change the template and
+        generate the header file, or modify header file and auto-generate
+        the template.
+     2. Flow of writing NV data: encode the template in the data stream, so the
+        NV data is "self-sufficient". No separate template, no compability
+        issue, no need of version control.
+     3. Flow of reading NV data: parse the binary NV data stream based on the
+        template info in the data stream.
+     4. The above NV logic is decoupled from the actual data content, a generic,
+        content ergonostic parser (reading) and encoder (writing).
+        The NV logic is common code shared by tools, s/w
+        (both host and firmware), and off-line utilities.
+     5. NV data parsing and "acceptanace" into an s/w moduel data structure can
+        be "configured" in several ways:
+        5.1 only total matching of all fields, otherwise, reject the whole data
+        stream (a table).
+        5.2 partial matching of fields allowed and the rest fields assume
+        reasonal default values,
+        The choice can be determined later, but the capability is provided.
+     6. We could also design in this selection on an individua table base.
+        To design such capability, reserve some header bits in the data stream.
+     7. The NV data streams can be modified, replaced, or intact with a new data
+        stream of the same table ID added to NV data.
+        The choice can be determined later, but the NV scheme provides such
+        capability.
+     8. The template construct definitions can be common to all tables
+        (tbd: in a common section) or table specific, or updated in a
+        subsequent format section.
+        The use cases are:
+        - An index enum (e.g. RF channels) is common to all tables when the NV
+          data is created. Later new enums are added (e.g.
+        additional channels), one can choose to add the new index enum for new
+        tables appended to the NV data, or replace the
+        old table with new template info and data.
+        The template precedence is table specific then common, and later
+        "common" overwrites "earlier" commmon.
+        - A new field is added to the table, the user decides to replace the
+          old table data, he can simply encode the template info in the
+          data stream.
+        - In the same scenario (a new field is added), the user decides to
+          append a new table, he can encode the template
+        in the new data table and append it to NV data, or write a new common
+        template section and append the data.
+
+  Key "ingredients", (re-iterate the most important features and capabilities)
+     1. How to parse the data is embedded in the NV data itself. It removes the
+        dependency on header file matching,
+        version checking, compatibility among tools, host and firmware.
+     2. Table field ID enables "partial" data acceptance in an s/w module data
+        structure. Whether full matching or reject the whole table, or "partial"
+        acceptance, the capabiilty is in place and further ensures the robust
+        NV data extensibility and compatibility.
+     3. The table granularity, data stream based NV data has variable length
+        and flexibility of modifying an existing table data, replacing the
+        whole data, or leaving the existing data table intact and appending
+        a new table.
+  Misc notes:
+     1. For endianness, support only 4 bytes integer or 4 1-byte
+     2. String identifier needs to be shortened to save storage
+     3. string_field_name,  field type,  field storage class,  storage size
+*/
+
+
+#include "wlan_nv_types.h"
+
+typedef enum _nvFieldSizeEnums {
+   INDEX_ENUM_ALL = 0,
+   INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS,
+   INDEX_ENUM_NUM_REG_DOMAINS,
+   INDEX_ENUM_NUM_RF_SUBBANDS,
+   INDEX_ENUM_NUM_RF_CHANNELS,
+   INDEX_ENUM_NUM_2_4GHZ_CHANNELS,
+   INDEX_ENUM_NUM_802_11_MODES,
+   INDEX_ENUM_NUM_HAL_PHY_RATES,
+   INDEX_ENUM_BUILTIN_LAST,
+   INDEX_ENUM_BUILTIN_MAX,
+} _NV_FIELD_SIZE_ENUMS;
+
+#define INDEX_ENUM_MAX  MAX(INDEX_ENUM_PREDEFINED_MAX, INDEX_ENUM_BUILTIN_MAX)
+
+int getEnumNoOfFields(int enumIdx);
+extern _NV_TEMPLATE_ENUM NvEnumsBuiltIn[/*INDEX_ENUM_MAX*/][ENUM_ENTRIES_MAX];
+
+typedef enum _nvTableIDs {
+   TABLE_sHalNv,
+   TABLE_sNvFields,
+   TABLE_sRegulatoryChannel,
+   TABLE_sRssiChannelOffsets,
+   TABLE_sCalData,
+   TABLE_sTxBbFilterMode,
+   TABLE_sOfdmCmdPwrOffset,
+   TABLE_sDefaultCountry,
+   TABLE_sFwConfig,
+   TABLE_tTpcPowerTable,
+   TABLE_tRateGroupPwr,
+   TABLE_tRateGroupPwrVR,
+   TABLE_sRegulatoryDomains,
+   TABLE_sHwCalValues,
+   TABLE_sNvTables,
+   TABLE_BUILTIN_LAST,
+   TABLE_BUILTIN_MAX,
+} _NV_TABLE_ID;
+
+#define TABLES_MAX    MAX(TABLE_PREDEFINED_MAX, TABLE_BUILTIN_MAX)
+
+int getTableNoOfFields(int tblIdx);
+extern _NV_TEMPLATE_TABLE NvTablesBuiltIn[/*TABLES_MAX*/][TABLE_ENTRIES_MAX];
+
+#endif //#if !defined(_WLAN_NV_TEMPLATEBUILTIN_H)
diff --git a/CORE/VOSS/inc/wlan_nv_template_internal.h b/CORE/VOSS/inc/wlan_nv_template_internal.h
new file mode 100755
index 0000000..714749f
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_template_internal.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined _WLAN_NV_TEMPLATE_INTERNAL_H
+#define  _WLAN_NV_TEMPLATE_INTERNAL_H
+
+/*
+  Template constructs
+     1. TABLE_: struct
+     2. INDEX_ENUM: enums, e.g. {RATE_OFDM_6M,RATE_OFDM_54M}
+     3. INDEX_INT: int, e.g.{min, max, increment}
+     3. Basic data types: tANI_U8, tANI_S8, tANI_U32, tANI_S32
+     4. Storage types:
+        4.1 SINGULAR: one element of basic data type
+        4.2 ARRAY_1: one dimensional array, x-axis
+        4.3 ARRAY_2: two dimensional array, (x, y)
+        4.4 ARRAY_3: three dimensional array, (x, y, z)
+
+  Implementation notes
+     1. Flow of changing NV data format: (TBD) Either change the template and
+        generate the header file, or
+        modify header file and auto-generate the template.
+     2. Flow of writing NV data: encode the template in the data stream, so the
+        NV data is "self-sufficient".
+        No separate template, no compability issue, no need of version control.
+     3. Flow of reading NV data: parse the binary NV data stream based on the
+        template info in the data stream.
+     4. The above NV logic is decoupled from the actual data content, a
+        generic, content ergonostic parser (reading) and encoder (writing).
+        The NV logic is common code shared by tools, s/w
+        (both host and firmware), and off-line utilities.
+     5. NV data parsing and "acceptanace" into an s/w moduel data structure can
+        be "configured" in several ways:
+        5.1 only total matching of all fields, otherwise, reject the whole data
+        stream (a table).
+        5.2 partial matching of fields allowed and the rest fields assume
+        reasonal default values,
+        The choice can be determined later, but the capability is provided.
+     6. We could also design in this selection on an individua table base.
+        To design such capability, reserve some header bits in the data stream.
+     7. The NV data streams can be modified, replaced, or intact with a new
+        data stream of the same table ID added to NV data.
+        The choice can be determined later, but the NV scheme provides such
+        capability.
+     8. The template construct definitions can be common to all tables
+        (tbd: in a common section) or table specific, or updated
+        in a subsequent format section.
+        The use cases are:
+        - An index enum (e.g. RF channels) is common to all tables when the NV
+          data is created. Later new enums are added (e.g.
+        additional channels), one can choose to add the new index enum for new
+        tables appended to the NV data, or replace the
+        old table with new template info and data.
+        The template precedence is table specific then common, and later
+        "common" overwrites "earlier" commmon.
+        - A new field is added to the table, the user decides to replace the old
+        table data, he can simply encode the template
+        info in the data stream.
+        - In the same scenario (a new field is added), the user decides to
+        append a new table, he can encode the template
+        in the new data table and append it to NV data, or write a new common
+        template section and append the data.
+
+  Key "ingredients", (re-iterate the most important features and capabilities)
+     1. How to parse the data is embedded in the NV data itself. It removes the
+        dependency on header file matching,
+        version checking, compatibility among tools, host and firmware.
+     2. Table field ID enables "partial" data acceptance in an s/w module data
+        structure. Whether full matching or reject the whole table, or "partial"
+        acceptance, the capabiilty is in place and further ensures the robust
+        NV data extensibility and compatibility.
+     3. The table granularity, data stream based NV data has variable length
+        and flexibility of modifying an existing table data, replacing
+        the whole data,or leaving the existing data table intact and
+        appending a new table.
+  Misc notes:
+     1. For endianness, support only 4 bytes integer or 4 1-byte
+     2. String identifier needs to be shortened to save storage
+     3. string_field_name,  field type,  field storage class,  storage size
+*/
+
+#include "wlan_nv_types.h"
+
+/*
+ * Stream header bitmap
+ *                       streamType
+ *                        bitmap[7]
+ *                      /                    \
+ *                1: template               0: data
+ *                 bitmap[6]
+ *                /     \
+ *             0: enum  1: table
+ *
+ */
+/* Stream header type[7], 0:  data, 1:  template */
+#define STREAM_HEADER_TYPE_MASK   0x80
+#define STREAM_HEADER_TYPE_LSB    7
+#define IsStreamTemplate(b)       (((b) & (STREAM_HEADER_TYPE_MASK)) ? 1 : 0)
+
+/* Stream header template type [6],  0: enum; 1:  table */
+#define STREAM_HEADER_TEMPLATE_TYPE_MASK   0x40
+#define STREAM_HEADER_TEMPLATE_TYPE_LSB    6
+#define IsTemplateStreamTable(b)   (((b) & (STREAM_HEADER_TEMPLATE_TYPE_MASK)) ? 1 : 0)
+
+/*
+ * Field identifier bitmap
+ *
+ *                field identifier
+ *                bitmap[7]
+ *                 /           \
+ *            0: table/enum     1: basic data type
+ *            bitmap[6:0]         bitmap[6:0]
+ *               |                  |
+ *            tableIdx/          data types (U8, U32, etc.)
+ *            enumIdx
+ */
+/* Field Identifier type [7]
+ *    0:  table
+ *    1:  basic data types
+ * Note that
+ *    - bit[7] table value=0 makes the table ID following data header stream or
+ *       template header stream identical to field ID
+ *    - tableIdx 0 is the "table of all tables", a.k.a. table content of all
+ *      table indexes
+ *    - enumIdx 0 is the "enum of all enums", a.k.a. table content of all enum
+ *      indexes
+ */
+
+#define FIELD_ID_TYPE_MASK                  0x80
+#define FIELD_ID_TYPE_LSB                   7
+#define IsFieldTypeBasicData(b)             (((b) & (FIELD_ID_TYPE_MASK)) ? 1 : 0)
+
+/* Field Identifier table index [6:0] */
+#define FIELD_ID_TABLE_OR_ENUM_IDX_MASK     0x7f
+#define FIELD_ID_TABLE_OR_ENUM_IDX_LSB      0
+#define _TABLE_IDX(b)                       (((b) & ~FIELD_ID_TYPE_MASK) | ((b) & FIELD_ID_TABLE_OR_ENUM_IDX_MASK))
+#define IsIdxTableOfAllTables(b)            (((b) & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ? 0 : 1)
+#define IsIdxEnumOfAllEnums(b)              (((b) & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ? 0 : 1)
+
+/* Field Identifier basic data types [6:0]
+ *    0:  U8
+ *    1:  U32
+ *    2:  S8
+ *    3:  S32
+ *    4:  U16
+ *    5:  S16
+ */
+
+#define FIELD_ID_BASIC_DATA_TYPES_MASK      0x7F
+#define FIELD_ID_BASIC_DATA_TYPES_LSB       0
+
+typedef enum {
+   _FIELD_ID_DATA_TYPE_U8 = 0,
+   _FIELD_ID_DATA_TYPE_U32,
+   _FIELD_ID_DATA_TYPE_S8,
+   _FIELD_ID_DATA_TYPE_S32,
+   _FIELD_ID_DATA_TYPE_U16,
+   _FIELD_ID_DATA_TYPE_S16,
+   _FIELD_ID_DATA_TYPE_LAST,
+} _FIELD_ID_BASIC_DATA_TYPE;
+
+#define TheBasicDataType(b)                 (((b) & (FIELD_ID_BASIC_DATA_TYPES_MASK)) >> FIELD_ID_BASIC_DATA_TYPES_LSB)
+#define _ID_U8                              ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_U8))
+#define _ID_U32                             ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_U32))
+#define _ID_S8                              ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_S8))
+#define _ID_S32                             ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_S32))
+#define _ID_U16                             ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_U16))
+#define _ID_S16                             ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_S16))
+
+/*
+ * field storage class
+ */
+typedef enum {
+   SINGULAR = 0,
+   ARRAY_1,
+   ARRAY_2,
+   ARRAY_3,
+   STORAGE_TYPE_LAST,
+} _FIELD_ID_STORAGE_TYPE;
+
+#define _STORAGE_TYPE(b)   ((b) & 0x3)
+#define _STORAGE_SIZE1(byteLow, byteHigh)   (((((byteHigh) >> 2) & 0x3) << 7) | (((byteLow) >> FIELD_SIZE_VALUE_LSB) & FIELD_SIZE_VALUE_MASK))
+#define _STORAGE_SIZE2(byteLow, byteHigh)   (((((byteHigh) >> 4) & 0x3) << 7) | (((byteLow) >> FIELD_SIZE_VALUE_LSB) & FIELD_SIZE_VALUE_MASK))
+#define _STORAGE_SIZE3(byteLow, byteHigh)   (((((byteHigh) >> 6) & 0x3) << 7) | (((byteLow) >> FIELD_SIZE_VALUE_LSB) & FIELD_SIZE_VALUE_MASK))
+
+#define _ADD_SIZE1(b)  ((((b) >> 7) & 0x3) << 2)
+#define _ADD_SIZE2(b)  ((((b) >> 7) & 0x3) << 4)
+#define _ADD_SIZE3(b)  ((((b) >> 7) & 0x3) << 6)
+
+/*
+ * Field storage size type  [7]
+ *         /       \
+ *     1: int      0: enum
+ *   bitmap[6:0]   bitmap[6:0]
+ *       |             |
+ *   max int index  enum index into enum tables
+ *
+ * Note that enum=0 makes the template enum ID following template stream byte
+ * identical to enum field storage size type
+ *
+ * Field storage size value [6:0]
+ */
+#define FIELD_SIZE_TYPE_MASK              0x80
+#define FIELD_SIZE_TYPE_LSB               7
+#define FIELD_SIZE_TYPE_BIT(t)            (((t)<< (FIELD_SIZE_TYPE_LSB)) & (FIELD_SIZE_TYPE_MASK))
+#define IsFieldSizeInt(b)                 (((b) & (FIELD_SIZE_TYPE_MASK)) ? 1 : 0)
+
+typedef enum {
+   FIELD_SIZE_IDX_ENUM = 0,
+   FIELD_SIZE_IDX_INT = 1,
+} FIELD_SIZE_TYPE;
+
+#define FIELD_SIZE_VALUE_MASK             0x7f
+#define FIELD_SIZE_VALUE_LSB              0
+#define FIELD_SIZE_VALUE_BITS(val)        (((val) << (FIELD_SIZE_VALUE_LSB)) & (FIELD_SIZE_VALUE_MASK))
+
+/*
+ * NV table storage struct in an s/w module
+ */
+#define _TABLE_NAME_LEN  2
+#define _TABLE_FIELD_FULL_NAME_LEN  47
+
+typedef struct _nvTemplateTableStructInternal {
+   tANI_U8   fieldName[_TABLE_NAME_LEN + 1];
+   tANI_U8   fieldId;
+   tANI_U8   fieldStorageType;
+   tANI_U8   fieldStorageSize1;
+   tANI_U8   fieldStorageSize2;
+   tANI_U8   fieldStorageSize3;
+   tANI_U32  offset; //void     *offset;
+   tANI_U8   fieldFullName[_TABLE_FIELD_FULL_NAME_LEN +1];
+} _NV_TEMPLATE_TABLE;
+
+#define _OFFSET_NOT_SET        0xFFFFFFFF
+#define TABLE_PREDEFINED_MAX   50
+#define TABLE_ENTRIES_MAX      50
+#define _LIST_OF_TABLES_IDX     0
+#define _TABLE_FIELDS_POS       2
+#define _ENUM_START_POS         2
+#define _TABLE_FIELD_MIN_LEN    4
+#define _ENUM_MIN_LEN           3
+
+#define _ENUM_NAME_LEN _TABLE_NAME_LEN
+#define _ENUM_FULL_NAME_LEN    47
+typedef struct _nvTemplateEnumStruct {
+   tANI_U8   enumName[3];  // 2 char string
+   tANI_U8   enumValue;
+   tANI_U8   enumValuePeer;
+   tANI_U8   enumFullName[_ENUM_FULL_NAME_LEN +1];
+} _NV_TEMPLATE_ENUM;
+#define INDEX_ENUM_PREDEFINED_MAX    20
+#define ENUM_ENTRIES_MAX             200
+
+typedef enum {
+   _MIS_MATCH = 0,
+   _MATCH,
+} _NV_TEMPLATE_PROCESS_RC;
+
+#define _NV_BIN_STREAM_HEADER_BYTE          0
+#define _NV_BIN_STREAM_TABLE_ID_BYTE        1
+#define _NV_BIN_STREAM_ENUM_ID_BYTE         1
+#define _NV_BIN_DATA_STREAM_TABLEID_BYTE    1
+#define _NV_BIN_ENUM_TEMPLATE_ENTRY_SIZE    3
+#define _NV_LIST_OF_TABLE_ID                0
+
+/*
+ * Stream write
+ */
+#define _STREAM_HEADER_POS            0
+#define _ENUM_STREAM_HEADER_POS       _STREAM_HEADER_POS
+#define _TABLE_STREAM_HEADER_POS      _STREAM_HEADER_POS
+#define _TEMPLATE_INDEX_HEADER_POS    1
+#define _ENUM_INDEX_HEADER_POS        _TEMPLATE_INDEX_HEADER_POS
+#define _TABLE_INDEX_HEADER_POS       _TEMPLATE_INDEX_HEADER_POS
+
+/*
+ * Additional typedef
+ */
+typedef struct _enumMetaData {
+   _NV_TEMPLATE_PROCESS_RC match;
+} _ENUM_META_DATA;
+
+#define MAX(a, b)     (((a) > (b)) ? (a) : (b))
+#define _NV_STREAM_LEN_MAX           35000
+
+/*
+ * Error code should be expanded, this is the beginning set
+ */
+typedef enum {
+   _OK = 0,
+   _RESET_STREAM_FAILED,
+   _WRITE_STREAM_FAILED,
+   _STREAM_NOT_FIT_BUF,
+   _SW_BIN_MISMATCH,
+   _INSUFFICIENT_FOR_FIELD_PARSER_ERROR,
+   _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES,
+   _ENUM_NOT_FOUND_IN_BUILT_IN,
+} _ErrorCode;
+
+/*
+ * Use the stream test stub
+ */
+//#define _USE_STREAM_STUB
+#define RESET_STREAM(b)   resetStream(b)
+#define NEXT_STREAM(b,c)    nextStream(b,c)
+
+#endif /*#if !defined(_WLAN_NV_TEMPLATE_INTERNAL_H)*/
diff --git a/CORE/VOSS/inc/wlan_nv_types.h b/CORE/VOSS/inc/wlan_nv_types.h
new file mode 100755
index 0000000..34642cb
--- /dev/null
+++ b/CORE/VOSS/inc/wlan_nv_types.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+#if !defined __WLAN_NV_TYPES_H
+#define __WLAN_NV_TYPES_H
+
+#include "halLegacyPalTypes.h"
+#include "halCompiler.h"
+#include "vos_status.h"
+#include <linux/string.h>
+
+typedef char tANI_BOOL;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define nul '\0'
+
+#endif
diff --git a/CORE/VOSS/src/vos_getBin.c b/CORE/VOSS/src/vos_getBin.c
index fa47645..7e980a6 100644
--- a/CORE/VOSS/src/vos_getBin.c
+++ b/CORE/VOSS/src/vos_getBin.c
@@ -109,6 +109,9 @@
         case VOS_BINARY_ID_HO_CONFIG:
            pFileName = WLAN_HO_CFG_FILE;
            break;
+        case VOS_BINARY_ID_DICT_CONFIG:
+           pFileName = WLAN_DICT_FILE;
+           break;
         default:
            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Invalid binaryID");
            return VosSts;
diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c
index ce305c4..c867534 100644
--- a/CORE/VOSS/src/vos_nvitem.c
+++ b/CORE/VOSS/src/vos_nvitem.c
@@ -63,6 +63,7 @@
 #include "vos_api.h"
 #include "wlan_hdd_misc.h"
 #include "vos_sched.h"
+#include "wlan_nv_parser.h"
 #include "wlan_hdd_main.h"
 #include <net/cfg80211.h>
 static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
@@ -80,6 +81,7 @@
 #define VOS_HARD_CODED_MAC    {0, 0x0a, 0xf5, 4, 5, 6}
 
 #define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF
+#define MAGIC_NUMBER            0xCAFEBABE
 
 /*----------------------------------------------------------------------------
  * Type Declarations
@@ -377,6 +379,12 @@
 nvEFSTable_t *gnvEFSTable;
 /* EFS Table  to send the NV structure to HAL*/ 
 static nvEFSTable_t *pnvEFSTable;
+static v_U8_t *pnvEncodedBuf;
+static v_U8_t *pDictFile;
+static v_U8_t *pEncodedBuf;
+static v_SIZE_t nvReadEncodeBufSize;
+static v_SIZE_t nDictionarySize;
+static v_U32_t magicNumber;
 
 const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
 {
@@ -485,6 +493,64 @@
    return VOS_STATUS_SUCCESS;
 }
 
+/**------------------------------------------------------------------------
+  \brief vos_nv_get_dictionary_data() - get the dictionary data required for
+  \ tools
+  \return VOS_STATUS_SUCCESS - dictionary data is read successfully
+          otherwise  - not successful
+  \sa
+-------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_get_dictionary_data(void)
+{
+   VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
+
+   if (MAGIC_NUMBER != magicNumber)
+   {
+      return VOS_STATUS_SUCCESS;
+   }
+
+   nDictionarySize = 0;
+
+   vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL,
+                                                &nDictionarySize );
+   if (VOS_STATUS_E_NOMEM != vosStatus)
+   {
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                 "Error obtaining binary size" );
+/// NOTE:
+/// We can still work without a dictionary file..
+      return VOS_STATUS_SUCCESS;
+   }
+
+   // malloc a buffer to read in the Configuration binary file.
+   pDictFile = vos_mem_malloc( nDictionarySize );
+   if (NULL == pDictFile)
+   {
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+              "Unable to allocate memory for the CFG binary [size= %d bytes]",
+                 nDictionarySize );
+      vosStatus = VOS_STATUS_E_NOMEM;
+      goto fail;
+   }
+
+   /* Get the entire CFG file image... */
+   vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile,
+                                                         &nDictionarySize );
+   if (!VOS_IS_STATUS_SUCCESS( vosStatus ))
+   {
+      VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+         "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]",
+                                                             nDictionarySize );
+      return VOS_STATUS_SUCCESS;
+   }
+
+   VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
+         "Dict file image from vOSS. [size= %d bytes]", nDictionarySize );
+
+fail:
+   return vosStatus;
+}
+
 VOS_STATUS vos_nv_open(void)
 {
     VOS_STATUS status = VOS_STATUS_SUCCESS;
@@ -492,11 +558,13 @@
     v_SIZE_t bufSize;
     v_SIZE_t nvReadBufSize;
     v_BOOL_t itemIsValid = VOS_FALSE;
-    
+    v_U32_t dataOffset;
+    sHalNv *pnvData = NULL;
+
     /*Get the global context */
     pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
-    
-    if(pVosContext == NULL)
+
+    if (NULL == pVosContext)
     {
         return (eHAL_STATUS_FAILURE);
     }
@@ -504,17 +572,94 @@
     bufSize = sizeof(nvEFSTable_t);
     status = hdd_request_firmware(WLAN_NV_FILE,
                                   ((VosContextType*)(pVosContext))->pHDDContext,
-                                  (v_VOID_t**)&gnvEFSTable, &nvReadBufSize);
+                                  (v_VOID_t**)&pnvEncodedBuf, &nvReadBufSize);
 
-    if ( (!VOS_IS_STATUS_SUCCESS( status )) || !gnvEFSTable)
+    if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvEncodedBuf))
     {
-         VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
+       VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                    "%s: unable to download NV file %s",
                    __func__, WLAN_NV_FILE);
-         return VOS_STATUS_E_RESOURCES;
+       return VOS_STATUS_E_RESOURCES;
     }
 
-     VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+    memcpy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t));
+
+    /// Allocate buffer with maximum length..
+    pEncodedBuf = (v_U8_t *)vos_mem_malloc(nvReadBufSize);
+
+    if (NULL == pEncodedBuf)
+    {
+        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                    "%s : failed to allocate memory for NV", __func__);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf;
+
+    if (MAGIC_NUMBER == magicNumber)
+    {
+        pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv));
+
+        if (NULL == pnvData)
+        {
+            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                      "%s : failed to allocate memory for NV", __func__);
+            return VOS_STATUS_E_NOMEM;
+        }
+
+        memset(pnvData, 0, sizeof(sHalNv));
+
+        /// Data starts from offset of validity bit map + magic number..
+        dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t);
+
+        status = nvParser(&pnvEncodedBuf[dataOffset],
+                     (nvReadBufSize-dataOffset), pnvData);
+
+        ///ignore validity bit map
+        nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t);
+
+        vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)],
+            nvReadEncodeBufSize);
+
+        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+                   "readEncodeBufSize %d",nvReadEncodeBufSize);
+
+        if (VOS_STATUS_SUCCESS == status) {
+           VOS_TRACE(VOS_MODULE_ID_VOSS,  VOS_TRACE_LEVEL_ERROR,
+                       "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d",
+                        pnvData->fields.productId,
+                        pnvData->fields.couplerType,
+                        pnvData->fields.wlanNvRevId);
+
+           vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv));
+
+           nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t);
+        }
+        else
+        {
+           VOS_TRACE(VOS_MODULE_ID_VOSS,  VOS_TRACE_LEVEL_ERROR,
+                       "nvParser failed %d",status);
+
+           nvReadBufSize = 0;
+
+           vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv));
+
+           nvReadEncodeBufSize = sizeof(sHalNv);
+        }
+    }
+    else
+    {
+       dataOffset = sizeof(v_U32_t);
+       nvReadEncodeBufSize = sizeof(sHalNv);
+       memcpy(pEncodedBuf, &pnvEncodedBuf[dataOffset], nvReadEncodeBufSize);
+    }
+
+    if (NULL != pnvData)
+    {
+       vos_mem_free(pnvData);
+    }
+
+    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "INFO: NV binary file version=%d Driver default NV version=%d, continue...\n",
            gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION);
 
@@ -522,7 +667,7 @@
     {
         /* Allocate memory to global NV table */
         pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t));
-        if (NULL == pnvEFSTable)
+        if ( NULL == pnvEFSTable )
         {
             VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                       "%s : failed to allocate memory for NV", __func__);
@@ -530,7 +675,7 @@
         }
 
         /*Copying the NV defaults */
-        vos_mem_copy(&(pnvEFSTable->halnv),&nvDefaults,sizeof(sHalNv));
+        vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv));
 
         /* Size mismatch */
         if ( nvReadBufSize != bufSize)
@@ -731,6 +876,7 @@
     return VOS_STATUS_SUCCESS;
 error:
     vos_mem_free(pnvEFSTable);
+    vos_mem_free(pEncodedBuf);
     return eHAL_STATUS_FAILURE ;
 }
 
@@ -748,6 +894,9 @@
         return VOS_STATUS_E_FAILURE;
     }
     vos_mem_free(pnvEFSTable);
+    vos_mem_free(pEncodedBuf);
+    vos_mem_free(pDictFile);
+
     gnvEFSTable=NULL;
     return VOS_STATUS_SUCCESS;
 }
@@ -1750,7 +1899,6 @@
   -------------------------------------------------------------------------*/
 VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
 {
-
    /* Send the NV structure and size */
    *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
    *pSize = sizeof(sHalNv);
@@ -1759,6 +1907,62 @@
 }
 
 /**------------------------------------------------------------------------
+  \brief vos_nv_getBuffer -
+  \param pBuffer  - to return the buffer address
+              pSize     - buffer size.
+  \return status of the NV read operation
+  \sa
+  -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
+{
+   /* Send the NV structure and size */
+   VOS_STATUS status;
+
+   status = vos_nv_isEmbeddedNV();
+
+   if (VOS_STATUS_SUCCESS == status)
+   {
+      *pNvBuffer = (v_VOID_t *)(pEncodedBuf);
+      *pSize = nvReadEncodeBufSize;
+   }
+   else
+   {
+      *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv);
+      *pSize = sizeof(sHalNv);
+   }
+
+   return VOS_STATUS_SUCCESS;
+}
+
+
+VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize)
+{
+    /* Send the NV structure and size */
+   *pNvBuffer = (v_VOID_t *)(pDictFile);
+   *pSize = nDictionarySize;
+
+   return VOS_STATUS_SUCCESS;
+}
+
+VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t)
+{
+   if (MAGIC_NUMBER == magicNumber)
+   {
+      return VOS_STATUS_SUCCESS;
+   }
+
+   return VOS_STATUS_E_FAILURE;
+}
+
+VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size)
+{
+    vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)],
+            (size-sizeof(v_U32_t)));
+
+    return VOS_STATUS_SUCCESS;
+}
+
+/**------------------------------------------------------------------------
   \brief vos_nv_setRegDomain - 
   \param clientCtxt  - Client Context, Not used for PRIMA
               regId  - Regulatory Domain ID
diff --git a/CORE/VOSS/src/wlan_nv_parser.c b/CORE/VOSS/src/wlan_nv_parser.c
new file mode 100755
index 0000000..ea8f3c1
--- /dev/null
+++ b/CORE/VOSS/src/wlan_nv_parser.c
@@ -0,0 +1,2146 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*===========================================================================
+                       EDIT HISTORY FOR FILE
+
+  This section contains comments describing changes made to the module.
+  Notice that changes are listed in reverse chronological order.
+
+  $Header:$ $DateTime: $ $Author: $
+
+  when        who        what, where, why
+  --------    ---        -----------------------------------------------------
+  04/10/13    kumarpra   nv parser creation
+===========================================================================*/
+
+#include <linux/string.h>
+#include "wlan_nv.h"
+
+/*
+ * NV stream layer service
+ */
+#include "wlan_nv_stream.h"
+#include "wlan_nv_template_internal.h"
+#include "wlan_nv_parser_internal.h"
+#include "wlan_nv_template_api.h"
+#include "wlan_nv_template_builtin.h"
+
+#define _RECURSIVE_DATA_TABLE_PARSING
+// Recursive/iterative switch !! Default iterative
+#define _RECURSIVE_VERSION
+
+/*
+ * Build process should have created the built-in templates in
+ *     "wlan_nv_templateBuiltIn.c"
+ *     Include its auto-generated companion header file
+ *     "wlan_nv_templateBuiltIn.h"
+ *
+ * The main definitions are
+ *     _NV_TEMPLATE_TABLE NvTablesBuiltIn[];
+ *
+ */
+
+/*
+ * Parsing control bitmap
+ */
+tANI_U32 gNVParsingControlLo;
+static int subTableSize;
+static int fieldSize;
+static sHalNv *gpnvData_t;
+/* store enum comparison results*/
+static _ENUM_META_DATA enumMetaDataFromBin[INDEX_ENUM_MAX];
+
+
+/*
+ * This data copy logic ignores the enum or int data types,
+ * but simply copy the whole chunk to the NV data structure
+ */
+typedef struct {
+   int idxSubFromBin;
+   int idxSubBuiltin;
+} _SUBTABLES_QUEUE;
+
+pF_NumElemBasedOnStorageType numElemBasedOnStorageType[] = {
+   numElemSingular,     // SINGULAR=0
+   numElemArray1,       // ARRAY_1=1
+   numElemArray2,       // ARRAY_2=2
+   numElemArray3,       // ARRAY_3=3
+};
+
+static int sizeOneElemBasedOnFieldIdBasicDataType[] = {
+   1,  // _FIELD_ID_DATA_TYPE_U8 =0
+   4,  // _FIELD_ID_DATA_TYPE_U32
+   1,  // _FIELD_ID_DATA_TYPE_S8
+   4,  // _FIELD_ID_DATA_TYPE_S32
+   2,  // _FIELD_ID_DATA_TYPE_U16
+   2,  // _FIELD_ID_DATA_TYPE_S16
+};
+
+static _NV_STREAM_BUF nvStream[_NV_STREAM_LEN_MAX];
+static int subTableRd, subTableWr;
+
+#if !defined(_RECURSIVE_VERSION)
+#define _SUBTABLES_MAX 32
+static _SUBTABLES_QUEUE subTablesQueue[_SUBTABLES_MAX];
+#endif
+
+/*==============================================================================
+*
+* Storage for NvTablesFromBin
+*
+*===============================================================================
+*/
+
+/*
+ * Init NvTablesFromBin
+ * All entries are initialized to 0, pointers to NULL
+*/
+
+_NV_TEMPLATE_TABLE NvTablesFromBin[TABLES_MAX][TABLE_ENTRIES_MAX] = {
+   { /* TABLE_LAST*/
+       {{nul}, 0, 0, 0, 0, 0, 0, {nul}},
+   },
+};
+
+static void initNvTablesFromBin(void)
+{
+   int i, j;
+
+   for (i = 0; i < TABLES_MAX; i++) {
+      for (j = 0; j < TABLE_ENTRIES_MAX; j++) {
+         NvTablesFromBin[i][j].fieldName[0] = nul;
+         NvTablesFromBin[i][j].fieldName[1] = nul;
+         NvTablesFromBin[i][j].fieldName[2] = nul;
+         NvTablesFromBin[i][j].fieldId = 0;
+         NvTablesFromBin[i][j].fieldStorageType = 0;
+         NvTablesFromBin[i][j].fieldStorageSize1 = 0;
+         NvTablesFromBin[i][j].fieldStorageSize2 = 0;
+         NvTablesFromBin[i][j].fieldStorageSize3 = 0;
+         NvTablesFromBin[i][j].offset = 0;
+         NvTablesFromBin[i][j].fieldFullName[0] = nul;
+         NvTablesFromBin[i][j].fieldFullName[1] = nul;
+         NvTablesFromBin[i][j].fieldFullName[2] = nul;
+      }
+   }
+
+   return;
+}
+
+/*==============================================================================
+*
+* Storage for NvEnumsFromBin
+*
+* ==============================================================================
+*/
+
+/*
+ * Prepare the NV enum templates storage parsed from nv.bin
+ * They are used later for parsing the nv.bin data
+ * All entries are initialized to 0, pointers to NULL
+ */
+
+_NV_TEMPLATE_ENUM NvEnumsFromBin[INDEX_ENUM_MAX][ENUM_ENTRIES_MAX] = {
+   { /* INDEX_ENUM_LAST */
+      {{nul}, 0, 0, {nul}},
+   },
+};
+
+static void initNvEnumsFromBin(void)
+{
+   int i, j;
+
+   for(i = 0; i < INDEX_ENUM_MAX; i++) {
+      for(j = 0; j < ENUM_ENTRIES_MAX; j++) {
+         NvEnumsFromBin[i][j].enumName[0] = nul;
+         NvEnumsFromBin[i][j].enumName[1] = nul;
+         NvEnumsFromBin[i][j].enumName[2] = nul;
+         NvEnumsFromBin[i][j].enumValue = 0;
+         NvEnumsFromBin[i][j].enumValuePeer = 0xFF;
+         NvEnumsFromBin[i][j].enumFullName[0] = nul;
+      }
+   }
+   return;
+}
+
+
+// =============================================================================
+//
+// Parse template streams
+//
+// =============================================================================
+
+/*
+ * Read nv.bin to extract the template info
+ *     _NV_TEMPLATE_TABLE NvTablesFromBin[];
+ */
+
+/*
+ * Parse nv.bin data and extract to the build-in data storage
+ *
+ * There are two outcomes from earlier templates comparison operation.
+ *     different or identical
+ * If identical, this operation will most likely take place.
+ * If different,
+ *     One is to simply indicate to the user and abort reading the nv.bin data
+ *     The other is to continue this operation, and extract the matching entries
+ *      in nv.bin
+ */
+
+/*
+ * The template based NV logic:
+ *    - the s/w module has the built-in templates
+ *    - nv.bin is read one stream at a time, sequentially from beginning to end
+ *    - if the stream is an enum stream,
+ *    -     add to nv.bin template data structure
+ *    -     compare with the built in template, by the string ID
+ *    -     if two match, move on
+ *    -     if not match, indicate mismatch, act based on the global logic
+ *    _     selection
+ *    -         if abort, exit here
+ *    -         if extract-matching-ones,
+ *    -             copy the enum from the built-in template over to a separate
+ *    _             column
+ *    -             when the enum comparison is done, all correlated enums have
+ *    -             a built-in enum value
+ *    -                 all mismtached ones have 0xff
+ *    - else if the stream is a table
+ *    -     add to nv.bin template data structure
+ *    -     compare with the built-in template, by the field string ID
+ *    -     if two tables match, move on
+ *    -     if not match, indicate mismatch and proceed based on the global
+ *    -     logic selection
+ *    -         if abort, exit here
+ *    -         if extract-matching-ones,
+ *    -             copy the built-in template offset to a separate column
+ *    - eles if the stream is a data stream
+ *    -     parse the data stream based on the accumulated NV templates so far,
+ *    -     note at this point,
+ *    -         1. the accumulated templates may be incomplete, to make up the
+ *    -            whole NV structure
+ *    -         2. some will be "overwritten" by later templates definitions
+ *    -            that change the earlier templates)
+ *    -     how to parse?
+ *    -         based on the nv.bin accumulated templates so far,
+ *    -         select the table definition from the data stream,
+ *    -         find the corresponding table template,
+ *    -         start parsing data based on the template's field string IDs,
+ *    -         field by field sequentially.
+ *    -         if the field is a nested table,
+ *    -             go inside to the next level
+ *    -         if the field is a basic type,
+ *    -             copy data of the given size to the offset which is the
+ *    -             offset in the built-in nv data storage
+ *    - end of the logic
+ */
+
+/*----------------------------------------------------------------------------
+  \brief nvParser() - parse nv data provided in input buffer and store
+  \ output in sHalNv
+  \param inputEncodedbuffer, length, sHalNv - ptr to input stream,
+  \param length, sHalNv
+  \return success when successfully decode and copy to sHalNv structure
+  \sa
+-----------------------------------------------------------------------------*/
+
+VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
+   sHalNv *hal_nv)
+{
+   _STREAM_RC streamRc;
+   _NV_STREAM_BUF *pStream = &nvStream[0];
+   tANI_U32 len;
+   _ErrorCode errCode = _OK;
+   VOS_STATUS ret = VOS_STATUS_SUCCESS;
+   gpnvData_t = hal_nv;
+
+    // prepare storages for parsing nv.bin
+   initNvTablesFromBin();
+   initNvEnumsFromBin();
+
+    // init stream read pointer
+   initReadStream(pnvEncodedBuf, nvReadBufSize);
+
+    // get and process streams one by one
+   while (RC_FAIL != (streamRc = NEXT_STREAM(&len, &nvStream[0])) ) {
+        // need to copy, stream layer is freeing it
+      if (len > _NV_STREAM_LEN_MAX) {
+         errCode = _STREAM_NOT_FIT_BUF;
+         goto _error;
+      }
+        // template or data
+      if (IsStreamTemplate(pStream[_NV_BIN_STREAM_HEADER_BYTE])) {
+          if (_MIS_MATCH == processNvTemplate(pStream, len)) {
+              if (_FLAG_AND_ABORT(gNVParsingControlLo) ) {
+                  errCode = _SW_BIN_MISMATCH;
+                  break;
+              }
+          }
+      }
+      else {
+          processNvData(pStream, len);
+      }
+   }
+
+_error:
+   if (_OK != errCode) {
+      ret = VOS_STATUS_E_INVAL;
+   }
+
+    // all done
+   return ret;
+}
+
+static _NV_TEMPLATE_PROCESS_RC processNvTemplate(_NV_STREAM_BUF *pStream,
+   int len)
+{
+    // Table or enum
+    if (IsTemplateStreamTable(pStream[_NV_BIN_STREAM_HEADER_BYTE])) {
+        return processNvTemplateTable(pStream, len);
+    }
+    else {
+        return processNvTemplateEnum(pStream, len);
+    }
+}
+
+/* -----------------------------------------------------------------------------
+ *
+ * Parse one table template stream in nv.bin
+ * The length of table templates varies, based on the field ID class,
+ * field size type
+ */
+
+static _NV_TEMPLATE_PROCESS_RC processNvTemplateTable(_NV_STREAM_BUF *pStream,
+   int len)
+{
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+   char tableNameFromBin[_TABLE_NAME_LEN +1];
+   int tableIdxFromBin;
+
+    // construct the template table in the NvTablesFromBin
+   memset((void*)tableNameFromBin, '\0', (size_t) (_TABLE_NAME_LEN +1));
+   tableIdxFromBin = constructATemplateTable(pStream, len, tableNameFromBin);
+
+    // fetch the table name from the first entry, the Table of all tables
+    // search for the corresponding table in NvDataBuiltIn
+   if (tableIdxFromBin) {
+       rc = compareWithBuiltinTable(tableIdxFromBin, tableNameFromBin);
+   }
+    // done
+   return rc;
+}
+
+static int getOffsetFromBuiltIn(char *tableNameFromBin)
+{
+   int offset = _OFFSET_NOT_SET;
+   int i;
+
+   _NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
+    // search NvTablesBuiltIn for the same string named table, and its idx
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+       if (nul == pTableBuiltin[0][i].fieldName[0]) {
+          break;
+       }
+       if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) {
+          offset = pTableBuiltin[0][i].offset;
+          break;
+       }
+   }
+   return offset;
+}
+
+/*
+ * Construct a table template in the NvTablesFromBin
+ * it returns the newly constructed table, for comparison with NvTablesBuiltIn
+ */
+static int constructATemplateTable(_NV_STREAM_BUF *pStream, int len,
+   char *tableStrName)
+{
+   int pos = 0;
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+   int tableIdx, entryIdx;
+   int i;
+   _ErrorCode errCode = _OK;
+
+   tableIdx = (pStream[_NV_BIN_STREAM_TABLE_ID_BYTE] &
+                        FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+
+   if (IsIdxTableOfAllTables(tableIdx)) {
+   }
+   else {
+        // find the string name of the table
+      for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+         if (nul == pTable[0][i].fieldName[0]) {
+            break;
+         }
+         if ((pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ==
+           tableIdx) {
+            strlcpy(tableStrName, pTable[0][i].fieldName, (_TABLE_NAME_LEN +1));
+            break;
+         }
+     }
+     if (TABLE_ENTRIES_MAX == i) {
+            // if string name not found, don't know what to do
+        errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES;
+        goto _error;
+     }
+   }
+
+    // check if the table is already populated
+   if (nul != pTable[tableIdx][0].fieldName[0]) {  // there is data in that enty
+       // tbd: decision logic based on Parsing Control (bitmap)
+   }
+
+    // overwrite table entry, tableIdx
+   pos = _TABLE_FIELDS_POS;
+   entryIdx = 0;
+   while (pos < len) {
+      if (!(pos <= (len - _TABLE_FIELD_MIN_LEN))) {
+           // error condition
+         errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR;
+         break;
+      }
+
+        //  populate the entry
+      memset(pTable[tableIdx][entryIdx].fieldName, '\0',
+         (size_t) (_TABLE_NAME_LEN + 1));
+      memset(pTable[tableIdx][entryIdx].fieldFullName, '\0',
+        (size_t) (_TABLE_FIELD_FULL_NAME_LEN + 1));
+      pTable[tableIdx][entryIdx].fieldName[0] = pStream[pos++];
+      pTable[tableIdx][entryIdx].fieldName[1] = pStream[pos++];
+      pTable[tableIdx][entryIdx].fieldId = pStream[pos++];
+      pTable[tableIdx][entryIdx].fieldStorageType = pStream[pos++];
+      pTable[tableIdx][entryIdx].fieldStorageSize1 = 0;
+      pTable[tableIdx][entryIdx].fieldStorageSize2 = 0;
+      pTable[tableIdx][entryIdx].fieldStorageSize3 = 0;
+      pTable[tableIdx][entryIdx].offset =
+         getOffsetFromBuiltIn(pTable[tableIdx][entryIdx].fieldName);
+
+      if (SINGULAR ==
+         _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
+      }
+      else if (ARRAY_1 ==
+         _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
+         pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
+      }
+      else if (ARRAY_2 ==
+         _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
+         pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
+         pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++];
+      }
+      else if (ARRAY_3 ==
+         _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
+         pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
+         pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++];
+         pTable[tableIdx][entryIdx].fieldStorageSize3 = pStream[pos++];
+      }
+        //
+      entryIdx++;
+   }
+
+_error:
+   if (_OK != errCode) {
+   }
+
+    // all done
+   return tableIdx;
+}
+
+/* -----------------------------------------------------------------------------
+ *
+ * Table Compare logic:
+ *
+ * 1. the fields need to be in the same order. Looping through fields doesn't
+ *    guarantee order.
+ * 2. whenever mismatch occurs in this "same-order" comparison, flag.
+ * 3. If extract matching entries' option is selected, proceed to nv.bin table
+ *    and extract data.
+ *
+ * Note
+ *   "compareWithBuiltinTable" is the initiating point.
+ *   "compare2Tables" is the top level compare logic.
+ *       it is naturally implemented as a recursive call, but out of stack
+ *       overflow concern,
+ *       it is also implemented as an iterative loop.
+ *
+ */
+
+static _NV_TEMPLATE_PROCESS_RC compareWithBuiltinTable(int idxFromBin,
+   char *tableNameFromBin)
+{
+   int i;
+   _NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
+   int tableIdxBuiltin = 0;
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+   _ErrorCode errCode = _OK;
+
+    // search NvTablesBuiltIn for the same string named table, and its idx
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+      if (nul == pTableBuiltin[0][i].fieldName[0]) {
+         break;
+      }
+      if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) {
+          tableIdxBuiltin = (pTableBuiltin[0][i].fieldId &
+             FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+          break;
+      }
+   }
+
+   // compare and copy values
+   if (!tableIdxBuiltin) {
+      errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES;
+      rc = _MIS_MATCH;
+   }
+   else {
+      subTableRd = 0;
+      subTableWr = 0;
+
+      // fire the comparison logic
+      if (_MIS_MATCH == compare2Tables(idxFromBin, tableIdxBuiltin)) {
+          rc = _MIS_MATCH;
+      }
+
+      // for iterative version
+      // return code (rc) should only be set to _MIS_MATCH when it happens at
+      // least once
+#if !defined(_RECURSIVE_VERSION)
+      {
+      int idxSubFromBin, idxSubBuiltin;
+      while (subTableRd != subTableWr) {
+          idxSubFromBin = subTablesQueue[subTableRd].idxSubFromBin;
+          idxSubBuiltin = subTablesQueue[subTableRd].idxSubBuiltin;
+          if (_MIS_MATCH == compare2Tables(idxSubFromBin, idxSubBuiltin)) {
+              rc = _MIS_MATCH;
+          }
+          // increment read pointer
+          subTableRd = (subTableRd+1) % _SUBTABLES_MAX;
+     }
+     }
+#endif //#if !defined(_RECURSIVE_VERSION)
+   }
+
+//_error:
+   if (_OK != errCode) {
+        //printf("Error %d \n", errCode);
+   }
+
+   //
+   return rc;
+}
+
+static _NV_TEMPLATE_PROCESS_RC compare2Tables(int idxFromBin, int idxBuiltin)
+{
+   int i, j;
+   _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX];
+   _NV_TEMPLATE_TABLE (*pTableFromBin)[TABLE_ENTRIES_MAX];
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+
+   pTableBuiltIn = NvTablesBuiltIn;
+   pTableFromBin = NvTablesFromBin;
+
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+      if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) ||
+      // end of table occurs in either table
+          (nul == pTableFromBin[idxFromBin][i].fieldName[0])) {
+          // end of table occurs in either table
+         if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) &&
+             (nul == pTableFromBin[idxFromBin][i].fieldName[0])) {
+            rc = _MATCH;
+         }
+         else {
+            rc = _MIS_MATCH;
+
+            for (j=0; j<TABLE_ENTRIES_MAX; j++) {
+               if (nul == pTableBuiltIn[idxBuiltin][j].fieldName[0]) {
+                       // end of bin table
+                  break;
+               }
+               if (!strcmp(
+                  (const char*) pTableBuiltIn[idxBuiltin][j].fieldName,
+                  (const char*) pTableFromBin[idxFromBin][i].fieldName)) {
+                        // found matching field in bin table
+                        // DO NOT check return code, it's already a mismatch
+                  compare2FieldsAndCopyFromBin(
+                       &(pTableBuiltIn[idxBuiltin][j]),
+                       &(pTableFromBin[idxFromBin][i]), idxBuiltin,
+                       idxFromBin);
+                  break;
+               }
+            }
+         }
+         break; // end of table, either table, condition
+      }
+      else {
+         if (!strcmp(pTableBuiltIn[idxBuiltin][i].fieldName,
+                 pTableFromBin[idxFromBin][i].fieldName)) {
+         // two field names match
+            if (_MATCH == compare2FieldsAndCopyFromBin(
+                             &(pTableBuiltIn[idxBuiltin][i]),
+                             &(pTableFromBin[idxFromBin][i]),
+                             idxBuiltin, idxFromBin)) {
+               rc = _MATCH;
+            }
+            else {
+               rc = _MIS_MATCH;
+               if ( _FLAG_AND_ABORT(gNVParsingControlLo) ) {
+                  break;
+               }
+            }
+         }
+         else {
+            rc = _MIS_MATCH;
+            if ( _FLAG_AND_ABORT(gNVParsingControlLo) ) {
+               break;
+            }
+            // else
+            // loop through the WHOLE bin tables, looking for a matching field.
+            // this would take care of both cases where bin table field is
+            // either "ahead" or "behind"
+            for (j = 0; j < TABLE_ENTRIES_MAX; j++) {
+            // end of bin table
+               if (nul == pTableFromBin[idxBuiltin][j].fieldName[0]) {
+                   break;
+               }
+               if (!strcmp(pTableBuiltIn[idxBuiltin][j].fieldName,
+                     pTableFromBin[idxFromBin][i].fieldName)) {
+                // found matching field in bin table
+                // DO NOT check return code, it's already a mismatch
+                  compare2FieldsAndCopyFromBin(&(pTableBuiltIn[idxBuiltin][j]),
+                      &(pTableFromBin[idxFromBin][i]), idxBuiltin, idxFromBin);
+                  break;
+               }
+            }
+         }
+      }
+   }
+
+   return rc;
+}
+
+static _NV_TEMPLATE_PROCESS_RC compare2FieldsAndCopyFromBin(
+   _NV_TEMPLATE_TABLE*pTableBuiltIn,
+   _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin)
+{
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+
+   // Verified already the fieldNames match
+   // fieldId type matching?
+   /*
+    * If it's a simple type, simple comparison, ==,after mask out the data type
+    * else if it's a table, need to compare 2 tables, don't call recursively
+    */
+   if (_MIS_MATCH == compare2FieldIDType(pTableBuiltIn, pTableFromBin,
+         idxBuiltin, idxFromBin)) {
+      rc = _MIS_MATCH;
+      goto _end;
+   }
+    // storage type matching?
+    // If it's SINGULAR, simple == comparison
+    // else if it's ARRAY_n, besides check ARRAY_n equal, check sizes
+    //     if sizes are Index_int, simple comparison
+    //     else if sizes are INDEX_ENUM, need to loop through enums
+    //
+   if (_MIS_MATCH == compare2FieldStorageTypeAndSizes(pTableBuiltIn,
+            pTableFromBin, idxBuiltin, idxFromBin)) {
+      rc = _MIS_MATCH;
+      goto _end;
+   }
+
+   // all matched, copy offset over
+   rc = _MATCH;
+   pTableFromBin->offset = pTableBuiltIn->offset;
+
+_end:
+   return rc;
+}
+
+static _NV_TEMPLATE_PROCESS_RC compare2FieldIDType(
+   _NV_TEMPLATE_TABLE *pTableBuiltIn,
+   _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin)
+{
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+
+   if (IsFieldTypeBasicData(pTableBuiltIn->fieldId)) {
+      if (pTableBuiltIn->fieldId == pTableFromBin->fieldId) {
+         rc = _MATCH;
+      }
+      else {
+         rc = _MIS_MATCH;
+      }
+   }
+   else { // field is a table
+      int idxSubBuiltin = pTableBuiltIn->fieldId &
+        FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
+      int idxSubFromBin = pTableFromBin->fieldId &
+        FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
+#if defined(_RECURSIVE_VERSION)
+      rc = compare2Tables(idxSubFromBin, idxSubBuiltin);
+#else
+      {
+      subTablesQueue[subTableWr].idxSubFromBin = idxSubFromBin;
+      subTablesQueue[subTableWr].idxSubBuiltin = idxSubBuiltin;
+      subTableWr = (subTableWr +1) % _SUBTABLES_MAX;
+      }
+#endif //#if defined(_RECURSIVE_VERSION)
+   }
+
+   return rc;
+}
+
+
+static _NV_TEMPLATE_PROCESS_RC compare2FieldStorageTypeAndSizes(
+   _NV_TEMPLATE_TABLE *pTableBuiltIn,
+   _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltIn, int idxFromBin)
+{
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+
+   if (_STORAGE_TYPE(pTableBuiltIn->fieldStorageType) ==
+      _STORAGE_TYPE(pTableFromBin->fieldStorageType)) {
+      if (SINGULAR == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
+         rc = _MATCH;
+      }
+      else if (ARRAY_1 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
+         if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
+            _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
+               pTableBuiltIn->fieldStorageType),
+            _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
+               pTableFromBin->fieldStorageType),
+            pTableBuiltIn->fieldStorageSize1,
+            pTableFromBin->fieldStorageSize1)) ) {
+
+            rc = _MATCH;
+         }
+      }
+      else if (ARRAY_2 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
+         if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
+             _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
+                pTableBuiltIn->fieldStorageType),
+             _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
+                pTableFromBin->fieldStorageType),
+             pTableBuiltIn->fieldStorageSize1,
+             pTableFromBin->fieldStorageSize1)) &&
+            (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
+             _STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2,
+                pTableBuiltIn->fieldStorageType),
+                _STORAGE_SIZE2(pTableFromBin->fieldStorageSize2,
+                pTableFromBin->fieldStorageType),
+                pTableBuiltIn->fieldStorageSize2,
+                pTableFromBin->fieldStorageSize2)) ) {
+                rc = _MATCH;
+         }
+      }
+      else if (ARRAY_3 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
+         if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
+             _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
+                pTableBuiltIn->fieldStorageType),
+             _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
+                pTableFromBin->fieldStorageType),
+             pTableBuiltIn->fieldStorageSize1,
+             pTableFromBin->fieldStorageSize1)) &&
+             (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
+                _STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2,
+                   pTableBuiltIn->fieldStorageType),
+                _STORAGE_SIZE2(pTableFromBin->fieldStorageSize2,
+                   pTableFromBin->fieldStorageType),
+                pTableBuiltIn->fieldStorageSize2,
+                pTableFromBin->fieldStorageSize2)) &&
+             (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
+                _STORAGE_SIZE3(pTableBuiltIn->fieldStorageSize3,
+                   pTableBuiltIn->fieldStorageType),
+                _STORAGE_SIZE3(pTableFromBin->fieldStorageSize3,
+                   pTableFromBin->fieldStorageType),
+                pTableBuiltIn->fieldStorageSize3,
+                pTableFromBin->fieldStorageSize3)) ) {
+                rc = _MATCH;
+         }
+      }
+   }
+   else {
+      rc = _MIS_MATCH;
+   }
+   return rc;
+}
+
+static _NV_TEMPLATE_PROCESS_RC compare2StorageSize(int idxBuiltIn,
+   int idxFromBin, int sizeBuiltIn,
+   int sizeFromBin, tANI_U8 sizeBuiltInLowByte, tANI_U8 sizeFromBinLowByte)
+{
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+
+   if (IsFieldSizeInt(sizeBuiltInLowByte) &&
+         IsFieldSizeInt(sizeFromBinLowByte)) {
+      if (sizeBuiltIn == sizeFromBin) {
+         rc = _MATCH;
+      }
+      else {
+         rc = _MIS_MATCH;
+      }
+   }
+   else if (!IsFieldSizeInt(sizeBuiltInLowByte) &&
+              !IsFieldSizeInt(sizeFromBinLowByte)) {
+        // enums should have been compared when enum streams are parsed
+        // The implication is that the enum streams should go before tables'
+      rc = enumMetaDataFromBin[idxFromBin].match;
+   }
+   else {
+      rc = _MIS_MATCH;
+   }
+
+   return rc;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ *
+ * Parse one enum template stream in nv.bin
+ */
+static _NV_TEMPLATE_PROCESS_RC processNvTemplateEnum(_NV_STREAM_BUF *pStream,
+   int len)
+{
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+   char enumStr[_ENUM_NAME_LEN + 1];
+    //_NV_TEMPLATE_ENUM *pEnum;
+   int enumIdx;
+
+    // construct the enum template in the NvEnumsFromBin
+   memset((void*)enumStr, '\0', (size_t) (_ENUM_NAME_LEN + 1));
+   enumIdx = constructATemplateEnum(pStream, len, enumStr);
+
+    // Compare the enum template
+    // also record compare results for later use in the table
+    // templates parsing where
+    // the fields may be indexed by enums
+    // if enumIdx ==0, didn't construct any entry,
+    // (or only the first entry)
+   if (enumIdx) {
+      compareEnumWithBuiltin(enumStr, enumIdx);
+   }
+
+   return rc;
+}
+
+static void compareEnumWithBuiltin(char *enumStr, int enumIdxFromBin)
+{
+   int i;
+   int enumIdxBuiltin = 0;
+   _NV_TEMPLATE_ENUM (*pEnumBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn;
+   _ErrorCode errCode = _OK;
+
+   for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
+      if (nul == pEnumBuiltin[0][i].enumName[0]) {
+          break;
+      }
+      if (!strcmp(enumStr, pEnumBuiltin[0][i].enumName)) {
+          enumIdxBuiltin = pEnumBuiltin[0][i].enumValue;
+          break;
+      }
+   }
+   if (!enumIdxBuiltin) {
+      errCode = _ENUM_NOT_FOUND_IN_BUILT_IN;
+      return;
+   }
+   else {
+      compare2EnumEntriesAndCopy(enumIdxFromBin, enumIdxBuiltin);
+   }
+
+//_error:
+   if (_OK != errCode) {
+      //printf("Error %d\n", errCode);
+   }
+
+   return;
+}
+
+static _NV_TEMPLATE_PROCESS_RC compare2EnumEntriesAndCopy(int idxFromBin,
+   int idxBuiltin)
+{
+   int i,j;
+   _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
+   _NV_TEMPLATE_ENUM (*enumsFromBin)[ENUM_ENTRIES_MAX] = NvEnumsFromBin;
+   _NV_TEMPLATE_ENUM (*enumsBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn;
+
+    // need to go through all enums
+   for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
+       // end conditions: either both reach the end (match),
+       // or one of them reaching the end (mismatch)
+      if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) ||
+          (nul == enumsFromBin[idxFromBin][i].enumName[0])) {
+          if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) &&
+              (nul == enumsFromBin[idxFromBin][i].enumName[0])) {
+                // fully matched
+              rc = _MATCH;
+              break;
+          }
+          else {
+              rc = _MIS_MATCH;
+              for (j = 0; j < ENUM_ENTRIES_MAX; j++) {
+                  if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) {
+                      break;
+                  }
+                  if (!strcmp((const char*)enumsFromBin[idxFromBin][i].enumName,
+                       (const char*)enumsBuiltin[idxBuiltin][j].enumName)) {
+                      enumsFromBin[idxFromBin][i].enumValuePeer =
+                             enumsBuiltin[idxBuiltin][j].enumValue;
+                      break;
+                  }
+              }
+              break;
+          }
+      }
+      else {
+          if (!strcmp(enumsBuiltin[idxBuiltin][i].enumName,
+                enumsFromBin[idxFromBin][i].enumName)) {
+                // copy builtIn enum value to fromBin
+              enumsFromBin[idxFromBin][i].enumValuePeer =
+                 enumsBuiltin[idxBuiltin][i].enumValue;
+          }
+          else {
+              // mismatch, but still loop through the whole enum list
+              // for the "ahead" and "behind" scenarios
+              rc = _MIS_MATCH;
+              for (j = 0; j < ENUM_ENTRIES_MAX; j++) {
+                 if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) {
+                     break;
+                 }
+                 if (!strcmp(enumsFromBin[idxFromBin][i].enumName,
+                        enumsBuiltin[idxBuiltin][j].enumName)) {
+                     enumsFromBin[idxFromBin][i].enumValuePeer =
+                        enumsBuiltin[idxBuiltin][j].enumValue;
+                     break;
+                 }
+              }
+         }
+      }
+   }
+
+   // record match or mismatch for later data parsing use
+   enumMetaDataFromBin[idxFromBin].match = rc;
+
+   // all done
+   return rc;
+}
+
+static int constructATemplateEnum(_NV_STREAM_BUF *pStream, int len,
+   char *enumStr)
+{
+    int pos = 0;
+    _NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX];
+    int enumIdx = 0;
+    int i;
+    int entryIdx;
+    _ErrorCode errCode = _OK;
+
+    enumIdx = (pStream[_NV_BIN_STREAM_ENUM_ID_BYTE] &
+       FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+    pEnum = NvEnumsFromBin;
+
+    // find its string name
+    // the logic:
+    // since the nv.bin doesn't encode the enum string name in the actual enum
+    // stream, only the first "enum of all enums"
+    //    has the names of all enums.
+    if (IsIdxEnumOfAllEnums(enumIdx)) {
+    }
+    else {
+        for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
+            if (nul == pEnum[0][i].enumName[0]) {
+                break;
+            }
+            if (pEnum[0][i].enumValue == enumIdx) {
+                strlcpy(enumStr, pEnum[0][i].enumName,(_ENUM_NAME_LEN + 1));
+                break;
+            }
+        }
+        if (ENUM_ENTRIES_MAX == i) {
+            // without a string name, don't know what to do with the enum indexed
+            errCode = _ENUM_NOT_FOUND_IN_BUILT_IN;
+            goto _error;
+        }
+    }
+
+    // Found the enum string name, now parsing decision time ...
+    // Is the entry already populated?
+    if (nul != pEnum[enumIdx][0].enumName[0]) {  // there is data in that entry
+        // TBD:
+        // the logic here depends on how we support "parsing data based on the
+        // latest template".
+        // one way is to overwrite the template, so the subsequent parsing will
+        // be based on the "latest".
+        // the second way is to "append" the template, and the parsing should
+        // always be based on the "last" of the same name
+        // for simplicity, support the first approach for now.
+        //
+        // the logic:
+        // based on the parsing control (bitmap), we may proceed on overwriting
+        // enums with blind faith that the writing logic is correct,
+        // or ignore the appended.
+        //
+    }
+
+    // overwrite entry, enumIdx
+    pos = _ENUM_START_POS;
+    entryIdx = 0;
+    while (pos < len) {
+        if (!(pos <= (len - _ENUM_MIN_LEN))) {
+            // error condition
+            errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR;
+            break;
+        }
+
+        // populate the entry
+        memset(pEnum[enumIdx][entryIdx].enumName, '\0',
+           (size_t) (_ENUM_NAME_LEN +1));
+        memset(pEnum[enumIdx][entryIdx].enumFullName, '\0',
+           (size_t) (_ENUM_FULL_NAME_LEN +1));
+        pEnum[enumIdx][entryIdx].enumName[0] = pStream[pos++];
+        pEnum[enumIdx][entryIdx].enumName[1] = pStream[pos++];
+        pEnum[enumIdx][entryIdx].enumValue   = pStream[pos++];
+        entryIdx++;
+    }
+
+_error:
+    if (_OK != errCode) {
+        //printf("Error %d\n", errCode);
+    }
+
+    // all done
+    return enumIdx;
+}
+
+/* -----------------------------------------------------------------------------
+ *
+ * Process data stream
+ * The purpose is to copy nv.bin data into built in NV data structure.
+ * This is the parser function.
+ *
+ * Next phase:
+ * With NV data in the s/w module data structure, nv.bin conforming
+ * to the new format can be generated. That is the nv.bin generation logic.)
+ *
+ * Data stream has the following format
+ *
+ * delimiter|streamHeader|tableID|data....|CRC|delimiter
+ * Note
+ *    1. delimiters are not present in the stream data, pStream.
+ *    2. nested tables do NOT have table IDs with them.
+ *
+ */
+// NV data, per built in templates
+// Recursive table parsing, which is naturally depth-first
+// If iterative, a bit hard to implement
+
+static void parseSubDataTable4Size(int tableIdx, int numElem)
+{
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+   int idxSubTable;
+   int i;
+   int numSubElem = 0, idx=0;
+
+   // "apply" template to data -- parsing the actual NV data,
+   //     so far we have been parsing and building templates
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+      if (nul == pTable[tableIdx][i].fieldName[0]) {
+          // data parsing done for this stream
+          break;
+      }
+      if (IsFieldTypeBasicData(pTable[tableIdx][i].fieldId)) {
+          getBasicDataSize(&(pTable[tableIdx][i]));
+      }
+      else {
+         // number of element
+         idx =
+            _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType);
+         numSubElem = numElemBasedOnStorageType[idx](
+                         &(pTable[tableIdx][i]), 1);
+         // get size of the sub-table
+         idxSubTable = (pTable[tableIdx][i].fieldId &
+            FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+         // recursive calls for the total size of the subtable
+         parseSubDataTable4Size(idxSubTable, numSubElem);
+      }
+   }
+   // update subTableSize for the number of elements
+   subTableSize *= numElem;
+
+   return;
+}
+
+static void copyDataToBuiltInFromBin(int tableIdx,int fieldId,
+    _NV_STREAM_BUF *pStream, int *pos, int addOffset, int tableBaseOffset)
+{
+   int i,j,k,storageType;
+   int idx=0, size1=0, size2=0, size3=0;
+   int enumIdx1=0, enumIdx2=0, enumIdx3=0, sizeOneElem=0;
+   int isFirstFieldEnum=0,isSecondFieldEnum=0,isThirdFieldEnum=0;
+   int index,index1,index2;
+   int dindex,dindex1,dindex2,totalSize;
+   int offset=0,sizeBuiltIn,tableIdxBuiltIn,fieldIdBuiltIn;
+   int idxBuiltIn=0, size1BuiltIn=0, size2BuiltIn=0, size3BuiltIn=0;
+   int size1Bin=0, size2Bin=0, size3Bin=0, numElemBuiltIn;
+   int sizeOneElemBuiltIn=0, field;
+   unsigned char *ptr, *dptr;
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+   _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
+
+   storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
+   field = pTable[tableIdx][fieldId].fieldId;
+   sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
+                    FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
+   sizeBuiltIn = getBuiltInFieldCount(tableIdx,
+                    pTable[tableIdx][fieldId].fieldName,
+                    &tableIdxBuiltIn,&fieldIdBuiltIn,&numElemBuiltIn);
+
+   field = pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldId;
+   sizeOneElemBuiltIn = sizeOneElemBasedOnFieldIdBasicDataType[field &
+                          FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
+
+   if (storageType == SINGULAR ) {
+      ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
+      dptr = (unsigned char *)&pStream[*pos];
+
+      if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
+         idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
+         size1Bin = numElemBasedOnStorageType[idx](
+                       &(pTable[tableIdx][fieldId]), 1);
+         field = pTable[tableIdx][fieldId].fieldId;
+         sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
+                         FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
+
+         idxBuiltIn = _STORAGE_TYPE(
+           pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+         size1BuiltIn = numElemBasedOnStorageType[idx](
+                      &(pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn]), 0);
+
+         size1 = size1Bin;
+         if (size1 > size1BuiltIn) {
+            size1 = size1BuiltIn;
+         }
+      }
+      totalSize = size1 * sizeOneElem;
+
+      offset = 0;
+      for (i = 0; i < size1; i++) {
+         memcpy(&ptr[offset], &dptr[offset], sizeOneElem);
+         offset = offset + sizeOneElem;
+      }
+
+      *pos = *pos + (size1Bin * sizeOneElem);
+   }
+   else {
+      if (ARRAY_1 == storageType) {
+         ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
+         dptr = (unsigned char *)&pStream[*pos];
+
+         idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+                 pTable[tableIdx][fieldId].fieldStorageType);
+         size1Bin = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
+
+         idx = _STORAGE_SIZE1(
+               pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
+               pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+         size1BuiltIn = getNumElemOutOfStorageSize(idx,
+            pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0);
+
+         size1 = size1Bin;
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
+            enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+               FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+            isFirstFieldEnum = 1;
+         }
+         else {
+            isFirstFieldEnum = 0;
+            if (size1 > size1BuiltIn) {
+               size1 = size1BuiltIn;
+            }
+         }
+
+         offset = 0;
+         for (i = 0; i < size1; i++) {
+            if (isFirstFieldEnum) {
+               if (NvEnumsFromBin[enumIdx1][i].enumValuePeer != 0xFF) {
+                  index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
+                  dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
+
+                  index = index * sizeOneElem;
+                  dindex = dindex * sizeOneElem;
+
+                  memcpy(&ptr[index], &dptr[dindex], sizeOneElem);
+               }
+            }
+            else {
+               memcpy(&ptr[offset], &dptr[offset], sizeOneElem);
+               offset = offset + sizeOneElem;
+            }
+         }
+
+         *pos = *pos + (size1Bin * sizeOneElem);
+      }
+      else if (ARRAY_2 == storageType) {
+         ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
+         dptr = (unsigned char *)&pStream[*pos];
+
+         idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+                  pTable[tableIdx][fieldId].fieldStorageType);
+         size1Bin = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
+
+         idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
+                  pTable[tableIdx][fieldId].fieldStorageType);
+
+         size2Bin = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize2, 1);
+
+         idx = _STORAGE_SIZE1(
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+         size1BuiltIn = getNumElemOutOfStorageSize(idx,
+            pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0);
+
+         idx = _STORAGE_SIZE2(
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+         size2BuiltIn = getNumElemOutOfStorageSize(idx,
+            pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, 0);
+
+         size1 = size1Bin;
+         size2 = size2Bin;
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
+            enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+               FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+            isFirstFieldEnum = 1;
+         }
+         else {
+            isFirstFieldEnum = 0;
+            if (size1 > size1BuiltIn) {
+               size1 = size1BuiltIn;
+            }
+         }
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
+            enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
+               FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+            isSecondFieldEnum = 1;
+         }
+         else {
+            isSecondFieldEnum = 0;
+            if (size2 > size2BuiltIn) {
+               size2 = size2BuiltIn;
+            }
+         }
+
+         offset = 0;
+
+         for (i = 0; i < size1; i++) {
+            if (isFirstFieldEnum) {
+              if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) {
+                 continue;
+              }
+
+              index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
+              dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
+            }
+            else {
+               index = dindex = i;
+            }
+
+            for (j = 0; j < size2; j++) {
+              if (isSecondFieldEnum) {
+                 if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
+                    continue;
+                 }
+
+                 index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer;
+                 dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue;
+              }
+              else {
+                 index1 = dindex1 = j;
+              }
+
+              memcpy(&ptr[(index1 + index * size2BuiltIn)*sizeOneElem],
+                   &dptr[(dindex1+dindex*size2Bin)*sizeOneElem], sizeOneElem);
+              offset = offset + sizeOneElem;
+            }
+         }
+
+         *pos = *pos + size2Bin * size1Bin * sizeOneElem;
+      }
+      else if (ARRAY_3 == storageType) {
+         ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
+         dptr = (unsigned char *)&pStream[*pos];
+
+         idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+                  pTable[tableIdx][fieldId].fieldStorageType);
+         size1Bin = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
+
+         idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
+                  pTable[tableIdx][fieldId].fieldStorageType);
+         size2Bin = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize2, 1);
+
+         idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
+                  pTable[tableIdx][fieldId].fieldStorageType);
+         size3Bin = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize3, 1);
+
+         idx = _STORAGE_SIZE1(
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+         size1BuiltIn = getNumElemOutOfStorageSize(idx,
+            pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
+            0);
+
+         idx = _STORAGE_SIZE2(
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+         size2BuiltIn = getNumElemOutOfStorageSize(idx,
+            pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
+            0);
+
+         idx = _STORAGE_SIZE3(
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
+             pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+         size3BuiltIn = getNumElemOutOfStorageSize(idx,
+            pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
+            0);
+
+         size1 = size1Bin;
+         size2 = size2Bin;
+         size3 = size3Bin;
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
+            enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+               FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+            isFirstFieldEnum = 1;
+         }
+         else {
+            isFirstFieldEnum = 0;
+            if (size1 > size1BuiltIn) {
+               size1 = size1BuiltIn;
+            }
+         }
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
+            enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
+               FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+            isSecondFieldEnum = 1;
+         }
+         else {
+            isSecondFieldEnum = 0;
+            if (size2 > size2BuiltIn) {
+               size2 = size2BuiltIn;
+            }
+         }
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
+            enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
+               FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+            isThirdFieldEnum = 1;
+         }
+         else {
+            isThirdFieldEnum = 0;
+            if (size3 > size3BuiltIn) {
+               size3 = size3BuiltIn;
+            }
+         }
+
+         offset = 0;
+         for (i = 0; i < size1; i++) {
+            if (isFirstFieldEnum) {
+              if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) {
+                 continue;
+              }
+
+              index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
+              dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
+            }
+            else {
+              index = dindex = i;
+            }
+
+            for (j = 0; j < size2; j++) {
+              if (isSecondFieldEnum) {
+                 if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
+                    continue;
+                 }
+
+                 index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer;
+                 dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue;
+              }
+              else {
+                 index1 = dindex1 = j;
+              }
+
+              for (k = 0; k < size3; k++) {
+                 if (isThirdFieldEnum) {
+                    if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
+                       continue;
+                    }
+
+                    index2 = NvEnumsFromBin[enumIdx3][k].enumValuePeer;
+                    dindex2 = NvEnumsFromBin[enumIdx3][k].enumValue;
+                 }
+                 else {
+                    index2 = dindex2 = k;
+                 }
+
+                 memcpy(&ptr[(index2 + (index1 * size2BuiltIn) +
+                          (index * size3BuiltIn * size2BuiltIn)) * sizeOneElem],
+                        &dptr[(dindex2 + (dindex1 * size2Bin) +
+                          (dindex * size3Bin * size2Bin))*sizeOneElem],
+                        sizeOneElem);
+
+                 offset = offset + sizeOneElem;
+              }
+            }
+         }
+
+         *pos = *pos + size1Bin * size2Bin * size3Bin * sizeOneElem;
+      }
+      else {
+      }
+   }
+}
+
+// search NvTablesBuiltIn for the same string named table, and its idx
+static int getBuiltInFieldCount (int tableIdxBin, char *tableNameFromBin,
+   int *tblIdBuiltIn, int *fieldIdBuitIn, int *numElements)
+{
+   int i,idx,numElem,tableIdxBuiltin=0,fieldCnt;
+   _NV_TEMPLATE_TABLE (*pTableBin)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
+   int found=0, fieldIndex = 0;
+
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+       if (nul == pTableBin[0][i].fieldName[0]) {
+           break;
+       }
+
+       if ((pTableBin[0][i].fieldId &
+            FIELD_ID_TABLE_OR_ENUM_IDX_MASK) == tableIdxBin) {
+           found = 1;
+           break;
+       }
+   }
+
+   if (!found) {
+      return -1;
+   }
+
+   //fieldName index got from tableId from Bin
+   fieldIndex = i;
+   found = 0;
+
+   for (i=0;i<TABLE_ENTRIES_MAX;i++) {
+      if (nul == pTable[0][i].fieldName[0]) {
+           break;
+       }
+
+       if (!strcmp((const char*)pTableBin[0][fieldIndex].fieldName,
+          (const char*)pTable[0][i].fieldName)) {
+          found = 1;
+          break;
+       }
+   }
+
+   if (!found) {
+      return -1;
+   }
+
+   //found tableId of builtIn
+   tableIdxBuiltin = *tblIdBuiltIn =
+                 (pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+   found = 0;
+
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+      if (nul == pTable[tableIdxBuiltin][i].fieldName[0]) {
+         break;
+      }
+
+      if (!strcmp((const char*)tableNameFromBin,
+         (const char*)pTable[tableIdxBuiltin][i].fieldName)) {
+         found = 1;
+         break;
+      }
+   }
+
+   if (!found) {
+      return -1;
+   }
+
+   *fieldIdBuitIn = i;
+
+   idx = _STORAGE_TYPE(pTable[tableIdxBuiltin][i].fieldStorageType);
+   numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdxBuiltin][i]), 0);
+
+   fieldSize = 0;
+   fieldCnt = getFieldCount (tableIdxBuiltin, i, numElem, 0);
+
+   *numElements = numElem;
+
+   return fieldCnt;
+}
+
+static int getFieldCount(int tableIdx, int fieldId, int numElem, int nvBin)
+{
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX];
+   int idxSubTable;
+   int i, j, storageType, field;
+   int numSubElem=0, idx =0, size1=0, size2=0, size3=0, sizeOneElem=0;
+   int enumIdx1=0, enumIdx2=0, enumIdx3=0;
+
+   if ( nvBin ) {
+      pTable = NvTablesFromBin;
+   }
+   else {
+      pTable = NvTablesBuiltIn;
+   }
+
+   storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
+
+   if (SINGULAR == storageType) {
+      if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
+         idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
+         size1 = numElemBasedOnStorageType[idx](&(pTable[tableIdx][fieldId]),
+                   nvBin);
+      }
+      else {
+      }
+   }
+   else {
+      if (ARRAY_1 == storageType) {
+         idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+               pTable[tableIdx][fieldId].fieldStorageType);
+         size1 = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
+            enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+                         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+         }
+      }
+      else if (ARRAY_2 == storageType) {
+         idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+               pTable[tableIdx][fieldId].fieldStorageType);
+         size1 = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
+
+         idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
+               pTable[tableIdx][fieldId].fieldStorageType);
+
+         size2 = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize2,nvBin);
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
+            enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+                         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+         }
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
+            enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
+                         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+         }
+      }
+      else if (ARRAY_3 == storageType) {
+         idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+               pTable[tableIdx][fieldId].fieldStorageType);
+         size1 = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
+
+         idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
+               pTable[tableIdx][fieldId].fieldStorageType);
+         size2 = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize2,nvBin);
+
+         idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
+               pTable[tableIdx][fieldId].fieldStorageType);
+         size3 = getNumElemOutOfStorageSize(idx,
+                 pTable[tableIdx][fieldId].fieldStorageSize3,nvBin);
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
+            enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+                         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+         }
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
+            enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
+                         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+         }
+
+         if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
+            enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
+                         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+         }
+      }
+      else {
+      }
+   }
+
+   if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
+       field = pTable[tableIdx][fieldId].fieldId;
+       sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
+                       FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
+       if ( size3 ) {
+          fieldSize = fieldSize + size3  * size2 * size1 * sizeOneElem;
+       }
+       else if ( size2 ) {
+          fieldSize = fieldSize + size2 * size1 * sizeOneElem;
+       }
+       else if ( size1 ) {
+          fieldSize = fieldSize + size1 * sizeOneElem;
+       }
+       else {
+       }
+   }
+   else {
+      idxSubTable = (pTable[tableIdx][fieldId].fieldId &
+            FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+
+      for (j=0; j<numElem; j++) {
+         for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+            if (nul == pTable[idxSubTable][i].fieldName[0]) {
+             // data parsing done for this stream
+             break;
+            }
+
+            idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType);
+            numSubElem = numElemBasedOnStorageType[idx](
+                            &(pTable[idxSubTable][i]),nvBin);
+
+            getFieldCount(idxSubTable, i, numSubElem, nvBin);
+         }
+      }
+   }
+
+   return fieldSize;
+}
+
+static void parseSubDataTableAndCopy(int tableIdx, int numElem, int numElem2,
+   int numElem3, int fieldId, _NV_STREAM_BUF *pStream, int *pos, int addOffset,
+   int tableBaseOffset, int localAddOffset)
+{
+   int idxSubTable, i, j, l, m, idx1, storageType, fieldCount=0;
+   int size1BuiltIn, size2BuiltIn, size3BuiltIn;
+   int tableIdxBuiltIn, fieldIdBuiltIn, numElemBuiltIn, incAddOffset=0;
+   int totalOffset=0, enumIdx, size1Bin, size2Bin, size3Bin;
+   int numSubElem, numSubElem2, numSubElem3, sizeBuiltIn=0, idx=0;
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+   _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
+
+   // "apply" template to data -- parsing the actual NV data,
+   //     so far we have been parsing and building templates
+   if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
+      // First Entry, same as off addOffset just increment localOffset
+      if (pTable[tableIdx][fieldId].offset == addOffset) {
+         totalOffset = localAddOffset + pTable[tableIdx][fieldId].offset;
+      }
+      else {
+         // Multiple  Entry next index array, addOffset and localOffset
+         totalOffset = localAddOffset + pTable[tableIdx][fieldId].offset +
+                       addOffset;
+      }
+      copyDataToBuiltInFromBin(tableIdx, fieldId, pStream, pos, totalOffset,
+         tableBaseOffset);
+   }
+   else {
+      // number of element
+      // get size of the sub-table
+      idxSubTable = (pTable[tableIdx][fieldId].fieldId &
+                      FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+
+      fieldSize = 0;
+      sizeBuiltIn = getBuiltInFieldCount(tableIdx,
+                      pTable[tableIdx][fieldId].fieldName,
+                      &tableIdxBuiltIn, &fieldIdBuiltIn, &numElemBuiltIn);
+      incAddOffset = 0;
+
+      if (numElemBuiltIn) {
+         incAddOffset = sizeBuiltIn/numElemBuiltIn;
+      }
+
+      storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
+
+      fieldSize = 0;
+      fieldCount = getFieldCount(tableIdx, fieldId, numElem, 1);
+
+      idx1 = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
+               pTable[tableIdx][fieldId].fieldStorageType);
+      size1Bin = getNumElemOutOfStorageSize(idx1,
+                 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
+
+      for (l=0; l < numElem3; l++) {
+         if (storageType == ARRAY_3) {
+            idx1 = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
+                      pTable[tableIdx][fieldId].fieldStorageType);
+
+            size3Bin = getNumElemOutOfStorageSize(idx1,
+                    pTable[tableIdx][fieldId].fieldStorageSize3, 1);
+
+            fieldSize = 0;
+            getBuiltInFieldCount(tableIdx,
+              pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
+              &fieldIdBuiltIn, &numElemBuiltIn);
+
+            idx1 = _STORAGE_SIZE3(
+              pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
+              pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+            size3BuiltIn = getNumElemOutOfStorageSize(idx1,
+              pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
+              0);
+
+            if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
+               enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
+                  FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+               if (NvEnumsFromBin[enumIdx][l].enumValuePeer == 0xFF) {
+                  *pos = *pos + (fieldCount/size1Bin) * numElem * numElem2;
+                  continue;
+               }
+            }
+            else {
+               if ((l+1) > size3BuiltIn) {
+                  *pos = *pos + (fieldCount/size1Bin) * numElem * numElem2;
+                  continue;
+               }
+            }
+         }
+         for (m=0; m < numElem2; m++) {
+            if (storageType == ARRAY_2) {
+               idx1 = _STORAGE_SIZE2(
+                         pTable[tableIdx][fieldId].fieldStorageSize2,
+                         pTable[tableIdx][fieldId].fieldStorageType);
+               size2Bin = getNumElemOutOfStorageSize(idx1,
+                    pTable[tableIdx][fieldId].fieldStorageSize2, 1);
+
+               fieldSize = 0;
+               getBuiltInFieldCount(tableIdx,
+                 pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
+                 &fieldIdBuiltIn, &numElemBuiltIn);
+
+               idx1 = _STORAGE_SIZE2(
+               pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
+               pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+               size2BuiltIn = getNumElemOutOfStorageSize(idx1,
+               pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
+               0);
+
+               if (!IsFieldSizeInt(
+                  pTable[tableIdx][fieldId].fieldStorageSize2)) {
+                  enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
+                     FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+                  if (NvEnumsFromBin[enumIdx][m].enumValuePeer == 0xFF) {
+                     *pos = *pos + (fieldCount/size1Bin) * numElem;
+                     continue;
+                  }
+               }
+               else {
+                  if ((m+1) > size2BuiltIn) {
+                     *pos = *pos + (fieldCount/size1Bin) * numElem;
+                     continue;
+                  }
+               }
+            }
+            for (j=0; j < numElem; j++) {
+               if (storageType == ARRAY_1) {
+                  fieldSize = 0;
+                  getBuiltInFieldCount(tableIdx,
+                  pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
+                  &fieldIdBuiltIn, &numElemBuiltIn);
+
+                  idx1 = _STORAGE_SIZE1(
+                  pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
+                  pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
+
+                  size1BuiltIn = getNumElemOutOfStorageSize(idx1,
+                  pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
+                  0);
+
+                  if (!IsFieldSizeInt(
+                        pTable[tableIdx][fieldId].fieldStorageSize1)) {
+                     enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
+                        FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+                     if (NvEnumsFromBin[enumIdx][j].enumValuePeer == 0xFF) {
+                        *pos = *pos + (fieldCount/size1Bin);
+                        continue;
+                     }
+                  }
+                  else {
+                     if ((j+1) > size1BuiltIn) {
+                        *pos = *pos + (fieldCount/size1Bin);
+                        continue;
+                     }
+                  }
+               }
+
+               for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+                  if (nul == pTable[idxSubTable][i].fieldName[0]) {
+                   // data parsing done for this stream
+                      break;
+                  }
+
+                  idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType);
+                  numSubElem = numElemBasedOnStorageType[idx](
+                     &(pTable[idxSubTable][i]),1);
+                  numSubElem2 = numSubElem3 = 1;
+
+                  if (idx == ARRAY_1) {
+                     idx1 = _STORAGE_SIZE1(
+                        pTable[idxSubTable][i].fieldStorageSize1,
+                        pTable[idxSubTable][i].fieldStorageType);
+                     numSubElem = getNumElemOutOfStorageSize(idx1,
+                       pTable[idxSubTable][i].fieldStorageSize1, 1);
+                  }
+                  else if (idx == ARRAY_2) {
+                     idx1 = _STORAGE_SIZE1(
+                        pTable[idxSubTable][i].fieldStorageSize1,
+                        pTable[idxSubTable][i].fieldStorageType);
+                     numSubElem = getNumElemOutOfStorageSize(idx1,
+                       pTable[idxSubTable][i].fieldStorageSize1, 1);
+
+                     idx1 = _STORAGE_SIZE2(
+                        pTable[idxSubTable][i].fieldStorageSize2,
+                        pTable[idxSubTable][i].fieldStorageType);
+                     numSubElem2 = getNumElemOutOfStorageSize(idx1,
+                       pTable[idxSubTable][i].fieldStorageSize2, 1);
+                  }
+                  else if (idx == ARRAY_3) {
+                     idx1 = _STORAGE_SIZE1(
+                        pTable[idxSubTable][i].fieldStorageSize1,
+                        pTable[idxSubTable][i].fieldStorageType);
+                     numSubElem = getNumElemOutOfStorageSize(idx1,
+                       pTable[idxSubTable][i].fieldStorageSize1, 1);
+
+                     idx1 = _STORAGE_SIZE2(
+                        pTable[idxSubTable][i].fieldStorageSize2,
+                        pTable[idxSubTable][i].fieldStorageType);
+                     numSubElem2 = getNumElemOutOfStorageSize(idx1,
+                       pTable[idxSubTable][i].fieldStorageSize2, 1);
+
+                     idx1 = _STORAGE_SIZE3(
+                        pTable[idxSubTable][i].fieldStorageSize3,
+                        pTable[idxSubTable][i].fieldStorageType);
+                     numSubElem3 = getNumElemOutOfStorageSize(idx1,
+                       pTable[idxSubTable][i].fieldStorageSize3, 1);
+                  }
+
+                  if (_OFFSET_NOT_SET != pTable[idxSubTable][i].offset) {
+                     if ( pTable[tableIdx][fieldId].offset == addOffset ) {
+                        parseSubDataTableAndCopy(idxSubTable, numSubElem,
+                           numSubElem2, numSubElem3, i, pStream, pos,
+                           addOffset, tableBaseOffset, localAddOffset);
+                     }
+                     else {
+                  // NOT the first Entry in the table..
+                        if ( !pTable[tableIdx][fieldId].offset ) {
+                           parseSubDataTableAndCopy(idxSubTable, numSubElem,
+                             numSubElem2, numSubElem3, i, pStream, pos,
+                             addOffset, tableBaseOffset, localAddOffset);
+                        }
+                        else {
+                           //First Entry in the the table..
+                           //(Sending parent offset..)
+                           parseSubDataTableAndCopy(idxSubTable, numSubElem,
+                              numSubElem2, numSubElem3, i, pStream, pos,
+                              addOffset, tableBaseOffset,
+                              pTable[tableIdx][fieldId].offset);
+                        }
+                     }
+                  }
+                  else {
+                     fieldSize = 0;
+                     fieldCount = getFieldCount(idxSubTable, i, numSubElem, 1);
+                     *pos += fieldCount;
+                  }
+              }
+
+              localAddOffset = localAddOffset + incAddOffset;
+           }
+        }
+     }
+  }
+
+  return;
+}
+
+static void processNvData(_NV_STREAM_BUF *pStream, int len)
+{
+   int tableIdx, pos, idx = 0, addOffset = 0, i;
+   int numElem = 0, additionalOffset = 0, tableBaseOffset = 0;
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+
+    // fetch the table template
+   pos = 0; // stream header byte is already checked, that's why we are here
+   pos += _NV_BIN_DATA_STREAM_TABLEID_BYTE;
+   tableIdx = (pStream[_NV_BIN_DATA_STREAM_TABLEID_BYTE] &
+       FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+   pos++;
+
+   // call the table parsing
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+      if (nul == pTable[0][i].fieldName[0]) {
+          break;
+      }
+      if (tableIdx == _TABLE_IDX(pTable[0][i].fieldId)) {
+         // Table base offset, stored in the "table of all tables" (index 0),
+         // will be added to
+         // fields relative offset in all tables.
+         tableBaseOffset = pTable[0][i].offset;
+
+         idx = _STORAGE_TYPE(pTable[0][i].fieldStorageType);
+
+         // number of element
+         numElem = numElemBasedOnStorageType[idx](&(pTable[0][i]),1);
+
+         // recursive calls for the total size of the subtable, which may
+         // contain nested tables
+         subTableSize = 0;
+         parseSubDataTable4Size(tableIdx, numElem);
+
+         // additional offset for EACH subsequent table element
+         additionalOffset = subTableSize/numElem;
+
+         break;
+      }
+   }
+
+   if (numElem) {
+      for (i = 0; i < numElem; i++) {
+          addOffset = (i * additionalOffset);
+          parseDataTable_new(pStream, &pos, tableIdx, addOffset,
+             tableBaseOffset);
+      }
+   }
+
+   // the above recursive data table parser takes care of the nested tables
+   // all done
+   return;
+}
+
+static void parseDataTable_new(_NV_STREAM_BUF *pStream, int* pos, int tableIdx,
+   int addOffset, int tableBaseOffset)
+{
+   _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
+   int i, idx, fieldCount;
+   int numElem, numElem2, numElem3, storageType, idxSubTable;
+
+   // "apply" template to data -- parsing the actual NV data,
+   //     so far we have been parsing and building templates
+   for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
+      if (nul == pTable[tableIdx][i].fieldName[0]) {
+          // data parsing done for this stream
+          break;
+      }
+
+      // get size of the sub-table
+      idxSubTable = (pTable[tableIdx][i].fieldId &
+                             FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
+
+      idx = _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType);
+
+      numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdx][i]),1);
+
+      addOffset = pTable[tableIdx][i].offset;
+
+      fieldSize = 0;
+      fieldCount = getFieldCount(tableIdx, i, numElem, 1);
+
+      numElem2 = numElem3 = 1;
+
+      if (idx == ARRAY_1 ) {
+         storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
+                       pTable[tableIdx][i].fieldStorageType);
+         numElem = getNumElemOutOfStorageSize(storageType,
+                 pTable[tableIdx][i].fieldStorageSize1, 1);
+      }
+      else if (idx == ARRAY_2) {
+         storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
+                       pTable[tableIdx][i].fieldStorageType);
+
+         numElem = getNumElemOutOfStorageSize(storageType,
+                 pTable[tableIdx][i].fieldStorageSize1, 1);
+
+         storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2,
+                       pTable[tableIdx][i].fieldStorageType);
+
+         numElem2 = getNumElemOutOfStorageSize(storageType,
+                 pTable[tableIdx][i].fieldStorageSize2, 1);
+      }
+      else if (idx == ARRAY_3) {
+         storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
+                       pTable[tableIdx][i].fieldStorageType);
+
+         numElem = getNumElemOutOfStorageSize(storageType,
+                 pTable[tableIdx][i].fieldStorageSize1, 1);
+
+         storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2,
+                       pTable[tableIdx][i].fieldStorageType);
+
+         numElem2 = getNumElemOutOfStorageSize(storageType,
+                 pTable[tableIdx][i].fieldStorageSize2, 1);
+
+         storageType = _STORAGE_SIZE3(pTable[tableIdx][i].fieldStorageSize3,
+                       pTable[tableIdx][i].fieldStorageType);
+
+         numElem3 = getNumElemOutOfStorageSize(storageType,
+                 pTable[tableIdx][i].fieldStorageSize3, 1);
+      }
+
+      if (_OFFSET_NOT_SET != pTable[tableIdx][i].offset) {
+         parseSubDataTableAndCopy(tableIdx, numElem, numElem2, numElem3, i,
+                 pStream, pos, addOffset, tableBaseOffset, 0);
+      }
+      else {
+         *pos += fieldCount;
+      }
+   }
+}
+
+static void getBasicDataSize(_NV_TEMPLATE_TABLE *pTableEntry)
+{
+   int numElem, sizeOneElem, totalSize;
+   int idx, idx1;
+
+   // number of element
+   idx = _STORAGE_TYPE(pTableEntry->fieldStorageType);
+   numElem = numElemBasedOnStorageType[idx](pTableEntry, 1);
+
+   // size of each element
+   idx1 = pTableEntry->fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
+   sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[idx1];
+
+   // total size in bytes
+   totalSize = numElem * sizeOneElem;
+
+   // all done, update global
+   subTableSize += totalSize;
+
+   return;
+}
+
+static int numElemSingular(_NV_TEMPLATE_TABLE *pTableEntry, int unused)
+{
+    return 1;
+}
+
+static int getNumElemOutOfStorageSize(int fieldStorageSize,
+   uint8 fieldStorageSizeLowByte, int nvBin)
+{
+   int ret = 0;
+   if (IsFieldSizeInt(fieldStorageSizeLowByte)) {
+       return fieldStorageSize;
+   }
+   else {
+      int maxEnumVal=0, i;
+      _NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX];
+      int enumIdx = ((fieldStorageSizeLowByte &
+         FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
+
+      if (nvBin) {
+         pEnum = NvEnumsFromBin;
+      }
+      else {
+         pEnum = NvEnumsBuiltIn;
+      }
+
+      for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
+          if (nul == pEnum[enumIdx][i].enumName[0]) {
+              if ( i == 0 ) {
+                 maxEnumVal = 0;
+              }
+              else {
+                 maxEnumVal = pEnum[enumIdx][i-1].enumValue;
+              }
+              break;
+          }
+      }
+      ret = (maxEnumVal + 1);
+      return ret; // +1 to count for 0 to maxEnumVal
+   }
+}
+
+static int numElemArray1(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
+{
+   int fieldStorageSize = 0;
+
+   fieldStorageSize = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
+             pTableEntry->fieldStorageSize1, pTableEntry->fieldStorageType),
+             pTableEntry->fieldStorageSize1, nvBin);
+
+   return fieldStorageSize;
+}
+
+static int numElemArray2(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
+{
+   int fieldStorageSize1,fieldStorageSize2,fieldStorageSize;
+
+   fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
+                         pTableEntry->fieldStorageSize1,
+                         pTableEntry->fieldStorageType),
+                         pTableEntry->fieldStorageSize1, nvBin);
+
+   fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2(
+                        pTableEntry->fieldStorageSize2,
+                        pTableEntry->fieldStorageType),
+                        pTableEntry->fieldStorageSize2, nvBin);
+
+   fieldStorageSize = fieldStorageSize1 * fieldStorageSize2;
+
+   return fieldStorageSize;
+}
+
+static int numElemArray3(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
+{
+   int fieldStorageSize1,fieldStorageSize2,fieldStorageSize3,fieldStorageSize;
+
+   fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
+                         pTableEntry->fieldStorageSize1,
+                         pTableEntry->fieldStorageType),
+                         pTableEntry->fieldStorageSize1, nvBin);
+
+   fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2(
+                        pTableEntry->fieldStorageSize2,
+                        pTableEntry->fieldStorageType),
+                        pTableEntry->fieldStorageSize2, nvBin);
+
+   fieldStorageSize3 = getNumElemOutOfStorageSize(_STORAGE_SIZE3(
+                        pTableEntry->fieldStorageSize3,
+                        pTableEntry->fieldStorageType),
+                        pTableEntry->fieldStorageSize3, nvBin);
+
+   fieldStorageSize = fieldStorageSize1 * fieldStorageSize2 * fieldStorageSize3;
+
+   return fieldStorageSize;
+}
diff --git a/CORE/VOSS/src/wlan_nv_stream_read.c b/CORE/VOSS/src/wlan_nv_stream_read.c
new file mode 100755
index 0000000..bba4542
--- /dev/null
+++ b/CORE/VOSS/src/wlan_nv_stream_read.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+/*===========================================================================
+                       EDIT HISTORY FOR FILE
+
+  This section contains comments describing changes made to the module.
+  Notice that changes are listed in reverse chronological order.
+
+  $Header:$ $DateTime: $ $Author: $
+
+  when        who        what, where, why
+  --------    ---        --------------------------------------------------------
+  04/10/13    kumarpra   nv stream layer creation
+===========================================================================*/
+
+#include "wlan_nv_stream.h"
+
+_STREAM_BUF streamBuf;
+
+static tANI_U32 deCodeData(tANI_U8 *ipdata, tANI_U32 length, tANI_U8 *opdata,
+   tANI_U32 *currentIndex);
+
+/*----------------------------------------------------------------------------
+  \brief initReadStream() - stream Initialization
+  This function will initialize stream read
+  \param readBuf, length - ptr to read Buffer, number of bytes
+  \return success on init
+  \sa
+--------------------------------------------------------------------------*/
+_STREAM_RC initReadStream(tANI_U8 *readBuf, tANI_U32 length)
+{
+   _STREAM_RC rc = RC_SUCCESS;
+   streamBuf.currentIndex = 0;
+   streamBuf.totalLength = 0;
+   streamBuf.totalLength = length;
+   streamBuf.dataBuf = (_NV_STREAM_BUF *)&readBuf[0];
+   return rc;
+}
+
+/*----------------------------------------------------------------------------
+  \brief nextStream() - get next Stream in buffer
+  This function will provide next stream in the buffere initalized
+  \param readBuf, length - ptr to stream length, stream data
+  \return success when stream length is non-zero else error
+  \sa
+--------------------------------------------------------------------------*/
+
+_STREAM_RC nextStream(tANI_U32 *length, tANI_U8 *dataBuf)
+{
+   _STREAM_RC rc = RC_SUCCESS;
+
+   if (streamBuf.currentIndex >= streamBuf.totalLength)
+   {
+       *length = 0;
+   }
+   else
+   {
+       *length = deCodeData(&streamBuf.dataBuf[streamBuf.currentIndex],
+                    (streamBuf.totalLength - streamBuf.currentIndex), dataBuf,
+                    &streamBuf.currentIndex);
+   }
+
+   if (*length == 0)
+   {
+      rc = RC_FAIL;
+   }
+
+   return rc;
+}
+
+/*----------------------------------------------------------------------------
+  \brief decodeData() - decode the input data
+  This function will decode stream read
+  \param readBuf, length - ptr to input stream, length, output stream data,
+  \index pointer
+  \return success when stream length is non-zero else error
+  \sa
+--------------------------------------------------------------------------*/
+
+tANI_U32 deCodeData(tANI_U8 *ipdata, tANI_U32 length, tANI_U8 *opdata,
+   tANI_U32 *currentIndex)
+{
+   tANI_U16 oplength = 0;
+
+   oplength = ipdata[0];
+   oplength = oplength | (ipdata[1] << 8);
+
+   memcpy(opdata, &ipdata[sizeof(tANI_U16)], oplength);
+
+   *currentIndex = *currentIndex + sizeof(tANI_U16) + oplength;
+
+   return oplength;
+}
diff --git a/CORE/VOSS/src/wlan_nv_template_builtin.c b/CORE/VOSS/src/wlan_nv_template_builtin.c
new file mode 100755
index 0000000..806895b
--- /dev/null
+++ b/CORE/VOSS/src/wlan_nv_template_builtin.c
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *    * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *\
+/*===========================================================================
+                       EDIT HISTORY FOR FILE
+
+  This section contains comments describing changes made to the module.
+  Notice that changes are listed in reverse chronological order.
+
+  $Header:$ $DateTime: $ $Author: $
+
+  when        who        what, where, why
+  --------    ---        -----------------------------------------------
+  04/10/13    kumarpra   nv built in  creation
+===========================================================================*/
+
+
+/*
+  -----------------------------------------
+  This file is generated by nvTmplRun Parser
+  -----------------------------------------
+  To be auto-generated, or
+  This is the source file and the header file can be generated from this
+  template file.
+
+  Template constructs
+     1. TABLE_: struct
+     2. INDEX_ENUM: enums, e.g. {RATE_OFDM_6M,RATE_OFDM_54M}
+     3. INDEX_INT: int, e.g.{min, max, increment}
+     3. Basic data types: tANI_U8, tANI_S8, tANI_U32, tANI_S32
+     4. Storage types:
+        4.1 SINGULAR: one element of basic data type
+        4.2 ARRAY_1: one dimensional array, x-axis
+        4.3 ARRAY_2: two dimensional array, (x, y)
+        4.4 ARRAY_3: three dimensional array, (x, y, z)
+        4.5 ARRAY_4: four dimensional array, (x, y, z, t)
+
+  Implementation notes
+     1. Flow of changing NV data format: (TBD) Either change the template and
+        generate the header file, or modify header file and auto-generate
+        the template.
+     2. Flow of writing NV data: encode the template in the data stream, so the
+        NV data is "self-sufficient". No separate template, no compability
+        issue, no need of version control.
+     3. Flow of reading NV data: parse the binary NV data stream based on the
+        template info in the data stream.
+     4. The above NV logic is decoupled from the actual data content, a generic,
+        content ergonostic parser (reading) and encoder (writing).
+        The NV logic is common code shared by tools, s/w
+        (both host and firmware), and off-line utilities.
+     5. NV data parsing and "acceptanace" into an s/w moduel data structure can
+        be "configured" in several ways:
+        5.1 only total matching of all fields, otherwise, reject the whole data
+        stream (a table).
+        5.2 partial matching of fields allowed and the rest fields assume
+        reasonal default values,
+        The choice can be determined later, but the capability is provided.
+     6. We could also design in this selection on an individual table base.
+        To design such capability, reserve some header bits in the data stream.
+     7. The NV data streams can be modified, replaced, or intact with a new data
+        stream of the same table ID added to NV data.
+        The choice can be determined later, but the NV scheme provides such
+        capability.
+     8. The template construct definitions can be common to all tables
+        (tbd: in a common section) or table specific, or updated in a
+        subsequent format section.
+        The use cases are:
+        - An index enum (e.g. RF channels) is common to all tables when the NV
+          data is created. Later new enums are added (e.g.
+        additional channels), one can choose to add the new index enum for new
+        tables appended to the NV data, or replace the
+        old table with new template info and data.
+        The template precedence is table specific then common, and later
+        "common" overwrites "earlier" commmon.
+        - A new field is added to the table, the user decides to replace the
+          old table data, he can simply encode the template info in the
+          data stream.
+        - In the same scenario (a new field is added), the user decides to
+          append a new table, he can encode the template
+        in the new data table and append it to NV data, or write a new common
+        template section and append the data.
+
+  Key "ingredients", (re-iterate the most important features and capabilities)
+     1. How to parse the data is embedded in the NV data itself. It removes the
+        dependency on header file matching,
+        version checking, compatibility among tools, host and firmware.
+     2. Table field ID enables "partial" data acceptance in an s/w module data
+        structure. Whether full matching or reject the whole table, or "partial"
+        acceptance, the capabiilty is in place and further ensures the robust
+        NV data extensibility and compatibility.
+     3. The table granularity, data stream based NV data has variable length
+        and flexibility of modifying an existing table data, replacing the
+        whole data, or leaving the existing data table intact and appending
+        a new table.
+  Misc notes:
+     1. For endianness, support only 4 bytes integer or 4 1-byte
+     2. String identifier needs to be shortened to save storage
+     3. string_field_name,  field type,  field storage class,  storage size
+*/
+
+
+#include "wlan_nv_types.h"
+#include "wlan_nv_stream.h"
+#include "wlan_nv.h"
+#include "wlan_nv_template_internal.h"
+#include "wlan_nv_template_api.h"
+#include "wlan_nv_template_builtin.h"
+
+
+
+static int enumNoOfFieldArray[INDEX_ENUM_BUILTIN_MAX] =
+     {7,1,9,5,80,14,3,55};
+
+_NV_TEMPLATE_ENUM NvEnumsBuiltIn[/*INDEX_ENUM_MAX*/][ENUM_ENTRIES_MAX] = {
+   { // INDEX_ENUM_ALL
+      {"j1",INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS,0,{nul}},
+      {"j2",INDEX_ENUM_NUM_REG_DOMAINS,0,{nul}},
+      {"j3",INDEX_ENUM_NUM_RF_SUBBANDS,0,{nul}},
+      {"j4",INDEX_ENUM_NUM_RF_CHANNELS,0,{nul}},
+      {"j5",INDEX_ENUM_NUM_2_4GHZ_CHANNELS,0,{nul}},
+      {"j6",INDEX_ENUM_NUM_802_11_MODES,0,{nul}},
+      {"j7",INDEX_ENUM_NUM_HAL_PHY_RATES,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_ALL
+
+   { // INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS
+      {"a1",PHY_TX_CHAIN_0,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS
+
+   { // INDEX_ENUM_NUM_REG_DOMAINS
+      {"a3",REG_DOMAIN_FCC,0,{nul}},
+      {"a4",REG_DOMAIN_ETSI,0,{nul}},
+      {"a5",REG_DOMAIN_JAPAN,0,{nul}},
+      {"a6",REG_DOMAIN_WORLD,0,{nul}},
+      {"a7",REG_DOMAIN_N_AMER_EXC_FCC,0,{nul}},
+      {"a8",REG_DOMAIN_APAC,0,{nul}},
+      {"a9",REG_DOMAIN_KOREA,0,{nul}},
+      {"ba",REG_DOMAIN_HI_5GHZ,0,{nul}},
+      {"bb",REG_DOMAIN_NO_5GHZ,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_REG_DOMAINS
+
+   { // INDEX_ENUM_NUM_RF_SUBBANDS
+      {"bd",RF_SUBBAND_2_4_GHZ,0,{nul}},
+      {"be",RF_SUBBAND_5_LOW_GHZ,0,{nul}},
+      {"bf",RF_SUBBAND_5_MID_GHZ,0,{nul}},
+      {"bg",RF_SUBBAND_5_HIGH_GHZ,0,{nul}},
+      {"bh",RF_SUBBAND_4_9_GHZ,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_RF_SUBBANDS
+
+   { // INDEX_ENUM_NUM_RF_CHANNELS
+      {"bj",RF_CHAN_1,0,{nul}},
+      {"bk",RF_CHAN_2,0,{nul}},
+      {"bl",RF_CHAN_3,0,{nul}},
+      {"bm",RF_CHAN_4,0,{nul}},
+      {"bn",RF_CHAN_5,0,{nul}},
+      {"bo",RF_CHAN_6,0,{nul}},
+      {"bp",RF_CHAN_7,0,{nul}},
+      {"bq",RF_CHAN_8,0,{nul}},
+      {"br",RF_CHAN_9,0,{nul}},
+      {"bs",RF_CHAN_10,0,{nul}},
+      {"bt",RF_CHAN_11,0,{nul}},
+      {"bu",RF_CHAN_12,0,{nul}},
+      {"bv",RF_CHAN_13,0,{nul}},
+      {"bw",RF_CHAN_14,0,{nul}},
+      {"bx",RF_CHAN_240,0,{nul}},
+      {"by",RF_CHAN_244,0,{nul}},
+      {"bz",RF_CHAN_248,0,{nul}},
+      {"b0",RF_CHAN_252,0,{nul}},
+      {"b1",RF_CHAN_208,0,{nul}},
+      {"b2",RF_CHAN_212,0,{nul}},
+      {"b3",RF_CHAN_216,0,{nul}},
+      {"b4",RF_CHAN_36,0,{nul}},
+      {"b5",RF_CHAN_40,0,{nul}},
+      {"b6",RF_CHAN_44,0,{nul}},
+      {"b7",RF_CHAN_48,0,{nul}},
+      {"b8",RF_CHAN_52,0,{nul}},
+      {"b9",RF_CHAN_56,0,{nul}},
+      {"ca",RF_CHAN_60,0,{nul}},
+      {"cb",RF_CHAN_64,0,{nul}},
+      {"cc",RF_CHAN_100,0,{nul}},
+      {"cd",RF_CHAN_104,0,{nul}},
+      {"ce",RF_CHAN_108,0,{nul}},
+      {"cf",RF_CHAN_112,0,{nul}},
+      {"cg",RF_CHAN_116,0,{nul}},
+      {"ch",RF_CHAN_120,0,{nul}},
+      {"ci",RF_CHAN_124,0,{nul}},
+      {"cj",RF_CHAN_128,0,{nul}},
+      {"ck",RF_CHAN_132,0,{nul}},
+      {"cl",RF_CHAN_136,0,{nul}},
+      {"cm",RF_CHAN_140,0,{nul}},
+      {"cn",RF_CHAN_149,0,{nul}},
+      {"co",RF_CHAN_153,0,{nul}},
+      {"cp",RF_CHAN_157,0,{nul}},
+      {"cq",RF_CHAN_161,0,{nul}},
+      {"cr",RF_CHAN_165,0,{nul}},
+      {"cs",RF_CHAN_BOND_3,0,{nul}},
+      {"ct",RF_CHAN_BOND_4,0,{nul}},
+      {"cu",RF_CHAN_BOND_5,0,{nul}},
+      {"cv",RF_CHAN_BOND_6,0,{nul}},
+      {"cw",RF_CHAN_BOND_7,0,{nul}},
+      {"cx",RF_CHAN_BOND_8,0,{nul}},
+      {"cy",RF_CHAN_BOND_9,0,{nul}},
+      {"cz",RF_CHAN_BOND_10,0,{nul}},
+      {"c0",RF_CHAN_BOND_11,0,{nul}},
+      {"c1",RF_CHAN_BOND_242,0,{nul}},
+      {"c2",RF_CHAN_BOND_246,0,{nul}},
+      {"c3",RF_CHAN_BOND_250,0,{nul}},
+      {"c4",RF_CHAN_BOND_210,0,{nul}},
+      {"c5",RF_CHAN_BOND_214,0,{nul}},
+      {"c6",RF_CHAN_BOND_38,0,{nul}},
+      {"c7",RF_CHAN_BOND_42,0,{nul}},
+      {"c8",RF_CHAN_BOND_46,0,{nul}},
+      {"c9",RF_CHAN_BOND_50,0,{nul}},
+      {"da",RF_CHAN_BOND_54,0,{nul}},
+      {"db",RF_CHAN_BOND_58,0,{nul}},
+      {"dc",RF_CHAN_BOND_62,0,{nul}},
+      {"dd",RF_CHAN_BOND_102,0,{nul}},
+      {"de",RF_CHAN_BOND_106,0,{nul}},
+      {"df",RF_CHAN_BOND_110,0,{nul}},
+      {"dg",RF_CHAN_BOND_114,0,{nul}},
+      {"dh",RF_CHAN_BOND_118,0,{nul}},
+      {"di",RF_CHAN_BOND_122,0,{nul}},
+      {"dj",RF_CHAN_BOND_126,0,{nul}},
+      {"dk",RF_CHAN_BOND_130,0,{nul}},
+      {"dl",RF_CHAN_BOND_134,0,{nul}},
+      {"dm",RF_CHAN_BOND_138,0,{nul}},
+      {"dn",RF_CHAN_BOND_151,0,{nul}},
+      {"do",RF_CHAN_BOND_155,0,{nul}},
+      {"dp",RF_CHAN_BOND_159,0,{nul}},
+      {"dq",RF_CHAN_BOND_163,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_RF_CHANNELS
+
+   { // INDEX_ENUM_NUM_2_4GHZ_CHANNELS
+      {"ke",RF_CHAN_1_1,0,{nul}},
+      {"kf",RF_CHAN_2_1,0,{nul}},
+      {"kg",RF_CHAN_3_1,0,{nul}},
+      {"kh",RF_CHAN_4_1,0,{nul}},
+      {"ki",RF_CHAN_5_1,0,{nul}},
+      {"kj",RF_CHAN_6_1,0,{nul}},
+      {"kk",RF_CHAN_7_1,0,{nul}},
+      {"kl",RF_CHAN_8_1,0,{nul}},
+      {"km",RF_CHAN_9_1,0,{nul}},
+      {"kn",RF_CHAN_10_1,0,{nul}},
+      {"ko",RF_CHAN_11_1,0,{nul}},
+      {"kp",RF_CHAN_12_1,0,{nul}},
+      {"kq",RF_CHAN_13_1,0,{nul}},
+      {"kr",RF_CHAN_14_1,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_2_4GHZ_CHANNELS
+
+   { // INDEX_ENUM_NUM_802_11_MODES
+      {"d6",MODE_802_11B,0,{nul}},
+      {"d7",MODE_802_11AG,0,{nul}},
+      {"d8",MODE_802_11N,0,{nul}},
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_802_11_MODES
+
+   { // INDEX_ENUM_NUM_HAL_PHY_RATES
+      {"ez",HAL_PHY_RATE_11B_LONG_1_MBPS,0,{nul}},
+      {"e0",HAL_PHY_RATE_11B_LONG_2_MBPS,0,{nul}},
+      {"e1",HAL_PHY_RATE_11B_LONG_5_5_MBPS,0,{nul}},
+      {"e2",HAL_PHY_RATE_11B_LONG_11_MBPS,0,{nul}},
+      {"e3",HAL_PHY_RATE_11B_SHORT_2_MBPS,0,{nul}},
+      {"e4",HAL_PHY_RATE_11B_SHORT_5_5_MBPS,0,{nul}},
+      {"e5",HAL_PHY_RATE_11B_SHORT_11_MBPS,0,{nul}},
+      {"e6",HAL_PHY_RATE_11A_6_MBPS,0,{nul}},
+      {"e7",HAL_PHY_RATE_11A_9_MBPS,0,{nul}},
+      {"e8",HAL_PHY_RATE_11A_12_MBPS,0,{nul}},
+      {"e9",HAL_PHY_RATE_11A_18_MBPS,0,{nul}},
+      {"fa",HAL_PHY_RATE_11A_24_MBPS,0,{nul}},
+      {"fb",HAL_PHY_RATE_11A_36_MBPS,0,{nul}},
+      {"fc",HAL_PHY_RATE_11A_48_MBPS,0,{nul}},
+      {"fd",HAL_PHY_RATE_11A_54_MBPS,0,{nul}},
+      {"fe",HAL_PHY_RATE_11A_DUP_6_MBPS,0,{nul}},
+      {"ff",HAL_PHY_RATE_11A_DUP_9_MBPS,0,{nul}},
+      {"fg",HAL_PHY_RATE_11A_DUP_12_MBPS,0,{nul}},
+      {"fh",HAL_PHY_RATE_11A_DUP_18_MBPS,0,{nul}},
+      {"fi",HAL_PHY_RATE_11A_DUP_24_MBPS,0,{nul}},
+      {"fj",HAL_PHY_RATE_11A_DUP_36_MBPS,0,{nul}},
+      {"fk",HAL_PHY_RATE_11A_DUP_48_MBPS,0,{nul}},
+      {"fl",HAL_PHY_RATE_11A_DUP_54_MBPS,0,{nul}},
+      {"fm",HAL_PHY_RATE_MCS_1NSS_6_5_MBPS,0,{nul}},
+      {"fn",HAL_PHY_RATE_MCS_1NSS_13_MBPS,0,{nul}},
+      {"fo",HAL_PHY_RATE_MCS_1NSS_19_5_MBPS,0,{nul}},
+      {"fp",HAL_PHY_RATE_MCS_1NSS_26_MBPS,0,{nul}},
+      {"fq",HAL_PHY_RATE_MCS_1NSS_39_MBPS,0,{nul}},
+      {"fr",HAL_PHY_RATE_MCS_1NSS_52_MBPS,0,{nul}},
+      {"fs",HAL_PHY_RATE_MCS_1NSS_58_5_MBPS,0,{nul}},
+      {"ft",HAL_PHY_RATE_MCS_1NSS_65_MBPS,0,{nul}},
+      {"fu",HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS,0,{nul}},
+      {"fv",HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS,0,{nul}},
+      {"fw",HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS,0,{nul}},
+      {"fx",HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS,0,{nul}},
+      {"fy",HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS,0,{nul}},
+      {"fz",HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS,0,{nul}},
+      {"f0",HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS,0,{nul}},
+      {"f1",HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS,0,{nul}},
+      {"f2",HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS,0,{nul}},
+      {"f3",HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS,0,{nul}},
+      {"f4",HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS,0,{nul}},
+      {"f5",HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS,0,{nul}},
+      {"f6",HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS,0,{nul}},
+      {"f7",HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS,0,{nul}},
+      {"f8",HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS,0,{nul}},
+      {"f9",HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS,0,{nul}},
+      {"ga",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS,0,{nul}},
+      {"gb",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS,0,{nul}},
+      {"gc",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS,0,{nul}},
+      {"gd",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS,0,{nul}},
+      {"ge",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS,0,{nul}},
+      {"gf",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS,0,{nul}},
+      {"gg",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS,0,{nul}},
+      {"gh",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS,0,{nul}},
+#ifdef WLAN_FEATURE_11AC
+      {"gj",HAL_PHY_RATE_11AC_DUP_6_MBPS,0,{nul}},
+      {"gk",HAL_PHY_RATE_11AC_DUP_9_MBPS,0,{nul}},
+      {"gl",HAL_PHY_RATE_11AC_DUP_12_MBPS,0,{nul}},
+      {"gm",HAL_PHY_RATE_11AC_DUP_18_MBPS,0,{nul}},
+      {"gn",HAL_PHY_RATE_11AC_DUP_24_MBPS,0,{nul}},
+      {"go",HAL_PHY_RATE_11AC_DUP_36_MBPS,0,{nul}},
+      {"gp",HAL_PHY_RATE_11AC_DUP_48_MBPS,0,{nul}},
+      {"gq",HAL_PHY_RATE_11AC_DUP_54_MBPS,0,{nul}},
+      {"gr",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_6_5_MBPS,0,{nul}},
+      {"gs",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_13_MBPS,0,{nul}},
+      {"gt",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_19_5_MBPS,0,{nul}},
+      {"gu",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_26_MBPS,0,{nul}},
+      {"gv",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_39_MBPS,0,{nul}},
+      {"gw",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_52_MBPS,0,{nul}},
+      {"gx",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_58_5_MBPS,0,{nul}},
+      {"gy",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_65_MBPS,0,{nul}},
+      {"gz",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_78_MBPS,0,{nul}},
+#ifdef WCN_PRONTO
+      {"j8",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS,0,{nul}},
+#endif
+      {"g0",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_7_2_MBPS,0,{nul}},
+      {"g1",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_14_4_MBPS,0,{nul}},
+      {"g2",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_21_6_MBPS,0,{nul}},
+      {"g3",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_28_8_MBPS,0,{nul}},
+      {"g4",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_43_3_MBPS,0,{nul}},
+      {"g5",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_57_7_MBPS,0,{nul}},
+      {"g6",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_65_MBPS,0,{nul}},
+      {"g7",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_72_2_MBPS,0,{nul}},
+      {"g8",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_86_6_MBPS,0,{nul}},
+#ifdef WCN_PRONTO
+      {"j9",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS,0,{nul}},
+#endif
+      {"g9",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS,0,{nul}},
+      {"ha",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS,0,{nul}},
+      {"hb",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS,0,{nul}},
+      {"hc",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS,0,{nul}},
+      {"hd",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS,0,{nul}},
+      {"he",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS,0,{nul}},
+      {"hf",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS,0,{nul}},
+      {"hg",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS,0,{nul}},
+      {"hh",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS,0,{nul}},
+      {"hi",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS,0,{nul}},
+      {"hj",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS,0,{nul}},
+      {"hk",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS,0,{nul}},
+      {"hl",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS,0,{nul}},
+      {"hm",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS,0,{nul}},
+      {"hn",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS,0,{nul}},
+      {"ho",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS,0,{nul}},
+      {"hp",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS,0,{nul}},
+      {"hq",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS,0,{nul}},
+      {"hr",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS,0,{nul}},
+      {"hs",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS,0,{nul}},
+      {"ht",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS,0,{nul}},
+      {"hu",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS,0,{nul}},
+      {"hv",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS,0,{nul}},
+      {"hw",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS,0,{nul}},
+      {"hx",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS,0,{nul}},
+      {"hy",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS,0,{nul}},
+      {"hz",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS,0,{nul}},
+      {"h0",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS,0,{nul}},
+      {"h1",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS,0,{nul}},
+      {"h2",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS,0,{nul}},
+      {"h3",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS,0,{nul}},
+      {"h4",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS,0,{nul}},
+      {"h5",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS,0,{nul}},
+      {"h6",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS,0,{nul}},
+      {"h7",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS,0,{nul}},
+      {"h8",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS,0,{nul}},
+      {"h9",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS,0,{nul}},
+      {"ia",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS,0,{nul}},
+      {"ib",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS,0,{nul}},
+      {"ic",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS,0,{nul}},
+#endif
+      {{nul},0, 0,{nul}},
+   }, // INDEX_ENUM_NUM_HAL_PHY_RATES
+
+   { //INDEX_ENUM_LAST
+      {{nul},0, 0,{nul}},
+   }, //INDEX_ENUM_LAST
+}; // END _NV_TEMPLATE_ENUM
+
+
+int getEnumNoOfFields(int enumIdx){
+#ifdef WLAN_FEATURE_11AC
+   enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 17;
+#ifdef WCN_PRONTO
+   enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 1;
+#endif
+   enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 9;
+#ifdef WCN_PRONTO
+   enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 1;
+#endif
+   enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 40;
+#endif
+
+   return enumNoOfFieldArray[enumIdx];
+}
+
+
+static int tableNoOfFieldArray[TABLE_BUILTIN_MAX] =
+     {14,12,2,2,16,1,2,2,23,1,1,1,4,2,13};
+
+_NV_TEMPLATE_TABLE NvTablesBuiltIn[/*TABLES_MAX*/][TABLE_ENTRIES_MAX] = {
+   { // TABLE_sHalNv
+      {"jz",_TABLE_IDX(TABLE_sNvFields),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.fields) - (int)&nvDefaults),"fields"},
+      {"jm",_TABLE_IDX(TABLE_tRateGroupPwr),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0,
+         ((int)&(nvDefaults.tables.pwrOptimum[0]) - (int)&nvDefaults.tables),
+         "pwrOptimum"},
+      {"dx",_TABLE_IDX(TABLE_sRegulatoryChannel),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].channels[0]) -
+          (int)&nvDefaults.tables.regDomains[0]),"channels"},
+      {"jn",_TABLE_IDX(TABLE_sRegulatoryDomains),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_REG_DOMAINS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0]) - (int)&nvDefaults.tables),
+         "regDomains"},
+      {"jo",_TABLE_IDX(TABLE_sDefaultCountry),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.defaultCountryTable) -
+          (int)&nvDefaults.tables),"defaultCountryTable"},
+      {"jp",_TABLE_IDX(TABLE_tTpcPowerTable),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.plutCharacterized[0]) -
+          (int)&nvDefaults.tables),"plutCharacterized"},
+      {"jr",_TABLE_IDX(TABLE_tRateGroupPwrVR),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0,
+         ((int)&(nvDefaults.tables.pwrOptimum_virtualRate[0]) -
+          (int)&nvDefaults.tables),"pwrOptimum_virtualRate"},
+      {"js",_TABLE_IDX(TABLE_sFwConfig),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig) - (int)&nvDefaults.tables),
+         "fwConfig"},
+      {"jt",_TABLE_IDX(TABLE_sRssiChannelOffsets),(_ADD_SIZE1(2)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|(FIELD_SIZE_VALUE_BITS(2))),
+         0,0,((int)&(nvDefaults.tables.rssiChanOffsets[0]) -
+          (int)&nvDefaults.tables),"rssiChanOffsets"},
+      {"er",_TABLE_IDX(TABLE_sCalData),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData) -
+          (int)&nvDefaults.tables.hwCalValues),"calData"},
+      {"ju",_TABLE_IDX(TABLE_sHwCalValues),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues) - (int)&nvDefaults.tables),
+         "hwCalValues"},
+      {"jx",_TABLE_IDX(TABLE_sOfdmCmdPwrOffset),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.ofdmCmdPwrOffset) - (int)&nvDefaults.tables),
+         "ofdmCmdPwrOffset"},
+      {"jy",_TABLE_IDX(TABLE_sTxBbFilterMode),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.txbbFilterMode) - (int)&nvDefaults.tables),
+         "txbbFilterMode"},
+      {"j0",_TABLE_IDX(TABLE_sNvTables),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables) - (int)&nvDefaults),"tables"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sHalNv
+
+   { // TABLE_sNvFields
+      {"ap",_ID_U16,SINGULAR,0,0,0,((int)&(nvDefaults.fields.productId) -
+          (int)&nvDefaults.fields),"productId"},
+      {"aq",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.fields.productBands) -
+          (int)&nvDefaults.fields),"productBands"},
+      {"ar",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.fields.wlanNvRevId) -
+          (int)&nvDefaults.fields),"wlanNvRevId"},
+      {"as",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.fields.numOfTxChains) -
+          (int)&nvDefaults.fields),"numOfTxChains"},
+      {"at",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.fields.numOfRxChains) -
+          (int)&nvDefaults.fields),"numOfRxChains"},
+      {"au",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0,
+         ((int)&(nvDefaults.fields.macAddr[0]) - (int)&nvDefaults.fields),
+         "macAddr"},
+      {"av",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0,
+         ((int)&(nvDefaults.fields.macAddr2[0]) - (int)&nvDefaults.fields),
+         "macAddr2"},
+      {"aw",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0,
+         ((int)&(nvDefaults.fields.macAddr3[0]) - (int)&nvDefaults.fields),
+         "macAddr3"},
+      {"ax",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0,
+         ((int)&(nvDefaults.fields.macAddr4[0]) - (int)&nvDefaults.fields),
+         "macAddr4"},
+      {"ay",_ID_U8,(_ADD_SIZE1(NV_FIELD_MFG_SN_SIZE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NV_FIELD_MFG_SN_SIZE))),0,0,
+         ((int)&(nvDefaults.fields.mfgSN[0]) - (int)&nvDefaults.fields),"mfgSN"}
+         ,
+      {"az",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.fields.couplerType) -
+          (int)&nvDefaults.fields),"couplerType"},
+      {"a0",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.fields.nvVersion) -
+          (int)&nvDefaults.fields),"nvVersion"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sNvFields
+
+   { // TABLE_sRegulatoryChannel
+      {"dv",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].channels[0].enabled) -
+          (int)&nvDefaults.tables.regDomains[0].channels[0]),"enabled"},
+      {"dw",_ID_S8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].channels[0].pwrLimit) -
+          (int)&nvDefaults.tables.regDomains[0].channels[0]),"pwrLimit"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sRegulatoryChannel
+
+   { // TABLE_sRssiChannelOffsets
+      {"d1",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.rssiChanOffsets[0].bRssiOffset[0]) -
+          (int)&nvDefaults.tables.rssiChanOffsets[0]),"bRssiOffset"},
+      {"d2",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.rssiChanOffsets[0].gnRssiOffset[0]) -
+          (int)&nvDefaults.tables.rssiChanOffsets[0]),"gnRssiOffset"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sRssiChannelOffsets
+
+   { // TABLE_sCalData
+      {"ea",_ID_U16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHd2G) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"psSlpTimeOvrHd2G"},
+      {"eb",_ID_U16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHd5G) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"psSlpTimeOvrHd5G"},
+      {"ec",_ID_U16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHdxLNA5G) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"psSlpTimeOvrHdxLNA5G"},
+      {"ed",_ID_U8,SINGULAR,0,0,0,
+         (((int)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHdxLNA5G) +
+          sizeof(uint16)) - (int)&nvDefaults.tables.hwCalValues.calData),
+         "nv_TxBBFSel9MHz"},
+      {"ee",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam2) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam2"},
+      {"ef",_ID_U16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.custom_tcxo_reg8) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"custom_tcxo_reg8"},
+      {"eg",_ID_U16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.custom_tcxo_reg9) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"custom_tcxo_reg9"},
+      {"eh",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam3) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam3"},
+      {"ei",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam4) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam4"},
+      {"ej",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam5) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam5"},
+      {"ek",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam6) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam6"},
+      {"el",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam7) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam7"},
+      {"em",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam8) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam8"},
+      {"en",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam9) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam9"},
+      {"eo",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam10) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam10"},
+      {"ep",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData.hwParam11) -
+          (int)&nvDefaults.tables.hwCalValues.calData),"hwParam11"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sCalData
+
+   { // TABLE_sTxBbFilterMode
+      {"es",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.txbbFilterMode.txFirFilterMode) -
+          (int)&nvDefaults.tables.txbbFilterMode),"txFirFilterMode"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sTxBbFilterMode
+
+   { // TABLE_sOfdmCmdPwrOffset
+      {"et",_ID_S16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.ofdmCmdPwrOffset.ofdmPwrOffset) -
+          (int)&nvDefaults.tables.ofdmCmdPwrOffset),"ofdmPwrOffset"},
+      {"eu",_ID_S16,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.ofdmCmdPwrOffset.rsvd) -
+          (int)&nvDefaults.tables.ofdmCmdPwrOffset),"rsvd"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sOfdmCmdPwrOffset
+
+   { // TABLE_sDefaultCountry
+      {"if",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.defaultCountryTable.regDomain) -
+          (int)&nvDefaults.tables.defaultCountryTable),"regDomain"},
+      {"ig",_ID_U8,(_ADD_SIZE1(NV_FIELD_COUNTRY_CODE_SIZE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NV_FIELD_COUNTRY_CODE_SIZE))),0,0,
+         ((int)&(nvDefaults.tables.defaultCountryTable.countryCode[0]) -
+          (int)&nvDefaults.tables.defaultCountryTable),"countryCode"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sDefaultCountry
+
+   { // TABLE_sFwConfig
+      {"ih",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.skuID) -
+          (int)&nvDefaults.tables.fwConfig),"skuID"},
+      {"ii",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.tpcMode2G)
+          - (int)&nvDefaults.tables.fwConfig),"tpcMode2G"},
+      {"ij",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.tpcMode5G)
+          - (int)&nvDefaults.tables.fwConfig),"tpcMode5G"},
+      {"ik",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.configItem1)
+          - (int)&nvDefaults.tables.fwConfig),"configItem1"},
+      {"il",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xPA2G) -
+          (int)&nvDefaults.tables.fwConfig),"xPA2G"},
+      {"im",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xPA5G) -
+          (int)&nvDefaults.tables.fwConfig),"xPA5G"},
+      {"in",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.extPaCtrl0Polarity) -
+          (int)&nvDefaults.tables.fwConfig),"extPaCtrl0Polarity"},
+      {"io",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.extPaCtrl1Polarity) -
+          (int)&nvDefaults.tables.fwConfig),"extPaCtrl1Polarity"},
+      {"ip",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xLNA2G) -
+          (int)&nvDefaults.tables.fwConfig),"xLNA2G"},
+      {"iq",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xLNA5G) -
+          (int)&nvDefaults.tables.fwConfig),"xLNA5G"},
+      {"ir",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xCoupler2G)
+          - (int)&nvDefaults.tables.fwConfig),"xCoupler2G"},
+      {"is",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xCoupler5G)
+          - (int)&nvDefaults.tables.fwConfig),"xCoupler5G"},
+      {"it",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xPdet2G) -
+          (int)&nvDefaults.tables.fwConfig),"xPdet2G"},
+      {"iu",_ID_U8,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.xPdet5G) -
+          (int)&nvDefaults.tables.fwConfig),"xPdet5G"},
+      {"iv",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.enableDPD2G) -
+          (int)&nvDefaults.tables.fwConfig),"enableDPD2G"},
+      {"iw",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.enableDPD5G) -
+          (int)&nvDefaults.tables.fwConfig),"enableDPD5G"},
+      {"ix",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.pdadcSelect2G) -
+          (int)&nvDefaults.tables.fwConfig),"pdadcSelect2G"},
+      {"iy",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.pdadcSelect5GLow) -
+          (int)&nvDefaults.tables.fwConfig),"pdadcSelect5GLow"},
+      {"iz",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.pdadcSelect5GMid) -
+          (int)&nvDefaults.tables.fwConfig),"pdadcSelect5GMid"},
+      {"i0",_ID_U8,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig.pdadcSelect5GHigh) -
+          (int)&nvDefaults.tables.fwConfig),"pdadcSelect5GHigh"},
+      {"i1",_ID_U32,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.configItem2)
+          - (int)&nvDefaults.tables.fwConfig),"configItem2"},
+      {"i2",_ID_U32,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.configItem3)
+          - (int)&nvDefaults.tables.fwConfig),"configItem3"},
+      {"i3",_ID_U32,SINGULAR,0,0,0,((int)&(nvDefaults.tables.fwConfig.configItem4)
+          - (int)&nvDefaults.tables.fwConfig),"configItem4"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sFwConfig
+
+   { // TABLE_tTpcPowerTable
+      {"kc",_ID_U8,(_ADD_SIZE2(TPC_MEM_POWER_LUT_DEPTH)|ARRAY_2),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS))),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(TPC_MEM_POWER_LUT_DEPTH))),0,
+         ((int)&(nvDefaults.tables.plutCharacterized[0]) -
+          (int)&nvDefaults.tables.plutCharacterized[0]),"tTpcPowerTable"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_tTpcPowerTable
+
+   { // TABLE_tRateGroupPwr
+      {"kb",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_HAL_PHY_RATES))),0,0,
+         ((int)&(nvDefaults.tables.pwrOptimum[0]) -
+          (int)&nvDefaults.tables.pwrOptimum[0]),"tRateGroupPwr"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_tRateGroupPwr
+
+   { // TABLE_tRateGroupPwrVR
+      {"kd",_ID_U32,(_ADD_SIZE1(NUM_RF_VR_RATE)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|
+         (FIELD_SIZE_VALUE_BITS(NUM_RF_VR_RATE))),0,0,
+         ((int)&(nvDefaults.tables.pwrOptimum_virtualRate[0]) -
+          (int)&nvDefaults.tables.pwrOptimum_virtualRate[0]),"tRateGroupPwrVR"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_tRateGroupPwrVR
+
+   { // TABLE_sRegulatoryDomains
+      {"dx",_TABLE_IDX(TABLE_sRegulatoryChannel),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].channels[0]) -
+          (int)&nvDefaults.tables.regDomains[0]),"channels"},
+      {"dy",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].antennaGain[0]) -
+          (int)&nvDefaults.tables.regDomains[0]),"antennaGain"},
+      {"dz",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_2_4GHZ_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].bRatePowerOffset[0]) -
+          (int)&nvDefaults.tables.regDomains[0]),"bRatePowerOffset"},
+      {"d0",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0].gnRatePowerOffset[0]) -
+          (int)&nvDefaults.tables.regDomains[0]),"gnRatePowerOffset"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sRegulatoryDomains
+
+   { // TABLE_sHwCalValues
+      {"eq",_ID_U32,SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.validBmap) -
+          (int)&nvDefaults.tables.hwCalValues),"validBmap"},
+      {"er",_TABLE_IDX(TABLE_sCalData),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues.calData) -
+          (int)&nvDefaults.tables.hwCalValues),"calData"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sHwCalValues
+
+   { // TABLE_sNvTables
+      {"jm",_TABLE_IDX(TABLE_tRateGroupPwr),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0,
+         ((int)&(nvDefaults.tables.pwrOptimum[0]) - (int)&nvDefaults.tables),
+         "pwrOptimum"},
+      {"jn",_TABLE_IDX(TABLE_sRegulatoryDomains),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_REG_DOMAINS))),0,0,
+         ((int)&(nvDefaults.tables.regDomains[0]) - (int)&nvDefaults.tables),
+         "regDomains"},
+      {"jo",_TABLE_IDX(TABLE_sDefaultCountry),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.defaultCountryTable) -
+          (int)&nvDefaults.tables),"defaultCountryTable"},
+      {"jp",_TABLE_IDX(TABLE_tTpcPowerTable),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.plutCharacterized[0]) -
+          (int)&nvDefaults.tables),"plutCharacterized"},
+      {"jq",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.plutPdadcOffset[0]) -
+          (int)&nvDefaults.tables),"plutPdadcOffset"},
+      {"jr",_TABLE_IDX(TABLE_tRateGroupPwrVR),(ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0,
+         ((int)&(nvDefaults.tables.pwrOptimum_virtualRate[0]) -
+          (int)&nvDefaults.tables),"pwrOptimum_virtualRate"},
+      {"js",_TABLE_IDX(TABLE_sFwConfig),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.fwConfig) - (int)&nvDefaults.tables),
+         "fwConfig"},
+      {"jt",_TABLE_IDX(TABLE_sRssiChannelOffsets),(_ADD_SIZE1(2)|ARRAY_1),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|(FIELD_SIZE_VALUE_BITS(2))),
+         0,0,((int)&(nvDefaults.tables.rssiChanOffsets[0]) -
+          (int)&nvDefaults.tables),"rssiChanOffsets"},
+      {"ju",_TABLE_IDX(TABLE_sHwCalValues),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.hwCalValues) - (int)&nvDefaults.tables),
+         "hwCalValues"},
+      {"jv",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0,
+         ((int)&(nvDefaults.tables.antennaPathLoss[0]) -
+          (int)&nvDefaults.tables),"antennaPathLoss"},
+      {"jw",_ID_S16,(ARRAY_2),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_802_11_MODES))),
+         ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))|
+         (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,
+         ((int)&(nvDefaults.tables.pktTypePwrLimits[0][0]) -
+          (int)&nvDefaults.tables),"pktTypePwrLimits"},
+      {"jx",_TABLE_IDX(TABLE_sOfdmCmdPwrOffset),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.ofdmCmdPwrOffset) - (int)&nvDefaults.tables),
+         "ofdmCmdPwrOffset"},
+      {"jy",_TABLE_IDX(TABLE_sTxBbFilterMode),SINGULAR,0,0,0,
+         ((int)&(nvDefaults.tables.txbbFilterMode) - (int)&nvDefaults.tables),
+         "txbbFilterMode"},
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, // TABLE_sNvTables
+
+   { //INDEX_TABLE_LAST
+      {{nul}, 0, 0, 0, 0, 0, 0,{nul}},
+   }, //INDEX_TABLE_LAST
+}; // END _NV_TEMPLATE_TABLE
+
+int getTableNoOfFields(int tblIdx)
+{
+   return tableNoOfFieldArray[tblIdx];
+}
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 41ee8f0..f5942b8 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -9427,7 +9427,8 @@
    }
    
    /* Get the NV structure base address and size from VOS */
-   vos_nv_getNVBuffer(&pNvBuffer,&bufferSize);
+   vos_nv_getNVEncodedBuffer(&pNvBuffer,&bufferSize);
+
    wdiNvDownloadReqParam = (WDI_NvDownloadReqParamsType *)vos_mem_malloc(
                                           sizeof(WDI_NvDownloadReqParamsType)) ;
    if(NULL == wdiNvDownloadReqParam) 
diff --git a/Kbuild b/Kbuild
index aebe984..ebb304d 100644
--- a/Kbuild
+++ b/Kbuild
@@ -382,7 +382,10 @@
 		$(VOSS_SRC_DIR)/vos_timer.o \
 		$(VOSS_SRC_DIR)/vos_trace.o \
 		$(VOSS_SRC_DIR)/vos_types.o \
-		$(VOSS_SRC_DIR)/vos_utils.o
+                $(VOSS_SRC_DIR)/vos_utils.o \
+                $(VOSS_SRC_DIR)/wlan_nv_parser.o \
+                $(VOSS_SRC_DIR)/wlan_nv_stream_read.o \
+                $(VOSS_SRC_DIR)/wlan_nv_template_builtin.o
 
 ifeq ($(BUILD_DIAG_VERSION),1)
 VOSS_OBJS += $(VOSS_SRC_DIR)/vos_diag.o