TDLS : Host Changes supporting PUAPSD implementation.

This commit has the host changes to support the PUAPSD
implementation in the firmware.

Change-Id: I60a33f8067ea316d5179374cf6ec41400ceabbf2
CRs-fixed: 488980
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 742c32f..81162c9 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -2115,6 +2115,7 @@
       roamResult == eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND" :
       roamResult == eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND? "DEL_ALL_TDLS_PEER_IND" :
       roamResult == eCSR_ROAM_RESULT_UPDATE_TDLS_PEER? "UPDATE_TDLS_PEER" :
+      roamResult == eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP? "LINK_ESTABLISH_REQ_RSP" :
 #ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
       roamResult == eCSR_ROAM_RESULT_TDLS_DISAPPEAR_AP_IND? "DISAPPEAR_AP_DEREG_STA" :
 #endif
@@ -2207,6 +2208,16 @@
             complete(&pAdapter->tdls_add_station_comp);
             break;
         }
+        case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
+        {
+            if (eSIR_SME_SUCCESS != pRoamInfo->statusCode)
+            {
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                     "%s: Link Establish Request failed. %d", __func__, pRoamInfo->statusCode);
+            }
+            complete(&pAdapter->tdls_link_establish_req_comp);
+            break;
+        }
         case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
         {
             hddTdlsPeer_t *curr_peer;
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 98fc710..688207f 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2134,6 +2134,34 @@
               CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_DEFAULT,
               CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN,
               CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX ),
+
+REG_VARIABLE( CFG_TDLS_QOS_WMM_UAPSD_MASK_NAME , WLAN_PARAM_HexInteger,
+                 hdd_config_t, fTDLSUapsdMask,
+                 VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+                 CFG_TDLS_QOS_WMM_UAPSD_MASK_DEFAULT,
+                 CFG_TDLS_QOS_WMM_UAPSD_MASK_MIN,
+                 CFG_TDLS_QOS_WMM_UAPSD_MASK_MAX ),
+
+REG_VARIABLE( CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE, WLAN_PARAM_Integer,
+              hdd_config_t, fEnableTDLSBufferSta,
+              VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+              CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_DEFAULT,
+              CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MIN,
+              CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MAX ),
+
+REG_VARIABLE( CFG_TDLS_PUAPSD_INACTIVITY_TIME, WLAN_PARAM_Integer,
+              hdd_config_t, fTDLSPuapsdInactivityTimer,
+              VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+              CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEFAULT,
+              CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN,
+              CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX ),
+
+REG_VARIABLE( CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD, WLAN_PARAM_Integer,
+              hdd_config_t, fTDLSRxFrameThreshold,
+              VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+              CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_DEFAULT,
+              CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MIN,
+              CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX ),
 #endif
 
 #ifdef WLAN_SOFTAP_VSTA_FEATURE
@@ -3777,6 +3805,34 @@
       hddLog(LOGE, "Could not pass on WNI_CFG_MAX_MEDIUM_TIME to CCM");
    }
 
+#ifdef FEATURE_WLAN_TDLS
+
+   if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, pConfig->fTDLSUapsdMask,
+      NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
+   {
+      fStatus = FALSE;
+      hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK to CCM\n");
+   }
+   if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_BUF_STA_ENABLED, pConfig->fEnableTDLSBufferSta,
+      NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
+   {
+      fStatus = FALSE;
+      hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_BUF_STA_ENABLED to CCM\n");
+   }
+   if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_PUAPSD_INACT_TIME, pConfig->fTDLSPuapsdInactivityTimer,
+      NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
+   {
+      fStatus = FALSE;
+      hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_PUAPSD_INACT_TIME to CCM\n");
+   }
+   if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_RX_FRAME_THRESHOLD, pConfig->fTDLSRxFrameThreshold,
+      NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
+   {
+      fStatus = FALSE;
+      hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_RX_FRAME_THRESHOLD to CCM\n");
+   }
+#endif
+
    return fStatus;
 }
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index f474e8c..9564479 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -83,6 +83,7 @@
 #include <qc_sap_ioctl.h>
 #ifdef FEATURE_WLAN_TDLS
 #include "wlan_hdd_tdls.h"
+#include "wlan_hdd_wmm.h"
 #endif
 #include "wlan_nv.h"
 
@@ -3043,13 +3044,13 @@
                     isBufSta = 1;
                 }
             }
