Subject: 3c900b-tpo fix
From: Jason Wright <[email-masked]>
To: [email-masked]
Date: Sun, 2 Jan 2000 20:05:41 -0500

Here's the patch against 2.6-release.

The 3C900B-TPO fails to select the correct media type (it never sees or
sends packets).

Apply by doing:
        cd /usr/src
        patch -p0 < 012_3c900b.patch

And then rebuild your kernel.

--- sys/dev/pci/if_xl.c.orig	Sun Jan  2 15:28:49 2000
+++ sys/dev/pci/if_xl.c	Sun Jan  2 15:28:49 2000
@@ -179,7 +179,7 @@
 u_int8_t xl_calchash	__P((caddr_t));
 void xl_setmulti	__P((struct xl_softc *));
 void xl_setmulti_hash	__P((struct xl_softc *));
-void xl_reset		__P((struct xl_softc *));
+void xl_reset		__P((struct xl_softc *, int));
 int xl_list_rx_init	__P((struct xl_softc *));
 int xl_list_tx_init	__P((struct xl_softc *));
 void xl_wait		__P((struct xl_softc *));
@@ -822,13 +822,16 @@
 	XL_SEL_WIN(7);
 }
 
-void xl_reset(sc)
+void xl_reset(sc, hard)
 	struct xl_softc		*sc;
 {
 	register int		i;
 
 	XL_SEL_WIN(0);
-	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET);
+	if (hard)
+		CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET);
+	else
+		CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET | 0x0010);
 	xl_wait(sc);
 
 	for (i = 0; i < XL_TIMEOUT; i++) {
@@ -1364,7 +1367,7 @@
 		}
 
 		if (status & XL_STAT_ADFAIL) {
-			xl_reset(sc);
+			xl_reset(sc, 0);
 			xl_init(sc);
 		}
 
@@ -2014,7 +2017,7 @@
 	xl_txeoc(sc);
 	xl_txeof(sc);
 	xl_rxeof(sc);
-	xl_reset(sc);
+	xl_reset(sc, 0);
 	xl_init(sc);
 
 	if (ifp->if_snd.ifq_head != NULL)
@@ -2213,7 +2216,7 @@
 	}
 	printf(": %s", intrstr);
 
-	xl_reset(sc);
+	xl_reset(sc, 1);
 
 	/*
 	 * Get station address from the EEPROM.
@@ -2315,8 +2318,10 @@
 	 * a 10/100 card of some kind, we need to force the transceiver
 	 * type to something sane.
 	 */
-	if (sc->xl_xcvr == XL_XCVR_AUTO)
+	if (sc->xl_xcvr == XL_XCVR_AUTO) {
 		xl_choose_xcvr(sc, 0);
+		xl_reset(sc, 0);
+	}
 
 	if (sc->xl_media & XL_MEDIAOPT_BT) {
 		ifmedia_add(ifm, IFM_ETHER|IFM_10_T, 0, NULL);
@@ -2414,6 +2419,7 @@
 {
 	struct xl_softc	*sc = (struct xl_softc *)v;
 
+	xl_reset(sc, 1);
 	xl_stop(sc);
 }