[BACK]Return to if_ne_pcmcia.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pcmcia

Annotation of src/sys/dev/pcmcia/if_ne_pcmcia.c, Revision 1.128

1.128   ! mycroft     1: /*     $NetBSD: if_ne_pcmcia.c,v 1.127 2004/08/09 00:00:36 mycroft Exp $       */
1.2       thorpej     2:
                      3: /*
                      4:  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following 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:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *     This product includes software developed by Marc Horowitz.
                     17:  * 4. The name of the author may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     30:  */
1.83      lukem      31:
                     32: #include <sys/cdefs.h>
1.128   ! mycroft    33: __KERNEL_RCSID(0, "$NetBSD: if_ne_pcmcia.c,v 1.127 2004/08/09 00:00:36 mycroft Exp $");
1.2       thorpej    34:
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/select.h>
                     38: #include <sys/device.h>
                     39: #include <sys/socket.h>
                     40:
                     41: #include <net/if_types.h>
                     42: #include <net/if.h>
1.5       thorpej    43: #include <net/if_media.h>
1.2       thorpej    44: #include <net/if_ether.h>
                     45:
                     46: #include <machine/bus.h>
                     47: #include <machine/intr.h>
                     48:
                     49: #include <dev/pcmcia/pcmciareg.h>
                     50: #include <dev/pcmcia/pcmciavar.h>
1.15      christos   51: #include <dev/pcmcia/pcmciadevs.h>
1.2       thorpej    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:
1.22      thorpej    59: #include <dev/ic/rtl80x9reg.h>
                     60: #include <dev/ic/rtl80x9var.h>
                     61:
1.75      thorpej    62: #include <dev/ic/dl10019var.h>
                     63:
1.80      enami      64: #include <dev/ic/ax88190reg.h>
                     65: #include <dev/ic/ax88190var.h>
                     66:
1.25      thorpej    67: int    ne_pcmcia_match __P((struct device *, struct cfdata *, void *));
                     68: void   ne_pcmcia_attach __P((struct device *, struct device *, void *));
                     69: int    ne_pcmcia_detach __P((struct device *, int));
1.2       thorpej    70:
                     71: int    ne_pcmcia_enable __P((struct dp8390_softc *));
                     72: void   ne_pcmcia_disable __P((struct dp8390_softc *));
                     73:
                     74: struct ne_pcmcia_softc {
                     75:        struct ne2000_softc sc_ne2000;          /* real "ne2000" softc */
                     76:
                     77:        /* PCMCIA-specific goo */
                     78:        struct pcmcia_io_handle sc_pcioh;       /* PCMCIA i/o information */
1.127     mycroft    79:        struct pcmcia_io_handle sc_pcioh2;      /* PCMCIA i/o information */
1.126     mycroft    80:        int sc_io_window;                       /* i/o window */
1.127     mycroft    81:        int sc_io_window2;                      /* i/o window */
1.2       thorpej    82:        struct pcmcia_function *sc_pf;          /* our PCMCIA function */
                     83:        void *sc_ih;                            /* interrupt handle */
                     84: };
                     85:
1.53      enami      86: u_int8_t *
                     87:        ne_pcmcia_get_enaddr __P((struct ne_pcmcia_softc *, int,
                     88:            u_int8_t [ETHER_ADDR_LEN]));
                     89: u_int8_t *
                     90:        ne_pcmcia_dl10019_get_enaddr __P((struct ne_pcmcia_softc *,
                     91:            u_int8_t [ETHER_ADDR_LEN]));
1.55      enami      92: int    ne_pcmcia_ax88190_set_iobase __P((struct ne_pcmcia_softc *));
1.52      itojun     93:
1.98      thorpej    94: CFATTACH_DECL(ne_pcmcia, sizeof(struct ne_pcmcia_softc),
1.99      thorpej    95:     ne_pcmcia_match, ne_pcmcia_attach, ne_pcmcia_detach, dp8390_activate);
1.2       thorpej    96:
1.67      jdolecek   97: static const struct ne2000dev {
1.4       enami      98:     int32_t manufacturer;
                     99:     int32_t product;
1.15      christos  100:     char *cis_info[4];
1.2       thorpej   101:     int function;
                    102:     int enet_maddr;
                    103:     unsigned char enet_vendor[3];
1.39      enami     104:     int flags;
                    105: #define        NE2000DVF_DL10019       0x0001          /* chip is D-Link DL10019 */
1.55      enami     106: #define        NE2000DVF_AX88190       0x0002          /* chip is ASIX AX88190 */
1.2       thorpej   107: } ne2000devs[] = {
1.117     mycroft   108:     { PCMCIA_VENDOR_EDIMAX, PCMCIA_PRODUCT_EDIMAX_EP4000A,
1.123     mycroft   109:       PCMCIA_CIS_INVALID,
1.85      aymeric   110:       0, -1, { 0x00, 0xa0, 0x0c } },
                    111:
1.117     mycroft   112:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.69      aymeric   113:       PCMCIA_CIS_SYNERGY21_S21810,
1.70      aymeric   114:       0, -1, { 0x00, 0x48, 0x54 } },
1.69      aymeric   115:
1.117     mycroft   116:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.37      is        117:       PCMCIA_CIS_AMBICOM_AMB8002T,
                    118:       0, -1, { 0x00, 0x10, 0x7a } },
                    119:
1.117     mycroft   120:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.119     mycroft   121:       PCMCIA_CIS_AMBICOM_AMB8110,
                    122:       0, -1, { 0x00, 0x10, 0x7a }, NE2000DVF_AX88190 },
                    123:
                    124:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.15      christos  125:       PCMCIA_CIS_PREMAX_PE200,
                    126:       0, 0x07f0, { 0x00, 0x20, 0xe0 } },
                    127:
1.117     mycroft   128:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.118     mycroft   129:       PCMCIA_CIS_PREMAX_PE200,
                    130:       0, -1, { 0x00, 0x20, 0xe0 } },
                    131:
                    132:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.19      veego     133:       PCMCIA_CIS_PLANET_SMARTCOM2000,
                    134:       0, 0xff0, { 0x00, 0x00, 0xe8 } },
                    135:
1.117     mycroft   136:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.19      veego     137:       PCMCIA_CIS_DLINK_DE660,
1.79      christos  138:       0, -1, { 0x00, 0x80, 0xc8 } },
                    139:
1.117     mycroft   140:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.79      christos  141:       PCMCIA_CIS_DLINK_DE660PLUS,
1.19      veego     142:       0, -1, { 0x00, 0x80, 0xc8 } },
1.59      tron      143:
1.117     mycroft   144:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.59      tron      145:       PCMCIA_CIS_RPTI_EP400,
1.113     is        146:       0, 0x110, { 0x00, 0x40, 0x95 } },
1.19      veego     147:
1.117     mycroft   148:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.19      veego     149:       PCMCIA_CIS_RPTI_EP401,
                    150:       0, -1, { 0x00, 0x40, 0x95 } },
                    151:
