wlan: Add PMF (802.11w) support for station mode

These changes add Protected Management Frames (802.11w) support for
the device in station mode.

Change-Id: I2cdc60c4a9ed3ab40303de11ca3b679a9fe1d455
CRs-Fixed: 452422, 452831, 455139, 450564, 452558
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 932a388..901217b 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -81,6 +81,9 @@
     eCSR_AUTH_TYPE_CCKM_WPA,
     eCSR_AUTH_TYPE_CCKM_RSN,
 #endif /* FEATURE_WLAN_CCX */
+#ifdef WLAN_FEATURE_11W
+    eCSR_AUTH_TYPE_RSN_PSK_SHA256,
+#endif
     eCSR_NUM_OF_SUPPORT_AUTH_TYPE,
     eCSR_AUTH_TYPE_FAILED = 0xff,
     eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED,
@@ -459,6 +462,9 @@
     eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, //Disaconnect all the clients
     eCSR_ROAM_SEND_P2P_STOP_BSS, //Stopbss triggered from SME due to different
                                  // beacon interval
+#ifdef WLAN_FEATURE_11W
+    eCSR_ROAM_UNPROT_MGMT_FRAME_IND,
+#endif
 
 }eRoamCmdStatus;
 
@@ -704,7 +710,8 @@
 
 }eCsrWEPStaticKeyID;
 
-#define CSR_MAX_NUM_KEY     (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 1)
+// Two extra key indicies are used for the IGTK (which is used by BIP)
+#define CSR_MAX_NUM_KEY     (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1)
 
 typedef enum
 {
@@ -825,6 +832,13 @@
     //This field is for output only, not for input
     eCsrEncryptionType negotiatedMCEncryptionType;
 
+#ifdef WLAN_FEATURE_11W
+    // Management Frame Protection
+    tANI_BOOLEAN MFPEnabled;
+    tANI_U8 MFPRequired;
+    tANI_U8 MFPCapable;
+#endif
+
     tCsrKeys Keys;
     eCsrCBChoice CBMode; //up, down or auto
     tCsrChannelInfo ChannelInfo;
diff --git a/CORE/SME/inc/csrSupport.h b/CORE/SME/inc/csrSupport.h
index a28f33d..45a0586 100644
--- a/CORE/SME/inc/csrSupport.h
+++ b/CORE/SME/inc/csrSupport.h
@@ -40,15 +40,13 @@
  */
 
 /** ------------------------------------------------------------------------- * 
-    ------------------------------------------------------------------------- *  
 
-  
     \file csrSupport.h
-  
+
     Exports and types for the Common Scan and Roaming supporting interfaces.
   
    Copyright (C) 2006 Airgo Networks, Incorporated
- 
+
    ========================================================================== */
 #ifndef CSR_SUPPORT_H__
 #define CSR_SUPPORT_H__
@@ -593,7 +591,9 @@
     tANI_U16 NoPairwise:1;
     tANI_U16 PTKSAReplayCounter:2;
     tANI_U16 GTKSAReplayCounter:2;
-    tANI_U16 Reserved:10;
+    tANI_U16 MFPRequired:1;
+    tANI_U16 MFPCapable:1;
+    tANI_U16 Reserved:8;
 } __ani_attr_packed tCsrRSNCapabilities;
 
 typedef __ani_attr_pre_packed struct tagCsrRSNPMKIe 
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 71f1da8..c1555ac 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -150,6 +150,9 @@
         n = AUTH_WPA2_EAP;
         break;
     case eCSR_AUTH_TYPE_RSN_PSK:
+#ifdef WLAN_FEATURE_11W
+    case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+#endif
         n = AUTH_WPA2_PSK;
         break;
 #ifdef FEATURE_WLAN_WAPI
@@ -4436,6 +4439,10 @@
        (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) ||
        (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)
 #endif /* FEATURE_WLAN_WAPI */
+#ifdef WLAN_FEATURE_11W
+      ||
+       (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType)
+#endif /* FEATURE_WLAN_WAPI */
         )
     {
         if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
@@ -4451,6 +4458,9 @@
                 (eCSR_AUTH_TYPE_FT_RSN == authType) ||
                 (eCSR_AUTH_TYPE_FT_RSN_PSK == authType) ||
 #endif /* WLAN_FEATURE_VOWIFI_11R */
+#if defined WLAN_FEATURE_11W
+                (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
+#endif
                 (eCSR_AUTH_TYPE_RSN_PSK == authType))
             {
                 if(pIesLocal->RSN.present)
@@ -5582,6 +5592,11 @@
         pDstProfile->negotiatedUCEncryptionType = pSrcProfile->negotiatedUCEncryptionType;
         pDstProfile->negotiatedMCEncryptionType = pSrcProfile->negotiatedMCEncryptionType;
         pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType;
+#ifdef WLAN_FEATURE_11W
+        pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+        pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+        pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
         pDstProfile->BSSType = pSrcProfile->BSSType;
         pDstProfile->phyMode = pSrcProfile->phyMode;
         pDstProfile->csrPersona = pSrcProfile->csrPersona;
@@ -6563,6 +6578,9 @@
               || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) 
               || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) 
               || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) 
