summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_bnx.c259
-rw-r--r--sys/dev/pci/if_bnxreg.h16
2 files changed, 177 insertions, 98 deletions
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index 7048f52554c..0df4f6bd894 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnx.c,v 1.63 2008/06/13 21:40:21 brad Exp $ */
+/* $OpenBSD: if_bnx.c,v 1.64 2008/06/24 23:02:42 brad Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -374,6 +374,7 @@ int bnx_get_buf(struct bnx_softc *, struct mbuf *, u_int16_t *,
u_int16_t *, u_int32_t *);
int bnx_init_tx_chain(struct bnx_softc *);
+void bnx_fill_rx_chain(struct bnx_softc *);
int bnx_init_rx_chain(struct bnx_softc *);
void bnx_free_rx_chain(struct bnx_softc *);
void bnx_free_tx_chain(struct bnx_softc *);
@@ -2929,7 +2930,7 @@ bnx_stop(struct bnx_softc *sc)
/* Tell firmware that the driver is going away. */
bnx_reset(sc, BNX_DRV_MSG_CODE_SUSPEND_NO_WOL);
- /* Free the RX lists. */
+ /* Free RX buffers. */
bnx_free_rx_chain(sc);
/* Free TX buffers. */
@@ -3275,11 +3276,12 @@ bnx_get_buf(struct bnx_softc *sc, struct mbuf *m, u_int16_t *prod,
"0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod,
*prod_bseq);
+ /* Check whether this is a new mbuf allocation. */
if (m == NULL) {
+ /* Simulate an mbuf allocation failure. */
DBRUNIF(DB_RANDOMTRUE(bnx_debug_mbuf_allocation_failure),
- BNX_PRINTF(sc, "Simulating mbuf allocation failure.\n");
-
sc->mbuf_alloc_failed++;
+ sc->mbuf_sim_alloc_failed++;
rc = ENOBUFS;
goto bnx_get_buf_exit);
@@ -3290,13 +3292,24 @@ bnx_get_buf(struct bnx_softc *sc, struct mbuf *m, u_int16_t *prod,
"%s(%d): RX mbuf header allocation failed!\n",
__FILE__, __LINE__);
- DBRUNIF(1, sc->mbuf_alloc_failed++);
+ sc->mbuf_alloc_failed++;
rc = ENOBUFS;
goto bnx_get_buf_exit;
}
DBRUNIF(1, sc->rx_mbuf_alloc++);
+
+ /* Simulate an mbuf cluster allocation failure. */
+ DBRUNIF(DB_RANDOMTRUE(bnx_debug_mbuf_allocation_failure),
+ m_freem(m_new);
+ sc->rx_mbuf_alloc--;
+ sc->mbuf_alloc_failed++;
+ sc->mbuf_sim_alloc_failed++;
+ rc = ENOBUFS;
+ goto bnx_get_buf_exit);
+
+ /* Attach a cluster to the mbuf. */
MCLGET(m_new, M_DONTWAIT);
if (!(m_new->m_flags & M_EXT)) {
DBPRINT(sc, BNX_WARN,
@@ -3304,16 +3317,17 @@ bnx_get_buf(struct bnx_softc *sc, struct mbuf *m, u_int16_t *prod,
__FILE__, __LINE__);
m_freem(m_new);
-
DBRUNIF(1, sc->rx_mbuf_alloc--);
- DBRUNIF(1, sc->mbuf_alloc_failed++);
+ sc->mbuf_alloc_failed++;
rc = ENOBUFS;
goto bnx_get_buf_exit;
}
+ /* Initialize the mbuf cluster. */
m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
} else {
+ /* Reuse an existing mbuf. */
m_new = m;
m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
m_new->m_data = m_new->m_ext.ext_buf;
@@ -3327,22 +3341,32 @@ bnx_get_buf(struct bnx_softc *sc, struct mbuf *m, u_int16_t *prod,
__FILE__, __LINE__);
m_freem(m_new);
-
DBRUNIF(1, sc->rx_mbuf_alloc--);
rc = ENOBUFS;
goto bnx_get_buf_exit;
}
- /* Watch for overflow. */
- DBRUNIF((sc->free_rx_bd > USABLE_RX_BD),
- printf("%s: Too many free rx_bd (0x%04X > 0x%04X)!\n",
- sc->free_rx_bd, (u_int16_t) USABLE_RX_BD));
+ /* Make sure there is room in the receive chain. */
+ if (map->dm_nsegs > sc->free_rx_bd) {
+ bus_dmamap_unload(sc->bnx_dmatag, map);
+
+ m_freem(m_new);
+ DBRUNIF(1, sc->rx_mbuf_alloc--);
+
+ rc = EFBIG;
+ goto bnx_get_buf_exit;
+ }
+
+#ifdef BNX_DEBUG
+ /* Track the distribution of buffer segments. */
+ sc->rx_mbuf_segs[map->dm_nsegs]++;
+#endif
/* Update some debug statistics counters */
DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
sc->rx_low_watermark = sc->free_rx_bd);
- DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++);
+ DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
/* Setup the rx_bd for the first segment. */
rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
@@ -3503,6 +3527,8 @@ bnx_free_tx_chain(struct bnx_softc *sc)
for (i = 0; i < TX_PAGES; i++)
bzero((char *)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ);
+ sc->used_tx_bd = 0;
+
/* Check if we lost any mbufs in the process. */
DBRUNIF((sc->tx_mbuf_alloc),
printf("%s: Memory leak! Lost %d mbufs from tx chain!\n",
@@ -3512,6 +3538,60 @@ bnx_free_tx_chain(struct bnx_softc *sc)
}
/****************************************************************************/
+/* Add mbufs to the RX chain until its full or an mbuf allocation error */
+/* occurs. */
+/* */
+/* Returns: */
+/* Nothing */
+/****************************************************************************/
+void
+bnx_fill_rx_chain(struct bnx_softc *sc)
+{
+ u_int16_t prod, chain_prod;
+ u_int32_t prod_bseq;
+#ifdef BNX_DEBUG
+ int rx_mbuf_alloc_before, free_rx_bd_before;
+#endif
+
+ DBPRINT(sc, BNX_EXCESSIVE_RECV, "Entering %s()\n", __FUNCTION__);
+
+ prod = sc->rx_prod;
+ prod_bseq = sc->rx_prod_bseq;
+
+#ifdef BNX_DEBUG
+ rx_mbuf_alloc_before = sc->rx_mbuf_alloc;
+ free_rx_bd_before = sc->free_rx_bd;
+#endif
+
+ /* Keep filling the RX chain until it's full. */
+ while (sc->free_rx_bd > 0) {
+ chain_prod = RX_CHAIN_IDX(prod);
+ if (bnx_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq)) {
+ /* Bail out if we can't add an mbuf to the chain. */
+ break;
+ }
+ prod = NEXT_RX_BD(prod);
+ }
+
+#if 0
+ DBRUNIF((sc->rx_mbuf_alloc - rx_mbuf_alloc_before),
+ BNX_PRINTF(sc, "%s(): Installed %d mbufs in %d rx_bd entries.\n",
+ __FUNCTION__, (sc->rx_mbuf_alloc - rx_mbuf_alloc_before),
+ (free_rx_bd_before - sc->free_rx_bd)));
+#endif
+
+ /* Save the RX chain producer index. */
+ sc->rx_prod = prod;
+ sc->rx_prod_bseq = prod_bseq;
+
+ /* Tell the chip about the waiting rx_bd's. */
+ REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
+ REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
+
+ DBPRINT(sc, BNX_EXCESSIVE_RECV, "Exiting %s()\n", __FUNCTION__);
+}
+
+/****************************************************************************/
/* Allocate memory and initialize the RX data structures. */
/* */
/* Returns: */
@@ -3522,8 +3602,7 @@ bnx_init_rx_chain(struct bnx_softc *sc)
{
struct rx_bd *rxbd;
int i, rc = 0;
- u_int16_t prod, chain_prod;
- u_int32_t prod_bseq, val, addr;
+ u_int32_t val, addr;
DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
@@ -3567,32 +3646,14 @@ bnx_init_rx_chain(struct bnx_softc *sc)
val = (u_int32_t)(sc->rx_bd_chain_paddr[0]);
CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_NX_BDHADDR_LO, val);
- /* Allocate mbuf clusters for the rx_bd chain. */
- prod = prod_bseq = 0;
- while (prod < TOTAL_RX_BD) {
- chain_prod = RX_CHAIN_IDX(prod);
- if (bnx_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq)) {
- BNX_PRINTF(sc, "Error filling RX chain: rx_bd[0x%04X]!\n",
- chain_prod);
- rc = ENOBUFS;
- break;
- }
- prod = NEXT_RX_BD(prod);
- }
-
- /* Save the RX chain producer index. */
- sc->rx_prod = prod;
- sc->rx_prod_bseq = prod_bseq;
+ /* Fill up the RX chain. */
+ bnx_fill_rx_chain(sc);
for (i = 0; i < RX_PAGES; i++)
bus_dmamap_sync(sc->bnx_dmatag, sc->rx_bd_chain_map[i], 0,
sc->rx_bd_chain_map[i]->dm_mapsize,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- /* Tell the chip about the waiting rx_bd's. */
- REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
- REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
-
DBRUN(BNX_VERBOSE_RECV, bnx_dump_rx_chain(sc, 0, TOTAL_RX_BD));
DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
@@ -3610,9 +3671,16 @@ void
bnx_free_rx_chain(struct bnx_softc *sc)
{
int i;
+#ifdef BNX_DEBUG
+ int rx_mbuf_alloc_before;
+#endif
DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
+#ifdef BNX_DEBUG
+ rx_mbuf_alloc_before = sc->rx_mbuf_alloc;
+#endif
+
/* Free any mbufs still in the RX mbuf chain. */
for (i = 0; i < TOTAL_RX_BD; i++) {
if (sc->rx_mbuf_ptr[i] != NULL) {
@@ -3627,10 +3695,16 @@ bnx_free_rx_chain(struct bnx_softc *sc)
}
}
+ DBRUNIF((rx_mbuf_alloc_before - sc->rx_mbuf_alloc),
+ BNX_PRINTF(sc, "%s(): Released %d mbufs.\n",
+ __FUNCTION__, (rx_mbuf_alloc_before - sc->rx_mbuf_alloc)));
+
/* Clear each RX chain page. */
for (i = 0; i < RX_PAGES; i++)
bzero((char *)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
+ sc->free_rx_bd = sc->max_rx_bd;
+
/* Check if we lost any mbufs in the process. */
DBRUNIF((sc->rx_mbuf_alloc),
printf("%s: Memory leak! Lost %d mbufs from rx chain!\n",
@@ -3779,7 +3853,7 @@ bnx_rx_intr(struct bnx_softc *sc)
/* Update some debug statistics counters */
DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
sc->rx_low_watermark = sc->free_rx_bd);
- DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++);
+ DBRUNIF((sc->free_rx_bd == USABLE_RX_BD), sc->rx_empty_count++);
/*
* Scan through the receive chain as long
@@ -3791,6 +3865,9 @@ bnx_rx_intr(struct bnx_softc *sc)
unsigned int len;
u_int32_t status;
+ /* Clear the mbuf pointer. */
+ m = NULL;
+
/* Convert the producer/consumer indices to an actual
* rx_bd index.
*/
@@ -3826,7 +3903,7 @@ bnx_rx_intr(struct bnx_softc *sc)
bus_dmamap_unload(sc->bnx_dmatag,
sc->rx_mbuf_map[sw_chain_cons]);
- /* Remove the mbuf from the driver's chain. */
+ /* Remove the mbuf from RX chain. */
m = sc->rx_mbuf_ptr[sw_chain_cons];
sc->rx_mbuf_ptr[sw_chain_cons] = NULL;
@@ -3866,39 +3943,12 @@ bnx_rx_intr(struct bnx_softc *sc)
L2_FHDR_ERRORS_ALIGNMENT |
L2_FHDR_ERRORS_TOO_SHORT |
L2_FHDR_ERRORS_GIANT_FRAME)) {
+ /* Log the error and release the mbuf. */
ifp->if_ierrors++;
DBRUNIF(1, sc->l2fhdr_status_errors++);
- /* Reuse the mbuf for a new frame. */
- if (bnx_get_buf(sc, m, &sw_prod,
- &sw_chain_prod, &sw_prod_bseq)) {
- DBRUNIF(1, bnx_breakpoint(sc));
- panic("%s: Can't reuse RX mbuf!\n",
- sc->bnx_dev.dv_xname);
- }
- goto bnx_rx_int_next_rx;
- }
-
- /*
- * Get a new mbuf for the rx_bd. If no new
- * mbufs are available then reuse the current mbuf,
- * log an ierror on the interface, and generate
- * an error in the system log.
- */
- if (bnx_get_buf(sc, NULL, &sw_prod, &sw_chain_prod,
- &sw_prod_bseq)) {
- DBRUN(BNX_WARN, BNX_PRINTF(sc, "Failed to allocate "
- "new mbuf, incoming frame dropped!\n"));
-
- ifp->if_ierrors++;
-
- /* Try and reuse the exisitng mbuf. */
- if (bnx_get_buf(sc, m, &sw_prod,
- &sw_chain_prod, &sw_prod_bseq)) {
- DBRUNIF(1, bnx_breakpoint(sc));
- panic("%s: Double mbuf allocation "
- "failure!", sc->bnx_dev.dv_xname);
- }
+ m_freem(m);
+ m = NULL;
goto bnx_rx_int_next_rx;
}
@@ -3990,6 +4040,19 @@ bnx_rx_intr(struct bnx_softc *sc)
#endif
}
+ /* Pass the mbuf off to the upper layers. */
+ ifp->if_ipackets++;
+
+bnx_rx_int_next_rx:
+ sw_prod = NEXT_RX_BD(sw_prod);
+ }
+
+ sw_cons = NEXT_RX_BD(sw_cons);
+
+ /* If we have a packet, pass it up the stack */
+ if (m) {
+ sc->rx_cons = sw_cons;
+
#if NBPFILTER > 0
/*
* Handle BPF listeners. Let the BPF
@@ -3999,19 +4062,14 @@ bnx_rx_intr(struct bnx_softc *sc)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
#endif
- /* Pass the mbuf off to the upper layers. */
- ifp->if_ipackets++;
DBPRINT(sc, BNX_VERBOSE_RECV,
"%s(): Passing received frame up.\n", __FUNCTION__);
ether_input_mbuf(ifp, m);
DBRUNIF(1, sc->rx_mbuf_alloc--);
-bnx_rx_int_next_rx:
- sw_prod = NEXT_RX_BD(sw_prod);
+ sw_cons = sc->rx_cons;
}
- sw_cons = NEXT_RX_BD(sw_cons);
-
/* Refresh hw_cons to see if there's new work */
if (sw_cons == hw_cons) {
hw_cons = sc->hw_rx_cons =
@@ -4028,19 +4086,16 @@ bnx_rx_int_next_rx:
BUS_SPACE_BARRIER_READ);
}
+ /* No new packets to process. Refill the RX chain and exit. */
+ sc->rx_cons = sw_cons;
+ bnx_fill_rx_chain(sc);
+
for (i = 0; i < RX_PAGES; i++)
bus_dmamap_sync(sc->bnx_dmatag,
sc->rx_bd_chain_map[i], 0,
sc->rx_bd_chain_map[i]->dm_mapsize,
BUS_DMASYNC_PREWRITE);
- sc->rx_cons = sw_cons;
- sc->rx_prod = sw_prod;
- sc->rx_prod_bseq = sw_prod_bseq;
-
- REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
- REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
-
DBPRINT(sc, BNX_INFO_RECV, "%s(exit): rx_prod = 0x%04X, "
"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
@@ -4365,6 +4420,7 @@ bnx_tx_encap(struct bnx_softc *sc, struct mbuf **m_head)
sc->bnx_dev.dv_xname);
m_freem(m0);
*m_head = NULL;
+ sc->tx_dma_map_failures++;
return (error);
}
@@ -4635,6 +4691,13 @@ bnx_watchdog(struct ifnet *ifp)
DBRUN(BNX_WARN_SEND, bnx_dump_driver_state(sc);
bnx_dump_status_block(sc));
+ /*
+ * If we are in this routine because of pause frames, then
+ * don't reset the hardware.
+ */
+ if (REG_RD(sc, BNX_EMAC_TX_STATUS) & BNX_EMAC_TX_STATUS_XOFFED)
+ return;
+
printf("%s: Watchdog timeout occurred, resetting!\n",
ifp->if_xname);
@@ -5715,6 +5778,18 @@ bnx_dump_driver_state(struct bnx_softc *sc)
" 0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
sc->tx_prod_bseq);
+ BNX_PRINTF(sc,
+ " 0x%08X - (sc->tx_mbuf_alloc) tx mbufs allocated\n",
+ sc->tx_mbuf_alloc);
+
+ BNX_PRINTF(sc,
+ " 0x%08X - (sc->used_tx_bd) used tx_bd's\n",
+ sc->used_tx_bd);
+
+ BNX_PRINTF(sc,
+ " 0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
+ sc->tx_hi_watermark, sc->max_tx_bd);
+
BNX_PRINTF(sc, " 0x%08X - (sc->rx_prod) rx producer index\n",
sc->rx_prod);
@@ -5737,22 +5812,14 @@ bnx_dump_driver_state(struct bnx_softc *sc)
sc->rx_low_watermark, sc->max_rx_bd);
BNX_PRINTF(sc,
- " 0x%08X - (sc->txmbuf_alloc) tx mbufs allocated\n",
- sc->tx_mbuf_alloc);
-
- BNX_PRINTF(sc,
- " 0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
- sc->rx_mbuf_alloc);
-
- BNX_PRINTF(sc, " 0x%08X - (sc->used_tx_bd) used tx_bd's\n",
- sc->used_tx_bd);
-
- BNX_PRINTF(sc, "0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
- sc->tx_hi_watermark, sc->max_tx_bd);
+ " 0x%08X - (sc->mbuf_alloc_failed) "
+ "mbuf alloc failures\n",
+ sc->mbuf_alloc_failed);
BNX_PRINTF(sc,
- " 0x%08X - (sc->mbuf_alloc_failed) failed mbuf alloc\n",
- sc->mbuf_alloc_failed);
+ " 0x%0X - (sc->mbuf_sim_allocated_failed) "
+ "simulated mbuf alloc failures\n",
+ sc->mbuf_sim_alloc_failed);
BNX_PRINTF(sc, "-------------------------------------------"
"-----------------------------\n");
@@ -5828,10 +5895,10 @@ bnx_breakpoint(struct bnx_softc *sc)
bnx_dump_txbd(sc, 0, NULL);
bnx_dump_rxbd(sc, 0, NULL);
bnx_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
- bnx_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
+ bnx_dump_rx_mbuf_chain(sc, 0, sc->max_rx_bd);
bnx_dump_l2fhdr(sc, 0, NULL);
bnx_dump_tx_chain(sc, 0, USABLE_TX_BD);
- bnx_dump_rx_chain(sc, 0, USABLE_RX_BD);
+ bnx_dump_rx_chain(sc, 0, sc->max_rx_bd);
bnx_dump_status_block(sc);
bnx_dump_stats_block(sc);
bnx_dump_driver_state(sc);
diff --git a/sys/dev/pci/if_bnxreg.h b/sys/dev/pci/if_bnxreg.h
index 3631be964b5..e8763c70666 100644
--- a/sys/dev/pci/if_bnxreg.h
+++ b/sys/dev/pci/if_bnxreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnxreg.h,v 1.25 2008/06/13 07:40:30 brad Exp $ */
+/* $OpenBSD: if_bnxreg.h,v 1.26 2008/06/24 23:02:42 brad Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -424,6 +424,9 @@ struct flash_spec {
#define BNX_DRV_PULSE_MB 0x00000010
#define BNX_DRV_PULSE_SEQ_MASK 0x00007fff
+#define BNX_MB_ARGS_0 0x00000014
+#define BNX_MB_ARGS_1 0x00000018
+
/* Indicate to the firmware not to go into the
* OS absent when it is not getting driver pulse.
* This is used for debugging. */
@@ -4811,11 +4814,20 @@ struct bnx_softc
u_int32_t stat_CatchupInMBUFDiscards;
u_int32_t stat_CatchupInRuleCheckerP4Hit;
+ /* Mbuf allocation failure counter. */
+ u_int32_t mbuf_alloc_failed;
+
+ /* TX DMA mapping failure counter. */
+ u_int32_t tx_dma_map_failures;
+
#ifdef BNX_DEBUG
/* Track the number of enqueued mbufs. */
int tx_mbuf_alloc;
int rx_mbuf_alloc;
+ /* Track the distribution buffer segments. */
+ u_int32_t rx_mbuf_segs[BNX_MAX_SEGMENTS+1];
+
/* Track how many and what type of interrupts are generated. */
u_int32_t interrupts_generated;
u_int32_t interrupts_handled;
@@ -4826,7 +4838,7 @@ struct bnx_softc
u_int32_t rx_empty_count; /* Number of times the RX chain was empty. */
u_int32_t tx_hi_watermark; /* Greatest number of tx_bd's used. */
u_int32_t tx_full_count; /* Number of times the TX chain was full. */
- u_int32_t mbuf_alloc_failed; /* Mbuf allocation failure counter. */
+ u_int32_t mbuf_sim_alloc_failed; /* Mbuf simulated allocation failure counter. */
u_int32_t l2fhdr_status_errors;
u_int32_t unexpected_attentions;
u_int32_t lost_status_block_updates;