wlan: iwpriv getRoamRssi to query RSSI from roaming engine

A new iwpriv getRoamRssi is supported to query RSSI from
the LFR firmware monitoring.
Since the RSSI monitoring and penalization is done in
Riva in BMPS mode. Iwpriv wlan0 getRoamRSSI fetches RSSI
from the riva only in BMPS Mode. If this command is used
while not associated or not in BMPS mode, it returns a value of 0

Change-Id: Ifa660c51685af5dd5d20b28546aa1b9d4f217082
CRs-Fixed: 427473
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index f071385..1079255 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1171,6 +1171,14 @@
 
 
 eHalStatus csrGetRssi(tpAniSirGlobal pMac,tCsrRssiCallback callback,tANI_U8 staId,tCsrBssid bssId,void * pContext,void * pVosContext);
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
+eHalStatus csrGetRoamRssi(tpAniSirGlobal pMac,
+                          tCsrRssiCallback callback,
+                          tANI_U8 staId,
+                          tCsrBssid bssId,
+                          void * pContext,
+                          void * pVosContext);
+#endif
 eHalStatus csrRoamRegisterCallback(tpAniSirGlobal pMac, csrRoamCompleteCallback callback, void *pContext);
 /* ---------------------------------------------------------------------------
     \fn csrGetConfigParam
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index dc7dcc9..c7d7b25 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -771,7 +771,14 @@
 eHalStatus sme_GetRssi(tHalHandle hHal, 
                              tCsrRssiCallback callback, 
                              tANI_U8 staId, tCsrBssid bssId, void *pContext, void* pVosContext);
-
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
+eHalStatus sme_GetRoamRssi(tHalHandle hHal,
+                           tCsrRssiCallback callback,
+                           tANI_U8 staId,
+                           tCsrBssid bssId,
+                           void *pContext,
+                           void* pVosContext);
+#endif
 /* ---------------------------------------------------------------------------
     \fn sme_CfgSetInt
     \brief a wrapper function that HDD calls to set parameters in CFG. 
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index cf309bd..e80f70c 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -8362,6 +8362,41 @@
     }
     return;
 }
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
+void csrRoamRssiRspProcessor(tpAniSirGlobal pMac, void* pMsg)
+{
+    v_S7_t  rssi = 0;
+    tAniGetRoamRssiRsp* pRoamRssiRsp = (tAniGetRoamRssiRsp*)pMsg;
+
+    /* Get roam Rssi request is backed up and passed back to the response,
+       Extract the request message to fetch callback */
+    tpAniGetRssiReq reqBkp = (tAniGetRssiReq*)pRoamRssiRsp->rssiReq;
+    if(pRoamRssiRsp)
+    {
+        rssi = pRoamRssiRsp->rssi;
+        if((reqBkp) && (NULL != reqBkp->rssiCallback))
+        {
+            ((tCsrRssiCallback)(reqBkp->rssiCallback))(rssi, pRoamRssiRsp->staId, reqBkp->pDevContext);
+            reqBkp->rssiCallback = NULL;
+            vos_mem_free(reqBkp);
+        }
+        else
+        {
+            smsLog( pMac, LOGE, FL("reqBkp->rssiCallback is NULL"));
+            if (NULL != reqBkp)
+            {
+                vos_mem_free(reqBkp);
+            }
+        }
+    }
+    else
+    {
+        smsLog( pMac, LOGE, FL("pRoamRssiRsp is NULL"));
+    }
+    return;
+}
+#endif
+
 static void csrRoamRssiIndHdlr(tpAniSirGlobal pMac, void* pMsg)
 {
     WLANTL_TlIndicationReq *pTlRssiInd = (WLANTL_TlIndicationReq*)pMsg;
@@ -8374,12 +8409,12 @@
         }
         else
         {
-            smsLog( pMac, LOGE, FL("pTlRssiInd->tlCallback is NULL\n"));                
+            smsLog( pMac, LOGE, FL("pTlRssiInd->tlCallback is NULL\n"));
         }
     }
     else
     {
-        smsLog( pMac, LOGE, FL("pTlRssiInd is NULL\n"));    
+        smsLog( pMac, LOGE, FL("pTlRssiInd is NULL\n"));
     }
     return;
 }
