Переглянути джерело

qcacmn: Add support to set monitor filter dynamically

htt_h2t_rx_ring_cfg is invoked with suitable configuration based on
filter passed by wlan_set_monitor_filter.

Change-Id: I2fbb81e95903ae1bead92892fdb3165c8a515f14
nobelj 7 роки тому
батько
коміт
d124b749b7

+ 11 - 0
dp/inc/cdp_txrx_cmn.h

@@ -348,6 +348,17 @@ cdp_set_privacy_filters(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
 			filter, num);
 }
 
+static inline int
+cdp_set_monitor_filter(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+		struct cdp_monitor_filter *filter_val)
+{
+	if (soc->ops->mon_ops->txrx_set_advance_monitor_filter)
+		return soc->ops->mon_ops->txrx_set_advance_monitor_filter(pdev,
+					filter_val);
+	return 0;
+}
+
+
 /******************************************************************************
  * Data Interface (B Interface)
  *****************************************************************************/

+ 70 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -103,6 +103,55 @@
 #define CDP_MU_MAX_USERS 8
 #define CDP_MU_MAX_USER_INDEX (CDP_MU_MAX_USERS - 1)
 
+/*
+ * advance rx monitor filter
+ * */
+#define MON_FILTER_PASS			0x0001
+#define MON_FILTER_OTHER		0x0002
+#define MON_FILTER_ALL			0x0003
+
+#define FILTER_MGMT_ALL			0xFFFF
+#define FILTER_MGMT_ASSOC_REQ		0x0001
+#define FILTER_MGMT_ASSOC_RES		0x0002
+#define FILTER_MGMT_REASSOC_REQ		0x0004
+#define FILTER_MGMT_REASSOC_RES		0x0008
+#define FILTER_MGMT_PROBE_REQ		0x0010
+#define FILTER_MGMT_PROBE_RES		0x0020
+#define FILTER_MGMT_TIM_ADVT		0x0040
+#define FILTER_MGMT_RESERVED_7		0x0080
+#define FILTER_MGMT_BEACON		0x0100
+#define FILTER_MGMT_ATIM		0x0200
+#define FILTER_MGMT_DISASSOC		0x0400
+#define FILTER_MGMT_AUTH		0x0800
+#define FILTER_MGMT_DEAUTH		0x1000
+#define FILTER_MGMT_ACTION		0x2000
+#define FILTER_MGMT_ACT_NO_ACK		0x4000
+#define FILTER_MGMT_RESERVED_15		0x8000
+
+#define FILTER_CTRL_ALL			0xFFFF
+#define FILTER_CTRL_RESERVED_1		0x0001
+#define FILTER_CTRL_RESERVED_2		0x0002
+#define FILTER_CTRL_TRIGGER		0x0004
+#define FILTER_CTRL_RESERVED_4		0x0008
+#define FILTER_CTRL_BF_REP_POLL		0x0010
+#define FILTER_CTRL_VHT_NDP		0x0020
+#define FILTER_CTRL_FRAME_EXT		0x0040
+#define FILTER_CTRL_CTRLWRAP		0x0080
+#define FILTER_CTRL_BA_REQ		0x0100
+#define FILTER_CTRL_BA			0x0200
+#define FILTER_CTRL_PSPOLL		0x0400
+#define FILTER_CTRL_RTS			0x0800
+#define FILTER_CTRL_CTS			0x1000
+#define FILTER_CTRL_ACK			0x2000
+#define FILTER_CTRL_CFEND		0x4000
+#define FILTER_CTRL_CFEND_CFACK		0x8000
+
+#define FILTER_DATA_ALL			0xFFFF
+#define FILTER_DATA_MCAST		0x4000
+#define FILTER_DATA_UCAST		0x8000
+#define FILTER_DATA_DATA		0x0001
+#define FILTER_DATA_NULL		0x0008
+
 /*
  * DP configuration parameters
  */
@@ -1359,4 +1408,25 @@ struct cdp_txrx_stats_req {
 	uint32_t	param2;
 	uint32_t	param3;
 };
+
+/**
+ * struct cdp_monitor_filter - monitor filter info
+ * @mode: set filter mode
+ * @fp_mgmt: set Filter Pass MGMT Configuration
+ * @fp_ctrl: set Filter Pass CTRL Configuration
+ * @fp_data: set Filter Pass DATA Configuration
+ * @mo_mgmt: set Monitor Other MGMT Configuration
+ * @mo_ctrl: set Monitor Other CTRL Configuration
+ * @mo_data: set Monitor other DATA Configuration
+ *
+ */
+struct cdp_monitor_filter {
+	uint16_t mode;
+	uint16_t fp_mgmt;
+	uint16_t fp_ctrl;
+	uint16_t fp_data;
+	uint16_t mo_mgmt;
+	uint16_t mo_ctrl;
+	uint16_t mo_data;
+};
 #endif

+ 3 - 0
dp/inc/cdp_txrx_ops.h

@@ -490,6 +490,9 @@ struct cdp_mon_ops {
 		(struct cdp_vdev *vdev_txrx_handle);
 	int (*txrx_reset_monitor_mode)(struct cdp_pdev *pdev);
 
+	/* HK advance monitor filter support */
+	int (*txrx_set_advance_monitor_filter)
+		(struct cdp_pdev *pdev, struct cdp_monitor_filter *filter_val);
 };
 
 struct cdp_host_stats_ops {

+ 258 - 98
dp/wifi3.0/dp_htt.c

@@ -815,26 +815,48 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	*msg_word = 0;
 
 	if (htt_tlv_filter->enable_fp) {
+		/* TYPE: MGMT */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0000,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_ASSOC_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0001,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_ASSOC_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0010,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_REASSOC_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0011,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_REASSOC_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0100,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_PROBE_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0101,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_PROBE_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 0110,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_TIM_ADVT) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0001, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0110, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 0111, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 1000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
-				MGMT, 1001, 1);
+			MGMT, 0111,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_RESERVED_7) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 1000,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_BEACON) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			FP, MGMT, 1001,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_ATIM) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_md) {
@@ -861,26 +883,48 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_mo) {
+		/* TYPE: MGMT */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0000,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_ASSOC_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0001,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_ASSOC_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0010,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_REASSOC_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0011,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_REASSOC_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0100,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_PROBE_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0101,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_PROBE_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 0110,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_TIM_ADVT) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0001, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0110, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 0111, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 1000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
-				MGMT, 1001, 1);
+			MGMT, 0111,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_RESERVED_7) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 1000,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_BEACON) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MO, MGMT, 1001,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_ATIM) ? 1 : 0);
 	}
 
 	/* word 3 */
@@ -888,18 +932,32 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	*msg_word = 0;
 
 	if (htt_tlv_filter->enable_fp) {
+		/* TYPE: MGMT */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			FP, MGMT, 1010,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_DISASSOC) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			FP, MGMT, 1011,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_AUTH) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			FP, MGMT, 1100,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_DEAUTH) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			FP, MGMT, 1101,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_ACTION) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			FP, MGMT, 1110,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_ACT_NO_ACK) ? 1 : 0);
+		/* reserved*/
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
-				MGMT, 1010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
-				MGMT, 1011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
-				MGMT, 1100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
-				MGMT, 1101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
-				MGMT, 1110, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
-				MGMT, 1111, 1);
+			MGMT, 1111,
+			(htt_tlv_filter->fp_mgmt_filter &
+			FILTER_MGMT_RESERVED_15) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_md) {
@@ -916,18 +974,32 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_mo) {
+		/* TYPE: MGMT */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MO, MGMT, 1010,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_DISASSOC) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MO, MGMT, 1011,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_AUTH) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MO, MGMT, 1100,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_DEAUTH) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MO, MGMT, 1101,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_ACTION) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MO, MGMT, 1110,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_ACT_NO_ACK) ? 1 : 0);
+		/* reserved*/
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
-				MGMT, 1010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
-				MGMT, 1011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
-				MGMT, 1100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
-				MGMT, 1101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
-				MGMT, 1110, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
-				MGMT, 1111, 1);
+			MGMT, 1111,
+			(htt_tlv_filter->mo_mgmt_filter &
+			FILTER_MGMT_RESERVED_15) ? 1 : 0);
 	}
 
 	/* word 4 */
