ソースを参照

qcacld-3.0: Fix active cmd timeout for set_dual_mac_config during SSR

In error cases of set hw mode, set dual config etc are not handled
in all scenarios and thus the active cmd is not removed in this case
resulting in active cmd timeout.

Fix this by handling and sending failure resp for all the error
scenarios.

Change-Id: I21151798f58bf9816458430d96c7fd1d5f0ee07f
CRs-Fixed: 2341816
Abhishek Singh 6 年 前
コミット
d93a0b2d5c

+ 21 - 9
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -136,6 +136,7 @@ static QDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
 	buf = (struct s_sir_set_hw_mode *) msg;
 	if (!buf) {
 		pe_err("Set HW mode param is NULL");
+		status = QDF_STATUS_E_INVAL;
 		/* To free the active command list */
 		goto fail;
 	}
@@ -143,8 +144,11 @@ static QDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
 	len = sizeof(*req_msg);
 
 	req_msg = qdf_mem_malloc(len);
-	if (!req_msg)
-		return QDF_STATUS_E_NOMEM;
+	if (!req_msg) {
+		pe_debug("failed to allocate memory");
+		status = QDF_STATUS_E_NOMEM;
+		goto fail;
+	}
 
 	req_msg->hw_mode_index = buf->set_hw.hw_mode_index;
 	req_msg->reason = buf->set_hw.reason;
@@ -175,7 +179,7 @@ fail:
 	resp_msg.bodyptr = param;
 	resp_msg.bodyval = 0;
 	lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
-	return QDF_STATUS_SUCCESS;
+	return status;
 }
 
 /**
@@ -201,6 +205,7 @@ static QDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac,
 	buf = (struct sir_set_dual_mac_cfg *) msg;
 	if (!buf) {
 		pe_err("Set Dual mac config is NULL");
+		status = QDF_STATUS_E_INVAL;
 		/* To free the active command list */
 		goto fail;
 	}
@@ -208,8 +213,11 @@ static QDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac,
 	len = sizeof(*req_msg);
 
 	req_msg = qdf_mem_malloc(len);
-	if (!req_msg)
-		return QDF_STATUS_E_NOMEM;
+	if (!req_msg) {
+		pe_debug("failed to allocate memory");
+		status = QDF_STATUS_E_NOMEM;
+		goto fail;
+	}
 
 	req_msg->scan_config = buf->set_dual_mac.scan_config;
 	req_msg->fw_mode_config = buf->set_dual_mac.fw_mode_config;
@@ -239,7 +247,7 @@ fail:
 	resp_msg.bodyptr = param;
 	resp_msg.bodyval = 0;
 	lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
-	return QDF_STATUS_SUCCESS;
+	return status;
 }
 
 /**
@@ -265,13 +273,17 @@ static QDF_STATUS lim_process_set_antenna_mode_req(tpAniSirGlobal mac,
 	buf = (struct sir_set_antenna_mode *) msg;
 	if (!buf) {
 		pe_err("Set antenna mode is NULL");
+		status = QDF_STATUS_E_INVAL;
 		/* To free the active command list */
 		goto fail;
 	}
 
 	req_msg = qdf_mem_malloc(sizeof(*req_msg));
-	if (!req_msg)
-		return QDF_STATUS_E_NOMEM;
+	if (!req_msg) {
+		pe_debug("failed to allocate memory");
+		status = QDF_STATUS_E_NOMEM;
+		goto fail;
+	}
 
 	req_msg->num_rx_chains = buf->set_antenna_mode.num_rx_chains;
 	req_msg->num_tx_chains = buf->set_antenna_mode.num_tx_chains;
@@ -301,7 +313,7 @@ fail:
 	resp_msg.bodyptr = param;
 	resp_msg.bodyval = 0;
 	lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
