LCOV - code coverage report
Current view: top level - dev/ic - elink3.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 710 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: elink3.c,v 1.95 2017/01/22 10:17:38 dlg Exp $ */
       2             : /*      $NetBSD: elink3.c,v 1.32 1997/05/14 00:22:00 thorpej Exp $      */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1996, 1997 Jonathan Stone <jonathan@NetBSD.org>
       6             :  * Copyright (c) 1994 Herb Peyerl <hpeyerl@beer.org>
       7             :  * All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  * 2. Redistributions in binary form must reproduce the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer in the
      16             :  *    documentation and/or other materials provided with the distribution.
      17             :  * 3. All advertising materials mentioning features or use of this software
      18             :  *    must display the following acknowledgement:
      19             :  *      This product includes software developed by Herb Peyerl.
      20             :  * 4. The name of Herb Peyerl may not be used to endorse or promote products
      21             :  *    derived from this software without specific prior written permission.
      22             :  *
      23             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      24             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      25             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      26             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      27             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      28             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      29             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      30             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      31             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      32             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      33             :  */
      34             : 
      35             : #include "bpfilter.h"
      36             : 
      37             : #include <sys/param.h>
      38             : #include <sys/systm.h>
      39             : #include <sys/mbuf.h>
      40             : #include <sys/socket.h>
      41             : #include <sys/ioctl.h>
      42             : #include <sys/errno.h>
      43             : #include <sys/syslog.h>
      44             : #include <sys/selinfo.h>
      45             : #include <sys/timeout.h>
      46             : #include <sys/device.h>
      47             : 
      48             : #include <net/if.h>
      49             : #include <net/if_media.h>
      50             : 
      51             : #include <netinet/in.h>
      52             : #include <netinet/if_ether.h>
      53             : 
      54             : #if NBPFILTER > 0
      55             : #include <net/bpf.h>
      56             : #endif
      57             : 
      58             : #include <machine/cpu.h>
      59             : #include <machine/bus.h>
      60             : 
      61             : #include <dev/mii/mii.h>
      62             : #include <dev/mii/miivar.h>
      63             : 
      64             : #include <dev/ic/elink3var.h>
      65             : #include <dev/ic/elink3reg.h>
      66             : 
      67             : /*
      68             :  * Structure to map media-present bits in boards to 
      69             :  * ifmedia codes and printable media names. Used for table-driven
      70             :  * ifmedia initialization.
      71             :  */
      72             : struct ep_media {
      73             :         int     epm_eeprom_data;        /* bitmask for eeprom config */
      74             :         int     epm_conn;               /* sc->ep_connectors code for medium */
      75             :         char   *epm_name;               /* name of medium */
      76             :         uint64_t        epm_ifmedia;            /* ifmedia word for medium */
      77             :         int     epm_ifdata;
      78             : };
      79             : 
      80             : /*
      81             :  * ep_media table for Vortex/Demon/Boomerang:
      82             :  * map from media-present bits in register RESET_OPTIONS+2 
      83             :  * to  ifmedia "media words" and printable names.
      84             :  *
      85             :  * XXX indexed directly by INTERNAL_CONFIG default_media field,
      86             :  * (i.e., EPMEDIA_ constants)  forcing order of entries. 
      87             :  *  Note that 3 is reserved.
      88             :  */
      89             : const struct ep_media ep_vortex_media[] = {
      90             :   { EP_PCI_UTP,        EPC_UTP, "utp",            IFM_ETHER|IFM_10_T,
      91             :        EPMEDIA_10BASE_T },
      92             :   { EP_PCI_AUI,        EPC_AUI, "aui",            IFM_ETHER|IFM_10_5,
      93             :        EPMEDIA_AUI },
      94             :   { 0,                 0,       "reserved", IFM_NONE,  EPMEDIA_RESV1 },
      95             :   { EP_PCI_BNC,        EPC_BNC, "bnc",            IFM_ETHER|IFM_10_2,
      96             :        EPMEDIA_10BASE_2 },
      97             :   { EP_PCI_100BASE_TX, EPC_100TX, "100-TX", IFM_ETHER|IFM_100_TX,
      98             :        EPMEDIA_100BASE_TX },
      99             :   { EP_PCI_100BASE_FX, EPC_100FX, "100-FX", IFM_ETHER|IFM_100_FX,
     100             :        EPMEDIA_100BASE_FX },
     101             :   { EP_PCI_100BASE_MII,EPC_MII,   "mii",    IFM_ETHER|IFM_100_TX,
     102             :        EPMEDIA_MII },
     103             :   { EP_PCI_100BASE_T4, EPC_100T4, "100-T4", IFM_ETHER|IFM_100_T4,
     104             :        EPMEDIA_100BASE_T4 }
     105             : };
     106             : 
     107             : /*
     108             :  * ep_media table for 3c509/3c509b/3c579/3c589:
     109             :  * map from media-present bits in register CNFG_CNTRL
     110             :  * (window 0, offset ?) to  ifmedia "media words" and printable names.
     111             :  */
     112             : struct ep_media ep_isa_media[] = {
     113             :   { EP_W0_CC_UTP,  EPC_UTP, "utp",   IFM_ETHER|IFM_10_T, EPMEDIA_10BASE_T },
     114             :   { EP_W0_CC_AUI,  EPC_AUI, "aui",   IFM_ETHER|IFM_10_5, EPMEDIA_AUI },
     115             :   { EP_W0_CC_BNC,  EPC_BNC, "bnc",   IFM_ETHER|IFM_10_2, EPMEDIA_10BASE_2 },
     116             : };
     117             : 
     118             : /* Map vortex reset_options bits to if_media codes. */
     119             : const uint64_t ep_default_to_media[] = {
     120             :         IFM_ETHER | IFM_10_T,
     121             :         IFM_ETHER | IFM_10_5,
     122             :         0,                      /* reserved by 3Com */
     123             :         IFM_ETHER | IFM_10_2,
     124             :         IFM_ETHER | IFM_100_TX,
     125             :         IFM_ETHER | IFM_100_FX,
     126             :         IFM_ETHER | IFM_100_TX, /* XXX really MII: need to talk to PHY */
     127             :         IFM_ETHER | IFM_100_T4,
     128             : };
     129             : 
     130             : struct cfdriver ep_cd = {
     131             :         NULL, "ep", DV_IFNET
     132             : };
     133             : 
     134             : void ep_vortex_probemedia(struct ep_softc *sc);
     135             : void ep_isa_probemedia(struct ep_softc *sc);
     136             : 
     137             : void eptxstat(struct ep_softc *);
     138             : int epstatus(struct ep_softc *);
     139             : int epioctl(struct ifnet *, u_long, caddr_t);
     140             : void epstart(struct ifnet *);
     141             : void epwatchdog(struct ifnet *);
     142             : void epreset(struct ep_softc *);
     143             : void epread(struct ep_softc *);
     144             : struct mbuf *epget(struct ep_softc *, int);
     145             : void epmbuffill(void *);
     146             : void epmbufempty(struct ep_softc *);
     147             : void epsetfilter(struct ep_softc *);
     148             : void ep_roadrunner_mii_enable(struct ep_softc *);
     149             : int epsetmedia(struct ep_softc *, int);
     150             : 
     151             : /* ifmedia callbacks */
     152             : int ep_media_change(struct ifnet *);
     153             : void ep_media_status(struct ifnet *, struct ifmediareq *);
     154             : 
     155             : /* MII callbacks */
     156             : int ep_mii_readreg(struct device *, int, int);
     157             : void ep_mii_writereg(struct device *, int, int, int);
     158             : void ep_statchg(struct device *);
     159             : 
     160             : void    ep_mii_setbit(struct ep_softc *, u_int16_t);
     161             : void    ep_mii_clrbit(struct ep_softc *, u_int16_t);
     162             : u_int16_t ep_mii_readbit(struct ep_softc *, u_int16_t);
     163             : void    ep_mii_sync(struct ep_softc *);
     164             : void    ep_mii_sendbits(struct ep_softc *, u_int32_t, int);
     165             : 
     166             : int epbusyeeprom(struct ep_softc *);
     167             : u_int16_t ep_read_eeprom(struct ep_softc *, u_int16_t);
     168             : 
     169             : static inline void ep_reset_cmd(struct ep_softc *sc, u_int cmd,u_int arg);
     170             : static inline void ep_finish_reset(bus_space_tag_t, bus_space_handle_t);
     171             : static inline void ep_discard_rxtop(bus_space_tag_t, bus_space_handle_t);
     172             : static __inline int ep_w1_reg(struct ep_softc *, int);
     173             : 
     174             : /*
     175             :  * Issue a (reset) command, and be sure it has completed.
     176             :  * Used for global reset, TX_RESET, RX_RESET.
     177             :  */
     178             : static inline void
     179           0 : ep_reset_cmd(struct ep_softc *sc, u_int cmd, u_int arg)
     180             : {
     181           0 :         bus_space_tag_t iot = sc->sc_iot;
     182           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     183             : 
     184           0 :         bus_space_write_2(iot, ioh, cmd, arg);
     185           0 :         ep_finish_reset(iot, ioh);
     186           0 : }
     187             : 
     188             : /*
     189             :  * Wait for any pending reset to complete.
     190             :  */
     191             : static inline void
     192           0 : ep_finish_reset(bus_space_tag_t iot, bus_space_handle_t ioh)
     193             : {
     194             :         int i;
     195             : 
     196           0 :         for (i = 0; i < 10000; i++) {
     197           0 :                 if ((bus_space_read_2(iot, ioh, EP_STATUS) &
     198           0 :                     S_COMMAND_IN_PROGRESS) == 0)
     199             :                         break;
     200           0 :                 DELAY(10);
     201             :         }
     202           0 : }
     203             : 
     204             : static inline void
     205           0 : ep_discard_rxtop(bus_space_tag_t iot, bus_space_handle_t ioh)
     206             : {
     207             :         int i;
     208             : 
     209           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISCARD_TOP_PACK);
     210             : 
     211             :         /*
     212             :          * Spin for about 1 msec, to avoid forcing a DELAY() between
     213             :          * every received packet (adding latency and limiting pkt-recv rate).
     214             :          * On PCI, at 4 30-nsec PCI bus cycles for a read, 8000 iterations
     215             :          * is about right.
     216             :          */
     217           0 :         for (i = 0; i < 8000; i++) {
     218           0 :                 if ((bus_space_read_2(iot, ioh, EP_STATUS) &
     219           0 :                     S_COMMAND_IN_PROGRESS) == 0)
     220           0 :                         return;
     221             :         }
     222             : 
     223             :         /* not fast enough, do DELAY()s */
     224           0 :         ep_finish_reset(iot, ioh);
     225           0 : }
     226             : 
     227             : /*
     228             :  * Some chips (i.e., 3c574 RoadRunner) have Window 1 registers offset.
     229             :  */
     230             : static __inline int
     231           0 : ep_w1_reg(struct ep_softc *sc, int reg)
     232             : {
     233           0 :         switch (sc->ep_chipset) {
     234             :         case EP_CHIPSET_ROADRUNNER:
     235           0 :                 switch (reg) {
     236             :                 case EP_W1_FREE_TX:
     237             :                 case EP_W1_RUNNER_RDCTL:
     238             :                 case EP_W1_RUNNER_WRCTL:
     239           0 :                         return (reg);
     240             :                 }
     241           0 :                 return (reg + 0x10);
     242             :         }
     243           0 :         return (reg);
     244           0 : }
     245             : 
     246             : /*
     247             :  * Back-end attach and configure.
     248             :  */
     249             : void
     250           0 : epconfig(struct ep_softc *sc, u_short chipset, u_int8_t *enaddr)
     251             : {
     252           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     253           0 :         bus_space_tag_t iot = sc->sc_iot;
     254           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     255             :         u_int16_t i;
     256             : 
     257           0 :         sc->ep_chipset = chipset;
     258             : 
     259             :         /*
     260             :          * We could have been groveling around in other register
     261             :          * windows in the front-end; make sure we're in window 0
     262             :          * to read the EEPROM.
     263             :          */
     264           0 :         GO_WINDOW(0);
     265             : 
     266           0 :         if (enaddr == NULL) {
     267             :                 /*
     268             :                  * Read the station address from the eeprom.
     269             :                  */
     270           0 :                 for (i = 0; i < 3; i++) {
     271           0 :                         u_int16_t x = ep_read_eeprom(sc, i);
     272             : 
     273           0 :                         sc->sc_arpcom.ac_enaddr[(i << 1)] = x >> 8;
     274           0 :                         sc->sc_arpcom.ac_enaddr[(i << 1) + 1] = x;
     275             :                 }
     276             :         } else {
     277           0 :                 bcopy(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
     278             :         }
     279             : 
     280           0 :         printf(" address %s", ether_sprintf(sc->sc_arpcom.ac_enaddr));
     281           0 :         if (sc->ep_flags & EP_FLAGS_MII)
     282           0 :                 printf("\n");
     283             :         else
     284           0 :                 printf(", ");
     285             : 
     286             :         /*
     287             :          * Vortex-based (3c59x pci,eisa) cards allow FDDI-sized (4500) byte
     288             :          * packets.  Commands only take an 11-bit parameter, and  11 bits
     289             :          * isn't enough to hold a full-size packet length.
     290             :          * Commands to these cards implicitly upshift a packet size
     291             :          * or threshold by 2 bits. 
     292             :          * To detect  cards with large-packet support, we probe by setting
     293             :          * the transmit threshold register, then change windows and
     294             :          * read back the threshold register directly, and see if the
     295             :          * threshold value was shifted or not.
     296             :          */
     297           0 :         bus_space_write_2(iot, ioh, EP_COMMAND,
     298             :                           SET_TX_AVAIL_THRESH | EP_LARGEWIN_PROBE ); 
     299           0 :         GO_WINDOW(5);
     300           0 :         i = bus_space_read_2(iot, ioh, EP_W5_TX_AVAIL_THRESH);
     301           0 :         GO_WINDOW(1);
     302           0 :         switch (i)  {
     303             :         case EP_LARGEWIN_PROBE:
     304             :         case (EP_LARGEWIN_PROBE & EP_LARGEWIN_MASK):
     305           0 :                 sc->txashift = 0;
     306           0 :                 break;
     307             : 
     308             :         case (EP_LARGEWIN_PROBE << 2):
     309           0 :                 sc->txashift = 2;
     310             :                 /* XXX does the 3c515 support Vortex-style RESET_OPTIONS? */
     311           0 :                 break;
     312             : 
     313             :         default:
     314           0 :                 printf("wrote %x to TX_AVAIL_THRESH, read back %x. "
     315             :                     "Interface disabled\n", EP_THRESH_DISABLE, (int) i);
     316           0 :                 return;
     317             :         }
     318             : 
     319           0 :         timeout_set(&sc->sc_epmbuffill_tmo, epmbuffill, sc);
     320             : 
     321             :         /*
     322             :          * Ensure Tx-available interrupts are enabled for 
     323             :          * start the interface.
     324             :          * XXX should be in epinit()?
     325             :          */
     326           0 :         bus_space_write_2(iot, ioh, EP_COMMAND,
     327             :             SET_TX_AVAIL_THRESH | (1600 >> sc->txashift));
     328             : 
     329           0 :         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
     330           0 :         ifp->if_softc = sc;
     331           0 :         ifp->if_start = epstart;
     332           0 :         ifp->if_ioctl = epioctl;
     333           0 :         ifp->if_watchdog = epwatchdog;
     334           0 :         ifp->if_flags =
     335             :             IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     336             :         /* 64 packets are around 100ms on 10Mbps */
     337           0 :         IFQ_SET_MAXLEN(&ifp->if_snd, 64);
     338             : 
     339           0 :         if_attach(ifp);
     340           0 :         ether_ifattach(ifp);
     341             : 
     342             :         /*
     343             :          * Finish configuration: 
     344             :          * determine chipset if the front-end couldn't do so,
     345             :          * show board details, set media.
     346             :          */
     347             : 
     348           0 :         GO_WINDOW(0);
     349             : 
     350           0 :         ifmedia_init(&sc->sc_mii.mii_media, 0, ep_media_change,
     351             :             ep_media_status);
     352           0 :         sc->sc_mii.mii_ifp = ifp;
     353           0 :         sc->sc_mii.mii_readreg = ep_mii_readreg;
     354           0 :         sc->sc_mii.mii_writereg = ep_mii_writereg;
     355           0 :         sc->sc_mii.mii_statchg = ep_statchg;
     356             : 
     357             :         /*
     358             :          * If we've got an indirect (ISA, PCMCIA?) board, the chipset
     359             :          * is unknown.  If the board has large-packet support, it's a
     360             :          * Vortex/Boomerang, otherwise it's a 3c509.
     361             :          * XXX use eeprom capability word instead?
     362             :          */
     363           0 :         if (sc->ep_chipset == EP_CHIPSET_UNKNOWN && sc->txashift)  {
     364           0 :                 printf("warning: unknown chipset, possibly 3c515?\n");
     365             : #ifdef notyet
     366             :                 sc->sc_chipset = EP_CHIPSET_VORTEX;
     367             : #endif  /* notyet */
     368           0 :         }
     369             : 
     370             :         /*
     371             :          * Ascertain which media types are present and inform ifmedia.
     372             :          */
     373           0 :         switch (sc->ep_chipset) {
     374             :         case EP_CHIPSET_ROADRUNNER:
     375           0 :                 if (sc->ep_flags & EP_FLAGS_MII) {
     376           0 :                         ep_roadrunner_mii_enable(sc);
     377           0 :                         GO_WINDOW(0);
     378           0 :                 }
     379             :                 /* FALLTHROUGH */
     380             : 
     381             :         case EP_CHIPSET_BOOMERANG:
     382             :                 /*
     383             :                  * If the device has MII, probe it.  We won't be using
     384             :                  * any `native' media in this case, only PHYs.  If
     385             :                  * we don't, just treat the Boomerang like the Vortex.
     386             :                  */
     387           0 :                 if (sc->ep_flags & EP_FLAGS_MII) {
     388           0 :                         mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff,
     389             :                             MII_PHY_ANY, MII_OFFSET_ANY, 0);
     390           0 :                         if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
     391           0 :                                 ifmedia_add(&sc->sc_mii.mii_media,
     392             :                                     IFM_ETHER|IFM_NONE, 0, NULL);
     393           0 :                                 ifmedia_set(&sc->sc_mii.mii_media,
     394             :                                     IFM_ETHER|IFM_NONE);
     395           0 :                         } else {
     396           0 :                                 ifmedia_set(&sc->sc_mii.mii_media,
     397             :                                     IFM_ETHER|IFM_AUTO);
     398             :                         }
     399             :                         break;
     400             :                 }
     401             :                 /* FALLTHROUGH */
     402             : 
     403             :         /* on a direct bus, the attach routine can tell, but check anyway. */
     404             :         case EP_CHIPSET_VORTEX:
     405             :         case EP_CHIPSET_BOOMERANG2:
     406           0 :                 ep_vortex_probemedia(sc);
     407           0 :                 break;
     408             : 
     409             :         /* on ISA we can't yet tell 3c509 from 3c515. Assume the former. */
     410             :         case EP_CHIPSET_3C509:
     411             :         default:
     412           0 :                 ep_isa_probemedia(sc);
     413           0 :                 break;
     414             :         }
     415             : 
     416           0 :         GO_WINDOW(1);           /* Window 1 is operating window */
     417             : 
     418           0 :         sc->tx_start_thresh = 20;    /* probably a good starting point. */
     419             : 
     420           0 :         ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
     421           0 :         ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
     422           0 : }
     423             : 
     424             : int
     425           0 : ep_detach(struct device *self)
     426             : {
     427           0 :         struct ep_softc *sc = (struct ep_softc *)self;
     428           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     429             : 
     430           0 :         if (sc->ep_flags & EP_FLAGS_MII)
     431           0 :                 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
     432             : 
     433           0 :         ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
     434             : 
     435           0 :         ether_ifdetach(ifp);
     436           0 :         if_detach(ifp);
     437             : 
     438           0 :         return (0);
     439             : }
     440             : 
     441             : /*
     442             :  * Find supported media on 3c509-generation hardware that doesn't have
     443             :  * a "reset_options" register in window 3.
     444             :  * Use the config_cntrl register  in window 0 instead.
     445             :  * Used on original, 10Mbit ISA (3c509), 3c509B, and pre-Demon EISA cards
     446             :  * that implement  CONFIG_CTRL.  We don't have a good way to set the
     447             :  * default active medium; punt to ifconfig instead.
     448             :  *
     449             :  * XXX what about 3c515, pcmcia 10/100?
     450             :  */
     451             : void
     452           0 : ep_isa_probemedia(struct ep_softc *sc)
     453             : {
     454           0 :         bus_space_tag_t iot = sc->sc_iot;
     455           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     456           0 :         struct ifmedia *ifm = &sc->sc_mii.mii_media;
     457             :         int     conn, i;
     458             :         u_int16_t ep_w0_config, port;
     459             : 
     460             :         conn = 0;
     461           0 :         GO_WINDOW(0);
     462           0 :         ep_w0_config = bus_space_read_2(iot, ioh, EP_W0_CONFIG_CTRL);
     463           0 :         for (i = 0; i < nitems(ep_isa_media); i++) {
     464           0 :                 struct ep_media * epm = ep_isa_media + i;
     465             : 
     466           0 :                 if ((ep_w0_config & epm->epm_eeprom_data) != 0) {
     467           0 :                         ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_ifdata, 0);
     468           0 :                         if (conn)
     469           0 :                                 printf("/");
     470           0 :                         printf("%s", epm->epm_name);
     471           0 :                         conn |= epm->epm_conn;
     472           0 :                 }
     473             :         }
     474           0 :         sc->ep_connectors = conn;
     475             : 
     476             :         /* get default medium from EEPROM */
     477           0 :         if (epbusyeeprom(sc))
     478           0 :                 return;         /* XXX why is eeprom busy? */
     479           0 :         bus_space_write_2(iot, ioh, EP_W0_EEPROM_COMMAND,
     480             :             READ_EEPROM | EEPROM_ADDR_CFG);
     481           0 :         if (epbusyeeprom(sc))
     482           0 :                 return;         /* XXX why is  eeprom busy? */
     483           0 :         port = bus_space_read_2(iot, ioh, EP_W0_EEPROM_DATA);
     484           0 :         port = port >> 14;
     485             : 
     486           0 :         printf(" (default %s)\n", ep_vortex_media[port].epm_name);
     487             : 
     488             :         /* tell ifconfig what currently-active media is. */
     489           0 :         ifmedia_set(ifm, ep_default_to_media[port]);
     490             : 
     491             :         /* XXX autoselect not yet implemented */
     492           0 : }
     493             : 
     494             : 
     495             : /*
     496             :  * Find media present on large-packet-capable elink3 devices.
     497             :  * Show onboard configuration of large-packet-capable elink3 devices
     498             :  * (Demon, Vortex, Boomerang), which do not implement CONFIG_CTRL in window 0.
     499             :  * Use media and card-version info in window 3 instead.
     500             :  *
     501             :  * XXX how much of this works with 3c515, pcmcia 10/100?
     502             :  */
     503             : void
     504           0 : ep_vortex_probemedia(struct ep_softc *sc)
     505             : {
     506           0 :         bus_space_tag_t iot = sc->sc_iot;
     507           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     508           0 :         struct ifmedia *ifm = &sc->sc_mii.mii_media;
     509             :         u_int config1, conn;
     510             :         int reset_options;
     511             :         int default_media;      /* 3-bit encoding of default (EEPROM) media */
     512             :         int autoselect;         /* boolean: should default to autoselect */
     513             :         const char *medium_name;
     514             :         register int i;
     515             : 
     516           0 :         GO_WINDOW(3);
     517           0 :         config1 = (u_int)bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2);
     518           0 :         reset_options  = (int)bus_space_read_1(iot, ioh, EP_W3_RESET_OPTIONS);
     519           0 :         GO_WINDOW(0);
     520             : 
     521           0 :         default_media = (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
     522           0 :         autoselect = (config1 & CONFIG_AUTOSELECT) >> CONFIG_AUTOSELECT_SHIFT;
     523             : 
     524             :         /* set available media options */
     525             :         conn = 0;
     526           0 :         for (i = 0; i < nitems(ep_vortex_media); i++) {
     527           0 :                 const struct ep_media *epm = ep_vortex_media + i;
     528             : 
     529           0 :                 if ((reset_options & epm->epm_eeprom_data) != 0) {
     530           0 :                         if (conn)
     531           0 :                                 printf("/");
     532           0 :                         printf("%s", epm->epm_name);
     533           0 :                         conn |= epm->epm_conn;
     534           0 :                         ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_ifdata, 0);
     535           0 :                 }
     536             :         }
     537             : 
     538           0 :         sc->ep_connectors = conn;
     539             : 
     540             :         /* Show  eeprom's idea of default media.  */
     541           0 :         medium_name = (default_media > nitems(ep_vortex_media) - 1)
     542             :                 ? "(unknown/impossible media)"
     543           0 :                 : ep_vortex_media[default_media].epm_name;
     544           0 :         printf(" default %s%s",
     545           0 :                medium_name, (autoselect) ? "/autoselect" : "");
     546             : /*      sc->sc_media = ep_vortex_media[default_media].epm_ifdata;*/
     547             : 
     548             : #ifdef notyet   
     549             :         /*
     550             :          * Set default: either the active interface the card
     551             :          * reads  from the EEPROM, or if autoselect is true,
     552             :          * whatever we find is actually connected. 
     553             :          *
     554             :          * XXX autoselect not yet implemented.
     555             :          */
     556             : #endif  /* notyet */
     557             : 
     558             :         /* tell ifconfig what currently-active media is. */
     559           0 :         ifmedia_set(ifm, ep_default_to_media[default_media]);
     560           0 : }
     561             : 
     562             : /*
     563             :  * Bring device up.
     564             :  *
     565             :  * The order in here seems important. Otherwise we may not receive
     566             :  * interrupts. ?!
     567             :  */
     568             : void
     569           0 : epinit(struct ep_softc *sc)
     570             : {
     571           0 :         register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     572           0 :         bus_space_tag_t iot = sc->sc_iot;
     573           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     574             :         int i;
     575             : 
     576             :         /* make sure any pending reset has completed before touching board */
     577           0 :         ep_finish_reset(iot, ioh);
     578             : 
     579             :         /* cancel any pending I/O */
     580           0 :         epstop(sc);
     581             : 
     582           0 :         if (sc->bustype != EP_BUS_PCI) {
     583           0 :                 GO_WINDOW(0);
     584           0 :                 bus_space_write_2(iot, ioh, EP_W0_CONFIG_CTRL, 0);
     585           0 :                 bus_space_write_2(iot, ioh, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
     586           0 :         }
     587             : 
     588           0 :         if (sc->bustype == EP_BUS_PCMCIA) {
     589           0 :                 bus_space_write_2(iot, ioh, EP_W0_RESOURCE_CFG, 0x3f00);
     590           0 :         }
     591             : 
     592           0 :         GO_WINDOW(2);
     593           0 :         for (i = 0; i < 6; i++)      /* Reload the ether_addr. */
     594           0 :                 bus_space_write_1(iot, ioh, EP_W2_ADDR_0 + i,
     595             :                     sc->sc_arpcom.ac_enaddr[i]);
     596             : 
     597           0 :         if (sc->bustype == EP_BUS_PCI || sc->bustype == EP_BUS_EISA)
     598             :                 /*
     599             :                  * Reset the station-address receive filter.
     600             :                  * A bug workaround for busmastering  (Vortex, Demon) cards.
     601             :                  */
     602           0 :                 for (i = 0; i < 6; i++)
     603           0 :                         bus_space_write_1(iot, ioh, EP_W2_RECVMASK_0 + i, 0);
     604             : 
     605           0 :         ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
     606           0 :         ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
     607             : 
     608           0 :         GO_WINDOW(1);           /* Window 1 is operating window */
     609           0 :         for (i = 0; i < 31; i++)
     610           0 :                 bus_space_read_1(iot, ioh, ep_w1_reg(sc, EP_W1_TX_STATUS));
     611             : 
     612             :         /* Set threshold for for Tx-space available interrupt. */
     613           0 :         bus_space_write_2(iot, ioh, EP_COMMAND,
     614             :             SET_TX_AVAIL_THRESH | (1600 >> sc->txashift));
     615             : 
     616           0 :         if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER) {
     617             :                 /* Enable options in the PCMCIA LAN COR register, via
     618             :                  * RoadRunner Window 1.
     619             :                  *
     620             :                  * XXX MAGIC CONSTANTS!
     621             :                  */
     622             :                 u_int16_t cor;
     623             : 
     624           0 :                 bus_space_write_2(iot, ioh, EP_W1_RUNNER_RDCTL, (1 << 11));
     625             : 
     626           0 :                 cor = bus_space_read_2(iot, ioh, 0) & ~0x30;
     627           0 :                 bus_space_write_2(iot, ioh, 0, cor);
     628             : 
     629           0 :                 bus_space_write_2(iot, ioh, EP_W1_RUNNER_WRCTL, 0);
     630           0 :                 bus_space_write_2(iot, ioh, EP_W1_RUNNER_RDCTL, 0);
     631             : 
     632           0 :                 if (sc->ep_flags & EP_FLAGS_MII) {
     633           0 :                         ep_roadrunner_mii_enable(sc);
     634           0 :                         GO_WINDOW(1);
     635           0 :                 }
     636           0 :         }
     637             : 
     638             :         /* Enable interrupts. */
     639           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK |
     640             :             S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
     641           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK |
     642             :             S_CARD_FAILURE | S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
     643             : 
     644             :         /*
     645             :          * Attempt to get rid of any stray interrupts that occurred during
     646             :          * configuration.  On the i386 this isn't possible because one may
     647             :          * already be queued.  However, a single stray interrupt is
     648             :          * unimportant.
     649             :          */
     650           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR | 0xff);
     651             : 
     652           0 :         epsetfilter(sc);
     653           0 :         epsetmedia(sc, sc->sc_mii.mii_media.ifm_cur->ifm_data);
     654             : 
     655           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, RX_ENABLE);
     656           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
     657             : 
     658           0 :         epmbuffill(sc);
     659             : 
     660             :         /* Interface is now `running', with no output active. */
     661           0 :         ifp->if_flags |= IFF_RUNNING;
     662           0 :         ifq_clr_oactive(&ifp->if_snd);
     663             : 
     664             :         /* Attempt to start output, if any. */
     665           0 :         epstart(ifp);
     666           0 : }
     667             : 
     668             : /*
     669             :  * Set multicast receive filter. 
     670             :  * elink3 hardware has no selective multicast filter in hardware.
     671             :  * Enable reception of all multicasts and filter in software.
     672             :  */
     673             : void
     674           0 : epsetfilter(struct ep_softc *sc)
     675             : {
     676           0 :         register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
     677             : 
     678           0 :         GO_WINDOW(1);           /* Window 1 is operating window */
     679           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_COMMAND, SET_RX_FILTER |
     680             :             FIL_INDIVIDUAL | FIL_BRDCST |
     681             :             ((ifp->if_flags & IFF_MULTICAST) ? FIL_MULTICAST : 0 ) |
     682             :             ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0 ));
     683           0 : }
     684             : 
     685             : 
     686             : int
     687           0 : ep_media_change(struct ifnet *ifp)
     688             : {
     689           0 :         register struct ep_softc *sc = ifp->if_softc;
     690             : 
     691           0 :         return  epsetmedia(sc, sc->sc_mii.mii_media.ifm_cur->ifm_data);
     692             : }
     693             : 
     694             : /*
     695             :  * Reset and enable the MII on the RoadRunner.
     696             :  */
     697             : void
     698           0 : ep_roadrunner_mii_enable(struct ep_softc *sc)
     699             : {
     700           0 :         bus_space_tag_t iot = sc->sc_iot;
     701           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     702             : 
     703           0 :         GO_WINDOW(3);
     704           0 :         bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
     705             :             EP_PCI_100BASE_MII|EP_RUNNER_ENABLE_MII);
     706           0 :         delay(1000);
     707           0 :         bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
     708             :             EP_PCI_100BASE_MII|EP_RUNNER_MII_RESET|EP_RUNNER_ENABLE_MII);
     709           0 :         ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
     710           0 :         ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
     711           0 :         delay(1000);
     712           0 :         bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
     713             :             EP_PCI_100BASE_MII|EP_RUNNER_ENABLE_MII);
     714           0 : }
     715             : 
     716             : /*
     717             :  * Set active media to a specific given EPMEDIA_<> value.
     718             :  * For vortex/demon/boomerang cards, update media field in w3_internal_config,
     719             :  *       and power on selected transceiver.
     720             :  * For 3c509-generation cards (3c509/3c579/3c589/3c509B),
     721             :  *      update media field in w0_address_config, and power on selected xcvr.
     722             :  */
     723             : int
     724           0 : epsetmedia(struct ep_softc *sc, int medium)
     725             : {
     726           0 :         bus_space_tag_t iot = sc->sc_iot;
     727           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     728             :         int w4_media;
     729             :         int config0, config1;
     730             : 
     731             :         /*
     732             :          * you can `ifconfig (link0|-link0) ep0' to get the following
     733             :          * behaviour:
     734             :          *      -link0  disable AUI/UTP. enable BNC.
     735             :          *      link0   disable BNC. enable AUI.
     736             :          *      link1   if the card has a UTP connector, and link0 is
     737             :          *              set too, then you get the UTP port.
     738             :          */
     739             : 
     740             :         /*
     741             :          * First, change the media-control bits in EP_W4_MEDIA_TYPE.
     742             :          */
     743             : 
     744             :          /* Turn everything off.  First turn off linkbeat and UTP. */
     745           0 :         GO_WINDOW(4);
     746           0 :         w4_media = bus_space_read_2(iot, ioh, EP_W4_MEDIA_TYPE);
     747           0 :         w4_media =  w4_media & ~(ENABLE_UTP|SQE_ENABLE);
     748           0 :         bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, w4_media);
     749             : 
     750             :         /* Turn off coax */
     751           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
     752           0 :         delay(1000);
     753             : 
     754             :         /* If the device has MII, select it, and then tell the
     755             :          * PHY which media to use.
     756             :          */
     757           0 :         if (sc->ep_flags & EP_FLAGS_MII) {
     758           0 :                 GO_WINDOW(3);
     759             : 
     760           0 :                 if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER) {
     761             :                         int resopt;
     762             : 
     763           0 :                         resopt = bus_space_read_2(iot, ioh,
     764             :                             EP_W3_RESET_OPTIONS);
     765           0 :                         bus_space_write_2(iot, ioh, EP_W3_RESET_OPTIONS,
     766             :                             resopt | EP_RUNNER_ENABLE_MII);
     767           0 :                 }
     768             : 
     769           0 :                 config0 = (u_int)bus_space_read_2(iot, ioh,
     770             :                     EP_W3_INTERNAL_CONFIG);
     771           0 :                 config1 = (u_int)bus_space_read_2(iot, ioh,
     772             :                     EP_W3_INTERNAL_CONFIG + 2);
     773             : 
     774           0 :                 config1 = config1 & ~CONFIG_MEDIAMASK;
     775           0 :                 config1 |= (EPMEDIA_MII << CONFIG_MEDIAMASK_SHIFT);
     776             : 
     777           0 :                 bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG, config0);
     778           0 :                 bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2, config1);
     779           0 :                 GO_WINDOW(1);   /* back to operating window */
     780             : 
     781           0 :                 mii_mediachg(&sc->sc_mii);
     782           0 :                 return (0);
     783             :         }
     784             : 
     785             :         /*
     786             :          * Now turn on the selected media/transceiver.
     787             :          */
     788           0 :         GO_WINDOW(4);
     789           0 :         switch (medium) {
     790             :         case EPMEDIA_10BASE_T:
     791           0 :                 bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE, (ENABLE_UTP |
     792             :                     (sc->bustype == EP_BUS_PCMCIA ? MEDIA_LED : 0)));
     793           0 :                 break;
     794             : 
     795             :         case EPMEDIA_10BASE_2:
     796           0 :                 bus_space_write_2(iot, ioh, EP_COMMAND, START_TRANSCEIVER);
     797           0 :                 DELAY(1000);    /* 50ms not enough? */
     798           0 :                 break;
     799             : 
     800             :         /* XXX following only for new-generation cards */
     801             :         case EPMEDIA_100BASE_TX:
     802             :         case EPMEDIA_100BASE_FX:
     803             :         case EPMEDIA_100BASE_T4:        /* XXX check documentation */
     804           0 :                 bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE,
     805             :                     w4_media | LINKBEAT_ENABLE);
     806           0 :                 DELAY(1000);    /* not strictly necessary? */
     807           0 :                 break;
     808             : 
     809             :         case EPMEDIA_AUI:
     810           0 :                 bus_space_write_2(iot, ioh, EP_W4_MEDIA_TYPE,
     811             :                     w4_media | SQE_ENABLE);
     812           0 :                 DELAY(1000);    /*  not strictly necessary? */
     813           0 :                 break;
     814             :         case EPMEDIA_MII:
     815             :                 break;
     816             :         default:
     817             : #if defined(EP_DEBUG)
     818             :                 printf("%s unknown media 0x%x\n", sc->sc_dev.dv_xname, medium);
     819             : #endif
     820             :                 break;
     821             :                 
     822             :         }
     823             : 
     824             :         /*
     825             :          * Tell the chip which PHY [sic] to use.
     826             :          */
     827           0 :         switch (sc->ep_chipset) {
     828             :         case EP_CHIPSET_VORTEX:
     829             :         case EP_CHIPSET_BOOMERANG2:
     830           0 :                 GO_WINDOW(3);
     831           0 :                 config0 = (u_int)bus_space_read_2(iot, ioh,
     832             :                     EP_W3_INTERNAL_CONFIG);
     833           0 :                 config1 = (u_int)bus_space_read_2(iot, ioh,
     834             :                     EP_W3_INTERNAL_CONFIG + 2);
     835             : 
     836             : #if defined(EP_DEBUG)
     837             :                 printf("%s:  read 0x%x, 0x%x from EP_W3_CONFIG register\n",
     838             :                        sc->sc_dev.dv_xname, config0, config1);
     839             : #endif
     840           0 :                 config1 = config1 & ~CONFIG_MEDIAMASK;
     841           0 :                 config1 |= (medium << CONFIG_MEDIAMASK_SHIFT);
     842             :                 
     843             : #if defined(EP_DEBUG)
     844             :                 printf("epsetmedia: %s: medium 0x%x, 0x%x to EP_W3_CONFIG\n",
     845             :                     sc->sc_dev.dv_xname, medium, config1);
     846             : #endif
     847           0 :                 bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG, config0);
     848           0 :                 bus_space_write_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2, config1);
     849           0 :                 break;
     850             : 
     851             :         default:
     852           0 :                 GO_WINDOW(0);
     853           0 :                 config0 = bus_space_read_2(iot, ioh, EP_W0_ADDRESS_CFG);
     854           0 :                 config0 &= 0x3fff;
     855           0 :                 bus_space_write_2(iot, ioh, EP_W0_ADDRESS_CFG,
     856             :                     config0 | (medium << 14));
     857           0 :                 DELAY(1000);
     858           0 :                 break;
     859             :         }
     860             : 
     861           0 :         GO_WINDOW(1);           /* Window 1 is operating window */
     862           0 :         return (0);
     863           0 : }
     864             : 
     865             : 
     866             : /*
     867             :  * Get currently-selected media from card.
     868             :  * (if_media callback, may be called before interface is brought up).
     869             :  */
     870             : void
     871           0 : ep_media_status(struct ifnet *ifp, struct ifmediareq *req)
     872             : {
     873           0 :         register struct ep_softc *sc = ifp->if_softc;
     874           0 :         bus_space_tag_t iot = sc->sc_iot;
     875           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     876             :         u_int config1;
     877             :         u_int ep_mediastatus;
     878             : 
     879             :         /*
     880             :          * If we have MII, go ask the PHY what's going on.
     881             :          */
     882           0 :         if (sc->ep_flags & EP_FLAGS_MII) {
     883           0 :                 mii_pollstat(&sc->sc_mii);
     884           0 :                 req->ifm_active = sc->sc_mii.mii_media_active;
     885           0 :                 req->ifm_status = sc->sc_mii.mii_media_status;
     886           0 :                 return;
     887             :         }
     888             : 
     889             :         /* XXX read from softc when we start autosensing media */
     890           0 :         req->ifm_active = sc->sc_mii.mii_media.ifm_cur->ifm_media;
     891             :         
     892           0 :         switch (sc->ep_chipset) {
     893             :         case EP_CHIPSET_VORTEX:
     894             :         case EP_CHIPSET_BOOMERANG:
     895           0 :                 GO_WINDOW(3);
     896           0 :                 delay(5000);
     897             : 
     898           0 :                 config1 = bus_space_read_2(iot, ioh, EP_W3_INTERNAL_CONFIG + 2);
     899           0 :                 GO_WINDOW(1);
     900             : 
     901             :                 config1 = 
     902           0 :                     (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT;
     903           0 :                 req->ifm_active = ep_default_to_media[config1];
     904             : 
     905             :                 /* XXX check full-duplex bits? */
     906             : 
     907           0 :                 GO_WINDOW(4);
     908           0 :                 req->ifm_status = IFM_AVALID;        /* XXX */
     909           0 :                 ep_mediastatus = bus_space_read_2(iot, ioh, EP_W4_MEDIA_TYPE);
     910           0 :                 if (ep_mediastatus & LINKBEAT_DETECT)
     911           0 :                         req->ifm_status |= IFM_ACTIVE;       /* XXX  automedia */
     912             : 
     913             :                 break;
     914             : 
     915             :         case EP_CHIPSET_UNKNOWN:
     916             :         case EP_CHIPSET_3C509:
     917           0 :                 req->ifm_status = 0; /* XXX */
     918           0 :                 break;
     919             : 
     920             :         default:
     921           0 :                 printf("%s: media_status on unknown chipset 0x%x\n",
     922           0 :                        ifp->if_xname, sc->ep_chipset);
     923           0 :                 break;
     924             :         }
     925             : 
     926             :         /* XXX look for softc heartbeat for other chips or media */
     927             : 
     928           0 :         GO_WINDOW(1);
     929           0 :         return;
     930           0 : }
     931             : 
     932             : 
     933             : 
     934             : /*
     935             :  * Start outputting on the interface.
     936             :  * Always called as splnet().
     937             :  */
     938             : void
     939           0 : epstart(struct ifnet *ifp)
     940             : {
     941           0 :         register struct ep_softc *sc = ifp->if_softc;
     942           0 :         bus_space_tag_t iot = sc->sc_iot;
     943           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     944             :         struct mbuf *m, *m0;
     945             :         caddr_t data;
     946             :         int sh, len, pad, txreg;
     947             : 
     948             :         /* Don't transmit if interface is busy or not running */
     949           0 :         if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
     950           0 :                 return;
     951             : 
     952             : startagain:
     953             :         /* Sneak a peek at the next packet */
     954           0 :         m0 = ifq_deq_begin(&ifp->if_snd);
     955           0 :         if (m0 == NULL)
     956           0 :                 return;
     957             : 
     958             :         /* We need to use m->m_pkthdr.len, so require the header */
     959           0 :         if ((m0->m_flags & M_PKTHDR) == 0)
     960           0 :                 panic("epstart: no header mbuf");
     961           0 :         len = m0->m_pkthdr.len;
     962             : 
     963           0 :         pad = (4 - len) & 3;
     964             : 
     965             :         /*
     966             :          * The 3c509 automatically pads short packets to minimum ethernet
     967             :          * length, but we drop packets that are too large. Perhaps we should
     968             :          * truncate them instead?
     969             :          */
     970           0 :         if (len + pad > ETHER_MAX_LEN) {
     971             :                 /* packet is obviously too large: toss it */
     972           0 :                 ++ifp->if_oerrors;
     973           0 :                 ifq_deq_commit(&ifp->if_snd, m0);
     974           0 :                 m_freem(m0);
     975           0 :                 goto readcheck;
     976             :         }
     977             : 
     978           0 :         if (bus_space_read_2(iot, ioh, ep_w1_reg(sc, EP_W1_FREE_TX)) <
     979           0 :             len + pad + 4) {
     980           0 :                 bus_space_write_2(iot, ioh, EP_COMMAND,
     981             :                     SET_TX_AVAIL_THRESH | ((len + pad + 4) >> sc->txashift));
     982             :                 /* not enough room in FIFO */
     983           0 :                 ifq_deq_rollback(&ifp->if_snd, m0);
     984           0 :                 ifq_set_oactive(&ifp->if_snd);
     985           0 :                 return;
     986             :         } else {
     987           0 :                 bus_space_write_2(iot, ioh, EP_COMMAND,
     988             :                     SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
     989             :         }
     990             : 
     991           0 :         ifq_deq_commit(&ifp->if_snd, m0);
     992           0 :         if (m0 == NULL)
     993           0 :                 return;
     994             : 
     995           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, SET_TX_START_THRESH |
     996             :             ((len / 4 + sc->tx_start_thresh) /*>> sc->txashift*/));
     997             : 
     998             : #if NBPFILTER > 0
     999           0 :         if (ifp->if_bpf)
    1000           0 :                 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
    1001             : #endif
    1002             : 
    1003             :         /*
    1004             :          * Do the output at splhigh() so that an interrupt from another device
    1005             :          * won't cause a FIFO underrun.
    1006             :          */
    1007           0 :         sh = splhigh();
    1008             : 
    1009           0 :         txreg = ep_w1_reg(sc, EP_W1_TX_PIO_WR_1);
    1010             : 
    1011           0 :         bus_space_write_2(iot, ioh, txreg, len);
    1012           0 :         bus_space_write_2(iot, ioh, txreg, 0xffff); /* Second is meaningless */
    1013           0 :         if (EP_IS_BUS_32(sc->bustype)) {
    1014           0 :                 for (m = m0; m; ) {
    1015           0 :                         data = mtod(m, u_int8_t *);
    1016           0 :                         if (m->m_len > 3 && ALIGNED_POINTER(data, uint32_t)) {
    1017           0 :                                 bus_space_write_raw_multi_4(iot, ioh, txreg,
    1018             :                                     data, m->m_len & ~3);
    1019           0 :                                 if (m->m_len & 3)
    1020           0 :                                         bus_space_write_multi_1(iot, ioh, txreg,
    1021             :                                             data + (m->m_len & ~3),
    1022             :                                             m->m_len & 3);
    1023             :                         } else
    1024           0 :                                 bus_space_write_multi_1(iot, ioh, txreg,
    1025             :                                     data, m->m_len);
    1026           0 :                         m0 = m_free(m);
    1027             :                         m = m0;
    1028             :                 }
    1029             :         } else {
    1030           0 :                 for (m = m0; m; ) {
    1031           0 :                         data = mtod(m, u_int8_t *);
    1032           0 :                         if (m->m_len > 1 && ALIGNED_POINTER(data, uint16_t)) {
    1033           0 :                                 bus_space_write_raw_multi_2(iot, ioh, txreg,
    1034             :                                     data, m->m_len & ~1);
    1035           0 :                                 if (m->m_len & 1)
    1036           0 :                                         bus_space_write_1(iot, ioh, txreg,
    1037             :                                              *(data + m->m_len - 1));
    1038             :                         } else
    1039           0 :                                 bus_space_write_multi_1(iot, ioh, txreg,
    1040             :                                     data, m->m_len);
    1041           0 :                         m0 = m_free(m);
    1042             :                         m = m0;
    1043             :                 }
    1044             :         }
    1045           0 :         while (pad--)
    1046           0 :                 bus_space_write_1(iot, ioh, txreg, 0);
    1047             : 
    1048           0 :         splx(sh);
    1049             : 
    1050             : readcheck:
    1051           0 :         if ((bus_space_read_2(iot, ioh, ep_w1_reg(sc, EP_W1_RX_STATUS)) &
    1052           0 :             ERR_INCOMPLETE) == 0) {
    1053             :                 /* We received a complete packet. */
    1054           0 :                 u_int16_t status = bus_space_read_2(iot, ioh, EP_STATUS);
    1055             : 
    1056           0 :                 if ((status & S_INTR_LATCH) == 0) {
    1057             :                         /*
    1058             :                          * No interrupt, read the packet and continue
    1059             :                          * Is  this supposed to happen? Is my motherboard 
    1060             :                          * completely busted?
    1061             :                          */
    1062           0 :                         epread(sc);
    1063             :                 } else
    1064             :                         /* Got an interrupt, return to get it serviced. */
    1065           0 :                         return;
    1066           0 :         } else {
    1067             :                 /* Check if we are stuck and reset [see XXX comment] */
    1068           0 :                 if (epstatus(sc)) {
    1069             : #ifdef EP_DEBUG
    1070             :                         if (ifp->if_flags & IFF_DEBUG)
    1071             :                                 printf("%s: adapter reset\n",
    1072             :                                     sc->sc_dev.dv_xname);
    1073             : #endif
    1074           0 :                         epreset(sc);
    1075           0 :                 }
    1076             :         }
    1077             : 
    1078           0 :         goto startagain;
    1079           0 : }
    1080             : 
    1081             : 
    1082             : /*
    1083             :  * XXX: The 3c509 card can get in a mode where both the fifo status bit
    1084             :  *      FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
    1085             :  *      We detect this situation and we reset the adapter.
    1086             :  *      It happens at times when there is a lot of broadcast traffic
    1087             :  *      on the cable (once in a blue moon).
    1088             :  */
    1089             : int
    1090           0 : epstatus(struct ep_softc *sc)
    1091             : {
    1092           0 :         bus_space_tag_t iot = sc->sc_iot;
    1093           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1094             :         u_int16_t fifost;
    1095             : 
    1096             :         /*
    1097             :          * Check the FIFO status and act accordingly
    1098             :          */
    1099           0 :         GO_WINDOW(4);
    1100           0 :         fifost = bus_space_read_2(iot, ioh, EP_W4_FIFO_DIAG);
    1101           0 :         GO_WINDOW(1);
    1102             : 
    1103           0 :         if (fifost & FIFOS_RX_UNDERRUN) {
    1104             : #ifdef EP_DEBUG
    1105             :                 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
    1106             :                         printf("%s: RX underrun\n", sc->sc_dev.dv_xname);
    1107             : #endif
    1108           0 :                 epreset(sc);
    1109           0 :                 return 0;
    1110             :         }
    1111             : 
    1112           0 :         if (fifost & FIFOS_RX_STATUS_OVERRUN) {
    1113             : #ifdef EP_DEBUG
    1114             :                 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
    1115             :                         printf("%s: RX Status overrun\n", sc->sc_dev.dv_xname);
    1116             : #endif
    1117           0 :                 return 1;
    1118             :         }
    1119             : 
    1120           0 :         if (fifost & FIFOS_RX_OVERRUN) {
    1121             : #ifdef EP_DEBUG
    1122             :                 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
    1123             :                         printf("%s: RX overrun\n", sc->sc_dev.dv_xname);
    1124             : #endif
    1125           0 :                 return 1;
    1126             :         }
    1127             : 
    1128           0 :         if (fifost & FIFOS_TX_OVERRUN) {
    1129             : #ifdef EP_DEBUG
    1130             :                 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
    1131             :                         printf("%s: TX overrun\n", sc->sc_dev.dv_xname);
    1132             : #endif
    1133           0 :                 epreset(sc);
    1134           0 :                 return 0;
    1135             :         }
    1136             : 
    1137           0 :         return 0;
    1138           0 : }
    1139             : 
    1140             : 
    1141             : void
    1142           0 : eptxstat(struct ep_softc *sc)
    1143             : {
    1144           0 :         bus_space_tag_t iot = sc->sc_iot;
    1145           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1146             :         int i;
    1147             : 
    1148             :         /*
    1149             :          * We need to read+write TX_STATUS until we get a 0 status
    1150             :          * in order to turn off the interrupt flag.
    1151             :          */
    1152           0 :         while ((i = bus_space_read_1(iot, ioh,
    1153           0 :             ep_w1_reg(sc, EP_W1_TX_STATUS))) & TXS_COMPLETE) {
    1154           0 :                 bus_space_write_1(iot, ioh, ep_w1_reg(sc, EP_W1_TX_STATUS),
    1155             :                     0x0);
    1156             : 
    1157           0 :                 if (i & TXS_JABBER) {
    1158           0 :                         ++sc->sc_arpcom.ac_if.if_oerrors;
    1159             : #ifdef EP_DEBUG
    1160             :                         if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
    1161             :                                 printf("%s: jabber (%x)\n",
    1162             :                                        sc->sc_dev.dv_xname, i);
    1163             : #endif
    1164           0 :                         epreset(sc);
    1165           0 :                 } else if (i & TXS_UNDERRUN) {
    1166           0 :                         ++sc->sc_arpcom.ac_if.if_oerrors;
    1167             : #ifdef EP_DEBUG
    1168             :                         if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
    1169             :                                 printf("%s: fifo underrun (%x) @%d\n",
    1170             :                                        sc->sc_dev.dv_xname, i,
    1171             :                                        sc->tx_start_thresh);
    1172             : #endif
    1173           0 :                         if (sc->tx_succ_ok < 100)
    1174           0 :                                     sc->tx_start_thresh = min(ETHER_MAX_LEN,
    1175           0 :                                             sc->tx_start_thresh + 20);
    1176           0 :                         sc->tx_succ_ok = 0;
    1177           0 :                         epreset(sc);
    1178           0 :                 } else if (i & TXS_MAX_COLLISION) {
    1179           0 :                         ++sc->sc_arpcom.ac_if.if_collisions;
    1180           0 :                         bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
    1181           0 :                         ifq_clr_oactive(&sc->sc_arpcom.ac_if.if_snd);
    1182           0 :                 } else
    1183           0 :                         sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127;
    1184             :         }
    1185           0 : }
    1186             : 
    1187             : int
    1188           0 : epintr(void *arg)
    1189             : {
    1190           0 :         register struct ep_softc *sc = arg;
    1191           0 :         bus_space_tag_t iot = sc->sc_iot;
    1192           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1193           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1194             :         u_int16_t status;
    1195             :         int ret = 0;
    1196             : 
    1197           0 :         for (;;) {
    1198           0 :                 bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH);
    1199             : 
    1200           0 :                 status = bus_space_read_2(iot, ioh, EP_STATUS);
    1201             : 
    1202           0 :                 if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
    1203           0 :                                S_RX_COMPLETE | S_CARD_FAILURE)) == 0)
    1204             :                         break;
    1205             : 
    1206             :                 ret = 1;
    1207             : 
    1208             :                 /*
    1209             :                  * Acknowledge any interrupts.  It's important that we do this
    1210             :                  * first, since there would otherwise be a race condition.
    1211             :                  * Due to the i386 interrupt queueing, we may get spurious
    1212             :                  * interrupts occasionally.
    1213             :                  */
    1214           0 :                 bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR | status);
    1215             : 
    1216           0 :                 if (status & S_RX_COMPLETE)
    1217           0 :                         epread(sc);
    1218           0 :                 if (status & S_TX_AVAIL) {
    1219           0 :                         ifq_clr_oactive(&ifp->if_snd);
    1220           0 :                         epstart(ifp);
    1221           0 :                 }
    1222           0 :                 if (status & S_CARD_FAILURE) {
    1223           0 :                         epreset(sc);
    1224           0 :                         return (1);
    1225             :                 }
    1226           0 :                 if (status & S_TX_COMPLETE) {
    1227           0 :                         eptxstat(sc);
    1228           0 :                         epstart(ifp);
    1229           0 :                 }
    1230             :         }       
    1231             : 
    1232             :         /* no more interrupts */
    1233           0 :         return (ret);
    1234           0 : }
    1235             : 
    1236             : void
    1237           0 : epread(struct ep_softc *sc)
    1238             : {
    1239           0 :         bus_space_tag_t iot = sc->sc_iot;
    1240           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1241           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1242           0 :         struct mbuf_list ml = MBUF_LIST_INITIALIZER();
    1243             :         struct mbuf *m;
    1244             :         int len, error = 0;
    1245             : 
    1246           0 :         len = bus_space_read_2(iot, ioh, ep_w1_reg(sc, EP_W1_RX_STATUS));
    1247             : 
    1248             : again:
    1249             : #ifdef EP_DEBUG
    1250             :         if (ifp->if_flags & IFF_DEBUG) {
    1251             :                 int err = len & ERR_MASK;
    1252             :                 char *s = NULL;
    1253             : 
    1254             :                 if (len & ERR_INCOMPLETE)
    1255             :                         s = "incomplete packet";
    1256             :                 else if (err == ERR_OVERRUN)
    1257             :                         s = "packet overrun";
    1258             :                 else if (err == ERR_RUNT)
    1259             :                         s = "runt packet";
    1260             :                 else if (err == ERR_ALIGNMENT)
    1261             :                         s = "bad alignment";
    1262             :                 else if (err == ERR_CRC)
    1263             :                         s = "bad crc";
    1264             :                 else if (err == ERR_OVERSIZE)
    1265             :                         s = "oversized packet";
    1266             :                 else if (err == ERR_DRIBBLE)
    1267             :                         s = "dribble bits";
    1268             : 
    1269             :                 if (s)
    1270             :                         printf("%s: %s\n", sc->sc_dev.dv_xname, s);
    1271             :         }
    1272             : #endif
    1273             : 
    1274           0 :         if (len & ERR_INCOMPLETE)
    1275             :                 goto done;
    1276             : 
    1277           0 :         if (len & ERR_RX) {
    1278           0 :                 ++ifp->if_ierrors;
    1279             :                 error = 1;
    1280           0 :                 goto done;
    1281             :         }
    1282             : 
    1283           0 :         len &= RX_BYTES_MASK;       /* Lower 11 bits = RX bytes. */
    1284             : 
    1285             :         /* Pull packet off interface. */
    1286           0 :         m = epget(sc, len);
    1287           0 :         if (m == NULL) {
    1288           0 :                 ifp->if_ierrors++;
    1289             :                 error = 1;
    1290           0 :                 goto done;
    1291             :         }
    1292             : 
    1293           0 :         ml_enqueue(&ml, m);
    1294             : 
    1295             :         /*
    1296             :          * In periods of high traffic we can actually receive enough
    1297             :          * packets so that the fifo overrun bit will be set at this point,
    1298             :          * even though we just read a packet. In this case we
    1299             :          * are not going to receive any more interrupts. We check for
    1300             :          * this condition and read again until the fifo is not full.
    1301             :          * We could simplify this test by not using epstatus(), but
    1302             :          * rechecking the RX_STATUS register directly. This test could
    1303             :          * result in unnecessary looping in cases where there is a new
    1304             :          * packet but the fifo is not full, but it will not fix the
    1305             :          * stuck behavior.
    1306             :          *
    1307             :          * Even with this improvement, we still get packet overrun errors
    1308             :          * which are hurting performance. Maybe when I get some more time
    1309             :          * I'll modify epread() so that it can handle RX_EARLY interrupts.
    1310             :          */
    1311           0 :         if (epstatus(sc)) {
    1312           0 :                 len = bus_space_read_2(iot, ioh,
    1313             :                     ep_w1_reg(sc, EP_W1_RX_STATUS));
    1314             :                 /* Check if we are stuck and reset [see XXX comment] */
    1315           0 :                 if (len & ERR_INCOMPLETE) {
    1316             : #ifdef EP_DEBUG
    1317             :                         if (ifp->if_flags & IFF_DEBUG)
    1318             :                                 printf("%s: adapter reset\n",
    1319             :                                     sc->sc_dev.dv_xname);
    1320             : #endif
    1321           0 :                         epreset(sc);
    1322           0 :                         goto done;
    1323             :                 }
    1324           0 :                 goto again;
    1325             :         }
    1326             : done:
    1327           0 :         if (error)
    1328           0 :                 ep_discard_rxtop(iot, ioh);
    1329           0 :         if_input(ifp, &ml);
    1330           0 : }
    1331             : 
    1332             : struct mbuf *
    1333           0 : epget(struct ep_softc *sc, int totlen)
    1334             : {
    1335           0 :         bus_space_tag_t iot = sc->sc_iot;
    1336           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1337             :         struct mbuf *m;
    1338             :         caddr_t data;
    1339             :         int len, pad, off, sh, rxreg;
    1340             : 
    1341           0 :         splassert(IPL_NET);
    1342             : 
    1343           0 :         m = sc->mb[sc->next_mb];
    1344           0 :         sc->mb[sc->next_mb] = NULL;
    1345           0 :         if (m == NULL) {
    1346           0 :                 m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
    1347             :                 /* If the queue is no longer full, refill. */
    1348           0 :                 if (!timeout_pending(&sc->sc_epmbuffill_tmo))
    1349           0 :                         timeout_add(&sc->sc_epmbuffill_tmo, 1);
    1350             :         }
    1351           0 :         if (!m)
    1352           0 :                 return (NULL);
    1353             : 
    1354           0 :         sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
    1355             : 
    1356             :         len = MCLBYTES;
    1357           0 :         m->m_pkthdr.len = totlen;
    1358           0 :         m->m_len = totlen;
    1359             :         pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
    1360           0 :         m->m_data += pad;
    1361             :         len -= pad;
    1362             : 
    1363             :         /*
    1364             :          * We read the packet at splhigh() so that an interrupt from another
    1365             :          * device doesn't cause the card's buffer to overflow while we're
    1366             :          * reading it.  We may still lose packets at other times.
    1367             :          */
    1368           0 :         sh = splhigh();
    1369             : 
    1370           0 :         rxreg = ep_w1_reg(sc, EP_W1_RX_PIO_RD_1);
    1371             : 
    1372             :         off = 0;
    1373           0 :         while (totlen) {
    1374           0 :                 len = min(totlen, M_TRAILINGSPACE(m));
    1375           0 :                 if (len == 0)
    1376           0 :                         panic("ep_get: packet does not fit in MCLBYTES");
    1377             : 
    1378           0 :                 data = mtod(m, u_int8_t *);
    1379           0 :                 if (EP_IS_BUS_32(sc->bustype))
    1380           0 :                         pad = 4 - ((u_long)(data + off) & 0x3);
    1381             :                 else
    1382           0 :                         pad = (u_long)(data + off) & 0x1;
    1383             : 
    1384           0 :                 if (pad) {
    1385           0 :                         if (pad < len)
    1386           0 :                                 pad = len;
    1387           0 :                         bus_space_read_multi_1(iot, ioh, rxreg,
    1388             :                             data + off, pad);
    1389             :                         len = pad;
    1390           0 :                 } else if (EP_IS_BUS_32(sc->bustype) && len > 3 &&
    1391             :                     ALIGNED_POINTER(data, uint32_t)) {
    1392           0 :                         len &= ~3;
    1393           0 :                         bus_space_read_raw_multi_4(iot, ioh, rxreg,
    1394             :                             data + off, len);
    1395           0 :                 } else if (len > 1 && ALIGNED_POINTER(data, uint16_t)) {
    1396           0 :                         len &= ~1;
    1397           0 :                         bus_space_read_raw_multi_2(iot, ioh, rxreg,
    1398             :                             data + off, len);
    1399           0 :                 } else
    1400           0 :                         bus_space_read_multi_1(iot, ioh, rxreg,
    1401             :                             data + off, len);
    1402             : 
    1403           0 :                 off += len;
    1404           0 :                 totlen -= len;
    1405             :         }
    1406             : 
    1407           0 :         ep_discard_rxtop(iot, ioh);
    1408             : 
    1409           0 :         splx(sh);
    1410             : 
    1411           0 :         return m;
    1412           0 : }
    1413             : 
    1414             : int
    1415           0 : epioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
    1416             : {
    1417           0 :         struct ep_softc *sc = ifp->if_softc;
    1418           0 :         struct ifreq *ifr = (struct ifreq *)data;
    1419             :         int s, error = 0;
    1420             : 
    1421           0 :         s = splnet();
    1422             : 
    1423           0 :         switch (cmd) {
    1424             :         case SIOCSIFADDR:
    1425           0 :                 ifp->if_flags |= IFF_UP;
    1426           0 :                 if (!(ifp->if_flags & IFF_RUNNING))
    1427           0 :                         epinit(sc);
    1428             :                 break;
    1429             : 
    1430             :         case SIOCSIFFLAGS:
    1431           0 :                 if (ifp->if_flags & IFF_UP) {
    1432           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1433           0 :                                 error = ENETRESET;
    1434             :                         else
    1435           0 :                                 epinit(sc);
    1436             :                 } else {
    1437           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1438           0 :                                 epstop(sc);
    1439             :                 }
    1440             :                 break;
    1441             : 
    1442             :         case SIOCSIFMEDIA:
    1443             :         case SIOCGIFMEDIA:
    1444           0 :                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
    1445           0 :                 break;
    1446             : 
    1447             :         default:
    1448           0 :                 error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
    1449           0 :         }
    1450             : 
    1451           0 :         if (error == ENETRESET) {
    1452           0 :                 if (ifp->if_flags & IFF_RUNNING)
    1453           0 :                         epreset(sc);
    1454             :                 error = 0;
    1455           0 :         }
    1456             : 
    1457           0 :         splx(s);
    1458           0 :         return (error);
    1459             : }
    1460             : 
    1461             : void
    1462           0 : epreset(struct ep_softc *sc)
    1463             : {
    1464             :         int s;
    1465             : 
    1466           0 :         s = splnet();
    1467           0 :         epinit(sc);
    1468           0 :         splx(s);
    1469           0 : }
    1470             : 
    1471             : void
    1472           0 : epwatchdog(struct ifnet *ifp)
    1473             : {
    1474           0 :         struct ep_softc *sc = ifp->if_softc;
    1475             : 
    1476           0 :         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
    1477           0 :         ++sc->sc_arpcom.ac_if.if_oerrors;
    1478             : 
    1479           0 :         epreset(sc);
    1480           0 : }
    1481             : 
    1482             : void
    1483           0 : epstop(struct ep_softc *sc)
    1484             : {
    1485           0 :         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    1486           0 :         bus_space_tag_t iot = sc->sc_iot;
    1487           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1488             : 
    1489           0 :         ifp->if_flags &= ~IFF_RUNNING;
    1490           0 :         ifq_clr_oactive(&ifp->if_snd);
    1491             : 
    1492           0 :         if (sc->ep_flags & EP_FLAGS_MII) {
    1493           0 :                 mii_down(&sc->sc_mii);
    1494           0 :         }
    1495             : 
    1496           0 :         if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER) {
    1497             :                 /* Clear the FIFO buffer count, thus halting
    1498             :                  * any currently-running transactions.
    1499             :                  */
    1500           0 :                 GO_WINDOW(1);           /* sanity */
    1501           0 :                 bus_space_write_2(iot, ioh, EP_W1_RUNNER_WRCTL, 0);
    1502           0 :                 bus_space_write_2(iot, ioh, EP_W1_RUNNER_RDCTL, 0);
    1503           0 :         }
    1504             : 
    1505           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISABLE);
    1506           0 :         ep_discard_rxtop(iot, ioh);
    1507             : 
    1508           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, TX_DISABLE);
    1509           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
    1510             : 
    1511           0 :         ep_reset_cmd(sc, EP_COMMAND, RX_RESET);
    1512           0 :         ep_reset_cmd(sc, EP_COMMAND, TX_RESET);
    1513             : 
    1514           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH);
    1515           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK);
    1516           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK);
    1517           0 :         bus_space_write_2(iot, ioh, EP_COMMAND, SET_RX_FILTER);
    1518             : 
    1519           0 :         epmbufempty(sc);
    1520           0 : }
    1521             : 
    1522             : /*
    1523             :  * We get eeprom data from the id_port given an offset into the
    1524             :  * eeprom.  Basically; after the ID_sequence is sent to all of
    1525             :  * the cards; they enter the ID_CMD state where they will accept
    1526             :  * command requests. 0x80-0xbf loads the eeprom data.  We then
    1527             :  * read the port 16 times and with every read; the cards check
    1528             :  * for contention (ie: if one card writes a 0 bit and another
    1529             :  * writes a 1 bit then the host sees a 0. At the end of the cycle;
    1530             :  * each card compares the data on the bus; if there is a difference
    1531             :  * then that card goes into ID_WAIT state again). In the meantime;
    1532             :  * one bit of data is returned in the AX register which is conveniently
    1533             :  * returned to us by bus_space_read_1().  Hence; we read 16 times getting one
    1534             :  * bit of data with each read.
    1535             :  *
    1536             :  * NOTE: the caller must provide an i/o handle for ELINK_ID_PORT!
    1537             :  */
    1538             : u_int16_t
    1539           0 : epreadeeprom(bus_space_tag_t iot, bus_space_handle_t ioh, int offset)
    1540             : {
    1541             :         u_int16_t data = 0;
    1542             :         int i;
    1543             : 
    1544           0 :         bus_space_write_1(iot, ioh, 0, 0x80 + offset);
    1545           0 :         delay(1000);
    1546           0 :         for (i = 0; i < 16; i++)
    1547           0 :                 data = (data << 1) | (bus_space_read_2(iot, ioh, 0) & 1);
    1548           0 :         return (data);
    1549             : }
    1550             : 
    1551             : int
    1552           0 : epbusyeeprom(struct ep_softc *sc)
    1553             : {
    1554           0 :         bus_space_tag_t iot = sc->sc_iot;
    1555           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1556             :         int i = 100, j;
    1557             : 
    1558           0 :         while (i--) {
    1559           0 :                 j = bus_space_read_2(iot, ioh, EP_W0_EEPROM_COMMAND);
    1560           0 :                 if (j & EEPROM_BUSY)
    1561           0 :                         delay(100);
    1562             :                 else
    1563             :                         break;
    1564             :         }
    1565           0 :         if (!i) {
    1566           0 :                 printf("\n%s: eeprom failed to come ready\n",
    1567           0 :                     sc->sc_dev.dv_xname);
    1568           0 :                 return (1);
    1569             :         }
    1570           0 :         if (sc->bustype != EP_BUS_PCMCIA && sc->bustype != EP_BUS_PCI &&
    1571           0 :             (j & EEPROM_TST_MODE)) {
    1572           0 :                 printf("\n%s: erase pencil mark, or disable PnP mode!\n",
    1573           0 :                     sc->sc_dev.dv_xname);
    1574           0 :                 return (1);
    1575             :         }
    1576           0 :         return (0);
    1577           0 : }
    1578             : 
    1579             : u_int16_t
    1580           0 : ep_read_eeprom(struct ep_softc *sc, u_int16_t offset)
    1581             : {
    1582             :         u_int16_t readcmd;
    1583             : 
    1584             :         /*
    1585             :          * RoadRunner has a larger EEPROM, so a different read command
    1586             :          * is required.
    1587             :          */
    1588           0 :         if (sc->ep_chipset == EP_CHIPSET_ROADRUNNER)
    1589           0 :                 readcmd = READ_EEPROM_RR;
    1590             :         else
    1591             :                 readcmd = READ_EEPROM;
    1592             : 
    1593           0 :         if (epbusyeeprom(sc))
    1594           0 :                 return (0);                     /* XXX why is eeprom busy? */
    1595           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W0_EEPROM_COMMAND,
    1596             :             readcmd | offset);
    1597           0 :         if (epbusyeeprom(sc))
    1598           0 :                 return (0);                     /* XXX why is eeprom busy? */
    1599             : 
    1600           0 :         return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W0_EEPROM_DATA));
    1601           0 : }
    1602             : 
    1603             : void
    1604           0 : epmbuffill(void *v)
    1605             : {
    1606           0 :         struct ep_softc *sc = v;
    1607             :         int s, i;
    1608             : 
    1609           0 :         s = splnet();
    1610           0 :         for (i = 0; i < MAX_MBS; i++) {
    1611           0 :                 if (sc->mb[i] == NULL) {
    1612           0 :                         sc->mb[i] = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
    1613           0 :                         if (sc->mb[i] == NULL)
    1614             :                                 break;
    1615             :                 }
    1616             :         }
    1617             :         /* If the queue was not filled, try again. */
    1618           0 :         if (i < MAX_MBS)
    1619           0 :                 timeout_add(&sc->sc_epmbuffill_tmo, 1);
    1620           0 :         splx(s);
    1621           0 : }
    1622             : 
    1623             : void
    1624           0 : epmbufempty(struct ep_softc *sc)
    1625             : {
    1626             :         int s, i;
    1627             : 
    1628           0 :         s = splnet();
    1629           0 :         for (i = 0; i<MAX_MBS; i++) {
    1630           0 :                 if (sc->mb[i]) {
    1631           0 :                         m_freem(sc->mb[i]);
    1632           0 :                         sc->mb[i] = NULL;
    1633           0 :                 }
    1634             :         }
    1635           0 :         sc->next_mb = 0;
    1636           0 :         timeout_del(&sc->sc_epmbuffill_tmo);
    1637           0 :         splx(s);
    1638           0 : }
    1639             : 
    1640             : void
    1641           0 : ep_mii_setbit(struct ep_softc *sc, u_int16_t bit)
    1642             : {
    1643             :         u_int16_t val;
    1644             : 
    1645             :         /* We assume we're already in Window 4 */
    1646           0 :         val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT);
    1647           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT,
    1648             :             val | bit);
    1649           0 : }
    1650             : 
    1651             : void
    1652           0 : ep_mii_clrbit(struct ep_softc *sc, u_int16_t bit)
    1653             : {
    1654             :         u_int16_t val;
    1655             : 
    1656             :         /* We assume we're already in Window 4 */
    1657           0 :         val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT);
    1658           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT,
    1659             :             val & ~bit);
    1660           0 : }
    1661             : 
    1662             : u_int16_t
    1663           0 : ep_mii_readbit(struct ep_softc *sc, u_int16_t bit)
    1664             : {
    1665             : 
    1666             :         /* We assume we're already in Window 4 */
    1667           0 :         return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT) &
    1668           0 :             bit);
    1669             : }
    1670             : 
    1671             : void
    1672           0 : ep_mii_sync(struct ep_softc *sc)
    1673             : {
    1674             :         int i;
    1675             : 
    1676             :         /* We assume we're already in Window 4 */
    1677           0 :         ep_mii_clrbit(sc, PHYSMGMT_DIR);
    1678           0 :         for (i = 0; i < 32; i++) {
    1679           0 :                 ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1680           0 :                 ep_mii_setbit(sc, PHYSMGMT_CLK);
    1681             :         }
    1682           0 : }
    1683             : 
    1684             : void
    1685           0 : ep_mii_sendbits(struct ep_softc *sc, u_int32_t data, int nbits)
    1686             : {
    1687             :         int i;
    1688             : 
    1689             :         /* We assume we're already in Window 4 */
    1690           0 :         ep_mii_setbit(sc, PHYSMGMT_DIR);
    1691           0 :         for (i = 1 << (nbits - 1); i; i = i >> 1) {
    1692           0 :                 ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1693           0 :                 ep_mii_readbit(sc, PHYSMGMT_CLK);
    1694           0 :                 if (data & i)
    1695           0 :                         ep_mii_setbit(sc, PHYSMGMT_DATA);
    1696             :                 else
    1697           0 :                         ep_mii_clrbit(sc, PHYSMGMT_DATA);
    1698           0 :                 ep_mii_setbit(sc, PHYSMGMT_CLK);
    1699           0 :                 ep_mii_readbit(sc, PHYSMGMT_CLK);
    1700             :         }
    1701           0 : }
    1702             : 
    1703             : int
    1704           0 : ep_mii_readreg(struct device *self, int phy, int reg)
    1705             : {
    1706           0 :         struct ep_softc *sc = (struct ep_softc *)self;
    1707             :         int val = 0, i, err;
    1708             : 
    1709             :         /*
    1710             :          * Read the PHY register by manually driving the MII control lines.
    1711             :          */
    1712             : 
    1713           0 :         GO_WINDOW(4);
    1714             : 
    1715           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_BOOM_PHYSMGMT, 0);
    1716             : 
    1717           0 :         ep_mii_sync(sc);
    1718           0 :         ep_mii_sendbits(sc, MII_COMMAND_START, 2);
    1719           0 :         ep_mii_sendbits(sc, MII_COMMAND_READ, 2);
    1720           0 :         ep_mii_sendbits(sc, phy, 5);
    1721           0 :         ep_mii_sendbits(sc, reg, 5);
    1722             : 
    1723           0 :         ep_mii_clrbit(sc, PHYSMGMT_DIR);
    1724           0 :         ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1725           0 :         ep_mii_setbit(sc, PHYSMGMT_CLK);
    1726           0 :         ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1727             : 
    1728           0 :         err = ep_mii_readbit(sc, PHYSMGMT_DATA);
    1729           0 :         ep_mii_setbit(sc, PHYSMGMT_CLK);
    1730             : 
    1731             :         /* Even if an error occurs, must still clock out the cycle. */
    1732           0 :         for (i = 0; i < 16; i++) {
    1733           0 :                 val <<= 1;
    1734           0 :                 ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1735           0 :                 if (err == 0 && ep_mii_readbit(sc, PHYSMGMT_DATA))
    1736           0 :                         val |= 1;
    1737           0 :                 ep_mii_setbit(sc, PHYSMGMT_CLK);
    1738             :         }
    1739           0 :         ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1740           0 :         ep_mii_setbit(sc, PHYSMGMT_CLK);
    1741             : 
    1742           0 :         GO_WINDOW(1);   /* back to operating window */
    1743             : 
    1744           0 :         return (err ? 0 : val);
    1745             : }
    1746             : 
    1747             : void
    1748           0 : ep_mii_writereg(struct device *self, int phy, int reg, int val)
    1749             : {
    1750           0 :         struct ep_softc *sc = (struct ep_softc *)self;
    1751             : 
    1752             :         /*
    1753             :          * Write the PHY register by manually driving the MII control lines.
    1754             :          */
    1755             : 
    1756           0 :         GO_WINDOW(4);
    1757             : 
    1758           0 :         ep_mii_sync(sc);
    1759           0 :         ep_mii_sendbits(sc, MII_COMMAND_START, 2);
    1760           0 :         ep_mii_sendbits(sc, MII_COMMAND_WRITE, 2);
    1761           0 :         ep_mii_sendbits(sc, phy, 5);
    1762           0 :         ep_mii_sendbits(sc, reg, 5);
    1763           0 :         ep_mii_sendbits(sc, MII_COMMAND_ACK, 2);
    1764           0 :         ep_mii_sendbits(sc, val, 16);
    1765             : 
    1766           0 :         ep_mii_clrbit(sc, PHYSMGMT_CLK);
    1767           0 :         ep_mii_setbit(sc, PHYSMGMT_CLK);
    1768             : 
    1769           0 :         GO_WINDOW(1);   /* back to operating window */
    1770           0 : }
    1771             : 
    1772             : void
    1773           0 : ep_statchg(struct device *self)
    1774             : {
    1775           0 :         struct ep_softc *sc = (struct ep_softc *)self;
    1776           0 :         bus_space_tag_t iot = sc->sc_iot;
    1777           0 :         bus_space_handle_t ioh = sc->sc_ioh;
    1778             :         int mctl;
    1779             : 
    1780             :         /* XXX Update ifp->if_baudrate */
    1781             : 
    1782           0 :         GO_WINDOW(3);
    1783           0 :         mctl = bus_space_read_2(iot, ioh, EP_W3_MAC_CONTROL);
    1784           0 :         if (sc->sc_mii.mii_media_active & IFM_FDX)
    1785           0 :                 mctl |= MAC_CONTROL_FDX;
    1786             :         else
    1787           0 :                 mctl &= ~MAC_CONTROL_FDX;
    1788           0 :         bus_space_write_2(iot, ioh, EP_W3_MAC_CONTROL, mctl);
    1789           0 :         GO_WINDOW(1);   /* back to operating window */
    1790           0 : }

Generated by: LCOV version 1.13