TDLS: TDLS Scan Coexistence Implementation
This commit introduces TDLS Link and Scan
Coexistence functionality.
Scan coexistence on the TDLS Link is supported
provided a single TDLS session is present, DUT
is not Buffer STA capable and the TDLS peer is
Buffer Sta capable.
This capability shall be enabled based on the
gEnableTDLSScanCoexistence parameter.
CRs-Fixed: 668619
Change-Id: I6dad95ce4f453d774b4f6bea99cccca46b95aa5f
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 2b4fe94..4dea6d5 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1832,6 +1832,11 @@
#define CFG_TDLS_WMM_MODE_ENABLE_MIN (0)
#define CFG_TDLS_WMM_MODE_ENABLE_MAX (1)
#define CFG_TDLS_WMM_MODE_ENABLE_DEFAULT (0)
+
+#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE "gEnableTDLSScanCoexistence"
+#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MIN (0)
+#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MAX (1)
+#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_DEFAULT (0)
#endif
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
@@ -2559,6 +2564,7 @@
v_BOOL_t fTDLSExternalControl;
v_U32_t fEnableTDLSOffChannel;
v_U32_t fEnableTDLSWmmMode;
+ v_BOOL_t fEnableTDLSScanCoexSupport;
#endif
v_U32_t enableLpwrImgTransition;
#ifdef WLAN_SOFTAP_VSTA_FEATURE
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index de5644c..72b546b 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1288,6 +1288,7 @@
vos_timer_t tx_rx_trafficTmr;
v_U8_t drvr_miracast;
v_U8_t issplitscan_enabled;
+ v_U8_t isTdlsScanCoexistence;
/* VHT80 allowed*/
v_BOOL_t isVHT80Allowed;
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index dec97de..c43697f 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2531,6 +2531,13 @@
CFG_TDLS_WMM_MODE_ENABLE_DEFAULT,
CFG_TDLS_WMM_MODE_ENABLE_MIN,
CFG_TDLS_WMM_MODE_ENABLE_MAX ),
+
+REG_VARIABLE( CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE, WLAN_PARAM_Integer,
+ hdd_config_t, fEnableTDLSScanCoexSupport,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_DEFAULT,
+ CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MIN,
+ CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MAX ),
#endif
#ifdef WLAN_SOFTAP_VSTA_FEATURE
@@ -4591,6 +4598,16 @@
fStatus = FALSE;
hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK to CCM");
}
+
+ if (TRUE == pConfig->fEnableTDLSScanCoexSupport)
+ {
+ /* TDLSScanCoexistance feature is supported when the DUT acts as only
+ * the Sleep STA and hence explicitly disable the BufferSta capability
+ * on the DUT. DUT's Buffer STA capability is explicitly disabled to
+ * ensure that the TDLS peer shall not go to TDLS power save mode.
+ */
+ pConfig->fEnableTDLSBufferSta = FALSE;
+ }
if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_BUF_STA_ENABLED,
pConfig->fEnableTDLSBufferSta, NULL,
eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 0e2da14..75e0ddd 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -1514,6 +1514,17 @@
curr_peer->link_status = eTDLS_LINK_IDLE;
curr_peer->staId = 0;
+ /* Throughput Monitor shall disable the split scan when
+ * TDLS scan coexistance is disabled.At this point of time
+ * since TDLS scan coexistance is not meeting the criteria
+ * to be operational, explicitly make it false to enable
+ * throughput monitor takes the control of split scan.
+ */
+ if (pHddCtx->isTdlsScanCoexistence == TRUE)
+ {
+ pHddCtx->isTdlsScanCoexistence = FALSE;
+ }
+
if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
vos_timer_stop( &curr_peer->peerIdleTimer );
}
@@ -1600,6 +1611,44 @@
return pHddCtx->connected_peer_count;
}
+hddTdlsPeer_t *wlan_hdd_tdls_get_first_connected_peer(hdd_adapter_t *pAdapter)
+{
+ int i;
+ struct list_head *head;
+ struct list_head *pos;
+ hddTdlsPeer_t *curr_peer = NULL;
+ tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ if(0 != (wlan_hdd_validate_context(pHddCtx)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("pHddCtx is not valid"));
+ return NULL;
+ }
+
+ mutex_lock(&pHddCtx->tdls_lock);
+ pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
+ if (NULL == pHddTdlsCtx) {
+ mutex_unlock(&pHddCtx->tdls_lock);
+ return NULL;
+ }
+ for (i = 0; i < 256; i++) {
+ head = &pHddTdlsCtx->peer_list[i];
+
+ list_for_each(pos, head) {
+ curr_peer= list_entry (pos, hddTdlsPeer_t, node);
+ if (curr_peer)
+ {
+ mutex_unlock(&pHddCtx->tdls_lock);
+ return curr_peer;
+ }
+ }
+ }
+ mutex_unlock(&pHddCtx->tdls_lock);
+ return NULL;
+}
+
int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
{
int i;
@@ -2212,8 +2261,9 @@
{
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
u16 connectedTdlsPeers;
- hddTdlsPeer_t *curr_peer;
+ hddTdlsPeer_t *curr_peer, *connected_peer;
unsigned long delay;
+ hdd_config_t *cfg_param = pHddCtx->cfg_ini;
if(0 != (wlan_hdd_validate_context(pHddCtx)))
{
@@ -2278,6 +2328,66 @@
wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
/* indicate the teardown all connected to peer */
connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
+
+ /* check the TDLS link and Scan coexistance Capability */
+ if ( (TRUE == pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport) &&
+ (TRUE == sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE)) &&
+ (connectedTdlsPeers == 1) )
+ {
+ /* get connected peer information */
+ connected_peer = wlan_hdd_tdls_get_first_connected_peer(pAdapter);
+ if (NULL == connected_peer) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: Invalid connected_peer, Continue Scanning", __func__);
+ /* scan should continue */
+ return 1;
+ }
+ VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
+ ("%s: TDLS Scan Co-exist supported connectedTdlsPeers =%d buffersta =%d"),
+ __func__,connectedTdlsPeers,connected_peer->isBufSta);
+
+ if (connected_peer->isBufSta)
+ {
+ pHddCtx->isTdlsScanCoexistence = TRUE;
+ if ((cfg_param->dynSplitscan) && (!pHddCtx->issplitscan_enabled))
+ {
+ pHddCtx->issplitscan_enabled = TRUE;
+ sme_enable_disable_split_scan(
+ WLAN_HDD_GET_HAL_CTX(pAdapter),
+ cfg_param->nNumStaChanCombinedConc,
+ cfg_param->nNumP2PChanCombinedConc);
+ }
+ VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
+ ("%s:%d TDLS Scan Co-exist supported splitscan_enabled =%d "),
+ __func__, __LINE__, pHddCtx->issplitscan_enabled);
+ return 1;
+ }
+
+ }
+ else
+ {
+ /* Throughput Monitor shall disable the split scan when
+ * TDLS scan coexistance is disabled.At this point of time
+ * since TDLS scan coexistance is not meeting the criteria
+ * to be operational, explicitly make it false to enable
+ * throughput monitor takes the control of split scan.
+ */
+ pHddCtx->isTdlsScanCoexistence = FALSE;
+ }
+ VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
+ ("%s: TDLS Scan Co-exist not supported connectedTdlsPeers =%d"
+ " TDLSScanCoexSupport param =%d TDLS_SCAN_COEXISTENCE =%d"),
+ __func__, connectedTdlsPeers,
+ pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport,
+ sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE));
+
+ /* fall back to the implementation of teardown the peers on the scan
+ * when the number of connected peers are more than one. TDLS Scan
+ * coexistance feature is exercised only when a single peer is
+ * connected and the DUT shall not advertize the Buffer Sta capability,
+ * so that the peer shall not go to the TDLS power save
+ */
+
if (connectedTdlsPeers)
{
tANI_U8 staIdx;
@@ -2380,6 +2490,8 @@
hddTdlsPeer_t *curr_peer,
tANI_U16 reason)
{
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
if (NULL == pAdapter || NULL == curr_peer)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
@@ -2390,6 +2502,17 @@
if (eTDLS_LINK_CONNECTED != curr_peer->link_status)
return;
+ /* Throughput Monitor shall disable the split scan when
+ * TDLS scan coexistance is disabled.At this point of time
+ * since TDLS scan coexistance is not meeting the criteria
+ * to be operational, explicitly make it false to enable
+ * throughput monitor takes the control of split scan.
+ */
+ if (pHddCtx->isTdlsScanCoexistence == TRUE)
+ {
+ pHddCtx->isTdlsScanCoexistence = FALSE;
+ }
+
wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_TEARING);
cfg80211_tdls_oper_request(pAdapter->dev,
curr_peer->peerMac,
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index a2e6fae..8ee6f80 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -1916,7 +1916,11 @@
pAdapterNode = pNext;
}
- if (pHddCtx->issplitscan_enabled)
+ /* If TDLSScanCoexistence is enabled, then the TDLS module shall take care
+ * of disabling the split scan and thus do not disable the same when the
+ * low TXRX condition is met.
+ */
+ if ((pHddCtx->isTdlsScanCoexistence == FALSE) && (pHddCtx->issplitscan_enabled))
{
VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
"%s: Disable split scan", __func__);
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index f7090d3..6002b4a 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -102,6 +102,9 @@
UPDATE_CHANNEL_LIST = 35,
WLAN_MCADDR_FLT = 36,
WLAN_CH144 = 37,
+#ifdef FEATURE_WLAN_TDLS
+ TDLS_SCAN_COEXISTENCE = 39,
+#endif
//MAX_FEATURE_SUPPORTED = 128
} placeHolderInCapBitmap;
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 0efc00b..a839f05 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -167,6 +167,14 @@
,CH_SWITCH_V1 //33
,HT40_OBSS_SCAN //34
,UPDATE_CHANNEL_LIST //35
+ ,FEATURE_NOT_SUPPORTED //36
+ ,FEATURE_NOT_SUPPORTED //37
+ ,FEATURE_NOT_SUPPORTED //38
+#ifdef FEATURE_WLAN_TDLS
+ ,TDLS_SCAN_COEXISTENCE //39
+#else
+ ,FEATURE_NOT_SUPPORTED //39
+#endif
};
@@ -1215,6 +1223,9 @@
"%s", "EXTENDED_NSOFFLOAD_SLOT");
pCapStr += strlen("EXTENDED_NSOFFLOAD_SLOT");
break;
+ case TDLS_SCAN_COEXISTENCE: snprintf(pCapStr, sizeof("TDLS_SCAN_COEXISTENCE"), "%s", "TDLS_SCAN_COEXISTENCE");
+ pCapStr += strlen("TDLS_SCAN_COEXISTENCE");
+ break;
}
*pCapStr++ = ',';