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/smc/if_smc.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 /*-
    2  * Copyright (c) 2008 Benno Rice.  All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23  */
   24 
   25 #include <sys/cdefs.h>
   26 __FBSDID("$FreeBSD: releng/8.4/sys/dev/smc/if_smc.c 227278 2011-11-06 21:09:23Z marius $");
   27 
   28 /*
   29  * Driver for SMSC LAN91C111, may work for older variants.
   30  */
   31 
   32 #ifdef HAVE_KERNEL_OPTION_HEADERS
   33 #include "opt_device_polling.h"
   34 #endif
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/errno.h>
   39 #include <sys/kernel.h>
   40 #include <sys/sockio.h>
   41 #include <sys/malloc.h>
   42 #include <sys/mbuf.h>
   43 #include <sys/queue.h>
   44 #include <sys/socket.h>
   45 #include <sys/syslog.h>
   46 #include <sys/taskqueue.h>
   47 
   48 #include <sys/module.h>
   49 #include <sys/bus.h>
   50 
   51 #include <machine/bus.h>
   52 #include <machine/resource.h>
   53 #include <sys/rman.h>
   54 
   55 #include <net/ethernet.h>
   56 #include <net/if.h>
   57 #include <net/if_arp.h>
   58 #include <net/if_dl.h>
   59 #include <net/if_types.h>
   60 #include <net/if_mib.h>
   61 #include <net/if_media.h>
   62 
   63 #ifdef INET
   64 #include <netinet/in.h>
   65 #include <netinet/in_systm.h>
   66 #include <netinet/in_var.h>
   67 #include <netinet/ip.h>
   68 #endif
   69 
   70 #include <net/bpf.h>
   71 #include <net/bpfdesc.h>
   72 
   73 #include <dev/smc/if_smcreg.h>
   74 #include <dev/smc/if_smcvar.h>
   75 
   76 #include <dev/mii/mii.h>
   77 #include <dev/mii/mii_bitbang.h>
   78 #include <dev/mii/miivar.h>
   79 
   80 #define SMC_LOCK(sc)            mtx_lock(&(sc)->smc_mtx)
   81 #define SMC_UNLOCK(sc)          mtx_unlock(&(sc)->smc_mtx)
   82 #define SMC_ASSERT_LOCKED(sc)   mtx_assert(&(sc)->smc_mtx, MA_OWNED)
   83 
   84 #define SMC_INTR_PRIORITY       0
   85 #define SMC_RX_PRIORITY         5
   86 #define SMC_TX_PRIORITY         10
   87 
   88 devclass_t      smc_devclass;
   89 
   90 static const char *smc_chip_ids[16] = {
   91         NULL, NULL, NULL,
   92         /* 3 */ "SMSC LAN91C90 or LAN91C92",
   93         /* 4 */ "SMSC LAN91C94",
   94         /* 5 */ "SMSC LAN91C95",
   95         /* 6 */ "SMSC LAN91C96",
   96         /* 7 */ "SMSC LAN91C100",
   97         /* 8 */ "SMSC LAN91C100FD",
   98         /* 9 */ "SMSC LAN91C110FD or LAN91C111FD",
   99         NULL, NULL, NULL,
  100         NULL, NULL, NULL
  101 };
  102 
  103 static void     smc_init(void *);
  104 static void     smc_start(struct ifnet *);
  105 static void     smc_stop(struct smc_softc *);
  106 static int      smc_ioctl(struct ifnet *, u_long, caddr_t);
  107 
  108 static void     smc_init_locked(struct smc_softc *);
  109 static void     smc_start_locked(struct ifnet *);
  110 static void     smc_reset(struct smc_softc *);
  111 static int      smc_mii_ifmedia_upd(struct ifnet *);
  112 static void     smc_mii_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  113 static void     smc_mii_tick(void *);
  114 static void     smc_mii_mediachg(struct smc_softc *);
  115 static int      smc_mii_mediaioctl(struct smc_softc *, struct ifreq *, u_long);
  116 
  117 static void     smc_task_intr(void *, int);
  118 static void     smc_task_rx(void *, int);
  119 static void     smc_task_tx(void *, int);
  120 
  121 static driver_filter_t  smc_intr;
  122 static timeout_t        smc_watchdog;
  123 #ifdef DEVICE_POLLING
  124 static poll_handler_t   smc_poll;
  125 #endif
  126 
  127 /*
  128  * MII bit-bang glue
  129  */
  130 static uint32_t smc_mii_bitbang_read(device_t);
  131 static void smc_mii_bitbang_write(device_t, uint32_t);
  132 
  133 static const struct mii_bitbang_ops smc_mii_bitbang_ops = {
  134         smc_mii_bitbang_read,
  135         smc_mii_bitbang_write,
  136         {
  137                 MGMT_MDO,       /* MII_BIT_MDO */
  138                 MGMT_MDI,       /* MII_BIT_MDI */
  139                 MGMT_MCLK,      /* MII_BIT_MDC */
  140                 MGMT_MDOE,      /* MII_BIT_DIR_HOST_PHY */
  141                 0,              /* MII_BIT_DIR_PHY_HOST */
  142         }
  143 };
  144 
  145 static __inline void
  146 smc_select_bank(struct smc_softc *sc, uint16_t bank)
  147 {
  148 
  149         bus_barrier(sc->smc_reg, BSR, 2,
  150             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  151         bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK);
  152         bus_barrier(sc->smc_reg, BSR, 2,
  153             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  154 }
  155 
  156 /* Never call this when not in bank 2. */
  157 static __inline void
  158 smc_mmu_wait(struct smc_softc *sc)
  159 {
  160 
  161         KASSERT((bus_read_2(sc->smc_reg, BSR) &
  162             BSR_BANK_MASK) == 2, ("%s: smc_mmu_wait called when not in bank 2",
  163             device_get_nameunit(sc->smc_dev)));
  164         while (bus_read_2(sc->smc_reg, MMUCR) & MMUCR_BUSY)
  165                 ;
  166 }
  167 
  168 static __inline uint8_t
  169 smc_read_1(struct smc_softc *sc, bus_size_t offset)
  170 {
  171 
  172         return (bus_read_1(sc->smc_reg, offset));
  173 }
  174 
  175 static __inline void
  176 smc_write_1(struct smc_softc *sc, bus_size_t offset, uint8_t val)
  177 {
  178 
  179         bus_write_1(sc->smc_reg, offset, val);
  180 }
  181 
  182 static __inline uint16_t
  183 smc_read_2(struct smc_softc *sc, bus_size_t offset)
  184 {
  185 
  186         return (bus_read_2(sc->smc_reg, offset));
  187 }
  188 
  189 static __inline void
  190 smc_write_2(struct smc_softc *sc, bus_size_t offset, uint16_t val)
  191 {
  192 
  193         bus_write_2(sc->smc_reg, offset, val);
  194 }
  195 
  196 static __inline void
  197 smc_read_multi_2(struct smc_softc *sc, bus_size_t offset, uint16_t *datap,
  198     bus_size_t count)
  199 {
  200 
  201         bus_read_multi_2(sc->smc_reg, offset, datap, count);
  202 }
  203 
  204 static __inline void
  205 smc_write_multi_2(struct smc_softc *sc, bus_size_t offset, uint16_t *datap,
  206     bus_size_t count)
  207 {
  208 
  209         bus_write_multi_2(sc->smc_reg, offset, datap, count);
  210 }
  211 
  212 static __inline void
  213 smc_barrier(struct smc_softc *sc, bus_size_t offset, bus_size_t length,
  214     int flags)
  215 {
  216 
  217         bus_barrier(sc->smc_reg, offset, length, flags);
  218 }
  219 
  220 int
  221 smc_probe(device_t dev)
  222 {
  223         int                     rid, type, error;
  224         uint16_t                val;
  225         struct smc_softc        *sc;
  226         struct resource         *reg;
  227 
  228         sc = device_get_softc(dev);
  229         rid = 0;
  230         type = SYS_RES_IOPORT;
  231         error = 0;
  232 
  233         if (sc->smc_usemem)
  234                 type = SYS_RES_MEMORY;
  235 
  236         reg = bus_alloc_resource(dev, type, &rid, 0, ~0, 16, RF_ACTIVE);
  237         if (reg == NULL) {
  238                 if (bootverbose)
  239                         device_printf(dev,
  240                             "could not allocate I/O resource for probe\n");
  241                 return (ENXIO);
  242         }
  243 
  244         /* Check for the identification value in the BSR. */
  245         val = bus_read_2(reg, BSR);
  246         if ((val & BSR_IDENTIFY_MASK) != BSR_IDENTIFY) {
  247                 if (bootverbose)
  248                         device_printf(dev, "identification value not in BSR\n");
  249                 error = ENXIO;
  250                 goto done;
  251         }
  252 
  253         /*
  254          * Try switching banks and make sure we still get the identification
  255          * value.
  256          */
  257         bus_write_2(reg, BSR, 0);
  258         val = bus_read_2(reg, BSR);
  259         if ((val & BSR_IDENTIFY_MASK) != BSR_IDENTIFY) {
  260                 if (bootverbose)
  261                         device_printf(dev,
  262                             "identification value not in BSR after write\n");
  263                 error = ENXIO;
  264                 goto done;
  265         }
  266 
  267 #if 0
  268         /* Check the BAR. */
  269         bus_write_2(reg, BSR, 1);
  270         val = bus_read_2(reg, BAR);
  271         val = BAR_ADDRESS(val);
  272         if (rman_get_start(reg) != val) {
  273                 if (bootverbose)
  274                         device_printf(dev, "BAR address %x does not match "
  275                             "I/O resource address %lx\n", val,
  276                             rman_get_start(reg));
  277                 error = ENXIO;
  278                 goto done;
  279         }
  280 #endif
  281 
  282         /* Compare REV against known chip revisions. */
  283         bus_write_2(reg, BSR, 3);
  284         val = bus_read_2(reg, REV);
  285         val = (val & REV_CHIP_MASK) >> REV_CHIP_SHIFT;
  286         if (smc_chip_ids[val] == NULL) {
  287                 if (bootverbose)
  288                         device_printf(dev, "Unknown chip revision: %d\n", val);
  289                 error = ENXIO;
  290                 goto done;
  291         }
  292 
  293         device_set_desc(dev, smc_chip_ids[val]);
  294 
  295 done:
  296         bus_release_resource(dev, type, rid, reg);
  297         return (error);
  298 }
  299 
  300 int
  301 smc_attach(device_t dev)
  302 {
  303         int                     type, error;
  304         uint16_t                val;
  305         u_char                  eaddr[ETHER_ADDR_LEN];
  306         struct smc_softc        *sc;
  307         struct ifnet            *ifp;
  308 
  309         sc = device_get_softc(dev);
  310         error = 0;
  311 
  312         sc->smc_dev = dev;
  313 
  314         ifp = sc->smc_ifp = if_alloc(IFT_ETHER);
  315         if (ifp == NULL) {
  316                 error = ENOSPC;
  317                 goto done;
  318         }
  319 
  320         mtx_init(&sc->smc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
  321 
  322         /* Set up watchdog callout. */
  323         callout_init_mtx(&sc->smc_watchdog, &sc->smc_mtx, 0);
  324 
  325         type = SYS_RES_IOPORT;
  326         if (sc->smc_usemem)
  327                 type = SYS_RES_MEMORY;
  328 
  329         sc->smc_reg_rid = 0;
  330         sc->smc_reg = bus_alloc_resource(dev, type, &sc->smc_reg_rid, 0, ~0,
  331             16, RF_ACTIVE);
  332         if (sc->smc_reg == NULL) {
  333                 error = ENXIO;
  334                 goto done;
  335         }
  336 
  337         sc->smc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->smc_irq_rid, 0,
  338             ~0, 1, RF_ACTIVE | RF_SHAREABLE);
  339         if (sc->smc_irq == NULL) {
  340                 error = ENXIO;
  341                 goto done;
  342         }
  343 
  344         SMC_LOCK(sc);
  345         smc_reset(sc);
  346         SMC_UNLOCK(sc);
  347 
  348         smc_select_bank(sc, 3);
  349         val = smc_read_2(sc, REV);
  350         sc->smc_chip = (val & REV_CHIP_MASK) >> REV_CHIP_SHIFT;
  351         sc->smc_rev = (val * REV_REV_MASK) >> REV_REV_SHIFT;
  352         if (bootverbose)
  353                 device_printf(dev, "revision %x\n", sc->smc_rev);
  354 
  355         callout_init_mtx(&sc->smc_mii_tick_ch, &sc->smc_mtx,
  356             CALLOUT_RETURNUNLOCKED);
  357         if (sc->smc_chip >= REV_CHIP_91110FD) {
  358                 (void)mii_attach(dev, &sc->smc_miibus, ifp,
  359                     smc_mii_ifmedia_upd, smc_mii_ifmedia_sts, BMSR_DEFCAPMASK,
  360                     MII_PHY_ANY, MII_OFFSET_ANY, 0);
  361                 if (sc->smc_miibus != NULL) {
  362                         sc->smc_mii_tick = smc_mii_tick;
  363                         sc->smc_mii_mediachg = smc_mii_mediachg;
  364                         sc->smc_mii_mediaioctl = smc_mii_mediaioctl;
  365                 }
  366         }
  367 
  368         smc_select_bank(sc, 1);
  369         eaddr[0] = smc_read_1(sc, IAR0);
  370         eaddr[1] = smc_read_1(sc, IAR1);
  371         eaddr[2] = smc_read_1(sc, IAR2);
  372         eaddr[3] = smc_read_1(sc, IAR3);
  373         eaddr[4] = smc_read_1(sc, IAR4);
  374         eaddr[5] = smc_read_1(sc, IAR5);
  375 
  376         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  377         ifp->if_softc = sc;
  378         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  379         ifp->if_init = smc_init;
  380         ifp->if_ioctl = smc_ioctl;
  381         ifp->if_start = smc_start;
  382         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
  383         IFQ_SET_READY(&ifp->if_snd);
  384 
  385         ifp->if_capabilities = ifp->if_capenable = 0;
  386 
  387 #ifdef DEVICE_POLLING
  388         ifp->if_capabilities |= IFCAP_POLLING;
  389 #endif
  390 
  391         ether_ifattach(ifp, eaddr);
  392 
  393         /* Set up taskqueue */
  394         TASK_INIT(&sc->smc_intr, SMC_INTR_PRIORITY, smc_task_intr, ifp);
  395         TASK_INIT(&sc->smc_rx, SMC_RX_PRIORITY, smc_task_rx, ifp);
  396         TASK_INIT(&sc->smc_tx, SMC_TX_PRIORITY, smc_task_tx, ifp);
  397         sc->smc_tq = taskqueue_create_fast("smc_taskq", M_NOWAIT,
  398             taskqueue_thread_enqueue, &sc->smc_tq);
  399         taskqueue_start_threads(&sc->smc_tq, 1, PI_NET, "%s taskq",
  400             device_get_nameunit(sc->smc_dev));
  401 
  402         /* Mask all interrupts. */
  403         sc->smc_mask = 0;
  404         smc_write_1(sc, MSK, 0);
  405 
  406         /* Wire up interrupt */
  407         error = bus_setup_intr(dev, sc->smc_irq,
  408             INTR_TYPE_NET|INTR_MPSAFE, smc_intr, NULL, sc, &sc->smc_ih);
  409         if (error != 0)
  410                 goto done;
  411 
  412 done:
  413         if (error != 0)
  414                 smc_detach(dev);
  415         return (error);
  416 }
  417 
  418 int
  419 smc_detach(device_t dev)
  420 {
  421         int                     type;
  422         struct smc_softc        *sc;
  423 
  424         sc = device_get_softc(dev);
  425         SMC_LOCK(sc);
  426         smc_stop(sc);
  427         SMC_UNLOCK(sc);
  428 
  429         if (sc->smc_ifp != NULL) {
  430                 ether_ifdetach(sc->smc_ifp);
  431         }
  432         
  433         callout_drain(&sc->smc_watchdog);
  434         callout_drain(&sc->smc_mii_tick_ch);
  435         
  436 #ifdef DEVICE_POLLING
  437         if (sc->smc_ifp->if_capenable & IFCAP_POLLING)
  438                 ether_poll_deregister(sc->smc_ifp);
  439 #endif
  440 
  441         if (sc->smc_ih != NULL)
  442                 bus_teardown_intr(sc->smc_dev, sc->smc_irq, sc->smc_ih);
  443 
  444         if (sc->smc_tq != NULL) {
  445                 taskqueue_drain(sc->smc_tq, &sc->smc_intr);
  446                 taskqueue_drain(sc->smc_tq, &sc->smc_rx);
  447                 taskqueue_drain(sc->smc_tq, &sc->smc_tx);
  448                 taskqueue_free(sc->smc_tq);
  449                 sc->smc_tq = NULL;
  450         }
  451 
  452         if (sc->smc_ifp != NULL) {
  453                 if_free(sc->smc_ifp);
  454         }
  455 
  456         if (sc->smc_miibus != NULL) {
  457                 device_delete_child(sc->smc_dev, sc->smc_miibus);
  458                 bus_generic_detach(sc->smc_dev);
  459         }
  460 
  461         if (sc->smc_reg != NULL) {
  462                 type = SYS_RES_IOPORT;
  463                 if (sc->smc_usemem)
  464                         type = SYS_RES_MEMORY;
  465 
  466                 bus_release_resource(sc->smc_dev, type, sc->smc_reg_rid,
  467                     sc->smc_reg);
  468         }
  469 
  470         if (sc->smc_irq != NULL)
  471                 bus_release_resource(sc->smc_dev, SYS_RES_IRQ, sc->smc_irq_rid,
  472                    sc->smc_irq);
  473 
  474         if (mtx_initialized(&sc->smc_mtx))
  475                 mtx_destroy(&sc->smc_mtx);
  476 
  477         return (0);
  478 }
  479 
  480 static void
  481 smc_start(struct ifnet *ifp)
  482 {
  483         struct smc_softc        *sc;
  484 
  485         sc = ifp->if_softc;
  486         SMC_LOCK(sc);
  487         smc_start_locked(ifp);
  488         SMC_UNLOCK(sc);
  489 }
  490 
  491 static void
  492 smc_start_locked(struct ifnet *ifp)
  493 {
  494         struct smc_softc        *sc;
  495         struct mbuf             *m;
  496         u_int                   len, npages, spin_count;
  497 
  498         sc = ifp->if_softc;
  499         SMC_ASSERT_LOCKED(sc);
  500 
  501         if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
  502                 return;
  503         if (IFQ_IS_EMPTY(&ifp->if_snd))
  504                 return;
  505 
  506         /*
  507          * Grab the next packet.  If it's too big, drop it.
  508          */
  509         IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
  510         len = m_length(m, NULL);
  511         len += (len & 1);
  512         if (len > ETHER_MAX_LEN - ETHER_CRC_LEN) {
  513                 if_printf(ifp, "large packet discarded\n");
  514                 ++ifp->if_oerrors;
  515                 m_freem(m);
  516                 return; /* XXX readcheck? */
  517         }
  518 
  519         /*
  520          * Flag that we're busy.
  521          */
  522         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
  523         sc->smc_pending = m;
  524 
  525         /*
  526          * Work out how many 256 byte "pages" we need.  We have to include the
  527          * control data for the packet in this calculation.
  528          */
  529         npages = (len * PKT_CTRL_DATA_LEN) >> 8;
  530         if (npages == 0)
  531                 npages = 1;
  532 
  533         /*
  534          * Request memory.
  535          */
  536         smc_select_bank(sc, 2);
  537         smc_mmu_wait(sc);
  538         smc_write_2(sc, MMUCR, MMUCR_CMD_TX_ALLOC | npages);
  539 
  540         /*
  541          * Spin briefly to see if the allocation succeeds.
  542          */
  543         spin_count = TX_ALLOC_WAIT_TIME;
  544         do {
  545                 if (smc_read_1(sc, IST) & ALLOC_INT) {
  546                         smc_write_1(sc, ACK, ALLOC_INT);
  547                         break;
  548                 }
  549         } while (--spin_count);
  550 
  551         /*
  552          * If the allocation is taking too long, unmask the alloc interrupt
  553          * and wait.
  554          */
  555         if (spin_count == 0) {
  556                 sc->smc_mask |= ALLOC_INT;
  557                 if ((ifp->if_capenable & IFCAP_POLLING) == 0)
  558                         smc_write_1(sc, MSK, sc->smc_mask);
  559                 return;
  560         }
  561 
  562         taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
  563 }
  564 
  565 static void
  566 smc_task_tx(void *context, int pending)
  567 {
  568         struct ifnet            *ifp;
  569         struct smc_softc        *sc;
  570         struct mbuf             *m, *m0;
  571         u_int                   packet, len;
  572         int                     last_len;
  573         uint8_t                 *data;
  574 
  575         (void)pending;
  576         ifp = (struct ifnet *)context;
  577         sc = ifp->if_softc;
  578 
  579         SMC_LOCK(sc);
  580         
  581         if (sc->smc_pending == NULL) {
  582                 SMC_UNLOCK(sc);
  583                 goto next_packet;
  584         }
  585 
  586         m = m0 = sc->smc_pending;
  587         sc->smc_pending = NULL;
  588         smc_select_bank(sc, 2);
  589 
  590         /*
  591          * Check the allocation result.
  592          */
  593         packet = smc_read_1(sc, ARR);
  594 
  595         /*
  596          * If the allocation failed, requeue the packet and retry.
  597          */
  598         if (packet & ARR_FAILED) {
  599                 IFQ_DRV_PREPEND(&ifp->if_snd, m);
  600                 ++ifp->if_oerrors;
  601                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  602                 smc_start_locked(ifp);
  603                 SMC_UNLOCK(sc);
  604                 return;
  605         }
  606 
  607         /*
  608          * Tell the device to write to our packet number.
  609          */
  610         smc_write_1(sc, PNR, packet);
  611         smc_write_2(sc, PTR, 0 | PTR_AUTO_INCR);
  612 
  613         /*
  614          * Tell the device how long the packet is (including control data).
  615          */
  616         len = m_length(m, 0);
  617         len += PKT_CTRL_DATA_LEN;
  618         smc_write_2(sc, DATA0, 0);
  619         smc_write_2(sc, DATA0, len);
  620 
  621         /*
  622          * Push the data out to the device.
  623          */
  624         data = NULL;
  625         last_len = 0;
  626         for (; m != NULL; m = m->m_next) {
  627                 data = mtod(m, uint8_t *);
  628                 smc_write_multi_2(sc, DATA0, (uint16_t *)data, m->m_len / 2);
  629                 last_len = m->m_len;
  630         }
  631 
  632         /*
  633          * Push out the control byte and and the odd byte if needed.
  634          */
  635         if ((len & 1) != 0 && data != NULL)
  636                 smc_write_2(sc, DATA0, (CTRL_ODD << 8) | data[last_len - 1]);
  637         else
  638                 smc_write_2(sc, DATA0, 0);
  639 
  640         /*
  641          * Unmask the TX empty interrupt.
  642          */
  643         sc->smc_mask |= TX_EMPTY_INT;
  644         if ((ifp->if_capenable & IFCAP_POLLING) == 0)
  645                 smc_write_1(sc, MSK, sc->smc_mask);
  646 
  647         /*
  648          * Enqueue the packet.
  649          */
  650         smc_mmu_wait(sc);
  651         smc_write_2(sc, MMUCR, MMUCR_CMD_ENQUEUE);
  652         callout_reset(&sc->smc_watchdog, hz * 2, smc_watchdog, sc);
  653 
  654         /*
  655          * Finish up.
  656          */
  657         ifp->if_opackets++;
  658         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  659         SMC_UNLOCK(sc);
  660         BPF_MTAP(ifp, m0);
  661         m_freem(m0);
  662 
  663 next_packet:
  664         /*
  665          * See if there's anything else to do.
  666          */
  667         smc_start(ifp);
  668 }
  669 
  670 static void
  671 smc_task_rx(void *context, int pending)
  672 {
  673         u_int                   packet, status, len;
  674         uint8_t                 *data;
  675         struct ifnet            *ifp;
  676         struct smc_softc        *sc;
  677         struct mbuf             *m, *mhead, *mtail;
  678 
  679         (void)pending;
  680         ifp = (struct ifnet *)context;
  681         sc = ifp->if_softc;
  682         mhead = mtail = NULL;
  683 
  684         SMC_LOCK(sc);
  685 
  686         packet = smc_read_1(sc, FIFO_RX);
  687         while ((packet & FIFO_EMPTY) == 0) {
  688                 /*
  689                  * Grab an mbuf and attach a cluster.
  690                  */
  691                 MGETHDR(m, M_DONTWAIT, MT_DATA);
  692                 if (m == NULL) {
  693                         break;
  694                 }
  695                 MCLGET(m, M_DONTWAIT);
  696                 if ((m->m_flags & M_EXT) == 0) {
  697                         m_freem(m);
  698                         break;
  699                 }
  700         
  701                 /*
  702                  * Point to the start of the packet.
  703                  */
  704                 smc_select_bank(sc, 2);
  705                 smc_write_1(sc, PNR, packet);
  706                 smc_write_2(sc, PTR, 0 | PTR_READ | PTR_RCV | PTR_AUTO_INCR);
  707 
  708                 /*
  709                  * Grab status and packet length.
  710                  */
  711                 status = smc_read_2(sc, DATA0);
  712                 len = smc_read_2(sc, DATA0) & RX_LEN_MASK;
  713                 len -= 6;
  714                 if (status & RX_ODDFRM)
  715                         len += 1;
  716 
  717                 /*
  718                  * Check for errors.
  719                  */
  720                 if (status & (RX_TOOSHORT | RX_TOOLNG | RX_BADCRC | RX_ALGNERR)) {
  721                         smc_mmu_wait(sc);
  722                         smc_write_2(sc, MMUCR, MMUCR_CMD_RELEASE);
  723                         ifp->if_ierrors++;
  724                         m_freem(m);
  725                         break;
  726                 }
  727         
  728                 /*
  729                  * Set the mbuf up the way we want it.
  730                  */
  731                 m->m_pkthdr.rcvif = ifp;
  732                 m->m_pkthdr.len = m->m_len = len + 2; /* XXX: Is this right? */
  733                 m_adj(m, ETHER_ALIGN);
  734         
  735                 /*
  736                  * Pull the packet out of the device.  Make sure we're in the
  737                  * right bank first as things may have changed while we were
  738                  * allocating our mbuf.
  739                  */
  740                 smc_select_bank(sc, 2);
  741                 smc_write_1(sc, PNR, packet);
  742                 smc_write_2(sc, PTR, 4 | PTR_READ | PTR_RCV | PTR_AUTO_INCR);
  743                 data = mtod(m, uint8_t *);
  744                 smc_read_multi_2(sc, DATA0, (uint16_t *)data, len >> 1);
  745                 if (len & 1) {
  746                         data += len & ~1;
  747                         *data = smc_read_1(sc, DATA0);
  748                 }
  749 
  750                 /*
  751                  * Tell the device we're done.
  752                  */
  753                 smc_mmu_wait(sc);
  754                 smc_write_2(sc, MMUCR, MMUCR_CMD_RELEASE);
  755                 if (m == NULL) {
  756                         break;
  757                 }
  758                 
  759                 if (mhead == NULL) {
  760                         mhead = mtail = m;
  761                         m->m_next = NULL;
  762                 } else {
  763                         mtail->m_next = m;
  764                         mtail = m;
  765                 }
  766                 packet = smc_read_1(sc, FIFO_RX);
  767         }
  768 
  769         sc->smc_mask |= RCV_INT;
  770         if ((ifp->if_capenable & IFCAP_POLLING) == 0)
  771                 smc_write_1(sc, MSK, sc->smc_mask);
  772 
  773         SMC_UNLOCK(sc);
  774 
  775         while (mhead != NULL) {
  776                 m = mhead;
  777                 mhead = mhead->m_next;
  778                 m->m_next = NULL;
  779                 ifp->if_ipackets++;
  780                 (*ifp->if_input)(ifp, m);
  781         }
  782 }
  783 
  784 #ifdef DEVICE_POLLING
  785 static void
  786 smc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
  787 {
  788         struct smc_softc        *sc;
  789 
  790         sc = ifp->if_softc;
  791 
  792         SMC_LOCK(sc);
  793         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
  794                 SMC_UNLOCK(sc);
  795                 return;
  796         }
  797         SMC_UNLOCK(sc);
  798 
  799         if (cmd == POLL_AND_CHECK_STATUS)
  800                 taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr);
  801 }
  802 #endif
  803 
  804 static int
  805 smc_intr(void *context)
  806 {
  807         struct smc_softc        *sc;
  808         
  809         sc = (struct smc_softc *)context;
  810         taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr);
  811         return (FILTER_HANDLED);
  812 }
  813 
  814 static void
  815 smc_task_intr(void *context, int pending)
  816 {
  817         struct smc_softc        *sc;
  818         struct ifnet            *ifp;
  819         u_int                   status, packet, counter, tcr;
  820 
  821         (void)pending;
  822         ifp = (struct ifnet *)context;
  823         sc = ifp->if_softc;
  824 
  825         SMC_LOCK(sc);
  826         
  827         smc_select_bank(sc, 2);
  828 
  829         /*
  830          * Get the current mask, and then block all interrupts while we're
  831          * working.
  832          */
  833         if ((ifp->if_capenable & IFCAP_POLLING) == 0)
  834                 smc_write_1(sc, MSK, 0);
  835 
  836         /*
  837          * Find out what interrupts are flagged.
  838          */
  839         status = smc_read_1(sc, IST) & sc->smc_mask;
  840 
  841         /*
  842          * Transmit error
  843          */
  844         if (status & TX_INT) {
  845                 /*
  846                  * Kill off the packet if there is one and re-enable transmit.
  847                  */
  848                 packet = smc_read_1(sc, FIFO_TX);
  849                 if ((packet & FIFO_EMPTY) == 0) {
  850                         smc_write_1(sc, PNR, packet);
  851                         smc_write_2(sc, PTR, 0 | PTR_READ | 
  852                             PTR_AUTO_INCR);
  853                         tcr = smc_read_2(sc, DATA0);
  854                         if ((tcr & EPHSR_TX_SUC) == 0)
  855                                 device_printf(sc->smc_dev,
  856                                     "bad packet\n");
  857                         smc_mmu_wait(sc);
  858                         smc_write_2(sc, MMUCR, MMUCR_CMD_RELEASE_PKT);
  859 
  860                         smc_select_bank(sc, 0);
  861                         tcr = smc_read_2(sc, TCR);
  862                         tcr |= TCR_TXENA | TCR_PAD_EN;
  863                         smc_write_2(sc, TCR, tcr);
  864                         smc_select_bank(sc, 2);
  865                         taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
  866                 }
  867 
  868                 /*
  869                  * Ack the interrupt.
  870                  */
  871                 smc_write_1(sc, ACK, TX_INT);
  872         }
  873 
  874         /*
  875          * Receive
  876          */
  877         if (status & RCV_INT) {
  878                 smc_write_1(sc, ACK, RCV_INT);
  879                 sc->smc_mask &= ~RCV_INT;
  880                 taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_rx);
  881         }
  882 
  883         /*
  884          * Allocation
  885          */
  886         if (status & ALLOC_INT) {
  887                 smc_write_1(sc, ACK, ALLOC_INT);
  888                 sc->smc_mask &= ~ALLOC_INT;
  889                 taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
  890         }
  891 
  892         /*
  893          * Receive overrun
  894          */
  895         if (status & RX_OVRN_INT) {
  896                 smc_write_1(sc, ACK, RX_OVRN_INT);
  897                 ifp->if_ierrors++;
  898         }
  899 
  900         /*
  901          * Transmit empty
  902          */
  903         if (status & TX_EMPTY_INT) {
  904                 smc_write_1(sc, ACK, TX_EMPTY_INT);
  905                 sc->smc_mask &= ~TX_EMPTY_INT;
  906                 callout_stop(&sc->smc_watchdog);
  907 
  908                 /*
  909                  * Update collision stats.
  910                  */
  911                 smc_select_bank(sc, 0);
  912                 counter = smc_read_2(sc, ECR);
  913                 smc_select_bank(sc, 2);
  914                 ifp->if_collisions +=
  915                     (counter & ECR_SNGLCOL_MASK) >> ECR_SNGLCOL_SHIFT;
  916                 ifp->if_collisions +=
  917                     (counter & ECR_MULCOL_MASK) >> ECR_MULCOL_SHIFT;
  918 
  919                 /*
  920                  * See if there are any packets to transmit.
  921                  */
  922                 taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
  923         }
  924 
  925         /*
  926          * Update the interrupt mask.
  927          */
  928         if ((ifp->if_capenable & IFCAP_POLLING) == 0)
  929                 smc_write_1(sc, MSK, sc->smc_mask);
  930 
  931         SMC_UNLOCK(sc);
  932 }
  933 
  934 static uint32_t
  935 smc_mii_bitbang_read(device_t dev)
  936 {
  937         struct smc_softc        *sc;
  938         uint32_t                val;
  939 
  940         sc = device_get_softc(dev);
  941 
  942         SMC_ASSERT_LOCKED(sc);
  943         KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3,
  944             ("%s: smc_mii_bitbang_read called with bank %d (!= 3)",
  945             device_get_nameunit(sc->smc_dev),
  946             smc_read_2(sc, BSR) & BSR_BANK_MASK));
  947 
  948         val = smc_read_2(sc, MGMT);
  949         smc_barrier(sc, MGMT, 2,
  950             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  951 
  952         return (val);
  953 }
  954 
  955 static void
  956 smc_mii_bitbang_write(device_t dev, uint32_t val)
  957 {
  958         struct smc_softc        *sc;
  959 
  960         sc = device_get_softc(dev);
  961 
  962         SMC_ASSERT_LOCKED(sc);
  963         KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3,
  964             ("%s: smc_mii_bitbang_write called with bank %d (!= 3)",
  965             device_get_nameunit(sc->smc_dev),
  966             smc_read_2(sc, BSR) & BSR_BANK_MASK));
  967 
  968         smc_write_2(sc, MGMT, val);
  969         smc_barrier(sc, MGMT, 2,
  970             BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
  971 }
  972 
  973 int
  974 smc_miibus_readreg(device_t dev, int phy, int reg)
  975 {
  976         struct smc_softc        *sc;
  977         int                     val;
  978 
  979         sc = device_get_softc(dev);
  980 
  981         SMC_LOCK(sc);
  982 
  983         smc_select_bank(sc, 3);
  984 
  985         val = mii_bitbang_readreg(dev, &smc_mii_bitbang_ops, phy, reg);
  986 
  987         SMC_UNLOCK(sc);
  988         return (val);
  989 }
  990 
  991 int
  992 smc_miibus_writereg(device_t dev, int phy, int reg, int data)
  993 {
  994         struct smc_softc        *sc;
  995 
  996         sc = device_get_softc(dev);
  997 
  998         SMC_LOCK(sc);
  999 
 1000         smc_select_bank(sc, 3);
 1001 
 1002         mii_bitbang_writereg(dev, &smc_mii_bitbang_ops, phy, reg, data);
 1003 
 1004         SMC_UNLOCK(sc);
 1005         return (0);
 1006 }
 1007 
 1008 void
 1009 smc_miibus_statchg(device_t dev)
 1010 {
 1011         struct smc_softc        *sc;
 1012         struct mii_data         *mii;
 1013         uint16_t                tcr;
 1014 
 1015         sc = device_get_softc(dev);
 1016         mii = device_get_softc(sc->smc_miibus);
 1017 
 1018         SMC_LOCK(sc);
 1019 
 1020         smc_select_bank(sc, 0);
 1021         tcr = smc_read_2(sc, TCR);
 1022 
 1023         if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
 1024                 tcr |= TCR_SWFDUP;
 1025         else
 1026                 tcr &= ~TCR_SWFDUP;
 1027 
 1028         smc_write_2(sc, TCR, tcr);
 1029 
 1030         SMC_UNLOCK(sc);
 1031 }
 1032 
 1033 static int
 1034 smc_mii_ifmedia_upd(struct ifnet *ifp)
 1035 {
 1036         struct smc_softc        *sc;
 1037         struct mii_data         *mii;
 1038 
 1039         sc = ifp->if_softc;
 1040         if (sc->smc_miibus == NULL)
 1041                 return (ENXIO);
 1042 
 1043         mii = device_get_softc(sc->smc_miibus);
 1044         return (mii_mediachg(mii));
 1045 }
 1046 
 1047 static void
 1048 smc_mii_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 1049 {
 1050         struct smc_softc        *sc;
 1051         struct mii_data         *mii;
 1052 
 1053         sc = ifp->if_softc;
 1054         if (sc->smc_miibus == NULL)
 1055                 return;
 1056 
 1057         mii = device_get_softc(sc->smc_miibus);
 1058         mii_pollstat(mii);
 1059         ifmr->ifm_active = mii->mii_media_active;
 1060         ifmr->ifm_status = mii->mii_media_status;
 1061 }
 1062 
 1063 static void
 1064 smc_mii_tick(void *context)
 1065 {
 1066         struct smc_softc        *sc;
 1067 
 1068         sc = (struct smc_softc *)context;
 1069 
 1070         if (sc->smc_miibus == NULL)
 1071                 return;
 1072 
 1073         SMC_UNLOCK(sc);
 1074 
 1075         mii_tick(device_get_softc(sc->smc_miibus));
 1076         callout_reset(&sc->smc_mii_tick_ch, hz, smc_mii_tick, sc);
 1077 }
 1078 
 1079 static void
 1080 smc_mii_mediachg(struct smc_softc *sc)
 1081 {
 1082 
 1083         if (sc->smc_miibus == NULL)
 1084                 return;
 1085         mii_mediachg(device_get_softc(sc->smc_miibus));
 1086 }
 1087 
 1088 static int
 1089 smc_mii_mediaioctl(struct smc_softc *sc, struct ifreq *ifr, u_long command)
 1090 {
 1091         struct mii_data *mii;
 1092 
 1093         if (sc->smc_miibus == NULL)
 1094                 return (EINVAL);
 1095 
 1096         mii = device_get_softc(sc->smc_miibus);
 1097         return (ifmedia_ioctl(sc->smc_ifp, ifr, &mii->mii_media, command));
 1098 }
 1099 
 1100 static void
 1101 smc_reset(struct smc_softc *sc)
 1102 {
 1103         u_int   ctr;
 1104 
 1105         SMC_ASSERT_LOCKED(sc);
 1106 
 1107         smc_select_bank(sc, 2);
 1108 
 1109         /*
 1110          * Mask all interrupts.
 1111          */
 1112         smc_write_1(sc, MSK, 0);
 1113 
 1114         /*
 1115          * Tell the device to reset.
 1116          */
 1117         smc_select_bank(sc, 0);
 1118         smc_write_2(sc, RCR, RCR_SOFT_RST);
 1119 
 1120         /*
 1121          * Set up the configuration register.
 1122          */
 1123         smc_select_bank(sc, 1);
 1124         smc_write_2(sc, CR, CR_EPH_POWER_EN);
 1125         DELAY(1);
 1126 
 1127         /*
 1128          * Turn off transmit and receive.
 1129          */
 1130         smc_select_bank(sc, 0);
 1131         smc_write_2(sc, TCR, 0);
 1132         smc_write_2(sc, RCR, 0);
 1133 
 1134         /*
 1135          * Set up the control register.
 1136          */
 1137         smc_select_bank(sc, 1);
 1138         ctr = smc_read_2(sc, CTR);
 1139         ctr |= CTR_LE_ENABLE | CTR_AUTO_RELEASE;
 1140         smc_write_2(sc, CTR, ctr);
 1141 
 1142         /*
 1143          * Reset the MMU.
 1144          */
 1145         smc_select_bank(sc, 2);
 1146         smc_mmu_wait(sc);
 1147         smc_write_2(sc, MMUCR, MMUCR_CMD_MMU_RESET);
 1148 }
 1149 
 1150 static void
 1151 smc_enable(struct smc_softc *sc)
 1152 {
 1153         struct ifnet            *ifp;
 1154 
 1155         SMC_ASSERT_LOCKED(sc);
 1156         ifp = sc->smc_ifp;
 1157 
 1158         /*
 1159          * Set up the receive/PHY control register.
 1160          */
 1161         smc_select_bank(sc, 0);
 1162         smc_write_2(sc, RPCR, RPCR_ANEG | (RPCR_LED_LINK_ANY << RPCR_LSA_SHIFT)
 1163             | (RPCR_LED_ACT_ANY << RPCR_LSB_SHIFT));
 1164 
 1165         /*
 1166          * Set up the transmit and receive control registers.
 1167          */
 1168         smc_write_2(sc, TCR, TCR_TXENA | TCR_PAD_EN);
 1169         smc_write_2(sc, RCR, RCR_RXEN | RCR_STRIP_CRC);
 1170 
 1171         /*
 1172          * Set up the interrupt mask.
 1173          */
 1174         smc_select_bank(sc, 2);
 1175         sc->smc_mask = EPH_INT | RX_OVRN_INT | RCV_INT | TX_INT;
 1176         if ((ifp->if_capenable & IFCAP_POLLING) != 0)
 1177                 smc_write_1(sc, MSK, sc->smc_mask);
 1178 }
 1179 
 1180 static void
 1181 smc_stop(struct smc_softc *sc)
 1182 {
 1183 
 1184         SMC_ASSERT_LOCKED(sc);
 1185 
 1186         /*
 1187          * Turn off callouts.
 1188          */
 1189         callout_stop(&sc->smc_watchdog);
 1190         callout_stop(&sc->smc_mii_tick_ch);
 1191 
 1192         /*
 1193          * Mask all interrupts.
 1194          */
 1195         smc_select_bank(sc, 2);
 1196         sc->smc_mask = 0;
 1197         smc_write_1(sc, MSK, 0);
 1198 #ifdef DEVICE_POLLING
 1199         ether_poll_deregister(sc->smc_ifp);
 1200         sc->smc_ifp->if_capenable &= ~IFCAP_POLLING;
 1201         sc->smc_ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT;
 1202 #endif
 1203 
 1204         /*
 1205          * Disable transmit and receive.
 1206          */
 1207         smc_select_bank(sc, 0);
 1208         smc_write_2(sc, TCR, 0);
 1209         smc_write_2(sc, RCR, 0);
 1210 
 1211         sc->smc_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 1212 }
 1213 
 1214 static void
 1215 smc_watchdog(void *arg)
 1216 {
 1217         struct smc_softc        *sc;
 1218         
 1219         sc = (struct smc_softc *)arg;
 1220         device_printf(sc->smc_dev, "watchdog timeout\n");
 1221         taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr);
 1222 }
 1223 
 1224 static void
 1225 smc_init(void *context)
 1226 {
 1227         struct smc_softc        *sc;
 1228 
 1229         sc = (struct smc_softc *)context;
 1230         SMC_LOCK(sc);
 1231         smc_init_locked(sc);
 1232         SMC_UNLOCK(sc);
 1233 }
 1234 
 1235 static void
 1236 smc_init_locked(struct smc_softc *sc)
 1237 {
 1238         struct ifnet    *ifp;
 1239 
 1240         ifp = sc->smc_ifp;
 1241 
 1242         SMC_ASSERT_LOCKED(sc);
 1243 
 1244         smc_reset(sc);
 1245         smc_enable(sc);
 1246 
 1247         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 1248         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1249 
 1250         smc_start_locked(ifp);
 1251 
 1252         if (sc->smc_mii_tick != NULL)
 1253                 callout_reset(&sc->smc_mii_tick_ch, hz, sc->smc_mii_tick, sc);
 1254 
 1255 #ifdef DEVICE_POLLING
 1256         SMC_UNLOCK(sc);
 1257         ether_poll_register(smc_poll, ifp);
 1258         SMC_LOCK(sc);
 1259         ifp->if_capenable |= IFCAP_POLLING;
 1260         ifp->if_capenable |= IFCAP_POLLING_NOCOUNT;
 1261 #endif
 1262 }
 1263 
 1264 static int
 1265 smc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1266 {
 1267         struct smc_softc        *sc;
 1268         int                     error;
 1269 
 1270         sc = ifp->if_softc;
 1271         error = 0;
 1272 
 1273         switch (cmd) {
 1274         case SIOCSIFFLAGS:
 1275                 if ((ifp->if_flags & IFF_UP) == 0 &&
 1276                     (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
 1277                         SMC_LOCK(sc);
 1278                         smc_stop(sc);
 1279                         SMC_UNLOCK(sc);
 1280                 } else {
 1281                         smc_init(sc);
 1282                         if (sc->smc_mii_mediachg != NULL)
 1283                                 sc->smc_mii_mediachg(sc);
 1284                 }
 1285                 break;
 1286 
 1287         case SIOCADDMULTI:
 1288         case SIOCDELMULTI:
 1289                 /* XXX
 1290                 SMC_LOCK(sc);
 1291                 smc_setmcast(sc);
 1292                 SMC_UNLOCK(sc);
 1293                 */
 1294                 error = EINVAL;
 1295                 break;
 1296 
 1297         case SIOCGIFMEDIA:
 1298         case SIOCSIFMEDIA:
 1299                 if (sc->smc_mii_mediaioctl == NULL) {
 1300                         error = EINVAL;
 1301                         break;
 1302                 }
 1303                 sc->smc_mii_mediaioctl(sc, (struct ifreq *)data, cmd);
 1304                 break;
 1305 
 1306         default:
 1307                 error = ether_ioctl(ifp, cmd, data);
 1308                 break;
 1309         }
 1310 
 1311         return (error);
 1312 }

Cache object: ca6f796f1b36eacd2a1ceeb6458500df


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