Fix for device not coming to BMPS after teardown TDLS link

Once the TDLS link is up, the device goes into FULL_POWER mode
and never comes to BMPS mode even after all the TDLS links are
torn down.
Set the pmcState to FULL_POWER at the time of TDLS_ENABLE_LINK
and resets to BMPS mode after all the TDLS links are torn down.

CRs-Fixed: 452166
Change-Id: I3e2a25dca8d10fbf901ae739384c16e98f9abb60
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 1cd94d0..9921c53 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -958,8 +958,8 @@
 #ifdef WLAN_FEATURE_P2P
     tSirRemainOnChnReq  *gpLimRemainOnChanReq; //hold remain on chan request in this buf
     vos_list_t  gLimMgmtFrameRegistratinQueue;
-    tANI_U32    actionFrameSessionId;
 #endif
+    tANI_U32    mgmtFrameSessionId;
     tSirBackgroundScanMode gLimBackgroundScanMode;
 
 #if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
@@ -1096,7 +1096,7 @@
 #ifdef FEATURE_OEM_DATA_SUPPORT
     tOemDataStruct oemData;
 #endif
-#ifdef FEATURE_WLAN_TDLS
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
     tCsrTdlsCtxStruct tdlsCtx ;
 #endif
 #ifdef ANI_PRODUCT_TYPE_CLIENT
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index b139e7b..382b6e6 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4244,6 +4244,13 @@
    tANI_U16               length;
    tANI_U8                sessionId;     // Session ID
 } tSirTdlsDelAllPeerInd, *tpSirTdlsDelAllPeerInd;
+typedef struct sSirMgmtTxCompletionInd
+{
+   tANI_U16               messageType;
+   tANI_U16               length;
+   tANI_U8                sessionId;     // Session ID
+   tANI_U32               txCompleteStatus;
+} tSirMgmtTxCompletionInd, *tpSirMgmtTxCompletionInd;
 #endif /* FEATURE_WLAN_TDLS */
 
 #ifdef FEATURE_WLAN_TDLS_INTERNAL
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index b78af22..6c555a1 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -355,6 +355,7 @@
     eWNI_SME_TDLS_DEL_STA_RSP,
     eWNI_SME_TDLS_DEL_STA_IND,
     eWNI_SME_TDLS_DEL_ALL_PEER_IND,
+    eWNI_SME_MGMT_FRM_TX_COMPLETION_IND,
 #endif
     //NOTE: If you are planning to add more mesages, please make sure that 
     //SIR_LIM_ITC_MSG_TYPES_BEGIN is moved appropriately. It is set as
diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c
index a49a1ba..071b9cb 100644
--- a/CORE/MAC/src/pe/lim/limApi.c
+++ b/CORE/MAC/src/pe/lim/limApi.c
@@ -1082,10 +1082,8 @@
         return eSIR_FAILURE;
     }
 #endif
+    pMac->lim.mgmtFrameSessionId = 0xff;
 
-#ifdef WLAN_FEATURE_P2P
-    pMac->lim.actionFrameSessionId = 0xff;
-#endif
     if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pMac->lim.lkPeGlobalLock ) ) )
     {
         PELOGE(limLog(pMac, LOGE, FL("pe lock init failed!\n"));)
diff --git a/CORE/MAC/src/pe/lim/limP2P.c b/CORE/MAC/src/pe/lim/limP2P.c
index f3757d5..638ca96 100644
--- a/CORE/MAC/src/pe/lim/limP2P.c
+++ b/CORE/MAC/src/pe/lim/limP2P.c
@@ -563,7 +563,7 @@
 
     /* If remain on channel timer expired and action frame is pending then 
      * indicaiton confirmation with status failure */
-    if (pMac->lim.actionFrameSessionId != 0xff)
+    if (pMac->lim.mgmtFrameSessionId != 0xff)
     {
        limP2PActionCnf(pMac, 0);
     }
@@ -678,14 +678,14 @@
 
 eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess)
 {
-    if (pMac->lim.actionFrameSessionId != 0xff)
+    if (pMac->lim.mgmtFrameSessionId != 0xff)
     {
         /* The session entry might be invalid(0xff) action confirmation received after
          * remain on channel timer expired */
         limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
                 (txCompleteSuccess ? eSIR_SME_SUCCESS : eSIR_SME_SEND_ACTION_FAIL),
-                pMac->lim.actionFrameSessionId, 0);
-        pMac->lim.actionFrameSessionId = 0xff;
+                pMac->lim.mgmtFrameSessionId, 0);
+        pMac->lim.mgmtFrameSessionId = 0xff;
     }
 
     return eHAL_STATUS_SUCCESS;
@@ -1018,7 +1018,7 @@
            limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, 
                halstatus, pMbMsg->sessionId, 0);
         }
