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/ep/if_ep.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  * SPDX-License-Identifier: BSD-4-Clause
    3  *
    4  * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Herb Peyerl.
   18  * 4. The name of Herb Peyerl may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD: releng/12.0/sys/dev/ep/if_ep.c 339735 2018-10-25 17:00:39Z brooks $");
   35 
   36 /*
   37  *      Modified from the FreeBSD 1.1.5.1 version by:
   38  *                      Andres Vega Garcia
   39  *                      INRIA - Sophia Antipolis, France
   40  *                      avega@sophia.inria.fr
   41  */
   42 
   43 /*
   44  *  Promiscuous mode added and interrupt logic slightly changed
   45  *  to reduce the number of adapter failures. Transceiver select
   46  *  logic changed to use value from EEPROM. Autoconfiguration
   47  *  features added.
   48  *  Done by:
   49  *          Serge Babkin
   50  *          Chelindbank (Chelyabinsk, Russia)
   51  *          babkin@hq.icb.chel.su
   52  */
   53 
   54 /*
   55  * Pccard support for 3C589 by:
   56  *              HAMADA Naoki
   57  *              nao@tom-yam.or.jp
   58  */
   59 
   60 /*
   61  * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
   62  *                             <mdodd@FreeBSD.org>
   63  */
   64 
   65 #include <sys/param.h>
   66 #include <sys/systm.h>
   67 #include <sys/kernel.h>
   68 #include <sys/malloc.h>
   69 #include <sys/mbuf.h>
   70 #include <sys/socket.h>
   71 #include <sys/sockio.h>
   72 #include <sys/bus.h>
   73 
   74 #include <machine/bus.h>
   75 #include <machine/resource.h>
   76 #include <sys/rman.h>
   77 
   78 #include <net/if.h>
   79 #include <net/if_var.h>
   80 #include <net/if_dl.h>
   81 #include <net/if_media.h>
   82 #include <net/if_types.h>
   83 #include <net/ethernet.h>
   84 #include <net/bpf.h>
   85 
   86 #include <dev/ep/if_epreg.h>
   87 #include <dev/ep/if_epvar.h>
   88 
   89 /* Exported variables */
   90 devclass_t ep_devclass;
   91 
   92 static int ep_media2if_media[] =
   93 {IFM_10_T, IFM_10_5, IFM_NONE, IFM_10_2, IFM_NONE};
   94 
   95 /* if functions */
   96 static void epinit(void *);
   97 static int epioctl(struct ifnet *, u_long, caddr_t);
   98 static void epstart(struct ifnet *);
   99 
  100 static void ep_intr_locked(struct ep_softc *);
  101 static void epstart_locked(struct ifnet *);
  102 static void epinit_locked(struct ep_softc *);
  103 static void eptick(void *);
  104 static void epwatchdog(struct ep_softc *);
  105 
  106 /* if_media functions */
  107 static int ep_ifmedia_upd(struct ifnet *);
  108 static void ep_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  109 
  110 static void epstop(struct ep_softc *);
  111 static void epread(struct ep_softc *);
  112 static int eeprom_rdy(struct ep_softc *);
  113 
  114 #define EP_FTST(sc, f)  (sc->stat &   (f))
  115 #define EP_FSET(sc, f)  (sc->stat |=  (f))
  116 #define EP_FRST(sc, f)  (sc->stat &= ~(f))
  117 
  118 static int
  119 eeprom_rdy(struct ep_softc *sc)
  120 {
  121         int i;
  122 
  123         for (i = 0; is_eeprom_busy(sc) && i < MAX_EEPROMBUSY; i++)
  124                 DELAY(100);
  125 
  126         if (i >= MAX_EEPROMBUSY) {
  127                 device_printf(sc->dev, "eeprom failed to come ready.\n");
  128                 return (ENXIO);
  129         }
  130 
  131         return (0);
  132 }
  133 
  134 /*
  135  * get_e: gets a 16 bits word from the EEPROM. we must have set the window
  136  * before
  137  */
  138 int
  139 ep_get_e(struct ep_softc *sc, uint16_t offset, uint16_t *result)
  140 {
  141 
  142         if (eeprom_rdy(sc))
  143                 return (ENXIO);
  144 
  145         CSR_WRITE_2(sc, EP_W0_EEPROM_COMMAND,
  146             (EEPROM_CMD_RD << sc->epb.cmd_off) | offset);
  147 
  148         if (eeprom_rdy(sc))
  149                 return (ENXIO);
  150 
  151         (*result) = CSR_READ_2(sc, EP_W0_EEPROM_DATA);
  152 
  153         return (0);
  154 }
  155 
  156 static int
  157 ep_get_macaddr(struct ep_softc *sc, u_char *addr)
  158 {
  159         int i;
  160         uint16_t result;
  161         int error;
  162         uint16_t *macaddr;
  163 
  164         macaddr = (uint16_t *) addr;
  165 
  166         GO_WINDOW(sc, 0);
  167         for (i = EEPROM_NODE_ADDR_0; i <= EEPROM_NODE_ADDR_2; i++) {
  168                 error = ep_get_e(sc, i, &result);
  169                 if (error)
  170                         return (error);
  171                 macaddr[i] = htons(result);
  172         }
  173         return (0);
  174 }
  175 
  176 int
  177 ep_alloc(device_t dev)
  178 {
  179         struct ep_softc *sc = device_get_softc(dev);
  180         int rid;
  181         int error = 0;
  182         uint16_t result;
  183 
  184         rid = 0;
  185         sc->iobase = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
  186             RF_ACTIVE);
  187         if (!sc->iobase) {
  188                 device_printf(dev, "No I/O space?!\n");
  189                 error = ENXIO;
  190                 goto bad;
  191         }
  192         rid = 0;
  193         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
  194         if (!sc->irq) {
  195                 device_printf(dev, "No irq?!\n");
  196                 error = ENXIO;
  197                 goto bad;
  198         }
  199         sc->dev = dev;
  200         sc->stat = 0;           /* 16 bit access */
  201 
  202         sc->bst = rman_get_bustag(sc->iobase);
  203         sc->bsh = rman_get_bushandle(sc->iobase);
  204 
  205         sc->ep_connectors = 0;
  206         sc->ep_connector = 0;
  207 
  208         GO_WINDOW(sc, 0);
  209 
  210         error = ep_get_e(sc, EEPROM_PROD_ID, &result);
  211         if (error)
  212                 goto bad;
  213         sc->epb.prod_id = result;
  214 
  215         error = ep_get_e(sc, EEPROM_RESOURCE_CFG, &result);
  216         if (error)
  217                 goto bad;
  218         sc->epb.res_cfg = result;
  219 
  220 bad:
  221         if (error != 0)
  222                 ep_free(dev);
  223         return (error);
  224 }
  225 
  226 void
  227 ep_get_media(struct ep_softc *sc)
  228 {
  229         uint16_t config;
  230 
  231         GO_WINDOW(sc, 0);
  232         config = CSR_READ_2(sc, EP_W0_CONFIG_CTRL);
  233         if (config & IS_AUI)
  234                 sc->ep_connectors |= AUI;
  235         if (config & IS_BNC)
  236                 sc->ep_connectors |= BNC;
  237         if (config & IS_UTP)
  238                 sc->ep_connectors |= UTP;
  239 
  240         if (!(sc->ep_connectors & 7))
  241                 if (bootverbose)
  242                         device_printf(sc->dev, "no connectors!\n");
  243 
  244         /*
  245          * This works for most of the cards so we'll do it here.
  246          * The cards that require something different can override
  247          * this later on.
  248          */
  249         sc->ep_connector = CSR_READ_2(sc, EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
  250 }
  251 
  252 void
  253 ep_free(device_t dev)
  254 {
  255         struct ep_softc *sc = device_get_softc(dev);
  256 
  257         if (sc->ep_intrhand)
  258                 bus_teardown_intr(dev, sc->irq, sc->ep_intrhand);
  259         if (sc->iobase)
  260                 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->iobase);
  261         if (sc->irq)
  262                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
  263         sc->ep_intrhand = 0;
  264         sc->iobase = 0;
  265         sc->irq = 0;
  266 }
  267 
  268 static void
  269 ep_setup_station(struct ep_softc *sc, u_char *enaddr)
  270 {
  271         int i;
  272         
  273         /*
  274          * Setup the station address
  275          */
  276         GO_WINDOW(sc, 2);
  277         for (i = 0; i < ETHER_ADDR_LEN; i++)
  278                 CSR_WRITE_1(sc, EP_W2_ADDR_0 + i, enaddr[i]);
  279 }
  280 
  281 int
  282 ep_attach(struct ep_softc *sc)
  283 {
  284         struct ifnet *ifp = NULL;
  285         struct ifmedia *ifm = NULL;
  286         int error;
  287 
  288         sc->gone = 0;
  289         EP_LOCK_INIT(sc);
  290         if (! (sc->stat & F_ENADDR_SKIP)) {
  291                 error = ep_get_macaddr(sc, sc->eaddr);
  292                 if (error) {
  293                         device_printf(sc->dev, "Unable to get MAC address!\n");
  294                         EP_LOCK_DESTROY(sc);
  295                         return (ENXIO);
  296                 }
  297         }
  298         ep_setup_station(sc, sc->eaddr);
  299         ifp = sc->ifp = if_alloc(IFT_ETHER);
  300         if (ifp == NULL) {
  301                 device_printf(sc->dev, "if_alloc() failed\n");
  302                 EP_LOCK_DESTROY(sc);
  303                 return (ENOSPC);
  304         }
  305 
  306         ifp->if_softc = sc;
  307         if_initname(ifp, device_get_name(sc->dev), device_get_unit(sc->dev));
  308         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  309         ifp->if_start = epstart;
  310         ifp->if_ioctl = epioctl;
  311         ifp->if_init = epinit;
  312         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
  313         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
  314         IFQ_SET_READY(&ifp->if_snd);
  315 
  316         callout_init_mtx(&sc->watchdog_timer, &sc->sc_mtx, 0);
  317         if (!sc->epb.mii_trans) {
  318                 ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts);
  319 
  320                 if (sc->ep_connectors & AUI)
  321                         ifmedia_add(&sc->ifmedia,
  322                             IFM_ETHER | IFM_10_5, 0, NULL);
  323                 if (sc->ep_connectors & UTP)
  324                         ifmedia_add(&sc->ifmedia,
  325                             IFM_ETHER | IFM_10_T, 0, NULL);
  326                 if (sc->ep_connectors & BNC)
  327                         ifmedia_add(&sc->ifmedia,
  328                             IFM_ETHER | IFM_10_2, 0, NULL);
  329                 if (!sc->ep_connectors)
  330                         ifmedia_add(&sc->ifmedia,
  331                             IFM_ETHER | IFM_NONE, 0, NULL);
  332 
  333                 ifmedia_set(&sc->ifmedia,
  334                     IFM_ETHER | ep_media2if_media[sc->ep_connector]);
  335 
  336                 ifm = &sc->ifmedia;
  337                 ifm->ifm_media = ifm->ifm_cur->ifm_media;
  338                 ep_ifmedia_upd(ifp);
  339         }
  340         ether_ifattach(ifp, sc->eaddr);
  341 
  342 #ifdef EP_LOCAL_STATS
  343         sc->rx_no_first = sc->rx_no_mbuf = sc->rx_bpf_disc =
  344             sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
  345 #endif
  346         EP_FSET(sc, F_RX_FIRST);
  347         sc->top = sc->mcur = 0;
  348 
  349         EP_LOCK(sc);
  350         epstop(sc);
  351         EP_UNLOCK(sc);
  352 
  353         gone_by_fcp101_dev(sc->dev);
  354 
  355         return (0);
  356 }
  357 
  358 int
  359 ep_detach(device_t dev)
  360 {
  361         struct ep_softc *sc;
  362         struct ifnet *ifp;
  363 
  364         sc = device_get_softc(dev);
  365         ifp = sc->ifp;
  366         EP_ASSERT_UNLOCKED(sc);
  367         EP_LOCK(sc);
  368         if (bus_child_present(dev))
  369                 epstop(sc);
  370         sc->gone = 1;
  371         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
  372         EP_UNLOCK(sc);
  373         ether_ifdetach(ifp);
  374         callout_drain(&sc->watchdog_timer);
  375         ep_free(dev);
  376 
  377         if_free(ifp);
  378         EP_LOCK_DESTROY(sc);
  379 
  380         return (0);
  381 }
  382 
  383 static void
  384 epinit(void *xsc)
  385 {
  386         struct ep_softc *sc = xsc;
  387         EP_LOCK(sc);
  388         epinit_locked(sc);
  389         EP_UNLOCK(sc);
  390 }
  391 
  392 /*
  393  * The order in here seems important. Otherwise we may not receive
  394  * interrupts. ?!
  395  */
  396 static void
  397 epinit_locked(struct ep_softc *sc)
  398 {
  399         struct ifnet *ifp = sc->ifp;
  400         int i;
  401 
  402         if (sc->gone)
  403                 return;
  404 
  405         EP_ASSERT_LOCKED(sc);
  406         EP_BUSY_WAIT(sc);
  407 
  408         GO_WINDOW(sc, 0);
  409         CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
  410         GO_WINDOW(sc, 4);
  411         CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
  412         GO_WINDOW(sc, 0);
  413 
  414         /* Disable the card */
  415         CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, 0);
  416 
  417         /* Enable the card */
  418         CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
  419 
  420         GO_WINDOW(sc, 2);
  421         /* Reload the ether_addr. */
  422         ep_setup_station(sc, IF_LLADDR(sc->ifp));
  423 
  424         CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
  425         CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
  426         EP_BUSY_WAIT(sc);
  427 
  428         /* Window 1 is operating window */
  429         GO_WINDOW(sc, 1);
  430         for (i = 0; i < 31; i++)
  431                 CSR_READ_1(sc, EP_W1_TX_STATUS);
  432 
  433         /* get rid of stray intr's */
  434         CSR_WRITE_2(sc, EP_COMMAND, ACK_INTR | 0xff);
  435 
  436         CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
  437         CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
  438 
  439         if (ifp->if_flags & IFF_PROMISC)
  440                 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
  441                     FIL_MULTICAST | FIL_BRDCST | FIL_PROMISC);
  442         else
  443                 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
  444                     FIL_MULTICAST | FIL_BRDCST);
  445 
  446         if (!sc->epb.mii_trans)
  447                 ep_ifmedia_upd(ifp);
  448 
  449         if (sc->stat & F_HAS_TX_PLL)
  450                 CSR_WRITE_2(sc, EP_COMMAND, TX_PLL_ENABLE);
  451         CSR_WRITE_2(sc, EP_COMMAND, RX_ENABLE);
  452         CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
  453 
  454         ifp->if_drv_flags |= IFF_DRV_RUNNING;
  455         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;  /* just in case */
  456 
  457 #ifdef EP_LOCAL_STATS
  458         sc->rx_no_first = sc->rx_no_mbuf =
  459             sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
  460 #endif
  461         EP_FSET(sc, F_RX_FIRST);
  462         if (sc->top) {
  463                 m_freem(sc->top);
  464                 sc->top = sc->mcur = 0;
  465         }
  466         CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
  467         CSR_WRITE_2(sc, EP_COMMAND, SET_TX_START_THRESH | 16);
  468 
  469         GO_WINDOW(sc, 1);
  470         epstart_locked(ifp);
  471         callout_reset(&sc->watchdog_timer, hz, eptick, sc);
  472 }
  473 
  474 static void
  475 epstart(struct ifnet *ifp)
  476 {
  477         struct ep_softc *sc;
  478         sc = ifp->if_softc;
  479         EP_LOCK(sc);
  480         epstart_locked(ifp);
  481         EP_UNLOCK(sc);
  482 }
  483         
  484 static void
  485 epstart_locked(struct ifnet *ifp)
  486 {
  487         struct ep_softc *sc;
  488         u_int len;
  489         struct mbuf *m, *m0;
  490         int pad, started;
  491 
  492         sc = ifp->if_softc;
  493         if (sc->gone)
  494                 return;
  495         EP_ASSERT_LOCKED(sc);
  496         EP_BUSY_WAIT(sc);
  497         if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
  498                 return;
  499         started = 0;
  500 startagain:
  501         /* Sneak a peek at the next packet */
  502         IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
  503         if (m0 == NULL)
  504                 return;
  505         if (!started && (sc->stat & F_HAS_TX_PLL))
  506                 CSR_WRITE_2(sc, EP_COMMAND, TX_PLL_ENABLE);
  507         started++;
  508         for (len = 0, m = m0; m != NULL; m = m->m_next)
  509                 len += m->m_len;
  510 
  511         pad = (4 - len) & 3;
  512 
  513         /*
  514          * The 3c509 automatically pads short packets to minimum
  515          * ethernet length, but we drop packets that are too large.
  516          * Perhaps we should truncate them instead?
  517          */
  518         if (len + pad > ETHER_MAX_LEN) {
  519                 /* packet is obviously too large: toss it */
  520                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
  521                 m_freem(m0);
  522                 goto readcheck;
  523         }
  524         if (CSR_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
  525                 /* no room in FIFO */
  526                 CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
  527                 /* make sure */
  528                 if (CSR_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
  529                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
  530                         IFQ_DRV_PREPEND(&ifp->if_snd, m0);
  531                         goto done;
  532                 }
  533         } else
  534                 CSR_WRITE_2(sc, EP_COMMAND,
  535                     SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
  536 
  537         CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, len);
  538         /* Second dword meaningless */
  539         CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, 0x0);
  540 
  541         for (m = m0; m != NULL; m = m->m_next) {
  542                 if (m->m_len > 1)
  543                         CSR_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1,
  544                             mtod(m, uint16_t *), m->m_len / 2);
  545                 if (m->m_len & 1)
  546                         CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1,
  547                             *(mtod(m, uint8_t *)+m->m_len - 1));
  548         }
  549 
  550         while (pad--)
  551                 CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1, 0);  /* Padding */
  552 
  553         /* XXX and drop splhigh here */
  554 
  555         BPF_MTAP(ifp, m0);
  556 
  557         sc->tx_timer = 2;
  558         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
  559         m_freem(m0);
  560 
  561         /*
  562          * Is another packet coming in? We don't want to overflow
  563          * the tiny RX fifo.
  564          */
  565 readcheck:
  566         if (CSR_READ_2(sc, EP_W1_RX_STATUS) & RX_BYTES_MASK) {
  567                 /*
  568                  * we check if we have packets left, in that case
  569                  * we prepare to come back later
  570                  */
  571                 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
  572                         CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
  573                 goto done;
  574         }
  575         goto startagain;
  576 done:;
  577         return;
  578 }
  579 
  580 void
  581 ep_intr(void *arg)
  582 {
  583         struct ep_softc *sc;
  584 
  585         sc = (struct ep_softc *) arg;
  586         EP_LOCK(sc);
  587         ep_intr_locked(sc);
  588         EP_UNLOCK(sc);
  589 }
  590 
  591 static void
  592 ep_intr_locked(struct ep_softc *sc)
  593 {
  594         int status;
  595         struct ifnet *ifp;
  596 
  597         /* XXX 4.x splbio'd here to reduce interruptability */
  598 
  599         /*
  600          * quick fix: Try to detect an interrupt when the card goes away.
  601          */
  602         if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff)
  603                 return;
  604         ifp = sc->ifp;
  605 
  606         CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);     /* disable all Ints */
  607 
  608 rescan:
  609 
  610         while ((status = CSR_READ_2(sc, EP_STATUS)) & S_5_INTS) {
  611 
  612                 /* first acknowledge all interrupt sources */
  613                 CSR_WRITE_2(sc, EP_COMMAND, ACK_INTR | (status & S_MASK));
  614 
  615                 if (status & (S_RX_COMPLETE | S_RX_EARLY))
  616                         epread(sc);
  617                 if (status & S_TX_AVAIL) {
  618                         /* we need ACK */
  619                         sc->tx_timer = 0;
  620                         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  621                         GO_WINDOW(sc, 1);
  622                         CSR_READ_2(sc, EP_W1_FREE_TX);
  623                         epstart_locked(ifp);
  624                 }
  625                 if (status & S_CARD_FAILURE) {
  626                         sc->tx_timer = 0;
  627 #ifdef EP_LOCAL_STATS
  628                         device_printf(sc->dev, "\n\tStatus: %x\n", status);
  629                         GO_WINDOW(sc, 4);
  630                         printf("\tFIFO Diagnostic: %x\n",
  631                             CSR_READ_2(sc, EP_W4_FIFO_DIAG));
  632                         printf("\tStat: %x\n", sc->stat);
  633                         printf("\tIpackets=%d, Opackets=%d\n",
  634                             ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS),
  635                             ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS));
  636                         printf("\tNOF=%d, NOMB=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
  637                             sc->rx_no_first, sc->rx_no_mbuf, sc->rx_overrunf,
  638                             sc->rx_overrunl, sc->tx_underrun);
  639 #else
  640 
  641 #ifdef DIAGNOSTIC
  642                         device_printf(sc->dev,
  643                             "Status: %x (input buffer overflow)\n", status);
  644 #else
  645                         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  646 #endif
  647 
  648 #endif
  649                         epinit_locked(sc);
  650                         return;
  651                 }
  652                 if (status & S_TX_COMPLETE) {
  653                         sc->tx_timer = 0;
  654                         /*
  655                          * We need ACK. We do it at the end.
  656                          *
  657                          * We need to read TX_STATUS until we get a
  658                          * 0 status in order to turn off the interrupt flag.
  659                          */
  660                         while ((status = CSR_READ_1(sc, EP_W1_TX_STATUS)) &
  661                             TXS_COMPLETE) {
  662                                 if (status & TXS_SUCCES_INTR_REQ)
  663                                         ;       /* nothing */
  664                                 else if (status &
  665                                     (TXS_UNDERRUN | TXS_JABBER |
  666                                     TXS_MAX_COLLISION)) {
  667                                         CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
  668                                         if (status & TXS_UNDERRUN) {
  669 #ifdef EP_LOCAL_STATS
  670                                                 sc->tx_underrun++;
  671 #endif
  672                                         }
  673                                         if (status & TXS_MAX_COLLISION) {
  674                                                 /*
  675                                                  * TXS_MAX_COLLISION we
  676                                                  * shouldn't get here
  677                                                  */
  678                                                 if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
  679                                         }
  680                                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
  681                                         CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
  682                                         /*
  683                                          * To have a tx_avail_int but giving
  684                                          * the chance to the Reception
  685                                          */
  686                                         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
  687                                                 CSR_WRITE_2(sc, EP_COMMAND,
  688                                                     SET_TX_AVAIL_THRESH | 8);
  689                                 }
  690                                 /* pops up the next status */
  691                                 CSR_WRITE_1(sc, EP_W1_TX_STATUS, 0x0);
  692                         }       /* while */
  693                         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  694                         GO_WINDOW(sc, 1);
  695                         CSR_READ_2(sc, EP_W1_FREE_TX);
  696                         epstart_locked(ifp);
  697                 }       /* end TX_COMPLETE */
  698         }
  699 
  700         CSR_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH);      /* ACK int Latch */
  701 
  702         if ((status = CSR_READ_2(sc, EP_STATUS)) & S_5_INTS)
  703                 goto rescan;
  704 
  705         /* re-enable Ints */
  706         CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
  707 }
  708 
  709 static void
  710 epread(struct ep_softc *sc)
  711 {
  712         struct mbuf *top, *mcur, *m;
  713         struct ifnet *ifp;
  714         int lenthisone;
  715         short rx_fifo2, status;
  716         short rx_fifo;
  717 
  718 /* XXX Must be called with sc locked */
  719 
  720         ifp = sc->ifp;
  721         status = CSR_READ_2(sc, EP_W1_RX_STATUS);
  722 
  723 read_again:
  724 
  725         if (status & ERR_RX) {
  726                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  727                 if (status & ERR_RX_OVERRUN) {
  728                         /*
  729                          * We can think the rx latency is actually
  730                          * greather than we expect
  731                          */
  732 #ifdef EP_LOCAL_STATS
  733                         if (EP_FTST(sc, F_RX_FIRST))
  734                                 sc->rx_overrunf++;
  735                         else
  736                                 sc->rx_overrunl++;
  737 #endif
  738                 }
  739                 goto out;
  740         }
  741         rx_fifo = rx_fifo2 = status & RX_BYTES_MASK;
  742 
  743         if (EP_FTST(sc, F_RX_FIRST)) {
  744                 MGETHDR(m, M_NOWAIT, MT_DATA);
  745                 if (!m)
  746                         goto out;
  747                 if (rx_fifo >= MINCLSIZE)
  748                         MCLGET(m, M_NOWAIT);
  749                 sc->top = sc->mcur = top = m;
  750 #define EROUND  ((sizeof(struct ether_header) + 3) & ~3)
  751 #define EOFF    (EROUND - sizeof(struct ether_header))
  752                 top->m_data += EOFF;
  753 
  754                 /* Read what should be the header. */
  755                 CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
  756                     mtod(top, uint16_t *), sizeof(struct ether_header) / 2);
  757                 top->m_len = sizeof(struct ether_header);
  758                 rx_fifo -= sizeof(struct ether_header);
  759                 sc->cur_len = rx_fifo2;
  760         } else {
  761                 /* come here if we didn't have a complete packet last time */
  762                 top = sc->top;
  763                 m = sc->mcur;
  764                 sc->cur_len += rx_fifo2;
  765         }
  766 
  767         /* Reads what is left in the RX FIFO */
  768         while (rx_fifo > 0) {
  769                 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
  770                 if (lenthisone == 0) {  /* no room in this one */
  771                         mcur = m;
  772                         MGET(m, M_NOWAIT, MT_DATA);
  773                         if (!m)
  774                                 goto out;
  775                         if (rx_fifo >= MINCLSIZE)
  776                                 MCLGET(m, M_NOWAIT);
  777                         m->m_len = 0;
  778                         mcur->m_next = m;
  779                         lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
  780                 }
  781                 CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
  782                     (uint16_t *)(mtod(m, caddr_t)+m->m_len),
  783                     lenthisone / 2);
  784                 m->m_len += lenthisone;
  785                 if (lenthisone & 1)
  786                         *(mtod(m, caddr_t)+m->m_len - 1) =
  787                             CSR_READ_1(sc, EP_W1_RX_PIO_RD_1);
  788                 rx_fifo -= lenthisone;
  789         }
  790 
  791         if (status & ERR_RX_INCOMPLETE) {
  792                 /* we haven't received the complete packet */
  793                 sc->mcur = m;
  794 #ifdef EP_LOCAL_STATS
  795                 /* to know how often we come here */
  796                 sc->rx_no_first++;
  797 #endif
  798                 EP_FRST(sc, F_RX_FIRST);
  799                 status = CSR_READ_2(sc, EP_W1_RX_STATUS);
  800                 if (!(status & ERR_RX_INCOMPLETE)) {
  801                         /*
  802                          * We see if by now, the packet has completly
  803                          * arrived
  804                          */
  805                         goto read_again;
  806                 }
  807                 CSR_WRITE_2(sc, EP_COMMAND,
  808                     SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
  809                 return;
  810         }
  811         CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
  812         if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
  813         EP_FSET(sc, F_RX_FIRST);
  814         top->m_pkthdr.rcvif = sc->ifp;
  815         top->m_pkthdr.len = sc->cur_len;
  816 
  817         /*
  818          * Drop locks before calling if_input() since it may re-enter
  819          * ep_start() in the netisr case.  This would result in a
  820          * lock reversal.  Better performance might be obtained by
  821          * chaining all packets received, dropping the lock, and then
  822          * calling if_input() on each one.
  823          */
  824         EP_UNLOCK(sc);
  825         (*ifp->if_input) (ifp, top);
  826         EP_LOCK(sc);
  827         sc->top = 0;
  828         EP_BUSY_WAIT(sc);
  829         CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
  830         return;
  831 
  832 out:
  833         CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
  834         if (sc->top) {
  835                 m_freem(sc->top);
  836                 sc->top = 0;
  837 #ifdef EP_LOCAL_STATS
  838                 sc->rx_no_mbuf++;
  839 #endif
  840         }
  841         EP_FSET(sc, F_RX_FIRST);
  842         EP_BUSY_WAIT(sc);
  843         CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
  844 }
  845 
  846 static int
  847 ep_ifmedia_upd(struct ifnet *ifp)
  848 {
  849         struct ep_softc *sc = ifp->if_softc;
  850         int i = 0, j;
  851 
  852         GO_WINDOW(sc, 0);
  853         CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
  854         GO_WINDOW(sc, 4);
  855         CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
  856         GO_WINDOW(sc, 0);
  857 
  858         switch (IFM_SUBTYPE(sc->ifmedia.ifm_media)) {
  859         case IFM_10_T:
  860                 if (sc->ep_connectors & UTP) {
  861                         i = ACF_CONNECTOR_UTP;
  862                         GO_WINDOW(sc, 4);
  863                         CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, ENABLE_UTP);
  864                 }
  865                 break;
  866         case IFM_10_2:
  867                 if (sc->ep_connectors & BNC) {
  868                         i = ACF_CONNECTOR_BNC;
  869                         CSR_WRITE_2(sc, EP_COMMAND, START_TRANSCEIVER);
  870                         DELAY(DELAY_MULTIPLE * 1000);
  871                 }
  872                 break;
  873         case IFM_10_5:
  874                 if (sc->ep_connectors & AUI)
  875                         i = ACF_CONNECTOR_AUI;
  876                 break;
  877         default:
  878                 i = sc->ep_connector;
  879                 device_printf(sc->dev,
  880                     "strange connector type in EEPROM: assuming AUI\n");
  881         }
  882 
  883         GO_WINDOW(sc, 0);
  884         j = CSR_READ_2(sc, EP_W0_ADDRESS_CFG) & 0x3fff;
  885         CSR_WRITE_2(sc, EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
  886 
  887         return (0);
  888 }
  889 
  890 static void
  891 ep_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
  892 {
  893         struct ep_softc *sc = ifp->if_softc;
  894         uint16_t ms;
  895 
  896         switch (IFM_SUBTYPE(sc->ifmedia.ifm_media)) {
  897         case IFM_10_T:
  898                 GO_WINDOW(sc, 4);
  899                 ms = CSR_READ_2(sc, EP_W4_MEDIA_TYPE);
  900                 GO_WINDOW(sc, 0);
  901                 ifmr->ifm_status = IFM_AVALID;
  902                 if (ms & MT_LB) {
  903                         ifmr->ifm_status |= IFM_ACTIVE;
  904                         ifmr->ifm_active = IFM_ETHER | IFM_10_T;
  905                 } else {
  906                         ifmr->ifm_active = IFM_ETHER | IFM_NONE;
  907                 }
  908                 break;
  909         default:
  910                 ifmr->ifm_active = sc->ifmedia.ifm_media;
  911                 break;
  912         }
  913 }
  914 
  915 static int
  916 epioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  917 {
  918         struct ep_softc *sc = ifp->if_softc;
  919         struct ifreq *ifr = (struct ifreq *) data;
  920         int error = 0;
  921 
  922         switch (cmd) {
  923         case SIOCSIFFLAGS:
  924                 EP_LOCK(sc);
  925                 if (((ifp->if_flags & IFF_UP) == 0) &&
  926                     (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
  927                         epstop(sc);
  928                 } else
  929                         /* reinitialize card on any parameter change */
  930                         epinit_locked(sc);
  931                 EP_UNLOCK(sc);
  932                 break;
  933         case SIOCADDMULTI:
  934         case SIOCDELMULTI:
  935                 /*
  936                  * The Etherlink III has no programmable multicast
  937                  * filter.  We always initialize the card to be
  938                  * promiscuous to multicast, since we're always a
  939                  * member of the ALL-SYSTEMS group, so there's no
  940                  * need to process SIOC*MULTI requests.
  941                  */
  942                 error = 0;
  943                 break;
  944         case SIOCSIFMEDIA:
  945         case SIOCGIFMEDIA:
  946                 if (!sc->epb.mii_trans)
  947                         error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
  948                 else
  949                         error = EINVAL;
  950                 break;
  951         default:
  952                 error = ether_ioctl(ifp, cmd, data);
  953                 break;
  954         }
  955         return (error);
  956 }
  957 
  958 static void
  959 eptick(void *arg)
  960 {
  961         struct ep_softc *sc;
  962 
  963         sc = arg;
  964         if (sc->tx_timer != 0 && --sc->tx_timer == 0)
  965                 epwatchdog(sc);
  966         callout_reset(&sc->watchdog_timer, hz, eptick, sc);
  967 }
  968 
  969 static void
  970 epwatchdog(struct ep_softc *sc)
  971 {
  972         struct ifnet *ifp;
  973 
  974         ifp = sc->ifp;
  975         if (sc->gone)
  976                 return;
  977         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  978         epstart_locked(ifp);
  979         ep_intr_locked(sc);
  980 }
  981 
  982 static void
  983 epstop(struct ep_softc *sc)
  984 {
  985 
  986         EP_ASSERT_LOCKED(sc);
  987 
  988         CSR_WRITE_2(sc, EP_COMMAND, RX_DISABLE);
  989         CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
  990         EP_BUSY_WAIT(sc);
  991 
  992         CSR_WRITE_2(sc, EP_COMMAND, TX_DISABLE);
  993         CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
  994         DELAY(800);
  995 
  996         CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
  997         EP_BUSY_WAIT(sc);
  998         CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
  999         EP_BUSY_WAIT(sc);
 1000 
 1001         CSR_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH);
 1002         CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
 1003         CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
 1004         CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
 1005 
 1006         sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 1007         callout_stop(&sc->watchdog_timer);
 1008 }

Cache object: 90fa90a70f94b9620629feaf012f4ffa


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