wlan: Update channel switch request failure to HDD

Currently, Failure response from FW for channel switch request is
not honoured and thus misleading.
Fix is to honour the failure response from FW and update the same
to HDD.

Change-Id: I75e1fe0971ca51b61de3507cf3c26e453b4feb67
CRs-Fixed: 954212
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 84f9fbd..fe53ce9 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -2966,7 +2966,9 @@
               roamResult == eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ?
               "UPDATE_TDLS_PEER" :
               roamResult == eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
-              "LINK_ESTABLISH_REQ_RSP" : "UNKNOWN",
+              "LINK_ESTABLISH_REQ_RSP" :
+              roamResult == eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP ?
+              "CHANNEL_SWITCH_REQ_RSP" : "UNKNOWN",
               pRoamInfo->staId, MAC_ADDR_ARRAY(pRoamInfo->peerMac));
     switch( roamResult )
     {
@@ -3067,6 +3069,17 @@
             complete(&pAdapter->tdls_link_establish_req_comp);
             break;
         }
+        case eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP:
+        {
+            if (eSIR_SME_SUCCESS != pRoamInfo->statusCode)
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          "%s: Channel switch request failed. %d", __func__,
+                          pRoamInfo->statusCode);
+            else
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                          "%s: Channel switch request Success", __func__);
+            break;
+        }
         case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
         {
             hddTdlsPeer_t *curr_peer;
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 5ff54cb..aa2fac1 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4398,6 +4398,7 @@
     tANI_U16            transactionId; // Transaction ID for cmd
     tSirResultCodes        statusCode;
     tSirMacAddr            peerMac;
+    tANI_U16            sta_idx;
 }tSirTdlsChanSwitchReqRsp, *tpSirTdlsChanSwitchReqRsp;
 #endif /* FEATURE_WLAN_TDLS */
 
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 9717480..33da284 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -2232,6 +2232,8 @@
         {
             tpPESession     psessionEntry;
             tANI_U8         sessionId;
+            tDphHashNode   *pStaDs;
+            int i, aid;
             tTdlsChanSwitchParams *pTdlsChanSwitchParams;
             pTdlsChanSwitchParams = (tTdlsChanSwitchParams*) limMsg->bodyptr;
 
@@ -2251,10 +2253,26 @@
             }
             else
             {
+                for (i = 0;
+                     i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32);
+                                                                i++) {
+                    for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) {
+                        if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) {
+                            pStaDs = dphGetHashEntry(pMac,
+                                           (aid + i*(sizeof(tANI_U32) << 3)),
+                                            &psessionEntry->dph.dphHashTable);
+                              if ((NULL != pStaDs) &&
+                                   (pTdlsChanSwitchParams->staIdx ==
+                                                       pStaDs->staIndex))
+                                  goto send_chan_switch_resp;
+                        }
+                    }
+                }
+send_chan_switch_resp:
                 limSendSmeTdlsChanSwitchReqRsp(pMac,
                                                   psessionEntry->smeSessionId,
-                                                  NULL,
-                                                  NULL,
+                                                  pStaDs->staAddr,
+                                                  pStaDs,
                                                   pTdlsChanSwitchParams->status) ;
             }
             vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
diff --git a/CORE/MAC/src/pe/lim/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c
index b341efa..a6644b1 100644
--- a/CORE/MAC/src/pe/lim/limProcessTdls.c
+++ b/CORE/MAC/src/pe/lim/limProcessTdls.c
@@ -3094,12 +3094,18 @@
         PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
         return ;
     }
+
+    vos_mem_zero(pTdlsChanSwitchReqRsp, sizeof(tSirTdlsChanSwitchReqRsp));
+
     pTdlsChanSwitchReqRsp->statusCode = status ;
-    if ( peerMac )
+    if (pStaDs && peerMac )
     {
         vos_mem_copy(pTdlsChanSwitchReqRsp->peerMac, peerMac, sizeof(tSirMacAddr));
+        pTdlsChanSwitchReqRsp->sta_idx = pStaDs->staIndex;;
     }
+
     pTdlsChanSwitchReqRsp->sessionId = sessionId;
+
     mmhMsg.type = eWNI_SME_TDLS_CHANNEL_SWITCH_RSP ;
     mmhMsg.bodyptr = pTdlsChanSwitchReqRsp;
     mmhMsg.bodyval = 0;
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index e802f26..9d7338e 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -598,6 +598,7 @@
     eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND,
     eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND,
     eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP,
+    eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP,
 #endif
 
 }eCsrRoamResult;
diff --git a/CORE/SME/src/csr/csrTdlsProcess.c b/CORE/SME/src/csr/csrTdlsProcess.c
index d0da423..8bccfc2 100644
--- a/CORE/SME/src/csr/csrTdlsProcess.c
+++ b/CORE/SME/src/csr/csrTdlsProcess.c
@@ -971,6 +971,19 @@
                                 eCSR_ROAM_TDLS_STATUS_UPDATE,
                                 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP);
 #endif
+            tSirTdlsChanSwitchReqRsp *ChanSwitchReqRsp =
+                            (tSirTdlsChanSwitchReqRsp *) pMsgBuf ;
+            tCsrRoamInfo roamInfo = {0} ;
+
+            vos_mem_copy(&roamInfo.peerMac, ChanSwitchReqRsp->peerMac,
+                         sizeof(tSirMacAddr));
+            roamInfo.staId  = (tANI_U8)ChanSwitchReqRsp->sta_idx;
+            roamInfo.statusCode = ChanSwitchReqRsp->statusCode;
+
+            csrRoamCallCallback(pMac, ChanSwitchReqRsp->sessionId, &roamInfo, 0,
+                                eCSR_ROAM_TDLS_STATUS_UPDATE,
+                                eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP);
+
             /* remove pending eSmeCommandTdlsChanSwitch command */
             csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsChannelSwitch);
             break;