<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Apply by doing:
	cd /usr/src
	patch -p0 &lt; 036_qe.patch
And then re-config(8) and rebuild your kernel.

Index: sys/arch/sparc/conf/files.sparc
===================================================================
RCS file: /cvs/src/sys/arch/sparc/conf/files.sparc,v
retrieving revision 1.35
retrieving revision 1.38
diff -u -r1.35 -r1.38
--- sys/arch/sparc/conf/files.sparc	1999/11/08 15:36:10	1.35
+++ sys/arch/sparc/conf/files.sparc	2000/11/16 15:47:56	1.38
@@ -112,7 +112,7 @@
 attach	be at qec
 file	arch/sparc/dev/be.c		be
 
-device	qe: ifnet, ether
+device	qe: ifnet, ether, ifmedia
 attach	qe at qec
 file	arch/sparc/dev/qe.c		qe
 
Index: sys/arch/sparc/dev/qe.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc/dev/qe.c,v
retrieving revision 1.8
retrieving revision 1.13
diff -u -r1.8 -r1.13
--- sys/arch/sparc/dev/qe.c	1999/12/08 22:46:10	1.8
+++ sys/arch/sparc/dev/qe.c	2000/11/17 17:38:32	1.13
@@ -1,7 +1,7 @@
-/*	$OpenBSD: qe.c,v 1.8 1999/12/08 22:46:10 jason Exp $	*/
+/*	$OpenBSD: qe.c,v 1.13 2000/11/17 17:38:32 jason Exp $	*/
 
 /*
- * Copyright (c) 1998 Jason L. Wright.
+ * Copyright (c) 1998, 2000 Jason L. Wright.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,7 @@
 #include &lt;net/if.h&gt;
 #include &lt;net/if_dl.h&gt;
 #include &lt;net/if_types.h&gt;
+#include &lt;net/if_media.h&gt;
 #include &lt;net/netisr.h&gt;
 
 #ifdef INET
@@ -96,6 +97,8 @@
 void		qe_read __P((struct qesoftc *, int, int));
 struct mbuf *	qe_get __P((struct qesoftc *, int, int));
 void		qe_mcreset __P((struct qesoftc *));
+void		qe_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
+int		qe_ifmedia_upd __P((struct ifnet *));
 
 struct cfdriver qe_cd = {
 	NULL, "qe", DV_IFNET
@@ -163,6 +166,12 @@
 	ifp-&gt;if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
 	    IFF_MULTICAST;
 
+	ifmedia_init(&amp;sc-&gt;sc_ifmedia, IFM_IMASK,
+	    qe_ifmedia_upd, qe_ifmedia_sts);
+	ifmedia_add(&amp;sc-&gt;sc_ifmedia,
+	    IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0), 0, NULL);
+	ifmedia_set(&amp;sc-&gt;sc_ifmedia, IFM_ETHER | IFM_10_T);
+
 	/* Attach the interface. */
 	if_attach(ifp);
 	ether_ifattach(ifp);
@@ -248,17 +257,21 @@
 {	
 	struct qe_cregs *cr = sc-&gt;sc_cr;
 	struct qe_mregs *mr = sc-&gt;sc_mr;
-	int tries;
+	int n;
 
-	tries = 200;
 	mr-&gt;biucc = QE_MR_BIUCC_SWRST;
-	while ((mr-&gt;biucc &amp; QE_MR_BIUCC_SWRST) &amp;&amp; --tries)
+	for (n = 200; n &gt; 0; n--) {
+		if ((mr-&gt;biucc &amp; QE_MR_BIUCC_SWRST) == 0)
+			break;
 		DELAY(20);
+	}
 
-	tries = 200;
 	cr-&gt;ctrl = QE_CR_CTRL_RESET;
-	while ((cr-&gt;ctrl &amp; QE_CR_CTRL_RESET) &amp;&amp; --tries)
+	for (n = 200; n &gt; 0; n--) {
+		if ((cr-&gt;ctrl &amp; QE_CR_CTRL_RESET) == 0)
+			break;
 		DELAY(20);
+	}
 }
 
 /*
@@ -268,12 +281,8 @@
 qereset(sc)
 	struct qesoftc *sc;
 {
-	int s;
-
-	s = splnet();
 	qestop(sc);
 	qeinit(sc);
-	splx(s);
 }
 
 void
@@ -281,11 +290,14 @@
 	struct ifnet *ifp;
 {
 	struct qesoftc *sc = ifp-&gt;if_softc;
+	int s;
 
 	log(LOG_ERR, "%s: device timeout\n", sc-&gt;sc_dev.dv_xname);
 	++sc-&gt;sc_arpcom.ac_if.if_oerrors;
 
+	s = splnet();
 	qereset(sc);
+	splx(s);
 }
 
 /*
@@ -422,7 +434,6 @@
 		rst = 1;
 	}
 
-
 	if (why &amp; QE_CR_STAT_LCOLL) {
 		printf("%s: late tx transmission\n", sc-&gt;sc_dev.dv_xname);
 		ifp-&gt;if_oerrors++;
@@ -637,12 +648,6 @@
 			qestop(sc);
 			qeinit(sc);
 		}
-#ifdef IEDEBUG   
-		if (ifp-&gt;if_flags &amp; IFF_DEBUG)
-			sc-&gt;sc_debug = IED_ALL;
-		else
-			sc-&gt;sc_debug = 0;
-#endif
 		break;
 
 	case SIOCADDMULTI:
@@ -656,10 +661,15 @@
 			 * Multicast list has changed; set the hardware filter
 			 * accordingly.
 			 */
