xref: /netbsd-src/sys/dev/pcmcia/xirc.c (revision abb0f93cd77b67f080613360c65701f85e5f5cfe)
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