qcacld-3.0: Port modulated dtim and override listen interval

Port modulated dtim and override listen interval to PMO from
WMA.

Change-Id: Id965dd8ee0fbddfa563335fd2fe225dcd20cd162
CRs-Fixed: 2252788
这个提交包含在:
Nachiket Kukade
2018-06-01 22:53:06 +05:30
提交者 nshrivas
父节点 0368d66a73
当前提交 4b7c8e03c7
修改 13 个文件,包含 259 行新增635 行删除

查看文件

@@ -109,8 +109,10 @@ struct wlan_pmo_ctx {
* @p2plo_in_progress: true when p2plo_in_progress in progress else false
* @dtim_period: dtim period for vdev
* @beacon_interval: vdev beacon interval
* @alt_modulated_dtim_enabled:dynamic modulated dtim enabled
* @dyn_modulated_dtim: dynamically configured modulated dtim value
* @dyn_modulated_dtim_enabled: if dynamically modulated dtim is set or not
* @dtim_policy: tells vdev beacon dtim policy
* @dyn_listen_interval: dynamically user configured listen interval
* @pmo_vdev_lock: spin lock for pmo vdev priv ctx
*/
struct pmo_vdev_priv_obj {
@@ -131,8 +133,10 @@ struct pmo_vdev_priv_obj {
bool p2plo_in_progress;
uint8_t dtim_period;
uint8_t beacon_interval;
bool alt_modulated_dtim_enable;
uint32_t dyn_modulated_dtim;
bool dyn_modulated_dtim_enabled;
uint32_t dtim_policy;
uint32_t dyn_listen_interval;
qdf_spinlock_t pmo_vdev_lock;
};

查看文件

@@ -140,25 +140,6 @@ QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
QDF_STATUS pmo_core_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
enum qdf_suspend_type type);
/**
* pmo_core_update_alt_modulated_dtim_enable() - update alt modulatate dtim
* @vdev: objmgr vdev handle
* @value: true when alt modulated dtim enable else false
*
* Return: None
*/
static inline
void pmo_core_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
bool value)
{
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
vdev_ctx->alt_modulated_dtim_enable = value;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
}
/**
* pmo_core_vdev_set_dtim_policy() - Set vdev beacon dtim policy
* @vdev: objmgr vdev handle
@@ -388,6 +369,30 @@ void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
*/
void pmo_core_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
/**
* pmo_core_config_listen_interval() - function to dynamically configure
* listen interval
* @vdev: objmgr vdev
* @listen_interval: new listen interval passed by user
*
* This function allows user to configure listen interval dynamically
*
* Return: QDF_STATUS
*/
QDF_STATUS pmo_core_config_listen_interval(struct wlan_objmgr_vdev *vdev,
uint32_t listen_interval);
/**
* pmo_core_config_modulated_dtim() - function to configure modulated dtim
* @vdev: objmgr vdev handle
* @mod_dtim: New modulated dtim value passed by user
*
* This function configures the modulated dtim in firmware
*
* Return: QDF_STATUS
*/
QDF_STATUS pmo_core_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
uint32_t mod_dtim);
#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
#endif /* end of _WLAN_PMO_SUSPEND_RESUME_H_ */

查看文件