-			qe_mcreset(sc);
+			if (ifp-&gt;if_flags &amp; IFF_UP)
+				qeinit(sc);
 			error = 0;
 		}
 		break;
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &amp;sc-&gt;sc_ifmedia, cmd);
+		break;
 	default:
 		if ((error = ether_ioctl(ifp, &amp;sc-&gt;sc_arpcom, cmd, data)) &gt; 0) {
 			splx(s);
@@ -683,29 +693,30 @@
 	int s = splimp();
 	int i;
 
+	qestop(sc);
+
 	/*
 	 * Allocate descriptor ring and buffers, if not already done
 	 */
 	if (sc-&gt;sc_desc == NULL)
 		sc-&gt;sc_desc_dva = (struct qe_desc *) dvma_malloc(
 			sizeof(struct qe_desc), &amp;sc-&gt;sc_desc, M_NOWAIT);
+	bzero(sc-&gt;sc_desc, sizeof(struct qe_desc));
+
 	if (sc-&gt;sc_bufs == NULL)
 		sc-&gt;sc_bufs_dva = (struct qe_bufs *) dvma_malloc(
 			sizeof(struct qe_bufs), &amp;sc-&gt;sc_bufs, M_NOWAIT);
-	
-	for (i = 0; i &lt; QE_TX_RING_MAXSIZE; i++) {
+	bzero(sc-&gt;sc_bufs, sizeof(struct qe_bufs));
+
+	for (i = 0; i &lt; QE_TX_RING_MAXSIZE; i++)
 		sc-&gt;sc_desc-&gt;qe_txd[i].tx_addr =
 			(u_int32_t) &amp;sc-&gt;sc_bufs_dva-&gt;tx_buf[i % QE_TX_RING_SIZE][0];
-		sc-&gt;sc_desc-&gt;qe_txd[i].tx_flags = 0;
-	}
 	for (i = 0; i &lt; QE_RX_RING_MAXSIZE; i++) {
 		sc-&gt;sc_desc-&gt;qe_rxd[i].rx_addr =
 			(u_int32_t) &amp;sc-&gt;sc_bufs_dva-&gt;rx_buf[i % QE_RX_RING_SIZE][0];
 		if ((i / QE_RX_RING_SIZE) == 0)
 			sc-&gt;sc_desc-&gt;qe_rxd[i].rx_flags =
 				QE_RXD_OWN | QE_RXD_LENGTH;
-		else
-			sc-&gt;sc_desc-&gt;qe_rxd[i].rx_flags = 0;
 	}
 
 	cr-&gt;rxds = (u_int32_t) &amp;sc-&gt;sc_desc_dva-&gt;qe_rxd[0];
@@ -714,49 +725,55 @@
 	sc-&gt;sc_first_td = sc-&gt;sc_last_td = sc-&gt;sc_no_td = 0;
 	sc-&gt;sc_last_rd = 0;
 
-	qestop(sc);
-
 	cr-&gt;rimask = 0;
 	cr-&gt;timask = 0;
 	cr-&gt;qmask = 0;
-	cr-&gt;mmask = QE_CR_MMASK_RXCOLL;
-	cr-&gt;rxwbufptr = cr-&gt;rxrbufptr = sc-&gt;sc_channel * qec-&gt;sc_msize;
-	cr-&gt;txwbufptr = cr-&gt;txrbufptr = cr-&gt;rxrbufptr + qec-&gt;sc_rsize;
+	cr-&gt;mmask = QE_CR_MMASK_RXCOLL | QE_CR_MMASK_CLOSS;
 	cr-&gt;ccnt = 0;
 	cr-&gt;pipg = 0;
+	cr-&gt;rxwbufptr = cr-&gt;rxrbufptr = sc-&gt;sc_channel * qec-&gt;sc_msize;
+	cr-&gt;txwbufptr = cr-&gt;txrbufptr = cr-&gt;rxrbufptr + qec-&gt;sc_rsize;
 
-	mr-&gt;phycc = QE_MR_PHYCC_ASEL;
-	mr-&gt;xmtfc = QE_MR_XMTFC_APADXMT;
-	mr-&gt;rcvfc = 0;
-	mr-&gt;imr = QE_MR_IMR_CERRM | QE_MR_IMR_RCVINTM;
+	/*
+	 * When switching from mace&lt;-&gt;qec always guarantee an sbus
+	 * turnaround (if last op was read, perform a dummy write, and
+	 * vice versa).
+	 */
+	i = cr-&gt;qmask;		/* dummy */
+
 	mr-&gt;biucc = QE_MR_BIUCC_BSWAP | QE_MR_BIUCC_64TS;
 	mr-&gt;fifofc = QE_MR_FIFOCC_TXF16 | QE_MR_FIFOCC_RXF32 |
 	    QE_MR_FIFOCC_RFWU | QE_MR_FIFOCC_TFWU;
+	mr-&gt;xmtfc = QE_MR_XMTFC_APADXMT;
+	mr-&gt;rcvfc = 0;
+	mr-&gt;imr = QE_MR_IMR_CERRM | QE_MR_IMR_RCVINTM;
+	mr-&gt;phycc = QE_MR_PHYCC_ASEL;
 	mr-&gt;plscc = QE_MR_PLSCC_TP;
 
+	qe_ifmedia_upd(ifp);
+
 	mr-&gt;iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_PHYADDR;
+	for (i = 100; i &gt; 0; i--) {
+		if ((mr-&gt;iac &amp; QE_MR_IAC_ADDRCHG) == 0)
+			break;
+		DELAY(2);
+	}
 	mr-&gt;padr = sc-&gt;sc_arpcom.ac_enaddr[0];
 	mr-&gt;padr = sc-&gt;sc_arpcom.ac_enaddr[1];
 	mr-&gt;padr = sc-&gt;sc_arpcom.ac_enaddr[2];
 	mr-&gt;padr = sc-&gt;sc_arpcom.ac_enaddr[3];
 	mr-&gt;padr = sc-&gt;sc_arpcom.ac_enaddr[4];
 	mr-&gt;padr = sc-&gt;sc_arpcom.ac_enaddr[5];
-
-	mr-&gt;iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
-	for (i = 0; i &lt; 8; i++)
-		mr-&gt;ladrf = 0;
+	qe_mcreset(sc);
 	mr-&gt;iac = 0;
 
-	delay(50000);
-	if ((mr-&gt;phycc &amp; QE_MR_PHYCC_LNKFL) == QE_MR_PHYCC_LNKFL)
-		printf("%s: no carrier\n", sc-&gt;sc_dev.dv_xname);
-
 	i = mr-&gt;mpc;	/* cleared on read */
 
-	qe_mcreset(sc);
-
 	ifp-&gt;if_flags |= IFF_RUNNING;
 	ifp-&gt;if_flags &amp;= ~IFF_OACTIVE;
+
+	mr-&gt;maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV |
+	    ((ifp-&gt;if_flags &amp; IFF_PROMISC) ? QE_MR_MACCC_PROM : 0);
 	splx(s);
 }
 
