From 64b096fde9c1dadaf56126a255739f786466b179 Mon Sep 17 00:00:00 2001 From: Amruta Kulkarni Date: Fri, 19 Feb 2021 15:02:36 -0800 Subject: [PATCH] qcacmn: Support roam start and roam abort request in CM Add support for roam start and roam abort request in connection manager. CRs-Fixed: 2882233 Change-Id: I5780e7f22363ee6014d39b0df9cb068b4afdd71c --- os_if/linux/mlme/inc/osif_cm_util.h | 29 ++++++++ os_if/linux/mlme/src/osif_cm_util.c | 56 ++++++++++++++- .../connection_mgr/core/src/wlan_cm_connect.c | 6 ++ .../core/src/wlan_cm_disconnect.c | 8 ++- .../connection_mgr/core/src/wlan_cm_roam.h | 51 ++++++++++++- .../connection_mgr/core/src/wlan_cm_roam_sm.c | 72 +++++++++++++++---- .../core/src/wlan_cm_roam_util.c | 33 ++++++++- .../mlme/connection_mgr/core/src/wlan_cm_sm.c | 64 +++++++++++++---- .../mlme/connection_mgr/core/src/wlan_cm_sm.h | 9 ++- .../connection_mgr/core/src/wlan_cm_util.c | 29 +++++++- umac/mlme/include/wlan_mlme_cmn.h | 27 +++++++ .../dispatcher/src/wlan_cmn_mlme_main.c | 23 ++++++ 12 files changed, 373 insertions(+), 34 deletions(-) diff --git a/os_if/linux/mlme/inc/osif_cm_util.h b/os_if/linux/mlme/inc/osif_cm_util.h index 60d9b751cb..56545e2add 100644 --- a/os_if/linux/mlme/inc/osif_cm_util.h +++ b/os_if/linux/mlme/inc/osif_cm_util.h @@ -217,6 +217,20 @@ typedef QDF_STATUS enum netif_action_type action, enum netif_reason_type reason); +/** + * typedef os_if_cm_napi_serialize_ctrl_cb: Callback to update + * NAPI serialization + * @action: bool action to take on napi serialization + * + * This callback indicates legacy modules to take the actions + * related to napi serialization + * + * Context: Any context. + * Return: QDF_STATUS + */ +typedef QDF_STATUS + (*os_if_cm_napi_serialize_ctrl_cb)(bool action); + /** * osif_cm_unlink_bss() - function to unlink bss from kernel and scan database * on connect timeouts reasons @@ -251,6 +265,8 @@ void osif_cm_unlink_bss(struct wlan_objmgr_vdev *vdev, * legacy modules * @osif_cm_netif_queue_ctrl_cb: callback to legacy module to take * actions on netif queue + * @os_if_cm_napi_serialize_ctrl_cb: callback to legacy module to take + * actions on napi serialization * @save_gtk_cb : callback to legacy module to save gtk * @set_hlp_data_cb: callback to legacy module to save hlp data */ @@ -259,6 +275,7 @@ struct osif_cm_ops { osif_cm_disconnect_comp_cb disconnect_complete_cb; #ifdef CONN_MGR_ADV_FEATURE osif_cm_netif_queue_ctrl_cb netif_queue_control_cb; + os_if_cm_napi_serialize_ctrl_cb napi_serialize_control_cb; #endif #ifdef WLAN_FEATURE_FILS_SK osif_cm_save_gtk_cb save_gtk_cb; @@ -314,6 +331,18 @@ QDF_STATUS osif_cm_disconnect_comp_ind(struct wlan_objmgr_vdev *vdev, QDF_STATUS osif_cm_netif_queue_ind(struct wlan_objmgr_vdev *vdev, enum netif_action_type action, enum netif_reason_type reason); + +/** + * osif_cm_napi_serialize() - Function to indicate napi serialize + * action to legacy module + * @action: Action to take on napi serialization + * + * This function indicates to take the actions related to napi activities + * + * Context: Any context. + * Return: QDF_STATUS + */ +QDF_STATUS osif_cm_napi_serialize(bool action); #endif #ifdef WLAN_FEATURE_FILS_SK diff --git a/os_if/linux/mlme/src/osif_cm_util.c b/os_if/linux/mlme/src/osif_cm_util.c index 4dd1171797..baf500742b 100644 --- a/os_if/linux/mlme/src/osif_cm_util.c +++ b/os_if/linux/mlme/src/osif_cm_util.c @@ -296,6 +296,7 @@ osif_cm_disable_netif_queue(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_SUCCESS; } #endif + /** * osif_cm_disconnect_start_cb() - Disconnect start callback * @vdev: vdev pointer @@ -312,12 +313,53 @@ osif_cm_disconnect_start_cb(struct wlan_objmgr_vdev *vdev) return osif_cm_disable_netif_queue(vdev); } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * osif_cm_roam_start_cb() - Roam start callback + * @vdev: vdev pointer + * + * This callback indicates os_if that roaming has started + * so that os_if can stop all the activity on this connection + * + * Return: QDF_STATUS + */ +static QDF_STATUS +osif_cm_roam_start_cb(struct wlan_objmgr_vdev *vdev) +{ + return osif_cm_netif_queue_ind(vdev, + WLAN_STOP_ALL_NETIF_QUEUE, + WLAN_CONTROL_PATH); +} + +/** + * osif_cm_roam_abort_cb() - Roam abort callback + * @vdev: vdev pointer + * + * This callback indicates os_if that roaming has been aborted + * so that os_if can stop all the activity on this connection + * + * Return: QDF_STATUS + */ +static QDF_STATUS +osif_cm_roam_abort_cb(struct wlan_objmgr_vdev *vdev) +{ + osif_cm_napi_serialize(false); + return osif_cm_netif_queue_ind(vdev, + WLAN_WAKE_ALL_NETIF_QUEUE, + WLAN_CONTROL_PATH); +} +#endif + static struct mlme_cm_ops cm_ops = { .mlme_cm_connect_complete_cb = osif_cm_connect_complete_cb, .mlme_cm_failed_candidate_cb = osif_cm_failed_candidate_cb, .mlme_cm_update_id_and_src_cb = osif_cm_update_id_and_src_cb, .mlme_cm_disconnect_complete_cb = osif_cm_disconnect_complete_cb, .mlme_cm_disconnect_start_cb = osif_cm_disconnect_start_cb, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + .mlme_cm_roam_start_cb = osif_cm_roam_start_cb, + .mlme_cm_roam_abort_cb = osif_cm_roam_abort_cb, +#endif }; /** @@ -417,8 +459,20 @@ QDF_STATUS osif_cm_netif_queue_ind(struct wlan_objmgr_vdev *vdev, return ret; } -#endif +QDF_STATUS osif_cm_napi_serialize(bool action) +{ + os_if_cm_napi_serialize_ctrl_cb cb = NULL; + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (osif_cm_legacy_ops) + cb = osif_cm_legacy_ops->napi_serialize_control_cb; + if (cb) + ret = cb(action); + + return ret; +} +#endif #ifdef WLAN_FEATURE_FILS_SK QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_resp *rsp) diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c index 7819043812..6e551b362a 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c @@ -20,6 +20,7 @@ #include "wlan_cm_main_api.h" #include "wlan_scan_api.h" +#include "wlan_cm_roam.h" #include "wlan_cm_sm.h" #ifdef WLAN_POLICY_MGR_ENABLE #include "wlan_policy_mgr_api.h" @@ -994,6 +995,11 @@ cm_handle_connect_req_in_non_init_state(struct cnx_mgr *cm_ctx, { switch (cm_state_substate) { case WLAN_CM_S_ROAMING: + /* for FW roam/LFR3 remove the req from the list */ + if (cm_roam_offload_enabled(wlan_vdev_get_psoc(cm_ctx->vdev))) + cm_flush_pending_request(cm_ctx, ROAM_REQ_PREFIX, + false); + /* fallthrough */ case WLAN_CM_S_CONNECTED: case WLAN_CM_SS_JOIN_ACTIVE: /* diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c index b1343b1c3d..99830419ae 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c @@ -19,6 +19,7 @@ */ #include "wlan_cm_main_api.h" #include "wlan_cm_sm.h" +#include "wlan_cm_roam.h" #include #include "wlan_utility.h" #include "wlan_scan_api.h" @@ -527,8 +528,13 @@ cm_handle_discon_req_in_non_connected_state(struct cnx_mgr *cm_ctx, cm_flush_pending_request(cm_ctx, CONNECT_REQ_PREFIX, true); break; - case WLAN_CM_SS_JOIN_ACTIVE: case WLAN_CM_S_ROAMING: + /* for FW roam/LFR3 remove the req from the list */ + if (cm_roam_offload_enabled(wlan_vdev_get_psoc(cm_ctx->vdev))) + cm_flush_pending_request(cm_ctx, ROAM_REQ_PREFIX, + false); + /* fallthrough */ + case WLAN_CM_SS_JOIN_ACTIVE: /* * In join active/roaming state, there would be no pending * command, so no action required. so for new disconnect diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_roam.h b/umac/mlme/connection_mgr/core/src/wlan_cm_roam.h index 10dc1cfa37..0dda823ba6 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_roam.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_roam.h @@ -23,6 +23,8 @@ #ifndef __WLAN_CM_ROAM_H__ #define __WLAN_CM_ROAM_H__ +#include "wlan_cm_main.h" + #ifdef WLAN_FEATURE_HOST_ROAM /** * cm_roam_bss_peer_create_rsp() - handle bss peer create response for roam @@ -83,7 +85,6 @@ QDF_STATUS cm_reassoc_complete(struct cnx_mgr *cm_ctx, */ bool cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev, struct wlan_cm_vdev_reassoc_req *req); - /** * cm_host_roam_start_req() - Start host roam request * @cm_ctx: Connection manager context @@ -237,6 +238,16 @@ cm_fill_bss_info_in_roam_rsp_by_cm_id(struct cnx_mgr *cm_ctx, struct wlan_cm_connect_resp *resp); #ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * cm_fw_roam_start() - Handle roam start event + * @cm_ctx: connection mgr context + * + * This function handles the roam start event received from FW. + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_fw_roam_start(struct cnx_mgr *cm_ctx); + /** * cm_send_roam_invoke_req() - Send Roam invoke req to FW * @cm_ctx: connection manager context @@ -246,6 +257,7 @@ cm_fill_bss_info_in_roam_rsp_by_cm_id(struct cnx_mgr *cm_ctx, */ QDF_STATUS cm_send_roam_invoke_req(struct cnx_mgr *cm_ctx, struct cm_req *req); + /** * cm_roam_offload_enabled() - check if roam offload(LFR3) is enabled * @psoc: psoc pointer to get the INI @@ -254,6 +266,43 @@ cm_send_roam_invoke_req(struct cnx_mgr *cm_ctx, struct cm_req *req); */ bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc); +/** + * cm_get_first_roam_command() - Get first roam request from list + * @vdev: vdev pointer + * + * Context: Can be called from any context and to be used only after posting a + * msg to SM (ie holding the SM lock) to avoid use after free. also returned req + * should only be used till SM lock is hold. + * + * Return: cm roam req from the req list + */ +struct cm_roam_req *cm_get_first_roam_command(struct wlan_objmgr_vdev *vdev); + +/** + * cm_prepare_roam_cmd() - Prepare roam req + * @cm_ctx: connection mgr context + * @cm_req: connection mgr req + * @source: connection mgr req source + * + * This function prepares roam request when roam start ind is received + * when CM SM is in connected state. + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_prepare_roam_cmd(struct cnx_mgr *cm_ctx, + struct cm_req **roam_req, + enum wlan_cm_source source); +/** + * cm_add_fw_roam_cmd_to_list_n_ser() - Add roam req to list and serialize req + * @cm_ctx: connection mgr context + * @cm_req: connection mgr req + * + * This function adds roam request to list and the serialization queue. + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_add_fw_roam_cmd_to_list_n_ser(struct cnx_mgr *cm_ctx, + struct cm_req *cm_req); #else static inline bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc) { diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c index 69d463f002..58695a8e96 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_sm.c @@ -35,6 +35,58 @@ void cm_state_roaming_exit(void *ctx) { } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static +bool cm_handle_fw_roaming_event(struct cnx_mgr *cm_ctx, uint16_t event, + uint16_t data_len, void *data) +{ + bool event_handled = true; + QDF_STATUS status; + + switch (event) { + case WLAN_CM_SM_EV_ROAM_INVOKE: + status = cm_add_fw_roam_cmd_to_list_n_ser(cm_ctx, data); + if (QDF_IS_STATUS_ERROR(status)) { + event_handled = false; + break; + } + cm_sm_transition_to(cm_ctx, WLAN_CM_SS_ROAM_STARTED); + cm_sm_deliver_event_sync(cm_ctx, + WLAN_CM_SM_EV_ROAM_INVOKE, + data_len, data); + break; + case WLAN_CM_SM_EV_ROAM_START: + status = cm_add_fw_roam_cmd_to_list_n_ser(cm_ctx, data); + if (QDF_IS_STATUS_ERROR(status)) { + event_handled = false; + break; + } + cm_sm_transition_to(cm_ctx, WLAN_CM_SS_ROAM_STARTED); + cm_sm_deliver_event_sync(cm_ctx, + WLAN_CM_SM_EV_ROAM_START, + 0, NULL); + break; + case WLAN_CM_SM_EV_ROAM_ABORT: + cm_sm_transition_to(cm_ctx, WLAN_CM_S_CONNECTED); + cm_sm_deliver_event_sync(cm_ctx, event, + data_len, data); + break; + default: + event_handled = false; + break; + } + + return event_handled; +} +#else +static inline +bool cm_handle_fw_roaming_event(struct cnx_mgr *cm_ctx, uint16_t event, + uint16_t data_len, void *data) +{ + return false; +} +#endif + bool cm_state_roaming_event(void *ctx, uint16_t event, uint16_t data_len, void *data) { @@ -61,19 +113,9 @@ bool cm_state_roaming_event(void *ctx, uint16_t event, data_len, data); } break; - case WLAN_CM_SM_EV_ROAM_INVOKE: - cm_add_roam_req_to_list(cm_ctx, data); - cm_sm_transition_to(cm_ctx, WLAN_CM_SS_ROAM_STARTED); - cm_sm_deliver_event_sync(cm_ctx, - WLAN_CM_SM_EV_ROAM_INVOKE, - data_len, data); - break; - case WLAN_CM_SM_EV_ROAM_START: - cm_add_roam_req_to_list(cm_ctx, data); - /* cm_fw_roam_start(cm_ctx); define in LFR3/FW roam file */ - break; default: - event_handled = false; + event_handled = cm_handle_fw_roaming_event(cm_ctx, event, + data_len, data); break; } @@ -260,12 +302,16 @@ bool cm_subst_roam_start_event(void *ctx, uint16_t event, cm_handle_connect_disconnect_in_roam(cm_ctx, event, data_len, data); break; + case WLAN_CM_SM_EV_ROAM_START: + cm_fw_roam_start(ctx); + break; case WLAN_CM_SM_EV_ROAM_INVOKE: cm_send_roam_invoke_req(cm_ctx, data); break; + case WLAN_CM_SM_EV_ROAM_ABORT: case WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: cm_sm_transition_to(cm_ctx, WLAN_CM_S_CONNECTED); - cm_sm_deliver_event_sync(cm_ctx, WLAN_CM_SM_EV_ROAM_INVOKE_FAIL, + cm_sm_deliver_event_sync(cm_ctx, event, data_len, data); break; default: diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_roam_util.c b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_util.c index 853232de84..521e71e205 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_roam_util.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_roam_util.c @@ -164,7 +164,6 @@ bool cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev, return status; } #endif - QDF_STATUS cm_fill_bss_info_in_roam_rsp_by_cm_id(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id, @@ -204,3 +203,35 @@ cm_fill_bss_info_in_roam_rsp_by_cm_id(struct cnx_mgr *cm_ctx, return QDF_STATUS_E_FAILURE; } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +struct cm_roam_req *cm_get_first_roam_command(struct wlan_objmgr_vdev *vdev) +{ + struct cnx_mgr *cm_ctx; + qdf_list_node_t *cur_node = NULL, *next_node = NULL; + struct cm_req *cm_req = NULL; + uint32_t cm_id_prefix; + + cm_ctx = cm_get_cm_ctx(vdev); + + cm_req_lock_acquire(cm_ctx); + qdf_list_peek_front(&cm_ctx->req_list, &cur_node); + while (cur_node) { + qdf_list_peek_next(&cm_ctx->req_list, cur_node, &next_node); + + cm_req = qdf_container_of(cur_node, struct cm_req, node); + cm_id_prefix = CM_ID_GET_PREFIX((cm_req->cm_id)); + + if (cm_id_prefix == ROAM_REQ_PREFIX) { + cm_req_lock_release(cm_ctx); + return &cm_req->roam_req; + } + + cur_node = next_node; + next_node = NULL; + } + cm_req_lock_release(cm_ctx); + + return NULL; +} +#endif diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c index 11149ebee0..6b245f0bc5 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c @@ -217,6 +217,54 @@ static void cm_state_connected_exit(void *ctx) { } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static +bool cm_handle_fw_roam_connected_event(struct cnx_mgr *cm_ctx, uint16_t event, + uint16_t data_len, void *data) +{ + bool event_handled = true; + QDF_STATUS status; + struct cm_req *roam_cm_req; + + switch (event) { + case WLAN_CM_SM_EV_ROAM_INVOKE: + cm_sm_transition_to(cm_ctx, WLAN_CM_S_ROAMING); + cm_sm_deliver_event_sync(cm_ctx, + WLAN_CM_SM_EV_ROAM_INVOKE, + data_len, data); + break; + case WLAN_CM_SM_EV_ROAM_ABORT: + case WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: + cm_remove_cmd(cm_ctx, data); + break; + case WLAN_CM_SM_EV_ROAM_START: + status = cm_prepare_roam_cmd(cm_ctx, &roam_cm_req, + CM_ROAMING_FW); + if (QDF_IS_STATUS_ERROR(status)) { + event_handled = false; + break; + } + cm_sm_transition_to(cm_ctx, WLAN_CM_S_ROAMING); + cm_sm_deliver_event_sync(cm_ctx, + WLAN_CM_SM_EV_ROAM_START, + sizeof(*roam_cm_req), roam_cm_req); + break; + default: + event_handled = false; + break; + } + + return event_handled; +} +#else +static inline +bool cm_handle_fw_roam_connected_event(struct cnx_mgr *cm_ctx, uint16_t event, + uint16_t data_len, void *data) +{ + return false; +} +#endif + /** * cm_state_connected_event() - Connected State event handler for * connection mgr @@ -235,12 +283,6 @@ static bool cm_state_connected_event(void *ctx, uint16_t event, struct cm_req *roam_cm_req; switch (event) { - case WLAN_CM_SM_EV_ROAM_INVOKE: - cm_sm_transition_to(cm_ctx, WLAN_CM_S_ROAMING); - cm_sm_deliver_event_sync(cm_ctx, - WLAN_CM_SM_EV_ROAM_INVOKE, - data_len, data); - break; case WLAN_CM_SM_EV_ROAM_REQ: cm_sm_transition_to(cm_ctx, WLAN_CM_S_ROAMING); cm_sm_deliver_event_sync(cm_ctx, @@ -288,15 +330,12 @@ static bool cm_state_connected_event(void *ctx, uint16_t event, case WLAN_CM_SM_EV_REASSOC_DONE: cm_reassoc_complete(cm_ctx, data); break; - case WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: - cm_remove_cmd(cm_ctx, data); - break; - default: - event_handled = false; + event_handled = + cm_handle_fw_roam_connected_event(cm_ctx, event, + data_len, data); break; } - return event_handled; } @@ -952,6 +991,7 @@ static const char *cm_sm_event_names[] = { "EV_ROAM_COMPLETE", "EV_ROAM_REQ", "EV_ROAM_INVOKE", + "EV_ROAM_ABORT", }; enum wlan_cm_sm_state cm_get_state(struct cnx_mgr *cm_ctx) diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h index 0810842ed6..faa833ff61 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h @@ -28,6 +28,7 @@ /** * enum wlan_cm_sm_evt - connection manager related events + * Note: make sure to update cm_sm_event_names on updating this enum * @WLAN_CM_SM_EV_CONNECT_REQ: Connect request event from requester * @WLAN_CM_SM_EV_SCAN: Event to start connect scan * @WLAN_CM_SM_EV_SCAN_SUCCESS: Connect scan success event @@ -47,9 +48,9 @@ * @WLAN_CM_SM_EV_DISCONNECT_ACTIVE: Process disconnect after in active cmd * @WLAN_CM_SM_EV_DISCONNECT_DONE: Disconnect done event * @WLAN_CM_SM_EV_ROAM_START: Roam start event for LFR2 and LFR3 - * @WLAN_CM_SM_EV_ROAM_SYNC: Roam sync event fro LFR3 + * @WLAN_CM_SM_EV_ROAM_SYNC: Roam sync event for LFR3 * @WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: Roam invoke fail event - * @WLAN_CM_SM_EV_ROAM_HO_FAIL: Hand off failed event + * @WLAN_CM_SM_EV_ROAM_HO_FAIL: Hands off failed event * @WLAN_CM_SM_EV_PREAUTH_DONE: Preauth is completed * @WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP: Get next candidate as preauth failed * @WLAN_CM_SM_EV_PREAUTH_FAIL: Preauth failed for all candidate @@ -58,9 +59,10 @@ * @WLAN_CM_SM_EV_REASSOC_DONE: Reassoc completed * @WLAN_CM_SM_EV_REASSOC_FAILURE: Reassoc failed * @WLAN_CM_SM_EV_ROAM_COMPLETE: Roaming completed - * @WLAN_CM_SM_EV_ROAM_REQ: LFR3/FW roam - Roam req from FW + * @WLAN_CM_SM_EV_ROAM_REQ: LFR3/FW roam - Roam req from connect * LFR2/Host roam - Roam req from host/FW * @WLAN_CM_SM_EV_ROAM_INVOKE: Host initiated LFR3/FW roam req + * @WLAN_CM_SM_EV_ROAM_ABORT: Roam abort * @WLAN_CM_SM_EV_MAX: Max event */ enum wlan_cm_sm_evt { @@ -95,6 +97,7 @@ enum wlan_cm_sm_evt { WLAN_CM_SM_EV_ROAM_COMPLETE = 28, WLAN_CM_SM_EV_ROAM_REQ = 29, WLAN_CM_SM_EV_ROAM_INVOKE = 30, + WLAN_CM_SM_EV_ROAM_ABORT = 31, WLAN_CM_SM_EV_MAX, }; diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_util.c b/umac/mlme/connection_mgr/core/src/wlan_cm_util.c index 6bf97f91f3..0f98a8dbc5 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_util.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_util.c @@ -532,6 +532,11 @@ cm_flush_pending_request(struct cnx_mgr *cm_ctx, uint32_t prefix, qdf_list_node_t *cur_node = NULL, *next_node = NULL; struct cm_req *cm_req; uint32_t req_prefix; + bool roam_offload = false; + + if (cm_roam_offload_enabled(wlan_vdev_get_psoc(cm_ctx->vdev)) && + prefix == ROAM_REQ_PREFIX) + roam_offload = true; cm_req_lock_acquire(cm_ctx); qdf_list_peek_front(&cm_ctx->req_list, &cur_node); @@ -541,9 +546,14 @@ cm_flush_pending_request(struct cnx_mgr *cm_ctx, uint32_t prefix, req_prefix = CM_ID_GET_PREFIX(cm_req->cm_id); - /* Only remove the pending requests matching the flush prefix */ + /* + * Only remove requests matching the flush prefix and + * the pending req for non roam offload(LFR3) commands + * (roam command is dummy in FW roam/LFR3 so active + * command can be removed) + */ if (req_prefix != prefix || - cm_req->cm_id == cm_ctx->active_cm_id) + (!roam_offload && cm_req->cm_id == cm_ctx->active_cm_id)) goto next; /* If only_failed_req is set flush only failed req */ @@ -554,6 +564,8 @@ cm_flush_pending_request(struct cnx_mgr *cm_ctx, uint32_t prefix, cm_handle_connect_flush(cm_ctx, cm_req); cm_ctx->connect_count--; cm_free_connect_req_mem(&cm_req->connect_req); + } else if (req_prefix == ROAM_REQ_PREFIX) { + cm_free_roam_req_mem(&cm_req->roam_req); } else { cm_handle_disconnect_flush(cm_ctx, cm_req); cm_ctx->disconnect_count--; @@ -762,6 +774,19 @@ void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id) struct wlan_objmgr_psoc *psoc; QDF_STATUS status; + if (!cm_id) { + mlme_err("cmd_id is null"); + return; + } + + /* return if zero or invalid cm_id */ + if (!*cm_id || *cm_id == CM_ID_INVALID) { + mlme_debug(CM_PREFIX_FMT " Invalid cm_id", + CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), + *cm_id)); + return; + } + psoc = wlan_vdev_get_psoc(cm_ctx->vdev); if (!psoc) { mlme_err(CM_PREFIX_FMT "Failed to find psoc", diff --git a/umac/mlme/include/wlan_mlme_cmn.h b/umac/mlme/include/wlan_mlme_cmn.h index 8277e7a339..3a9c73c5d9 100644 --- a/umac/mlme/include/wlan_mlme_cmn.h +++ b/umac/mlme/include/wlan_mlme_cmn.h @@ -52,6 +52,11 @@ * @mlme_cm_disconnect_start_cb: Disconnect start callback * @vdev: vdev pointer * + * @mlme_cm_roam_start_cb: Roam start callback + * @vdev: vdev pointer + * + * @mlme_cm_roam_abort_cb: Roam abort callback + * @vdev: vdev pointer */ struct mlme_cm_ops { QDF_STATUS (*mlme_cm_connect_complete_cb)( @@ -69,6 +74,10 @@ struct mlme_cm_ops { struct wlan_cm_discon_rsp *rsp); QDF_STATUS (*mlme_cm_disconnect_start_cb)( struct wlan_objmgr_vdev *vdev); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + QDF_STATUS (*mlme_cm_roam_start_cb)(struct wlan_objmgr_vdev *vdev); + QDF_STATUS (*mlme_cm_roam_abort_cb)(struct wlan_objmgr_vdev *vdev); +#endif }; #endif @@ -589,6 +598,24 @@ mlme_cm_osif_disconnect_complete(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS mlme_cm_osif_disconnect_start_ind(struct wlan_objmgr_vdev *vdev); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * mlme_cm_osif_roam_start_ind() - osif Roam start indication + * @vdev: vdev pointer + * + * Return: QDF_STATUS + */ +QDF_STATUS mlme_cm_osif_roam_start_ind(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_cm_osif_roam_abort_ind() - osif Roam abort indication + * @vdev: vdev pointer + * + * Return: QDF_STATUS + */ +QDF_STATUS mlme_cm_osif_roam_abort_ind(struct wlan_objmgr_vdev *vdev); +#endif + /** * typedef osif_cm_get_global_ops_cb() - Callback to get connection manager * global ops diff --git a/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c b/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c index bd9a45841d..2022d87bcf 100644 --- a/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c +++ b/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c @@ -459,6 +459,29 @@ QDF_STATUS mlme_cm_osif_disconnect_start_ind(struct wlan_objmgr_vdev *vdev) return ret; } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS mlme_cm_osif_roam_start_ind(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (glbl_cm_ops && + glbl_cm_ops->mlme_cm_roam_start_cb) + ret = glbl_cm_ops->mlme_cm_roam_start_cb(vdev); + + return ret; +} + +QDF_STATUS mlme_cm_osif_roam_abort_ind(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (glbl_cm_ops && + glbl_cm_ops->mlme_cm_roam_abort_cb) + ret = glbl_cm_ops->mlme_cm_roam_abort_cb(vdev); + + return ret; +} +#endif void mlme_set_osif_cm_cb(osif_cm_get_global_ops_cb osif_cm_ops) { glbl_cm_ops_cb = osif_cm_ops;