From dce1c564b8b11d8e4bf24937c8ee16c0eadf535a Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Fri, 18 Nov 2016 10:00:45 -0800 Subject: [PATCH] qcacld-3.0: Do not allow disconnect during roaming The roam synch indication processing cleans up the entire stack with respect to the old peer and establishes the context of the new peer. A disconnect request from upper layer during the roam synch processing would cleanup old peer context partially and request be queued to the PE queue to be processed further. The roam synch indication processing resumes and picks up the semi-cleaned context of the old peer. So, do not allow disconnect if roaming is in progress. Set the roaming in progress flag when is a ROAM START is indicated by the firmware. Reset the flag once the roaming is complete or even if it failed for some reason. During the period when the flag is set, do not allow disconnections from upper layers to go through. Change-Id: If7cc92b25e2330f4280c7bf32c1ddd88fd4a510f CRs-Fixed: 1091054 --- core/hdd/inc/wlan_hdd_main.h | 4 ++++ core/hdd/src/wlan_hdd_assoc.c | 3 +++ core/hdd/src/wlan_hdd_main.c | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index ef8d6c6c8fef..dc5669149f93 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1570,6 +1570,7 @@ struct hdd_context_s { struct hdd_runtime_pm_context runtime_context; /* bit map to set/reset TDLS by different sources */ unsigned long tdls_source_bitmap; + bool roaming_in_progress; }; /*--------------------------------------------------------------------------- @@ -1988,4 +1989,7 @@ static inline int wlan_hdd_validate_session_id(u8 session_id) return -EINVAL; } +bool hdd_is_roaming_in_progress(void); +void hdd_set_roaming_in_progress(bool value); + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 39aa55815d54..8619629a1e4b 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -4651,6 +4651,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, case eCSR_ROAM_NAPI_OFF: hdd_info("After Roam Synch Comp: NAPI Serialize OFF"); hdd_napi_serialize(0); + hdd_set_roaming_in_progress(false); break; case eCSR_ROAM_SHOULD_ROAM: /* notify apps that we can't pass traffic anymore */ @@ -4938,6 +4939,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, WLAN_CONTROL_PATH); hdd_napi_serialize(1); cds_set_connection_in_progress(true); + hdd_set_roaming_in_progress(true); cds_restart_opportunistic_timer(true); break; case eCSR_ROAM_ABORT: @@ -4947,6 +4949,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH); cds_set_connection_in_progress(false); + hdd_set_roaming_in_progress(false); break; default: diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 5c1bd12b8c2a..9ae93842a913 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -589,6 +589,11 @@ int wlan_hdd_validate_context(hdd_context_t *hdd_ctx) return -EAGAIN; } + if (hdd_is_roaming_in_progress()) { + hdd_err("Roaming In Progress. Ignore!!!"); + return -EAGAIN; + } + return 0; } @@ -9824,6 +9829,46 @@ int hdd_enable_disable_ca_event(hdd_context_t *hddctx, uint8_t set_value) return 0; } +/** + * hdd_set_roaming_in_progress() - to set the roaming in progress flag + * @value: value to set + * + * This function will set the passed value to roaming in progress flag. + * + * Return: None + */ +void hdd_set_roaming_in_progress(bool value) +{ + hdd_context_t *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err("HDD context is NULL"); + return; + } + + hdd_ctx->roaming_in_progress = value; + hdd_info("Roaming in Progress set to %d", value); +} + +/** + * hdd_is_roaming_in_progress() - check if roaming is in progress + * @hdd_ctx - HDD context + * + * Return: true if roaming is in progress else false + */ +bool hdd_is_roaming_in_progress(void) +{ + hdd_context_t *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err("HDD context is NULL"); + return false; + } + return hdd_ctx->roaming_in_progress; +} + /* Register the module init/exit functions */ module_init(hdd_module_init); module_exit(hdd_module_exit);