git: 0491dc48b51a - stable/14 - e1000: Program Tx descriptor control by family
Kevin Bowling <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.src |
|---|---|
| Message-ID | <6a88f1b3.264c8.4df55187__4473.1321440608$1787359742$gmane$org@gitrepo.freebsd.org> |
The branch stable/14 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=0491dc48b51a80dd27eccb8a756f383b342d99aa commit 0491dc48b51a80dd27eccb8a756f383b342d99aa Author: Kevin Bowling <[email protected]> AuthorDate: 2026-08-08 11:48:43 +0000 Commit: Kevin Bowling <[email protected]> CommitDate: 2026-08-22 00:47:34 +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. (cherry picked from commit 66baeec9f8a4c4b1609d255b62e3572e0618747f) --- 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 6c489bec5a4c..a5c629ec0392 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -3679,6 +3679,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. @@ -3729,16 +3797,15 @@ em_initialize_transmit_unit(if_ctx_t ctx) E1000_READ_REG(hw, E1000_TDBAL(i)), E1000_READ_REG(hw, E1000_TDLEN(i))); - 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(i), txdctl); } diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 272bb5a7ba3f..ead107f67fd6 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -293,6 +293,9 @@ #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))