Răsfoiți Sursa

qcacmn: Add support for Mesh Rx filters

Added support to filter out received packets on mesh vap based on
rx filter setting.

Change-Id: Ibc541324d928a9d006531c8908f4792e0c7d854e
CRs-Fixed: 2003389
Venkateswara Swamy Bandaru 8 ani în urmă
părinte
comite
ec4f8e61c6
6 a modificat fișierele cu 292 adăugiri și 2 ștergeri
  1. 18 0
      dp/inc/cdp_txrx_ctrl.h
  2. 10 0
      dp/inc/cdp_txrx_ops.h
  3. 18 1
      dp/wifi3.0/dp_main.c
  4. 76 1
      dp/wifi3.0/dp_rx.c
  5. 7 0
      dp/wifi3.0/dp_types.h
  6. 163 0
      dp/wifi3.0/hal_rx.h

+ 18 - 0
dp/inc/cdp_txrx_ctrl.h

@@ -262,6 +262,24 @@ static inline void cdp_set_mesh_mode
 	return;
 }
 
+/**
+ * @brief set mesh rx filter
+ * @details based on the bits enabled in the filter packets has to be dropped.
+ *
+ * @param soc - pointer to the soc
+ * @param vdev - the data virtual device object
+ * @param val - value to be set
+ * @return - void
+ */
+static inline
+void cdp_set_mesh_rx_filter(ol_txrx_soc_handle soc,
+				struct cdp_vdev *vdev, uint32_t val)
+{
+	if (soc->ops->ctrl_ops->txrx_set_mesh_rx_filter)
+		return soc->ops->ctrl_ops->txrx_set_mesh_rx_filter(vdev, val);
+	return;
+}
+
 static inline void cdp_tx_flush_buffers
 (ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
 {

+ 10 - 0
dp/inc/cdp_txrx_ops.h

@@ -329,6 +329,16 @@ struct cdp_ctrl_ops {
 	/* Should be ol_txrx_ctrl_api.h */
 	void (*txrx_set_mesh_mode)(struct cdp_vdev *vdev, u_int32_t val);
 
+	/**
+	 * @brief setting mesh rx filter
+	 * @details
+	 *  based on the bits enabled in the filter packets has to be dropped.
+	 *
+	 * @param vdev - the data virtual device object
+	 * @param val - value to set
+	 */
+	void (*txrx_set_mesh_rx_filter)(struct cdp_vdev *vdev, uint32_t val);
+
 	void (*tx_flush_buffers)(struct cdp_vdev *vdev);
 
 	int (*txrx_is_target_ar900b)(struct cdp_vdev *vdev);

+ 18 - 1
dp/wifi3.0/dp_main.c

@@ -1831,7 +1831,7 @@ static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3(struct cdp_vdev *pvdev)
 }
 
 #ifdef MESH_MODE_SUPPORT
-void dp_peer_set_mesh_mode(struct cdp_vdev *vdev_hdl, u_int32_t val)
+void dp_peer_set_mesh_mode(struct cdp_vdev *vdev_hdl, uint32_t val)
 {
 	struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
 
@@ -1839,6 +1839,22 @@ void dp_peer_set_mesh_mode(struct cdp_vdev *vdev_hdl, u_int32_t val)
 		FL("%s: val %d"), __func__, val);
 	vdev->mesh_vdev = val;
 }
+
+/*
+ * dp_peer_set_mesh_rx_filter() - to set the mesh rx filter
+ * @vdev_hdl: virtual device object
+ * @val: value to be set
+ *
+ * Return: void
+ */
+void dp_peer_set_mesh_rx_filter(struct cdp_vdev *vdev_hdl, uint32_t val)
+{
+	struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
+		FL("val %d"), val);
+	vdev->mesh_rx_filter = val;
+}
 #endif
 
 static struct cdp_cmn_ops dp_ops_cmn = {
@@ -1868,6 +1884,7 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
 	.txrx_set_tx_encap_type = dp_set_vdev_tx_encap_type,
 #ifdef MESH_MODE_SUPPORT
 	.txrx_set_mesh_mode  = dp_peer_set_mesh_mode,
+	.txrx_set_mesh_rx_filter = dp_peer_set_mesh_rx_filter,
 #endif
 	/* TODO: Add other functions */
 };