-	return QDF_STATUS_SUCCESS;
+	return status;
 }
 
 /**

+ 7 - 7
core/sme/src/csr/csr_api_roam.c

@@ -21332,7 +21332,8 @@ void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command)
 		policy_mgr_set_hw_mode_change_in_progress(mac->psoc,
 			POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
 		sme_err("Posting to PE failed");
-		return;
+		cmd = NULL;
+		goto fail;
 	}
 	return;
 fail:
@@ -21398,15 +21399,14 @@ void csr_process_set_dual_mac_config(tpAniSirGlobal mac, tSmeCmd *command)
 	cmd->set_dual_mac.set_dual_mac_cb =
 		command->u.set_dual_mac_cmd.set_dual_mac_cb;
 
-	sme_debug(
-		"Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x",
-		cmd->set_dual_mac.scan_config,
-		cmd->set_dual_mac.fw_mode_config);
+	sme_debug("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x",
+		  cmd->set_dual_mac.scan_config,
+		  cmd->set_dual_mac.fw_mode_config);
 
 	status = umac_send_mb_message_to_mac(cmd);
-	if (QDF_STATUS_SUCCESS != status) {
+	if (QDF_IS_STATUS_ERROR(status)) {
 		sme_err("Posting to PE failed");
-		return;
+		goto fail;
 	}
 	return;
 fail:

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

@@ -225,6 +225,7 @@ enum ds_mode {
 #define WMA_DELETE_PEER_RSP 0x05
 
 #define WMA_PDEV_SET_HW_MODE_RESP 0x06
+#define WMA_PDEV_MAC_CFG_RESP 0x07
 
 #ifdef CONFIG_SLUB_DEBUG_ON
 #define SLUB_DEBUG_FACTOR (2)
@@ -237,6 +238,8 @@ enum ds_mode {
 #define WMA_VDEV_STOP_REQUEST_TIMEOUT    (6000) * (SLUB_DEBUG_FACTOR)
 #define WMA_VDEV_HW_MODE_REQUEST_TIMEOUT (6000) * (SLUB_DEBUG_FACTOR)
 #define WMA_VDEV_PLCY_MGR_CMD_TIMEOUT    (6000) * (SLUB_DEBUG_FACTOR)
+#define WMA_VDEV_DUAL_MAC_CFG_TIMEOUT    (5000) * (SLUB_DEBUG_FACTOR)
+
 #define WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT	WAKELOCK_DURATION_RECOMMENDED
 
 #define WMA_TGT_INVALID_SNR (0)

+ 20 - 6
core/wma/src/wma_dev_if.c

@@ -3398,16 +3398,30 @@ void wma_hold_req_timer(void *data)
 
 		WMA_LOGE(FL("set hw mode req timed out"));
 
-		if (params) {
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+						SIR_HAL_PDEV_SET_HW_MODE);
+		} else if (params) {
 			params->status = SET_HW_MODE_STATUS_ECANCELED;
 			params->cfgd_hw_mode_index = 0;
 			params->num_vdev_mac_entries = 0;
+			wma_send_msg_high_priority(wma,
+				SIR_HAL_PDEV_SET_HW_MODE_RESP, params, 0);
+		}
+	} else if ((tgt_req->msg_type == SIR_HAL_PDEV_DUAL_MAC_CFG_REQ) &&
+			(tgt_req->type == WMA_PDEV_MAC_CFG_RESP)) {
+		struct sir_dual_mac_config_resp *resp =
+						qdf_mem_malloc(sizeof(*resp));
 
-			if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true)
-				QDF_BUG(0);
-			else
-				wma_send_msg_high_priority(wma,
-					SIR_HAL_PDEV_SET_HW_MODE_RESP, params, 0);
+		WMA_LOGE(FL("set dual mac config timeout"));
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) {
+			wma_trigger_recovery_assert_on_fw_timeout(
+						SIR_HAL_PDEV_DUAL_MAC_CFG_REQ);
+		} else if (resp) {
+			resp->status = SET_HW_MODE_STATUS_ECANCELED;
+			wma_send_msg_high_priority(wma,
+						   SIR_HAL_PDEV_MAC_CFG_RESP,
+						   resp, 0);
 		}
 	} else {
 		WMA_LOGE(FL("Unhandled timeout for msg_type:%d and type:%d"),

+ 26 - 2
core/wma/src/wma_main.c

@@ -4155,6 +4155,8 @@ static int wma_pdev_set_dual_mode_config_resp_evt_handler(void *handle,
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+	wma_remove_req(wma, 0, WMA_PDEV_MAC_CFG_RESP);
+
 	dual_mac_cfg_resp = qdf_mem_malloc(sizeof(*dual_mac_cfg_resp));
 	if (!dual_mac_cfg_resp)
 		/* Since the mem alloc failed, we cannot send resp to LIM.
@@ -8735,7 +8737,7 @@ fail:
 	WMA_LOGE("%s: Sending HW mode fail response to LIM", __func__);
 	wma_send_msg(wma_handle, SIR_HAL_PDEV_SET_HW_MODE_RESP,
 			(void *) param, 0);
-	return QDF_STATUS_SUCCESS;
+	return QDF_STATUS_E_FAILURE;
 }
 
 /**
@@ -8751,6 +8753,8 @@ QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
 		struct policy_mgr_dual_mac_config *msg)
 {
 	QDF_STATUS status;
+	struct wma_target_req *req_msg;
+	struct sir_dual_mac_config_resp *resp;
 
 	if (!wma_handle) {
 		WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
@@ -8776,12 +8780,32 @@ QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
 		WMA_LOGE("%s: Failed to send WMI_PDEV_SET_DUAL_MAC_CONFIG_CMDID: %d",
 				__func__, status);
 		wma_release_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock);
-		return status;
+		goto fail;
 	}
 	policy_mgr_update_dbs_req_config(wma_handle->psoc,
 	msg->scan_config, msg->fw_mode_config);
 
+	req_msg = wma_fill_hold_req(wma_handle, 0,
+				SIR_HAL_PDEV_DUAL_MAC_CFG_REQ,
+				WMA_PDEV_MAC_CFG_RESP, NULL,
+				WMA_VDEV_DUAL_MAC_CFG_TIMEOUT);
+	if (!req_msg) {
+		WMA_LOGE("Failed to allocate request for SIR_HAL_PDEV_DUAL_MAC_CFG_REQ");
+		wma_remove_req(wma_handle, 0, WMA_PDEV_MAC_CFG_RESP);
+	}
+
 	return QDF_STATUS_SUCCESS;
+
+fail:
+	resp = qdf_mem_malloc(sizeof(*resp));
+	if (!resp)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	resp->status = SET_HW_MODE_STATUS_ECANCELED;
+	WMA_LOGE("%s: Sending failure response to LIM", __func__);
+	wma_send_msg(wma_handle, SIR_HAL_PDEV_MAC_CFG_RESP, (void *) resp, 0);
+	return QDF_STATUS_E_FAILURE;
+
 }
 
 /**