From b40c260f172685df9c7320907290d2d151d29bae Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Wed, 21 Aug 2019 14:17:48 +0530 Subject: [PATCH] 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 --- .../pmo/core/inc/wlan_pmo_static_config.h | 17 ++++++++-- .../pmo/core/src/wlan_pmo_static_config.c | 33 +++++++++++++++++-- .../pmo/core/src/wlan_pmo_suspend_resume.c | 4 +++ .../pmo/dispatcher/inc/wlan_pmo_ucfg_api.h | 22 +++++++++++++ .../inc/wlan_pmo_wow_public_struct.h | 32 ++++++++++++------ .../dispatcher/src/wlan_pmo_obj_mgmt_api.c | 1 - .../pmo/dispatcher/src/wlan_pmo_ucfg_api.c | 13 ++++++++ core/hdd/src/wlan_hdd_power.c | 29 ++++++++++++++++ 8 files changed, 134 insertions(+), 17 deletions(-) diff --git a/components/pmo/core/inc/wlan_pmo_static_config.h b/components/pmo/core/inc/wlan_pmo_static_config.h index aac288ca5717..c0b220057c29 100644 --- a/components/pmo/core/inc/wlan_pmo_static_config.h +++ b/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 diff --git a/components/pmo/core/src/wlan_pmo_static_config.c b/components/pmo/core/src/wlan_pmo_static_config.c index a0faa7d5a7c1..4ac669afb29c 100644 --- a/components/pmo/core/src/wlan_pmo_static_config.c +++ b/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; +} diff --git a/components/pmo/core/src/wlan_pmo_suspend_resume.c b/components/pmo/core/src/wlan_pmo_suspend_resume.c index c72aac78d996..b0a7c004a48e 100644 --- a/components/pmo/core/src/wlan_pmo_suspend_resume.c +++ b/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); } } diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 1a751d743619..06e0432b319d 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/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 diff --git a/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h index 19e5c8e67c85..0eb32a811ac8 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h +++ b/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 diff --git a/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c index 291abb5cc1b6..d167d336ad20 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c +++ b/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); diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index bc3615da54a2..7cd6aa222853 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/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); diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 7818c2dbcbf4..9fe32f11ca0a 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/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();