From 3dd7895b19fc22ee27004733dfc1e7eef376d2d0 Mon Sep 17 00:00:00 2001 From: abhinav kumar Date: Mon, 23 Jan 2023 11:53:43 +0530 Subject: [PATCH] qcacld-3.0: Abort connection for next AP if SAP stop/start is pending In the case of STA/CLI + STA/CLI, if an STA/CLI is in connecting state and a disconnect is received on any other STA/CLI, the disconnect can timeout waiting for the connection on the first STA/CLI to get completed. This is because the connection is a blocking serialization command and it can try multiple candidates and thus can take up to 30+ sec to complete. Same way if an SAP/GO has a start/stop command or peer disconnect in pending queue, the delay is processing it can cause timeouts and other issues. So abort the next connection attempt if any of the vdev is waiting for vdev operation to avoid timeouts. Change-Id: I09077555b4f3a33f5ef5846ffd6e2bc5ea998858 CRs-Fixed: 3386150 --- core/sme/src/csr/csr_api_roam.c | 69 +++++++++++++++++++++---------- core/sme/src/csr/csr_inside_api.h | 9 ++-- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 854b6c35a72e..0b75b2e3a1e8 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -8711,35 +8711,60 @@ bool is_disconnect_pending(struct mac_context *pmac, uint8_t vdev_id) return disconnect_cmd_exist; } -bool is_disconnect_pending_on_other_vdev(struct mac_context *pmac, - uint8_t vdev_id) +bool is_any_other_vdev_connecting_disconnecting(struct mac_context *pmac, + uint8_t vdev_id) { tListElem *entry = NULL; tListElem *next_entry = NULL; tSmeCmd *command = NULL; - bool disconnect_cmd_exist = false; + bool is_pending_cmd = false; + enum QDF_OPMODE opmode; entry = csr_nonscan_pending_ll_peek_head(pmac, LL_ACCESS_NOLOCK); while (entry) { next_entry = csr_nonscan_pending_ll_next(pmac, entry, LL_ACCESS_NOLOCK); command = GET_BASE_ADDR(entry, tSmeCmd, Link); - /* - * check if any other vdev NB disconnect or SB disconnect - * (eSmeCommandWmStatusChange) is pending - */ - if (command && (CSR_IS_DISCONNECT_COMMAND(command) || - command->command == eSmeCommandWmStatusChange) && - command->vdev_id != vdev_id) { - sme_debug("disconnect is pending on vdev:%d, cmd:%d", - command->vdev_id, command->command); - disconnect_cmd_exist = true; - break; + if (!command) { + entry = next_entry; + continue; } + + opmode = wlan_get_opmode_from_vdev_id(pmac->pdev, + command->vdev_id); + + if (opmode == QDF_STA_MODE || opmode == QDF_P2P_CLIENT_MODE) { + /* + * check if any other vdev NB disconnect or SB + * disconnect (eSmeCommandWmStatusChange) is pending + */ + if ((CSR_IS_DISCONNECT_COMMAND(command) || + command->command == eSmeCommandWmStatusChange) && + command->vdev_id != vdev_id) { + sme_debug("disconnect is pending on vdev:%d, cmd:%d", + command->vdev_id, command->command); + is_pending_cmd = true; + break; + } + } + + if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { + /* Check if START/STOP AP OP is in progress */ + if ((command->command == eSmeCommandRoam && + (command->u.roamCmd.roamReason == eCsrStopBss || + command->u.roamCmd.roamReason == eCsrHddIssued))) { + sme_debug("vdev ops pending on vdev_id:%d, cmd:%d, reason:%d", + command->vdev_id, command->command, + command->u.roamCmd.roamReason); + is_pending_cmd = true; + break; + } + } + entry = next_entry; } - return disconnect_cmd_exist; + return is_pending_cmd; } #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -8861,7 +8886,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, struct csr_roam_connectedinfo *prev_connect_info; struct wlan_crypto_pmksa *pmksa; uint32_t len = 0, roamId = 0, reason_code = 0; - bool is_dis_pending, is_dis_pending_on_other_vdev; + bool is_dis_pending, is_vdev_ops_pending_on_other_vdev; bool use_same_bss = false; uint8_t max_retry_count = 1; bool retry_same_bss = false; @@ -8965,8 +8990,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, reason_code); is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId); - is_dis_pending_on_other_vdev = - is_disconnect_pending_on_other_vdev(mac, + is_vdev_ops_pending_on_other_vdev = + is_any_other_vdev_connecting_disconnecting(mac, session_ptr->sessionId); is_time_allowed = csr_is_time_allowed_for_connect_attempt(pCommand, @@ -8976,7 +9001,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * if userspace has issued disconnection or we have reached mac tries or * max time, driver should not continue for next connection. */ - if (is_dis_pending || is_dis_pending_on_other_vdev || !is_time_allowed || + if (is_dis_pending || is_vdev_ops_pending_on_other_vdev || !is_time_allowed || session_ptr->join_bssid_count >= CSR_MAX_BSSID_COUNT) attempt_next_bss = false; @@ -9092,8 +9117,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, if (is_dis_pending) sme_err("disconnect is pending, complete roam"); - if (is_dis_pending_on_other_vdev) - sme_err("disconnect is pending on other vdev, complete roam"); + if (is_vdev_ops_pending_on_other_vdev) + sme_err("vdev ops is pending on other vdev, complete roam"); if (!is_time_allowed) sme_err("time can exceed the active timeout for connection attempt"); diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index b873e2aa8692..d9f9d701cc4c 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -984,15 +985,15 @@ bool is_disconnect_pending(struct mac_context *mac_ctx, uint8_t sessionid); /** - * is_disconnect_pending_on_other_vdev() - To check whether a disconnect req - * is pending on any other vdev or not + * is_any_other_vdev_connecting_disconnecting() - To check whether any other + * vdev is in waiting for vdev operations (connect/disconnect or start/stop AP) * @mac_tx: mac context * @sessionid: session id * * Return true if disconnect is pending on any other vdev */ -bool is_disconnect_pending_on_other_vdev(struct mac_context *mac_ctx, - uint8_t sessionid); +bool is_any_other_vdev_connecting_disconnecting(struct mac_context *mac_ctx, + uint8_t sessionid); QDF_STATUS csr_roam_prepare_bss_config_from_profile(struct mac_context *mac_ctx,