From: Sepherosa Ziehau Date: Sun, 31 Mar 2013 10:26:40 +0000 (+0800) Subject: bge: Limit STD RX ring prod index increment to 8 for 5750, 5752 and 5755 X-Git-Tag: v3.4.0rc~11 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/4849f4a34b2854c78dd0989f3258794db98520ab bge: Limit STD RX ring prod index increment to 8 for 5750, 5752 and 5755 This works around hardware errata. NOTE: For 5750, 5752 and 5755, the STD RX ring replesh threshold has already been set to 8. Obtained-from: tg3 --- diff --git a/sys/dev/netif/bge/if_bge.c b/sys/dev/netif/bge/if_bge.c index c8b754db54..0c7051ff8b 100644 --- a/sys/dev/netif/bge/if_bge.c +++ b/sys/dev/netif/bge/if_bge.c @@ -2089,6 +2089,15 @@ bge_attach(device_t dev) if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906) sc->bge_flags |= BGE_FLAG_SHORTDMA; + /* + * Increase STD RX ring prod index by at most 8 for BCM5750, + * BCM5752 and BCM5755 to workaround hardware errata. + */ + if (sc->bge_asicrev == BGE_ASICREV_BCM5750 || + sc->bge_asicrev == BGE_ASICREV_BCM5752 || + sc->bge_asicrev == BGE_ASICREV_BCM5755) + sc->bge_rx_wreg = 8; + /* * Check if this is a PCI-X or PCI Express device. */ @@ -2950,6 +2959,8 @@ bge_rxeof(struct bge_softc *sc, uint16_t rx_prod, int count) continue; } } else { + int discard = 0; + BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); stdcnt++; @@ -2959,20 +2970,30 @@ bge_rxeof(struct bge_softc *sc, uint16_t rx_prod, int count) "and hw std index(%d) mismatch, drop!\n", sc->bge_std, rxidx); bge_setup_rxdesc_std(sc, rxidx); - continue; + discard = 1; + goto refresh_rx; } m = sc->bge_cdata.bge_rx_std_chain[rxidx].bge_mbuf; if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { IFNET_STAT_INC(ifp, ierrors, 1); bge_setup_rxdesc_std(sc, sc->bge_std); - continue; + discard = 1; + goto refresh_rx; } if (bge_newbuf_std(sc, sc->bge_std, 0)) { IFNET_STAT_INC(ifp, ierrors, 1); bge_setup_rxdesc_std(sc, sc->bge_std); - continue; + discard = 1; } +refresh_rx: + if (sc->bge_rx_wreg > 0 && stdcnt >= sc->bge_rx_wreg) { + bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, + sc->bge_std); + stdcnt = 0; + } + if (discard) + continue; } IFNET_STAT_INC(ifp, ipackets, 1); diff --git a/sys/dev/netif/bge/if_bgevar.h b/sys/dev/netif/bge/if_bgevar.h index 249f40b334..a61687e178 100644 --- a/sys/dev/netif/bge/if_bgevar.h +++ b/sys/dev/netif/bge/if_bgevar.h @@ -253,6 +253,7 @@ struct bge_softc { uint32_t bge_tx_coal_bds_int; uint32_t bge_tx_prodidx; int bge_tx_wreg; + int bge_rx_wreg; uint32_t bge_tx_buf_ratio; uint32_t bge_mi_mode; int bge_force_defrag;