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