@@ -911,19 +928,17 @@
 	u_int16_t hash[4];
 	u_int8_t octet, *ladrp = (u_int8_t *)&amp;hash[0];
 	int i, j;
-
-	if (ifp-&gt;if_flags &amp; IFF_PROMISC) {
-		mr-&gt;maccc = QE_MR_MACCC_PROM | QE_MR_MACCC_ENXMT |
-		    QE_MR_MACCC_ENRCV;
-		return;
-	}
 
+allmulti:
 	if (ifp-&gt;if_flags &amp; IFF_ALLMULTI) {
 		mr-&gt;iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
+		for (i = 100; i &gt; 0; i--) {
+			if ((mr-&gt;iac &amp; QE_MR_IAC_ADDRCHG) == 0)
+				break;
+			DELAY(2);
+		}
 		for (i = 0; i &lt; 8; i++)
 			mr-&gt;ladrf = 0xff;
-		mr-&gt;iac = 0;
-		mr-&gt;maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV;
 		return;
 	}
 
@@ -943,12 +958,8 @@
 			 * which the range is big enough to require
 			 * all bits set.)
 			 */
-			mr-&gt;iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
-			for (i = 0; i &lt; 8; i++)
-				mr-&gt;ladrf = 0xff;
-			mr-&gt;iac = 0;
 			ifp-&gt;if_flags |= IFF_ALLMULTI;