1.117     mycroft   152:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.19      veego     153:       PCMCIA_CIS_ACCTON_EN2212,
                    154:       0, 0x0ff0, { 0x00, 0x00, 0xe8 } },
1.117     mycroft   155:
                    156:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.96      bouyer    157:       PCMCIA_CIS_ACCTON_EN2216,
                    158:       0, -1, { 0x00, 0x00, 0xe8 } },
1.29      thorpej   159:
1.117     mycroft   160:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.29      thorpej   161:       PCMCIA_CIS_SVEC_COMBOCARD,
                    162:       0, -1, { 0x00, 0xe0, 0x98 } },
1.34      augustss  163:
1.117     mycroft   164:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.31      marc      165:       PCMCIA_CIS_SVEC_LANCARD,
                    166:       0, 0x7f0, { 0x00, 0xc0, 0x6c } },
1.19      veego     167:
1.117     mycroft   168:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_EPSON_EEN10B,
1.45      danw      169:       PCMCIA_CIS_EPSON_EEN10B,
                    170:       0, 0xff0, { 0x00, 0x00, 0x48 } },
1.77      christos  171:
1.117     mycroft   172:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.108     uwe       173:       PCMCIA_CIS_TAMARACK_ETHERNET,
                    174:       0, -1, { 0x00, 0x00, 0x00 } },
                    175:
1.117     mycroft   176:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.77      christos  177:       PCMCIA_CIS_CNET_NE2000,
                    178:       0, -1, { 0x00, 0x80, 0xad } },
1.81      christos  179:
1.119     mycroft   180:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
                    181:       PCMCIA_CIS_GENIUS_ME3000II,
                    182:       0, -1, { 0x00, 0x40, 0x95 } },
                    183:
                    184:
1.19      veego     185:     /*
                    186:      * You have to add new entries which contains
                    187:      * PCMCIA_VENDOR_INVALID and/or PCMCIA_PRODUCT_INVALID
                    188:      * in front of this comment.
                    189:      *
                    190:      * There are cards which use a generic vendor and product id but needs
                    191:      * a different handling depending on the cis_info, so ne2000_match
                    192:      * needs a table where the exceptions comes first and then the normal
                    193:      * product and vendor entries.
                    194:      */
                    195:
1.117     mycroft   196:     { PCMCIA_VENDOR_IBM, PCMCIA_PRODUCT_IBM_INFOMOVER,
1.123     mycroft   197:       PCMCIA_CIS_INVALID,
1.117     mycroft   198:       0, 0x0ff0, { 0xff, 0xff, 0xff } },
1.15      christos  199:
1.117     mycroft   200:     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ECARD_1,
1.123     mycroft   201:       PCMCIA_CIS_INVALID,
1.24      itohy     202:       0, -1, { 0x00, 0x80, 0xc8 } },
                    203:
1.117     mycroft   204:     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
1.123     mycroft   205:       PCMCIA_CIS_INVALID,
                    206:       0, -1, { 0xff, 0xff, 0xff }, NE2000DVF_DL10019 },
1.46      mycroft   207:
1.117     mycroft   208:     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
1.123     mycroft   209:       PCMCIA_CIS_INVALID,
                    210:       0, -1, { 0xff, 0xff, 0xff }, NE2000DVF_AX88190 },
1.56      enami     211:
1.123     mycroft   212:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.86      is        213:       PCMCIA_CIS_LANTECH_FASTNETTX,
                    214:       0, -1, { 0x00, 0x04, 0x1c }, NE2000DVF_AX88190 },
                    215:
1.117     mycroft   216:     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_ETHERFAST,
1.123     mycroft   217:       PCMCIA_CIS_INVALID,
1.117     mycroft   218:       0, -1, { 0xff, 0xff, 0xff }, NE2000DVF_DL10019 },
1.46      mycroft   219:
1.117     mycroft   220:     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA410TXC,
1.123     mycroft   221:       PCMCIA_CIS_INVALID,
                    222:       0, -1, { 0xff, 0xff, 0xff }, NE2000DVF_DL10019 },
                    223:
                    224:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.110     cube      225:       PCMCIA_CIS_DLINK_DFE670TXD,
1.117     mycroft   226:       0, -1, { 0xff, 0xff, 0xff }, NE2000DVF_DL10019 },
1.110     cube      227:
1.123     mycroft   228:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.65      msaitoh   229:       PCMCIA_CIS_MELCO_LPC2_TX,
                    230:       0, -1, { 0x00, 0x40, 0x26 }, NE2000DVF_DL10019 },
                    231:
1.117     mycroft   232:     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_COMBO_ECARD,
1.123     mycroft   233:       PCMCIA_CIS_INVALID,
1.2       thorpej   234:       0, -1, { 0x00, 0x80, 0xc8 } },
1.17      thorpej   235:
1.117     mycroft   236:     { PCMCIA_VENDOR_LINKSYS, PCMCIA_PRODUCT_LINKSYS_TRUST_COMBO_ECARD,
1.123     mycroft   237:       PCMCIA_CIS_INVALID,
1.17      thorpej   238:       0, 0x0120, { 0x20, 0x04, 0x49 } },
1.20      jtk       239:
                    240:     /* Although the comments above say to put VENDOR/PRODUCT INVALID IDs
                    241:        above this list, we need to keep this one below the ECARD_1, or else
                    242:        both will match the same more-generic entry rather than the more
                    243:        specific one above with proper vendor and product IDs. */
1.117     mycroft   244:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.20      jtk       245:       PCMCIA_CIS_LINKSYS_ECARD_2,
                    246:       0, -1, { 0x00, 0x80, 0xc8 } },
1.24      itohy     247:
                    248:     /*
                    249:      * D-Link DE-650 has many minor versions:
                    250:      *
                    251:      *   CIS information          Manufacturer Product  Note
                    252:      * 1 "D-Link, DE-650"             INVALID  INVALID  white card
                    253:      * 2 "D-Link, DE-650, Ver 01.00"  INVALID  INVALID  became bare metal
                    254:      * 3 "D-Link, DE-650, Ver 01.00"   0x149    0x265   minor change in look
                    255:      * 4 "D-Link, DE-650, Ver 01.00"   0x149    0x265   collision LED added
                    256:      *
                    257:      * While the 1st and the 2nd types should use the "D-Link DE-650" entry,
                    258:      * the 3rd and the 4th types should use the "Linksys EtherCard" entry.
                    259:      * Therefore, this enty must be below the LINKSYS_ECARD_1.  --itohy
                    260:      */
