wlan : Fast transition (11r)

- Set Key along with the Config BSS command to HAL
  to improve the 11r roam latencies
- Move the TL state to Authenticated to allow TX Data
  when set GTK is received at driver from supplicant
- Optimize the memcpy in hdd_SendFTEvent

Change-Id: Iab9f1fbcc4a11bd1a2e521885a6beaf1f6a9068a
CRs-fixed: 465419
diff --git a/CORE/SME/inc/sme_FTApi.h b/CORE/SME/inc/sme_FTApi.h
index 115f3f9..1dba737 100644
--- a/CORE/SME/inc/sme_FTApi.h
+++ b/CORE/SME/inc/sme_FTApi.h
@@ -39,6 +39,8 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+
+
 #if !defined( __SME_FTAPI_H )
 #define __SME_FTAPI_H
 
@@ -49,9 +51,9 @@
   
   \brief macros and prototype for SME APIs
   
-   Copyright 2008 (c) Qualcomm, Incorporated.  All Rights Reserved.
+   Copyright 2008 (c) Qualcomm Technologies, Inc.  All Rights Reserved.
    
-   Qualcomm Confidential and Proprietary.
+   Qualcomm Technologies Confidential and Proprietary.
   
   ========================================================================*/
 typedef enum eFTIEState
@@ -82,9 +84,12 @@
 
     // Saved pFTPreAuthRsp
     tpSirFTPreAuthRsp psavedFTPreAuthRsp;
+    v_BOOL_t          setFTPreAuthState;
+    v_BOOL_t          setFTPTKState;
 
     // Time to trigger reassoc once pre-auth is successful
     tPalTimerHandle   preAuthReassocIntvlTimer;
+    tCsrRoamSetKey    *pCsrFTKeyInfo;
 
 } tftSMEContext, *tpftSMEContext;
 
@@ -99,6 +104,10 @@
 void sme_GetFTPreAuthResponse( tHalHandle hHal, tANI_U8 *ft_ies, tANI_U32 ft_ies_ip_len, tANI_U16 *ft_ies_length );
 void sme_GetRICIEs( tHalHandle hHal, tANI_U8 *ric_ies, tANI_U32 ric_ies_ip_len, tANI_U32 *ric_ies_length );
 void sme_PreauthReassocIntvlTimerCallback(void *context);
+void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state);
+v_BOOL_t sme_GetFTPreAuthState(tHalHandle hHal);
+v_BOOL_t sme_GetFTPTKState(tHalHandle hHal);
+void sme_SetFTPTKState(tHalHandle hHal, v_BOOL_t state);
 
 
 #endif //#if !defined( __SME_FTAPI_H )
diff --git a/CORE/SME/src/sme_common/sme_FTApi.c b/CORE/SME/src/sme_common/sme_FTApi.c
index 81219f6..929592b 100644
--- a/CORE/SME/src/sme_common/sme_FTApi.c
+++ b/CORE/SME/src/sme_common/sme_FTApi.c
@@ -70,7 +70,8 @@
 
     pMac->ft.ftSmeContext.reassoc_ft_ies = NULL;                        
     pMac->ft.ftSmeContext.reassoc_ft_ies_length = 0;       
-
+    pMac->ft.ftSmeContext.setFTPreAuthState = FALSE;
+    pMac->ft.ftSmeContext.setFTPTKState = FALSE;
     status = palTimerAlloc(pMac->hHdd, &pMac->ft.ftSmeContext.preAuthReassocIntvlTimer, 
                             sme_PreauthReassocIntvlTimerCallback, (void *)pMac);
 
@@ -81,6 +82,7 @@
     }                 
 
     pMac->ft.ftSmeContext.psavedFTPreAuthRsp = NULL;                        
+    pMac->ft.ftSmeContext.pCsrFTKeyInfo = NULL;
 
     pMac->ft.ftSmeContext.FTState = eFT_START_READY;
 }
@@ -130,6 +132,17 @@
     palTimerFree(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
 }
 
