1*8bc54e5bSmsaitoh /* $NetBSD: if_ep_pcmcia.c,v 1.64 2016/07/07 06:55:42 msaitoh Exp $ */
24c88513dSthorpej
34c88513dSthorpej /*-
48ccc9500Smycroft * Copyright (c) 1998, 2000, 2004 The NetBSD Foundation, Inc.
54c88513dSthorpej * All rights reserved.
64c88513dSthorpej *
74c88513dSthorpej * This code is derived from software contributed to The NetBSD Foundation
84c88513dSthorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
98ccc9500Smycroft * NASA Ames Research Center, and by Charles M. Hannum.
104c88513dSthorpej *
114c88513dSthorpej * Redistribution and use in source and binary forms, with or without
124c88513dSthorpej * modification, are permitted provided that the following conditions
134c88513dSthorpej * are met:
144c88513dSthorpej * 1. Redistributions of source code must retain the above copyright
154c88513dSthorpej * notice, this list of conditions and the following disclaimer.
164c88513dSthorpej * 2. Redistributions in binary form must reproduce the above copyright
174c88513dSthorpej * notice, this list of conditions and the following disclaimer in the
184c88513dSthorpej * documentation and/or other materials provided with the distribution.
194c88513dSthorpej *
204c88513dSthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
214c88513dSthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
224c88513dSthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
234c88513dSthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
244c88513dSthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
254c88513dSthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
264c88513dSthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
274c88513dSthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
284c88513dSthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
294c88513dSthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
304c88513dSthorpej * POSSIBILITY OF SUCH DAMAGE.
314c88513dSthorpej */
32c66b8643Sthorpej
33c66b8643Sthorpej /*
34c66b8643Sthorpej * Copyright (c) 1997 Marc Horowitz. All rights reserved.
35c66b8643Sthorpej *
36c66b8643Sthorpej * Redistribution and use in source and binary forms, with or without
37c66b8643Sthorpej * modification, are permitted provided that the following conditions
38c66b8643Sthorpej * are met:
39c66b8643Sthorpej * 1. Redistributions of source code must retain the above copyright
40c66b8643Sthorpej * notice, this list of conditions and the following disclaimer.
41c66b8643Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
42c66b8643Sthorpej * notice, this list of conditions and the following disclaimer in the
43c66b8643Sthorpej * documentation and/or other materials provided with the distribution.
44c66b8643Sthorpej * 3. All advertising materials mentioning features or use of this software
45c66b8643Sthorpej * must display the following acknowledgement:
46c66b8643Sthorpej * This product includes software developed by Marc Horowitz.
47c66b8643Sthorpej * 4. The name of the author may not be used to endorse or promote products
48c66b8643Sthorpej * derived from this software without specific prior written permission.
49c66b8643Sthorpej *
50c66b8643Sthorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
51c66b8643Sthorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52c66b8643Sthorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53c66b8643Sthorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
54c66b8643Sthorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
55c66b8643Sthorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56c66b8643Sthorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57c66b8643Sthorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58c66b8643Sthorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
59c66b8643Sthorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60c66b8643Sthorpej */
61c66b8643Sthorpej
62ab5d9d2bSlukem #include <sys/cdefs.h>
63*8bc54e5bSmsaitoh __KERNEL_RCSID(0, "$NetBSD: if_ep_pcmcia.c,v 1.64 2016/07/07 06:55:42 msaitoh Exp $");
64ab5d9d2bSlukem
65c66b8643Sthorpej #include <sys/param.h>
66c66b8643Sthorpej #include <sys/systm.h>
67c66b8643Sthorpej #include <sys/mbuf.h>
68c66b8643Sthorpej #include <sys/socket.h>
69c66b8643Sthorpej #include <sys/ioctl.h>
70c66b8643Sthorpej #include <sys/errno.h>
71c66b8643Sthorpej #include <sys/syslog.h>
72c66b8643Sthorpej #include <sys/select.h>
73c66b8643Sthorpej #include <sys/device.h>
74c66b8643Sthorpej
75c66b8643Sthorpej #include <net/if.h>
76c66b8643Sthorpej #include <net/if_dl.h>
77c66b8643Sthorpej #include <net/if_ether.h>
78c66b8643Sthorpej #include <net/if_media.h>
79c66b8643Sthorpej
80a2a38285Sad #include <sys/cpu.h>
81a2a38285Sad #include <sys/bus.h>
82a2a38285Sad #include <sys/intr.h>
83c66b8643Sthorpej
84b170caf7Sthorpej #include <dev/mii/miivar.h>
85b170caf7Sthorpej
86c66b8643Sthorpej #include <dev/ic/elink3var.h>
87c66b8643Sthorpej #include <dev/ic/elink3reg.h>
88c66b8643Sthorpej
89c66b8643Sthorpej #include <dev/pcmcia/pcmciareg.h>
90c66b8643Sthorpej #include <dev/pcmcia/pcmciavar.h>
91e3bc2915Schristos #include <dev/pcmcia/pcmciadevs.h>
92c66b8643Sthorpej
9391ca465cSchristos int ep_pcmcia_match(device_t, cfdata_t, void *);
9491ca465cSchristos void ep_pcmcia_attach(device_t, device_t, void *);
9591ca465cSchristos int ep_pcmcia_detach(device_t, int);
96c66b8643Sthorpej
9718db93c7Sperry int ep_pcmcia_get_enaddr(struct pcmcia_tuple *, void *);
9818db93c7Sperry int ep_pcmcia_enable(struct ep_softc *);
9918db93c7Sperry void ep_pcmcia_disable(struct ep_softc *);
100c66b8643Sthorpej
10118db93c7Sperry void ep_pcmcia_disable1(struct ep_softc *);
1025c85ae87Sthorpej
103c66b8643Sthorpej struct ep_pcmcia_softc {
104c66b8643Sthorpej struct ep_softc sc_ep; /* real "ep" softc */
105c66b8643Sthorpej
106c66b8643Sthorpej /* PCMCIA-specific goo */
107c66b8643Sthorpej struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */
108c66b8643Sthorpej int sc_io_window; /* our i/o window */
109c66b8643Sthorpej struct pcmcia_function *sc_pf; /* our PCMCIA function */
110c66b8643Sthorpej };
111c66b8643Sthorpej
11291ca465cSchristos CFATTACH_DECL_NEW(ep_pcmcia, sizeof(struct ep_pcmcia_softc),
113b75a007dSthorpej ep_pcmcia_match, ep_pcmcia_attach, ep_pcmcia_detach, ep_activate);
114c66b8643Sthorpej
115942a54e0Scgd const struct ep_pcmcia_product {
116942a54e0Scgd struct pcmcia_product epp_product;
1174c88513dSthorpej u_short epp_chipset; /* 3Com chipset used */
1184c88513dSthorpej int epp_flags; /* initial softc flags */
1194c88513dSthorpej } ep_pcmcia_products[] = {
120adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3C562,
121adbea351Smycroft PCMCIA_CIS_INVALID },
122942a54e0Scgd ELINK_CHIPSET_3C509, 0 },
1234c88513dSthorpej
124adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3C589,
125adbea351Smycroft PCMCIA_CIS_INVALID },
126942a54e0Scgd ELINK_CHIPSET_3C509, 0 },
127b6a56aacSmarc
128adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556,
129adbea351Smycroft PCMCIA_CIS_INVALID },
130942a54e0Scgd ELINK_CHIPSET_3C509, 0 },
13136224362Stron
132adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556INT,
133adbea351Smycroft PCMCIA_CIS_INVALID },
134942a54e0Scgd ELINK_CHIPSET_3C509, 0 },
1356bfd748bSthorpej
136adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3C574,
137adbea351Smycroft PCMCIA_CIS_INVALID },
138942a54e0Scgd ELINK_CHIPSET_ROADRUNNER, ELINK_FLAGS_MII },
139eda20693Sthorpej
140adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CCFEM556BI,
141adbea351Smycroft PCMCIA_CIS_INVALID },
142942a54e0Scgd ELINK_CHIPSET_ROADRUNNER, ELINK_FLAGS_MII },
143942a54e0Scgd
144adbea351Smycroft { { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3C1,
145adbea351Smycroft PCMCIA_CIS_INVALID },
1465402c76dScgd ELINK_CHIPSET_3C509, 0 },
1474c88513dSthorpej };
148adbea351Smycroft const size_t ep_pcmcia_nproducts =
149adbea351Smycroft sizeof(ep_pcmcia_products) / sizeof(ep_pcmcia_products[0]);
1504c88513dSthorpej
151c66b8643Sthorpej int
ep_pcmcia_match(device_t parent,cfdata_t match,void * aux)15291ca465cSchristos ep_pcmcia_match(device_t parent, cfdata_t match, void *aux)
153c66b8643Sthorpej {
154c66b8643Sthorpej struct pcmcia_attach_args *pa = aux;
155c66b8643Sthorpej
156adbea351Smycroft /* This is to differentiate the serial function of some cards. */
157adbea351Smycroft if (pa->pf->function != PCMCIA_FUNCTION_NETWORK)
15891ca465cSchristos return 0;
159c66b8643Sthorpej
160adbea351Smycroft if (pcmcia_product_lookup(pa, ep_pcmcia_products, ep_pcmcia_nproducts,
161adbea351Smycroft sizeof(ep_pcmcia_products[0]), NULL))
16291ca465cSchristos return 1;
16391ca465cSchristos return 0;
164c66b8643Sthorpej }
165c66b8643Sthorpej
166c66b8643Sthorpej int
ep_pcmcia_enable(struct ep_softc * sc)16791ca465cSchristos ep_pcmcia_enable(struct ep_softc *sc)
168c66b8643Sthorpej {
169c66b8643Sthorpej struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *) sc;
170b01ada14Smarc struct pcmcia_function *pf = psc->sc_pf;
171c7573d51Senami int error;
172c66b8643Sthorpej
173c66b8643Sthorpej /* establish the interrupt. */
174b01ada14Smarc sc->sc_ih = pcmcia_intr_establish(pf, IPL_NET, epintr, sc);
17570ca4b2fSmycroft if (!sc->sc_ih)
17691ca465cSchristos return EIO;
177c66b8643Sthorpej
17870ca4b2fSmycroft error = pcmcia_function_enable(pf);
17970ca4b2fSmycroft if (error) {
1802ae40d3eSmycroft pcmcia_intr_disestablish(pf, sc->sc_ih);
181d11fb31eSmycroft sc->sc_ih = 0;
18291ca465cSchristos return error;
1832ae40d3eSmycroft }
1842ae40d3eSmycroft
185b6a56aacSmarc if ((psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3C562) ||
18636224362Stron (psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3CXEM556) ||
18736224362Stron (psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3CXEM556INT)) {
188b01ada14Smarc int reg;
189b01ada14Smarc
190b01ada14Smarc /* turn off the serial-disable bit */
191b01ada14Smarc
192b01ada14Smarc reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION);
193b01ada14Smarc if (reg & 0x08) {
194b01ada14Smarc reg &= ~0x08;
195b01ada14Smarc pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg);
196b01ada14Smarc }
197b01ada14Smarc
198b01ada14Smarc }
199b01ada14Smarc
20091ca465cSchristos return 0;
201c66b8643Sthorpej }
202c66b8643Sthorpej
203c66b8643Sthorpej void
ep_pcmcia_disable(struct ep_softc * sc)20491ca465cSchristos ep_pcmcia_disable(struct ep_softc *sc)
205c66b8643Sthorpej {
206c66b8643Sthorpej struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *) sc;
207c66b8643Sthorpej
2085c85ae87Sthorpej pcmcia_function_disable(psc->sc_pf);
2099092e2c9Smycroft pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
21070ca4b2fSmycroft sc->sc_ih = 0;
2115c85ae87Sthorpej }
2125c85ae87Sthorpej
2135c85ae87Sthorpej void
ep_pcmcia_attach(device_t parent,device_t self,void * aux)21491ca465cSchristos ep_pcmcia_attach(device_t parent, device_t self, void *aux)
215c66b8643Sthorpej {
21691ca465cSchristos struct ep_pcmcia_softc *psc = device_private(self);
217c66b8643Sthorpej struct ep_softc *sc = &psc->sc_ep;
218c66b8643Sthorpej struct pcmcia_attach_args *pa = aux;
219c66b8643Sthorpej struct pcmcia_config_entry *cfe;
220942a54e0Scgd const struct ep_pcmcia_product *epp;
221c66b8643Sthorpej u_int8_t myla[ETHER_ADDR_LEN];
2226bfd748bSthorpej u_int8_t *enaddr = NULL;
2234c88513dSthorpej int i;
22470ca4b2fSmycroft int error;
225c66b8643Sthorpej
22691ca465cSchristos sc->sc_dev = self;
227c66b8643Sthorpej psc->sc_pf = pa->pf;
228c66b8643Sthorpej
2292ae40d3eSmycroft SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) {
2302ae40d3eSmycroft if (cfe->num_memspace != 0)
2312ae40d3eSmycroft continue;
2322ae40d3eSmycroft if (cfe->num_iospace != 1)
2332ae40d3eSmycroft continue;
234c66b8643Sthorpej
235c66b8643Sthorpej if (pa->product == PCMCIA_PRODUCT_3COM_3C562) {
236441bea91Schristos /*
237441bea91Schristos * the 3c562 can only use 0x??00-0x??7f
238441bea91Schristos * according to the Linux driver
239441bea91Schristos */
240071d0cb3Schristos
241071d0cb3Schristos /*
242071d0cb3Schristos * 3c562 i/o may decodes address line not only A0-3
243071d0cb3Schristos * but also A7. Anyway, we must sweep at most
244071d0cb3Schristos * [0x0000, 0x0100). The address higher is given by a
245071d0cb3Schristos * pcmcia bridge. But pcmcia bus-space allocation
246071d0cb3Schristos * function implies cards will decode 10-bit address
247071d0cb3Schristos * line. So we must search [0x0000, 0x0400).
248071d0cb3Schristos *
249071d0cb3Schristos * XXX: We must not check the bunch of I/O space range
250071d0cb3Schristos * [0x400*n, 0x300 + 0x400*n) because they are
251071d0cb3Schristos * reserved for legacy ISA devices and their alias
252071d0cb3Schristos * images on PC/AT architecture.
253071d0cb3Schristos */
254071d0cb3Schristos for (i = 0x0300; i < 0x0380; i += 0x10) {
2552ae40d3eSmycroft if (pcmcia_io_alloc(pa->pf, i,
2562ae40d3eSmycroft cfe->iospace[0].length,
2572ae40d3eSmycroft cfe->iospace[0].length,
2582ae40d3eSmycroft &psc->sc_pcioh) == 0)
259c66b8643Sthorpej break;
260c66b8643Sthorpej }
2612ae40d3eSmycroft if (i != 0x0380)
2622ae40d3eSmycroft break;
263c66b8643Sthorpej } else {
2642ae40d3eSmycroft if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
2652ae40d3eSmycroft cfe->iospace[0].length, cfe->iospace[0].length,
2662ae40d3eSmycroft &psc->sc_pcioh) == 0)
2672ae40d3eSmycroft break;
2682ae40d3eSmycroft }
2692ae40d3eSmycroft }
2702ae40d3eSmycroft if (!cfe) {
271bebbf57bScegger aprint_error_dev(self, "failed to allocate I/O space\n");
272c7573d51Senami goto ioalloc_failed;
273c7573d51Senami }
274c66b8643Sthorpej
275c66b8643Sthorpej sc->sc_iot = psc->sc_pcioh.iot;
276c66b8643Sthorpej sc->sc_ioh = psc->sc_pcioh.ioh;
277c66b8643Sthorpej
2782ae40d3eSmycroft /* Enable the card. */
2792ae40d3eSmycroft pcmcia_function_init(pa->pf, cfe);
2802ae40d3eSmycroft
281c66b8643Sthorpej if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
282c8180f49Smycroft PCMCIA_WIDTH_AUTO : PCMCIA_WIDTH_IO8), &psc->sc_pcioh,
283ebed70c6Smycroft &psc->sc_io_window)) {
284bebbf57bScegger aprint_error_dev(self, "can't map i/o space\n");
285c7573d51Senami goto iomap_failed;
286c66b8643Sthorpej }
2876bfd748bSthorpej
28870ca4b2fSmycroft error = ep_pcmcia_enable(sc);
28970ca4b2fSmycroft if (error)
2902ae40d3eSmycroft goto enable_failed;
2912ae40d3eSmycroft sc->enabled = 1;
2922ae40d3eSmycroft
2936bfd748bSthorpej switch (pa->product) {
2946bfd748bSthorpej case PCMCIA_PRODUCT_3COM_3C562:
295441bea91Schristos /*
296441bea91Schristos * 3c562a-c use this; 3c562d does it in the regular way.
297441bea91Schristos * we might want to check the revision and produce a warning
298441bea91Schristos * in the future.
299441bea91Schristos */
3006bfd748bSthorpej /* FALLTHROUGH */
3016bfd748bSthorpej case PCMCIA_PRODUCT_3COM_3C574:
302eda20693Sthorpej case PCMCIA_PRODUCT_3COM_3CCFEM556BI:
3036bfd748bSthorpej /*
3046bfd748bSthorpej * Apparently, some 3c574s do it this way, as well.
3056bfd748bSthorpej */
3066bfd748bSthorpej if (pcmcia_scan_cis(parent, ep_pcmcia_get_enaddr, myla))
307c66b8643Sthorpej enaddr = myla;
3086bfd748bSthorpej break;
309c66b8643Sthorpej }
310c66b8643Sthorpej
311*8bc54e5bSmsaitoh epp = pcmcia_product_lookup(pa, ep_pcmcia_products,
312*8bc54e5bSmsaitoh ep_pcmcia_nproducts, sizeof(ep_pcmcia_products[0]), NULL);
313adbea351Smycroft if (!epp)
3144c88513dSthorpej panic("ep_pcmcia_attach: impossible");
315c66b8643Sthorpej
316c9ee8bf3Sthorpej sc->bustype = ELINK_BUS_PCMCIA;
317c9ee8bf3Sthorpej sc->ep_flags = epp->epp_flags;
318c9ee8bf3Sthorpej
319c66b8643Sthorpej sc->enable = ep_pcmcia_enable;
320c66b8643Sthorpej sc->disable = ep_pcmcia_disable;
321c66b8643Sthorpej
322285bec82Smycroft if (epconfig(sc, epp->epp_chipset, enaddr))
323bebbf57bScegger aprint_error_dev(self, "couldn't configure controller\n");
324c66b8643Sthorpej
325c66b8643Sthorpej sc->enabled = 0;
3262ae40d3eSmycroft ep_pcmcia_disable(sc);
327c7573d51Senami return;
328c7573d51Senami
329c7573d51Senami enable_failed:
3302ae40d3eSmycroft pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
3312ae40d3eSmycroft iomap_failed:
3322ae40d3eSmycroft pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
3332ae40d3eSmycroft ioalloc_failed:
334c7573d51Senami psc->sc_io_window = -1;
335c66b8643Sthorpej }
336c66b8643Sthorpej
337c66b8643Sthorpej int
ep_pcmcia_detach(device_t self,int flags)33891ca465cSchristos ep_pcmcia_detach(device_t self, int flags)
339d0889022Sthorpej {
34091ca465cSchristos struct ep_pcmcia_softc *psc = device_private(self);
341ea45df4dSaugustss int rv;
342ea45df4dSaugustss
343c7573d51Senami if (psc->sc_io_window == -1)
344c7573d51Senami /* Nothing to detach. */
34591ca465cSchristos return 0;
346c7573d51Senami
347ea45df4dSaugustss rv = ep_detach(self, flags);
348c7573d51Senami if (rv != 0)
34991ca465cSchristos return rv;
350d0889022Sthorpej
351257d3e31Sthorpej /* Unmap our i/o window. */
352257d3e31Sthorpej pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
353257d3e31Sthorpej
354257d3e31Sthorpej /* Free our i/o space. */
355257d3e31Sthorpej pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
356257d3e31Sthorpej
35791ca465cSchristos return 0;
358d0889022Sthorpej }
359d0889022Sthorpej
360d0889022Sthorpej int
ep_pcmcia_get_enaddr(struct pcmcia_tuple * tuple,void * arg)36191ca465cSchristos ep_pcmcia_get_enaddr(struct pcmcia_tuple *tuple, void *arg)
362c66b8643Sthorpej {
363c66b8643Sthorpej u_int8_t *myla = arg;
364c66b8643Sthorpej int i;
365c66b8643Sthorpej
366441bea91Schristos /* this is 3c562a-c magic */
367c66b8643Sthorpej if (tuple->code == 0x88) {
368c66b8643Sthorpej if (tuple->length < ETHER_ADDR_LEN)
36991ca465cSchristos return 0;
370c66b8643Sthorpej
371c66b8643Sthorpej for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
372c66b8643Sthorpej myla[i] = pcmcia_tuple_read_1(tuple, i + 1);
373c66b8643Sthorpej myla[i + 1] = pcmcia_tuple_read_1(tuple, i);
374c66b8643Sthorpej }
375c66b8643Sthorpej
37691ca465cSchristos return 1;
377c66b8643Sthorpej }
37891ca465cSchristos return 0;
379c66b8643Sthorpej }
380