1.117     mycroft   261:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.24      itohy     262:       PCMCIA_CIS_DLINK_DE650,
                    263:       0, 0x0040, { 0x00, 0x80, 0xc8 } },
1.15      christos  264:
1.44      enami     265:     /*
                    266:      * IO-DATA PCLA/TE and later version of PCLA/T has valid
                    267:      * vendor/product ID and it is possible to read MAC address
                    268:      * using standard I/O ports.  It also read from CIS offset 0x01c0.
                    269:      * On the other hand, earlier version of PCLA/T doesn't have valid
                    270:      * vendor/product ID and MAC address must be read from CIS offset
                    271:      * 0x0ff0 (i.e., usual ne2000 way to read it doesn't work).
                    272:      * And CIS information of earlier and later version of PCLA/T are
                    273:      * same except fourth element.  So, for now, we place the entry for
                    274:      * PCLA/TE (and later version of PCLA/T) followed by entry
                    275:      * for the earlier version of PCLA/T (or, modify to match all CIS
                    276:      * information and have three or more individual entries).
                    277:      */
1.117     mycroft   278:     { PCMCIA_VENDOR_IODATA, PCMCIA_PRODUCT_IODATA_PCLATE,
1.123     mycroft   279:       PCMCIA_CIS_INVALID,
1.124     mycroft   280:       0, -1, { 0xff, 0xff, 0xff } },
1.44      enami     281:
                    282:     /*
                    283:      * This entry should be placed after above PCLA-TE entry.
                    284:      * See above comments for detail.
                    285:      */
1.117     mycroft   286:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.15      christos  287:       PCMCIA_CIS_IODATA_PCLAT,
1.44      enami     288:       0, 0x0ff0, { 0x00, 0xa0, 0xb0 } },
1.15      christos  289:
1.117     mycroft   290:     { PCMCIA_VENDOR_DAYNA, PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_1,
1.123     mycroft   291:       PCMCIA_CIS_INVALID,
1.15      christos  292:       0, 0x0110, { 0x00, 0x80, 0x19 } },
1.18      dbj       293:
1.117     mycroft   294:     { PCMCIA_VENDOR_DAYNA, PCMCIA_PRODUCT_DAYNA_COMMUNICARD_E_2,
1.123     mycroft   295:       PCMCIA_CIS_INVALID,
1.18      dbj       296:       0, -1, { 0x00, 0x80, 0x19 } },
1.28      thorpej   297:
1.123     mycroft   298:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.38      enami     299:       PCMCIA_CIS_COREGA_ETHER_PCC_T,
1.82      mjl       300:       0, -1, { 0x00, 0x00, 0xf4 } },
                    301:
1.123     mycroft   302:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.82      mjl       303:       PCMCIA_CIS_COREGA_ETHER_PCC_TD,
1.107     hamajima  304:       0, -1, { 0x00, 0x00, 0xf4 } },
                    305:
1.123     mycroft   306:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.107     hamajima  307:       PCMCIA_CIS_COREGA_ETHER_PCC_TL,
1.38      enami     308:       0, -1, { 0x00, 0x00, 0xf4 } },
                    309:
1.123     mycroft   310:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.38      enami     311:       PCMCIA_CIS_COREGA_ETHER_II_PCC_T,
1.91      itojun    312:       0, -1, { 0x00, 0x00, 0xf4 } },
                    313:
1.123     mycroft   314:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.91      itojun    315:       PCMCIA_CIS_COREGA_ETHER_II_PCC_TD,
1.28      thorpej   316:       0, -1, { 0x00, 0x00, 0xf4 } },
1.42      jun       317:
1.123     mycroft   318:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.42      jun       319:       PCMCIA_CIS_COREGA_FAST_ETHER_PCC_TX,
                    320:       0, -1, { 0x00, 0x00, 0xf4 }, NE2000DVF_DL10019 },
1.73      ichiro    321:
1.123     mycroft   322:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.73      ichiro    323:       PCMCIA_CIS_COREGA_FETHER_PCC_TXF,
                    324:       0, -1, { 0x00, 0x90, 0x99 }, NE2000DVF_DL10019 },
1.71      ichiro    325:
1.123     mycroft   326:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.71      ichiro    327:       PCMCIA_CIS_COREGA_FETHER_PCC_TXD,
                    328:       0, -1, { 0x00, 0x90, 0x99 } },
1.40      jun       329:
1.123     mycroft   330:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.114     itohy     331:       PCMCIA_CIS_COREGA_FETHER_II_PCC_TXD,
1.123     mycroft   332:       0, -1, { 0x00, 0x90, 0x99 }, NE2000DVF_AX88190 },
1.114     itohy     333:
1.117     mycroft   334:     { PCMCIA_VENDOR_COMPEX, PCMCIA_PRODUCT_COMPEX_LINKPORT_ENET_B,
1.123     mycroft   335:       PCMCIA_CIS_INVALID,
                    336:       0, 0x01c0, { 0xff, 0xff, 0xff } },
1.35      christos  337:
1.117     mycroft   338:     { PCMCIA_VENDOR_SMC, PCMCIA_PRODUCT_SMC_EZCARD,
1.123     mycroft   339:       PCMCIA_CIS_INVALID,
1.35      christos  340:       0, 0x01c0, { 0x00, 0xe0, 0x29 } },
1.100     kanaoka   341:
1.123     mycroft   342:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.100     kanaoka   343:       PCMCIA_CIS_SMC_8041,
                    344:       0, -1, { 0x00, 0x04, 0xe2 } },
1.43      jun       345:
1.117     mycroft   346:     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_EA_ETHER,
1.123     mycroft   347:       PCMCIA_CIS_INVALID,
1.72      jhawk     348:       0, -1, { 0x00, 0xc0, 0x1b } },
                    349:
1.117     mycroft   350:     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETHER_CF,
1.123     mycroft   351:       PCMCIA_CIS_INVALID,
1.66      toddpw    352:       0, -1, { 0x00, 0xc0, 0x1b } },
1.102     martin    353:
1.117     mycroft   354:     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETH_10_100_CF,
1.123     mycroft   355:       PCMCIA_CIS_INVALID,
1.102     martin    356:       0, -1, { 0x00, 0xe0, 0x98 }, NE2000DVF_DL10019 },
1.66      toddpw    357:
1.117     mycroft   358:     { PCMCIA_VENDOR_SOCKET, PCMCIA_PRODUCT_SOCKET_LP_ETHER,
1.123     mycroft   359:       PCMCIA_CIS_INVALID,
1.63      shin      360:       0, -1, { 0x00, 0xc0, 0x1b } },
1.28      thorpej   361:
1.117     mycroft   362:     { PCMCIA_VENDOR_KINGSTON, PCMCIA_PRODUCT_KINGSTON_KNE2,
1.123     mycroft   363:       PCMCIA_CIS_INVALID,
1.76      toddpw    364:       0, -1, { 0x00, 0xc0, 0xf0 } },
                    365:
