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