root/dev/sbus/qe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qematch
  2. qeattach
  3. qe_get
  4. qe_put
  5. qe_read
  6. qestart
  7. qestop
  8. qereset
  9. qewatchdog
  10. qeintr
  11. qe_tint
  12. qe_rint
  13. qe_eint
  14. qeioctl
  15. qeinit
  16. qe_mcreset
  17. qe_ifmedia_sts
  18. qe_ifmedia_upd

    1 /*      $OpenBSD: qe.c,v 1.20 2006/06/21 18:08:47 jason Exp $   */
    2 /*      $NetBSD: qe.c,v 1.16 2001/03/30 17:30:18 christos Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Paul Kranenburg.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Copyright (c) 1998 Jason L. Wright.
   42  * All rights reserved.
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  *
   53  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   54  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   55  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   56  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   57  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   58  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   59  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   60  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   61  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   62  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   63  */
   64 
   65 /*
   66  * Driver for the SBus qec+qe QuadEthernet board.
   67  *
   68  * This driver was written using the AMD MACE Am79C940 documentation, some
   69  * ideas gleaned from the S/Linux driver for this card, Solaris header files,
   70  * and a loan of a card from Paul Southworth of the Internet Engineering
   71  * Group (www.ieng.com).
   72  */
   73 
   74 #define QEDEBUG
   75 
   76 #include "bpfilter.h"
   77 
   78 #include <sys/param.h>
   79 #include <sys/systm.h>
   80 #include <sys/kernel.h>
   81 #include <sys/errno.h>
   82 #include <sys/ioctl.h>
   83 #include <sys/mbuf.h>
   84 #include <sys/socket.h>
   85 #include <sys/syslog.h>
   86 #include <sys/device.h>
   87 #include <sys/malloc.h>
   88 
   89 #include <net/if.h>
   90 #include <net/if_dl.h>
   91 #include <net/if_types.h>
   92 #include <net/netisr.h>
   93 #include <net/if_media.h>
   94 
   95 #ifdef INET
   96 #include <netinet/in.h>
   97 #include <netinet/in_systm.h>
   98 #include <netinet/in_var.h>
   99 #include <netinet/ip.h>
  100 #include <netinet/if_ether.h>
  101 #endif
  102 
  103 #if NBPFILTER > 0
  104 #include <net/bpf.h>
  105 #endif
  106 
  107 #include <machine/bus.h>
  108 #include <machine/intr.h>
  109 #include <machine/autoconf.h>
  110 
  111 #include <dev/sbus/sbusvar.h>
  112 #include <dev/sbus/qecreg.h>
  113 #include <dev/sbus/qecvar.h>
  114 #include <dev/sbus/qereg.h>
  115 
  116 struct qe_softc {
  117         struct  device  sc_dev;         /* base device */
  118         bus_space_tag_t sc_bustag;      /* bus & dma tags */
  119         bus_dma_tag_t   sc_dmatag;
  120         bus_dmamap_t    sc_dmamap;
  121         struct  arpcom sc_arpcom;
  122         struct  ifmedia sc_ifmedia;     /* interface media */
  123 
  124         struct  qec_softc *sc_qec;      /* QEC parent */
  125 
  126         bus_space_handle_t      sc_qr;  /* QEC registers */
  127         bus_space_handle_t      sc_mr;  /* MACE registers */
  128         bus_space_handle_t      sc_cr;  /* channel registers */
  129 
  130         int     sc_channel;             /* channel number */
  131         u_int   sc_rev;                 /* board revision */
  132 
  133         int     sc_burst;
  134 
  135         struct  qec_ring        sc_rb;  /* Packet Ring Buffer */
  136 
  137 #ifdef QEDEBUG
  138         int     sc_debug;
  139 #endif
  140 };
  141 
  142 int     qematch(struct device *, void *, void *);
  143 void    qeattach(struct device *, struct device *, void *);
  144 
  145 void    qeinit(struct qe_softc *);
  146 void    qestart(struct ifnet *);
  147 void    qestop(struct qe_softc *);
  148 void    qewatchdog(struct ifnet *);
  149 int     qeioctl(struct ifnet *, u_long, caddr_t);
  150 void    qereset(struct qe_softc *);
  151 
  152 int     qeintr(void *);
  153 int     qe_eint(struct qe_softc *, u_int32_t);
  154 int     qe_rint(struct qe_softc *);
  155 int     qe_tint(struct qe_softc *);
  156 void    qe_mcreset(struct qe_softc *);
  157 
  158 int     qe_put(struct qe_softc *, int, struct mbuf *);
  159 void    qe_read(struct qe_softc *, int, int);
  160 struct mbuf     *qe_get(struct qe_softc *, int, int);
  161 
  162 /* ifmedia callbacks */
  163 void    qe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  164 int     qe_ifmedia_upd(struct ifnet *);
  165 
  166 struct cfattach qe_ca = {
  167         sizeof(struct qe_softc), qematch, qeattach
  168 };
  169 
  170 struct cfdriver qe_cd = {
  171         NULL, "qe", DV_IFNET
  172 };
  173 
  174 int
  175 qematch(parent, vcf, aux)
  176         struct device *parent;
  177         void *vcf;
  178         void *aux;
  179 {
  180         struct cfdata *cf = vcf;
  181         struct sbus_attach_args *sa = aux;
  182 
  183         return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
  184 }
  185 
  186 void
  187 qeattach(parent, self, aux)
  188         struct device *parent, *self;
  189         void *aux;
  190 {
  191         struct sbus_attach_args *sa = aux;
  192         struct qec_softc *qec = (struct qec_softc *)parent;
  193         struct qe_softc *sc = (struct qe_softc *)self;
  194         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  195         int node = sa->sa_node;
  196         bus_dma_tag_t dmatag = sa->sa_dmatag;
  197         bus_dma_segment_t seg;
  198         bus_size_t size;
  199         int rseg, error;
  200         extern void myetheraddr(u_char *);
  201 
  202         /* Pass on the bus tags */
  203         sc->sc_bustag = sa->sa_bustag;
  204         sc->sc_dmatag = sa->sa_dmatag;
  205 
  206         if (sa->sa_nreg < 2) {
  207                 printf("%s: only %d register sets\n",
  208                     self->dv_xname, sa->sa_nreg);
  209                 return;
  210         }
  211 
  212         if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
  213             (bus_addr_t)sa->sa_reg[0].sbr_offset,
  214             (bus_size_t)sa->sa_reg[0].sbr_size, 0, 0, &sc->sc_cr) != 0) {
  215                 printf("%s: cannot map registers\n", self->dv_xname);
  216                 return;
  217         }
  218 
  219         if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[1].sbr_slot,
  220             (bus_addr_t)sa->sa_reg[1].sbr_offset,
  221             (bus_size_t)sa->sa_reg[1].sbr_size, 0, 0, &sc->sc_mr) != 0) {
  222                 printf("%s: cannot map registers\n", self->dv_xname);
  223                 return;
  224         }
  225 
  226         sc->sc_rev = getpropint(node, "mace-version", -1);
  227         printf(" rev %x", sc->sc_rev);
  228 
  229         sc->sc_qec = qec;
  230         sc->sc_qr = qec->sc_regs;
  231 
  232         sc->sc_channel = getpropint(node, "channel#", -1);
  233         sc->sc_burst = qec->sc_burst;
  234 
  235         qestop(sc);
  236 
  237         /* Note: no interrupt level passed */
  238         if (bus_intr_establish(sa->sa_bustag, 0, IPL_NET, 0, qeintr, sc,
  239             self->dv_xname) == NULL) {
  240                 printf(": no interrupt established\n");
  241                 return;
  242         }
  243 
  244         myetheraddr(sc->sc_arpcom.ac_enaddr);
  245 
  246         /*
  247          * Allocate descriptor ring and buffers.
  248          */
  249 
  250         /* for now, allocate as many bufs as there are ring descriptors */
  251         sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE;
  252         sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE;
  253 
  254         size =
  255             QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
  256             QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
  257             sc->sc_rb.rb_ntbuf * QE_PKT_BUF_SZ +
  258             sc->sc_rb.rb_nrbuf * QE_PKT_BUF_SZ;
  259 
  260         /* Get a DMA handle */
  261         if ((error = bus_dmamap_create(dmatag, size, 1, size, 0,
  262             BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
  263                 printf("%s: DMA map create error %d\n", self->dv_xname, error);
  264                 return;
  265         }
  266 
  267         /* Allocate DMA buffer */
  268         if ((error = bus_dmamem_alloc(dmatag, size, 0, 0,
  269             &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  270                 printf("%s: DMA buffer alloc error %d\n",
  271                         self->dv_xname, error);
  272                 return;
  273         }
  274 
  275         /* Map DMA buffer in CPU addressable space */
  276         if ((error = bus_dmamem_map(dmatag, &seg, rseg, size,
  277             &sc->sc_rb.rb_membase,
  278             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  279                 printf("%s: DMA buffer map error %d\n",
  280                     self->dv_xname, error);
  281                 bus_dmamem_free(dmatag, &seg, rseg);
  282                 return;
  283         }
  284 
  285         /* Load the buffer */
  286         if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap,
  287             sc->sc_rb.rb_membase, size, NULL, BUS_DMA_NOWAIT)) != 0) {
  288                 printf("%s: DMA buffer map load error %d\n",
  289                         self->dv_xname, error);
  290                 bus_dmamem_unmap(dmatag, sc->sc_rb.rb_membase, size);
  291                 bus_dmamem_free(dmatag, &seg, rseg);
  292                 return;
  293         }
  294         sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
  295 
  296         /* Initialize media properties */
  297         ifmedia_init(&sc->sc_ifmedia, 0, qe_ifmedia_upd, qe_ifmedia_sts);
  298         ifmedia_add(&sc->sc_ifmedia,
  299             IFM_MAKEWORD(IFM_ETHER,IFM_10_T,0,0), 0, NULL);
  300         ifmedia_add(&sc->sc_ifmedia,
  301             IFM_MAKEWORD(IFM_ETHER,IFM_10_5,0,0), 0, NULL);
  302         ifmedia_add(&sc->sc_ifmedia,
  303             IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,0), 0, NULL);
  304         ifmedia_set(&sc->sc_ifmedia, IFM_ETHER|IFM_AUTO);
  305 
  306         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  307         ifp->if_softc = sc;
  308         ifp->if_start = qestart;
  309         ifp->if_ioctl = qeioctl;
  310         ifp->if_watchdog = qewatchdog;
  311         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
  312             IFF_MULTICAST;
  313         IFQ_SET_READY(&ifp->if_snd);
  314 
  315         /* Attach the interface. */
  316         if_attach(ifp);
  317         ether_ifattach(ifp);
  318 
  319         printf(" address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
  320 }
  321 
  322 /*
  323  * Pull data off an interface.
  324  * Len is the length of data, with local net header stripped.
  325  * We copy the data into mbufs.  When full cluster sized units are present,
  326  * we copy into clusters.
  327  */
  328 struct mbuf *
  329 qe_get(sc, idx, totlen)
  330         struct qe_softc *sc;
  331         int idx, totlen;
  332 {
  333         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  334         struct mbuf *m;
  335         struct mbuf *top, **mp;
  336         int len, pad, boff = 0;
  337         caddr_t bp;
  338 
  339         bp = sc->sc_rb.rb_rxbuf + (idx % sc->sc_rb.rb_nrbuf) * QE_PKT_BUF_SZ;
  340 
  341         MGETHDR(m, M_DONTWAIT, MT_DATA);
  342         if (m == NULL)
  343                 return (NULL);
  344         m->m_pkthdr.rcvif = ifp;
  345         m->m_pkthdr.len = totlen;
  346         pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
  347         m->m_data += pad;
  348         len = MHLEN - pad;
  349         top = NULL;
  350         mp = &top;
  351 
  352         while (totlen > 0) {
  353                 if (top) {
  354                         MGET(m, M_DONTWAIT, MT_DATA);
  355                         if (m == NULL) {
  356                                 m_freem(top);
  357                                 return (NULL);
  358                         }
  359                         len = MLEN;
  360                 }
  361                 if (top && totlen >= MINCLSIZE) {
  362                         MCLGET(m, M_DONTWAIT);
  363                         if (m->m_flags & M_EXT)
  364                                 len = MCLBYTES;
  365                 }
  366                 m->m_len = len = min(totlen, len);
  367                 bcopy(bp + boff, mtod(m, caddr_t), len);
  368                 boff += len;
  369                 totlen -= len;
  370                 *mp = m;
  371                 mp = &m->m_next;
  372         }
  373 
  374         return (top);
  375 }
  376 
  377 /*
  378  * Routine to copy from mbuf chain to transmit buffer in
  379  * network buffer memory.
  380  */
  381 __inline__ int
  382 qe_put(sc, idx, m)
  383         struct qe_softc *sc;
  384         int idx;
  385         struct mbuf *m;
  386 {
  387         struct mbuf *n;
  388         int len, tlen = 0, boff = 0;
  389         caddr_t bp;
  390 
  391         bp = sc->sc_rb.rb_txbuf + (idx % sc->sc_rb.rb_ntbuf) * QE_PKT_BUF_SZ;
  392 
  393         for (; m; m = n) {
  394                 len = m->m_len;
  395                 if (len == 0) {
  396                         MFREE(m, n);
  397                         continue;
  398                 }
  399                 bcopy(mtod(m, caddr_t), bp+boff, len);
  400                 boff += len;
  401                 tlen += len;
  402                 MFREE(m, n);
  403         }
  404         return (tlen);
  405 }
  406 
  407 /*
  408  * Pass a packet to the higher levels.
  409  */
  410 __inline__ void
  411 qe_read(sc, idx, len)
  412         struct qe_softc *sc;
  413         int idx, len;
  414 {
  415         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  416         struct mbuf *m;
  417 
  418         if (len <= sizeof(struct ether_header) ||
  419             len > ETHERMTU + sizeof(struct ether_header)) {
  420 
  421                 printf("%s: invalid packet size %d; dropping\n",
  422                     ifp->if_xname, len);
  423 
  424                 ifp->if_ierrors++;
  425                 return;
  426         }
  427 
  428         /*
  429          * Pull packet off interface.
  430          */
  431         m = qe_get(sc, idx, len);
  432         if (m == NULL) {
  433                 ifp->if_ierrors++;
  434                 return;
  435         }
  436         ifp->if_ipackets++;
  437 
  438 #if NBPFILTER > 0
  439         /*
  440          * Check if there's a BPF listener on this interface.
  441          * If so, hand off the raw packet to BPF.
  442          */
  443         if (ifp->if_bpf)
  444                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
  445 #endif
  446         /* Pass the packet up. */
  447         ether_input_mbuf(ifp, m);
  448 }
  449 
  450 /*
  451  * Start output on interface.
  452  * We make two assumptions here:
  453  *  1) that the current priority is set to splnet _before_ this code
  454  *     is called *and* is returned to the appropriate priority after
  455  *     return
  456  *  2) that the IFF_OACTIVE flag is checked before this code is called
  457  *     (i.e. that the output part of the interface is idle)
  458  */
  459 void
  460 qestart(ifp)
  461         struct ifnet *ifp;
  462 {
  463         struct qe_softc *sc = (struct qe_softc *)ifp->if_softc;
  464         struct qec_xd *txd = sc->sc_rb.rb_txd;
  465         struct mbuf *m;
  466         unsigned int bix, len;
  467         unsigned int ntbuf = sc->sc_rb.rb_ntbuf;
  468 
  469         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
  470                 return;
  471 
  472         bix = sc->sc_rb.rb_tdhead;
  473 
  474         for (;;) {
  475                 IFQ_POLL(&ifp->if_snd, m);
  476                 if (m == NULL)
  477                         break;
  478 
  479                 IFQ_DEQUEUE(&ifp->if_snd, m);
  480 
  481 #if NBPFILTER > 0
  482                 /*
  483                  * If BPF is listening on this interface, let it see the
  484                  * packet before we commit it to the wire.
  485                  */
  486                 if (ifp->if_bpf)
  487                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
  488 #endif
  489 
  490                 /*
  491                  * Copy the mbuf chain into the transmit buffer.
  492                  */
  493                 len = qe_put(sc, bix, m);
  494 
  495                 /*
  496                  * Initialize transmit registers and start transmission
  497                  */
  498                 txd[bix].xd_flags = QEC_XD_OWN | QEC_XD_SOP | QEC_XD_EOP |
  499                     (len & QEC_XD_LENGTH);
  500                 bus_space_write_4(sc->sc_bustag, sc->sc_cr, QE_CRI_CTRL,
  501                     QE_CR_CTRL_TWAKEUP);
  502 
  503                 if (++bix == QEC_XD_RING_MAXSIZE)
  504                         bix = 0;
  505 
  506                 if (++sc->sc_rb.rb_td_nbusy == ntbuf) {
  507                         ifp->if_flags |= IFF_OACTIVE;
  508                         break;
  509                 }
  510         }
  511 
  512         sc->sc_rb.rb_tdhead = bix;
  513 }
  514 
  515 void
  516 qestop(sc)
  517         struct qe_softc *sc;
  518 {       
  519         bus_space_tag_t t = sc->sc_bustag;
  520         bus_space_handle_t mr = sc->sc_mr;
  521         bus_space_handle_t cr = sc->sc_cr;
  522         int n;
  523 
  524         /* Stop the schwurst */
  525         bus_space_write_1(t, mr, QE_MRI_BIUCC, QE_MR_BIUCC_SWRST);
  526         for (n = 200; n > 0; n--) {
  527                 if ((bus_space_read_1(t, mr, QE_MRI_BIUCC) &
  528                     QE_MR_BIUCC_SWRST) == 0)
  529                         break;
  530                 DELAY(20);
  531         }
  532 
  533         /* then reset */
  534         bus_space_write_4(t, cr, QE_CRI_CTRL, QE_CR_CTRL_RESET);
  535         for (n = 200; n > 0; n--) {
  536                 if ((bus_space_read_4(t, cr, QE_CRI_CTRL) &
  537                     QE_CR_CTRL_RESET) == 0)
  538                         break;
  539                 DELAY(20);
  540         }
  541 }
  542 
  543 /*
  544  * Reset interface.
  545  */
  546 void
  547 qereset(sc)
  548         struct qe_softc *sc;
  549 {
  550         int s;
  551 
  552         s = splnet();
  553         qestop(sc);
  554         qeinit(sc);
  555         splx(s);
  556 }
  557 
  558 void
  559 qewatchdog(ifp)
  560         struct ifnet *ifp;
  561 {
  562         struct qe_softc *sc = ifp->if_softc;
  563 
  564         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
  565         ifp->if_oerrors++;
  566 
  567         qereset(sc);
  568 }
  569 
  570 /*
  571  * Interrupt dispatch.
  572  */
  573 int
  574 qeintr(arg)
  575         void *arg;
  576 {
  577         struct qe_softc *sc = (struct qe_softc *)arg;
  578         bus_space_tag_t t = sc->sc_bustag;
  579         u_int32_t qecstat, qestat;
  580         int r = 0;
  581 
  582         /* Read QEC status and channel status */
  583         qecstat = bus_space_read_4(t, sc->sc_qr, QEC_QRI_STAT);
  584 #ifdef QEDEBUG
  585         if (sc->sc_debug) {
  586                 printf("qe%d: intr: qecstat=%x\n", sc->sc_channel, qecstat);
  587         }
  588 #endif
  589 
  590         /* Filter out status for this channel */
  591         qecstat = qecstat >> (4 * sc->sc_channel);
  592         if ((qecstat & 0xf) == 0)
  593                 return (r);
  594 
  595         qestat = bus_space_read_4(t, sc->sc_cr, QE_CRI_STAT);
  596 
  597 #ifdef QEDEBUG
  598         if (sc->sc_debug) {
  599                 int i;
  600                 bus_space_tag_t t = sc->sc_bustag;
  601                 bus_space_handle_t mr = sc->sc_mr;
  602 
  603                 printf("qe%d: intr: qestat=%b\n", sc->sc_channel,
  604                     qestat, QE_CR_STAT_BITS);
  605 
  606                 printf("MACE registers:\n");
  607                 for (i = 0 ; i < 32; i++) {
  608                         printf("  m[%d]=%x,", i, bus_space_read_1(t, mr, i));
  609                         if (((i+1) & 7) == 0)
  610                                 printf("\n");
  611                 }
  612         }
  613 #endif
  614 
  615         if (qestat & QE_CR_STAT_ALLERRORS) {
  616 #ifdef QEDEBUG
  617                 if (sc->sc_debug)
  618                         printf("qe%d: eint: qestat=%b\n", sc->sc_channel,
  619                             qestat, QE_CR_STAT_BITS);
  620 #endif
  621                 r |= qe_eint(sc, qestat);
  622                 if (r == -1)
  623                         return (1);
  624         }
  625 
  626         if (qestat & QE_CR_STAT_TXIRQ)
  627                 r |= qe_tint(sc);
  628 
  629         if (qestat & QE_CR_STAT_RXIRQ)
  630                 r |= qe_rint(sc);
  631 
  632         return (1);
  633 }
  634 
  635 /*
  636  * Transmit interrupt.
  637  */
  638 int
  639 qe_tint(sc)
  640         struct qe_softc *sc;
  641 {
  642         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  643         unsigned int bix, txflags;
  644 
  645         bix = sc->sc_rb.rb_tdtail;
  646 
  647         for (;;) {
  648                 if (sc->sc_rb.rb_td_nbusy <= 0)
  649                         break;
  650 
  651                 txflags = sc->sc_rb.rb_txd[bix].xd_flags;
  652 
  653                 if (txflags & QEC_XD_OWN)
  654                         break;
  655 
  656                 ifp->if_flags &= ~IFF_OACTIVE;
  657                 ifp->if_opackets++;
  658 
  659                 if (++bix == QEC_XD_RING_MAXSIZE)
  660                         bix = 0;
  661 
  662                 --sc->sc_rb.rb_td_nbusy;
  663         }
  664 
  665         if (sc->sc_rb.rb_td_nbusy == 0)
  666                 ifp->if_timer = 0;
  667 
  668         if (sc->sc_rb.rb_tdtail != bix) {
  669                 sc->sc_rb.rb_tdtail = bix;
  670                 if (ifp->if_flags & IFF_OACTIVE) {
  671                         ifp->if_flags &= ~IFF_OACTIVE;
  672                         qestart(ifp);
  673                 }
  674         }
  675 
  676         return (1);
  677 }
  678 
  679 /*
  680  * Receive interrupt.
  681  */
  682 int
  683 qe_rint(sc)
  684         struct qe_softc *sc;
  685 {
  686         struct qec_xd *xd = sc->sc_rb.rb_rxd;
  687         unsigned int bix, len;
  688         unsigned int nrbuf = sc->sc_rb.rb_nrbuf;
  689 #ifdef QEDEBUG
  690         int npackets = 0;
  691 #endif
  692 
  693         bix = sc->sc_rb.rb_rdtail;
  694 
  695         /*
  696          * Process all buffers with valid data.
  697          */
  698         for (;;) {
  699                 len = xd[bix].xd_flags;
  700                 if (len & QEC_XD_OWN)
  701                         break;
  702 
  703 #ifdef QEDEBUG
  704                 npackets++;
  705 #endif
  706 
  707                 len &= QEC_XD_LENGTH;
  708                 len -= 4;
  709                 qe_read(sc, bix, len);
  710 
  711                 /* ... */
  712                 xd[(bix+nrbuf) % QEC_XD_RING_MAXSIZE].xd_flags =
  713                     QEC_XD_OWN | (QE_PKT_BUF_SZ & QEC_XD_LENGTH);
  714 
  715                 if (++bix == QEC_XD_RING_MAXSIZE)
  716                         bix = 0;
  717         }
  718 #ifdef QEDEBUG
  719         if (npackets == 0 && sc->sc_debug)
  720                 printf("%s: rint: no packets; rb index %d; status 0x%x\n",
  721                     sc->sc_dev.dv_xname, bix, len);
  722 #endif
  723 
  724         sc->sc_rb.rb_rdtail = bix;
  725 
  726         return (1);
  727 }
  728 
  729 /*
  730  * Error interrupt.
  731  */
  732 int
  733 qe_eint(sc, why)
  734         struct qe_softc *sc;
  735         u_int32_t why;
  736 {
  737         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  738         int r = 0, rst = 0;
  739 
  740         if (why & QE_CR_STAT_EDEFER) {
  741                 printf("%s: excessive tx defers.\n", sc->sc_dev.dv_xname);
  742                 r |= 1;
  743                 ifp->if_oerrors++;
  744         }
  745 
  746         if (why & QE_CR_STAT_CLOSS) {
  747                 ifp->if_oerrors++;
  748                 r |= 1;
  749         }
  750 
  751         if (why & QE_CR_STAT_ERETRIES) {
  752                 printf("%s: excessive tx retries\n", sc->sc_dev.dv_xname);
  753                 ifp->if_oerrors++;
  754                 r |= 1;
  755                 rst = 1;
  756         }
  757 
  758 
  759         if (why & QE_CR_STAT_LCOLL) {
  760                 printf("%s: late tx transmission\n", sc->sc_dev.dv_xname);
  761                 ifp->if_oerrors++;
  762                 r |= 1;
  763                 rst = 1;
  764         }
  765 
  766         if (why & QE_CR_STAT_FUFLOW) {
  767                 printf("%s: tx fifo underflow\n", sc->sc_dev.dv_xname);
  768                 ifp->if_oerrors++;
  769                 r |= 1;
  770                 rst = 1;
  771         }
  772 
  773         if (why & QE_CR_STAT_JERROR) {
  774                 printf("%s: jabber seen\n", sc->sc_dev.dv_xname);
  775                 r |= 1;
  776         }
  777 
  778         if (why & QE_CR_STAT_BERROR) {
  779                 printf("%s: babble seen\n", sc->sc_dev.dv_xname);
  780                 r |= 1;
  781         }
  782 
  783         if (why & QE_CR_STAT_TCCOFLOW) {
  784                 ifp->if_collisions += 256;
  785                 ifp->if_oerrors += 256;
  786                 r |= 1;
  787         }
  788 
  789         if (why & QE_CR_STAT_TXDERROR) {
  790                 printf("%s: tx descriptor is bad\n", sc->sc_dev.dv_xname);
  791                 rst = 1;
  792                 r |= 1;
  793         }
  794 
  795         if (why & QE_CR_STAT_TXLERR) {
  796                 printf("%s: tx late error\n", sc->sc_dev.dv_xname);
  797                 ifp->if_oerrors++;
  798                 rst = 1;
  799                 r |= 1;
  800         }
  801 
  802         if (why & QE_CR_STAT_TXPERR) {
  803                 printf("%s: tx dma parity error\n", sc->sc_dev.dv_xname);
  804                 ifp->if_oerrors++;
  805                 rst = 1;
  806                 r |= 1;
  807         }
  808 
  809         if (why & QE_CR_STAT_TXSERR) {
  810                 printf("%s: tx dma sbus error ack\n", sc->sc_dev.dv_xname);
  811                 ifp->if_oerrors++;
  812                 rst = 1;
  813                 r |= 1;
  814         }
  815 
  816         if (why & QE_CR_STAT_RCCOFLOW) {
  817                 ifp->if_collisions += 256;
  818                 ifp->if_ierrors += 256;
  819                 r |= 1;
  820         }
  821 
  822         if (why & QE_CR_STAT_RUOFLOW) {
  823                 ifp->if_ierrors += 256;
  824                 r |= 1;
  825         }
  826 
  827         if (why & QE_CR_STAT_MCOFLOW) {
  828                 ifp->if_ierrors += 256;
  829                 r |= 1;
  830         }
  831 
  832         if (why & QE_CR_STAT_RXFOFLOW) {
  833                 printf("%s: rx fifo overflow\n", sc->sc_dev.dv_xname);
  834                 ifp->if_ierrors++;
  835                 r |= 1;
  836         }
  837 
  838         if (why & QE_CR_STAT_RLCOLL) {
  839                 printf("%s: rx late collision\n", sc->sc_dev.dv_xname);
  840                 ifp->if_ierrors++;
  841                 ifp->if_collisions++;
  842                 r |= 1;
  843         }
  844 
  845         if (why & QE_CR_STAT_FCOFLOW) {
  846                 ifp->if_ierrors += 256;
  847                 r |= 1;
  848         }
  849 
  850         if (why & QE_CR_STAT_CECOFLOW) {
  851                 ifp->if_ierrors += 256;
  852                 r |= 1;
  853         }
  854 
  855         if (why & QE_CR_STAT_RXDROP) {
  856                 printf("%s: rx packet dropped\n", sc->sc_dev.dv_xname);
  857                 ifp->if_ierrors++;
  858                 r |= 1;
  859         }
  860 
  861         if (why & QE_CR_STAT_RXSMALL) {
  862                 printf("%s: rx buffer too small\n", sc->sc_dev.dv_xname);
  863                 ifp->if_ierrors++;
  864                 r |= 1;
  865                 rst = 1;
  866         }
  867 
  868         if (why & QE_CR_STAT_RXLERR) {
  869                 printf("%s: rx late error\n", sc->sc_dev.dv_xname);
  870                 ifp->if_ierrors++;
  871                 r |= 1;
  872                 rst = 1;
  873         }
  874 
  875         if (why & QE_CR_STAT_RXPERR) {
  876                 printf("%s: rx dma parity error\n", sc->sc_dev.dv_xname);
  877                 ifp->if_ierrors++;
  878                 r |= 1;
  879                 rst = 1;
  880         }
  881 
  882         if (why & QE_CR_STAT_RXSERR) {
  883                 printf("%s: rx dma sbus error ack\n", sc->sc_dev.dv_xname);
  884                 ifp->if_ierrors++;
  885                 r |= 1;
  886                 rst = 1;
  887         }
  888 
  889         if (r == 0)
  890                 printf("%s: unexpected interrupt error: %08x\n",
  891                         sc->sc_dev.dv_xname, why);
  892 
  893         if (rst) {
  894                 printf("%s: resetting...\n", sc->sc_dev.dv_xname);
  895                 qereset(sc);
  896                 return (-1);
  897         }
  898 
  899         return (r);
  900 }
  901 
  902 int
  903 qeioctl(ifp, cmd, data)
  904         struct ifnet *ifp;
  905         u_long cmd;
  906         caddr_t data;
  907 {
  908         struct qe_softc *sc = ifp->if_softc;
  909         struct ifaddr *ifa = (struct ifaddr *)data;
  910         struct ifreq *ifr = (struct ifreq *)data;
  911         int s, error = 0;
  912 
  913         s = splnet();
  914 
  915         if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
  916                 splx(s);
  917                 return (error);
  918         }
  919 
  920         switch (cmd) {
  921         case SIOCSIFADDR:
  922                 ifp->if_flags |= IFF_UP;
  923                 switch (ifa->ifa_addr->sa_family) {
  924 #ifdef INET
  925                 case AF_INET:
  926                         qeinit(sc);
  927                         arp_ifinit(&sc->sc_arpcom, ifa);
  928                         break;
  929 #endif /* INET */
  930                 default:
  931                         qeinit(sc);
  932                         break;
  933                 }
  934                 break;
  935 
  936         case SIOCSIFFLAGS:
  937                 if ((ifp->if_flags & IFF_UP) == 0 &&
  938                     (ifp->if_flags & IFF_RUNNING) != 0) {
  939                         /*
  940                          * If interface is marked down and it is running, then
  941                          * stop it.
  942                          */
  943                         qestop(sc);
  944                         ifp->if_flags &= ~IFF_RUNNING;
  945                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
  946                            (ifp->if_flags & IFF_RUNNING) == 0) {
  947                         /*
  948                          * If interface is marked up and it is stopped, then
  949                          * start it.
  950                          */
  951                         qeinit(sc);
  952                 } else {
  953                         /*
  954                          * Reset the interface to pick up changes in any other
  955                          * flags that affect hardware registers.
  956                          */
  957                         qestop(sc);
  958                         qeinit(sc);
  959                 }
  960 #ifdef QEDEBUG
  961                 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
  962 #endif
  963                 break;
  964 
  965         case SIOCADDMULTI:
  966         case SIOCDELMULTI:
  967                 error = (cmd == SIOCADDMULTI) ?
  968                     ether_addmulti(ifr, &sc->sc_arpcom):
  969                     ether_delmulti(ifr, &sc->sc_arpcom);
  970 
  971                 if (error == ENETRESET) {
  972                         /*
  973                          * Multicast list has changed; set the hardware filter
  974                          * accordingly.
  975                          */
  976                         if (ifp->if_flags & IFF_RUNNING)
  977                                 qe_mcreset(sc);
  978                         error = 0;
  979                 }
  980                 break;
  981 
  982         case SIOCGIFMEDIA:
  983         case SIOCSIFMEDIA:
  984                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
  985                 break;
  986 
  987         default:
  988                 error = EINVAL;
  989                 break;
  990         }
  991 
  992         splx(s);
  993         return (error);
  994 }
  995 
  996 
  997 void
  998 qeinit(sc)
  999         struct qe_softc *sc;
 1000 {
 1001         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1002         bus_space_tag_t t = sc->sc_bustag;
 1003         bus_space_handle_t cr = sc->sc_cr;
 1004         bus_space_handle_t mr = sc->sc_mr;
 1005         struct qec_softc *qec = sc->sc_qec;
 1006         u_int32_t qecaddr;
 1007         u_int8_t *ea;
 1008         int s;
 1009 
 1010         s = splnet();
 1011 
 1012         qestop(sc);
 1013 
 1014         /*
 1015          * Allocate descriptor ring and buffers
 1016          */
 1017         qec_meminit(&sc->sc_rb, QE_PKT_BUF_SZ);
 1018 
 1019         /* Channel registers: */
 1020         bus_space_write_4(t, cr, QE_CRI_RXDS, (u_int32_t)sc->sc_rb.rb_rxddma);
 1021         bus_space_write_4(t, cr, QE_CRI_TXDS, (u_int32_t)sc->sc_rb.rb_txddma);
 1022 
 1023         bus_space_write_4(t, cr, QE_CRI_RIMASK, 0);
 1024         bus_space_write_4(t, cr, QE_CRI_TIMASK, 0);
 1025         bus_space_write_4(t, cr, QE_CRI_QMASK, 0);
 1026         bus_space_write_4(t, cr, QE_CRI_MMASK, QE_CR_MMASK_RXCOLL);
 1027         bus_space_write_4(t, cr, QE_CRI_CCNT, 0);
 1028         bus_space_write_4(t, cr, QE_CRI_PIPG, 0);
 1029 
 1030         qecaddr = sc->sc_channel * qec->sc_msize;
 1031         bus_space_write_4(t, cr, QE_CRI_RXWBUF, qecaddr);
 1032         bus_space_write_4(t, cr, QE_CRI_RXRBUF, qecaddr);
 1033         bus_space_write_4(t, cr, QE_CRI_TXWBUF, qecaddr + qec->sc_rsize);
 1034         bus_space_write_4(t, cr, QE_CRI_TXRBUF, qecaddr + qec->sc_rsize);
 1035 
 1036         /*
 1037          * When switching from mace<->qec always guarantee an sbus
 1038          * turnaround (if last op was read, perform a dummy write, and
 1039          * vice versa).
 1040          */
 1041         bus_space_read_4(t, cr, QE_CRI_QMASK);
 1042 
 1043         /* MACE registers: */
 1044         bus_space_write_1(t, mr, QE_MRI_PHYCC, QE_MR_PHYCC_ASEL);
 1045         bus_space_write_1(t, mr, QE_MRI_XMTFC, QE_MR_XMTFC_APADXMT);
 1046         bus_space_write_1(t, mr, QE_MRI_RCVFC, 0);
 1047 
 1048         /*
 1049          * Mask MACE's receive interrupt, since we're being notified
 1050          * by the QEC after DMA completes.
 1051          */
 1052         bus_space_write_1(t, mr, QE_MRI_IMR,
 1053             QE_MR_IMR_CERRM | QE_MR_IMR_RCVINTM);
 1054 
 1055         bus_space_write_1(t, mr, QE_MRI_BIUCC,
 1056             QE_MR_BIUCC_BSWAP | QE_MR_BIUCC_64TS);
 1057 
 1058         bus_space_write_1(t, mr, QE_MRI_FIFOFC,
 1059             QE_MR_FIFOCC_TXF16 | QE_MR_FIFOCC_RXF32 |
 1060             QE_MR_FIFOCC_RFWU | QE_MR_FIFOCC_TFWU);
 1061 
 1062         bus_space_write_1(t, mr, QE_MRI_PLSCC, QE_MR_PLSCC_TP);
 1063 
 1064         /*
 1065          * Station address
 1066          */
 1067         ea = sc->sc_arpcom.ac_enaddr;
 1068         bus_space_write_1(t, mr, QE_MRI_IAC,
 1069             QE_MR_IAC_ADDRCHG | QE_MR_IAC_PHYADDR);
 1070         bus_space_write_multi_1(t, mr, QE_MRI_PADR, ea, 6);
 1071 
 1072         /* Apply media settings */
 1073         qe_ifmedia_upd(ifp);
 1074 
 1075         /*
 1076          * Clear Logical address filter
 1077          */
 1078         bus_space_write_1(t, mr, QE_MRI_IAC,
 1079             QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR);
 1080         bus_space_set_multi_1(t, mr, QE_MRI_LADRF, 0, 8);
 1081         bus_space_write_1(t, mr, QE_MRI_IAC, 0);
 1082 
 1083         /* Clear missed packet count (register cleared on read) */
 1084         (void)bus_space_read_1(t, mr, QE_MRI_MPC);
 1085 
 1086 #if 0
 1087         /* test register: */
 1088         bus_space_write_1(t, mr, QE_MRI_UTR, 0);
 1089 #endif
 1090 
 1091         /* Reset multicast filter */
 1092         qe_mcreset(sc);
 1093 
 1094         ifp->if_flags |= IFF_RUNNING;
 1095         ifp->if_flags &= ~IFF_OACTIVE;
 1096         splx(s);
 1097 }
 1098 
 1099 /*
 1100  * Reset multicast filter.
 1101  */
 1102 void
 1103 qe_mcreset(sc)
 1104         struct qe_softc *sc;
 1105 {
 1106         struct arpcom *ac = &sc->sc_arpcom;
 1107         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1108         bus_space_tag_t t = sc->sc_bustag;
 1109         bus_space_handle_t mr = sc->sc_mr;
 1110         struct ether_multi *enm;
 1111         struct ether_multistep step;
 1112         u_int32_t crc;
 1113         u_int16_t hash[4];
 1114         u_int8_t octet, maccc, *ladrp = (u_int8_t *)&hash[0];
 1115         int i, j;
 1116 
 1117         /* We also enable transmitter & receiver here */
 1118         maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV;
 1119 
 1120         if (ifp->if_flags & IFF_PROMISC) {
 1121                 maccc |= QE_MR_MACCC_PROM;
 1122                 bus_space_write_1(t, mr, QE_MRI_MACCC, maccc);
 1123                 return;
 1124         }
 1125 
 1126         if (ifp->if_flags & IFF_ALLMULTI) {
 1127                 bus_space_write_1(t, mr, QE_MRI_IAC,
 1128                     QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR);
 1129                 bus_space_set_multi_1(t, mr, QE_MRI_LADRF, 0xff, 8);
 1130                 bus_space_write_1(t, mr, QE_MRI_IAC, 0);
 1131                 bus_space_write_1(t, mr, QE_MRI_MACCC, maccc);
 1132                 return;
 1133         }
 1134 
 1135         hash[3] = hash[2] = hash[1] = hash[0] = 0;
 1136 
 1137         ETHER_FIRST_MULTI(step, ac, enm);
 1138         while (enm != NULL) {
 1139                 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
 1140                     ETHER_ADDR_LEN) != 0) {
 1141                         /*
 1142                          * We must listen to a range of multicast
 1143                          * addresses. For now, just accept all
 1144                          * multicasts, rather than trying to set only
 1145                          * those filter bits needed to match the range.
 1146                          * (At this time, the only use of address
 1147                          * ranges is for IP multicast routing, for
 1148                          * which the range is big enough to require
 1149                          * all bits set.)
 1150                          */
 1151                         bus_space_write_1(t, mr, QE_MRI_IAC,
 1152                             QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR);
 1153                         bus_space_set_multi_1(t, mr, QE_MRI_LADRF, 0xff, 8);
 1154                         bus_space_write_1(t, mr, QE_MRI_IAC, 0);
 1155                         ifp->if_flags |= IFF_ALLMULTI;
 1156                         break;
 1157                 }
 1158 
 1159                 crc = 0xffffffff;
 1160 
 1161                 for (i = 0; i < ETHER_ADDR_LEN; i++) {
 1162                         octet = enm->enm_addrlo[i];
 1163 
 1164                         for (j = 0; j < 8; j++) {
 1165                                 if ((crc & 1) ^ (octet & 1)) {
 1166                                         crc >>= 1;
 1167                                         crc ^= MC_POLY_LE;
 1168                                 }
 1169                                 else
 1170                                         crc >>= 1;
 1171                                 octet >>= 1;
 1172                         }
 1173                 }
 1174 
 1175                 crc >>= 26;
 1176                 hash[crc >> 4] |= 1 << (crc & 0xf);
 1177                 ETHER_NEXT_MULTI(step, enm);
 1178         }
 1179 
 1180         bus_space_write_1(t, mr, QE_MRI_IAC,
 1181             QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR);
 1182         bus_space_write_multi_1(t, mr, QE_MRI_LADRF, ladrp, 8);
 1183         bus_space_write_1(t, mr, QE_MRI_IAC, 0);
 1184         bus_space_write_1(t, mr, QE_MRI_MACCC, maccc);
 1185 }
 1186 
 1187 /*
 1188  * Get current media settings.
 1189  */
 1190 void
 1191 qe_ifmedia_sts(ifp, ifmr)
 1192         struct ifnet *ifp;
 1193         struct ifmediareq *ifmr;
 1194 {
 1195         struct qe_softc *sc = ifp->if_softc;
 1196         u_int8_t phycc;
 1197 
 1198         ifmr->ifm_active = IFM_ETHER | IFM_10_T;
 1199         phycc = bus_space_read_1(sc->sc_bustag, sc->sc_mr, QE_MRI_PHYCC);
 1200         if ((phycc & QE_MR_PHYCC_DLNKTST) == 0) {
 1201                 ifmr->ifm_status |= IFM_AVALID;
 1202                 if (phycc & QE_MR_PHYCC_LNKFL)
 1203                         ifmr->ifm_status &= ~IFM_ACTIVE;
 1204                 else
 1205                         ifmr->ifm_status |= IFM_ACTIVE;
 1206         }
 1207 }
 1208 
 1209 /*
 1210  * Set media options.
 1211  */
 1212 int
 1213 qe_ifmedia_upd(ifp)
 1214         struct ifnet *ifp;
 1215 {
 1216         struct qe_softc *sc = ifp->if_softc;
 1217         int media = sc->sc_ifmedia.ifm_media;
 1218 
 1219         if (IFM_TYPE(media) != IFM_ETHER)
 1220                 return (EINVAL);
 1221 
 1222         if (IFM_SUBTYPE(media) != IFM_10_T)
 1223                 return (EINVAL);
 1224 
 1225         return (0);
 1226 }

/* [<][>][^][v][top][bottom][index][help] */