diff --git a/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h b/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h index 7451dd5cb564..e360d2b8015d 100644 --- a/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h +++ b/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h @@ -28,19 +28,23 @@ #include #include -#ifdef FEATURE_VDEV_RSP_WAKELOCK +#ifdef FEATURE_VDEV_OPS_WAKELOCK /** * struct wlan_vdev_wakelock - vdev wake lock sub structure * @start_wakelock: wakelock for vdev start * @stop_wakelock: wakelock for vdev stop * @delete_wakelock: wakelock for vdev delete * @wmi_cmd_rsp_runtime_lock: run time lock + * @prevent_runtime_lock: run time lock + * @is_link_up: flag to check link status */ struct psoc_mlme_wakelock { qdf_wake_lock_t start_wakelock; qdf_wake_lock_t stop_wakelock; qdf_wake_lock_t delete_wakelock; qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock; + qdf_runtime_lock_t prevent_runtime_lock; + bool is_link_up; }; #endif @@ -50,7 +54,7 @@ enum wakelock_mode { DELETE_WAKELOCK }; -#ifdef FEATURE_VDEV_RSP_WAKELOCK +#ifdef FEATURE_VDEV_OPS_WAKELOCK /** * target_if_wake_lock_init() - API to initialize @@ -97,6 +101,27 @@ QDF_STATUS target_if_wake_lock_timeout_acquire(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS target_if_wake_lock_timeout_release(struct wlan_objmgr_psoc *psoc, enum wakelock_mode mode); + +/** + * target_if_vdev_start_link_handler() - check for SAP mode and DFS freq + to handle link up/down + * @vdev: pointer to vdev + * @cfreq1 : center freq1 + * @cfreq2 : center freq2 + * + * Return: None + */ +void target_if_vdev_start_link_handler(struct wlan_objmgr_vdev *vdev, + uint32_t cfreq1, uint32_t cfreq2); + +/** + * target_if_vdev_stop_link_handler() - check for SAP mode to handle link + * @vdev: pointer to vdev + * + * Return: None + */ +void target_if_vdev_stop_link_handler(struct wlan_objmgr_vdev *vdev); + #else static inline void target_if_wake_lock_init(struct wlan_objmgr_psoc *psoc) { @@ -119,5 +144,17 @@ static inline QDF_STATUS target_if_wake_lock_timeout_release( { return QDF_STATUS_SUCCESS; } + +static inline void +target_if_vdev_start_link_handler(struct wlan_objmgr_vdev *vdev, + uint32_t cfreq1, uint32_t cfreq2) +{ +} + +static inline void +target_if_vdev_stop_link_handler(struct wlan_objmgr_vdev *vdev) +{ +} + #endif #endif diff --git a/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c b/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c index 1446318683f5..352666663fff 100644 --- a/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c +++ b/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include "init_deinit_lmac.h" void target_if_wake_lock_init(struct wlan_objmgr_psoc *psoc) { @@ -49,6 +51,8 @@ void target_if_wake_lock_init(struct wlan_objmgr_psoc *psoc) qdf_wake_lock_create(&psoc_wakelock->delete_wakelock, "vdev_delete"); qdf_runtime_lock_init(&psoc_wakelock->wmi_cmd_rsp_runtime_lock); + qdf_runtime_lock_init(&psoc_wakelock->prevent_runtime_lock); + psoc_wakelock->is_link_up = false; } void target_if_wake_lock_deinit(struct wlan_objmgr_psoc *psoc) @@ -70,6 +74,7 @@ void target_if_wake_lock_deinit(struct wlan_objmgr_psoc *psoc) qdf_wake_lock_destroy(&psoc_wakelock->delete_wakelock); qdf_runtime_lock_deinit(&psoc_wakelock->wmi_cmd_rsp_runtime_lock); + qdf_runtime_lock_deinit(&psoc_wakelock->prevent_runtime_lock); } QDF_STATUS target_if_wake_lock_timeout_acquire( @@ -80,7 +85,7 @@ QDF_STATUS target_if_wake_lock_timeout_acquire( struct wlan_lmac_if_mlme_rx_ops *rx_ops; rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - if (!rx_ops && !rx_ops->psoc_get_wakelock_info) { + if (!rx_ops || !rx_ops->psoc_get_wakelock_info) { mlme_err("psoc_id:%d No Rx Ops", wlan_psoc_get_id(psoc)); return QDF_STATUS_E_INVAL; @@ -148,3 +153,95 @@ QDF_STATUS target_if_wake_lock_timeout_release( return QDF_STATUS_SUCCESS; } +static void +target_if_vote_for_link_down(struct wlan_objmgr_psoc *psoc, + struct psoc_mlme_wakelock *psoc_wakelock) +{ + void *htc_handle; + + htc_handle = lmac_get_htc_hdl(psoc); + if (!htc_handle) { + mlme_err("HTC handle is NULL"); + return; + } + + if (psoc_wakelock->is_link_up) { + htc_vote_link_down(htc_handle); + qdf_runtime_pm_allow_suspend(&psoc_wakelock->prevent_runtime_lock); + psoc_wakelock->is_link_up = false; + } +} + +static void +target_if_vote_for_link_up(struct wlan_objmgr_psoc *psoc, + struct psoc_mlme_wakelock *psoc_wakelock) +{ + void *htc_handle; + + htc_handle = lmac_get_htc_hdl(psoc); + if (!htc_handle) { + mlme_err("HTC handle is NULL"); + return; + } + + if (!psoc_wakelock->is_link_up) { + htc_vote_link_up(htc_handle); + qdf_runtime_pm_prevent_suspend(&psoc_wakelock->prevent_runtime_lock); + psoc_wakelock->is_link_up = true; + } +} + +void target_if_vdev_start_link_handler(struct wlan_objmgr_vdev *vdev, + uint32_t cfreq1, uint32_t cfreq2) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + struct psoc_mlme_wakelock *psoc_wakelock; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + psoc = wlan_vdev_get_psoc(vdev); + pdev = wlan_vdev_get_pdev(vdev); + + if (!pdev) { + mlme_err("pdev is NULL"); + return; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->psoc_get_wakelock_info) { + mlme_err("psoc_id:%d No Rx Ops", + wlan_psoc_get_id(psoc)); + return; + } + + psoc_wakelock = rx_ops->psoc_get_wakelock_info(psoc); + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { + if ((wlan_reg_chan_has_dfs_attribute_for_freq(pdev, + cfreq1)) || + (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, + cfreq2))) + target_if_vote_for_link_up(psoc, psoc_wakelock); + else + target_if_vote_for_link_down(psoc, psoc_wakelock); + } +} + +void target_if_vdev_stop_link_handler(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_psoc *psoc; + struct psoc_mlme_wakelock *psoc_wakelock; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + psoc = wlan_vdev_get_psoc(vdev); + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->psoc_get_wakelock_info) { + mlme_err("psoc_id:%d No Rx Ops", + wlan_psoc_get_id(psoc)); + return; + } + + psoc_wakelock = rx_ops->psoc_get_wakelock_info(psoc); + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) + target_if_vote_for_link_down(psoc, psoc_wakelock); +} + diff --git a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c index 5e979de0da5f..535dfbc4e995 100644 --- a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c +++ b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c @@ -479,6 +479,10 @@ static QDF_STATUS target_if_vdev_mgr_start_send( else target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, START_RESPONSE_BIT); + } else { + target_if_vdev_start_link_handler(vdev, + param->channel.cfreq1, + param->channel.cfreq2); } return status; } @@ -614,6 +618,8 @@ static QDF_STATUS target_if_vdev_mgr_stop_send( target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, STOP_RESPONSE_BIT); target_if_wake_lock_timeout_release(psoc, STOP_WAKELOCK); + } else { + target_if_vdev_stop_link_handler(vdev); } return status; } 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 12960ad49205..521fc038a7ff 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 @@ -1782,7 +1782,7 @@ struct wlan_lmac_if_mlme_rx_ops { QDF_STATUS (*vdev_mgr_multi_vdev_restart_resp)( struct wlan_objmgr_psoc *psoc, struct multi_vdev_restart_resp *rsp); -#ifdef FEATURE_VDEV_RSP_WAKELOCK +#ifdef FEATURE_VDEV_OPS_WAKELOCK struct psoc_mlme_wakelock *(*psoc_get_wakelock_info)( struct wlan_objmgr_psoc *psoc); #endif diff --git a/umac/mlme/include/wlan_psoc_mlme.h b/umac/mlme/include/wlan_psoc_mlme.h index d0d31a49b271..526cedadb232 100644 --- a/umac/mlme/include/wlan_psoc_mlme.h +++ b/umac/mlme/include/wlan_psoc_mlme.h @@ -24,7 +24,7 @@ #include #include #include -#ifdef FEATURE_VDEV_RSP_WAKELOCK +#ifdef FEATURE_VDEV_OPS_WAKELOCK #include #endif /* Max RNR size given max vaps are 16 */ @@ -89,7 +89,7 @@ struct psoc_mlme_obj { struct wlan_objmgr_psoc *psoc; mlme_psoc_ext_t *ext_psoc_ptr; struct vdev_response_timer psoc_vdev_rt[WLAN_UMAC_PSOC_MAX_VDEVS]; -#ifdef FEATURE_VDEV_RSP_WAKELOCK +#ifdef FEATURE_VDEV_OPS_WAKELOCK struct psoc_mlme_wakelock psoc_mlme_wakelock; #endif struct wlan_6ghz_rnr_global_cache rnr_6ghz_cache; diff --git a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c index 2979d716a30b..3a0577ff3470 100644 --- a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c +++ b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c @@ -211,7 +211,7 @@ static QDF_STATUS tgt_vdev_mgr_multi_vdev_restart_resp_handler( return mlme_vdev_ops_ext_hdl_multivdev_restart_resp(psoc, resp); } -#ifdef FEATURE_VDEV_RSP_WAKELOCK +#ifdef FEATURE_VDEV_OPS_WAKELOCK static struct psoc_mlme_wakelock * tgt_psoc_get_wakelock_info(struct wlan_objmgr_psoc *psoc) {