Jelajahi Sumber

qcacld-3.0: Set power save enable directly to FW

Currently, the driver schedules the message to set
power save enable/disable to FW as part of the
set power mgmt command received from the userspace.
This command is then scheduled and is sent via
the scheduler thread.
Generally, userspace sets the power save disable
when it starts the DHCP process and enables the
power save back when the DHCP is completed.
DHCP packets are sent through the Datapath and the
PS enable/disable command would be sent via the
control path explained above.
the Race could happen that the scheduler was busy
with some other task and the PS disable command
was in the queue and the DHCP process began.
This would result in DHCP packets going to the peer
with PS enabled.

The fix is to set the power save enable/disable directly
instead of using the scheduler path.

Change-Id: I0f2aed37f875c283f318fb44bcc40d0ab401413a
CRs-Fixed: 2611480
gaurank kathpalia 5 tahun lalu
induk
melakukan
e7bd43280f

+ 0 - 2
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -402,8 +402,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
 		CASE_RETURN_STRING(WMA_CHNL_SWITCH_REQ);
 		CASE_RETURN_STRING(WMA_ADD_TS_REQ);
 		CASE_RETURN_STRING(WMA_DEL_TS_REQ);
-		CASE_RETURN_STRING(WMA_EXIT_PS_REQ);
-		CASE_RETURN_STRING(WMA_ENTER_PS_REQ);
 		CASE_RETURN_STRING(WMA_MISSED_BEACON_IND);
 
 		CASE_RETURN_STRING(WMA_SWITCH_CHANNEL_RSP);

+ 16 - 28
core/sme/src/common/sme_power_save.c

@@ -138,13 +138,12 @@ static void sme_get_ps_state(struct mac_context *mac_ctx,
  *
  * Return: QDF_STATUS
  */
-static QDF_STATUS sme_ps_enable_ps_req_params(struct mac_context *mac_ctx,
-		uint32_t session_id)
+static QDF_STATUS
+sme_ps_enable_ps_req_params(struct mac_context *mac_ctx, uint32_t vdev_id)
 {
 	struct sEnablePsParams *enable_ps_req_params;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	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];
+	struct ps_params *ps_param = &ps_global_info->ps_params[vdev_id];
 	enum ps_state ps_state;
 
 	enable_ps_req_params =  qdf_mem_malloc(sizeof(*enable_ps_req_params));
@@ -155,21 +154,20 @@ static QDF_STATUS sme_ps_enable_ps_req_params(struct mac_context *mac_ctx,
 		enable_ps_req_params->psSetting = eSIR_ADDON_ENABLE_UAPSD;
 		sme_ps_fill_uapsd_req_params(mac_ctx,
 				&enable_ps_req_params->uapsdParams,
-				session_id, &ps_state);
+				vdev_id, &ps_state);
 		ps_state = UAPSD_MODE;
 		enable_ps_req_params->uapsdParams.enable_ps = true;
 	} else {
 		enable_ps_req_params->psSetting = eSIR_ADDON_NOTHING;
 		ps_state = LEGACY_POWER_SAVE_MODE;
 	}
-	enable_ps_req_params->sessionid = session_id;
+	enable_ps_req_params->sessionid = vdev_id;
 
-	status = sme_post_ps_msg_to_wma(WMA_ENTER_PS_REQ, enable_ps_req_params);
-	if (!QDF_IS_STATUS_SUCCESS(status))
-		return QDF_STATUS_E_FAILURE;
-	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
-		FL("Message WMA_ENTER_PS_REQ Successfully sent to WMA"));
+	wma_enable_sta_ps_mode(enable_ps_req_params);
+
+	sme_debug("Powersave Enable sent to FW");
 	ps_param->ps_state = ps_state;
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -181,24 +179,21 @@ static QDF_STATUS sme_ps_enable_ps_req_params(struct mac_context *mac_ctx,
  * Return: QDF_STATUS
  */
 static QDF_STATUS sme_ps_disable_ps_req_params(struct mac_context *mac_ctx,
-		uint32_t session_id)
+					       uint32_t vdev_id)
 {
 	struct  sDisablePsParams *disable_ps_req_params;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	disable_ps_req_params = qdf_mem_malloc(sizeof(*disable_ps_req_params));
 	if (!disable_ps_req_params)
 		return QDF_STATUS_E_NOMEM;
 
 	disable_ps_req_params->psSetting = eSIR_ADDON_NOTHING;
-	disable_ps_req_params->sessionid = session_id;
+	disable_ps_req_params->sessionid = vdev_id;
+
+	wma_disable_sta_ps_mode(disable_ps_req_params);
+	sme_debug("Powersave disable sent to FW");
+	sme_set_ps_state(mac_ctx, vdev_id, FULL_POWER_MODE);
 
-	status = sme_post_ps_msg_to_wma(WMA_EXIT_PS_REQ, disable_ps_req_params);
-	if (!QDF_IS_STATUS_SUCCESS(status))
-		return QDF_STATUS_E_FAILURE;
-	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
-			FL("Message WMA_EXIT_PS_REQ Successfully sent to WMA"));
-	sme_set_ps_state(mac_ctx, session_id, FULL_POWER_MODE);
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -411,7 +406,6 @@ QDF_STATUS sme_ps_timer_flush_sync(mac_handle_t mac_handle, uint8_t session_id)
 	enum ps_state ps_state;
 	QDF_TIMER_STATE tstate;
 	struct sEnablePsParams *req;
