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();