-        pMac->lim.actionFrameSessionId = 0xff;
+        pMac->lim.mgmtFrameSessionId = 0xff;
     }
     else
     {
@@ -1032,13 +1032,13 @@
              limLog( pMac, LOGE, FL("could not send action frame!\n" ));
              limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, halstatus, 
                 pMbMsg->sessionId, 0);
-             pMac->lim.actionFrameSessionId = 0xff;
+             pMac->lim.mgmtFrameSessionId = 0xff;
         }
         else
         {
-             pMac->lim.actionFrameSessionId = pMbMsg->sessionId;
+             pMac->lim.mgmtFrameSessionId = pMbMsg->sessionId;
              limLog( pMac, LOG2, FL("lim.actionFrameSessionId = %lu\n" ), 
-                     pMac->lim.actionFrameSessionId);
+                     pMac->lim.mgmtFrameSessionId);
 
         }
     }
diff --git a/CORE/MAC/src/pe/lim/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c
index 5a0b86e..920ea4b 100644
--- a/CORE/MAC/src/pe/lim/limProcessTdls.c
+++ b/CORE/MAC/src/pe/lim/limProcessTdls.c
@@ -441,6 +441,29 @@
 }
 
 /*
+ * TX Complete for Management frames
+ */
+ eHalStatus limMgmtTXComplete(tpAniSirGlobal pMac,
+                                   tANI_U32 txCompleteSuccess)
+{
+    tpPESession psessionEntry = NULL ;
+
+    if (0xff != pMac->lim.mgmtFrameSessionId)
+    {
+        psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.mgmtFrameSessionId);
+        if (NULL == psessionEntry)
+        {
+            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
+                      ("%s: sessionID %d is not found"), __func__, pMac->lim.mgmtFrameSessionId);
+            return eHAL_STATUS_FAILURE;
+        }
+        limSendSmeMgmtTXCompletion(pMac, psessionEntry, txCompleteSuccess);
+        pMac->lim.mgmtFrameSessionId = 0xff;
+    }
+    return eHAL_STATUS_SUCCESS;
+}
+
+/*
  * This function can be used for bacst or unicast discovery request
  * We are not differentiating it here, it will all depnds on peer MAC address,
  */
@@ -608,22 +631,26 @@
     LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA "),
             SIR_MAC_TDLS_DIS_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ) ));
 
-    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                             HAL_TXRX_FRM_802_11_DATA,
                             ANI_TXDIR_TODS,
                             7,
-                            limTxComplete, pFrame, HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME);
+                            limTxComplete, pFrame,
+                            limMgmtTXComplete,
+                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME);
     if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
     {
+        pMac->lim.mgmtFrameSessionId = 0xff;
         limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
         return eSIR_FAILURE;
-
     }
+    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
 
     return eSIR_SUCCESS;
 
 }
 
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
 /*
  * Once Discovery response is sent successfully (or failure) on air, now send
  * response to PE and send del STA to HAL.
@@ -632,7 +659,6 @@
                                            tANI_U32 txCompleteSuccess)
 {
     eHalStatus status = eHAL_STATUS_SUCCESS ;
-#ifdef FEATURE_WLAN_TDLS_INTERNAL
     tpDphHashNode pStaDs = NULL ;
     tSirTdlsPeerInfo *peerInfo = 0 ;
 
@@ -703,10 +729,12 @@
         status = eHAL_STATUS_SUCCESS ;
     }
     //pMac->hal.pCBackFnTxComp = NULL ;
-#endif 
     return status ;
 
 }
+#endif
+
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
 /*
  * Once setup CNF is sent successfully (or failure) on air, now send
  * response to PE and send del STA to HAL.
@@ -715,7 +743,6 @@
                                            tANI_U32 txCompleteSuccess)
 {
     eHalStatus status = eHAL_STATUS_SUCCESS ;
-#ifdef FEATURE_WLAN_TDLS_INTERNAL
     tLimTdlsLinkSetupPeer *peerInfo = 0 ;
     /* find peer by looking into the list by expected state */
     limTdlsFindSetupPeerByState(pMac, 
@@ -762,11 +789,11 @@
         status = eHAL_STATUS_SUCCESS ;
     }
     //pMac->hal.pCBackFnTxComp = NULL ;
-#endif 
     return status ;
-
 }
+#endif
 
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
 /*
  * Tx Complete for Teardown frame
  */
@@ -774,7 +801,6 @@
                                            tANI_U32 txCompleteSuccess)  
 {
     eHalStatus status = eHAL_STATUS_SUCCESS ;
-#ifdef FEATURE_WLAN_TDLS_INTERNAL
     tpDphHashNode pStaDs = NULL ;
     tLimTdlsLinkSetupPeer *peerInfo = 0 ;
     tpPESession psessionEntry = NULL ;
@@ -883,9 +909,9 @@
     }
 #endif  
     status = eHAL_STATUS_SUCCESS ;
