From b8b58d8d12e9a024b4fed9ab7c53968077cdca8b Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 20 Oct 2020 12:14:54 +0530 Subject: [PATCH] qcacmn: Move disconnect wait logic from osif to connection mgr Move disconnect wait logic from osif to connection mgr, so that MLO/IF manager can use the wait logic for disconnect during vdev delete. Change-Id: Ied2bbcfd6a532209f8008499424f94acc41efc0e CRs-Fixed: 2800990 --- os_if/linux/mlme/src/osif_cm_disconnect_rsp.c | 1 - os_if/linux/mlme/src/osif_cm_req.c | 21 +------------ os_if/linux/mlme/src/osif_cm_util.c | 16 +--------- os_if/linux/wlan_osif_priv.h | 3 -- .../core/src/wlan_cm_disconnect.c | 29 ++++++++++++++++++ .../connection_mgr/core/src/wlan_cm_main.c | 2 ++ .../connection_mgr/core/src/wlan_cm_main.h | 3 ++ .../core/src/wlan_cm_main_api.h | 14 +++++++++ .../dispatcher/inc/wlan_cm_api.h | 30 ++++++++++++++++--- .../dispatcher/inc/wlan_cm_ucfg_api.h | 16 ++++++++++ .../dispatcher/src/wlan_cm_api.c | 29 ++++++++++++++++-- .../dispatcher/src/wlan_cm_ucfg_api.c | 7 +++++ 12 files changed, 125 insertions(+), 46 deletions(-) diff --git a/os_if/linux/mlme/src/osif_cm_disconnect_rsp.c b/os_if/linux/mlme/src/osif_cm_disconnect_rsp.c index 7e1ee7fb2a..c23fdb5184 100644 --- a/os_if/linux/mlme/src/osif_cm_disconnect_rsp.c +++ b/os_if/linux/mlme/src/osif_cm_disconnect_rsp.c @@ -160,7 +160,6 @@ QDF_STATUS osif_disconnect_handler(struct wlan_objmgr_vdev *vdev, rsp->ap_discon_ie.len, GFP_KERNEL); osif_cm_disconnect_comp_ind(vdev, rsp, OSIF_POST_USERSPACE_UPDATE); - qdf_event_set(&osif_priv->cm_info.disconnect_complete); return status; } diff --git a/os_if/linux/mlme/src/osif_cm_req.c b/os_if/linux/mlme/src/osif_cm_req.c index 410c257d2a..9d69f2aa90 100644 --- a/os_if/linux/mlme/src/osif_cm_req.c +++ b/os_if/linux/mlme/src/osif_cm_req.c @@ -489,31 +489,12 @@ int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev, int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason) { uint8_t vdev_id = wlan_vdev_get_id(vdev); - struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); QDF_STATUS status; - if (ucfg_cm_is_vdev_disconnected(vdev)) - return 0; - - if (!osif_priv) { - osif_err("vdev %d invalid vdev osif priv", vdev_id); - return -EINVAL; - } - osif_info("vdevid-%d: Received Disconnect reason:%d %s", vdev_id, reason, ucfg_cm_reason_code_to_str(reason)); - qdf_event_reset(&osif_priv->cm_info.disconnect_complete); - status = osif_cm_send_disconnect(vdev, reason); - if (QDF_IS_STATUS_ERROR(status)) { - osif_err("Disconnect failed with status %d", status); - return qdf_status_to_os_return(status); - } - - status = qdf_wait_single_event(&osif_priv->cm_info.disconnect_complete, - CM_DISCONNECT_CMD_TIMEOUT); - if (QDF_IS_STATUS_ERROR(status)) - osif_err("Disconnect timeout with status %d", status); + status = ucfg_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT, reason); return qdf_status_to_os_return(status); } diff --git a/os_if/linux/mlme/src/osif_cm_util.c b/os_if/linux/mlme/src/osif_cm_util.c index 3def3982e3..313815c218 100644 --- a/os_if/linux/mlme/src/osif_cm_util.c +++ b/os_if/linux/mlme/src/osif_cm_util.c @@ -337,7 +337,6 @@ QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev) { struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev); enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(vdev); - QDF_STATUS status; if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; @@ -349,19 +348,7 @@ QDF_STATUS osif_cm_osif_priv_init(struct wlan_objmgr_vdev *vdev) qdf_spinlock_create(&osif_priv->cm_info.cmd_id_lock); - status = qdf_event_create(&osif_priv->cm_info.disconnect_complete); - if (QDF_IS_STATUS_ERROR(status)) { - osif_err("failed to create disconnect complete event fro vdev %d", - wlan_vdev_get_id(vdev)); - goto event_create_fail; - } - - return status; - -event_create_fail: - qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock); - - return status; + return QDF_STATUS_SUCCESS; } QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev) @@ -376,7 +363,6 @@ QDF_STATUS osif_cm_osif_priv_deinit(struct wlan_objmgr_vdev *vdev) osif_err("Invalid vdev osif priv"); return QDF_STATUS_E_INVAL; } - qdf_event_destroy(&osif_priv->cm_info.disconnect_complete); qdf_spinlock_destroy(&osif_priv->cm_info.cmd_id_lock); return QDF_STATUS_SUCCESS; diff --git a/os_if/linux/wlan_osif_priv.h b/os_if/linux/wlan_osif_priv.h index 30d7bcf19e..ff4bd6c2b1 100644 --- a/os_if/linux/wlan_osif_priv.h +++ b/os_if/linux/wlan_osif_priv.h @@ -21,7 +21,6 @@ #define _WLAN_OSIF_PRIV_H_ #include "qdf_net_if.h" -#include #include "wlan_cm_public_struct.h" #include @@ -50,7 +49,6 @@ struct pdev_osif_priv { * @cmd_id_lock: lock to update and read last command source * @last_disconnect_reason: last disconnect reason to be indicated in get * station - * @disconnect_complete: disconnect completion wait event * @ext_priv: legacy data pointer. */ struct osif_cm_info { @@ -58,7 +56,6 @@ struct osif_cm_info { wlan_cm_id last_id; struct qdf_spinlock cmd_id_lock; enum qca_disconnect_reason_codes last_disconnect_reason; - qdf_event_t disconnect_complete; void *ext_priv; }; #endif 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 efb13529c7..93410aadcb 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c @@ -401,6 +401,10 @@ QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx, if (!cm_ctx->disconnect_count && cm_ctx->connect_count) cm_flush_pending_request(cm_ctx, CONNECT_REQ_PREFIX, true); + /* Set the disconnect wait event once all disconnect are completed */ + if (!cm_ctx->disconnect_count) + qdf_event_set(&cm_ctx->disconnect_complete); + return QDF_STATUS_SUCCESS; } @@ -539,6 +543,31 @@ QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev, return status; } +QDF_STATUS cm_disconnect_start_req_sync(struct wlan_objmgr_vdev *vdev, + struct wlan_cm_disconnect_req *req) +{ + struct cnx_mgr *cm_ctx; + QDF_STATUS status; + + cm_ctx = cm_get_cm_ctx(vdev); + if (!cm_ctx) + return QDF_STATUS_E_INVAL; + + qdf_event_reset(&cm_ctx->disconnect_complete); + status = cm_disconnect_start_req(vdev, req); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Disconnect failed with status %d", status); + return status; + } + + status = qdf_wait_single_event(&cm_ctx->disconnect_complete, + CM_DISCONNECT_CMD_TIMEOUT); + if (QDF_IS_STATUS_ERROR(status)) + mlme_err("Disconnect timeout with status %d", status); + + return status; +} + QDF_STATUS cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev, struct wlan_cm_discon_rsp *resp) { diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main.c b/umac/mlme/connection_mgr/core/src/wlan_cm_main.c index cf95fb04e5..c2fce29774 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_main.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main.c @@ -96,6 +96,7 @@ QDF_STATUS wlan_cm_init(struct vdev_mlme_obj *vdev_mlme) "CM", wlan_cm_scan_cb, vdev_mlme->cnx_mgr_ctx); + qdf_event_create(&vdev_mlme->cnx_mgr_ctx->disconnect_complete); return QDF_STATUS_SUCCESS; } @@ -110,6 +111,7 @@ QDF_STATUS wlan_cm_deinit(struct vdev_mlme_obj *vdev_mlme) if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; + qdf_event_destroy(&vdev_mlme->cnx_mgr_ctx->disconnect_complete); scan_requester_id = vdev_mlme->cnx_mgr_ctx->scan_requester_id; wlan_scan_unregister_requester(psoc, scan_requester_id); diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main.h b/umac/mlme/connection_mgr/core/src/wlan_cm_main.h index d65c17c48c..148f03471a 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_main.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main.h @@ -24,6 +24,7 @@ #define __WLAN_CM_MAIN_H__ #include "include/wlan_vdev_mlme.h" +#include #ifdef FEATURE_CM_ENABLE #include @@ -177,6 +178,7 @@ struct connect_ies { * @global_cmd_id: global cmd id for getting cm id for connect/disconnect req * @max_connect_attempts: Max attempts to be tried for a connect req * @scan_requester_id: scan requester id. + * @disconnect_complete: disconnect completion wait event */ struct cnx_mgr { struct wlan_objmgr_vdev *vdev; @@ -195,6 +197,7 @@ struct cnx_mgr { qdf_atomic_t global_cmd_id; uint8_t max_connect_attempts; wlan_scan_requester scan_requester_id; + qdf_event_t disconnect_complete; }; /** diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h b/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h index 4692d910ff..50aae42f17 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h @@ -363,6 +363,20 @@ QDF_STATUS cm_add_disconnect_req_to_list(struct cnx_mgr *cm_ctx, QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev, struct wlan_cm_disconnect_req *req); +/** + * cm_disconnect_start_req_sync() - disconnect request with wait till + * completed + * @vdev: vdev pointer + * @req: disconnect req + * + * Context: Only call for north bound disconnect req, if wait till complete + * is required, e.g. during vdev delete. Do not call from scheduler context. + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_disconnect_start_req_sync(struct wlan_objmgr_vdev *vdev, + struct wlan_cm_disconnect_req *req); + /** * cm_bss_peer_delete_req() - Connection manager bss peer delete * request diff --git a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h index 8e16dc5005..cf37d32028 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h @@ -37,14 +37,36 @@ QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_req *req); /** - * wlan_cm_start_disconnect() - disconnect start request + * wlan_cm_disconnect() - disconnect start request * @vdev: vdev pointer - * @req: disconnect req + * @source: disconnect source + * @reason_code: disconnect reason + * @bssid: bssid of AP to disconnect, can be null if not known + * + * Context: can be called from any context * * Return: QDF_STATUS */ -QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_disconnect_req *req); +QDF_STATUS wlan_cm_disconnect(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + enum wlan_reason_code reason_code, + struct qdf_mac_addr *bssid); + +/** + * wlan_cm_disconnect_sync() - disconnect request with wait till + * completed + * @vdev: vdev pointer + * @source: disconnect source + * @reason_code: disconnect reason + * + * Context: Only call for north bound disconnect req, if wait till complete + * is required, e.g. during vdev delete. Do not call from scheduler context. + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + enum wlan_reason_code reason_code); /** * wlan_cm_bss_select_ind_rsp() - Connection manager resp for bss diff --git a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_ucfg_api.h b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_ucfg_api.h index 066f902d3d..87bd7baf94 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_ucfg_api.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_ucfg_api.h @@ -47,6 +47,22 @@ QDF_STATUS ucfg_cm_start_connect(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, struct wlan_cm_disconnect_req *req); +/** + * ucfg_cm_disconnect_sync() - disconnect request with wait till + * completed + * @vdev: vdev pointer + * @source: disconnect source + * @reason_code: disconnect reason + * + * Context: Only call for north bound disconnect req, if wait till complete + * is required, e.g. during vdev delete. Do not call from scheduler context. + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + enum wlan_reason_code reason_code); + /** * ucfg_cm_is_vdev_connecting() - check if vdev is in conneting state * @vdev: vdev pointer diff --git a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c index 0f490c73c4..60602dae92 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c @@ -29,10 +29,33 @@ QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev, return cm_connect_start_req(vdev, req); } -QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_disconnect_req *req) +QDF_STATUS wlan_cm_disconnect(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + enum wlan_reason_code reason_code, + struct qdf_mac_addr *bssid) { - return cm_disconnect_start_req(vdev, req); + struct wlan_cm_disconnect_req req = {0}; + + req.vdev_id = wlan_vdev_get_id(vdev); + req.source = source; + req.reason_code = reason_code; + if (bssid) + qdf_copy_macaddr(&req.bssid, bssid); + + return cm_disconnect_start_req(vdev, &req); +} + +QDF_STATUS wlan_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + enum wlan_reason_code reason_code) +{ + struct wlan_cm_disconnect_req req = {0}; + + req.vdev_id = wlan_vdev_get_id(vdev); + req.source = source; + req.reason_code = reason_code; + + return cm_disconnect_start_req_sync(vdev, &req); } QDF_STATUS wlan_cm_bss_select_ind_rsp(struct wlan_objmgr_vdev *vdev, diff --git a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_ucfg_api.c b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_ucfg_api.c index dcf6a7daa7..bff4e6a30b 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_ucfg_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_ucfg_api.c @@ -35,6 +35,13 @@ QDF_STATUS ucfg_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, return cm_disconnect_start_req(vdev, req); } +QDF_STATUS ucfg_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, + enum wlan_cm_source source, + enum wlan_reason_code reason_code) +{ + return wlan_cm_disconnect_sync(vdev, source, reason_code); +} + bool ucfg_cm_is_vdev_connecting(struct wlan_objmgr_vdev *vdev) { return cm_is_vdev_connecting(vdev);