@@ -462,6 +462,8 @@ static void em_finish_fatal_error_reset(struct e1000_softc *);
462462static void em_configure_peind_memory_errors (struct e1000_softc * );
463463static void em_configure_82575_memory_errors (struct e1000_softc * );
464464static void em_configure_82580_memory_errors (struct e1000_softc * );
465+ static void em_update_82580_ecc_stats (struct e1000_softc * , u32 , u32 ,
466+ u32 );
465467static void em_if_multi_set (if_ctx_t );
466468static void em_if_update_admin_status (if_ctx_t );
467469static void em_if_debug (if_ctx_t );
@@ -2303,10 +2305,11 @@ em_configure_82580_memory_errors(struct e1000_softc *sc)
23032305 em_clear_82580_memory_error_status (hw , E1000_DRPARS_82580 );
23042306 em_clear_82580_memory_error_status (hw , E1000_DDPARS_82580 );
23052307 em_clear_82580_memory_error_status (hw , E1000_PCIEERRSTS );
2306- em_clear_82580_memory_error_status (hw , E1000_PCIEECCSTS );
23072308 (void )E1000_READ_REG (hw , E1000_LANPERRSTS );
2308- (void )E1000_READ_REG (hw , E1000_RPBECCSTS );
2309- (void )E1000_READ_REG (hw , E1000_TPBECCSTS );
2309+ em_update_82580_ecc_stats (sc ,
2310+ E1000_READ_REG (hw , E1000_RPBECCSTS ),
2311+ E1000_READ_REG (hw , E1000_TPBECCSTS ),
2312+ E1000_READ_REG (hw , E1000_PCIEECCSTS ));
23102313 E1000_WRITE_REG (hw , E1000_RPBECCSTS ,
23112314 E1000_PBECCSTS_82580_ECC_ENABLE );
23122315 E1000_WRITE_REG (hw , E1000_TPBECCSTS ,
@@ -2434,6 +2437,21 @@ em_fatal_error_intr_mask(struct e1000_softc *sc)
24342437 return (em_memory_error_intr_mask (& sc -> hw ));
24352438}
24362439
2440+ static void
2441+ em_update_82580_ecc_stats (struct e1000_softc * sc , u32 rpbeccsts ,
2442+ u32 tpbeccsts , u32 pcieeccsts )
2443+ {
2444+ u32 status ;
2445+
2446+ sc -> corrected_error_packet_buffer_count +=
2447+ (rpbeccsts & E1000_PBECCSTS_82580_CORR_CNT_MASK ) +
2448+ (tpbeccsts & E1000_PBECCSTS_82580_CORR_CNT_MASK );
2449+ status = pcieeccsts & E1000_PCIEECCSTS_82580_ERROR_MASK ;
2450+ sc -> uncorrected_error_pcie_count += bitcount32 (status );
2451+ if (status != 0 )
2452+ E1000_WRITE_REG (& sc -> hw , E1000_PCIEECCSTS , status );
2453+ }
2454+
24372455static void
24382456em_update_82575_ecc_stats (struct e1000_softc * sc , u32 pbeccsts ,
24392457 u32 rdhests , u32 tdhests )
@@ -2625,8 +2643,7 @@ static void
26252643em_handle_fatal_error_intr (struct e1000_softc * sc , u32 icr )
26262644{
26272645 struct e1000_hw * hw ;
2628- u32 dma_host , dma_rx , dma_tx , error_mask , lanerr , pcieecc ;
2629- u32 pcieerr , peind ;
2646+ u32 dma_host , dma_rx , dma_tx , error_mask , lanerr , pcieerr , peind ;
26302647
26312648 error_mask = em_memory_error_intr_mask (& sc -> hw );
26322649 if (!em_has_memory_errors (& sc -> hw ) ||
@@ -2657,7 +2674,6 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr)
26572674 E1000_PEIND_FATAL_MASK ;
26582675 pcieerr = E1000_READ_REG (hw , E1000_PCIEERRSTS ) &
26592676 em_pcie_fatal_error_mask (hw );
2660- pcieecc = 0 ;
26612677 dma_host = 0 ;
26622678 if (em_has_82580_memory_errors (hw )) {
26632679 /*
@@ -2667,8 +2683,6 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr)
26672683 * status registers.
26682684 */
26692685 peind &= E1000_PEIND_MNG_PARITY_FATAL ;
2670- pcieecc = E1000_READ_REG (hw , E1000_PCIEECCSTS ) &
2671- E1000_PCIEECCSTS_82580_ERROR_MASK ;
26722686 dma_tx = E1000_READ_REG (hw , E1000_DTPARS_82580 );
26732687 dma_rx = E1000_READ_REG (hw , E1000_DRPARS_82580 );
26742688 dma_host = E1000_READ_REG (hw ,
@@ -2688,15 +2702,14 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr)
26882702 lanerr = E1000_READ_REG (hw , E1000_LANPERRSTS ) &
26892703 E1000_LANPERRSTS_RETX_BUF ;
26902704 }
2691- if (pcieerr != 0 || pcieecc != 0 )
2705+ if (pcieerr != 0 )
26922706 peind |= E1000_PEIND_PCIE_PARITY_FATAL ;
26932707 if (lanerr != 0 )
26942708 peind |= E1000_PEIND_LANPORT_PARITY_FATAL ;
26952709 if (dma_tx != 0 || dma_rx != 0 || dma_host != 0 )
26962710 peind |= E1000_PEIND_DMA_PARITY_FATAL ;
26972711 sc -> fatal_error_peind = peind ;
26982712 sc -> fatal_error_pcie = pcieerr ;
2699- sc -> fatal_error_pcie_ecc = pcieecc ;
27002713 sc -> fatal_error_lan = lanerr ;
27012714 sc -> fatal_error_dma_tx = dma_tx ;
27022715 sc -> fatal_error_dma_rx = dma_rx ;
@@ -2710,7 +2723,7 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr)
27102723static bool
27112724em_handle_fatal_error_admin (struct e1000_softc * sc )
27122725{
2713- u32 error_mask , peind ;
2726+ u32 error_mask , pcieecc , peind ;
27142727 bool reset_required ;
27152728
27162729 if (!atomic_cmpset_acq_32 (& sc -> fatal_error_state ,
@@ -2761,6 +2774,20 @@ em_handle_fatal_error_admin(struct e1000_softc *sc)
27612774 "requesting reset\n" , peind );
27622775 } else {
27632776 peind = sc -> fatal_error_peind ;
2777+ if (em_has_82580_memory_errors (& sc -> hw )) {
2778+ pcieecc = E1000_READ_REG (& sc -> hw ,
2779+ E1000_PCIEECCSTS ) &
2780+ E1000_PCIEECCSTS_82580_ERROR_MASK ;
2781+ sc -> fatal_error_pcie_ecc |= pcieecc ;
2782+ if (pcieecc != 0 ) {
2783+ peind |= E1000_PEIND_PCIE_PARITY_FATAL ;
2784+ sc -> fatal_error_peind = peind ;
2785+ }
2786+ em_update_82580_ecc_stats (sc ,
2787+ E1000_READ_REG (& sc -> hw , E1000_RPBECCSTS ),
2788+ E1000_READ_REG (& sc -> hw , E1000_TPBECCSTS ),
2789+ pcieecc );
2790+ }
27642791 if (peind & E1000_PEIND_LANPORT_PARITY_FATAL )
27652792 sc -> fatal_error_lan_count ++ ;
27662793 if (peind & E1000_PEIND_MNG_PARITY_FATAL )
@@ -2843,6 +2870,9 @@ em_handle_fatal_error_admin(struct e1000_softc *sc)
28432870 * PCIe traffic for a fatal error in any host-owned region, so use the same
28442871 * order for every 82580 recovery. This differs from the normal reset path,
28452872 * which disables the bus master first.
2873+ *
2874+ * Indications that relatch after admin accounting are discarded during
2875+ * reset; sticky bits cannot distinguish them from the saved event.
28462876 */
28472877static void
28482878em_prepare_fatal_error_reset (struct e1000_softc * sc )
@@ -6587,6 +6617,11 @@ em_update_stats_counters(struct e1000_softc *sc)
65876617 E1000_READ_REG (& sc -> hw , E1000_TDHESTS_82575 ));
65886618 else if (em_has_82576_memory_errors (& sc -> hw ))
65896619 em_update_82576_ecc_stats (sc );
6620+ else if (em_has_82580_memory_errors (& sc -> hw ))
6621+ em_update_82580_ecc_stats (sc ,
6622+ E1000_READ_REG (& sc -> hw , E1000_RPBECCSTS ),
6623+ E1000_READ_REG (& sc -> hw , E1000_TPBECCSTS ),
6624+ E1000_READ_REG (& sc -> hw , E1000_PCIEECCSTS ));
65906625 else if (em_has_i350_memory_errors (& sc -> hw ))
65916626 em_update_i350_ecc_stats (sc );
65926627 else if (em_has_i210_memory_errors (& sc -> hw ))
@@ -7101,7 +7136,16 @@ em_add_hw_stats(struct e1000_softc *sc)
71017136 "fatal_unknown" , CTLFLAG_RD ,
71027137 & sc -> fatal_error_unknown_count ,
71037138 "Fatal memory errors without a reported region" );
7104- if (em_has_i210_memory_errors (& sc -> hw )) {
7139+ if (em_has_82580_memory_errors (& sc -> hw )) {
7140+ SYSCTL_ADD_UQUAD (ctx , memerr_list , OID_AUTO ,
7141+ "corrected_packet_buffer" , CTLFLAG_RD ,
7142+ & sc -> corrected_error_packet_buffer_count ,
7143+ "Corrected packet-buffer ECC errors" );
7144+ SYSCTL_ADD_UQUAD (ctx , memerr_list , OID_AUTO ,
7145+ "uncorrected_pcie" , CTLFLAG_RD ,
7146+ & sc -> uncorrected_error_pcie_count ,
7147+ "Uncorrected PCIe command-memory ECC indications" );
7148+ } else if (em_has_i210_memory_errors (& sc -> hw )) {
71057149 SYSCTL_ADD_UQUAD (ctx , memerr_list , OID_AUTO ,
71067150 "corrected_dma" , CTLFLAG_RD ,
71077151 & sc -> corrected_error_dma_count ,
0 commit comments