-			break;
+			goto allmulti;
 		}
 
 		crc = 0xffffffff;
@@ -973,9 +984,46 @@
 	}
 
 	mr-&gt;iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
+	for (i = 100; i &gt; 0; i--) {
+		if ((mr-&gt;iac &amp; QE_MR_IAC_ADDRCHG) == 0)
+			break;
+		DELAY(2);
+	}
 	for (i = 0; i &lt; 8; i++)
 		mr-&gt;ladrf = ladrp[i];
-	mr-&gt;iac = 0;
+}
+
+void
+qe_ifmedia_sts(ifp, ifmr)
+	struct ifnet *ifp;
+	struct ifmediareq *ifmr;
+{
+	struct qesoftc *sc = (struct qesoftc *)ifp-&gt;if_softc;
+	u_int8_t phycc;
+
+	ifmr-&gt;ifm_active = IFM_ETHER | IFM_10_T;
+	phycc = sc-&gt;sc_mr-&gt;phycc;
+	if ((phycc &amp; QE_MR_PHYCC_DLNKTST) == 0) {
+		ifmr-&gt;ifm_status |= IFM_AVALID;
+		if (phycc &amp; QE_MR_PHYCC_LNKFL)
+			ifmr-&gt;ifm_status &amp;= ~IFM_ACTIVE;
+		else
+			ifmr-&gt;ifm_status |= IFM_ACTIVE;
+	}
+}
+
+int
+qe_ifmedia_upd(ifp)
+	struct ifnet *ifp;
+{
+	struct qesoftc *sc = (struct qesoftc *)ifp-&gt;if_softc;
+	int media = sc-&gt;sc_ifmedia.ifm_media;
+
+	if (IFM_TYPE(media) != IFM_ETHER)
+		return (EINVAL);
+
+	if (IFM_SUBTYPE(media) != IFM_10_T)
+		return (EINVAL);
 
-	mr-&gt;maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV;
+	return (0);
 }
Index: sys/arch/sparc/dev/qereg.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc/dev/qereg.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- sys/arch/sparc/dev/qereg.h	1999/03/12 18:56:18	1.4
+++ sys/arch/sparc/dev/qereg.h	2000/11/16 15:47:57	1.5
@@ -1,7 +1,7 @@
-/*	$OpenBSD: qereg.h,v 1.4 1999/03/12 18:56:18 jason Exp $	*/
+/*	$OpenBSD: qereg.h,v 1.5 2000/11/16 15:47:57 jason Exp $	*/
 
 /*
- * Copyright (c) 1998 Jason L. Wright.
+ * Copyright (c) 1998, 2000 Jason L. Wright.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -255,6 +255,7 @@
 
 /* qe_mregs.plscc: pls config control. */
 #define	QE_MR_PLSCC_XMTSEL	0x08		/* tx mode select */
+#define	QE_MR_PLSCC_PORTMASK	0x06		/* media mask */
 #define	QE_MR_PLSCC_GPSI	0x06		/* use gpsi connector */
 #define	QE_MR_PLSCC_DAI		0x04		/* use dai connector */
 #define	QE_MR_PLSCC_TP		0x02		/* use twistedpair connector */
Index: sys/arch/sparc/dev/qevar.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc/dev/qevar.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sys/arch/sparc/dev/qevar.h	1999/02/24 06:57:45	1.3
+++ sys/arch/sparc/dev/qevar.h	2000/11/16 15:47:57	1.4
@@ -1,7 +1,7 @@
-/*	$OpenBSD: qevar.h,v 1.3 1999/02/24 06:57:45 jason Exp $	*/
+/*	$OpenBSD: qevar.h,v 1.4 2000/11/16 15:47:57 jason Exp $	*/
 
 /*
- * Copyright (c) 1998 Jason L. Wright.
+ * Copyright (c) 1998, 2000 Jason L. Wright.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,4 +48,5 @@
 
 	int	sc_no_td, sc_first_td, sc_last_td;
 	int	sc_last_rd;
+	struct	ifmedia sc_ifmedia;
 };
</pre></body></html>