-	t_wma_handle *wma;
 
 	QDF_BUG(session_id < WLAN_MAX_VDEVS);
 	if (session_id >= WLAN_MAX_VDEVS)
@@ -432,12 +426,6 @@ QDF_STATUS sme_ps_timer_flush_sync(mac_handle_t mac_handle, uint8_t session_id)
 
 	qdf_mc_timer_stop(&ps_parm->auto_ps_enable_timer);
 
-	wma = cds_get_context(QDF_MODULE_ID_WMA);
-	if (!wma) {
-		sme_err("wma is null");
-		return QDF_STATUS_E_INVAL;
-	}
-
 	req = qdf_mem_malloc(sizeof(*req));
 	if (!req)
 		return QDF_STATUS_E_NOMEM;
@@ -454,7 +442,7 @@ QDF_STATUS sme_ps_timer_flush_sync(mac_handle_t mac_handle, uint8_t session_id)
 	}
 	req->sessionid = session_id;
 
-	wma_enable_sta_ps_mode(wma, req);
+	wma_enable_sta_ps_mode(req);
 	qdf_mem_free(req);
 
 	ps_parm->ps_state = ps_state;

+ 2 - 3
core/wma/inc/wma_internal.h

@@ -1034,12 +1034,11 @@ void wma_process_update_userpos(tp_wma_handle wma_handle,
 
 /**
  * wma_enable_sta_ps_mode() - enable sta powersave params in fw
- * @wma: wma handle
  * @ps_req: power save request
  *
  * Return: none
  */
-void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req);
+void wma_enable_sta_ps_mode(tpEnablePsParams ps_req);
 
 QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
 					    uint32_t vdev_id, uint32_t param,
@@ -1059,7 +1058,7 @@ void wma_set_tx_power(WMA_HANDLE handle,
 void wma_set_max_tx_power(WMA_HANDLE handle,
 				 tMaxTxPowerParams *tx_pwr_params);
 
-void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req);
+void wma_disable_sta_ps_mode(tpDisablePsParams ps_req);
 
 /**
  * wma_enable_uapsd_mode() - enable uapsd mode in fw

+ 0 - 3
core/wma/inc/wma_types.h

@@ -140,9 +140,6 @@
 
 #define WMA_MISSED_BEACON_IND          SIR_HAL_MISSED_BEACON_IND
 
-#define WMA_ENTER_PS_REQ               SIR_HAL_ENTER_PS_REQ
-#define WMA_EXIT_PS_REQ                SIR_HAL_EXIT_PS_REQ
-
 #define WMA_HIDDEN_SSID_RESTART_RSP    SIR_HAL_HIDDEN_SSID_RESTART_RSP
 #define WMA_SWITCH_CHANNEL_RSP         SIR_HAL_SWITCH_CHANNEL_RSP
 #define WMA_P2P_NOA_ATTR_IND           SIR_HAL_P2P_NOA_ATTR_IND

+ 0 - 10
core/wma/src/wma_main.c

@@ -8319,16 +8319,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
 		qdf_mem_free(msg->bodyptr);
 		break;
 #endif /* REMOVE_PKT_LOG */
-	case WMA_ENTER_PS_REQ:
-		wma_enable_sta_ps_mode(wma_handle,
-				       (tpEnablePsParams) msg->bodyptr);
-		qdf_mem_free(msg->bodyptr);
-		break;
-	case WMA_EXIT_PS_REQ:
-		wma_disable_sta_ps_mode(wma_handle,
-					(tpDisablePsParams) msg->bodyptr);
-		qdf_mem_free(msg->bodyptr);
-		break;
 	case WMA_ENABLE_UAPSD_REQ:
 		wma_enable_uapsd_mode(wma_handle,
 				      (tpEnableUapsdParams) msg->bodyptr);

+ 46 - 23
core/wma/src/wma_power.c

@@ -719,33 +719,44 @@ static enum powersave_qpower_mode wma_get_qpower_config(tp_wma_handle wma)
 	}
 }
 
