diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index a5b643e263d5..49f9d2f2e113 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -550,6 +550,7 @@ struct cds_conc_connection_info { bool cds_is_connection_in_progress(void); void cds_dump_concurrency_info(void); +bool cds_check_is_tdls_allowed(enum tQDF_ADAPTER_MODE device_mode); void cds_set_tdls_ct_mode(hdd_context_t *hdd_ctx); void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode); void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode); @@ -782,4 +783,6 @@ QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id); void cds_set_do_hw_mode_change_flag(bool flag); bool cds_is_hw_mode_change_after_vdev_up(void); void cds_dump_connection_status_info(void); +uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode, + uint32_t *list); #endif /* __CDS_CONCURRENCY_H */ diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 5a2993b45549..ad89f6df623f 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -1950,6 +1950,27 @@ next_action_three_connection_table[CDS_MAX_TWO_CONNECTION_MODE] }; +/** + * cds_get_connection_count() - provides the count of + * current connections + * + * This function provides the count of current connections + * + * Return: connection count + */ +uint32_t cds_get_connection_count(void) +{ + uint32_t conn_index, count = 0; + + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (conc_connection_list[conn_index].in_use) + count++; + } + + return count; +} + /** * cds_is_sta_connection_pending() - This function will check if sta connection * is pending or not. @@ -2136,7 +2157,7 @@ static void cds_update_conc_list(uint32_t conn_index, * * Return: connection count of specific type */ -static uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode, +uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode, uint32_t *list) { uint32_t conn_index = 0, count = 0; @@ -3295,6 +3316,34 @@ void cds_dump_concurrency_info(void) hdd_ctx->mcc_mode = !cds_current_concurrency_is_scc(); } +/* + * cds_check_is_tdls_allowed() - check is tdls allowed or not + * @adapter: pointer to adapter + * + * Function determines the whether TDLS allowed in the system + * + * Return: true or false + */ +bool cds_check_is_tdls_allowed(enum tQDF_ADAPTER_MODE device_mode) +{ + bool state = false; + uint32_t count; + + count = cds_get_connection_count(); + + if (count > 1) + state = false; + else if (device_mode == QDF_STA_MODE || + device_mode == QDF_P2P_CLIENT_MODE) + state = true; + + /* If any concurrency is detected */ + if (!state) + cds_dump_concurrency_info(); + + return state; +} + /** * cds_set_tdls_ct_mode() - Set the tdls connection tracker mode * @hdd_ctx: hdd context @@ -3308,17 +3357,34 @@ void cds_set_tdls_ct_mode(hdd_context_t *hdd_ctx) bool state = false; /* If any concurrency is detected, skip tdls pkt tracker */ - if (((1 << QDF_STA_MODE) == hdd_ctx->concurrency_mode) && - (hdd_ctx->no_of_active_sessions[QDF_STA_MODE] == 1) && - (hdd_ctx->config->fEnableTDLSImplicitTrigger) && - (eTDLS_SUPPORT_DISABLED != hdd_ctx->tdls_mode)) { - if (hdd_ctx->config->fTDLSExternalControl) { - if (hdd_ctx->tdls_external_peer_count) - state = true; - goto set_state; - } else { + if (cds_get_connection_count() > 1) { + state = false; + goto set_state; + } + + if (eTDLS_SUPPORT_DISABLED == hdd_ctx->tdls_mode || + (!hdd_ctx->config->fEnableTDLSImplicitTrigger)) { + state = false; + goto set_state; + } else if (cds_mode_specific_connection_count(QDF_STA_MODE, + NULL) == 1) { + state = true; + } else if (cds_mode_specific_connection_count(QDF_P2P_CLIENT_MODE, + NULL) == 1){ + state = true; + } else { + state = false; + goto set_state; + } + + /* In case of TDLS external control, peer should be added + * by the user space to start connection tracker. + */ + if (hdd_ctx->config->fTDLSExternalControl) { + if (hdd_ctx->tdls_external_peer_count) state = true; - } + else + state = false; } set_state: @@ -3518,8 +3584,6 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode, break; } - /* set tdls connection tracker state */ - cds_set_tdls_ct_mode(hdd_ctx); cds_info("No.# of active sessions for mode %d = %d", mode, hdd_ctx->no_of_active_sessions[mode]); @@ -3535,6 +3599,10 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode, cds_info("Set PCL of STA to FW"); } cds_incr_connection_count(session_id); + + /* set tdls connection tracker state */ + cds_set_tdls_ct_mode(hdd_ctx); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } @@ -3786,13 +3854,14 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode, break; } - /* set tdls connection tracker state */ - cds_set_tdls_ct_mode(hdd_ctx); - cds_info("No.# of active sessions for mode %d = %d", mode, hdd_ctx->no_of_active_sessions[mode]); cds_decr_connection_count(session_id); + + /* set tdls connection tracker state */ + cds_set_tdls_ct_mode(hdd_ctx); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } @@ -3969,27 +4038,6 @@ uint32_t cds_get_connection_for_vdev_id(uint32_t vdev_id) return conn_index; } - -/** - * cds_get_connection_count() - provides the count of - * current connections - * - * - * This function provides the count of current connections - * - * Return: connection count - */ -uint32_t cds_get_connection_count(void) -{ - uint32_t conn_index, count = 0; - for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; - conn_index++) { - if (conc_connection_list[conn_index].in_use) - count++; - } - return count; -} - /** * cds_get_mode() - Get mode from type and subtype * @type: type diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 4179d18ffce6..cffdf54cb6e4 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1261,6 +1261,7 @@ struct hdd_context_s { #ifdef FEATURE_WLAN_TDLS eTDLSSupportMode tdls_mode; + bool concurrency_marked; eTDLSSupportMode tdls_mode_last; tdlsConnInfo_t tdlsConnInfo[HDD_MAX_NUM_TDLS_STA]; /* maximum TDLS station number allowed upon runtime condition */ @@ -1278,6 +1279,7 @@ struct hdd_context_s { uint8_t tdls_external_peer_count; bool tdls_nss_switch_in_progress; int32_t tdls_teardown_peers_cnt; + struct tdls_set_state_info set_state_info; #endif void *hdd_ipa; diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index f17857d3e42d..4273d722ea36 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -314,6 +314,17 @@ struct tdls_ct_mac_table { uint32_t rx_packet_cnt; uint32_t peer_timestamp_ms; }; + +/** + * struct tdls_set_state_db - set state command data base + * @set_state_cnt: tdls set state count + * @vdev_id: vdev id of last set state command + */ +struct tdls_set_state_info { + uint8_t set_state_cnt; + uint8_t vdev_id; +}; + /** * struct tdlsCtx_t - tdls context * @@ -684,6 +695,8 @@ void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx); int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, uint32_t mode); +hdd_adapter_t *wlan_hdd_tdls_check_and_enable(hdd_context_t *hdd_ctx); + #else static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, @@ -714,6 +727,19 @@ static inline int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx, { return 0; } + +static inline hdd_adapter_t *wlan_hdd_tdls_check_and_enable( + hdd_context_t *hdd_ctx) +{ + return NULL; +} + +static inline void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited) +{ +} + #endif /* End of FEATURE_WLAN_TDLS */ #ifdef FEATURE_WLAN_DIAG_SUPPORT diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 103a369d8b14..9b0d63f924a9 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1247,6 +1247,7 @@ static void hdd_send_association_event(struct net_device *dev, int we_event; char *msg; struct qdf_mac_addr peerMacAddr; + hdd_adapter_t *tdls_adapter; /* Added to find the auth type on the fly at run time */ /* rather than with cfg to see if FT is enabled */ @@ -1340,6 +1341,14 @@ static void hdd_send_association_event(struct net_device *dev, &chan_info, pAdapter->device_mode); + hdd_info("Assoc: Check and enable or disable TDLS state "); + if ((pAdapter->device_mode == QDF_STA_MODE || + pAdapter->device_mode == QDF_P2P_CLIENT_MODE) && + !pHddCtx->concurrency_marked) + wlan_hdd_update_tdls_info(pAdapter, + pCsrRoamInfo->tdls_prohibited, + pCsrRoamInfo->tdls_chan_swit_prohibited); + #ifdef MSM_PLATFORM #ifdef CONFIG_CNSS /* start timer in sta/p2p_cli */ @@ -1389,16 +1398,21 @@ static void hdd_send_association_event(struct net_device *dev, wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0); #endif #ifdef FEATURE_WLAN_TDLS - if ((pAdapter->device_mode == QDF_STA_MODE) && - (pCsrRoamInfo)) { - hddLog(LOG4, - FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"), - pCsrRoamInfo->tdls_prohibited, - pCsrRoamInfo->tdls_chan_swit_prohibited); - - wlan_hdd_update_tdls_info(pAdapter, - pCsrRoamInfo->tdls_prohibited, - pCsrRoamInfo->tdls_chan_swit_prohibited); + hdd_info("Disassoc: Check and enable or disable TDLS state "); + if ((pAdapter->device_mode == QDF_STA_MODE || + pAdapter->device_mode == QDF_P2P_CLIENT_MODE) && + !pHddCtx->concurrency_marked) { + wlan_hdd_update_tdls_info(pAdapter, + true, + true); + } + if (!pHddCtx->concurrency_marked) { + tdls_adapter = wlan_hdd_tdls_check_and_enable( + pHddCtx); + if (NULL != tdls_adapter) + wlan_hdd_update_tdls_info(tdls_adapter, + false, + false); } #endif #ifdef MSM_PLATFORM @@ -3903,12 +3917,8 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER: { /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */ - if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) || - (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) { - hddLog(LOG2, - FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"), - pHddCtx->concurrency_mode, - pHddCtx->no_of_active_sessions[QDF_STA_MODE]); + if (!cds_check_is_tdls_allowed(pAdapter->device_mode)) { + hdd_err("TDLS not allowed, ignore SHOULD_DISCOVER"); status = QDF_STATUS_E_FAILURE; break; } diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 5b107bb50b9d..a96d9c5079e2 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -641,6 +641,24 @@ void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { mutex_init(&hdd_ctx->tdls_lock); qdf_spinlock_create(&hdd_ctx->tdls_ct_spinlock); + + /* initialize TDLS global context */ + hdd_ctx->connected_peer_count = 0; + hdd_ctx->tdls_nss_switch_in_progress = false; + hdd_ctx->tdls_teardown_peers_cnt = 0; + hdd_ctx->tdls_scan_ctxt.magic = 0; + hdd_ctx->tdls_scan_ctxt.attempt = 0; + hdd_ctx->tdls_scan_ctxt.reject = 0; + hdd_ctx->tdls_scan_ctxt.scan_request = NULL; + hdd_ctx->tdls_external_peer_count = 0; + hdd_ctx->set_state_info.set_state_cnt = 0; + hdd_ctx->set_state_info.vdev_id = 0; + + /* This flag will set be true, only when device operates in + * standalone STA mode + */ + hdd_ctx->enable_tdls_connection_tracker = false; + hdd_ctx->concurrency_marked = false; } /** @@ -653,6 +671,9 @@ void hdd_tdls_context_init(hdd_context_t *hdd_ctx) */ void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { + hdd_ctx->tdls_external_peer_count = 0; + hdd_ctx->concurrency_marked = false; + hdd_ctx->enable_tdls_connection_tracker = false; mutex_destroy(&hdd_ctx->tdls_lock); qdf_spinlock_destroy(&hdd_ctx->tdls_ct_spinlock); } @@ -670,11 +691,12 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) int i; uint8_t staIdx; tdlsInfo_t *tInfo; - QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; if (NULL == pHddCtx) return -EINVAL; + ENTER(); + mutex_lock(&pHddCtx->tdls_lock); if (false == pHddCtx->config->fEnableTDLSSupport) { @@ -741,18 +763,9 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddCtx->connected_peer_count = 0; } - /* initialize TDLS global context */ - pHddCtx->connected_peer_count = 0; - pHddCtx->tdls_nss_switch_in_progress = false; - pHddCtx->tdls_teardown_peers_cnt = 0; sme_set_tdls_power_save_prohibited(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, 0); - pHddCtx->tdls_scan_ctxt.magic = 0; - pHddCtx->tdls_scan_ctxt.attempt = 0; - pHddCtx->tdls_scan_ctxt.reject = 0; - pHddCtx->tdls_scan_ctxt.scan_request = NULL; - pHddCtx->tdls_external_peer_count = 0; if (pHddCtx->config->fEnableTDLSSleepSta || pHddCtx->config->fEnableTDLSBufferSta || @@ -776,11 +789,6 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddTdlsCtx->magic = 0; pHddTdlsCtx->valid_mac_entries = 0; - /* This flag will set be true, only when device operates in - * standalone STA mode - */ - pHddCtx->enable_tdls_connection_tracker = false; - /* remember configuration even if it is not used right now. it could be used later */ pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->config->fTDLSTxStatsPeriod; @@ -864,14 +872,7 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddCtx->config->tdls_peer_kickout_threshold; dump_tdls_state_param_setting(tInfo); - qdf_ret_status = sme_update_fw_tdls_state(pHddCtx->hHal, tInfo, true); - if (QDF_STATUS_SUCCESS != qdf_ret_status) { - qdf_mem_free(tInfo); - qdf_mc_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); - qdf_mem_free(pHddTdlsCtx); - return -EINVAL; - } - + EXIT(); return 0; } @@ -886,8 +887,8 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) tdlsCtx_t *pHddTdlsCtx; hdd_context_t *pHddCtx; tdlsInfo_t *tInfo; - QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; + ENTER(); pHddCtx = WLAN_HDD_GET_CTX(pAdapter); if (!pHddCtx) { QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, @@ -965,12 +966,6 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) tInfo->tdls_peer_kickout_threshold = pHddCtx->config->tdls_peer_kickout_threshold; dump_tdls_state_param_setting(tInfo); - - qdf_ret_status = - sme_update_fw_tdls_state(pHddCtx->hHal, tInfo, false); - if (QDF_STATUS_SUCCESS != qdf_ret_status) { - qdf_mem_free(tInfo); - } } else { hddLog(QDF_TRACE_LEVEL_ERROR, "%s: qdf_mem_malloc failed for tInfo", __func__); @@ -978,7 +973,6 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) } pHddTdlsCtx->magic = 0; - pHddCtx->tdls_external_peer_count = 0; pHddTdlsCtx->pAdapter = NULL; qdf_mem_free(pHddTdlsCtx); @@ -986,6 +980,7 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) pHddTdlsCtx = NULL; done: + EXIT(); clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags); } @@ -1859,6 +1854,31 @@ int wlan_hdd_tdls_set_params(struct net_device *dev, return 0; } +/** + * wlan_hdd_tdls_check_and_enable() - check system state and enable tdls + * @hdd_ctx: hdd context + * + * After every disassociation in the system, check whether TDLS + * can be enabled in the system. If TDLS possible return the + * corresponding hdd adapter to enable TDLS. + * + * Return: hdd adapter pointer or NULL. + */ +hdd_adapter_t *wlan_hdd_tdls_check_and_enable(hdd_context_t *hdd_ctx) +{ + if (cds_get_connection_count() > 1) + return NULL; + if (cds_mode_specific_connection_count(QDF_STA_MODE, + NULL) == 1) + return hdd_get_adapter(hdd_ctx, + QDF_STA_MODE); + if (cds_mode_specific_connection_count(QDF_P2P_CLIENT_MODE, + NULL) == 1) + return hdd_get_adapter(hdd_ctx, + QDF_P2P_CLIENT_MODE); + return NULL; +} + /** * wlan_hdd_update_tdls_info - update tdls status info * @adapter: ptr to device adapter. @@ -1896,8 +1916,18 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, return; } - /* If AP indicated TDLS Prohibited then disable tdls mode */ + hdd_info("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d", + tdls_prohibited, tdls_chan_swit_prohibited); + mutex_lock(&hdd_ctx->tdls_lock); + + if (hdd_ctx->set_state_info.set_state_cnt == 0 && + tdls_prohibited) { + mutex_unlock(&hdd_ctx->tdls_lock); + return; + } + + /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ if (tdls_prohibited) { hdd_ctx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; } else { @@ -1908,15 +1938,41 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, else hdd_ctx->tdls_mode = eTDLS_SUPPORT_ENABLED; } - mutex_unlock(&hdd_ctx->tdls_lock); tdls_param = qdf_mem_malloc(sizeof(*tdls_param)); if (!tdls_param) { + mutex_unlock(&hdd_ctx->tdls_lock); hddLog(QDF_TRACE_LEVEL_ERROR, FL("memory allocation failed for tdlsParams")); return; } - tdls_param->vdev_id = adapter->sessionId; + /* If any concurrency detected, teardown all TDLS links and disable + * the tdls support + */ + hdd_warn("Concurrency check in TDLS! set state cnt %d tdls_prohibited %d", + hdd_ctx->set_state_info.set_state_cnt, tdls_prohibited); + + if (hdd_ctx->set_state_info.set_state_cnt == 1 && + !tdls_prohibited) { + hdd_warn("Concurrency not allowed in TDLS! set state cnt %d", + hdd_ctx->set_state_info.set_state_cnt); + if (hdd_ctx->connected_peer_count >= 1) { + hdd_ctx->concurrency_marked = true; + mutex_unlock(&hdd_ctx->tdls_lock); + wlan_hdd_tdls_disable_offchan_and_teardown_links( + hdd_ctx); + qdf_mem_free(tdls_param); + return; + } + tdls_prohibited = true; + hdd_ctx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + tdls_param->vdev_id = hdd_ctx->set_state_info.vdev_id; + } else { + tdls_param->vdev_id = adapter->sessionId; + } + + mutex_unlock(&hdd_ctx->tdls_lock); + tdls_param->tdls_state = hdd_ctx->tdls_mode; tdls_param->notification_interval_ms = hdd_tdls_ctx->threshold_config.tx_period_t; @@ -1966,6 +2022,20 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, qdf_mem_free(tdls_param); return; } + + mutex_lock(&hdd_ctx->tdls_lock); + + if (!tdls_prohibited) { + hdd_ctx->set_state_info.set_state_cnt++; + hdd_ctx->set_state_info.vdev_id = adapter->sessionId; + } else { + hdd_ctx->set_state_info.set_state_cnt--; + } + + hdd_info("TDLS Set state cnt %d", + hdd_ctx->set_state_info.set_state_cnt); + + mutex_unlock(&hdd_ctx->tdls_lock); return; } @@ -2469,6 +2539,8 @@ void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter) void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter) { hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_adapter_t *tdls_adapter; + uint16_t connected_peer_count; ENTER(); @@ -2484,7 +2556,26 @@ void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter) hddLog(LOG1, "%s: %d", __func__, pHddCtx->connected_peer_count); + connected_peer_count = pHddCtx->connected_peer_count; + mutex_unlock(&pHddCtx->tdls_lock); + + if (connected_peer_count == 0 && + pHddCtx->concurrency_marked) { + tdls_adapter = hdd_get_adapter_by_vdev(pHddCtx, + pHddCtx->set_state_info.vdev_id); + if (tdls_adapter) { + wlan_hdd_update_tdls_info(tdls_adapter, true, true); + pHddCtx->concurrency_marked = false; + } else { + hdd_err("TDLS set state is not cleared correctly !!!"); + pHddCtx->concurrency_marked = false; + } + tdls_adapter = wlan_hdd_tdls_check_and_enable(pHddCtx); + if (tdls_adapter) + wlan_hdd_update_tdls_info(tdls_adapter, false, false); + } + EXIT(); } @@ -3922,8 +4013,8 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); /* - * STA should be connected and authenticated before sending - * any TDLS frames + * STA or P2P client should be connected and authenticated before + * sending any TDLS frames */ if ((eConnectionState_Associated != hdd_sta_ctx->conn_info.connState) || @@ -3934,17 +4025,12 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, return -EAGAIN; } - /* If any concurrency is detected */ - if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) || - (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) { - QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Multiple STA OR Concurrency detected. Ignore TDLS MGMT frame. action_code=%d, concurrency_mode: 0x%x, active_sessions: %d", - __func__, - action_code, - pHddCtx->concurrency_mode, - pHddCtx->no_of_active_sessions[QDF_STA_MODE]); + if (!cds_check_is_tdls_allowed(pAdapter->device_mode)) { + hdd_err("TDLS not allowed, reject TDLS MGMT, action_code=%d", + action_code); return -EPERM; } + /* other than teardown frame, mgmt frames are not sent if disabled */ if (SIR_MAC_TDLS_TEARDOWN != action_code) { /* if tdls_mode is disabled to respond to peer's request */