From 2d67497cfb13ec55fce35b0f96d3bd34d401a78c Mon Sep 17 00:00:00 2001 From: Gururaj Pandurangi Date: Tue, 30 May 2023 12:53:48 -0700 Subject: [PATCH] qcacmn: Add support to force power save the active MLO links Add MLO manager and target interface support to force power save on all the active MLO links for a defined number of beacon periods. Force power save allows the firmware to suspend STA links for X beacon periods and remain asleep even if the AP advertises TIM as opposed to regular power save mode where STA links wake up if the AP indicates that it has buffered data to send. Change-Id: Idb3ea42cfc2333a4b177780d09ddec6904ea0c16 CRs-Fixed: 3514468 --- target_if/mlo_mgr/inc/target_if_mlo_mgr.h | 10 +++++++ target_if/mlo_mgr/src/target_if_mlo_mgr.c | 21 +++++++++++++++ .../dispatcher/inc/wlan_mgmt_txrx_utils_api.h | 10 +++++++ .../lmac_if/inc/wlan_lmac_if_def.h | 3 +++ umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h | 22 +++++++++++++++ umac/mlo_mgr/src/wlan_mlo_mgr_sta.c | 27 +++++++++++++++++++ 6 files changed, 93 insertions(+) diff --git a/target_if/mlo_mgr/inc/target_if_mlo_mgr.h b/target_if/mlo_mgr/inc/target_if_mlo_mgr.h index 14aea18798..dab940c5cd 100644 --- a/target_if/mlo_mgr/inc/target_if_mlo_mgr.h +++ b/target_if/mlo_mgr/inc/target_if_mlo_mgr.h @@ -93,6 +93,16 @@ QDF_STATUS target_if_mlo_send_link_removal_cmd( struct wlan_objmgr_psoc *psoc, const struct mlo_link_removal_cmd_params *param); +/** + * target_if_mlo_send_vdev_pause() - Send WMI command for MLO vdev pause + * @psoc: psoc pointer + * @info: MLO vdev pause information + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS target_if_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, + struct mlo_vdev_pause *info); + /** * target_if_extract_mlo_link_removal_info_mgmt_rx() - Extract MLO link removal * information from MGMT Rx event diff --git a/target_if/mlo_mgr/src/target_if_mlo_mgr.c b/target_if/mlo_mgr/src/target_if_mlo_mgr.c index d70b490278..8f77ad2b5c 100644 --- a/target_if/mlo_mgr/src/target_if_mlo_mgr.c +++ b/target_if/mlo_mgr/src/target_if_mlo_mgr.c @@ -631,6 +631,25 @@ QDF_STATUS target_if_mlo_send_link_removal_cmd( return wmi_send_mlo_link_removal_cmd(wmi_handle, param); } +QDF_STATUS target_if_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, + struct mlo_vdev_pause *info) +{ + struct wmi_unified *wmi_handle; + + if (!psoc) { + target_if_err("null psoc"); + return QDF_STATUS_E_NULL_VALUE; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("null handle"); + return QDF_STATUS_E_FAILURE; + } + + return wmi_send_mlo_vdev_pause(wmi_handle, info); +} + /** * target_if_mlo_register_tx_ops() - lmac handler to register mlo tx ops * callback functions @@ -664,6 +683,8 @@ target_if_mlo_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) mlo_tx_ops->send_link_removal_cmd = target_if_mlo_send_link_removal_cmd; mlo_tx_ops->request_link_state_info_cmd = target_if_request_ml_link_state_info; + mlo_tx_ops->send_vdev_pause = target_if_mlo_send_vdev_pause; + return QDF_STATUS_SUCCESS; } diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h index 21acdec657..1bffebbed2 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h +++ b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h @@ -894,6 +894,16 @@ struct mlo_bcast_t2lm_info { uint8_t vdev_id[MAX_AP_MLDS_PER_LINK]; uint32_t expected_duration[MAX_AP_MLDS_PER_LINK]; }; + +/** + * struct mlo_vdev_pause - ML vdev pause info + * @vdev_id: vdev id of vdev to be paused + * @vdev_pause_duration: vdev pause duration + */ +struct mlo_vdev_pause { + uint16_t vdev_id; + uint32_t vdev_pause_duration; +}; #endif /** diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 754bd9bbb8..0b9494ce8b 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -1511,6 +1511,7 @@ struct wlan_lmac_if_son_rx_ops { * @shmem_local_ops: operations specific to WLAN_MLO_GLOBAL_SHMEM_SUPPORT * @send_tid_to_link_mapping: function to send T2LM command to FW * @send_link_removal_cmd: function to send MLO link removal command to FW + * @send_vdev_pause: function to send MLO vdev pause to FW */ struct wlan_lmac_if_mlo_tx_ops { QDF_STATUS (*register_events)(struct wlan_objmgr_psoc *psoc); @@ -1529,6 +1530,8 @@ struct wlan_lmac_if_mlo_tx_ops { QDF_STATUS (*send_link_removal_cmd)( struct wlan_objmgr_psoc *psoc, const struct mlo_link_removal_cmd_params *param); + QDF_STATUS (*send_vdev_pause)(struct wlan_objmgr_psoc *psoc, + struct mlo_vdev_pause *info); }; /** diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h index d396697221..66dd8c34d1 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h @@ -703,6 +703,21 @@ void mlo_process_ml_reconfig_ie(struct wlan_objmgr_vdev *vdev, struct scan_cache_entry *scan_entry, uint8_t *ml_ie, qdf_size_t ml_ie_len, struct mlo_partner_info *partner_info); + +/** + * wlan_mlo_send_vdev_pause() - send MLO vdev pause to FW + * @psoc: pointer to psoc + * @vdev: vdev pointer + * @session_id: session ID + * @vdev_pause_dur: vdev pause duration + * + * Return: None + */ +void wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + uint16_t session_id, + uint16_t vdev_pause_dur); + /** * mlo_allocate_and_copy_ies() - allocate and copy ies * @target: target connect req pointer @@ -924,5 +939,12 @@ mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } #endif + +static inline +void wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + uint16_t session_id, + uint16_t vdev_pause_dur) +{} #endif #endif diff --git a/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c b/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c index e0ca7684ed..0d077498da 100644 --- a/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c +++ b/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c @@ -2503,4 +2503,31 @@ mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +void +wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev, + uint16_t session_id, + uint16_t vdev_pause_dur) +{ + struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops; + struct mlo_vdev_pause vdev_pause_info; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + mlo_tx_ops = &psoc->soc_cb.tx_ops->mlo_ops; + if (!mlo_tx_ops) { + mlo_err("tx_ops is null!"); + return; + } + + if (!mlo_tx_ops->send_vdev_pause) { + mlo_err("send_vdev_pause is null"); + return; + } + + vdev_pause_info.vdev_id = session_id; + vdev_pause_info.vdev_pause_duration = vdev_pause_dur; + status = mlo_tx_ops->send_vdev_pause(psoc, &vdev_pause_info); + if (QDF_IS_STATUS_ERROR(status)) + mlo_err("Failed to send vdev pause to FW"); +} #endif