@@ -935,26 +1007,50 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	*msg_word = 0;
 
 	if (htt_tlv_filter->enable_fp) {
+		/* TYPE: CTRL */
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0000, 1);
+			CTRL, 0000,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_RESERVED_1) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0001, 1);
+			CTRL, 0001,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_RESERVED_2) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0010, 1);
+			CTRL, 0010,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_TRIGGER) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0011, 1);
+			CTRL, 0011,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_RESERVED_4) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0100, 1);
+			CTRL, 0100,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_BF_REP_POLL) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0101, 1);
+			CTRL, 0101,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_VHT_NDP) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0110, 1);
+			CTRL, 0110,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_FRAME_EXT) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 0111, 1);
+			CTRL, 0111,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_CTRLWRAP) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 1000, 1);
+			CTRL, 1000,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_BA_REQ) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
-				CTRL, 1001, 1);
+			CTRL, 1001,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_BA) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_md) {
@@ -981,50 +1077,94 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_mo) {
+		/* TYPE: CTRL */
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0000, 1);
+			CTRL, 0000,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_RESERVED_1) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0001, 1);
+			CTRL, 0001,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_RESERVED_2) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0010, 1);
+			CTRL, 0010,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_TRIGGER) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0011, 1);
+			CTRL, 0011,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_RESERVED_4) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0100, 1);
+			CTRL, 0100,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_BF_REP_POLL) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0101, 1);
+			CTRL, 0101,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_VHT_NDP) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0110, 1);
+			CTRL, 0110,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_FRAME_EXT) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0111, 1);
+			CTRL, 0111,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_CTRLWRAP) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 1000, 1);
+			CTRL, 1000,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_BA_REQ) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 1001, 1);
+			CTRL, 1001,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_BA) ? 1 : 0);
 	}
 
 	/* word 5 */
 	msg_word++;
 	*msg_word = 0;
 	if (htt_tlv_filter->enable_fp) {
+		/* TYPE: CTRL */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				CTRL, 1010, 1);
+			CTRL, 1010,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_PSPOLL) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				CTRL, 1011, 1);
+			CTRL, 1011,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_RTS) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				CTRL, 1100, 1);
+			CTRL, 1100,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_CTS) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				CTRL, 1101, 1);
+			CTRL, 1101,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_ACK) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				CTRL, 1110, 1);
+			CTRL, 1110,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_CFEND) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				CTRL, 1111, 1);
+			CTRL, 1111,
+			(htt_tlv_filter->fp_ctrl_filter &
+			FILTER_CTRL_CFEND_CFACK) ? 1 : 0);
+		/* TYPE: DATA */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				DATA, MCAST, 1);
+			DATA, MCAST,
+			(htt_tlv_filter->fp_data_filter &
+			FILTER_DATA_MCAST) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				DATA, UCAST, 1);
+			DATA, UCAST,
+			(htt_tlv_filter->fp_data_filter &
+			FILTER_DATA_UCAST) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
-				DATA, NULL, 1);
+			DATA, NULL,
+			(htt_tlv_filter->fp_data_filter &
+			FILTER_DATA_NULL) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_md) {
@@ -1049,24 +1189,44 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_mo) {
+		/* TYPE: CTRL */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				CTRL, 1010, 1);
+			CTRL, 1010,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_PSPOLL) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				CTRL, 1011, 1);
+			CTRL, 1011,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_RTS) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				CTRL, 1100, 1);
+			CTRL, 1100,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_CTS) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				CTRL, 1101, 1);
+			CTRL, 1101,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_ACK) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				CTRL, 1110, 1);
+			CTRL, 1110,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_CFEND) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				CTRL, 1111, 1);
+			CTRL, 1111,
+			(htt_tlv_filter->mo_ctrl_filter &
+			FILTER_CTRL_CFEND_CFACK) ? 1 : 0);
+		/* TYPE: DATA */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				DATA, MCAST, 1);
+			DATA, MCAST,
+			(htt_tlv_filter->mo_data_filter &
+			FILTER_DATA_MCAST) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				DATA, UCAST, 1);
+			DATA, UCAST,
+			(htt_tlv_filter->mo_data_filter &
+			FILTER_DATA_UCAST) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
-				DATA, NULL, 1);
+			DATA, NULL,
+			(htt_tlv_filter->mo_data_filter &
+			FILTER_DATA_NULL) ? 1 : 0);
 	}
 
 	/* word 6 */

