git: e0f4cdba5336 - main - e1000: fix interface capabilities management

From: Vincenzo Maffione <vmaffione_at_FreeBSD.org>
Date: Wed, 08 Dec 2021 09:00:25 UTC
The branch main has been updated by vmaffione:

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

commit e0f4cdba533693bb6ef9d90243acdad89605b150
Author:     Vincenzo Maffione <vmaffione@FreeBSD.org>
AuthorDate: 2021-12-08 08:55:04 +0000
Commit:     Vincenzo Maffione <vmaffione@FreeBSD.org>
CommitDate: 2021-12-08 08:55:40 +0000

    e1000: fix interface capabilities management
    
    The e1000 drivers (em, lem, igb) are currently looking at the
    iflib copies of the capabilities bitvectors (scctx->isc_capabilities
    and scctx->isc_capenable) rather than the ifnet ones
    (ifp->if_capabilities and ifp->if_capenable). However, the latter
    are the ones that are actually updated by ifconfig and that should
    be used by the drivers during interface operation. The former are
    set by the driver on interface attach (for iflib internal use)
    and should not be used anymore by the driver.
    This patch fixes the e1000 driver to use the correct bitvectors.
    
    PR:             260068
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D33154
---
 sys/dev/e1000/if_em.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index b3775b351c70..cb0c01c9c65d 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -297,12 +297,12 @@ static void	em_if_debug(if_ctx_t);
 static void	em_update_stats_counters(struct e1000_softc *);
 static void	em_add_hw_stats(struct e1000_softc *);
 static int	em_if_set_promisc(if_ctx_t, int);
-static bool	em_if_vlan_filter_capable(struct e1000_softc *);
-static bool	em_if_vlan_filter_used(struct e1000_softc *);
+static bool	em_if_vlan_filter_capable(if_ctx_t);
+static bool	em_if_vlan_filter_used(if_ctx_t);
 static void	em_if_vlan_filter_enable(struct e1000_softc *);
 static void	em_if_vlan_filter_disable(struct e1000_softc *);
 static void	em_if_vlan_filter_write(struct e1000_softc *);
-static void	em_setup_vlan_hw_support(struct e1000_softc *);
+static void	em_setup_vlan_hw_support(if_ctx_t ctx);
 static int	em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
 static void	em_print_nvm_info(struct e1000_softc *);
 static void	em_fw_version_locked(if_ctx_t);
@@ -915,14 +915,15 @@ em_if_attach_pre(if_ctx_t ctx)
 		scctx->isc_rxd_size[0] = sizeof(struct e1000_rx_desc);
 		scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP;
 		scctx->isc_txrx = &lem_txrx;
-		scctx->isc_capabilities = scctx->isc_capenable = LEM_CAPS;
+		scctx->isc_capabilities = LEM_CAPS;
 		if (hw->mac.type < e1000_82543)
-			scctx->isc_capenable &= ~(IFCAP_HWCSUM|IFCAP_VLAN_HWCSUM);
+			scctx->isc_capabilities &= ~(IFCAP_HWCSUM|IFCAP_VLAN_HWCSUM);
 		/* 82541ER doesn't do HW tagging */
 		if (hw->device_id == E1000_DEV_ID_82541ER || hw->device_id == E1000_DEV_ID_82541ER_LOM)
-			scctx->isc_capenable &= ~IFCAP_VLAN_HWTAGGING;
+			scctx->isc_capabilities &= ~IFCAP_VLAN_HWTAGGING;
 		/* INTx only */
 		scctx->isc_msix_bar = 0;
+		scctx->isc_capenable = scctx->isc_capabilities;
 	}
 
 	/* Setup PCI resources */
@@ -1356,7 +1357,7 @@ em_if_init(if_ctx_t ctx)
 	em_initialize_receive_unit(ctx);
 
 	/* Set up VLAN support and filter */
-	em_setup_vlan_hw_support(sc);
+	em_setup_vlan_hw_support(ctx);
 
 	/* Don't lose promiscuous settings */
 	em_if_set_promisc(ctx, if_getflags(ifp));
