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/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index 019efb8..2aee5e7 100644
--- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -1095,6 +1095,13 @@
     
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     // That done, pack the struct:
     if ( ! pAddTS->wmeTspecPresent )
     {
@@ -1687,6 +1694,13 @@
     #endif //TO SUPPORT BT-AMP
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     // That done, pack the struct:
     if ( ! pAddTS->wmeTspecPresent )
     {
@@ -1869,6 +1883,13 @@
     #endif //TO SUPPORT BT-AMP
     sirCopyMacAddr(pMacHdr->bssId, psessionEntry->bssId);
     
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     // That done, pack the struct:
     if ( !wmmTspecPresent )
     {
@@ -3660,6 +3681,13 @@
     // Prepare the BSSID
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
     
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     nStatus = dot11fPackDisassociation( pMac, &frm, pFrame +
                                         sizeof(tSirMacMgmtHdr),
                                         nPayload, &nPayload );
@@ -3836,6 +3864,13 @@
     // Prepare the BSSID
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     nStatus = dot11fPackDeAuth( pMac, &frm, pFrame +
                                 sizeof(tSirMacMgmtHdr),
                                 nPayload, &nPayload );
@@ -4066,6 +4101,13 @@
         return eSIR_FAILURE;    // just allocated...
     }
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     nStatus = dot11fPackMeasurementReport( pMac, &frm, pFrame +
                                            sizeof(tSirMacMgmtHdr),
                                            nPayload, &nPayload );
@@ -4185,6 +4227,13 @@
         return;                 // just allocated...
     }
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     nStatus = dot11fPackTPCRequest( pMac, &frm, pFrame +
                                     sizeof(tSirMacMgmtHdr),
                                     nPayload, &nPayload );
@@ -4312,6 +4361,13 @@
         return eSIR_FAILURE;    // just allocated...
     }
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     nStatus = dot11fPackTPCReport( pMac, &frm, pFrame +
                                    sizeof(tSirMacMgmtHdr),
                                    nPayload, &nPayload );
@@ -4454,6 +4510,14 @@
         return eSIR_FAILURE;    // just allocated...
     }
 #endif
+
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     nStatus = dot11fPackChannelSwitch( pMac, &frm, pFrame +
                                        sizeof(tSirMacMgmtHdr),
                                        nPayload, &nPayload );
@@ -4883,6 +4947,13 @@
     #endif//TO SUPPORT BT-AMP
     sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
