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