Subject: kern/15083: changing the media or duplex mode on a tl interface causes a panic
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dive@endersgame.net>
List: netbsd-bugs
Date: 12/29/2001 01:52:09
>Number:         15083
>Category:       kern
>Synopsis:       changing the media/duplex on a tl interface without downing it causes a panic
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Dec 28 17:53:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD 1.5ZA
>Organization:
EGnet
>Environment:
tl0 at pci2 dev 0 function 0
tl0: Compaq Dual Port Netelligent 10/100 TX
tl0: Ethernet address 00:08:c7:a4:a9:40
tl0: interrupting at irq 12
nsphy0 at tl0 phy 1: DP83840 10/100 media interface, rev. 1
nsphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
tlphy0 at tl0 phy 31: ThunderLAN 10BASE-T media interface, rev. 5
tlphy0: 10base5
tl1 at pci2 dev 1 function 0
tl1: Compaq Dual Port Netelligent 10/100 TX
tl1: Ethernet address 00:08:c7:a4:a9:c0
tl1: interrupting at irq 10
nsphy1 at tl1 phy 1: DP83840 10/100 media interface, rev. 1
nsphy1: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
tlphy1 at tl1 phy 31: ThunderLAN 10BASE-T media interface, rev. 5
tlphy1: 10base5
System: NetBSD eros.endersgame.net 1.5ZA NetBSD 1.5ZA (EROS) #244: Fri Dec 28 20:24:19 EST 2001 dive@eros.endersgame.net:/disk2/a/cvs/netbsd-current/src/sys/arch/i386/compile/EROS i386
Architecture: i386
Machine: i386
>Description:
	If you have a tl interface up, and attempt to change the media from
	10baseT to 100baseTX (or vice versa), or change to full-duplex from half
	(or vice versa), it causes a kernel panic.
>How-To-Repeat:
	ifconfig tl0 <ip> netmask <netmask> media 10baseT
	ifconfig tl0 up
	ifconfig tl0 media 100baseTX mediaopt full-duplex
	<panic happens here>
>Fix:
--- if_tl.c.orig	Fri Dec 28 20:41:46 2001
+++ if_tl.c	Fri Dec 28 09:33:49 2001
@@ -860,9 +860,9 @@
 	tl_mii_sendbits(sc, reg, 5);
 	tl_mii_sendbits(sc, MII_COMMAND_ACK, 2);
 	tl_mii_sendbits(sc, val, 16);
-
 	netsio_clr(sc, TL_NETSIO_MCLK);
 	netsio_set(sc, TL_NETSIO_MCLK);
+	tl_mii_sync(sc);
 }
 
 void
@@ -1196,6 +1196,10 @@
 	struct tl_softc *sc = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *)data;
 	int s, error;
+	if (ifp == NULL) {
+		printf("tf_ioctl: ifp is a null pointer!\n");
+		return(0);
+	}
 	
 	s = splnet();
 	switch(cmd) {
@@ -1406,9 +1410,14 @@
 tl_mediachange(ifp)
 	struct ifnet *ifp;
 {
-
-	if (ifp->if_flags & IFF_UP)
-		tl_init(ifp->if_softc);
+	tl_softc_t *sc;
+	if (ifp == NULL) {
+		printf("tl_mediachange: ifp is a null pointer!\n");
+		return(0);
+	}
+	sc = ifp->if_softc;
+	mii_pollstat(&sc->tl_mii);
+	mii_mediachg(&sc->tl_mii);
 	return (0);
 }
 
>Release-Note:
>Audit-Trail:
>Unformatted:
 		kernel/userland 12/28/2001