tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: boot problems with bge(4)



On 06/03/11 18:37, Christoph Egger wrote:
On 03.06.11 17:55, SAITOH Masanobu wrote:
Hi Christoph.

BCM5785 should not be PCIX chip. It's PCIe chip.

I suspect that your have some local patches for if_bge.c
Could you mail it to me? Please.

Yes, I can do that on monday.

Here we go.

Christoph


Thanks.

(2011/06/03 21:58), Christoph Egger wrote:
On 06/03/11 14:18, Christoph Egger wrote:

Hi,


[...]
bge0 at pci0 dev 20 function 6: Broadcom BCM5785G Gigabit Ethernet
bge0: interrupting at ioapic1 pin 18, event channel 9
bge0: unable to find PCIX capability
bge0: firmware handshake timed out, val = 4b657654
bge0: firmware handshake timed out, val = 4b657654
bge0: ASIC unknown BCM5785 (0x5785041), Ethernet address
00:00:1a:1a:d8:ab
brgphy0 at bge0 phy 1: BCM5785 1000BASE-T media interface, rev. 3
brgphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT,
1000baseT-FD , auto
[...]

I have a local patch to attach brgphy on bge(4) rather ukphy(4) ...


bge0: firmware handshake timed out, val = 4b657654
bge0: firmware handshake timed out, val = 4b657654
bge0: discarding oversize frame (len=-4)
bge0: discarding oversize frame (len=-4)
nfs_boot: trying DHCP/BOOTP
bge0: watchdog timeout -- resetting
bge0: firmware handshake timed out, val = 4b657654
bge0: firmware handshake timed out, val = 4b657654
bge0: discarding oversize frame (len=-4)
bge0: discarding oversize frame (len=-4)
nfs_boot: timeout...
nfs_boot: timeout...


The "discarding oversize frame" message comes from if_ethersubr.c

I just figured out in bge_rxeof():

      m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;

cur_rx->bge_len is 0.

Christoph




Index: if_bge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.197
diff -u -p -r1.197 if_bge.c
--- if_bge.c    3 Jun 2011 09:51:40 -0000       1.197
+++ if_bge.c    6 Jun 2011 13:05:45 -0000
@@ -518,6 +518,14 @@ static const struct bge_product {
          "BCM5784M NetLink 1000baseT Ethernet",
        },
        { PCI_VENDOR_BROADCOM,
+         PCI_PRODUCT_BROADCOM_BCM5785F,
+         "Broadcom BCM5785F Gigabit Ethernet",
+       },
+       { PCI_VENDOR_BROADCOM,
+         PCI_PRODUCT_BROADCOM_BCM5785G,
+         "Broadcom BCM5785G Gigabit Ethernet",
+       },
+       { PCI_VENDOR_BROADCOM,
          PCI_PRODUCT_BROADCOM_BCM5786,
          "Broadcom BCM5786 Gigabit Ethernet",
        },
@@ -1333,11 +1341,16 @@ bge_newbuf_std(struct bge_softc *sc, int
 
        if (m == NULL) {
                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-               if (m_new == NULL)
+               if (m_new == NULL) {
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: MGETHDR failed: ENOBUFS\n", __func__);
                        return ENOBUFS;
+               }
 
                MCLGET(m_new, M_DONTWAIT);
                if (!(m_new->m_flags & M_EXT)) {
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: MCLGET failed: ENOBUFS\n", __func__);
                        m_freem(m_new);
                        return ENOBUFS;
                }
@@ -1351,8 +1364,11 @@ bge_newbuf_std(struct bge_softc *sc, int
        if (!(sc->bge_flags & BGE_RX_ALIGNBUG))
            m_adj(m_new, ETHER_ALIGN);
        if (bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_new,
-           BUS_DMA_READ|BUS_DMA_NOWAIT))
+           BUS_DMA_READ|BUS_DMA_NOWAIT)) {
+               aprint_error_dev(sc->bge_dev,
+                   "%s: bus_dmamap_load_mbuf failed: ENOBUFS\n", __func__);
                return ENOBUFS;
+       }
        bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
            BUS_DMASYNC_PREREAD);
 
