1/* $NetBSD: xirc.c,v 1.32 2010/01/19 22:07:43 pooka Exp $ */ 2 3/*- 4 * Copyright (c) 1999, 2000, 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center and by Charles M. Hannum. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> 34__KERNEL_RCSID(0, "$NetBSD: xirc.c,v 1.32 2010/01/19 22:07:43 pooka Exp $"); 35 36#include "opt_inet.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/mbuf.h> 41#include <sys/socket.h> 42#include <sys/ioctl.h> 43#include <sys/errno.h> 44#include <sys/syslog.h> 45#include <sys/select.h> 46#include <sys/tty.h> 47#include <sys/device.h> 48 49#include <net/if.h> 50#include <net/if_dl.h> 51#include <net/if_ether.h> 52#include <net/if_media.h> 53 54#ifdef INET 55#include <netinet/in.h> 56#include <netinet/in_systm.h> 57#include <netinet/in_var.h> 58#include <netinet/ip.h> 59#include <netinet/if_inarp.h> 60#endif 61 62 63#include <net/bpf.h> 64#include <net/bpfdesc.h> 65 66#include <sys/intr.h> 67#include <sys/bus.h> 68 69#include <dev/pcmcia/pcmciareg.h> 70#include <dev/pcmcia/pcmciavar.h> 71#include <dev/pcmcia/pcmciadevs.h> 72 73#include "xirc.h" 74 75#if NCOM_XIRC > 0 76#include <dev/ic/comreg.h> 77#include <dev/ic/comvar.h> 78#endif 79 80#if NXI_XIRC > 0 81#include <dev/mii/mii.h> 82#include <dev/mii/miivar.h> 83 84#include <dev/pcmcia/if_xivar.h> 85#endif 86#include <dev/pcmcia/if_xireg.h> 87 88struct xirc_softc { 89 device_t sc_dev; /* generic device glue */ 90 91 struct pcmcia_function *sc_pf; /* our PCMCIA function */ 92 void *sc_ih; /* interrupt handle */ 93 94 u_int16_t sc_id; 95 u_int8_t sc_mako_intmask; 96 int sc_chipset; 97 98 /* 99 * Data for the Modem portion. 100 */ 101 device_t sc_modem; 102 struct pcmcia_io_handle sc_modem_pcioh; 103 int sc_modem_io_window; 104 105 /* 106 * Data for the Ethernet portion. 107 */ 108 device_t sc_ethernet; 109 struct pcmcia_io_handle sc_ethernet_pcioh; 110 int sc_ethernet_io_window; 111 112 int sc_flags; 113#define XIRC_MODEM_MAPPED 0x01 114#define XIRC_ETHERNET_MAPPED 0x02 115#define XIRC_MODEM_ENABLED 0x04 116#define XIRC_ETHERNET_ENABLED 0x08 117#define XIRC_MODEM_ALLOCED 0x10 118#define XIRC_ETHERNET_ALLOCED 0x20 119}; 120 121int xirc_match(device_t, cfdata_t, void *); 122void xirc_attach(device_t, device_t, void *); 123int xirc_detach(device_t, int); 124void xirc_childdet(device_t, device_t); 125 126CFATTACH_DECL2_NEW(xirc, sizeof(struct xirc_softc), 127 xirc_match, xirc_attach, xirc_detach, NULL, NULL, xirc_childdet); 128 129int xirc_print(void *, const char *); 130 131int xirc_manfid_ciscallback(struct pcmcia_tuple *, void *); 132struct pcmcia_config_entry * 133 xirc_mako_alloc(struct xirc_softc *); 134struct pcmcia_config_entry * 135 xirc_dingo_alloc_modem(struct xirc_softc *); 136struct pcmcia_config_entry * 137 xirc_dingo_alloc_ethernet(struct xirc_softc *); 138 139int xirc_enable(struct xirc_softc *, int, int); 140void xirc_disable(struct xirc_softc *, int, int); 141 142int xirc_intr(void *); 143 144int 145xirc_match(device_t parent, cfdata_t match, 146 void *aux) 147{ 148 struct pcmcia_attach_args *pa = aux; 149 150 /* XXX Toshiba, Accton */ 151 152 if (pa->manufacturer == PCMCIA_VENDOR_COMPAQ2 && 153 pa->product == PCMCIA_PRODUCT_COMPAQ2_CPQ_10_100) 154 return (1); 155 156 if (pa->manufacturer == PCMCIA_VENDOR_INTEL && 157 pa->product == PCMCIA_PRODUCT_INTEL_EEPRO100) 158 return (1); 159 160 if (pa->manufacturer == PCMCIA_VENDOR_XIRCOM && 161 (pa->product & (XIMEDIA_ETHER << 8)) != 0) 162 return (2); 163 164 return (0); 165} 166 167void 168xirc_attach(device_t parent, device_t self, void *aux) 169{ 170 struct xirc_softc *sc = device_private(self); 171 struct pcmcia_attach_args *pa = aux; 172 struct pcmcia_config_entry *cfe; 173 int rv; 174 int error; 175 176 sc->sc_dev = self; 177 178 sc->sc_pf = pa->pf; 179 180 pcmcia_socket_enable(parent); 181 rv = pcmcia_scan_cis(parent, xirc_manfid_ciscallback, &sc->sc_id); 182 pcmcia_socket_disable(parent); 183 if (!rv) { 184 aprint_error_dev(self, "failed to find ID\n"); 185 return; 186 } 187 188 switch (sc->sc_id & 0x100f) { 189 case 0x0001: /* CE */ 190 case 0x0002: /* CE2 */ 191 sc->sc_chipset = XI_CHIPSET_SCIPPER; 192 break; 193 case 0x0003: /* CE3 */ 194 sc->sc_chipset = XI_CHIPSET_MOHAWK; 195 break; 196 case 0x1001: 197 case 0x1002: 198 case 0x1003: 199 case 0x1004: 200 sc->sc_chipset = XI_CHIPSET_SCIPPER; 201 break; 202 case 0x1005: 203 sc->sc_chipset = XI_CHIPSET_MOHAWK; 204 break; 205 case 0x1006: 206 case 0x1007: 207 sc->sc_chipset = XI_CHIPSET_DINGO; 208 break; 209 default: 210 aprint_error_dev(self, "unknown ID %04x\n", 211 sc->sc_id); 212 return; 213 } 214 215 aprint_normal_dev(self, "id=%04x\n", sc->sc_id); 216 217 if (sc->sc_id & (XIMEDIA_MODEM << 8)) { 218 if (sc->sc_chipset >= XI_CHIPSET_DINGO) { 219 cfe = xirc_dingo_alloc_modem(sc); 220 if (cfe && sc->sc_id & (XIMEDIA_ETHER << 8)) { 221 if (!xirc_dingo_alloc_ethernet(sc)) { 222 pcmcia_io_free(pa->pf, 223 &sc->sc_modem_pcioh); 224 cfe = 0; 225 } 226 } 227 } else 228 cfe = xirc_mako_alloc(sc); 229 } else 230 cfe = xirc_dingo_alloc_ethernet(sc); 231 if (!cfe) { 232 aprint_error_dev(self, "failed to allocate I/O space\n"); 233 goto fail; 234 } 235 236 /* Enable the card. */ 237 pcmcia_function_init(pa->pf, cfe); 238 239 if (sc->sc_id & (XIMEDIA_MODEM << 8)) { 240 if (pcmcia_io_map(sc->sc_pf, PCMCIA_WIDTH_IO8, 241 &sc->sc_modem_pcioh, &sc->sc_modem_io_window)) { 242 aprint_error_dev(self, "unable to map I/O space\n"); 243 goto fail; 244 } 245 sc->sc_flags |= XIRC_MODEM_MAPPED; 246 } 247 248 if (sc->sc_id & (XIMEDIA_ETHER << 8)) { 249 if (pcmcia_io_map(sc->sc_pf, PCMCIA_WIDTH_AUTO, 250 &sc->sc_ethernet_pcioh, &sc->sc_ethernet_io_window)) { 251 aprint_error_dev(self, "unable to map I/O space\n"); 252 goto fail; 253 } 254 sc->sc_flags |= XIRC_ETHERNET_MAPPED; 255 } 256 257 error = xirc_enable(sc, XIRC_MODEM_ENABLED|XIRC_ETHERNET_ENABLED, 258 sc->sc_id & (XIMEDIA_MODEM|XIMEDIA_ETHER)); 259 if (error) 260 goto fail; 261 262 sc->sc_mako_intmask = 0xee; 263 264 if (sc->sc_id & (XIMEDIA_MODEM << 8)) 265 /*XXXUNCONST*/ 266 sc->sc_modem = config_found(self, __UNCONST("com"), xirc_print); 267 if (sc->sc_id & (XIMEDIA_ETHER << 8)) 268 /*XXXUNCONST*/ 269 sc->sc_ethernet = config_found(self, __UNCONST("xi"), 270 xirc_print); 271 272 xirc_disable(sc, XIRC_MODEM_ENABLED|XIRC_ETHERNET_ENABLED, 273 sc->sc_id & (XIMEDIA_MODEM|XIMEDIA_ETHER)); 274 return; 275 276fail: 277 /* I/O spaces will be freed by detach. */ 278 ; 279} 280 281int 282xirc_manfid_ciscallback(struct pcmcia_tuple *tuple, void *arg) 283{ 284 u_int16_t *id = arg; 285 286 if (tuple->code != PCMCIA_CISTPL_MANFID) 287 return (0); 288 289 if (tuple->length < 5) 290 return (0); 291 292 *id = (pcmcia_tuple_read_1(tuple, 3) << 8) | 293 pcmcia_tuple_read_1(tuple, 4); 294 return (1); 295} 296 297struct pcmcia_config_entry * 298xirc_mako_alloc(struct xirc_softc *sc) 299{ 300 struct pcmcia_config_entry *cfe; 301 302 SIMPLEQ_FOREACH(cfe, &sc->sc_pf->cfe_head, cfe_list) { 303 if (cfe->num_iospace != 1) 304 continue; 305 306 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[0].start, 307 cfe->iospace[0].length, cfe->iospace[0].length, 308 &sc->sc_modem_pcioh)) 309 continue; 310 311 cfe->iospace[1].start = cfe->iospace[0].start+8; 312 cfe->iospace[1].length = 18; 313 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[1].start, 314 cfe->iospace[1].length, 0x20, 315 &sc->sc_ethernet_pcioh)) { 316 cfe->iospace[1].start = cfe->iospace[0].start-24; 317 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[1].start, 318 cfe->iospace[1].length, 0x20, 319 &sc->sc_ethernet_pcioh)) 320 continue; 321 } 322 323 /* Found one! */ 324 sc->sc_flags |= XIRC_MODEM_ALLOCED; 325 sc->sc_flags |= XIRC_ETHERNET_ALLOCED; 326 return (cfe); 327 } 328 329 return (0); 330} 331 332struct pcmcia_config_entry * 333xirc_dingo_alloc_modem(struct xirc_softc *sc) 334{ 335 struct pcmcia_config_entry *cfe; 336 337 SIMPLEQ_FOREACH(cfe, &sc->sc_pf->cfe_head, cfe_list) { 338 if (cfe->num_iospace != 1) 339 continue; 340 341 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[0].start, 342 cfe->iospace[0].length, cfe->iospace[0].length, 343 &sc->sc_modem_pcioh)) 344 continue; 345 346 /* Found one! */ 347 sc->sc_flags |= XIRC_MODEM_ALLOCED; 348 return (cfe); 349 } 350 351 return (0); 352} 353 354struct pcmcia_config_entry * 355xirc_dingo_alloc_ethernet(struct xirc_softc *sc) 356{ 357 struct pcmcia_config_entry *cfe; 358 bus_addr_t port; 359 360 for (port = 0x300; port < 0x400; port += XI_IOSIZE) { 361 if (pcmcia_io_alloc(sc->sc_pf, port, 362 XI_IOSIZE, XI_IOSIZE, &sc->sc_ethernet_pcioh)) 363 continue; 364 365 /* Found one for the ethernet! */ 366 sc->sc_flags |= XIRC_ETHERNET_ALLOCED; 367 cfe = SIMPLEQ_FIRST(&sc->sc_pf->cfe_head); 368 return (cfe); 369 } 370 371 return (0); 372} 373 374int 375xirc_print(void *aux, const char *pnp) 376{ 377 const char *name = aux; 378 379 if (pnp) 380 aprint_normal("%s at %s(*)", name, pnp); 381 382 return (UNCONF); 383} 384 385void 386xirc_childdet(device_t self, device_t child) 387{ 388 struct xirc_softc *sc = device_private(self); 389 390 if (sc->sc_ethernet == child) 391 sc->sc_ethernet = NULL; 392 393 if (sc->sc_modem == child) 394 sc->sc_modem = NULL; 395} 396 397int 398xirc_detach(device_t self, int flags) 399{ 400 struct xirc_softc *sc = device_private(self); 401 int rv; 402 403 if (sc->sc_ethernet != NULL) { 404 if ((rv = config_detach(sc->sc_ethernet, flags)) != 0) 405 return rv; 406 } 407 408 if (sc->sc_modem != NULL) { 409 if ((rv = config_detach(sc->sc_modem, flags)) != 0) 410 return rv; 411 } 412 413 /* Unmap our i/o windows. */ 414 if (sc->sc_flags & XIRC_ETHERNET_MAPPED) 415 pcmcia_io_unmap(sc->sc_pf, sc->sc_ethernet_io_window); 416 if (sc->sc_flags & XIRC_MODEM_MAPPED) 417 pcmcia_io_unmap(sc->sc_pf, sc->sc_modem_io_window); 418 419 /* Free our i/o spaces. */ 420 if (sc->sc_flags & XIRC_ETHERNET_ALLOCED) 421 pcmcia_io_free(sc->sc_pf, &sc->sc_ethernet_pcioh); 422 if (sc->sc_flags & XIRC_MODEM_ALLOCED) 423 pcmcia_io_free(sc->sc_pf, &sc->sc_modem_pcioh); 424 sc->sc_flags = 0; 425 426 return (0); 427} 428 429int 430xirc_intr(void *arg) 431{ 432 struct xirc_softc *sc = arg; 433 int rval = 0; 434 435#if NCOM_XIRC > 0 436 if (sc->sc_modem != NULL && 437 (sc->sc_flags & XIRC_MODEM_ENABLED) != 0) 438 rval |= comintr(device_private(sc->sc_modem)); 439#endif 440 441#if NXI_XIRC > 0 442 if (sc->sc_ethernet != NULL && 443 (sc->sc_flags & XIRC_ETHERNET_ENABLED) != 0) 444 rval |= xi_intr(device_private(sc->sc_ethernet)); 445#endif 446 447 return (rval); 448} 449 450int 451xirc_enable(struct xirc_softc *sc, int flag, int media) 452{ 453 int error; 454 455 if ((sc->sc_flags & flag) == flag) { 456 printf("%s: already enabled\n", device_xname(sc->sc_dev)); 457 return (0); 458 } 459 460 if ((sc->sc_flags & (XIRC_MODEM_ENABLED|XIRC_ETHERNET_ENABLED)) != 0) { 461 sc->sc_flags |= flag; 462 return (0); 463 } 464 465 /* 466 * Establish our interrupt handler. 467 * 468 * XXX Note, we establish this at IPL_NET. This is suboptimal 469 * XXX the Modem portion, but is necessary to make the Ethernet 470 * XXX portion have the correct interrupt level semantics. 471 * 472 * XXX Eventually we should use the `enabled' bits in the 473 * XXX flags word to determine which level we should be at. 474 */ 475 sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET, xirc_intr, sc); 476 if (!sc->sc_ih) 477 return (EIO); 478 479 error = pcmcia_function_enable(sc->sc_pf); 480 if (error) { 481 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih); 482 sc->sc_ih = 0; 483 return (error); 484 } 485 486 sc->sc_flags |= flag; 487 488 if (sc->sc_chipset < XI_CHIPSET_DINGO && 489 sc->sc_id & (XIMEDIA_MODEM << 8)) { 490 sc->sc_mako_intmask |= media; 491 bus_space_write_1(sc->sc_ethernet_pcioh.iot, 492 sc->sc_ethernet_pcioh.ioh, 0x10, sc->sc_mako_intmask); 493 } 494 495 return (0); 496} 497 498void 499xirc_disable(struct xirc_softc *sc, int flag, int media) 500{ 501 502 if ((sc->sc_flags & flag) == 0) { 503 printf("%s: already disabled\n", device_xname(sc->sc_dev)); 504 return; 505 } 506 507 if (sc->sc_chipset < XI_CHIPSET_DINGO && 508 sc->sc_id & (XIMEDIA_MODEM << 8)) { 509 sc->sc_mako_intmask &= ~media; 510 bus_space_write_1(sc->sc_ethernet_pcioh.iot, 511 sc->sc_ethernet_pcioh.ioh, 0x10, sc->sc_mako_intmask); 512 } 513 514 sc->sc_flags &= ~flag; 515 if ((sc->sc_flags & (XIRC_MODEM_ENABLED|XIRC_ETHERNET_ENABLED)) != 0) 516 return; 517 518 pcmcia_function_disable(sc->sc_pf); 519 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih); 520 sc->sc_ih = 0; 521} 522 523/****** Here begins the com attachment code. ******/ 524 525#if NCOM_XIRC > 0 526int com_xirc_match(device_t, cfdata_t , void *); 527void com_xirc_attach(device_t, device_t, void *); 528int com_xirc_detach(device_t, int); 529 530/* No xirc-specific goo in the softc; it's all in the parent. */ 531CFATTACH_DECL_NEW(com_xirc, sizeof(struct com_softc), 532 com_xirc_match, com_xirc_attach, com_detach, NULL); 533 534int com_xirc_enable(struct com_softc *); 535void com_xirc_disable(struct com_softc *); 536 537int 538com_xirc_match(device_t parent, cfdata_t match, void *aux) 539{ 540 extern struct cfdriver com_cd; 541 const char *name = aux; 542 543 if (strcmp(name, com_cd.cd_name) == 0) 544 return (1); 545 546 return (0); 547} 548 549void 550com_xirc_attach(device_t parent, device_t self, void *aux) 551{ 552 struct com_softc *sc = device_private(self); 553 struct xirc_softc *msc = device_private(parent); 554 555 sc->sc_dev = self; 556 557 aprint_normal("\n"); 558 559 COM_INIT_REGS(sc->sc_regs, 560 msc->sc_modem_pcioh.iot, 561 msc->sc_modem_pcioh.ioh, 562 -1); 563 564 sc->enabled = 1; 565 566 sc->sc_frequency = COM_FREQ; 567 568 sc->enable = com_xirc_enable; 569 sc->disable = com_xirc_disable; 570 571 aprint_normal("%s", device_xname(self)); 572 573 com_attach_subr(sc); 574 575 sc->enabled = 0; 576} 577 578int 579com_xirc_enable(struct com_softc *sc) 580{ 581 struct xirc_softc *msc = 582 device_private(device_parent(sc->sc_dev)); 583 584 return (xirc_enable(msc, XIRC_MODEM_ENABLED, XIMEDIA_MODEM)); 585} 586 587void 588com_xirc_disable(struct com_softc *sc) 589{ 590 struct xirc_softc *msc = 591 device_private(device_parent(sc->sc_dev)); 592 593 xirc_disable(msc, XIRC_MODEM_ENABLED, XIMEDIA_MODEM); 594} 595 596#endif /* NCOM_XIRC > 0 */ 597 598/****** Here begins the xi attachment code. ******/ 599 600#if NXI_XIRC > 0 601int xi_xirc_match(device_t, cfdata_t, void *); 602void xi_xirc_attach(device_t, device_t, void *); 603 604/* No xirc-specific goo in the softc; it's all in the parent. */ 605CFATTACH_DECL_NEW(xi_xirc, sizeof(struct xi_softc), 606 xi_xirc_match, xi_xirc_attach, xi_detach, NULL); 607 608int xi_xirc_enable(struct xi_softc *); 609void xi_xirc_disable(struct xi_softc *); 610int xi_xirc_lan_nid_ciscallback(struct pcmcia_tuple *, void *); 611 612int 613xi_xirc_match(device_t parent, cfdata_t match, void *aux) 614{ 615 extern struct cfdriver xi_cd; 616 const char *name = aux; 617 618 if (strcmp(name, xi_cd.cd_name) == 0) 619 return (1); 620 621 return (0); 622} 623 624void 625xi_xirc_attach(device_t parent, device_t self, void *aux) 626{ 627 struct xi_softc *sc = device_private(self); 628 struct xirc_softc *msc = device_private(parent); 629 u_int8_t myla[ETHER_ADDR_LEN]; 630 631 sc->sc_dev = self; 632 633 aprint_normal("\n"); 634 635 sc->sc_bst = msc->sc_ethernet_pcioh.iot; 636 sc->sc_bsh = msc->sc_ethernet_pcioh.ioh; 637 638 sc->sc_chipset = msc->sc_chipset; 639 640 sc->sc_enable = xi_xirc_enable; 641 sc->sc_disable = xi_xirc_disable; 642 643 if (!pcmcia_scan_cis(device_parent(msc->sc_dev), 644 xi_xirc_lan_nid_ciscallback, myla)) { 645 aprint_error_dev(self, "can't find MAC address\n"); 646 return; 647 } 648 649 /* Perform generic initialization. */ 650 xi_attach(sc, myla); 651} 652 653int 654xi_xirc_enable(struct xi_softc *sc) 655{ 656 struct xirc_softc *msc = device_private(device_parent(sc->sc_dev)); 657 658 return (xirc_enable(msc, XIRC_ETHERNET_ENABLED, XIMEDIA_ETHER)); 659} 660 661void 662xi_xirc_disable(struct xi_softc *sc) 663{ 664 struct xirc_softc *msc = device_private(device_parent(sc->sc_dev)); 665 666 xirc_disable(msc, XIRC_ETHERNET_ENABLED, XIMEDIA_ETHER); 667} 668 669int 670xi_xirc_lan_nid_ciscallback(struct pcmcia_tuple *tuple, void *arg) 671{ 672 u_int8_t *myla = arg; 673 int i; 674 675 if (tuple->length < 2) 676 return (0); 677 678 switch (tuple->code) { 679 case PCMCIA_CISTPL_FUNCE: 680 switch (pcmcia_tuple_read_1(tuple, 0)) { 681 case PCMCIA_TPLFE_TYPE_LAN_NID: 682 if (pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN) 683 return (0); 684 for (i = 0; i < ETHER_ADDR_LEN; i++) 685 myla[i] = pcmcia_tuple_read_1(tuple, i + 2); 686 return (1); 687 688 case 0x02: 689 /* 690 * Not sure about this, I don't have a CE2 691 * that puts the ethernet addr here. 692 */ 693 if (pcmcia_tuple_read_1(tuple, 1) != 0x01 || 694 pcmcia_tuple_read_1(tuple, 2) != ETHER_ADDR_LEN) 695 return (0); 696 for (i = 0; i < ETHER_ADDR_LEN; i++) 697 myla[i] = pcmcia_tuple_read_1(tuple, i + 3); 698 return (1); 699 } 700 701 case 0x89: 702 if (pcmcia_tuple_read_1(tuple, 0) != 0x04 || 703 pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN) 704 return (0); 705 for (i = 0; i < ETHER_ADDR_LEN; i++) 706 myla[i] = pcmcia_tuple_read_1(tuple, i + 2); 707 return (1); 708 } 709 710 return (0); 711} 712 713#endif /* NXI_XIRC > 0 */ 714