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 abf23a1776d9..59785a71121b 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 @@ static struct vdev_mlme_ops sta_mlme_ops; static struct vdev_mlme_ops ap_mlme_ops; +static struct vdev_mlme_ops mon_mlme_ops; static struct mlme_ext_ops ext_ops; bool mlme_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode) @@ -74,6 +75,8 @@ QDF_STATUS mlme_register_vdev_mgr_ops(struct vdev_mlme_obj *vdev_mlme) if (mlme_is_vdev_in_beaconning_mode(vdev->vdev_mlme.vdev_opmode)) vdev_mlme->ops = &ap_mlme_ops; + else if (vdev->vdev_mlme.vdev_opmode == QDF_MONITOR_MODE) + vdev_mlme->ops = &mon_mlme_ops; else vdev_mlme->ops = &sta_mlme_ops; @@ -468,6 +471,7 @@ static QDF_STATUS vdevmgr_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, vdev_mlme->vdev->vdev_objmgr.vdev_id); return wma_ap_mlme_vdev_down_send(vdev_mlme, data_len, data); } + /** * vdevmgr_notify_down_complete() - callback to indicate vdev down is completed * @vdev_mlme: vdev mlme object @@ -844,6 +848,119 @@ static QDF_STATUS ap_vdev_dfs_cac_timer_stop(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_SUCCESS; } +/** + * mon_mlme_vdev_start_restart_send () - send vdev start/restart req + * @vdev_mlme: vdev mlme object + * @data_len: event data length + * @data: event data + * + * This function is called to initiate actions of VDEV start/restart + * + * Return: QDF_STATUS + */ +static QDF_STATUS mon_mlme_vdev_start_restart_send( + struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + mlme_legacy_debug("vdev id = %d", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return lim_mon_mlme_vdev_start_send(vdev_mlme, data_len, data); +} + +/** + * mon_start_continue () - vdev start rsp calback + * @vdev_mlme: vdev mlme object + * @data_len: event data length + * @data: event data + * + * This function is called to handle the VDEV START/RESTART calback + * + * Return: QDF_STATUS + */ +static QDF_STATUS mon_mlme_start_continue(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + mlme_legacy_debug("vdev id = %d", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return wma_mon_mlme_vdev_start_continue(vdev_mlme, data_len, data); +} + +/** + * mon_mlme_vdev_up_send() - callback to send vdev up + * @vdev_mlme: vdev mlme object + * @data_len: event data length + * @data: event data + * + * This function is called to send vdev up req + * + * Return: QDF_STATUS + */ +static QDF_STATUS mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + mlme_legacy_debug("vdev id = %d", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return wma_mon_mlme_vdev_up_send(vdev_mlme, data_len, data); +} + +/** + * mon_mlme_vdev_disconnect_peers() - callback to disconnect all connected peers + * @vdev_mlme: vdev mlme object + * @data_len: event data length + * @data: event data + * + * montior mode no connected peers, only do VDEV state transition. + * + * Return: QDF_STATUS + */ +static QDF_STATUS mon_mlme_vdev_disconnect_peers( + struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + mlme_legacy_debug("vdev id = %d", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return wlan_vdev_mlme_sm_deliver_evt( + vdev_mlme->vdev, + WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE, + 0, NULL); +} + +/** + * mon_mlme_vdev_stop_send() - callback to send stop vdev request + * @vdev_mlme: vdev mlme object + * @data_len: event data length + * @data: event data + * + * This function is called to send stop vdev request + * + * Return: QDF_STATUS + */ +static QDF_STATUS mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + mlme_legacy_debug("vdev id = %d", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return wma_mon_mlme_vdev_stop_send(vdev_mlme, data_len, data); +} + +/** + * mon_mlme_vdev_down_send() - callback to send vdev down req + * @vdev_mlme: vdev mlme object + * @data_len: event data length + * @data: event data + * + * This function is called to send vdev down req + * + * Return: QDF_STATUS + */ +static QDF_STATUS mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + mlme_legacy_debug("vdev id = %d", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return wma_mon_mlme_vdev_down_send(vdev_mlme, data_len, data); +} + /** * struct sta_mlme_ops - VDEV MLME operation callbacks strucutre for sta * @mlme_vdev_start_send: callback to initiate actions of VDEV @@ -934,6 +1051,16 @@ static struct vdev_mlme_ops ap_mlme_ops = { .mlme_vdev_is_newchan_no_cac = ap_mlme_vdev_is_newchan_no_cac, }; +static struct vdev_mlme_ops mon_mlme_ops = { + .mlme_vdev_start_send = mon_mlme_vdev_start_restart_send, + .mlme_vdev_restart_send = mon_mlme_vdev_start_restart_send, + .mlme_vdev_start_continue = mon_mlme_start_continue, + .mlme_vdev_up_send = mon_mlme_vdev_up_send, + .mlme_vdev_disconnect_peers = mon_mlme_vdev_disconnect_peers, + .mlme_vdev_stop_send = mon_mlme_vdev_stop_send, + .mlme_vdev_down_send = mon_mlme_vdev_down_send, +}; + /** * struct mlme_ext_ops - VDEV MLME legacy global callbacks structure * @mlme_vdev_ext_hdl_create: callback to invoke creation of legacy diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 916205bbef8f..f38227e66074 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -5810,7 +5810,7 @@ static struct cdp_me_ops ol_ops_me = { }; static struct cdp_mon_ops ol_ops_mon = { - /* EMPTY FOR MCL */ + .txrx_monitor_record_channel = ol_htt_mon_note_chan, }; static struct cdp_host_stats_ops ol_ops_host_stats = { 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 687e5e2a2858..b2da3afeb8ad 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 @@ -4996,11 +4996,36 @@ static void lim_process_sme_start_beacon_req(struct mac_context *mac, uint32_t * } } +static void lim_mon_change_channel( + struct mac_context *mac_ctx, + struct pe_session *session_entry) +{ + if (wlan_vdev_mlme_get_state(session_entry->vdev) == WLAN_VDEV_S_INIT) + wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev, + WLAN_VDEV_SM_EV_START, + sizeof(*session_entry), + session_entry); + else if (wlan_vdev_mlme_get_state(session_entry->vdev) == + WLAN_VDEV_S_UP) { + mlme_set_chan_switch_in_progress(session_entry->vdev, true); + wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev, + WLAN_VDEV_SM_EV_FW_VDEV_RESTART, + sizeof(*session_entry), + session_entry); + } else { + pe_err("Invalid vdev state to change channel"); + } +} + static void lim_change_channel( struct mac_context *mac_ctx, struct pe_session *session_entry) { + if (session_entry->bssType == eSIR_MONITOR_MODE) + return lim_mon_change_channel(mac_ctx, session_entry); + 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, diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 087cbc859938..86e0e7b4c36c 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -8097,6 +8097,35 @@ QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_SUCCESS; } +QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + struct mac_context *mac_ctx; + struct pe_session *session = (struct pe_session *)data; + + if (!data) { + pe_err("data is NULL"); + return QDF_STATUS_E_INVAL; + } + + mac_ctx = session->mac_ctx; + if (!mac_ctx) { + pe_err("mac_ctx is NULL"); + return QDF_STATUS_E_INVAL; + } + + lim_set_channel(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; +} + void lim_send_start_bss_confirm(struct mac_context *mac_ctx, tLimMlmStartCnf *start_cnf) { diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 1d1d1c8bfd8d..c64e3a202996 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -1682,6 +1682,20 @@ QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); +/** + * lim_mon_mlme_vdev_start_send() - Invokes VDEV start operation + * @vdev_mlme_obj: VDEV MLME comp object + * @data_len: data size + * @data: event data + * + * API invokes VDEV start operation + * + * Return: SUCCESS on successful completion of start operation + * FAILURE, if it fails due to any + */ +QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *event); + #ifdef CRYPTO_SET_KEY_CONVERGED static inline bool lim_is_set_key_req_converged(void) { diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index c9fd089d9b8f..d10fc610f855 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -452,7 +452,7 @@ bool wma_get_hidden_ssid_restart_in_progress(struct wma_txrx_node *iface); bool wma_get_channel_switch_in_progress(struct wma_txrx_node *iface); /** - * wma_sta_mlme_vdev_start_continue - VDEV start response handling + * wma_sta_mlme_vdev_start_continue() - VDEV start response handling * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -466,7 +466,7 @@ QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_sta_mlme_vdev_roam_notify - VDEV roam notify handling + * wma_sta_mlme_vdev_roam_notify() - VDEV roam notify handling * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -480,7 +480,7 @@ QDF_STATUS wma_sta_mlme_vdev_roam_notify(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_ap_mlme_vdev_start_continue - VDEV start response handling + * wma_ap_mlme_vdev_start_continue() - VDEV start response handling * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -494,7 +494,7 @@ QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_sta_vdev_up_send - Send VDEV UP command + * wma_sta_vdev_up_send() - Send VDEV UP command * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -508,7 +508,7 @@ QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_mlme_vdev_stop_continue - VDEV stop response handling + * wma_mlme_vdev_stop_continue() - VDEV stop response handling * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -522,7 +522,7 @@ QDF_STATUS wma_mlme_vdev_stop_continue(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_ap_mlme_vdev_down_send - VDEV down operation + * wma_ap_mlme_vdev_down_send() - VDEV down operation * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -536,7 +536,7 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_mlme_vdev_notify_down_complete - VDEV init state transition + * wma_mlme_vdev_notify_down_complete() - VDEV init state transition * notification * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size @@ -552,7 +552,7 @@ wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_ap_mlme_vdev_stop_start_send - handle vdev stop during start req + * wma_ap_mlme_vdev_stop_start_send() - handle vdev stop during start req * @vdev_mlme_obj: VDEV MLME comp object * @type: restart req or start req * @data_len: data size @@ -567,7 +567,7 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); /** - * wma_sta_mlme_vdev_down_send - VDEV down operation + * wma_sta_mlme_vdev_down_send() - VDEV down operation * @vdev_mlme_obj: VDEV MLME comp object * @data_len: data size * @data: event data @@ -580,6 +580,62 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS wma_sta_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); +/** + * wma_mon_mlme_vdev_start_continue() - VDEV start response handling + * @vdev_mlme_obj: VDEV MLME comp object + * @data_len: data size + * @data: event data + * + * API invokes VDEV start response actions + * + * Return: SUCCESS on successful completion of start response operation + * FAILURE, if it fails due to any + */ +QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data); + +/** + * wma_mon_mlme_vdev_up_send() - Send VDEV UP command + * @vdev_mlme_obj: VDEV MLME comp object + * @data_len: data size + * @data: event data + * + * API invokes VDEV UP Command + * + * Return: SUCCESS on successful completion of start response operation + * FAILURE, if it fails due to any + */ +QDF_STATUS wma_mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data); + +/** + * wma_mon_mlme_vdev_stop_send() - VDEV stop operation + * @vdev_mlme_obj: VDEV MLME comp object + * @data_len: data size + * @data: event data + * + * API invokes VDEV stop operation + * + * Return: SUCCESS on successful completion of VDEV stop operation + * FAILURE, if it fails due to any + */ +QDF_STATUS wma_mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data); + +/** + * wma_mon_mlme_vdev_down_send() - VDEV down operation + * @vdev_mlme_obj: VDEV MLME comp object + * @data_len: data size + * @data: event data + * + * API invokes VDEV down operation + * + * Return: SUCCESS on successful completion of VDEV down operation + * FAILURE, if it fails due to any + */ +QDF_STATUS wma_mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data); + #ifdef FEATURE_WLM_STATS /** * typedef wma_wlm_stats_cb() - Callback function for WLM stats diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 915c501ce222..e5b8dfdfb4c0 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -735,14 +735,13 @@ wma_release_vdev_ref(struct wma_txrx_node *iface) static void wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma, uint8_t vdev_id) { - if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { - WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__); - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_STOP); - } + struct wma_txrx_node *iface; - if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS) - WMA_LOGE("Failed to send vdev down cmd: vdev %d", vdev_id); + iface = &wma->interfaces[vdev_id]; + wlan_vdev_mlme_sm_deliver_evt(iface->vdev, + WLAN_VDEV_SM_EV_DOWN, + 0, NULL); + iface->vdev_active = false; } static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, @@ -1037,8 +1036,10 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, pdel_sta_self_req_param, generateRsp); } - if (QDF_IS_STATUS_SUCCESS(status)) + if (QDF_IS_STATUS_SUCCESS(status) && + iface->type != WMI_VDEV_TYPE_MONITOR) iface->vdev_active = false; + return status; send_fail_rsp: @@ -2636,6 +2637,7 @@ wma_handle_vdev_stop_rsp(tp_wma_handle wma, struct wma_txrx_node *iface; iface = &wma->interfaces[resp_event->vdev_id]; + return wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_STOP_RESP, sizeof(*resp_event), resp_event); diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index ac8104d9ca07..18d30d39c4f2 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -76,6 +76,7 @@ #include "wlan_mlme_api.h" #include #include +#include #ifdef FEATURE_WLAN_EXTSCAN #define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED @@ -3517,12 +3518,6 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) } } - if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() && - wma_is_vdev_up(vdev_id)) { - WMA_LOGD("%s: setting channel switch to true for vdev_id:%d", - __func__, req.vdev_id); - } - msg = wma_fill_vdev_req(wma, req.vdev_id, WMA_CHNL_SWITCH_REQ, WMA_TARGET_REQ_TYPE_VDEV_START, params, WMA_VDEV_START_REQUEST_TIMEOUT); @@ -3543,9 +3538,12 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) goto send_resp; } - /* This is temporary, should be removed */ - if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) - ol_htt_mon_note_chan(pdev, req.chan); + /* + * Record monitor mode channel here in case HW + * indicate RX PPDU TLV with invalid channel number. + */ + if (intr[vdev_id].type == WMI_VDEV_TYPE_MONITOR) + cdp_record_monitor_chan_num(soc, pdev, req.chan); return; send_resp: diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 4ceb968d2738..393b4e72bafb 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -5064,6 +5064,103 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, return wma_vdev_send_start_resp(wma, bss_params); } +QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev)) + mlme_set_chan_switch_in_progress(vdev_mlme->vdev, false); + + wlan_vdev_mlme_sm_deliver_evt(vdev_mlme->vdev, + WLAN_VDEV_SM_EV_START_SUCCESS, + data_len, + data); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wma_mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + struct vdev_up_params param; + uint8_t vdev_id; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + QDF_STATUS status; + struct wma_txrx_node *iface; + + if (!wma) { + WMA_LOGE("%s wma handle is NULL", __func__); + return QDF_STATUS_E_INVAL; + } + vdev_id = wlan_vdev_get_id(vdev_mlme->vdev); + param.vdev_id = vdev_id; + iface = &wma->interfaces[vdev_id]; + + status = wma_send_vdev_up_to_fw(wma, ¶m, iface->bssid); + + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM", + __func__, vdev_id, iface->bssid); + + wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, + data, 0); + + return status; +} + +QDF_STATUS wma_mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + uint8_t vdev_id; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + QDF_STATUS status; + + if (!wma) { + WMA_LOGE("%s wma handle is NULL", __func__); + return QDF_STATUS_E_INVAL; + } + vdev_id = wlan_vdev_get_id(vdev_mlme->vdev); + + status = wma_send_vdev_stop_to_fw(wma, vdev_id); + + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("%s: Failed to send vdev stop cmd: vdev %d", + __func__, vdev_id); + + wlan_vdev_mlme_sm_deliver_evt(vdev_mlme->vdev, + WLAN_VDEV_SM_EV_MLME_DOWN_REQ, + 0, + NULL); + + return status; +} + +QDF_STATUS wma_mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, + uint16_t data_len, void *data) +{ + uint8_t vdev_id; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + QDF_STATUS status; + + if (!wma) { + WMA_LOGE("%s wma handle is NULL", __func__); + return QDF_STATUS_E_INVAL; + } + vdev_id = wlan_vdev_get_id(vdev_mlme->vdev); + + status = wma_send_vdev_down_to_fw(wma, vdev_id); + + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("%s: Failed to send vdev down cmd: vdev %d", + __func__, vdev_id); + + wlan_vdev_mlme_sm_deliver_evt(vdev_mlme->vdev, + WLAN_VDEV_SM_EV_DOWN_COMPLETE, + 0, + NULL); + + return status; +} + #ifdef FEATURE_WLM_STATS int wma_wlm_stats_req(int vdev_id, uint32_t bitmask, uint32_t max_size, wma_wlm_stats_cb cb, void *cookie)