The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sbus/be.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: be.c,v 1.42.2.1 2004/07/10 13:27:49 tron Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Paul Kranenburg.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
   41  * All rights reserved.
   42  *
   43  * Redistribution and use in source and binary forms, with or without
   44  * modification, are permitted provided that the following conditions
   45  * are met:
   46  * 1. Redistributions of source code must retain the above copyright
   47  *    notice, this list of conditions and the following disclaimer.
   48  * 2. Redistributions in binary form must reproduce the above copyright
   49  *    notice, this list of conditions and the following disclaimer in the
   50  *    documentation and/or other materials provided with the distribution.
   51  * 3. The name of the authors may not be used to endorse or promote products
   52  *    derived from this software without specific prior written permission.
   53  *
   54  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   57  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   64  */
   65 
   66 #include <sys/cdefs.h>
   67 __KERNEL_RCSID(0, "$NetBSD: be.c,v 1.42.2.1 2004/07/10 13:27:49 tron Exp $");
   68 
   69 #include "opt_ddb.h"
   70 #include "opt_inet.h"
   71 #include "opt_ccitt.h"
   72 #include "opt_llc.h"
   73 #include "opt_ns.h"
   74 #include "bpfilter.h"
   75 #include "rnd.h"
   76 
   77 #include <sys/param.h>
   78 #include <sys/systm.h>
   79 #include <sys/callout.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 #if NRND > 0
   89 #include <sys/rnd.h>
   90 #endif
   91 
   92 #include <net/if.h>
   93 #include <net/if_dl.h>
   94 #include <net/if_types.h>
   95 #include <net/netisr.h>
   96 #include <net/if_media.h>
   97 #include <net/if_ether.h>
   98 
   99 #ifdef INET
  100 #include <netinet/in.h>
  101 #include <netinet/if_inarp.h>
  102 #include <netinet/in_systm.h>
  103 #include <netinet/in_var.h>
  104 #include <netinet/ip.h>
  105 #endif
  106 
  107 #ifdef NS
  108 #include <netns/ns.h>
  109 #include <netns/ns_if.h>
  110 #endif
  111 
  112 #if NBPFILTER > 0
  113 #include <net/bpf.h>
  114 #include <net/bpfdesc.h>
  115 #endif
  116 
  117 #include <machine/bus.h>
  118 #include <machine/intr.h>
  119 #include <machine/autoconf.h>
  120 
  121 #include <dev/sbus/sbusvar.h>
  122 
  123 #include <dev/mii/mii.h>
  124 #include <dev/mii/miivar.h>
  125 
  126 #include <dev/sbus/qecreg.h>
  127 #include <dev/sbus/qecvar.h>
  128 #include <dev/sbus/bereg.h>
  129 
  130 struct be_softc {
  131         struct  device  sc_dev;
  132         struct  sbusdev sc_sd;          /* sbus device */
  133         bus_space_tag_t sc_bustag;      /* bus & DMA tags */
  134         bus_dma_tag_t   sc_dmatag;
  135         bus_dmamap_t    sc_dmamap;
  136         struct  ethercom sc_ethercom;
  137         /*struct        ifmedia sc_ifmedia;     -* interface media */
  138         struct mii_data sc_mii;         /* MII media control */
  139 #define sc_media        sc_mii.mii_media/* shorthand */
  140         int             sc_phys[2];     /* MII instance -> phy */
  141 
  142         struct callout sc_tick_ch;
  143 
  144         /*
  145          * Some `mii_softc' items we need to emulate MII operation
  146          * for our internal transceiver.
  147          */
  148         int             sc_mii_inst;    /* instance of internal phy */
  149         int             sc_mii_active;  /* currently active medium */
  150         int             sc_mii_ticks;   /* tick counter */
  151         int             sc_mii_flags;   /* phy status flags */
  152 #define MIIF_HAVELINK   0x04000000
  153         int             sc_intphy_curspeed;     /* Established link speed */
  154 
  155         struct  qec_softc *sc_qec;      /* QEC parent */
  156 
  157         bus_space_handle_t      sc_qr;  /* QEC registers */
  158         bus_space_handle_t      sc_br;  /* BE registers */
  159         bus_space_handle_t      sc_cr;  /* channel registers */
  160         bus_space_handle_t      sc_tr;  /* transceiver registers */
  161 
  162         u_int   sc_rev;
  163 
  164         int     sc_channel;             /* channel number */
  165         int     sc_burst;
  166 
  167         struct  qec_ring        sc_rb;  /* Packet Ring Buffer */
  168 
  169         /* MAC address */
  170         u_int8_t sc_enaddr[6];
  171 #ifdef BEDEBUG
  172         int     sc_debug;
  173 #endif
  174 };
  175 
  176 int     bematch __P((struct device *, struct cfdata *, void *));
  177 void    beattach __P((struct device *, struct device *, void *));
  178 
  179 void    beinit __P((struct be_softc *));
  180 void    bestart __P((struct ifnet *));
  181 void    bestop __P((struct be_softc *));
  182 void    bewatchdog __P((struct ifnet *));
  183 int     beioctl __P((struct ifnet *, u_long, caddr_t));
  184 void    bereset __P((struct be_softc *));
  185 
  186 int     beintr __P((void *));
  187 int     berint __P((struct be_softc *));
  188 int     betint __P((struct be_softc *));
  189 int     beqint __P((struct be_softc *, u_int32_t));
  190 int     beeint __P((struct be_softc *, u_int32_t));
  191 
  192 static void     be_read __P((struct be_softc *, int, int));
  193 static int      be_put __P((struct be_softc *, int, struct mbuf *));
  194 static struct mbuf *be_get __P((struct be_softc *, int, int));
  195 
  196 void    be_pal_gate __P((struct be_softc *, int));
  197 
  198 /* ifmedia callbacks */
  199 void    be_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
  200 int     be_ifmedia_upd __P((struct ifnet *));
  201 
  202 void    be_mcreset __P((struct be_softc *));
  203 
  204 /* MII methods & callbacks */
  205 static int      be_mii_readreg __P((struct device *, int, int));
  206 static void     be_mii_writereg __P((struct device *, int, int, int));
  207 static void     be_mii_statchg __P((struct device *));
  208 
  209 /* MII helpers */
  210 static void     be_mii_sync __P((struct be_softc *));
  211 static void     be_mii_sendbits __P((struct be_softc *, int, u_int32_t, int));
  212 static int      be_mii_reset __P((struct be_softc *, int));
  213 static int      be_tcvr_read_bit __P((struct be_softc *, int));
  214 static void     be_tcvr_write_bit __P((struct be_softc *, int, int));
  215 
  216 void    be_tick __P((void *));
  217 void    be_intphy_auto __P((struct be_softc *));
  218 void    be_intphy_status __P((struct be_softc *));
  219 int     be_intphy_service __P((struct be_softc *, struct mii_data *, int));
  220 
  221 
  222 CFATTACH_DECL(be, sizeof(struct be_softc),
  223     bematch, beattach, NULL, NULL);
  224 
  225 int
  226 bematch(parent, cf, aux)
  227         struct device *parent;
  228         struct cfdata *cf;
  229         void *aux;
  230 {
  231         struct sbus_attach_args *sa = aux;
  232 
  233         return (strcmp(cf->cf_name, sa->sa_name) == 0);
  234 }
  235 
  236 void
  237 beattach(parent, self, aux)
  238         struct device *parent, *self;
  239         void *aux;
  240 {
  241         struct sbus_attach_args *sa = aux;
  242         struct qec_softc *qec = (struct qec_softc *)parent;
  243         struct be_softc *sc = (struct be_softc *)self;
  244         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  245         struct mii_data *mii = &sc->sc_mii;
  246         struct mii_softc *child;
  247         int node = sa->sa_node;
  248         bus_dma_tag_t dmatag = sa->sa_dmatag;
  249         bus_dma_segment_t seg;
  250         bus_size_t size;
  251         int instance;
  252         int rseg, error;
  253         u_int32_t v;
  254 
  255         if (sa->sa_nreg < 3) {
  256                 printf("%s: only %d register sets\n",
  257                         self->dv_xname, sa->sa_nreg);
  258                 return;
  259         }
  260 
  261         if (bus_space_map(sa->sa_bustag,
  262                           (bus_addr_t)BUS_ADDR(
  263                                 sa->sa_reg[0].oa_space,
  264                                 sa->sa_reg[0].oa_base),
  265                           (bus_size_t)sa->sa_reg[0].oa_size,
  266                           0, &sc->sc_cr) != 0) {
  267                 printf("beattach: cannot map registers\n");
  268                 return;
  269         }
  270 
  271         if (bus_space_map(sa->sa_bustag,
  272                           (bus_addr_t)BUS_ADDR(
  273                                 sa->sa_reg[1].oa_space,
  274                                 sa->sa_reg[1].oa_base),
  275                           (bus_size_t)sa->sa_reg[1].oa_size,
  276                           0, &sc->sc_br) != 0) {
  277                 printf("beattach: cannot map registers\n");
  278                 return;
  279         }
  280 
  281         if (bus_space_map(sa->sa_bustag,
  282                           (bus_addr_t)BUS_ADDR(
  283                                 sa->sa_reg[2].oa_space,
  284                                 sa->sa_reg[2].oa_base),
  285                           (bus_size_t)sa->sa_reg[2].oa_size,
  286                           0, &sc->sc_tr) != 0) {
  287                 printf("beattach: cannot map registers\n");
  288                 return;
  289         }
  290 
  291         sc->sc_bustag = sa->sa_bustag;
  292         sc->sc_qec = qec;
  293         sc->sc_qr = qec->sc_regs;
  294 
  295         sc->sc_rev = prom_getpropint(node, "board-version", -1);
  296         printf(" rev %x", sc->sc_rev);
  297 
  298         bestop(sc);
  299 
  300         sc->sc_channel = prom_getpropint(node, "channel#", -1);
  301         if (sc->sc_channel == -1)
  302                 sc->sc_channel = 0;
  303 
  304         sc->sc_burst = prom_getpropint(node, "burst-sizes", -1);
  305         if (sc->sc_burst == -1)
  306                 sc->sc_burst = qec->sc_burst;
  307 
  308         /* Clamp at parent's burst sizes */
  309         sc->sc_burst &= qec->sc_burst;
  310 
  311         /* Establish interrupt handler */
  312         if (sa->sa_nintr)
  313                 (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET,
  314                                          beintr, sc);
  315 
  316         prom_getether(node, sc->sc_enaddr);
  317         printf(" address %s\n", ether_sprintf(sc->sc_enaddr));
  318 
  319         /*
  320          * Allocate descriptor ring and buffers.
  321          */
  322 
  323         /* for now, allocate as many bufs as there are ring descriptors */
  324         sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE;
  325         sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE;
  326 
  327         size =  QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
  328                 QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
  329                 sc->sc_rb.rb_ntbuf * BE_PKT_BUF_SZ +
  330                 sc->sc_rb.rb_nrbuf * BE_PKT_BUF_SZ;
  331 
  332         /* Get a DMA handle */
  333         if ((error = bus_dmamap_create(dmatag, size, 1, size, 0,
  334                                     BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
  335                 printf("%s: DMA map create error %d\n", self->dv_xname, error);
  336                 return;
  337         }
  338 
  339         /* Allocate DMA buffer */
  340         if ((error = bus_dmamem_alloc(sa->sa_dmatag, size, 0, 0,
  341                                       &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  342                 printf("%s: DMA buffer alloc error %d\n",
  343                         self->dv_xname, error);
  344                 return;
  345         }
  346 
  347         /* Map DMA memory in CPU addressable space */
  348         if ((error = bus_dmamem_map(sa->sa_dmatag, &seg, rseg, size,
  349                                     &sc->sc_rb.rb_membase,
  350                                     BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  351                 printf("%s: DMA buffer map error %d\n",
  352                         self->dv_xname, error);
  353                 bus_dmamem_free(sa->sa_dmatag, &seg, rseg);
  354                 return;
  355         }
  356 
  357         /* Load the buffer */
  358         if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap,
  359                                      sc->sc_rb.rb_membase, size, NULL,
  360                                      BUS_DMA_NOWAIT)) != 0) {
  361                 printf("%s: DMA buffer map load error %d\n",
  362                         self->dv_xname, error);
  363                 bus_dmamem_unmap(dmatag, sc->sc_rb.rb_membase, size);
  364                 bus_dmamem_free(dmatag, &seg, rseg);
  365                 return;
  366         }
  367         sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
  368 
  369         /*
  370          * Initialize our media structures and MII info.
  371          */
  372         mii->mii_ifp = ifp;
  373         mii->mii_readreg = be_mii_readreg;
  374         mii->mii_writereg = be_mii_writereg;
  375         mii->mii_statchg = be_mii_statchg;
  376 
  377         ifmedia_init(&mii->mii_media, 0, be_ifmedia_upd, be_ifmedia_sts);
  378 
  379         callout_init(&sc->sc_tick_ch);
  380 
  381         /*
  382          * Initialize transceiver and determine which PHY connection to use.
  383          */
  384         be_mii_sync(sc);
  385         v = bus_space_read_4(sc->sc_bustag, sc->sc_tr, BE_TRI_MGMTPAL);
  386 
  387         instance = 0;
  388 
  389         if ((v & MGMT_PAL_EXT_MDIO) != 0) {
  390 
  391                 mii_attach(&sc->sc_dev, mii, 0xffffffff, BE_PHY_EXTERNAL,
  392                     MII_OFFSET_ANY, 0);
  393 
  394                 child = LIST_FIRST(&mii->mii_phys);
  395                 if (child == NULL) {
  396                         /* No PHY attached */
  397                         ifmedia_add(&sc->sc_media,
  398                                     IFM_MAKEWORD(IFM_ETHER,IFM_NONE,0,instance),
  399                                     0, NULL);
  400                         ifmedia_set(&sc->sc_media,
  401                                    IFM_MAKEWORD(IFM_ETHER,IFM_NONE,0,instance));
  402                 } else {
  403                         /*
  404                          * Note: we support just one PHY on the external
  405                          * MII connector.
  406                          */
  407 #ifdef DIAGNOSTIC
  408                         if (LIST_NEXT(child, mii_list) != NULL) {
  409                                 printf("%s: spurious MII device %s attached\n",
  410                                        sc->sc_dev.dv_xname,
  411                                        child->mii_dev.dv_xname);
  412                         }
  413 #endif
  414                         if (child->mii_phy != BE_PHY_EXTERNAL ||
  415                             child->mii_inst > 0) {
  416                                 printf("%s: cannot accomodate MII device %s"
  417                                        " at phy %d, instance %d\n",
  418                                        sc->sc_dev.dv_xname,
  419                                        child->mii_dev.dv_xname,
  420                                        child->mii_phy, child->mii_inst);
  421                         } else {
  422                                 sc->sc_phys[instance] = child->mii_phy;
  423                         }
  424 
  425                         /*
  426                          * XXX - we can really do the following ONLY if the
  427                          * phy indeed has the auto negotiation capability!!
  428                          */
  429                         ifmedia_set(&sc->sc_media,
  430                                    IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance));
  431 
  432                         /* Mark our current media setting */
  433                         be_pal_gate(sc, BE_PHY_EXTERNAL);
  434                         instance++;
  435                 }
  436 
  437         }
  438 
  439         if ((v & MGMT_PAL_INT_MDIO) != 0) {
  440                 /*
  441                  * The be internal phy looks vaguely like MII hardware,
  442                  * but not enough to be able to use the MII device
  443                  * layer. Hence, we have to take care of media selection
  444                  * ourselves.
  445                  */
  446 
  447                 sc->sc_mii_inst = instance;
  448                 sc->sc_phys[instance] = BE_PHY_INTERNAL;
  449 
  450                 /* Use `ifm_data' to store BMCR bits */
  451                 ifmedia_add(&sc->sc_media,
  452                             IFM_MAKEWORD(IFM_ETHER,IFM_10_T,0,instance),
  453                             0, NULL);
  454                 ifmedia_add(&sc->sc_media,
  455                             IFM_MAKEWORD(IFM_ETHER,IFM_100_TX,0,instance),
  456                             BMCR_S100, NULL);
  457                 ifmedia_add(&sc->sc_media,
  458                             IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance),
  459                             0, NULL);
  460 
  461                 printf("on-board transceiver at %s: 10baseT, 100baseTX, auto\n",
  462                         self->dv_xname);
  463 
  464                 be_mii_reset(sc, BE_PHY_INTERNAL);
  465                 /* Only set default medium here if there's no external PHY */
  466                 if (instance == 0) {
  467                         be_pal_gate(sc, BE_PHY_INTERNAL);
  468                         ifmedia_set(&sc->sc_media,
  469                                    IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance));
  470                 } else
  471                         be_mii_writereg((void *)sc,
  472                                 BE_PHY_INTERNAL, MII_BMCR, BMCR_ISO);
  473         }
  474 
  475         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  476         ifp->if_softc = sc;
  477         ifp->if_start = bestart;
  478         ifp->if_ioctl = beioctl;
  479         ifp->if_watchdog = bewatchdog;
  480         ifp->if_flags =
  481                 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
  482         IFQ_SET_READY(&ifp->if_snd);
  483 
  484         /* claim 802.1q capability */
  485         sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
  486 
  487         /* Attach the interface. */
  488         if_attach(ifp);
  489         ether_ifattach(ifp, sc->sc_enaddr);
  490 }
  491 
  492 
  493 /*
  494  * Routine to copy from mbuf chain to transmit buffer in
  495  * network buffer memory.
  496  */
  497 static __inline__ int
  498 be_put(sc, idx, m)
  499         struct be_softc *sc;
  500         int idx;
  501         struct mbuf *m;
  502 {
  503         struct mbuf *n;
  504         int len, tlen = 0, boff = 0;
  505         caddr_t bp;
  506 
  507         bp = sc->sc_rb.rb_txbuf + (idx % sc->sc_rb.rb_ntbuf) * BE_PKT_BUF_SZ;
  508 
  509         for (; m; m = n) {
  510                 len = m->m_len;
  511                 if (len == 0) {
  512                         MFREE(m, n);
  513                         continue;
  514                 }
  515                 bcopy(mtod(m, caddr_t), bp+boff, len);
  516                 boff += len;
  517                 tlen += len;
  518                 MFREE(m, n);
  519         }
  520         return (tlen);
  521 }
  522 
  523 /*
  524  * Pull data off an interface.
  525  * Len is the length of data, with local net header stripped.
  526  * We copy the data into mbufs.  When full cluster sized units are present,
  527  * we copy into clusters.
  528  */
  529 static __inline__ struct mbuf *
  530 be_get(sc, idx, totlen)
  531         struct be_softc *sc;
  532         int idx, totlen;
  533 {
  534         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  535         struct mbuf *m;
  536         struct mbuf *top, **mp;
  537         int len, pad, boff = 0;
  538         caddr_t bp;
  539 
  540         bp = sc->sc_rb.rb_rxbuf + (idx % sc->sc_rb.rb_nrbuf) * BE_PKT_BUF_SZ;
  541 
  542         MGETHDR(m, M_DONTWAIT, MT_DATA);
  543         if (m == NULL)
  544                 return (NULL);
  545         m->m_pkthdr.rcvif = ifp;
  546         m->m_pkthdr.len = totlen;
  547 
  548         pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
  549         m->m_data += pad;
  550         len = MHLEN - pad;
  551         top = NULL;
  552         mp = &top;
  553 
  554         while (totlen > 0) {
  555                 if (top) {
  556                         MGET(m, M_DONTWAIT, MT_DATA);
  557                         if (m == NULL) {
  558                                 m_freem(top);
  559                                 return (NULL);
  560                         }
  561                         len = MLEN;
  562                 }
  563                 if (top && totlen >= MINCLSIZE) {
  564                         MCLGET(m, M_DONTWAIT);
  565                         if (m->m_flags & M_EXT)
  566                                 len = MCLBYTES;
  567                 }
  568                 m->m_len = len = min(totlen, len);
  569                 bcopy(bp + boff, mtod(m, caddr_t), len);
  570                 boff += len;
  571                 totlen -= len;
  572                 *mp = m;
  573                 mp = &m->m_next;
  574         }
  575 
  576         return (top);
  577 }
  578 
  579 /*
  580  * Pass a packet to the higher levels.
  581  */
  582 static __inline__ void
  583 be_read(sc, idx, len)
  584         struct be_softc *sc;
  585         int idx, len;
  586 {
  587         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  588         struct mbuf *m;
  589 
  590         if (len <= sizeof(struct ether_header) ||
  591             len > ETHER_MAX_LEN + ETHERCAP_VLAN_MTU) {
  592 #ifdef BEDEBUG
  593                 if (sc->sc_debug)
  594                         printf("%s: invalid packet size %d; dropping\n",
  595                                 ifp->if_xname, len);
  596 #endif
  597                 ifp->if_ierrors++;
  598                 return;
  599         }
  600 
  601         /*
  602          * Pull packet off interface.
  603          */
  604         m = be_get(sc, idx, len);
  605         if (m == NULL) {
  606                 ifp->if_ierrors++;
  607                 return;
  608         }
  609         ifp->if_ipackets++;
  610 
  611 #if NBPFILTER > 0
  612         /*
  613          * Check if there's a BPF listener on this interface.
  614          * If so, hand off the raw packet to BPF.
  615          */
  616         if (ifp->if_bpf)
  617                 bpf_mtap(ifp->if_bpf, m);
  618 #endif
  619         /* Pass the packet up. */
  620         (*ifp->if_input)(ifp, m);
  621 }
  622 
  623 /*
  624  * Start output on interface.
  625  * We make two assumptions here:
  626  *  1) that the current priority is set to splnet _before_ this code
  627  *     is called *and* is returned to the appropriate priority after
  628  *     return
  629  *  2) that the IFF_OACTIVE flag is checked before this code is called
  630  *     (i.e. that the output part of the interface is idle)
  631  */
  632 void
  633 bestart(ifp)
  634         struct ifnet *ifp;
  635 {
  636         struct be_softc *sc = (struct be_softc *)ifp->if_softc;
  637         struct qec_xd *txd = sc->sc_rb.rb_txd;
  638         struct mbuf *m;
  639         unsigned int bix, len;
  640         unsigned int ntbuf = sc->sc_rb.rb_ntbuf;
  641 
  642         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
  643                 return;
  644 
  645         bix = sc->sc_rb.rb_tdhead;
  646 
  647         for (;;) {
  648                 IFQ_DEQUEUE(&ifp->if_snd, m);
  649                 if (m == 0)
  650                         break;
  651 
  652 #if NBPFILTER > 0
  653                 /*
  654                  * If BPF is listening on this interface, let it see the
  655                  * packet before we commit it to the wire.
  656                  */
  657                 if (ifp->if_bpf)
  658                         bpf_mtap(ifp->if_bpf, m);
  659 #endif
  660 
  661                 /*
  662                  * Copy the mbuf chain into the transmit buffer.
  663                  */
  664                 len = be_put(sc, bix, m);
  665 
  666                 /*
  667                  * Initialize transmit registers and start transmission
  668                  */
  669                 txd[bix].xd_flags = QEC_XD_OWN | QEC_XD_SOP | QEC_XD_EOP |
  670                                     (len & QEC_XD_LENGTH);
  671                 bus_space_write_4(sc->sc_bustag, sc->sc_cr, BE_CRI_CTRL,
  672                                   BE_CR_CTRL_TWAKEUP);
  673 
  674                 if (++bix == QEC_XD_RING_MAXSIZE)
  675                         bix = 0;
  676 
  677                 if (++sc->sc_rb.rb_td_nbusy == ntbuf) {
  678                         ifp->if_flags |= IFF_OACTIVE;
  679                         break;
  680                 }
  681         }
  682 
  683         sc->sc_rb.rb_tdhead = bix;
  684 }
  685 
  686 void
  687 bestop(sc)
  688         struct be_softc *sc;
  689 {
  690         int n;
  691         bus_space_tag_t t = sc->sc_bustag;
  692         bus_space_handle_t br = sc->sc_br;
  693 
  694         callout_stop(&sc->sc_tick_ch);
  695 
  696         /* Down the MII. */
  697         mii_down(&sc->sc_mii);
  698         (void)be_intphy_service(sc, &sc->sc_mii, MII_DOWN);
  699 
  700         /* Stop the transmitter */
  701         bus_space_write_4(t, br, BE_BRI_TXCFG, 0);
  702         for (n = 32; n > 0; n--) {
  703                 if (bus_space_read_4(t, br, BE_BRI_TXCFG) == 0)
  704                         break;
  705                 DELAY(20);
  706         }
  707 
  708         /* Stop the receiver */
  709         bus_space_write_4(t, br, BE_BRI_RXCFG, 0);
  710         for (n = 32; n > 0; n--) {
  711                 if (bus_space_read_4(t, br, BE_BRI_RXCFG) == 0)
  712                         break;
  713                 DELAY(20);
  714         }
  715 }
  716 
  717 /*
  718  * Reset interface.
  719  */
  720 void
  721 bereset(sc)
  722         struct be_softc *sc;
  723 {
  724         int s;
  725 
  726         s = splnet();
  727         bestop(sc);
  728         if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0)
  729                 beinit(sc);
  730         splx(s);
  731 }
  732 
  733 void
  734 bewatchdog(ifp)
  735         struct ifnet *ifp;
  736 {
  737         struct be_softc *sc = ifp->if_softc;
  738 
  739         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
  740         ++sc->sc_ethercom.ec_if.if_oerrors;
  741 
  742         bereset(sc);
  743 }
  744 
  745 int
  746 beintr(v)
  747         void *v;
  748 {
  749         struct be_softc *sc = (struct be_softc *)v;
  750         bus_space_tag_t t = sc->sc_bustag;
  751         u_int32_t whyq, whyb, whyc;
  752         int r = 0;
  753 
  754         /* Read QEC status, channel status and BE status */
  755         whyq = bus_space_read_4(t, sc->sc_qr, QEC_QRI_STAT);
  756         whyc = bus_space_read_4(t, sc->sc_cr, BE_CRI_STAT);
  757         whyb = bus_space_read_4(t, sc->sc_br, BE_BRI_STAT);
  758 
  759         if (whyq & QEC_STAT_BM)
  760                 r |= beeint(sc, whyb);
  761 
  762         if (whyq & QEC_STAT_ER)
  763                 r |= beqint(sc, whyc);
  764 
  765         if (whyq & QEC_STAT_TX && whyc & BE_CR_STAT_TXIRQ)
  766                 r |= betint(sc);
  767 
  768         if (whyq & QEC_STAT_RX && whyc & BE_CR_STAT_RXIRQ)
  769                 r |= berint(sc);
  770 
  771         return (r);
  772 }
  773 
  774 /*
  775  * QEC Interrupt.
  776  */
  777 int
  778 beqint(sc, why)
  779         struct be_softc *sc;
  780         u_int32_t why;
  781 {
  782         int r = 0, rst = 0;
  783 
  784         if (why & BE_CR_STAT_TXIRQ)
  785                 r |= 1;
  786         if (why & BE_CR_STAT_RXIRQ)
  787                 r |= 1;
  788 
  789         if (why & BE_CR_STAT_BERROR) {
  790                 r |= 1;
  791                 rst = 1;
  792                 printf("%s: bigmac error\n", sc->sc_dev.dv_xname);
  793         }
  794 
  795         if (why & BE_CR_STAT_TXDERR) {
  796                 r |= 1;
  797                 rst = 1;
  798                 printf("%s: bogus tx descriptor\n", sc->sc_dev.dv_xname);
  799         }
  800 
  801         if (why & (BE_CR_STAT_TXLERR | BE_CR_STAT_TXPERR | BE_CR_STAT_TXSERR)) {
  802                 r |= 1;
  803                 rst = 1;
  804                 printf("%s: tx DMA error ( ", sc->sc_dev.dv_xname);
  805                 if (why & BE_CR_STAT_TXLERR)
  806                         printf("Late ");
  807                 if (why & BE_CR_STAT_TXPERR)
  808                         printf("Parity ");
  809                 if (why & BE_CR_STAT_TXSERR)
  810                         printf("Generic ");
  811                 printf(")\n");
  812         }
  813 
  814         if (why & BE_CR_STAT_RXDROP) {
  815                 r |= 1;
  816                 rst = 1;
  817                 printf("%s: out of rx descriptors\n", sc->sc_dev.dv_xname);
  818         }
  819 
  820         if (why & BE_CR_STAT_RXSMALL) {
  821                 r |= 1;
  822                 rst = 1;
  823                 printf("%s: rx descriptor too small\n", sc->sc_dev.dv_xname);
  824         }
  825 
  826         if (why & (BE_CR_STAT_RXLERR | BE_CR_STAT_RXPERR | BE_CR_STAT_RXSERR)) {
  827                 r |= 1;
  828                 rst = 1;
  829                 printf("%s: rx DMA error ( ", sc->sc_dev.dv_xname);
  830                 if (why & BE_CR_STAT_RXLERR)
  831                         printf("Late ");
  832                 if (why & BE_CR_STAT_RXPERR)
  833                         printf("Parity ");
  834                 if (why & BE_CR_STAT_RXSERR)
  835                         printf("Generic ");
  836                 printf(")\n");
  837         }
  838 
  839         if (!r) {
  840                 rst = 1;
  841                 printf("%s: unexpected error interrupt %08x\n",
  842                         sc->sc_dev.dv_xname, why);
  843         }
  844 
  845         if (rst) {
  846                 printf("%s: resetting\n", sc->sc_dev.dv_xname);
  847                 bereset(sc);
  848         }
  849 
  850         return (r);
  851 }
  852 
  853 /*
  854  * Error interrupt.
  855  */
  856 int
  857 beeint(sc, why)
  858         struct be_softc *sc;
  859         u_int32_t why;
  860 {
  861         int r = 0, rst = 0;
  862 
  863         if (why & BE_BR_STAT_RFIFOVF) {
  864                 r |= 1;
  865                 rst = 1;
  866                 printf("%s: receive fifo overrun\n", sc->sc_dev.dv_xname);
  867         }
  868         if (why & BE_BR_STAT_TFIFO_UND) {
  869                 r |= 1;
  870                 rst = 1;
  871                 printf("%s: transmit fifo underrun\n", sc->sc_dev.dv_xname);
  872         }
  873         if (why & BE_BR_STAT_MAXPKTERR) {
  874                 r |= 1;
  875                 rst = 1;
  876                 printf("%s: max packet size error\n", sc->sc_dev.dv_xname);
  877         }
  878 
  879         if (!r) {
  880                 rst = 1;
  881                 printf("%s: unexpected error interrupt %08x\n",
  882                         sc->sc_dev.dv_xname, why);
  883         }
  884 
  885         if (rst) {
  886                 printf("%s: resetting\n", sc->sc_dev.dv_xname);
  887                 bereset(sc);
  888         }
  889 
  890         return (r);
  891 }
  892 
  893 /*
  894  * Transmit interrupt.
  895  */
  896 int
  897 betint(sc)
  898         struct be_softc *sc;
  899 {
  900         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  901         bus_space_tag_t t = sc->sc_bustag;
  902         bus_space_handle_t br = sc->sc_br;
  903         unsigned int bix, txflags;
  904 
  905         /*
  906          * Unload collision counters
  907          */
  908         ifp->if_collisions +=
  909                 bus_space_read_4(t, br, BE_BRI_NCCNT) +
  910                 bus_space_read_4(t, br, BE_BRI_FCCNT) +
  911                 bus_space_read_4(t, br, BE_BRI_EXCNT) +
  912                 bus_space_read_4(t, br, BE_BRI_LTCNT);
  913 
  914         /*
  915          * the clear the hardware counters
  916          */
  917         bus_space_write_4(t, br, BE_BRI_NCCNT, 0);
  918         bus_space_write_4(t, br, BE_BRI_FCCNT, 0);
  919         bus_space_write_4(t, br, BE_BRI_EXCNT, 0);
  920         bus_space_write_4(t, br, BE_BRI_LTCNT, 0);
  921 
  922         bix = sc->sc_rb.rb_tdtail;
  923 
  924         for (;;) {
  925                 if (sc->sc_rb.rb_td_nbusy <= 0)
  926                         break;
  927 
  928                 txflags = sc->sc_rb.rb_txd[bix].xd_flags;
  929 
  930                 if (txflags & QEC_XD_OWN)
  931                         break;
  932 
  933                 ifp->if_flags &= ~IFF_OACTIVE;
  934                 ifp->if_opackets++;
  935 
  936                 if (++bix == QEC_XD_RING_MAXSIZE)
  937                         bix = 0;
  938 
  939                 --sc->sc_rb.rb_td_nbusy;
  940         }
  941 
  942         sc->sc_rb.rb_tdtail = bix;
  943 
  944         bestart(ifp);
  945 
  946         if (sc->sc_rb.rb_td_nbusy == 0)
  947                 ifp->if_timer = 0;
  948 
  949         return (1);
  950 }
  951 
  952 /*
  953  * Receive interrupt.
  954  */
  955 int
  956 berint(sc)
  957         struct be_softc *sc;
  958 {
  959         struct qec_xd *xd = sc->sc_rb.rb_rxd;
  960         unsigned int bix, len;
  961         unsigned int nrbuf = sc->sc_rb.rb_nrbuf;
  962 
  963         bix = sc->sc_rb.rb_rdtail;
  964 
  965         /*
  966          * Process all buffers with valid data.
  967          */
  968         for (;;) {
  969                 len = xd[bix].xd_flags;
  970                 if (len & QEC_XD_OWN)
  971                         break;
  972 
  973                 len &= QEC_XD_LENGTH;
  974                 be_read(sc, bix, len);
  975 
  976                 /* ... */
  977                 xd[(bix+nrbuf) % QEC_XD_RING_MAXSIZE].xd_flags =
  978                         QEC_XD_OWN | (BE_PKT_BUF_SZ & QEC_XD_LENGTH);
  979 
  980                 if (++bix == QEC_XD_RING_MAXSIZE)
  981                         bix = 0;
  982         }
  983 
  984         sc->sc_rb.rb_rdtail = bix;
  985 
  986         return (1);
  987 }
  988 
  989 int
  990 beioctl(ifp, cmd, data)
  991         struct ifnet *ifp;
  992         u_long cmd;
  993         caddr_t data;
  994 {
  995         struct be_softc *sc = ifp->if_softc;
  996         struct ifaddr *ifa = (struct ifaddr *)data;
  997         struct ifreq *ifr = (struct ifreq *)data;
  998         int s, error = 0;
  999 
 1000         s = splnet();
 1001 
 1002         switch (cmd) {
 1003         case SIOCSIFADDR:
 1004                 ifp->if_flags |= IFF_UP;
 1005                 switch (ifa->ifa_addr->sa_family) {
 1006 #ifdef INET
 1007                 case AF_INET:
 1008                         beinit(sc);
 1009                         arp_ifinit(ifp, ifa);
 1010                         break;
 1011 #endif /* INET */
 1012 #ifdef NS
 1013                 case AF_NS:
 1014                     {
 1015                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
 1016 
 1017                         if (ns_nullhost(*ina))
 1018                                 ina->x_host =
 1019                                         *(union ns_host *)LLADDR(ifp->if_sadl);
 1020                         else
 1021                                 bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
 1022                                       sizeof(sc->sc_enaddr));
 1023                         /* Set new address. */
 1024                         beinit(sc);
 1025                         break;
 1026                     }
 1027 #endif /* NS */
 1028                 default:
 1029                         beinit(sc);
 1030                         break;
 1031                 }
 1032                 break;
 1033 
 1034         case SIOCSIFFLAGS:
 1035                 if ((ifp->if_flags & IFF_UP) == 0 &&
 1036                     (ifp->if_flags & IFF_RUNNING) != 0) {
 1037                         /*
 1038                          * If interface is marked down and it is running, then
 1039                          * stop it.
 1040                          */
 1041                         bestop(sc);
 1042                         ifp->if_flags &= ~IFF_RUNNING;
 1043                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
 1044                     (ifp->if_flags & IFF_RUNNING) == 0) {
 1045                         /*
 1046                          * If interface is marked up and it is stopped, then
 1047                          * start it.
 1048                          */
 1049                         beinit(sc);
 1050                 } else {
 1051                         /*
 1052                          * Reset the interface to pick up changes in any other
 1053                          * flags that affect hardware registers.
 1054                          */
 1055                         bestop(sc);
 1056                         beinit(sc);
 1057                 }
 1058 #ifdef BEDEBUG
 1059                 if (ifp->if_flags & IFF_DEBUG)
 1060                         sc->sc_debug = 1;
 1061                 else
 1062                         sc->sc_debug = 0;
 1063 #endif
 1064                 break;
 1065 
 1066         case SIOCADDMULTI:
 1067         case SIOCDELMULTI:
 1068                 error = (cmd == SIOCADDMULTI) ?
 1069                     ether_addmulti(ifr, &sc->sc_ethercom):
 1070                     ether_delmulti(ifr, &sc->sc_ethercom);
 1071 
 1072                 if (error == ENETRESET) {
 1073                         /*
 1074                          * Multicast list has changed; set the hardware filter
 1075                          * accordingly.
 1076                          */
 1077                         be_mcreset(sc);
 1078                         error = 0;
 1079                 }
 1080                 break;
 1081         case SIOCGIFMEDIA:
 1082         case SIOCSIFMEDIA:
 1083                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
 1084                 break;
 1085         default:
 1086                 error = EINVAL;
 1087                 break;
 1088         }
 1089         splx(s);
 1090         return (error);
 1091 }
 1092 
 1093 
 1094 void
 1095 beinit(sc)
 1096         struct be_softc *sc;
 1097 {
 1098         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1099         bus_space_tag_t t = sc->sc_bustag;
 1100         bus_space_handle_t br = sc->sc_br;
 1101         bus_space_handle_t cr = sc->sc_cr;
 1102         struct qec_softc *qec = sc->sc_qec;
 1103         u_int32_t v;
 1104         u_int32_t qecaddr;
 1105         u_int8_t *ea;
 1106         int s;
 1107 
 1108         s = splnet();
 1109 
 1110         qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ);
 1111 
 1112         bestop(sc);
 1113 
 1114         ea = sc->sc_enaddr;
 1115         bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]);
 1116         bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]);
 1117         bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]);
 1118 
 1119         /* Clear hash table */
 1120         bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0);
 1121         bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0);
 1122         bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0);
 1123         bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0);
 1124 
 1125         /* Re-initialize RX configuration */
 1126         v = BE_BR_RXCFG_FIFO;
 1127         bus_space_write_4(t, br, BE_BRI_RXCFG, v);
 1128 
 1129         be_mcreset(sc);
 1130 
 1131         bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd);
 1132 
 1133         bus_space_write_4(t, br, BE_BRI_XIFCFG,
 1134                           BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV);
 1135 
 1136         bus_space_write_4(t, br, BE_BRI_JSIZE, 4);
 1137 
 1138         /*
 1139          * Turn off counter expiration interrupts as well as
 1140          * 'gotframe' and 'sentframe'
 1141          */
 1142         bus_space_write_4(t, br, BE_BRI_IMASK,
 1143                           BE_BR_IMASK_GOTFRAME  |
 1144                           BE_BR_IMASK_RCNTEXP   |
 1145                           BE_BR_IMASK_ACNTEXP   |
 1146                           BE_BR_IMASK_CCNTEXP   |
 1147                           BE_BR_IMASK_LCNTEXP   |
 1148                           BE_BR_IMASK_CVCNTEXP  |
 1149                           BE_BR_IMASK_SENTFRAME |
 1150                           BE_BR_IMASK_NCNTEXP   |
 1151                           BE_BR_IMASK_ECNTEXP   |
 1152                           BE_BR_IMASK_LCCNTEXP  |
 1153                           BE_BR_IMASK_FCNTEXP   |
 1154                           BE_BR_IMASK_DTIMEXP);
 1155 
 1156         /* Channel registers: */
 1157         bus_space_write_4(t, cr, BE_CRI_RXDS, (u_int32_t)sc->sc_rb.rb_rxddma);
 1158         bus_space_write_4(t, cr, BE_CRI_TXDS, (u_int32_t)sc->sc_rb.rb_txddma);
 1159 
 1160         qecaddr = sc->sc_channel * qec->sc_msize;
 1161         bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr);
 1162         bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr);
 1163         bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize);
 1164         bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize);
 1165 
 1166         bus_space_write_4(t, cr, BE_CRI_RIMASK, 0);
 1167         bus_space_write_4(t, cr, BE_CRI_TIMASK, 0);
 1168         bus_space_write_4(t, cr, BE_CRI_QMASK, 0);
 1169         bus_space_write_4(t, cr, BE_CRI_BMASK, 0);
 1170         bus_space_write_4(t, cr, BE_CRI_CCNT, 0);
 1171 
 1172         /* Set max packet length */
 1173         v = ETHER_MAX_LEN;
 1174         if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU)
 1175                 v += ETHER_VLAN_ENCAP_LEN;
 1176         bus_space_write_4(t, br, BE_BRI_RXMAX, v);
 1177         bus_space_write_4(t, br, BE_BRI_TXMAX, v);
 1178 
 1179         /* Enable transmitter */
 1180         bus_space_write_4(t, br, BE_BRI_TXCFG,
 1181                           BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE);
 1182 
 1183         /* Enable receiver */
 1184         v = bus_space_read_4(t, br, BE_BRI_RXCFG);
 1185         v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE;
 1186         bus_space_write_4(t, br, BE_BRI_RXCFG, v);
 1187 
 1188         ifp->if_flags |= IFF_RUNNING;
 1189         ifp->if_flags &= ~IFF_OACTIVE;
 1190 
 1191         be_ifmedia_upd(ifp);
 1192         callout_reset(&sc->sc_tick_ch, hz, be_tick, sc);
 1193         splx(s);
 1194 }
 1195 
 1196 void
 1197 be_mcreset(sc)
 1198         struct be_softc *sc;
 1199 {
 1200         struct ethercom *ec = &sc->sc_ethercom;
 1201         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1202         bus_space_tag_t t = sc->sc_bustag;
 1203         bus_space_handle_t br = sc->sc_br;
 1204         u_int32_t crc;
 1205         u_int16_t hash[4];
 1206         u_int8_t octet;
 1207         u_int32_t v;
 1208         int i, j;
 1209         struct ether_multi *enm;
 1210         struct ether_multistep step;
 1211 
 1212         if (ifp->if_flags & IFF_PROMISC) {
 1213                 v = bus_space_read_4(t, br, BE_BRI_RXCFG);
 1214                 v |= BE_BR_RXCFG_PMISC;
 1215                 bus_space_write_4(t, br, BE_BRI_RXCFG, v);
 1216                 return;
 1217         }
 1218 
 1219         if (ifp->if_flags & IFF_ALLMULTI) {
 1220                 hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
 1221                 goto chipit;
 1222         }
 1223 
 1224         hash[3] = hash[2] = hash[1] = hash[0] = 0;
 1225 
 1226         ETHER_FIRST_MULTI(step, ec, enm);
 1227         while (enm != NULL) {
 1228                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
 1229                         /*
 1230                          * We must listen to a range of multicast
 1231                          * addresses.  For now, just accept all
 1232                          * multicasts, rather than trying to set only
 1233                          * those filter bits needed to match the range.
 1234                          * (At this time, the only use of address
 1235                          * ranges is for IP multicast routing, for
 1236                          * which the range is big enough to require
 1237                          * all bits set.)
 1238                          */
 1239                         hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
 1240                         ifp->if_flags |= IFF_ALLMULTI;
 1241                         goto chipit;
 1242                 }
 1243 
 1244                 crc = 0xffffffff;
 1245 
 1246                 for (i = 0; i < ETHER_ADDR_LEN; i++) {
 1247                         octet = enm->enm_addrlo[i];
 1248 
 1249                         for (j = 0; j < 8; j++) {
 1250                                 if ((crc & 1) ^ (octet & 1)) {
 1251                                         crc >>= 1;
 1252                                         crc ^= MC_POLY_LE;
 1253                                 }
 1254                                 else
 1255                                         crc >>= 1;
 1256                                 octet >>= 1;
 1257                         }
 1258                 }
 1259 
 1260                 crc >>= 26;
 1261                 hash[crc >> 4] |= 1 << (crc & 0xf);
 1262                 ETHER_NEXT_MULTI(step, enm);
 1263         }
 1264 
 1265         ifp->if_flags &= ~IFF_ALLMULTI;
 1266 
 1267 chipit:
 1268         /* Enable the hash filter */
 1269         bus_space_write_4(t, br, BE_BRI_HASHTAB0, hash[0]);
 1270         bus_space_write_4(t, br, BE_BRI_HASHTAB1, hash[1]);
 1271         bus_space_write_4(t, br, BE_BRI_HASHTAB2, hash[2]);
 1272         bus_space_write_4(t, br, BE_BRI_HASHTAB3, hash[3]);
 1273 
 1274         v = bus_space_read_4(t, br, BE_BRI_RXCFG);
 1275         v &= ~BE_BR_RXCFG_PMISC;
 1276         v |= BE_BR_RXCFG_HENABLE;
 1277         bus_space_write_4(t, br, BE_BRI_RXCFG, v);
 1278 }
 1279 
 1280 /*
 1281  * Set the tcvr to an idle state
 1282  */
 1283 void
 1284 be_mii_sync(sc)
 1285         struct be_softc *sc;
 1286 {
 1287         bus_space_tag_t t = sc->sc_bustag;
 1288         bus_space_handle_t tr = sc->sc_tr;
 1289         int n = 32;
 1290 
 1291         while (n--) {
 1292                 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
 1293                                   MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
 1294                                   MGMT_PAL_OENAB);
 1295                 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1296                 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
 1297                                   MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
 1298                                   MGMT_PAL_OENAB | MGMT_PAL_DCLOCK);
 1299                 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1300         }
 1301 }
 1302 
 1303 void
 1304 be_pal_gate(sc, phy)
 1305         struct be_softc *sc;
 1306         int phy;
 1307 {
 1308         bus_space_tag_t t = sc->sc_bustag;
 1309         bus_space_handle_t tr = sc->sc_tr;
 1310         u_int32_t v;
 1311 
 1312         be_mii_sync(sc);
 1313 
 1314         v = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE);
 1315         if (phy == BE_PHY_INTERNAL)
 1316                 v &= ~TCVR_PAL_SERIAL;
 1317 
 1318         bus_space_write_4(t, tr, BE_TRI_TCVRPAL, v);
 1319         (void)bus_space_read_4(t, tr, BE_TRI_TCVRPAL);
 1320 }
 1321 
 1322 static int
 1323 be_tcvr_read_bit(sc, phy)
 1324         struct be_softc *sc;
 1325         int phy;
 1326 {
 1327         bus_space_tag_t t = sc->sc_bustag;
 1328         bus_space_handle_t tr = sc->sc_tr;
 1329         int ret;
 1330 
 1331         if (phy == BE_PHY_INTERNAL) {
 1332                 bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_EXT_MDIO);
 1333                 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1334                 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
 1335                                   MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK);
 1336                 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1337                 ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) &
 1338                         MGMT_PAL_INT_MDIO) >> MGMT_PAL_INT_MDIO_SHIFT;
 1339         } else {
 1340                 bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_INT_MDIO);
 1341                 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1342                 ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) &
 1343                         MGMT_PAL_EXT_MDIO) >> MGMT_PAL_EXT_MDIO_SHIFT;
 1344                 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
 1345                                   MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK);
 1346                 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1347         }
 1348 
 1349         return (ret);
 1350 }
 1351 
 1352 static void
 1353 be_tcvr_write_bit(sc, phy, bit)
 1354         struct be_softc *sc;
 1355         int phy;
 1356         int bit;
 1357 {
 1358         bus_space_tag_t t = sc->sc_bustag;
 1359         bus_space_handle_t tr = sc->sc_tr;
 1360         u_int32_t v;
 1361 
 1362         if (phy == BE_PHY_INTERNAL) {
 1363                 v = ((bit & 1) << MGMT_PAL_INT_MDIO_SHIFT) |
 1364                         MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO;
 1365         } else {
 1366                 v = ((bit & 1) << MGMT_PAL_EXT_MDIO_SHIFT)
 1367                         | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO;
 1368         }
 1369         bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v);
 1370         (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1371         bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v | MGMT_PAL_DCLOCK);
 1372         (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
 1373 }
 1374 
 1375 static void
 1376 be_mii_sendbits(sc, phy, data, nbits)
 1377         struct be_softc *sc;
 1378         int phy;
 1379         u_int32_t data;
 1380         int nbits;
 1381 {
 1382         int i;
 1383 
 1384         for (i = 1 << (nbits - 1); i != 0; i >>= 1) {
 1385                 be_tcvr_write_bit(sc, phy, (data & i) != 0);
 1386         }
 1387 }
 1388 
 1389 static int
 1390 be_mii_readreg(self, phy, reg)
 1391         struct device *self;
 1392         int phy, reg;
 1393 {
 1394         struct be_softc *sc = (struct be_softc *)self;
 1395         int val = 0, i;
 1396 
 1397         /*
 1398          * Read the PHY register by manually driving the MII control lines.
 1399          */
 1400         be_mii_sync(sc);
 1401         be_mii_sendbits(sc, phy, MII_COMMAND_START, 2);
 1402         be_mii_sendbits(sc, phy, MII_COMMAND_READ, 2);
 1403         be_mii_sendbits(sc, phy, phy, 5);
 1404         be_mii_sendbits(sc, phy, reg, 5);
 1405 
 1406         (void) be_tcvr_read_bit(sc, phy);
 1407         (void) be_tcvr_read_bit(sc, phy);
 1408 
 1409         for (i = 15; i >= 0; i--)
 1410                 val |= (be_tcvr_read_bit(sc, phy) << i);
 1411 
 1412         (void) be_tcvr_read_bit(sc, phy);
 1413         (void) be_tcvr_read_bit(sc, phy);
 1414         (void) be_tcvr_read_bit(sc, phy);
 1415 
 1416         return (val);
 1417 }
 1418 
 1419 void
 1420 be_mii_writereg(self, phy, reg, val)
 1421         struct device *self;
 1422         int phy, reg, val;
 1423 {
 1424         struct be_softc *sc = (struct be_softc *)self;
 1425         int i;
 1426 
 1427         /*
 1428          * Write the PHY register by manually driving the MII control lines.
 1429          */
 1430         be_mii_sync(sc);
 1431         be_mii_sendbits(sc, phy, MII_COMMAND_START, 2);
 1432         be_mii_sendbits(sc, phy, MII_COMMAND_WRITE, 2);
 1433         be_mii_sendbits(sc, phy, phy, 5);
 1434         be_mii_sendbits(sc, phy, reg, 5);
 1435 
 1436         be_tcvr_write_bit(sc, phy, 1);
 1437         be_tcvr_write_bit(sc, phy, 0);
 1438 
 1439         for (i = 15; i >= 0; i--)
 1440                 be_tcvr_write_bit(sc, phy, (val >> i) & 1);
 1441 }
 1442 
 1443 int
 1444 be_mii_reset(sc, phy)
 1445         struct be_softc *sc;
 1446         int phy;
 1447 {
 1448         int n;
 1449 
 1450         be_mii_writereg((struct device *)sc, phy, MII_BMCR,
 1451                         BMCR_LOOP | BMCR_PDOWN | BMCR_ISO);
 1452         be_mii_writereg((struct device *)sc, phy, MII_BMCR, BMCR_RESET);
 1453 
 1454         for (n = 16; n >= 0; n--) {
 1455                 int bmcr = be_mii_readreg((struct device *)sc, phy, MII_BMCR);
 1456                 if ((bmcr & BMCR_RESET) == 0)
 1457                         break;
 1458                 DELAY(20);
 1459         }
 1460         if (n == 0) {
 1461                 printf("%s: bmcr reset failed\n", sc->sc_dev.dv_xname);
 1462                 return (EIO);
 1463         }
 1464 
 1465         return (0);
 1466 }
 1467 
 1468 void
 1469 be_tick(arg)
 1470         void    *arg;
 1471 {
 1472         struct be_softc *sc = arg;
 1473         int s = splnet();
 1474 
 1475         mii_tick(&sc->sc_mii);
 1476         (void)be_intphy_service(sc, &sc->sc_mii, MII_TICK);
 1477 
 1478         splx(s);
 1479         callout_reset(&sc->sc_tick_ch, hz, be_tick, sc);
 1480 }
 1481 
 1482 void
 1483 be_mii_statchg(self)
 1484         struct device *self;
 1485 {
 1486         struct be_softc *sc = (struct be_softc *)self;
 1487         bus_space_tag_t t = sc->sc_bustag;
 1488         bus_space_handle_t br = sc->sc_br;
 1489         u_int instance;
 1490         u_int32_t v;
 1491 
 1492         instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
 1493 #ifdef DIAGNOSTIC
 1494         if (instance > 1)
 1495                 panic("be_mii_statchg: instance %d out of range", instance);
 1496 #endif
 1497 
 1498         /* Update duplex mode in TX configuration */
 1499         v = bus_space_read_4(t, br, BE_BRI_TXCFG);
 1500         if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0)
 1501                 v |= BE_BR_TXCFG_FULLDPLX;
 1502         else
 1503                 v &= ~BE_BR_TXCFG_FULLDPLX;
 1504         bus_space_write_4(t, br, BE_BRI_TXCFG, v);
 1505 
 1506         /* Change to appropriate gate in transceiver PAL */
 1507         be_pal_gate(sc, sc->sc_phys[instance]);
 1508 }
 1509 
 1510 /*
 1511  * Get current media settings.
 1512  */
 1513 void
 1514 be_ifmedia_sts(ifp, ifmr)
 1515         struct ifnet *ifp;
 1516         struct ifmediareq *ifmr;
 1517 {
 1518         struct be_softc *sc = ifp->if_softc;
 1519 
 1520         mii_pollstat(&sc->sc_mii);
 1521         (void)be_intphy_service(sc, &sc->sc_mii, MII_POLLSTAT);
 1522 
 1523         ifmr->ifm_status = sc->sc_mii.mii_media_status;
 1524         ifmr->ifm_active = sc->sc_mii.mii_media_active;
 1525         return;
 1526 }
 1527 
 1528 /*
 1529  * Set media options.
 1530  */
 1531 int
 1532 be_ifmedia_upd(ifp)
 1533         struct ifnet *ifp;
 1534 {
 1535         struct be_softc *sc = ifp->if_softc;
 1536         int error;
 1537 
 1538         if ((error = mii_mediachg(&sc->sc_mii)) != 0)
 1539                 return (error);
 1540 
 1541         return (be_intphy_service(sc, &sc->sc_mii, MII_MEDIACHG));
 1542 }
 1543 
 1544 /*
 1545  * Service routine for our pseudo-MII internal transceiver.
 1546  */
 1547 int
 1548 be_intphy_service(sc, mii, cmd)
 1549         struct be_softc *sc;
 1550         struct mii_data *mii;
 1551         int cmd;
 1552 {
 1553         struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
 1554         int bmcr, bmsr;
 1555         int error;
 1556 
 1557         switch (cmd) {
 1558         case MII_POLLSTAT:
 1559                 /*
 1560                  * If we're not polling our PHY instance, just return.
 1561                  */
 1562                 if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst)
 1563                         return (0);
 1564 
 1565                 break;
 1566 
 1567         case MII_MEDIACHG:
 1568 
 1569                 /*
 1570                  * If the media indicates a different PHY instance,
 1571                  * isolate ourselves.
 1572                  */
 1573                 if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst) {
 1574                         bmcr = be_mii_readreg((void *)sc,
 1575                                 BE_PHY_INTERNAL, MII_BMCR);
 1576                         be_mii_writereg((void *)sc,
 1577                                 BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO);
 1578                         sc->sc_mii_flags &= ~MIIF_HAVELINK;
 1579                         sc->sc_intphy_curspeed = 0;
 1580                         return (0);
 1581                 }
 1582 
 1583 
 1584                 if ((error = be_mii_reset(sc, BE_PHY_INTERNAL)) != 0)
 1585                         return (error);
 1586 
 1587                 bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
 1588 
 1589                 /*
 1590                  * Select the new mode and take out of isolation
 1591                  */
 1592                 if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX)
 1593                         bmcr |= BMCR_S100;
 1594                 else if (IFM_SUBTYPE(ife->ifm_media) == IFM_10_T)
 1595                         bmcr &= ~BMCR_S100;
 1596                 else if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
 1597                         if ((sc->sc_mii_flags & MIIF_HAVELINK) != 0) {
 1598                                 bmcr &= ~BMCR_S100;
 1599                                 bmcr |= sc->sc_intphy_curspeed;
 1600                         } else {
 1601                                 /* Keep isolated until link is up */
 1602                                 bmcr |= BMCR_ISO;
 1603                                 sc->sc_mii_flags |= MIIF_DOINGAUTO;
 1604                         }
 1605                 }
 1606 
 1607                 if ((IFM_OPTIONS(ife->ifm_media) & IFM_FDX) != 0)
 1608                         bmcr |= BMCR_FDX;
 1609                 else
 1610                         bmcr &= ~BMCR_FDX;
 1611 
 1612                 be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr);
 1613                 break;
 1614 
 1615         case MII_TICK:
 1616                 /*
 1617                  * If we're not currently selected, just return.
 1618                  */
 1619                 if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst)
 1620                         return (0);
 1621 
 1622                 /* Only used for automatic media selection */
 1623                 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
 1624                         return (0);
 1625 
 1626                 /* Is the interface even up? */
 1627                 if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
 1628                         return (0);
 1629 
 1630                 /*
 1631                  * Check link status; if we don't have a link, try another
 1632                  * speed. We can't detect duplex mode, so half-duplex is
 1633                  * what we have to settle for.
 1634                  */
 1635 
 1636                 /* Read twice in case the register is latched */
 1637                 bmsr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMSR) |
 1638                        be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMSR);
 1639 
 1640                 if ((bmsr & BMSR_LINK) != 0) {
 1641                         /* We have a carrier */
 1642                         bmcr = be_mii_readreg((void *)sc,
 1643                                         BE_PHY_INTERNAL, MII_BMCR);
 1644 
 1645                         if ((sc->sc_mii_flags & MIIF_DOINGAUTO) != 0) {
 1646                                 bmcr = be_mii_readreg((void *)sc,
 1647                                                 BE_PHY_INTERNAL, MII_BMCR);
 1648 
 1649                                 sc->sc_mii_flags |= MIIF_HAVELINK;
 1650                                 sc->sc_intphy_curspeed = (bmcr & BMCR_S100);
 1651                                 sc->sc_mii_flags &= ~MIIF_DOINGAUTO;
 1652 
 1653                                 bmcr &= ~BMCR_ISO;
 1654                                 be_mii_writereg((void *)sc,
 1655                                         BE_PHY_INTERNAL, MII_BMCR, bmcr);
 1656 
 1657                                 printf("%s: link up at %s Mbps\n",
 1658                                         sc->sc_dev.dv_xname,
 1659                                         (bmcr & BMCR_S100) ? "100" : "10");
 1660                         }
 1661                         return (0);
 1662                 }
 1663 
 1664                 if ((sc->sc_mii_flags & MIIF_DOINGAUTO) == 0) {
 1665                         sc->sc_mii_flags |= MIIF_DOINGAUTO;
 1666                         sc->sc_mii_flags &= ~MIIF_HAVELINK;
 1667                         sc->sc_intphy_curspeed = 0;
 1668                         printf("%s: link down\n", sc->sc_dev.dv_xname);
 1669                 }
 1670 
 1671                 /* Only retry autonegotiation every 5 seconds. */
 1672                 if (++sc->sc_mii_ticks < 5)
 1673                         return(0);
 1674 
 1675                 sc->sc_mii_ticks = 0;
 1676                 bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
 1677                 /* Just flip the fast speed bit */
 1678                 bmcr ^= BMCR_S100;
 1679                 be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr);
 1680 
 1681                 break;
 1682 
 1683         case MII_DOWN:
 1684                 /* Isolate this phy */
 1685                 bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
 1686                 be_mii_writereg((void *)sc,
 1687                                 BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO);
 1688                 return (0);
 1689         }
 1690 
 1691         /* Update the media status. */
 1692         be_intphy_status(sc);
 1693 
 1694         /* Callback if something changed. */
 1695         if (sc->sc_mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
 1696                 (*mii->mii_statchg)((struct device *)sc);
 1697                 sc->sc_mii_active = mii->mii_media_active;
 1698         }
 1699         return (0);
 1700 }
 1701 
 1702 /*
 1703  * Determine status of internal transceiver
 1704  */
 1705 void
 1706 be_intphy_status(sc)
 1707         struct be_softc *sc;
 1708 {
 1709         struct mii_data *mii = &sc->sc_mii;
 1710         int media_active, media_status;
 1711         int bmcr, bmsr;
 1712 
 1713         media_status = IFM_AVALID;
 1714         media_active = 0;
 1715 
 1716         /*
 1717          * Internal transceiver; do the work here.
 1718          */
 1719         bmcr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMCR);
 1720 
 1721         switch (bmcr & (BMCR_S100 | BMCR_FDX)) {
 1722         case (BMCR_S100 | BMCR_FDX):
 1723                 media_active = IFM_ETHER | IFM_100_TX | IFM_FDX;
 1724                 break;
 1725         case BMCR_S100:
 1726                 media_active = IFM_ETHER | IFM_100_TX | IFM_HDX;
 1727                 break;
 1728         case BMCR_FDX:
 1729                 media_active = IFM_ETHER | IFM_10_T | IFM_FDX;
 1730                 break;
 1731         case 0:
 1732                 media_active = IFM_ETHER | IFM_10_T | IFM_HDX;
 1733                 break;
 1734         }
 1735 
 1736         /* Read twice in case the register is latched */
 1737         bmsr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMSR)|
 1738                be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMSR);
 1739         if (bmsr & BMSR_LINK)
 1740                 media_status |=  IFM_ACTIVE;
 1741 
 1742         mii->mii_media_status = media_status;
 1743         mii->mii_media_active = media_active;
 1744 }

Cache object: 14e2dbb4805684caada538a84a832150


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.