qcacld-2.0: Monitor mode - Frame filtering
Use WMI Monitor mode Filter CMD to send frame type
to firmware for filtering
Add iwpriv option for user to select frame type
iwpriv wlan0 setMonFilter FrameType
Change-Id: Ib22dc782d01de83ada3b6effb277436c7e386014
CRs-Fixed: 2169766
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 49708b9..bcc7967 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -245,6 +245,13 @@
#define WE_SET_MODULATED_DTIM 88
+#define WE_SET_MON_FILTER 89
+typedef enum eMonFilterType{
+ MON_MGMT_PKT,
+ MON_CTRL_PKT,
+ MON_DATA_PKT,
+ MON_ALL_PKT,
+} tMonFilterType;
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -369,33 +376,33 @@
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
-#define WE_LOG_DUMP_CMD 1
+#define WE_LOG_DUMP_CMD 1
-#define WE_P2P_NOA_CMD 2
+#define WE_P2P_NOA_CMD 2
//IOCTL to configure MCC params
-#define WE_MCC_CONFIG_CREDENTIAL 3
-#define WE_MCC_CONFIG_PARAMS 4
+#define WE_MCC_CONFIG_CREDENTIAL 3
+#define WE_MCC_CONFIG_PARAMS 4
#ifdef FEATURE_WLAN_TDLS
-#define WE_TDLS_CONFIG_PARAMS 5
+#define WE_TDLS_CONFIG_PARAMS 5
#endif
-#define WE_IBSS_GET_PEER_INFO 6
-#define WE_UNIT_TEST_CMD 7
+#define WE_IBSS_GET_PEER_INFO 6
+#define WE_UNIT_TEST_CMD 7
-#define WE_MTRACE_DUMP_CMD 8
+#define WE_MTRACE_DUMP_CMD 8
#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9
#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
-#define WE_LED_FLASHING_PARAM 10
+#define WE_LED_FLASHING_PARAM 10
#endif
#ifdef MEMORY_DEBUG
-#define WE_MEM_TRACE_DUMP 11
+#define WE_MEM_TRACE_DUMP 11
#endif
#ifdef FEATURE_WLAN_TDLS
#undef MAX_VAR_ARGS
-#define MAX_VAR_ARGS 11
+#define MAX_VAR_ARGS 11
#else
-#define MAX_VAR_ARGS 7
+#define MAX_VAR_ARGS 7
#endif
/* Private ioctls (with no sub-ioctls) */
@@ -5997,6 +6004,51 @@
return VOS_STATUS_SUCCESS;
}
+/**
+ * wlan_hdd_mnt_filter_type_cmd() - set filter packet type
+ * configuration to firmware
+ * @data: pointer to filter type configuration data.
+ * @data_len: the length in byte of filter type data.
+ *
+ * This is called when wlan driver needs to set
+ * filter packet type to firmware in monitor mode.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int wlan_hdd_mnt_filter_type_cmd(hdd_adapter_t *pAdapter, v_U8_t *data,
+ int data_len)
+{
+ hdd_context_t *pHddCtx = NULL;
+ v_CONTEXT_t pVosContext = NULL;
+ struct sme_mnt_filter_type_req filter_type;
+ VOS_STATUS status;
+ int ret_val = -EIO;
+
+ /* Get the Global VOSS Context */
+ pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+ if (!pVosContext) {
+ hddLog(VOS_TRACE_LEVEL_FATAL,"%s: VOS context is Null", __func__);
+ return ret_val;
+ }
+
+ /* Get the HDD context */
+ pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
+ if (!pHddCtx) {
+ hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
+ return ret_val;
+ }
+
+ filter_type.vdev_id = pAdapter->sessionId;
+ filter_type.request_data_len = data_len;
+ filter_type.request_data = data;
+
+ status = sme_mnt_filter_type_cmd(&filter_type);
+ if (VOS_STATUS_SUCCESS == status) {
+ ret_val = 0;
+ }
+ return ret_val;
+}
+
/* set param sub-ioctls */
static int __iw_setint_getnone(struct net_device *dev,
struct iw_request_info *info,
@@ -7315,11 +7367,42 @@
}
break;
}
+ case WE_SET_MON_FILTER:
+ {
+ v_U8_t filter_type = 0;
+
+ if (VOS_MONITOR_MODE != hdd_get_conparam()) {
+ hddLog(LOGE, "Unable to set Monitor Mode Filters");
+ hddLog(LOGE, "WLAN Device is not in Monitor mode!!");
+ return -EINVAL;
+ }
+
+ if (set_value < MON_MGMT_PKT || set_value > MON_ALL_PKT) {
+ hddLog(LOGE, "Invalid Filter value recieved...");
+ hddLog(LOGE, "Valid Values to set monitor mode filter:");
+ hddLog(LOGE, "0: Filter management packets");
+ hddLog(LOGE, "1: Filter control packets");
+ hddLog(LOGE, "2: Filter data packets");
+ hddLog(LOGE, "3: Filter All packets");
+ return -EINVAL;
+ }
+ filter_type = (v_U8_t) (set_value & 0xFF);
+
+ /* filter packetin monitor mode. */
+ if (filter_type < MON_MGMT_PKT || filter_type > MON_ALL_PKT) {
+ hddLog(LOGE, "Invalid monitor mode filter type received");
+ return -EINVAL;
+ }
+
+ hddLog(LOG1, "Monitor Mode Filter type = %d", filter_type);
+ wlan_hdd_mnt_filter_type_cmd(pAdapter, &filter_type,sizeof(v_U8_t));
+ break;
+ }
default:
{
- hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
- ret = -EINVAL;
- break;
+ hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
+ ret = -EINVAL;
+ break;
}
}
EXIT();
@@ -12020,6 +12103,11 @@
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "setModDTIM" },
+ {
+ WE_SET_MON_FILTER,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setMonFilter" },
+
/* handlers for sub-ioctl */
{ WE_GET_11D_STATE,
0,
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 826ae6c..4bf2841 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -798,7 +798,8 @@
#define SIR_HAL_PEER_FLUSH_PENDING (SIR_HAL_ITC_MSG_TYPES_BEGIN + 375)
#define SIR_HAL_SET_AC_TXQ_OPTIMIZE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 376)
-#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
+#define SIR_HAL_MNT_FILTER_TYPE_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 377)
+#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
#define SIR_CFG_MSG_TYPES_BEGIN (SIR_CFG_MODULE_ID << 8)
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index ef97c56..f99ad45 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -33734,6 +33734,59 @@
peer_tid_bitmap, vdev_id);
}
+/**
+ * wma_mnt_filter_type_cmd() - set filter packet type to firmware
+ * in monitor mode.
+ * @wda_handle: pointer to wma handle.
+ * @enable_monitor_req: pointer to filter type request.
+ *
+ * This is called to filter type to firmware via WMI command.
+ *
+ * Return: VOS_STATUS.
+ */
+VOS_STATUS wma_mnt_filter_type_cmd(tp_wma_handle wma_handle,
+ struct hal_mnt_filter_type_request *filter_type_req)
+{
+ wmi_mnt_filter_cmd_fixed_param *cmd;
+ int status = 0;
+ wmi_buf_t buf;
+ u_int8_t *buf_ptr;
+ int32_t len = sizeof(wmi_mnt_filter_cmd_fixed_param);
+
+ if (!wma_handle || !wma_handle->wmi_handle) {
+ WMA_LOGE(FL("WMA is closed, can not issue cmd"));
+ return VOS_STATUS_E_INVAL;
+ }
+
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP(FL("wmi_buf_alloc failed"));
+ return -ENOMEM;
+ }
+ buf_ptr = (u_int8_t *) wmi_buf_data(buf);
+ cmd = (wmi_mnt_filter_cmd_fixed_param *) buf_ptr;
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_mnt_filter_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_mnt_filter_cmd_fixed_param));
+ cmd->vdev_id = filter_type_req->vdev_id;
+ if (filter_type_req->request_data_len) {
+ vos_mem_copy(&(cmd->configure_type),
+ filter_type_req->request_data, filter_type_req->request_data_len);
+ }
+ WMA_LOGI("%s: Filter type=0x%x",__func__,cmd->configure_type);
+ status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_MNT_FILTER_CMDID);
+ if (status != EOK) {
+ WMA_LOGE("%s: wmi_unified_cmd_send WMI_MNT_FILTER_CMDID"
+ " returned Error %d",
+ __func__, status);
+ wmi_buf_free(buf);
+ return VOS_STATUS_E_FAILURE;
+ }
+ return VOS_STATUS_SUCCESS;
+}
+
/*
* function : wma_mc_process_msg
* Description :
@@ -34664,9 +34717,9 @@
(struct action_frame_random_filter *)msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
- case WDA_GET_ISOLATION:
- wma_get_isolation(wma_handle);
- break;
+ case WDA_GET_ISOLATION:
+ wma_get_isolation(wma_handle);
+ break;
case WDA_PEER_FLUSH_PENDING:
wma_peer_flush_pending(wma_handle, msg->bodyptr);
vos_mem_free(msg->bodyptr);
@@ -34675,6 +34728,11 @@
wma_set_ac_txq_optimize(wma_handle, msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
+ case WDA_MNT_FILTER_TYPE_CMD:
+ wma_mnt_filter_type_cmd(wma_handle,
+ (struct hal_mnt_filter_type_request*)msg->bodyptr);
+ vos_mem_free(msg->bodyptr);
+ break;
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 7ed05ff..777f7eb 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -297,6 +297,12 @@
uint8_t max_rssi_penalize_5g;
};
+struct sme_mnt_filter_type_req{
+ u_int32_t vdev_id;
+ u_int16_t request_data_len;
+ u_int8_t* request_data;
+};
+
/*-------------------------------------------------------------------------
Function declarations and documentation
------------------------------------------------------------------------*/
@@ -4847,4 +4853,5 @@
eHalStatus sme_set_ac_txq_optimize(tHalHandle hal_handle, uint8_t *value);
+VOS_STATUS sme_mnt_filter_type_cmd(struct sme_mnt_filter_type_req *input);
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 1206f1b..e6c6ae4 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -17943,6 +17943,49 @@
}
/**
+ * sme_mnt_filter_type_cmd() - set filter packet type to firmware
+ * @input: pointer to filter type request data.
+ *
+ * Return: VOS_STATUS.
+ */
+VOS_STATUS sme_mnt_filter_type_cmd(struct sme_mnt_filter_type_req *input)
+{
+ vos_msg_t msg;
+ struct hal_mnt_filter_type_request *data;
+ size_t data_len;
+
+ data_len = sizeof(struct hal_mnt_filter_type_request) + input->request_data_len;
+ data = vos_mem_malloc(data_len);
+
+ if (data == NULL) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Memory allocation failure"));
+ return VOS_STATUS_E_FAULT;
+ }
+
+ vos_mem_zero(data, data_len);
+ data->request_data_len = input->request_data_len;
+ data->vdev_id = input->vdev_id;
+ if (input->request_data_len) {
+ vos_mem_copy(data->request_data,
+ input->request_data, input->request_data_len);
+ }
+
+ msg.type = WDA_MNT_FILTER_TYPE_CMD;
+ msg.reserved = 0;
+ msg.bodyptr = data;
+
+ if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Not able to post WDA_MNT_FILTER_TYPE_CMD message to WDA"));
+ vos_mem_free(data);
+ return VOS_STATUS_SUCCESS;
+ }
+
+ return VOS_STATUS_SUCCESS;
+}
+
+/**
* sme_set_tsfcb() - set callback which to handle WMI_VDEV_TSF_REPORT_EVENTID
*
* @hHal: Handler return by macOpen.
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index e5f1861..0c3a8c7 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1514,4 +1514,11 @@
};
#endif
+struct hal_mnt_filter_type_request
+{
+ u_int32_t vdev_id;
+ u_int16_t request_data_len;
+ u_int8_t request_data[];
+};
+
#endif /* _HALMSGAPI_H_ */
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index de561c9..8f016c5 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1105,6 +1105,7 @@
#define WDA_ACTION_FRAME_RANDOM_MAC SIR_HAL_ACTION_FRAME_RANDOM_MAC
#define WDA_SET_AC_TXQ_OPTIMIZE SIR_HAL_SET_AC_TXQ_OPTIMIZE
+#define WDA_MNT_FILTER_TYPE_CMD SIR_HAL_MNT_FILTER_TYPE_CMD
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);