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

Cache object: f1d2239141b2aec658915a1e53df4e29


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