Apply by doing:
       cd /usr/src
       patch -p0 < 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 <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
+#include <net/if_media.h>
#include <net/netisr.h>

#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->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
           IFF_MULTICAST;

+       ifmedia_init(&sc->sc_ifmedia, IFM_IMASK,
+           qe_ifmedia_upd, qe_ifmedia_sts);
+       ifmedia_add(&sc->sc_ifmedia,
+           IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0), 0, NULL);
+       ifmedia_set(&sc->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->sc_cr;
       struct qe_mregs *mr = sc->sc_mr;
-       int tries;
+       int n;

-       tries = 200;
       mr->biucc = QE_MR_BIUCC_SWRST;
-       while ((mr->biucc & QE_MR_BIUCC_SWRST) && --tries)
+       for (n = 200; n > 0; n--) {
+               if ((mr->biucc & QE_MR_BIUCC_SWRST) == 0)
+                       break;
               DELAY(20);
+       }

-       tries = 200;
       cr->ctrl = QE_CR_CTRL_RESET;
-       while ((cr->ctrl & QE_CR_CTRL_RESET) && --tries)
+       for (n = 200; n > 0; n--) {
+               if ((cr->ctrl & 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->if_softc;
+       int s;

       log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
       ++sc->sc_arpcom.ac_if.if_oerrors;

+       s = splnet();
       qereset(sc);
+       splx(s);
}

/*
@@ -422,7 +434,6 @@
               rst = 1;
       }

-
       if (why & QE_CR_STAT_LCOLL) {
               printf("%s: late tx transmission\n", sc->sc_dev.dv_xname);
               ifp->if_oerrors++;
@@ -637,12 +648,6 @@
                       qestop(sc);
                       qeinit(sc);
               }
-#ifdef IEDEBUG
-               if (ifp->if_flags & IFF_DEBUG)
-                       sc->sc_debug = IED_ALL;
-               else
-                       sc->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->if_flags & IFF_UP)
+                               qeinit(sc);
                       error = 0;
               }
               break;
+       case SIOCGIFMEDIA:
+       case SIOCSIFMEDIA:
+               error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
+               break;
       default:
               if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 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->sc_desc == NULL)
               sc->sc_desc_dva = (struct qe_desc *) dvma_malloc(
                       sizeof(struct qe_desc), &sc->sc_desc, M_NOWAIT);
+       bzero(sc->sc_desc, sizeof(struct qe_desc));
+
       if (sc->sc_bufs == NULL)
               sc->sc_bufs_dva = (struct qe_bufs *) dvma_malloc(
                       sizeof(struct qe_bufs), &sc->sc_bufs, M_NOWAIT);
-
-       for (i = 0; i < QE_TX_RING_MAXSIZE; i++) {
+       bzero(sc->sc_bufs, sizeof(struct qe_bufs));
+
+       for (i = 0; i < QE_TX_RING_MAXSIZE; i++)
               sc->sc_desc->qe_txd[i].tx_addr =
                       (u_int32_t) &sc->sc_bufs_dva->tx_buf[i % QE_TX_RING_SIZE][0];
-               sc->sc_desc->qe_txd[i].tx_flags = 0;
-       }
       for (i = 0; i < QE_RX_RING_MAXSIZE; i++) {
               sc->sc_desc->qe_rxd[i].rx_addr =
                       (u_int32_t) &sc->sc_bufs_dva->rx_buf[i % QE_RX_RING_SIZE][0];
               if ((i / QE_RX_RING_SIZE) == 0)
                       sc->sc_desc->qe_rxd[i].rx_flags =
                               QE_RXD_OWN | QE_RXD_LENGTH;
-               else
-                       sc->sc_desc->qe_rxd[i].rx_flags = 0;
       }

       cr->rxds = (u_int32_t) &sc->sc_desc_dva->qe_rxd[0];
@@ -714,49 +725,55 @@
       sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
       sc->sc_last_rd = 0;

-       qestop(sc);
-
       cr->rimask = 0;
       cr->timask = 0;
       cr->qmask = 0;
-       cr->mmask = QE_CR_MMASK_RXCOLL;
-       cr->rxwbufptr = cr->rxrbufptr = sc->sc_channel * qec->sc_msize;
-       cr->txwbufptr = cr->txrbufptr = cr->rxrbufptr + qec->sc_rsize;
+       cr->mmask = QE_CR_MMASK_RXCOLL | QE_CR_MMASK_CLOSS;
       cr->ccnt = 0;
       cr->pipg = 0;
+       cr->rxwbufptr = cr->rxrbufptr = sc->sc_channel * qec->sc_msize;
+       cr->txwbufptr = cr->txrbufptr = cr->rxrbufptr + qec->sc_rsize;

-       mr->phycc = QE_MR_PHYCC_ASEL;
-       mr->xmtfc = QE_MR_XMTFC_APADXMT;
-       mr->rcvfc = 0;
-       mr->imr = QE_MR_IMR_CERRM | QE_MR_IMR_RCVINTM;
+       /*
+        * When switching from mace<->qec always guarantee an sbus
+        * turnaround (if last op was read, perform a dummy write, and
+        * vice versa).
+        */
+       i = cr->qmask;          /* dummy */
+
       mr->biucc = QE_MR_BIUCC_BSWAP | QE_MR_BIUCC_64TS;
       mr->fifofc = QE_MR_FIFOCC_TXF16 | QE_MR_FIFOCC_RXF32 |
           QE_MR_FIFOCC_RFWU | QE_MR_FIFOCC_TFWU;
+       mr->xmtfc = QE_MR_XMTFC_APADXMT;
+       mr->rcvfc = 0;
+       mr->imr = QE_MR_IMR_CERRM | QE_MR_IMR_RCVINTM;
+       mr->phycc = QE_MR_PHYCC_ASEL;
       mr->plscc = QE_MR_PLSCC_TP;

+       qe_ifmedia_upd(ifp);
+
       mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_PHYADDR;
+       for (i = 100; i > 0; i--) {
+               if ((mr->iac & QE_MR_IAC_ADDRCHG) == 0)
+                       break;
+               DELAY(2);
+       }
       mr->padr = sc->sc_arpcom.ac_enaddr[0];
       mr->padr = sc->sc_arpcom.ac_enaddr[1];
       mr->padr = sc->sc_arpcom.ac_enaddr[2];
       mr->padr = sc->sc_arpcom.ac_enaddr[3];
       mr->padr = sc->sc_arpcom.ac_enaddr[4];
       mr->padr = sc->sc_arpcom.ac_enaddr[5];
-
-       mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
-       for (i = 0; i < 8; i++)
-               mr->ladrf = 0;
+       qe_mcreset(sc);
       mr->iac = 0;

-       delay(50000);
-       if ((mr->phycc & QE_MR_PHYCC_LNKFL) == QE_MR_PHYCC_LNKFL)
-               printf("%s: no carrier\n", sc->sc_dev.dv_xname);
-
       i = mr->mpc;    /* cleared on read */

-       qe_mcreset(sc);
-
       ifp->if_flags |= IFF_RUNNING;
       ifp->if_flags &= ~IFF_OACTIVE;
+
+       mr->maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV |
+           ((ifp->if_flags & 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 *)&hash[0];
       int i, j;
-
-       if (ifp->if_flags & IFF_PROMISC) {
-               mr->maccc = QE_MR_MACCC_PROM | QE_MR_MACCC_ENXMT |
-                   QE_MR_MACCC_ENRCV;
-               return;
-       }

+allmulti:
       if (ifp->if_flags & IFF_ALLMULTI) {
               mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
+               for (i = 100; i > 0; i--) {
+                       if ((mr->iac & QE_MR_IAC_ADDRCHG) == 0)
+                               break;
+                       DELAY(2);
+               }
               for (i = 0; i < 8; i++)
                       mr->ladrf = 0xff;
-               mr->iac = 0;
-               mr->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->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
-                       for (i = 0; i < 8; i++)
-                               mr->ladrf = 0xff;
-                       mr->iac = 0;
                       ifp->if_flags |= IFF_ALLMULTI;
-                       break;
+                       goto allmulti;
               }

               crc = 0xffffffff;
@@ -973,9 +984,46 @@
       }

       mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
+       for (i = 100; i > 0; i--) {
+               if ((mr->iac & QE_MR_IAC_ADDRCHG) == 0)
+                       break;
+               DELAY(2);
+       }
       for (i = 0; i < 8; i++)
               mr->ladrf = ladrp[i];
-       mr->iac = 0;
+}
+
+void
+qe_ifmedia_sts(ifp, ifmr)
+       struct ifnet *ifp;
+       struct ifmediareq *ifmr;
+{
+       struct qesoftc *sc = (struct qesoftc *)ifp->if_softc;
+       u_int8_t phycc;
+
+       ifmr->ifm_active = IFM_ETHER | IFM_10_T;
+       phycc = sc->sc_mr->phycc;
+       if ((phycc & QE_MR_PHYCC_DLNKTST) == 0) {
+               ifmr->ifm_status |= IFM_AVALID;
+               if (phycc & QE_MR_PHYCC_LNKFL)
+                       ifmr->ifm_status &= ~IFM_ACTIVE;
+               else
+                       ifmr->ifm_status |= IFM_ACTIVE;
+       }
+}
+
+int
+qe_ifmedia_upd(ifp)
+       struct ifnet *ifp;
+{
+       struct qesoftc *sc = (struct qesoftc *)ifp->if_softc;
+       int media = sc->sc_ifmedia.ifm_media;
+
+       if (IFM_TYPE(media) != IFM_ETHER)
+               return (EINVAL);
+
+       if (IFM_SUBTYPE(media) != IFM_10_T)
+               return (EINVAL);

-       mr->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;
};