1.117     mycroft   366:     { PCMCIA_VENDOR_XIRCOM, PCMCIA_PRODUCT_XIRCOM_CFE_10,
1.123     mycroft   367:       PCMCIA_CIS_INVALID,
1.54      enami     368:       0, -1, { 0x00, 0x10, 0xa4 } },
                    369:
1.117     mycroft   370:     { PCMCIA_VENDOR_MELCO, PCMCIA_PRODUCT_MELCO_LPC3_TX,
1.123     mycroft   371:       PCMCIA_CIS_INVALID,
1.117     mycroft   372:       0, -1, { 0xff, 0xff, 0xff }, NE2000DVF_AX88190 },
1.116     mycroft   373:
1.123     mycroft   374:     { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC_CF_CLT,
                    375:       PCMCIA_CIS_INVALID,
1.89      uch       376:       0, -1, { 0x00, 0x07, 0x40 } },
1.58      uch       377:
1.123     mycroft   378:     { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC3_CLT,
                    379:       PCMCIA_CIS_INVALID,
1.121     enami     380:       0, -1, { 0x00, 0x07, 0x40 } },
                    381:
1.117     mycroft   382:     { PCMCIA_VENDOR_BUFFALO, PCMCIA_PRODUCT_BUFFALO_LPC4_CLX,
1.123     mycroft   383:       PCMCIA_CIS_INVALID,
                    384:       0, -1, { 0x00, 0x40, 0xfa }, NE2000DVF_AX88190 },
1.104     christos  385:
1.117     mycroft   386:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.58      uch       387:       PCMCIA_CIS_BILLIONTON_LNT10TN,
1.101     christos  388:       0, -1, { 0x00, 0x00, 0x00 } },
                    389:
1.117     mycroft   390:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.101     christos  391:       PCMCIA_CIS_BILLIONTON_CFLT10N,
1.58      uch       392:       0, -1, { 0x00, 0x00, 0x00 } },
1.60      scw       393:
1.117     mycroft   394:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.60      scw       395:       PCMCIA_CIS_NDC_ND5100_E,
                    396:       0, -1, { 0x00, 0x80, 0xc6 } },
1.65      msaitoh   397:
1.117     mycroft   398:     { PCMCIA_VENDOR_TELECOMDEVICE, PCMCIA_PRODUCT_TELECOMDEVICE_TCD_HPC100,
1.123     mycroft   399:       PCMCIA_CIS_INVALID,
1.65      msaitoh   400:       0, -1, { 0x00, 0x40, 0x26 }, NE2000DVF_AX88190 },
                    401:
1.117     mycroft   402:     { PCMCIA_VENDOR_MACNICA, PCMCIA_PRODUCT_MACNICA_ME1_JEIDA,
1.123     mycroft   403:       PCMCIA_CIS_INVALID,
1.65      msaitoh   404:       0, 0x00b8, { 0x08, 0x00, 0x42 } },
1.90      chris     405:
1.117     mycroft   406:     { PCMCIA_VENDOR_NETGEAR, PCMCIA_PRODUCT_NETGEAR_FA411,
1.123     mycroft   407:       PCMCIA_CIS_INVALID,
1.90      chris     408:       0, -1, { 0x00, 0x40, 0xf4 } },
1.94      christos  409:
1.123     mycroft   410:     { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
1.94      christos  411:       PCMCIA_CIS_DYNALINK_L10C,
                    412:       0, -1, { 0x00, 0x00, 0x00 } },
1.55      enami     413:
1.123     mycroft   414:     { PCMCIA_VENDOR_ALLIEDTELESIS, PCMCIA_PRODUCT_ALLIEDTELESIS_LA_PCM,
                    415:       PCMCIA_CIS_INVALID,
                    416:       0, 0x0ff0, { 0x00, 0x00, 0xf4 } },
                    417:
                    418:     { PCMCIA_VENDOR_NEXTCOM, PCMCIA_PRODUCT_NEXTCOM_NEXTHAWK,
                    419:       PCMCIA_CIS_INVALID,
                    420:       0, -1, { 0x00, 0x40, 0xb4 } },
                    421:
