Date: Thu, 13 Apr 2000 17:06:45 -0400 (EDT) From: Bill Paul <wpaul@skynet.ctr.columbia.edu> To: locke@mcs.net Cc: bugs@freebsd.org Subject: Re: kern/17965: vr (MII-bus version in 4.0 ONLY) driver lock-up problems Message-ID: <200004132106.RAA29981@skynet.ctr.columbia.edu> In-Reply-To: <200004130316.UAA17121@freefall.freebsd.org> from "locke@mcs.net" at Apr 12, 2000 08:16:12 pm
next in thread | previous in thread | raw e-mail | index | archive | help
Of all the gin joints in all the towns in all the world, locke@mcs.net
had to walk into mine and say:
> Moderate to heavy traffic load on the vr card can periodically cause
> the network to completely freeze up (all connections die, everything
> unreachable with ping, etc) for about 10-30 secs. Also, the following
> message appears in the system log:
> vr0: watchdog timeout
The only thing I can come up with is that polling the MII bus while
the chip is transmitting might be confusing it. (This driver uses
the bitbang MII access method, which requires reading lots of registers.)
I'm including a patch for if_vr.c and if_vrreg.h which should drastically
cut down on the register accesses. This *may* help, but I need you to
test it to be sure.
To apply this patch:
- Save this message to a file, e.g. /tmp/vr.patch
- cd /sys/pci
- diff < /tmp/vr.patch
- Compile a new kernel (or recompile and reload the if_vr.ko module).
-Bill
--
=============================================================================
-Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu
Work: wpaul@ctr.columbia.edu | Center for Telecommunications Research
Home: wpaul@skynet.ctr.columbia.edu | Columbia University, New York City
=============================================================================
"It is not I who am crazy; it is I who am mad!" - Ren Hoek, "Space Madness"
=============================================================================
*** if_vr.c.orig Sat Apr 8 17:26:18 2000
--- if_vr.c Thu Apr 13 20:58:36 2000
***************
*** 948,956 ****
m_adj(m_new, sizeof(u_int64_t));
c->vr_mbuf = m_new;
- c->vr_ptr->vr_status = VR_RXSTAT;
c->vr_ptr->vr_data = vtophys(mtod(m_new, caddr_t));
c->vr_ptr->vr_ctl = VR_RXCTL | VR_RXLEN;
return(0);
}
--- 948,956 ----
m_adj(m_new, sizeof(u_int64_t));
c->vr_mbuf = m_new;
c->vr_ptr->vr_data = vtophys(mtod(m_new, caddr_t));
c->vr_ptr->vr_ctl = VR_RXCTL | VR_RXLEN;
+ c->vr_ptr->vr_status = VR_RXSTAT;
return(0);
}
***************
*** 1014,1021 ****
printf("unknown rx error\n");
break;
}
! vr_newbuf(sc, cur_rx, m);
! continue;
}
/* No errors; receive the packet. */
--- 1014,1021 ----
printf("unknown rx error\n");
break;
}
! vr_init(sc);
! return;
}
/* No errors; receive the packet. */
***************
*** 1187,1192 ****
--- 1187,1221 ----
sc = xsc;
mii = device_get_softc(sc->vr_miibus);
+
+ if (sc->vr_link == 0)
+ mii_tick(mii);
+
+ if (sc->vr_link) {
+ if (CSR_READ_1(sc, VR_MIISTAT) & VR_MIISTAT_LINKFAULT) {
+ VR_CLRBIT(sc, VR_MIICMD, VR_MIICMD_AUTOPOLL);
+ VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_DIRECTPGM);
+ sc->vr_link = 0;
+ mii_tick(mii);
+ sc->vr_stat_ch = timeout(vr_tick, sc, hz);
+ splx(s);
+ return;
+ } else {
+ VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_AUTOPOLL);
+ VR_CLRBIT(sc, VR_MIICMD, VR_MIICMD_DIRECTPGM);
+ }
+ }
+
+ if (sc->vr_link == 0) {
+ mii_pollstat(mii);
+ if (mii->mii_media_status & IFM_ACTIVE &&
+ IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
+ sc->vr_link++;
+ VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_AUTOPOLL);
+ VR_CLRBIT(sc, VR_MIICMD, VR_MIICMD_DIRECTPGM);
+ }
+ }
+
mii_tick(mii);
sc->vr_stat_ch = timeout(vr_tick, sc, hz);
***************
*** 1317,1322 ****
--- 1346,1353 ----
if (m_head->m_len < VR_MIN_FRAMELEN) {
m_new->m_pkthdr.len += VR_MIN_FRAMELEN - m_new->m_len;
m_new->m_len = m_new->m_pkthdr.len;
+ bzero(mtod(m_new, char *) + m_new->m_pkthdr.len,
+ VR_MIN_FRAMELEN - m_new->m_pkthdr.len);
}
f = c->vr_ptr;
f->vr_data = vtophys(mtod(m_new, caddr_t));
***************
*** 1482,1487 ****
--- 1513,1519 ----
CSR_WRITE_2(sc, VR_IMR, VR_INTRS);
mii_mediachg(mii);
+ sc->vr_link = 0;
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
*** if_vrreg.h.orig Thu Apr 13 21:01:09 2000
--- if_vrreg.h Thu Apr 13 17:57:15 2000
***************
*** 404,409 ****
--- 404,410 ----
struct vr_type *vr_info; /* Rhine adapter info */
u_int8_t vr_unit; /* interface number */
u_int8_t vr_type;
+ u_int8_t vr_link;
struct vr_list_data *vr_ldata;
struct vr_chain_data vr_cdata;
struct callout_handle vr_stat_ch;
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200004132106.RAA29981>
