From 2f48b53345284d99ceb3ac990298b5e68e3a5025 Mon Sep 17 00:00:00 2001 From: Amruta Kulkarni Date: Wed, 5 Aug 2020 11:27:51 -0700 Subject: [PATCH] qcacmn: Prevent link down for SAP on DFS channel For SAP on DFS channel, the PCIe link down should be prevented so that HalPhy can access DDR memory to report Radar found event. Change-Id: I5eb1076196c509f0279781dbe3269d62132aeabc CRs-Fixed: 2712800 --- .../mlme/psoc/inc/target_if_psoc_wake_lock.h | 41 +++++++- .../mlme/psoc/src/target_if_psoc_wake_lock.c | 99 ++++++++++++++++++- .../vdev_mgr/src/target_if_vdev_mgr_tx_ops.c | 6 ++ .../lmac_if/inc/wlan_lmac_if_def.h | 2 +- umac/mlme/include/wlan_psoc_mlme.h | 4 +- .../src/wlan_vdev_mgr_tgt_if_rx_api.c | 2 +- 6 files changed, 147 insertions(+), 7 deletions(-) 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 7451dd5cb5..e360d2b801 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 1446318683..352666663f 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 5e979de0da..535dfbc4e9 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 12960ad492..521fc038a7 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 d0d31a49b2..526cedadb2 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 2979d716a3..3a0577ff34 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) {