-void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
+void wma_enable_sta_ps_mode(tpEnablePsParams ps_req)
 {
 	uint32_t vdev_id = ps_req->sessionid;
 	QDF_STATUS ret;
-	enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
-	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+	enum powersave_qpower_mode qpower_config;
+	struct wma_txrx_node *iface;
+	t_wma_handle *wma_handle;
 
-	if (!iface->vdev) {
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		wma_err("wma handle is null");
+		return;
+	}
+
+	iface = &wma_handle->interfaces[vdev_id];
+
+	if (!iface || !iface->vdev) {
 		WMA_LOGE("%s: vdev is NULL for vdev_%d", __func__, vdev_id);
 		return;
 	}
 
+	qpower_config = wma_get_qpower_config(wma_handle);
 	if (eSIR_ADDON_NOTHING == ps_req->psSetting) {
 		if (qpower_config && iface->uapsd_cached_val) {
 			qpower_config = 0;
 			WMA_LOGD("Qpower is disabled");
 		}
 		WMA_LOGD("Enable Sta Mode Ps vdevId %d", vdev_id);
-		ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+		ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
+						   vdev_id,
 				WMI_STA_PS_PARAM_UAPSD, 0);
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			WMA_LOGE("Set Uapsd param 0 Failed vdevId %d", vdev_id);
 			return;
 		}
 
-		ret = wma_set_force_sleep(wma, vdev_id, false,
-				qpower_config, true);
+		ret = wma_set_force_sleep(wma_handle, vdev_id, false,
+					  qpower_config, true);
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			WMA_LOGE("Enable Sta Ps Failed vdevId %d", vdev_id);
 			return;
@@ -757,10 +768,11 @@ void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
 		if (uapsd_val != iface->uapsd_cached_val) {
 			WMA_LOGD("Enable Uapsd vdevId %d Mask %d",
 					vdev_id, uapsd_val);
-			ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
-					vdev_id,
-					WMI_STA_PS_PARAM_UAPSD,
-					uapsd_val);
+			ret =
+			 wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
+						      vdev_id,
+						      WMI_STA_PS_PARAM_UAPSD,
+						      uapsd_val);
 			if (QDF_IS_STATUS_ERROR(ret)) {
 				WMA_LOGE("Enable Uapsd Failed vdevId %d",
 						vdev_id);
@@ -778,27 +790,27 @@ void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
 			WMA_LOGD("Qpower is disabled");
 		}
 		WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id);
-		ret = wma_set_force_sleep(wma, vdev_id, true,
-				qpower_config, true);
+		ret = wma_set_force_sleep(wma_handle, vdev_id, true,
+					  qpower_config, true);
 
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			WMA_LOGE("Enable Forced Sleep Failed vdevId %d",
-					vdev_id);
+				 vdev_id);
 			return;
 		}
 	}
 
-	if (wma->ito_repeat_count) {
+	if (wma_handle->ito_repeat_count) {
 		WMA_LOGI("Set ITO count to %d for vdevId %d",
-					wma->ito_repeat_count, vdev_id);
+					wma_handle->ito_repeat_count, vdev_id);
 
-		ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
+		ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
 			vdev_id,
 			WMI_STA_PS_PARAM_MAX_RESET_ITO_COUNT_ON_TIM_NO_TXRX,
-			wma->ito_repeat_count);
+			wma_handle->ito_repeat_count);
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			WMA_LOGE("Set ITO count failed vdevId %d Error %d",
-								vdev_id, ret);
+				 vdev_id, ret);
 			return;
 		}
 	}
@@ -807,6 +819,7 @@ void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
 	iface->in_bmps = true;
 }
 
+
 /**
  * wma_disable_sta_ps_mode() - disable sta powersave params in fw
  * @wma: wma handle
@@ -814,16 +827,25 @@ void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
  *
  * Return: none
  */
-void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req)
+void wma_disable_sta_ps_mode(tpDisablePsParams ps_req)
 {
 	QDF_STATUS ret;
 	uint32_t vdev_id = ps_req->sessionid;
-	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+	struct wma_txrx_node *iface;
+	t_wma_handle *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		wma_err("wma handle is null");
+		return;
+	}
+
+	iface = &wma_handle->interfaces[vdev_id];
 
 	WMA_LOGD("Disable Sta Mode Ps vdevId %d", vdev_id);
 
 	/* Disable Sta Mode Power save */
-	ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
+	ret = wmi_unified_set_sta_ps(wma_handle->wmi_handle, vdev_id, false);
 	if (QDF_IS_STATUS_ERROR(ret)) {
 		WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
 		return;
@@ -833,7 +855,8 @@ void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req)
 	/* Disable UAPSD incase if additional Req came */
 	if (eSIR_ADDON_DISABLE_UAPSD == ps_req->psSetting) {
 		WMA_LOGD("Disable Uapsd vdevId %d", vdev_id);
-		ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
+		ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
+						   vdev_id,
 				WMI_STA_PS_PARAM_UAPSD, 0);
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id);