From 19ebe2b13fb3ff4e850118f997f91137d0b35c94 Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Fri, 18 Nov 2016 10:00:45 -0800 Subject: 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 c0b37f9879e5..99edbff2b482 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1573,6 +1573,7 @@ struct hdd_context_s { /* counters for failed suspend reasons */ uint32_t suspend_fail_stats[SUSPEND_FAIL_MAX_COUNT]; struct hdd_runtime_pm_context runtime_context; + bool roaming_in_progress; }; /*--------------------------------------------------------------------------- @@ -1991,4 +1992,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 fb319418124f..2ea1ac58c30f 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -4625,6 +4625,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 */ @@ -4912,6 +4913,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: @@ -4921,6 +4923,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 6190d59c217b..4cb11a9b25ed 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -588,6 +588,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; } @@ -9826,6 +9831,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); -- cgit v1.2.3