Browse Source

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
Mukul Sharma 8 years ago
parent
commit
5e31b638c3

+ 12 - 31
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;
 }

+ 8 - 5
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();
 

+ 43 - 0
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_ */

+ 15 - 2
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;
 };

+ 116 - 0
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;
+}
+
+