diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index ae9c505e1193..1e4c45d7eda9 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -2537,6 +2537,43 @@ typedef enum {
#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX (65535)
#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT (90)
+/**
+ * enum station_keepalive_method - available keepalive methods for stations
+ * @HDD_STA_KEEPALIVE_NULL_DATA: null data packet
+ * @HDD_STA_KEEPALIVE_GRAT_ARP: gratuitous ARP packet
+ * @HDD_STA_KEEPALIVE_COUNT: number of method options available
+ */
+enum station_keepalive_method {
+ HDD_STA_KEEPALIVE_NULL_DATA,
+ HDD_STA_KEEPALIVE_GRAT_ARP,
+ /* keep at the end */
+ HDD_STA_KEEPALIVE_COUNT
+};
+
+/*
+ *
+ * gStaKeepAliveMethod - Which keepalive method to use
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini determines which keepalive method to use for station interfaces
+ * 1) Use null data packets
+ * 2) Use gratuitous ARP packets
+ *
+ * Related: gStaKeepAlivePeriod, gApKeepAlivePeriod, gGoKeepAlivePeriod
+ *
+ * Supported Feature: STA, Keepalive
+ *
+ * Usage: Internal/External
+ *
+ *
+ */
+#define CFG_STA_KEEPALIVE_METHOD_NAME "gStaKeepAliveMethod"
+#define CFG_STA_KEEPALIVE_METHOD_MIN (HDD_STA_KEEPALIVE_NULL_DATA)
+#define CFG_STA_KEEPALIVE_METHOD_MAX (HDD_STA_KEEPALIVE_COUNT - 1)
+#define CFG_STA_KEEPALIVE_METHOD_DEFAULT (HDD_STA_KEEPALIVE_GRAT_ARP)
+
/* WMM configuration */
/*
*
@@ -8852,6 +8889,7 @@ enum hdd_wext_control {
#define CFG_EXTWOW_TCP_RX_TIMEOUT_DEFAULT (200)
#endif
+
/*
* Type declarations
*/
@@ -8901,6 +8939,7 @@ struct hdd_config {
uint8_t enableLTECoex;
uint32_t apKeepAlivePeriod;
uint32_t goKeepAlivePeriod;
+ enum station_keepalive_method sta_keepalive_method;
uint32_t apLinkMonitorPeriod;
uint32_t goLinkMonitorPeriod;
uint32_t nBeaconInterval;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 0fba0191aecf..634aa5f5f62d 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -1591,6 +1591,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MIN,
CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX),
+ REG_VARIABLE(CFG_STA_KEEPALIVE_METHOD_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, sta_keepalive_method,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_STA_KEEPALIVE_METHOD_DEFAULT,
+ CFG_STA_KEEPALIVE_METHOD_MIN,
+ CFG_STA_KEEPALIVE_METHOD_MAX),
+
REG_VARIABLE(CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME, WLAN_PARAM_Integer,
struct hdd_config, AddTSWhenACMIsOff,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 4be1736cf620..7f77c959ff1e 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -687,11 +687,18 @@ static int hdd_set_grat_arp_keepalive(hdd_adapter_t *adapter)
*/
static void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
{
- hdd_adapter_t *pAdapter =
- container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
+ hdd_adapter_t *adapter;
+ hdd_context_t *hdd_ctx;
+
ENTER();
- hdd_enable_arp_offload(pAdapter, pmo_ipv4_change_notify);
- hdd_set_grat_arp_keepalive(pAdapter);
+
+ adapter = container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
+ hdd_enable_arp_offload(adapter, pmo_ipv4_change_notify);
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ if (hdd_ctx->config->sta_keepalive_method == HDD_STA_KEEPALIVE_GRAT_ARP)
+ hdd_set_grat_arp_keepalive(adapter);
+
EXIT();
}