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