diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index cf1332f982..f5e15d19f3 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -4614,9 +4614,9 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM) { sme_debug("Continue connect/reassoc on vdev %d request_id %x reason %d", vdev_id, request_id, reason); - wlan_cm_hw_mode_change_resp(pm_ctx->pdev, vdev_id, - request_id, - QDF_STATUS_SUCCESS); + wlan_connect_hw_mode_change_resp(pm_ctx->pdev, vdev_id, + request_id, + QDF_STATUS_SUCCESS); } policy_mgr_debug("No action needed right now"); ret = policy_mgr_set_opportunistic_update(psoc); diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 142a83dca9..061c1974f7 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -3775,4 +3775,9 @@ void wlan_mlme_get_safe_mode_enable(struct wlan_objmgr_psoc *psoc, * Return: 6g_power_type */ uint32_t wlan_mlme_get_6g_ap_power_type(struct wlan_objmgr_vdev *vdev); + +QDF_STATUS wlan_connect_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, + wlan_cm_id cm_id, + QDF_STATUS status); #endif /* _WLAN_MLME_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 28809ed6e6..b28608c900 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -31,6 +31,7 @@ #include "wlan_utility.h" #include "wlan_policy_mgr_ucfg.h" #include "wlan_vdev_mgr_utils_api.h" +#include <../../core/src/wlan_cm_vdev_api.h> /* quota in milliseconds */ #define MCC_DUTY_CYCLE 70 @@ -5944,3 +5945,10 @@ uint32_t wlan_mlme_get_6g_ap_power_type(struct wlan_objmgr_vdev *vdev) return mlme_obj->reg_tpc_obj.power_type_6g; } +QDF_STATUS wlan_connect_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status) +{ + return wlan_cm_handle_hw_mode_change_resp(pdev, vdev_id, cm_id, + status); +} diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h index 75032b6310..48f2ccd769 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h @@ -107,6 +107,20 @@ struct cm_vdev_disconnect_rsp { struct wlan_objmgr_psoc *psoc; }; +/* + * struct cm_vdev_hw_mode_rsp - hw mode change from vdev mgr to CM + * @pdev: pdev pointer + * @vdev_id: vdev id + * @cm_id: connection ID which gave the hw mode change request + * @status: status of the HW mode change. + */ +struct cm_vdev_hw_mode_rsp { + struct wlan_objmgr_pdev *pdev; + uint8_t vdev_id; + wlan_cm_id cm_id; + QDF_STATUS status; +}; + /** * struct cm_vdev_join_rsp - connect rsp from vdev mgr to connection mgr * @psoc: psoc object @@ -691,6 +705,22 @@ QDF_STATUS wlan_cm_send_connect_rsp(struct scheduler_msg *msg); */ void wlan_cm_free_connect_rsp(struct cm_vdev_join_rsp *rsp); +/** + * wlan_cm_handle_hw_mode_change_resp() Process hw_mode_change_resp + * @pdev: pdev pointer + * @vdev_id: vdev_id + * @cm_id: connection manager id + * @status: status + * + * This API is to break the context and avoid calling CM API to take CM lock + * while holding SME lock. + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_handle_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status); /** * wlan_cm_rso_stop_continue_disconnect() - Continue disconnect after RSO stop * @psoc: psoc object diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c index 83cfb257e8..7346061f16 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c @@ -1623,3 +1623,53 @@ bool cm_is_vdevid_active(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id) return active; } + +static +QDF_STATUS cm_handle_hw_mode_change_resp_cb(struct scheduler_msg *msg) +{ + struct cm_vdev_hw_mode_rsp *rsp; + + if (!msg || !msg->bodyptr) + return QDF_STATUS_E_FAILURE; + + rsp = msg->bodyptr; + wlan_cm_hw_mode_change_resp(rsp->pdev, rsp->vdev_id, rsp->cm_id, + rsp->status); + + qdf_mem_free(rsp); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_cm_handle_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status) +{ + struct cm_vdev_hw_mode_rsp *rsp; + struct scheduler_msg rsp_msg = {0}; + QDF_STATUS qdf_status; + + rsp = qdf_mem_malloc(sizeof(*rsp)); + if (!rsp) + return QDF_STATUS_E_FAILURE; + + rsp->pdev = pdev; + rsp->vdev_id = vdev_id; + rsp->cm_id = cm_id; + rsp->status = status; + + rsp_msg.bodyptr = rsp; + rsp_msg.callback = cm_handle_hw_mode_change_resp_cb; + + qdf_status = scheduler_post_message(QDF_MODULE_ID_MLME, + QDF_MODULE_ID_TARGET_IF, + QDF_MODULE_ID_TARGET_IF, &rsp_msg); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + mlme_err(CM_PREFIX_FMT "Failed to post HW mode change rsp", + CM_PREFIX_REF(vdev_id, cm_id)); + qdf_mem_free(rsp); + } + + return qdf_status; +} diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 0ea76fa6d1..dfca5fc910 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -236,8 +236,9 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t param->status == SET_HW_MODE_STATUS_ALREADY) status = QDF_STATUS_SUCCESS; - wlan_cm_hw_mode_change_resp(mac->pdev, session_id, request_id, - status); + wlan_cm_handle_hw_mode_change_resp(mac->pdev, session_id, + request_id, + status); } end: