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