Browse Source

qcacld-3.0: Generate bug report if scan rejected by driver

qcacld-2.0 to qcacld-3.0 propagation

Driver will not allow scan if connection is in progress.

Add driver changes to generate bug report and trigger SSR
if current session id, rejected reason matches with last rejected
sesssion id, reason and time delta between current time and
last rejected timestamp is greater than 5 mins

Change-Id: Ic64a6fd443104b291b5b7f6cda3bfbe8273c671a
CRs-Fixed: 1081489
Sreelakshmi Konamki 8 years ago
parent
commit
b53c629c0f

+ 2 - 1
core/cds/inc/cds_concurrency.h

@@ -729,7 +729,8 @@ typedef const enum cds_conc_next_action next_action_two_connection_table_type
 typedef const enum cds_conc_next_action next_action_three_connection_table_type
 [CDS_MAX_TWO_CONNECTION_MODE][CDS_MAX_BAND];
 
-bool cds_is_connection_in_progress(void);
+bool cds_is_connection_in_progress(uint8_t *session_id,
+				enum scan_reject_states *reason);
 void cds_dump_concurrency_info(void);
 
 #ifdef FEATURE_WLAN_TDLS

+ 20 - 2
core/cds/src/cds_concurrency.c

@@ -846,13 +846,15 @@ QDF_STATUS cds_pdev_set_hw_mode(uint32_t session_id,
 
 /**
  * cds_is_connection_in_progress() - check if connection is in progress
- * @hdd_ctx - HDD context
+ * @session_id: session id
+ * @reason: scan reject reason
  *
  * Go through each adapter and check if Connection is in progress
  *
  * Return: true if connection is in progress else false
  */
-bool cds_is_connection_in_progress(void)
+bool cds_is_connection_in_progress(uint8_t *session_id,
+				enum scan_reject_states *reason)
 {
 	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
 	hdd_station_ctx_t *hdd_sta_ctx = NULL;
@@ -890,6 +892,10 @@ bool cds_is_connection_in_progress(void)
 			cds_err("%p(%d) Connection is in progress",
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter),
 				adapter->sessionId);
+			if (session_id && reason) {
+				*session_id = adapter->sessionId;
+				*reason = eHDD_CONNECTION_IN_PROGRESS;
+			}
 			return true;
 		}
 		if ((QDF_STA_MODE == adapter->device_mode) &&
@@ -899,6 +905,10 @@ bool cds_is_connection_in_progress(void)
 			cds_err("%p(%d) Reassociation in progress",
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter),
 				adapter->sessionId);
