The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/fe/if_fe_pccard.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
    3  *
    4  * This software may be used, modified, copied, distributed, and sold, in
    5  * both source and binary form provided that the above copyright, these
    6  * terms and the following disclaimer are retained.  The name of the author
    7  * and/or the contributor may not be used to endorse or promote products
    8  * derived from this software without specific prior written permission.
    9  *
   10  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
   11  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   12  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   13  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
   14  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   15  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   16  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
   17  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   18  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   19  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   20  * SUCH DAMAGE.
   21  *
   22  */
   23 
   24 #include <sys/cdefs.h>
   25 __FBSDID("$FreeBSD$");
   26 
   27 #include <sys/param.h>
   28 #include <sys/kernel.h>
   29 #include <sys/socket.h>
   30 #include <sys/systm.h>
   31 #include <sys/module.h>
   32 
   33 #include <sys/bus.h>
   34 #include <machine/bus.h>
   35 #include <machine/resource.h>
   36 #include <sys/rman.h>
   37 
   38 #include <net/ethernet.h>
   39 #include <net/if.h>
   40 #include <net/if_mib.h>
   41 #include <net/if_media.h>
   42 
   43 #include <netinet/in.h>
   44 #include <netinet/if_ether.h>
   45 
   46 #include <i386/isa/ic/mb86960.h>
   47 #include <dev/fe/if_fereg.h>
   48 #include <dev/fe/if_fevar.h>
   49 
   50 #include <dev/pccard/pccardvar.h>
   51 #include <dev/pccard/pccard_cis.h>
   52 
   53 #include "card_if.h"
   54 #include "pccarddevs.h"
   55 
   56 /*
   57  *      PC-Card (PCMCIA) specific code.
   58  */
   59 static int fe_pccard_probe(device_t);
   60 static int fe_pccard_attach(device_t);
   61 static int fe_pccard_detach(device_t);
   62 static int fe_pccard_match(device_t);
   63 
   64 static const struct fe_pccard_product {
   65         struct pccard_product mpp_product;
   66         int mpp_flags;
   67 #define MPP_MBH10302 1
   68 } fe_pccard_products[] = {
   69         /* These need to be first */
   70         { PCMCIA_CARD(FUJITSU2, FMV_J181, 0), MPP_MBH10302 },
   71         { PCMCIA_CARD(FUJITSU2, FMV_J182, 0), 0 },
   72         { PCMCIA_CARD(FUJITSU2, FMV_J182A, 0), 0 },
   73         { PCMCIA_CARD(FUJITSU2, ITCFJ182A, 0), 0 },
   74         /* These need to be second */
   75         { PCMCIA_CARD(TDK, LAK_CD021BX, 0), 0 }, 
   76         { PCMCIA_CARD(TDK, LAK_CF010, 0), 0 }, 
   77 #if 0 /* XXX 86960-based? */
   78         { PCMCIA_CARD(TDK, LAK_DFL9610, 1), 0 }, 
   79 #endif
   80         { PCMCIA_CARD(CONTEC, CNETPC, 0), 0 },
   81         { PCMCIA_CARD(FUJITSU, LA501, 0), 0 },
   82         { PCMCIA_CARD(FUJITSU, LA10S, 0), 0 },
   83         { PCMCIA_CARD(FUJITSU, NE200T, 0), MPP_MBH10302 },/* Sold by Eagle */
   84         { PCMCIA_CARD(RATOC, REX_R280, 0), 0 },
   85         { { NULL } }
   86 };
   87 
   88 static int
   89 fe_pccard_match(device_t dev)
   90 {
   91         const struct pccard_product *pp;
   92         int             error;
   93         uint32_t        fcn = PCCARD_FUNCTION_UNSPEC;
   94 
   95         /* Make sure we're a network function */
   96         error = pccard_get_function(dev, &fcn);
   97         if (error != 0)
   98                 return (error);
   99         if (fcn != PCCARD_FUNCTION_NETWORK)
  100                 return (ENXIO);
  101 
  102         if ((pp = pccard_product_lookup(dev,
  103             (const struct pccard_product *)fe_pccard_products,
  104             sizeof(fe_pccard_products[0]), NULL)) != NULL) {
  105                 if (pp->pp_name != NULL)
  106                         device_set_desc(dev, pp->pp_name);
  107                 return 0;
  108         }
  109         return EIO;
  110 }
  111 
  112 static device_method_t fe_pccard_methods[] = {
  113         /* Device interface */
  114         DEVMETHOD(device_probe,         pccard_compat_probe),
  115         DEVMETHOD(device_attach,        pccard_compat_attach),
  116         DEVMETHOD(device_detach,        fe_pccard_detach),
  117 
  118         /* Card interface */
  119         DEVMETHOD(card_compat_match,    fe_pccard_match),
  120         DEVMETHOD(card_compat_probe,    fe_pccard_probe),
  121         DEVMETHOD(card_compat_attach,   fe_pccard_attach),
  122 
  123         { 0, 0 }
  124 };
  125 
  126 static driver_t fe_pccard_driver = {
  127         "fe",
  128         fe_pccard_methods,
  129         sizeof (struct fe_softc)
  130 };
  131 
  132 DRIVER_MODULE(fe, pccard, fe_pccard_driver, fe_devclass, 0, 0);
  133 
  134 static int fe_probe_mbh(device_t, const struct fe_pccard_product *);
  135 static int fe_probe_tdk(device_t, const struct fe_pccard_product *);
  136 /*
  137  *      Initialize the device - called from Slot manager.
  138  */
  139 static int
  140 fe_pccard_probe(device_t dev)
  141 {
  142         struct fe_softc *sc;
  143         const struct fe_pccard_product *pp;
  144         int error;
  145 
  146         /* Prepare for the device probe process.  */
  147         sc = device_get_softc(dev);
  148         sc->sc_unit = device_get_unit(dev);
  149 
  150         pp = (const struct fe_pccard_product *) pccard_product_lookup(dev,
  151             (const struct pccard_product *)fe_pccard_products,
  152             sizeof(fe_pccard_products[0]), NULL);
  153         if (pp == NULL)
  154                 return (ENXIO);
  155 
  156         if (pp->mpp_flags & MPP_MBH10302)
  157                 error = fe_probe_mbh(dev, pp);
  158         else
  159                 error = fe_probe_tdk(dev, pp);
  160         if (error == 0)
  161                 error = fe_alloc_irq(dev, 0);
  162 
  163         fe_release_resource(dev);
  164         return (error);
  165 }
  166 
  167 static int
  168 fe_pccard_attach(device_t dev)
  169 {
  170         struct fe_softc *sc = device_get_softc(dev);
  171 
  172         if (sc->port_used)
  173                 fe_alloc_port(dev, sc->port_used);
  174         fe_alloc_irq(dev, 0);
  175 
  176         return fe_attach(dev);
  177 }
  178 
  179 /*
  180  *      feunload - unload the driver and clear the table.
  181  */
  182 static int
  183 fe_pccard_detach(device_t dev)
  184 {
  185         struct fe_softc *sc = device_get_softc(dev);
  186         struct ifnet *ifp = &sc->arpcom.ac_if;
  187 
  188         fe_stop(sc);
  189         ether_ifdetach(ifp);
  190         bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
  191         fe_release_resource(dev);
  192 
  193         return 0;
  194 }
  195 
  196 
  197 /*
  198  * Probe and initialization for Fujitsu MBH10302 PCMCIA Ethernet interface.
  199  * Note that this is for 10302 only; MBH10304 is handled by fe_probe_tdk().
  200  */
  201 static void
  202 fe_init_mbh(struct fe_softc *sc)
  203 {
  204         /* Minimal initialization of 86960.  */
  205         DELAY(200);
  206         fe_outb(sc, FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE);
  207         DELAY(200);
  208 
  209         /* Disable all interrupts.  */
  210         fe_outb(sc, FE_DLCR2, 0);
  211         fe_outb(sc, FE_DLCR3, 0);
  212 
  213         /* Enable master interrupt flag.  */
  214         fe_outb(sc, FE_MBH0, FE_MBH0_MAGIC | FE_MBH0_INTR_ENABLE);
  215 }
  216 
  217 static int
  218 fe_probe_mbh(device_t dev, const struct fe_pccard_product *pp)
  219 {
  220         struct fe_softc *sc = device_get_softc(dev);
  221 
  222         static struct fe_simple_probe_struct probe_table [] = {
  223                 { FE_DLCR2, 0x58, 0x00 },
  224                 { FE_DLCR4, 0x08, 0x00 },
  225                 { FE_DLCR6, 0xFF, 0xB6 },
  226                 { 0 }
  227         };
  228 
  229         /* MBH10302 occupies 32 I/O addresses. */
  230         if (fe_alloc_port(dev, 32))
  231                 return ENXIO;
  232 
  233         /* Fill the softc struct with default values.  */
  234         fe_softc_defaults(sc);
  235 
  236         /*
  237          * See if MBH10302 is on its address.
  238          * I'm not sure the following probe code works.  FIXME.
  239          */
  240         if (!fe_simple_probe(sc, probe_table))
  241                 return ENXIO;
  242 
  243         /* Get our station address from EEPROM.  */
  244         fe_inblk(sc, FE_MBH10, sc->sc_enaddr, ETHER_ADDR_LEN);
  245 
  246         /* Make sure we got a valid station address.  */
  247         if (!fe_valid_Ether_p(sc->sc_enaddr, 0))
  248                 return ENXIO;
  249 
  250         /* Determine the card type.  */
  251         sc->type = FE_TYPE_MBH;
  252         sc->typestr = "MBH10302 (PCMCIA)";
  253 
  254         /* We seems to need our own IDENT bits...  FIXME.  */
  255         sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE;
  256 
  257         /* Setup hooks.  We need a special initialization procedure.  */
  258         sc->init = fe_init_mbh;
  259 
  260         return 0;
  261 }
  262 
  263 /*
  264  * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface.
  265  * by MASUI Kenji <masui@cs.titech.ac.jp>
  266  *
  267  * (Contec uses TDK Ethenet chip -- hosokawa)
  268  *
  269  * This version of fe_probe_tdk has been rewrote to handle
  270  * *generic* PC card implementation of Fujitsu MB8696x family.  The
  271  * name _tdk is just for a historical reason. :-)
  272  */
  273 static int
  274 fe_probe_tdk (device_t dev, const struct fe_pccard_product *pp)
  275 {
  276         struct fe_softc *sc = device_get_softc(dev);
  277 
  278         static struct fe_simple_probe_struct probe_table [] = {
  279                 { FE_DLCR2, 0x50, 0x00 },
  280                 { FE_DLCR4, 0x08, 0x00 },
  281             /*  { FE_DLCR5, 0x80, 0x00 },       Does not work well.  */
  282                 { 0 }
  283         };
  284 
  285         /* C-NET(PC)C occupies 16 I/O addresses. */
  286         if (fe_alloc_port(dev, 16))
  287                 return ENXIO;
  288 
  289         /* Fill the softc struct with default values.  */
  290         fe_softc_defaults(sc);
  291 
  292         /*
  293          * See if C-NET(PC)C is on its address.
  294          */
  295         if (!fe_simple_probe(sc, probe_table))
  296                 return ENXIO;
  297 
  298         /* Determine the card type.  */
  299         sc->type = FE_TYPE_TDK;
  300         sc->typestr = "Generic MB8696x/78Q837x Ethernet (PCMCIA)";
  301 
  302         pccard_get_ether(dev, sc->sc_enaddr);
  303 
  304         /* Make sure we got a valid station address.  */
  305         if (!fe_valid_Ether_p(sc->sc_enaddr, 0))
  306                 return ENXIO;
  307 
  308         return 0;
  309 }

Cache object: 1f9f647e8f22098324e8f56347e68e63


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.