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

          Line data    Source code
       1             : /*      $OpenBSD: if_ne_pcmcia.c,v 1.99 2015/11/24 13:33:18 mpi Exp $   */
       2             : /*      $NetBSD: if_ne_pcmcia.c,v 1.17 1998/08/15 19:00:04 thorpej Exp $        */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  * 3. All advertising materials mentioning features or use of this software
      16             :  *    must display the following acknowledgement:
      17             :  *      This product includes software developed by Marc Horowitz.
      18             :  * 4. The name of the author may not be used to endorse or promote products
      19             :  *    derived from this software without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      22             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      23             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      24             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      25             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      26             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      30             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #include <sys/param.h>
      34             : #include <sys/systm.h>
      35             : #include <sys/selinfo.h>
      36             : #include <sys/device.h>
      37             : #include <sys/socket.h>
      38             : 
      39             : #include <net/if.h>
      40             : #include <net/if_media.h>
      41             : #include <netinet/in.h>
      42             : #include <netinet/if_ether.h>
      43             : 
      44             : #include <machine/bus.h>
      45             : 
      46             : #include <dev/pcmcia/pcmciareg.h>
      47             : #include <dev/pcmcia/pcmciavar.h>
      48             : #include <dev/pcmcia/pcmciadevs.h>
      49             : 
      50             : #include <dev/mii/miivar.h>
      51             : #include <dev/mii/mii_bitbang.h>
      52             : 
      53             : #include <dev/ic/dp8390reg.h>
      54             : #include <dev/ic/dp8390var.h>
      55             : 
      56             : #include <dev/ic/ne2000reg.h>
      57             : #include <dev/ic/ne2000var.h>
      58             : 
      59             : #include <dev/ic/dl10019var.h>
      60             : 
      61             : #include <dev/ic/rtl80x9reg.h>
      62             : #include <dev/ic/rtl80x9var.h>
      63             : 
      64             : #include <dev/ic/ax88190reg.h>
      65             : #include <dev/ic/ax88190var.h>
      66             : 
      67             : int     ne_pcmcia_match(struct device *, void *, void *);
      68             : void    ne_pcmcia_attach(struct device *, struct device *, void *);
      69             : int     ne_pcmcia_detach(struct device *, int);
      70             : int     ne_pcmcia_activate(struct device *, int);
      71             : 
      72             : int     ne_pcmcia_enable(struct dp8390_softc *);
      73             : void    ne_pcmcia_disable(struct dp8390_softc *);
      74             : 
      75             : struct ne_pcmcia_softc {
      76             :         struct ne2000_softc sc_ne2000;          /* real "ne2000" softc */
      77             : 
      78             :         /* PCMCIA-specific goo */
      79             :         struct pcmcia_io_handle sc_pcioh;       /* PCMCIA i/o information */
      80             :         int sc_asic_io_window;                  /* i/o window for ASIC */
      81             :         int sc_nic_io_window;                   /* i/o window for NIC */
      82             :         struct pcmcia_function *sc_pf;          /* our PCMCIA function */
      83             :         void *sc_ih;                            /* interrupt handle */
      84             : };
      85             : 
      86             : u_int8_t *
      87             :         ne_pcmcia_get_enaddr(struct ne_pcmcia_softc *, int,
      88             :             u_int8_t[ETHER_ADDR_LEN]);
      89             : u_int8_t *
      90             :         ne_pcmcia_dl10019_get_enaddr(struct ne_pcmcia_softc *,
      91             :             u_int8_t[ETHER_ADDR_LEN]);
      92             : int     ne_pcmcia_ax88190_set_iobase(struct ne_pcmcia_softc *);
      93             : 
      94             : struct cfattach ne_pcmcia_ca = {
      95             :         sizeof(struct ne_pcmcia_softc), ne_pcmcia_match, ne_pcmcia_attach,
      96             :         ne_pcmcia_detach, ne_pcmcia_activate
      97             : };
      98             : 
      99             : const struct ne2000dev {
     100             :     u_int16_t manufacturer;
     101             :     u_int16_t product;
     102             :     char *cis_info[4];
     103             :     int function;
     104             :     int enet_maddr;
     105             :     unsigned char enet_vendor[3];
     106             :     int flags;
     107             : #define NE2000DVF_AX88190       0x0002  /* chip is ASIX AX88190 */
     108             : } ne2000devs[] = {
     109             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     110             :       PCMCIA_CIS_AMBICOM_AMB8002T,
     111             :       0, -1, { 0x00, 0x10, 0x7a } },
     112             : 
     113             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     114             :       PCMCIA_CIS_PREMAX_PE200,
     115             :       0, 0x07f0, { 0x00, 0x20, 0xe0 } },
     116             : 
     117             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     118             :       PCMCIA_CIS_DIGITAL_DEPCMXX,
     119             :       0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
     120             : 
     121             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     122             :       PCMCIA_CIS_PLANET_SMARTCOM2000,
     123             :       0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
     124             : 
     125             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     126             :       PCMCIA_CIS_DLINK_DE660,
     127             :       0, -1, { 0x00, 0x80, 0xc8 } },
     128             : 
     129             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     130             :       PCMCIA_CIS_DLINK_DE660PLUS,
     131             :       0, -1, { 0x00, 0x80, 0xc8 } },
     132             : 
     133             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     134             :       PCMCIA_CIS_RPTI_EP400,
     135             :       0, -1, { 0x00, 0x40, 0x95 } },
     136             : 
     137             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     138             :       PCMCIA_CIS_RPTI_EP401,
     139             :       0, -1, { 0x00, 0x40, 0x95 } },
     140             : 
     141             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     142             :       PCMCIA_CIS_ACCTON_EN2212,
     143             :       0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
     144             : 
     145             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     146             :       PCMCIA_CIS_ADDTRON_W89C926,
     147             :       0, -1, { 0x00, 0x40, 0x33 } },
     148             : 
     149             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     150             :       PCMCIA_CIS_SVEC_COMBOCARD,
     151             :       0, -1, { 0x00, 0xe0, 0x98 } },
     152             : 
     153             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     154             :       PCMCIA_CIS_SVEC_LANCARD,
     155             :       0, 0x07f0, { 0x00, 0xc0, 0x6c } },
     156             : 
     157             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_EPSON_EEN10B,
     158             :       PCMCIA_CIS_EPSON_EEN10B,
     159             :       0, 0x0ff0, { 0x00, 0x00, 0x48 } },
     160             : 
     161             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     162             :       PCMCIA_CIS_EDIMAX_NE2000,
     163             :       0, -1, { 0x00, 0x00, 0xb4 } },
     164             : 
     165             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     166             :       PCMCIA_CIS_CNET_NE2000,
     167             :       0, -1, { 0x00, 0x80, 0xad } },
     168             : 
     169             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_CNET_CNF301,
     170             :       PCMCIA_CIS_CNET_CNF301,
     171             :       0, -1, { 0x00, 0x10, 0x60 } },
     172             : 
     173             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     174             :       PCMCIA_CIS_BILLIONTON_LNT10TN,
     175             :       0, -1, { 0x00, 0x00, 0x00 } },
     176             : 
     177             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     178             :       PCMCIA_CIS_NDC_ND5100_E,
     179             :       0, -1, { 0x00, 0x80, 0xc6 } },
     180             : 
     181             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     182             :       PCMCIA_CIS_SYNERGY21_S21810,
     183             :       0, -1, { 0x00, 0x48, 0x54 } },
     184             : 
     185             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     186             :       PCMCIA_CIS_TAMARACK_NE2000,
     187             :       0, -1, { 0x00, 0x47, 0x43 } },
     188             : 
     189             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     190             :       PCMCIA_CIS_GVC_NIC2000P,
     191             :       0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
     192             : 
     193             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     194             :       PCMCIA_CIS_WISECOM_T210CT,
     195             :       0, -1, { 0x00, 0x20, 0x18 } },
     196             : 
     197             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     198             :       PCMCIA_CIS_WISECOM_IPORT,
     199             :       0, -1, { 0x00, 0x02, 0xdd } },
     200             : 
     201             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     202             :       PCMCIA_CIS_AROWANA_FE,
     203             :       0, -1, { 0x00, 0x48, 0x54 }, NE2000DVF_AX88190 },
     204             : 
     205             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     206             :       PCMCIA_CIS_GVC_NP0335,
     207             :       0, -1, { 0x00, 0x40, 0x05 } },
     208             : 
     209             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     210             :       PCMCIA_CIS_RELIA_RE2408T,
     211             :       0, -1, { 0x00, 0xc0, 0x0c } },
     212             : 
     213             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     214             :       PCMCIA_CIS_BILLIONTON_CFLT2,
     215             :       0, -1, { 0x00, 0x10, 0x60 } },
     216             : 
     217             :     /*
     218             :      * You have to add new entries which contains
     219             :      * PCMCIA_VENDOR_INVALID and/or PCMCIA_PRODUCT_INVALID
     220             :      * in front of this comment.
     221             :      *
     222             :      * There are cards which use a generic vendor and product id but needs
     223             :      * a different handling depending on the cis_info, so ne2000_match
     224             :      * needs a table where the exceptions comes first and then the normal
     225             :      * product and vendor entries.
     226             :      */
     227             : 
     228             :     { PCMCIA_VENDOR_GREYCELL, PCMCIA_PRODUCT_GREYCELL_GCS2000,
     229             :       PCMCIA_CIS_GREYCELL_GCS2000,
     230             :       0, -1, { 0x00, 0x47, 0x43 } },
     231             : 
     232             :     { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
     233             :       PCMCIA_CIS_IBM_INFOMOVER,
     234             :       0, 0x0ff0, { 0x08, 0x00, 0x5a } },
     235             : 
     236             :     { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
     237             :       PCMCIA_CIS_IBM_INFOMOVER,
     238             :       0, 0x0ff0, { 0x00, 0x04, 0xac } },
     239             : 
     240             :     { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
     241             :       PCMCIA_CIS_IBM_INFOMOVER,
     242             :       0, 0x0ff0, { 0x00, 0x06, 0x29 } },
     243             : 
     244             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ECARD_1,
     245             :       PCMCIA_CIS_LINKSYS_ECARD_1,
     246             :       0, -1, { 0x00, 0x80, 0xc8 } },
     247             : 
     248             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_PCM100,
     249             :       PCMCIA_CIS_LINKSYS_PCM100,
     250             :       0, -1, { 0x00, 0x04, 0x5a } },
     251             : 
     252             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
     253             :       PCMCIA_CIS_LINKSYS_COMBO_ECARD,
     254             :       0, -1, { 0x00, 0x04, 0x5a }, NE2000DVF_AX88190 },
     255             : 
     256             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
     257             :       PCMCIA_CIS_LINKSYS_COMBO_ECARD,
     258             :       0, -1, { 0x00, 0x80, 0xc8 } },
     259             : 
     260             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
     261             :       PCMCIA_CIS_PLANEX_FNW3600T,
     262             :       0, -1, { 0x00, 0x90, 0xcc } },
     263             : 
     264             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
     265             :       PCMCIA_CIS_SVEC_PN650TX,
     266             :       0, -1, { 0x00, 0xe0, 0x98 } },
     267             : 
     268             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
     269             :       PCMCIA_CIS_TRENDNET_TECF100,
     270             :       0, -1, { 0x00, 0x12, 0x0e } },
     271             : 
     272             :     /*
     273             :      * This entry should be here so that above two cards doesn't
     274             :      * match with this.  FNW-3700T won't match above entries due to
     275             :      * MAC address check.
     276             :      */
     277             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
     278             :       PCMCIA_CIS_PLANEX_FNW3700T,
     279             :       0, -1, { 0x00, 0x90, 0xcc }, NE2000DVF_AX88190 },
     280             : 
     281             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
     282             :       PCMCIA_CIS_LINKSYS_ETHERFAST,
     283             :       0, -1, { 0x00, 0x80, 0xc8 } },
     284             : 
     285             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
     286             :       PCMCIA_CIS_LINKSYS_ETHERFAST,
     287             :       0, -1, { 0x00, 0x50, 0xba } },
     288             : 
     289             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
     290             :       PCMCIA_CIS_DLINK_DE650,
     291             :       0, -1, { 0x00, 0xe0, 0x98 } },
     292             : 
     293             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
     294             :       PCMCIA_CIS_IODATA_PCETTXR,
     295             :       0, -1, { 0x00, 0xa0, 0xb0 } },
     296             : 
     297             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     298             :       PCMCIA_CIS_DLINK_DFE670TXD,
     299             :       0, -1, { 0x00, 0x05, 0x5d } },
     300             : 
     301             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     302             :       PCMCIA_CIS_DLINK_DFE670TXD,
     303             :       0, -1, { 0x00, 0x50, 0xba } },
     304             : 
     305             :      { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     306             :        PCMCIA_CIS_DLINK_DFE670TXD,
     307             :        0, -1, { 0x00, 0x0d, 0x88 } },
     308             : 
     309             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     310             :       PCMCIA_CIS_DLINK_DFE670TXD,
     311             :       0, -1, { 0x00, 0x13, 0x46 } },
     312             : 
     313             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     314             :       PCMCIA_CIS_DLINK_DFE670TXD,
     315             :       0, -1, { 0x00, 0x40, 0x05 } },
     316             : 
     317             :     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_TRUST_COMBO_ECARD,
     318             :       PCMCIA_CIS_LINKSYS_TRUST_COMBO_ECARD,
     319             :       0, 0x0120, { 0x20, 0x04, 0x49 } },
     320             : 
     321             :     /* Although the comments above say to put VENDOR/PRODUCT INVALID IDs
     322             :        above this list, we need to keep this one below the ECARD_1, or else
     323             :        both will match the same more-generic entry rather than the more
     324             :        specific one above with proper vendor and product IDs. */
     325             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     326             :       PCMCIA_CIS_LINKSYS_ECARD_2,
     327             :       0, -1, { 0x00, 0x80, 0xc8 } },
     328             : 
     329             :     /*
     330             :      * D-Link DE-650 has many minor versions:
     331             :      *
     332             :      *   CIS information          Manufacturer Product  Note
     333             :      * 1 "D-Link, DE-650"             INVALID  INVALID  white card
     334             :      * 2 "D-Link, DE-650, Ver 01.00"  INVALID  INVALID  became bare metal
     335             :      * 3 "D-Link, DE-650, Ver 01.00"   0x149    0x265   minor change in look
     336             :      * 4 "D-Link, DE-650, Ver 01.00"   0x149    0x265   collision LED added
     337             :      *
     338             :      * While the 1st and the 2nd types should use the "D-Link DE-650" entry,
     339             :      * the 3rd and the 4th types should use the "Linksys EtherCard" entry.
     340             :      * Therefore, this entry must be below the LINKSYS_ECARD_1.  --itohy
     341             :      */
     342             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     343             :       PCMCIA_CIS_DLINK_DE650,
     344             :       0, 0x0040, { 0x00, 0x80, 0xc8 } },
     345             : 
     346             :     /*
     347             :      * IO-DATA PCLA/TE and later version of PCLA/T has valid
     348             :      * vendor/product ID and it is possible to read MAC address
     349             :      * using standard I/O ports.  It also read from CIS offset 0x01c0.
     350             :      * On the other hand, earlier version of PCLA/T doesn't have valid
     351             :      * vendor/product ID and MAC address must be read from CIS offset
     352             :      * 0x0ff0 (i.e., usual ne2000 way to read it doesn't work).
     353             :      * And CIS information of earlier and later version of PCLA/T are
     354             :      * same except fourth element.  So, for now, we place the entry for
     355             :      * PCLA/TE (and later version of PCLA/T) followed by entry
     356             :      * for the earlier version of PCLA/T (or, modify to match all CIS
     357             :      * information and have three or more individual entries).
     358             :      */
     359             :     { PCMCIA_VENDOR_IODATA, PCMCIA_PRODUCT_IODATA_PCLATE,
     360             :       PCMCIA_CIS_IODATA_PCLATE,
     361             :       0, -1, { 0x00, 0xa0, 0xb0 } },
     362             : 
     363             :     /*
     364             :      * This entry should be placed after above PCLA-TE entry.
     365             :      * See above comments for detail.
     366             :      */
     367             :     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
     368             :       PCMCIA_CIS_IODATA_PCLAT,
     369             :       0, 0x0ff0, { 0x00, 0xa0, 0xb0 } },
     370             : 
     371             :     { PCMCIA_VENDOR_DAYNA, PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_1,
     372             :       PCMCIA_CIS_DAYNA_COMMUNICARD_E_1,
     373             :       0, 0x0110, { 0x00, 0x80, 0x19 } },
     374             : 
     375             :     { PCMCIA_VENDOR_DAYNA, PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_2,
     376             :       PCMCIA_CIS_DAYNA_COMMUNICARD_E_2,
     377             :       0, -1, { 0x00, 0x80, 0x19 } },
     378             : 
     379             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_PCC_T,
     380             :       PCMCIA_CIS_COREGA_ETHER_PCC_T,
     381             :       0, -1, { 0x00, 0x00, 0xf4 } },
     382             : 
     383             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_PCC_TD,
     384             :       PCMCIA_CIS_COREGA_ETHER_PCC_TD,
     385             :       0, -1, { 0x00, 0x00, 0xf4 } },
     386             : 
     387             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_II_PCC_T,
     388             :       PCMCIA_CIS_COREGA_ETHER_II_PCC_T,
     389             :       0, -1, { 0x00, 0x00, 0xf4 } },
     390             : 
     391             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_ETHER_II_PCC_TD,
     392             :       PCMCIA_CIS_COREGA_ETHER_II_PCC_TD,
     393             :       0, -1, { 0x00, 0x00, 0xf4 } },
     394             : 
     395             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_FAST_ETHER_PCC_TX,
     396             :       PCMCIA_CIS_COREGA_FAST_ETHER_PCC_TX,
     397             :       0, -1, { 0x00, 0x00, 0xf4 } },
     398             : 
     399             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_FETHER_PCC_TXF,
     400             :       PCMCIA_CIS_COREGA_FETHER_PCC_TXF,
     401             :       0, -1, { 0x00, 0x90, 0x99 } },
     402             : 
     403             :     { PCMCIA_VENDOR_COREGA, PCMCIA_PRODUCT_COREGA_FETHER_PCC_TXD,
     404             :       PCMCIA_CIS_COREGA_FETHER_PCC_TXD,
     405             :       0, -1, { 0x00, 0x90, 0x99 } },
     406             : 
     407             :     { PCMCIA_VENDOR_COMPEX, PCMCIA_PRODUCT_COMPEX_LINKPORT_ENET_B,
     408             :       PCMCIA_CIS_COMPEX_LINKPORT_ENET_B,
     409             :       0, 0x01c0, { 0x00, 0xa0, 0x0c } },
     410             : 
     411             :     { PCMCIA_VENDOR_SMC, PCMCIA_PRODUCT_SMC_EZCARD,
     412             :       PCMCIA_CIS_SMC_EZCARD,
     413             :       0, 0x01c0, { 0x00, 0xe0, 0x29 } },
     414             : 
     415             :     { PCMCIA_VENDOR_IODATA, PCMCIA_PRODUCT_IODATA_8041TX,
     416             :       PCMCIA_CIS_IODATA_8041TX,
     417             :       0, -1, { 0x00, 0x04, 0xe2 } },
     418             : 
     419             :     { PCMCIA_VENDOR_SMC, PCMCIA_PRODUCT_SMC_8041,
     420             :       PCMCIA_CIS_SMC_8041,
     421             :       0, -1, { 0x00, 0x04, 0xe2 } },
     422             : 
     423             :     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETHER_CF,
     424             :       PCMCIA_CIS_SOCKET_LP_ETHER_CF,
     425             :       0, -1, { 0x00, 0xc0, 0x1b} },
     426             : 
     427             :     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETHER,
     428             :       PCMCIA_CIS_SOCKET_LP_ETHER,
     429             :       0, -1, { 0x00, 0xc0, 0x1b } },
     430             : 
     431             :     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_ETHER_CF_10_100,
     432             :       PCMCIA_CIS_SOCKET_ETHER_CF_10_100,
     433             :       0, -1, { 0x00, 0x12, 0x0e } },
     434             : 
     435             :     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_ETHER_CF_10_100,
     436             :       PCMCIA_CIS_SOCKET_ETHER_CF_10_100,
     437             :       0, -1, { 0x00, 0xe0, 0x98 } },
     438             : 
     439             :     { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CFE_10,
     440             :       PCMCIA_CIS_XIRCOM_CFE_10,
     441             :       0, -1, { 0x00, 0x10, 0xa4 } },
     442             : 
     443             :     { PCMCIA_VENDOR_MELCO, PCMCIA_PRODUCT_MELCO_LPC3_TX,
     444             :       PCMCIA_CIS_MELCO_LPC3_TX,
     445             :       0, -1, { 0x00, 0x40, 0x26 }, NE2000DVF_AX88190 },
     446             : 
     447             :     { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC_CF_CLT,
     448             :       PCMCIA_CIS_INVALID,
     449             :       0, -1, { 0x00, 0x07, 0x40 } },
     450             : 
     451             :     { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC3_CLT,
     452             :       PCMCIA_CIS_INVALID,
     453             :       0, -1, { 0x00, 0x07, 0x40 } },
     454             : 
     455             :     { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC4_CLX,
     456             :       PCMCIA_CIS_INVALID,
     457             :       0, -1, { 0x00, 0x40, 0xfa }, NE2000DVF_AX88190 },
     458             : 
     459             :     { PCMCIA_VENDOR_DUAL, PCMCIA_PRODUCT_DUAL_NE2000,
     460             :       PCMCIA_CIS_DUAL_NE2000,
     461             :       0, 0x0ff0, { 0x00, 0xa0, 0x0c } },
     462             : 
     463             :     { PCMCIA_VENDOR_ALLIEDTELESIS, PCMCIA_PRODUCT_ALLIEDTELESIS_LA_PCM,
     464             :       PCMCIA_CIS_ALLIEDTELESIS_LA_PCM,
     465             :       0, 0x0ff0, { 0x00, 0x00, 0xf4 } },
     466             : 
     467             :     { PCMCIA_VENDOR_KINGSTON, PCMCIA_PRODUCT_KINGSTON_KNE_PCM,
     468             :       PCMCIA_CIS_KINGSTON_KNE_PCM,
     469             :       0, 0x0ff0, { 0xe2, 0x0c, 0x0f } },
     470             : 
     471             :     { PCMCIA_VENDOR_KINGSTON, PCMCIA_PRODUCT_KINGSTON_KNE_PC2,
     472             :       PCMCIA_CIS_KINGSTON_KNE_PC2,
     473             :       0, 0x0180, { 0x00, 0xc0, 0xf0 } },
     474             : 
     475             :     { PCMCIA_VENDOR_TELECOMDEVICE, PCMCIA_PRODUCT_TELECOMDEVICE_TCD_HPC100,
     476             :       PCMCIA_CIS_TELECOMDEVICE_TCD_HPC100,
     477             :       0, -1, { 0x00, 0x40, 0x26 }, NE2000DVF_AX88190 },
     478             : 
     479             :     { PCMCIA_VENDOR_MACNICA, PCMCIA_PRODUCT_MACNICA_ME1_JEIDA,
     480             :       PCMCIA_CIS_MACNICA_ME1_JEIDA,
     481             :       0, 0x00b8, { 0x08, 0x00, 0x42 } },
     482             : 
     483             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     484             :       PCMCIA_CIS_NETGEAR_FA410TXC,
     485             :       0, -1, { 0x00, 0x40, 0xf4 } },
     486             : 
     487             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     488             :       PCMCIA_CIS_NETGEAR_FA410TXC,
     489             :       0, -1, { 0x00, 0x48, 0x54 } },
     490             : 
     491             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     492             :       PCMCIA_CIS_DLINK_DFE670TXD,
     493             :       0, -1, { 0x00, 0x40, 0x05 } },
     494             : 
     495             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     496             :       PCMCIA_CIS_DLINK_DFE670TXD,
     497             :       0, -1, { 0x00, 0x11, 0x95 } },
     498             : 
     499             :      { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
     500             :        PCMCIA_CIS_DLINK_DFE670TXD,
     501             :        0, -1, { 0x00, 0x0d, 0x88 } },
     502             : 
     503             :     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA411,
     504             :       PCMCIA_CIS_NETGEAR_FA411,
     505             :       0, -1, { 0x00, 0x40, 0xf4 } },
     506             : 
     507             :     { PCMCIA_VENDOR_BELKIN, PCMCIA_PRODUCT_BELKIN_F5D5020,
     508             :       PCMCIA_CIS_BELKIN_F5D5020,
     509             :       0, -1, { 0x00, 0x30, 0xbd } },
     510             : 
     511             : #if 0
     512             :     /* the rest of these are stolen from the linux pcnet pcmcia device
     513             :        driver.  Since I don't know the manfid or cis info strings for
     514             :        any of them, they're not compiled in until I do. */
     515             :     { "APEX MultiCard",
     516             :       0x0000, 0x0000, NULL, NULL, 0,
     517             :       0x03f4, { 0x00, 0x20, 0xe5 } },
     518             :     { "ASANTE FriendlyNet",
     519             :       0x0000, 0x0000, NULL, NULL, 0,
     520             :       0x4910, { 0x00, 0x00, 0x94 } },
     521             :     { "Danpex EN-6200P2",
     522             :       0x0000, 0x0000, NULL, NULL, 0,
     523             :       0x0110, { 0x00, 0x40, 0xc7 } },
     524             :     { "DataTrek NetCard",
     525             :       0x0000, 0x0000, NULL, NULL, 0,
     526             :       0x0ff0, { 0x00, 0x20, 0xe8 } },
     527             :     { "EP-210 Ethernet",
     528             :       0x0000, 0x0000, NULL, NULL, 0,
     529             :       0x0110, { 0x00, 0x40, 0x33 } },
     530             :     { "ELECOM Laneed LD-CDWA",
     531             :       0x0000, 0x0000, NULL, NULL, 0,
     532             :       0x00b8, { 0x08, 0x00, 0x42 } },
     533             :     { "Grey Cell GCS2220",
     534             :       0x0000, 0x0000, NULL, NULL, 0,
     535             :       0x0000, { 0x00, 0x47, 0x43 } },
     536             :     { "Hypertec Ethernet",
     537             :       0x0000, 0x0000, NULL, NULL, 0,
     538             :       0x01c0, { 0x00, 0x40, 0x4c } },
     539             :     { "IBM FME",
     540             :       0x0000, 0x0000, NULL, NULL, 0,
     541             :       0x0374, { 0x00, 0x04, 0xac } },
     542             :     { "IBM FME",
     543             :       0x0000, 0x0000, NULL, NULL, 0,
     544             :       0x0374, { 0x08, 0x00, 0x5a } },
     545             :     { "Katron PE-520",
     546             :       0x0000, 0x0000, NULL, NULL, 0,
     547             :       0x0110, { 0x00, 0x40, 0xf6 } },
     548             :     { "Kingston KNE-PCM/x",
     549             :       0x0000, 0x0000, NULL, NULL, 0,
     550             :       0x0ff0, { 0x00, 0xc0, 0xf0 } },
     551             :     { "Longshine LCS-8534",
     552             :       0x0000, 0x0000, NULL, NULL, 0,
     553             :       0x0000, { 0x08, 0x00, 0x00 } },
     554             :     { "Maxtech PCN2000",
     555             :       0x0000, 0x0000, NULL, NULL, 0,
     556             :       0x5000, { 0x00, 0x00, 0xe8 } },
     557             :     { "NDC Instant-Link",
     558             :       0x0000, 0x0000, NULL, NULL, 0,
     559             :       0x003a, { 0x00, 0x80, 0xc6 } },
     560             :     { "Network General Sniffer",
     561             :       0x0000, 0x0000, NULL, NULL, 0,
     562             :       0x0ff0, { 0x00, 0x00, 0x65 } },
     563             :     { "Panasonic VEL211",
     564             :       0x0000, 0x0000, NULL, NULL, 0,
     565             :       0x0ff0, { 0x00, 0x80, 0x45 } },
     566             :     { "SCM Ethernet",
     567             :       0x0000, 0x0000, NULL, NULL, 0,
     568             :       0x0ff0, { 0x00, 0x20, 0xcb } },
     569             :     { "Socket EA",
     570             :       0x0000, 0x0000, NULL, NULL, 0,
     571             :       0x4000, { 0x00, 0xc0, 0x1b } },
     572             :     { "Volktek NPL-402CT",
     573             :       0x0000, 0x0000, NULL, NULL, 0,
     574             :       0x0060, { 0x00, 0x40, 0x05 } },
     575             : #endif
     576             : };
     577             : 
     578             : #define NE2000_NDEVS    (sizeof(ne2000devs) / sizeof(ne2000devs[0]))
     579             : 
     580             : #define ne2000_match(card, fct, n) \
     581             : ((((((card)->manufacturer != PCMCIA_VENDOR_INVALID) && \
     582             :     ((card)->manufacturer == ne2000devs[(n)].manufacturer) && \
     583             :     ((card)->product != PCMCIA_PRODUCT_INVALID) && \
     584             :     ((card)->product == ne2000devs[(n)].product)) || \
     585             :    ((ne2000devs[(n)].cis_info[0]) && (ne2000devs[(n)].cis_info[1]) && \
     586             :     ((card)->cis1_info[0]) && ((card)->cis1_info[1]) && \
     587             :     (strcmp((card)->cis1_info[0], ne2000devs[(n)].cis_info[0]) == 0) && \
     588             :     (strcmp((card)->cis1_info[1], ne2000devs[(n)].cis_info[1]) == 0))) && \
     589             :   ((fct) == ne2000devs[(n)].function))? \
     590             :  &ne2000devs[(n)]:NULL)
     591             : 
     592             : int
     593           0 : ne_pcmcia_match(parent, match, aux)
     594             :         struct device *parent;
     595             :         void *match, *aux;
     596             : {
     597           0 :         struct pcmcia_attach_args *pa = aux;
     598             :         int i;
     599             : 
     600           0 :         for (i = 0; i < NE2000_NDEVS; i++) {
     601           0 :                 if (ne2000_match(pa->card, pa->pf->number, i))
     602           0 :                         return (1);
     603             :         }
     604             : 
     605           0 :         return (0);
     606           0 : }
     607             : 
     608             : void
     609           0 : ne_pcmcia_attach(parent, self, aux)
     610             :         struct device *parent, *self;
     611             :         void *aux;
     612             : {
     613           0 :         struct ne_pcmcia_softc *psc = (void *) self;
     614           0 :         struct ne2000_softc *nsc = &psc->sc_ne2000;
     615           0 :         struct dp8390_softc *dsc = &nsc->sc_dp8390;
     616           0 :         struct pcmcia_attach_args *pa = aux;
     617             :         struct pcmcia_config_entry *cfe;
     618             :         const struct ne2000dev *ne_dev;
     619             :         const char *intrstr;
     620             :         int i;
     621           0 :         u_int8_t myea[6], *enaddr;
     622             : 
     623           0 :         psc->sc_pf = pa->pf;
     624             : 
     625           0 :         for (cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head); cfe != NULL;
     626           0 :             cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
     627             : #if 0
     628             :                 /*
     629             :                  * Some ne2000 driver's claim to have memory; others don't.
     630             :                  * Since I don't care, I don't check.
     631             :                  */
     632             : 
     633             :                 if (cfe->num_memspace != 1) {
     634             :                         printf(": unexpected number of memory spaces, "
     635             :                             " %d should be 1\n", cfe->num_memspace);
     636             :                         return;
     637             :                 }
     638             : #endif
     639             : 
     640           0 :                 if (cfe->num_iospace == 1) {
     641           0 :                         if (cfe->iospace[0].length != NE2000_NPORTS) {
     642           0 :                                 printf(": unexpected I/O space "
     643             :                                     "configuration\n");
     644           0 :                                 continue;
     645             :                         }
     646           0 :                 } else if (cfe->num_iospace == 2) {
     647             :                         /*
     648             :                          * Some cards report a separate space for NIC and ASIC.
     649             :                          * This make some sense, but we must allocate a single
     650             :                          * NE2000_NPORTS-sized chunk, due to brain damaged
     651             :                          * address decoders on some of these cards.
     652             :                          */
     653           0 :                         if (cfe->iospace[0].length + cfe->iospace[1].length !=
     654             :                             NE2000_NPORTS) {
     655             : #ifdef DIAGNOSTIC
     656           0 :                                 printf(": unexpected I/O space "
     657             :                                     "configuration\n");
     658             : #endif
     659           0 :                                 continue;
     660             :                         }
     661             :                 } else {
     662             : #ifdef DIAGNOSTIC
     663           0 :                         printf(": unexpected number of i/o spaces %d"
     664             :                             " should be 1 or 2\n", cfe->num_iospace);
     665             : #endif
     666           0 :                         continue;
     667             :                 }
     668             : 
     669           0 :                 if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
     670             :                     NE2000_NPORTS, NE2000_NPORTS, &psc->sc_pcioh)) {
     671             : #ifdef DIAGNOSTIC
     672           0 :                         printf(": can't allocate I/O space\n");
     673             : #endif
     674           0 :                         continue;
     675             :                 }
     676             : 
     677             :                 break;
     678             :         }
     679             : 
     680           0 :         if (cfe == NULL) {
     681           0 :                 printf(": no suitable config entry\n");
     682           0 :                 goto fail_1;
     683             :         }
     684             : 
     685           0 :         dsc->sc_regt = psc->sc_pcioh.iot;
     686           0 :         dsc->sc_regh = psc->sc_pcioh.ioh;
     687             : 
     688           0 :         nsc->sc_asict = psc->sc_pcioh.iot;
     689           0 :         if (bus_space_subregion(dsc->sc_regt, dsc->sc_regh,
     690           0 :             NE2000_ASIC_OFFSET, NE2000_ASIC_NPORTS, &nsc->sc_asich)) {
     691           0 :                 printf(": can't get subregion for asic\n");
     692           0 :                 goto fail_2;
     693             :         }
     694             : 
     695             : #ifdef notyet
     696             :         /* Set up power management hooks. */
     697             :         dsc->sc_enable = ne_pcmcia_enable;
     698             :         dsc->sc_disable = ne_pcmcia_disable;
     699             : #endif
     700             : 
     701             :         /* Enable the card. */
     702           0 :         pcmcia_function_init(pa->pf, cfe);
     703           0 :         if (pcmcia_function_enable(pa->pf)) {
     704           0 :                 printf(": function enable failed\n");
     705           0 :                 goto fail_2;
     706             :         }
     707             : 
     708           0 :         dsc->sc_enabled = 1;
     709             : 
     710             :         /* some cards claim to be io16, but they're lying. */
     711           0 :         if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO8, NE2000_NIC_OFFSET,
     712           0 :             NE2000_NIC_NPORTS, &psc->sc_pcioh, &psc->sc_nic_io_window)) {
     713           0 :                 printf(": can't map NIC I/O space\n");
     714           0 :                 goto fail_3;
     715             :         }
     716             : 
     717           0 :         if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO16, NE2000_ASIC_OFFSET,
     718           0 :             NE2000_ASIC_NPORTS, &psc->sc_pcioh, &psc->sc_asic_io_window)) {
     719           0 :                 printf(": can't map ASIC I/O space\n");
     720           0 :                 goto fail_4;
     721             :         }
     722             : 
     723           0 :         printf(" port 0x%lx/%d", psc->sc_pcioh.addr, NE2000_NPORTS);
     724             : 
     725             :         /*
     726             :          * Read the station address from the board.
     727             :          */
     728           0 :         i = 0;
     729             : again:
     730             :         enaddr = NULL;                  /* Ask ASIC by default */
     731           0 :         for (; i < NE2000_NDEVS; i++) {
     732           0 :                 ne_dev = ne2000_match(pa->card, pa->pf->number, i);
     733           0 :                 if (ne_dev != NULL) {
     734           0 :                         if (ne_dev->enet_maddr >= 0) {
     735           0 :                                 enaddr = ne_pcmcia_get_enaddr(psc,
     736           0 :                                     ne_dev->enet_maddr, myea);
     737           0 :                                 if (enaddr == NULL)
     738             :                                         continue;
     739             :                         } else {
     740           0 :                                 enaddr = ne_pcmcia_dl10019_get_enaddr(psc,
     741           0 :                                     myea);
     742             :                         }
     743             :                         break;
     744             :                 }
     745             :         }
     746           0 :         if (i == NE2000_NDEVS) {
     747           0 :                 printf(": can't match ethernet vendor code\n");
     748           0 :                 goto fail_5;
     749             :         }
     750             : 
     751           0 :         if (enaddr != NULL) {
     752             :                 /*
     753             :                  * Make sure this is what we expect.
     754             :                  */
     755           0 :                 if (enaddr[0] != ne_dev->enet_vendor[0] ||
     756           0 :                     enaddr[1] != ne_dev->enet_vendor[1] ||
     757           0 :                     enaddr[2] != ne_dev->enet_vendor[2]) {
     758           0 :                         ++i;
     759           0 :                         goto again;
     760             :                 }
     761             :         }
     762             : 
     763           0 :         if ((ne_dev->flags & NE2000DVF_AX88190) != 0) {
     764           0 :                 if (ne_pcmcia_ax88190_set_iobase(psc))
     765             :                         goto fail_5;
     766             : 
     767           0 :                 dsc->sc_mediachange = ax88190_mediachange;
     768           0 :                 dsc->sc_mediastatus = ax88190_mediastatus;
     769           0 :                 dsc->init_card = ax88190_init_card;
     770           0 :                 dsc->stop_card = ax88190_stop_card;
     771           0 :                 dsc->sc_media_init = ax88190_media_init;
     772           0 :                 dsc->sc_media_fini = ax88190_media_fini;
     773             : 
     774           0 :                 nsc->sc_type = NE2000_TYPE_AX88190;
     775           0 :         }
     776             : 
     777             :         /*
     778             :          * Check for a Realtek 8019.
     779             :          */
     780           0 :         bus_space_write_1(dsc->sc_regt, dsc->sc_regh, ED_P0_CR,
     781             :             ED_CR_PAGE_0 | ED_CR_STP);
     782           0 :         if (bus_space_read_1(dsc->sc_regt, dsc->sc_regh, NERTL_RTL0_8019ID0)
     783           0 :                 == RTL0_8019ID0 &&
     784           0 :             bus_space_read_1(dsc->sc_regt, dsc->sc_regh, NERTL_RTL0_8019ID1)
     785           0 :                 == RTL0_8019ID1) {
     786           0 :                 dsc->sc_mediachange = rtl80x9_mediachange;
     787           0 :                 dsc->sc_mediastatus = rtl80x9_mediastatus;
     788           0 :                 dsc->init_card = rtl80x9_init_card;
     789           0 :                 dsc->sc_media_init = rtl80x9_media_init;
     790           0 :         }
     791             : 
     792           0 :         if (nsc->sc_type == NE2000_TYPE_DL10019 ||
     793           0 :             nsc->sc_type == NE2000_TYPE_DL10022) {
     794           0 :                 dsc->sc_mediachange = dl10019_mediachange;
     795           0 :                 dsc->sc_mediastatus = dl10019_mediastatus;
     796           0 :                 dsc->init_card = dl10019_init_card;
     797           0 :                 dsc->stop_card = dl10019_stop_card;
     798           0 :                 dsc->sc_media_init = dl10019_media_init;
     799           0 :                 dsc->sc_media_fini = dl10019_media_fini;
     800           0 :         }
     801             : 
     802             :         /* set up the interrupt */
     803           0 :         psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, dp8390_intr,
     804           0 :             dsc, dsc->sc_dev.dv_xname);
     805           0 :         intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih);
     806           0 :         if (*intrstr)
     807           0 :                 printf(", %s", intrstr);
     808             : 
     809           0 :         if (ne2000_attach(nsc, enaddr))
     810             :                 goto fail_5;
     811             : 
     812             : #if notyet
     813             :         pcmcia_function_disable(pa->pf);
     814             : #endif
     815           0 :         return;
     816             : 
     817             : fail_5:
     818             :         /* Unmap ASIC I/O windows. */
     819           0 :         pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window);
     820             : 
     821             : fail_4:
     822             :         /* Unmap NIC I/O windows. */
     823           0 :         pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window);
     824             : 
     825             : fail_3:
     826           0 :         pcmcia_function_disable(pa->pf);
     827             : 
     828             : fail_2:
     829             :         /* Free our I/O space. */
     830           0 :         pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
     831             : 
     832             : fail_1:
     833           0 :         psc->sc_nic_io_window = -1;
     834           0 : }
     835             : 
     836             : int
     837           0 : ne_pcmcia_detach(dev, flags)
     838             :         struct device *dev;
     839             :         int flags;
     840             : {
     841           0 :         struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dev;
     842             :         int error;
     843             : 
     844           0 :         if (psc->sc_nic_io_window == -1)
     845             :                 /* Nothing to detach. */
     846           0 :                 return (0);
     847             : 
     848           0 :         error = ne2000_detach(&psc->sc_ne2000, flags);
     849           0 :         if (error != 0)
     850           0 :                 return (error);
     851             : 
     852             :         /* Unmap our i/o windows. */
     853           0 :         pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window);
     854           0 :         pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window);
     855             : 
     856             :         /* Free our i/o space. */
     857           0 :         pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
     858             : 
     859           0 :         return (0);
     860           0 : }
     861             : 
     862             : int
     863           0 : ne_pcmcia_activate(dev, act)
     864             :         struct device *dev;
     865             :         int act;
     866             : {
     867           0 :         struct ne_pcmcia_softc *sc = (struct ne_pcmcia_softc *)dev;
     868           0 :         struct dp8390_softc *esc = &sc->sc_ne2000.sc_dp8390;
     869           0 :         struct ifnet *ifp = &esc->sc_arpcom.ac_if;
     870             : 
     871           0 :         switch (act) {
     872             :         case DVACT_SUSPEND:
     873           0 :                 ifp->if_timer = 0;
     874           0 :                 if (ifp->if_flags & IFF_RUNNING) {
     875           0 :                         dp8390_stop(esc);
     876           0 :                         ifp->if_flags &= ~IFF_RUNNING;
     877           0 :                 }
     878           0 :                 if (sc->sc_ih != NULL)
     879           0 :                         pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
     880           0 :                 sc->sc_ih = NULL;
     881           0 :                 pcmcia_function_disable(sc->sc_pf);
     882           0 :                 break;
     883             :         case DVACT_RESUME:
     884           0 :                 pcmcia_function_enable(sc->sc_pf);
     885           0 :                 sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
     886           0 :                     dp8390_intr, sc, esc->sc_dev.dv_xname);
     887           0 :                 dp8390_enable(esc);
     888           0 :                 if (ifp->if_flags & IFF_UP)
     889           0 :                         dp8390_init(esc);
     890             :                 break;
     891             :         case DVACT_DEACTIVATE:
     892           0 :                 ifp->if_timer = 0;
     893           0 :                 if (ifp->if_flags & IFF_RUNNING) {
     894           0 :                         dp8390_stop(esc);
     895           0 :                         ifp->if_flags &= ~IFF_RUNNING;
     896           0 :                 }
     897           0 :                 if (sc->sc_ih != NULL)
     898           0 :                         pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
     899           0 :                 sc->sc_ih = NULL;
     900           0 :                 pcmcia_function_disable(sc->sc_pf);
     901           0 :                 break;
     902             :         }
     903           0 :         return (0);
     904             : }
     905             : 
     906             : #ifdef notyet
     907             : int
     908             : ne_pcmcia_enable(dsc)
     909             :         struct dp8390_softc *dsc;
     910             : {
     911             :         struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
     912             : 
     913             :         /* set up the interrupt */
     914             :         psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, dp8390_intr,
     915             :             dsc, dsc->sc_dev.dv_xname);
     916             :         if (psc->sc_ih == NULL) {
     917             :                 printf("%s: couldn't establish interrupt\n",
     918             :                     dsc->sc_dev.dv_xname);
     919             :                 return (1);
     920             :         }
     921             : 
     922             :         return (pcmcia_function_enable(psc->sc_pf));
     923             : }
     924             : 
     925             : void
     926             : ne_pcmcia_disable(dsc)
     927             :         struct dp8390_softc *dsc;
     928             : {
     929             :         struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
     930             : 
     931             :         pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
     932             :         pcmcia_function_disable(psc->sc_pf);
     933             : }
     934             : #endif
     935             : 
     936             : u_int8_t *
     937           0 : ne_pcmcia_get_enaddr(psc, maddr, myea)
     938             :         struct ne_pcmcia_softc *psc;
     939             :         int maddr;
     940             :         u_int8_t myea[ETHER_ADDR_LEN];
     941             : {
     942           0 :         struct ne2000_softc *nsc = &psc->sc_ne2000;
     943           0 :         struct dp8390_softc *dsc = &nsc->sc_dp8390;
     944           0 :         struct pcmcia_mem_handle pcmh;
     945           0 :         bus_size_t offset;
     946             :         u_int8_t *enaddr = NULL;
     947           0 :         int j, mwindow;
     948             : 
     949           0 :         if (maddr < 0)
     950           0 :                 return (NULL);
     951             : 
     952           0 :         if (pcmcia_mem_alloc(psc->sc_pf, ETHER_ADDR_LEN * 2, &pcmh)) {
     953           0 :                 printf("%s: can't alloc mem for enet addr\n",
     954           0 :                     dsc->sc_dev.dv_xname);
     955           0 :                 goto fail_1;
     956             :         }
     957           0 :         if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR, maddr,
     958             :             ETHER_ADDR_LEN * 2, &pcmh, &offset, &mwindow)) {
     959           0 :                 printf("%s: can't map mem for enet addr\n",
     960           0 :                     dsc->sc_dev.dv_xname);
     961           0 :                 goto fail_2;
     962             :         }
     963           0 :         for (j = 0; j < ETHER_ADDR_LEN; j++)
     964           0 :                 myea[j] = bus_space_read_1(pcmh.memt, pcmh.memh,
     965             :                     offset + (j * 2));
     966             :         enaddr = myea;
     967             : 
     968           0 :         pcmcia_mem_unmap(psc->sc_pf, mwindow);
     969             :  fail_2:
     970           0 :         pcmcia_mem_free(psc->sc_pf, &pcmh);
     971             :  fail_1:
     972           0 :         return (enaddr);
     973           0 : }
     974             : 
     975             : u_int8_t *
     976           0 : ne_pcmcia_dl10019_get_enaddr(psc, myea)
     977             :         struct ne_pcmcia_softc *psc;
     978             :         u_int8_t myea[ETHER_ADDR_LEN];
     979             : {
     980           0 :         struct ne2000_softc *nsc = &psc->sc_ne2000;
     981             :         u_int8_t sum;
     982             :         int j, type;
     983             : 
     984           0 :         for (j = 0, sum = 0; j < 8; j++) {
     985           0 :                 sum += bus_space_read_1(nsc->sc_asict, nsc->sc_asich,
     986             :                     0x04 + j);
     987             :         }
     988           0 :         if (sum != 0xff)
     989           0 :                 return (NULL);
     990             : 
     991           0 :         for (j = 0; j < ETHER_ADDR_LEN; j++) {
     992           0 :                 myea[j] = bus_space_read_1(nsc->sc_asict,
     993             :                     nsc->sc_asich, 0x04 + j);
     994             :         }
     995             : 
     996             :         /* XXX - magic values from Linux */
     997           0 :         type = bus_space_read_1(nsc->sc_asict, nsc->sc_asich, 0x0f);
     998           0 :         if (type == 0x91 || type == 0x99)
     999           0 :                 nsc->sc_type = NE2000_TYPE_DL10022;
    1000             :         else
    1001           0 :                 nsc->sc_type = NE2000_TYPE_DL10019;
    1002             : 
    1003           0 :         return (myea);
    1004           0 : }
    1005             : 
    1006             : int
    1007           0 : ne_pcmcia_ax88190_set_iobase(psc)
    1008             :         struct ne_pcmcia_softc *psc;
    1009             : {
    1010           0 :         struct ne2000_softc *nsc = &psc->sc_ne2000;
    1011           0 :         struct dp8390_softc *dsc = &nsc->sc_dp8390;
    1012           0 :         struct pcmcia_mem_handle pcmh;
    1013           0 :         bus_size_t offset;
    1014           0 :         int rv = 1, mwindow;
    1015             : 
    1016           0 :         if (pcmcia_mem_alloc(psc->sc_pf, AX88190_LAN_IOSIZE, &pcmh)) {
    1017           0 :                 printf("%s: can't alloc mem for LAN iobase\n",
    1018           0 :                     dsc->sc_dev.dv_xname);
    1019           0 :                 goto fail_1;
    1020             :         }
    1021           0 :         if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR,
    1022             :             AX88190_LAN_IOBASE, AX88190_LAN_IOSIZE, &pcmh, &offset,
    1023             :             &mwindow)) {
    1024           0 :                 printf("%s: can't map mem for LAN iobase\n",
    1025           0 :                     dsc->sc_dev.dv_xname);
    1026           0 :                 goto fail_2;
    1027             :         }
    1028             : 
    1029             : #ifdef NE_DEBUG
    1030             :         printf(": LAN iobase 0x%x (0x%x) ->",
    1031             :             bus_space_read_1(pcmh.memt, pcmh.memh, offset + 0) |
    1032             :             bus_space_read_1(pcmh.memt, pcmh.memh, offset + 2) << 8,
    1033             :             (u_int)psc->sc_pcioh.addr);
    1034             : #endif
    1035           0 :         bus_space_write_1(pcmh.memt, pcmh.memh, offset,
    1036             :             psc->sc_pcioh.addr & 0xff);
    1037           0 :         bus_space_write_1(pcmh.memt, pcmh.memh, offset + 2,
    1038             :             psc->sc_pcioh.addr >> 8);
    1039             : #ifdef NE_DEBUG
    1040             :         printf(" 0x%x", bus_space_read_1(pcmh.memt, pcmh.memh, offset + 0) |
    1041             :             bus_space_read_1(pcmh.memt, pcmh.memh, offset + 2) << 8);
    1042             : #endif
    1043             :         rv = 0;
    1044             : 
    1045           0 :         pcmcia_mem_unmap(psc->sc_pf, mwindow);
    1046             :  fail_2:
    1047           0 :         pcmcia_mem_free(psc->sc_pf, &pcmh);
    1048             :  fail_1:
    1049           0 :         return (rv);
    1050           0 : }

Generated by: LCOV version 1.13