1.2       thorpej   422: #if 0
                    423:     /* the rest of these are stolen from the linux pcnet pcmcia device
                    424:        driver.  Since I don't know the manfid or cis info strings for
                    425:        any of them, they're not compiled in until I do. */
                    426:     { "APEX MultiCard",
                    427:       0x0000, 0x0000, NULL, NULL, 0,
                    428:       0x03f4, { 0x00, 0x20, 0xe5 } },
                    429:     { "ASANTE FriendlyNet",
                    430:       0x0000, 0x0000, NULL, NULL, 0,
                    431:       0x4910, { 0x00, 0x00, 0x94 } },
                    432:     { "Danpex EN-6200P2",
                    433:       0x0000, 0x0000, NULL, NULL, 0,
                    434:       0x0110, { 0x00, 0x40, 0xc7 } },
                    435:     { "DataTrek NetCard",
                    436:       0x0000, 0x0000, NULL, NULL, 0,
                    437:       0x0ff0, { 0x00, 0x20, 0xe8 } },
                    438:     { "EP-210 Ethernet",
                    439:       0x0000, 0x0000, NULL, NULL, 0,
                    440:       0x0110, { 0x00, 0x40, 0x33 } },
                    441:     { "ELECOM Laneed LD-CDWA",
                    442:       0x0000, 0x0000, NULL, NULL, 0,
                    443:       0x00b8, { 0x08, 0x00, 0x42 } },
                    444:     { "Grey Cell GCS2220",
                    445:       0x0000, 0x0000, NULL, NULL, 0,
                    446:       0x0000, { 0x00, 0x47, 0x43 } },
                    447:     { "Hypertec Ethernet",
                    448:       0x0000, 0x0000, NULL, NULL, 0,
                    449:       0x01c0, { 0x00, 0x40, 0x4c } },
                    450:     { "IBM CCAE",
                    451:       0x0000, 0x0000, NULL, NULL, 0,
                    452:       0x0ff0, { 0x08, 0x00, 0x5a } },
                    453:     { "IBM CCAE",
                    454:       0x0000, 0x0000, NULL, NULL, 0,
                    455:       0x0ff0, { 0x00, 0x04, 0xac } },
                    456:     { "IBM CCAE",
                    457:       0x0000, 0x0000, NULL, NULL, 0,
                    458:       0x0ff0, { 0x00, 0x06, 0x29 } },
                    459:     { "IBM FME",
                    460:       0x0000, 0x0000, NULL, NULL, 0,
                    461:       0x0374, { 0x00, 0x04, 0xac } },
                    462:     { "IBM FME",
                    463:       0x0000, 0x0000, NULL, NULL, 0,
                    464:       0x0374, { 0x08, 0x00, 0x5a } },
                    465:     { "Katron PE-520",
                    466:       0x0000, 0x0000, NULL, NULL, 0,
                    467:       0x0110, { 0x00, 0x40, 0xf6 } },
                    468:     { "Kingston KNE-PCM/x",
                    469:       0x0000, 0x0000, NULL, NULL, 0,
                    470:       0x0ff0, { 0x00, 0xc0, 0xf0 } },
                    471:     { "Kingston KNE-PCM/x",
                    472:       0x0000, 0x0000, NULL, NULL, 0,
                    473:       0x0ff0, { 0xe2, 0x0c, 0x0f } },
                    474:     { "Longshine LCS-8534",
                    475:       0x0000, 0x0000, NULL, NULL, 0,
                    476:       0x0000, { 0x08, 0x00, 0x00 } },
                    477:     { "Maxtech PCN2000",
                    478:       0x0000, 0x0000, NULL, NULL, 0,
                    479:       0x5000, { 0x00, 0x00, 0xe8 } },
                    480:     { "NDC Instant-Link",
                    481:       0x0000, 0x0000, NULL, NULL, 0,
                    482:       0x003a, { 0x00, 0x80, 0xc6 } },
                    483:     { "NE2000 Compatible",
                    484:       0x0000, 0x0000, NULL, NULL, 0,
                    485:       0x0ff0, { 0x00, 0xa0, 0x0c } },
                    486:     { "Network General Sniffer",
                    487:       0x0000, 0x0000, NULL, NULL, 0,
                    488:       0x0ff0, { 0x00, 0x00, 0x65 } },
                    489:     { "Panasonic VEL211",
                    490:       0x0000, 0x0000, NULL, NULL, 0,
                    491:       0x0ff0, { 0x00, 0x80, 0x45 } },
                    492:     { "SCM Ethernet",
                    493:       0x0000, 0x0000, NULL, NULL, 0,
                    494:       0x0ff0, { 0x00, 0x20, 0xcb } },
                    495:     { "Volktek NPL-402CT",
                    496:       0x0000, 0x0000, NULL, NULL, 0,
                    497:       0x0060, { 0x00, 0x40, 0x05 } },
                    498: #endif
                    499: };
                    500:
                    501: #define        NE2000_NDEVS    (sizeof(ne2000devs) / sizeof(ne2000devs[0]))
                    502:
                    503: #define ne2000_match(card, fct, n) \
1.15      christos  504: ((((((card)->manufacturer != PCMCIA_VENDOR_INVALID) && \
1.4       enami     505:     ((card)->manufacturer == ne2000devs[(n)].manufacturer) && \
                    506:     ((card)->product != PCMCIA_PRODUCT_INVALID) && \
1.2       thorpej   507:     ((card)->product == ne2000devs[(n)].product)) || \
1.15      christos  508:    ((ne2000devs[(n)].cis_info[0]) && (ne2000devs[(n)].cis_info[1]) && \
                    509:     (strcmp((card)->cis1_info[0], ne2000devs[(n)].cis_info[0]) == 0) && \
                    510:     (strcmp((card)->cis1_info[1], ne2000devs[(n)].cis_info[1]) == 0))) && \
1.3       enami     511:   ((fct) == ne2000devs[(n)].function))? \
1.2       thorpej   512:  &ne2000devs[(n)]:NULL)
                    513:
                    514: int
                    515: ne_pcmcia_match(parent, match, aux)
                    516:        struct device *parent;
1.7       drochner  517:        struct cfdata *match;
1.2       thorpej   518:        void *aux;
                    519: {
                    520:        struct pcmcia_attach_args *pa = aux;
                    521:        int i;
                    522:
                    523:        for (i = 0; i < NE2000_NDEVS; i++) {
                    524:                if (ne2000_match(pa->card, pa->pf->number, i))
                    525:                        return (1);
                    526:        }
                    527:
                    528:        return (0);
                    529: }
                    530:
                    531: void
                    532: ne_pcmcia_attach(parent, self, aux)
                    533:        struct device *parent, *self;
                    534:        void *aux;
                    535: {
                    536:        struct ne_pcmcia_softc *psc = (void *) self;
                    537:        struct ne2000_softc *nsc = &psc->sc_ne2000;
                    538:        struct dp8390_softc *dsc = &nsc->sc_dp8390;
                    539:        struct pcmcia_attach_args *pa = aux;
                    540:        struct pcmcia_config_entry *cfe;
1.106     mycroft   541:        const struct ne2000dev *ne_dev;
1.53      enami     542:        int i;
1.55      enami     543:        u_int8_t myea[6], *enaddr;
1.22      thorpej   544:        const char *typestr = "";
                    545:
1.125     mycroft   546:        aprint_normal("\n");
1.2       thorpej   547:        psc->sc_pf = pa->pf;
                    548:
1.92      lukem     549:        SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) {
1.127     mycroft   550:                if (cfe->num_iospace < 1)
1.57      enami     551:                        continue;
1.2       thorpej   552:
1.127     mycroft   553:                if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
                    554:                    cfe->iospace[0].length, cfe->iospace[0].length,
                    555:                    &psc->sc_pcioh)) {
1.57      enami     556: #ifdef DIAGNOSTIC
1.127     mycroft   557:                        aprint_error("%s: can't allocate i/o space %lx (ignored\n)",
                    558:                            self->dv_xname, cfe->iospace[0].start);
1.57      enami     559: #endif
                    560:                        continue;
1.2       thorpej   561:                }
1.57      enami     562:
1.127     mycroft   563:                /*
                    564:                 * Try to make the second chunk contiguous with the
                    565:                 * first.
                    566:                 */
                    567:                if (cfe->num_iospace >= 2 &&
                    568:                    pcmcia_io_alloc(pa->pf,
                    569:                    cfe->iospace[0].start + cfe->iospace[0].length,
                    570:                    cfe->iospace[1].length, cfe->iospace[1].length,
                    571:                    &psc->sc_pcioh2)) {
1.57      enami     572: #ifdef DIAGNOSTIC
1.125     mycroft   573:                        aprint_error("%s: can't allocate i/o space %lx (ignored\n)",
1.127     mycroft   574:                            self->dv_xname,
                    575:                            cfe->iospace[0].start + cfe->iospace[0].length);
1.57      enami     576: #endif
1.127     mycroft   577:                        pcmcia_io_free(pa->pf, &psc->sc_pcioh2);
1.57      enami     578:                        continue;
1.2       thorpej   579:                }
1.57      enami     580:
                    581:                /* Ok, found. */
                    582:                break;
1.2       thorpej   583:        }
1.128   ! mycroft   584:        if (!cfe) {
1.125     mycroft   585:                aprint_error("%s: no suitable config entry\n", self->dv_xname);
1.53      enami     586:                goto fail_1;
1.2       thorpej   587:        }
                    588:
                    589:        dsc->sc_regt = psc->sc_pcioh.iot;
                    590:        dsc->sc_regh = psc->sc_pcioh.ioh;
                    591:
1.127     mycroft   592:        if (cfe->num_iospace == 1) {
                    593:                nsc->sc_asict = psc->sc_pcioh.iot;
                    594:                if (bus_space_subregion(dsc->sc_regt, dsc->sc_regh,
                    595:                    NE2000_ASIC_OFFSET, NE2000_ASIC_NPORTS,
                    596:                    &nsc->sc_asich)) {
                    597:                        aprint_error("%s: can't get subregion for asic\n",
                    598:                            self->dv_xname);
1.128   ! mycroft   599:                        goto fail_2;
1.127     mycroft   600:                }
                    601:        } else {
                    602:                nsc->sc_asict = psc->sc_pcioh2.iot;
                    603:                nsc->sc_asich = psc->sc_pcioh2.ioh;
1.2       thorpej   604:        }
                    605:
1.128   ! mycroft   606:        /* Enable the card. */
        !           607:        pcmcia_function_init(pa->pf, cfe);
1.2       thorpej   608:
1.127     mycroft   609:        if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, &psc->sc_pcioh,
1.126     mycroft   610:            &psc->sc_io_window)) {
1.125     mycroft   611:                aprint_error("%s: can't map NIC i/o space\n", self->dv_xname);
1.128   ! mycroft   612:                goto fail_2;
1.2       thorpej   613:        }
                    614:
1.127     mycroft   615:        if (cfe->num_iospace >= 2 &&
                    616:            pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, &psc->sc_pcioh2,
                    617:            &psc->sc_io_window2)) {
                    618:                aprint_error("%s: can't map ASIC i/o space\n", self->dv_xname);
1.128   ! mycroft   619:                goto fail_3;
        !           620:        }
        !           621:
        !           622:        if (pcmcia_function_enable(pa->pf)) {
        !           623:                aprint_error("%s: function enable failed\n", self->dv_xname);
1.127     mycroft   624:                goto fail_4;
                    625:        }
                    626:
1.128   ! mycroft   627:        /* Set up power management hooks. */
        !           628:        dsc->sc_enable = ne_pcmcia_enable;
        !           629:        dsc->sc_disable = ne_pcmcia_disable;
        !           630:
1.2       thorpej   631:        /*
                    632:         * Read the station address from the board.
                    633:         */
1.46      mycroft   634:        i = 0;
                    635: again:
1.55      enami     636:        enaddr = NULL;                  /* Ask ASIC by default */
1.93      jonathan  637:        typestr = "";                   /* clear previous card-type */
1.46      mycroft   638:        for (; i < NE2000_NDEVS; i++) {
1.53      enami     639:                ne_dev = ne2000_match(pa->card, pa->pf->number, i);
                    640:                if (ne_dev != NULL) {
1.2       thorpej   641:                        if (ne_dev->enet_maddr >= 0) {
1.53      enami     642:                                enaddr = ne_pcmcia_get_enaddr(psc,
                    643:                                    ne_dev->enet_maddr, myea);
                    644:                                if (enaddr == NULL)
                    645:                                        continue;
1.2       thorpej   646:                        }
1.106     mycroft   647:                        goto found;
1.2       thorpej   648:                }
1.39      enami     649:        }
1.119     mycroft   650:        aprint_error("%s: can't match ethernet vendor code\n", self->dv_xname);
1.111     cube      651:        if (enaddr != NULL)
                    652:                aprint_error("%s: ethernet vendor code %02x:%02x:%02x\n",
1.119     mycroft   653:                    self->dv_xname, enaddr[0], enaddr[1], enaddr[2]);
1.127     mycroft   654:        goto fail_5;
1.39      enami     655:
1.106     mycroft   656: found:
1.39      enami     657:        if ((ne_dev->flags & NE2000DVF_DL10019) != 0) {
1.74      thorpej   658:                u_int8_t type;
                    659:
1.53      enami     660:                enaddr = ne_pcmcia_dl10019_get_enaddr(psc, myea);
                    661:                if (enaddr == NULL) {
1.47      mycroft   662:                        ++i;
                    663:                        goto again;
1.39      enami     664:                }
1.74      thorpej   665:
1.75      thorpej   666:                dsc->sc_mediachange = dl10019_mediachange;
                    667:                dsc->sc_mediastatus = dl10019_mediastatus;
                    668:                dsc->init_card = dl10019_init_card;
                    669:                dsc->stop_card = dl10019_stop_card;
                    670:                dsc->sc_media_init = dl10019_media_init;
                    671:                dsc->sc_media_fini = dl10019_media_fini;
                    672:
1.74      thorpej   673:                /* Determine if this is a DL10019 or a DL10022. */
                    674:                type = bus_space_read_1(nsc->sc_asict, nsc->sc_asich, 0x0f);
                    675:                if (type == 0x91 || type == 0x99) {
                    676:                        nsc->sc_type = NE2000_TYPE_DL10022;
                    677:                        typestr = " (DL10022)";
                    678:                } else {
                    679:                        nsc->sc_type = NE2000_TYPE_DL10019;
                    680:                        typestr = " (DL10019)";
                    681:                }
1.2       thorpej   682:        }
                    683:
1.55      enami     684:        if ((ne_dev->flags & NE2000DVF_AX88190) != 0) {
1.123     mycroft   685:                u_int8_t test;
                    686:
1.64      msaitoh   687:                if (ne_pcmcia_ax88190_set_iobase(psc)) {
                    688:                        ++i;
                    689:                        goto again;
                    690:                }
1.80      enami     691:
                    692:                dsc->sc_mediachange = ax88190_mediachange;
                    693:                dsc->sc_mediastatus = ax88190_mediastatus;
                    694:                dsc->init_card = ax88190_init_card;
                    695:                dsc->stop_card = ax88190_stop_card;
                    696:                dsc->sc_media_init = ax88190_media_init;
                    697:                dsc->sc_media_fini = ax88190_media_fini;
                    698:
1.123     mycroft   699:                test = bus_space_read_1(nsc->sc_asict, nsc->sc_asich, 0x05);
                    700:                if (test != 0) {
1.104     christos  701:                        nsc->sc_type = NE2000_TYPE_AX88790;
                    702:                        typestr = " (AX88790)";
                    703:                } else {
                    704:                        nsc->sc_type = NE2000_TYPE_AX88190;
                    705:                        typestr = " (AX88190)";
                    706:                }
1.55      enami     707:        }
                    708:
