Browse Source

qcacld-3.0: Register action frames for wake up during runtime PM

Currently the bitmap of action frames that can wake up the host
during suspend is sent via the wmi command
WMI_WOW_SET_ACTION_WAKE_UP_CMDID. This bitmap doesn't include
RRM action frames so currently the host doesn't wake up for rrm
action frames when in suspend mode.

Selectively enable wake up for rrm action frames during runtime PM
alone. Don't enable host wake up during normal suspend as it will
consume more power.

Change-Id: I097596118c2888fc9ea24802e4dbe69d02c5c5f7
CRs-Fixed: 2507185
Pragaspathi Thilagaraj 5 years ago
parent
commit
b40c260f17

+ 14 - 3
components/pmo/core/inc/wlan_pmo_static_config.h

@@ -55,14 +55,25 @@ void pmo_register_wow_default_patterns(struct wlan_objmgr_vdev *vdev);
 /**
  * pmo_register_action_frame_patterns() - register action frame map to fw
  * @vdev: objmgr vdev
+ * @suspend_type: suspend mode runtime pm suspend or normal suspend.
  *
  * This is called to push action frames wow patterns from local
  * cache to firmware.
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-void pmo_register_action_frame_patterns(
-		struct wlan_objmgr_vdev *vdev);
+QDF_STATUS
+pmo_register_action_frame_patterns(struct wlan_objmgr_vdev *vdev,
+				   enum qdf_suspend_type suspend_type);
+
+/**
+ * pmo_clear_action_frame_patterns() - clear the action frame
+ * pattern bitmap in firmware
+ * @vdev: objmgr vdev
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_clear_action_frame_patterns(struct wlan_objmgr_vdev *vdev);
 
 /**
  * pmo_set_wow_event_bitmap() - Assign bitmask with wow event

+ 30 - 3
components/pmo/core/src/wlan_pmo_static_config.c

@@ -398,17 +398,25 @@ static void set_action_id_drop_pattern_for_public_action(
 				= DROP_PUBLIC_ACTION_FRAME_BITMAP;
 }
 
-void pmo_register_action_frame_patterns(struct wlan_objmgr_vdev *vdev)
+QDF_STATUS
+pmo_register_action_frame_patterns(struct wlan_objmgr_vdev *vdev,
+				   enum qdf_suspend_type suspend_type)
 {
 
 	struct pmo_action_wakeup_set_params cmd = {0};
 	int i = 0;
-	QDF_STATUS status;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	cmd.vdev_id = pmo_vdev_get_id(vdev);
 	cmd.operation = pmo_action_wakeup_set;
 
-	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP0;
+	if (suspend_type == QDF_SYSTEM_SUSPEND)
+		cmd.action_category_map[i++] =
+			SYSTEM_SUSPEND_ALLOWED_ACTION_FRAMES_BITMAP0;
+	else
+		cmd.action_category_map[i++] =
+				RUNTIME_PM_ALLOWED_ACTION_FRAMES_BITMAP0;
+
 	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP1;
 	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP2;
 	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP3;
@@ -438,5 +446,24 @@ void pmo_register_action_frame_patterns(struct wlan_objmgr_vdev *vdev)
 	if (status != QDF_STATUS_SUCCESS)
 		pmo_err("Failed to config wow action frame map, ret %d",
 			status);
+
+	return status;
 }
 
+QDF_STATUS
+pmo_clear_action_frame_patterns(struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_action_wakeup_set_params cmd = {0};
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	cmd.vdev_id = pmo_vdev_get_id(vdev);
+	cmd.operation = pmo_action_wakeup_reset;
+
+	/*  clear action frame pattern */
+	status = pmo_tgt_send_action_frame_pattern_req(vdev, &cmd);
+	if (QDF_IS_STATUS_ERROR(status))
+		pmo_err("Failed to clear wow action frame map, ret %d",
+			status);
+
+	return status;
+}

+ 4 - 0
components/pmo/core/src/wlan_pmo_suspend_resume.c