+void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state)
+{
+  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+  pMac->ft.ftSmeContext.setFTPreAuthState = state;
+}
+
+v_BOOL_t sme_GetFTPreAuthState(tHalHandle hHal)
+{
+  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+  return pMac->ft.ftSmeContext.setFTPreAuthState;
+}
 
 /*--------------------------------------------------------------------------
   Each time the supplicant sends down the FT IEs to the driver.
@@ -259,17 +272,17 @@
     tANI_U16 msgLen;
     eHalStatus status = eHAL_STATUS_FAILURE;
     tAniEdType tmpEdType;
-    tAniKeyDirection tmpDirection;
-    //tANI_U8 *pBuf;
-    tANI_U8 *p = NULL;
+    tSirKeyMaterial *keymaterial = NULL;
     tAniEdType edType;
     tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
     int i = 0;
 
-    smsLog(pMac, LOGE, FL("keyLength %d"), pFTKeyInfo->keyLength);
+    smsLog(pMac, LOG1, FL("keyLength %d"), pFTKeyInfo->keyLength);
 
-      for(i=0; i<pFTKeyInfo->keyLength; i++)
-          smsLog(pMac, LOGE, FL("%02x"), pFTKeyInfo->Key[i]);
+    for (i=0; i<pFTKeyInfo->keyLength; i++)
+      smsLog(pMac, LOG1, FL("%02x"), pFTKeyInfo->Key[i]);
+#endif
 
     msgLen  = sizeof( tANI_U16) + sizeof( tANI_U16 ) + 
        sizeof( pMsg->keyMaterial.length ) + sizeof( pMsg->keyMaterial.edType ) + 
@@ -285,66 +298,78 @@
     pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_FT_UPDATE_KEY);
     pMsg->length = pal_cpu_to_be16(msgLen);
 
-    p = (tANI_U8 *)&pMsg->keyMaterial;
+    keymaterial = &pMsg->keyMaterial;
 
-    // Set the pMsg->keyMaterial.length field (this length is defined as all data that follows the edType field
-    // in the tSirKeyMaterial keyMaterial; field).
-    //
-    // !!NOTE:  This keyMaterial.length contains the length of a MAX size key, though the keyLength can be 
-    // shorter than this max size.  Is LIM interpreting this ok ?
-    p = pal_set_U16( p, pal_cpu_to_be16((tANI_U16)( sizeof( pMsg->keyMaterial.numKeys ) + 
-                                                    ( pMsg->keyMaterial.numKeys * sizeof( pMsg->keyMaterial.key ) ) )) );
+    keymaterial->length = pFTKeyInfo->keyLength;
 
-    // set pMsg->keyMaterial.edType
     edType = csrTranslateEncryptTypeToEdType( pFTKeyInfo->encType );
     tmpEdType = pal_cpu_to_be32(edType);
-    palCopyMemory( pMac->hHdd, p, (tANI_U8 *)&tmpEdType, sizeof(tAniEdType) );
-    p += sizeof( pMsg->keyMaterial.edType );
+    keymaterial->edType = tmpEdType;
 
-    // set the pMsg->keyMaterial.numKeys field
-    *p = pMsg->keyMaterial.numKeys;
-    p += sizeof( pMsg->keyMaterial.numKeys );   
+    // Set the pMsg->keyMaterial.length field (this length is defined as all
+    // data that follows the edType field
+    // in the tSirKeyMaterial keyMaterial; field).
+    //
+    // !!NOTE:  This keyMaterial.length contains the length of a MAX size key,
+    // though the keyLength can be
+    // shorter than this max size.  Is LIM interpreting this ok ?
+    keymaterial->numKeys = 1;
+    keymaterial->key[ 0 ].keyId = pFTKeyInfo->keyId;
+    keymaterial->key[ 0 ].unicast = (tANI_U8)eANI_BOOLEAN_TRUE;
+    keymaterial->key[ 0 ].keyDirection = pFTKeyInfo->keyDirection;
 
-    // set pSirKey->keyId = keyId;
-    *p = pMsg->keyMaterial.key[ 0 ].keyId;
-    p += sizeof( pMsg->keyMaterial.key[ 0 ].keyId );
+    palCopyMemory( pMac->hHdd, &keymaterial->key[ 0 ].keyRsc,
+                   pFTKeyInfo->keyRsc, CSR_MAX_RSC_LEN );
 
-    // set pSirKey->unicast = (tANI_U8)fUnicast;
-    *p = (tANI_U8)eANI_BOOLEAN_TRUE;
-    p += sizeof( pMsg->keyMaterial.key[ 0 ].unicast );
+    keymaterial->key[ 0 ].paeRole = pFTKeyInfo->paeRole;
 
-    // set pSirKey->keyDirection = aniKeyDirection;
-    tmpDirection = pal_cpu_to_be32(pFTKeyInfo->keyDirection);
-    palCopyMemory( pMac->hHdd, p, (tANI_U8 *)&tmpDirection, sizeof(tAniKeyDirection) );
-    p += sizeof(tAniKeyDirection);
-    //    pSirKey->keyRsc = ;;
-    palCopyMemory( pMac->hHdd, p, pFTKeyInfo->keyRsc, CSR_MAX_RSC_LEN );
-    p += sizeof( pMsg->keyMaterial.key[ 0 ].keyRsc );
+    keymaterial->key[ 0 ].keyLength = pFTKeyInfo->keyLength;
 
-    // set pSirKey->paeRole
-    *p = pFTKeyInfo->paeRole;   // 0 is Supplicant
-    p++;
-
-    // set pSirKey->keyLength = keyLength;
-    p = pal_set_U16( p, pal_cpu_to_be16(pFTKeyInfo->keyLength) );
-
-    if ( pFTKeyInfo->keyLength && pFTKeyInfo->Key ) 
-    {   
-        palCopyMemory( pMac->hHdd, p, pFTKeyInfo->Key, pFTKeyInfo->keyLength ); 
+    if ( pFTKeyInfo->keyLength && pFTKeyInfo->Key )
+    {
+        palCopyMemory( pMac->hHdd, &keymaterial->key[ 0 ].key,
+                       pFTKeyInfo->Key, pFTKeyInfo->keyLength );
         if(pFTKeyInfo->keyLength == 16)
         {
-            smsLog(pMac, LOG1, "  SME Set keyIdx (%d) encType(%d) key = %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
-            pFTKeyInfo->keyId, edType, pFTKeyInfo->Key[0], pFTKeyInfo->Key[1], pFTKeyInfo->Key[2], pFTKeyInfo->Key[3], pFTKeyInfo->Key[4],
-            pFTKeyInfo->Key[5], pFTKeyInfo->Key[6], pFTKeyInfo->Key[7], pFTKeyInfo->Key[8],
-            pFTKeyInfo->Key[9], pFTKeyInfo->Key[10], pFTKeyInfo->Key[11], pFTKeyInfo->Key[12], pFTKeyInfo->Key[13], pFTKeyInfo->Key[14], pFTKeyInfo->Key[15]);
+          smsLog(pMac, LOG1, "SME Set Update Ind keyIdx (%d) encType(%d) key = "
+          "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
+          pMsg->keyMaterial.key[0].keyId, (tAniEdType)pMsg->keyMaterial.edType,
+          pMsg->keyMaterial.key[0].key[0], pMsg->keyMaterial.key[0].key[1],
+          pMsg->keyMaterial.key[0].key[2], pMsg->keyMaterial.key[0].key[3],
+          pMsg->keyMaterial.key[0].key[4], pMsg->keyMaterial.key[0].key[5],
+          pMsg->keyMaterial.key[0].key[6], pMsg->keyMaterial.key[0].key[7],
+          pMsg->keyMaterial.key[0].key[8], pMsg->keyMaterial.key[0].key[9],
+          pMsg->keyMaterial.key[0].key[10], pMsg->keyMaterial.key[0].key[11],
+          pMsg->keyMaterial.key[0].key[12], pMsg->keyMaterial.key[0].key[13],
+          pMsg->keyMaterial.key[0].key[14], pMsg->keyMaterial.key[0].key[15]);
         }
     }
 
+    vos_mem_copy( &pMsg->bssId[ 0 ],
+                  &pFTKeyInfo->peerMac[ 0 ],
+                  sizeof(tCsrBssid) );
+
+    smsLog(pMac, LOG1, "BSSID = %02X-%02X-%02X-%02X-%02X-%02X",
+           pMsg->bssId[0], pMsg->bssId[1], pMsg->bssId[2],
+           pMsg->bssId[3], pMsg->bssId[4], pMsg->bssId[5]);
+
     status = palSendMBMessage(pMac->hHdd, pMsg);
 
     return( status );
 }
 
+v_BOOL_t sme_GetFTPTKState(tHalHandle hHal)
+{
+  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+  return pMac->ft.ftSmeContext.setFTPTKState;
+}
+
+void sme_SetFTPTKState(tHalHandle hHal, v_BOOL_t state)
+{
+  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+  pMac->ft.ftSmeContext.setFTPTKState = state;
+}
+
 eHalStatus sme_FTUpdateKey( tHalHandle hHal, tCsrRoamSetKey * pFTKeyInfo )
 {
     tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
@@ -372,11 +397,28 @@
     switch(pMac->ft.ftSmeContext.FTState)
     {
     case eFT_SET_KEY_WAIT:
-       status = eHAL_STATUS_FT_PREAUTH_KEY_WAIT;
-       pMac->ft.ftSmeContext.FTState = eFT_START_READY;
+    if (sme_GetFTPreAuthState (hHal) == TRUE)
+      {
+          status = sme_FTSendUpdateKeyInd(pMac, pFTKeyInfo);
+          if (status != 0 )
+          {
+              smsLog( pMac, LOGE, "%s: Key set failure %d", __func__,
+                      status);
+              pMac->ft.ftSmeContext.setFTPTKState = FALSE;
+              status = eHAL_STATUS_FT_PREAUTH_KEY_FAILED;
+          }
+          else
+          {
+              pMac->ft.ftSmeContext.setFTPTKState = TRUE;
+              status = eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS;
+              smsLog( pMac, LOG1, "%s: Key set success", __func__);
+          }
+          sme_SetFTPreAuthState(hHal, FALSE);
+      }
+      pMac->ft.ftSmeContext.FTState = eFT_START_READY;
 #ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
-       smsLog( pMac, LOG1, "%s: state changed to %d", __func__,
-               pMac->ft.ftSmeContext.FTState);
+      smsLog( pMac, LOG1, "%s: state changed to %d status %d", __func__,
+              pMac->ft.ftSmeContext.FTState, status);
 #endif
        break;