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

Cache object: df2cc8b0546f395e99ce5889f5b1f0d9


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