@@ -438,6 +438,8 @@ static void pmo_core_enable_runtime_pm_offloads(struct wlan_objmgr_psoc *psoc)
 		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
 		if (!vdev)
 			continue;
+
+		pmo_register_action_frame_patterns(vdev, QDF_RUNTIME_SUSPEND);
 	}
 }
 
@@ -451,6 +453,8 @@ static void pmo_core_disable_runtime_pm_offloads(struct wlan_objmgr_psoc *psoc)
 		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
 		if (!vdev)
 			continue;
+
+		pmo_clear_action_frame_patterns(vdev);
 	}
 }
 

+ 22 - 0
components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h

@@ -405,6 +405,28 @@ ucfg_pmo_ns_addr_scope(uint32_t ipv6_scope);
  */
 QDF_STATUS ucfg_pmo_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * ucfg_pmo_enable_action_frame_patterns() - enable the action frame wake up
+ * patterns as part of the enable host offloads.
+ * @vdev: objmgr vdev to configure
+ * @suspend_type: Suspend type. Runtime PM or System Suspend mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ucfg_pmo_enable_action_frame_patterns(struct wlan_objmgr_vdev *vdev,
+				      enum qdf_suspend_type suspend_type);
+
+/**
+ * ucfg_pmo_disable_action_frame_patterns() - Reset the action frame wake up
+ * patterns as a part of suspend resume.
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ucfg_pmo_disable_action_frame_patterns(struct wlan_objmgr_vdev *vdev);
+
 /**
  * ucfg_pmo_disable_hw_filter_in_fwr() - disable previously configured hw filter
  * @vdev: objmgr vdev to configure

+ 22 - 10
components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h

@@ -96,16 +96,16 @@
  * PMO_ACTION_VHT             21      1
  * ----------------------------+------+-------+
  */
-#define ALLOWED_ACTION_FRAMES_BITMAP0 \
-		((1 << PMO_MAC_ACTION_SPECTRUM_MGMT) | \
-		 (1 << PMO_MAC_ACTION_QOS_MGMT) | \
-		 (1 << PMO_MAC_ACTION_PUBLIC_USAGE) | \
-		 (1 << PMO_MAC_ACTION_SA_QUERY) | \
-		 (1 << PMO_MAC_ACTION_PROT_DUAL_PUB) | \
-		 (1 << PMO_MAC_ACTION_WNM) | \
-		 (1 << PMO_MAC_ACTION_WME) | \
-		 (1 << PMO_MAC_ACTION_FST) | \
-		 (1 << PMO_MAC_ACTION_VHT))
+#define SYSTEM_SUSPEND_ALLOWED_ACTION_FRAMES_BITMAP0 \
+			((1 << PMO_MAC_ACTION_SPECTRUM_MGMT) | \
+			 (1 << PMO_MAC_ACTION_QOS_MGMT) | \
+			 (1 << PMO_MAC_ACTION_PUBLIC_USAGE) | \
+			 (1 << PMO_MAC_ACTION_SA_QUERY) | \
+			 (1 << PMO_MAC_ACTION_PROT_DUAL_PUB) | \
+			 (1 << PMO_MAC_ACTION_WNM) | \
+			 (1 << PMO_MAC_ACTION_WME) | \
+			 (1 << PMO_MAC_ACTION_FST) | \
+			 (1 << PMO_MAC_ACTION_VHT))
 
 #define ALLOWED_ACTION_FRAMES_BITMAP1   0x0
 #define ALLOWED_ACTION_FRAMES_BITMAP2   0x0
@@ -117,6 +117,18 @@
 
 #define ALLOWED_ACTION_FRAME_MAP_WORDS (PMO_MAC_ACTION_MAX / 32)
 