@@ -1683,7 +1684,7 @@ em_if_set_promisc(if_ctx_t ctx, int flags)
 			reg_rctl &= ~E1000_RCTL_UPE;
 			E1000_WRITE_REG(&sc->hw, E1000_RCTL, reg_rctl);
 		}
-		if (em_if_vlan_filter_used(sc))
+		if (em_if_vlan_filter_used(ctx))
 			em_if_vlan_filter_enable(sc);
 	}
 	return (0);
@@ -3242,12 +3243,12 @@ em_initialize_receive_unit(if_ctx_t ctx)
 
 	/* Set up L3 and L4 csum Rx descriptor offloads */
 	rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
-	if (scctx->isc_capenable & IFCAP_RXCSUM) {
+	if (if_getcapenable(ifp) & IFCAP_RXCSUM) {
 		rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL;
 		if (hw->mac.type > e1000_82575)
 			rxcsum |= E1000_RXCSUM_CRCOFL;
 		else if (hw->mac.type < em_mac_min &&
-		    scctx->isc_capenable & IFCAP_HWCSUM_IPV6)
+		    if_getcapenable(ifp) & IFCAP_HWCSUM_IPV6)
 			rxcsum |= E1000_RXCSUM_IPV6OFL;
 	} else {
 		rxcsum &= ~(E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
@@ -3441,11 +3442,11 @@ em_if_vlan_unregister(if_ctx_t ctx, u16 vtag)
 }
 
 static bool
-em_if_vlan_filter_capable(struct e1000_softc *sc)
+em_if_vlan_filter_capable(if_ctx_t ctx)
 {
-	if_softc_ctx_t scctx = sc->shared;
+	if_t ifp = iflib_get_ifp(ctx);
 
-	if ((scctx->isc_capenable & IFCAP_VLAN_HWFILTER) &&
+	if ((if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) &&
 	    !em_disable_crc_stripping)
 		return (true);
 
@@ -3453,9 +3454,11 @@ em_if_vlan_filter_capable(struct e1000_softc *sc)
 }
 
 static bool
-em_if_vlan_filter_used(struct e1000_softc *sc)
+em_if_vlan_filter_used(if_ctx_t ctx)
 {
-	if (!em_if_vlan_filter_capable(sc))
+	struct e1000_softc *sc = iflib_get_softc(ctx);
+
+	if (!em_if_vlan_filter_capable(ctx))
 		return (false);
 
 	for (int i = 0; i < EM_VFTA_SIZE; i++)
@@ -3515,10 +3518,11 @@ em_if_vlan_filter_write(struct e1000_softc *sc)
 }
 
 static void
-em_setup_vlan_hw_support(struct e1000_softc *sc)
+em_setup_vlan_hw_support(if_ctx_t ctx)
 {
-	if_softc_ctx_t scctx = sc->shared;
+	struct e1000_softc *sc = iflib_get_softc(ctx);
 	struct e1000_hw *hw = &sc->hw;
+	struct ifnet *ifp = iflib_get_ifp(ctx);
 	u32 reg;
 
 	/* XXXKB: Return early if we are a VF until VF decap and filter management
@@ -3527,7 +3531,7 @@ em_setup_vlan_hw_support(struct e1000_softc *sc)
 	if (sc->vf_ifp)
 		return;
 
-	if (scctx->isc_capenable & IFCAP_VLAN_HWTAGGING &&
+	if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING &&
 	    !em_disable_crc_stripping) {
 		reg = E1000_READ_REG(hw, E1000_CTRL);
 		reg |= E1000_CTRL_VME;
@@ -3539,7 +3543,7 @@ em_setup_vlan_hw_support(struct e1000_softc *sc)
 	}
 
 	/* If we aren't doing HW filtering, we're done */
-	if (!em_if_vlan_filter_capable(sc))  {
+	if (!em_if_vlan_filter_capable(ctx))  {
 		em_if_vlan_filter_disable(sc);
 		return;
 	}