[dpdk-dev] [PATCH 04/56] net/sfc: import libefx filters support

Andrew Rybchenko arybchenko at solarflare.com
Mon Nov 21 16:00:18 CET 2016


Filtering capabilities depend on NIC family and used firmware
variant. Provided API allows to get supported filter types
(in a priority order), add/delete individual filters and
restore entire filter table after, for example, NIC management
CPU reboot.

Rx filters allow to redirect matching flow to specified Rx queue.

Tx filters allow to control generated traffic (e.g. to implement
virtual function anti-spoofing control).

EFSYS_OPT_FILTER should be enabled to use it. It is required
for SFN7xxx and SFN8xxx adapter families support.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
 drivers/net/sfc/efx/base/efx.h        | 157 ++++++++++++++++
 drivers/net/sfc/efx/base/efx_check.h  |   5 +
 drivers/net/sfc/efx/base/efx_filter.c | 332 ++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/base/efx_impl.h   |  38 ++++
 4 files changed, 532 insertions(+)
 create mode 100644 drivers/net/sfc/efx/base/efx_filter.c

diff --git a/drivers/net/sfc/efx/base/efx.h b/drivers/net/sfc/efx/base/efx.h
index 79c6fdc..485ce51 100644
--- a/drivers/net/sfc/efx/base/efx.h
+++ b/drivers/net/sfc/efx/base/efx.h
@@ -1044,6 +1044,163 @@ efx_tx_qdestroy(
 
 /* FILTER */
 
+#if EFSYS_OPT_FILTER
+
+#define	EFX_ETHER_TYPE_IPV4 0x0800
+#define	EFX_ETHER_TYPE_IPV6 0x86DD
+
+#define	EFX_IPPROTO_TCP 6
+#define	EFX_IPPROTO_UDP 17
+
+typedef enum efx_filter_flag_e {
+	EFX_FILTER_FLAG_RX_RSS = 0x01,		/* use RSS to spread across
+						 * multiple queues */
+	EFX_FILTER_FLAG_RX_SCATTER = 0x02,	/* enable RX scatter */
+	EFX_FILTER_FLAG_RX_OVER_AUTO = 0x04,	/* Override an automatic filter
+						 * (priority EFX_FILTER_PRI_AUTO).
+						 * May only be set by the filter
+						 * implementation for each type.
+						 * A removal request will
+						 * restore the automatic filter
+						 * in its place. */
+	EFX_FILTER_FLAG_RX = 0x08,		/* Filter is for RX */
+	EFX_FILTER_FLAG_TX = 0x10,		/* Filter is for TX */
+} efx_filter_flag_t;
+
+typedef enum efx_filter_match_flags_e {
+	EFX_FILTER_MATCH_REM_HOST = 0x0001,	/* Match by remote IP host
+						 * address */
+	EFX_FILTER_MATCH_LOC_HOST = 0x0002,	/* Match by local IP host
+						 * address */
+	EFX_FILTER_MATCH_REM_MAC = 0x0004,	/* Match by remote MAC address */
+	EFX_FILTER_MATCH_REM_PORT = 0x0008,	/* Match by remote TCP/UDP port */
+	EFX_FILTER_MATCH_LOC_MAC = 0x0010,	/* Match by remote TCP/UDP port */
+	EFX_FILTER_MATCH_LOC_PORT = 0x0020,	/* Match by local TCP/UDP port */
+	EFX_FILTER_MATCH_ETHER_TYPE = 0x0040,	/* Match by Ether-type */
+	EFX_FILTER_MATCH_INNER_VID = 0x0080,	/* Match by inner VLAN ID */
+	EFX_FILTER_MATCH_OUTER_VID = 0x0100,	/* Match by outer VLAN ID */
+	EFX_FILTER_MATCH_IP_PROTO = 0x0200,	/* Match by IP transport
+						 * protocol */
+	EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400,	/* Match by local MAC address
+						 * I/G bit. Used for RX default
+						 * unicast and multicast/
+						 * broadcast filters. */
+} efx_filter_match_flags_t;
+
+typedef enum efx_filter_priority_s {
+	EFX_FILTER_PRI_HINT = 0,	/* Performance hint */
+	EFX_FILTER_PRI_AUTO,		/* Automatic filter based on device
+					 * address list or hardware
+					 * requirements. This may only be used
+					 * by the filter implementation for
+					 * each NIC type. */
+	EFX_FILTER_PRI_MANUAL,		/* Manually configured filter */
+	EFX_FILTER_PRI_REQUIRED,	/* Required for correct behaviour of the
+					 * client (e.g. SR-IOV, HyperV VMQ etc.)
+					 */
+} efx_filter_priority_t;
+
+/*
+ * FIXME: All these fields are assumed to be in little-endian byte order.
+ * It may be better for some to be big-endian. See bug42804.
+ */
+
+typedef struct efx_filter_spec_s {
+	uint32_t	efs_match_flags:12;
+	uint32_t	efs_priority:2;
+	uint32_t	efs_flags:6;
+	uint32_t	efs_dmaq_id:12;
+	uint32_t	efs_rss_context;
+	uint16_t	efs_outer_vid;
+	uint16_t	efs_inner_vid;
+	uint8_t		efs_loc_mac[EFX_MAC_ADDR_LEN];
+	uint8_t		efs_rem_mac[EFX_MAC_ADDR_LEN];
+	uint16_t	efs_ether_type;
+	uint8_t		efs_ip_proto;
+	uint16_t	efs_loc_port;
+	uint16_t	efs_rem_port;
+	efx_oword_t	efs_rem_host;
+	efx_oword_t	efs_loc_host;
+} efx_filter_spec_t;
+
+
+/* Default values for use in filter specifications */
+#define	EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT	0xffffffff
+#define	EFX_FILTER_SPEC_RX_DMAQ_ID_DROP		0xfff
+#define	EFX_FILTER_SPEC_VID_UNSPEC		0xffff
+
+extern	__checkReturn	efx_rc_t
+efx_filter_init(
+	__in		efx_nic_t *enp);
+
+extern			void
+efx_filter_fini(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_insert(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_remove(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_restore(
+	__in		efx_nic_t *enp);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_supported_filters(
+	__in		efx_nic_t *enp,
+	__out		uint32_t *list,
+	__out		size_t *length);
+
+extern			void
+efx_filter_spec_init_rx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_filter_priority_t priority,
+	__in		efx_filter_flag_t flags,
+	__in		efx_rxq_t *erp);
+
+extern			void
+efx_filter_spec_init_tx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_txq_t *etp);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_ipv4_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t host,
+	__in		uint16_t port);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_ipv4_full(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t lhost,
+	__in		uint16_t lport,
+	__in		uint32_t rhost,
+	__in		uint16_t rport);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_eth_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint16_t vid,
+	__in		const uint8_t *addr);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_uc_def(
+	__inout		efx_filter_spec_t *spec);
+
+extern	__checkReturn	efx_rc_t
+efx_filter_spec_set_mc_def(
+	__inout		efx_filter_spec_t *spec);
+
+#endif	/* EFSYS_OPT_FILTER */
+
 /* HASH */
 
 extern	__checkReturn		uint32_t
