summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2016-01-14 16:19:58 +0000
committerarybchik <arybchik@FreeBSD.org>2016-01-14 16:19:58 +0000
commitfcd6be20105c13afccd70e945adfdaee55df87ec (patch)
tree57adf474fab65360a157b1f1f2188cd78606a888
parent6a84664c88a86fe772fabb3ac8a6b8fe851a461a (diff)
downloadFreeBSD-src-fcd6be20105c13afccd70e945adfdaee55df87ec.zip
FreeBSD-src-fcd6be20105c13afccd70e945adfdaee55df87ec.tar.gz
MFC r293807
sfxge: rework RX prefix handling in the common code Submitted by: Andy Moreton <amoreton at solarflare.com> Reviewed by: gnn Sponsored by: Solarflare Communications, Inc.
-rw-r--r--sys/dev/sfxge/common/efx.h2
-rw-r--r--sys/dev/sfxge/common/efx_impl.h6
-rw-r--r--sys/dev/sfxge/common/efx_rx.c149
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h12
-rw-r--r--sys/dev/sfxge/common/hunt_rx.c59
5 files changed, 155 insertions, 73 deletions
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index 5bf2c78..b9d2061 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -1883,7 +1883,7 @@ efx_rx_scale_key_set(
__in_ecount(n) uint8_t *key,
__in size_t n);
-extern uint32_t
+extern __checkReturn uint32_t
efx_psuedo_hdr_hash_get(
__in efx_nic_t *enp,
__in efx_rx_hash_alg_t func,
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index 7d659cc..a8c17f5 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -166,7 +166,11 @@ typedef struct efx_rx_ops_s {
efx_rc_t (*erxo_scale_key_set)(efx_nic_t *, uint8_t *, size_t);
efx_rc_t (*erxo_scale_tbl_set)(efx_nic_t *, unsigned int *,
size_t);
-#endif
+ uint32_t (*erxo_prefix_hash)(efx_nic_t *, efx_rx_hash_alg_t,
+ uint8_t *);
+#endif /* EFSYS_OPT_RX_SCALE */
+ efx_rc_t (*erxo_prefix_pktlen)(efx_nic_t *, uint8_t *,
+ uint16_t *);
void (*erxo_qpost)(efx_rxq_t *, efsys_dma_addr_t *, size_t,
unsigned int, unsigned int,
unsigned int);
diff --git a/sys/dev/sfxge/common/efx_rx.c b/sys/dev/sfxge/common/efx_rx.c
index d8edeb6..b8339ff 100644
--- a/sys/dev/sfxge/common/efx_rx.c
+++ b/sys/dev/sfxge/common/efx_rx.c
@@ -75,6 +75,18 @@ falconsiena_rx_scale_tbl_set(
__in_ecount(n) unsigned int *table,
__in size_t n);
+static __checkReturn uint32_t
+falconsiena_rx_prefix_hash(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer);
+
+static __checkReturn efx_rc_t
+falconsiena_rx_prefix_pktlen(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *lengthp);
+
#endif /* EFSYS_OPT_RX_SCALE */
static void
@@ -130,7 +142,9 @@ static efx_rx_ops_t __efx_rx_falcon_ops = {
falconsiena_rx_scale_mode_set, /* erxo_scale_mode_set */
falconsiena_rx_scale_key_set, /* erxo_scale_key_set */
falconsiena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+ falconsiena_rx_prefix_hash, /* erxo_prefix_hash */
#endif
+ falconsiena_rx_prefix_pktlen, /* erxo_prefix_pktlen */
falconsiena_rx_qpost, /* erxo_qpost */
falconsiena_rx_qpush, /* erxo_qpush */
falconsiena_rx_qflush, /* erxo_qflush */
@@ -151,7 +165,9 @@ static efx_rx_ops_t __efx_rx_siena_ops = {
falconsiena_rx_scale_mode_set, /* erxo_scale_mode_set */
falconsiena_rx_scale_key_set, /* erxo_scale_key_set */
falconsiena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+ falconsiena_rx_prefix_hash, /* erxo_prefix_hash */
#endif
+ falconsiena_rx_prefix_pktlen, /* erxo_prefix_pktlen */
falconsiena_rx_qpost, /* erxo_qpost */
falconsiena_rx_qpush, /* erxo_qpush */
falconsiena_rx_qflush, /* erxo_qflush */
@@ -172,7 +188,9 @@ static efx_rx_ops_t __efx_rx_ef10_ops = {
ef10_rx_scale_mode_set, /* erxo_scale_mode_set */
ef10_rx_scale_key_set, /* erxo_scale_key_set */
ef10_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+ ef10_rx_prefix_hash, /* erxo_prefix_hash */
#endif
+ ef10_rx_prefix_pktlen, /* erxo_prefix_pktlen */
ef10_rx_qpost, /* erxo_qpost */
ef10_rx_qpush, /* erxo_qpush */
ef10_rx_qflush, /* erxo_qflush */
@@ -553,92 +571,29 @@ efx_rx_qdestroy(
erxop->erxo_qdestroy(erp);
}
-/*
- * Psuedo-header info for Siena/Falcon.
- *
- * The psuedo-header is a byte array of one of the forms:
- *
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.TT.TT.TT.TT
- * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.LL.LL
- *
- * where:
- *
- * TT.TT.TT.TT is a 32-bit Toeplitz hash
- * LL.LL is a 16-bit LFSR hash
- *
- * Hash values are in network (big-endian) byte order.
- *
- *
- * On EF10 the pseudo-header is laid out as:
- * (See also SF-109306-TC section 9)
- *
- * Toeplitz hash (32 bits, little-endian)
- * Out-of-band outer VLAN tag
- * (16 bits, big-endian, 0 if the packet did not have an outer VLAN tag)
- * Out-of-band inner VLAN tag
- * (16 bits, big-endian, 0 if the packet did not have an inner VLAN tag)
- * Packet length (16 bits, little-endian, may be 0)
- * MAC timestamp (32 bits, little-endian, may be 0)
- * VLAN tag
- * (16 bits, big-endian, 0 if the packet did not have an outer VLAN tag)
- * VLAN tag
- * (16 bits, big-endian, 0 if the packet did not have an inner VLAN tag)
- */
-
__checkReturn efx_rc_t
efx_psuedo_hdr_pkt_length_get(
__in efx_nic_t *enp,
__in uint8_t *buffer,
- __out uint16_t *pkt_lengthp)
+ __out uint16_t *lengthp)
{
- if (enp->en_family != EFX_FAMILY_HUNTINGTON &&
- enp->en_family != EFX_FAMILY_MEDFORD) {
- EFSYS_ASSERT(0);
- return (ENOTSUP);
- }
-
- *pkt_lengthp = buffer[8] | (buffer[9] << 8);
+ efx_rx_ops_t *erxop = enp->en_erxop;
- return (0);
+ return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
}
#if EFSYS_OPT_RX_SCALE
-
-uint32_t
+ __checkReturn uint32_t
efx_psuedo_hdr_hash_get(
__in efx_nic_t *enp,
__in efx_rx_hash_alg_t func,
__in uint8_t *buffer)
{
- if (func == EFX_RX_HASHALG_TOEPLITZ) {
- switch (enp->en_family) {
- case EFX_FAMILY_FALCON:
- case EFX_FAMILY_SIENA:
- return ((buffer[12] << 24) |
- (buffer[13] << 16) |
- (buffer[14] << 8) |
- buffer[15]);
- case EFX_FAMILY_HUNTINGTON:
- case EFX_FAMILY_MEDFORD:
- return (buffer[0] |
- (buffer[1] << 8) |
- (buffer[2] << 16) |
- (buffer[3] << 24));
- default:
- EFSYS_ASSERT(0);
- return (0);
- }
- } else if (func == EFX_RX_HASHALG_LFSR) {
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_FALCON ||
- enp->en_family == EFX_FAMILY_SIENA);
- return ((buffer[14] << 8) | buffer[15]);
- } else {
- EFSYS_ASSERT(0);
- return (0);
- }
-}
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
+ return (erxop->erxo_prefix_hash(enp, func, buffer));
+}
#endif /* EFSYS_OPT_RX_SCALE */
#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
@@ -1026,6 +981,58 @@ fail1:
}
#endif
+/*
+ * Falcon/Siena psuedo-header
+ * --------------------------
+ *
+ * Receive packets are prefixed by an optional 16 byte pseudo-header.
+ * The psuedo-header is a byte array of one of the forms:
+ *
+ * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
+ * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
+ *
+ * where:
+ * TT.TT.TT.TT Toeplitz hash (32-bit big-endian)
+ * LL.LL LFSR hash (16-bit big-endian)
+ */
+
+#if EFSYS_OPT_RX_SCALE
+static __checkReturn uint32_t
+falconsiena_rx_prefix_hash(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer)
+{
+ switch (func) {
+ case EFX_RX_HASHALG_TOEPLITZ:
+ return ((buffer[12] << 24) |
+ (buffer[13] << 16) |
+ (buffer[14] << 8) |
+ buffer[15]);
+
+ case EFX_RX_HASHALG_LFSR:
+ return ((buffer[14] << 8) | buffer[15]);
+
+ default:
+ EFSYS_ASSERT(0);
+ return (0);
+ }
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+static __checkReturn efx_rc_t
+falconsiena_rx_prefix_pktlen(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *lengthp)
+{
+ /* Not supported by Falcon/Siena hardware */
+ EFSYS_ASSERT(0);
+ return (ENOTSUP);
+}
+
+
static void
falconsiena_rx_qpost(
__in efx_rxq_t *erp,
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
index c476c49..6d65bc0 100644
--- a/sys/dev/sfxge/common/hunt_impl.h
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -874,6 +874,18 @@ ef10_rx_scale_tbl_set(
__in_ecount(n) unsigned int *table,
__in size_t n);
+extern __checkReturn uint32_t
+ef10_rx_prefix_hash(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer);
+
+extern __checkReturn efx_rc_t
+ef10_rx_prefix_pktlen(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *lengthp);
+
#endif /* EFSYS_OPT_RX_SCALE */
extern void
diff --git a/sys/dev/sfxge/common/hunt_rx.c b/sys/dev/sfxge/common/hunt_rx.c
index 666885c..de57f5b 100644
--- a/sys/dev/sfxge/common/hunt_rx.c
+++ b/sys/dev/sfxge/common/hunt_rx.c
@@ -575,6 +575,65 @@ fail1:
}
#endif /* EFSYS_OPT_RX_SCALE */
+
+/*
+ * EF10 RX pseudo-header
+ * ---------------------
+ *
+ * Receive packets are prefixed by an (optional) 14 byte pseudo-header:
+ *
+ * +00: Toeplitz hash value.
+ * (32bit little-endian)
+ * +04: Outer VLAN tag. Zero if the packet did not have an outer VLAN tag.
+ * (16bit big-endian)
+ * +06: Inner VLAN tag. Zero if the packet did not have an inner VLAN tag.
+ * (16bit big-endian)
+ * +08: Packet Length. Zero if the RX datapath was in cut-through mode.
+ * (16bit little-endian)
+ * +10: MAC timestamp. Zero if timestamping is not enabled.
+ * (32bit little-endian)
+ *
+ * See "The RX Pseudo-header" in SF-109306-TC.
+ */
+
+ __checkReturn efx_rc_t
+ef10_rx_prefix_pktlen(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *lengthp)
+{
+ /*
+ * The RX pseudo-header contains the packet length, excluding the
+ * pseudo-header. If the hardware receive datapath was operating in
+ * cut-through mode then the length in the RX pseudo-header will be
+ * zero, and the packet length must be obtained from the DMA length
+ * reported in the RX event.
+ */
+ *lengthp = buffer[8] | (buffer[9] << 8);
+ return (0);
+}
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn uint32_t
+ef10_rx_prefix_hash(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer)
+{
+ switch (func) {
+ case EFX_RX_HASHALG_TOEPLITZ:
+ return (buffer[0] |
+ (buffer[1] << 8) |
+ (buffer[2] << 16) |
+ (buffer[3] << 24));
+
+ default:
+ EFSYS_ASSERT(0);
+ return (0);
+ }
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
void
ef10_rx_qpost(
__in efx_rxq_t *erp,
OpenPOWER on IntegriCloud