diff --git a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h index d97ecff05dd6..bf69395737ba 100644 --- a/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h +++ b/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h @@ -23,8 +23,20 @@ #define _WLAN_MLME_VDEV_MGR_INT_API_H_ #ifdef CONFIG_VDEV_SM +#include #include "include/wlan_vdev_mlme.h" +/** + * struct mlme_legacy_priv - VDEV MLME legacy priv object + * @chan_switch_in_progress: flag to indicate that channel switch is in progress + * @hidden_ssid_restart_in_progress: flag to indicate hidden ssid restart is + * in progress + */ +struct mlme_legacy_priv { + bool chan_switch_in_progress; + bool hidden_ssid_restart_in_progress; +}; + /** * mlme_register_vdev_mgr_ops() - Register vdev mgr ops * @vdev_mlme: vdev mlme object @@ -43,5 +55,24 @@ QDF_STATUS mlme_register_vdev_mgr_ops(void *mlme); * Return: QDF_STATUS */ QDF_STATUS mlme_unregister_vdev_mgr_ops(struct vdev_mlme_obj *vdev_mlme); + +/** + * ap_mlme_set_chan_switch_in_progress() - set mlme priv restart in progress + * @vdev: vdev pointer + * @val: value to be set + * + * Return: QDF_STATUS + */ +QDF_STATUS ap_mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev, + bool val); + +/** + * ap_mlme_get_chan_switch_in_progress() - get mlme priv restart in progress + * @vdev: vdev pointer + * + * Return: value of mlme priv restart in progress + */ +bool ap_mlme_get_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev); + #endif #endif 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 10e06d600ca8..0c2842984bd2 100644 --- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -18,7 +18,6 @@ /** * DOC: define internal APIs related to the mlme component */ -#include #include "wlan_mlme_main.h" #include "wlan_mlme_vdev_mgr_interface.h" #include "lim_utils.h" @@ -460,20 +459,19 @@ static QDF_STATUS ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme, } /** - * sap_mlme_vdev_restart_send() a callback to send vdev restart + * ap_mlme_vdev_restart_send() a callback to send vdev restart * @vdev_mlme: vdev mlme object - * @event_data_len: event data length - * @event_data: event data + * @data_len: event data length + * @data: event data * * This function is called to initiate and send vdev restart req * * Return: QDF_STATUS */ static QDF_STATUS ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, - void *event_data) + uint16_t data_len, void *data) { - return QDF_STATUS_SUCCESS; + return lim_ap_mlme_vdev_restart_send(vdev_mlme, data_len, data); } static QDF_STATUS ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, @@ -484,15 +482,72 @@ static QDF_STATUS ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_SUCCESS; } -static -QDF_STATUS ap_mlme_vdev_legacy_hdl_create(struct vdev_mlme_obj *vdev_mlme) +QDF_STATUS ap_mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev, + bool val) { + struct vdev_mlme_obj *vdev_mlme; + struct mlme_legacy_priv *mlme_priv; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr; + + mlme_priv->chan_switch_in_progress = val; + return QDF_STATUS_SUCCESS; } +bool ap_mlme_get_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *vdev_mlme; + struct mlme_legacy_priv *mlme_priv; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_err("vdev component object is NULL"); + return false; + } + + mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr; + + return mlme_priv->chan_switch_in_progress; +} + +/** + * ap_mlme_vdev_legacy_hdl_create () - Create sap mlme legacy priv object + * @vdev_mlme: vdev mlme object + * + * Return: QDF_STATUS + */ +static +QDF_STATUS ap_mlme_vdev_legacy_hdl_create(struct vdev_mlme_obj *vdev_mlme) +{ + vdev_mlme->legacy_vdev_ptr = + qdf_mem_malloc(sizeof(struct mlme_legacy_priv)); + if (!vdev_mlme->legacy_vdev_ptr) { + mlme_err("failed to allocate meory for legacy_vdev_ptr"); + return QDF_STATUS_E_NOMEM; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * ap_mlme_vdev_legacy_hdl_destroy () - Destroy sap mlme legacy priv object + * @vdev_mlme: vdev mlme object + * + * Return: QDF_STATUS + */ static QDF_STATUS ap_mlme_vdev_legacy_hdl_destroy(struct vdev_mlme_obj *vdev_mlme) { + qdf_mem_free(vdev_mlme->legacy_vdev_ptr); + vdev_mlme->legacy_vdev_ptr = NULL; + return QDF_STATUS_SUCCESS; } diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 6f916942b84e..cd535ca4ee2d 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -229,6 +229,8 @@ enum eWniMsgTypes { eWNI_SME_SET_ADDBA_ACCEPT, eWNI_SME_UPDATE_EDCA_PROFILE, WNI_SME_UPDATE_MU_EDCA_PARAMS, + eWNI_SME_CSA_RESTART_REQ, + eWNI_SME_CSA_RESTART_RSP, eWNI_SME_MSG_TYPES_END }; diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 113afcc5098c..edc3fc898984 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -561,6 +561,8 @@ typedef struct sPESession /* Added to Support BT-AMP */ uint8_t peer_twt_responder; #endif bool enable_session_twt_support; + uint32_t cac_duration_ms; + uint32_t dfs_regdomain; } tPESession, *tpPESession; struct session_params { diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index ab698a4af549..ebcc04eda9cc 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -2080,6 +2080,11 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx, qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; +#ifdef CONFIG_VDEV_SM + case eWNI_SME_CSA_RESTART_REQ: + lim_send_csa_restart_req(mac_ctx, msg->bodyval); + break; +#endif default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; 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 be20acb6dbb1..b83d00737671 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 @@ -5024,6 +5024,9 @@ static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx, ch_change_req->targetChannel; session_entry->limRFBand = lim_get_rf_band(session_entry->currentOperChannel); + session_entry->cac_duration_ms = ch_change_req->cac_duration_ms; + session_entry->dfs_regdomain = ch_change_req->dfs_regdomain; + session_entry->maxTxPower = max_tx_pwr; /* Update the global beacon filter */ lim_update_bcn_probe_filter(mac_ctx, session_entry); @@ -5045,6 +5048,23 @@ static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx, qdf_mem_copy(&session_entry->extRateSet, &ch_change_req->extended_rateset, sizeof(session_entry->extRateSet)); + +#ifdef CONFIG_VDEV_SM + ap_mlme_set_chan_switch_in_progress(session_entry->vdev, true); + if (wlan_vdev_mlme_get_state(session_entry->vdev) == + WLAN_VDEV_S_DFS_CAC_WAIT) + wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev, + WLAN_VDEV_SM_EV_RADAR_DETECTED, + sizeof(*session_entry), + session_entry); + else + wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev, + WLAN_VDEV_SM_EV_CSA_COMPLETE, + sizeof(*session_entry), + session_entry); + + +#else lim_set_channel(mac_ctx, ch_change_req->targetChannel, session_entry->ch_center_freq_seg0, session_entry->ch_center_freq_seg1, @@ -5052,6 +5072,7 @@ static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx, max_tx_pwr, session_entry->peSessionId, ch_change_req->cac_duration_ms, ch_change_req->dfs_regdomain); +#endif } /****************************************************************************** @@ -6154,3 +6175,21 @@ void lim_process_obss_color_collision_info(tpAniSirGlobal mac_ctx, } } #endif + +#ifdef CONFIG_VDEV_SM +void lim_send_csa_restart_req(tpAniSirGlobal mac_ctx, uint8_t vdev_id) +{ + tpPESession session; + + session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id); + + if (!session) { + pe_err("session not found for vdev id %d", vdev_id); + return; + } + + wlan_vdev_mlme_sm_deliver_evt(session->vdev, + WLAN_VDEV_SM_EV_CSA_RESTART, + sizeof(*session), session); +} +#endif diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index cdc36065fd61..6a7f87bf8498 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -2374,7 +2374,7 @@ lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac, if (!is_ch_dfs) { if (channelId == psessionEntry->currentOperChannel) { lim_apply_configuration(pMac, psessionEntry); - lim_send_beacon_ind(pMac, psessionEntry); + lim_send_beacon(pMac, psessionEntry); } else { pe_debug("Failed to Transmit Beacons on channel: %d after AP channel change response", psessionEntry->bcnLen); diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 7031a910617d..489a2a1ea694 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -1083,6 +1083,16 @@ void lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx, */ void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx, struct scheduler_msg *msg); + +/** + * lim_send_csa_restart_req() - send csa restart req + * @mac_ctx Pointer to Global MAC structure + * @vdev_id: vdev id + * + * Return: None + */ +void lim_send_csa_restart_req(tpAniSirGlobal mac_ctx, uint8_t vdev_id); + /** * lim_process_mlm_start_req() - process MLM_START_REQ message * diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 57bf7efdbdda..3b93acd482ff 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -8463,6 +8463,21 @@ QDF_STATUS lim_ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_SUCCESS; } +static inline void lim_send_csa_restart_resp(tpAniSirGlobal mac_ctx, + tpPESession session) +{ + struct scheduler_msg msg = {0}; + QDF_STATUS status; + + msg.type = eWNI_SME_CSA_RESTART_RSP; + msg.bodyptr = NULL; + msg.bodyval = session->smeSessionId; + + status = scheduler_post_msg(QDF_MODULE_ID_SME, &msg); + if (QDF_IS_STATUS_ERROR(status)) + sme_err("Failed to post eWNI_SME_CSA_RESTART_RSP"); +} + QDF_STATUS lim_ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme, enum beacon_update_op op, uint16_t data_len, void *data) @@ -8473,11 +8488,12 @@ QDF_STATUS lim_ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme, pe_err("event_data is NULL"); return QDF_STATUS_E_INVAL; } + session = (tpPESession)data; - if (op == BEACON_INIT) { - session = (tpPESession)data; + if (op == BEACON_INIT) lim_send_beacon_ind(session->mac_ctx, session); - } + else if (op == BEACON_CSA) + lim_send_csa_restart_resp(session->mac_ctx, session); return QDF_STATUS_SUCCESS; } @@ -8518,6 +8534,27 @@ QDF_STATUS lim_ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme, return lim_send_vdev_stop((tpPESession)data); } +QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + tpPESession session = (tpPESession)data; + + if (!data) { + pe_err("data is NULL"); + return QDF_STATUS_E_INVAL; + } + + lim_set_channel(session->mac_ctx, session->currentOperChannel, + session->ch_center_freq_seg0, + session->ch_center_freq_seg1, + session->ch_width, + session->maxTxPower, session->peSessionId, + session->cac_duration_ms, + session->dfs_regdomain); + + return QDF_STATUS_SUCCESS; +} + #else void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session) diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 0ac4fd6ee9f5..6e5fc3deefb2 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -37,6 +37,7 @@ #include "lim_timer_utils.h" #include "lim_trace.h" #include "include/wlan_vdev_mlme.h" +#include "wlan_mlme_vdev_mgr_interface.h" typedef enum { ONE_BYTE = 1, @@ -1566,6 +1567,21 @@ QDF_STATUS lim_ap_mlme_vdev_disconnect_peers(struct vdev_mlme_obj *vdev_mlme, */ QDF_STATUS lim_ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); + +/** + * lim_ap_mlme_vdev_restart_send - Invokes VDEV restart operation + * @vdev_mlme_obj: VDEV MLME comp object + * @data_len: data size + * @data: event data + * + * API invokes VDEV restart operation + * + * Return: SUCCESS on successful completion of restart operation + * FAILURE, if it fails due to any + */ +QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data); + #endif #endif /* __LIM_UTILS_H */ 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 34e48e560aa6..b0e08bb7884b 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 @@ -378,6 +378,8 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_TRIGGER_SAE); CASE_RETURN_STRING(eWNI_SME_SEND_MGMT_FRAME_TX); CASE_RETURN_STRING(eWNI_SME_SEND_SAE_MSG); + CASE_RETURN_STRING(eWNI_SME_CSA_RESTART_REQ); + CASE_RETURN_STRING(eWNI_SME_CSA_RESTART_RSP); CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END); default: return (uint8_t *) "UNKNOWN"; diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index ed8ba5e10c79..a4588712063b 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -1191,6 +1191,14 @@ wlansap_roam_callback(void *ctx, struct csr_roam_info *csr_roam_info, wlansap_roam_process_dfs_radar_found(mac_ctx, sap_ctx, &qdf_ret_status); break; + case eCSR_ROAM_RESULT_CSA_RESTART_RSP: + qdf_ret_status = wlansap_dfs_send_csa_ie_request(sap_ctx); + + if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, + FL("CSR roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP %d"), + roam_result); + break; case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS: wlansap_roam_process_dfs_chansw_update(hal, sap_ctx, &qdf_ret_status); diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index b4b7bfee9223..02cd9697e659 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -2262,7 +2262,11 @@ sap_fsm_state_init(struct sap_context *sap_ctx, QDF_TRACE_LEVEL_ERROR, FL("sap_goto_starting failed")); } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { -#ifndef CONFIG_VDEV_SM +#ifdef CONFIG_VDEV_SM + sap_ctx->fsm_state = SAP_STARTING; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, + FL("from state SAP_INIT => SAP_STARTING")); +#else /* * No need of state check here, caller is expected to perform * the checks before sending the event @@ -2681,12 +2685,19 @@ static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, QDF_TRACE_LEVEL_INFO_MED, FL("sapdfs: Sending CSAIE for sapctx[%pK]"), temp_sap_ctx); +#ifdef CONFIG_VDEV_SM + qdf_status = sme_csa_restart(mac_ctx, + temp_sap_ctx->sessionId); +#else qdf_status = wlansap_dfs_send_csa_ie_request(temp_sap_ctx); +#endif } } - } else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) { + } +#ifndef CONFIG_VDEV_SM + else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) { enum QDF_OPMODE persona; if (!sap_ctx) { @@ -2704,7 +2715,9 @@ static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona)) qdf_status = wlansap_dfs_send_csa_ie_request(sap_ctx); - } else { + } +#endif + else { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("in state %s, invalid event msg %d"), "SAP_STARTED", msg); diff --git a/core/sap/src/sap_fsm_ext.h b/core/sap/src/sap_fsm_ext.h index 8f4b68fd7bd7..e3a37ab81e91 100644 --- a/core/sap/src/sap_fsm_ext.h +++ b/core/sap/src/sap_fsm_ext.h @@ -42,8 +42,9 @@ typedef enum { eSAP_DFS_CHANNEL_CAC_END, eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START, eSAP_OPERATING_CHANNEL_CHANGED, +#ifndef CONFIG_VDEV_SM eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START, - +#endif eSAP_NO_MSG } eSapMsg_t; diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 58fac92e4f8a..a3a68a51175c 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1264,8 +1264,9 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext, enum phy_ch_width target_bw, bool strict) { - +#ifndef CONFIG_VDEV_SM tWLAN_SAPEvent sapEvent; +#endif tpAniSirGlobal pMac = NULL; void *hHal = NULL; bool valid; @@ -1394,7 +1395,9 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext, pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; sap_cac_reset_notify(hHal); - +#ifdef CONFIG_VDEV_SM + sme_csa_restart(hHal, sapContext->sessionId); +#else /* * Post the eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START * to SAP state machine to process the channel @@ -1407,7 +1410,7 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext, sapEvent.u2 = 0; sap_fsm(sapContext, &sapEvent); - +#endif } else { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, "%s: Failed to request Channel Change, since SAP is not in SAP_STARTED state", diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 2d7502a68020..f84936f9c7cc 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -571,6 +571,7 @@ typedef enum { eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND, eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS, eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE, + eCSR_ROAM_RESULT_CSA_RESTART_RSP, eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND, diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 169c17ab62c3..8830d71c3246 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -875,6 +875,18 @@ QDF_STATUS sme_roam_channel_change_req(tHalHandle hHal, QDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal, struct qdf_mac_addr bssid, uint8_t dfsCacWaitStatus); + +#ifdef CONFIG_VDEV_SM +/** + * sme_csa_restart() - request CSA IE transmission from PE + * @mac_ctx: mac context + * @session_id: SAP session id + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id); +#endif + QDF_STATUS sme_roam_csa_ie_request(tHalHandle hHal, struct qdf_mac_addr bssid, uint8_t targetChannel, uint8_t csaIeReqd, struct ch_params *ch_params); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index fe9ac8753031..dc84e7bab470 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1319,6 +1319,16 @@ static QDF_STATUS dfs_msg_processor(tpAniSirGlobal mac, session_id); break; } + case eWNI_SME_CSA_RESTART_RSP: + { + session_id = msg->bodyval; + roam_status = 0; + roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP; + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "sapdfs: Received eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_REQ vdevid%d", + session_id); + break; + } default: { sme_err("Invalid DFS message: 0x%x", msg->type); @@ -2108,6 +2118,7 @@ QDF_STATUS sme_process_msg(tpAniSirGlobal pMac, struct scheduler_msg *pMsg) case eWNI_SME_DFS_RADAR_FOUND: case eWNI_SME_DFS_CAC_COMPLETE: case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: + case eWNI_SME_CSA_RESTART_RSP: status = dfs_msg_processor(pMac, pMsg); qdf_mem_free(pMsg->bodyptr); break; @@ -10466,6 +10477,21 @@ QDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal, struct qdf_mac_addr bssid, return status; } +#ifdef CONFIG_VDEV_SM +QDF_STATUS sme_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + status = sme_acquire_global_lock(&mac_ctx->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + status = csr_csa_restart(mac_ctx, session_id); + sme_release_global_lock(&mac_ctx->sme); + } + + return status; +} +#endif + /** * sme_roam_csa_ie_request() - request CSA IE transmission from PE * @hHal: handle returned by mac_open diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index a80a0ec637b6..9cea05318628 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -20909,6 +20909,25 @@ QDF_STATUS csr_send_ext_change_channel(tpAniSirGlobal mac_ctx, uint32_t channel, return status; } +#ifdef CONFIG_VDEV_SM +QDF_STATUS csr_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id) +{ + QDF_STATUS status; + struct scheduler_msg message = {0}; + + /* Serialize the req through MC thread */ + message.bodyval = session_id; + message.type = eWNI_SME_CSA_RESTART_REQ; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &message); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("scheduler_post_msg failed!(err=%d)", status); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} +#endif + /** * csr_roam_send_chan_sw_ie_request() - Request to transmit CSA IE * @mac_ctx: Global MAC context diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 7d2dfe85fc18..fe7a6b6d5e68 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -999,6 +999,17 @@ void csr_clear_votes_for_country_info(tpAniSirGlobal pMac); QDF_STATUS csr_send_ext_change_channel(tpAniSirGlobal mac_ctx, uint32_t channel, uint8_t session_id); +#ifdef CONFIG_VDEV_SM +/** + * csr_csa_start() - request CSA IE transmission from PE + * @mac_ctx: handle returned by mac_open + * @session_id: SAP session id + * + * Return: QDF_STATUS + */ +QDF_STATUS csr_csa_restart(tpAniSirGlobal mac_ctx, uint8_t session_id); +#endif + #ifdef QCA_HT_2040_COEX QDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId, diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 2144d3436a19..c6f54d495814 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -355,6 +355,7 @@ const char *get_e_csr_roam_result_str(eCsrRoamResult val) CASE_RETURN_STR(eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND); CASE_RETURN_STR(eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS); CASE_RETURN_STR(eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_CSA_RESTART_RSP); CASE_RETURN_STR(eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS); CASE_RETURN_STR(eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND); CASE_RETURN_STR(eCSR_ROAM_RESULT_NDI_CREATE_RSP); diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index af8d39755154..d451d13b2b43 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -34,6 +34,7 @@ #include "wma_sar_public_structs.h" #include #include "include/wlan_vdev_mlme.h" +#include "wlan_mlme_vdev_mgr_interface.h" typedef void *WMA_HANDLE; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 9dd0521d1d18..aa2448aa8f7d 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1305,9 +1305,14 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, &iface->beacon_filter); } } - +#ifdef CONFIG_VDEV_SM + wlan_vdev_mlme_sm_deliver_evt(iface->vdev, + WLAN_VDEV_SM_EV_RESTART_RESP, + sizeof(*params), params); +#else wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, (void *)params, 0); +#endif } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) { tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data; diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index a1f7d20126d2..4b2cd063e4c4 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -4815,7 +4815,18 @@ wma_ap_vdev_send_start_resp(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data) { - return wma_ap_vdev_send_start_resp(vdev_mlme, data); + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (ap_mlme_get_chan_switch_in_progress(vdev_mlme->vdev)) { + wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, + data, 0); + ap_mlme_set_chan_switch_in_progress(vdev_mlme->vdev, false); + } else { + status = wma_ap_vdev_send_start_resp(vdev_mlme, data); + } + + return status; } QDF_STATUS wma_ap_mlme_vdev_stop_continue(struct vdev_mlme_obj *vdev_mlme,