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
This commit is contained in:
Amruta Kulkarni 2020-08-05 11:27:51 -07:00 committed by snandini
parent fa65000c6b
commit 2f48b53345
6 changed files with 147 additions and 7 deletions

View File

@ -28,19 +28,23 @@
#include <wlan_objmgr_psoc_obj.h>
#include <qdf_lock.h>
#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

View File

@ -29,6 +29,8 @@
#include <wlan_objmgr_psoc_obj.h>
#include <target_if.h>
#include <target_if_vdev_mgr_rx_ops.h>
#include <wlan_reg_services_api.h>
#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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -24,7 +24,7 @@
#include <wlan_vdev_mgr_tgt_if_rx_defs.h>
#include <qdf_timer.h>
#include <wlan_cm_bss_score_param.h>
#ifdef FEATURE_VDEV_RSP_WAKELOCK
#ifdef FEATURE_VDEV_OPS_WAKELOCK
#include <target_if_psoc_wake_lock.h>
#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;

View File

@ -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)
{