From nobody Wed Aug 12 19:40:07 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hKzNR5jnLz6nqvY for ; Wed, 12 Aug 2026 19:40:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hKzNR5VRQz42C3 for ; Wed, 12 Aug 2026 19:40:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786563607; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=MDVcieUv38L35f5HkeX7P3ZxH49hmQzUGlz92Usqo48=; b=N4YLbsYHlzOyZ3OaX9g3LmtkZjWoOQpxZd6wjizDkeQgBxoWUDDV5SwrRH3EdeGJ9ctGHg 5n6y0keLZEra3bQ2l7GX+scgV85n9xOihonR2oAwDhpOctLPtrYnBG8p5cDzqgYKIQ6iRC eK+hXsfEgXFMukpmoZCB3NXQfCRAfeY199MRzukuiQbdfiwN1uUjaONl9/Y0f2mORvL7dC scVQ52xiguGoPxZaXxWk7oru9xRvvF2lQnRgb3pA0ht8z3A173Cq4bpJC38ZhqMfzZ5dUa jFfjG4jalx/kDfvo8oWjLoCdDbOufq9WX6v/kFsjcRqX+d7BbJrvAnWc8g6G9Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786563607; a=rsa-sha256; cv=none; b=deQJtc+ELelsD/qqZuTDzfqM8ypWfcfyrPA3CPlv+DgmV3lMwpmOklXmggV369pkhS/5Vk iK4ybe6mq02ieFxdn4eyUqZ1/zffsNDu0DjTCKKjlGFB/RP8xai6eZyDLhMtiwy+kbAxzq yQG/GqWiHmtvbPcDpm3jxNFSnM/XFvqGBw5kLtcb9286YjxOPvu6Jb7kNAtlSyxGhTFwlg WVTL1HyHiPhhMdHaT2q4jlnGp73geWBirsTDrtF3oyFhIqBJGC2ospFsWIosIkaDdv+ceI JluwCuj7qOQXZcJq/pTtbGJEo+q0Fe3NCfh4TnMrSsssz+iY7dOBe4o1uho53w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786563607; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=MDVcieUv38L35f5HkeX7P3ZxH49hmQzUGlz92Usqo48=; b=rPbF+l2hcpbeo3RgWbiE8/OvMj2DcMSyW3/AjqIIpvZvhKOWP+LsoHdQ8TjgjMdTeRKEeh 2hEM/uTrzq3or/c9EuTtti7V7CK1x0CybGB0IaZi/U6uoyDw92aNL4/M7VoqxGZwGuVkrE xdpNbG9yHSb98lM01LJJwD/x9ycAIuxaIb/DgqARLU3sDALS4ZTfx6Ge0ug3FBdbLqxbNi Poogdz59vvHGpqMFIfE++wxX7gK2COwygqv/zqpc/HZXPpdiT/hOBiG6QRLz5l26tOp9EU EjgCX4kGo/BaXexZxh7NghjjkVk3+sluB5on1pS5Jze78m/7gv3HGvg2dQzusQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hKzNR4Gqkzg04 for ; Wed, 12 Aug 2026 19:40:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 314b3 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 12 Aug 2026 19:40:07 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: bbf93227fe9e - main - igc: Recover from fatal internal memory errors List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: bbf93227fe9ee1f38b7db5477398c3564e5c84bc Auto-Submitted: auto-generated Date: Wed, 12 Aug 2026 19:40:07 +0000 Message-Id: <6a7ccc17.314b3.1a396455@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=bbf93227fe9ee1f38b7db5477398c3564e5c84bc commit bbf93227fe9ee1f38b7db5477398c3564e5c84bc Author: Kevin Bowling AuthorDate: 2026-08-12 04:12:49 +0000 Commit: Kevin Bowling CommitDate: 2026-08-12 19:39:54 +0000 igc: Recover from fatal internal memory errors I225 and I226 report uncorrectable internal memory errors through ICR.FER and identify the affected region in PEIND. Depending on the region, hardware stops transmit or all PCIe and DMA traffic until the port is reset and reinitialized. Enable the fatal error interrupt and capture its read clear status in the interrupt filter. Mask the cause while an iflib reset is pending, report the affected memory regions, and expose per region indication counters. PCIe region parity failures require a different recovery order from a normal reset: assert DEV_RST, wait at least 3 ms, disable PCIe master requests, clear PCIEERRSTS, and then reinitialize the port. Follow that sequence before entering the normal reset path and clear the remaining LAN status afterward. The I225/I226 PBECCSTS layout is unrelated to the PCH layout previously copied into the igc headers. Replace those unused definitions with the I225/I226 memory error register definitions. Hardware validation used an I225-IT revision 3 and a debug kernel that wrote only the documented self-clearing injection bits. It did not synthesize interrupt or status state. Coverage, notably DMA and Mgmt are not fully testable in my setup: Region Observed hardware status Result LAN PEIND 0x1, LANPERRSTS 0x200 Reset and recovered PCIe PEIND 0x4, PCIEERRSTS 0x8 Reset and recovered DMA DRPARC injection read back zero DFT-gated on test NIC Mgmt Host debug strap unavailable Not injectable The repeated LAN and PCIe tests recovered without a panic or watchdog. A PCIe-to-LAN sequence also verified that reset-time PEIND indications are drained before FER is unmasked. MFC after: 2 weeks Sponsored by: BBOX.io --- sys/dev/igc/if_igc.c | 226 +++++++++++++++++++++++++++++++++++++++++++++- sys/dev/igc/if_igc.h | 10 ++ sys/dev/igc/igc_defines.h | 25 ++++- sys/dev/igc/igc_regs.h | 9 +- 4 files changed, 258 insertions(+), 12 deletions(-) diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c index 359cd1d6dc39..add391f9195f 100644 --- a/sys/dev/igc/if_igc.c +++ b/sys/dev/igc/if_igc.c @@ -127,6 +127,10 @@ static void igc_if_intr_enable(if_ctx_t); static void igc_if_intr_disable(if_ctx_t); static int igc_if_rx_queue_intr_enable(if_ctx_t, uint16_t); static int igc_if_tx_queue_intr_enable(if_ctx_t, uint16_t); +static void igc_handle_fatal_error_intr(struct igc_softc *, u32); +static bool igc_handle_fatal_error_admin(struct igc_softc *); +static void igc_prepare_fatal_error_reset(struct igc_softc *); +static void igc_finish_fatal_error_reset(struct igc_softc *); static void igc_if_multi_set(if_ctx_t); static void igc_if_update_admin_status(if_ctx_t); static void igc_apply_i225_ipg_workaround(struct igc_softc *); @@ -162,6 +166,13 @@ static void igc_enable_wakeup(if_ctx_t); int igc_intr(void *); +enum igc_fatal_error_state { + IGC_FATAL_ERROR_NONE, + IGC_FATAL_ERROR_CAPTURING, + IGC_FATAL_ERROR_DETECTED, + IGC_FATAL_ERROR_RESET_REQUESTED, +}; + /* MSI-X handlers */ static int igc_if_msix_intr_assign(if_ctx_t, int); static int igc_msix_link(void *); @@ -1120,6 +1131,8 @@ igc_intr(void *arg) if (reg_icr & IGC_ICR_RXO) sc->rx_overruns++; + igc_handle_fatal_error_intr(sc, reg_icr); + igc_neweitr(sc, que, rxr); return (FILTER_SCHEDULE_THREAD); @@ -1185,8 +1198,13 @@ igc_msix_link(void *arg) if (reg_icr & (IGC_ICR_RXSEQ | IGC_ICR_LSC)) { igc_handle_link(sc->ctx); } + igc_handle_fatal_error_intr(sc, reg_icr); - IGC_WRITE_REG(&sc->hw, IGC_IMS, IGC_IMS_LSC); + reg_icr = IGC_IMS_LSC; + if (atomic_load_acq_32(&sc->fatal_error_state) == + IGC_FATAL_ERROR_NONE) + reg_icr |= IGC_IMS_FER; + IGC_WRITE_REG(&sc->hw, IGC_IMS, reg_icr); IGC_WRITE_REG(&sc->hw, IGC_EIMS, sc->link_mask); return (FILTER_HANDLED); @@ -1202,6 +1220,93 @@ igc_handle_link(void *context) iflib_admin_intr_deferred(ctx); } +/* + * Fatal internal memory errors stop some or all device traffic. Capture the + * read-clear indication before handing recovery to the iflib admin task. + */ +static void +igc_handle_fatal_error_intr(struct igc_softc *sc, u32 icr) +{ + struct igc_hw *hw; + u32 lanerr, mngerr, pcieerr, peind; + + if ((icr & IGC_ICR_FER) == 0) + return; + + hw = &sc->hw; + IGC_WRITE_REG(hw, IGC_IMC, IGC_IMS_FER); + if (!atomic_cmpset_32(&sc->fatal_error_state, + IGC_FATAL_ERROR_NONE, IGC_FATAL_ERROR_CAPTURING)) + return; + + peind = IGC_READ_REG(hw, IGC_PEIND) & IGC_PEIND_FATAL_MASK; + pcieerr = IGC_READ_REG(hw, IGC_PCIEERRSTS) & + IGC_PCIEERRSTS_FATAL_MASK; + lanerr = IGC_READ_REG(hw, IGC_LANPERRSTS) & + IGC_LANPERRSTS_RETX_BUF; + mngerr = IGC_READ_REG(hw, IGC_MNGPARSTS) & + IGC_MNGPARSTS_FATAL_MASK; + if (pcieerr != 0) + peind |= IGC_PEIND_PCIE_PARITY_FATAL; + if (lanerr != 0) + peind |= IGC_PEIND_LANPORT_PARITY_FATAL; + + sc->fatal_error_peind = peind; + sc->fatal_error_pcie = pcieerr; + sc->fatal_error_lan = lanerr; + sc->fatal_error_mng = mngerr; + atomic_store_rel_32(&sc->fatal_error_state, + IGC_FATAL_ERROR_DETECTED); + iflib_admin_intr_deferred(sc->ctx); +} + +static bool +igc_handle_fatal_error_admin(struct igc_softc *sc) +{ + u32 peind; + + if (!atomic_cmpset_acq_32(&sc->fatal_error_state, + IGC_FATAL_ERROR_DETECTED, IGC_FATAL_ERROR_RESET_REQUESTED)) + return (atomic_load_acq_32(&sc->fatal_error_state) != + IGC_FATAL_ERROR_NONE); + + peind = sc->fatal_error_peind; + if (peind & IGC_PEIND_LANPORT_PARITY_FATAL) + sc->fatal_error_lan_count++; + if (peind & IGC_PEIND_MNG_PARITY_FATAL) + sc->fatal_error_mng_count++; + if (peind & IGC_PEIND_PCIE_PARITY_FATAL) + sc->fatal_error_pcie_count++; + if (peind & IGC_PEIND_DMA_PARITY_FATAL) + sc->fatal_error_dma_count++; + if (peind == 0) + sc->fatal_error_unknown_count++; + + device_printf(sc->dev, + "fatal internal memory error: PEIND %#x, PCIEERRSTS %#x, " + "LANPERRSTS %#x, MNGPARSTS %#x\n", + peind, sc->fatal_error_pcie, sc->fatal_error_lan, + sc->fatal_error_mng); + /* Management-memory recovery is owned by management firmware. */ + if (peind != 0 && (peind & IGC_PEIND_HOST_FATAL_MASK) == 0) { + sc->fatal_error_peind = 0; + sc->fatal_error_pcie = 0; + sc->fatal_error_lan = 0; + sc->fatal_error_mng = 0; + atomic_store_rel_32(&sc->fatal_error_state, + IGC_FATAL_ERROR_NONE); + IGC_WRITE_REG(&sc->hw, IGC_IMS, IGC_IMS_FER); + IGC_WRITE_FLUSH(&sc->hw); + return (true); + } + + device_printf(sc->dev, "requesting reset after memory error\n"); + iflib_request_reset(sc->ctx); + /* Re-enter the admin task so it observes the reset request. */ + iflib_admin_intr_deferred(sc->ctx); + return (true); +} + /********************************************************************* * * Media Ioctl callback @@ -1446,6 +1551,9 @@ igc_if_update_admin_status(if_ctx_t ctx) device_t dev = iflib_get_dev(ctx); u32 link_check, thstat, ctrl; + if (igc_handle_fatal_error_admin(sc)) + return; + link_check = thstat = ctrl = 0; /* Get the cached link value or read phy for real */ switch (hw->phy.media_type) { @@ -1501,10 +1609,93 @@ igc_if_stop(if_ctx_t ctx) INIT_DEBUGOUT("igc_if_stop: begin"); igc_led_restore(sc); + igc_prepare_fatal_error_reset(sc); igc_reset_hw(&sc->hw); + igc_finish_fatal_error_reset(sc); IGC_WRITE_REG(&sc->hw, IGC_WUC, 0); } +/* + * A PCIe-region parity failure stops PCIe and DMA traffic. Intel requires a + * device reset before master disable in this case, unlike the normal reset + * path, which disables the bus master first. + */ +static void +igc_prepare_fatal_error_reset(struct igc_softc *sc) +{ + struct igc_hw *hw; + s32 error; + u32 ctrl, pcieerr; + int i; + + if (atomic_load_acq_32(&sc->fatal_error_state) == + IGC_FATAL_ERROR_NONE) + return; + + hw = &sc->hw; + pcieerr = sc->fatal_error_pcie | + (IGC_READ_REG(hw, IGC_PCIEERRSTS) & IGC_PCIEERRSTS_FATAL_MASK); + if ((sc->fatal_error_peind & IGC_PEIND_PCIE_PARITY_FATAL) == 0 && + pcieerr == 0) + return; + + ctrl = IGC_READ_REG(hw, IGC_CTRL); + IGC_WRITE_REG(hw, IGC_CTRL, ctrl | IGC_CTRL_DEV_RST); + /* Do not access device registers for at least 3 ms after DEV_RST. */ + msec_delay(3); + for (i = 0; i < AUTO_READ_DONE_TIMEOUT; i++) { + if ((IGC_READ_REG(hw, IGC_EECD) & IGC_EECD_AUTO_RD) != 0 && + (IGC_READ_REG(hw, IGC_STATUS) & IGC_STATUS_RST_DONE) != 0) + break; + msec_delay(1); + } + if (i == AUTO_READ_DONE_TIMEOUT) + device_printf(sc->dev, + "device reset did not complete during parity recovery\n"); + error = igc_disable_pcie_master_generic(hw); + if (error != IGC_SUCCESS) + device_printf(sc->dev, + "PCIe master disable failed during parity recovery: %d\n", + error); + pcieerr |= IGC_READ_REG(hw, IGC_PCIEERRSTS) & + IGC_PCIEERRSTS_FATAL_MASK; + if (pcieerr != 0) + IGC_WRITE_REG(hw, IGC_PCIEERRSTS, pcieerr); +} + +static void +igc_finish_fatal_error_reset(struct igc_softc *sc) +{ + struct igc_hw *hw; + u32 lanerr, pcieerr; + + if (atomic_load_acq_32(&sc->fatal_error_state) == + IGC_FATAL_ERROR_NONE) + return; + + hw = &sc->hw; + pcieerr = sc->fatal_error_pcie | + (IGC_READ_REG(hw, IGC_PCIEERRSTS) & IGC_PCIEERRSTS_FATAL_MASK); + if (pcieerr != 0) + IGC_WRITE_REG(hw, IGC_PCIEERRSTS, pcieerr); + lanerr = sc->fatal_error_lan | + (IGC_READ_REG(hw, IGC_LANPERRSTS) & IGC_LANPERRSTS_RETX_BUF); + if (lanerr != 0) + IGC_WRITE_REG(hw, IGC_LANPERRSTS, lanerr); + /* + * DEV_RST can relatch PEIND from a subordinate status register + * before that register is cleared. Drain the recovered indication + * before unmasking FER so a later error is not misattributed. + */ + (void)IGC_READ_REG(hw, IGC_PEIND); + + sc->fatal_error_peind = 0; + sc->fatal_error_pcie = 0; + sc->fatal_error_lan = 0; + sc->fatal_error_mng = 0; + atomic_store_rel_32(&sc->fatal_error_state, IGC_FATAL_ERROR_NONE); +} + /* * I225/I226 have three configurable LED outputs. DPDK uses LED1 for * adapter identification; retain that convention and preserve the OEM's @@ -2569,9 +2760,13 @@ igc_if_intr_enable(if_ctx_t ctx) IGC_WRITE_REG(hw, IGC_EIAC, mask); IGC_WRITE_REG(hw, IGC_EIAM, mask); IGC_WRITE_REG(hw, IGC_EIMS, mask); - IGC_WRITE_REG(hw, IGC_IMS, IGC_IMS_LSC); + mask = IGC_IMS_LSC; } else - IGC_WRITE_REG(hw, IGC_IMS, IMS_ENABLE_MASK); + mask = IMS_ENABLE_MASK; + if (atomic_load_acq_32(&sc->fatal_error_state) == + IGC_FATAL_ERROR_NONE) + mask |= IGC_IMS_FER; + IGC_WRITE_REG(hw, IGC_IMS, mask); IGC_WRITE_FLUSH(hw); } @@ -2901,8 +3096,10 @@ igc_add_hw_stats(struct igc_softc *sc) struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); struct igc_hw_stats *stats = &sc->stats; - struct sysctl_oid *eee_node, *stat_node, *queue_node, *int_node; - struct sysctl_oid_list *eee_list, *stat_list, *queue_list, *int_list; + struct sysctl_oid *eee_node, *memerr_node, *stat_node, *queue_node, + *int_node; + struct sysctl_oid_list *eee_list, *memerr_list, *stat_list, *queue_list, + *int_list; #define QUEUE_NAME_LEN 32 char namebuf[QUEUE_NAME_LEN]; @@ -2931,6 +3128,25 @@ igc_add_hw_stats(struct igc_softc *sc) SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_low_water", CTLFLAG_RD, &sc->hw.fc.low_water, 0, "Flow Control Low Watermark"); + memerr_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "memory_errors", + CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, + "Internal memory error indications"); + memerr_list = SYSCTL_CHILDREN(memerr_node); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "fatal_lan", + CTLFLAG_RD, &sc->fatal_error_lan_count, + "Fatal LAN-port memory error indications"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "fatal_management", + CTLFLAG_RD, &sc->fatal_error_mng_count, + "Fatal management-memory error indications"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "fatal_pcie", + CTLFLAG_RD, &sc->fatal_error_pcie_count, + "Fatal PCIe memory error indications"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "fatal_dma", + CTLFLAG_RD, &sc->fatal_error_dma_count, + "Fatal DMA memory error indications"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "fatal_unknown", + CTLFLAG_RD, &sc->fatal_error_unknown_count, + "Fatal memory errors without a reported region"); eee_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "eee", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Energy Efficient Ethernet statistics"); diff --git a/sys/dev/igc/if_igc.h b/sys/dev/igc/if_igc.h index c98f17a97ca3..8b35e1f59a60 100644 --- a/sys/dev/igc/if_igc.h +++ b/sys/dev/igc/if_igc.h @@ -414,6 +414,16 @@ struct igc_softc { unsigned long dropped_pkts; unsigned long link_irq; unsigned long rx_overruns; + u32 fatal_error_state; + u32 fatal_error_peind; + u32 fatal_error_pcie; + u32 fatal_error_lan; + u32 fatal_error_mng; + uint64_t fatal_error_lan_count; + uint64_t fatal_error_mng_count; + uint64_t fatal_error_pcie_count; + uint64_t fatal_error_dma_count; + uint64_t fatal_error_unknown_count; struct igc_hw_stats stats; u16 vf_ifp; }; diff --git a/sys/dev/igc/igc_defines.h b/sys/dev/igc/igc_defines.h index 885f0799f6a6..1856c86b91a8 100644 --- a/sys/dev/igc/igc_defines.h +++ b/sys/dev/igc/igc_defines.h @@ -254,6 +254,7 @@ #define IGC_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Compltn by NVM */ #define IGC_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ #define IGC_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */ +#define IGC_STATUS_RST_DONE 0x00200000 /* Device reset complete */ #define IGC_STATUS_2P5_SKU 0x00001000 /* Val of 2.5GBE SKU strap */ #define IGC_STATUS_2P5_SKU_OVER 0x00002000 /* Val of 2.5GBE SKU Over */ #define IGC_STATUS_PCIM_STATE 0x40000000 /* PCIm function state */ @@ -427,11 +428,25 @@ #define IGC_PBS_16K IGC_PBA_16K -/* Uncorrectable/correctable ECC Error counts and enable bits */ -#define IGC_PBECCSTS_CORR_ERR_CNT_MASK 0x000000FF -#define IGC_PBECCSTS_UNCORR_ERR_CNT_MASK 0x0000FF00 -#define IGC_PBECCSTS_UNCORR_ERR_CNT_SHIFT 8 -#define IGC_PBECCSTS_ECC_ENABLE 0x00010000 +/* I225/I226 memory error status bits. */ +#define IGC_PEIND_LANPORT_PARITY_FATAL 0x00000001 +#define IGC_PEIND_MNG_PARITY_FATAL 0x00000002 +#define IGC_PEIND_PCIE_PARITY_FATAL 0x00000004 +#define IGC_PEIND_DMA_PARITY_FATAL 0x00000008 +#define IGC_PEIND_FATAL_MASK 0x0000000F +#define IGC_PEIND_HOST_FATAL_MASK (IGC_PEIND_LANPORT_PARITY_FATAL | \ + IGC_PEIND_PCIE_PARITY_FATAL | IGC_PEIND_DMA_PARITY_FATAL) + +#define IGC_PBECCSTS_ECC_ENABLE 0x00000001 +#define IGC_PBECCSTS_CORR_ERR 0x00000004 + +#define IGC_PCIEERRSTS_FATAL_MASK 0x00000078 +#define IGC_PCIEECCSTS_TX_WR_DATA 0x00000010 +#define IGC_PCIEECCSTS_RETRY_BUF 0x00000020 +#define IGC_PCIEECCSTS_CORR_MASK 0x00000030 + +#define IGC_LANPERRSTS_RETX_BUF 0x00000200 +#define IGC_MNGPARSTS_FATAL_MASK 0x00000003 #define IFS_MAX 80 #define IFS_MIN 40 diff --git a/sys/dev/igc/igc_regs.h b/sys/dev/igc/igc_regs.h index f4690e24c2af..849b13b2adf2 100644 --- a/sys/dev/igc/igc_regs.h +++ b/sys/dev/igc/igc_regs.h @@ -376,8 +376,13 @@ #define IGC_FCRTC 0x02170 /* Flow Control Rx high watermark */ #define IGC_PCIEMISC 0x05BB8 /* PCIE misc config register */ -/* PCIe Parity Status Register */ -#define IGC_PCIEERRSTS 0x05BA8 +/* Memory error detection registers */ +#define IGC_PEIND 0x01084 /* Parity and ECC Indication - RC */ +#define IGC_PBECCSTS 0x0245C /* Packet Buffer ECC Status */ +#define IGC_PCIEERRSTS 0x05BA8 /* PCIe Parity Status - RW1C */ +#define IGC_PCIEECCSTS 0x05BAC /* PCIe ECC Status - RW1C */ +#define IGC_LANPERRSTS 0x05F58 /* LAN Port Parity Status - RW1C */ +#define IGC_MNGPARSTS 0x08F24 /* Management Parity Status */ #define IGC_PROXYS 0x5F64 /* Proxying Status */ #define IGC_PROXYFC 0x5F60 /* Proxying Filter Control */