summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h20
-rw-r--r--core/hdd/inc/wlan_hdd_power.h18
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c10
-rw-r--r--core/hdd/src/wlan_hdd_power.c38
-rw-r--r--core/mac/inc/sir_api.h10
-rw-r--r--core/mac/src/include/sir_params.h3
-rw-r--r--core/mac/src/sys/legacy/src/utils/src/mac_trace.c2
-rw-r--r--core/sme/inc/sme_api.h22
-rw-r--r--core/sme/src/common/sme_api.c112
-rw-r--r--core/wma/inc/wma_internal.h12
-rw-r--r--core/wma/inc/wma_types.h5
-rw-r--r--core/wma/src/wma_features.c34
-rw-r--r--core/wma/src/wma_main.c7
13 files changed, 293 insertions, 0 deletions
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 10bf01aa7471..bdbcab9df473 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -7027,6 +7027,25 @@ enum dot11p_mode {
#define CFG_ACTIVE_BPF_MODE_MAX (ACTIVE_BPF_MODE_COUNT - 1)
#define CFG_ACTIVE_BPF_MODE_DEFAULT (ACTIVE_BPF_DISABLED)
+/*
+ * <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)
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -7736,6 +7755,7 @@ struct hdd_config {
uint32_t max_sched_scan_plan_iterations;
uint8_t enable_phy_reg_retention;
enum active_bpf_mode active_bpf_mode;
+ bool hw_broadcast_filter;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
index e7b43ccdff53..22233ea29444 100644
--- a/core/hdd/inc/wlan_hdd_power.h
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -163,6 +163,24 @@ QDF_STATUS hdd_wlan_re_init(void);
QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable);
void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, bool fenable);
+/**
+ * hdd_set_non_arp_hw_broadcast_filter() - enable HW Broadcast filter
+ * when target goes to wow suspend/resume mode
+ * @adapter: Adapter context for which broadcast filter is to be configured
+ *
+ * Return: zero if success, non-zero otherwise
+ */
+int hdd_set_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter);
+
+/**
+ * hdd_clear_non_arp_hw_broadcast_filter() - disable HW Broadcast filter
+ * when target goes to wow suspend/resume mode
+ * @adapter: Adapter context for which broadcast filter is to be configured
+ *
+ * Return: zero if success, non-zero otherwise
+ */
+int hdd_clear_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter);
+
#ifdef WLAN_FEATURE_PACKET_FILTERING
int wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set);
#else
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index e1919f2f7bde..5a2d14f89456 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -4223,6 +4223,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ACTIVE_BPF_MODE_DEFAULT,
CFG_ACTIVE_BPF_MODE_MIN,
CFG_ACTIVE_BPF_MODE_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),
};
/**
@@ -5699,6 +5706,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_info("Name = [%s] Value = [%u]",
CFG_ENABLE_PHY_REG_NAME,
pHddCtx->config->enable_phy_reg_retention);
+ hdd_err("Name = [%s] Value = [%u]",
+ CFG_HW_BC_FILTER_NAME,
+ pHddCtx->config->hw_broadcast_filter);
hdd_per_roam_print_ini_config(pHddCtx);
}
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 925707dbb795..f5a47e03b739 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -654,6 +654,20 @@ void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, bool fenable)
hdd_conf_ns_offload(pAdapter, fenable);
}
+ /*
+ * Filter Non-Arp HW broadcast filter when target goes to
+ * wow suspend/resume mode
+ */
+ if (pHddCtx->config->hw_broadcast_filter) {
+ if (fenable) {
+ hdd_info("set hw broadcast fliter");
+ hdd_set_non_arp_hw_broadcast_filter(pAdapter);
+ } else {
+ hdd_info("clear hw broadcast fliter");
+ hdd_clear_non_arp_hw_broadcast_filter(pAdapter);
+ }
+ }
+
EXIT();
return;
}
@@ -907,6 +921,30 @@ QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable)
}
}
+int hdd_set_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter)
+{
+ if (QDF_STATUS_SUCCESS !=
+ sme_enable_non_arp_broadcast_filter(
+ WLAN_HDD_GET_HAL_CTX(adapter), adapter->sessionId)) {
+ hdd_err("Failed to enable broadcast filter");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int hdd_clear_non_arp_hw_broadcast_filter(hdd_adapter_t *adapter)
+{
+ if (QDF_STATUS_SUCCESS !=
+ sme_disable_nonarp_broadcast_filter(
+ WLAN_HDD_GET_HAL_CTX(adapter), adapter->sessionId)) {
+ hdd_err("Failed to disable broadcast filter");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
#ifdef WLAN_FEATURE_PACKET_FILTERING
/**
* wlan_hdd_set_mc_addr_list() - set MC address list in FW
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 7db6a76770cd..edff9f5e30fa 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -2698,6 +2698,16 @@ typedef struct sSirNsOffloadReq {
} tSirNsOffloadReq, *tpSirNsOffloadReq;
#endif /* WLAN_NS_OFFLOAD */
+/**
+ * struct broadcast_filter_request - For enable/disable HW Broadcast Filter
+ * @enable: value to enable disable feature
+ * @bss_id: bss_id for get session.
+ */
+struct broadcast_filter_request {
+ bool enable;
+ struct qdf_mac_addr bssid;
+};
+
typedef struct sSirHostOffloadReq {
uint8_t offloadType;
uint8_t enableOrDisable;
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index affb1642b172..87455ced90a1 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -650,6 +650,9 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_GET_RCPI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 372)
+#define SIR_HAL_ENABLE_BCAST_FILTER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 373)
+#define SIR_HAL_DISABLE_BCAST_FILTER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 374)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* CFG message types */
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
index 8f4d75b0bc0e..add2fa762386 100644
--- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -644,6 +644,8 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
CASE_RETURN_STRING(WMA_FW_MEM_DUMP_REQ);
CASE_RETURN_STRING(WMA_SET_WISA_PARAMS);
CASE_RETURN_STRING(WMA_GET_RCPI_REQ);
+ CASE_RETURN_STRING(WMA_ENABLE_BCAST_FILTER);
+ CASE_RETURN_STRING(WMA_DISABLE_HW_BCAST_FILTER);
default:
return (uint8_t *) "UNKNOWN";
break;
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 16d5f96a58f8..b8a076fd3ffa 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -471,6 +471,28 @@ QDF_STATUS sme_roam_update_apwparsni_es(tHalHandle hHal, uint8_t sessionId,
QDF_STATUS sme_change_mcc_beacon_interval(tHalHandle hHal, uint8_t sessionId);
QDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId,
tpSirHostOffloadReq pRequest);
+
+/**
+ * sme_enable_non_arp_broadcast_filter(): API to enable Broadcast filter
+ * when target goes to wow suspend/resume mode
+ * @hal: The handle returned by mac_open.
+ * @session_id: Session Identifier
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_enable_non_arp_broadcast_filter(tHalHandle hal,
+ uint8_t session_id);
+/**
+ * sme_disable_nonarp_broadcast_filter(): API to disable Broadcast filter
+ * when target goes to wow suspend/resume mode
+ * @hal: The handle returned by mac_open.
+ * @session_id: Session Identifier
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS sme_disable_nonarp_broadcast_filter(tHalHandle hal,
+ uint8_t session_id);
+
QDF_STATUS sme_set_keep_alive(tHalHandle hHal, uint8_t sessionId,
tpSirKeepAliveReq pRequest);
QDF_STATUS sme_get_operation_channel(tHalHandle hHal, uint32_t *pChannel,
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index a41ff6c1ce34..11c4ded56130 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -6368,6 +6368,118 @@ QDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId,
return status;
}
+QDF_STATUS sme_enable_non_arp_broadcast_filter(tHalHandle hal,
+ uint8_t session_id)
+{
+ struct broadcast_filter_request *request_buf;
+ cds_msg_t msg;
+
+ tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+ status = sme_acquire_global_lock(&pMac->sme);
+
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ tCsrRoamSession *session = CSR_GET_SESSION(pMac, session_id);
+
+ if (NULL == session) {
+ sme_release_global_lock(&pMac->sme);
+ sms_log(pMac, LOGE, FL("Session not found "));
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ request_buf = qdf_mem_malloc(sizeof(*request_buf));
+ if (NULL == request_buf) {
+ sme_release_global_lock(&pMac->sme);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Not able to allocate memory for bc filter request"));
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ qdf_copy_macaddr(&request_buf->bssid,
+ &session->connectedProfile.bssid);
+
+ request_buf->enable = true;
+
+ msg.type = WMA_ENABLE_BCAST_FILTER;
+ msg.reserved = 0;
+ msg.bodyptr = request_buf;
+ MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+ session_id, msg.type));
+ if (QDF_STATUS_SUCCESS !=
+ cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
+ sme_release_global_lock(&pMac->sme);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Not able to post WMA_ENABLE_BCAST_FILTER message to HAL"));
+ qdf_mem_free(request_buf);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ sme_release_global_lock(&pMac->sme);
+ } else {
+ sms_log(pMac, LOGE, FL("sme_acquire_global_lock failed"));
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return status;
+}
+
+QDF_STATUS sme_disable_nonarp_broadcast_filter(tHalHandle hal,
+ uint8_t session_id)
+{
+ struct broadcast_filter_request *request_buf;
+ cds_msg_t msg;
+
+ tpAniSirGlobal pMac = PMAC_STRUCT(hal);
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+ status = sme_acquire_global_lock(&pMac->sme);
+
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ tCsrRoamSession *session = CSR_GET_SESSION(pMac, session_id);
+
+ if (NULL == session) {
+ sme_release_global_lock(&pMac->sme);
+ sms_log(pMac, LOGE, FL("Session not found "));
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ request_buf = qdf_mem_malloc(sizeof(*request_buf));
+ if (NULL == request_buf) {
+ sme_release_global_lock(&pMac->sme);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Not able to allocate memory for bc filter request"));
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ qdf_copy_macaddr(&request_buf->bssid,
+ &session->connectedProfile.bssid);
+
+ request_buf->enable = false;
+
+ msg.type = WMA_DISABLE_HW_BCAST_FILTER;
+ msg.reserved = 0;
+ msg.bodyptr = request_buf;
+ MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+ session_id, msg.type));
+ if (QDF_STATUS_SUCCESS !=
+ cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
+ sme_release_global_lock(&pMac->sme);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Not able to post WMA_DISABLE_HW_BCAST_FILTER message to HAL"));
+ qdf_mem_free(request_buf);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ sme_release_global_lock(&pMac->sme);
+ } else {
+ sms_log(pMac, LOGE, FL("sme_acquire_global_lock failed"));
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return status;
+}
+
#ifdef WLAN_FEATURE_GTK_OFFLOAD
/**
* sme_set_gtk_offload(): API to set GTK offload information.
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index ecd31a487f4a..2ba525f8f8bf 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -1038,6 +1038,18 @@ QDF_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
tpSirHostOffloadReq pHostOffloadParams,
bool bArpOnly);
+/**
+ * wma_configure_non_arp_broadcast_filter() - API to Enable/Disable Broadcast
+ * filter
+ * when target goes to wow suspend/resume mode
+ * @wma: wma handle
+ * @bcastFilter: broadcast filter request
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS wma_configure_non_arp_broadcast_filter(tp_wma_handle wma,
+ struct broadcast_filter_request *bcast_filter);
+
QDF_STATUS wma_process_cesium_enable_ind(tp_wma_handle wma);
QDF_STATUS wma_process_get_peer_info_req
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index 815234ffc4a7..a2e4346432e3 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -252,6 +252,11 @@
#ifdef WLAN_NS_OFFLOAD
#define WMA_SET_NS_OFFLOAD SIR_HAL_SET_NS_OFFLOAD
#endif /* WLAN_NS_OFFLOAD */
+
+#define WMA_ENABLE_BCAST_FILTER SIR_HAL_ENABLE_BCAST_FILTER
+#define WMA_DISABLE_HW_BCAST_FILTER SIR_HAL_DISABLE_BCAST_FILTER
+
+
#define WMA_ADD_STA_SELF_REQ SIR_HAL_ADD_STA_SELF_REQ
#define WMA_DEL_STA_SELF_REQ SIR_HAL_DEL_STA_SELF_REQ
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index f720ec1d6f71..d115e7e6bffa 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -5580,6 +5580,40 @@ QDF_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
return QDF_STATUS_SUCCESS;
}
+QDF_STATUS wma_configure_non_arp_broadcast_filter(tp_wma_handle wma,
+ struct broadcast_filter_request *bcast_filter)
+{
+ int32_t res;
+ uint8_t vdev_id;
+
+ /* Get the vdev id */
+ if (!wma_find_vdev_by_bssid(wma, bcast_filter->bssid.bytes,
+ &vdev_id)) {
+ WMA_LOGE("vdev handle is invalid for %pM",
+ bcast_filter->bssid.bytes);
+ qdf_mem_free(bcast_filter);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!wma->interfaces[vdev_id].vdev_up) {
+ WMA_LOGE("vdev %d is not up skipping enable Broadcast Filter",
+ vdev_id);
+ qdf_mem_free(bcast_filter);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ res = wmi_unified_configure_broadcast_filter_cmd(wma->wmi_handle,
+ vdev_id, bcast_filter->enable);
+
+ if (res) {
+ WMA_LOGE("Failed to enable/disable Broadcast Filter");
+ qdf_mem_free(bcast_filter);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ qdf_mem_free(bcast_filter);
+ return QDF_STATUS_SUCCESS;
+}
/**
* wma_process_cesium_enable_ind() - enables cesium functionality in target
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index d7274c2c6f4b..28ba82df84bf 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -7119,6 +7119,13 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
wma_get_rcpi_req(wma_handle,
(struct sme_rcpi_req *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
+ case WMA_ENABLE_BCAST_FILTER:
+ wma_configure_non_arp_broadcast_filter(wma_handle,
+ (struct broadcast_filter_request *) msg->bodyptr);
+ break;
+ case WMA_DISABLE_HW_BCAST_FILTER:
+ wma_configure_non_arp_broadcast_filter(wma_handle,
+ (struct broadcast_filter_request *) msg->bodyptr);
break;
default:
WMA_LOGE("Unhandled WMA message of type %d", msg->type);