-#endif
     return status ;
 }
+#endif
 
 /*
  * Send TDLS discovery response frame on direct link.
@@ -1074,14 +1100,15 @@
                             ANI_TXDIR_IBSS,
                             0,
                             limTxComplete, pFrame, 
-                            limTdlsDisRspTxComplete,
+                            limMgmtTXComplete,
                             HAL_USE_SELF_STA_REQUESTED_MASK );
     if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
     {
+        pMac->lim.mgmtFrameSessionId = 0xff;
         limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
         return eSIR_FAILURE;
-
     }
+    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
 
     return eSIR_SUCCESS;
 
@@ -1272,17 +1299,21 @@
     LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"),
             SIR_MAC_TDLS_SETUP_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ) ));
 
-    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                             HAL_TXRX_FRM_802_11_DATA,
                             ANI_TXDIR_TODS,
                             7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
-                            limTxComplete, pFrame, HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
+                            limTxComplete, pFrame,
+                            limMgmtTXComplete,
+                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
+
     if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
     {
+        pMac->lim.mgmtFrameSessionId = 0xff;
         limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
         return eSIR_FAILURE;
-
     }
+    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
 
     return eSIR_SUCCESS;
 
@@ -1468,14 +1499,16 @@
                             ANI_TXDIR_TODS,
                             7,
                             limTxComplete, pFrame, 
-                            limTdlsTeardownTxComplete,
+                            limMgmtTXComplete,
                             HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
     if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
     {
+        pMac->lim.mgmtFrameSessionId = 0xff;
         limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
         return eSIR_FAILURE;
 
     }
+    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
     return eSIR_SUCCESS;
 
 }
@@ -1664,18 +1697,21 @@
     LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"),
          SIR_MAC_TDLS_SETUP_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP) ));
 
-    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                             HAL_TXRX_FRM_802_11_DATA,
                             ANI_TXDIR_TODS,
                             //ANI_TXDIR_IBSS,
                             7,
-                            limTxComplete, pFrame, HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
+                            limTxComplete, pFrame,
+                            limMgmtTXComplete,
+                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
     if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
     {
+        pMac->lim.mgmtFrameSessionId = 0xff;
         limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
         return eSIR_FAILURE;
-
     }
+    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
 
     return eSIR_SUCCESS;
 
@@ -1890,16 +1926,18 @@
                             ANI_TXDIR_TODS,
                             7,
                             limTxComplete, pFrame, 
-                            limTdlsSetupCnfTxComplete,
+                            limMgmtTXComplete,
                             HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
 
 
     if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
     {
+        pMac->lim.mgmtFrameSessionId = 0xff;
         limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
         return eSIR_FAILURE;
 
     }
+    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
 
     return eSIR_SUCCESS;
 }
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index 853872f..dc25d9a 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -1522,6 +1522,57 @@
     limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
     return;
 }/*** end limSendSmeTDLSDeleteAllPeerInd() ***/
+
+/**
+ * limSendSmeMgmtTXCompletion()
+ *
+ *FUNCTION:
+ * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
+ * message to SME.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param  pMac   - Pointer to global MAC structure
+ * @param  psessionEntry - Pointer to the session entry
+ * @param  txCompleteStatus - TX Complete Status of Mgmt Frames
+ * @return None
+ */
+void
+limSendSmeMgmtTXCompletion(tpAniSirGlobal pMac,
+                           tpPESession psessionEntry,
+                           tANI_U32 txCompleteStatus)
+{
+    tSirMsgQ  mmhMsg;
+    tSirMgmtTxCompletionInd  *pSirMgmtTxCompletionInd;
+
+    if ( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirMgmtTxCompletionInd, sizeof(tSirMgmtTxCompletionInd)))
+    {
+        limLog(pMac, LOGP, FL("palAllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND"));
+        return;
+    }
+
+    //messageType
+    pSirMgmtTxCompletionInd->messageType = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+    pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd);
+
+    //sessionId
+    pSirMgmtTxCompletionInd->sessionId = psessionEntry->smeSessionId;
+
+    pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus;
+
+    mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+    mmhMsg.bodyptr = pSirMgmtTxCompletionInd;
+    mmhMsg.bodyval = 0;
+
+
+    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+    return;
+}/*** end limSendSmeTDLSDeleteAllPeerInd() ***/
 #endif
 
 
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index a7c9ead..9812f4f 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -789,6 +789,9 @@
 tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac, 
                                                            tANI_U32 *pMsgBuf);
 void limSendSmeTDLSDeleteAllPeerInd(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void limSendSmeMgmtTXCompletion(tpAniSirGlobal pMac,
+                                tpPESession psessionEntry,
+                                tANI_U32 txCompleteStatus);
 tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry);
 eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, tpPESession);
 tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac,