bge: Limit STD RX ring prod index increment to 8 for 5750, 5752 and 5755
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 31 Mar 2013 10:26:40 +0000 (18:26 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 31 Mar 2013 10:28:49 +0000 (18:28 +0800)
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

sys/dev/netif/bge/if_bge.c
sys/dev/netif/bge/if_bgevar.h

index c8b754d..0c7051f 100644 (file)
@@ -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);
index 249f40b..a61687e 100644 (file)
@@ -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;