Jelajahi Sumber

qcacld-3.0: Reset PS timeout when PS requested from user space

When receiving a power save request from user space, disable any active
power save timer and start a new one using the timeout supplied from
user space.

Change-Id: I88299776a973118e1bdba8cfd5fa4c8018f0758a
CRs-Fixed: 1065234
Dustin Brown 8 tahun lalu
induk
melakukan
f660fb4c10

+ 2 - 1
core/hdd/inc/wlan_hdd_power.h

@@ -179,7 +179,8 @@ int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
 				  enum nl80211_tx_power_setting type,
 				  int dbm);
 int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
-				     struct net_device *dev, bool mode,
+				     struct net_device *dev,
+				     bool allow_power_save,
 				     int timeout);
 
 int wlan_hdd_ipv4_changed(struct notifier_block *nb,

+ 6 - 1
core/hdd/src/wlan_hdd_assoc.c

@@ -2133,8 +2133,13 @@ static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
 						 tCsrRoamInfo *roaminfo)
 {
 	int ret;
+	uint32_t timeout;
 	hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 
+	timeout = hddstactx->hdd_ReassocScenario ?
+		AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE :
+		AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE;
+
 	hddLog(LOG1,
 		"Changing TL state to AUTHENTICATED for StaId= %d",
 		hddstactx->conn_info.staId[0]);
@@ -2152,7 +2157,7 @@ static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
 		sme_ps_enable_auto_ps_timer(
 			WLAN_HDD_GET_HAL_CTX(adapter),
 			adapter->sessionId,
-			hddstactx->hdd_ReassocScenario);
+			timeout);
 	}
 
 	return ret;

+ 53 - 48
core/hdd/src/wlan_hdd_power.c

@@ -81,16 +81,6 @@
 
 /* Type declarations */
 
-/**
- * enum hdd_power_mode - Power Mode enumerations
- * @DRIVER_POWER_MODE_AUTO: Driver can place device into power save
- * @DRIVER_POWER_MODE_ACTIVE: Driver should operate at full power
- */
-enum hdd_power_mode {
-	DRIVER_POWER_MODE_AUTO = 0,
-	DRIVER_POWER_MODE_ACTIVE = 1,
-};
-
 #ifdef FEATURE_WLAN_DIAG_SUPPORT
 /**
  * hdd_wlan_suspend_resume_event()- send suspend/resume state
@@ -1572,12 +1562,13 @@ success:
 /**
  * wlan_hdd_set_powersave() - Set powersave mode
  * @adapter: adapter upon which the request was received
- * @mode: desired powersave mode
+ * @allow_power_save: is wlan allowed to go into power save mode
+ * @timeout: timeout period in ms
  *
  * Return: 0 on success, non-zero on any error
  */
-static int
-wlan_hdd_set_powersave(hdd_adapter_t *adapter, enum hdd_power_mode mode)
+static int wlan_hdd_set_powersave(hdd_adapter_t *adapter,
+	bool allow_power_save, uint32_t timeout)
 {
 	tHalHandle hal;
 	hdd_context_t *hdd_ctx;
@@ -1593,26 +1584,18 @@ wlan_hdd_set_powersave(hdd_adapter_t *adapter, enum hdd_power_mode mode)
 		return -EINVAL;
 	}
 
-	hdd_info("power mode=%d", mode);
+	hdd_info("Allow power save: %d", allow_power_save);
 	hal = WLAN_HDD_GET_HAL_CTX(adapter);
 
