Skip site navigation (1)Skip section navigation (2)
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>