-            //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
-            //                                      params->max_sp, isBufSta);
-            //if (VOS_STATUS_SUCCESS != status) {
-            //    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-            //              "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
-            //    return -EINVAL;
-            //}
+            status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
+                                                  params->max_sp, isBufSta);
+            if (VOS_STATUS_SUCCESS != status) {
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
+                return -EINVAL;
+            }
             status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
 
             if (VOS_STATUS_SUCCESS != status) {
@@ -7586,6 +7587,7 @@
         case NL80211_TDLS_ENABLE_LINK:
             {
                 VOS_STATUS status;
+                tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
 
                 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
                 {
@@ -7597,6 +7599,26 @@
 
                 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
                 {
+                    if (0 != wlan_hdd_tdls_get_link_establish_params(pAdapter, peer,&tdlsLinkEstablishParams)) {
+                         return -EINVAL;
+                    }
+                    INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
+
+                    sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                                                    pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
+                    /* Send TDLS peer UAPSD capabilities to the firmware and
+                     * register with the TL on after the response for this operation
+                     * is received .
+                     */
+                    status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_link_establish_req_comp,
+                              msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
+                    if (status <= 0)
+                    {
+                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                                  "%s: Link Establish Request Faled Status %ld",
+                                  __func__, status);
+                        return -EINVAL;
+                    }
                     wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
                     /* Mark TDLS client Authenticated .*/
                     status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
@@ -7619,6 +7641,68 @@
                         wlan_hdd_tdls_increment_peer_count(pAdapter);
                     }
                     wlan_hdd_tdls_check_bmps(pAdapter);
+
+                    /* Update TL about the UAPSD masks , to route the packets to firmware */
+                    if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
+                        pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VO )
+                    {
+                        status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+                                                          pTdlsPeer->staId,
+                                                          WLANTL_AC_VO,
+                                                          7,
+                                                          7,
+                                                          0,
+                                                          0,
+                                                          WLANTL_BI_DIR );
+
+                        VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
+                    }
+
+                    if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
+                        pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VI )
+                    {
+                       status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+                                                         pTdlsPeer->staId,
+                                                         WLANTL_AC_VI,
+                                                         5,
+                                                         5,
+                                                         0,
+                                                         0,
+                                                         WLANTL_BI_DIR );
+
+                       VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
+                    }
+
+                    if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
+                        pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BK )
+                    {
+                       status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+                                                         pTdlsPeer->staId,
+                                                         WLANTL_AC_BK,
+                                                         2,
+                                                         2,
+                                                         0,
+                                                         0,
+                                                         WLANTL_BI_DIR );
+
+                       VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
+                    }
+
+                    if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
+                        pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BE )
+                    {
+                       status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+                                                         pTdlsPeer->staId,
+                                                         WLANTL_AC_BE,
+                                                         3,
+                                                         3,
+                                                         0,
+                                                         0,
+                                                         WLANTL_BI_DIR );
+
+                       VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
+                    }
+
                 }
 
             }
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 04aa401..033bce8 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -3071,6 +3071,7 @@
       init_completion(&pAdapter->tdls_add_station_comp);
       init_completion(&pAdapter->tdls_del_station_comp);
       init_completion(&pAdapter->tdls_mgmt_comp);
+      init_completion(&pAdapter->tdls_link_establish_req_comp);
 #endif
       init_completion(&pHddCtx->mc_sus_event_var);
       init_completion(&pHddCtx->tx_sus_event_var);
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 6e3519c..0ab884a 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -904,6 +904,40 @@
     return 0;
 }
 
+int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter,
+                                u8 *mac,
+                                tANI_U8 uapsdQueues,
+                                tANI_U8 maxSp,
+                                tANI_BOOLEAN isBufSta)
+{
+    hddTdlsPeer_t *curr_peer;
+
+    curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
+    if (curr_peer == NULL)
+        return -1;
+
+    curr_peer->uapsdQueues = uapsdQueues;
+    curr_peer->maxSp = maxSp;
+    curr_peer->isBufSta = isBufSta;
+    return 0;
+}
+
+int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac,
+                                            tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams)
+{
+    hddTdlsPeer_t *curr_peer;
+
+    curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
+    if (curr_peer == NULL)
+        return -1;
+
+    tdlsLinkEstablishParams->isResponder = curr_peer->is_responder;
+    tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues;
+    tdlsLinkEstablishParams->maxSp = curr_peer->maxSp;
+    tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta;
+    return 0;
+}
+
 int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
 {
     hddTdlsPeer_t *curr_peer;
diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c
index b9faa76..40f59f8 100644
--- a/CORE/HDD/src/wlan_hdd_wmm.c
+++ b/CORE/HDD/src/wlan_hdd_wmm.c
@@ -100,13 +100,6 @@
 #endif
 
 
-// UAPSD Mask bits
-// (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored)
-#define HDD_AC_VO 0x1
-#define HDD_AC_VI 0x2
-#define HDD_AC_BK 0x4
-#define HDD_AC_BE 0x8
-
 #define WLAN_HDD_MAX_DSCP 0x3f
 
 static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];