+#define RUNTIME_PM_ALLOWED_ACTION_FRAMES_BITMAP0 \
+		((1 << PMO_MAC_ACTION_SPECTRUM_MGMT) | \
+		 (1 << PMO_MAC_ACTION_QOS_MGMT) | \
+		 (1 << PMO_MAC_ACTION_PUBLIC_USAGE) | \
+		 (1 << PMO_MAC_ACTION_RRM) | \
+		 (1 << PMO_MAC_ACTION_SA_QUERY) | \
+		 (1 << PMO_MAC_ACTION_PROT_DUAL_PUB) | \
+		 (1 << PMO_MAC_ACTION_WNM) | \
+		 (1 << PMO_MAC_ACTION_WME) | \
+		 (1 << PMO_MAC_ACTION_FST) | \
+		 (1 << PMO_MAC_ACTION_VHT))
+
 /* Public Action for 20/40 BSS Coexistence */
 #define PMO_MAC_ACTION_MEASUREMENT_PILOT    7
 

+ 0 - 1
components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c

@@ -280,7 +280,6 @@ QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
 
 	/* Register static configuration with firmware */
 	pmo_register_wow_wakeup_events(vdev);
-	pmo_register_action_frame_patterns(vdev);
 
 	/* Register default wow patterns with firmware */
 	pmo_register_wow_default_patterns(vdev);

+ 13 - 0
components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c

@@ -32,6 +32,7 @@
 #include "wlan_pmo_pkt_filter.h"
 #include "wlan_pmo_hw_filter.h"
 #include "wlan_pmo_cfg.h"
+#include "wlan_pmo_static_config.h"
 #include "cfg_ucfg_api.h"
 
 QDF_STATUS ucfg_pmo_psoc_open(struct wlan_objmgr_psoc *psoc)
@@ -467,6 +468,18 @@ QDF_STATUS ucfg_pmo_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
 	return pmo_core_enable_hw_filter_in_fwr(vdev);
 }
 
+QDF_STATUS
+ucfg_pmo_enable_action_frame_patterns(struct wlan_objmgr_vdev *vdev,
+				      enum qdf_suspend_type suspend_type)
+{
+	return pmo_register_action_frame_patterns(vdev, suspend_type);
+}
+
+QDF_STATUS ucfg_pmo_disable_action_frame_patterns(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_clear_action_frame_patterns(vdev);
+}
+
 QDF_STATUS ucfg_pmo_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
 {
 	return pmo_core_disable_hw_filter_in_fwr(vdev);

+ 29 - 0
core/hdd/src/wlan_hdd_power.c

@@ -542,6 +542,33 @@ static void hdd_disable_hw_filter(struct hdd_adapter *adapter)
 	hdd_exit();
 }
 
+static void hdd_enable_action_frame_patterns(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = ucfg_pmo_enable_action_frame_patterns(adapter->vdev,
+						       QDF_SYSTEM_SUSPEND);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_info("Failed to enable action frame patterns");
+
+	hdd_exit();
+}
+
+static void hdd_disable_action_frame_patterns(struct hdd_adapter *adapter)
+{
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = ucfg_pmo_disable_action_frame_patterns(adapter->vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_info("Failed to disable action frame patterns");
+
+	hdd_exit();
+}
+
 void hdd_enable_host_offloads(struct hdd_adapter *adapter,
 	enum pmo_offload_trigger trigger)
 {
@@ -564,6 +591,7 @@ void hdd_enable_host_offloads(struct hdd_adapter *adapter,
 	hdd_enable_ns_offload(adapter, trigger);
 	hdd_enable_mc_addr_filtering(adapter, trigger);
 	hdd_enable_hw_filter(adapter);
+	hdd_enable_action_frame_patterns(adapter);
 out:
 	hdd_exit();
 
@@ -591,6 +619,7 @@ void hdd_disable_host_offloads(struct hdd_adapter *adapter,
 	hdd_disable_ns_offload(adapter, trigger);
 	hdd_disable_mc_addr_filtering(adapter, trigger);
 	hdd_disable_hw_filter(adapter);
+	hdd_disable_action_frame_patterns(adapter);
 out:
 	hdd_exit();