@@ -9231,6 +9266,12 @@
             smsLog( pMac, LOG2, FL("Stats rsp from PE\n"));
             csrRoamStatsRspProcessor( pMac, pSirMsg );
             break;
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
+        case eWNI_SME_GET_ROAM_RSSI_RSP:
+            smsLog( pMac, LOG2, FL("Stats rsp from PE"));
+            csrRoamRssiRspProcessor( pMac, pSirMsg );
+            break;
+#endif
         case eWNI_SME_GET_RSSI_REQ:
             smsLog( pMac, LOG2, FL("GetRssiReq from self\n"));
             csrUpdateRssi( pMac, pSirMsg );
@@ -13990,6 +14031,39 @@
    smsLog(pMac, LOG2, FL("returned"));      
    return status;
 }
+
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
+eHalStatus csrGetRoamRssi(tpAniSirGlobal pMac,
+                            tCsrRssiCallback callback,
+                            tANI_U8 staId, tCsrBssid bssId, void *pContext, void* pVosContext)
+{
+   eHalStatus status = eHAL_STATUS_SUCCESS;
+   tAniGetRssiReq *pMsg;
+
+   status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, sizeof(tAniGetRssiReq));
+   if ( !HAL_STATUS_SUCCESS(status) )
+   {
+      smsLog(pMac, LOGE, " csrGetRoamRssi: failed to allocate mem for req");
+      return status;
+   }
+   // need to initiate a stats request to PE
+   pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_ROAM_RSSI_REQ);
+   pMsg->msgLen = (tANI_U16)sizeof(tAniGetRssiReq);
+   pMsg->staId = staId;
+   pMsg->rssiCallback = callback;
+   pMsg->pDevContext = pContext;
+   pMsg->pVosContext = pVosContext;
+   status = palSendMBMessage(pMac->hHdd, pMsg );
+   if(!HAL_STATUS_SUCCESS(status))
+   {
+      smsLog(pMac, LOG1, " csrGetRoamRssi: failed to send down the stats req");
+      palFreeMemory(pMac->hHdd, (void *)pMsg);
+      status = eHAL_STATUS_FAILURE;
+   }
+   return status;
+}
+#endif
+
 eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requesterId, 
                             tANI_U32 statsMask, 
                             tCsrStatsCallback callback, 
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 48c2e0c..fd59a38 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -3822,6 +3822,36 @@
    }
    return (status);
 }
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
+/* ---------------------------------------------------------------------------
+    \fn sme_GetRoamRssi
+    \brief a wrapper function that client calls to register a callback to get Roam RSSI
+
+    \param callback - SME sends back the requested stats using the callback
+    \param staId - The station ID for which the stats is requested for
+    \param pContext - user context to be passed back along with the callback
+    \param pVosContext - vos context
+    \return eHalStatus
+  ---------------------------------------------------------------------------*/
+eHalStatus sme_GetRoamRssi(tHalHandle hHal,
+                             tCsrRssiCallback callback,
+                             tANI_U8 staId, tCsrBssid bssId,
+                             void *pContext, void* pVosContext)
+{
+   eHalStatus status = eHAL_STATUS_FAILURE;
+   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+   status = sme_AcquireGlobalLock( &pMac->sme );
+   if ( HAL_STATUS_SUCCESS( status ) )
+   {
+      status = csrGetRoamRssi( pMac, callback,
+                                 staId, bssId, pContext, pVosContext);
+      sme_ReleaseGlobalLock( &pMac->sme );
+   }
+   return (status);
+}
+#endif
+
 
 /* ---------------------------------------------------------------------------
     \fn sme_GetStatistics