Date: Thu, 21 Nov 2002 21:18:51 -0500 From: Don Bowman <don@sandvine.com> To: 'Sam Leffler' <sam@errno.com>, Don Bowman <don@sandvine.com>, "'freebsd-stable@freebsd.org'" <freebsd-stable@FreeBSD.ORG>, "'freebsd-net@freebsd.org'" <freebsd-net@FreeBSD.ORG> Cc: "'mp@FreeBSD.org'" <mp@FreeBSD.ORG>, jdp@polstra.com, m.barthelow@F5.com Subject: RE: bge bug w/ out of bounds return receiver, staying in rxeof al l the time, patch Message-ID: <FE045D4D9F7AED4CBFF1B3B813C8533701022FFE@mail.sandvine.com>
next in thread | raw e-mail | index | archive | help
> From: Sam Leffler [mailto:sam@errno.com]
> > I would recommend a committer look this over and
> > commit it. If you wish, I can make the patch *just*
> > be the change (changing the 16-bit to 32-bit writes,
> > without the VPD stuff), but the other changes seemed
> > generally useful.
>
> Please whittle the patch down to just the bug fix; 5.0 is in
> code freeze.
>
> Sam
>
Sigh, I was afraid someone would say that. Will do.
The patch is against RELENG_4, but is fairly trivial. It is below,
just the bug fix is there (changing the writing to the
receiver control block to be 32-bits all the time).
Patch follows:
Index: if_bge.c
===================================================================
RCS file: /cvs/src/sys/dev/bge/if_bge.c,v
retrieving revision 1.3.2.18
diff -U3 -r1.3.2.18 if_bge.c
--- if_bge.c 2 Nov 2002 18:22:23 -0000 1.3.2.18
+++ if_bge.c 22 Nov 2002 02:01:48 -0000
@@ -913,7 +913,7 @@
{
int i;
struct bge_rcb *rcb;
- struct bge_rcb_opaque *rcbo;
+ bge_max_len_flags len_flags;
for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
@@ -923,9 +923,9 @@
sc->bge_jumbo = i - 1;
rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
- rcbo = (struct bge_rcb_opaque *)rcb;
- rcb->bge_flags = 0;
- CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcbo->bge_reg2);
+ len_flags.bge_len_flags = rcb->bge_len_flags.bge_len_flags;
+ len_flags.s.bge_flags = 0;
+ CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS,
len_flags.bge_len_flags);
CSR_WRITE_4(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo);
@@ -1133,6 +1133,7 @@
struct bge_rcb *rcb;
struct bge_rcb_opaque *rcbo;
int i;
+ bge_max_len_flags len_flags;
/*
* Initialize the memory window pointer register so that
@@ -1202,12 +1203,13 @@
rcb = &sc->bge_rdata->bge_info.bge_std_rx_rcb;
BGE_HOSTADDR(rcb->bge_hostaddr) =
vtophys(&sc->bge_rdata->bge_rx_std_ring);
- rcb->bge_max_len = BGE_MAX_FRAMELEN;
+ len_flags.s.bge_max_len = BGE_MAX_FRAMELEN;
+ len_flags.s.bge_flags = 0;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
if (sc->bge_extram)
rcb->bge_nicaddr = BGE_EXT_STD_RX_RINGS;
else
rcb->bge_nicaddr = BGE_STD_RX_RINGS;
- rcb->bge_flags = 0;
rcbo = (struct bge_rcb_opaque *)rcb;
CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcbo->bge_reg0);
CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcbo->bge_reg1);
@@ -1224,12 +1226,13 @@
rcb = &sc->bge_rdata->bge_info.bge_jumbo_rx_rcb;
BGE_HOSTADDR(rcb->bge_hostaddr) =
vtophys(&sc->bge_rdata->bge_rx_jumbo_ring);
- rcb->bge_max_len = BGE_MAX_FRAMELEN;
+ len_flags.s.bge_max_len = BGE_MAX_FRAMELEN;
+ len_flags.s.bge_flags = BGE_RCB_FLAG_RING_DISABLED;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
if (sc->bge_extram)
rcb->bge_nicaddr = BGE_EXT_JUMBO_RX_RINGS;
else
rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
- rcb->bge_flags = BGE_RCB_FLAG_RING_DISABLED;
rcbo = (struct bge_rcb_opaque *)rcb;
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI, rcbo->bge_reg0);
@@ -1239,7 +1242,9 @@
/* Set up dummy disabled mini ring RCB */
rcb = &sc->bge_rdata->bge_info.bge_mini_rx_rcb;
- rcb->bge_flags = BGE_RCB_FLAG_RING_DISABLED;
+ len_flags.s.bge_max_len = 0;
+ len_flags.s.bge_flags = BGE_RCB_FLAG_RING_DISABLED;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
rcbo = (struct bge_rcb_opaque *)rcb;
CSR_WRITE_4(sc, BGE_RX_MINI_RCB_MAXLEN_FLAGS, rcbo->bge_reg2);
@@ -1259,8 +1264,9 @@
rcb = (struct bge_rcb *)(sc->bge_vhandle + BGE_MEMWIN_START +
BGE_SEND_RING_RCB);
for (i = 0; i < BGE_TX_RINGS_EXTSSRAM_MAX; i++) {
- rcb->bge_flags = BGE_RCB_FLAG_RING_DISABLED;
- rcb->bge_max_len = 0;
+ len_flags.s.bge_max_len = 0;
+ len_flags.s.bge_flags = BGE_RCB_FLAG_RING_DISABLED;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
rcb->bge_nicaddr = 0;
rcb++;
}
@@ -1272,17 +1278,20 @@
BGE_HOSTADDR(rcb->bge_hostaddr) =
vtophys(&sc->bge_rdata->bge_tx_ring);
rcb->bge_nicaddr = BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT);
- rcb->bge_max_len = BGE_TX_RING_CNT;
- rcb->bge_flags = 0;
+ len_flags.s.bge_max_len = BGE_TX_RING_CNT;
+ len_flags.s.bge_flags = 0;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
/* Disable all unused RX return rings */
rcb = (struct bge_rcb *)(sc->bge_vhandle + BGE_MEMWIN_START +
BGE_RX_RETURN_RING_RCB);
- for (i = 0; i < BGE_RX_RINGS_MAX; i++) {
+ rcb++;
+ for (i = 1; i < BGE_RX_RINGS_MAX; i++) {
rcb->bge_hostaddr.bge_addr_hi = 0;
rcb->bge_hostaddr.bge_addr_lo = 0;
- rcb->bge_flags = BGE_RCB_FLAG_RING_DISABLED;
- rcb->bge_max_len = BGE_RETURN_RING_CNT;
+ len_flags.s.bge_max_len = BGE_RETURN_RING_CNT;
+ len_flags.s.bge_flags = BGE_RCB_FLAG_RING_DISABLED;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
rcb->bge_nicaddr = 0;
CSR_WRITE_4(sc, BGE_MBX_RX_CONS0_LO +
(i * (sizeof(u_int64_t))), 0);
@@ -1306,8 +1315,9 @@
BGE_HOSTADDR(rcb->bge_hostaddr) =
vtophys(&sc->bge_rdata->bge_rx_return_ring);
rcb->bge_nicaddr = 0x00000000;
- rcb->bge_max_len = BGE_RETURN_RING_CNT;
- rcb->bge_flags = 0;
+ len_flags.s.bge_max_len = BGE_RETURN_RING_CNT;
+ len_flags.s.bge_flags = 0;
+ rcb->bge_len_flags.bge_len_flags = len_flags.bge_len_flags;
/* Set random backoff seed for TX */
CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
@@ -1363,13 +1373,11 @@
CSR_WRITE_4(sc, BGE_HCC_STATS_TICKS, sc->bge_stat_ticks);
/* Set up address of statistics block */
- CSR_WRITE_4(sc, BGE_HCC_STATS_BASEADDR, BGE_STATS_BLOCK);
CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_HI, 0);
CSR_WRITE_4(sc, BGE_HCC_STATS_ADDR_LO,
vtophys(&sc->bge_rdata->bge_info.bge_stats));
/* Set up address of status block */
- CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_BASEADDR, BGE_STATUS_BLOCK);
CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_HI, 0);
CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_LO,
vtophys(&sc->bge_rdata->bge_status_block));
@@ -2082,7 +2090,7 @@
#ifdef notdef
/* Avoid this for now -- checking this register is expensive. */
/* Make sure this is really our interrupt. */
- if (!(CSR_READ_4(sc, BGE_MISC_LOCAL_CTL) & BGE_MLC_INTR_STATE))
+ if ((CSR_READ_4(sc, BGE_MISC_LOCAL_CTL) & BGE_MLC_INTR_STATE))
return;
#endif
/* Ack interrupt and stop others from occuring. */
Index: if_bgereg.h
===================================================================
RCS file: /cvs/src/sys/dev/bge/if_bgereg.h,v
retrieving revision 1.1.2.7
diff -U3 -r1.1.2.7 if_bgereg.h
--- if_bgereg.h 2 Nov 2002 18:17:55 -0000 1.1.2.7
+++ if_bgereg.h 22 Nov 2002 01:58:45 -0000
@@ -1678,11 +1678,23 @@
} bge_hostaddr;
#define BGE_HOSTADDR(x) x.bge_addr_lo
+typedef union {
+ struct {
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int16_t bge_max_len;
+ u_int16_t bge_flags;
+#else
+ u_int16_t bge_flags;
+ u_int16_t bge_max_len;
+#endif
+ } s;
+ u_int32_t bge_len_flags;
+} bge_max_len_flags;
+
/* Ring control block structure */
struct bge_rcb {
bge_hostaddr bge_hostaddr;
- u_int16_t bge_flags;
- u_int16_t bge_max_len;
+ bge_max_len_flags bge_len_flags;
u_int32_t bge_nicaddr;
};
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FE045D4D9F7AED4CBFF1B3B813C8533701022FFE>