+			if (session_id && reason) {
+				*session_id = adapter->sessionId;
+				*reason = eHDD_REASSOC_IN_PROGRESS;
+			}
 			return true;
 		}
 		if ((QDF_STA_MODE == adapter->device_mode) ||
@@ -915,6 +925,10 @@ bool cds_is_connection_in_progress(void)
 				cds_err("client " MAC_ADDRESS_STR
 					" is in middle of WPS/EAPOL exchange.",
 					MAC_ADDR_ARRAY(sta_mac));
+				if (session_id && reason) {
+					*session_id = adapter->sessionId;
+					*reason = eHDD_EAPOL_IN_PROGRESS;
+				}
 				return true;
 			}
 		} else if ((QDF_SAP_MODE == adapter->device_mode) ||
@@ -932,6 +946,10 @@ bool cds_is_connection_in_progress(void)
 				cds_err("client " MAC_ADDRESS_STR
 				" of SAP/GO is in middle of WPS/EAPOL exchange",
 				MAC_ADDR_ARRAY(sta_mac));
+				if (session_id && reason) {
+					*session_id = adapter->sessionId;
+					*reason = eHDD_SAP_EAPOL_IN_PROGRESS;
+				}
 				return true;
 			}
 			if (hdd_ctx->connection_in_progress) {

+ 20 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -267,6 +267,23 @@
 /* session ID invalid */
 #define HDD_SESSION_ID_INVALID    0xFF
 
+#define SCAN_REJECT_THRESHOLD_TIME 300000 /* Time is in msec, equal to 5 mins */
+
+/*
+ * @eHDD_SCAN_REJECT_DEFAULT: default value
+ * @eHDD_CONNECTION_IN_PROGRESS: connection is in progress
+ * @eHDD_REASSOC_IN_PROGRESS: reassociation is in progress
+ * @eHDD_EAPOL_IN_PROGRESS: STA/P2P-CLI is in middle of EAPOL/WPS exchange
+ * @eHDD_SAP_EAPOL_IN_PROGRESS: SAP/P2P-GO is in middle of EAPOL/WPS exchange
+ */
+enum scan_reject_states {
+	eHDD_SCAN_REJECT_DEFAULT = 0,
+	eHDD_CONNECTION_IN_PROGRESS,
+	eHDD_REASSOC_IN_PROGRESS,
+	eHDD_EAPOL_IN_PROGRESS,
+	eHDD_SAP_EAPOL_IN_PROGRESS,
+};
+
 /* Default Psoc id */
 #define DEFAULT_PSOC_ID 1
 
@@ -1566,6 +1583,9 @@ struct hdd_context_s {
 	/* tdls source timer to enable/disable TDLS on p2p listen */
 	qdf_mc_timer_t tdls_source_timer;
 	uint8_t beacon_probe_rsp_cnt_per_scan;
+	uint8_t last_scan_reject_session_id;
+	enum scan_reject_states last_scan_reject_reason;
+	unsigned long last_scan_reject_timestamp;
 };
 
 /**

+ 1 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -12866,7 +12866,7 @@ static int wlan_hdd_cfg80211_connect_start(hdd_adapter_t *pAdapter,
 		goto ret_status;
 	}
 
-	if (true == cds_is_connection_in_progress()) {
+	if (true == cds_is_connection_in_progress(NULL, NULL)) {
 		hdd_err("Connection refused: conn in progress");
 		status = -EINVAL;
 		goto ret_status;

+ 2 - 2
core/hdd/src/wlan_hdd_hostapd.c

@@ -7214,7 +7214,7 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 
 	ENTER();
 
-	if (!update_beacon && cds_is_connection_in_progress()) {
+	if (!update_beacon && cds_is_connection_in_progress(NULL, NULL)) {
 		hdd_err("Can't start BSS: connection is in progress");
 		return -EINVAL;
 	}
@@ -8086,7 +8086,7 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 		pAdapter->device_mode, cds_is_sub_20_mhz_enabled());
 
 
-	if (cds_is_connection_in_progress()) {
+	if (cds_is_connection_in_progress(NULL, NULL)) {
 		hdd_err("Can't start BSS: connection is in progress");
 		return -EBUSY;
 	}

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

@@ -6867,6 +6867,7 @@ static hdd_context_t *hdd_context_create(struct device *dev)
 
 	hdd_ctx->pcds_context = p_cds_context;
 	hdd_ctx->parent_dev = dev;
+	hdd_ctx->last_scan_reject_session_id = 0xFF;
 
 	hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
 	if (hdd_ctx->config == NULL) {

+ 1 - 1
core/hdd/src/wlan_hdd_p2p.c

@@ -852,7 +852,7 @@ static int wlan_hdd_request_remain_on_channel(struct wiphy *wiphy,
 	ret = wlan_hdd_validate_context(pHddCtx);
 	if (0 != ret)
 		return ret;
-	if (cds_is_connection_in_progress()) {
+	if (cds_is_connection_in_progress(NULL, NULL)) {
 		hdd_err("Connection is in progress");
 		isBusy = true;
 	}

+ 4 - 0
core/hdd/src/wlan_hdd_power.c

@@ -1392,6 +1392,10 @@ QDF_STATUS hdd_wlan_re_init(void)
 	/* Restart all adapters */
 	hdd_start_all_adapters(pHddCtx);
 
+	pHddCtx->last_scan_reject_session_id = 0xFF;
+	pHddCtx->last_scan_reject_reason = 0;
+	pHddCtx->last_scan_reject_timestamp = 0;
+
 	pHddCtx->btCoexModeSet = false;
 
 	/* Allow the phone to go to sleep */

+ 34 - 1
core/hdd/src/wlan_hdd_scan.c

@@ -1508,6 +1508,8 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 	uint16_t con_dfs_ch;
 	uint8_t num_chan = 0;
 	bool is_p2p_scan = false;
+	uint8_t curr_session_id;
+	enum scan_reject_states curr_reason;
 
 	ENTER();
 
@@ -1612,10 +1614,41 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 #endif
 
 	/* Check if scan is allowed at this point of time */
-	if (cds_is_connection_in_progress()) {
+	if (cds_is_connection_in_progress(&curr_session_id, &curr_reason)) {
 		hdd_err("Scan not allowed");
+		if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
+		    pHddCtx->last_scan_reject_reason != curr_reason ||
+		    !pHddCtx->last_scan_reject_timestamp) {
+			pHddCtx->last_scan_reject_session_id = curr_session_id;
+			pHddCtx->last_scan_reject_reason = curr_reason;
+			pHddCtx->last_scan_reject_timestamp =
+				jiffies_to_msecs(jiffies);
+		} else {
+			hdd_err("curr_session id %d curr_reason %d time delta %lu",
+				curr_session_id, curr_reason,
+				(jiffies_to_msecs(jiffies) -
+				 pHddCtx->last_scan_reject_timestamp));
+			if ((jiffies_to_msecs(jiffies) -
+			    pHddCtx->last_scan_reject_timestamp) >=
+			    SCAN_REJECT_THRESHOLD_TIME) {
+				pHddCtx->last_scan_reject_timestamp = 0;
+				if (pHddCtx->config->enable_fatal_event) {
+					cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+					    WLAN_LOG_INDICATOR_HOST_DRIVER,
+					    WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
+					    false, true);
+				} else {
+					hdd_err("Triggering SSR due to scan stuck");
+					cds_trigger_recovery(false);
+				}
+			}
+		}
 		return -EBUSY;
 	}
