root/dev/pci/if_lmc_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lmc_gpio_mkinput
  2. lmc_gpio_mkoutput
  3. lmc_led_on
  4. lmc_led_off
  5. lmc_reset
  6. lmc_dec_reset
  7. lmc_initcsrs

    1 /*      $OpenBSD: if_lmc_common.c,v 1.11 2005/11/07 00:29:21 brad Exp $ */
    2 /*      $NetBSD: if_lmc_common.c,v 1.1 1999/03/25 03:32:43 explorer Exp $       */
    3 
    4 /*-
    5  * Copyright (c) 1997-1999 LAN Media Corporation (LMC)
    6  * All rights reserved.  www.lanmedia.com
    7  *
    8  * This code is written by Michael Graff <graff@vix.com> for LMC.
    9  * The code is derived from permitted modifications to software created
   10  * by Matt Thomas (matt@3am-software.com).
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above
   18  *    copyright notice, this list of conditions and the following disclaimer
   19  *    in the documentation and/or other materials provided with the
   20  *    distribution.
   21  * 3. All marketing or advertising materials mentioning features or
   22  *    use of this software must display the following acknowledgement:
   23  *      This product includes software developed by LAN Media Corporation
   24  *      and its contributors.
   25  * 4. Neither the name of LAN Media Corporation nor the names of its
   26  *    contributors may be used to endorse or promote products derived
   27  *    from this software without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY LAN MEDIA CORPORATION AND CONTRIBUTORS
   30  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   32  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   33  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   34  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   35  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   36  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   37  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   39  * THE POSSIBILITY OF SUCH DAMAGE.
   40  */
   41 
   42 /*-
   43  * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
   44  * All rights reserved.
   45  *
   46  * Redistribution and use in source and binary forms, with or without
   47  * modification, are permitted provided that the following conditions
   48  * are met:
   49  * 1. Redistributions of source code must retain the above copyright
   50  *    notice, this list of conditions and the following disclaimer.
   51  * 2. The name of the author may not be used to endorse or promote products
   52  *    derived from this software without specific prior written permission
   53  *
   54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   57  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   64  */
   65 
   66 #include "bpfilter.h"
   67 
   68 #include <sys/param.h>
   69 #include <sys/systm.h>
   70 #include <sys/mbuf.h>
   71 #include <sys/socket.h>
   72 #include <sys/ioctl.h>
   73 #include <sys/errno.h>
   74 #include <sys/malloc.h>
   75 #include <sys/kernel.h>
   76 #include <sys/proc.h>   /* only for declaration of wakeup() used by vm.h */
   77 #include <sys/device.h>
   78 
   79 #include <dev/pci/pcidevs.h>
   80 
   81 #include <net/if.h>
   82 #include <net/if_types.h>
   83 #include <net/if_dl.h>
   84 #include <net/netisr.h>
   85 
   86 #if NBPFILTER > 0
   87 #include <net/bpf.h>
   88 #endif
   89 
   90 #include <net/if_sppp.h>
   91 
   92 #include <machine/bus.h>
   93 
   94 #include <dev/pci/pcireg.h>
   95 #include <dev/pci/pcivar.h>
   96 #include <dev/ic/dc21040reg.h>
   97 
   98 #define d_length1 u.bd_length1
   99 #define d_length2 u.bd_length2
  100 #define d_flag u.bd_flag
  101 
  102 #include <dev/pci/if_lmc_types.h>
  103 #include <dev/pci/if_lmcioctl.h>
  104 #include <dev/pci/if_lmcvar.h>
  105 
  106 void
  107 lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits)
  108 {
  109         sc->lmc_gpio_io &= ~bits;
  110         LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
  111 }
  112 
  113 void
  114 lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits)
  115 {
  116         sc->lmc_gpio_io |= bits;
  117         LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
  118 }
  119 
  120 void
  121 lmc_led_on(lmc_softc_t * const sc, u_int32_t led)
  122 {
  123         sc->lmc_miireg16 &= ~led;
  124         lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
  125 }
  126 
  127 void
  128 lmc_led_off(lmc_softc_t * const sc, u_int32_t led)
  129 {
  130         sc->lmc_miireg16 |= led;
  131         lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
  132 }
  133 
  134 void
  135 lmc_reset(lmc_softc_t * const sc)
  136 {
  137         sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
  138         lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
  139 
  140         sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
  141         lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
  142 
  143         /*
  144          * make some of the GPIO pins be outputs
  145          */
  146         lmc_gpio_mkoutput(sc, LMC_GEP_DP | LMC_GEP_RESET);
  147 
  148         /*
  149          * drive DP and RESET low to force configuration.  This also forces
  150          * the transmitter clock to be internal, but we expect to reset
  151          * that later anyway.
  152          */
  153         sc->lmc_gpio &= ~(LMC_GEP_DP | LMC_GEP_RESET);
  154         LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
  155 
  156         /*
  157          * hold for more than 10 microseconds
  158          */
  159         DELAY(50);
  160 
  161         /*
  162          * stop driving Xilinx-related signals
  163          */
  164         lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);
  165 
  166         /*
  167          * busy wait for the chip to reset
  168          */
  169         while ((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0);
  170 
  171         /*
  172          * Call media specific init routine
  173          */
  174         sc->lmc_media->init(sc);
  175 }
  176 
  177 void
  178 lmc_dec_reset(lmc_softc_t * const sc)
  179 {
  180 #ifndef __linux__
  181         lmc_ringinfo_t *ri;
  182         lmc_desc_t *di;
  183 #endif
  184         u_int32_t val;
  185 
  186         /*
  187          * disable all interrupts
  188          */
  189         sc->lmc_intrmask = 0;
  190         LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
  191 
  192         /*
  193          * we are, obviously, down.
  194          */
  195 #ifndef __linux__
  196         sc->lmc_flags &= ~(LMC_IFUP | LMC_MODEMOK);
  197 
  198         DP(("lmc_dec_reset\n"));
  199 #endif
  200 
  201         /*
  202          * Reset the chip with a software reset command.
  203          * Wait 10 microseconds (actually 50 PCI cycles but at 
  204          * 33MHz that comes to two microseconds but wait a
  205          * bit longer anyways)
  206          */
  207         LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
  208         DELAY(10);
  209         sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command);
  210 
  211         /*
  212          * We want:
  213          *   no ethernet address in frames we write
  214          *   disable padding (txdesc, padding disable)
  215          *   ignore runt frames (rdes0 bit 15)
  216          *   no receiver watchdog or transmitter jabber timer
  217          *       (csr15 bit 0,14 == 1)
  218          *   if using 16-bit CRC, turn off CRC (trans desc, crc disable)
  219          */
  220 
  221 #ifndef TULIP_CMD_RECEIVEALL
  222 #define TULIP_CMD_RECEIVEALL 0x40000000L
  223 #endif
  224 
  225         sc->lmc_cmdmode |= ( TULIP_CMD_PROMISCUOUS
  226                                | TULIP_CMD_FULLDUPLEX
  227                                | TULIP_CMD_PASSBADPKT
  228                                | TULIP_CMD_NOHEARTBEAT
  229                                | TULIP_CMD_PORTSELECT
  230                                | TULIP_CMD_RECEIVEALL
  231                                | TULIP_CMD_MUSTBEONE
  232                                );
  233         sc->lmc_cmdmode &= ~( TULIP_CMD_OPERMODE
  234                                 | TULIP_CMD_THRESHOLDCTL
  235                                 | TULIP_CMD_STOREFWD
  236                                 | TULIP_CMD_TXTHRSHLDCTL
  237                                 );
  238 
  239         LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
  240 
  241         /*
  242          * disable receiver watchdog and transmit jabber
  243          */
  244         val = LMC_CSR_READ(sc, csr_sia_general);
  245         val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE);
  246         LMC_CSR_WRITE(sc, csr_sia_general, val);
  247 
  248         /*
  249          * turn off those LEDs...
  250          */
  251         sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
  252         lmc_led_on(sc, LMC_MII16_LED0);
  253 
  254 #ifndef __linux__
  255         /*
  256          * reprogram the tx desc, rx desc, and PCI bus options
  257          */
  258         LMC_CSR_WRITE(sc, csr_txlist, sc->lmc_txdescmap->dm_segs[0].ds_addr);
  259         LMC_CSR_WRITE(sc, csr_rxlist, sc->lmc_rxdescmap->dm_segs[0].ds_addr);
  260         LMC_CSR_WRITE(sc, csr_busmode,
  261                 (1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8))
  262                 |TULIP_BUSMODE_CACHE_ALIGN8
  263                 |TULIP_BUSMODE_READMULTIPLE);
  264 
  265         sc->lmc_txq.ifq_maxlen = LMC_TXDESCS;
  266 
  267         /*
  268          * Free all the mbufs that were on the transmit ring.
  269          */
  270         for (;;) {
  271                 bus_dmamap_t map;
  272                 struct mbuf *m;
  273 
  274                 IF_DEQUEUE(&sc->lmc_txq, m);
  275                 if (m == NULL)
  276                         break;
  277                 map = LMC_GETCTX(m, bus_dmamap_t);
  278                 bus_dmamap_unload(sc->lmc_dmatag, map);
  279                 sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
  280                 m_freem(m);
  281         }
  282 
  283         /*
  284          * reset descriptor state and reclaim all descriptors.
  285          */
  286         ri = &sc->lmc_txinfo;
  287         ri->ri_nextin = ri->ri_nextout = ri->ri_first;
  288         ri->ri_free = ri->ri_max;
  289         for (di = ri->ri_first; di < ri->ri_last; di++)
  290                 di->d_status = 0;
  291         bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_txdescmap,
  292                 0, sc->lmc_txdescmap->dm_mapsize,
  293                 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  294 
  295         /*
  296          * We need to collect all the mbufs were on the 
  297          * receive ring before we reinit it either to put
  298          * them back on or to know if we have to allocate
  299          * more.
  300          */
  301         ri = &sc->lmc_rxinfo;
  302         ri->ri_nextin = ri->ri_nextout = ri->ri_first;
  303         ri->ri_free = ri->ri_max;
  304         for (di = ri->ri_first; di < ri->ri_last; di++) {
  305                 u_int32_t ctl = di->d_ctl;
  306                 di->d_status = 0;
  307                 di->d_ctl = LMC_CTL(LMC_CTL_FLGS(ctl),0,0);
  308                 di->d_addr1 = 0;
  309                 di->d_addr2 = 0;
  310         }
  311         bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_rxdescmap,
  312                 0, sc->lmc_rxdescmap->dm_mapsize,
  313                 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  314         for (;;) {
  315                 bus_dmamap_t map;
  316                 struct mbuf *m;
  317                 IF_DEQUEUE(&sc->lmc_rxq, m);
  318                 if (m == NULL)
  319                         break;
  320                 map = LMC_GETCTX(m, bus_dmamap_t);
  321                 bus_dmamap_unload(sc->lmc_dmatag, map);
  322                 sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
  323                 m_freem(m);
  324         }
  325 #endif
  326 }
  327 
  328 void
  329 lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base,
  330              size_t csr_size)
  331 {
  332         sc->lmc_csrs.csr_busmode        = csr_base +  0 * csr_size;
  333         sc->lmc_csrs.csr_txpoll         = csr_base +  1 * csr_size;
  334         sc->lmc_csrs.csr_rxpoll         = csr_base +  2 * csr_size;
  335         sc->lmc_csrs.csr_rxlist         = csr_base +  3 * csr_size;
  336         sc->lmc_csrs.csr_txlist         = csr_base +  4 * csr_size;
  337         sc->lmc_csrs.csr_status         = csr_base +  5 * csr_size;
  338         sc->lmc_csrs.csr_command        = csr_base +  6 * csr_size;
  339         sc->lmc_csrs.csr_intr           = csr_base +  7 * csr_size;
  340         sc->lmc_csrs.csr_missed_frames  = csr_base +  8 * csr_size;
  341         sc->lmc_csrs.csr_9              = csr_base +  9 * csr_size;
  342         sc->lmc_csrs.csr_10             = csr_base + 10 * csr_size;
  343         sc->lmc_csrs.csr_11             = csr_base + 11 * csr_size;
  344         sc->lmc_csrs.csr_12             = csr_base + 12 * csr_size;
  345         sc->lmc_csrs.csr_13             = csr_base + 13 * csr_size;
  346         sc->lmc_csrs.csr_14             = csr_base + 14 * csr_size;
  347         sc->lmc_csrs.csr_15             = csr_base + 15 * csr_size;
  348 }

/* [<][>][^][v][top][bottom][index][help] */