+ 9 - 0
dp/wifi3.0/dp_htt.h

@@ -105,6 +105,9 @@ struct htt_soc {
  * @enable_fp: enable/disable FP packet
  * @enable_md: enable/disable MD packet
  * @enable_mo: enable/disable MO packet
+ * @enable_mgmt: enable/disable MGMT packet
+ * @enable_ctrl: enable/disable CTRL packet
+ * @enable_data: enable/disable DATA packet
  */
 struct htt_rx_ring_tlv_filter {
 	u_int32_t mpdu_start:1,
@@ -123,6 +126,12 @@ struct htt_rx_ring_tlv_filter {
 		enable_fp:1,
 		enable_md:1,
 		enable_mo:1;
+	u_int32_t fp_mgmt_filter:16,
+		mo_mgmt_filter:16;
+	u_int32_t fp_ctrl_filter:16,
+		mo_ctrl_filter:16;
+	u_int32_t fp_data_filter:16,
+		mo_data_filter:16;
 };
 
 void *

+ 175 - 4
dp/wifi3.0/dp_main.c

@@ -2263,6 +2263,15 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 	}
 	DP_STATS_INIT(pdev);
 
+	/* Monitor filter init */
+	pdev->mon_filter_mode = MON_FILTER_ALL;
+	pdev->fp_mgmt_filter = FILTER_MGMT_ALL;
+	pdev->fp_ctrl_filter = FILTER_CTRL_ALL;
+	pdev->fp_data_filter = FILTER_DATA_ALL;
+	pdev->mo_mgmt_filter = FILTER_MGMT_ALL;
+	pdev->mo_ctrl_filter = FILTER_CTRL_ALL;
+	pdev->mo_data_filter = FILTER_DATA_ALL;
+
 #ifndef CONFIG_WIN
 	/* MCL */
 	dp_local_peer_id_pool_init(pdev);
@@ -3517,6 +3526,13 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle,
 	if (smart_monitor)
 		return QDF_STATUS_SUCCESS;
 
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+		"MODE[%x] FP[%02x|%02x|%02x] MO[%02x|%02x|%02x]\n",
+		pdev->mon_filter_mode, pdev->fp_mgmt_filter,
+		pdev->fp_ctrl_filter, pdev->fp_data_filter,
+		pdev->mo_mgmt_filter, pdev->mo_ctrl_filter,
+		pdev->mo_data_filter);
+
 	htt_tlv_filter.mpdu_start = 1;
 	htt_tlv_filter.msdu_start = 1;
 	htt_tlv_filter.packet = 1;
@@ -3530,9 +3546,17 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle,
 	htt_tlv_filter.ppdu_end_user_stats_ext = 0;
 	htt_tlv_filter.ppdu_end_status_done = 0;
 	htt_tlv_filter.header_per_msdu = 1;
-	htt_tlv_filter.enable_fp = 1;
+	htt_tlv_filter.enable_fp =
+		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
 	htt_tlv_filter.enable_md = 0;
-	htt_tlv_filter.enable_mo = 1;
+	htt_tlv_filter.enable_mo =
+		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
+	htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
+	htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
+	htt_tlv_filter.fp_data_filter = pdev->fp_data_filter;
+	htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
+	htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
+	htt_tlv_filter.mo_data_filter = pdev->mo_data_filter;
 
 	htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
 		pdev->rxdma_mon_buf_ring.hal_srng,
@@ -3551,9 +3575,136 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle,
 	htt_tlv_filter.ppdu_end_user_stats_ext = 1;
 	htt_tlv_filter.ppdu_end_status_done = 1;
 	htt_tlv_filter.header_per_msdu = 0;
