From 3862ca9efad20a1967cc80b9eb97813253f41cfd Mon Sep 17 00:00:00 2001 From: Hanumanth Reddy Pothula Date: Fri, 12 Jan 2018 16:44:10 +0530 Subject: [PATCH] qcacld-3.0: Flush scan results on interface down After successful connection, if interface down(STA) happens on DUT and if AP changes data rates before interface up happens, there is a possibility of STA to send packets at older data rates, because of holding older scan results in SME scan cache. This results in using stale scan result even after wifi turn off and on. If stale scan result is used and if AP has updated some params like rates DUT will not be using those supported rates for tx which is an issue. To mitigate this issue, flush scan results on STA interface down. Also, make sure there are no other STA interfaces before flushing scan results. Change-Id: I3505c128276fa8e5e05ea5d9110eb75275a746e9 CRs-Fixed: 2171523 --- core/hdd/inc/wlan_hdd_main.h | 11 ++++++++++- core/hdd/src/wlan_hdd_hostapd.c | 4 ++++ core/hdd/src/wlan_hdd_main.c | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 7e76ca34f431..99cd7358473e 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1,4 +1,4 @@ -/* + /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. @@ -2871,4 +2871,13 @@ void hdd_driver_memdump_deinit(void); uint8_t hdd_check_green_ap_enable(struct hdd_context *hdd_ctx, bool *is_enabled); +/** + * hdd_is_cli_iface_up() - check if there is any cli iface up + * @hdd_ctx: HDD context + * + * Return: return true if there is any cli iface(STA/P2P_CLI) is up + * else return false + */ +bool hdd_is_cli_iface_up(struct hdd_context *hdd_ctx); + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 28d6c675d767..8dfbae14c290 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -518,6 +518,10 @@ static int __hdd_hostapd_stop(struct net_device *dev) hdd_stop_adapter(hdd_ctx, adapter); hdd_deinit_adapter(hdd_ctx, adapter, true); clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); + + if (!hdd_is_cli_iface_up(hdd_ctx)) + sme_scan_flush_result(hdd_ctx->hHal); + /* Stop all tx queues */ hdd_debug("Disabling queues"); wlan_hdd_netif_queue_control(adapter, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index ba900346980f..366ee955e0e6 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -3006,6 +3006,13 @@ static int __hdd_stop(struct net_device *dev) hdd_deinit_adapter(hdd_ctx, adapter, true); + /* + * Upon wifi turn off, DUT has to flush the scan results so if + * this is the last cli iface, flush the scan database. + */ + if (!hdd_is_cli_iface_up(hdd_ctx)) + sme_scan_flush_result(hdd_ctx->hHal); + /* * Find if any iface is up. If any iface is up then can't put device to * sleep/power save mode @@ -13599,6 +13606,22 @@ void hdd_set_rx_mode_rps(bool enable) } } +bool hdd_is_cli_iface_up(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *adapter = NULL; + + hdd_for_each_adapter(hdd_ctx, adapter) { + if ((adapter->device_mode == QDF_STA_MODE || + adapter->device_mode == QDF_P2P_CLIENT_MODE) && + qdf_atomic_test_bit(DEVICE_IFACE_OPENED, + &adapter->event_flags)){ + return true; + } + } + + return false; +} + /* Register the module init/exit functions */ module_init(hdd_module_init); module_exit(hdd_module_exit);