Browse Source

qcacld-3.0: Trigger host crash for command timeout

Add feature to trigger host crash when firmware
fails to send the response and host timesout.

Change-Id: I47f23e03f2729981a346e2a9e8c8541ba9119af4
CRs-Fixed: 1078192
Sandeep Puligilla 8 years ago
parent
commit
afa5289e90

+ 2 - 0
core/cds/inc/cds_config.h

@@ -96,6 +96,7 @@ enum cfg_sub_20_channel_width {
  * @self_gen_frm_pwr: Self gen from power
  * @sub_20_channel_width: Sub 20 MHz ch width, ini intersected with fw cap
  * @flow_steering_enabled: Receive flow steering.
+ * @is_fw_timeout: Indicate whether crash host when fw timesout or not
  * Structure for holding cds ini parameters.
  */
 
@@ -148,5 +149,6 @@ struct cds_config_info {
 	enum cfg_sub_20_channel_width sub_20_channel_width;
 	bool flow_steering_enabled;
 	bool self_recovery_enabled;
+	bool fw_timeout_crash;
 };
 #endif /* !defined( __CDS_CONFIG_H ) */

+ 8 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -3591,6 +3591,13 @@ enum dot11p_mode {
 #define CFG_OPTIMIZE_CA_EVENT_ENABLE     (1)
 #define CFG_OPTIMIZE_CA_EVENT_DEFAULT    (0)
 
+/* Trigger BUG ON when firmware fails to send response */
+#define CFG_CRASH_FW_TIMEOUT_NAME       "fw_timeout_crash"
+#define CFG_CRASH_FW_TIMEOUT_DISABLE    (0)
+#define CFG_CRASH_FW_TIMEOUT_ENABLE     (1)
+#define CFG_CRASH_FW_TIMEOUT_DEFAULT    (0)
+
+
 /*---------------------------------------------------------------------------
    Type declarations
    -------------------------------------------------------------------------*/
@@ -4261,6 +4268,7 @@ struct hdd_config {
 	uint32_t rx_aggregation_size;
 	bool sta_prefer_80MHz_over_160MHz;
 	uint8_t sap_max_inactivity_override;
+	bool fw_timeout_crash;
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

+ 10 - 1
core/hdd/src/wlan_hdd_cfg.c

@@ -4041,7 +4041,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
 		CFG_SAP_MAX_INACTIVITY_OVERRIDE_DEFAULT,
 		CFG_SAP_MAX_INACTIVITY_OVERRIDE_MIN,
-		CFG_SAP_MAX_INACTIVITY_OVERRIDE_MAX)
+		CFG_SAP_MAX_INACTIVITY_OVERRIDE_MAX),
+	REG_VARIABLE(CFG_CRASH_FW_TIMEOUT_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, fw_timeout_crash,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_CRASH_FW_TIMEOUT_DEFAULT,
+		CFG_CRASH_FW_TIMEOUT_DISABLE,
+		CFG_CRASH_FW_TIMEOUT_ENABLE),
 };
 
 /**
@@ -5726,6 +5732,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	hdd_info("Name = [%s] Value = [%u]",
 		CFG_ENABLE_GO_CTS2SELF_FOR_STA,
 		pHddCtx->config->enable_go_cts2self_for_sta);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_CRASH_FW_TIMEOUT_NAME,
+		pHddCtx->config->fw_timeout_crash);
 }
 
 

+ 1 - 0
core/hdd/src/wlan_hdd_main.c

@@ -6995,6 +6995,7 @@ static int hdd_update_cds_config(hdd_context_t *hdd_ctx)
 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
 	cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
 	cds_cfg->self_recovery_enabled = hdd_ctx->config->enableSelfRecovery;
+	cds_cfg->fw_timeout_crash = hdd_ctx->config->fw_timeout_crash;
 
 	hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);

+ 4 - 4
core/wma/inc/wma.h

@@ -252,15 +252,15 @@ enum ds_mode {
 #define WMA_TARGET_REQ_TYPE_VDEV_DEL   0x3
 
 #define WMA_PEER_ASSOC_CNF_START 0x01
-#define WMA_PEER_ASSOC_TIMEOUT (3000) /* 3 seconds */
+#define WMA_PEER_ASSOC_TIMEOUT (6000) /* 6 seconds */
 
 #define WMA_DELETE_STA_RSP_START 0x02
 #define WMA_DELETE_STA_TIMEOUT (6000) /* 6 seconds */
 
 #define WMA_DEL_P2P_SELF_STA_RSP_START 0x03
 