+#ifdef WLAN_FEATURE_11W
+              || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+#endif
               || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
         && (pMac->roam.configParam.isCcxIniFeatureEnabled))
     {
@@ -7829,16 +7847,15 @@
 
 #ifdef WLAN_FEATURE_11W
         //Check for 11w BIP
-        else if ( eCSR_ENCRYPT_TYPE_AES_CMAC == pSetKey->encType )
+        else if (eCSR_ENCRYPT_TYPE_AES_CMAC == pSetKey->encType)
         {
-            tANI_U16 count = 0;
-            if ( pSetKey->keyLength < CSR_AES_KEY_LEN )
+            if (pSetKey->keyLength < CSR_AES_KEY_LEN)
             {
-                smsLog( pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength );
+                smsLog(pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength);
                 break;
             }
             pCommand->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN;
-            palCopyMemory( pMac->hHdd, pCommand->u.setKeyCmd.Key, pSetKey->Key, CSR_AES_KEY_LEN );
+            palCopyMemory(pMac->hHdd, pCommand->u.setKeyCmd.Key, pSetKey->Key, CSR_AES_KEY_LEN);
         }
 #endif
         status = eHAL_STATUS_SUCCESS;
@@ -11878,6 +11895,19 @@
         dwTmp = pal_cpu_to_be32( csrTranslateEncryptTypeToEdType( pProfile->negotiatedMCEncryptionType) );
         palCopyMemory( pMac->hHdd, pBuf, &dwTmp, sizeof(tANI_U32) );
         pBuf += sizeof(tANI_U32);
+#ifdef WLAN_FEATURE_11W
+        //MgmtEncryption
+        if (pProfile->MFPEnabled)
+        {
+            dwTmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC);
+        }
+        else
+        {
+            dwTmp = pal_cpu_to_be32(eSIR_ED_NONE);
+        }
+        palCopyMemory(pMac->hHdd, pBuf, &dwTmp, sizeof(tANI_U32));
+        pBuf += sizeof(tANI_U32);
+#endif
 #ifdef WLAN_FEATURE_VOWIFI_11R
         pProfile->MDID.mdiePresent = pBssDescription->mdiePresent;
         if (csrIsProfile11r( pProfile )
@@ -11912,6 +11942,9 @@
                        || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
                        || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
                        || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+                       || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+#endif
                        || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
                  && (pMac->roam.configParam.isCcxIniFeatureEnabled))
         {
@@ -11945,6 +11978,9 @@
                   || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
                   || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
                   || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+                  || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+#endif
                   || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
             && (pMac->roam.configParam.isCcxIniFeatureEnabled))
         {
diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c
index 6d9e6a9..25bff95 100644
--- a/CORE/SME/src/csr/csrUtil.c
+++ b/CORE/SME/src/csr/csrUtil.c
@@ -2753,6 +2753,9 @@
 #ifdef FEATURE_WLAN_CCX
         case eCSR_AUTH_TYPE_CCKM_RSN:
 #endif 
+#ifdef WLAN_FEATURE_11W
+        case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+#endif
             fRSNProfile = TRUE;
             break;
 
@@ -3410,7 +3413,7 @@
 {
 #ifdef WLAN_FEATURE_11W
     return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) ||
-            csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[05], Oui ));
+            csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ));
 #else
     return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) );
 #endif
@@ -3427,6 +3430,15 @@
 #endif
 }
 
+#ifdef WLAN_FEATURE_11W
+static tANI_BOOLEAN csrIsAuthRSNPskSha256( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
+                                      tANI_U8 cAllSuites,
+                                      tANI_U8 Oui[] )
+{
+    return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ) );
+}
+#endif
+
 static tANI_BOOLEAN csrIsAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE],
                                 tANI_U8 cAllSuites,
                                 tANI_U8 Oui[] )
