1 /* $NetBSD: xirc.c,v 1.25 2008/07/28 14:25:30 drochner 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.25 2008/07/28 14:25:30 drochner 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 struct device 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 struct device *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 struct device *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(struct device *, struct cfdata *, void *); 125 void xirc_attach(struct device *, struct device *, void *); 126 int xirc_detach(struct device *, int); 127 int xirc_activate(struct device *, enum devact); 128 129 CFATTACH_DECL(xirc, sizeof(struct xirc_softc), 130 xirc_match, xirc_attach, xirc_detach, xirc_activate); 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(struct device *parent, struct cfdata *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(parent, self, aux) 172 struct device *parent, *self; 173 void *aux; 174 { 175 struct xirc_softc *sc = (void *)self; 176 struct pcmcia_attach_args *pa = aux; 177 struct pcmcia_config_entry *cfe; 178 int rv; 179 int error; 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(tuple, arg) 286 struct pcmcia_tuple *tuple; 287 void *arg; 288 { 289 u_int16_t *id = arg; 290 291 if (tuple->code != PCMCIA_CISTPL_MANFID) 292 return (0); 293 294 if (tuple->length < 5) 295 return (0); 296 297 *id = (pcmcia_tuple_read_1(tuple, 3) << 8) | 298 pcmcia_tuple_read_1(tuple, 4); 299 return (1); 300 } 301 302 struct pcmcia_config_entry * 303 xirc_mako_alloc(sc) 304 struct xirc_softc *sc; 305 { 306 struct pcmcia_config_entry *cfe; 307 308 SIMPLEQ_FOREACH(cfe, &sc->sc_pf->cfe_head, cfe_list) { 309 if (cfe->num_iospace != 1) 310 continue; 311 312 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[0].start, 313 cfe->iospace[0].length, cfe->iospace[0].length, 314 &sc->sc_modem_pcioh)) 315 continue; 316 317 cfe->iospace[1].start = cfe->iospace[0].start+8; 318 cfe->iospace[1].length = 18; 319 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[1].start, 320 cfe->iospace[1].length, 0x20, 321 &sc->sc_ethernet_pcioh)) { 322 cfe->iospace[1].start = cfe->iospace[0].start-24; 323 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[1].start, 324 cfe->iospace[1].length, 0x20, 325 &sc->sc_ethernet_pcioh)) 326 continue; 327 } 328 329 /* Found one! */ 330 sc->sc_flags |= XIRC_MODEM_ALLOCED; 331 sc->sc_flags |= XIRC_ETHERNET_ALLOCED; 332 return (cfe); 333 } 334 335 return (0); 336 } 337 338 struct pcmcia_config_entry * 339 xirc_dingo_alloc_modem(sc) 340 struct xirc_softc *sc; 341 { 342 struct pcmcia_config_entry *cfe; 343 344 SIMPLEQ_FOREACH(cfe, &sc->sc_pf->cfe_head, cfe_list) { 345 if (cfe->num_iospace != 1) 346 continue; 347 348 if (pcmcia_io_alloc(sc->sc_pf, cfe->iospace[0].start, 349 cfe->iospace[0].length, cfe->iospace[0].length, 350 &sc->sc_modem_pcioh)) 351 continue; 352 353 /* Found one! */ 354 sc->sc_flags |= XIRC_MODEM_ALLOCED; 355 return (cfe); 356 } 357 358 return (0); 359 } 360 361 struct pcmcia_config_entry * 362 xirc_dingo_alloc_ethernet(sc) 363 struct xirc_softc *sc; 364 { 365 struct pcmcia_config_entry *cfe; 366 bus_addr_t port; 367 368 for (port = 0x300; port < 0x400; port += XI_IOSIZE) { 369 if (pcmcia_io_alloc(sc->sc_pf, port, 370 XI_IOSIZE, XI_IOSIZE, &sc->sc_ethernet_pcioh)) 371 continue; 372 373 /* Found one for the ethernet! */ 374 sc->sc_flags |= XIRC_ETHERNET_ALLOCED; 375 cfe = SIMPLEQ_FIRST(&sc->sc_pf->cfe_head); 376 return (cfe); 377 } 378 379 return (0); 380 } 381 382 int 383 xirc_print(aux, pnp) 384 void *aux; 385 const char *pnp; 386 { 387 const char *name = aux; 388 389 if (pnp) 390 aprint_normal("%s at %s(*)", name, pnp); 391 392 return (UNCONF); 393 } 394 395 int 396 xirc_detach(self, flags) 397 struct device *self; 398 int flags; 399 { 400 struct xirc_softc *sc = (void *)self; 401 int rv; 402 403 if (sc->sc_ethernet != NULL) { 404 rv = config_detach(sc->sc_ethernet, flags); 405 if (rv != 0) 406 return (rv); 407 sc->sc_ethernet = NULL; 408 } 409 410 if (sc->sc_modem != NULL) { 411 rv = config_detach(sc->sc_modem, flags); 412 if (rv != 0) 413 return (rv); 414 sc->sc_modem = NULL; 415 } 416 417 /* Unmap our i/o windows. */ 418 if (sc->sc_flags & XIRC_ETHERNET_MAPPED) 419 pcmcia_io_unmap(sc->sc_pf, sc->sc_ethernet_io_window); 420 if (sc->sc_flags & XIRC_MODEM_MAPPED) 421 pcmcia_io_unmap(sc->sc_pf, sc->sc_modem_io_window); 422 423 /* Free our i/o spaces. */ 424 if (sc->sc_flags & XIRC_ETHERNET_ALLOCED) 425 pcmcia_io_free(sc->sc_pf, &sc->sc_ethernet_pcioh); 426 if (sc->sc_flags & XIRC_MODEM_ALLOCED) 427 pcmcia_io_free(sc->sc_pf, &sc->sc_modem_pcioh); 428 sc->sc_flags = 0; 429 430 return (0); 431 } 432 433 int 434 xirc_activate(self, act) 435 struct device *self; 436 enum devact act; 437 { 438 struct xirc_softc *sc = (void *)self; 439 int s, rv = 0; 440 441 s = splhigh(); 442 switch (act) { 443 case DVACT_ACTIVATE: 444 rv = EOPNOTSUPP; 445 break; 446 447 case DVACT_DEACTIVATE: 448 if (sc->sc_ethernet != NULL) { 449 rv = config_deactivate(sc->sc_ethernet); 450 if (rv != 0) 451 goto out; 452 } 453 454 if (sc->sc_modem != NULL) { 455 rv = config_deactivate(sc->sc_modem); 456 if (rv != 0) 457 goto out; 458 } 459 break; 460 } 461 out: 462 splx(s); 463 return (rv); 464 } 465 466 int 467 xirc_intr(arg) 468 void *arg; 469 { 470 struct xirc_softc *sc = arg; 471 int rval = 0; 472 473 #if NCOM_XIRC > 0 474 if (sc->sc_modem != NULL && 475 (sc->sc_flags & XIRC_MODEM_ENABLED) != 0) 476 rval |= comintr(device_private(sc->sc_modem)); 477 #endif 478 479 #if NXI_XIRC > 0 480 if (sc->sc_ethernet != NULL && 481 (sc->sc_flags & XIRC_ETHERNET_ENABLED) != 0) 482 rval |= xi_intr(device_private(sc->sc_ethernet)); 483 #endif 484 485 return (rval); 486 } 487 488 int 489 xirc_enable(sc, flag, media) 490 struct xirc_softc *sc; 491 int flag, media; 492 { 493 int error; 494 495 if ((sc->sc_flags & flag) == flag) { 496 printf("%s: already enabled\n", device_xname(&sc->sc_dev)); 497 return (0); 498 } 499 500 if ((sc->sc_flags & (XIRC_MODEM_ENABLED|XIRC_ETHERNET_ENABLED)) != 0) { 501 sc->sc_flags |= flag; 502 return (0); 503 } 504 505 /* 506 * Establish our interrupt handler. 507 * 508 * XXX Note, we establish this at IPL_NET. This is suboptimal 509 * XXX the Modem portion, but is necessary to make the Ethernet 510 * XXX portion have the correct interrupt level semantics. 511 * 512 * XXX Eventually we should use the `enabled' bits in the 513 * XXX flags word to determine which level we should be at. 514 */ 515 sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET, xirc_intr, sc); 516 if (!sc->sc_ih) 517 return (EIO); 518 519 error = pcmcia_function_enable(sc->sc_pf); 520 if (error) { 521 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih); 522 sc->sc_ih = 0; 523 return (error); 524 } 525 526 sc->sc_flags |= flag; 527 528 if (sc->sc_chipset < XI_CHIPSET_DINGO && 529 sc->sc_id & (XIMEDIA_MODEM << 8)) { 530 sc->sc_mako_intmask |= media; 531 bus_space_write_1(sc->sc_ethernet_pcioh.iot, 532 sc->sc_ethernet_pcioh.ioh, 0x10, sc->sc_mako_intmask); 533 } 534 535 return (0); 536 } 537 538 void 539 xirc_disable(sc, flag, media) 540 struct xirc_softc *sc; 541 int flag, media; 542 { 543 544 if ((sc->sc_flags & flag) == 0) { 545 printf("%s: already disabled\n", device_xname(&sc->sc_dev)); 546 return; 547 } 548 549 if (sc->sc_chipset < XI_CHIPSET_DINGO && 550 sc->sc_id & (XIMEDIA_MODEM << 8)) { 551 sc->sc_mako_intmask &= ~media; 552 bus_space_write_1(sc->sc_ethernet_pcioh.iot, 553 sc->sc_ethernet_pcioh.ioh, 0x10, sc->sc_mako_intmask); 554 } 555 556 sc->sc_flags &= ~flag; 557 if ((sc->sc_flags & (XIRC_MODEM_ENABLED|XIRC_ETHERNET_ENABLED)) != 0) 558 return; 559 560 pcmcia_function_disable(sc->sc_pf); 561 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih); 562 sc->sc_ih = 0; 563 } 564 565 /****** Here begins the com attachment code. ******/ 566 567 #if NCOM_XIRC > 0 568 int com_xirc_match(device_t, cfdata_t , void *); 569 void com_xirc_attach(device_t, device_t, void *); 570 int com_xirc_detach(device_t, int); 571 572 /* No xirc-specific goo in the softc; it's all in the parent. */ 573 CFATTACH_DECL_NEW(com_xirc, sizeof(struct com_softc), 574 com_xirc_match, com_xirc_attach, com_detach, com_activate); 575 576 int com_xirc_enable(struct com_softc *); 577 void com_xirc_disable(struct com_softc *); 578 579 int 580 com_xirc_match(device_t parent, cfdata_t match, void *aux) 581 { 582 extern struct cfdriver com_cd; 583 const char *name = aux; 584 585 if (strcmp(name, com_cd.cd_name) == 0) 586 return (1); 587 588 return (0); 589 } 590 591 void 592 com_xirc_attach(device_t parent, device_t self, void *aux) 593 { 594 struct com_softc *sc = device_private(self); 595 struct xirc_softc *msc = device_private(parent); 596 597 sc->sc_dev = self; 598 599 aprint_normal("\n"); 600 601 COM_INIT_REGS(sc->sc_regs, 602 msc->sc_modem_pcioh.iot, 603 msc->sc_modem_pcioh.ioh, 604 -1); 605 606 sc->enabled = 1; 607 608 sc->sc_frequency = COM_FREQ; 609 610 sc->enable = com_xirc_enable; 611 sc->disable = com_xirc_disable; 612 613 aprint_normal("%s", device_xname(self)); 614 615 com_attach_subr(sc); 616 617 sc->enabled = 0; 618 } 619 620 int 621 com_xirc_enable(struct com_softc *sc) 622 { 623 struct xirc_softc *msc = 624 device_private(device_parent(sc->sc_dev)); 625 626 return (xirc_enable(msc, XIRC_MODEM_ENABLED, XIMEDIA_MODEM)); 627 } 628 629 void 630 com_xirc_disable(struct com_softc *sc) 631 { 632 struct xirc_softc *msc = 633 device_private(device_parent(sc->sc_dev)); 634 635 xirc_disable(msc, XIRC_MODEM_ENABLED, XIMEDIA_MODEM); 636 } 637 638 #endif /* NCOM_XIRC > 0 */ 639 640 /****** Here begins the xi attachment code. ******/ 641 642 #if NXI_XIRC > 0 643 int xi_xirc_match(struct device *, struct cfdata *, void *); 644 void xi_xirc_attach(struct device *, struct device *, void *); 645 646 /* No xirc-specific goo in the softc; it's all in the parent. */ 647 CFATTACH_DECL(xi_xirc, sizeof(struct xi_softc), 648 xi_xirc_match, xi_xirc_attach, xi_detach, xi_activate); 649 650 int xi_xirc_enable(struct xi_softc *); 651 void xi_xirc_disable(struct xi_softc *); 652 int xi_xirc_lan_nid_ciscallback(struct pcmcia_tuple *, void *); 653 654 int 655 xi_xirc_match(struct device *parent, struct cfdata *match, 656 void *aux) 657 { 658 extern struct cfdriver xi_cd; 659 const char *name = aux; 660 661 if (strcmp(name, xi_cd.cd_name) == 0) 662 return (1); 663 664 return (0); 665 } 666 667 void 668 xi_xirc_attach(struct device *parent, struct device *self, void *aux) 669 { 670 struct xi_softc *sc = (void *)self; 671 struct xirc_softc *msc = (void *)parent; 672 u_int8_t myla[ETHER_ADDR_LEN]; 673 674 aprint_normal("\n"); 675 676 sc->sc_bst = msc->sc_ethernet_pcioh.iot; 677 sc->sc_bsh = msc->sc_ethernet_pcioh.ioh; 678 679 sc->sc_chipset = msc->sc_chipset; 680 681 sc->sc_enable = xi_xirc_enable; 682 sc->sc_disable = xi_xirc_disable; 683 684 if (!pcmcia_scan_cis(device_parent(&msc->sc_dev), 685 xi_xirc_lan_nid_ciscallback, myla)) { 686 aprint_error_dev(self, "can't find MAC address\n"); 687 return; 688 } 689 690 /* Perform generic initialization. */ 691 xi_attach(sc, myla); 692 } 693 694 int 695 xi_xirc_enable(sc) 696 struct xi_softc *sc; 697 { 698 struct xirc_softc *msc = 699 (struct xirc_softc *)device_parent(&sc->sc_dev); 700 701 return (xirc_enable(msc, XIRC_ETHERNET_ENABLED, XIMEDIA_ETHER)); 702 } 703 704 void 705 xi_xirc_disable(sc) 706 struct xi_softc *sc; 707 { 708 struct xirc_softc *msc = 709 (struct xirc_softc *)device_parent(&sc->sc_dev); 710 711 xirc_disable(msc, XIRC_ETHERNET_ENABLED, XIMEDIA_ETHER); 712 } 713 714 int 715 xi_xirc_lan_nid_ciscallback(tuple, arg) 716 struct pcmcia_tuple *tuple; 717 void *arg; 718 { 719 u_int8_t *myla = arg; 720 int i; 721 722 if (tuple->length < 2) 723 return (0); 724 725 switch (tuple->code) { 726 case PCMCIA_CISTPL_FUNCE: 727 switch (pcmcia_tuple_read_1(tuple, 0)) { 728 case PCMCIA_TPLFE_TYPE_LAN_NID: 729 if (pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN) 730 return (0); 731 for (i = 0; i < ETHER_ADDR_LEN; i++) 732 myla[i] = pcmcia_tuple_read_1(tuple, i + 2); 733 return (1); 734 735 case 0x02: 736 /* 737 * Not sure about this, I don't have a CE2 738 * that puts the ethernet addr here. 739 */ 740 if (pcmcia_tuple_read_1(tuple, 1) != 0x01 || 741 pcmcia_tuple_read_1(tuple, 2) != ETHER_ADDR_LEN) 742 return (0); 743 for (i = 0; i < ETHER_ADDR_LEN; i++) 744 myla[i] = pcmcia_tuple_read_1(tuple, i + 3); 745 return (1); 746 } 747 748 case 0x89: 749 if (pcmcia_tuple_read_1(tuple, 0) != 0x04 || 750 pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN) 751 return (0); 752 for (i = 0; i < ETHER_ADDR_LEN; i++) 753 myla[i] = pcmcia_tuple_read_1(tuple, i + 2); 754 return (1); 755 } 756 757 return (0); 758 } 759 760 #endif /* NXI_XIRC > 0 */ 761