-
-	if (DRIVER_POWER_MODE_ACTIVE == mode) {
-		hdd_info("Wlan driver Entering Full Power");
-
-		/*
-		 * Enter Full power command received from GUI
-		 * this means we are disconnected
-		 */
-		sme_ps_enable_disable(hal, adapter->sessionId, SME_PS_DISABLE);
-	} else if (DRIVER_POWER_MODE_AUTO == mode) {
-		if ((QDF_STA_MODE == adapter->device_mode) ||
-				(QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
+	if (allow_power_save) {
+		if (QDF_STA_MODE == adapter->device_mode ||
+		    QDF_P2P_CLIENT_MODE == adapter->device_mode) {
 			hdd_notice("Disabling Auto Power save timer");
-			sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
-					(adapter),
-					adapter->sessionId);
+			sme_ps_disable_auto_ps_timer(
+				WLAN_HDD_GET_HAL_CTX(adapter),
+				adapter->sessionId);
 		}
+
 		if (hdd_ctx->config && hdd_ctx->config->is_ps_enabled) {
 			hdd_notice("Wlan driver Entering Power save");
 
@@ -1625,7 +1608,20 @@ wlan_hdd_set_powersave(hdd_adapter_t *adapter, enum hdd_power_mode mode)
 		} else {
 			hdd_info("Power Save is not enabled in the cfg");
 		}
+	} else {
+		hdd_info("Wlan driver Entering Full Power");
+
+		/*
+		 * Enter Full power command received from GUI
+		 * this means we are disconnected
+		 */
+		sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX(adapter),
+			adapter->sessionId);
+		sme_ps_enable_disable(hal, adapter->sessionId, SME_PS_DISABLE);
+		sme_ps_enable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX(adapter),
+			adapter->sessionId, timeout);
 	}
+
 	return 0;
 }
 
@@ -1983,13 +1979,14 @@ int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
  * __wlan_hdd_cfg80211_set_power_mgmt() - set cfg80211 power management config
  * @wiphy: Pointer to wiphy
  * @dev: Pointer to network device
- * @mode: Driver mode
- * @timeout: Timeout value
+ * @allow_power_save: is wlan allowed to go into power save mode
+ * @timeout: Timeout value in ms
  *
  * Return: 0 for success, non-zero for failure
  */
 static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
-					      struct net_device *dev, bool mode,
+					      struct net_device *dev,
+					      bool allow_power_save,
 					      int timeout)
 {
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
@@ -1997,6 +1994,12 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 	QDF_STATUS qdf_status;
 	int status;
 
+	if (timeout < 0) {
+		hdd_notice("User space timeout: %d; Using default instead: %d",
+			timeout, AUTO_PS_ENTRY_USER_TIMER_DEFAULT_VALUE);
+		timeout = AUTO_PS_ENTRY_USER_TIMER_DEFAULT_VALUE;
+	}
+
 	ENTER();
 
 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
@@ -2022,13 +2025,13 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 	}
 	mutex_unlock(&pHddCtx->iface_change_lock);
 
