Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / dev / netif / fe / if_fe_cbus.c
1 /*
2  * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
3  *
4  * This software may be used, modified, copied, distributed, and sold, in
5  * both source and binary form provided that the above copyright, these
6  * terms and the following disclaimer are retained.  The name of the author
7  * and/or the contributor may not be used to endorse or promote products
8  * derived from this software without specific prior written permission.
9  *
10  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
11  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
14  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
17  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20  * SUCH DAMAGE.
21  *
22  * $FreeBSD: src/sys/dev/fe/if_fe_cbus.c,v 1.2.2.5 2002/02/09 03:12:27 nyan Exp $
23  * $DragonFly: src/sys/dev/netif/fe/Attic/if_fe_cbus.c,v 1.2 2003/06/17 04:28:25 dillon Exp $
24  */
25
26 #include "opt_fe.h"
27 #include "opt_inet.h"
28 #include "opt_ipx.h"
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/socket.h>
34 #include <sys/module.h>
35 #include <machine/clock.h>
36
37 #include <sys/bus.h>
38 #include <machine/bus.h>
39 #include <sys/rman.h>
40 #include <machine/resource.h>
41
42 #include <net/ethernet.h>
43 #include <net/if.h>
44 #include <net/if_mib.h>
45 #include <net/if_media.h>
46
47 #include <netinet/in.h>
48 #include <netinet/if_ether.h>
49
50 #include <i386/isa/ic/mb86960.h>
51 #include <dev/fe/if_fereg.h>
52 #include <dev/fe/if_fevar.h>
53
54 #include <isa/isavar.h>
55
56 /*
57  *      Cbus specific code.
58  */
59 static int fe_isa_probe(device_t);
60 static int fe_isa_attach(device_t);
61
62 static struct isa_pnp_id fe_ids[] = {
63         { 0x101ee0d,    NULL },         /* CON0101 - Contec C-NET(98)P2-T */
64         { 0,            NULL }
65 };
66
67 static device_method_t fe_isa_methods[] = {
68         /* Device interface */
69         DEVMETHOD(device_probe,         fe_isa_probe),
70         DEVMETHOD(device_attach,        fe_isa_attach),
71
72         { 0, 0 }
73 };
74
75 static driver_t fe_isa_driver = {
76         "fe",
77         fe_isa_methods,
78         sizeof (struct fe_softc)
79 };
80
81 DRIVER_MODULE(fe, isa, fe_isa_driver, fe_devclass, 0, 0);
82
83
84 static int fe98_alloc_port(device_t, int);
85
86 static int fe_probe_re1000(device_t);
87 static int fe_probe_cnet9ne(device_t);
88 static int fe_probe_rex(device_t);
89 static int fe_probe_ssi(device_t);
90 static int fe_probe_jli(device_t);
91 static int fe_probe_lnx(device_t);
92 static int fe_probe_gwy(device_t);
93 static int fe_probe_ubn(device_t);
94
95 /*
96  * Determine if the device is present at a specified I/O address.  The
97  * main entry to the driver.
98  */
99 static int
100 fe_isa_probe(device_t dev)
101 {
102         struct fe_softc *sc;
103         int error;
104
105         /* Prepare for the softc struct.  */
106         sc = device_get_softc(dev);
107         sc->sc_unit = device_get_unit(dev);
108
109         /* Check isapnp ids */
110         error = ISA_PNP_PROBE(device_get_parent(dev), dev, fe_ids);
111
112         /* If the card had a PnP ID that didn't match any we know about */
113         if (error == ENXIO)
114                 goto end;
115
116         /* If we had some other problem. */
117         if (!(error == 0 || error == ENOENT))
118                 goto end;
119
120         /* Probe for supported boards.  */
121         if ((error = fe_probe_re1000(dev)) == 0)
122                 goto end;
123         fe_release_resource(dev);
124
125         if ((error = fe_probe_cnet9ne(dev)) == 0)
126                 goto end;
127         fe_release_resource(dev);
128
129         if ((error = fe_probe_rex(dev)) == 0)
130                 goto end;
131         fe_release_resource(dev);
132
133         if ((error = fe_probe_ssi(dev)) == 0)
134                 goto end;
135         fe_release_resource(dev);
136
137         if ((error = fe_probe_jli(dev)) == 0)
138                 goto end;
139         fe_release_resource(dev);
140
141         if ((error = fe_probe_lnx(dev)) == 0)
142                 goto end;
143         fe_release_resource(dev);
144
145         if ((error = fe_probe_ubn(dev)) == 0)
146                 goto end;
147         fe_release_resource(dev);
148
149         if ((error = fe_probe_gwy(dev)) == 0)
150                 goto end;
151         fe_release_resource(dev);
152
153 end:
154         if (error == 0)
155                 error = fe_alloc_irq(dev, 0);
156
157         fe_release_resource(dev);
158         return (error);
159 }
160
161 static int
162 fe_isa_attach(device_t dev)
163 {
164         struct fe_softc *sc = device_get_softc(dev);
165
166         if (sc->port_used)
167                 fe98_alloc_port(dev, sc->type);
168         fe_alloc_irq(dev, 0);
169
170         return fe_attach(dev);
171 }
172
173
174 /* Generic I/O address table */
175 static bus_addr_t ioaddr_generic[MAXREGISTERS] = {
176         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
177         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
178         0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017,
179         0x018, 0x019, 0x01a, 0x01b, 0x01c, 0x01d, 0x01e, 0x01f,
180 };
181
182 /* I/O address table for RE1000/1000Plus */
183 static bus_addr_t ioaddr_re1000[MAXREGISTERS] = {
184         0x0000, 0x0001, 0x0200, 0x0201, 0x0400, 0x0401, 0x0600, 0x0601,
185         0x0800, 0x0801, 0x0a00, 0x0a01, 0x0c00, 0x0c01, 0x0e00, 0x0e01,
186         0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00,
187         0x1001, 0x1201, 0x1401, 0x1601, 0x1801, 0x1a01, 0x1c01, 0x1e01,
188 };
189
190 /* I/O address table for CNET9NE */
191 static bus_addr_t ioaddr_cnet9ne[MAXREGISTERS] = {
192         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
193         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
194         0x400, 0x402, 0x404, 0x406, 0x408, 0x40a, 0x40c, 0x40e,
195         0x401, 0x403, 0x405, 0x407, 0x409, 0x40b, 0x40d, 0x40f,
196 };
197
198 /* I/O address table for LAC-98 */
199 static bus_addr_t ioaddr_lnx[MAXREGISTERS] = {
200         0x000, 0x002, 0x004, 0x006, 0x008, 0x00a, 0x00c, 0x00e,
201         0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e,
202         0x200, 0x202, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x20e,
203         0x300, 0x302, 0x304, 0x306, 0x308, 0x30a, 0x30c, 0x30e,
204 };
205
206 /* I/O address table for Access/PC N98C+ */
207 static bus_addr_t ioaddr_ubn[MAXREGISTERS] = {
208         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
209         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
210         0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x206, 0x207,
211         0x208, 0x209, 0x20a, 0x20b, 0x20c, 0x20d, 0x20e, 0x20f,
212 };
213
214 /* I/O address table for REX-9880 */
215 static bus_addr_t ioaddr_rex[MAXREGISTERS] = {
216         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
217         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
218         0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107,
219         0x108, 0x109, 0x10a, 0x10b, 0x10c, 0x10d, 0x10e, 0x10f,
220 };
221
222 static int
223 fe98_alloc_port(device_t dev, int type)
224 {
225         struct fe_softc *sc = device_get_softc(dev);
226         struct resource *res;
227         bus_addr_t *iat;
228         int size, rid;
229
230         switch (type) {
231         case FE_TYPE_RE1000:
232                 iat = ioaddr_re1000;
233                 size = MAXREGISTERS;
234                 break;
235         case FE_TYPE_CNET9NE:
236                 iat = ioaddr_cnet9ne;
237                 size = MAXREGISTERS;
238                 break;
239         case FE_TYPE_SSI:
240                 iat = ioaddr_generic;
241                 size = MAXREGISTERS;
242                 break;
243         case FE_TYPE_LNX:
244                 iat = ioaddr_lnx;
245                 size = MAXREGISTERS;
246                 break;
247         case FE_TYPE_GWY:
248                 iat = ioaddr_generic;
249                 size = MAXREGISTERS;
250                 break;
251         case FE_TYPE_UBN:
252                 iat = ioaddr_ubn;
253                 size = MAXREGISTERS;
254                 break;
255         case FE_TYPE_REX:
256                 iat = ioaddr_rex;
257                 size = MAXREGISTERS;
258                 break;
259         default:
260                 iat = ioaddr_generic;
261                 size = MAXREGISTERS;
262                 break;
263         }
264
265         rid = 0;
266         res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
267                                   iat, size, RF_ACTIVE);
268         if (res == NULL)
269                 return ENOENT;
270
271         isa_load_resourcev(res, iat, size);
272
273         sc->type = type;
274         sc->port_used = size;
275         sc->port_res = res;
276         sc->iot = rman_get_bustag(res);
277         sc->ioh = rman_get_bushandle(res);
278         return (0);
279 }
280
281
282 /*
283  * Probe and initialization for Allied-Telesis RE1000 series.
284  */
285 static void
286 fe_init_re1000(struct fe_softc *sc)
287 {
288         /* Setup IRQ control register on the ASIC.  */
289         fe_outb(sc, FE_RE1000_IRQCONF, sc->priv_info);
290 }
291
292 static int
293 fe_probe_re1000(device_t dev)
294 {
295         struct fe_softc *sc = device_get_softc(dev);
296         int i, n;
297         u_long iobase, irq;
298         u_char sum;
299
300         static struct fe_simple_probe_struct probe_table [] = {
301                 { FE_DLCR2, 0x58, 0x00 },
302                 { FE_DLCR4, 0x08, 0x00 },
303                 { 0 }
304         };
305
306         /* See if the specified I/O address is possible for RE1000.  */
307         /* [01]D[02468ACE] are allowed.  */ 
308         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
309                 return ENXIO;
310         if ((iobase & ~0x10E) != 0xD0)
311                 return ENXIO;
312
313         if (fe98_alloc_port(dev, FE_TYPE_RE1000))
314                 return ENXIO;
315
316         /* Fill the softc struct with default values.  */
317         fe_softc_defaults(sc);
318
319         /* See if the card is on its address.  */
320         if (!fe_simple_probe(sc, probe_table))
321                 return ENXIO;
322
323         /* Get our station address from EEPROM.  */
324         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
325
326         /* Make sure it is Allied-Telesis's.  */
327         if (!valid_Ether_p(sc->sc_enaddr, 0x0000F4))
328                 return ENXIO;
329 #if 1
330         /* Calculate checksum.  */
331         sum = fe_inb(sc, 0x1e);
332         for (i = 0; i < ETHER_ADDR_LEN; i++)
333                 sum ^= sc->sc_enaddr[i];
334         if (sum != 0)
335                 return ENXIO;
336 #endif
337         /* Setup the board type.  */
338         sc->typestr = "RE1000";
339
340         /* This looks like an RE1000 board.  It requires an
341            explicit IRQ setting in config.  Make sure we have one,
342            determining an appropriate value for the IRQ control
343            register.  */
344         irq = 0;
345         bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
346         switch (irq) {
347         case 3:  n = 0x10; break;
348         case 5:  n = 0x20; break;
349         case 6:  n = 0x40; break;
350         case 12: n = 0x80; break;
351         default:
352                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
353                 return ENXIO;
354         }
355         sc->priv_info = (fe_inb(sc, FE_RE1000_IRQCONF) & 0x0f) | n;
356
357         /* Setup hooks.  We need a special initialization procedure.  */
358         sc->init = fe_init_re1000;
359
360         return 0;
361 }
362
363 /* JLI sub-probe for Allied-Telesis RE1000Plus/ME1500 series.  */
364 static u_short const *
365 fe_probe_jli_re1000p(struct fe_softc * sc, u_char const * eeprom)
366 {
367         int i;
368         static u_short const irqmaps_re1000p [4] = { 3, 5, 6, 12 };
369
370         /* Make sure the EEPROM contains Allied-Telesis bit pattern.  */
371         if (eeprom[1] != 0xFF) return NULL;
372         for (i =  2; i <  8; i++) if (eeprom[i] != 0xFF) return NULL;
373         for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL;
374
375         /* Get our station address from EEPROM, and make sure the
376            EEPROM contains Allied-Telesis's address.  */
377         bcopy(eeprom + 8, sc->sc_enaddr, ETHER_ADDR_LEN);
378         if (!valid_Ether_p(sc->sc_enaddr, 0x0000F4))
379                 return NULL;
380
381         /* I don't know any sub-model identification.  */
382         sc->typestr = "RE1000Plus/ME1500";
383
384         /* Returns the IRQ table for the RE1000Plus.  */
385         return irqmaps_re1000p;
386 }
387
388
389 /*
390  * Probe for Allied-Telesis RE1000Plus/ME1500 series.
391  */
392 static int
393 fe_probe_jli(device_t dev)
394 {
395         struct fe_softc *sc = device_get_softc(dev);
396         int i, n, xirq, error;
397         u_long iobase, irq;
398         u_char eeprom [JLI_EEPROM_SIZE];
399         u_short const * irqmap;
400
401         static u_short const baseaddr [8] =
402                 { 0x1D6, 0x1D8, 0x1DA, 0x1D4, 0x0D4, 0x0D2, 0x0D8, 0x0D0 };
403         static struct fe_simple_probe_struct const probe_table [] = {
404         /*      { FE_DLCR1,  0x20, 0x00 },      Doesn't work. */
405                 { FE_DLCR2,  0x50, 0x00 },
406                 { FE_DLCR4,  0x08, 0x00 },
407         /*      { FE_DLCR5,  0x80, 0x00 },      Doesn't work. */
408 #if 0
409                 { FE_BMPR16, 0x1B, 0x00 },
410                 { FE_BMPR17, 0x7F, 0x00 },
411 #endif
412                 { 0 }
413         };
414
415         /*
416          * See if the specified address is possible for MB86965A JLI mode.
417          */
418         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
419                 return ENXIO;
420         for (i = 0; i < 8; i++) {
421                 if (baseaddr[i] == iobase)
422                         break;
423         }
424         if (i == 8)
425                 return ENXIO;
426
427         if (fe98_alloc_port(dev, FE_TYPE_RE1000))
428                 return ENXIO;
429
430         /* Fill the softc struct with default values.  */
431         fe_softc_defaults(sc);
432
433         /*
434          * We should test if MB86965A is on the base address now.
435          * Unfortunately, it is very hard to probe it reliably, since
436          * we have no way to reset the chip under software control.
437          * On cold boot, we could check the "signature" bit patterns
438          * described in the Fujitsu document.  On warm boot, however,
439          * we can predict almost nothing about register values.
440          */
441         if (!fe_simple_probe(sc, probe_table))
442                 return ENXIO;
443
444         /* Check if our I/O address matches config info on 86965.  */
445         n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT;
446         if (baseaddr[n] != iobase)
447                 return ENXIO;
448
449         /*
450          * We are now almost sure we have an MB86965 at the given
451          * address.  So, read EEPROM through it.  We have to write
452          * into LSI registers to read from EEPROM.  I want to avoid it
453          * at this stage, but I cannot test the presence of the chip
454          * any further without reading EEPROM.  FIXME.
455          */
456         fe_read_eeprom_jli(sc, eeprom);
457
458         /* Make sure that config info in EEPROM and 86965 agree.  */
459         if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19))
460                 return ENXIO;
461
462         /* Use 86965 media selection scheme, unless othewise
463            specified.  It is "AUTO always" and "select with BMPR13".
464            This behaviour covers most of the 86965 based board (as
465            minimum requirements.)  It is backward compatible with
466            previous versions, also.  */
467         sc->mbitmap = MB_HA;
468         sc->defmedia = MB_HA;
469         sc->msel = fe_msel_965;
470
471         /* Perform board-specific probe.  */
472         if ((irqmap = fe_probe_jli_re1000p(sc, eeprom)) == NULL)
473                 return ENXIO;
474
475         /* Find the IRQ read from EEPROM.  */
476         n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT;
477         xirq = irqmap[n];
478
479         /* Try to determine IRQ setting.  */
480         error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
481         if (error && xirq == NO_IRQ) {
482                 /* The device must be configured with an explicit IRQ.  */
483                 device_printf(dev, "IRQ auto-detection does not work\n");
484                 return ENXIO;
485         } else if (error && xirq != NO_IRQ) {
486                 /* Just use the probed IRQ value.  */
487                 bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1);
488         } else if (!error && xirq == NO_IRQ) {
489                 /* No problem.  Go ahead.  */
490         } else if (irq == xirq) {
491                 /* Good.  Go ahead.  */
492         } else {
493                 /* User must be warned in this case.  */
494                 sc->stability |= UNSTABLE_IRQ;
495         }
496
497         /* Setup a hook, which resets te 86965 when the driver is being
498            initialized.  This may solve a nasty bug.  FIXME.  */
499         sc->init = fe_init_jli;
500
501         return 0;
502 }
503
504
505 /*
506  * Probe and initialization for Contec C-NET(9N)E series.
507  */
508
509 /* TODO: Should be in "if_fereg.h" */
510 #define FE_CNET9NE_INTR         0x10            /* Interrupt Mask? */
511
512 static void
513 fe_init_cnet9ne(struct fe_softc *sc)
514 {
515         /* Enable interrupt?  FIXME.  */
516         fe_outb(sc, FE_CNET9NE_INTR, 0x10);
517 }
518
519 static int
520 fe_probe_cnet9ne (device_t dev)
521 {
522         struct fe_softc *sc = device_get_softc(dev);
523         u_long iobase, irq;
524
525         static struct fe_simple_probe_struct probe_table [] = {
526                 { FE_DLCR2, 0x58, 0x00 },
527                 { FE_DLCR4, 0x08, 0x00 },
528                 { 0 }
529         };
530
531         /* See if the specified I/O address is possible for C-NET(9N)E.  */
532         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
533                 return ENXIO;
534         if (iobase != 0x73D0)
535                 return ENXIO;
536
537         if (fe98_alloc_port(dev, FE_TYPE_CNET9NE))
538                 return ENXIO;
539
540         /* Fill the softc struct with default values.  */
541         fe_softc_defaults(sc);
542
543         /* See if the card is on its address.  */
544         if (!fe_simple_probe(sc, probe_table))
545                 return ENXIO;
546
547         /* Get our station address from EEPROM.  */
548         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
549
550         /* Make sure it is Contec's.  */
551         if (!valid_Ether_p(sc->sc_enaddr, 0x00804C))
552                 return ENXIO;
553
554         /* Determine the card type.  */
555         if (sc->sc_enaddr[3] == 0x06) {
556                 sc->typestr = "C-NET(9N)C";
557
558                 /* We seems to need our own IDENT bits...  FIXME.  */
559                 sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE;
560
561                 /* C-NET(9N)C requires an explicit IRQ to work.  */
562                 if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) {
563                         fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL);
564                         return ENXIO;
565                 }
566         } else {
567                 sc->typestr = "C-NET(9N)E";
568
569                 /* C-NET(9N)E works only IRQ5.  */
570                 if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0)
571                         return ENXIO;
572                 if (irq != 5) {
573                         fe_irq_failure(sc->typestr, sc->sc_unit, irq, "5");
574                         return ENXIO;
575                 }
576
577                 /* We need an init hook to initialize ASIC before we start.  */
578                 sc->init = fe_init_cnet9ne;
579         }
580
581         /* C-NET(9N)E has 64KB SRAM.  */
582         sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
583                         | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;
584
585         return 0;
586 }
587
588
589 /*
590  * Probe for Contec C-NET(98)P2 series.
591  * (Logitec LAN-98TP/LAN-98T25P - parhaps)
592  */
593 static int
594 fe_probe_ssi(device_t dev)
595 {
596         struct fe_softc *sc = device_get_softc(dev);
597         u_long iobase, irq;
598
599         u_char eeprom [SSI_EEPROM_SIZE];
600         static struct fe_simple_probe_struct probe_table [] = {
601                 { FE_DLCR2, 0x08, 0x00 },
602                 { FE_DLCR4, 0x08, 0x00 },
603                 { 0 }
604         };
605         static u_short const irqmap[] = {
606                 /*                        INT0          INT1    INT2       */
607                 NO_IRQ, NO_IRQ, NO_IRQ,      3, NO_IRQ,    5,      6, NO_IRQ,
608                 NO_IRQ,      9,     10, NO_IRQ,     12,   13, NO_IRQ, NO_IRQ,
609                 /*        INT3   INT41            INT5  INT6               */
610         };
611
612         /* See if the specified I/O address is possible for 78Q8377A.  */
613         /* [0-D]3D0 are allowed.  */
614         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
615                 return ENXIO;
616         if ((iobase & 0xFFF) != 0x3D0)
617                 return ENXIO;
618                 
619         if (fe98_alloc_port(dev, FE_TYPE_SSI))
620                 return ENXIO;
621
622         /* Fill the softc struct with default values.  */
623         fe_softc_defaults(sc);
624
625         /* See if the card is on its address.  */
626         if (!fe_simple_probe(sc, probe_table))
627                 return ENXIO;
628
629         /* We now have to read the config EEPROM.  We should be very
630            careful, since doing so destroys a register.  (Remember, we
631            are not yet sure we have a C-NET(98)P2 board here.)  Don't
632            remember to select BMPRs bofore reading EEPROM, since other
633            register bank may be selected before the probe() is called.  */
634         fe_read_eeprom_ssi(sc, eeprom);
635
636         /* Make sure the Ethernet (MAC) station address is of Contec's.  */
637         if (!valid_Ether_p(eeprom + FE_SSI_EEP_ADDR, 0x00804C))
638                 return ENXIO;
639         bcopy(eeprom + FE_SSI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN);
640
641         /* Setup the board type.  */
642         sc->typestr = "C-NET(98)P2";
643
644         /* Non-PnP mode, set static resource from eeprom. */
645         if (!isa_get_vendorid(dev)) {
646                 /* Get IRQ configuration from EEPROM.  */
647                 irq = irqmap[eeprom[FE_SSI_EEP_IRQ]];
648                 if (irq == NO_IRQ) {
649                         fe_irq_failure(sc->typestr, sc->sc_unit, irq,
650                                        "3/5/6/9/10/12/13");
651                         return ENXIO;
652                 }
653                 bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
654         }
655
656         /* Get Duplex-mode configuration from EEPROM.  */
657         sc->proto_dlcr4 |= (eeprom[FE_SSI_EEP_DUPLEX] & FE_D4_DSC);
658
659         /* Fill softc struct accordingly.  */
660         sc->mbitmap = MB_HT;
661         sc->defmedia = MB_HT;
662
663         return 0;
664 }
665
666
667 /*
668  * Probe for TDK LAC-98012/013/025/9N011 - parhaps.
669  */
670 static int
671 fe_probe_lnx(device_t dev)
672 {
673 #ifndef FE_8BIT_SUPPORT
674         device_printf(dev,
675                       "skip LAC-98012/013(only 16-bit cards are supported)\n");
676         return ENXIO;
677 #else
678         struct fe_softc *sc = device_get_softc(dev);
679
680         u_long iobase, irq;
681         u_char eeprom [LNX_EEPROM_SIZE];
682
683         static struct fe_simple_probe_struct probe_table [] = {
684                 { FE_DLCR2, 0x58, 0x00 },
685                 { FE_DLCR4, 0x08, 0x00 },
686                 { 0 }
687         };
688
689         /* See if the specified I/O address is possible for TDK/LANX boards. */
690         /* 0D0, 4D0, 8D0, and CD0 are allowed.  */
691         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
692                 return ENXIO;
693         if ((iobase & ~0xC00) != 0xD0)
694                 return ENXIO;
695
696         if (fe98_alloc_port(dev, FE_TYPE_LNX))
697                 return ENXIO;
698
699         /* Fill the softc struct with default values.  */
700         fe_softc_defaults(sc);
701
702         /* See if the card is on its address.  */
703         if (!fe_simple_probe(sc, probe_table))
704                 return ENXIO;
705
706         /* We now have to read the config EEPROM.  We should be very
707            careful, since doing so destroys a register.  (Remember, we
708            are not yet sure we have a LAC-98012/98013 board here.)  */
709         fe_read_eeprom_lnx(sc, eeprom);
710
711         /* Make sure the Ethernet (MAC) station address is of TDK/LANX's.  */
712         if (!valid_Ether_p(eeprom, 0x008098))
713                 return ENXIO;
714         bcopy(eeprom, sc->sc_enaddr, ETHER_ADDR_LEN);
715
716         /* Setup the board type.  */
717         sc->typestr = "LAC-98012/98013";
718
719         /* This looks like a TDK/LANX board.  It requires an
720            explicit IRQ setting in config.  Make sure we have one,
721            determining an appropriate value for the IRQ control
722            register.  */
723         irq = 0;
724         if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0)
725                 return ENXIO;
726         switch (irq) {
727         case 3 : sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break;
728         case 5 : sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break;
729         case 6 : sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break;
730         case 12: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break;
731         default:
732                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
733                 return ENXIO;
734         }
735
736         /* LAC-98's system bus width is 8-bit.  */ 
737         sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x2KB
738                         | FE_D6_BBW_BYTE | FE_D6_SBW_BYTE | FE_D6_SRAM_150ns;
739
740         /* Setup hooks.  We need a special initialization procedure.  */
741         sc->init = fe_init_lnx;
742
743         return 0;
744 #endif /* FE_8BIT_SUPPORT */
745 }
746
747
748 /*
749  * Probe for Gateway Communications' old cards.
750  * (both as Generic MB86960 probe routine)
751  */
752 static int
753 fe_probe_gwy(device_t dev)
754 {
755         struct fe_softc *sc = device_get_softc(dev);
756
757         static struct fe_simple_probe_struct probe_table [] = {
758             /*  { FE_DLCR2, 0x70, 0x00 }, */
759                 { FE_DLCR2, 0x58, 0x00 },
760                 { FE_DLCR4, 0x08, 0x00 },
761                 { 0 }
762         };
763
764         /*
765          * XXX
766          * I'm not sure which address is possible, so accepts any.
767          */
768
769         if (fe98_alloc_port(dev, FE_TYPE_GWY))
770                 return ENXIO;
771
772         /* Fill the softc struct with default values.  */
773         fe_softc_defaults(sc);
774
775         /* See if the card is on its address.  */
776         if (!fe_simple_probe(sc, probe_table))
777                 return ENXIO;
778
779         /* Get our station address from EEPROM. */
780         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
781         if (!valid_Ether_p(sc->sc_enaddr, 0x000000))
782                 return ENXIO;
783
784         /* Determine the card type.  */
785         sc->typestr = "Generic MB86960 Ethernet";
786         if (valid_Ether_p(sc->sc_enaddr, 0x000061))
787                 sc->typestr = "Gateway Ethernet (Fujitsu chipset)";
788
789         /* Gateway's board requires an explicit IRQ to work, since it
790            is not possible to probe the setting of jumpers.  */
791         if (bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0) {
792                 fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL);
793                 return ENXIO;
794         }
795
796         return 0;
797 }
798
799
800 /*
801  * Probe for Ungermann-Bass Access/PC N98C+(Model 85152).
802  */
803 static int
804 fe_probe_ubn(device_t dev)
805 {
806         struct fe_softc *sc = device_get_softc(dev);
807
808         u_char sum, save7;
809         u_long iobase, irq;
810         int i;
811         static struct fe_simple_probe_struct const probe_table [] = {
812                 { FE_DLCR2, 0x58, 0x00 },
813                 { FE_DLCR4, 0x08, 0x00 },
814                 { 0 }
815         };
816
817         /* See if the specified I/O address is possible for Access/PC.  */
818         /* [01][048C]D0 are allowed.  */ 
819         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
820                 return ENXIO;
821         if ((iobase & ~0x1C00) != 0xD0)
822                 return ENXIO;
823
824         if (fe98_alloc_port(dev, FE_TYPE_UBN))
825                 return ENXIO;
826
827         /* Fill the softc struct with default values.  */
828         fe_softc_defaults(sc);
829
830         /* Simple probe.  */
831         if (!fe_simple_probe(sc, probe_table))
832                 return ENXIO;
833
834         /* NOTE: Access/NOTE N98 sometimes freeze when reading station
835            address.  In case of using it togather with C-NET(9N)C,
836            this problem usually happens.
837            Writing DLCR7 prevents freezing, but I don't know why.  FIXME.  */
838
839         /* Save the current value for the DLCR7 register we are about
840            to destroy.  */
841         save7 = fe_inb(sc, FE_DLCR7);
842         fe_outb(sc, FE_DLCR7,
843                 sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
844
845         /* Get our station address form ID ROM and make sure it is UBN's.  */
846         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
847         if (!valid_Ether_p(sc->sc_enaddr, 0x00DD01))
848                 goto fail_ubn;
849 #if 1
850         /* Calculate checksum.  */
851         sum = fe_inb(sc, 0x1e);
852         for (i = 0; i < ETHER_ADDR_LEN; i++)
853                 sum ^= sc->sc_enaddr[i];
854         if (sum != 0)
855                 goto fail_ubn;
856 #endif
857
858         /* Setup the board type.  */
859         sc->typestr = "Access/PC";
860
861         /* This looks like an AccessPC/N98C+ board.  It requires an
862            explicit IRQ setting in config.  Make sure we have one,
863            determining an appropriate value for the IRQ control
864            register.  */
865         irq = 0;
866         bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
867         switch (irq) {
868         case 3:  sc->priv_info = 0x01; break;
869         case 5:  sc->priv_info = 0x02; break;
870         case 6:  sc->priv_info = 0x04; break;
871         case 12: sc->priv_info = 0x08; break;
872         default:
873                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
874                 goto fail_ubn;
875         }
876
877         /* Setup hooks.  We need a special initialization procedure.  */
878         sc->init = fe_init_ubn;
879
880         return 0;
881
882 fail_ubn:
883         fe_outb(sc, FE_DLCR7, save7);
884         return ENXIO;
885 }
886
887
888 /*
889  * REX boards(non-JLI type) support routine.
890  */
891
892 #define REX_EEPROM_SIZE 32
893 #define REX_DAT 0x01
894
895 static void
896 fe_read_eeprom_rex(struct fe_softc *sc, u_char *data)
897 {
898         int i;
899         u_char bit, val;
900         u_char save16;
901
902         save16 = fe_inb(sc, 0x10);
903
904         /* Issue a start condition.  */
905         val = fe_inb(sc, 0x10) & 0xf0;
906         fe_outb(sc, 0x10, val);
907
908         (void) fe_inb(sc, 0x10);
909         (void) fe_inb(sc, 0x10);
910         (void) fe_inb(sc, 0x10);
911         (void) fe_inb(sc, 0x10);
912
913         /* Read bytes from EEPROM.  */
914         for (i = 0; i < REX_EEPROM_SIZE; i++) {
915                 /* Read a byte and store it into the buffer.  */
916                 val = 0x00;
917                 for (bit = 0x01; bit != 0x00; bit <<= 1)
918                         if (fe_inb(sc, 0x10) & REX_DAT)
919                                 val |= bit;
920                 *data++ = val;
921         }
922
923         fe_outb(sc, 0x10, save16);
924
925 #if 1
926         /* Report what we got.  */
927         if (bootverbose) {
928                 data -= REX_EEPROM_SIZE;
929                 for (i = 0; i < REX_EEPROM_SIZE; i += 16) {
930                         printf("fe%d: EEPROM(REX):%3x: %16D\n",
931                                sc->sc_unit, i, data + i, " ");
932                 }
933         }
934 #endif
935 }
936
937
938 static void
939 fe_init_rex(struct fe_softc *sc)
940 {
941         /* Setup IRQ control register on the ASIC.  */
942         fe_outb(sc, 0x10, sc->priv_info);
943 }
944
945 /*
946  * Probe for RATOC REX-9880/81/82/83 series.
947  */
948 static int
949 fe_probe_rex(device_t dev)
950 {
951         struct fe_softc *sc = device_get_softc(dev);
952
953         int i;
954         u_long iobase, irq;
955         u_char eeprom [REX_EEPROM_SIZE];
956
957         static struct fe_simple_probe_struct probe_table [] = {
958                 { FE_DLCR2, 0x58, 0x00 },
959                 { FE_DLCR4, 0x08, 0x00 },
960                 { 0 }
961         };
962
963         /* See if the specified I/O address is possible for REX-9880.  */
964         /* 6[46CE]D0 are allowed.  */ 
965         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
966                 return ENXIO;
967         if ((iobase & ~0xA00) != 0x64D0)
968                 return ENXIO;
969
970         if (fe98_alloc_port(dev, FE_TYPE_REX))
971                 return ENXIO;
972
973         /* Fill the softc struct with default values.  */
974         fe_softc_defaults(sc);
975
976         /* See if the card is on its address.  */
977         if (!fe_simple_probe(sc, probe_table))
978                 return ENXIO;
979
980         /* We now have to read the config EEPROM.  We should be very
981            careful, since doing so destroys a register.  (Remember, we
982            are not yet sure we have a REX-9880 board here.)  */
983         fe_read_eeprom_rex(sc, eeprom);
984         for (i = 0; i < ETHER_ADDR_LEN; i++)
985                 sc->sc_enaddr[i] = eeprom[7 - i];
986
987         /* Make sure it is RATOC's.  */
988         if (!valid_Ether_p(sc->sc_enaddr, 0x00C0D0) &&
989             !valid_Ether_p(sc->sc_enaddr, 0x00803D))
990                 return 0;
991
992         /* Setup the board type.  */
993         sc->typestr = "REX-9880/9883";
994
995         /* This looks like a REX-9880 board.  It requires an
996            explicit IRQ setting in config.  Make sure we have one,
997            determining an appropriate value for the IRQ control
998            register.  */
999         irq = 0;
1000         bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
1001         switch (irq) {
1002         case 3:  sc->priv_info = 0x10; break;
1003         case 5:  sc->priv_info = 0x20; break;
1004         case 6:  sc->priv_info = 0x40; break;
1005         case 12: sc->priv_info = 0x80; break;
1006         default:
1007                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
1008                 return ENXIO;
1009         }
1010
1011         /* Setup hooks.  We need a special initialization procedure.  */
1012         sc->init = fe_init_rex;
1013
1014         /* REX-9880 has 64KB SRAM.  */
1015         sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
1016                         | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;
1017 #if 1
1018         sc->proto_dlcr7 |= FE_D7_EOPPOL;        /* XXX */
1019 #endif
1020
1021         return 0;
1022 }