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/ic/smc91cxx.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: smc91cxx.c,v 1.58 2006/11/16 01:32:52 christos Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
    9  * NASA Ames Research Center.
   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) 1996 Gardner Buchanan <gbuchanan@shl.com>
   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  * 3. All advertising materials mentioning features or use of this software
   53  *    must display the following acknowledgement:
   54  *      This product includes software developed by Gardner Buchanan.
   55  * 4. The name of Gardner Buchanan may not be used to endorse or promote
   56  *    products derived from this software without specific prior written
   57  *    permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   60  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   61  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   62  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   63  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   64  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   65  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   67  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   68  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   69  *
   70  *   from FreeBSD Id: if_sn.c,v 1.4 1996/03/18 15:47:16 gardner Exp
   71  */
   72 
   73 /*
   74  * Core driver for the SMC 91Cxx family of Ethernet chips.
   75  *
   76  * Memory allocation interrupt logic is drived from an SMC 91C90 driver
   77  * written for NetBSD/amiga by Michael Hitch.
   78  */
   79 
   80 #include <sys/cdefs.h>
   81 __KERNEL_RCSID(0, "$NetBSD: smc91cxx.c,v 1.58 2006/11/16 01:32:52 christos Exp $");
   82 
   83 #include "opt_inet.h"
   84 #include "bpfilter.h"
   85 #include "rnd.h"
   86 
   87 #include <sys/param.h>
   88 #include <sys/systm.h>
   89 #include <sys/mbuf.h>
   90 #include <sys/syslog.h>
   91 #include <sys/socket.h>
   92 #include <sys/device.h>
   93 #include <sys/kernel.h>
   94 #include <sys/malloc.h>
   95 #include <sys/ioctl.h>
   96 #include <sys/errno.h>
   97 #if NRND > 0
   98 #include <sys/rnd.h>
   99 #endif
  100 
  101 #include <machine/bus.h>
  102 #include <machine/intr.h>
  103 
  104 #include <net/if.h>
  105 #include <net/if_dl.h>
  106 #include <net/if_ether.h>
  107 #include <net/if_media.h>
  108 
  109 #ifdef INET
  110 #include <netinet/in.h>
  111 #include <netinet/if_inarp.h>
  112 #include <netinet/in_systm.h>
  113 #include <netinet/in_var.h>
  114 #include <netinet/ip.h>
  115 #endif
  116 
  117 
  118 
  119 #if NBPFILTER > 0
  120 #include <net/bpf.h>
  121 #include <net/bpfdesc.h>
  122 #endif
  123 
  124 #include <dev/mii/mii.h>
  125 #include <dev/mii/miivar.h>
  126 #include <dev/mii/mii_bitbang.h>
  127 
  128 #include <dev/ic/smc91cxxreg.h>
  129 #include <dev/ic/smc91cxxvar.h>
  130 
  131 #ifndef __BUS_SPACE_HAS_STREAM_METHODS
  132 #define bus_space_write_multi_stream_2 bus_space_write_multi_2
  133 #define bus_space_write_multi_stream_4 bus_space_write_multi_4
  134 #define bus_space_read_multi_stream_2  bus_space_read_multi_2
  135 #define bus_space_read_multi_stream_4  bus_space_read_multi_4
  136 
  137 #define bus_space_write_stream_4 bus_space_write_4
  138 #define bus_space_read_stream_4  bus_space_read_4
  139 #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
  140 
  141 /* XXX Hardware padding doesn't work yet(?) */
  142 #define SMC91CXX_SW_PAD
  143 
  144 const char *smc91cxx_idstrs[] = {
  145         NULL,                           /* 0 */
  146         NULL,                           /* 1 */
  147         NULL,                           /* 2 */
  148         "SMC91C90/91C92",               /* 3 */
  149         "SMC91C94/91C96",               /* 4 */
  150         "SMC91C95",                     /* 5 */
  151         NULL,                           /* 6 */
  152         "SMC91C100",                    /* 7 */
  153         "SMC91C100FD",                  /* 8 */
  154         "SMC91C111",                    /* 9 */
  155         NULL,                           /* 10 */
  156         NULL,                           /* 11 */
  157         NULL,                           /* 12 */
  158         NULL,                           /* 13 */
  159         NULL,                           /* 14 */
  160         NULL,                           /* 15 */
  161 };
  162 
  163 /* Supported media types. */
  164 const int smc91cxx_media[] = {
  165         IFM_ETHER|IFM_10_T,
  166         IFM_ETHER|IFM_10_5,
  167 };
  168 #define NSMC91CxxMEDIA  (sizeof(smc91cxx_media) / sizeof(smc91cxx_media[0]))
  169 
  170 /*
  171  * MII bit-bang glue.
  172  */
  173 u_int32_t smc91cxx_mii_bitbang_read(struct device *);
  174 void smc91cxx_mii_bitbang_write(struct device *, u_int32_t);
  175 
  176 const struct mii_bitbang_ops smc91cxx_mii_bitbang_ops = {
  177         smc91cxx_mii_bitbang_read,
  178         smc91cxx_mii_bitbang_write,
  179         {
  180                 MR_MDO,         /* MII_BIT_MDO */
  181                 MR_MDI,         /* MII_BIT_MDI */
  182                 MR_MCLK,        /* MII_BIT_MDC */
  183                 MR_MDOE,        /* MII_BIT_DIR_HOST_PHY */
  184                 0,              /* MII_BIT_DIR_PHY_HOST */
  185         }
  186 };
  187 
  188 /* MII callbacks */
  189 int     smc91cxx_mii_readreg(struct device *, int, int);
  190 void    smc91cxx_mii_writereg(struct device *, int, int, int);
  191 void    smc91cxx_statchg(struct device *);
  192 void    smc91cxx_tick(void *);
  193 
  194 int     smc91cxx_mediachange(struct ifnet *);
  195 void    smc91cxx_mediastatus(struct ifnet *, struct ifmediareq *);
  196 
  197 int     smc91cxx_set_media(struct smc91cxx_softc *, int);
  198 
  199 void    smc91cxx_init(struct smc91cxx_softc *);
  200 void    smc91cxx_read(struct smc91cxx_softc *);
  201 void    smc91cxx_reset(struct smc91cxx_softc *);
  202 void    smc91cxx_start(struct ifnet *);
  203 void    smc91cxx_copy_tx_frame(struct smc91cxx_softc *, struct mbuf *);
  204 void    smc91cxx_resume(struct smc91cxx_softc *);
  205 void    smc91cxx_stop(struct smc91cxx_softc *);
  206 void    smc91cxx_watchdog(struct ifnet *);
  207 int     smc91cxx_ioctl(struct ifnet *, u_long, caddr_t);
  208 
  209 static inline int ether_cmp(void *, void *);
  210 static inline int
  211 ether_cmp(va, vb)
  212         void *va, *vb;
  213 {
  214         u_int8_t *a = va;
  215         u_int8_t *b = vb;
  216 
  217         return ((a[5] != b[5]) || (a[4] != b[4]) || (a[3] != b[3]) ||
  218                 (a[2] != b[2]) || (a[1] != b[1]) || (a[0] != b[0]));
  219 }
  220 
  221 void
  222 smc91cxx_attach(sc, myea)
  223         struct smc91cxx_softc *sc;
  224         u_int8_t *myea;
  225 {
  226         struct ifnet *ifp = &sc->sc_ec.ec_if;
  227         bus_space_tag_t bst = sc->sc_bst;
  228         bus_space_handle_t bsh = sc->sc_bsh;
  229         struct ifmedia *ifm = &sc->sc_mii.mii_media;
  230         const char *idstr;
  231         u_int32_t miicapabilities;
  232         u_int16_t tmp;
  233         u_int8_t enaddr[ETHER_ADDR_LEN];
  234         int i, aui, mult, scale, memsize;
  235         char pbuf[9];
  236 
  237         tmp = bus_space_read_2(bst, bsh, BANK_SELECT_REG_W);
  238         /* check magic number */
  239         if ((tmp & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
  240                 aprint_error("%s: failed to detect chip, bsr=%04x\n",
  241                     sc->sc_dev.dv_xname, tmp);
  242                 return;
  243         }
  244 
  245         /* Make sure the chip is stopped. */
  246         smc91cxx_stop(sc);
  247 
  248         SMC_SELECT_BANK(sc, 3);
  249         tmp = bus_space_read_2(bst, bsh, REVISION_REG_W);
  250         sc->sc_chipid = RR_ID(tmp);
  251         idstr = smc91cxx_idstrs[sc->sc_chipid];
  252 
  253         aprint_normal("%s: ", sc->sc_dev.dv_xname);
  254         if (idstr != NULL)
  255                 aprint_normal("%s, ", idstr);
  256         else
  257                 aprint_normal("unknown chip id %d, ", sc->sc_chipid);
  258         aprint_normal("revision %d, ", RR_REV(tmp));
  259 
  260         SMC_SELECT_BANK(sc, 0);
  261         switch (sc->sc_chipid) {
  262         default:
  263                 mult = MCR_MEM_MULT(bus_space_read_2(bst, bsh, MEM_CFG_REG_W));
  264                 scale = MIR_SCALE_91C9x;
  265                 break;
  266 
  267         case CHIP_91C111:
  268                 mult = MIR_MULT_91C111;
  269                 scale = MIR_SCALE_91C111;
  270         }
  271         memsize = bus_space_read_2(bst, bsh, MEM_INFO_REG_W) & MIR_TOTAL_MASK;
  272         if (memsize == 255) memsize++;
  273         memsize *= scale * mult;
  274 
  275         format_bytes(pbuf, sizeof(pbuf), memsize);
  276         aprint_normal("buffer size: %s\n", pbuf);
  277 
  278         /* Read the station address from the chip. */
  279         SMC_SELECT_BANK(sc, 1);
  280         if (myea == NULL) {
  281                 myea = enaddr;
  282                 for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
  283                         tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + i);
  284                         myea[i + 1] = (tmp >> 8) & 0xff;
  285                         myea[i] = tmp & 0xff;
  286                 }
  287         }
  288         aprint_normal("%s: MAC address %s, ", sc->sc_dev.dv_xname,
  289             ether_sprintf(myea));
  290 
  291         /* Initialize the ifnet structure. */
  292         strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  293         ifp->if_softc = sc;
  294         ifp->if_start = smc91cxx_start;
  295         ifp->if_ioctl = smc91cxx_ioctl;
  296         ifp->if_watchdog = smc91cxx_watchdog;
  297         ifp->if_flags =
  298             IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
  299         IFQ_SET_READY(&ifp->if_snd);
  300 
  301         /* Attach the interface. */
  302         if_attach(ifp);
  303         ether_ifattach(ifp, myea);
  304 
  305         /*
  306          * Initialize our media structures and MII info.  We will
  307          * probe the MII if we are on the SMC91Cxx
  308          */
  309         sc->sc_mii.mii_ifp = ifp;
  310         sc->sc_mii.mii_readreg = smc91cxx_mii_readreg;
  311         sc->sc_mii.mii_writereg = smc91cxx_mii_writereg;
  312         sc->sc_mii.mii_statchg = smc91cxx_statchg;
  313         ifmedia_init(ifm, IFM_IMASK, smc91cxx_mediachange, smc91cxx_mediastatus);
  314 
  315         SMC_SELECT_BANK(sc, 1);
  316         tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
  317 
  318         miicapabilities = BMSR_MEDIAMASK|BMSR_ANEG;
  319         switch (sc->sc_chipid) {
  320         case CHIP_91100:
  321                 /*
  322                  * The 91100 does not have full-duplex capabilities,
  323                  * even if the PHY does.
  324                  */
  325                 miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX);
  326         case CHIP_91100FD:
  327         case CHIP_91C111:
  328                 if (tmp & CR_MII_SELECT) {
  329                         aprint_normal("default media MII");
  330                         if (sc->sc_chipid == CHIP_91C111) {
  331                                 aprint_normal(" (%s PHY)\n", (tmp & CR_AUI_SELECT) ?
  332                                     "external" : "internal");
  333                                 sc->sc_internal_phy = !(tmp & CR_AUI_SELECT);
  334                         } else
  335                                 aprint_normal("\n");
  336                         mii_attach(&sc->sc_dev, &sc->sc_mii, miicapabilities,
  337                             MII_PHY_ANY, MII_OFFSET_ANY, 0);
  338                         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
  339                                 ifmedia_add(&sc->sc_mii.mii_media,
  340                                     IFM_ETHER|IFM_NONE, 0, NULL);
  341                                 ifmedia_set(&sc->sc_mii.mii_media,
  342                                     IFM_ETHER|IFM_NONE);
  343                         } else {
  344                                 ifmedia_set(&sc->sc_mii.mii_media,
  345                                     IFM_ETHER|IFM_AUTO);
  346                         }
  347                         sc->sc_flags |= SMC_FLAGS_HAS_MII;
  348                         break;
  349                 } else
  350                 if (sc->sc_chipid == CHIP_91C111) {
  351                         /*
  352                          * XXX: Should bring it out of low-power mode
  353                          */
  354                         aprint_normal("EPH interface in low power mode\n");
  355                         sc->sc_internal_phy = 0;
  356                         return;
  357                 }
  358                 /*FALLTHROUGH*/
  359         default:
  360                 aprint_normal("default media %s\n", (aui = (tmp & CR_AUI_SELECT)) ?
  361                     "AUI" : "UTP");
  362                 for (i = 0; i < NSMC91CxxMEDIA; i++)
  363                         ifmedia_add(ifm, smc91cxx_media[i], 0, NULL);
  364                 ifmedia_set(ifm, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T));
  365                 break;
  366         }
  367 
  368 #if NRND > 0
  369         rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
  370                           RND_TYPE_NET, 0);
  371 #endif
  372 
  373         /* The attach is successful. */
  374         sc->sc_flags |= SMC_FLAGS_ATTACHED;
  375 }
  376 
  377 /*
  378  * Change media according to request.
  379  */
  380 int
  381 smc91cxx_mediachange(ifp)
  382         struct ifnet *ifp;
  383 {
  384         struct smc91cxx_softc *sc = ifp->if_softc;
  385 
  386         return (smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_media));
  387 }
  388 
  389 int
  390 smc91cxx_set_media(sc, media)
  391         struct smc91cxx_softc *sc;
  392         int media;
  393 {
  394         bus_space_tag_t bst = sc->sc_bst;
  395         bus_space_handle_t bsh = sc->sc_bsh;
  396         u_int16_t tmp;
  397 
  398         /*
  399          * If the interface is not currently powered on, just return.
  400          * When it is enabled later, smc91cxx_init() will properly set
  401          * up the media for us.
  402          */
  403         if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0)
  404                 return (0);
  405 
  406         if (IFM_TYPE(media) != IFM_ETHER)
  407                 return (EINVAL);
  408 
  409         if (sc->sc_flags & SMC_FLAGS_HAS_MII)
  410                 return (mii_mediachg(&sc->sc_mii));
  411 
  412         switch (IFM_SUBTYPE(media)) {
  413         case IFM_10_T:
  414         case IFM_10_5:
  415                 SMC_SELECT_BANK(sc, 1);
  416                 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
  417                 if (IFM_SUBTYPE(media) == IFM_10_5)
  418                         tmp |= CR_AUI_SELECT;
  419                 else
  420                         tmp &= ~CR_AUI_SELECT;
  421                 bus_space_write_2(bst, bsh, CONFIG_REG_W, tmp);
  422                 delay(20000);   /* XXX is this needed? */
  423                 break;
  424 
  425         default:
  426                 return (EINVAL);
  427         }
  428 
  429         return (0);
  430 }
  431 
  432 /*
  433  * Notify the world which media we're using.
  434  */
  435 void
  436 smc91cxx_mediastatus(ifp, ifmr)
  437         struct ifnet *ifp;
  438         struct ifmediareq *ifmr;
  439 {
  440         struct smc91cxx_softc *sc = ifp->if_softc;
  441         bus_space_tag_t bst = sc->sc_bst;
  442         bus_space_handle_t bsh = sc->sc_bsh;
  443         u_int16_t tmp;
  444 
  445         if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) {
  446                 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
  447                 ifmr->ifm_status = 0;
  448                 return;
  449         }
  450 
  451         /*
  452          * If we have MII, go ask the PHY what's going on.
  453          */
  454         if (sc->sc_flags & SMC_FLAGS_HAS_MII) {
  455                 mii_pollstat(&sc->sc_mii);
  456                 ifmr->ifm_active = sc->sc_mii.mii_media_active;
  457                 ifmr->ifm_status = sc->sc_mii.mii_media_status;
  458                 return;
  459         }
  460 
  461         SMC_SELECT_BANK(sc, 1);
  462         tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
  463         ifmr->ifm_active =
  464             IFM_ETHER | ((tmp & CR_AUI_SELECT) ? IFM_10_5 : IFM_10_T);
  465 }
  466 
  467 /*
  468  * Reset and initialize the chip.
  469  */
  470 void
  471 smc91cxx_init(sc)
  472         struct smc91cxx_softc *sc;
  473 {
  474         struct ifnet *ifp = &sc->sc_ec.ec_if;
  475         bus_space_tag_t bst = sc->sc_bst;
  476         bus_space_handle_t bsh = sc->sc_bsh;
  477         u_int16_t tmp;
  478         u_int8_t *enaddr;
  479         int s, i;
  480 
  481         s = splnet();
  482 
  483         /*
  484          * This resets the registers mostly to defaults, but doesn't
  485          * affect the EEPROM.  After the reset cycle, we pause briefly
  486          * for the chip to recover.
  487          *
  488          * XXX how long are we really supposed to delay?  --thorpej
  489          */
  490         SMC_SELECT_BANK(sc, 0);
  491         bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, RCR_SOFTRESET);
  492         delay(100);
  493         bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0);
  494         delay(200);
  495 
  496         bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0);
  497 
  498         /* Set the Ethernet address. */
  499         SMC_SELECT_BANK(sc, 1);
  500         enaddr = (u_int8_t *)LLADDR(ifp->if_sadl);
  501         for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
  502                 tmp = enaddr[i + 1] << 8 | enaddr[i];
  503                 bus_space_write_2(bst, bsh, IAR_ADDR0_REG_W + i, tmp);
  504         }
  505 
  506         /*
  507          * Set the control register to automatically release successfully
  508          * transmitted packets (making the best use of our limited memory)
  509          * and enable the EPH interrupt on certain TX errors.
  510          */
  511         bus_space_write_2(bst, bsh, CONTROL_REG_W, (CTR_AUTO_RELEASE |
  512             CTR_TE_ENABLE | CTR_CR_ENABLE | CTR_LE_ENABLE));
  513 
  514         /*
  515          * Reset the MMU and wait for it to be un-busy.
  516          */
  517         SMC_SELECT_BANK(sc, 2);
  518         bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RESET);
  519         for (;;) {
  520                 tmp = bus_space_read_2(bst, bsh, MMU_CMD_REG_W);
  521                 if (tmp == 0xffff)      /* card went away! */
  522                         return;
  523                 if ((tmp & MMUCR_BUSY) == 0)
  524                         break;
  525         }
  526 
  527         /*
  528          * Disable all interrupts.
  529          */
  530         bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
  531 
  532         /*
  533          * On the 91c111, enable auto-negotiation, and set the LED
  534          * status pins to something sane.
  535          * XXX: Should be some way for MD code to decide the latter.
  536          */
  537         SMC_SELECT_BANK(sc, 0);
  538         if (sc->sc_chipid == CHIP_91C111) {
  539                 bus_space_write_2(bst, bsh, RX_PHY_CONTROL_REG_W,
  540                     RPC_ANEG |
  541                     (RPC_LS_LINK_DETECT << RPC_LSA_SHIFT) |
  542                     (RPC_LS_TXRX << RPC_LSB_SHIFT));
  543         }
  544 
  545         /*
  546          * Set current media.
  547          */
  548         smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_cur->ifm_media);
  549 
  550         /*
  551          * Set the receive filter.  We want receive enable and auto
  552          * strip of CRC from received packet.  If we are in promisc. mode,
  553          * then set that bit as well.
  554          *
  555          * XXX Initialize multicast filter.  For now, we just accept
  556          * XXX all multicast.
  557          */
  558         SMC_SELECT_BANK(sc, 0);
  559 
  560         tmp = RCR_ENABLE | RCR_STRIP_CRC | RCR_ALMUL;
  561         if (ifp->if_flags & IFF_PROMISC)
  562                 tmp |= RCR_PROMISC;
  563 
  564         bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, tmp);
  565 
  566         /*
  567          * Set transmitter control to "enabled".
  568          */
  569         tmp = TCR_ENABLE;
  570 
  571 #ifndef SMC91CXX_SW_PAD
  572         /*
  573          * Enable hardware padding of transmitted packets.
  574          * XXX doesn't work?
  575          */
  576         tmp |= TCR_PAD_ENABLE;
  577 #endif
  578 
  579         bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, tmp);
  580 
  581         /*
  582          * Now, enable interrupts.
  583          */
  584         SMC_SELECT_BANK(sc, 2);
  585 
  586         if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy) {
  587                 bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
  588                     IM_EPH_INT | IM_RX_OVRN_INT |
  589                     IM_RCV_INT | IM_TX_INT | IM_MD_INT);
  590         } else {
  591                 bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
  592                     IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT);
  593         }
  594 
  595         /* Interface is now running, with no output active. */
  596         ifp->if_flags |= IFF_RUNNING;
  597         ifp->if_flags &= ~IFF_OACTIVE;
  598 
  599         if (sc->sc_flags & SMC_FLAGS_HAS_MII) {
  600                 /* Start the one second clock. */
  601                 callout_reset(&sc->sc_mii_callout, hz, smc91cxx_tick, sc);
  602         }
  603 
  604         /*
  605          * Attempt to start any pending transmission.
  606          */
  607         smc91cxx_start(ifp);
  608 
  609         splx(s);
  610 }
  611 
  612 /*
  613  * Start output on an interface.
  614  * Must be called at splnet or interrupt level.
  615  */
  616 void
  617 smc91cxx_start(ifp)
  618         struct ifnet *ifp;
  619 {
  620         struct smc91cxx_softc *sc = ifp->if_softc;
  621         bus_space_tag_t bst = sc->sc_bst;
  622         bus_space_handle_t bsh = sc->sc_bsh;
  623         u_int len;
  624         struct mbuf *m;
  625         u_int16_t length, npages;
  626         u_int8_t packetno;
  627         int timo, pad;
  628 
  629         if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
  630                 return;
  631 
  632  again:
  633         /*
  634          * Peek at the next packet.
  635          */
  636         IFQ_POLL(&ifp->if_snd, m);
  637         if (m == NULL)
  638                 return;
  639 
  640         /*
  641          * Compute the frame length and set pad to give an overall even
  642          * number of bytes.  Below, we assume that the packet length
  643          * is even.
  644          */
  645         for (len = 0; m != NULL; m = m->m_next)
  646                 len += m->m_len;
  647         pad = (len & 1);
  648 
  649         /*
  650          * We drop packets that are too large.  Perhaps we should
  651          * truncate them instead?
  652          */
  653         if ((len + pad) > (ETHER_MAX_LEN - ETHER_CRC_LEN)) {
  654                 printf("%s: large packet discarded\n", sc->sc_dev.dv_xname);
  655                 ifp->if_oerrors++;
  656                 IFQ_DEQUEUE(&ifp->if_snd, m);
  657                 m_freem(m);
  658                 goto readcheck;
  659         }
  660 
  661 #ifdef SMC91CXX_SW_PAD
  662         /*
  663          * Not using hardware padding; pad to ETHER_MIN_LEN.
  664          */
  665         if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN))
  666                 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
  667 #endif
  668 
  669         length = pad + len;
  670 
  671         /*
  672          * The MMU has a 256 byte page size.  The MMU expects us to
  673          * ask for "npages - 1".  We include space for the status word,
  674          * byte count, and control bytes in the allocation request.
  675          */
  676         npages = (length + 6) >> 8;
  677 
  678         /*
  679          * Now allocate the memory.
  680          */
  681         SMC_SELECT_BANK(sc, 2);
  682         bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ALLOC | npages);
  683 
  684         timo = MEMORY_WAIT_TIME;
  685         do {
  686                 if (bus_space_read_1(bst, bsh, INTR_STAT_REG_B) & IM_ALLOC_INT)
  687                         break;
  688                 delay(1);
  689         } while (--timo);
  690 
  691         packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B);
  692 
  693         if (packetno & ARR_FAILED || timo == 0) {
  694                 /*
  695                  * No transmit memory is available.  Record the number
  696                  * of requestd pages and enable the allocation completion
  697                  * interrupt.  Set up the watchdog timer in case we miss
  698                  * the interrupt.  Mark the interface as active so that
  699                  * no one else attempts to transmit while we're allocating
  700                  * memory.
  701                  */
  702                 bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
  703                     bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | IM_ALLOC_INT);
  704 
  705                 ifp->if_timer = 5;
  706                 ifp->if_flags |= IFF_OACTIVE;
  707 
  708                 return;
  709         }
  710 
  711         /*
  712          * We have a packet number - set the data window.
  713          */
  714         bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno);
  715 
  716         /*
  717          * Point to the beginning of the packet.
  718          */
  719         bus_space_write_2(bst, bsh, POINTER_REG_W, PTR_AUTOINC /* | 0x0000 */);
  720 
  721         /*
  722          * Send the packet length (+6 for stats, length, and control bytes)
  723          * and the status word (set to zeros).
  724          */
  725         bus_space_write_2(bst, bsh, DATA_REG_W, 0);
  726         bus_space_write_2(bst, bsh, DATA_REG_W, (length + 6) & 0x7ff);
  727 
  728         /*
  729          * Get the packet from the kernel.  This will include the Ethernet
  730          * frame header, MAC address, etc.
  731          */
  732         IFQ_DEQUEUE(&ifp->if_snd, m);
  733 
  734         /*
  735          * Push the packet out to the card.
  736          */
  737         smc91cxx_copy_tx_frame(sc, m);
  738 
  739 #ifdef SMC91CXX_SW_PAD
  740         /*
  741          * Push out padding.
  742          */
  743         while (pad > 1) {
  744                 bus_space_write_2(bst, bsh, DATA_REG_W, 0);
  745                 pad -= 2;
  746         }
  747         if (pad)
  748                 bus_space_write_1(bst, bsh, DATA_REG_B, 0);
  749 #endif
  750 
  751         /*
  752          * Push out control byte and unused packet byte.  The control byte
  753          * is 0, meaning the packet is even lengthed and no special
  754          * CRC handling is necessary.
  755          */
  756         bus_space_write_2(bst, bsh, DATA_REG_W, 0);
  757 
  758         /*
  759          * Enable transmit interrupts and let the chip go.  Set a watchdog
  760          * in case we miss the interrupt.
  761          */
  762         bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
  763             bus_space_read_1(bst, bsh, INTR_MASK_REG_B) |
  764             IM_TX_INT | IM_TX_EMPTY_INT);
  765 
  766         bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ENQUEUE);
  767 
  768         ifp->if_timer = 5;
  769 
  770 #if NBPFILTER > 0
  771         /* Hand off a copy to the bpf. */
  772         if (ifp->if_bpf)
  773                 bpf_mtap(ifp->if_bpf, m);
  774 #endif
  775 
  776         ifp->if_opackets++;
  777         m_freem(m);
  778 
  779  readcheck:
  780         /*
  781          * Check for incoming pcakets.  We don't want to overflow the small
  782          * RX FIFO.  If nothing has arrived, attempt to queue another
  783          * transmit packet.
  784          */
  785         if (bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & FIFO_REMPTY)
  786                 goto again;
  787 }
  788 
  789 /*
  790  * Squirt a (possibly misaligned) mbuf to the device
  791  */
  792 void
  793 smc91cxx_copy_tx_frame(sc, m0)
  794         struct smc91cxx_softc *sc;
  795         struct mbuf *m0;
  796 {
  797         bus_space_tag_t bst = sc->sc_bst;
  798         bus_space_handle_t bsh = sc->sc_bsh;
  799         struct mbuf *m;
  800         int len, leftover;
  801         u_int16_t dbuf;
  802         u_int8_t *p;
  803 #ifdef DIAGNOSTIC
  804         u_int8_t *lim;
  805 #endif
  806 
  807         /* start out with no leftover data */
  808         leftover = 0;
  809         dbuf = 0;
  810 
  811         /* Process the chain of mbufs */
  812         for (m = m0; m != NULL; m = m->m_next) {
  813                 /*
  814                  * Process all of the data in a single mbuf.
  815                  */
  816                 p = mtod(m, u_int8_t *);
  817                 len = m->m_len;
  818 #ifdef DIAGNOSTIC
  819                 lim = p + len;
  820 #endif
  821 
  822                 while (len > 0) {
  823                         if (leftover) {
  824                                 /*
  825                                  * Data left over (from mbuf or realignment).
  826                                  * Buffer the next byte, and write it and
  827                                  * the leftover data out.
  828                                  */
  829                                 dbuf |= *p++ << 8;
  830                                 len--;
  831                                 bus_space_write_2(bst, bsh, DATA_REG_W, dbuf);
  832                                 leftover = 0;
  833                         } else if ((long) p & 1) {
  834                                 /*
  835                                  * Misaligned data.  Buffer the next byte.
  836                                  */
  837                                 dbuf = *p++;
  838                                 len--;
  839                                 leftover = 1;
  840                         } else {
  841                                 /*
  842                                  * Aligned data.  This is the case we like.
  843                                  *
  844                                  * Write-region out as much as we can, then
  845                                  * buffer the remaining byte (if any).
  846                                  */
  847                                 leftover = len & 1;
  848                                 len &= ~1;
  849                                 bus_space_write_multi_stream_2(bst, bsh,
  850                                     DATA_REG_W, (u_int16_t *)p, len >> 1);
  851                                 p += len;
  852 
  853                                 if (leftover)
  854                                         dbuf = *p++;
  855                                 len = 0;
  856                         }
  857                 }
  858                 if (len < 0)
  859                         panic("smc91cxx_copy_tx_frame: negative len");
  860 #ifdef DIAGNOSTIC
  861                 if (p != lim)
  862                         panic("smc91cxx_copy_tx_frame: p != lim");
  863 #endif
  864         }
  865         if (leftover)
  866                 bus_space_write_1(bst, bsh, DATA_REG_B, dbuf);
  867 }
  868 
  869 /*
  870  * Interrupt service routine.
  871  */
  872 int
  873 smc91cxx_intr(arg)
  874         void *arg;
  875 {
  876         struct smc91cxx_softc *sc = arg;
  877         struct ifnet *ifp = &sc->sc_ec.ec_if;
  878         bus_space_tag_t bst = sc->sc_bst;
  879         bus_space_handle_t bsh = sc->sc_bsh;
  880         u_int8_t mask, interrupts, status;
  881         u_int16_t packetno, tx_status, card_stats;
  882 
  883         if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 ||
  884             !device_is_active(&sc->sc_dev))
  885                 return (0);
  886 
  887         SMC_SELECT_BANK(sc, 2);
  888 
  889         /*
  890          * Obtain the current interrupt mask.
  891          */
  892         mask = bus_space_read_1(bst, bsh, INTR_MASK_REG_B);
  893 
  894         /*
  895          * Get the set of interrupt which occurred and eliminate any
  896          * which are not enabled.
  897          */
  898         interrupts = bus_space_read_1(bst, bsh, INTR_STAT_REG_B);
  899         status = interrupts & mask;
  900 
  901         /* Ours? */
  902         if (status == 0)
  903                 return (0);
  904 
  905         /*
  906          * It's ours; disable all interrupts while we process them.
  907          */
  908         bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
  909 
  910         /*
  911          * Receive overrun interrupts.
  912          */
  913         if (status & IM_RX_OVRN_INT) {
  914                 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_RX_OVRN_INT);
  915                 ifp->if_ierrors++;
  916         }
  917 
  918         /*
  919          * Receive interrupts.
  920          */
  921         if (status & IM_RCV_INT) {
  922 #if 1 /* DIAGNOSTIC */
  923                 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W);
  924                 if (packetno & FIFO_REMPTY) {
  925                         printf("%s: receive interrupt on empty fifo\n",
  926                             sc->sc_dev.dv_xname);
  927                         goto out;
  928                 } else
  929 #endif
  930                 smc91cxx_read(sc);
  931         }
  932 
  933         /*
  934          * Memory allocation interrupts.
  935          */
  936         if (status & IM_ALLOC_INT) {
  937                 /* Disable this interrupt. */
  938                 mask &= ~IM_ALLOC_INT;
  939 
  940                 /*
  941                  * Release the just-allocated memory.  We will reallocate
  942                  * it through the normal start logic.
  943                  */
  944                 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
  945                         /* XXX bound this loop! */ ;
  946                 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT);
  947 
  948                 ifp->if_flags &= ~IFF_OACTIVE;
  949                 ifp->if_timer = 0;
  950         }
  951 
  952         /*
  953          * Transmit complete interrupt.  Handle transmission error messages.
  954          * This will only be called on error condition because of AUTO RELEASE
  955          * mode.
  956          */
  957         if (status & IM_TX_INT) {
  958                 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_INT);
  959 
  960                 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) &
  961                     FIFO_TX_MASK;
  962 
  963                 /*
  964                  * Select this as the packet to read from.
  965                  */
  966                 bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno);
  967 
  968                 /*
  969                  * Position the pointer to the beginning of the packet.
  970                  */
  971                 bus_space_write_2(bst, bsh, POINTER_REG_W,
  972                     PTR_AUTOINC | PTR_READ /* | 0x0000 */);
  973 
  974                 /*
  975                  * Fetch the TX status word.  This will be a copy of
  976                  * the EPH_STATUS_REG_W at the time of the transmission
  977                  * failure.
  978                  */
  979                 tx_status = bus_space_read_2(bst, bsh, DATA_REG_W);
  980 
  981                 if (tx_status & EPHSR_TX_SUC)
  982                         printf("%s: successful packet caused TX interrupt?!\n",
  983                             sc->sc_dev.dv_xname);
  984                 else
  985                         ifp->if_oerrors++;
  986 
  987                 if (tx_status & EPHSR_LATCOL)
  988                         ifp->if_collisions++;
  989 
  990                 /*
  991                  * Some of these errors disable the transmitter; reenable it.
  992                  */
  993                 SMC_SELECT_BANK(sc, 0);
  994 #ifdef SMC91CXX_SW_PAD
  995                 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, TCR_ENABLE);
  996 #else
  997                 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W,
  998                     TCR_ENABLE | TCR_PAD_ENABLE);
  999 #endif
 1000 
 1001                 /*
 1002                  * Kill the failed packet and wait for the MMU to unbusy.
 1003                  */
 1004                 SMC_SELECT_BANK(sc, 2);
 1005                 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
 1006                         /* XXX bound this loop! */ ;
 1007                 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT);
 1008 
 1009                 ifp->if_timer = 0;
 1010         }
 1011 
 1012         /*
 1013          * Transmit underrun interrupts.  We use this opportunity to
 1014          * update transmit statistics from the card.
 1015          */
 1016         if (status & IM_TX_EMPTY_INT) {
 1017                 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_EMPTY_INT);
 1018 
 1019                 /* Disable this interrupt. */
 1020                 mask &= ~IM_TX_EMPTY_INT;
 1021 
 1022                 SMC_SELECT_BANK(sc, 0);
 1023                 card_stats = bus_space_read_2(bst, bsh, COUNTER_REG_W);
 1024 
 1025                 /* Single collisions. */
 1026                 ifp->if_collisions += card_stats & ECR_COLN_MASK;
 1027 
 1028                 /* Multiple collisions. */
 1029                 ifp->if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4;
 1030 
 1031                 SMC_SELECT_BANK(sc, 2);
 1032 
 1033                 ifp->if_timer = 0;
 1034         }
 1035 
 1036         if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy &&
 1037             (status & IM_MD_INT)) {
 1038                 /*
 1039                  * Internal PHY status change
 1040                  */
 1041                 mii_tick(&sc->sc_mii);
 1042         }
 1043 
 1044         /*
 1045          * Other errors.  Reset the interface.
 1046          */
 1047         if (status & IM_EPH_INT) {
 1048                 smc91cxx_stop(sc);
 1049                 smc91cxx_init(sc);
 1050         }
 1051 
 1052         /*
 1053          * Attempt to queue more packets for transmission.
 1054          */
 1055         smc91cxx_start(ifp);
 1056 
 1057 out:
 1058         /*
 1059          * Reenable the interrupts we wish to receive now that processing
 1060          * is complete.
 1061          */
 1062         mask |= bus_space_read_1(bst, bsh, INTR_MASK_REG_B);
 1063         bus_space_write_1(bst, bsh, INTR_MASK_REG_B, mask);
 1064 
 1065 #if NRND > 0
 1066         if (status)
 1067                 rnd_add_uint32(&sc->rnd_source, status);
 1068 #endif
 1069 
 1070         return (1);
 1071 }
 1072 
 1073 /*
 1074  * Read a packet from the card and pass it up to the kernel.
 1075  * NOTE!  WE EXPECT TO BE IN REGISTER WINDOW 2!
 1076  */
 1077 void
 1078 smc91cxx_read(sc)
 1079         struct smc91cxx_softc *sc;
 1080 {
 1081         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1082         bus_space_tag_t bst = sc->sc_bst;
 1083         bus_space_handle_t bsh = sc->sc_bsh;
 1084         struct ether_header *eh;
 1085         struct mbuf *m;
 1086         u_int16_t status, packetno, packetlen;
 1087         u_int8_t *data;
 1088         u_int32_t dr;
 1089 
 1090  again:
 1091         /*
 1092          * Set data pointer to the beginning of the packet.  Since
 1093          * PTR_RCV is set, the packet number will be found automatically
 1094          * in FIFO_PORTS_REG_W, FIFO_RX_MASK.
 1095          */
 1096         bus_space_write_2(bst, bsh, POINTER_REG_W,
 1097             PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */);
 1098 
 1099         /*
 1100          * First two words are status and packet length.
 1101          */
 1102         if ((sc->sc_flags & SMC_FLAGS_32BIT_READ) == 0) {
 1103                 status = bus_space_read_2(bst, bsh, DATA_REG_W);
 1104                 packetlen = bus_space_read_2(bst, bsh, DATA_REG_W);
 1105         } else {
 1106                 dr = bus_space_read_4(bst, bsh, DATA_REG_W);
 1107 #if BYTE_ORDER == LITTLE_ENDIAN
 1108                 status = (u_int16_t)dr;
 1109                 packetlen = (u_int16_t)(dr >> 16);
 1110 #else
 1111                 packetlen = (u_int16_t)dr;
 1112                 status = (u_int16_t)(dr >> 16);
 1113 #endif
 1114         }
 1115 
 1116         packetlen &= RLEN_MASK;
 1117 
 1118         /*
 1119          * The packet length includes 3 extra words: status, length,
 1120          * and an extra word that includes the control byte.
 1121          */
 1122         packetlen -= 6;
 1123 
 1124         /*
 1125          * Account for receive errors and discard.
 1126          */
 1127         if (status & RS_ERRORS) {
 1128                 ifp->if_ierrors++;
 1129                 goto out;
 1130         }
 1131 
 1132         /*
 1133          * Adjust for odd-length packet.
 1134          */
 1135         if (status & RS_ODDFRAME)
 1136                 packetlen++;
 1137 
 1138         /*
 1139          * Allocate a header mbuf.
 1140          */
 1141         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1142         if (m == NULL)
 1143                 goto out;
 1144         m->m_pkthdr.rcvif = ifp;
 1145         m->m_pkthdr.len = packetlen;
 1146 
 1147         /*
 1148          * Always put the packet in a cluster.
 1149          * XXX should chain small mbufs if less than threshold.
 1150          */
 1151         MCLGET(m, M_DONTWAIT);
 1152         if ((m->m_flags & M_EXT) == 0) {
 1153                 m_freem(m);
 1154                 ifp->if_ierrors++;
 1155                 printf("%s: can't allocate cluster for incoming packet\n",
 1156                     sc->sc_dev.dv_xname);
 1157                 goto out;
 1158         }
 1159 
 1160         /*
 1161          * Pull the packet off the interface.  Make sure the payload
 1162          * is aligned.
 1163          */
 1164         if ((sc->sc_flags & SMC_FLAGS_32BIT_READ) == 0) {
 1165                 m->m_data = (caddr_t) ALIGN(mtod(m, caddr_t) +
 1166                     sizeof(struct ether_header)) - sizeof(struct ether_header);
 1167 
 1168                 eh = mtod(m, struct ether_header *);
 1169                 data = mtod(m, u_int8_t *);
 1170                 if (packetlen > 1)
 1171                         bus_space_read_multi_stream_2(bst, bsh, DATA_REG_W,
 1172                             (u_int16_t *)data, packetlen >> 1);
 1173                 if (packetlen & 1) {
 1174                         data += packetlen & ~1;
 1175                         *data = bus_space_read_1(bst, bsh, DATA_REG_B);
 1176                 }
 1177         } else {
 1178                 u_int8_t *dp;
 1179 
 1180                 m->m_data = (caddr_t) ALIGN(mtod(m, caddr_t));
 1181                 eh = mtod(m, struct ether_header *);
 1182                 dp = data = mtod(m, u_int8_t *);
 1183                 if (packetlen > 3)
 1184                         bus_space_read_multi_stream_4(bst, bsh, DATA_REG_W,
 1185                             (u_int32_t *)data, packetlen >> 2);
 1186                 if (packetlen & 3) {
 1187                         data += packetlen & ~3;
 1188                         *((u_int32_t *)data) =
 1189                             bus_space_read_stream_4(bst, bsh, DATA_REG_W);
 1190                 }
 1191         }
 1192 
 1193         ifp->if_ipackets++;
 1194 
 1195         /*
 1196          * Make sure to behave as IFF_SIMPLEX in all cases.
 1197          * This is to cope with SMC91C92 (Megahertz XJ10BT), which
 1198          * loops back packets to itself on promiscuous mode.
 1199          * (should be ensured by chipset configuration)
 1200          */
 1201         if ((ifp->if_flags & IFF_PROMISC) != 0) {
 1202                 /*
 1203                  * Drop packet looped back from myself.
 1204                  */
 1205                 if (ether_cmp(eh->ether_shost, LLADDR(ifp->if_sadl)) == 0) {
 1206                         m_freem(m);
 1207                         goto out;
 1208                 }
 1209         }
 1210 
 1211         m->m_pkthdr.len = m->m_len = packetlen;
 1212 
 1213 #if NBPFILTER > 0
 1214         /*
 1215          * Hand the packet off to bpf listeners.
 1216          */
 1217         if (ifp->if_bpf)
 1218                 bpf_mtap(ifp->if_bpf, m);
 1219 #endif
 1220 
 1221         (*ifp->if_input)(ifp, m);
 1222 
 1223  out:
 1224         /*
 1225          * Tell the card to free the memory occupied by this packet.
 1226          */
 1227         while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
 1228                 /* XXX bound this loop! */ ;
 1229         bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RELEASE);
 1230 
 1231         /*
 1232          * Check for another packet.
 1233          */
 1234         packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W);
 1235         if (packetno & FIFO_REMPTY)
 1236                 return;
 1237         goto again;
 1238 }
 1239 
 1240 /*
 1241  * Process an ioctl request.
 1242  */
 1243 int
 1244 smc91cxx_ioctl(ifp, cmd, data)
 1245         struct ifnet *ifp;
 1246         u_long cmd;
 1247         caddr_t data;
 1248 {
 1249         struct smc91cxx_softc *sc = ifp->if_softc;
 1250         struct ifaddr *ifa = (struct ifaddr *)data;
 1251         struct ifreq *ifr = (struct ifreq *)data;
 1252         int s, error = 0;
 1253 
 1254         s = splnet();
 1255 
 1256         switch (cmd) {
 1257         case SIOCSIFADDR:
 1258                 if ((error = smc91cxx_enable(sc)) != 0)
 1259                         break;
 1260                 ifp->if_flags |= IFF_UP;
 1261                 switch (ifa->ifa_addr->sa_family) {
 1262 #ifdef INET
 1263                 case AF_INET:
 1264                 smc91cxx_init(sc);
 1265                 arp_ifinit(ifp, ifa);
 1266                 break;
 1267 #endif
 1268                 default:
 1269                         smc91cxx_init(sc);
 1270                         break;
 1271                 }
 1272                 break;
 1273 
 1274 
 1275         case SIOCSIFFLAGS:
 1276                 if ((ifp->if_flags & IFF_UP) == 0 &&
 1277                     (ifp->if_flags & IFF_RUNNING) != 0) {
 1278                         /*
 1279                          * If interface is marked down and it is running,
 1280                          * stop it.
 1281                          */
 1282                         smc91cxx_stop(sc);
 1283                         ifp->if_flags &= ~IFF_RUNNING;
 1284                         smc91cxx_disable(sc);
 1285                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
 1286                            (ifp->if_flags & IFF_RUNNING) == 0) {
 1287                         /*
 1288                          * If interface is marked up and it is stopped,
 1289                          * start it.
 1290                          */
 1291                         if ((error = smc91cxx_enable(sc)) != 0)
 1292                                 break;
 1293                         smc91cxx_init(sc);
 1294                 } else if ((ifp->if_flags & IFF_UP) != 0) {
 1295                         /*
 1296                          * Reset the interface to pick up changes in any
 1297                          * other flags that affect hardware registers.
 1298                          */
 1299                         smc91cxx_reset(sc);
 1300                 }
 1301                 break;
 1302 
 1303         case SIOCADDMULTI:
 1304         case SIOCDELMULTI:
 1305                 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) {
 1306                         error = EIO;
 1307                         break;
 1308                 }
 1309 
 1310                 error = (cmd == SIOCADDMULTI) ?
 1311                     ether_addmulti(ifr, &sc->sc_ec) :
 1312                     ether_delmulti(ifr, &sc->sc_ec);
 1313                 if (error == ENETRESET) {
 1314                         /*
 1315                          * Multicast list has changed; set the hardware
 1316                          * filter accordingly.
 1317                          */
 1318                         if (ifp->if_flags & IFF_RUNNING)
 1319                                 smc91cxx_reset(sc);
 1320                         error = 0;
 1321                 }
 1322                 break;
 1323 
 1324         case SIOCGIFMEDIA:
 1325         case SIOCSIFMEDIA:
 1326                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
 1327                 break;
 1328 
 1329         default:
 1330                 error = EINVAL;
 1331                 break;
 1332         }
 1333 
 1334         splx(s);
 1335         return (error);
 1336 }
 1337 
 1338 /*
 1339  * Reset the interface.
 1340  */
 1341 void
 1342 smc91cxx_reset(sc)
 1343         struct smc91cxx_softc *sc;
 1344 {
 1345         int s;
 1346 
 1347         s = splnet();
 1348         smc91cxx_stop(sc);
 1349         smc91cxx_init(sc);
 1350         splx(s);
 1351 }
 1352 
 1353 /*
 1354  * Watchdog timer.
 1355  */
 1356 void
 1357 smc91cxx_watchdog(ifp)
 1358         struct ifnet *ifp;
 1359 {
 1360         struct smc91cxx_softc *sc = ifp->if_softc;
 1361 
 1362         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
 1363         ifp->if_oerrors++;
 1364         smc91cxx_reset(sc);
 1365 }
 1366 
 1367 /*
 1368  * Stop output on the interface.
 1369  */
 1370 void
 1371 smc91cxx_stop(sc)
 1372         struct smc91cxx_softc *sc;
 1373 {
 1374         bus_space_tag_t bst = sc->sc_bst;
 1375         bus_space_handle_t bsh = sc->sc_bsh;
 1376 
 1377         /*
 1378          * Clear interrupt mask; disable all interrupts.
 1379          */
 1380         SMC_SELECT_BANK(sc, 2);
 1381         bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
 1382 
 1383         /*
 1384          * Disable transmitter and receiver.
 1385          */
 1386         SMC_SELECT_BANK(sc, 0);
 1387         bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0);
 1388         bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0);
 1389 
 1390         /*
 1391          * Cancel watchdog timer.
 1392          */
 1393         sc->sc_ec.ec_if.if_timer = 0;
 1394 }
 1395 
 1396 /*
 1397  * Enable power on the interface.
 1398  */
 1399 int
 1400 smc91cxx_enable(sc)
 1401         struct smc91cxx_softc *sc;
 1402 {
 1403 
 1404         if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 && sc->sc_enable != NULL) {
 1405                 if ((*sc->sc_enable)(sc) != 0) {
 1406                         printf("%s: device enable failed\n",
 1407                             sc->sc_dev.dv_xname);
 1408                         return (EIO);
 1409                 }
 1410         }
 1411 
 1412         sc->sc_flags |= SMC_FLAGS_ENABLED;
 1413         return (0);
 1414 }
 1415 
 1416 /*
 1417  * Disable power on the interface.
 1418  */
 1419 void
 1420 smc91cxx_disable(sc)
 1421         struct smc91cxx_softc *sc;
 1422 {
 1423 
 1424         if ((sc->sc_flags & SMC_FLAGS_ENABLED) != 0 && sc->sc_disable != NULL) {
 1425                 (*sc->sc_disable)(sc);
 1426                 sc->sc_flags &= ~SMC_FLAGS_ENABLED;
 1427         }
 1428 }
 1429 
 1430 int
 1431 smc91cxx_activate(self, act)
 1432         struct device *self;
 1433         enum devact act;
 1434 {
 1435         struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self;
 1436         int rv = 0, s;
 1437 
 1438         s = splnet();
 1439         switch (act) {
 1440         case DVACT_ACTIVATE:
 1441                 rv = EOPNOTSUPP;
 1442                 break;
 1443 
 1444         case DVACT_DEACTIVATE:
 1445                 if_deactivate(&sc->sc_ec.ec_if);
 1446                 break;
 1447         }
 1448         splx(s);
 1449         return (rv);
 1450 }
 1451 
 1452 int
 1453 smc91cxx_detach(struct device *self, int flags)
 1454 {
 1455         struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self;
 1456         struct ifnet *ifp = &sc->sc_ec.ec_if;
 1457 
 1458         /* Succeed now if there's no work to do. */
 1459         if ((sc->sc_flags & SMC_FLAGS_ATTACHED) == 0)
 1460                 return (0);
 1461 
 1462 
 1463         /* smc91cxx_disable() checks SMC_FLAGS_ENABLED */
 1464         smc91cxx_disable(sc);
 1465 
 1466         /* smc91cxx_attach() never fails */
 1467 
 1468         /* Delete all media. */
 1469         ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
 1470 
 1471 #if NRND > 0
 1472         rnd_detach_source(&sc->rnd_source);
 1473 #endif
 1474         ether_ifdetach(ifp);
 1475         if_detach(ifp);
 1476 
 1477         return (0);
 1478 }
 1479 
 1480 u_int32_t
 1481 smc91cxx_mii_bitbang_read(self)
 1482         struct device *self;
 1483 {
 1484         struct smc91cxx_softc *sc = (void *) self;
 1485 
 1486         /* We're already in bank 3. */
 1487         return (bus_space_read_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W));
 1488 }
 1489 
 1490 void
 1491 smc91cxx_mii_bitbang_write(self, val)
 1492         struct device *self;
 1493         u_int32_t val;
 1494 {
 1495         struct smc91cxx_softc *sc = (void *) self;
 1496 
 1497         /* We're already in bank 3. */
 1498         bus_space_write_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W, val);
 1499 }
 1500 
 1501 int
 1502 smc91cxx_mii_readreg(self, phy, reg)
 1503         struct device *self;
 1504         int phy, reg;
 1505 {
 1506         struct smc91cxx_softc *sc = (void *) self;
 1507         int val;
 1508 
 1509         SMC_SELECT_BANK(sc, 3);
 1510 
 1511         val = mii_bitbang_readreg(self, &smc91cxx_mii_bitbang_ops, phy, reg);
 1512 
 1513         SMC_SELECT_BANK(sc, 2);
 1514 
 1515         return (val);
 1516 }
 1517 
 1518 void
 1519 smc91cxx_mii_writereg(self, phy, reg, val)
 1520         struct device *self;
 1521         int phy, reg, val;
 1522 {
 1523         struct smc91cxx_softc *sc = (void *) self;
 1524 
 1525         SMC_SELECT_BANK(sc, 3);
 1526 
 1527         mii_bitbang_writereg(self, &smc91cxx_mii_bitbang_ops, phy, reg, val);
 1528 
 1529         SMC_SELECT_BANK(sc, 2);
 1530 }
 1531 
 1532 void
 1533 smc91cxx_statchg(self)
 1534         struct device *self;
 1535 {
 1536         struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self;
 1537         bus_space_tag_t bst = sc->sc_bst;
 1538         bus_space_handle_t bsh = sc->sc_bsh;
 1539         int mctl;
 1540 
 1541         SMC_SELECT_BANK(sc, 0);
 1542         mctl = bus_space_read_2(bst, bsh, TXMIT_CONTROL_REG_W);
 1543         if (sc->sc_mii.mii_media_active & IFM_FDX)
 1544                 mctl |= TCR_SWFDUP;
 1545         else
 1546                 mctl &= ~TCR_SWFDUP;
 1547         bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, mctl);
 1548         SMC_SELECT_BANK(sc, 2); /* back to operating window */
 1549 }
 1550 
 1551 /*
 1552  * One second timer, used to tick the MII.
 1553  */
 1554 void
 1555 smc91cxx_tick(arg)
 1556         void *arg;
 1557 {
 1558         struct smc91cxx_softc *sc = arg;
 1559         int s;
 1560 
 1561 #ifdef DIAGNOSTIC
 1562         if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0)
 1563                 panic("smc91cxx_tick");
 1564 #endif
 1565 
 1566         if (!device_is_active(&sc->sc_dev))
 1567                 return;
 1568 
 1569         s = splnet();
 1570         mii_tick(&sc->sc_mii);
 1571         splx(s);
 1572 
 1573         callout_reset(&sc->sc_mii_callout, hz, smc91cxx_tick, sc);
 1574 }
 1575 

Cache object: 41fcdb3e118a641d37becd3c36bfd52b


[ 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.