qcacmn: Add get/update vdev pause bitmap support in PMO

Add get/update vdev pause bitmap support in PMO.

Change-Id: I25ff425f3e2199ee1d3940816bbe2c71c286eeb3
CRs-Fixed: 2016081
This commit is contained in:
Mukul Sharma 2017-03-10 17:49:45 +05:30 • committed by Sandeep Puligilla
commit 5e31b638c3
5 changed files with 194 additions and 38 deletions

View file

@ -311,45 +311,26 @@ enum pmo_power_save_qpower_mode pmo_core_psoc_get_qpower_config(
}
}
/**
* pmo_core_vdev_update_pause_bitmap() - update vdev pause bitmap value
* @vdev: objmgr vdev handle
* @value: value of pause bitmap
*
* Return: None
*/
static inline
void pmo_core_vdev_update_pause_bitmap(struct wlan_objmgr_vdev *vdev,
uint16_t value)
{
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_get_vdev_priv_ctx(vdev);
if (!vdev_ctx)
return;
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
vdev_ctx->pause_bitmap = value;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
}
/**
* pmo_core_vdev_get_pause_bitmap() - Get vdev pause bitmap
* @vdev: objmgr vdev handle
* @psoc_ctx: psoc priv ctx
* @vdev_id: vdev id
*
* Return: vdev pause bitmap
*/
static inline
uint16_t pmo_core_vdev_get_pause_bitmap(struct wlan_objmgr_vdev *vdev)
uint16_t pmo_core_vdev_get_pause_bitmap(struct pmo_psoc_priv_obj *psoc_ctx,
uint8_t vdev_id)
{
uint16_t value;
struct pmo_vdev_priv_obj *vdev_ctx;
uint16_t value = 0;
pmo_get_pause_bitmap handler;
vdev_ctx = pmo_get_vdev_priv_ctx(vdev);
if (!vdev_ctx)
return 0;
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
value = vdev_ctx->pause_bitmap;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
qdf_spin_lock_bh(&psoc_ctx->lock);
handler = psoc_ctx->get_pause_bitmap;
qdf_spin_unlock_bh(&psoc_ctx->lock);
if (handler)
value = handler(vdev_id);
return value;
}

View file

@ -417,7 +417,8 @@ static void pmo_core_set_resume_dtim(struct wlan_objmgr_psoc *psoc)
*
* Return: none
*/
static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc)
static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc,
struct pmo_psoc_priv_obj *psoc_ctx)
{
uint8_t vdev_id;
struct wlan_objmgr_psoc_objmgr *objmgr;
@ -439,12 +440,14 @@ static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc)
* When host resume, by default,
* unpause all active vdev
*/
if (pmo_core_vdev_get_pause_bitmap(vdev)) {
if (pmo_core_vdev_get_pause_bitmap(psoc_ctx, vdev_id)) {
cdp_fc_vdev_unpause(
pmo_core_psoc_get_dp_handle(psoc),
pmo_core_vdev_get_dp_handle(vdev),
0xffffffff);
/* wma_vdev_update_pause_bitmap(vdev_id, 0); */
if (psoc_ctx->pause_bitmap_notifier)
psoc_ctx->pause_bitmap_notifier(vdev_id,
0);
}
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
}
@ -484,7 +487,7 @@ QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
/* need to reset if hif_pci_suspend_fails */
pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
/* unpause the vdev if left paused and hif_pci_suspend fails */
pmo_unpause_all_vdev(psoc);
pmo_unpause_all_vdev(psoc, psoc_ctx);
dec_psoc_ref:
wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID);
@ -778,7 +781,7 @@ QDF_STATUS pmo_core_psoc_disable_wow_in_fw(struct wlan_objmgr_psoc *psoc,
/* To allow the tx pause/unpause events */
pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
/* Unpause the vdev as we are resuming */
pmo_unpause_all_vdev(psoc);
pmo_unpause_all_vdev(psoc, psoc_ctx);
out:
PMO_EXIT();

View file

@ -172,4 +172,47 @@ QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
enum qdf_suspend_type suspend_type);
/**
* pmo_register_pause_bitmap_notifier(): API to register pause bitmap notifier
* @psoc: objmgr psoc handle
* @handler: pause bitmap updated notifier
*
* Return QDF_STATUS status - in case of success else return error
*/
QDF_STATUS pmo_register_pause_bitmap_notifier(
struct wlan_objmgr_psoc *psoc,
pmo_notify_pause_bitmap handler);
/**
* pmo_unregister_pause_bitmap_notifier(): API to unregister pause bitmap notifier
* @psoc: objmgr psoc handle
* @handler: pause bitmap updated notifier
*
* Return QDF_STATUS status - in case of success else return error
*/
QDF_STATUS pmo_unregister_pause_bitmap_notifier(
struct wlan_objmgr_psoc *psoc,
pmo_notify_pause_bitmap handler);
/**
* pmo_register_get_pause_bitmap(): API to get register pause bitmap notifier
* @psoc: objmgr psoc handle
* @handler: pause bitmap updated notifier
*
* Return QDF_STATUS status - in case of success else return error
*/
QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
pmo_get_pause_bitmap handler);
/**
* pmo_unregister_get_pause_bitmap(): API to unregister get pause bitmap callback
* @psoc: objmgr psoc handle
* @handler: pause bitmap updated notifier
*
* Return QDF_STATUS status - in case of success else return error
*/
QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
pmo_get_pause_bitmap handler);
#endif /* end of _WLAN_PMO_OBJ_MGMT_API_H_ */

