diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 37034530506e..2602f12f31cb 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -30,7 +30,9 @@ #include "qdf_status.h" #include "wlan_objmgr_psoc_obj.h" #include "wlan_policy_mgr_public_struct.h" +#include "wlan_cm_roam_public_srtuct.h" #include "wlan_utility.h" +#include "sir_types.h" struct target_psoc_info; @@ -595,11 +597,13 @@ static inline void policy_mgr_change_sap_channel_with_csa( * policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo * @psoc: PSOC object information * @mode: Adapter mode + * @vdev_id: Vdev Id * * Return: None */ void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode); + enum policy_mgr_con_mode mode, + uint8_t vdev_id); /** * policy_mgr_incr_active_session() - increments the number of active sessions * @psoc: PSOC object information @@ -1344,9 +1348,11 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, * @sme_soc_set_dual_mac_config: Set the dual MAC scan & FW * config * @sme_pdev_set_hw_mode: Set the new HW mode to FW - * @sme_pdev_set_pcl: Set new PCL to FW + * @sme_set_pcl: Set new PCL to FW * @sme_nss_update_request: Update NSS value to FW * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW + * @sme_rso_start_cb: Enable roaming offload callback + * @sme_rso_stop_cb: Disable roaming offload callback */ struct policy_mgr_sme_cbacks { void (*sme_get_nss_for_vdev)(enum QDF_OPMODE, @@ -1354,7 +1360,8 @@ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_soc_set_dual_mac_config)( struct policy_mgr_dual_mac_config msg); QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg); - QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list *msg); + QDF_STATUS (*sme_set_pcl)(struct policy_mgr_pcl_list *msg, + uint8_t vdev_id, bool clear_vdev_pcl); QDF_STATUS (*sme_nss_update_request)(uint32_t vdev_id, uint8_t new_nss, uint8_t ch_width, policy_mgr_nss_update_cback cback, @@ -1368,6 +1375,12 @@ struct policy_mgr_sme_cbacks { uint32_t *ch_freq); QDF_STATUS (*sme_scan_result_purge)( void *scan_result); + QDF_STATUS (*sme_rso_start_cb)( + mac_handle_t mac_handle, uint8_t vdev_id, + uint8_t reason, enum wlan_cm_rso_control_requestor requestor); + QDF_STATUS (*sme_rso_stop_cb)( + mac_handle_t mac_handle, uint8_t vdev_id, + uint8_t reason, enum wlan_cm_rso_control_requestor requestor); }; /** diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 1ff2a3e8e46e..1a6551aacbfc 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -1346,13 +1346,15 @@ QDF_STATUS policy_mgr_pdev_get_pcl(struct wlan_objmgr_psoc *psoc, /** * policy_mgr_set_pcl_for_existing_combo() - Set PCL for existing connection * @mode: Connection mode of type 'policy_mgr_con_mode' + * @vdev_id: Vdev Id * * Set the PCL for an existing connection * * Return: None */ -void policy_mgr_set_pcl_for_existing_combo( - struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) +void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t vdev_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_conc_connection_info @@ -1386,7 +1388,7 @@ void policy_mgr_set_pcl_for_existing_combo( /* Send PCL only if policy_mgr_pdev_get_pcl returned success */ if (QDF_IS_STATUS_SUCCESS(status)) { - status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl); + status = pm_ctx->sme_cbacks.sme_set_pcl(&pcl, vdev_id, false); if (QDF_IS_STATUS_ERROR(status)) policy_mgr_err("Send set PCL to SME failed"); } diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 1a0de679ebc6..ca9b1a803d6d 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -35,6 +35,8 @@ #include "wlan_nan_api.h" #include "nan_public_structs.h" #include "wlan_reg_services_api.h" +#include "wlan_cm_roam_public_srtuct.h" +#include "csr_neighbor_roam.h" /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 @@ -1717,8 +1719,10 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, uint8_t session_id) { + mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME); struct policy_mgr_psoc_priv_obj *pm_ctx; - uint32_t conn_6ghz_flag = 0; + uint32_t conn_6ghz_flag = 0, conn_idx = 0; + uint8_t vdev_id = WLAN_INVALID_VDEV_ID; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1759,10 +1763,36 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); policy_mgr_incr_connection_count(psoc, session_id, mode); + if ((policy_mgr_mode_specific_connection_count( psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) { + /* Send set pcl for all the connected STA vdev */ qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE); + for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_idx++) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (!(pm_conc_connection_list[conn_idx].mode == + PM_STA_MODE && + pm_conc_connection_list[conn_idx].in_use)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + continue; + } + + vdev_id = pm_conc_connection_list[conn_idx].vdev_id; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + pm_ctx->sme_cbacks.sme_rso_stop_cb( + mac_handle, vdev_id, + REASON_DRIVER_DISABLED, + RSO_SET_PCL); + + policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, + vdev_id); + pm_ctx->sme_cbacks.sme_rso_start_cb( + mac_handle, vdev_id, + REASON_DRIVER_ENABLED, + RSO_SET_PCL); + } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); } diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c index ee643f4cebf2..c50c9d37e6dc 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c @@ -655,8 +655,8 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, sme_cbacks->sme_nss_update_request; pm_ctx->sme_cbacks.sme_pdev_set_hw_mode = sme_cbacks->sme_pdev_set_hw_mode; - pm_ctx->sme_cbacks.sme_pdev_set_pcl = - sme_cbacks->sme_pdev_set_pcl; + pm_ctx->sme_cbacks.sme_set_pcl = + sme_cbacks->sme_set_pcl; pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config = sme_cbacks->sme_soc_set_dual_mac_config; pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval = @@ -665,6 +665,10 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, sme_cbacks->sme_get_ap_channel_from_scan; pm_ctx->sme_cbacks.sme_scan_result_purge = sme_cbacks->sme_scan_result_purge; + pm_ctx->sme_cbacks.sme_rso_start_cb = + sme_cbacks->sme_rso_start_cb; + pm_ctx->sme_cbacks.sme_rso_stop_cb = + sme_cbacks->sme_rso_stop_cb; return QDF_STATUS_SUCCESS; } diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index f66f2eaa57ad..638d20c74342 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -33,6 +33,7 @@ #include "wlan_objmgr_global_obj.h" #include "wlan_utility.h" #include "wlan_mlme_ucfg_api.h" +#include "csr_neighbor_roam.h" /** * first_connection_pcl_table - table which provides PCL for the @@ -112,6 +113,9 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, { QDF_STATUS qdf_status; struct policy_mgr_psoc_priv_obj *pm_ctx; + mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME); + uint32_t conn_idx = 0; + uint8_t vdev_id = WLAN_INVALID_VDEV_ID; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -139,7 +143,38 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, * given to the FW. After setting the PCL, we need to restore * the entry that we have saved before. */ - policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE); + + if ((policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL) > 0) && mode != QDF_STA_MODE) { + for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_idx++) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (!(pm_conc_connection_list[conn_idx].mode == + PM_STA_MODE && + pm_conc_connection_list[conn_idx].in_use)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + continue; + } + + vdev_id = pm_conc_connection_list[conn_idx].vdev_id; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + /* Send RSO stop before sending set pcl command */ + pm_ctx->sme_cbacks.sme_rso_stop_cb( + mac_handle, session_id, + REASON_DRIVER_DISABLED, + RSO_SET_PCL); + + policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, + session_id); + + pm_ctx->sme_cbacks.sme_rso_start_cb( + mac_handle, session_id, + REASON_DRIVER_ENABLED, + RSO_SET_PCL); + } + } + /* do we need to change the HW mode */ policy_mgr_check_n_start_opportunistic_timer(psoc); return; diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c index d8552b77afb0..b78eb14ef731 100644 --- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -27,6 +27,7 @@ #include #include <../../core/src/vdev_mgr_ops.h> #include "wlan_psoc_mlme_api.h" +#include "target_if_cm_roam_offload.h" static struct vdev_mlme_ops sta_mlme_ops; static struct vdev_mlme_ops ap_mlme_ops; @@ -941,6 +942,9 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme) return QDF_STATUS_E_NOMEM; } + target_if_cm_roam_register_tx_ops( + &vdev_mlme->ext_vdev_ptr->cm_roam.tx_ops); + return QDF_STATUS_SUCCESS; } diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h index 2d27b6437b7f..f84fb85a6111 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h @@ -52,11 +52,13 @@ enum wlan_cm_rso_control_requestor { * struct set_pcl_req - Request message to set the PCL * @vdev_id: Vdev id * @band_mask: Supported band mask + * @clear_vdev_pcl: Clear the configured vdev pcl channels * @chan_weights: PCL channel weights */ struct set_pcl_req { uint8_t vdev_id; uint32_t band_mask; + bool clear_vdev_pcl; struct wmi_pcl_chan_weights chan_weights; }; diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c index e166244bb1a5..1f93cbb35d89 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c @@ -50,7 +50,7 @@ void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, /* value - true (vdev pcl) false - pdev pcl */ mlme_priv->cm_roam.pcl_vdev_cmd_active = pcl_per_vdev; - mlme_legacy_debug("CM_ROAM: SET PCL cmd level - [%s]", + mlme_legacy_debug("CM_ROAM: vdev[%d] SET PCL cmd level - [%s]", vdev_id, pcl_per_vdev ? "VDEV" : "PDEV"); } diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c index d0a1e876fb77..8cc1ca919c77 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c @@ -81,6 +81,9 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, weights->saved_chan_list[i] = freq_list->freq[i]; weights->saved_num_chan = freq_list->num_channels; + if (pcl_req->clear_vdev_pcl) + weights->saved_num_chan = 0; + status = policy_mgr_get_valid_chan_weights( psoc, (struct policy_mgr_pcl_chan_weights *)weights); @@ -109,7 +112,7 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, goto end; } - mlme_debug("LFR3: Dump Vdev PCL weights"); + mlme_debug("LFR3: vdev[%d] Dump Vdev PCL weights", pcl_req->vdev_id); policy_mgr_dump_channel_list(weights->saved_num_chan, weights->saved_chan_list, weights->weighed_valid_list); diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 551d0f3e4434..1bb403279e30 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -73,6 +73,7 @@ #include "wlan_hdd_sta_info.h" #include "wlan_hdd_ftm_time_sync.h" #include "wlan_hdd_periodic_sta_stats.h" +#include "wlan_cm_roam_api.h" #include #include "wlan_pkt_capture_ucfg_api.h" @@ -1987,9 +1988,13 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, hdd_print_bss_info(sta_ctx); - if (policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) + if (policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc) && + QDF_STA_MODE == adapter->device_mode) { sme_enable_roaming_on_connected_sta(mac_handle, adapter->vdev_id); + sme_clear_and_set_pcl_for_connected_vdev(mac_handle, + adapter->vdev_id); + } return status; } @@ -2824,6 +2829,14 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, adapter->device_mode == QDF_P2P_CLIENT_MODE) { hdd_debug("p2p cli active keep roam disabled"); } else { + /* + * On successful association. set the vdev PCL for the + * already existing STA which was connected first + */ + sme_set_pcl_for_first_connected_vdev( + hdd_ctx->mac_handle, + adapter->vdev_id); + /* * Enable roaming on other STA iface except this one. * Firmware dosent support connection on one STA iface diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index db71280f27dd..7163052f8d62 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -3784,9 +3784,19 @@ static int drv_cmd_set_roam_intra_band(struct hdd_adapter *adapter, val); ucfg_mlme_set_roam_intra_band(hdd_ctx->psoc, (bool)val); - policy_mgr_set_pcl_for_existing_combo( - hdd_ctx->psoc, - PM_STA_MODE); + + /* Disable roaming on Vdev before setting PCL */ + sme_stop_roaming(hdd_ctx->mac_handle, adapter->vdev_id, + REASON_DRIVER_DISABLED, + RSO_SET_PCL); + + policy_mgr_set_pcl_for_existing_combo(hdd_ctx->psoc, PM_STA_MODE, + adapter->vdev_id); + + /* Enable roaming once SET pcl is done */ + sme_start_roaming(hdd_ctx->mac_handle, adapter->vdev_id, + REASON_DRIVER_ENABLED, + RSO_SET_PCL); exit: return ret; diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index e7026f2a670d..49084af07e8f 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -381,7 +381,7 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_FLUSH_LOG_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160) -#define SIR_HAL_PDEV_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) +#define SIR_HAL_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) #ifdef WLAN_MWS_INFO_DEBUGFS #define SIR_HAL_GET_MWS_COEX_INFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 162) diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index a07296e737b7..49edcfa56ee9 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -3464,7 +3464,7 @@ static void lim_send_roam_set_pcl(struct mac_context *mac_ctx, struct scheduler_msg wma_msg = {0}; QDF_STATUS status; - wma_msg.type = SIR_HAL_PDEV_SET_PCL_TO_FW; + wma_msg.type = SIR_HAL_SET_PCL_TO_FW; wma_msg.bodyptr = msg_buf; status = wma_post_ctrl_msg(mac_ctx, &wma_msg); diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 2eaf648a172d..08835b3c3e34 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -531,7 +531,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(SIR_HAL_CONFIG_GUARD_TIME); CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING); CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW); - CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW); + CASE_RETURN_STRING(SIR_HAL_SET_PCL_TO_FW); CASE_RETURN_STRING(SIR_HAL_PDEV_SET_HW_MODE); CASE_RETURN_STRING(SIR_HAL_PDEV_DUAL_MAC_CFG_REQ); CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND); diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index 922045cd6ad4..743ebaa126d5 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/core/sme/inc/csr_neighbor_roam.h @@ -354,15 +354,17 @@ csr_roam_update_cfg(struct mac_context *mac, uint8_t vdev_id, uint8_t reason) * csr_get_roam_enabled_sta_sessionid() - get the session id of the sta on which * roaming is enabled. * @mac_ctx: pointer to global mac structure + * @vdev_id: vdev id of the requestor * - * The function check if any sta is present and has roaming enabled and return - * the session id of the sta with roaming enabled else if roaming is not enabled - * on any STA return WLAN_UMAC_VDEV_ID_MAX + * The function checks if any sta(other than the provided vdev_id) is present + * and has roaming enabled and return the session id of the sta with roaming + * enabled else if roaming is not enabled on any STA return + * WLAN_UMAC_VDEV_ID_MAX. * * Return: session id of STA on which roaming is enabled */ -uint8_t csr_get_roam_enabled_sta_sessionid( - struct mac_context *mac_ctx); +uint8_t csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx, + uint8_t vdev_id); #if defined(WLAN_FEATURE_FILS_SK) /** diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 7bcb0ff0f862..eb8f7ead862f 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -46,6 +46,7 @@ #include #include "wmi_unified.h" #include "wmi_unified_param.h" +#include "wlan_cm_roam_public_srtuct.h" /*-------------------------------------------------------------------------- Preprocessor definitions and constants @@ -971,10 +972,43 @@ QDF_STATUS sme_config_fast_roaming(mac_handle_t mac_handle, uint8_t session_id, const bool is_fast_roam_enabled); QDF_STATUS sme_stop_roaming(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t reason, uint32_t requestor); + uint8_t reason, + enum wlan_cm_rso_control_requestor requestor); QDF_STATUS sme_start_roaming(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t reason, uint32_t requestor); + uint8_t reason, + enum wlan_cm_rso_control_requestor requestor); + +/** + * sme_set_pcl_for_first_connected_vdev - Set the vdev pcl for the connected + * STA vdev + * @mac_handle: Pointer to opaque mac handle + * @vdev_id: vdev id + * + * This API will be called from the association completion handler of the + * 2nd STA to set the vdev pcl for the 1st. + * + * Return: None + */ +void sme_set_pcl_for_first_connected_vdev(mac_handle_t mac_handle, + uint8_t vdev_id); + +/** + * sme_clear_and_set_pcl_for_connected_vdev - Clear the vdev pcl for the + * current connected VDEV and Set PDEV pcl for that vdev. + * + * @mac_handle: Pointer to opaque mac handle + * @vdev_id: vdev id + * + * This API will be called from the disconnection handler of the 2nd STA. + * In the disconnection path. Clear the existing vdev pcl for the 1st STA + * and set the PDEV pcl. + * + * Return: None + */ +void sme_clear_and_set_pcl_for_connected_vdev(mac_handle_t mac_handle, + uint8_t vdev_id); + #ifdef FEATURE_WLAN_ESE QDF_STATUS sme_update_is_ese_feature_enabled(mac_handle_t mac_handle, uint8_t sessionId, @@ -1808,7 +1842,21 @@ void sme_update_user_configured_nss(mac_handle_t mac_handle, uint8_t nss); bool sme_is_any_session_in_connected_state(mac_handle_t mac_handle); -QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg); +/** + * sme_set_pcl() - Send set pcl command to the WMA via lim + * @msg: PCL channel list and length structure + * @vdev_id: Vdev id + * @clear_vdev_pcl: flag to clear the configured vdev pcl + * + * Sends the set pcl command to lim->WMA to send WMI_PDEV_SET_PCL_CMDID to FW + * if dual sta roaming is disabled. If dual sta roaming is enabled, + * WMI_VDEV_SET_PCL_CMDID will be sent. + * + * Return: QDF_STATUS_SUCCESS on successful posting + */ +QDF_STATUS sme_set_pcl(struct policy_mgr_pcl_list *msg, uint8_t vdev_id, + bool clear_vdev_pcl); + QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg); QDF_STATUS sme_nss_update_request(uint32_t vdev_id, uint8_t new_nss, uint8_t ch_width, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 3c4f0b1b541d..4bdaaabe73d6 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -64,6 +64,9 @@ #include "wlan_mlme_ucfg_api.h" #include "wlan_psoc_mlme_api.h" #include "mac_init_api.h" +#include "wlan_cm_roam_public_srtuct.h" +#include "wlan_cm_roam_api.h" +#include "wlan_cm_tgt_if_tx_api.h" static QDF_STATUS init_sme_cmd_list(struct mac_context *mac); @@ -1209,7 +1212,7 @@ QDF_STATUS sme_start(mac_handle_t mac_handle) sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss; sme_cbacks.sme_nss_update_request = sme_nss_update_request; sme_cbacks.sme_pdev_set_hw_mode = sme_pdev_set_hw_mode; - sme_cbacks.sme_pdev_set_pcl = sme_pdev_set_pcl; + sme_cbacks.sme_set_pcl = sme_set_pcl; sme_cbacks.sme_soc_set_dual_mac_config = sme_soc_set_dual_mac_config; sme_cbacks.sme_change_mcc_beacon_interval = @@ -1217,6 +1220,8 @@ QDF_STATUS sme_start(mac_handle_t mac_handle) sme_cbacks.sme_get_ap_channel_from_scan = sme_get_ap_channel_from_scan; sme_cbacks.sme_scan_result_purge = sme_scan_result_purge; + sme_cbacks.sme_rso_start_cb = sme_start_roaming; + sme_cbacks.sme_rso_stop_cb = sme_stop_roaming; status = policy_mgr_register_sme_cb(mac->psoc, &sme_cbacks); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err("Failed to register sme cb with Policy Manager: %d", @@ -6315,7 +6320,8 @@ int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id, * Other status on failure */ QDF_STATUS sme_stop_roaming(mac_handle_t mac_handle, uint8_t session_id, - uint8_t reason, uint32_t requestor) + uint8_t reason, + enum wlan_cm_rso_control_requestor requestor) { QDF_STATUS status; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); @@ -6349,7 +6355,8 @@ QDF_STATUS sme_stop_roaming(mac_handle_t mac_handle, uint8_t session_id, * Other status on failure */ QDF_STATUS sme_start_roaming(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t reason, uint32_t requestor) + uint8_t reason, + enum wlan_cm_rso_control_requestor requestor) { struct mac_context *mac = MAC_CONTEXT(mac_handle); QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -6372,6 +6379,68 @@ QDF_STATUS sme_start_roaming(mac_handle_t mac_handle, uint8_t sessionId, return status; } +void sme_set_pcl_for_first_connected_vdev(mac_handle_t mac_handle, + uint8_t vdev_id) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + uint8_t roam_enabled_vdev_id; + + /* + * Get the vdev id of the STA on which roaming is already + * initialized and set the vdev PCL for that STA vdev if dual + * STA roaming feature is enabled + * If this is the first connected STA vdev, then PDEV pcl will + * be set at csr_roam_switch_to_init. + */ + roam_enabled_vdev_id = csr_get_roam_enabled_sta_sessionid(mac, vdev_id); + + if (wlan_mlme_get_dual_sta_roaming_enabled(mac->psoc) && + roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { + wlan_cm_roam_activate_pcl_per_vdev(mac->psoc, + roam_enabled_vdev_id, + true); + policy_mgr_set_pcl_for_existing_combo(mac->psoc, PM_STA_MODE, + roam_enabled_vdev_id); + } +} + +void sme_clear_and_set_pcl_for_connected_vdev(mac_handle_t mac_handle, + uint8_t vdev_id) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct policy_mgr_pcl_list *msg; + uint8_t roam_enabled_vdev_id; + + /* + * Clear VDEV PCL for other STA vdev when dual sta roaming + * is enabled on disconnection on one STA. + * This is followed by set PDEV pcl to firmware + */ + roam_enabled_vdev_id = csr_get_roam_enabled_sta_sessionid(mac, vdev_id); + + if (wlan_mlme_get_dual_sta_roaming_enabled(mac->psoc) && + roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { + msg = qdf_mem_malloc(sizeof(*msg)); + if (!msg) + return; + + /* + * Here the PCL level should be at vdev level already as this + * is invoked from disconnect handler. Clear the vdev pcl + * for the existing connected STA vdev and this is followed + * by set PDEV pcl. + */ + sme_set_pcl(msg, roam_enabled_vdev_id, true); + qdf_mem_free(msg); + + wlan_cm_roam_activate_pcl_per_vdev(mac->psoc, + roam_enabled_vdev_id, + false); + policy_mgr_set_pcl_for_existing_combo(mac->psoc, PM_STA_MODE, + roam_enabled_vdev_id); + } +} + /* * sme_set_roam_opportunistic_scan_threshold_diff() - * Update Opportunistic Scan threshold diff @@ -12080,40 +12149,52 @@ QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle) /** * sme_get_connected_roaming_vdev_band_mask() - get connected vdev band mask + * @vdev_id: Vdev id * * Return: reg wifi band mask */ -static uint32_t sme_get_connected_roaming_vdev_band_mask(void) +static uint32_t +sme_get_connected_roaming_vdev_band_mask(uint8_t vdev_id) { uint32_t band_mask = REG_BAND_MASK_ALL; struct mac_context *mac = sme_get_mac_context(); struct csr_roam_session *session; - uint8_t session_id; + bool dual_sta_roam_active; if (!mac) { sme_debug("MAC Context is NULL"); return band_mask; } - session_id = csr_get_roam_enabled_sta_sessionid(mac); - if (session_id != WLAN_UMAC_VDEV_ID_MAX) { - session = CSR_GET_SESSION(mac, session_id); - band_mask = BIT(wlan_reg_freq_to_band( - session->connectedProfile.op_freq)); + + session = CSR_GET_SESSION(mac, vdev_id); + if (!session) { + sme_err("Session not found for vdev:%d", vdev_id); return band_mask; } + /* + * If PCL command is PDEV level, only one sta is active. + * So fill the band mask if intra band roaming is enabled + */ + if (!wlan_cm_roam_is_pcl_per_vdev_active(mac->psoc, vdev_id)) { + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac)) + band_mask = BIT(wlan_reg_freq_to_band( + session->connectedProfile.op_freq)); + + return band_mask; + } + + dual_sta_roam_active = + wlan_mlme_get_dual_sta_roaming_enabled(mac->psoc); + if (dual_sta_roam_active) + band_mask = BIT(wlan_reg_freq_to_band( + session->connectedProfile.op_freq)); + return band_mask; } -/* - * sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA - * @mac_handle: Handle returned by macOpen - * @msg: PCL channel list and length structure - * - * Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW - * Return: QDF_STATUS_SUCCESS on successful posting - */ -QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg) +QDF_STATUS sme_set_pcl(struct policy_mgr_pcl_list *msg, uint8_t vdev_id, + bool clear_vdev_pcl) { QDF_STATUS status = QDF_STATUS_SUCCESS; struct mac_context *mac = sme_get_mac_context(); @@ -12131,21 +12212,34 @@ QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg) return QDF_STATUS_E_FAILURE; } + if (!MLME_IS_ROAM_INITIALIZED(mac->psoc, vdev_id)) { + sme_debug("Roam is not initialized on vdev:%d", vdev_id); + return QDF_STATUS_E_FAILURE; + } + req_msg = qdf_mem_malloc(sizeof(*req_msg)); if (!req_msg) return QDF_STATUS_E_NOMEM; - req_msg->band_mask = REG_BAND_MASK_ALL; - if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac)) { - req_msg->band_mask = sme_get_connected_roaming_vdev_band_mask(); - sme_debug("Connected STA band mask%d", req_msg->band_mask); - } + req_msg->band_mask = sme_get_connected_roaming_vdev_band_mask(vdev_id); + sme_debug("Connected STA band mask%d", req_msg->band_mask); + for (i = 0; i < msg->pcl_len; i++) { req_msg->chan_weights.pcl_list[i] = msg->pcl_list[i]; req_msg->chan_weights.weight_list[i] = msg->weight_list[i]; } req_msg->chan_weights.pcl_len = msg->pcl_len; + req_msg->clear_vdev_pcl = clear_vdev_pcl; + + /* + * Set vdev value as WLAN_UMAC_VDEV_ID_MAX, if PDEV level + * PCL command needs to be sent. + */ + if (!wlan_cm_roam_is_pcl_per_vdev_active(mac->psoc, vdev_id)) + vdev_id = WLAN_UMAC_VDEV_ID_MAX; + + req_msg->vdev_id = vdev_id; status = sme_acquire_global_lock(&mac->sme); if (status != QDF_STATUS_SUCCESS) { @@ -12156,11 +12250,11 @@ QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg) /* Serialize the req through MC thread */ message.bodyptr = req_msg; - message.type = SIR_HAL_PDEV_SET_PCL_TO_FW; + message.type = eWNI_SME_ROAM_SEND_SET_PCL_REQ; status = scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, &message); - if (!QDF_IS_STATUS_SUCCESS(status)) { + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &message); + if (QDF_IS_STATUS_ERROR(status)) { sme_err("scheduler_post_msg failed!(err=%d)", status); qdf_mem_free(req_msg); status = QDF_STATUS_E_FAILURE; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 010e3cb804f1..a1bb43ace175 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1225,10 +1225,12 @@ QDF_STATUS csr_update_channel_list(struct mac_context *mac) eCSR_CFG_DOT11_MODE_11AX_ONLY)) pChanList->he_en = true; + pChanList->numChan = num_channel; + mlme_store_fw_scan_channels(mac->psoc, pChanList); + msg.type = WMA_UPDATE_CHAN_LIST_REQ; msg.reserved = 0; msg.bodyptr = pChanList; - pChanList->numChan = num_channel; MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, NO_SESSION, msg.type)); if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, @@ -18413,7 +18415,8 @@ static void csr_update_score_params(struct mac_context *mac_ctx, roam_score_params->min_roam_score_delta; } -uint8_t csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx) +uint8_t +csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx, uint8_t vdev_id) { struct csr_roam_session *session; uint8_t i; @@ -18426,6 +18429,9 @@ uint8_t csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx) session->pCurRoamProfile->csrPersona != QDF_STA_MODE) continue; + if (vdev_id == i) + continue; + if (MLME_IS_ROAM_INITIALIZED(mac_ctx->psoc, i)) return i; } @@ -18512,10 +18518,14 @@ csr_roam_switch_to_init(struct mac_context *mac, uint8_t vdev_id, uint8_t reason) { enum roam_offload_state cur_state; - uint8_t temp_vdev_id; + uint8_t temp_vdev_id, roam_enabled_vdev_id; uint32_t roaming_bitmap; + bool dual_sta_roam_active; QDF_STATUS status; + dual_sta_roam_active = + wlan_mlme_get_dual_sta_roaming_enabled(mac->psoc); + cur_state = mlme_get_roam_state(mac->psoc, vdev_id); switch (cur_state) { case ROAM_DEINIT: @@ -18527,13 +18537,16 @@ csr_roam_switch_to_init(struct mac_context *mac, uint8_t vdev_id, return QDF_STATUS_E_FAILURE; } + if (dual_sta_roam_active) + break; + /* * Disable roaming on the enabled sta if supplicant wants to * enable roaming on this vdev id */ - temp_vdev_id = csr_get_roam_enabled_sta_sessionid(mac); - if ((temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) && - (vdev_id != temp_vdev_id)) { + temp_vdev_id = csr_get_roam_enabled_sta_sessionid( + mac, vdev_id); + if (temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { /* * Roam init state can be requested as part of * initial connection or due to enable from @@ -18564,12 +18577,25 @@ csr_roam_switch_to_init(struct mac_context *mac, uint8_t vdev_id, } status = csr_send_roam_offload_init_msg(mac, vdev_id, true); - if (QDF_IS_STATUS_ERROR(status)) return status; mlme_set_roam_state(mac->psoc, vdev_id, ROAM_INIT); + roam_enabled_vdev_id = + csr_get_roam_enabled_sta_sessionid(mac, vdev_id); + + /* Send PDEV pcl command if only one STA is in connected state + * If there is another STA connection exist, then set the + * PCL type to vdev level + */ + if (roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX && + dual_sta_roam_active) + wlan_cm_roam_activate_pcl_per_vdev(mac->psoc, vdev_id, true); + + /* Set PCL before sending RSO start */ + policy_mgr_set_pcl_for_existing_combo(mac->psoc, PM_STA_MODE, vdev_id); + return QDF_STATUS_SUCCESS; } @@ -18698,7 +18724,6 @@ csr_roam_switch_to_deinit(struct mac_context *mac, uint8_t vdev_id, } status = csr_send_roam_offload_init_msg(mac, vdev_id, false); - if (QDF_IS_STATUS_ERROR(status)) return status; @@ -18779,7 +18804,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, &mac_ctx->roam.neighborRoamInfo[session_id]; struct roam_ext_params *roam_params_dst; struct roam_ext_params *roam_params_src; - uint8_t temp_session_id; bool prev_roaming_state; enum csr_akm_type roam_profile_akm = eCSR_AUTH_TYPE_UNKNOWN; uint32_t fw_akm_bitmap; @@ -18803,14 +18827,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, return QDF_STATUS_E_FAILURE; } - temp_session_id = csr_get_roam_enabled_sta_sessionid(mac_ctx); - if ((temp_session_id != WLAN_UMAC_VDEV_ID_MAX) && - (session_id != temp_session_id)) { - sme_debug("Roam cmd not for session %d on which roaming is enabled", - temp_session_id); - return QDF_STATUS_E_FAILURE; - } - if (session->pCurRoamProfile) roam_profile_akm = session->pCurRoamProfile->AuthType.authType[0]; @@ -19026,7 +19042,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, csr_update_11k_offload_params(mac_ctx, session, req_buf, FALSE); prev_roaming_state = mlme_get_roam_state(mac_ctx->psoc, session_id); - policy_mgr_set_pcl_for_existing_combo(mac_ctx->psoc, PM_STA_MODE); /* Update PER config to FW. No need to update in case of stop command, * FW takes care of stopping this internally @@ -19041,8 +19056,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, __func__); mlme_set_roam_state(mac_ctx->psoc, session_id, prev_roaming_state); - policy_mgr_set_pcl_for_existing_combo(mac_ctx->psoc, - PM_STA_MODE); return QDF_STATUS_E_FAILURE; } /* update the last sent cmd */ @@ -21538,7 +21551,7 @@ csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id) uint32_t count; uint32_t idx; - sta_vdev_id = csr_get_roam_enabled_sta_sessionid(mac); + sta_vdev_id = csr_get_roam_enabled_sta_sessionid(mac, vdev_id); if (sta_vdev_id != WLAN_UMAC_VDEV_ID_MAX) return QDF_STATUS_E_FAILURE; diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 513641a019c4..86595a147ff7 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1484,8 +1484,8 @@ QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma, */ wmi_pcl_chan_weight wma_map_pcl_weights(uint32_t pcl_weight); -QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, - struct set_pcl_req *msg); +QDF_STATUS wma_send_set_pcl_cmd(tp_wma_handle wma_handle, + struct set_pcl_req *msg); QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle, struct policy_mgr_hw_mode *msg); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 28b8f2605b93..a720bc25a4af 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -45,6 +45,8 @@ #include "wma_types.h" #include "lim_api.h" #include "lim_session_utils.h" +#include "wlan_cm_tgt_if_tx_api.h" +#include "wlan_cm_roam_api.h" #include "cds_utils.h" @@ -8759,9 +8761,9 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) wma_set_rssi_monitoring(wma_handle, msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case SIR_HAL_PDEV_SET_PCL_TO_FW: - wma_send_pdev_set_pcl_cmd(wma_handle, - (struct set_pcl_req *)msg->bodyptr); + case SIR_HAL_SET_PCL_TO_FW: + wma_send_set_pcl_cmd(wma_handle, + (struct set_pcl_req *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; case SIR_HAL_PDEV_SET_HW_MODE: @@ -9033,7 +9035,7 @@ wmi_pcl_chan_weight wma_map_pcl_weights(uint32_t pcl_weight) } /** - * wma_send_pdev_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW + * wma_send_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW * @wma_handle: WMA handle * @msg: PCL structure containing the PCL and the number of channels * @@ -9051,8 +9053,8 @@ wmi_pcl_chan_weight wma_map_pcl_weights(uint32_t pcl_weight) * * Return: Success if the cmd is sent successfully to the firmware */ -QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, - struct set_pcl_req *msg) +QDF_STATUS wma_send_set_pcl_cmd(tp_wma_handle wma_handle, + struct set_pcl_req *msg) { uint32_t i; QDF_STATUS status; @@ -9063,6 +9065,15 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, return QDF_STATUS_E_NULL_VALUE; } + /* + * if vdev_id is WLAN_UMAC_VDEV_ID_MAX, then roaming is enabled on + * only one sta, so PDEV PCL command needs to be sent. + * If a valid vdev id is present, then vdev pcl command needs to be + * sent. + */ + if (msg->vdev_id != WLAN_UMAC_VDEV_ID_MAX) + return wlan_cm_roam_send_set_vdev_pcl(wma_handle->psoc, msg); + for (i = 0; i < wma_handle->saved_chan.num_channels; i++) { msg->chan_weights.saved_chan_list[i] = wma_handle->saved_chan.ch_freq_list[i];