diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index 87706bb09b3d..8bfd31ba0f62 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/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 diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 4dd404ab6283..b1eded79c881 100644 --- a/core/cds/src/cds_concurrency.c +++ b/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) { diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 5b975b1100cd..d561d4b4d872 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/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; }; /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 044a42423c5d..054492e0c7ba 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/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; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index db71a14dafe5..75484326edab 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/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; } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d8da608f7521..007963207336 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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) { diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index 7f39d458b92a..4c34b8072f08 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/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; } diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index dbc7b516e7c1..a2a690e23144 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/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 */ diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index d9b4df2f02fc..a19e6a07b67b 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/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)) { diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index a1f45d6b113e..26e85863b859 100644 --- a/core/mac/inc/ani_global.h +++ b/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, }; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 1965ef599bdc..14b90be63fba 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/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;