-	if ((DRIVER_POWER_MODE_AUTO == !mode) &&
-	    (true == pHddCtx->hdd_wlan_suspended) &&
-	    (pHddCtx->config->fhostArpOffload) &&
+	if (allow_power_save &&
+	    pHddCtx->hdd_wlan_suspended &&
+	    pHddCtx->config->fhostArpOffload &&
 	    (eConnectionState_Associated ==
 	     (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) {
-
-		hdd_notice("offload: in cfg80211_set_power_mgmt, calling arp offload");
+		hdd_notice("offload: in cfg80211_set_power_mgmt, "
+			"calling arp offload");
 		qdf_status = hdd_conf_arp_offload(pAdapter, true);
 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 			hdd_notice("Failed to enable ARPOFFLOAD Feature %d",
@@ -2036,21 +2039,21 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 		}
 	}
 
-	status = wlan_hdd_set_powersave(pAdapter, !mode);
+	status = wlan_hdd_set_powersave(pAdapter, allow_power_save, timeout);
 
-	if (!mode) {
+	if (allow_power_save) {
+		hdd_warn("DHCP stop indicated through power save");
+		sme_dhcp_stop_ind(pHddCtx->hHal, pAdapter->device_mode,
+				  pAdapter->macAddressCurrent.bytes,
+				  pAdapter->sessionId);
+		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DHCP);
+	} else {
 		hdd_err("DHCP start indicated through power save");
 		hdd_prevent_suspend_timeout(1000,
 					    WIFI_POWER_EVENT_WAKELOCK_DHCP);
 		sme_dhcp_start_ind(pHddCtx->hHal, pAdapter->device_mode,
 				   pAdapter->macAddressCurrent.bytes,
 				   pAdapter->sessionId);
-	} else {
-		hdd_warn("DHCP stop indicated through power save");
-		sme_dhcp_stop_ind(pHddCtx->hHal, pAdapter->device_mode,
-				  pAdapter->macAddressCurrent.bytes,
-				  pAdapter->sessionId);
-		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DHCP);
 	}
 
 	EXIT();
@@ -2061,19 +2064,21 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
  * wlan_hdd_cfg80211_set_power_mgmt() - set cfg80211 power management config
  * @wiphy: Pointer to wiphy
  * @dev: Pointer to network device
- * @mode: Driver mode
+ * @allow_power_save: is wlan allowed to go into power save mode
  * @timeout: Timeout value
  *
  * Return: 0 for success, non-zero for failure
  */
 int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
-				     struct net_device *dev, bool mode,
+				     struct net_device *dev,
+				     bool allow_power_save,
 				     int timeout)
 {
 	int ret;
 
 	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
+	ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev,
+		allow_power_save, timeout);
 	cds_ssr_unprotect(__func__);
 
 	return ret;

+ 5 - 0
core/sme/inc/sme_power_save.h

@@ -41,6 +41,11 @@
 /* Auto Deferred Ps Entry Timer value - 20000 ms */
 #define AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE 20000
 
+/*
+ * Auto Ps Entry User default timeout value, used instead of negative timeouts
+ * from user space - 5000ms
+ */
+#define AUTO_PS_ENTRY_USER_TIMER_DEFAULT_VALUE 5000
 
 
 /**

+ 1 - 1
core/sme/inc/sme_power_save_api.h

@@ -71,7 +71,7 @@ tSirRetStatus sme_post_pe_message(tpAniSirGlobal mac_ctx, tpSirMsgQ pMsg);
 
 QDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
 		uint32_t sessionId,
-		bool isReassoc);
+		uint32_t timeout);
 QDF_STATUS sme_ps_disable_auto_ps_timer(tHalHandle hal_ctx,
 		uint32_t sessionId);
 

+ 13 - 11
core/sme/src/common/sme_power_save.c

@@ -980,26 +980,28 @@ tSirRetStatus sme_post_pe_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
 	return eSIR_SUCCESS;
 }
 
+/**
+ * sme_ps_enable_auto_ps_timer(): Enable power-save auto timer with timeout
+ *
+ * @hal_ctx:	HAL context
+ * @session_id:	adapter session Id
+ * @timeout:	timeout period in ms
+ *
+ * Returns:	0 on success, non-zero on failure
+ */
 QDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
-		uint32_t session_id,
-		bool is_reassoc)
+	uint32_t session_id, uint32_t timeout)
 {
 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
 	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
 	struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
 	QDF_STATUS qdf_status;
-	uint32_t timer_value;
-
-	if (is_reassoc)
-		timer_value = AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE;
-	else
-		timer_value = AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE;
 
-	sms_log(mac_ctx, LOGE, FL("Start auto_ps_timer for %d is_reassoc:%d "),
-			timer_value, is_reassoc);
+	sms_log(mac_ctx, LOGE, FL("Start auto_ps_timer for %d ms"),
+		timeout);
 
 	qdf_status = qdf_mc_timer_start(&ps_param->auto_ps_enable_timer,
-			timer_value);
+		timeout);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		if (QDF_STATUS_E_ALREADY == qdf_status) {
 			/* Consider this ok since the timer is already started*/