+	pHddCtx->last_scan_reject_timestamp = 0;
+	pHddCtx->last_scan_reject_session_id = 0xFF;
+	pHddCtx->last_scan_reject_reason = 0;
+
 	/* Check whether SAP scan can be skipped or not */
 	if (pAdapter->device_mode == QDF_SAP_MODE &&
 	   wlan_hdd_sap_skip_scan_check(pHddCtx, request)) {

+ 2 - 0
core/mac/inc/ani_global.h

@@ -171,6 +171,7 @@ enum log_event_indicator {
    @WLAN_LOG_REASON_SME_OUT_OF_CMD_BUFL sme out of cmd buffer
  * @WLAN_LOG_REASON_NO_SCAN_RESULTS: no scan results to report from HDD
  * This enum contains the different reason codes for bug report
+ * @WLAN_LOG_REASON_SCAN_NOT_ALLOWED: scan not allowed due to connection states
  */
 enum log_event_host_reason_code {
 	WLAN_LOG_REASON_CODE_UNUSED,
@@ -184,6 +185,7 @@ enum log_event_host_reason_code {
 	WLAN_LOG_REASON_HDD_TIME_OUT,
 	WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
 	WLAN_LOG_REASON_NO_SCAN_RESULTS,
+	WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
 };
 
 

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

@@ -19506,7 +19506,7 @@ void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command)
 
 	if ((SIR_UPDATE_REASON_OPPORTUNISTIC ==
 	     command->u.set_hw_mode_cmd.reason) &&
-	    (true == cds_is_connection_in_progress())) {
+	    (true == cds_is_connection_in_progress(NULL, NULL))) {
 		sms_log(mac, LOGE, FL("Set HW mode refused: conn in progress"));
 		cds_restart_opportunistic_timer(false);
 		goto fail;