wlan: Defer scan if back to back scan on STA interface.
If there is scan on STA interface back to back with
time diff nDeferScanTimeInterval, driver will not
issue a new scan. Driver will return previous result to kernel.
CRs-Fixed: 757773
Change-Id: I09e9b23f64d959ef5846096cdae810f84b8a1b97
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 497b052..856fce7 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -417,6 +417,13 @@
CFG_IMPS_MAXIMUM_SLEEP_TIME_MIN,
CFG_IMPS_MAXIMUM_SLEEP_TIME_MAX ),
+ REG_VARIABLE( CFG_DEFER_SCAN_TIME_INTERVAL, WLAN_PARAM_Integer,
+ hdd_config_t, nDeferScanTimeInterval,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DEFER_SCAN_TIME_INTERVAL_DEFAULT,
+ CFG_DEFER_SCAN_TIME_INTERVAL_MIN,
+ CFG_DEFER_SCAN_TIME_INTERVAL_MAX ),
+
REG_VARIABLE( CFG_IMPS_MODERATE_SLEEP_TIME_NAME, WLAN_PARAM_Integer,
hdd_config_t, nImpsModSleepTime,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -3630,7 +3637,8 @@
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApHT4024G] Value = [%u]", pHddCtx->cfg_ini->apHT40_24GEnabled);
#endif
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAcsScanBandPreference] Value = [%u] ",pHddCtx->cfg_ini->acsScanBandPreference);
- VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,"Name = [gACSBandSwitchThreshold] value = [%u]\n",pHddCtx->cfg_ini->acsBandSwitchThreshold);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gACSBandSwitchThreshold] value = [%u]\n",pHddCtx->cfg_ini->acsBandSwitchThreshold);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gDeferScanTimeInterval] value = [%u]\n",pHddCtx->cfg_ini->nDeferScanTimeInterval);
}
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 48835b5..1df9d16 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -9432,6 +9432,7 @@
int ret = 0;
bool aborted = false;
long waitRet = 0;
+ tANI_U8 i;
ENTER();
@@ -9516,6 +9517,27 @@
/* Scan is no longer pending */
pScanInfo->mScanPending = VOS_FALSE;
+ /* last_scan_timestamp is used to decide if new scan
+ * is needed or not on station interface. If last station
+ * scan time and new station scan time is less then
+ * last_scan_timestamp ; driver will return cached scan.
+ */
+ if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
+ {
+ pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
+
+ if ( req->n_channels )
+ {
+ for (i = 0; i < req->n_channels ; i++ )
+ {
+ pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
+ }
+ /* store no of channel scanned */
+ pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
+ }
+
+ }
+
/*
* cfg80211_scan_done informing NL80211 about completion
* of scanning
@@ -9668,6 +9690,7 @@
int status;
hdd_scaninfo_t *pScanInfo = NULL;
v_U8_t* pP2pIe = NULL;
+ int ret = 0;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
struct net_device *dev = NULL;
@@ -9798,6 +9821,7 @@
hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
(int)request->n_ssids);
+
/* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
* Becasue of this, driver is assuming that this is not wildcard scan and so
* is not aging out the scan results.
@@ -9900,6 +9924,39 @@
/* set requestType to full scan */
scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
+ /* if there is back to back scan happening in driver with in
+ * nDeferScanTimeInterval interval driver should defer new scan request
+ * and should provide last cached scan results instead of new channel list.
+ * This rule is not applicable if scan is p2p scan.
+ * This condition will work only in case when last request no of channels
+ * and channels are exactly same as new request.
+ */
+ if (pScanInfo->last_scan_timestamp !=0 &&
+ (FALSE == request->no_cck) && // no_cck is set during p2p find.
+ ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
+ {
+ if (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels &&
+ vos_mem_compare(pScanInfo->last_scan_channelList,
+ channelList, pScanInfo->last_scan_numChannels))
+ {
+ hddLog(VOS_TRACE_LEVEL_WARN,
+ " New and old station scan time differ is less then %u",
+ pHddCtx->cfg_ini->nDeferScanTimeInterval);
+
+ ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
+ pAdapter);
+
+ hddLog(VOS_TRACE_LEVEL_WARN,
+ "Return old cached scan as all channels"
+ "and no of channles are same");
+ if (0 > ret)
+ hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
+
+ cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
+ return eHAL_STATUS_SUCCESS ;
+ }
+ }
+
/* Flush the scan results(only p2p beacons) for STA scan and P2P
* search (Flush on both full scan and social scan but not on single
* channel scan).P2P search happens on 3 social channels (1, 6, 11)