From bd6a23767755b7229a1266b4bb3cf309bfd84442 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Fri, 7 Aug 2020 10:36:19 +0530 Subject: [PATCH] qcacmn: Serialize connect and disconnect request Serialize connect and disconnect request in CM Change-Id: I7eacafaf2fb1c71d7c42a493d4acb855f399c698 CRs-Fixed: 2750754 --- .../obj_mgr/inc/wlan_objmgr_cmn.h | 5 +- .../connection_mgr/core/src/wlan_cm_connect.c | 98 ++++++++++++++++- .../core/src/wlan_cm_disconnect.c | 100 +++++++++++++++++- 3 files changed, 200 insertions(+), 3 deletions(-) diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index b75fe62652..61f029d20d 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -268,6 +268,7 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_PKT_CAPTURE_ID Packet capture operations * @WLAN_DCS_ID: DCS operations * @WLAN_IOT_SIM_ID: IOT Simulation feature + * @WLAN_MLME_CM_ID Connection Manager reference ID * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ /* New value added to the enum must also be reflected in function @@ -351,6 +352,7 @@ typedef enum { WLAN_PKT_CAPTURE_ID = 74, WLAN_DCS_ID = 75, WLAN_IOT_SIM_ID = 76, + WLAN_MLME_CM_ID = 77, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; @@ -440,7 +442,8 @@ static inline const char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "FTM_TIME_SYNC_ID", "WLAN_PKT_CAPTURE_ID", "WLAN_DCS_ID", - "WLAN_IOT_SIM_ID"}; + "WLAN_IOT_SIM_ID", + "WLAN_MLME_CM_ID"}; if (id >= WLAN_REF_ID_MAX) return "Unknown"; 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 344b6c413c..16111188ee 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c @@ -25,6 +25,7 @@ #ifdef WLAN_POLICY_MGR_ENABLE #include "wlan_policy_mgr_api.h" #endif +#include #ifdef WLAN_POLICY_MGR_ENABLE static void @@ -187,6 +188,93 @@ static QDF_STATUS cm_connect_get_candidates(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +static QDF_STATUS +cm_ser_connect_cb(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_vdev *vdev; + + if (!cmd) { + mlme_err("cmd is NULL, reason: %d", reason); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + vdev = cmd->vdev; + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* To do:- Post event to move CM SM to join active */ + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + */ + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + mlme_err("Active command timeout cm_id %d", cmd->cmd_id); + QDF_ASSERT(0); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command completed. Release reference of vdev + */ + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); + break; + + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +#define CONNECT_TIMEOUT 30000 + +static QDF_STATUS cm_ser_connect_req(struct wlan_objmgr_pdev *pdev, + struct cnx_mgr *cm_ctx, + struct cm_connect_req *cm_req) +{ + struct wlan_serialization_command cmd = {0, }; + enum wlan_serialization_status ser_cmd_status; + QDF_STATUS status; + + status = wlan_objmgr_vdev_try_get_ref(cm_ctx->vdev, WLAN_MLME_CM_ID); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("unable to get reference"); + return status; + } + + cmd.cmd_type = WLAN_SER_CMD_VDEV_CONNECT; + cmd.cmd_id = cm_req->cm_id; + cmd.cmd_cb = cm_connect_serialize_callback; + cmd.source = WLAN_UMAC_COMP_MLME; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = CONNECT_TIMEOUT; + cmd.vdev = cm_ctx->vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list.Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + default: + mlme_err("ser cmd status %d", ser_cmd_status); + wlan_objmgr_vdev_release_ref(cm_ctx->vdev, WLAN_MLME_CM_ID); + + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx, struct cm_connect_req *cm_req) { @@ -198,6 +286,7 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx, pdev = wlan_vdev_get_pdev(cm_ctx->vdev); if (!pdev) return QDF_STATUS_E_INVAL; + status = cm_connect_get_candidates(pdev, cm_ctx, cm_req); if (QDF_IS_STATUS_ERROR(status)) { reason = CM_NO_CANDIDATE_FOUND; @@ -205,8 +294,15 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx, } /* TODO: Do HW mode change */ - /* TODO: serialize */ + + status = cm_serialize_connect_req(pdev, cm_ctx, cm_req); + if (QDF_IS_STATUS_ERROR(status)) { + reason = CM_SER_FAILURE; + goto connect_err; + } + return QDF_STATUS_SUCCESS; + connect_err: return cm_send_connect_start_fail(cm_ctx, cm_req, reason); } 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 9ee6e9851d..b85061bbb1 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c @@ -19,14 +19,112 @@ */ #include "wlan_cm_main_api.h" #include "wlan_cm_sm.h" +#include + +static QDF_STATUS +cm_ser_disconnect_cb(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_vdev *vdev; + + if (!cmd) { + mlme_err("cmd is NULL, reason: %d", reason); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + vdev = cmd->vdev; + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* To do:- Post event disconnect acitve to CM SM*/ + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + */ + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + mlme_err("Active command timeout cm_id %d", cmd->cmd_id); + QDF_ASSERT(0); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command completed. Release reference of vdev + */ + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); + break; + + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +#define DISCONNECT_TIMEOUT STOP_RESPONSE_TIMER + DELETE_RESPONSE_TIMER + 1000 + +static QDF_STATUS cm_ser_disconnect_req(struct wlan_objmgr_pdev *pdev, + struct cnx_mgr *cm_ctx, + struct cm_disconnect_req *req) +{ + struct wlan_serialization_command cmd = {0, }; + enum wlan_serialization_status ser_cmd_status; + QDF_STATUS status; + + status = wlan_objmgr_vdev_try_get_ref(cm_ctx->vdev, WLAN_MLME_CM_ID); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("unable to get reference"); + return status; + } + + cmd.cmd_type = WLAN_SER_CMD_VDEV_CONNECT; + cmd.cmd_id = req->cm_id; + cmd.cmd_cb = cm_disconnect_serialize_callback; + cmd.source = WLAN_UMAC_COMP_MLME; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = DISCONNECT_TIMEOUT; + cmd.vdev = cm_ctx->vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list.Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + default: + mlme_err("ser cmd status %d", ser_cmd_status); + wlan_objmgr_vdev_release_ref(cm_ctx->vdev, WLAN_MLME_CM_ID); + + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} QDF_STATUS cm_disconnect_start(struct cnx_mgr *cm_ctx, struct cm_disconnect_req *req) { + struct wlan_objmgr_pdev *pdev; + + /* TODO: Interface event */ + pdev = wlan_vdev_get_pdev(cm_ctx->vdev); + if (!pdev) + return QDF_STATUS_E_INVAL; + /* * TODO: Interface event, stop scan, disconnect TDLS, P2P roc cleanup - * queue serialization. */ + + /* Serialize disconnect req, TODO:- Handle failure status */ + cm_serialize_disconnect_req(pdev, cm_ctx, req); + return QDF_STATUS_SUCCESS; }