View file

@ -33,12 +33,25 @@
#include "wlan_pmo_wow_public_struct.h"
#include "wlan_pmo_mc_addr_filtering_public_struct.h"
/**
* typedef for vdev notifying the vdev pause bitmap new value to mlme
*/
typedef void (*pmo_notify_pause_bitmap)(
uint8_t vdev_id, uint16_t value);
/**
* typedef for getting vdev pause bitmap
*/
typedef uint16_t(*pmo_get_pause_bitmap)(uint8_t vdev_id);
/**
* struct pmo_psoc_priv_obj - psoc related data require for pmo
* @psoc_cfg: place holder for psoc configuration
* @wow: wow configuration
* @dp_hdl: psoc data path handle
* @htc_hdl: htc layer handle
* @pause_bitmap_notifier: registered callback to update pause bitmap value
* @pmo_get_pause_bitmap: registered callback to get pause bitmap value
* @lock: spin lock for pmo psoc
*/
struct pmo_psoc_priv_obj {
@ -46,6 +59,8 @@ struct pmo_psoc_priv_obj {
struct pmo_wow wow;
void *dp_hdl;
void *htc_hdl;
pmo_notify_pause_bitmap pause_bitmap_notifier;
pmo_get_pause_bitmap get_pause_bitmap;
qdf_spinlock_t lock;
};
@ -90,7 +105,6 @@ struct wlan_pmo_ctx {
* @beacon_interval: vdev beacon interval
* @alt_modulated_dtim_enabled:dynamic modulated dtim enabled
* @dtim_policy: tells vdev beacon dtim policy
* @pause_bitmap: tell about reason why vde is paused
* @vdev_dp_hdl: vdev data path handle
* @pmo_vdev_lock: spin lock for pmo vdev priv ctx
*/
@ -114,7 +128,6 @@ struct pmo_vdev_priv_obj {
uint8_t beacon_interval;
bool alt_modulated_dtim_enable;
uint32_t dtim_policy;
uint16_t pause_bitmap;
void *vdev_dp_hdl;
qdf_spinlock_t pmo_vdev_lock;
};

View file

@ -576,3 +576,119 @@ out:
return component_ret;
}
QDF_STATUS pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
pmo_notify_pause_bitmap handler)
{
struct pmo_psoc_priv_obj *psoc_ctx;
if (!psoc) {
pmo_err("psoc is null");
return QDF_STATUS_E_NULL_VALUE;
}
if (!handler) {
pmo_err("pmo_notify_vdev_pause_bitmap is null");
return QDF_STATUS_E_NULL_VALUE;
}
psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
if (!psoc_ctx) {
pmo_err("psoc_ctx is null");
return QDF_STATUS_E_NULL_VALUE;
}
qdf_spin_lock_bh(&psoc_ctx->lock);
psoc_ctx->pause_bitmap_notifier = handler;
qdf_spin_unlock_bh(&psoc_ctx->lock);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
pmo_notify_pause_bitmap handler)
{
struct pmo_psoc_priv_obj *psoc_ctx;
if (!psoc) {
pmo_err("psoc is null");
return QDF_STATUS_E_NULL_VALUE;
}
if (!handler) {
pmo_err("pmo_notify_vdev_pause_bitmap is null");
return QDF_STATUS_E_NULL_VALUE;
}
psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
if (!psoc_ctx) {
pmo_err("psoc_ctx is null");
return QDF_STATUS_E_NULL_VALUE;
}
qdf_spin_lock_bh(&psoc_ctx->lock);
if (psoc_ctx->pause_bitmap_notifier == handler)
psoc_ctx->pause_bitmap_notifier = NULL;
qdf_spin_unlock_bh(&psoc_ctx->lock);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
pmo_get_pause_bitmap handler)
{
struct pmo_psoc_priv_obj *psoc_ctx;
if (!psoc) {
pmo_err("psoc is null");
return QDF_STATUS_E_NULL_VALUE;
}
if (!handler) {
pmo_err("pmo_get_pause_bitmap is null");
return QDF_STATUS_E_NULL_VALUE;
}
psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
if (!psoc_ctx) {
pmo_err("psoc_ctx is null");
return QDF_STATUS_E_NULL_VALUE;
}
qdf_spin_lock_bh(&psoc_ctx->lock);
psoc_ctx->get_pause_bitmap = handler;
qdf_spin_unlock_bh(&psoc_ctx->lock);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
pmo_get_pause_bitmap handler)
{
struct pmo_psoc_priv_obj *psoc_ctx;
if (!psoc) {
pmo_err("psoc is null");
return QDF_STATUS_E_NULL_VALUE;
}
if (!handler) {
pmo_err("pmo_get_pause_bitmap is null");
return QDF_STATUS_E_NULL_VALUE;
}
psoc_ctx = pmo_get_psoc_priv_ctx(psoc);
if (!psoc_ctx) {
pmo_err("psoc_ctx is null");
return QDF_STATUS_E_NULL_VALUE;
}
qdf_spin_lock_bh(&psoc_ctx->lock);
if (psoc_ctx->get_pause_bitmap == handler)
psoc_ctx->get_pause_bitmap = NULL;
qdf_spin_unlock_bh(&psoc_ctx->lock);
return QDF_STATUS_SUCCESS;
}