@@ -214,6 +214,26 @@ static void pmo_core_set_vdev_suspend_dtim(struct wlan_objmgr_psoc *psoc,
}
}
/*
* pmo_is_listen_interval_user_set() - Check if listen interval is configured
* by user or not
* @vdev_ctx: PMO vdev private object
*
* Return: true if listen interval is user configured else false
*/
static inline
bool pmo_is_listen_interval_user_set(struct pmo_vdev_priv_obj *vdev_ctx)
{
bool retval;
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
retval = vdev_ctx->dyn_modulated_dtim_enabled
|| vdev_ctx->dyn_listen_interval;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
return retval;
}
/**
* pmo_core_set_suspend_dtim() - set suspend dtim
* @psoc: objmgr psoc handle
@@ -225,9 +245,17 @@ static void pmo_core_set_suspend_dtim(struct wlan_objmgr_psoc *psoc)
uint8_t vdev_id;
struct wlan_objmgr_vdev *vdev;
struct pmo_vdev_priv_obj *vdev_ctx;
bool alt_mdtim_enabled;
struct pmo_psoc_priv_obj *psoc_ctx;
bool li_offload_support = false;
QDF_STATUS status;
pmo_psoc_with_ctx(psoc, psoc_ctx) {
li_offload_support = psoc_ctx->caps.li_offload;
}
if (li_offload_support)
pmo_debug("listen interval offload support is enabled");
/* Iterate through VDEV list */
for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
vdev = pmo_psoc_get_vdev(psoc, vdev_id);
@@ -239,11 +267,8 @@ static void pmo_core_set_suspend_dtim(struct wlan_objmgr_psoc *psoc)
continue;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
alt_mdtim_enabled = vdev_ctx->alt_modulated_dtim_enable;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
if (!alt_mdtim_enabled)
if (!pmo_is_listen_interval_user_set(vdev_ctx)
&& !li_offload_support)
pmo_core_set_vdev_suspend_dtim(psoc, vdev, vdev_ctx);
pmo_vdev_put_ref(vdev);
@@ -482,9 +507,17 @@ static void pmo_core_set_resume_dtim(struct wlan_objmgr_psoc *psoc)
uint8_t vdev_id;
struct wlan_objmgr_vdev *vdev;
struct pmo_vdev_priv_obj *vdev_ctx;
bool alt_mdtim_enabled;
struct pmo_psoc_priv_obj *psoc_ctx;
bool li_offload_support = false;
QDF_STATUS status;
pmo_psoc_with_ctx(psoc, psoc_ctx) {
li_offload_support = psoc_ctx->caps.li_offload;
}
if (li_offload_support)
pmo_debug("listen interval offload support is enabled");
/* Iterate through VDEV list */
for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
vdev = pmo_psoc_get_vdev(psoc, vdev_id);
@@ -496,13 +529,9 @@ static void pmo_core_set_resume_dtim(struct wlan_objmgr_psoc *psoc)
continue;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
alt_mdtim_enabled = vdev_ctx->alt_modulated_dtim_enable;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
if (!alt_mdtim_enabled)
if (!pmo_is_listen_interval_user_set(vdev_ctx)
&& !li_offload_support)
pmo_core_set_vdev_resume_dtim(psoc, vdev, vdev_ctx);
pmo_vdev_put_ref(vdev);
}
}
@@ -1270,3 +1299,132 @@ out:
pmo_exit();
}
QDF_STATUS pmo_core_config_listen_interval(struct wlan_objmgr_vdev *vdev,
uint32_t new_li)
{
uint32_t listen_interval;
QDF_STATUS status;
struct pmo_vdev_priv_obj *vdev_ctx;
struct pmo_psoc_priv_obj *psoc_ctx;
uint8_t vdev_id;
pmo_enter();
status = pmo_vdev_get_ref(vdev);
if (QDF_IS_STATUS_ERROR(status))
goto out;
vdev_ctx = pmo_vdev_get_priv(vdev);
vdev_id = pmo_vdev_get_id(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
if (vdev_ctx->dyn_listen_interval == new_li) {
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
status = QDF_STATUS_SUCCESS;
pmo_debug("Listen Interval(%d) already set for vdev id %d",
new_li, vdev_id);
goto dec_ref;
}
vdev_ctx->dyn_listen_interval = new_li;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
listen_interval = new_li ? new_li : PMO_DEFAULT_LISTEN_INTERVAL;
if (!new_li) {
/* Configure default LI as we do on resume */
pmo_psoc_with_ctx(pmo_vdev_get_psoc(vdev), psoc_ctx) {
if (psoc_ctx->get_cfg_int &&
(QDF_STATUS_SUCCESS != psoc_ctx->get_cfg_int(
PMO_CFG_LISTEN_INTERVAL,
&listen_interval))) {
pmo_err("Failed to get listen interval");
}
}
}
pmo_debug("Set Listen Interval %d for vdevId %d", listen_interval,
vdev_id);
status = pmo_tgt_vdev_update_param_req(vdev,
pmo_vdev_param_listen_interval,
listen_interval);
if (QDF_IS_STATUS_ERROR(status)) {
/* even it fails continue fwr will take default LI */
pmo_err("Failed to Set Listen Interval");
}
/* Set it to Normal DTIM */
status = pmo_tgt_vdev_update_param_req(vdev,
pmo_vdev_param_dtim_policy,
pmo_normal_dtim);
if (QDF_IS_STATUS_ERROR(status)) {
pmo_err("Failed to set Normal DTIM for vdev id %d", vdev_id);
} else {
pmo_debug("Set DTIM Policy to Normal for vdev id %d", vdev_id);
pmo_core_vdev_set_dtim_policy(vdev, pmo_normal_dtim);
}
dec_ref:
pmo_vdev_put_ref(vdev);
out:
pmo_exit();
return status;
}
QDF_STATUS pmo_core_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
uint32_t mod_dtim)
{
struct pmo_vdev_priv_obj *vdev_ctx;
bool prev_dtim_enabled;
uint32_t listen_interval;
QDF_STATUS status;
uint8_t vdev_id;
pmo_enter();
status = pmo_vdev_get_ref(vdev);
if (status != QDF_STATUS_SUCCESS)
goto out;
vdev_id = pmo_vdev_get_id(vdev);
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
vdev_ctx->dyn_modulated_dtim = mod_dtim;
prev_dtim_enabled = vdev_ctx->dyn_modulated_dtim_enabled;
vdev_ctx->dyn_modulated_dtim_enabled = mod_dtim != 1;
listen_interval = vdev_ctx->dyn_modulated_dtim *
pmo_core_get_vdev_dtim_period(vdev);
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
if (prev_dtim_enabled || mod_dtim != 1) {
status = pmo_tgt_vdev_update_param_req(vdev,
pmo_vdev_param_listen_interval,
listen_interval);
if (QDF_IS_STATUS_ERROR(status))
/* even it fails continue fwr will take default LI */
pmo_err("Failed to set Listen Interval for vdev id %d",
vdev_id);
else
pmo_debug("Set Listen Interval %d for vdev id %d",
listen_interval, vdev_id);
status = pmo_tgt_vdev_update_param_req(vdev,
pmo_vdev_param_dtim_policy,
pmo_normal_dtim);
if (QDF_IS_STATUS_ERROR(status)) {
pmo_err("Failed to set Normal DTIM for vdev id %d",
vdev_id);
} else {
pmo_debug("Set DTIM Policy to Normal for vdev id %d",
vdev_id);
pmo_core_vdev_set_dtim_policy(vdev, pmo_normal_dtim);
}
}
pmo_vdev_put_ref(vdev);
out:
pmo_exit();
return status;
}

