qcacld-3.0: Enable HW broadcast filter

Add ini to param to enable/disable HW filter for bc
(except arp) frame

Change-Id: I5aaa962cf9610d7f6a1922e4593748b64e32cd49
CRs-Fixed: 1113544
diff --git a/Kbuild b/Kbuild
index 45e4ed6..400eb1d 100644
--- a/Kbuild
+++ b/Kbuild
@@ -862,6 +862,7 @@
 		$(PMO_DIR)/core/src/wlan_pmo_wow.o \
 		$(PMO_DIR)/core/src/wlan_pmo_lphb.o \
 		$(PMO_DIR)/core/src/wlan_pmo_suspend_resume.o \
+		$(PMO_DIR)/core/src/wlan_pmo_hw_bcast_fltr.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_obj_mgmt_api.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_ucfg_api.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_arp.o \
@@ -871,7 +872,8 @@
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_static_config.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_lphb.o \
-		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_suspend_resume.o
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_suspend_resume.o \
+		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_non_arp_bcast_fltr.o
 
 ############## UMAC P2P ###########
 P2P_DIR := umac/p2p
@@ -930,6 +932,7 @@
 		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o \
 		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_gtk.o \
 		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_wow.o \
+		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_non_arp_bcast_fltr.o \
 		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_mc_addr_filtering.o \
 		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_static_config.o \
 		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_lphb.o \
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index a25a500..6ff7888 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -4130,6 +4130,25 @@
 
 /*
  * <ini>
+ * g_enable_non_arp_bc_hw_filter - Enable HW broadcast filtering
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini support to dynamically enable/disable Broadast filter
+ * when target goes to wow suspend/resume mode
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_HW_BC_FILTER_NAME     "g_enable_non_arp_bc_hw_filter"
+#define CFG_HW_FILTER_DEFAULT         (0)
+#define CFG_HW_FILTER_MIN             (0)
+#define CFG_HW_FILTER_MAX             (1)
+
+/*
+ * <ini>
  * BandCapability - Preferred band (0: Both,  1: 2.4G only,  2: 5G only)
  * @Min: 0
  * @Max: 2
@@ -10016,6 +10035,7 @@
 	bool bSingleTidRc;
 	uint8_t mcastBcastFilterSetting;
 	bool fhostArpOffload;
+	bool hw_broadcast_filter;
 	bool ssdp;
 
 #ifdef FEATURE_RUNTIME_PM
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
index 754c906..081a6a2 100644
--- a/core/hdd/inc/wlan_hdd_power.h
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -148,6 +148,22 @@
 QDF_STATUS hdd_wlan_re_init(void);
 
 /**
+ * hdd_enable_non_arp_hw_broadcast_filter() - API to enable broadcast filter
+ * @adapter: Adapter context for which ARP offload is to be configured
+ *
+ * Return: None
+ */
+void hdd_enable_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter);
+
+/**
+ * hdd_disable_non_arp_hw_broadcast_filter() - API to disable broadcast filter
+ * @adapter: Adapter context for which ARP offload is to be configured
+ *
+ * Return: None
+ */
+void hdd_disable_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter);
+
+/**
  * hdd_enable_arp_offload() - API to enable ARP offload
  * @adapter: Adapter context for which ARP offload is to be configured
  * @trigger: trigger reason for request
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 971c1f1..42ef43a 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -1465,6 +1465,13 @@
 		     CFG_ENABLE_HOST_ARPOFFLOAD_MIN,
 		     CFG_ENABLE_HOST_ARPOFFLOAD_MAX),
 
+	REG_VARIABLE(CFG_HW_BC_FILTER_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, hw_broadcast_filter,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_HW_FILTER_DEFAULT,
+		     CFG_HW_FILTER_MIN,
+		     CFG_HW_FILTER_MAX),
+
 #ifdef FEATURE_WLAN_RA_FILTERING
 	REG_VARIABLE(CFG_RA_FILTER_ENABLE_NAME, WLAN_PARAM_Integer,
 		     struct hdd_config, IsRArateLimitEnabled,
@@ -5280,6 +5287,8 @@
 		  pHddCtx->config->mcastBcastFilterSetting);
 	hdd_info("Name = [fhostArpOffload] Value = [%u] ",
 		  pHddCtx->config->fhostArpOffload);
+	hdd_info("Name = [hw_broadcast_filter] Value = [%u]",
+		  pHddCtx->config->hw_broadcast_filter);
 	hdd_info("Name = [ssdp] Value = [%u] ", pHddCtx->config->ssdp);
 	hdd_cfg_print_runtime_pm(pHddCtx);
 #ifdef FEATURE_WLAN_RA_FILTERING
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 505ffec..3660b99 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -10989,6 +10989,7 @@
 	psoc_cfg.bpf_enable =
 		hdd_ctx->config->bpf_packet_filter_enable;
 	psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload;
+	psoc_cfg.hw_bcast_filter = hdd_ctx->config->hw_broadcast_filter;
 	psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload;
 	if (hdd_ctx->config->fhostNSOffload)
 		psoc_cfg.ns_offload_enable_dynamic = true;
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 2e26f3d..ee3eed4 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -510,6 +510,7 @@
 	hdd_enable_arp_offload(adapter, trigger);
 	hdd_enable_ns_offload(adapter, trigger);
 	hdd_enable_mc_addr_filtering(adapter, trigger);
+	hdd_enable_non_arp_hw_broadcast_filter(adapter);
 out:
 	EXIT();
 
@@ -536,6 +537,7 @@
 	hdd_disable_arp_offload(adapter, trigger);
 	hdd_disable_ns_offload(adapter, trigger);
 	hdd_disable_mc_addr_filtering(adapter, trigger);
+	hdd_disable_non_arp_hw_broadcast_filter(adapter);
 out:
 	EXIT();
 
@@ -893,6 +895,35 @@
 	EXIT();
 }
 
+void hdd_enable_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter)
+{
+	QDF_STATUS status;
+
+	ENTER();
+
+	status = pmo_ucfg_enable_non_arp_bcast_filter_in_fwr(
+							adapter->hdd_vdev);
+
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_info("Failed to enable broadcast filter");
+
+	EXIT();
+}
+
+void hdd_disable_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter)
+{
+	QDF_STATUS status;
+
+	ENTER();
+
+	status = pmo_ucfg_disable_non_arp_bcast_filter_in_fwr(
+							adapter->hdd_vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_info("Failed to disable broadcast filter");
+
+	EXIT();
+}
+
 void hdd_enable_mc_addr_filtering(hdd_adapter_t *adapter,
 		enum pmo_offload_trigger trigger)
 {