diff --git a/drivers/net/sfc/efx/base/efx_check.h b/drivers/net/sfc/efx/base/efx_check.h
index 78cfd8e..555c184 100644
--- a/drivers/net/sfc/efx/base/efx_check.h
+++ b/drivers/net/sfc/efx/base/efx_check.h
@@ -59,6 +59,11 @@
 # error "FALCON_NIC_CFG_OVERRIDE is obsolete and is not supported."
 #endif
 
+#if EFSYS_OPT_FILTER
+/* Support hardware packet filters */
+#  error "FILTER requires SIENA or HUNTINGTON or MEDFORD"
+#endif /* EFSYS_OPT_FILTER */
+
 #ifdef EFSYS_OPT_MAC_FALCON_GMAC
 # error "MAC_FALCON_GMAC is obsolete and is not supported."
 #endif
diff --git a/drivers/net/sfc/efx/base/efx_filter.c b/drivers/net/sfc/efx/base/efx_filter.c
new file mode 100644
index 0000000..8ae865f
--- /dev/null
+++ b/drivers/net/sfc/efx/base/efx_filter.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_FILTER
+
+	__checkReturn	efx_rc_t
+efx_filter_insert(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec)
+{
+	const efx_filter_ops_t *efop = enp->en_efop;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+	return (efop->efo_add(enp, spec, B_FALSE));
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_remove(
+	__in		efx_nic_t *enp,
+	__inout		efx_filter_spec_t *spec)
+{
+	const efx_filter_ops_t *efop = enp->en_efop;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+	return (efop->efo_delete(enp, spec));
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_restore(
+	__in		efx_nic_t *enp)
+{
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+	if ((rc = enp->en_efop->efo_restore(enp)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_init(
+	__in		efx_nic_t *enp)
+{
+	const efx_filter_ops_t *efop;
+	efx_rc_t rc;
+
+	/* Check that efx_filter_spec_t is 64 bytes. */
+	EFX_STATIC_ASSERT(sizeof (efx_filter_spec_t) == 64);
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER));
+
+	switch (enp->en_family) {
+
+	default:
+		EFSYS_ASSERT(0);
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = efop->efo_init(enp)) != 0)
+		goto fail2;
+
+	enp->en_efop = efop;
+	enp->en_mod_flags |= EFX_MOD_FILTER;
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	enp->en_efop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_FILTER;
+	return (rc);
+}
+
+			void
+efx_filter_fini(
+	__in		efx_nic_t *enp)
+{
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+	enp->en_efop->efo_fini(enp);
+
+	enp->en_efop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_FILTER;
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_supported_filters(
+	__in		efx_nic_t *enp,
+	__out		uint32_t *list,
+	__out		size_t *length)
+{
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+	EFSYS_ASSERT(enp->en_efop->efo_supported_filters != NULL);
+
+	if ((rc = enp->en_efop->efo_supported_filters(enp, list, length)) != 0)
+		goto fail1;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_filter_reconfigure(
+	__in				efx_nic_t *enp,
+	__in_ecount(6)			uint8_t const *mac_addr,
+	__in				boolean_t all_unicst,
+	__in				boolean_t mulcst,
+	__in				boolean_t all_mulcst,
+	__in				boolean_t brdcst,
+	__in_ecount(6*count)		uint8_t const *addrs,
+	__in				uint32_t count)
+{
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+	if (enp->en_efop->efo_reconfigure != NULL) {
+		if ((rc = enp->en_efop->efo_reconfigure(enp, mac_addr,
+							all_unicst, mulcst,
+							all_mulcst, brdcst,
+							addrs, count)) != 0)
+			goto fail1;
+	}
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+		void
+efx_filter_spec_init_rx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_filter_priority_t priority,
+	__in		efx_filter_flag_t flags,
+	__in		efx_rxq_t *erp)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3P(erp, !=, NULL);
+	EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
+				EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+
+	memset(spec, 0, sizeof (*spec));
+	spec->efs_priority = priority;
+	spec->efs_flags = EFX_FILTER_FLAG_RX | flags;
+	spec->efs_rss_context = EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT;
+	spec->efs_dmaq_id = (uint16_t)erp->er_index;
+}
+
+		void
+efx_filter_spec_init_tx(
+	__out		efx_filter_spec_t *spec,
+	__in		efx_txq_t *etp)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3P(etp, !=, NULL);
+
+	memset(spec, 0, sizeof (*spec));
+	spec->efs_priority = EFX_FILTER_PRI_REQUIRED;
+	spec->efs_flags = EFX_FILTER_FLAG_TX;
+	spec->efs_dmaq_id = (uint16_t)etp->et_index;
+}
+
+
+/*
+ *  Specify IPv4 host, transport protocol and port in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_ipv4_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t host,
+	__in		uint16_t port)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |=
+		EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+		EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
+	spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+	spec->efs_ip_proto = proto;
+	spec->efs_loc_host.eo_u32[0] = host;
+	spec->efs_loc_port = port;
+	return (0);
+}
+
+/*
+ * Specify IPv4 hosts, transport protocol and ports in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_ipv4_full(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint8_t proto,
+	__in		uint32_t lhost,
+	__in		uint16_t lport,
+	__in		uint32_t rhost,
+	__in		uint16_t rport)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |=
+		EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+		EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+		EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+	spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+	spec->efs_ip_proto = proto;
+	spec->efs_loc_host.eo_u32[0] = lhost;
+	spec->efs_loc_port = lport;
+	spec->efs_rem_host.eo_u32[0] = rhost;
+	spec->efs_rem_port = rport;
+	return (0);
+}
+
+/*
+ * Specify local Ethernet address and/or VID in filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_eth_local(
+	__inout		efx_filter_spec_t *spec,
+	__in		uint16_t vid,
+	__in		const uint8_t *addr)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+	EFSYS_ASSERT3P(addr, !=, NULL);
+
+	if (vid == EFX_FILTER_SPEC_VID_UNSPEC && addr == NULL)
+		return (EINVAL);
+
+	if (vid != EFX_FILTER_SPEC_VID_UNSPEC) {
+		spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
+		spec->efs_outer_vid = vid;
+	}
+	if (addr != NULL) {
+		spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
+		memcpy(spec->efs_loc_mac, addr, EFX_MAC_ADDR_LEN);
+	}
+	return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched unicast in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_uc_def(
+	__inout		efx_filter_spec_t *spec)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+	return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched multicast in a filter specification
+ */
+__checkReturn		efx_rc_t
+efx_filter_spec_set_mc_def(
+	__inout		efx_filter_spec_t *spec)
+{
+	EFSYS_ASSERT3P(spec, !=, NULL);
+
+	spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+	spec->efs_loc_mac[0] = 1;
+	return (0);
+}
+
+
+
+#endif /* EFSYS_OPT_FILTER */
diff --git a/drivers/net/sfc/efx/base/efx_impl.h b/drivers/net/sfc/efx/base/efx_impl.h
index 15bca37..47d4819 100644
--- a/drivers/net/sfc/efx/base/efx_impl.h
+++ b/drivers/net/sfc/efx/base/efx_impl.h
@@ -161,6 +161,33 @@ typedef struct efx_phy_ops_s {
 	efx_rc_t	(*epo_oui_get)(efx_nic_t *, uint32_t *);
 } efx_phy_ops_t;
 
+#if EFSYS_OPT_FILTER
+typedef struct efx_filter_ops_s {
+	efx_rc_t	(*efo_init)(efx_nic_t *);
+	void		(*efo_fini)(efx_nic_t *);
+	efx_rc_t	(*efo_restore)(efx_nic_t *);
+	efx_rc_t	(*efo_add)(efx_nic_t *, efx_filter_spec_t *,
+				   boolean_t may_replace);
+	efx_rc_t	(*efo_delete)(efx_nic_t *, efx_filter_spec_t *);
+	efx_rc_t	(*efo_supported_filters)(efx_nic_t *, uint32_t *, size_t *);
+	efx_rc_t	(*efo_reconfigure)(efx_nic_t *, uint8_t const *, boolean_t,
+				   boolean_t, boolean_t, boolean_t,
+				   uint8_t const *, uint32_t);
+} efx_filter_ops_t;
+
+extern	__checkReturn	efx_rc_t
+efx_filter_reconfigure(
+	__in				efx_nic_t *enp,
+	__in_ecount(6)			uint8_t const *mac_addr,
+	__in				boolean_t all_unicst,
+	__in				boolean_t mulcst,
+	__in				boolean_t all_mulcst,
+	__in				boolean_t brdcst,
+	__in_ecount(6*count)		uint8_t const *addrs,
+	__in				uint32_t count);
+
+#endif /* EFSYS_OPT_FILTER */
+
 
 typedef struct efx_port_s {
 	efx_mac_type_t		ep_mac_type;
@@ -245,6 +272,13 @@ typedef struct efx_nic_ops_s {
 #define	EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
 #endif
 
+#if EFSYS_OPT_FILTER
+
+typedef struct efx_filter_s {
+} efx_filter_t;
+
+#endif	/* EFSYS_OPT_FILTER */
+
 typedef struct efx_drv_cfg_s {
 	uint32_t		edc_min_vi_count;
 	uint32_t		edc_max_vi_count;
@@ -274,6 +308,10 @@ struct efx_nic_s {
 	const efx_ev_ops_t	*en_eevop;
 	const efx_tx_ops_t	*en_etxop;
 	const efx_rx_ops_t	*en_erxop;
+#if EFSYS_OPT_FILTER
+	efx_filter_t		en_filter;
+	const efx_filter_ops_t	*en_efop;
+#endif	/* EFSYS_OPT_FILTER */
 	uint32_t		en_vport_id;
 	union {
 		int	enu_unused;
-- 
2.5.5



More information about the dev mailing list