Date: Sat, 08 Aug 2026 15:57:53 +0000 From: Kevin Bowling <kbowling@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 66baeec9f8a4 - main - e1000: Program Tx descriptor control by family Message-ID: <6a775201.303c9.3554c0ce@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=66baeec9f8a4c4b1609d255b62e3572e0618747f commit 66baeec9f8a4c4b1609d255b62e3572e0618747f Author: Kevin Bowling <kbowling@FreeBSD.org> AuthorDate: 2026-08-08 11:48:43 +0000 Commit: Kevin Bowling <kbowling@FreeBSD.org> CommitDate: 2026-08-08 15:29:05 +0000 e1000: Program Tx descriptor control by family TXDCTL programming is family dependent. 82543 erratum 35 and 82544 erratum 20 require WTHRESH to remain zero; a nonzero value can corrupt descriptor writebacks and hang the controller. Leave all descriptor-control thresholds at their reset values on 82542, 82543, and 82544. On the remaining em controllers, retain the established PTHRESH=31, HTHRESH=1, WTHRESH=1, and descriptor granularity policy. Several legacy specification updates identify full descriptor writeback as a workaround for transmit descriptor-queue errata. TXDCTL bit 22 is also family dependent. It is COUNT_DESC on the 82571 family and 80003ES2LAN. Intel shared initialization explicitly sets raw bit 22 on both transmit queues of every supported ICH/PCH generation, although the integrated public documentation marks it reserved. Preserve that required setting when iflib programs the thresholds, as DPDK does. Clearing it caused a persistent I219 transmit stall under descriptor pressure. The combined em/igb setup also wrote LWTHRESH=1 on every em controller. The driver does not enable the TXD_LOW interrupt controlled by that field. Enumerate every supported em MAC type and leave the unused low-water threshold disabled. This keeps the legacy descriptor-writeback safety policies separate from igb sparse-RS operation while programming only the fields appropriate to each family. MFC after: 2 weeks --- sys/dev/e1000/if_em.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++----- sys/dev/e1000/if_em.h | 3 ++ 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 6ef36eb579b6..e7bc457ed1bd 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -4137,6 +4137,74 @@ em_if_queues_free(if_ctx_t ctx) } } +static u32 +em_legacy_txdctl(struct e1000_hw *hw) +{ + u32 txdctl; + + /* + * Start with the established full-descriptor writeback policy. + * Several generations have descriptor-queue errata for which it is + * a documented workaround. The unsafe early controllers are + * overridden below. + */ + txdctl = EM_TX_PTHRESH | (EM_TX_HTHRESH << 8) | + (EM_TX_WTHRESH << 16) | E1000_TXDCTL_GRAN; + + switch (hw->mac.type) { + case e1000_82571: + case e1000_82572: + case e1000_82573: + case e1000_82574: + case e1000_82583: + case e1000_80003es2lan: + /* Match the Intel shared-code policy for these families. */ + txdctl |= E1000_TXDCTL_COUNT_DESC; + break; + case e1000_ich8lan: + case e1000_ich9lan: + case e1000_ich10lan: + case e1000_pchlan: + case e1000_pch2lan: + case e1000_pch_lpt: + case e1000_pch_spt: + case e1000_pch_cnp: + case e1000_pch_tgp: + case e1000_pch_adp: + case e1000_pch_mtp: + case e1000_pch_ptp: + /* Preserve the required bit set by the integrated shared code. */ + txdctl |= (1U << 22); + break; + case e1000_82542: + case e1000_82543: + case e1000_82544: + /* + * 82543 erratum 35 and 82544 erratum 20 require + * WTHRESH=0. Leave all descriptor-control thresholds at + * their reset values on these early controllers. + */ + txdctl = 0; + break; + case e1000_82540: + case e1000_82545: + case e1000_82545_rev_3: + case e1000_82546: + case e1000_82546_rev_3: + case e1000_82541: + case e1000_82541_rev_2: + case e1000_82547: + case e1000_82547_rev_2: + break; + default: + KASSERT(0, ("%s: unsupported MAC type %d", __func__, + hw->mac.type)); + break; + } + + return (txdctl); +} + /********************************************************************* * * Enable transmit unit. @@ -4187,16 +4255,15 @@ em_initialize_transmit_rings(if_ctx_t ctx) E1000_READ_REG(hw, E1000_TDBAL(qid)), E1000_READ_REG(hw, E1000_TDLEN(qid))); - txdctl = 0; /* clear txdctl */ - txdctl |= 0x1f; /* PTHRESH */ - txdctl |= 1 << 8; /* HTHRESH */ - txdctl |= 1 << 16;/* WTHRESH */ if (hw->mac.type < igb_mac_min) { - txdctl |= 1 << 22; /* Reserved bit must always be 1 */ - txdctl |= E1000_TXDCTL_GRAN; - txdctl |= 1 << 25; /* LWTHRESH */ - } else + txdctl = em_legacy_txdctl(hw); + } else { + txdctl = 0; + txdctl |= 0x1f; /* PTHRESH */ + txdctl |= 1 << 8; /* HTHRESH */ + txdctl |= 1 << 16; /* WTHRESH */ txdctl |= E1000_TXDCTL_QUEUE_ENABLE; + } E1000_WRITE_REG(hw, E1000_TXDCTL(qid), txdctl); } diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 6d3f312715d4..5f53f4074fcf 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -296,6 +296,9 @@ struct igb_vf_mac_filter; #define PCICFG_DESC_RING_STATUS 0xe4 #define FLUSH_DESC_REQUIRED 0x100 +#define EM_TX_PTHRESH 31 +#define EM_TX_HTHRESH 1 +#define EM_TX_WTHRESH 1 #define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : \ ((hw->mac.type <= e1000_82576) ? 16 : 8))home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a775201.303c9.3554c0ce>
