diff --git a/components/pmo/core/inc/wlan_pmo_main.h b/components/pmo/core/inc/wlan_pmo_main.h
index 26af6ee269..efcf76efb4 100644
--- a/components/pmo/core/inc/wlan_pmo_main.h
+++ b/components/pmo/core/inc/wlan_pmo_main.h
@@ -385,6 +385,40 @@ pmo_intersect_packet_filter(struct pmo_psoc_priv_obj *psoc_ctx)
psoc_ctx->caps.packet_filter;
}
+/*
+ * pmo_enable_ssr_on_page_fault: Enable/disable ssr on pagefault
+ * @psoc: objmgr psoc
+ *
+ * Return: True if SSR is enabled on pagefault
+ */
+bool pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * pmo_get_max_pagefault_wakeups_for_ssr: get pagefault wakeups for ssr
+ * @psoc: objmgr psoc
+ *
+ * Return: SSR interval for pagefault
+ */
+uint8_t
+pmo_get_max_pagefault_wakeups_for_ssr(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * pmo_get_interval_for_pagefault_wakeup_counts: get ssr interval for pagefault
+ * @psoc: objmgr psoc
+ *
+ * Return: SSR interval for pagefault
+ */
+uint32_t
+pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * pmo_get_ssr_frequency_on_pagefault: get ssr frequency on pagefault
+ * @psoc: objmgr psoc
+ *
+ * Return: SSR frequency on pagefault
+ */
+uint32_t pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc);
+
#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
#endif /* end of _WLAN_PMO_MAIN_H_ */
diff --git a/components/pmo/core/src/wlan_pmo_main.c b/components/pmo/core/src/wlan_pmo_main.c
index acec4b6235..041a3924d9 100644
--- a/components/pmo/core/src/wlan_pmo_main.c
+++ b/components/pmo/core/src/wlan_pmo_main.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021,2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -291,6 +291,18 @@ static void wlan_pmo_init_cfg(struct wlan_objmgr_psoc *psoc,
psoc_cfg->disconnect_sap_tdls_in_wow =
cfg_get(psoc, CFG_DISCONNECT_SAP_TDLS_IN_WOW);
wlan_pmo_get_icmp_offload_enable_cfg(psoc, psoc_cfg);
+
+ psoc_cfg->enable_ssr_on_page_fault =
+ cfg_get(psoc,
+ CFG_ENABLE_SSR_ON_PAGEFAULT);
+ psoc_cfg->max_pagefault_wakeups_for_ssr =
+ cfg_get(psoc,
+ CFG_MAX_PAGEFAULT_WAKEUPS_FOR_SSR);
+ psoc_cfg->interval_for_pagefault_wakeup_counts =
+ cfg_get(psoc,
+ CFG_INTERVAL_FOR_PAGEFAULT_WAKEUP_COUNT);
+ psoc_cfg->ssr_frequency_on_pagefault =
+ cfg_get(psoc, CFG_SSR_FREQUENCY_ON_PAGEFAULT);
}
QDF_STATUS pmo_psoc_open(struct wlan_objmgr_psoc *psoc)
@@ -487,3 +499,44 @@ uint8_t pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc)
return txrx_pdev_id;
}
+
+bool pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (!pmo_psoc_ctx)
+ return 0;
+
+ return pmo_psoc_ctx->psoc_cfg.enable_ssr_on_page_fault;
+}
+
+uint8_t pmo_get_max_pagefault_wakeups_for_ssr(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (!pmo_psoc_ctx)
+ return 0;
+
+ return pmo_psoc_ctx->psoc_cfg.max_pagefault_wakeups_for_ssr;
+}
+
+uint32_t
+pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (!pmo_psoc_ctx)
+ return 0;
+
+ return pmo_psoc_ctx->psoc_cfg.interval_for_pagefault_wakeup_counts;
+}
+
+uint32_t pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (!pmo_psoc_ctx)
+ return 0;
+
+ return pmo_psoc_ctx->psoc_cfg.ssr_frequency_on_pagefault;
+}
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h
index 271b1d27ec..2d41d2e5c4 100644
--- a/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h
+++ b/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -609,6 +609,115 @@
0, \
"disconnect sap tdls in wow")
+/*
+ *
+ * enable_ssr_on_page_fault - Enable SSR on pagefault
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This INI is used to enable/disable SSR when host is woken up with the reason
+ * as pagefault.
+ * For ex: If enable_ssr_on_page_fault = 1, max_pagefault_wakeups_for_ssr = 30,
+ * interval_for_pagefault_wakeup_counts = 180000 (3 mins) and
+ * ssr_frequency_on_pagefault = 3600000 (1hr), in this case host will trigger
+ * the SSR if it receives 30 wakeups because of pagefaults in 3 mins, host will
+ * trigger SSR only once in 1 hr. Once the SSR is triggered, host will not
+ * trigger next SSR for next 1 hr even if it receives 30 wakeups from fw because
+ * of pagefaults. This 1 hr time is getting monitored from last SSR.
+ *
+ *
+ */
+#define CFG_ENABLE_SSR_ON_PAGEFAULT CFG_INI_BOOL( \
+ "enable_ssr_on_page_fault", \
+ 0, \
+ "Enable SSR on pagefault")
+
+/*
+ *
+ * max_pagefault_wakeups_for_ssr - Max number of pagefaults wakeups to trigger
+ * SSR
+ * @Min: 1
+ * @Max: 255
+ * @Default: 30
+ *
+ * This ini is used to trigger SSR if fw wakes up host for
+ * max_pagefault_wakeups_for_ssr number of times in
+ * interval_for_pagefault_wakeup_counts interval. SSR is triggered only once
+ * in ssr_frequency_on_pagefault interval.
+ * For ex: If enable_ssr_on_page_fault = 1, max_pagefault_wakeups_for_ssr = 30,
+ * interval_for_pagefault_wakeup_counts = 180000 (3 mins) and
+ * ssr_frequency_on_pagefault = 3600000 (1hr), in this case host will trigger
+ * the SSR if it receives 30 wakeups because of pagefaults in 3 mins, host will
+ * trigger SSR only once in 1 hr. Once the SSR is triggered, host will not
+ * trigger next SSR for next 1 hr even if it receives 30 wakeups from fw because
+ * of pagefaults. This 1 hr time is getting monitored from last SSR.
+ */
+#define CFG_MAX_PAGEFAULT_WAKEUPS_FOR_SSR CFG_INI_UINT( \
+ "max_pagefault_wakeups_for_ssr", \
+ 1, \
+ 255, \
+ 30, \
+ CFG_VALUE_OR_DEFAULT, \
+ "Max number of pagefaults wakeups to trigger SSR")
+
+/*
+ *
+ * interval_for_pagefault_wakeup_counts - Time in ms in which
+ * max_pagefault_wakeups_for_ssr needs to be monitored
+ * @Min: 60000
+ * @Max: 300000
+ * @Default: 180000 (3 mins)
+ *
+ * This ini define time in ms in which max_pagefault_wakeups_for_ssr needs to be
+ * Monitored. If in interval_for_pagefault_wakeup_counts ms,
+ * max_pagefault_wakeups_for_ssr is reached host will trigger the SSR.
+ * SSR is triggered only once in ssr_frequency_on_pagefault interval.
+ * For ex: If enable_ssr_on_page_fault = 1, max_pagefault_wakeups_for_ssr = 30,
+ * interval_for_pagefault_wakeup_counts = 180000 (3 mins) and
+ * ssr_frequency_on_pagefault = 3600000 (1hr), in this case host will trigger
+ * the SSR if it receives 30 wakeups because of pagefaults in 3 mins, host will
+ * trigger SSR only once in 1 hr. Once the SSR is triggered, host will not
+ * trigger next SSR for next 1 hr even if it receives 30 wakeups from fw because
+ * of pagefaults. This 1 hr time is getting monitored from last SSR.
+ */
+#define CFG_INTERVAL_FOR_PAGEFAULT_WAKEUP_COUNT CFG_INI_UINT( \
+ "interval_for_pagefault_wakeup_counts", \
+ 60000, \
+ 300000, \
+ 180000, \
+ CFG_VALUE_OR_DEFAULT, \
+ "Interval in which max_pagefault_wakeups_for_ssr needs to be monitored")
+
+/*
+ *
+ * ssr_frequency_on_pagefault - Time in ms in which host needs to trigger the
+ * next SSR
+ * @Min: 60000
+ * @Max: 7200000
+ * @Default: 3600000 (1 hr)
+ *
+ * This ini define time in ms in which next SSR needs to be triggered if
+ * max_pagefault_wakeups_for_ssr is reached in
+ * interval_for_pagefault_wakeup_counts time.
+ * INIs max_pagefault_wakeups_for_ssr, interval_for_pagefault_wakeup_counts and
+ * ssr_frequency_on_pagefault needs to be considered together.
+ * For ex: If enable_ssr_on_page_fault = 1, max_pagefault_wakeups_for_ssr = 30,
+ * interval_for_pagefault_wakeup_counts = 180000 (3 mins) and
+ * ssr_frequency_on_pagefault = 3600000 (1hr), in this case host will trigger
+ * the SSR if it receives 30 wakeups because of pagefaults in 3 mins, host will
+ * trigger SSR only once in 1 hr. Once the SSR is triggered, host will not
+ * trigger next SSR for next 1 hr even if it receives 30 wakeups from fw because
+ * of pagefaults. This 1 hr time is getting monitored from last SSR.
+ */
+#define CFG_SSR_FREQUENCY_ON_PAGEFAULT CFG_INI_UINT( \
+ "ssr_frequency_on_pagefault", \
+ 60000, \
+ 7200000, \
+ 3600000, \
+ CFG_VALUE_OR_DEFAULT, \
+ "Interval in which max_pagefault_wakeups_for_ssr needs to be monitored")
+
/*
*
* gEnableIcmpOffload - Enable/disable ICMP offload
@@ -654,6 +763,10 @@
CFG(CFG_ENABLE_BUS_SUSPEND_IN_GO_MODE)\
CFG(CFG_DISCONNECT_SAP_TDLS_IN_WOW) \
CFG(CFG_IGMP_VERSION_SUPPORT) \
- CFG(CFG_ENABLE_ICMP_OFFLOAD)
+ CFG(CFG_ENABLE_ICMP_OFFLOAD) \
+ CFG(CFG_ENABLE_SSR_ON_PAGEFAULT) \
+ CFG(CFG_MAX_PAGEFAULT_WAKEUPS_FOR_SSR) \
+ CFG(CFG_INTERVAL_FOR_PAGEFAULT_WAKEUP_COUNT) \
+ CFG(CFG_SSR_FREQUENCY_ON_PAGEFAULT)
#endif /* WLAN_PMO_COMMON_CFG_H__ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
index 946bfbf89a..834443a294 100644
--- a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
+++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
@@ -397,6 +397,13 @@ struct pmo_icmp_offload {
* @disconnect_sap_tdls_in_wow: sap/p2p_go disconnect or teardown tdls link
* @is_icmp_offload_enable: true if icmp offload is supported
* for psoc else false
+ * @enable_ssr_on_page_fault: Enable ssr on pagefault
+ * @max_pagefault_wakeups_for_ssr: Maximum number of pagefaults after which host
+ * needs to trigger SSR
+ * @interval_for_pagefault_wakeup_counts: Time in ms in which max pagefault
+ * wakeups needs to be monitored.
+ * @ssr_frequency_on_pagefault: Time in ms in which SSR needs to be triggered
+ * on max pagefault
*/
struct pmo_psoc_cfg {
bool ptrn_match_enable_all_vdev;
@@ -477,6 +484,10 @@ struct pmo_psoc_cfg {
#ifdef WLAN_FEATURE_ICMP_OFFLOAD
bool is_icmp_offload_enable;
#endif
+ bool enable_ssr_on_page_fault;
+ uint8_t max_pagefault_wakeups_for_ssr;
+ uint32_t interval_for_pagefault_wakeup_counts;
+ uint32_t ssr_frequency_on_pagefault;
};
/**
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
index 370e397d0b..76690d78bb 100644
--- a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
@@ -292,6 +292,34 @@ wlan_pmo_get_sap_mode_bus_suspend(struct wlan_objmgr_psoc *psoc);
bool
wlan_pmo_get_go_mode_bus_suspend(struct wlan_objmgr_psoc *psoc);
+/*
+ * wlan_pmo_enable_ssr_on_page_fault: Enable/disable ssr on pagefault
+ * @psoc: objmgr psoc
+ *
+ * Return: True if SSR is enabled on pagefault
+ */
+bool wlan_pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * wlan_pmo_get_max_pagefault_wakeups_for_ssr: get max pagefault wakeups for ssr
+ * @psoc: objmgr psoc
+ *
+ * Return: Max pagefault wakeups for SSR
+ */
+uint8_t
+wlan_pmo_get_max_pagefault_wakeups_for_ssr(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * wlan_pmo_get_interval_for_pagefault_wakeup_counts: get ssr interval for
+ * pagefault
+ * @psoc: objmgr psoc
+ *
+ * Return: SSR interval for pagefault
+ */
+uint32_t
+wlan_pmo_get_interval_for_pagefault_wakeup_counts(
+ struct wlan_objmgr_psoc *psoc);
+
#else /* WLAN_POWER_MANAGEMENT_OFFLOAD */
static inline QDF_STATUS pmo_init(void)
@@ -455,6 +483,24 @@ wlan_pmo_get_go_mode_bus_suspend(struct wlan_objmgr_psoc *psoc)
return false;
}
+static inline bool
+wlan_pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc)
+{
+ return 0;
+}
+
+static inline uint8_t
+wlan_pmo_get_max_pagefault_wakeups_for_ssr(struct wlan_objmgr_psoc *psoc)
+{
+ return 0;
+}
+
+static inline uint32_t
+wlan_pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc)
+{
+ return 0;
+}
+
#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
#endif /* end of _WLAN_PMO_OBJ_MGMT_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
index 39acf86d75..5031397cf8 100644
--- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
@@ -1355,6 +1355,14 @@ bool ucfg_pmo_get_moddtim_user_active(struct wlan_objmgr_vdev *vdev);
*/
uint32_t ucfg_pmo_get_moddtim_user(struct wlan_objmgr_vdev *vdev);
+/*
+ * ucfg_pmo_get_ssr_frequency_on_pagefault: get ssr frequency on pagefault
+ * @psoc: objmgr psoc
+ *
+ * Return: SSR frequency on pagefault
+ */
+uint32_t ucfg_pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc);
+
/*
* ucfg_pmo_get_disconnect_sap_tdls_in_wow: get if disconnect sap/p2p_go
* or tdls in wow
@@ -2104,6 +2112,12 @@ ucfg_pmo_get_moddtim_user(struct wlan_objmgr_vdev *vdev)
return 0;
}
+static inline uint32_t
+ucfg_pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc)
+{
+ return 0;
+}
+
static inline bool
ucfg_pmo_get_disconnect_sap_tdls_in_wow(struct wlan_objmgr_psoc *psoc)
{
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 be4c3e56ab..84f27184af 100644
--- a/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
+++ b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -888,3 +889,20 @@ wlan_pmo_get_go_mode_bus_suspend(struct wlan_objmgr_psoc *psoc)
return pmo_psoc_ctx->psoc_cfg.is_bus_suspend_enabled_in_go_mode;
}
+
+bool wlan_pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_enable_ssr_on_page_fault(psoc);
+}
+
+uint8_t
+wlan_pmo_get_max_pagefault_wakeups_for_ssr(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_get_max_pagefault_wakeups_for_ssr(psoc);
+}
+
+uint32_t
+wlan_pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_get_interval_for_pagefault_wakeup_counts(psoc);
+}
diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
index d80fcb483e..485e76e1b5 100644
--- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
+++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1024,6 +1024,12 @@ uint32_t ucfg_pmo_get_moddtim_user(struct wlan_objmgr_vdev *vdev)
return pmo_core_vdev_get_moddtim_user(vdev);
}
+uint32_t
+ucfg_pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_get_ssr_frequency_on_pagefault(psoc);
+}
+
bool
ucfg_pmo_get_disconnect_sap_tdls_in_wow(struct wlan_objmgr_psoc *psoc)
{