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 e24429d2ac1b..748a3a7f8e31 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c @@ -31,6 +31,20 @@ #include "wlan_blm_api.h" #endif +static void +cm_fill_failure_resp_from_cm_id(struct cnx_mgr *cm_ctx, + struct wlan_cm_connect_rsp *resp, + wlan_cm_id cm_id, + enum wlan_cm_connect_fail_reason reason) +{ + resp->connect_status = QDF_STATUS_E_FAILURE; + resp->cm_id = cm_id; + resp->vdev_id = wlan_vdev_get_id(cm_ctx->vdev); + resp->reason = reason; + /* Get bssid and ssid and freq for the cm id from the req list */ + cm_fill_bss_info_in_connect_rsp_by_cm_id(cm_ctx, cm_id, resp); +} + /** * cm_connect_handle_event_post_fail() - initiate connect failure if msg posting * to SM fails @@ -52,11 +66,8 @@ cm_connect_handle_event_post_fail(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id) if (!resp) return; - resp->connect_status = QDF_STATUS_E_FAILURE; - resp->cm_id = cm_id; - resp->vdev_id = wlan_vdev_get_id(cm_ctx->vdev); - resp->reason = CM_ABORT_DUE_TO_NEW_REQ_RECVD; - + cm_fill_failure_resp_from_cm_id(cm_ctx, resp, cm_id, + CM_ABORT_DUE_TO_NEW_REQ_RECVD); cm_connect_complete(cm_ctx, resp); qdf_mem_free(resp); } @@ -71,13 +82,7 @@ static QDF_STATUS cm_connect_cmd_timeout(struct cnx_mgr *cm_ctx, if (!resp) return QDF_STATUS_E_NOMEM; - resp->connect_status = QDF_STATUS_E_FAILURE; - resp->cm_id = cm_id; - resp->vdev_id = wlan_vdev_get_id(cm_ctx->vdev); - resp->reason = CM_SER_TIMEOUT; - wlan_vdev_mlme_get_ssid(cm_ctx->vdev, resp->ssid.ssid, - &resp->ssid.length); - + cm_fill_failure_resp_from_cm_id(cm_ctx, resp, cm_id, CM_SER_TIMEOUT); status = cm_sm_deliver_event(cm_ctx->vdev, WLAN_CM_SM_EV_CONNECT_FAILURE, sizeof(*resp), resp); @@ -105,10 +110,29 @@ cm_ser_connect_cb(struct wlan_serialization_command *cmd, vdev = cmd->vdev; + cm_ctx = cm_get_cm_ctx(vdev); + if (!cm_ctx) { + mlme_err("cm_ctx is NULL, reason: %d", reason); + return QDF_STATUS_E_NULL_VALUE; + } + switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: - status = cm_sm_deliver_event(vdev, WLAN_CM_SM_EV_CONNECT_ACTIVE, - sizeof(wlan_cm_id), &cmd->cmd_id); + /* + * For pending to active reason, use async api to take lock. + * For direct activation use sync api to avoid taking lock + * as lock is already acquired by the requester. + */ + if (cmd->activation_reason == SER_PENDING_TO_ACTIVE) + status = cm_sm_deliver_event(vdev, + WLAN_CM_SM_EV_CONNECT_ACTIVE, + sizeof(wlan_cm_id), + &cmd->cmd_id); + else + status = cm_sm_deliver_event_sync(cm_ctx, + WLAN_CM_SM_EV_CONNECT_ACTIVE, + sizeof(wlan_cm_id), + &cmd->cmd_id); if (QDF_IS_STATUS_SUCCESS(status)) break; /* @@ -118,9 +142,7 @@ cm_ser_connect_cb(struct wlan_serialization_command *cmd, * new command has been received connect activation should be * aborted from here with connect req cleanup. */ - cm_ctx = cm_get_cm_ctx(vdev); - if (cm_ctx) - cm_connect_handle_event_post_fail(cm_ctx, cmd->cmd_id); + cm_connect_handle_event_post_fail(cm_ctx, cmd->cmd_id); break; case WLAN_SER_CB_CANCEL_CMD: /* command removed from pending list. */ @@ -128,9 +150,8 @@ cm_ser_connect_cb(struct wlan_serialization_command *cmd, case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: mlme_err("Active command timeout cm_id %d", cmd->cmd_id); QDF_ASSERT(0); - cm_ctx = cm_get_cm_ctx(vdev); - if (cm_ctx) - cm_connect_cmd_timeout(cm_ctx, cmd->cmd_id); + + cm_connect_cmd_timeout(cm_ctx, cmd->cmd_id); break; case WLAN_SER_CB_RELEASE_MEM_CMD: cm_reset_active_cm_id(vdev, cmd->cmd_id); @@ -471,58 +492,6 @@ static QDF_STATUS cm_connect_get_candidates(struct wlan_objmgr_pdev *pdev, 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", 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; - } - - status = cm_connect_get_candidates(pdev, cm_ctx, cm_req); - if (QDF_IS_STATUS_ERROR(status)) { - reason = CM_NO_CANDIDATE_FOUND; - goto connect_err; - } - - 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)) { - reason = CM_SER_FAILURE; - goto connect_err; - } - - return QDF_STATUS_SUCCESS; - -connect_err: - return cm_send_connect_start_fail(cm_ctx, cm_req, reason); -} - #ifdef WLAN_FEATURE_INTERFACE_MGR static QDF_STATUS cm_validate_candidate(struct cnx_mgr *cm_ctx, struct scan_cache_entry *scan_entry) @@ -555,6 +524,13 @@ cm_inform_if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } + +static QDF_STATUS +cm_inform_if_mgr_connect_start(struct wlan_objmgr_vdev *vdev) +{ + return if_mgr_deliver_event(vdev, WLAN_IF_MGR_EV_CONNECT_START, NULL); +} + #else static inline QDF_STATUS cm_validate_candidate(struct cnx_mgr *cm_ctx, @@ -569,8 +545,70 @@ cm_inform_if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_SUCCESS; } + +static QDF_STATUS +cm_inform_if_mgr_connect_start(struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} + #endif +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", 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; + } + + cm_inform_if_mgr_connect_start(cm_ctx->vdev); + mlme_cm_connect_start_ind(cm_ctx->vdev, &cm_req->req); + + status = cm_connect_get_candidates(pdev, cm_ctx, cm_req); + if (QDF_IS_STATUS_ERROR(status)) { + reason = CM_NO_CANDIDATE_FOUND; + goto connect_err; + } + + 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)) { + reason = CM_SER_FAILURE; + goto connect_err; + } + + return QDF_STATUS_SUCCESS; + +connect_err: + return cm_send_connect_start_fail(cm_ctx, cm_req, reason); +} + /** * cm_get_valid_candidate() - This API will be called to get the next valid * candidate @@ -640,20 +678,6 @@ static QDF_STATUS cm_get_valid_candidate(struct cnx_mgr *cm_ctx, return QDF_STATUS_SUCCESS; } -static void -cm_fill_resp_for_bss_create_fail(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_connect_rsp *resp, - wlan_cm_id cm_id, - struct qdf_mac_addr *peer_mac) -{ - resp->connect_status = QDF_STATUS_E_FAILURE; - resp->cm_id = cm_id; - resp->vdev_id = wlan_vdev_get_id(vdev); - resp->reason = CM_PEER_CREATE_FAILED; - qdf_copy_macaddr(&resp->bssid, peer_mac); - wlan_vdev_mlme_get_ssid(vdev, resp->ssid.ssid, &resp->ssid.length); -} - static void cm_create_bss_peer(struct cnx_mgr *cm_ctx, struct cm_connect_req *req) { @@ -672,8 +696,8 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx, if (!resp) return; - cm_fill_resp_for_bss_create_fail(cm_ctx->vdev, resp, req->cm_id, - bssid); + cm_fill_failure_resp_from_cm_id(cm_ctx, resp, req->cm_id, + CM_PEER_CREATE_FAILED); cm_sm_deliver_event_sync(cm_ctx, WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE, sizeof(*resp), resp); @@ -681,6 +705,39 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx, } } +static QDF_STATUS +cm_send_candidate_select_indication(struct cnx_mgr *cm_ctx, + struct cm_connect_req *req) +{ + QDF_STATUS status; + struct wlan_cm_vdev_connect_req vdev_req; + struct wlan_cm_connect_rsp *resp; + + vdev_req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev); + vdev_req.cm_id = req->cm_id; + vdev_req.bss = req->cur_candidate; + + status = mlme_cm_candidate_select_ind(cm_ctx->vdev, &vdev_req); + if (QDF_IS_STATUS_SUCCESS(status) || + status == QDF_STATUS_E_NOSUPPORT) + return status; + + /* In supported and failure try with next candidate */ + mlme_err("mlme candidate select indication failed %d", status); + resp = qdf_mem_malloc(sizeof(*resp)); + if (!resp) + return QDF_STATUS_E_FAILURE; + + cm_fill_failure_resp_from_cm_id(cm_ctx, resp, req->cm_id, + CM_CANDIDATE_SELECT_IND_FAILED); + cm_sm_deliver_event_sync(cm_ctx, + WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE, + sizeof(*resp), resp); + qdf_mem_free(resp); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS cm_try_next_candidate(struct cnx_mgr *cm_ctx, struct wlan_cm_connect_rsp *resp) { @@ -699,7 +756,16 @@ QDF_STATUS cm_try_next_candidate(struct cnx_mgr *cm_ctx, mlme_cm_osif_failed_candidate_ind(cm_ctx->vdev, resp); - cm_create_bss_peer(cm_ctx, &cm_req->connect_req); + status = cm_send_candidate_select_indication(cm_ctx, + &cm_req->connect_req); + /* + * If candidate select indication is not supported continue with bss + * peer create, else peer will be created after resp. + */ + if (status == QDF_STATUS_E_NOSUPPORT) + cm_create_bss_peer(cm_ctx, &cm_req->connect_req); + else if (QDF_IS_STATUS_ERROR(status)) + goto connect_err; return QDF_STATUS_SUCCESS; @@ -735,7 +801,16 @@ QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id) if (QDF_IS_STATUS_ERROR(status)) goto connect_err; - cm_create_bss_peer(cm_ctx, &cm_req->connect_req); + status = cm_send_candidate_select_indication(cm_ctx, + &cm_req->connect_req); + /* + * If candidate select indication is not supported continue with bss + * peer create, else peer will be created after resp. + */ + if (status == QDF_STATUS_E_NOSUPPORT) + cm_create_bss_peer(cm_ctx, &cm_req->connect_req); + else if (QDF_IS_STATUS_ERROR(status)) + goto connect_err; return QDF_STATUS_SUCCESS; @@ -744,6 +819,23 @@ connect_err: &cm_req->connect_req, CM_JOIN_FAILED); } +QDF_STATUS +cm_peer_create_on_candidate_select_ind_resp(struct cnx_mgr *cm_ctx, + wlan_cm_id *cm_id) +{ + struct cm_req *cm_req; + + cm_req = cm_get_req_by_cm_id(cm_ctx, *cm_id); + if (!cm_req) { + mlme_err("cm req NULL for *cm_id %x", *cm_id); + return QDF_STATUS_E_FAILURE; + } + + cm_create_bss_peer(cm_ctx, &cm_req->connect_req); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id) { @@ -806,6 +898,10 @@ cm_inform_blm_connect_complete(struct wlan_objmgr_vdev *vdev, QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx, struct wlan_cm_connect_rsp *resp) { + enum wlan_cm_sm_state sm_state; + struct bss_info bss_info; + struct mlme_info mlme_info; + /* * If the entry is not present in the list, it must have been cleared * already. @@ -813,16 +909,30 @@ QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx, if (!cm_get_req_by_cm_id(cm_ctx, resp->cm_id)) return QDF_STATUS_SUCCESS; + sm_state = cm_get_state(cm_ctx); mlme_cm_osif_connect_complete(cm_ctx->vdev, resp); + mlme_cm_connect_complete_ind(cm_ctx->vdev, resp); - if (cm_get_state(cm_ctx) == WLAN_CM_S_INIT || - cm_get_state(cm_ctx) == WLAN_CM_S_CONNECTED) { + if (sm_state == WLAN_CM_S_INIT || sm_state == WLAN_CM_S_CONNECTED) { cm_inform_if_mgr_connect_complete(cm_ctx->vdev, resp->connect_status); - cm_inform_blm_connect_complete(cm_ctx->vdev, resp); + } - mlme_cm_connect_complete_ind(cm_ctx->vdev, resp); + /* Update scan entry in case connect is success or fails with bssid */ + if (!qdf_is_macaddr_zero(&resp->bssid)) { + if (QDF_IS_STATUS_SUCCESS(resp->connect_status)) + mlme_info.assoc_state = SCAN_ENTRY_CON_STATE_ASSOC; + else + mlme_info.assoc_state = SCAN_ENTRY_CON_STATE_NONE; + qdf_copy_macaddr(&bss_info.bssid, &resp->bssid); + bss_info.freq = resp->freq; + bss_info.ssid.length = resp->ssid.length; + qdf_mem_copy(&bss_info.ssid.ssid, resp->ssid.ssid, + bss_info.ssid.length); + wlan_scan_update_mlme_by_bssinfo( + wlan_vdev_get_pdev(cm_ctx->vdev), + &bss_info, &mlme_info); } /* @@ -908,6 +1018,67 @@ post_err: return qdf_status; } +QDF_STATUS cm_candidate_select_ind_rsp(struct wlan_objmgr_vdev *vdev, + QDF_STATUS status) +{ + struct cnx_mgr *cm_ctx; + QDF_STATUS qdf_status; + wlan_cm_id cm_id; + uint32_t prefix; + struct wlan_cm_connect_rsp *resp; + + cm_ctx = cm_get_cm_ctx(vdev); + if (!cm_ctx) { + mlme_err("cm ctx NULL"); + return QDF_STATUS_E_INVAL; + } + + cm_id = cm_ctx->active_cm_id; + prefix = CM_ID_GET_PREFIX(cm_id); + + if (prefix != CONNECT_REQ_PREFIX) { + mlme_err("Active req %x is not connect req", cm_id); + return QDF_STATUS_E_INVAL; + } + + if (QDF_IS_STATUS_SUCCESS(status)) { + qdf_status = + cm_sm_deliver_event(vdev, + WLAN_CM_SM_EV_CANDIDATE_SELECT_IND_SUCCESS, + sizeof(wlan_cm_id), &cm_id); + if (QDF_IS_STATUS_SUCCESS(qdf_status)) + return qdf_status; + + goto post_err; + } + + /* In case of failure try with next candidate */ + resp = qdf_mem_malloc(sizeof(*resp)); + if (!resp) { + qdf_status = QDF_STATUS_E_NOMEM; + goto post_err; + } + + cm_fill_failure_resp_from_cm_id(cm_ctx, resp, cm_id, + CM_CANDIDATE_SELECT_IND_FAILED); + qdf_status = + cm_sm_deliver_event(vdev, + WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE, + sizeof(*resp), resp); + qdf_mem_free(resp); + if (QDF_IS_STATUS_SUCCESS(qdf_status)) + return qdf_status; + +post_err: + /* + * If there is a event posting error it means the SM state is not in + * JOIN ACTIVE (some new cmd has changed the state of SM), so just + * complete the connect command. + */ + cm_connect_handle_event_post_fail(cm_ctx, cm_id); + return qdf_status; +} + QDF_STATUS cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev, QDF_STATUS status, struct qdf_mac_addr *peer_mac) @@ -936,8 +1107,8 @@ QDF_STATUS cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_SUCCESS(status)) { qdf_status = cm_sm_deliver_event(vdev, - WLAN_CM_EV_BSS_CREATE_PEER_SUCCESS, - sizeof(wlan_cm_id), &cm_id); + WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS, + sizeof(wlan_cm_id), &cm_id); if (QDF_IS_STATUS_SUCCESS(qdf_status)) return qdf_status; @@ -952,8 +1123,8 @@ QDF_STATUS cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev, goto post_err; } - cm_fill_resp_for_bss_create_fail(cm_ctx->vdev, resp, cm_id, peer_mac); - + cm_fill_failure_resp_from_cm_id(cm_ctx, resp, cm_id, + CM_PEER_CREATE_FAILED); qdf_status = cm_sm_deliver_event(vdev, WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE, 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 b992ff6b62a3..458163beca92 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 @@ -103,6 +103,18 @@ QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id); QDF_STATUS cm_try_next_candidate(struct cnx_mgr *cm_ctx, struct wlan_cm_connect_rsp *connect_resp); +/** + * cm_peer_create_on_candidate_select_ind_resp() - Called to create peer + * if peer select inidication's resp was success + * @cm_ctx: connection manager context + * @cm_id: Connection mgr ID assigned to this connect request. + * + * Return: QDF status + */ +QDF_STATUS +cm_peer_create_on_candidate_select_ind_resp(struct cnx_mgr *cm_ctx, + wlan_cm_id *cm_id); + /** * cm_resume_connect_after_peer_create() - Called after bss create rsp * @cm_ctx: connection manager context @@ -113,6 +125,17 @@ QDF_STATUS cm_try_next_candidate(struct cnx_mgr *cm_ctx, QDF_STATUS cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id); +/** + * cm_candidate_select_ind_rsp() - Connection manager resp for candidate + * select indication + * @vdev: vdev pointer + * @status: Status + * + * Return: QDF_STATUS + */ +QDF_STATUS cm_candidate_select_ind_rsp(struct wlan_objmgr_vdev *vdev, + QDF_STATUS status); + /** * cm_bss_peer_create_rsp() - handle bss peer create response * @vdev: vdev @@ -352,6 +375,24 @@ void cm_free_connect_req_mem(struct cm_connect_req *connect_req); */ QDF_STATUS cm_delete_req_from_list(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id); +/** + * cm_fill_bss_info_in_connect_rsp_by_cm_id() - fill bss info for the cm id + * @cm_ctx: connection manager context + * @cm_id: cm id of connect/disconnect req + * @resp: resp to copy bss info like ssid/bssid and freq + * + * Fill the SSID form the connect req. + * Fill freq and bssid from current candidate if available (i.e the connection + * has tried to connect to a candidate), else get the bssid from req bssid or + * bssid hint which ever is present. + * + * Return: Success if entry was found else failure + */ +QDF_STATUS +cm_fill_bss_info_in_connect_rsp_by_cm_id(struct cnx_mgr *cm_ctx, + wlan_cm_id cm_id, + struct wlan_cm_connect_rsp *resp); + /** * cm_remove_cmd() - Remove cmd from req list and serialization * @cm_ctx: connection manager context 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 142c0a4dbca2..5e4d7eeb9752 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c @@ -571,7 +571,16 @@ static bool cm_subst_join_active_event(void *ctx, uint16_t event, cm_sm_deliver_event_sync(cm_ctx, event, data_len, data); status = true; break; - case WLAN_CM_EV_BSS_CREATE_PEER_SUCCESS: + case WLAN_CM_SM_EV_CANDIDATE_SELECT_IND_SUCCESS: + /* check if cm id is valid for the current req */ + if (!cm_check_cmid_match_list_head(cm_ctx, data)) { + status = false; + break; + } + cm_peer_create_on_candidate_select_ind_resp(cm_ctx, data); + status = true; + break; + case WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS: /* check if cm id is valid for the current req */ if (!cm_check_cmid_match_list_head(cm_ctx, data)) { status = false; @@ -751,6 +760,7 @@ static const char *cm_sm_event_names[] = { "EV_CONNECT_START", "EV_CONNECT_ACTIVE", "EV_CONNECT_SUCCESS", + "EV_MLME_CANDIDATE_SELECT_IND_SUCCESS", "EV_BSS_CREATE_PEER_SUCCESS" "EV_CONNECT_GET_NXT_CANDIDATE", "EV_CONNECT_FAILURE", 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 7aeca0ba2072..0d9704e842d9 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.h @@ -37,7 +37,9 @@ * @WLAN_CM_SM_EV_CONNECT_START: Connect start process initiate * @WLAN_CM_SM_EV_CONNECT_ACTIVE: Connect request is activated * @WLAN_CM_SM_EV_CONNECT_SUCCESS: Connect success - * @WLAN_CM_EV_BSS_CREATE_PEER_SUCCESS: BSS peer create success + * @WLAN_CM_SM_EV_CANDIDATE_SELECT_IND_SUCCESS: Mlme resp for mlme active cmd + * req + * @WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS: BSS peer create success * @WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE: Get next candidate for connection * @WLAN_CM_SM_EV_CONNECT_FAILURE: Connect failed for all candidate * @WLAN_CM_SM_EV_DISCONNECT_REQ: Disconnect request event from @@ -68,24 +70,25 @@ enum wlan_cm_sm_evt { WLAN_CM_SM_EV_CONNECT_START = 6, WLAN_CM_SM_EV_CONNECT_ACTIVE = 7, WLAN_CM_SM_EV_CONNECT_SUCCESS = 8, - WLAN_CM_EV_BSS_CREATE_PEER_SUCCESS = 9, - WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE = 10, - WLAN_CM_SM_EV_CONNECT_FAILURE = 11, - WLAN_CM_SM_EV_DISCONNECT_REQ = 12, - WLAN_CM_SM_EV_DISCONNECT_START = 13, - WLAN_CM_SM_EV_DISCONNECT_ACTIVE = 14, - WLAN_CM_SM_EV_DISCONNECT_DONE = 15, - WLAN_CM_SM_EV_ROAM_START = 16, - WLAN_CM_SM_EV_ROAM_SYNC = 17, - WLAN_CM_SM_EV_ROAM_INVOKE_FAIL = 18, - WLAN_CM_SM_EV_ROAM_HO_FAIL = 19, - WLAN_CM_SM_EV_PREAUTH_DONE = 20, - WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP = 21, - WLAN_CM_SM_EV_PREAUTH_FAIL = 22, - WLAN_CM_SM_EV_START_REASSOC = 23, - WLAN_CM_SM_EV_REASSOC_DONE = 24, - WLAN_CM_SM_EV_REASSOC_FAILURE = 25, - WLAN_CM_SM_EV_ROAM_COMPLETE = 26, + WLAN_CM_SM_EV_CANDIDATE_SELECT_IND_SUCCESS = 9, + WLAN_CM_SM_EV_BSS_CREATE_PEER_SUCCESS = 10, + WLAN_CM_SM_EV_CONNECT_GET_NEXT_CANDIDATE = 11, + WLAN_CM_SM_EV_CONNECT_FAILURE = 12, + WLAN_CM_SM_EV_DISCONNECT_REQ = 13, + WLAN_CM_SM_EV_DISCONNECT_START = 14, + WLAN_CM_SM_EV_DISCONNECT_ACTIVE = 15, + WLAN_CM_SM_EV_DISCONNECT_DONE = 16, + WLAN_CM_SM_EV_ROAM_START = 17, + WLAN_CM_SM_EV_ROAM_SYNC = 18, + WLAN_CM_SM_EV_ROAM_INVOKE_FAIL = 19, + WLAN_CM_SM_EV_ROAM_HO_FAIL = 20, + WLAN_CM_SM_EV_PREAUTH_DONE = 21, + WLAN_CM_SM_EV_GET_NEXT_PREAUTH_AP = 22, + WLAN_CM_SM_EV_PREAUTH_FAIL = 23, + WLAN_CM_SM_EV_START_REASSOC = 24, + WLAN_CM_SM_EV_REASSOC_DONE = 25, + WLAN_CM_SM_EV_REASSOC_FAILURE = 26, + WLAN_CM_SM_EV_ROAM_COMPLETE = 27, 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 6b4ac86cf7f2..d18e04740cec 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_util.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_util.c @@ -198,6 +198,57 @@ struct cm_req *cm_get_req_by_cm_id(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id) return NULL; } +QDF_STATUS +cm_fill_bss_info_in_connect_rsp_by_cm_id(struct cnx_mgr *cm_ctx, + wlan_cm_id cm_id, + struct wlan_cm_connect_rsp *resp) +{ + qdf_list_node_t *cur_node = NULL, *next_node = NULL; + struct cm_req *cm_req; + uint32_t prefix = CM_ID_GET_PREFIX(cm_id); + struct scan_cache_node *candidate; + struct wlan_cm_connect_req *req; + + if (prefix != CONNECT_REQ_PREFIX) + return QDF_STATUS_E_INVAL; + + 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); + + if (cm_req->cm_id == cm_id) { + req = &cm_req->connect_req.req; + candidate = cm_req->connect_req.cur_candidate; + if (candidate) + qdf_copy_macaddr(&resp->bssid, + &candidate->entry->bssid); + else if (!qdf_is_macaddr_zero(&req->bssid)) + qdf_copy_macaddr(&resp->bssid, + &req->bssid); + else + qdf_copy_macaddr(&resp->bssid, + &req->bssid_hint); + if (candidate) + resp->freq = + candidate->entry->channel.chan_freq; + else + resp->freq = req->chan_freq; + qdf_mem_copy(&resp->ssid, &req->ssid, + sizeof(resp->bssid)); + cm_req_lock_release(cm_ctx); + return QDF_STATUS_SUCCESS; + } + + cur_node = next_node; + next_node = NULL; + } + cm_req_lock_release(cm_ctx); + + return QDF_STATUS_E_FAILURE; +} + QDF_STATUS cm_add_req_to_list_and_indicate_osif(struct cnx_mgr *cm_ctx, struct cm_req *cm_req, enum wlan_cm_source source) 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 3f55945c23ee..2aca5b51df34 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h @@ -46,6 +46,17 @@ QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev, QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, struct wlan_cm_disconnect_req *req); +/** + * wlan_cm_candidate_select_ind_rsp() - Connection manager resp for candidate + * select indication + * @vdev: vdev pointer + * @status: Status + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_candidate_select_ind_rsp(struct wlan_objmgr_vdev *vdev, + QDF_STATUS status); + /** * wlan_cm_bss_peer_create_rsp() - Connection manager bss peer create response * @vdev: vdev pointer diff --git a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h index 3e9ad3227ad7..e15c8ab3e641 100644 --- a/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h +++ b/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h @@ -207,6 +207,7 @@ struct wlan_cm_vdev_discon_req { * enum wlan_cm_connect_fail_reason: connection manager connect fail reason * @CM_NO_CANDIDATE_FOUND: No candidate found * @CM_ABORT_DUE_TO_NEW_REQ_RECVD: Aborted as new command is received and + * @CM_CANDIDATE_SELECT_IND_FAILED: Failed candidate select indication * State machine is not able to handle as state has changed due to new command. * @CM_PEER_CREATE_FAILED: peer create failed * @CM_JOIN_FAILED: Failed in joining state @@ -225,6 +226,7 @@ struct wlan_cm_vdev_discon_req { enum wlan_cm_connect_fail_reason { CM_NO_CANDIDATE_FOUND, CM_ABORT_DUE_TO_NEW_REQ_RECVD, + CM_CANDIDATE_SELECT_IND_FAILED, CM_PEER_CREATE_FAILED, CM_JOIN_FAILED, CM_JOIN_TIMEOUT, 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 9b201203428d..1b5ae666deb0 100644 --- a/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c +++ b/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c @@ -35,6 +35,12 @@ QDF_STATUS wlan_cm_start_disconnect(struct wlan_objmgr_vdev *vdev, return cm_disconnect_start_req(vdev, req); } +QDF_STATUS wlan_cm_candidate_select_ind_rsp(struct wlan_objmgr_vdev *vdev, + QDF_STATUS status) +{ + return cm_candidate_select_ind_rsp(vdev, status); +} + QDF_STATUS wlan_cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev, QDF_STATUS status, struct qdf_mac_addr *peer_mac) diff --git a/umac/mlme/include/wlan_mlme_cmn.h b/umac/mlme/include/wlan_mlme_cmn.h index 37643ba3dbc4..00f313f09cc4 100644 --- a/umac/mlme/include/wlan_mlme_cmn.h +++ b/umac/mlme/include/wlan_mlme_cmn.h @@ -99,7 +99,8 @@ struct mlme_cm_ops { * @mlme_multi_vdev_restart_resp: callback to process multivdev * restart response * @mlme_cm_ext_connect_start_ind_cb: callback to indicate connect start - * @mlme_cm_ext_connect_active_ind_cb: callback to indicate connect active + * @mlme_cm_ext_candidate_select_ind_cb: callback to indicate candidate + * select for connect * @mlme_cm_ext_bss_peer_create_req_cb: callback to bss peer create request * @mlme_cm_ext_connect_req_cb: callback for connect request to * VDEV/PEER SM @@ -148,7 +149,7 @@ struct mlme_ext_ops { QDF_STATUS (*mlme_cm_ext_connect_start_ind_cb)( struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_req *req); - QDF_STATUS (*mlme_cm_ext_connect_active_ind_cb)( + QDF_STATUS (*mlme_cm_ext_candidate_select_ind_cb)( struct wlan_objmgr_vdev *vdev, struct wlan_cm_vdev_connect_req *req); QDF_STATUS (*mlme_cm_ext_bss_peer_create_req_cb)( @@ -383,15 +384,15 @@ QDF_STATUS mlme_cm_connect_start_ind(struct wlan_objmgr_vdev *vdev, struct wlan_cm_connect_req *req); /** - * mlme_cm_connect_active_ind() - Connection manager ext Connect active - * indication + * mlme_cm_candidate_select_ind() - Connection manager ext Connect candidate + * select indication, to do operations for the candidate * @vdev: VDEV object * @req: Vdev connect request * * Return: QDF_STATUS */ -QDF_STATUS mlme_cm_connect_active_ind(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_vdev_connect_req *req); +QDF_STATUS mlme_cm_candidate_select_ind(struct wlan_objmgr_vdev *vdev, + struct wlan_cm_vdev_connect_req *req); /** * mlme_cm_bss_peer_create_req() - Connection manager ext bss peer create 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 e6a458b7f7c7..d0c680fe43e4 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 @@ -258,13 +258,13 @@ QDF_STATUS mlme_cm_connect_start_ind(struct wlan_objmgr_vdev *vdev, return ret; } -QDF_STATUS mlme_cm_connect_active_ind(struct wlan_objmgr_vdev *vdev, - struct wlan_cm_vdev_connect_req *req) +QDF_STATUS mlme_cm_candidate_select_ind(struct wlan_objmgr_vdev *vdev, + struct wlan_cm_vdev_connect_req *req) { - QDF_STATUS ret = QDF_STATUS_SUCCESS; + QDF_STATUS ret = QDF_STATUS_E_NOSUPPORT; - if ((glbl_ops) && glbl_ops->mlme_cm_ext_connect_active_ind_cb) - ret = glbl_ops->mlme_cm_ext_connect_active_ind_cb(vdev, req); + if ((glbl_ops) && glbl_ops->mlme_cm_ext_candidate_select_ind_cb) + ret = glbl_ops->mlme_cm_ext_candidate_select_ind_cb(vdev, req); return ret; }