git: 95f7b36e8fac - main - e1000: lem(4)/em(4) ifcaps, TSO and hwcsum fixes

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Fri, 21 Jul 2023 03:44:41 UTC
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=95f7b36e8fac45092b9a4eea5e32732e979989f0

commit 95f7b36e8fac45092b9a4eea5e32732e979989f0
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2023-07-21 03:30:00 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2023-07-21 03:44:04 +0000

    e1000: lem(4)/em(4) ifcaps, TSO and hwcsum fixes
    
    * em(4) obey administrative ifcaps for using hwcsum offload
    * em(4) obey administrative ifcaps for hw vlan receive tagging
    * em(4) add additional TSO6 ifcap, but disabled by default as is TSO4
    * lem(4) obey administrative ifcaps for using hwcsum offload
    * lem(4) add support for hw vlan receive tagging
    * lem(4) Add ifcaps for TSO offload experimentation, but disabled by
      default due to errata and possibly missing txrx code.
    * lem(4) disable HWCSUM ifcaps by default on 82547 due to errata around
      full duplex links.  It may still be administratively enabled.
    
    Reviewed by:    markj (previous version)
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D30072
---
 sys/dev/e1000/em_txrx.c | 15 ++++++++-------
 sys/dev/e1000/if_em.c   | 48 ++++++++++++++++++++++++++++++++----------------
 2 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/sys/dev/e1000/em_txrx.c b/sys/dev/e1000/em_txrx.c
index 47f9b187aa14..069a1c00a4b2 100644
--- a/sys/dev/e1000/em_txrx.c
+++ b/sys/dev/e1000/em_txrx.c
@@ -674,12 +674,12 @@ lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
 		i++;
 	} while (!eop);
 
-	/* XXX add a faster way to look this up */
-	if (sc->hw.mac.type >= e1000_82543)
+	if (scctx->isc_capenable & IFCAP_RXCSUM)
 		em_receive_checksum(status, errors, ri);
 
-	if (status & E1000_RXD_STAT_VP) {
-		ri->iri_vtag = le16toh(rxd->special);
+	if (scctx->isc_capenable & IFCAP_VLAN_HWTAGGING &&
+	    status & E1000_RXD_STAT_VP) {
+		ri->iri_vtag = le16toh(rxd->special & E1000_RXD_SPC_VLAN_MASK);
 		ri->iri_flags |= M_VLANTAG;
 	}
 
@@ -699,11 +699,11 @@ em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
 
 	uint16_t len;
 	uint32_t pkt_info;
-	uint32_t staterr = 0;
+	uint32_t staterr;
 	bool eop;
 	int i, cidx;
 
-	i = 0;
+	staterr = i = 0;
 	cidx = ri->iri_cidx;
 
 	do {
@@ -739,7 +739,8 @@ em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
 	if (scctx->isc_capenable & IFCAP_RXCSUM)
 		em_receive_checksum(staterr, staterr >> 24, ri);
 
-	if (staterr & E1000_RXD_STAT_VP) {
+	if (scctx->isc_capenable & IFCAP_VLAN_HWTAGGING &&
+	    staterr & E1000_RXD_STAT_VP) {
 		ri->iri_vtag = le16toh(rxd->wb.upper.vlan);
 		ri->iri_flags |= M_VLANTAG;
 	}
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 0b664b155872..b5a6e7e777d3 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -781,19 +781,21 @@ em_set_num_queues(if_ctx_t ctx)
 	return (maxqueues);
 }
 
-#define	LEM_CAPS							\
-    IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |		\
-    IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER
-
-#define	EM_CAPS								\
-    IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |		\
-    IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 |	\
-    IFCAP_LRO | IFCAP_VLAN_HWTSO
-
-#define	IGB_CAPS							\
-    IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |		\
-    IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 |	\
-    IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 |\
+#define LEM_CAPS \
+    IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
+    IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \
+    IFCAP_LRO | IFCAP_JUMBO_MTU
+
+#define EM_CAPS \
+    IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
+    IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \
+    IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 | \
+    IFCAP_TSO6
+
+#define IGB_CAPS \
+    IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
+    IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \
+    IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 | \
     IFCAP_TSO6
 
 /*********************************************************************
@@ -897,7 +899,7 @@ em_if_attach_pre(if_ctx_t ctx)
 		scctx->isc_tx_tso_segsize_max = EM_TSO_SEG_SIZE;
 		scctx->isc_capabilities = scctx->isc_capenable = EM_CAPS;
 		/*
-		 * For EM-class devices, don't enable IFCAP_{TSO4,VLAN_HWTSO}
+		 * For EM-class devices, don't enable IFCAP_{TSO4,VLAN_HWTSO,TSO6}
 		 * by default as we don't have workarounds for all associated
 		 * silicon errata.  E. g., with several MACs such as 82573E,
 		 * TSO only works at Gigabit speed and otherwise can cause the
@@ -912,8 +914,9 @@ em_if_attach_pre(if_ctx_t ctx)
 		 * work for a few MACs of this class - at least when sticking
 		 * with Gigabit - in which case users may enable TSO manually.
 		 */
-		scctx->isc_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO);
-		scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO;
+		scctx->isc_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO | IFCAP_TSO6);
+		scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO |
+		    CSUM_IP6_TCP | CSUM_IP6_UDP;
 		/*
 		 * We support MSI-X with 82574 only, but indicate to iflib(4)
 		 * that it shall give MSI at least a try with other devices.
@@ -932,6 +935,19 @@ em_if_attach_pre(if_ctx_t ctx)
 		scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP;
 		scctx->isc_txrx = &lem_txrx;
 		scctx->isc_capabilities = LEM_CAPS;
+
+		/*
+		 * For LEM-class devices, don't enable IFCAP {TSO4,VLAN_HWTSO}
+		 * by default as we don't have workarounds for all associated
+		 * silicon errata.  TSO4 may work on > 82544 but its status
+		 * is unknown by the authors.  Please report any success or failures.
+		 */
+		 scctx->isc_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO);
+
+		/* 8254x SDM4.0 page 33 - FDX requirement on these chips */
+		if (hw->mac.type == e1000_82547 || hw->mac.type == e1000_82547_rev_2)
+			scctx->isc_capenable &= ~(IFCAP_HWCSUM|IFCAP_VLAN_HWCSUM);
+
 		if (hw->mac.type < e1000_82543)
 			scctx->isc_capabilities &= ~(IFCAP_HWCSUM|IFCAP_VLAN_HWCSUM);
 		/* 82541ER doesn't do HW tagging */