From 96fb5eb6259e2a406493ee412679a25e78d171a2 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 25 Aug 2020 18:16:26 +0530 Subject: [PATCH] qcacmn: Take care of hw mode change in Connection mgr Set hw mode before initiating connection request and send vdev start to FW. Change-Id: I658f0f03a68da923dbfa1213e278490bc1e874cf CRs-Fixed: 2763364 --- .../connection_mgr/core/src/wlan_cm_connect.c | 219 +++++++++++------- .../core/src/wlan_cm_main_api.h | 14 ++ .../dispatcher/inc/wlan_cm_api.h | 25 +- .../dispatcher/src/wlan_cm_api.c | 8 + 4 files changed, 177 insertions(+), 89 deletions(-) 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 07f6b720aea8..22e4293f621f 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c @@ -27,7 +27,109 @@ #endif #include +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: + /* 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_ser_connect_cb; + 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; +} + #ifdef WLAN_POLICY_MGR_ENABLE + +void cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status) +{ + mlme_debug("vdev %d cm id %d Continue connect after HW mode change, status %d", + vdev_id, cm_id, status); +} + +static QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc, + qdf_list_t *scan_list, + uint8_t vdev_id, + wlan_cm_id connect_id) +{ + return policy_mgr_change_hw_mode_sta_connect(psoc, scan_list, vdev_id, + connect_id); +} + static void cm_get_pcl_chan_weigtage_for_sta(struct wlan_objmgr_pdev *pdev, struct pcl_freq_weight_list *pcl_lst) @@ -70,6 +172,15 @@ static void cm_calculate_scores(struct wlan_objmgr_pdev *pdev, qdf_mem_free(pcl_lst); } #else + +static QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc, + qdf_list_t *scan_list, + uint8_t vdev_id, + uint8_t connect_id) +{ + return QDF_STATUS_E_ALREADY; +} + static inline void cm_calculate_scores(struct wlan_objmgr_pdev *pdev, struct scan_filter *filter, qdf_list_t *list) @@ -190,103 +301,25 @@ 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: - /* 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_ser_connect_cb; - 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) { struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; enum wlan_cm_connect_fail_reason reason = CM_GENERIC_FAILURE; QDF_STATUS status; + uint8_t vdev_id = wlan_vdev_get_id(cm_ctx->vdev); /* Interface event */ pdev = wlan_vdev_get_pdev(cm_ctx->vdev); if (!pdev) { - mlme_err("Failed to find pdev from vdev %d", - wlan_vdev_get_id(cm_ctx->vdev)); + mlme_err("Failed to find pdev from vdev %d", vdev_id); + goto connect_err; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + mlme_err("Failed to find psoc from vdev %d", vdev_id); goto connect_err; } @@ -296,7 +329,17 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx, goto connect_err; } - /* Do HW mode change */ + status = cm_check_for_hw_mode_change(psoc, cm_req->candidate_list, + vdev_id, cm_req->cm_id); + if (QDF_IS_STATUS_ERROR(status) && status != QDF_STATUS_E_ALREADY) { + reason = CM_HW_MODE_FAILURE; + mlme_err("Vdev %d Failed to set HW mode change", vdev_id); + goto connect_err; + } else if (QDF_IS_STATUS_SUCCESS(status)) { + mlme_debug("Vdev %d Connect will continue after HW mode change", + vdev_id); + return QDF_STATUS_SUCCESS; + } status = cm_ser_connect_req(pdev, cm_ctx, cm_req); if (QDF_IS_STATUS_ERROR(status)) { 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 6c9594fa47a3..bf882ba5a307 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 @@ -157,4 +157,18 @@ QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx, QDF_STATUS cm_disconnect_start_req(struct wlan_objmgr_vdev *vdev, struct wlan_cm_disconnect_req *req); +/** + * cm_hw_mode_change_resp() - HW mode change response + * @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. + * + * Return: QDF_STATUS + */ +#ifdef WLAN_POLICY_MGR_ENABLE +void cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status); + +#endif #endif /* __WLAN_CM_MAIN_API_H__ */ 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 7b5cb163ea2d..2bfeaed7bff4 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h @@ -98,6 +98,29 @@ QDF_STATUS wlan_cm_bss_peer_delete_rsp(struct wlan_objmgr_vdev *vdev, QDF_STATUS wlan_cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev, struct wlan_cm_discon_rsp cm_discon_rsp); +/** + * wlan_cm_hw_mode_change_resp() - HW mode change response + * @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. + * + * Return: void + */ +#ifdef WLAN_POLICY_MGR_ENABLE +void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status); +#endif /* ifdef POLICY_MGR_ENABLE */ + +#else + +#ifdef WLAN_POLICY_MGR_ENABLE +static inline void +wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + uint32_t cm_id, QDF_STATUS status) +{ +} +#endif /* ifdef POLICY_MGR_ENABLE */ + #endif #endif /* __WLAN_CM_UCFG_API_H */ - 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 d468ace1f14e..0b27d936cc52 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c @@ -65,3 +65,11 @@ QDF_STATUS wlan_cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_SUCCESS; } + +#ifdef WLAN_POLICY_MGR_ENABLE +void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_cm_id cm_id, QDF_STATUS status) +{ + cm_hw_mode_change_resp(pdev, vdev_id, cm_id, status); +} +#endif /* ifdef POLICY_MGR_ENABLE */