+ 76 - 1
dp/wifi3.0/dp_rx.c

@@ -291,12 +291,77 @@ void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 						rx_info->rs_keyix);
 
 }
+
+/**
+ * dp_rx_fill_mesh_stats() - Filters mesh unwanted packets
+ *
+ * @vdev: DP Virtual device handle
+ * @nbuf: Buffer pointer
+ *
+ * This checks if the received packet is matching any filter out
+ * catogery and and drop the packet if it matches.
+ *
+ * Return: status(0 indicates drop, 1 indicate to no drop)
+ */
+
+static inline
+QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
+{
+	uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf);
+	union dp_align_mac_addr mac_addr;
+
+	if (qdf_unlikely(vdev->mesh_rx_filter)) {
+		if (vdev->mesh_rx_filter & MESH_FILTER_OUT_FROMDS)
+			if (hal_rx_mpdu_get_fr_ds(rx_tlv_hdr))
+				return  QDF_STATUS_SUCCESS;
+
+		if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TODS)
+			if (hal_rx_mpdu_get_to_ds(rx_tlv_hdr))
+				return  QDF_STATUS_SUCCESS;
+
+		if (vdev->mesh_rx_filter & MESH_FILTER_OUT_NODS)
+			if (!hal_rx_mpdu_get_fr_ds(rx_tlv_hdr)
+				&& !hal_rx_mpdu_get_to_ds(rx_tlv_hdr))
+				return  QDF_STATUS_SUCCESS;
+
+		if (vdev->mesh_rx_filter & MESH_FILTER_OUT_RA) {
+			if (hal_rx_mpdu_get_addr1(rx_tlv_hdr,
+					&mac_addr.raw[0]))
+				return QDF_STATUS_E_FAILURE;
+
+			if (!qdf_mem_cmp(&mac_addr.raw[0],
+					&vdev->mac_addr.raw[0],
+					DP_MAC_ADDR_LEN))
+				return  QDF_STATUS_SUCCESS;
+		}
+
+		if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TA) {
+			if (hal_rx_mpdu_get_addr2(rx_tlv_hdr,
+					&mac_addr.raw[0]))
+				return QDF_STATUS_E_FAILURE;
+
+			if (!qdf_mem_cmp(&mac_addr.raw[0],
+					&vdev->mac_addr.raw[0],
+					DP_MAC_ADDR_LEN))
+				return  QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 #else
 static
 void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 {
 }
 
+static inline
+QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
 #endif
 
 
@@ -541,8 +606,18 @@ done:
 			/* Set length in nbuf */
 			qdf_nbuf_set_pktlen(nbuf, pkt_len);
 
-			if (qdf_unlikely(vdev->mesh_vdev))
+			if (qdf_unlikely(vdev->mesh_vdev)) {
+				if (dp_rx_filter_mesh_packets(vdev, nbuf)
+						== QDF_STATUS_SUCCESS) {
+					QDF_TRACE(QDF_MODULE_ID_DP,
+						QDF_TRACE_LEVEL_INFO_MED,
+						FL("mesh pkt filtered"));
+
+					qdf_nbuf_free(nbuf);
+					continue;
+				}
 				dp_rx_fill_mesh_stats(vdev, nbuf);
+			}
 
 			/*
 			 * Advance the packet start pointer by total size of

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

@@ -578,6 +578,10 @@ union dp_align_mac_addr {
 		uint32_t bytes_abcd;
 		uint16_t bytes_ef;
 	} align4;
+	struct {
+		uint16_t bytes_ab;
+		uint32_t bytes_cdef;
+	} align4_2;
 };
 
 #define MAX_HTT_METADATA_LEN 32
@@ -663,6 +667,9 @@ struct dp_vdev {
 	/* Mesh mode vdev */
 	uint32_t mesh_vdev;
 
+	/* Mesh mode rx filter setting */
+	uint32_t mesh_rx_filter;
+
 	/* DSCP-TID mapping table ID */
 	uint8_t dscp_tid_map_id;
 

+ 163 - 0
dp/wifi3.0/hal_rx.h

@@ -990,6 +990,169 @@ hal_rx_msdu_start_nss_get(uint8_t *buf)
 	return nss;
 }
 