-#define WMA_VDEV_START_REQUEST_TIMEOUT (3000)   /* 3 seconds */
-#define WMA_VDEV_STOP_REQUEST_TIMEOUT  (3000)   /* 3 seconds */
+#define WMA_VDEV_START_REQUEST_TIMEOUT (6000)   /* 6 seconds */
+#define WMA_VDEV_STOP_REQUEST_TIMEOUT  (6000)   /* 6 seconds */
 
 #define WMA_TGT_INVALID_SNR 0x127
 
@@ -1604,8 +1604,8 @@ typedef struct {
 	bool nan_datapath_enabled;
 	QDF_STATUS (*pe_ndp_event_handler)(tpAniSirGlobal mac_ctx,
 					   cds_msg_t *msg);
+	bool fw_timeout_crash;
 	bool sub_20_support;
-
 	tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb;
 	tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb;
 } t_wma_handle, *tp_wma_handle;

+ 51 - 21
core/wma/src/wma_dev_if.c

@@ -2273,14 +2273,20 @@ void wma_hold_req_timer(void *data)
 		WMA_LOGA(FL("WMA_ADD_STA_REQ timed out"));
 		WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"),
 			 params->staMac, params->status);
-		wma_send_msg(wma, WMA_ADD_STA_RSP, (void *)params, 0);
+		if (wma->fw_timeout_crash == true)
+			BUG_ON(1);
+		else
+			wma_send_msg(wma, WMA_ADD_STA_RSP, (void *)params, 0);
 	} else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
 		tpAddBssParams  params = (tpAddBssParams) tgt_req->user_data;
 		params->status = QDF_STATUS_E_TIMEOUT;
 		WMA_LOGA(FL("WMA_ADD_BSS_REQ timed out"));
 		WMA_LOGD(FL("Sending add bss rsp to umac (mac:%pM, status:%d)"),
 			params->selfMacAddr, params->status);
