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 aa5987cf54..8a5c275ec5 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 @@ -606,6 +606,40 @@ static inline void policy_mgr_change_sap_channel_with_csa( void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t vdev_id); + +/** + * policy_mgr_set_pcl_for_connected_vdev() - Set the PCL for connected vdevs + * @psoc: PSOC object information + * @vdev_id: Vdev Id + * @clear_pcl: option to clear the PCL first before setting the new one + * + * This API will set the preferred channel list for other connected vdevs aside + * from the calling function's vdev + * + * Context: Any kernel thread + * Return: None + */ +void policy_mgr_set_pcl_for_connected_vdev(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool clear_pcl); + +/** + * policy_mgr_set_pcl() - Set preferred channel list in the FW + * @psoc: PSOC object information + * @msg: message containing preferred channel list information + * @vdev_id: Vdev Id + * @clear_vdev_pcl: clear PCL flag + * + * Sends the set pcl command and PCL info to FW + * + * Context: Any kernel thread + * Return: QDF_STATUS_SUCCESS on successful posting, fail status in any other + * case + */ +QDF_STATUS policy_mgr_set_pcl(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_pcl_list *msg, + uint8_t vdev_id, + bool clear_vdev_pcl); + /** * policy_mgr_incr_active_session() - increments the number of active sessions * @psoc: PSOC object information @@ -1367,7 +1401,6 @@ 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_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 @@ -1379,8 +1412,6 @@ 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_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, 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 e6133113f4..5c58276771 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 @@ -29,6 +29,9 @@ #include "qdf_types.h" #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" +#include "wlan_mlme_api.h" +#include "wlan_cm_roam_api.h" +#include "wlan_mlme_ucfg_api.h" #define POLICY_MGR_MAX_CON_STRING_LEN 100 @@ -1391,12 +1394,159 @@ void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc, /* Send PCL only if policy_mgr_pdev_get_pcl returned success */ if (QDF_IS_STATUS_SUCCESS(status)) { - status = pm_ctx->sme_cbacks.sme_set_pcl(&pcl, vdev_id, false); + status = policy_mgr_set_pcl(psoc, &pcl, vdev_id, false); if (QDF_IS_STATUS_ERROR(status)) - policy_mgr_err("Send set PCL to SME failed"); + policy_mgr_err("Send set PCL to policy mgr failed"); } } +void policy_mgr_set_pcl_for_connected_vdev(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool clear_pcl) +{ + struct policy_mgr_pcl_list msg = { {0} }; + 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. + */ + roam_enabled_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(psoc, + vdev_id); + + if (wlan_mlme_get_dual_sta_roaming_enabled(psoc) && + roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX) { + if (clear_pcl) { + /* + * 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. + */ + policy_mgr_set_pcl(psoc, &msg, + roam_enabled_vdev_id, true); + wlan_cm_roam_activate_pcl_per_vdev(psoc, + roam_enabled_vdev_id, + false); + } else { + wlan_cm_roam_activate_pcl_per_vdev(psoc, + roam_enabled_vdev_id, + true); + } + policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, + roam_enabled_vdev_id); + } +} + +/** + * policy_mgr_get_connected_roaming_vdev_band_mask() - get connected vdev + * band mask + * @psoc: PSOC object + * @vdev_id: Vdev id + * + * Return: reg wifi band mask + */ +static uint32_t +policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + uint32_t band_mask = REG_BAND_MASK_ALL; + struct wlan_objmgr_vdev *vdev; + bool dual_sta_roam_active; + struct wlan_channel *chan; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_POLICY_MGR_ID); + if (!vdev) { + policy_mgr_err("vdev is NULL"); + return 0; + } + + chan = wlan_vdev_get_active_channel(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + if (!chan) { + policy_mgr_err("no active channel"); + return 0; + } + + /* + * 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(psoc, vdev_id)) { + if (ucfg_mlme_is_roam_intra_band(psoc)) + band_mask = BIT(wlan_reg_freq_to_band(chan->ch_freq)); + + return band_mask; + } + + dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc); + if (dual_sta_roam_active) + band_mask = BIT(wlan_reg_freq_to_band(chan->ch_freq)); + + return band_mask; +} + +QDF_STATUS policy_mgr_set_pcl(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_pcl_list *msg, + uint8_t vdev_id, + bool clear_vdev_pcl) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct scheduler_msg message = {0}; + struct set_pcl_req *req_msg; + uint32_t i; + + if (!msg) { + policy_mgr_err("msg is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (!MLME_IS_ROAM_INITIALIZED(psoc, vdev_id)) { + policy_mgr_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 = + policy_mgr_get_connected_roaming_vdev_band_mask(psoc, vdev_id); + policy_mgr_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(psoc, vdev_id)) + vdev_id = WLAN_UMAC_VDEV_ID_MAX; + + req_msg->vdev_id = vdev_id; + + /* Serialize the req through MC thread */ + message.bodyptr = req_msg; + message.type = SIR_HAL_SET_PCL_TO_FW; + status = scheduler_post_message(QDF_MODULE_ID_POLICY_MGR, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, &message); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("scheduler_post_msg failed!(err=%d)", status); + qdf_mem_free(req_msg); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} + static uint32_t pm_get_vdev_id_of_first_conn_idx(struct wlan_objmgr_psoc *psoc) { uint32_t conn_index = 0, vdev_id = 0; 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 acc68ef001..accaa12848 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 @@ -672,8 +672,6 @@ 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_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 = diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 4885fe7543..1d4dd6d132 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -1302,6 +1302,14 @@ ucfg_mlme_set_lfr_enabled(struct wlan_objmgr_psoc *psoc, bool val); QDF_STATUS ucfg_mlme_is_roam_prefer_5ghz(struct wlan_objmgr_psoc *psoc, bool *val); +/** + * ucfg_mlme_is_roam_intra_band() - Get the preference to roam within band + * @psoc: pointer to psoc object + * + * Return: True if vdev should roam within band, false otherwise + */ +bool ucfg_mlme_is_roam_intra_band(struct wlan_objmgr_psoc *psoc); + /** * ucfg_mlme_set_roam_intra_band() - Set roam intra modes * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index b5de09e2b7..c11b45d123 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -1013,6 +1013,17 @@ ucfg_mlme_is_roam_prefer_5ghz(struct wlan_objmgr_psoc *psoc, bool *val) return QDF_STATUS_SUCCESS; } +bool ucfg_mlme_is_roam_intra_band(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return true; + + return mlme_obj->cfg.lfr.roam_intra_band; +} + QDF_STATUS ucfg_mlme_set_roam_intra_band(struct wlan_objmgr_psoc *psoc, bool val) { diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 519701cf1c..27562e35ec 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -2037,8 +2037,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, 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); + policy_mgr_set_pcl_for_connected_vdev(hdd_ctx->psoc, + adapter->vdev_id, true); } #endif @@ -2893,9 +2893,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, * 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); + policy_mgr_set_pcl_for_connected_vdev(hdd_ctx->psoc, + adapter->vdev_id, + false); /* * Enable roaming on other STA iface except this one. diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 00a56ee786..dc02d29c1e 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1023,36 +1023,6 @@ QDF_STATUS sme_abort_roaming(mac_handle_t mac_handle, uint8_t vdev_id); */ bool sme_roaming_in_progress(mac_handle_t mac_handle, uint8_t vdev_id); -/** - * 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, @@ -1889,21 +1859,6 @@ 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); -/** - * 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 9c43dbb549..5d0a57a21b 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1249,7 +1249,6 @@ 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_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 = @@ -6554,68 +6553,6 @@ bool sme_roaming_in_progress(mac_handle_t mac_handle, uint8_t vdev_id) #endif -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 @@ -12274,123 +12211,6 @@ QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle) return sme_set_rssi_threshold_breached_cb(mac_handle, NULL); } -/** - * 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(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; - bool dual_sta_roam_active; - - if (!mac) { - sme_debug("MAC Context is NULL"); - return band_mask; - } - - 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; -} - -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(); - struct scheduler_msg message = {0}; - struct set_pcl_req *req_msg; - uint32_t i; - - if (!mac) { - sme_err("mac is NULL"); - return QDF_STATUS_E_FAILURE; - } - - if (!msg) { - sme_err("msg is NULL"); - 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 = 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) { - sme_err("sme_acquire_global_lock failed!(status=%d)", status); - qdf_mem_free(req_msg); - return status; - } - - /* Serialize the req through MC thread */ - message.bodyptr = req_msg; - message.type = eWNI_SME_ROAM_SEND_SET_PCL_REQ; - status = scheduler_post_message(QDF_MODULE_ID_SME, - 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; - } - sme_release_global_lock(&mac->sme); - - return status; -} - /* * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA * @mac_handle: Handle returned by macOpen