Merge "wlan: Address memory corruption due to double free"
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 5e82fb2..f8bfbe9 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -220,6 +220,16 @@
#define CFG_IMPS_MAXIMUM_SLEEP_TIME_MAX ( 65535 )
#define CFG_IMPS_MAXIMUM_SLEEP_TIME_DEFAULT ( 15 )
+/*If there is scan on STA interface back to back with
+ *time diff nDeferScanTimeInterval, driver will not
+ *issue a new scan. Driver will return cached result to kernel.
+ *the interval is in msec
+ */
+#define CFG_DEFER_SCAN_TIME_INTERVAL "gDeferScanTimeInterval"
+#define CFG_DEFER_SCAN_TIME_INTERVAL_MIN ( 0 )
+#define CFG_DEFER_SCAN_TIME_INTERVAL_MAX ( 65535 )
+#define CFG_DEFER_SCAN_TIME_INTERVAL_DEFAULT ( 2000 )
+
//BMPS = BeaconModePowerSave
#define CFG_ENABLE_BMPS_NAME "gEnableBmps"
#define CFG_ENABLE_BMPS_MIN ( 0 )
@@ -2393,6 +2403,7 @@
v_BOOL_t ShortSlotTimeEnabled;
v_BOOL_t Is11dSupportEnabled;
v_BOOL_t Is11hSupportEnabled;
+ v_U32_t nDeferScanTimeInterval;
v_BOOL_t fEnforce11dChannels;
v_BOOL_t fSupplicantCountryCodeHasPriority;
v_BOOL_t fEnforceCountryCodeMatch;
@@ -2809,7 +2820,7 @@
#endif
char overrideCountryCode[4];
v_U32_t gAsdProbeInterval;
- v_U32_t gAsdTriggerThreshold;
+ v_S7_t gAsdTriggerThreshold;
v_U32_t gAsdRTTRssiHystThreshold;
v_BOOL_t debugP2pRemainOnChannel;
v_U32_t cfgBtcCTS2SduringSCO;
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index df67b4e..ebf03cf 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -767,6 +767,10 @@
hdd_scan_pending_option_e scan_pending_option;
tANI_U8 sessionId;
+ /* time to store last station scan done. */
+ v_TIME_t last_scan_timestamp;
+ tANI_U8 last_scan_channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+ tANI_U8 last_scan_numChannels;
}hdd_scaninfo_t;
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index f53e85e..5acb5b6 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,
@@ -2904,7 +2911,7 @@
CFG_ASD_PROBE_INTERVAL_MIN,
CFG_ASD_PROBE_INTERVAL_MAX),
- REG_VARIABLE( CFG_ASD_TRIGGER_THRESHOLD_NAME, WLAN_PARAM_Integer,
+ REG_VARIABLE( CFG_ASD_TRIGGER_THRESHOLD_NAME, WLAN_PARAM_SignedInteger,
hdd_config_t, gAsdTriggerThreshold,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_ASD_TRIGGER_THRESHOLD_DEFAULT,
@@ -3612,12 +3619,13 @@
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [overrideCountryCode] Value = [%s] ",pHddCtx->cfg_ini->overrideCountryCode);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdProbeInterval] Value = [%u]",pHddCtx->cfg_ini->gAsdProbeInterval);
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdTriggerThreshold] Value = [%u]",pHddCtx->cfg_ini->gAsdTriggerThreshold);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdTriggerThreshold] Value = [%hhd]",pHddCtx->cfg_ini->gAsdTriggerThreshold);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdRTTRssiHystThreshold]Value = [%u]",pHddCtx->cfg_ini->gAsdRTTRssiHystThreshold);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gRoamtoDFSChannel] Value = [%u] ",pHddCtx->cfg_ini->allowDFSChannelRoam);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gMaxConcurrentActiveSessions] Value = [%u] ", pHddCtx->cfg_ini->gMaxConcurrentActiveSessions);
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 cf86cab..ae0a6b5 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -9426,6 +9426,7 @@
int ret = 0;
bool aborted = false;
long waitRet = 0;
+ tANI_U8 i;
ENTER();
@@ -9510,6 +9511,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
@@ -9656,6 +9678,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;
@@ -9786,6 +9809,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.
@@ -9888,6 +9912,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)
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 8919893..0d88f2e 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -171,8 +171,18 @@
--------------------------------------------------------------------------*/
int hdd_hostapd_open (struct net_device *dev)
{
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
ENTER();
+ if(!test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
+ {
+ //WMM_INIT OR BSS_START not completed
+ hddLog( LOGW, "Ignore hostadp open request");
+ EXIT();
+ return 0;
+ }
+
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
//Turn ON carrier state
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 80bebbc..ab6df87 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -7193,6 +7193,11 @@
clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
}
+ if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
+ {
+ clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
+ }
+
#ifdef FEATURE_WLAN_BATCH_SCAN
if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
{
diff --git a/CORE/MAC/inc/wniCfgAp.h b/CORE/MAC/inc/wniCfgAp.h
index b7fc34a..f9cbb3e 100644
--- a/CORE/MAC/inc/wniCfgAp.h
+++ b/CORE/MAC/inc/wniCfgAp.h
@@ -2644,13 +2644,13 @@
#define WNI_CFG_ASD_PROBE_INTERVAL_APMAX 100
#define WNI_CFG_ASD_PROBE_INTERVAL_APDEF 50
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMIN 0
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMAX 120
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STADEF 45
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMIN -120
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMAX 0
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STADEF -75
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_APMIN 0
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_APMAX 120
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_APDEF 45
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_APMIN -120
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_APMAX 0
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_APDEF -75
#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMIN 0
#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMAX 100
diff --git a/CORE/MAC/inc/wniCfgSta.h b/CORE/MAC/inc/wniCfgSta.h
index 4cf0894..8785e3f 100644
--- a/CORE/MAC/inc/wniCfgSta.h
+++ b/CORE/MAC/inc/wniCfgSta.h
@@ -1717,9 +1717,9 @@
#define WNI_CFG_ASD_PROBE_INTERVAL_STAMAX 100
#define WNI_CFG_ASD_PROBE_INTERVAL_STADEF 50
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMIN 0
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMAX 120
-#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STADEF 45
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMIN -120
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMAX 0
+#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STADEF -75
#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMIN 0
#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMAX 100
diff --git a/CORE/MAC/src/cfg/cfgApi.c b/CORE/MAC/src/cfg/cfgApi.c
index a9ea14a..4fa4bc5 100644
--- a/CORE/MAC/src/cfg/cfgApi.c
+++ b/CORE/MAC/src/cfg/cfgApi.c
@@ -232,10 +232,20 @@
PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);)
retVal = eSIR_CFG_INVALID_ID;
}
- else if ((pMac->cfg.gCfgIBufMin[index] > value) ||
- (pMac->cfg.gCfgIBufMax[index] < value))
+ else if ((pMac->cfg.gCfgIBufMin[index] < pMac->cfg.gCfgIBufMax[index]) &&
+ ((pMac->cfg.gCfgIBufMin[index] > value) ||
+ (pMac->cfg.gCfgIBufMax[index] < value)))
{
- PELOGE(cfgLog(pMac, LOGE, FL("Value %d out of range [%d,%d] cfg id %d"),
+ PELOGE(cfgLog(pMac, LOGE, FL("Value %u out of range [%u,%u] cfgid %hu"),
+ value, pMac->cfg.gCfgIBufMin[index],
+ pMac->cfg.gCfgIBufMax[index], cfgId);)
+ retVal = eSIR_CFG_INVALID_ID;
+ }
+ else if (!(pMac->cfg.gCfgIBufMin[index] < pMac->cfg.gCfgIBufMax[index]) &&
+ (((tANI_S32)(pMac->cfg.gCfgIBufMin[index]) > (tANI_S32)value) ||
+ ((tANI_S32)(pMac->cfg.gCfgIBufMax[index]) < (tANI_S32)value)))
+ {
+ PELOGE(cfgLog(pMac, LOGE, FL("Value %d out of range [%d,%d] cfgid %hu"),
value, pMac->cfg.gCfgIBufMin[index],
pMac->cfg.gCfgIBufMax[index], cfgId);)
retVal = eSIR_CFG_INVALID_ID;
diff --git a/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/CORE/SVC/src/logging/wlan_logging_sock_svc.c
index 16c0159..7a0b678 100644
--- a/CORE/SVC/src/logging/wlan_logging_sock_svc.c
+++ b/CORE/SVC/src/logging/wlan_logging_sock_svc.c
@@ -309,11 +309,6 @@
pr_err("%s\n", to_be_sent);
}
- // wlan logging svc resources are not yet initialized
- if (!gwlan_logging.pcur_node) {
- return -EIO;
- }
-
/* Format the Log time [Secondselapsedinaday.microseconds] */
do_gettimeofday(&tv);
tlen = snprintf(tbuf, sizeof(tbuf), "[%s][%5lu.%06lu] ", current->comm,
@@ -325,6 +320,12 @@
spin_lock_irqsave(&gwlan_logging.spin_lock, flags);
+ // wlan logging svc resources are not yet initialized
+ if (!gwlan_logging.pcur_node) {
+ spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags);
+ return -EIO;
+ }
+
pfilled_length = &gwlan_logging.pcur_node->filled_length;
/* Check if we can accomodate more log into current node/buffer */