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