summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNachiket Kukade <nkukade@codeaurora.org>2018-06-18 15:52:36 +0530
committernshrivas <nshrivas@codeaurora.org>2018-07-04 08:40:17 -0700
commitd79e903986f8d984e99fc61e8664d33068fa5128 (patch)
tree98f834300d7d8edc10d308c307d006b6884c4058
parent95de7fc4ceeb238d04ec3d7f35aa2d569bab273f (diff)
qcacld-3.0: Add upper limit check on Listen Interval configuration
User can override the Listen Interval value set during association by using wifi config set vendor command. Since there is no limit check in host, a very high value causes an assert in the Firmware. Add an upper limit check on the user Listen Interval value. Change-Id: I8128ccbb875adf57c95a15d0391fb442d3dbbbc3 CRs-Fixed: 2256334
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c6
-rw-r--r--core/wma/src/wma_main.c41
2 files changed, 37 insertions, 10 deletions
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index c6012b50d73c..461fddbe4e74 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -5732,6 +5732,12 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
override_li = nla_get_u32(
tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL]);
+ if (override_li > CFG_ENABLE_DYNAMIC_DTIM_MAX) {
+ hdd_err_ratelimited(HDD_NL_ERR_RATE_LIMIT,
+ "Invalid value for listen interval - %d",
+ override_li);
+ return -EINVAL;
+ }
status = sme_override_listen_interval(hdd_ctx->hHal,
adapter->sessionId,
override_li);
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index c3906c25dfff..898d3ebea0c3 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -832,6 +832,8 @@ static void wma_set_modulated_dtim(tp_wma_handle wma,
&wma->interfaces[vdev_id];
bool prev_dtim_enabled;
uint32_t listen_interval;
+ uint32_t beacon_interval_mod;
+ uint32_t max_mod_dtim;
QDF_STATUS ret;
iface->alt_modulated_dtim = privcmd->param_value;
@@ -846,22 +848,41 @@ static void wma_set_modulated_dtim(tp_wma_handle wma,
if ((true == iface->alt_modulated_dtim_enabled) ||
(true == prev_dtim_enabled)) {
- listen_interval = iface->alt_modulated_dtim
- * iface->dtimPeriod;
+ beacon_interval_mod = iface->beaconInterval / 100;
+ if (!beacon_interval_mod)
+ beacon_interval_mod = 1;
- ret = wma_vdev_set_param(wma->wmi_handle,
- privcmd->param_vdev_id,
- WMI_VDEV_PARAM_LISTEN_INTERVAL,
- listen_interval);
+ if (iface->dtimPeriod)
+ max_mod_dtim = wma->staMaxLIModDtim
+ / (iface->dtimPeriod*beacon_interval_mod);
+ else
+ max_mod_dtim = wma->staMaxLIModDtim/beacon_interval_mod;
+
+ if (!max_mod_dtim)
+ max_mod_dtim = 1;
+
+ if (iface->alt_modulated_dtim > max_mod_dtim) {
+ WMA_LOGE("User ModDtim(%d) exceeding ceiling limit(%d)",
+ iface->alt_modulated_dtim, max_mod_dtim);
+ listen_interval = max_mod_dtim * iface->dtimPeriod;
+ } else {
+ listen_interval = iface->alt_modulated_dtim
+ * iface->dtimPeriod;
+ }
+
+ WMA_LOGD("Setting Listen Interval %d for vdev id %d",
+ listen_interval, vdev_id);
+ ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+ WMI_VDEV_PARAM_LISTEN_INTERVAL,
+ listen_interval);
if (QDF_IS_STATUS_ERROR(ret))
/* Even if it fails, continue */
WMA_LOGW("Failed to set listen interval %d",
listen_interval);
- ret = wma_vdev_set_param(wma->wmi_handle,
- privcmd->param_vdev_id,
- WMI_VDEV_PARAM_DTIM_POLICY,
- NORMAL_DTIM);
+ ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+ WMI_VDEV_PARAM_DTIM_POLICY,
+ NORMAL_DTIM);
if (QDF_IS_STATUS_ERROR(ret))
WMA_LOGE("Failed to Set to Normal DTIM policy");
}