From 5e31b638c38ceffd32e7a4cf3de25df623e8e37f Mon Sep 17 00:00:00 2001 From: Mukul Sharma Date: Fri, 10 Mar 2017 17:49:45 +0530 Subject: [PATCH] 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 --- .../core/inc/wlan_pmo_suspend_resume.h | 43 ++----- .../core/src/wlan_pmo_suspend_resume.c | 13 +- .../dispatcher/inc/wlan_pmo_obj_mgmt_api.h | 43 +++++++ .../inc/wlan_pmo_obj_mgmt_public_struct.h | 17 ++- .../dispatcher/src/wlan_pmo_obj_mgmt_api.c | 116 ++++++++++++++++++ 5 files changed, 194 insertions(+), 38 deletions(-) diff --git a/power_management_offloads/core/inc/wlan_pmo_suspend_resume.h b/power_management_offloads/core/inc/wlan_pmo_suspend_resume.h index 854153e63cf9..38dc3a0f676e 100644 --- a/power_management_offloads/core/inc/wlan_pmo_suspend_resume.h +++ b/power_management_offloads/core/inc/wlan_pmo_suspend_resume.h @@ -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; } diff --git a/power_management_offloads/core/src/wlan_pmo_suspend_resume.c b/power_management_offloads/core/src/wlan_pmo_suspend_resume.c index 6cc9f998d2c0..ea4cdf75798e 100644 --- a/power_management_offloads/core/src/wlan_pmo_suspend_resume.c +++ b/power_management_offloads/core/src/wlan_pmo_suspend_resume.c @@ -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(); diff --git a/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_api.h b/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_api.h index 1cec0caf5414..a3ffd904da1a 100644 --- a/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_api.h +++ b/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_api.h @@ -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_ */ diff --git a/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h b/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h index d16bf6c11aa7..c43cf55e8fa5 100644 --- a/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h +++ b/power_management_offloads/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h @@ -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; }; diff --git a/power_management_offloads/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/power_management_offloads/dispatcher/src/wlan_pmo_obj_mgmt_api.c index 8ed90dc13c3b..5600242ac399 100644 --- a/power_management_offloads/dispatcher/src/wlan_pmo_obj_mgmt_api.c +++ b/power_management_offloads/dispatcher/src/wlan_pmo_obj_mgmt_api.c @@ -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; +} + +