-		wma_send_msg(wma, WMA_ADD_BSS_RSP, (void *)params, 0);
+		if (wma->fw_timeout_crash == true)
+			BUG_ON(1);
+		else
+			wma_send_msg(wma, WMA_ADD_BSS_RSP, (void *)params, 0);
 	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
 		(tgt_req->type == WMA_DELETE_STA_RSP_START)) {
 		tpDeleteStaParams params =
@@ -2289,12 +2295,18 @@ void wma_hold_req_timer(void *data)
 		WMA_LOGE(FL("WMA_DEL_STA_REQ timed out"));
 		WMA_LOGP(FL("Sending del sta rsp to umac (mac:%pM, status:%d)"),
 			 params->staMac, params->status);
-		/*
-		 * Assert in development build only.
-		 * Send response in production builds.
-		 */
-		QDF_ASSERT(0);
-		wma_send_msg(wma, WMA_DELETE_STA_RSP, (void *)params, 0);
+
+		if (wma->fw_timeout_crash == true) {
+			BUG_ON(1);
+		} else {
+			/*
+			 * Assert in development build only.
+			 * Send response in production builds.
+			 */
+			QDF_ASSERT(0);
+			wma_send_msg(wma, WMA_DELETE_STA_RSP,
+				    (void *)params, 0);
+		}
 	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
 		(tgt_req->type == WMA_DEL_P2P_SELF_STA_RSP_START)) {
 		WMA_LOGA(FL("wma delete sta p2p request timed out"));
@@ -2435,7 +2447,13 @@ void wma_vdev_resp_timer(void *data)
 			(tpSwitchChannelParams) tgt_req->user_data;
 		params->status = QDF_STATUS_E_TIMEOUT;
 		WMA_LOGA("%s: WMA_SWITCH_CHANNEL_REQ timedout", __func__);
-		wma_send_msg(wma, WMA_SWITCH_CHANNEL_RSP, (void *)params, 0);
+
+		/* Trigger host crash if the flag is set */
+		if (wma->fw_timeout_crash == true)
+			BUG_ON(1);
+		else
+			wma_send_msg(wma, WMA_SWITCH_CHANNEL_RSP,
+				    (void *)params, 0);
 		if (wma->interfaces[tgt_req->vdev_id].is_channel_switch) {
 			wma->interfaces[tgt_req->vdev_id].is_channel_switch =
 				false;
@@ -2509,7 +2527,11 @@ void wma_vdev_resp_timer(void *data)
 		}
 		params->status = QDF_STATUS_E_TIMEOUT;
 		WMA_LOGA("%s: WMA_DELETE_BSS_REQ timedout", __func__);
-		wma_send_msg(wma, WMA_DELETE_BSS_RSP, (void *)params, 0);
+		if (wma->fw_timeout_crash == true)
+			BUG_ON(1);
+		else
+			wma_send_msg(wma, WMA_DELETE_BSS_RSP,
+				    (void *)params, 0);
 		if (iface->del_staself_req) {
 			WMA_LOGA("scheduling defered deletion(vdev id %x)",
 				 tgt_req->vdev_id);
@@ -2531,14 +2553,19 @@ void wma_vdev_resp_timer(void *data)
 		params->status = QDF_STATUS_E_TIMEOUT;
 
 		WMA_LOGA("%s: WMA_DEL_STA_SELF_REQ timedout", __func__);
-		sme_msg.type = eWNI_SME_DEL_STA_SELF_RSP;
-		sme_msg.bodyptr = iface->del_staself_req;
-		sme_msg.bodyval = 0;
-
-		status = cds_mq_post_message(QDF_MODULE_ID_SME, &sme_msg);
-		if (!QDF_IS_STATUS_SUCCESS(status)) {
-			WMA_LOGE("Failed to post eWNI_SME_ADD_STA_SELF_RSP");
-			qdf_mem_free(iface->del_staself_req);
+		if (wma->fw_timeout_crash == true) {
+			BUG_ON(1);
+		} else {
+			sme_msg.type = eWNI_SME_DEL_STA_SELF_RSP;
+			sme_msg.bodyptr = iface->del_staself_req;
+			sme_msg.bodyval = 0;
+
+			status = cds_mq_post_message(QDF_MODULE_ID_SME,
+						     &sme_msg);
+			if (!QDF_IS_STATUS_SUCCESS(status)) {
+				WMA_LOGE("Failed to post eWNI_SME_ADD_STA_SELF_RSP");
+				qdf_mem_free(iface->del_staself_req);
+			}
 		}
 		if (iface->addBssStaContext)
 			qdf_mem_free(iface->addBssStaContext);
@@ -2551,8 +2578,12 @@ void wma_vdev_resp_timer(void *data)
 		WMA_LOGA("%s: WMA_ADD_BSS_REQ timedout", __func__);
 		WMA_LOGI("%s: bssid %pM vdev_id %d", __func__, params->bssId,
 			 tgt_req->vdev_id);
-		wma_send_msg(wma, WMA_ADD_BSS_RSP, (void *)params, 0);
-		QDF_ASSERT(0);
+		if (wma->fw_timeout_crash == true) {
+			BUG_ON(1);
+		} else {
+			wma_send_msg(wma, WMA_ADD_BSS_RSP, (void *)params, 0);
+			QDF_ASSERT(0);
+		}
 		goto free_tgt_req;
 
 	} else if (tgt_req->msg_type == WMA_OCB_SET_CONFIG_CMD) {
@@ -3228,7 +3259,6 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 		else
 			WMA_LOGD("Sent PKT_PWR_SAVE_5G_EBT cmd to target, val = %x, status = %d",
 				pps_val, status);
-
 		wma_send_peer_assoc(wma, add_bss->nwType,
 					    &add_bss->staContext);
 		peer_assoc_sent = true;

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

@@ -2071,6 +2071,7 @@ QDF_STATUS wma_open(void *cds_context,
 	wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
 	wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
 	wma_handle->saved_chan.num_channels = 0;
+	wma_handle->fw_timeout_crash = cds_cfg->fw_timeout_crash;
 
 	qdf_status = qdf_event_create(&wma_handle->wma_ready_event);
 	if (qdf_status != QDF_STATUS_SUCCESS) {