+#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info,	\
+		RX_MPDU_INFO_2_TO_DS_OFFSET)),	\
+		RX_MPDU_INFO_2_TO_DS_MASK,	\
+		RX_MPDU_INFO_2_TO_DS_LSB))
+
+/*
+ * hal_rx_mpdu_get_tods(): API to get the tods info
+ * from rx_mpdu_start
+ *
+ * @buf: pointer to the start of RX PKT TLV header
+ * Return: uint32_t(to_ds)
+ */
+
+static inline uint32_t
+hal_rx_mpdu_get_to_ds(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_mpdu_start *mpdu_start =
+				 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
+
+	struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
+	uint32_t to_ds;
+
+	to_ds = HAL_RX_MPDU_GET_TODS(mpdu_info);
+
+	return to_ds;
+}
+
+#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info,	\
+		RX_MPDU_INFO_2_FR_DS_OFFSET)),	\
+		RX_MPDU_INFO_2_FR_DS_MASK,	\
+		RX_MPDU_INFO_2_FR_DS_LSB))
+
+/*
+ * hal_rx_mpdu_get_fr_ds(): API to get the from ds info
+ * from rx_mpdu_start
+ *
+ * @buf: pointer to the start of RX PKT TLV header
+ * Return: uint32_t(fr_ds)
+ */
+
+static inline uint32_t
+hal_rx_mpdu_get_fr_ds(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_mpdu_start *mpdu_start =
+				 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
+
+	struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
+	uint32_t fr_ds;
+
+	fr_ds = HAL_RX_MPDU_GET_FROMDS(mpdu_info);
+
+	return fr_ds;
+}
+
+#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
+		RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \
+		RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK,	\
+		RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB))
+
+#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
+		RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \
+		RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK,	\
+		RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB))
+
+#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
+		RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \
+		RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK,	\
+		RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB))
+
+#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
+		RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \
+		RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK,	\
+		RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB))
+
+#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
+		RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \
+		RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK,	\
+		RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB))
+
+#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
+		RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \
+		RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK,	\
+		RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB))
+
+/*
+ * hal_rx_mpdu_get_addr1(): API to check get address1 of the mpdu
+ *
+ * @buf: pointer to the start of RX PKT TLV headera
+ * @mac_addr: pointer to mac address
+ * Return: sucess/failure
+ */
+static inline
+QDF_STATUS hal_rx_mpdu_get_addr1(uint8_t *buf, uint8_t *mac_addr)
+{
+	struct __attribute__((__packed__)) hal_addr1 {
+		uint32_t ad1_31_0;
+		uint16_t ad1_47_32;
+	};
+
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_mpdu_start *mpdu_start =
+				 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
+
+	struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
+	struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr;
+	uint32_t mac_addr_ad1_valid;
+
+	mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info);
+
+	if (mac_addr_ad1_valid) {
+		addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info);
+		addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/*
+ * hal_rx_mpdu_get_addr2(): API to check get address2 of the mpdu
+ * in the packet
+ *
+ * @buf: pointer to the start of RX PKT TLV header
+ * @mac_addr: pointer to mac address
+ * Return: sucess/failure
+ */
+static inline
+QDF_STATUS hal_rx_mpdu_get_addr2(uint8_t *buf, uint8_t *mac_addr)
+{
+	struct __attribute__((__packed__)) hal_addr2 {
+		uint16_t ad2_15_0;
+		uint32_t ad2_47_16;
+	};
+
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_mpdu_start *mpdu_start =
+				 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
+
+	struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
+	struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr;
+	uint32_t mac_addr_ad2_valid;
+
+	mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info);
+
+	if (mac_addr_ad2_valid) {
+		addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info);
+		addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 /*******************************************************************************
  * RX ERROR APIS
  ******************************************************************************/