@@ -3636,6 +3648,13 @@
                     if (eCSR_AUTH_TYPE_RSN_PSK == pAuthType->authType[i])
                         negAuthType = eCSR_AUTH_TYPE_RSN_PSK;
                 }
+#ifdef WLAN_FEATURE_11W
+                if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPskSha256( pMac, AuthSuites, cAuthSuites, Authentication ) )
+                {
+                    if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == pAuthType->authType[i])
+                        negAuthType = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+                }
+#endif
 
                 // The 1st auth type in the APs RSN IE, to match stations connecting
                 // profiles auth type will cause us to exit this loop
@@ -3676,9 +3695,12 @@
             Capabilities->PreAuthSupported = (pRSNIe->RSN_Cap[0] >> 0) & 0x1 ; // Bit 0 PreAuthentication
             Capabilities->NoPairwise = (pRSNIe->RSN_Cap[0] >> 1) & 0x1 ; // Bit 1 No Pairwise
             Capabilities->PTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 2) & 0x3 ; // Bit 2, 3 PTKSA Replay Counter
-            Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4,5 GTKSA Replay Counter
-            Capabilities->Reserved = (pRSNIe->RSN_Cap[0] >> 6) & 0x3 ; // remaining reserved
-            Capabilities->Reserved = (Capabilities->Reserved >> 2) | (pRSNIe->RSN_Cap[1]  & 0xff) ; // remaining reserved
+            Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4, 5 GTKSA Replay Counter
+#ifdef WLAN_FEATURE_11W
+            Capabilities->MFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1 ; // Bit 6 MFPR
+            Capabilities->MFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1 ; // Bit 7 MFPC
+#endif
+            Capabilities->Reserved = pRSNIe->RSN_Cap[1]  & 0xff ; // remaining reserved
         }
     }
     return( fAcceptableCyphers );
@@ -3798,7 +3820,12 @@
         // !!REVIEW - What should STA put in RSN capabilities, currently
         // just putting back APs capabilities
         // For one, we shouldn't EVER be sending out "pre-auth supported".  It is an AP only capability
+        // For another, we should use the Management Frame Protection values given by the supplicant
         RSNCapabilities.PreAuthSupported = 0;
+#ifdef WLAN_FEATURE_11W
+        RSNCapabilities.MFPRequired = pProfile->MFPRequired;
+        RSNCapabilities.MFPCapable = pProfile->MFPCapable;
+#endif
         *(tANI_U16 *)( &pAuthSuite->AuthOui[ 1 ] ) = *((tANI_U16 *)(&RSNCapabilities));
 
         pPMK = (tCsrRSNPMKIe *)( ((tANI_U8 *)(&pAuthSuite->AuthOui[ 1 ])) + sizeof(tANI_U16) );
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index f19da09..d2d10ff 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -118,6 +118,11 @@
 tANI_BOOLEAN csrIsScanAllowed(tpAniSirGlobal pMac);
 #endif
 
+#ifdef WLAN_FEATURE_11W
+eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
+                                      tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm );
+#endif
+
 //Internal SME APIs
 eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme)
 {
@@ -1400,6 +1405,34 @@
 #endif // WLAN_FEATURE_PACKET_FILTERING
 
 
+#ifdef WLAN_FEATURE_11W
+/*------------------------------------------------------------------
+ *
+ * Handle the unprotected management frame indication from LIM and
+ * forward it to HDD.
+ *
+ *------------------------------------------------------------------*/
+
+eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
+                                      tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
+{
+    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+    eHalStatus  status = eHAL_STATUS_SUCCESS;
+    tCsrRoamInfo pRoamInfo = {0};
+    tANI_U32 SessionId = pSmeMgmtFrm->sessionId;
+
+    pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen;
+    pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
+    pRoamInfo.frameType = pSmeMgmtFrm->frameType;
+
+    /* forward the mgmt frame to HDD */
+    csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
+
+    return status;
+}
+#endif
+
+
 /*--------------------------------------------------------------------------
 
   \brief sme_ProcessMsg() - The main message processor for SME.
@@ -1708,6 +1741,20 @@
                 }
 #endif
 
+#ifdef WLAN_FEATURE_11W
+           case eWNI_SME_UNPROT_MGMT_FRM_IND:
+                if (pMsg->bodyptr)
+                {
+                    sme_UnprotectedMgmtFrmInd(pMac, pMsg->bodyptr);
+                    vos_mem_free(pMsg->bodyptr);
+                }
+                else
+                {
+                    smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_UNPROT_MGMT_FRM_IND), nothing to process");
+                }
+                break;
+#endif
+
           default:
 
              if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN )