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