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/ed/if_ed_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  * Copyright (c) 1995, David Greenman
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD$
   28  */
   29 
   30 #include "opt_ed.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/socket.h>
   35 #include <sys/kernel.h>
   36 #include <sys/conf.h>
   37 #include <sys/uio.h>
   38 
   39 #include <sys/module.h>
   40 #include <sys/bus.h>
   41 #include <machine/bus.h>
   42 #include <sys/rman.h>
   43 #include <machine/resource.h>
   44 
   45 #include <net/ethernet.h>
   46 #include <net/if.h>
   47 #include <net/if_arp.h>
   48 #include <net/if_mib.h>
   49 #include <net/if_media.h>
   50 
   51 #include <dev/ed/if_edreg.h>
   52 #include <dev/ed/if_edvar.h>
   53 #include <dev/pccard/pccardvar.h>
   54 #include <dev/pccard/pccard_cis.h>
   55 #ifndef ED_NO_MIIBUS
   56 #include <dev/mii/mii.h>
   57 #include <dev/mii/miivar.h>
   58 #endif
   59 
   60 #include "card_if.h"
   61 #ifndef ED_NO_MIIBUS
   62 /* "device miibus" required.  See GENERIC if you get errors here. */
   63 #include "miibus_if.h"
   64 #endif
   65 #include "pccarddevs.h"
   66 
   67 #ifndef ED_NO_MIIBUS
   68 MODULE_DEPEND(ed, miibus, 1, 1, 1);
   69 #endif
   70 MODULE_DEPEND(ed, ether, 1, 1, 1);
   71 
   72 /*
   73  *      PC-Card (PCMCIA) specific code.
   74  */
   75 static int      ed_pccard_match(device_t);
   76 static int      ed_pccard_probe(device_t);
   77 static int      ed_pccard_attach(device_t);
   78 static int      ed_pccard_detach(device_t);
   79 
   80 static int      ed_pccard_ax88190(device_t dev);
   81 
   82 static void     ax88190_geteprom(struct ed_softc *);
   83 static int      ed_pccard_memwrite(device_t dev, off_t offset, u_char byte);
   84 #ifndef ED_NO_MIIBUS
   85 static void     ed_pccard_dlink_mii_reset(struct ed_softc *sc);
   86 static u_int    ed_pccard_dlink_mii_readbits(struct ed_softc *sc, int nbits);
   87 static void     ed_pccard_dlink_mii_writebits(struct ed_softc *sc, u_int val,
   88     int nbits);
   89 #endif
   90 static int      ed_pccard_Linksys(device_t dev);
   91 
   92 /*
   93  *      ed_pccard_detach - unload the driver and clear the table.
   94  */
   95 static int
   96 ed_pccard_detach(device_t dev)
   97 {
   98         struct ed_softc *sc = device_get_softc(dev);
   99         struct ifnet *ifp = &sc->arpcom.ac_if;
  100 
  101         if (sc->gone)
  102                 return (0);
  103         ed_stop(sc);
  104         ifp->if_flags &= ~IFF_RUNNING;
  105         ether_ifdetach(ifp);
  106         sc->gone = 1;
  107         bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
  108         ed_release_resources(dev);
  109         return (0);
  110 }
  111 
  112 static const struct ed_product {
  113         struct pccard_product   prod;
  114         int flags;
  115 #define NE2000DVF_DL10019       0x0001          /* chip is D-Link DL10019 */
  116 #define NE2000DVF_AX88190       0x0002          /* chip is ASIX AX88190 */
  117 } ed_pccard_products[] = {
  118         { PCMCIA_CARD(ACCTON, EN2212, 0), 0},
  119         { PCMCIA_CARD(ACCTON, EN2216, 0), 0},
  120         { PCMCIA_CARD(ALLIEDTELESIS, LA_PCM, 0), 0},
  121         { PCMCIA_CARD(AMBICOM, AMB8002T, 0), 0},
  122         { PCMCIA_CARD(BILLIONTON, LNT10TN, 0), 0},
  123         { PCMCIA_CARD(BILLIONTON, CFLT10N, 0), 0},
  124         { PCMCIA_CARD(BUFFALO, LPC3_CLT,  0), 0},
  125         { PCMCIA_CARD(BUFFALO, LPC3_CLX,  0), NE2000DVF_AX88190},
  126         { PCMCIA_CARD(BUFFALO, LPC_CF_CLT,  0), 0},
  127         { PCMCIA_CARD(CNET, NE2000, 0), 0},
  128         { PCMCIA_CARD(COMPEX, LINKPORT_ENET_B, 0), 0},
  129         { PCMCIA_CARD(COREGA, ETHER_II_PCC_T, 0), 0},
  130         { PCMCIA_CARD(COREGA, ETHER_II_PCC_TD, 0), 0},
  131         { PCMCIA_CARD(COREGA, ETHER_PCC_T, 0), 0},
  132         { PCMCIA_CARD(COREGA, ETHER_PCC_TD, 0), 0},
  133         { PCMCIA_CARD(COREGA, FAST_ETHER_PCC_TX, 0), NE2000DVF_DL10019 },
  134         { PCMCIA_CARD(COREGA, FETHER_PCC_TXD, 0), NE2000DVF_AX88190 },
  135         { PCMCIA_CARD(COREGA, FETHER_PCC_TXF, 0), NE2000DVF_DL10019 },
  136         { PCMCIA_CARD(DAYNA, COMMUNICARD_E_1, 0), 0},
  137         { PCMCIA_CARD(DAYNA, COMMUNICARD_E_2, 0), 0},
  138         { PCMCIA_CARD(DLINK, DE650, 0), 0},
  139         { PCMCIA_CARD(DLINK, DE660, 0), 0 },
  140         { PCMCIA_CARD(DLINK, DE660PLUS, 0), 0},
  141         { PCMCIA_CARD(DLINK, DFE670TXD, 0), NE2000DVF_DL10019},
  142         { PCMCIA_CARD(DYNALINK, L10C, 0), 0},
  143         { PCMCIA_CARD(EDIMAX, EP4000A, 0), 0},
  144         { PCMCIA_CARD(EPSON, EEN10B, 0), 0},
  145         { PCMCIA_CARD(EXP, THINLANCOMBO, 0), 0},
  146         { PCMCIA_CARD(GREY_CELL, DMF650TX, 0), 0},
  147         { PCMCIA_CARD(IBM, HOME_AND_AWAY, 0), 0},
  148         { PCMCIA_CARD(IBM, INFOMOVER, 0), 0},
  149         { PCMCIA_CARD(IODATA3, PCLAT, 0), 0},
  150         { PCMCIA_CARD(KINGSTON, KNE2, 0), 0},
  151         { PCMCIA_CARD(LANTECH, FASTNETTX, 0),NE2000DVF_AX88190 },
  152         { PCMCIA_CARD(LINKSYS, COMBO_ECARD, 0), NE2000DVF_DL10019 },
  153         { PCMCIA_CARD(LINKSYS, ECARD_1, 0), 0},
  154         { PCMCIA_CARD(LINKSYS, ECARD_2, 0), 0},
  155         { PCMCIA_CARD(LINKSYS, ETHERFAST, 0), NE2000DVF_DL10019 },
  156         { PCMCIA_CARD(LINKSYS, PCM100, 0), 0},
  157         { PCMCIA_CARD(LINKSYS, TRUST_COMBO_ECARD, 0), 0},
  158         { PCMCIA_CARD(LINKSYS, ETHERFAST, 0), NE2000DVF_DL10019 },
  159         { PCMCIA_CARD(MACNICA, ME1_JEIDA, 0), 0},
  160         { PCMCIA_CARD(MAGICRAM, ETHER, 0), 0},
  161         { PCMCIA_CARD(MELCO, LPC3_CLX,  0), NE2000DVF_AX88190},
  162         { PCMCIA_CARD(MELCO, LPC3_TX, 0), NE2000DVF_AX88190 },
  163         { PCMCIA_CARD(NDC, ND5100_E, 0), 0},
  164         { PCMCIA_CARD(NETGEAR, FA410TXC, 0), NE2000DVF_DL10019},
  165         { PCMCIA_CARD(NETGEAR, FA411, 0), NE2000DVF_AX88190},
  166         { PCMCIA_CARD(NEXTCOM, NEXTHAWK, 0), 0},
  167         { PCMCIA_CARD(PLANET, SMARTCOM2000, 0), 0 },
  168         { PCMCIA_CARD(PREMAX, PE200, 0), 0},
  169         { PCMCIA_CARD(RACORE, ETHERNET, 0), 0},
  170         { PCMCIA_CARD(RPTI, EP400, 0), 0},
  171         { PCMCIA_CARD(RPTI, EP401, 0), 0},
  172         { PCMCIA_CARD(SMC, EZCARD, 0), 0},
  173         { PCMCIA_CARD(SOCKET, EA_ETHER, 0), 0},
  174         { PCMCIA_CARD(SOCKET, LP_ETHER, 0), 0},
  175         { PCMCIA_CARD(SOCKET, LP_ETHER_CF, 0), 0},
  176         { PCMCIA_CARD(SOCKET, LP_ETH_10_100_CF, 0), NE2000DVF_DL10019},
  177         { PCMCIA_CARD(SVEC, COMBOCARD, 0), 0},
  178         { PCMCIA_CARD(SVEC, LANCARD, 0), 0},
  179         { PCMCIA_CARD(SYNERGY21, S21810, 0), 0},
  180         { PCMCIA_CARD(TDK, LAK_CD031, 0), 0},
  181         { PCMCIA_CARD(TELECOMDEVICE, TCD_HPC100, 0), NE2000DVF_AX88190 },
  182         { PCMCIA_CARD(XIRCOM, CFE_10, 0), 0},
  183         { PCMCIA_CARD(ZONET, ZEN, 0), 0},
  184         { { NULL } }
  185 };
  186 
  187 static int
  188 ed_pccard_match(device_t dev)
  189 {
  190         const struct ed_product *pp;
  191         int             error;
  192         uint32_t        fcn = PCCARD_FUNCTION_UNSPEC;
  193 
  194         /* Make sure we're a network function */
  195         error = pccard_get_function(dev, &fcn);
  196         if (error != 0)
  197                 return (error);
  198         if (fcn != PCCARD_FUNCTION_NETWORK)
  199                 return (ENXIO);
  200 
  201         if ((pp = (const struct ed_product *) pccard_product_lookup(dev, 
  202             (const struct pccard_product *) ed_pccard_products,
  203             sizeof(ed_pccard_products[0]), NULL)) != NULL) {
  204                 if (pp->prod.pp_name != NULL)
  205                         device_set_desc(dev, pp->prod.pp_name);
  206                 return (0);
  207         }
  208         return (ENXIO);
  209 }
  210 
  211 /* 
  212  * Probe framework for pccards.  Replicates the standard framework,
  213  * minus the pccard driver registration and ignores the ether address
  214  * supplied (from the CIS), relying on the probe to find it instead.
  215  */
  216 static int
  217 ed_pccard_probe(device_t dev)
  218 {
  219         const struct ed_product *pp;
  220         int     error;
  221 
  222         if ((pp = (const struct ed_product *) pccard_product_lookup(dev, 
  223             (const struct pccard_product *) ed_pccard_products,
  224             sizeof(ed_pccard_products[0]), NULL)) == NULL)
  225                 return (ENXIO);
  226         if (pp->flags & NE2000DVF_DL10019) {
  227                 error = ed_probe_Novell(dev, 0, 0);
  228                 if (error == 0)
  229                         error = ed_pccard_Linksys(dev);
  230                 ed_release_resources(dev);
  231                 if (error == 0)
  232                         goto end2;
  233         }
  234         if (pp->flags & NE2000DVF_AX88190) {
  235                 error = ed_pccard_ax88190(dev);
  236                 if (error == 0)
  237                         goto end2;
  238         }
  239         error = ed_probe_Novell(dev, 0, 0);
  240 end2:
  241         if (error == 0)
  242                 error = ed_alloc_irq(dev, 0, 0);
  243 
  244         ed_release_resources(dev);
  245         return (error);
  246 }
  247 
  248 static int
  249 ed_pccard_attach(device_t dev)
  250 {
  251         int error;
  252         int i;
  253         struct ed_softc *sc = device_get_softc(dev);
  254         u_char sum;
  255         u_char ether_addr[ETHER_ADDR_LEN];
  256         
  257         if (sc->port_used > 0)
  258                 ed_alloc_port(dev, sc->port_rid, sc->port_used);
  259         if (sc->mem_used)
  260                 ed_alloc_memory(dev, sc->mem_rid, sc->mem_used);
  261         ed_alloc_irq(dev, sc->irq_rid, 0);
  262                 
  263         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
  264                                edintr, sc, &sc->irq_handle);
  265         if (error) {
  266                 device_printf(dev, "setup intr failed %d \n", error);
  267                 ed_release_resources(dev);
  268                 return (error);
  269         }             
  270 
  271         if (sc->vendor != ED_VENDOR_LINKSYS) {
  272                 pccard_get_ether(dev, ether_addr);
  273                 for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
  274                         sum |= ether_addr[i];
  275                 if (sum)
  276                         bcopy(ether_addr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
  277         }
  278 
  279         error = ed_attach(dev);
  280 #ifndef ED_NO_MIIBUS
  281         if (error == 0 && sc->vendor == ED_VENDOR_LINKSYS) {
  282                 /* Probe for an MII bus, but ignore errors. */
  283                 ed_pccard_dlink_mii_reset(sc);
  284                 sc->mii_readbits = ed_pccard_dlink_mii_readbits;
  285                 sc->mii_writebits = ed_pccard_dlink_mii_writebits;
  286                 mii_phy_probe(dev, &sc->miibus, ed_ifmedia_upd,
  287                     ed_ifmedia_sts);
  288         }
  289 #endif
  290         return (error);
  291 }
  292 
  293 static void
  294 ax88190_geteprom(struct ed_softc *sc)
  295 {
  296         int prom[16],i;
  297         u_char tmp;
  298         struct {
  299                 unsigned char offset, value;
  300         } pg_seq[] = {
  301                 {ED_P0_CR, ED_CR_RD2|ED_CR_STP},/* Select Page0 */
  302                 {ED_P0_DCR, 0x01},
  303                 {ED_P0_RBCR0, 0x00},            /* Clear the count regs. */
  304                 {ED_P0_RBCR1, 0x00},
  305                 {ED_P0_IMR, 0x00},              /* Mask completion irq. */
  306                 {ED_P0_ISR, 0xff},
  307                 {ED_P0_RCR, ED_RCR_MON | ED_RCR_INTT}, /* Set To Monitor */
  308                 {ED_P0_TCR, ED_TCR_LB0},        /* loopback mode. */
  309                 {ED_P0_RBCR0, 32},
  310                 {ED_P0_RBCR1, 0x00},
  311                 {ED_P0_RSAR0, 0x00},
  312                 {ED_P0_RSAR1, 0x04},
  313                 {ED_P0_CR ,ED_CR_RD0 | ED_CR_STA},
  314         };
  315 
  316         /* Reset Card */
  317         tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
  318         ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
  319         DELAY(5000);
  320         ed_asic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
  321         DELAY(5000);
  322 
  323         /* Card Settings */
  324         for (i = 0; i < sizeof(pg_seq) / sizeof(pg_seq[0]); i++)
  325                 ed_nic_outb(sc, pg_seq[i].offset, pg_seq[i].value);
  326 
  327         /* Get Data */
  328         for (i = 0; i < 16; i++)
  329                 prom[i] = ed_asic_inb(sc, 0);
  330         sc->arpcom.ac_enaddr[0] = prom[0] & 0xff;
  331         sc->arpcom.ac_enaddr[1] = prom[0] >> 8;
  332         sc->arpcom.ac_enaddr[2] = prom[1] & 0xff;
  333         sc->arpcom.ac_enaddr[3] = prom[1] >> 8;
  334         sc->arpcom.ac_enaddr[4] = prom[2] & 0xff;
  335         sc->arpcom.ac_enaddr[5] = prom[2] >> 8;
  336 }
  337 
  338 static int
  339 ed_pccard_memwrite(device_t dev, off_t offset, u_char byte)
  340 {
  341         int cis_rid;
  342         struct resource *cis;
  343 
  344         cis_rid = 0;
  345         cis = bus_alloc_resource(dev, SYS_RES_MEMORY, &cis_rid, 0, ~0, 
  346             4 << 10, RF_ACTIVE | RF_SHAREABLE);
  347         if (cis == NULL)
  348                 return (ENXIO);
  349         CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
  350             cis_rid, PCCARD_A_MEM_ATTR);
  351 
  352         bus_space_write_1(rman_get_bustag(cis), rman_get_bushandle(cis),
  353             offset, byte);
  354 
  355         bus_deactivate_resource(dev, SYS_RES_MEMORY, cis_rid, cis);
  356         bus_release_resource(dev, SYS_RES_MEMORY, cis_rid, cis);
  357 
  358         return (0);
  359 }
  360 
  361 /*
  362  * Probe the Ethernet MAC addrees for PCMCIA Linksys EtherFast 10/100 
  363  * and compatible cards (DL10019C Ethernet controller).
  364  *
  365  * Note: The PAO patches try to use more memory for the card, but that
  366  * seems to fail for my card.  A future optimization would add this back
  367  * conditionally.
  368  */
  369 static int
  370 ed_pccard_Linksys(device_t dev)
  371 {
  372         struct ed_softc *sc = device_get_softc(dev);
  373         u_char sum;
  374         uint8_t id;
  375         int i;
  376 
  377         /*
  378          * Linksys registers(offset from ASIC base)
  379          *
  380          * 0x04-0x09 : Physical Address Register 0-5 (PAR0-PAR5)
  381          * 0x0A      : Card ID Register (CIR)
  382          * 0x0B      : Check Sum Register (SR)
  383          */
  384         for (sum = 0, i = 0x04; i < 0x0c; i++)
  385                 sum += ed_asic_inb(sc, i);
  386         if (sum != 0xff)
  387                 return (ENXIO);         /* invalid DL10019C */
  388         for (i = 0; i < ETHER_ADDR_LEN; i++)
  389                 sc->arpcom.ac_enaddr[i] = ed_asic_inb(sc, 0x04 + i);
  390         ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
  391         id = ed_asic_inb(sc, 0xf);
  392         sc->isa16bit = 1;
  393         sc->vendor = ED_VENDOR_LINKSYS;
  394         sc->type = ED_TYPE_NE2000;
  395         sc->type_str = ((id & 0x90) == 0x90) ? "DL10022" : "DL10019";
  396         return (0);
  397 }
  398 
  399 /*
  400  * Special setup for AX88190
  401  */
  402 static int
  403 ed_pccard_ax88190(device_t dev)
  404 {
  405         int     error;
  406         int     flags = device_get_flags(dev);
  407         int     iobase;
  408         struct  ed_softc *sc = device_get_softc(dev);
  409 
  410         /* Allocate the port resource during setup. */
  411         error = ed_alloc_port(dev, 0, ED_NOVELL_IO_PORTS);
  412         if (error)
  413                 return (error);
  414 
  415         sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
  416         sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
  417         sc->chip_type = ED_CHIP_TYPE_AX88190;
  418 
  419         /*
  420          * Set Attribute Memory IOBASE Register.  Is this a deficiency in
  421          * the PC Card layer, or an ax88190 specific issue? xxx
  422          */
  423         iobase = rman_get_start(sc->port_res);
  424         ed_pccard_memwrite(dev, ED_AX88190_IOBASE0, iobase & 0xff);
  425         ed_pccard_memwrite(dev, ED_AX88190_IOBASE1, (iobase >> 8) & 0xff);
  426         ax88190_geteprom(sc);
  427         ed_release_resources(dev);
  428         error = ed_probe_Novell(dev, 0, flags);
  429         if (error == 0) {
  430                 sc->vendor = ED_VENDOR_PCCARD;
  431                 sc->type = ED_TYPE_NE2000;
  432                 sc->type_str = "AX88190";
  433         }
  434         return (error);
  435 }
  436 
  437 #ifndef ED_NO_MIIBUS
  438 /* MII bit-twiddling routines for cards using Dlink chipset */
  439 #define DLINK_MIISET(sc, x) ed_asic_outb(sc, ED_DLINK_MIIBUS, \
  440     ed_asic_inb(sc, ED_DLINK_MIIBUS) | (x))
  441 #define DLINK_MIICLR(sc, x) ed_asic_outb(sc, ED_DLINK_MIIBUS, \
  442     ed_asic_inb(sc, ED_DLINK_MIIBUS) & ~(x))
  443 
  444 static void
  445 ed_pccard_dlink_mii_reset(sc)
  446         struct ed_softc *sc;
  447 {
  448         ed_asic_outb(sc, ED_DLINK_MIIBUS, 0);
  449         DELAY(10);
  450         DLINK_MIISET(sc, ED_DLINK_MII_RESET2);
  451         DELAY(10);
  452         DLINK_MIISET(sc, ED_DLINK_MII_RESET1);
  453         DELAY(10);
  454         DLINK_MIICLR(sc, ED_DLINK_MII_RESET1);
  455         DELAY(10);
  456         DLINK_MIICLR(sc, ED_DLINK_MII_RESET2);
  457         DELAY(10);
  458 }
  459 
  460 static void
  461 ed_pccard_dlink_mii_writebits(sc, val, nbits)
  462         struct ed_softc *sc;
  463         u_int val;
  464         int nbits;
  465 {
  466         int i;
  467 
  468         DLINK_MIISET(sc, ED_DLINK_MII_DIROUT);
  469 
  470         for (i = nbits - 1; i >= 0; i--) {
  471                 if ((val >> i) & 1)
  472                         DLINK_MIISET(sc, ED_DLINK_MII_DATAOUT);
  473                 else
  474                         DLINK_MIICLR(sc, ED_DLINK_MII_DATAOUT);
  475                 DELAY(10);
  476                 DLINK_MIISET(sc, ED_DLINK_MII_CLK);
  477                 DELAY(10);
  478                 DLINK_MIICLR(sc, ED_DLINK_MII_CLK);
  479                 DELAY(10);
  480         }
  481 }
  482 
  483 static u_int
  484 ed_pccard_dlink_mii_readbits(sc, nbits)
  485         struct ed_softc *sc;
  486         int nbits;
  487 {
  488         int i;
  489         u_int val = 0;
  490 
  491         DLINK_MIICLR(sc, ED_DLINK_MII_DIROUT);
  492 
  493         for (i = nbits - 1; i >= 0; i--) {
  494                 DLINK_MIISET(sc, ED_DLINK_MII_CLK);
  495                 DELAY(10);
  496                 val <<= 1;
  497                 if (ed_asic_inb(sc, ED_DLINK_MIIBUS) & ED_DLINK_MII_DATATIN)
  498                         val++;
  499                 DLINK_MIICLR(sc, ED_DLINK_MII_CLK);
  500                 DELAY(10);
  501         }
  502 
  503         return val;
  504 }
  505 #endif
  506 
  507 static device_method_t ed_pccard_methods[] = {
  508         /* Device interface */
  509         DEVMETHOD(device_probe,         pccard_compat_probe),
  510         DEVMETHOD(device_attach,        pccard_compat_attach),
  511         DEVMETHOD(device_detach,        ed_pccard_detach),
  512 
  513 #ifndef ED_NO_MIIBUS
  514         /* Bus interface */
  515         DEVMETHOD(bus_child_detached,   ed_child_detached),
  516 
  517         /* MII interface */
  518         DEVMETHOD(miibus_readreg,       ed_miibus_readreg),
  519         DEVMETHOD(miibus_writereg,      ed_miibus_writereg),
  520 #endif
  521 
  522         /* Card interface */
  523         DEVMETHOD(card_compat_match,    ed_pccard_match),
  524         DEVMETHOD(card_compat_probe,    ed_pccard_probe),
  525         DEVMETHOD(card_compat_attach,   ed_pccard_attach),
  526         { 0, 0 }
  527 };
  528 
  529 static driver_t ed_pccard_driver = {
  530         "ed",
  531         ed_pccard_methods,
  532         sizeof(struct ed_softc)
  533 };
  534 
  535 DRIVER_MODULE(ed, pccard, ed_pccard_driver, ed_devclass, 0, 0);
  536 #ifndef ED_NO_MIIBUS
  537 DRIVER_MODULE(miibus, ed, miibus_driver, miibus_devclass, 0, 0);
  538 #endif

Cache object: 37823c3e0456038a041450739b92afe5


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