bge: Limit BCM5701 B5 to 32-bit mode
[dragonfly.git] / sys / dev / netif / bge / if_bge.c
index e1a65d4..6f44e62 100644 (file)
@@ -396,9 +396,9 @@ TUNABLE_INT("hw.bge.tx_max_coal_bds", &bge_tx_max_coal_bds);
 #define KTR_IF_BGE     KTR_ALL
 #endif
 KTR_INFO_MASTER(if_bge);
-KTR_INFO(KTR_IF_BGE, if_bge, intr, 0, "intr", 0);
-KTR_INFO(KTR_IF_BGE, if_bge, rx_pkt, 1, "rx_pkt", 0);
-KTR_INFO(KTR_IF_BGE, if_bge, tx_pkt, 2, "tx_pkt", 0);
+KTR_INFO(KTR_IF_BGE, if_bge, intr, 0, "intr");
+KTR_INFO(KTR_IF_BGE, if_bge, rx_pkt, 1, "rx_pkt");
+KTR_INFO(KTR_IF_BGE, if_bge, tx_pkt, 2, "tx_pkt");
 #define logif(name)    KTR_LOG(if_bge_ ## name)
 
 static device_method_t bge_methods[] = {
@@ -1295,6 +1295,16 @@ bge_chipinit(struct bge_softc *sc)
            BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS|
            BGE_MODECTL_TX_NO_PHDR_CSUM);
 
+       /*
+        * BCM5701 B5 have a bug causing data corruption when using
+        * 64-bit DMA reads, which can be terminated early and then
+        * completed later as 32-bit accesses, in combination with
+        * certain bridges.
+        */
+       if (sc->bge_asicrev == BGE_ASICREV_BCM5701 &&
+           sc->bge_chipid == BGE_CHIPID_BCM5701_B5)
+               BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);
+
        /*
         * Disable memory write invalidate.  Apparently it is not supported
         * properly by these devices.
@@ -2374,14 +2384,11 @@ bge_rxeof(struct bge_softc *sc)
 {
        struct ifnet *ifp;
        int stdcnt = 0, jumbocnt = 0;
-       struct mbuf_chain chain[MAXCPU];
 
        if (sc->bge_rx_saved_considx ==
            sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx)
                return;
 
-       ether_input_chain_init(chain);
-
        ifp = &sc->arpcom.ac_if;
 
        while (sc->bge_rx_saved_considx !=
@@ -2493,11 +2500,9 @@ bge_rxeof(struct bge_softc *sc)
                        m->m_pkthdr.ether_vlantag = vlan_tag;
                        have_tag = vlan_tag = 0;
                }
-               ether_input_chain(ifp, m, NULL, chain);
+               ifp->if_input(ifp, m);
        }
 
-       ether_input_dispatch(chain);
-
        bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx);
        if (stdcnt)
                bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);
@@ -2756,7 +2761,7 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head0, uint32_t *txidx)
 
        maxsegs = (BGE_TX_RING_CNT - sc->bge_txcnt) - BGE_NSEG_RSVD;
        KASSERT(maxsegs >= BGE_NSEG_SPARE,
-               ("not enough segments %d\n", maxsegs));
+               ("not enough segments %d", maxsegs));
 
        if (maxsegs > BGE_NSEG_NEW)
                maxsegs = BGE_NSEG_NEW;