+#ifdef WLAN_FEATURE_11W
+    if ( psessionEntry->limRmfEnabled )
+    {
+        pMacHdr->fc.wep = 1;
+    }
+#endif
+
     // Now, we're ready to "pack" the frames
     nStatus = dot11fPackAddBAReq( pMac,
       &frmAddBAReq,
@@ -5081,6 +5152,13 @@
       #endif // TO SUPPORT BT-AMP
       sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
+#ifdef WLAN_FEATURE_11W
+      if ( psessionEntry->limRmfEnabled )
+      {
+        pMacHdr->fc.wep = 1;
+      }
+#endif
+
       // Now, we're ready to "pack" the frames
       nStatus = dot11fPackAddBARsp( pMac,
           &frmAddBARsp,
@@ -5275,6 +5353,13 @@
       #endif //TO SUPPORT BT-AMP
       sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
 
+#ifdef WLAN_FEATURE_11W
+      if ( psessionEntry->limRmfEnabled )
+      {
+        pMacHdr->fc.wep = 1;
+      }
+#endif
+
       // Now, we're ready to "pack" the frames
       nStatus = dot11fPackDelBAInd( pMac,
           &frmDelBAInd,
@@ -5435,6 +5520,13 @@
 
    sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
 
+#ifdef WLAN_FEATURE_11W
+   if ( psessionEntry->limRmfEnabled )
+   {
+       pMacHdr->fc.wep = 1;
+   }
+#endif
+
    // Now, we're ready to "pack" the frames
    nStatus = dot11fPackNeighborReportRequest( pMac,
          &frm,
@@ -5599,6 +5691,13 @@
 
    sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
 
+#ifdef WLAN_FEATURE_11W
+   if ( psessionEntry->limRmfEnabled )
+   {
+       pMacHdr->fc.wep = 1;
+   }
+#endif
+
    // Now, we're ready to "pack" the frames
    nStatus = dot11fPackLinkMeasurementReport( pMac,
          &frm,
@@ -5785,6 +5884,13 @@
 
    sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
 
+#ifdef WLAN_FEATURE_11W
+   if ( psessionEntry->limRmfEnabled )
+   {
+       pMacHdr->fc.wep = 1;
+   }
+#endif
+
    // Now, we're ready to "pack" the frames
    nStatus = dot11fPackRadioMeasurementReport( pMac,
          frm,
@@ -5858,44 +5964,55 @@
  *
  * \param pMac    The global tpAniSirGlobal object
  *
- * \param peer    The Mac address of the AP to which this action frame is 
-addressed
+ * \param transId Transaction identifier received in SA query request action frame
  *
- * \param transId Transaction identifier received in SA query request action 
-frame 
+ * \param peer    The Mac address of the AP to which this action frame is addressed
+ *
+ * \param psessionEntry The PE session entry
  * 
  * \return eSIR_SUCCESS if setup completes successfully
  *         eSIR_FAILURE is some problem is encountered
  */
 
-tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, tANI_U16 transId,
+tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, tANI_U8 *transId,
 tSirMacAddr peer,tpPESession psessionEntry)
 {
 
-   tDot11wSaQueryRsp  frm; // SA query reponse action frame
+   tDot11fSaQueryRsp  frm; // SA query reponse action frame
    tANI_U8            *pFrame;
    tSirRetStatus      nSirStatus;
    tpSirMacMgmtHdr    pMacHdr;
-   tANI_U32           nBytes, nPayload;
+   tANI_U32           nBytes, nPayload, nStatus;
    void               *pPacket;
    eHalStatus         halstatus;
-   // Local variables used to dump prepared SA query response frame
-   tANI_U8            *pDump; 
-   tANI_U16           dumpCount;
-   tANI_U8             txFlag = 0;
-   //tANI_U16 nBytes
+   tANI_U8            txFlag = 0;
    
    palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
-   frm.category  = SIR_MAC_ACTION_SA_QUERY;
-   /*11w action  fiedl is :
+   frm.Category.category  = SIR_MAC_ACTION_SA_QUERY;
+   /*11w action  field is :
     action: 0 --> SA query request action frame
     action: 1 --> SA query response action frame */ 
-   frm.action    = 1;
-   /*11w Draft9.0 SA query response transId is same as
+   frm.Action.action    = SIR_MAC_SA_QUERY_RSP;
+   /*11w SA query response transId is same as
      SA query request transId*/
-   frm.transId   = transId;
+   vos_mem_copy( &frm.TransactionId.transId[0], &transId[0], 2 );
 
-   nPayload = sizeof(tDot11wSaQueryRsp);
+   nStatus = dot11fGetPackedSaQueryRspSize(pMac, &frm, &nPayload);
+   if ( DOT11F_FAILED( nStatus ) )
+   {
+      limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+               "or a SA Query Response (0x%08x)."),
+            nStatus );
+      // We'll fall back on the worst case scenario:
+      nPayload = sizeof( tDot11fSaQueryRsp );
+   }
+   else if ( DOT11F_WARNED( nStatus ) )
+   {
+      limLog( pMac, LOGW, FL("There were warnings while calculating"
+               "the packed size for an SA Query Response"
+               " (0x%08x)."), nStatus );
+   }
+
    nBytes = nPayload + sizeof( tSirMacMgmtHdr );
    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,  nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
@@ -5908,37 +6025,85 @@
    // Paranoia:
    palZeroMemory( pMac->hHdd, pFrame, nBytes );
 
-   // Next, we fill out the buffer descriptor:
-   nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
-                                SIR_MAC_MGMT_ACTION, peer,psessionEntry->selfMacAddr );
-   if ( eSIR_SUCCESS != nSirStatus )
-   {
-      limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
-                              "tor for a TPC Report (%d).\n"),
-               nSirStatus );
-      palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
-      return eSIR_FAILURE;    // just allocated...
-   }
+   // Copy necessary info to BD
+   if ( eSIR_SUCCESS !=
+         (nSirStatus = limPopulateMacHeader( pMac,
+                                      pFrame,
+                                      SIR_MAC_MGMT_FRAME,
+                                      SIR_MAC_MGMT_ACTION,
+                                      peer, psessionEntry->selfMacAddr)))
+      goto returnAfterError;
 
+   // Update A3 with the BSSID
    pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
 
-   // Pack 11w SA query response frame
-   DOT11F_MEMCPY(pMac, (tANI_U8 *)(pFrame + sizeof(tSirMacMgmtHdr)),(tANI_U8 *)&frm, nPayload);
-   pDump = (tANI_U8 *) pFrame;
+   sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
 
-   halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
-                            HAL_TXRX_FRM_802_11_MGMT,
-                            ANI_TXDIR_TODS,
-                            7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
-                            limTxComplete, pFrame,txFlag);
-   if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+   // Since this is a SA Query Response, set the "protect" (aka WEP) bit
+   // in the FC
+   if ( psessionEntry->limRmfEnabled )
    {
-      limLog( pMac, LOGE, FL("Failed to send a SA Query resp frame "
-                             "(%X)!\n"),halstatus );
-        //Pkt will be freed up by the callback
-      return eSIR_FAILURE;    // just allocated...
+       pMacHdr->fc.wep = 1;
    }
 
-   return eSIR_SUCCESS;
-}
+   // Pack 11w SA query response frame
+   nStatus = dot11fPackSaQueryRsp( pMac,
+         &frm,
+         pFrame + sizeof( tSirMacMgmtHdr ),
+         nPayload,
+         &nPayload );
+
+   if ( DOT11F_FAILED( nStatus ))
+   {
+      limLog( pMac, LOGE,
+            FL( "Failed to pack an SA Query Response (0x%08x)." ),
+            nStatus );
+      // FIXME - Need to convert to tSirRetStatus
+      nSirStatus = eSIR_FAILURE;
+      goto returnAfterError;
+   }
+   else if ( DOT11F_WARNED( nStatus ))
+   {
+      limLog( pMac, LOGW,
+            FL( "There were warnings while packing SA Query Response (0x%08x)." ),
+            nStatus);
+   }
+
+   limLog( pMac, LOG1,
+         FL( "Sending a SA Query Response to " ));
+   limPrintMacAddr( pMac, peer, LOGW );
+
+    if ( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+       || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+         ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+         )
+    {
+        txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+    }
+
+   if ( eHAL_STATUS_SUCCESS !=
+         (halstatus = halTxFrame( pMac,
+                                  pPacket,
+                                  (tANI_U16) nBytes,
+                                  HAL_TXRX_FRM_802_11_MGMT,
+                                  ANI_TXDIR_TODS,
+                                  7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+                                  limTxComplete,
+                                  pFrame, txFlag )))
+   {
+      PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );)
+      nSirStatus = eSIR_FAILURE;
+      //Pkt will be freed up by the callback
+      return nSirStatus;
+   }
+   else {
+      return eSIR_SUCCESS;
+   }
+
+returnAfterError:
+   palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+   return nSirStatus;
+} // End limSendSaQueryResponseFrame
 #endif