1.117     mycroft   709:        if (enaddr != NULL &&
                    710:            ne_dev->enet_vendor[0] != 0xff) {
1.2       thorpej   711:                /*
                    712:                 * Make sure this is what we expect.
                    713:                 */
                    714:                if (enaddr[0] != ne_dev->enet_vendor[0] ||
                    715:                    enaddr[1] != ne_dev->enet_vendor[1] ||
                    716:                    enaddr[2] != ne_dev->enet_vendor[2]) {
1.46      mycroft   717:                        ++i;
                    718:                        goto again;
1.2       thorpej   719:                }
                    720:        }
                    721:
1.22      thorpej   722:        /*
1.109     wiz       723:         * Check for a Realtek 8019.
1.22      thorpej   724:         */
1.75      thorpej   725:        if (nsc->sc_type == 0) {
                    726:                bus_space_write_1(dsc->sc_regt, dsc->sc_regh, ED_P0_CR,
                    727:                    ED_CR_PAGE_0 | ED_CR_STP);
                    728:                if (bus_space_read_1(dsc->sc_regt, dsc->sc_regh,
                    729:                    NERTL_RTL0_8019ID0) == RTL0_8019ID0 &&
                    730:                    bus_space_read_1(dsc->sc_regt, dsc->sc_regh,
                    731:                    NERTL_RTL0_8019ID1) == RTL0_8019ID1) {
                    732:                        typestr = " (RTL8019)";
                    733:                        dsc->sc_mediachange = rtl80x9_mediachange;
                    734:                        dsc->sc_mediastatus = rtl80x9_mediastatus;
1.95      simonb    735:                        dsc->init_card = rtl80x9_init_card;
1.75      thorpej   736:                        dsc->sc_media_init = rtl80x9_media_init;
                    737:                }
1.22      thorpej   738:        }
                    739:
1.68      thorpej   740:        if (ne2000_attach(nsc, enaddr))
1.128   ! mycroft   741:                goto fail_5;
1.2       thorpej   742:
                    743:        pcmcia_function_disable(pa->pf);
1.52      itojun    744:        return;
                    745:
1.127     mycroft   746: fail_5:
1.128   ! mycroft   747:        pcmcia_function_disable(pa->pf);
        !           748: fail_4:
1.127     mycroft   749:        if (cfe->num_iospace >= 2)
                    750:                pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window2);
1.128   ! mycroft   751: fail_3:
1.126     mycroft   752:        pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
                    753: fail_2:
1.127     mycroft   754:        if (cfe->num_iospace >= 2)
                    755:                pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh2);
1.53      enami     756:        pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
1.126     mycroft   757: fail_1:
                    758:        psc->sc_io_window = -1;
1.25      thorpej   759: }
                    760:
                    761: int
                    762: ne_pcmcia_detach(self, flags)
                    763:        struct device *self;
                    764:        int flags;
                    765: {
1.26      thorpej   766:        struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)self;
1.127     mycroft   767:        struct pcmcia_function *pf = psc->sc_pf;
1.53      enami     768:        int error;
1.26      thorpej   769:
1.126     mycroft   770:        if (psc->sc_io_window == -1)
1.53      enami     771:                /* Nothing to detach. */
                    772:                return (0);
                    773:
                    774:        error = ne2000_detach(&psc->sc_ne2000, flags);
                    775:        if (error != 0)
                    776:                return (error);
                    777:
                    778:        /* Unmap our i/o windows. */
1.127     mycroft   779:        if (pf->cfe->num_iospace >= 2)
                    780:                pcmcia_io_unmap(pf, psc->sc_io_window2);
                    781:        pcmcia_io_unmap(pf, psc->sc_io_window);
1.26      thorpej   782:
1.53      enami     783:        /* Free our i/o space. */
1.127     mycroft   784:        if (pf->cfe->num_iospace >= 2)
                    785:                pcmcia_io_free(pf, &psc->sc_pcioh2);
                    786:        pcmcia_io_free(pf, &psc->sc_pcioh);
1.53      enami     787:
                    788:        return (0);
1.2       thorpej   789: }
                    790:
                    791: int
                    792: ne_pcmcia_enable(dsc)
                    793:        struct dp8390_softc *dsc;
                    794: {
                    795:        struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
1.55      enami     796:        struct ne2000_softc *nsc = &psc->sc_ne2000;
1.104     christos  797:        struct pcmcia_mem_handle pcmh;
1.2       thorpej   798:
                    799:        /* set up the interrupt */
                    800:        psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, dp8390_intr,
                    801:            dsc);
                    802:        if (psc->sc_ih == NULL) {
                    803:                printf("%s: couldn't establish interrupt\n",
                    804:                    dsc->sc_dev.dv_xname);
1.53      enami     805:                goto fail_1;
1.2       thorpej   806:        }
                    807:
1.53      enami     808:        if (pcmcia_function_enable(psc->sc_pf))
                    809:                goto fail_2;
                    810:
1.104     christos  811:        if (nsc->sc_type == NE2000_TYPE_AX88190 ||
                    812:            nsc->sc_type == NE2000_TYPE_AX88790) {
1.55      enami     813:                if (ne_pcmcia_ax88190_set_iobase(psc))
                    814:                        goto fail_3;
1.104     christos  815:                if (nsc->sc_type == NE2000_TYPE_AX88790) {
                    816:                        bus_size_t offset;
                    817:                        int mwindow;
                    818:
                    819:                        if (pcmcia_mem_alloc(psc->sc_pf,
                    820:                            AX88790_CSR_SIZE, &pcmh)) {
                    821:                                printf("%s: can't alloc mem for CSR\n",
                    822:                                    dsc->sc_dev.dv_xname);
                    823:                                goto fail_3;
                    824:                        }
                    825:
                    826:                        if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR,
                    827:                            AX88790_CSR, AX88790_CSR_SIZE,
                    828:                            &pcmh, &offset, &mwindow)) {
                    829:                                printf("%s: can't map mem for CSR\n",
                    830:                                    dsc->sc_dev.dv_xname);
                    831:                                goto fail_4;
                    832:                        }
                    833:
                    834:                        bus_space_write_1(pcmh.memt, pcmh.memh, offset, 0x4);
                    835:                        pcmcia_mem_unmap(psc->sc_pf, mwindow);
                    836:                        pcmcia_mem_free(psc->sc_pf, &pcmh);
                    837:                }
                    838:        }
1.55      enami     839:
1.53      enami     840:        return (0);
                    841:
1.104     christos  842:  fail_4:
                    843:        pcmcia_mem_free(psc->sc_pf, &pcmh);
