From 28a7689e9173a5286b816a42d78ab4f7bd1f31f9 Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Wed, 19 Oct 2016 19:29:15 +0530 Subject: qcacld-3.0: Enable/Disable TDLS on p2p remain on channel request Propagation from qcacld-2.0 to qcacld-3.0 Currently, TDLS mode is not changed on p2p remain on channel request and if other source enable TDLS during ROC in progress then TDLS connection may proceed which is not supported. Fix is to ensure that TDLS will not be enabled/disabled until all the resources agree upon it. Change-Id: Ic20f364fc833008d8782c28efb21a7b884a2cb14 CRs-Fixed: 959085 --- core/hdd/inc/wlan_hdd_cfg.h | 25 ++++++++++++++++++++++ core/hdd/inc/wlan_hdd_main.h | 2 ++ core/hdd/inc/wlan_hdd_tdls.h | 50 ++++++++++++++++++++++++++----------------- core/hdd/src/wlan_hdd_cfg.c | 10 +++++++++ core/hdd/src/wlan_hdd_main.c | 7 ++++++ core/hdd/src/wlan_hdd_p2p.c | 2 ++ core/hdd/src/wlan_hdd_power.c | 2 ++ core/hdd/src/wlan_hdd_tdls.c | 42 ++++++++++++++++++++++++++++++++++++ 8 files changed, 120 insertions(+), 20 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index e890847e21e4..a525c9eca089 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -1905,6 +1905,29 @@ typedef enum { #endif +/* + * + * gTDLSEnableDeferTime - Timer to defer for enabling TDLS on P2P listen. + * @Min: 2000 + * @Max: 6000 + * @Default: 5000 + * + * This ini is used to set the timer to defer for enabling TDLS on P2P + * listen (value in milliseconds). + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_ENABLE_DEFER_TIMER "gTDLSEnableDeferTime" +#define CFG_TDLS_ENABLE_DEFER_TIMER_MIN (2000) +#define CFG_TDLS_ENABLE_DEFER_TIMER_MAX (6000) +#define CFG_TDLS_ENABLE_DEFER_TIMER_DEFAULT (5000) + /* Enable/Disable LPWR Image(cMEM uBSP) Transition */ #define CFG_ENABLE_LPWR_IMG_TRANSITION_NAME "gEnableLpwrImgTransition" #define CFG_ENABLE_LPWR_IMG_TRANSITION_MIN (0) @@ -4689,6 +4712,8 @@ struct hdd_config { bool flow_steering_enable; bool active_mode_offload; bool bpf_packet_filter_enable; + /* parameter for defer timer for enabling TDLS on p2p listen */ + uint16_t tdls_enable_defer_time; uint32_t fine_time_meas_cap; uint8_t max_scan_count; #ifdef WLAN_FEATURE_FASTPATH diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 3d70c32b0cb0..1adb46012515 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1570,6 +1570,8 @@ struct hdd_context_s { bool roaming_in_progress; /* bit map to set/reset TDLS by different sources */ unsigned long tdls_source_bitmap; + /* tdls source timer to enable/disable TDLS on p2p listen */ + qdf_mc_timer_t tdls_source_timer; qdf_atomic_t disable_lro_in_concurrency; }; diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index b252d8bba930..96b766ad5812 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -32,6 +32,25 @@ * WLAN Host Device Driver TDLS include file */ +/* + * enum eTDLSSupportMode - TDLS support modes + * @eTDLS_SUPPORT_NOT_ENABLED: TDLS support not enabled + * @eTDLS_SUPPORT_DISABLED: suppress implicit trigger and not respond + * to the peer + * @eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY: suppress implicit trigger, + * but respond to the peer + * @eTDLS_SUPPORT_ENABLED: implicit trigger + * @eTDLS_SUPPORT_EXTERNAL_CONTROL: implicit trigger but only to a + * peer mac configured by user space. + */ +typedef enum { + eTDLS_SUPPORT_NOT_ENABLED = 0, + eTDLS_SUPPORT_DISABLED, + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY, + eTDLS_SUPPORT_ENABLED, + eTDLS_SUPPORT_EXTERNAL_CONTROL, +} eTDLSSupportMode; + #ifdef FEATURE_WLAN_TDLS /* @@ -130,26 +149,6 @@ typedef struct { struct delayed_work tdls_scan_work; } tdls_scan_context_t; -/** - * enum eTDLSSupportMode - tdls support mode - * - * @eTDLS_SUPPORT_NOT_ENABLED: tdls support not enabled - * @eTDLS_SUPPORT_DISABLED: suppress implicit trigger and not - * respond to the peer - * @eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY: suppress implicit trigger, - * but respond to the peer - * @eTDLS_SUPPORT_ENABLED: implicit trigger - * @eTDLS_SUPPORT_EXTERNAL_CONTROL: External control means implicit - * trigger but only to a peer mac configured by user space. - */ -typedef enum { - eTDLS_SUPPORT_NOT_ENABLED = 0, - eTDLS_SUPPORT_DISABLED, - eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY, - eTDLS_SUPPORT_ENABLED, - eTDLS_SUPPORT_EXTERNAL_CONTROL, -} eTDLSSupportMode; - /** * enum tdls_spatial_streams - TDLS spatial streams * @TDLS_NSS_1x1_MODE: TDLS tx/rx spatial streams = 1 @@ -750,6 +749,9 @@ void wlan_hdd_tdls_notify_connect(hdd_adapter_t *adapter, * Return: None */ void wlan_hdd_tdls_notify_disconnect(hdd_adapter_t *adapter); +void wlan_hdd_change_tdls_mode(void *hdd_ctx); +void hdd_restart_tdls_source_timer(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode); /** * wlan_hdd_cfg80211_configure_tdls_mode() - configure tdls mode @@ -815,6 +817,14 @@ static inline int wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy, return 0; } +static inline void wlan_hdd_change_tdls_mode(void *hdd_ctx) +{ +} +static inline void +hdd_restart_tdls_source_timer(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode) +{ +} #endif /* End of FEATURE_WLAN_TDLS */ #ifdef FEATURE_WLAN_DIAG_SUPPORT diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 42fedb23e84a..919e71368f28 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -3481,6 +3481,13 @@ REG_TABLE_ENTRY g_registry_table[] = { CFG_BPF_PACKET_FILTER_OFFLOAD_MIN, CFG_BPF_PACKET_FILTER_OFFLOAD_MAX), + REG_VARIABLE(CFG_TDLS_ENABLE_DEFER_TIMER, WLAN_PARAM_Integer, + struct hdd_config, tdls_enable_defer_time, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_ENABLE_DEFER_TIMER_DEFAULT, + CFG_TDLS_ENABLE_DEFER_TIMER_MIN, + CFG_TDLS_ENABLE_DEFER_TIMER_MAX), + REG_VARIABLE(CFG_FLOW_STEERING_ENABLED_NAME, WLAN_PARAM_Integer, struct hdd_config, flow_steering_enable, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -5584,6 +5591,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_info("Name = [%s] Value = [%d]", CFG_BPF_PACKET_FILTER_OFFLOAD, pHddCtx->config->bpf_packet_filter_enable); + hdd_info("Name = [%s] Value = [%u]", + CFG_TDLS_ENABLE_DEFER_TIMER, + pHddCtx->config->tdls_enable_defer_time); hdd_info("Name = [%s] Value = [%d]", CFG_FILTER_MULTICAST_REPLAY_NAME, pHddCtx->config->multicast_replay_filter); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 00933befba88..353131be138a 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4801,6 +4801,8 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx) hdd_unregister_notifiers(hdd_ctx); + qdf_mc_timer_destroy(&hdd_ctx->tdls_source_timer); + hdd_bus_bandwidth_destroy(hdd_ctx); #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE @@ -8224,6 +8226,11 @@ int hdd_wlan_startup(struct device *dev) qdf_spinlock_create(&hdd_ctx->acs_skip_lock); #endif + qdf_mc_timer_init(&hdd_ctx->tdls_source_timer, + QDF_TIMER_TYPE_SW, + wlan_hdd_change_tdls_mode, + hdd_ctx); + hdd_bus_bandwidth_init(hdd_ctx); hdd_lpass_notify_start(hdd_ctx); diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index d82f52247848..2c882a19a61a 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -526,6 +526,7 @@ static void wlan_hdd_remain_on_chan_timeout(void *data) pRemainChanCtx->scan_id); } + hdd_restart_tdls_source_timer(hdd_ctx, eTDLS_SUPPORT_ENABLED); qdf_runtime_pm_allow_suspend(hdd_ctx->runtime_context.roc); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); } @@ -685,6 +686,7 @@ static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter, } } + hdd_restart_tdls_source_timer(pHddCtx, eTDLS_SUPPORT_DISABLED); return 0; } diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index b63575073712..6bf454143459 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1495,6 +1495,8 @@ QDF_STATUS hdd_wlan_shutdown(void) QDF_ASSERT(false); } + qdf_mc_timer_stop(&pHddCtx->tdls_source_timer); + hdd_bus_bandwidth_destroy(pHddCtx); wlansap_global_deinit(); diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 736a9dd8ccc0..9244b5b3071f 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -6007,3 +6007,45 @@ int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx, tdls_ant_sw_done: return 0; } + +/** + * wlan_hdd_change_tdls_mode - Change TDLS mode + * @data: void pointer + * + * Return: None + */ +void wlan_hdd_change_tdls_mode(void *data) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)data; + + wlan_hdd_tdls_set_mode(hdd_ctx, eTDLS_SUPPORT_ENABLED, false, + HDD_SET_TDLS_MODE_SOURCE_OFFCHANNEL); +} + +/** + * hdd_restart_tdls_source_timer - Restart TDLS source timer + * @pHddCtx: ptr to hdd context. + * @tdls_mode: value for TDLS support mode. + * + * This timer is the handler for avoiding overlapping for P2P listen + * and TDLS operation. This handler will start the source timer for + * the duration of tdls_enable_defer_time after P2P listen ends and + * before enabling TDLS again. + * + * Return: None + */ +void hdd_restart_tdls_source_timer(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode) +{ + qdf_mc_timer_stop(&pHddCtx->tdls_source_timer); + + if (tdls_mode == eTDLS_SUPPORT_DISABLED) + wlan_hdd_tdls_set_mode(pHddCtx, tdls_mode, false, + HDD_SET_TDLS_MODE_SOURCE_OFFCHANNEL); + + qdf_mc_timer_start(&pHddCtx->tdls_source_timer, + pHddCtx->config->tdls_enable_defer_time); + + return; +} + -- cgit v1.2.3