diff --git a/os_if/linux/mlme/src/osif_cm_req.c b/os_if/linux/mlme/src/osif_cm_req.c index 5b2e9499f2..a3aace4388 100644 --- a/os_if/linux/mlme/src/osif_cm_req.c +++ b/os_if/linux/mlme/src/osif_cm_req.c @@ -494,8 +494,9 @@ int osif_cm_connect(struct net_device *dev, struct wlan_objmgr_vdev *vdev, if (req->channel) connect_req->chan_freq = req->channel->center_freq; - else - connect_req->chan_freq = 0; + + if (req->channel_hint) + connect_req->chan_freq_hint = req->channel_hint->center_freq; status = osif_cm_set_crypto_params(connect_req, req); if (QDF_IS_STATUS_ERROR(status)) 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 7d73bf8005..8d6aa849b6 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_connect.c @@ -1626,7 +1626,7 @@ QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx, mlme_debug(CM_PREFIX_FMT, CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), resp->cm_id)); - cm_remove_cmd(cm_ctx, resp->cm_id); + cm_remove_cmd(cm_ctx, &resp->cm_id); return QDF_STATUS_SUCCESS; } 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 98a95a0ec5..c6c3eb30b2 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_disconnect.c @@ -481,7 +481,7 @@ QDF_STATUS cm_disconnect_complete(struct cnx_mgr *cm_ctx, if (resp->req.cm_id == cm_ctx->active_cm_id) cm_flush_pending_request(cm_ctx, DISCONNECT_REQ_PREFIX, false); - cm_remove_cmd(cm_ctx, resp->req.cm_id); + cm_remove_cmd(cm_ctx, &resp->req.cm_id); mlme_debug(CM_PREFIX_FMT "disconnect count %d connect count %d", CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), resp->req.cm_id), diff --git a/umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.c b/umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.c index 6abb643305..a47be804c7 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_host_roam.c @@ -458,8 +458,7 @@ reassoc_fail: wlan_vdev_get_pdev(vdev), &bss_info, &mlme_info); } - - cm_remove_cmd(cm_ctx, resp->cm_id); + cm_remove_cmd(cm_ctx, &resp->cm_id); /* * If roaming fails and conn_sm is in ROAMING state, then 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 fd2f1a3979..8fd701e9b5 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 @@ -679,7 +679,7 @@ void cm_flush_pending_request(struct cnx_mgr *cm_ctx, uint32_t prefix, * * Return: void */ -void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id); +void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id); /** * cm_add_req_to_list_and_indicate_osif() - Add the request to request list in 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 05151a5816..c7a5f36035 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_roam.h +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_roam.h @@ -237,17 +237,23 @@ cm_fill_bss_info_in_roam_rsp_by_cm_id(struct cnx_mgr *cm_ctx, struct wlan_cm_roam_resp *resp); #ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * cm_send_roam_invoke_req() - Send Roam invoke req to FW + * @cm_ctx: connection manager context + * @req: connection manager request + * + * Return: QDF_STATUS + */ +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 * * Return: bool */ -static inline bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc) -{ - /* use INI CFG_LFR3_ROAMING_OFFLOAD,return true for now */ - return true; -} +bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc); + #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 535d5fd1a3..9dc213122d 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 @@ -63,7 +63,10 @@ bool cm_state_roaming_event(void *ctx, uint16_t event, break; case WLAN_CM_SM_EV_ROAM_INVOKE: cm_add_roam_req_to_list(cm_ctx, data); - /* cm_start_roam_invoke(cm_ctx); define in LFR3/FW roam file */ + 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); @@ -253,6 +256,14 @@ 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_INVOKE: + cm_send_roam_invoke_req(cm_ctx, data); + break; + 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, + data_len, data); + break; default: event_handled = false; break; 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 5bfc3dd4f8..0112faceed 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 @@ -40,14 +40,20 @@ QDF_STATUS cm_check_and_prepare_roam_req(struct cnx_mgr *cm_ctx, struct qdf_mac_addr bssid; struct wlan_ssid ssid; struct cm_req *cm_req, *req_ptr; + qdf_freq_t freq = 0; cm_req = qdf_container_of(connect_req, struct cm_req, connect_req); req = &connect_req->req; + + if (req->chan_freq) + freq = req->chan_freq; + else if (req->chan_freq_hint) + freq = req->chan_freq_hint; /* * Reject re-assoc unless freq along with prev bssid and one * of bssid or bssid hint is present. */ - if (!req->chan_freq || qdf_is_macaddr_zero(&req->prev_bssid) || + if (!freq || qdf_is_macaddr_zero(&req->prev_bssid) || (qdf_is_macaddr_zero(&req->bssid) && qdf_is_macaddr_zero(&req->bssid_hint))) return QDF_STATUS_E_FAILURE; @@ -55,8 +61,12 @@ QDF_STATUS cm_check_and_prepare_roam_req(struct cnx_mgr *cm_ctx, wlan_vdev_get_bss_peer_mac(cm_ctx->vdev, &bssid); /* Reject re-assoc unless prev_bssid matches the current BSSID. */ - if (!qdf_is_macaddr_equal(&req->prev_bssid, &bssid)) + if (!qdf_is_macaddr_equal(&req->prev_bssid, &bssid)) { + mlme_debug("BSSID didn't matched: bssid: "QDF_MAC_ADDR_FMT " prev bssid: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssid.bytes), + QDF_MAC_ADDR_REF(req->prev_bssid.bytes)); return QDF_STATUS_E_FAILURE; + } status = wlan_vdev_mlme_get_ssid(cm_ctx->vdev, ssid.ssid, &ssid.length); if (QDF_IS_STATUS_ERROR(status)) { @@ -66,8 +76,12 @@ QDF_STATUS cm_check_and_prepare_roam_req(struct cnx_mgr *cm_ctx, /* Reject re-assoc unless ssid matches. */ if (ssid.length != req->ssid.length || - qdf_mem_cmp(ssid.ssid, req->ssid.ssid, ssid.length)) + qdf_mem_cmp(ssid.ssid, req->ssid.ssid, ssid.length)) { + mlme_debug("SSID didn't matched: self ssid: \"%.*s\", ssid in req: \"%.*s\"", + ssid.length, ssid.ssid, req->ssid.length, + req->ssid.ssid); return QDF_STATUS_E_FAILURE; + } /* fill roam_req for roaming and free cm_req */ *roam_req = qdf_mem_malloc(sizeof(**roam_req)); @@ -82,7 +96,7 @@ QDF_STATUS cm_check_and_prepare_roam_req(struct cnx_mgr *cm_ctx, &req->bssid_hint); qdf_copy_macaddr(&req_ptr->roam_req.req.prev_bssid, &req->prev_bssid); - req_ptr->roam_req.req.chan_freq = req->chan_freq; + req_ptr->roam_req.req.chan_freq = freq; req_ptr->roam_req.req.source = CM_ROAMING_HOST; /* Free the connect req, as reassoc is tried */ 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 9f80cd4f47..a92f831b9f 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_sm.c @@ -304,6 +304,11 @@ static bool cm_state_connected_event(void *ctx, uint16_t event, cm_reassoc_complete(cm_ctx, data); event_handled = true; break; + case WLAN_CM_SM_EV_ROAM_INVOKE_FAIL: + cm_remove_cmd(cm_ctx, data); + event_handled = true; + break; + default: event_handled = false; break; 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 441902e83c..9f77fd6b38 100644 --- a/umac/mlme/connection_mgr/core/src/wlan_cm_util.c +++ b/umac/mlme/connection_mgr/core/src/wlan_cm_util.c @@ -35,6 +35,7 @@ static uint32_t cm_get_prefix_for_cm_id(enum wlan_cm_source source) { return CONNECT_REQ_PREFIX; case CM_ROAMING_HOST: case CM_ROAMING_FW: + case CM_ROAMING_NUD_FAILURE: return ROAM_REQ_PREFIX; default: return DISCONNECT_REQ_PREFIX; @@ -747,7 +748,7 @@ cm_delete_req_from_list(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id) return QDF_STATUS_SUCCESS; } -void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id) +void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id) { struct wlan_objmgr_psoc *psoc; QDF_STATUS status; @@ -755,15 +756,15 @@ void cm_remove_cmd(struct cnx_mgr *cm_ctx, wlan_cm_id cm_id) psoc = wlan_vdev_get_psoc(cm_ctx->vdev); if (!psoc) { mlme_err(CM_PREFIX_FMT "Failed to find psoc", - CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), cm_id)); + CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), *cm_id)); return; } - status = cm_delete_req_from_list(cm_ctx, cm_id); + status = cm_delete_req_from_list(cm_ctx, *cm_id); if (QDF_IS_STATUS_ERROR(status)) return; - cm_remove_cmd_from_serialization(cm_ctx, cm_id); + cm_remove_cmd_from_serialization(cm_ctx, *cm_id); } void cm_vdev_scan_cancel(struct wlan_objmgr_pdev *pdev, 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 05bc3697c7..e996f97c92 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 @@ -124,6 +124,7 @@ struct wlan_fils_con_info { * enum wlan_cm_source - connection manager req source * @CM_OSIF_CONNECT: Connect req initiated by OSIF or north bound * @CM_ROAMING_HOST: Roaming request initiated by host + * @CM_ROAMING_NUD_FAILURE: Roaming request initiated by NUD failure * @CM_ROAMING_FW: Roam req initiated by FW * @CM_OSIF_DISCONNECT: Disconnect req initiated by OSIF or north bound * @CM_PEER_DISCONNECT: Disconnect req initiated by peer sending deauth/disassoc @@ -143,6 +144,7 @@ struct wlan_fils_con_info { enum wlan_cm_source { CM_OSIF_CONNECT, CM_ROAMING_HOST, + CM_ROAMING_NUD_FAILURE, CM_ROAMING_FW, CM_OSIF_DISCONNECT, CM_PEER_DISCONNECT, @@ -165,6 +167,7 @@ enum wlan_cm_source { * @ssid: profile SSID * @bssid_hint: bssid hint to connect * @chan_freq: channel of the AP + * @chan_freq_hint: channel hint * @crypto: crypto related info * @assoc_ie:Additional assoc IE to be appended in assoc req * (Include RSN/WPA/WAPI/WPS ies) @@ -194,7 +197,8 @@ struct wlan_cm_connect_req { struct qdf_mac_addr prev_bssid; struct wlan_ssid ssid; struct qdf_mac_addr bssid_hint; - uint32_t chan_freq; + qdf_freq_t chan_freq; + qdf_freq_t chan_freq_hint; struct wlan_cm_connect_crypto_info crypto; struct element_info assoc_ie; struct element_info scan_ie; @@ -257,6 +261,7 @@ struct wlan_cm_vdev_connect_req { * @bssid: bssid given * @prev_bssid: prev AP bssid, given in case supplican want to roam to new BSSID * @chan_freq: channel of the AP + * @forced_roaming: Roaming to be done without giving bssid, and channel. */ struct wlan_cm_roam_req { uint8_t vdev_id; @@ -264,6 +269,7 @@ struct wlan_cm_roam_req { struct qdf_mac_addr bssid; struct qdf_mac_addr prev_bssid; uint32_t chan_freq; + bool forced_roaming; }; /** diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index ec10fcd298..537ea7a839 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -749,8 +749,7 @@ QDF_STATUS (*send_process_roam_synch_complete_cmd)(wmi_unified_t wmi_handle, uint8_t vdev_id); QDF_STATUS (*send_roam_invoke_cmd)(wmi_unified_t wmi_handle, - struct wmi_roam_invoke_cmd *roaminvoke, - uint32_t ch_hz); + struct roam_invoke_req *roaminvoke); QDF_STATUS (*send_set_roam_trigger_cmd)(wmi_unified_t wmi_handle, struct wlan_roam_triggers *triggers);