1.55      enami     844:  fail_3:
                    845:        pcmcia_function_disable(psc->sc_pf);
1.53      enami     846:  fail_2:
                    847:        pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
                    848:  fail_1:
                    849:        return (1);
1.2       thorpej   850: }
                    851:
                    852: void
                    853: ne_pcmcia_disable(dsc)
                    854:        struct dp8390_softc *dsc;
                    855: {
                    856:        struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
                    857:
                    858:        pcmcia_function_disable(psc->sc_pf);
                    859:        pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
1.52      itojun    860: }
                    861:
1.53      enami     862: u_int8_t *
                    863: ne_pcmcia_get_enaddr(psc, maddr, myea)
1.52      itojun    864:        struct ne_pcmcia_softc *psc;
1.53      enami     865:        int maddr;
                    866:        u_int8_t myea[ETHER_ADDR_LEN];
1.52      itojun    867: {
1.53      enami     868:        struct ne2000_softc *nsc = &psc->sc_ne2000;
                    869:        struct dp8390_softc *dsc = &nsc->sc_dp8390;
                    870:        struct pcmcia_mem_handle pcmh;
1.84      soren     871:        bus_size_t offset;
1.53      enami     872:        u_int8_t *enaddr = NULL;
                    873:        int j, mwindow;
                    874:
                    875:        if (maddr < 0)
                    876:                return (NULL);
                    877:
                    878:        if (pcmcia_mem_alloc(psc->sc_pf, ETHER_ADDR_LEN * 2, &pcmh)) {
                    879:                printf("%s: can't alloc mem for enet addr\n",
                    880:                    dsc->sc_dev.dv_xname);
                    881:                goto fail_1;
                    882:        }
                    883:        if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR, maddr,
                    884:            ETHER_ADDR_LEN * 2, &pcmh, &offset, &mwindow)) {
                    885:                printf("%s: can't map mem for enet addr\n",
                    886:                    dsc->sc_dev.dv_xname);
                    887:                goto fail_2;
1.52      itojun    888:        }
1.53      enami     889:        for (j = 0; j < ETHER_ADDR_LEN; j++)
                    890:                myea[j] = bus_space_read_1(pcmh.memt, pcmh.memh,
                    891:                    offset + (j * 2));
                    892:        enaddr = myea;
                    893:
                    894:        pcmcia_mem_unmap(psc->sc_pf, mwindow);
                    895:  fail_2:
                    896:        pcmcia_mem_free(psc->sc_pf, &pcmh);
                    897:  fail_1:
                    898:        return (enaddr);
                    899: }
                    900:
                    901: u_int8_t *
                    902: ne_pcmcia_dl10019_get_enaddr(psc, myea)
                    903:        struct ne_pcmcia_softc *psc;
                    904:        u_int8_t myea[ETHER_ADDR_LEN];
                    905: {
                    906:        struct ne2000_softc *nsc = &psc->sc_ne2000;
                    907:        u_int8_t sum;
                    908:        int j;
                    909:
                    910: #define PAR0   0x04
                    911:        for (j = 0, sum = 0; j < 8; j++)
                    912:                sum += bus_space_read_1(nsc->sc_asict, nsc->sc_asich,
                    913:                    PAR0 + j);
                    914:        if (sum != 0xff)
                    915:                return (NULL);
                    916:        for (j = 0; j < ETHER_ADDR_LEN; j++)
                    917:                myea[j] = bus_space_read_1(nsc->sc_asict,
                    918:                    nsc->sc_asich, PAR0 + j);
                    919: #undef PAR0
                    920:        return (myea);
1.55      enami     921: }
                    922:
                    923: int
                    924: ne_pcmcia_ax88190_set_iobase(psc)
                    925:        struct ne_pcmcia_softc *psc;
                    926: {
                    927:        struct ne2000_softc *nsc = &psc->sc_ne2000;
                    928:        struct dp8390_softc *dsc = &nsc->sc_dp8390;
                    929:        struct pcmcia_mem_handle pcmh;
1.84      soren     930:        bus_size_t offset;
1.55      enami     931:        int rv = 1, mwindow;
1.64      msaitoh   932:        u_int last_liobase, new_liobase;
1.55      enami     933:
1.80      enami     934:        if (pcmcia_mem_alloc(psc->sc_pf, AX88190_LAN_IOSIZE, &pcmh)) {
1.64      msaitoh   935: #if 0
1.55      enami     936:                printf("%s: can't alloc mem for LAN iobase\n",
                    937:                    dsc->sc_dev.dv_xname);
1.64      msaitoh   938: #endif
1.55      enami     939:                goto fail_1;
                    940:        }
                    941:        if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR,
1.80      enami     942:            AX88190_LAN_IOBASE, AX88190_LAN_IOSIZE,
1.55      enami     943:            &pcmh, &offset, &mwindow)) {
                    944:                printf("%s: can't map mem for LAN iobase\n",
                    945:                    dsc->sc_dev.dv_xname);
                    946:                goto fail_2;
                    947:        }
                    948:
1.64      msaitoh   949:        last_liobase = bus_space_read_1(pcmh.memt, pcmh.memh, offset + 0) |
                    950:            (bus_space_read_1(pcmh.memt, pcmh.memh, offset + 2) << 8);
1.55      enami     951: #ifdef DIAGNOSTIC
                    952:        printf("%s: LAN iobase 0x%x (0x%x) ->", dsc->sc_dev.dv_xname,
1.64      msaitoh   953:            last_liobase, (u_int)psc->sc_pcioh.addr);
1.55      enami     954: #endif
                    955:        bus_space_write_1(pcmh.memt, pcmh.memh, offset,
                    956:            psc->sc_pcioh.addr & 0xff);
                    957:        bus_space_write_1(pcmh.memt, pcmh.memh, offset + 2,
                    958:            psc->sc_pcioh.addr >> 8);
1.64      msaitoh   959:
                    960:        new_liobase = bus_space_read_1(pcmh.memt, pcmh.memh, offset + 0) |
                    961:            (bus_space_read_1(pcmh.memt, pcmh.memh, offset + 2) << 8);
1.55      enami     962: #ifdef DIAGNOSTIC
1.64      msaitoh   963:        printf(" 0x%x\n", new_liobase);
1.55      enami     964: #endif
1.64      msaitoh   965:        if ((last_liobase == psc->sc_pcioh.addr)
                    966:            || (last_liobase != new_liobase))
                    967:                rv = 0;
1.55      enami     968:
                    969:        pcmcia_mem_unmap(psc->sc_pf, mwindow);
                    970:  fail_2:
                    971:        pcmcia_mem_free(psc->sc_pf, &pcmh);
                    972:  fail_1:
                    973:        return (rv);
1.2       thorpej   974: }

CVSweb <webmaster@jp.NetBSD.org>