查看文件

@@ -322,12 +322,14 @@ struct pmo_psoc_cfg {
* @unified_wow: Firmware supports "interface pause" flag in WoW command.
* This allows both D0-WoW (bus up) and Non-D0-WoW (bus down) to use one
* unified command
* @li_offload: Firmware has listen interval offload support
*/
struct pmo_device_caps {
bool apf;
bool arp_ns_offload;
bool packet_filter;
bool unified_wow;
bool li_offload;
};
#endif /* end of _WLAN_PMO_COMMONP_STRUCT_H_ */

查看文件

@@ -425,16 +425,6 @@ QDF_STATUS pmo_ucfg_lphb_config_req(struct wlan_objmgr_psoc *psoc,
struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
pmo_lphb_callback callback);
/**
* pmo_ucfg_update_alt_modulated_dtim_enable() - update alt modulatate dtim
* @vdev: objmgr vdev handle
* @value: true for alt_modulated_dtim enable else false
*
* Return: QDF status
*/
void pmo_ucfg_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
bool value);
/**
* pmo_ucfg_psoc_update_power_save_mode() - update power save mode
* @vdev: objmgr vdev handle
@@ -619,6 +609,30 @@ void pmo_ucfg_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
* Return: None
*/
void pmo_ucfg_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
/**
* pmo_ucfg_config_listen_interval() - function to configure listen interval
* @vdev: objmgr vdev
* @listen_interval: new listen interval passed by user
*
* This function allows user to configure listen interval dynamically
*
* Return: QDF_STATUS
*/
QDF_STATUS pmo_ucfg_config_listen_interval(struct wlan_objmgr_vdev *vdev,
uint32_t listen_interval);
/**
* pmo_ucfg_config_modulated_dtim() - function to configure modulated dtim
* @vdev: objmgr vdev handle
* @param_value: New modulated dtim value passed by user
*
* This function configures the modulated dtim in firmware
*
* Return: QDF_STATUS
*/
QDF_STATUS pmo_ucfg_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
uint32_t mod_dtim);
#else
static inline uint32_t
ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc)
@@ -866,13 +880,6 @@ pmo_ucfg_lphb_config_req(
return QDF_STATUS_SUCCESS;
}
static inline void
pmo_ucfg_update_alt_modulated_dtim_enable(
struct wlan_objmgr_vdev *vdev,
bool value)
{
}
static inline void
pmo_ucfg_psoc_update_power_save_mode(
struct wlan_objmgr_psoc *psoc,
@@ -1046,6 +1053,20 @@ pmo_ucfg_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
pmo_ucfg_config_listen_interval(struct wlan_objmgr_vdev *vdev,
uint32_t listen_interval)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
pmo_ucfg_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
uint32_t mod_dtim)
{
return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
#endif /* end of _WLAN_PMO_UCFG_API_H_ */

查看文件

@@ -255,12 +255,6 @@ QDF_STATUS pmo_ucfg_lphb_config_req(struct wlan_objmgr_psoc *psoc,
return pmo_core_lphb_config_req(psoc, lphb_req, lphb_cb_ctx, callback);
}
void pmo_ucfg_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
bool value)
{
pmo_core_update_alt_modulated_dtim_enable(vdev, value);
}
void pmo_ucfg_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
uint8_t value)
{
@@ -389,4 +383,15 @@ QDF_STATUS pmo_ucfg_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
return pmo_core_disable_hw_filter_in_fwr(vdev);
}
QDF_STATUS pmo_ucfg_config_listen_interval(struct wlan_objmgr_vdev *vdev,
uint32_t listen_interval)
{
return pmo_core_config_listen_interval(vdev, listen_interval);
}
QDF_STATUS pmo_ucfg_config_modulated_dtim(struct wlan_objmgr_vdev *vdev,
uint32_t mod_dtim)
{
return pmo_core_config_modulated_dtim(vdev, mod_dtim);
}