@@ -1387,8 +1403,11 @@ bge_newbuf_jumbo(struct bge_softc *sc, i
 
                /* Allocate the mbuf. */
                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-               if (m_new == NULL)
+               if (m_new == NULL) {
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: MGETHDR failed: ENOBUFS\n", __func__);
                        return ENOBUFS;
+               }
 
                /* Allocate the jumbo buffer */
                buf = bge_jalloc(sc);
@@ -1446,8 +1465,11 @@ bge_init_rx_ring_std(struct bge_softc *s
                return 0;
 
        for (i = 0; i < BGE_SSLOTS; i++) {
-               if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS)
+               if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS) {
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: bge_newbuf_std failed: ENOBUFS\n", __func__);
                        return ENOBUFS;
+               }
        }
 
        sc->bge_std = i - 1;
@@ -1490,8 +1512,11 @@ bge_init_rx_ring_jumbo(struct bge_softc 
                return 0;
 
        for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
-               if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
+               if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS) {
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: bge_newbuf_jumbo failed: ENOBUFS\n", __func__);
                        return ENOBUFS;
+               }
        };
 
        sc->bge_jumbo = i - 1;
@@ -1590,7 +1616,12 @@ bge_init_tx_ring(struct bge_softc *sc)
                if (bus_dmamap_create(sc->bge_dmatag, BGE_TXDMA_MAX,
                    BGE_NTXSEG, ETHER_MAX_LEN_JUMBO, 0, BUS_DMA_NOWAIT,
                    &dmamap))
+               {
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: bus_dmamap_create failed: ENOBUFS\n",
+                           __func__);
                        return ENOBUFS;
+               }
                if (dmamap == NULL)
                        panic("dmamap NULL in bge_init_tx_ring");
                dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT);
@@ -3405,6 +3450,11 @@ bge_rxeof(struct bge_softc *sc)
                        sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL;
                        stdcnt++;
                        dmamap = sc->bge_cdata.bge_rx_std_map[rxidx];
+                       if (dmamap == NULL) {
+                               ifp->if_ierrors++;
+                               bge_newbuf_std(sc, sc->bge_std, m, dmamap);
+                               continue;
+                       }
                        sc->bge_cdata.bge_rx_std_map[rxidx] = 0;
                        if (dmamap == NULL) {
                                ifp->if_ierrors++;
@@ -3441,7 +3491,11 @@ bge_rxeof(struct bge_softc *sc)
                }
 #endif
 
-               m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
+               if (cur_rx->bge_len >= ETHER_CRC_LEN)
+                       m->m_pkthdr.len = m->m_len = cur_rx->bge_len - 
ETHER_CRC_LEN;
+               else
+                       m->m_pkthdr.len = m->m_len = 0;
+
                m->m_pkthdr.rcvif = ifp;
 
                /*
@@ -3498,6 +3552,11 @@ bge_txeof(struct bge_softc *sc)
        int tosync;
        struct mbuf *m;
 
+       /* Nothing to do */
+       if (sc->bge_tx_saved_considx ==
+           sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx)
+               return;
+
        ifp = &sc->ethercom.ec_if;
 
        bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map,
@@ -3554,11 +3613,13 @@ bge_txeof(struct bge_softc *sc)
                }
                sc->bge_txcnt--;
                BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT);
-               ifp->if_timer = 0;
        }
 
-       if (cur_tx != NULL)
+       if (sc->bge_txcnt < BGE_TX_RING_CNT - 16) {
                ifp->if_flags &= ~IFF_OACTIVE;
+       }
+       if (sc->bge_txcnt == 0)
+               ifp->if_timer = 0;
 }
 
 static int
@@ -3622,9 +3685,7 @@ bge_intr(void *xsc)
 
                /* Re-enable interrupts. */
                bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
-
-               if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
-                       bge_start(ifp);
+               bge_start(ifp);
 
                return 1;
        } else
@@ -3778,8 +3839,10 @@ bge_cksum_pad(struct mbuf *pkt)
                        /* Allocate new empty mbuf, pad it. Compact later. */
                        struct mbuf *n;
                        MGET(n, M_DONTWAIT, MT_DATA);
-                       if (n == NULL)
+                       if (n == NULL) {
+                               printf("%s: MGET failed: ENOBUFS\n", __func__);
                                return ENOBUFS;
+                       }
                        n->m_len = 0;
                        last->m_next = n;
                        last = n;
@@ -3876,8 +3939,11 @@ bge_compact_dma_runt(struct mbuf *pkt)
                                int newprevlen = prev->m_len - shortfall;
 
                                MGET(n, M_NOWAIT, MT_DATA);
-                               if (n == NULL)
-                                  return ENOBUFS;
+                               if (n == NULL) {
+                                       printf("%s: MGET failed: ENOBUFS\n",
+                                           __func__);
+                                       return ENOBUFS;
+                               }
                                KASSERT(m->m_len + shortfall < MLEN
                                        /*,
                                          ("runt %d +prev %d too big\n", 
m->m_len, shortfall)*/);
@@ -3950,8 +4016,11 @@ bge_encap(struct bge_softc *sc, struct m
            m_head->m_pkthdr.len >= ETHER_MIN_NOPAD)
                goto check_dma_bug;
 
-       if (bge_cksum_pad(m_head) != 0)
-           return ENOBUFS;
+       if (bge_cksum_pad(m_head) != 0) {
+               aprint_error_dev(sc->bge_dev,
+                   "%s: bge_cksum_pad failed: ENOBUFS\n", __func__);
+               return ENOBUFS;
+       }
 
 check_dma_bug:
        if (!(BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX))
@@ -3962,13 +4031,19 @@ check_dma_bug:
         * less than eight bytes.  If we encounter a teeny mbuf
         * at the end of a chain, we can pad.  Otherwise, copy.
         */
-       if (bge_compact_dma_runt(m_head) != 0)
+       if (bge_compact_dma_runt(m_head) != 0) {
+               aprint_error_dev(sc->bge_dev,
+                   "%s: bge_compact_dma_runt failed: ENOBUFS\n", __func__);
                return ENOBUFS;
+       }
 
 doit:
        dma = SLIST_FIRST(&sc->txdma_list);
-       if (dma == NULL)
+       if (dma == NULL) {
+               aprint_error_dev(sc->bge_dev,
+                   "%s: txdma_list empty: ENOBUFS\n", __func__);
                return ENOBUFS;
+       }
        dmamap = dma->dmamap;
 
        /*
@@ -4005,6 +4080,9 @@ doit:
                        /*
                         * Don't support this protocol or encapsulation.
                         */
+                       aprint_error_dev(sc->bge_dev,
+                           "%s: no support for ethertype %d\n",
+                           __func__, htons(eh->ether_type));
                        return ENOBUFS;
                }
 
@@ -4051,6 +4129,7 @@ doit:
                         */
                        (void) ip; (void)th; (void) ip_tcp_hlen;
 
+                       aprint_error_dev(sc->bge_dev, "%s: ENOBUFS\n", 
__func__);
                        return ENOBUFS;
 #endif
                } else {
@@ -4114,13 +4193,15 @@ doit:
         */
        error = bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_head,
            BUS_DMA_NOWAIT);
-       if (error)
+       if (error) {
+               aprint_error_dev(sc->bge_dev,
+                   "%s: bus_dmamap_load_mbuf failed %i: ENOBUFS\n",
+                   __func__, error);
                return ENOBUFS;
-       /*
-        * Sanity check: avoid coming within 16 descriptors
-        * of the end of the ring.
-        */
-       if (dmamap->dm_nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) {
+       }
+
+       /* Check if we have enough free send BDs. */
+       if (sc->bge_txcnt + dmamap->dm_nsegs >= BGE_TX_RING_CNT) {
                BGE_TSO_PRINTF(("%s: "
                    " dmamap_load_mbuf too close to ring wrap\n",
                    device_xname(sc->bge_dev)));
@@ -4199,6 +4280,7 @@ doit:
 fail_unload:
        bus_dmamap_unload(sc->bge_dmatag, dmamap);
 
+       aprint_error_dev(sc->bge_dev, "%s: ENOBUFS\n", __func__);
        return ENOBUFS;
 }
 
@@ -4218,10 +4300,17 @@ bge_start(struct ifnet *ifp)
 
        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
                return;
+       if (!BGE_STS_BIT(sc, BGE_STS_LINK))
+               return;
 
        prodidx = sc->bge_tx_prodidx;
 
-       while (sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
+       for (pkts = 0; !IFQ_IS_EMPTY(&ifp->if_snd);) {
+               if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) {
+                       ifp->if_flags |= IFF_OACTIVE;
+                       break;
+               }
+
                IFQ_POLL(&ifp->if_snd, m_head);
                if (m_head == NULL)
                        break;


Home | Main Index | Thread Index | Old Index