-	htt_tlv_filter.enable_fp = 1;
+	htt_tlv_filter.enable_fp =
+		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
+	htt_tlv_filter.enable_md = 0;
+	htt_tlv_filter.enable_mo =
+		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
+	htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
+	htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
+	htt_tlv_filter.fp_data_filter = pdev->fp_data_filter;
+	htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
+	htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
+	htt_tlv_filter.mo_data_filter = pdev->mo_data_filter;
+
+	htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
+		pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS,
+		RX_BUFFER_SIZE, &htt_tlv_filter);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_pdev_set_advance_monitor_filter() - Set DP PDEV monitor filter
+ * @pdev_handle: Datapath PDEV handle
+ * @filter_val: Flag to select Filter for monitor mode
+ * Return: 0 on success, not 0 on failure
+ */
+static int dp_pdev_set_advance_monitor_filter(struct cdp_pdev *pdev_handle,
+	struct cdp_monitor_filter *filter_val)
+{
+	/* Many monitor VAPs can exists in a system but only one can be up at
+	 * anytime
+	 */
+	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
+	struct dp_vdev *vdev = pdev->monitor_vdev;
+	struct htt_rx_ring_tlv_filter htt_tlv_filter;
+	struct dp_soc *soc;
+	uint8_t pdev_id;
+
+	pdev_id = pdev->pdev_id;
+	soc = pdev->soc;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
+		"pdev=%pK, pdev_id=%d, soc=%pK vdev=%pK\n",
+		pdev, pdev_id, soc, vdev);
+
+	/*Check if current pdev's monitor_vdev exists */
+	if (!pdev->monitor_vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"vdev=%pK\n", vdev);
+		qdf_assert(vdev);
+	}
+
+	/* update filter mode, type in pdev structure */
+	pdev->mon_filter_mode = filter_val->mode;
+	pdev->fp_mgmt_filter = filter_val->fp_mgmt;
+	pdev->fp_ctrl_filter = filter_val->fp_ctrl;
+	pdev->fp_data_filter = filter_val->fp_data;
+	pdev->mo_mgmt_filter = filter_val->mo_mgmt;
+	pdev->mo_ctrl_filter = filter_val->mo_ctrl;
+	pdev->mo_data_filter = filter_val->mo_data;
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+		"MODE[%x] FP[%02x|%02x|%02x] MO[%02x|%02x|%02x]\n",
+		pdev->mon_filter_mode, pdev->fp_mgmt_filter,
+		pdev->fp_ctrl_filter, pdev->fp_data_filter,
+		pdev->mo_mgmt_filter, pdev->mo_ctrl_filter,
+		pdev->mo_data_filter);
+
+	qdf_mem_set(&(htt_tlv_filter), sizeof(htt_tlv_filter), 0x0);
+
+	htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
+		pdev->rxdma_mon_buf_ring.hal_srng,
+		RXDMA_MONITOR_BUF, RX_BUFFER_SIZE, &htt_tlv_filter);
+
+	htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
+		pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS,
+		RX_BUFFER_SIZE, &htt_tlv_filter);
+
+	htt_tlv_filter.mpdu_start = 1;
+	htt_tlv_filter.msdu_start = 1;
+	htt_tlv_filter.packet = 1;
+	htt_tlv_filter.msdu_end = 1;
+	htt_tlv_filter.mpdu_end = 1;
+	htt_tlv_filter.packet_header = 1;
+	htt_tlv_filter.attention = 1;
+	htt_tlv_filter.ppdu_start = 0;
+	htt_tlv_filter.ppdu_end = 0;
+	htt_tlv_filter.ppdu_end_user_stats = 0;
+	htt_tlv_filter.ppdu_end_user_stats_ext = 0;
+	htt_tlv_filter.ppdu_end_status_done = 0;
+	htt_tlv_filter.header_per_msdu = 1;
+	htt_tlv_filter.enable_fp =
+		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
+	htt_tlv_filter.enable_md = 0;
+	htt_tlv_filter.enable_mo =
+		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
+	htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
+	htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
+	htt_tlv_filter.fp_data_filter = pdev->fp_data_filter;
+	htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
+	htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
+	htt_tlv_filter.mo_data_filter = pdev->mo_data_filter;
+
+	htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
+		pdev->rxdma_mon_buf_ring.hal_srng, RXDMA_MONITOR_BUF,
+		RX_BUFFER_SIZE, &htt_tlv_filter);
+
+	htt_tlv_filter.mpdu_start = 1;
+	htt_tlv_filter.msdu_start = 1;
+	htt_tlv_filter.packet = 0;
+	htt_tlv_filter.msdu_end = 1;
+	htt_tlv_filter.mpdu_end = 1;
+	htt_tlv_filter.packet_header = 1;
+	htt_tlv_filter.attention = 1;
+	htt_tlv_filter.ppdu_start = 1;
+	htt_tlv_filter.ppdu_end = 1;
+	htt_tlv_filter.ppdu_end_user_stats = 1;
+	htt_tlv_filter.ppdu_end_user_stats_ext = 1;
+	htt_tlv_filter.ppdu_end_status_done = 1;
+	htt_tlv_filter.header_per_msdu = 0;
+	htt_tlv_filter.enable_fp =
+		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
 	htt_tlv_filter.enable_md = 0;
