Line data Source code
1 : /* $OpenBSD: if_xe.c,v 1.59 2017/01/22 10:17:39 dlg Exp $ */
2 :
3 : /*
4 : * Copyright (c) 1999 Niklas Hallqvist, Brandon Creighton, Job de Haas
5 : * All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : * 3. All advertising materials mentioning features or use of this software
16 : * must display the following acknowledgement:
17 : * This product includes software developed by Niklas Hallqvist,
18 : * C Stone and Job de Haas.
19 : * 4. The name of the author may not be used to endorse or promote products
20 : * derived from this software without specific prior written permission
21 : *
22 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 : */
33 :
34 : /*
35 : * A driver for Xircom ethernet PC-cards.
36 : *
37 : * The driver has been inspired by the xirc2ps_cs.c driver found in Linux'
38 : * PCMCIA package written by Werner Koch <werner.koch@guug.de>:
39 : * [xirc2ps_cs.c wk 14.04.97] (1.31 1998/12/09 19:32:55)
40 : * I will note that no code was used verbatim from that driver as it is under
41 : * the much too strong GNU General Public License, it was only used as a
42 : * "specification" of sorts.
43 : * Other inspirations have been if_fxp.c, if_ep_pcmcia.c and elink3.c as
44 : * they were found in OpenBSD 2.4.
45 : */
46 :
47 : #include "bpfilter.h"
48 :
49 : #include <sys/param.h>
50 : #include <sys/systm.h>
51 : #include <sys/device.h>
52 : #include <sys/ioctl.h>
53 : #include <sys/mbuf.h>
54 : #include <sys/malloc.h>
55 : #include <sys/kernel.h>
56 : #include <sys/socket.h>
57 : #include <sys/syslog.h>
58 :
59 : #include <net/if.h>
60 : #include <net/if_media.h>
61 :
62 : #include <netinet/in.h>
63 : #include <netinet/if_ether.h>
64 :
65 : #if NBPFILTER > 0
66 : #include <net/bpf.h>
67 : #endif
68 :
69 : /*
70 : * Maximum number of bytes to read per interrupt. Linux recommends
71 : * somewhere between 2000-22000.
72 : * XXX This is currently a hard maximum.
73 : */
74 : #define MAX_BYTES_INTR 12000
75 :
76 : #include <dev/mii/miivar.h>
77 :
78 : #include <dev/pcmcia/pcmciareg.h>
79 : #include <dev/pcmcia/pcmciavar.h>
80 : #include <dev/pcmcia/pcmciadevs.h>
81 : #include <dev/pcmcia/if_xereg.h>
82 :
83 : #ifdef __GNUC__
84 : #define INLINE __inline
85 : #else
86 : #define INLINE
87 : #endif /* __GNUC__ */
88 :
89 : #ifdef XEDEBUG
90 :
91 : #define XED_CONFIG 0x1
92 : #define XED_MII 0x2
93 : #define XED_INTR 0x4
94 : #define XED_FIFO 0x8
95 :
96 : #ifndef XEDEBUG_DEF
97 : #define XEDEBUG_DEF (XED_CONFIG|XED_INTR)
98 : #endif /* XEDEBUG_DEF */
99 :
100 : int xedebug = XEDEBUG_DEF;
101 :
102 : #define DPRINTF(cat, x) if (xedebug & (cat)) printf x
103 :
104 : #else /* XEDEBUG */
105 : #define DPRINTF(cat, x) (void)0
106 : #endif /* XEDEBUG */
107 :
108 : int xe_pcmcia_match(struct device *, void *, void *);
109 : void xe_pcmcia_attach(struct device *, struct device *, void *);
110 : int xe_pcmcia_detach(struct device *, int);
111 : int xe_pcmcia_activate(struct device *, int);
112 :
113 : /*
114 : * In case this chipset ever turns up out of pcmcia attachments (very
115 : * unlikely) do the driver splitup.
116 : */
117 : struct xe_softc {
118 : struct device sc_dev; /* Generic device info */
119 : u_int32_t sc_flags; /* Misc. flags */
120 : void *sc_ih; /* Interrupt handler */
121 : struct arpcom sc_arpcom; /* Ethernet common part */
122 : struct ifmedia sc_media; /* Media control */
123 : struct mii_data sc_mii; /* MII media information */
124 : int sc_all_mcasts; /* Receive all multicasts */
125 : bus_space_tag_t sc_bst; /* Bus cookie */
126 : bus_space_handle_t sc_bsh; /* Bus I/O handle */
127 : bus_size_t sc_offset; /* Offset of registers */
128 : u_int8_t sc_rev; /* Chip revision */
129 : };
130 :
131 : #define XEF_MOHAWK 0x001
132 : #define XEF_DINGO 0x002
133 : #define XEF_MODEM 0x004
134 : #define XEF_UNSUPPORTED 0x008
135 : #define XEF_CE 0x010
136 : #define XEF_CE2 0x020
137 : #define XEF_CE3 0x040
138 : #define XEF_CE33 0x080
139 : #define XEF_CE56 0x100
140 :
141 : struct xe_pcmcia_softc {
142 : struct xe_softc sc_xe; /* Generic device info */
143 : struct pcmcia_mem_handle sc_pcmh; /* PCMCIA memspace info */
144 : int sc_mem_window; /* mem window */
145 : struct pcmcia_io_handle sc_pcioh; /* iospace info */
146 : int sc_io_window; /* io window info */
147 : struct pcmcia_function *sc_pf; /* PCMCIA function */
148 : };
149 :
150 : /* Autoconfig definition of driver back-end */
151 : struct cfdriver xe_cd = {
152 : NULL, "xe", DV_IFNET
153 : };
154 :
155 : struct cfattach xe_pcmcia_ca = {
156 : sizeof (struct xe_pcmcia_softc), xe_pcmcia_match, xe_pcmcia_attach,
157 : xe_pcmcia_detach, xe_pcmcia_activate
158 : };
159 :
160 : void xe_cycle_power(struct xe_softc *);
161 : void xe_full_reset(struct xe_softc *);
162 : void xe_init(struct xe_softc *);
163 : int xe_intr(void *);
164 : int xe_ioctl(struct ifnet *, u_long, caddr_t);
165 : int xe_mdi_read(struct device *, int, int);
166 : void xe_mdi_write(struct device *, int, int, int);
167 : int xe_mediachange(struct ifnet *);
168 : void xe_mediastatus(struct ifnet *, struct ifmediareq *);
169 : int xe_pcmcia_funce_enaddr(struct device *, u_int8_t *);
170 : u_int32_t xe_pcmcia_interpret_manfid(struct device *);
171 : int xe_pcmcia_lan_nid_ciscallback(struct pcmcia_tuple *, void *);
172 : int xe_pcmcia_manfid_ciscallback(struct pcmcia_tuple *, void *);
173 : u_int16_t xe_get(struct xe_softc *);
174 : void xe_reset(struct xe_softc *);
175 : void xe_set_address(struct xe_softc *);
176 : void xe_start(struct ifnet *);
177 : void xe_statchg(struct device *);
178 : void xe_stop(struct xe_softc *);
179 : void xe_watchdog(struct ifnet *);
180 : #ifdef XEDEBUG
181 : void xe_reg_dump(struct xe_softc *);
182 : #endif /* XEDEBUG */
183 :
184 : int
185 0 : xe_pcmcia_match(parent, match, aux)
186 : struct device *parent;
187 : void *match, *aux;
188 : {
189 0 : struct pcmcia_attach_args *pa = aux;
190 :
191 0 : if (pa->pf->function != PCMCIA_FUNCTION_NETWORK)
192 0 : return (0);
193 :
194 0 : switch (pa->manufacturer) {
195 : case PCMCIA_VENDOR_COMPAQ:
196 : case PCMCIA_VENDOR_COMPAQ2:
197 0 : return (0);
198 :
199 : case PCMCIA_VENDOR_INTEL:
200 : case PCMCIA_VENDOR_XIRCOM:
201 : /* XXX Per-productid checking here. */
202 0 : return (1);
203 :
204 : default:
205 0 : return (0);
206 : }
207 0 : }
208 :
209 : void
210 0 : xe_pcmcia_attach(parent, self, aux)
211 : struct device *parent, *self;
212 : void *aux;
213 : {
214 0 : struct xe_pcmcia_softc *psc = (struct xe_pcmcia_softc *)self;
215 0 : struct xe_softc *sc = &psc->sc_xe;
216 0 : struct pcmcia_attach_args *pa = aux;
217 0 : struct pcmcia_function *pf = pa->pf;
218 : struct pcmcia_config_entry *cfe = NULL;
219 : struct ifnet *ifp;
220 0 : u_int8_t myla[ETHER_ADDR_LEN], *enaddr = NULL;
221 : int state = 0;
222 0 : struct pcmcia_mem_handle pcmh;
223 0 : int ccr_window;
224 0 : bus_size_t ccr_offset;
225 : const char *intrstr;
226 :
227 0 : psc->sc_pf = pf;
228 :
229 : #if 0
230 : /* Figure out what card we are. */
231 : sc->sc_flags = xe_pcmcia_interpret_manfid(parent);
232 : #endif
233 0 : if (sc->sc_flags & XEF_UNSUPPORTED) {
234 0 : printf(": card unsupported\n");
235 0 : goto bad;
236 : }
237 :
238 : /* Tell the pcmcia framework where the CCR is. */
239 0 : pf->ccr_base = 0x800;
240 0 : pf->ccr_mask = 0x67;
241 :
242 : /* Fake a cfe. */
243 0 : SIMPLEQ_FIRST(&pa->pf->cfe_head) = cfe = (struct pcmcia_config_entry *)
244 0 : malloc(sizeof *cfe, M_DEVBUF, M_NOWAIT | M_ZERO);
245 0 : if (!cfe) {
246 0 : printf(": function enable failed\n");
247 0 : return;
248 : }
249 :
250 : /*
251 : * XXX Use preprocessor symbols instead.
252 : * Enable ethernet & its interrupts, wiring them to -INT
253 : * No I/O base.
254 : */
255 0 : cfe->number = 0x5;
256 0 : cfe->flags = 0; /* XXX Check! */
257 0 : cfe->iftype = PCMCIA_IFTYPE_IO;
258 0 : cfe->num_iospace = 0;
259 0 : cfe->num_memspace = 0;
260 0 : cfe->irqmask = 0x8eb0;
261 :
262 : /* Enable the card. */
263 0 : pcmcia_function_init(pa->pf, cfe);
264 0 : if (pcmcia_function_enable(pa->pf)) {
265 0 : printf(": function enable failed\n");
266 0 : goto bad;
267 : }
268 :
269 : state++;
270 :
271 0 : if (pcmcia_io_alloc(pa->pf, 0, 16, 16, &psc->sc_pcioh)) {
272 0 : printf(": io allocation failed\n");
273 0 : goto bad;
274 : }
275 :
276 : state++;
277 :
278 0 : if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO16, 0, 16, &psc->sc_pcioh,
279 0 : &psc->sc_io_window)) {
280 0 : printf(": can't map io space\n");
281 0 : goto bad;
282 : }
283 0 : sc->sc_bst = psc->sc_pcioh.iot;
284 0 : sc->sc_bsh = psc->sc_pcioh.ioh;
285 0 : sc->sc_offset = 0;
286 :
287 0 : printf(" port 0x%lx/%d", psc->sc_pcioh.addr, 16);
288 :
289 : #if 0
290 : if (pcmcia_mem_alloc(pf, 16, &psc->sc_pcmh)) {
291 : printf(": pcmcia memory allocation failed\n");
292 : goto bad;
293 : }
294 : state++;
295 :
296 : if (pcmcia_mem_map(pf, PCMCIA_MEM_ATTR, 0x300, 16, &psc->sc_pcmh,
297 : &sc->sc_offset, &psc->sc_mem_window)) {
298 : printf(": pcmcia memory mapping failed\n");
299 : goto bad;
300 : }
301 :
302 : sc->sc_bst = psc->sc_pcmh.memt;
303 : sc->sc_bsh = psc->sc_pcmh.memh;
304 : #endif
305 :
306 : /* Figure out what card we are. */
307 0 : sc->sc_flags = xe_pcmcia_interpret_manfid(parent);
308 :
309 : /*
310 : * Configuration as advised by DINGO documentation.
311 : * We only know about this flag after the manfid interpretation.
312 : * Dingo has some extra configuration registers in the CCR space.
313 : */
314 0 : if (sc->sc_flags & XEF_DINGO) {
315 0 : if (pcmcia_mem_alloc(pf, PCMCIA_CCR_SIZE_DINGO, &pcmh)) {
316 : DPRINTF(XED_CONFIG, ("bad mem alloc\n"));
317 : goto bad;
318 : }
319 :
320 0 : if (pcmcia_mem_map(pf, PCMCIA_MEM_ATTR, pf->ccr_base,
321 : PCMCIA_CCR_SIZE_DINGO, &pcmh, &ccr_offset,
322 : &ccr_window)) {
323 : DPRINTF(XED_CONFIG, ("bad mem map\n"));
324 0 : pcmcia_mem_free(pf, &pcmh);
325 0 : goto bad;
326 : }
327 :
328 0 : bus_space_write_1(pcmh.memt, pcmh.memh,
329 : ccr_offset + PCMCIA_CCR_DCOR0, PCMCIA_CCR_DCOR0_SFINT);
330 0 : bus_space_write_1(pcmh.memt, pcmh.memh,
331 : ccr_offset + PCMCIA_CCR_DCOR1,
332 : PCMCIA_CCR_DCOR1_FORCE_LEVIREQ | PCMCIA_CCR_DCOR1_D6);
333 0 : bus_space_write_1(pcmh.memt, pcmh.memh,
334 : ccr_offset + PCMCIA_CCR_DCOR2, 0);
335 0 : bus_space_write_1(pcmh.memt, pcmh.memh,
336 : ccr_offset + PCMCIA_CCR_DCOR3, 0);
337 0 : bus_space_write_1(pcmh.memt, pcmh.memh,
338 : ccr_offset + PCMCIA_CCR_DCOR4, 0);
339 :
340 : /* We don't need them anymore and can free them (I think). */
341 0 : pcmcia_mem_unmap(pf, ccr_window);
342 0 : pcmcia_mem_free(pf, &pcmh);
343 0 : }
344 :
345 : /*
346 : * Try to get the ethernet address from FUNCE/LAN_NID tuple.
347 : */
348 0 : if (xe_pcmcia_funce_enaddr(parent, myla))
349 0 : enaddr = myla;
350 0 : ifp = &sc->sc_arpcom.ac_if;
351 0 : if (enaddr)
352 0 : bcopy(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
353 : else {
354 0 : printf(", unable to get ethernet address\n");
355 0 : goto bad;
356 : }
357 :
358 0 : bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
359 0 : ifp->if_softc = sc;
360 0 : ifp->if_flags =
361 : IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
362 0 : ifp->if_ioctl = xe_ioctl;
363 0 : ifp->if_start = xe_start;
364 0 : ifp->if_watchdog = xe_watchdog;
365 :
366 : /* Establish the interrupt. */
367 0 : sc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, xe_intr, sc,
368 : sc->sc_dev.dv_xname);
369 0 : if (sc->sc_ih == NULL) {
370 0 : printf(", couldn't establish interrupt\n");
371 0 : goto bad;
372 : }
373 0 : intrstr = pcmcia_intr_string(psc->sc_pf, sc->sc_ih);
374 0 : printf("%s%s: address %s\n", *intrstr ? ", " : "", intrstr,
375 0 : ether_sprintf(sc->sc_arpcom.ac_enaddr));
376 :
377 : /* Reset and initialize the card. */
378 0 : xe_full_reset(sc);
379 :
380 : /* Initialize our media structures and probe the phy. */
381 0 : sc->sc_mii.mii_ifp = ifp;
382 0 : sc->sc_mii.mii_readreg = xe_mdi_read;
383 0 : sc->sc_mii.mii_writereg = xe_mdi_write;
384 0 : sc->sc_mii.mii_statchg = xe_statchg;
385 0 : ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, xe_mediachange,
386 : xe_mediastatus);
387 : DPRINTF(XED_MII | XED_CONFIG,
388 : ("bmsr %x\n", xe_mdi_read(&sc->sc_dev, 0, 1)));
389 0 : mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
390 : 0);
391 0 : if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL)
392 0 : ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO, 0,
393 : NULL);
394 0 : ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
395 :
396 : /*
397 : * Attach the interface.
398 : */
399 0 : if_attach(ifp);
400 0 : ether_ifattach(ifp);
401 :
402 : /*
403 : * Reset and initialize the card again for DINGO (as found in Linux
404 : * driver). Without this Dingo will get a watchdog timeout the first
405 : * time. The ugly media tickling seems to be necessary for getting
406 : * autonegotiation to work too.
407 : */
408 0 : if (sc->sc_flags & XEF_DINGO) {
409 0 : xe_full_reset(sc);
410 0 : xe_init(sc);
411 0 : ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
412 0 : ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_NONE);
413 0 : xe_stop(sc);
414 0 : }
415 0 : return;
416 :
417 : bad:
418 0 : if (state > 2)
419 0 : pcmcia_io_unmap(pf, psc->sc_io_window);
420 0 : if (state > 1)
421 0 : pcmcia_io_free(pf, &psc->sc_pcioh);
422 0 : if (state > 0)
423 0 : pcmcia_function_disable(pa->pf);
424 0 : free(cfe, M_DEVBUF, 0);
425 0 : }
426 :
427 : int
428 0 : xe_pcmcia_detach(dev, flags)
429 : struct device *dev;
430 : int flags;
431 : {
432 0 : struct xe_pcmcia_softc *psc = (struct xe_pcmcia_softc *)dev;
433 0 : struct xe_softc *sc = &psc->sc_xe;
434 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
435 : int rv = 0;
436 :
437 0 : mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
438 0 : ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
439 :
440 0 : pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
441 0 : pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
442 :
443 0 : ether_ifdetach(ifp);
444 0 : if_detach(ifp);
445 :
446 0 : return (rv);
447 : }
448 :
449 : int
450 0 : xe_pcmcia_activate(dev, act)
451 : struct device *dev;
452 : int act;
453 : {
454 0 : struct xe_pcmcia_softc *sc = (struct xe_pcmcia_softc *)dev;
455 0 : struct ifnet *ifp = &sc->sc_xe.sc_arpcom.ac_if;
456 :
457 0 : switch (act) {
458 : case DVACT_SUSPEND:
459 0 : if (ifp->if_flags & IFF_RUNNING)
460 0 : xe_stop(&sc->sc_xe);
461 0 : ifp->if_flags &= ~IFF_RUNNING;
462 0 : if (sc->sc_xe.sc_ih)
463 0 : pcmcia_intr_disestablish(sc->sc_pf, sc->sc_xe.sc_ih);
464 0 : sc->sc_xe.sc_ih = NULL;
465 0 : pcmcia_function_disable(sc->sc_pf);
466 0 : break;
467 : case DVACT_RESUME:
468 0 : pcmcia_function_enable(sc->sc_pf);
469 0 : sc->sc_xe.sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
470 0 : xe_intr, sc, sc->sc_xe.sc_dev.dv_xname);
471 : /* XXX this is a ridiculous */
472 0 : xe_reset(&sc->sc_xe);
473 0 : if ((ifp->if_flags & IFF_UP) == 0)
474 0 : xe_stop(&sc->sc_xe);
475 : break;
476 : case DVACT_DEACTIVATE:
477 0 : ifp->if_timer = 0;
478 0 : ifp->if_flags &= ~IFF_RUNNING;
479 0 : if (sc->sc_xe.sc_ih)
480 0 : pcmcia_intr_disestablish(sc->sc_pf, sc->sc_xe.sc_ih);
481 0 : sc->sc_xe.sc_ih = NULL;
482 0 : pcmcia_function_disable(sc->sc_pf);
483 0 : break;
484 : }
485 0 : return (0);
486 : }
487 :
488 : /*
489 : * XXX These two functions might be OK to factor out into pcmcia.c since
490 : * if_sm_pcmcia.c uses similar ones.
491 : */
492 : int
493 0 : xe_pcmcia_funce_enaddr(parent, myla)
494 : struct device *parent;
495 : u_int8_t *myla;
496 : {
497 : /* XXX The Linux driver has more ways to do this in case of failure. */
498 0 : return (pcmcia_scan_cis(parent, xe_pcmcia_lan_nid_ciscallback, myla));
499 : }
500 :
501 : int
502 0 : xe_pcmcia_lan_nid_ciscallback(tuple, arg)
503 : struct pcmcia_tuple *tuple;
504 : void *arg;
505 : {
506 : u_int8_t *myla = arg;
507 : int i;
508 :
509 0 : if (tuple->code == PCMCIA_CISTPL_FUNCE) {
510 0 : if (tuple->length < 2)
511 0 : return (0);
512 :
513 0 : switch (pcmcia_tuple_read_1(tuple, 0)) {
514 : case PCMCIA_TPLFE_TYPE_LAN_NID:
515 0 : if (pcmcia_tuple_read_1(tuple, 1) != ETHER_ADDR_LEN)
516 0 : return (0);
517 : break;
518 :
519 : case 0x02:
520 : /*
521 : * Not sure about this, I don't have a CE2
522 : * that puts the ethernet addr here.
523 : */
524 0 : if (pcmcia_tuple_read_1(tuple, 1) != 13)
525 0 : return (0);
526 : break;
527 :
528 : default:
529 0 : return (0);
530 : }
531 :
532 0 : for (i = 0; i < ETHER_ADDR_LEN; i++)
533 0 : myla[i] = pcmcia_tuple_read_1(tuple, i + 2);
534 0 : return (1);
535 : }
536 :
537 : /* Yet another spot where this might be. */
538 0 : if (tuple->code == 0x89) {
539 0 : pcmcia_tuple_read_1(tuple, 1);
540 0 : for (i = 0; i < ETHER_ADDR_LEN; i++)
541 0 : myla[i] = pcmcia_tuple_read_1(tuple, i + 2);
542 0 : return (1);
543 : }
544 0 : return (0);
545 0 : }
546 :
547 : u_int32_t
548 0 : xe_pcmcia_interpret_manfid (parent)
549 : struct device *parent;
550 : {
551 0 : u_int32_t flags = 0;
552 0 : struct pcmcia_softc *psc = (struct pcmcia_softc *)parent;
553 : char *tptr;
554 :
555 0 : if (!pcmcia_scan_cis(parent, xe_pcmcia_manfid_ciscallback, &flags))
556 0 : return (XEF_UNSUPPORTED);
557 :
558 0 : if (flags & XEF_CE) {
559 0 : tptr = memchr(psc->card.cis1_info[2], 'C',
560 0 : strlen(psc->card.cis1_info[2]));
561 : /* XXX not sure if other CE2s hide "CE2" in different places */
562 0 : if (tptr && *(tptr + 1) == 'E' && *(tptr + 2) == '2') {
563 0 : flags ^= (XEF_CE | XEF_UNSUPPORTED);
564 0 : flags |= XEF_CE2;
565 0 : }
566 : }
567 0 : return (flags);
568 0 : }
569 :
570 : int
571 0 : xe_pcmcia_manfid_ciscallback(tuple, arg)
572 : struct pcmcia_tuple *tuple;
573 : void *arg;
574 : {
575 0 : u_int32_t *flagsp = arg;
576 : u_int8_t media, product;
577 :
578 0 : if (tuple->code == PCMCIA_CISTPL_MANFID) {
579 0 : if (tuple->length < 2)
580 0 : return (0);
581 :
582 0 : media = pcmcia_tuple_read_1(tuple, 3);
583 0 : product = pcmcia_tuple_read_1(tuple, 4);
584 :
585 0 : if (!(product & XEPROD_CREDITCARD) ||
586 0 : !(media & XEMEDIA_ETHER)) {
587 0 : *flagsp |= XEF_UNSUPPORTED;
588 0 : return (1);
589 : }
590 :
591 0 : if (media & XEMEDIA_MODEM)
592 0 : *flagsp |= XEF_MODEM;
593 :
594 0 : switch (product & XEPROD_IDMASK) {
595 : case 1:
596 : /* XXX Can be CE2 too (we double-check later). */
597 0 : *flagsp |= XEF_CE | XEF_UNSUPPORTED;
598 0 : break;
599 : case 2:
600 0 : *flagsp |= XEF_CE2;
601 0 : break;
602 : case 3:
603 0 : if (!(*flagsp & XEF_MODEM))
604 0 : *flagsp |= XEF_MOHAWK;
605 0 : *flagsp |= XEF_CE3;
606 0 : break;
607 : case 4:
608 0 : *flagsp |= XEF_CE33;
609 0 : break;
610 : case 5:
611 0 : *flagsp |= XEF_CE56 | XEF_MOHAWK;
612 0 : break;
613 : case 6:
614 : case 7:
615 0 : *flagsp |= XEF_CE56 | XEF_MOHAWK | XEF_DINGO;
616 0 : break;
617 : default:
618 0 : *flagsp |= XEF_UNSUPPORTED;
619 0 : break;
620 : }
621 :
622 0 : return (1);
623 : }
624 0 : return (0);
625 0 : }
626 :
627 : int
628 0 : xe_intr(arg)
629 : void *arg;
630 : {
631 0 : struct xe_softc *sc = arg;
632 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
633 : u_int8_t esr, rsr, isr, rx_status, savedpage;
634 : u_int16_t tx_status, recvcount = 0, tempint;
635 :
636 0 : ifp->if_timer = 0; /* turn watchdog timer off */
637 :
638 0 : if (sc->sc_flags & XEF_MOHAWK) {
639 : /* Disable interrupt (Linux does it). */
640 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
641 : 0);
642 0 : }
643 :
644 : savedpage =
645 0 : bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + PR);
646 :
647 0 : PAGE(sc, 0);
648 0 : esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + ESR);
649 0 : isr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + ISR0);
650 0 : rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RSR);
651 :
652 : /* Check to see if card has been ejected. */
653 0 : if (isr == 0xff) {
654 0 : printf("%s: interrupt for dead card\n", sc->sc_dev.dv_xname);
655 0 : goto end;
656 : }
657 :
658 0 : PAGE(sc, 40);
659 : rx_status =
660 0 : bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0);
661 : tx_status =
662 0 : bus_space_read_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0);
663 :
664 : /*
665 : * XXX Linux writes to RXST0 and TXST* here. My CE2 works just fine
666 : * without it, and I can't see an obvious reason for it.
667 : */
668 :
669 0 : PAGE(sc, 0);
670 0 : while (esr & FULL_PKT_RCV) {
671 0 : if (!(rsr & RSR_RX_OK))
672 : break;
673 :
674 : /* Compare bytes read this interrupt to hard maximum. */
675 0 : if (recvcount > MAX_BYTES_INTR) {
676 : DPRINTF(XED_INTR,
677 : ("%s: too many bytes this interrupt\n",
678 : sc->sc_dev.dv_xname));
679 0 : ifp->if_iqdrops++;
680 : /* Drop packet. */
681 0 : bus_space_write_2(sc->sc_bst, sc->sc_bsh,
682 : sc->sc_offset + DO0, DO_SKIP_RX_PKT);
683 0 : }
684 0 : tempint = xe_get(sc);
685 0 : recvcount += tempint;
686 0 : esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
687 : sc->sc_offset + ESR);
688 0 : rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
689 : sc->sc_offset + RSR);
690 : }
691 :
692 : /* Packet too long? */
693 0 : if (rsr & RSR_TOO_LONG) {
694 0 : ifp->if_ierrors++;
695 : DPRINTF(XED_INTR,
696 : ("%s: packet too long\n", sc->sc_dev.dv_xname));
697 0 : }
698 :
699 : /* CRC error? */
700 0 : if (rsr & RSR_CRCERR) {
701 0 : ifp->if_ierrors++;
702 : DPRINTF(XED_INTR,
703 : ("%s: CRC error detected\n", sc->sc_dev.dv_xname));
704 0 : }
705 :
706 : /* Alignment error? */
707 0 : if (rsr & RSR_ALIGNERR) {
708 0 : ifp->if_ierrors++;
709 : DPRINTF(XED_INTR,
710 : ("%s: alignment error detected\n", sc->sc_dev.dv_xname));
711 0 : }
712 :
713 : /* Check for rx overrun. */
714 0 : if (rx_status & RX_OVERRUN) {
715 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
716 : CLR_RX_OVERRUN);
717 : DPRINTF(XED_INTR, ("overrun cleared\n"));
718 0 : }
719 :
720 : /* Try to start more packets transmitting. */
721 0 : if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
722 0 : xe_start(ifp);
723 :
724 : /* Detected excessive collisions? */
725 0 : if (tx_status & EXCESSIVE_COLL) {
726 : DPRINTF(XED_INTR,
727 : ("%s: excessive collisions\n", sc->sc_dev.dv_xname));
728 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
729 : RESTART_TX);
730 0 : ifp->if_oerrors++;
731 0 : }
732 :
733 0 : if (tx_status & TX_ABORT)
734 0 : ifp->if_oerrors++;
735 :
736 : end:
737 : /* Reenable interrupts. */
738 0 : PAGE(sc, savedpage);
739 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
740 : ENABLE_INT);
741 :
742 0 : return (1);
743 : }
744 :
745 : u_int16_t
746 0 : xe_get(sc)
747 : struct xe_softc *sc;
748 : {
749 : u_int8_t rsr;
750 0 : struct mbuf *top, **mp, *m;
751 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
752 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
753 : u_int16_t pktlen, len, recvcount = 0;
754 : u_int8_t *data;
755 :
756 0 : PAGE(sc, 0);
757 0 : rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RSR);
758 :
759 : pktlen =
760 0 : bus_space_read_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RBC0) &
761 : RBC_COUNT_MASK;
762 0 : if (pktlen == 0) {
763 : /*
764 : * XXX At least one CE2 sets RBC0 == 0 occasionally, and only
765 : * when MPE is set. It is not known why.
766 : */
767 0 : return (0);
768 : }
769 : recvcount += pktlen;
770 :
771 0 : MGETHDR(m, M_DONTWAIT, MT_DATA);
772 0 : if (m == NULL)
773 0 : return (recvcount);
774 0 : m->m_pkthdr.len = pktlen;
775 : len = MHLEN;
776 0 : top = 0;
777 : mp = ⊤
778 :
779 0 : while (pktlen > 0) {
780 0 : if (top) {
781 0 : MGET(m, M_DONTWAIT, MT_DATA);
782 0 : if (m == NULL) {
783 0 : m_freem(top);
784 0 : return (recvcount);
785 : }
786 : len = MLEN;
787 0 : }
788 0 : if (pktlen >= MINCLSIZE) {
789 0 : MCLGET(m, M_DONTWAIT);
790 0 : if (!(m->m_flags & M_EXT)) {
791 0 : m_freem(m);
792 0 : m_freem(top);
793 0 : return (recvcount);
794 : }
795 : len = MCLBYTES;
796 0 : }
797 0 : if (!top) {
798 0 : caddr_t newdata = (caddr_t)ALIGN(m->m_data +
799 0 : sizeof (struct ether_header)) -
800 : sizeof (struct ether_header);
801 0 : len -= newdata - m->m_data;
802 0 : m->m_data = newdata;
803 0 : }
804 0 : len = min(pktlen, len);
805 :
806 0 : data = mtod(m, u_int8_t *);
807 0 : if (len > 1) {
808 0 : len &= ~1;
809 0 : bus_space_read_raw_multi_2(sc->sc_bst, sc->sc_bsh,
810 : sc->sc_offset + EDP, data, len);
811 0 : } else
812 0 : *data = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
813 : sc->sc_offset + EDP);
814 0 : m->m_len = len;
815 0 : pktlen -= len;
816 0 : *mp = m;
817 0 : mp = &m->m_next;
818 : }
819 :
820 : /* Skip Rx packet. */
821 0 : bus_space_write_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + DO0,
822 : DO_SKIP_RX_PKT);
823 :
824 0 : ml_enqueue(&ml, top);
825 0 : if_input(ifp, &ml);
826 :
827 0 : return (recvcount);
828 0 : }
829 :
830 :
831 : /*
832 : * Serial management for the MII.
833 : * The DELAY's below stem from the fact that the maximum frequency
834 : * acceptable on the MDC pin is 2.5 MHz and fast processors can easily
835 : * go much faster than that.
836 : */
837 :
838 : /* Let the MII serial management be idle for one period. */
839 : static INLINE void xe_mdi_idle(struct xe_softc *);
840 : static INLINE void
841 0 : xe_mdi_idle(sc)
842 : struct xe_softc *sc;
843 : {
844 0 : bus_space_tag_t bst = sc->sc_bst;
845 0 : bus_space_handle_t bsh = sc->sc_bsh;
846 0 : bus_size_t offset = sc->sc_offset;
847 :
848 : /* Drive MDC low... */
849 0 : bus_space_write_1(bst, bsh, offset + GP2, MDC_LOW);
850 0 : DELAY(1);
851 :
852 : /* and high again. */
853 0 : bus_space_write_1(bst, bsh, offset + GP2, MDC_HIGH);
854 0 : DELAY(1);
855 0 : }
856 :
857 : /* Pulse out one bit of data. */
858 : static INLINE void xe_mdi_pulse(struct xe_softc *, int);
859 : static INLINE void
860 0 : xe_mdi_pulse(sc, data)
861 : struct xe_softc *sc;
862 : int data;
863 : {
864 0 : bus_space_tag_t bst = sc->sc_bst;
865 0 : bus_space_handle_t bsh = sc->sc_bsh;
866 0 : bus_size_t offset = sc->sc_offset;
867 0 : u_int8_t bit = data ? MDIO_HIGH : MDIO_LOW;
868 :
869 : /* First latch the data bit MDIO with clock bit MDC low...*/
870 0 : bus_space_write_1(bst, bsh, offset + GP2, bit | MDC_LOW);
871 0 : DELAY(1);
872 :
873 : /* then raise the clock again, preserving the data bit. */
874 0 : bus_space_write_1(bst, bsh, offset + GP2, bit | MDC_HIGH);
875 0 : DELAY(1);
876 0 : }
877 :
878 : /* Probe one bit of data. */
879 : static INLINE int xe_mdi_probe(struct xe_softc *sc);
880 : static INLINE int
881 0 : xe_mdi_probe(sc)
882 : struct xe_softc *sc;
883 : {
884 0 : bus_space_tag_t bst = sc->sc_bst;
885 0 : bus_space_handle_t bsh = sc->sc_bsh;
886 0 : bus_size_t offset = sc->sc_offset;
887 : u_int8_t x;
888 :
889 : /* Pull clock bit MDCK low... */
890 0 : bus_space_write_1(bst, bsh, offset + GP2, MDC_LOW);
891 0 : DELAY(1);
892 :
893 : /* Read data and drive clock high again. */
894 0 : x = bus_space_read_1(bst, bsh, offset + GP2) & MDIO;
895 0 : bus_space_write_1(bst, bsh, offset + GP2, MDC_HIGH);
896 0 : DELAY(1);
897 :
898 0 : return (x);
899 : }
900 :
901 : /* Pulse out a sequence of data bits. */
902 : static INLINE void xe_mdi_pulse_bits(struct xe_softc *, u_int32_t, int);
903 : static INLINE void
904 0 : xe_mdi_pulse_bits(sc, data, len)
905 : struct xe_softc *sc;
906 : u_int32_t data;
907 : int len;
908 : {
909 : u_int32_t mask;
910 :
911 0 : for (mask = 1 << (len - 1); mask; mask >>= 1)
912 0 : xe_mdi_pulse(sc, data & mask);
913 0 : }
914 :
915 : /* Read a PHY register. */
916 : int
917 0 : xe_mdi_read(self, phy, reg)
918 : struct device *self;
919 : int phy;
920 : int reg;
921 : {
922 0 : struct xe_softc *sc = (struct xe_softc *)self;
923 : int i;
924 : u_int32_t mask;
925 : u_int32_t data = 0;
926 :
927 0 : PAGE(sc, 2);
928 0 : for (i = 0; i < 32; i++) /* Synchronize. */
929 0 : xe_mdi_pulse(sc, 1);
930 0 : xe_mdi_pulse_bits(sc, 0x06, 4); /* Start + Read opcode */
931 0 : xe_mdi_pulse_bits(sc, phy, 5); /* PHY address */
932 0 : xe_mdi_pulse_bits(sc, reg, 5); /* PHY register */
933 0 : xe_mdi_idle(sc); /* Turn around. */
934 0 : xe_mdi_probe(sc); /* Drop initial zero bit. */
935 :
936 0 : for (mask = 1 << 15; mask; mask >>= 1)
937 0 : if (xe_mdi_probe(sc))
938 0 : data |= mask;
939 0 : xe_mdi_idle(sc);
940 :
941 : DPRINTF(XED_MII,
942 : ("xe_mdi_read: phy %d reg %d -> %x\n", phy, reg, data));
943 0 : return (data);
944 : }
945 :
946 : /* Write a PHY register. */
947 : void
948 0 : xe_mdi_write(self, phy, reg, value)
949 : struct device *self;
950 : int phy;
951 : int reg;
952 : int value;
953 : {
954 0 : struct xe_softc *sc = (struct xe_softc *)self;
955 : int i;
956 :
957 0 : PAGE(sc, 2);
958 0 : for (i = 0; i < 32; i++) /* Synchronize. */
959 0 : xe_mdi_pulse(sc, 1);
960 0 : xe_mdi_pulse_bits(sc, 0x05, 4); /* Start + Write opcode */
961 0 : xe_mdi_pulse_bits(sc, phy, 5); /* PHY address */
962 0 : xe_mdi_pulse_bits(sc, reg, 5); /* PHY register */
963 0 : xe_mdi_pulse_bits(sc, 0x02, 2); /* Turn around. */
964 0 : xe_mdi_pulse_bits(sc, value, 16); /* Write the data */
965 0 : xe_mdi_idle(sc); /* Idle away. */
966 :
967 : DPRINTF(XED_MII,
968 : ("xe_mdi_write: phy %d reg %d val %x\n", phy, reg, value));
969 0 : }
970 :
971 : void
972 0 : xe_statchg(self)
973 : struct device *self;
974 : {
975 0 : }
976 :
977 : /*
978 : * Change media according to request.
979 : */
980 : int
981 0 : xe_mediachange(ifp)
982 : struct ifnet *ifp;
983 : {
984 0 : if (ifp->if_flags & IFF_UP)
985 0 : xe_init(ifp->if_softc);
986 0 : return (0);
987 : }
988 :
989 : /*
990 : * Notify the world which media we're using.
991 : */
992 : void
993 0 : xe_mediastatus(ifp, ifmr)
994 : struct ifnet *ifp;
995 : struct ifmediareq *ifmr;
996 : {
997 0 : struct xe_softc *sc = ifp->if_softc;
998 :
999 0 : mii_pollstat(&sc->sc_mii);
1000 0 : ifmr->ifm_status = sc->sc_mii.mii_media_status;
1001 0 : ifmr->ifm_active = sc->sc_mii.mii_media_active;
1002 0 : }
1003 :
1004 : void
1005 0 : xe_reset(sc)
1006 : struct xe_softc *sc;
1007 : {
1008 : int s;
1009 :
1010 0 : s = splnet();
1011 0 : xe_stop(sc);
1012 0 : xe_full_reset(sc);
1013 0 : xe_init(sc);
1014 0 : splx(s);
1015 0 : }
1016 :
1017 : void
1018 0 : xe_watchdog(ifp)
1019 : struct ifnet *ifp;
1020 : {
1021 0 : struct xe_softc *sc = ifp->if_softc;
1022 :
1023 0 : log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
1024 0 : ++sc->sc_arpcom.ac_if.if_oerrors;
1025 :
1026 0 : xe_reset(sc);
1027 0 : }
1028 :
1029 : void
1030 0 : xe_stop(sc)
1031 : register struct xe_softc *sc;
1032 : {
1033 : /* Disable interrupts. */
1034 0 : PAGE(sc, 0);
1035 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR, 0);
1036 :
1037 0 : PAGE(sc, 1);
1038 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + IMR0, 0);
1039 :
1040 : /* Power down, wait. */
1041 0 : PAGE(sc, 4);
1042 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + GP1, 0);
1043 0 : DELAY(40000);
1044 :
1045 : /* Cancel watchdog timer. */
1046 0 : sc->sc_arpcom.ac_if.if_timer = 0;
1047 0 : }
1048 :
1049 : void
1050 0 : xe_init(sc)
1051 : struct xe_softc *sc;
1052 : {
1053 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1054 : int s;
1055 :
1056 : DPRINTF(XED_CONFIG, ("xe_init\n"));
1057 :
1058 0 : s = splnet();
1059 :
1060 0 : xe_set_address(sc);
1061 :
1062 : /* Set current media. */
1063 0 : mii_mediachg(&sc->sc_mii);
1064 :
1065 0 : ifp->if_flags |= IFF_RUNNING;
1066 0 : ifq_clr_oactive(&ifp->if_snd);
1067 0 : splx(s);
1068 0 : }
1069 :
1070 : /*
1071 : * Start outputting on the interface.
1072 : * Always called as splnet().
1073 : */
1074 : void
1075 0 : xe_start(ifp)
1076 : struct ifnet *ifp;
1077 : {
1078 0 : struct xe_softc *sc = ifp->if_softc;
1079 0 : bus_space_tag_t bst = sc->sc_bst;
1080 0 : bus_space_handle_t bsh = sc->sc_bsh;
1081 0 : bus_size_t offset = sc->sc_offset;
1082 : unsigned int s, len, pad = 0;
1083 : struct mbuf *m0, *m;
1084 : u_int16_t space;
1085 :
1086 : /* Don't transmit if interface is busy or not running. */
1087 0 : if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
1088 0 : return;
1089 :
1090 : /* Peek at the next packet. */
1091 0 : m0 = ifq_deq_begin(&ifp->if_snd);
1092 0 : if (m0 == NULL)
1093 0 : return;
1094 :
1095 : /* We need to use m->m_pkthdr.len, so require the header. */
1096 0 : if (!(m0->m_flags & M_PKTHDR))
1097 0 : panic("xe_start: no header mbuf");
1098 :
1099 0 : len = m0->m_pkthdr.len;
1100 :
1101 : /* Pad to ETHER_MIN_LEN - ETHER_CRC_LEN. */
1102 0 : if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
1103 0 : pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
1104 :
1105 0 : PAGE(sc, 0);
1106 0 : space = bus_space_read_2(bst, bsh, offset + TSO0) & 0x7fff;
1107 0 : if (len + pad + 2 > space) {
1108 0 : ifq_deq_rollback(&ifp->if_snd, m0);
1109 : DPRINTF(XED_FIFO,
1110 : ("%s: not enough space in output FIFO (%d > %d)\n",
1111 : sc->sc_dev.dv_xname, len + pad + 2, space));
1112 0 : return;
1113 : }
1114 :
1115 0 : ifq_deq_commit(&ifp->if_snd, m0);
1116 :
1117 : #if NBPFILTER > 0
1118 0 : if (ifp->if_bpf)
1119 0 : bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1120 : #endif
1121 :
1122 : /*
1123 : * Do the output at splhigh() so that an interrupt from another device
1124 : * won't cause a FIFO underrun.
1125 : */
1126 0 : s = splhigh();
1127 :
1128 0 : bus_space_write_2(bst, bsh, offset + TSO2, (u_int16_t)len + pad + 2);
1129 0 : bus_space_write_2(bst, bsh, offset + EDP, (u_int16_t)len + pad);
1130 0 : for (m = m0; m; ) {
1131 0 : if (m->m_len > 1)
1132 0 : bus_space_write_raw_multi_2(bst, bsh, offset + EDP,
1133 : mtod(m, u_int8_t *), m->m_len & ~1);
1134 0 : if (m->m_len & 1)
1135 0 : bus_space_write_1(bst, bsh, offset + EDP,
1136 : *(mtod(m, u_int8_t *) + m->m_len - 1));
1137 0 : m0 = m_free(m);
1138 : m = m0;
1139 : }
1140 0 : if (sc->sc_flags & XEF_MOHAWK)
1141 0 : bus_space_write_1(bst, bsh, offset + CR, TX_PKT | ENABLE_INT);
1142 : else {
1143 0 : for (; pad > 1; pad -= 2)
1144 0 : bus_space_write_2(bst, bsh, offset + EDP, 0);
1145 0 : if (pad == 1)
1146 0 : bus_space_write_1(bst, bsh, offset + EDP, 0);
1147 : }
1148 :
1149 0 : splx(s);
1150 :
1151 0 : ifp->if_timer = 5;
1152 0 : }
1153 :
1154 : int
1155 0 : xe_ioctl(ifp, command, data)
1156 : struct ifnet *ifp;
1157 : u_long command;
1158 : caddr_t data;
1159 : {
1160 0 : struct xe_softc *sc = ifp->if_softc;
1161 0 : struct ifreq *ifr = (struct ifreq *)data;
1162 : int s, error = 0;
1163 :
1164 0 : s = splnet();
1165 :
1166 0 : switch (command) {
1167 : case SIOCSIFADDR:
1168 0 : ifp->if_flags |= IFF_UP;
1169 0 : xe_init(sc);
1170 0 : break;
1171 :
1172 : case SIOCSIFFLAGS:
1173 0 : sc->sc_all_mcasts = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;
1174 :
1175 0 : PAGE(sc, 0x42);
1176 0 : if ((ifp->if_flags & IFF_PROMISC) ||
1177 0 : (ifp->if_flags & IFF_ALLMULTI))
1178 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh,
1179 : sc->sc_offset + SWC1,
1180 : SWC1_PROMISC | SWC1_MCAST_PROM);
1181 : else
1182 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh,
1183 : sc->sc_offset + SWC1, 0);
1184 :
1185 : /*
1186 : * If interface is marked up and not running, then start it.
1187 : * If it is marked down and running, stop it.
1188 : * XXX If it's up then re-initialize it. This is so flags
1189 : * such as IFF_PROMISC are handled.
1190 : */
1191 0 : if (ifp->if_flags & IFF_UP) {
1192 0 : xe_init(sc);
1193 0 : } else {
1194 0 : if (ifp->if_flags & IFF_RUNNING)
1195 0 : xe_stop(sc);
1196 : }
1197 : break;
1198 :
1199 : case SIOCADDMULTI:
1200 : case SIOCDELMULTI:
1201 0 : sc->sc_all_mcasts = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;
1202 0 : error = (command == SIOCADDMULTI) ?
1203 0 : ether_addmulti(ifr, &sc->sc_arpcom) :
1204 0 : ether_delmulti(ifr, &sc->sc_arpcom);
1205 :
1206 0 : if (error == ENETRESET) {
1207 : /*
1208 : * Multicast list has changed; set the hardware
1209 : * filter accordingly.
1210 : */
1211 0 : if (!sc->sc_all_mcasts &&
1212 0 : !(ifp->if_flags & IFF_PROMISC))
1213 0 : xe_set_address(sc);
1214 :
1215 : /*
1216 : * xe_set_address() can turn on all_mcasts if we run
1217 : * out of space, so check it again rather than else {}.
1218 : */
1219 0 : if (sc->sc_all_mcasts)
1220 0 : xe_init(sc);
1221 : error = 0;
1222 0 : }
1223 : break;
1224 :
1225 : case SIOCSIFMEDIA:
1226 : case SIOCGIFMEDIA:
1227 : error =
1228 0 : ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
1229 0 : break;
1230 :
1231 : default:
1232 : error = ENOTTY;
1233 0 : }
1234 :
1235 0 : splx(s);
1236 0 : return (error);
1237 : }
1238 :
1239 : void
1240 0 : xe_set_address(sc)
1241 : struct xe_softc *sc;
1242 : {
1243 0 : bus_space_tag_t bst = sc->sc_bst;
1244 0 : bus_space_handle_t bsh = sc->sc_bsh;
1245 0 : bus_size_t offset = sc->sc_offset;
1246 0 : struct arpcom *arp = &sc->sc_arpcom;
1247 : struct ether_multi *enm;
1248 : struct ether_multistep step;
1249 0 : struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1250 : int i, page, pos, num;
1251 :
1252 0 : PAGE(sc, 0x50);
1253 0 : for (i = 0; i < 6; i++) {
1254 0 : bus_space_write_1(bst, bsh, offset + IA + i,
1255 : sc->sc_arpcom.ac_enaddr[(sc->sc_flags & XEF_MOHAWK) ?
1256 : 5 - i : i]);
1257 : }
1258 :
1259 0 : if (arp->ac_multirangecnt > 0) {
1260 0 : ifp->if_flags |= IFF_ALLMULTI;
1261 0 : sc->sc_all_mcasts=1;
1262 0 : } else if (arp->ac_multicnt > 0) {
1263 0 : if (arp->ac_multicnt > 9) {
1264 0 : PAGE(sc, 0x42);
1265 0 : bus_space_write_1(sc->sc_bst, sc->sc_bsh,
1266 : sc->sc_offset + SWC1,
1267 : SWC1_PROMISC | SWC1_MCAST_PROM);
1268 0 : return;
1269 : }
1270 :
1271 0 : ETHER_FIRST_MULTI(step, arp, enm);
1272 :
1273 : pos = IA + 6;
1274 0 : for (page = 0x50, num = arp->ac_multicnt; num > 0 && enm;
1275 0 : num--) {
1276 0 : for (i = 0; i < 6; i++) {
1277 0 : bus_space_write_1(bst, bsh, offset + pos,
1278 : enm->enm_addrlo[
1279 : (sc->sc_flags & XEF_MOHAWK) ? 5 - i : i]);
1280 :
1281 0 : if (++pos > 15) {
1282 : pos = IA;
1283 0 : page++;
1284 0 : PAGE(sc, page);
1285 0 : }
1286 : }
1287 : }
1288 : }
1289 0 : }
1290 :
1291 : void
1292 0 : xe_cycle_power(sc)
1293 : struct xe_softc *sc;
1294 : {
1295 0 : bus_space_tag_t bst = sc->sc_bst;
1296 0 : bus_space_handle_t bsh = sc->sc_bsh;
1297 0 : bus_size_t offset = sc->sc_offset;
1298 :
1299 0 : PAGE(sc, 4);
1300 0 : DELAY(1);
1301 0 : bus_space_write_1(bst, bsh, offset + GP1, 0);
1302 0 : DELAY(40000);
1303 0 : if (sc->sc_flags & XEF_MOHAWK)
1304 0 : bus_space_write_1(bst, bsh, offset + GP1, POWER_UP);
1305 : else
1306 : /* XXX What is bit 2 (aka AIC)? */
1307 0 : bus_space_write_1(bst, bsh, offset + GP1, POWER_UP | 4);
1308 0 : DELAY(20000);
1309 0 : }
1310 :
1311 : void
1312 0 : xe_full_reset(sc)
1313 : struct xe_softc *sc;
1314 : {
1315 0 : bus_space_tag_t bst = sc->sc_bst;
1316 0 : bus_space_handle_t bsh = sc->sc_bsh;
1317 0 : bus_size_t offset = sc->sc_offset;
1318 :
1319 : /* Do an as extensive reset as possible on all functions. */
1320 0 : xe_cycle_power(sc);
1321 0 : bus_space_write_1(bst, bsh, offset + CR, SOFT_RESET);
1322 0 : DELAY(20000);
1323 0 : bus_space_write_1(bst, bsh, offset + CR, 0);
1324 0 : DELAY(20000);
1325 0 : if (sc->sc_flags & XEF_MOHAWK) {
1326 0 : PAGE(sc, 4);
1327 : /*
1328 : * Drive GP1 low to power up ML6692 and GP2 high to power up
1329 : * the 10MHz chip. XXX What chip is that? The phy?
1330 : */
1331 0 : bus_space_write_1(bst, bsh, offset + GP0,
1332 : GP1_OUT | GP2_OUT | GP2_WR);
1333 0 : }
1334 0 : DELAY(500000);
1335 :
1336 : /* Get revision information. XXX Symbolic constants. */
1337 0 : sc->sc_rev = bus_space_read_1(bst, bsh, offset + BV) &
1338 0 : ((sc->sc_flags & XEF_MOHAWK) ? 0x70 : 0x30) >> 4;
1339 :
1340 : /* Media selection. XXX Maybe manual overriding too? */
1341 0 : if (!(sc->sc_flags & XEF_MOHAWK)) {
1342 0 : PAGE(sc, 4);
1343 : /*
1344 : * XXX I have no idea what this really does, it is from the
1345 : * Linux driver.
1346 : */
1347 0 : bus_space_write_1(bst, bsh, offset + GP0, GP1_OUT);
1348 0 : }
1349 0 : DELAY(40000);
1350 :
1351 : /* Setup the ethernet interrupt mask. */
1352 0 : PAGE(sc, 1);
1353 0 : bus_space_write_1(bst, bsh, offset + IMR0,
1354 : ISR_TX_OFLOW | ISR_PKT_TX | ISR_MAC_INT | /* ISR_RX_EARLY | */
1355 : ISR_RX_FULL | ISR_RX_PKT_REJ | ISR_FORCED_INT);
1356 : #if 0
1357 : bus_space_write_1(bst, bsh, offset + IMR0, 0xff);
1358 : #endif
1359 0 : if (!(sc->sc_flags & XEF_DINGO))
1360 : /* XXX What is this? Not for Dingo at least. */
1361 0 : bus_space_write_1(bst, bsh, offset + IMR1, 1);
1362 :
1363 : /*
1364 : * Disable source insertion.
1365 : * XXX Dingo does not have this bit, but Linux does it unconditionally.
1366 : */
1367 0 : if (!(sc->sc_flags & XEF_DINGO)) {
1368 0 : PAGE(sc, 0x42);
1369 0 : bus_space_write_1(bst, bsh, offset + SWC0, 0x20);
1370 0 : }
1371 :
1372 : /* Set the local memory dividing line. */
1373 0 : if (sc->sc_rev != 1) {
1374 0 : PAGE(sc, 2);
1375 : /* XXX Symbolic constant preferrable. */
1376 0 : bus_space_write_2(bst, bsh, offset + RBS0, 0x2000);
1377 0 : }
1378 :
1379 0 : xe_set_address(sc);
1380 :
1381 : /*
1382 : * Apparently the receive byte pointer can be bad after a reset, so
1383 : * we hardwire it correctly.
1384 : */
1385 0 : PAGE(sc, 0);
1386 0 : bus_space_write_2(bst, bsh, offset + DO0, DO_CHG_OFFSET);
1387 :
1388 : /* Setup ethernet MAC registers. XXX Symbolic constants. */
1389 0 : PAGE(sc, 0x40);
1390 0 : bus_space_write_1(bst, bsh, offset + RX0MSK,
1391 : PKT_TOO_LONG | CRC_ERR | RX_OVERRUN | RX_ABORT | RX_OK);
1392 0 : bus_space_write_1(bst, bsh, offset + TX0MSK,
1393 : CARRIER_LOST | EXCESSIVE_COLL | TX_UNDERRUN | LATE_COLLISION |
1394 : SQE | TX_ABORT | TX_OK);
1395 0 : if (!(sc->sc_flags & XEF_DINGO))
1396 : /* XXX From Linux, dunno what 0xb0 means. */
1397 0 : bus_space_write_1(bst, bsh, offset + TX1MSK, 0xb0);
1398 0 : bus_space_write_1(bst, bsh, offset + RXST0, 0);
1399 0 : bus_space_write_1(bst, bsh, offset + TXST0, 0);
1400 0 : bus_space_write_1(bst, bsh, offset + TXST1, 0);
1401 :
1402 : /* Enable MII function if available. */
1403 0 : if (LIST_FIRST(&sc->sc_mii.mii_phys)) {
1404 0 : PAGE(sc, 2);
1405 0 : bus_space_write_1(bst, bsh, offset + MSR,
1406 : bus_space_read_1(bst, bsh, offset + MSR) | SELECT_MII);
1407 0 : DELAY(20000);
1408 0 : } else {
1409 0 : PAGE(sc, 0);
1410 :
1411 : /* XXX Do we need to do this? */
1412 0 : PAGE(sc, 0x42);
1413 0 : bus_space_write_1(bst, bsh, offset + SWC1, SWC1_AUTO_MEDIA);
1414 0 : DELAY(50000);
1415 :
1416 : /* XXX Linux probes the media here. */
1417 : }
1418 :
1419 : /* Configure the LED registers. */
1420 0 : PAGE(sc, 2);
1421 :
1422 : /* XXX This is not good for 10base2. */
1423 0 : bus_space_write_1(bst, bsh, offset + LED,
1424 : LED_TX_ACT << LED1_SHIFT | LED_10MB_LINK << LED0_SHIFT);
1425 0 : if (sc->sc_flags & XEF_DINGO)
1426 0 : bus_space_write_1(bst, bsh, offset + LED3,
1427 : LED_100MB_LINK << LED3_SHIFT);
1428 :
1429 : /* Enable receiver and go online. */
1430 0 : PAGE(sc, 0x40);
1431 0 : bus_space_write_1(bst, bsh, offset + CMD0, ENABLE_RX | ONLINE);
1432 :
1433 : #if 0
1434 : /* XXX Linux does this here - is it necessary? */
1435 : PAGE(sc, 1);
1436 : bus_space_write_1(bst, bsh, offset + IMR0, 0xff);
1437 : if (!(sc->sc_flags & XEF_DINGO))
1438 : /* XXX What is this? Not for Dingo at least. */
1439 : bus_space_write_1(bst, bsh, offset + IMR1, 1);
1440 : #endif
1441 :
1442 : /* Enable interrupts. */
1443 0 : PAGE(sc, 0);
1444 0 : bus_space_write_1(bst, bsh, offset + CR, ENABLE_INT);
1445 :
1446 : /* XXX This is pure magic for me, found in the Linux driver. */
1447 0 : if ((sc->sc_flags & (XEF_DINGO | XEF_MODEM)) == XEF_MODEM) {
1448 0 : if ((bus_space_read_1(bst, bsh, offset + 0x10) & 0x01) == 0)
1449 : /* Unmask the master interrupt bit. */
1450 0 : bus_space_write_1(bst, bsh, offset + 0x10, 0x11);
1451 : }
1452 :
1453 : /*
1454 : * The Linux driver says this:
1455 : * We should switch back to page 0 to avoid a bug in revision 0
1456 : * where regs with offset below 8 can't be read after an access
1457 : * to the MAC registers.
1458 : */
1459 0 : PAGE(sc, 0);
1460 0 : }
1461 :
1462 : #ifdef XEDEBUG
1463 : void
1464 : xe_reg_dump(sc)
1465 : struct xe_softc *sc;
1466 : {
1467 : int page, i;
1468 : bus_space_tag_t bst = sc->sc_bst;
1469 : bus_space_handle_t bsh = sc->sc_bsh;
1470 : bus_size_t offset = sc->sc_offset;
1471 :
1472 : printf("%x: Common registers: ", sc->sc_dev.dv_xname);
1473 : for (i = 0; i < 8; i++) {
1474 : printf(" %2.2x", bus_space_read_1(bst, bsh, offset + i));
1475 : }
1476 : printf("\n");
1477 :
1478 : for (page = 0; page < 8; page++) {
1479 : printf("%s: Register page %2.2x: ", sc->sc_dev.dv_xname, page);
1480 : PAGE(sc, page);
1481 : for (i = 8; i < 16; i++) {
1482 : printf(" %2.2x",
1483 : bus_space_read_1(bst, bsh, offset + i));
1484 : }
1485 : printf("\n");
1486 : }
1487 :
1488 : for (page = 0x40; page < 0x5f; page++) {
1489 : if (page == 0x43 || (page >= 0x46 && page <= 0x4f) ||
1490 : (page >= 0x51 && page <= 0x5e))
1491 : continue;
1492 : printf("%s: Register page %2.2x: ", sc->sc_dev.dv_xname, page);
1493 : PAGE(sc, page);
1494 : for (i = 8; i < 16; i++) {
1495 : printf(" %2.2x",
1496 : bus_space_read_1(bst, bsh, offset + i));
1497 : }
1498 : printf("\n");
1499 : }
1500 : }
1501 : #endif /* XEDEBUG */
|