-	htt_tlv_filter.enable_mo = 1;
+	htt_tlv_filter.enable_mo =
+		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
+	htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
+	htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
+	htt_tlv_filter.fp_data_filter = pdev->fp_data_filter;
+	htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
+	htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
+	htt_tlv_filter.mo_data_filter = pdev->mo_data_filter;
 
 	htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id,
 		pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS,
@@ -4661,6 +4812,12 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev)
 	htt_tlv_filter.enable_fp = 1;
 	htt_tlv_filter.enable_md = 0;
 	htt_tlv_filter.enable_mo = 0;
+	htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
+	htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
+	htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
+	htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
+	htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
+	htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
 
 	htt_h2t_rx_ring_cfg(pdev->soc->htt_handle, pdev->pdev_id,
 		pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS,
@@ -5550,6 +5707,8 @@ static struct cdp_mon_ops dp_ops_mon = {
 	.txrx_monitor_get_filter_mcast_data = NULL,
 	.txrx_monitor_get_filter_non_data = NULL,
 	.txrx_reset_monitor_mode = dp_reset_monitor_mode,
+	/* Added support for HK advance filter */
+	.txrx_set_advance_monitor_filter = dp_pdev_set_advance_monitor_filter,
 };
 
 static struct cdp_host_stats_ops dp_ops_host_stats = {
@@ -5996,6 +6155,12 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				htt_tlv_filter.ppdu_end_user_stats_ext = 1;
 				htt_tlv_filter.ppdu_end_status_done = 1;
 				htt_tlv_filter.enable_fp = 1;
+				htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
+				htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
+				htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
+				htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
+				htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
+				htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
 
 				for (mac_id = 0; mac_id < max_mac_rings;
 								mac_id++) {
@@ -6033,6 +6198,12 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				htt_tlv_filter.ppdu_end_status_done = 1;
 				htt_tlv_filter.mpdu_start = 1;
 				htt_tlv_filter.enable_fp = 1;
+				htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
+				htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
+				htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
+				htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
+				htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
+				htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
 
 				for (mac_id = 0; mac_id < max_mac_rings;
 								mac_id++) {

+ 9 - 0
dp/wifi3.0/dp_types.h

@@ -1003,6 +1003,15 @@ struct dp_pdev {
 	/* Enhanced Stats is enabled */
 	bool enhanced_stats_en;
 
+	/* advance filter mode and type*/
+	uint8_t mon_filter_mode;
+	uint16_t fp_mgmt_filter;
+	uint16_t fp_ctrl_filter;
+	uint16_t fp_data_filter;
+	uint16_t mo_mgmt_filter;
+	uint16_t mo_ctrl_filter;
+	uint16_t mo_data_filter;
+
 	qdf_atomic_t num_tx_outstanding;
 
 	qdf_atomic_t num_tx_exception;