if_ed_cbus.c revision 141552
1/*-
2 * Copyright (c) 1995, David Greenman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/ed/if_ed_cbus.c 141552 2005-02-09 00:50:59Z imp $
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/socket.h>
33#include <sys/kernel.h>
34
35#include <sys/module.h>
36#include <sys/bus.h>
37#include <machine/bus.h>
38#include <sys/rman.h>
39#include <machine/resource.h>
40#include <machine/clock.h>
41#include <machine/md_var.h>
42
43#include <net/ethernet.h>
44#include <net/if.h>
45#include <net/if_arp.h>
46#include <net/if_mib.h>
47
48#include <isa/isavar.h>
49
50#include <dev/ed/if_edvar.h>
51#include <dev/ed/if_edreg.h>
52#include <dev/ed/if_ed98.h>
53
54static int ed98_alloc_port(device_t, int);
55static int ed98_alloc_memory(device_t, int);
56static int ed_pio_testmem(struct ed_softc *, int, int, int);
57static int ed_probe_SIC98(device_t, int, int);
58static int ed_probe_CNET98(device_t, int, int);
59static int ed_probe_CNET98EL(device_t, int, int);
60static int ed_probe_NEC77(device_t, int, int);
61static int ed_probe_NW98X(device_t, int, int);
62static int ed_probe_SB98(device_t, int, int);
63static int ed_probe_EZ98(device_t, int, int);
64static int ed98_probe_Novell(device_t, int, int);
65static int ed98_probe_generic8390(struct ed_softc *);
66static void ed_reset_CNET98(struct ed_softc *, int);
67static void ed_winsel_CNET98(struct ed_softc *, u_short);
68static void ed_get_SB98(struct ed_softc *);
69
70static int ed_cbus_probe(device_t);
71static int ed_cbus_attach(device_t);
72
73static struct isa_pnp_id ed_ids[] = {
74/* TODO - list up PnP boards for PC-98 */
75	{ 0,		NULL }
76};
77
78static int
79ed_cbus_probe(device_t dev)
80{
81	struct ed_softc *sc = device_get_softc(dev);
82	int flags = device_get_flags(dev);
83	int error = 0;
84
85	sc->type = ED_TYPE98(flags);
86#ifdef ED_DEBUG
87	device_printf(dev, "ed_cbus_probe: sc->type=%x\n", sc->type);
88#endif
89
90	/* Check isapnp ids */
91	error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids);
92#ifdef ED_DEBUG
93	device_printf(dev, "ed_cbus_probe: ISA_PNP_PROBE returns %d\n", error);
94#endif
95
96	/* If the card had a PnP ID that didn't match any we know about */
97	if (error == ENXIO)
98		goto end;
99
100	/* If we had some other problem. */
101	if (!(error == 0 || error == ENOENT))
102		goto end;
103
104	/* Heuristic probes */
105#ifdef ED_DEBUG
106	device_printf(dev, "ed_cbus_probe: Heuristic probes start\n");
107#endif
108	switch (sc->type) {
109	case ED_TYPE98_GENERIC:
110		/*
111		 * CAUTION!
112		 * sc->type of these boards are overwritten by PC/AT's value.
113		 */
114
115		/*
116		 * SMC EtherEZ98
117		 */
118		error = ed_probe_EZ98(dev, 0, flags);
119		if (error == 0)
120			goto end;
121
122		ed_release_resources(dev);
123
124		/*
125		 * Allied Telesis CenterCom LA-98-T
126		 */
127		error = ed_probe_Novell(dev, 0, flags);
128		if (error == 0)
129			goto end;
130		break;
131
132	/*
133	 * NE2000-like boards probe routine
134	 */
135	case ED_TYPE98_BDN:
136		/*
137		 * ELECOM LANEED LD-BDN
138		 * PLANET SMART COM 98 EN-2298
139		 */
140	case ED_TYPE98_LGY:
141		/*
142		 * MELCO LGY-98, IND-SP, IND-SS
143		 * MACNICA NE2098
144		 */
145	case ED_TYPE98_ICM:
146		/*
147		 * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET
148		 * D-Link DE-298P, DE-298
149		 */
150	case ED_TYPE98_EGY:
151		/*
152		 * MELCO EGY-98
153		 * Contec C-NET(98)E-A, C-NET(98)L-A
154		 */
155	case ED_TYPE98_108:
156		/*
157		 * NEC PC-9801-107,108
158		 */
159	case ED_TYPE98_NC5098:
160		/*
161		 * NextCom NC5098
162		 */
163		error = ed98_probe_Novell(dev, 0, flags);
164		break;
165
166	/*
167	 * other boards with special probe routine
168	 */
169	case ED_TYPE98_SIC:
170		/*
171		 * Allied Telesis SIC-98
172		 */
173		error = ed_probe_SIC98(dev, 0, flags);
174		break;
175
176	case ED_TYPE98_CNET98EL:
177		/*
178		 * Contec C-NET(98)E/L
179		 */
180		error = ed_probe_CNET98EL(dev, 0, flags);
181		break;
182
183	case ED_TYPE98_CNET98:
184		/*
185		 * Contec C-NET(98)
186		 */
187		error = ed_probe_CNET98(dev, 0, flags);
188		break;
189
190	case ED_TYPE98_LA98:
191		/*
192		 * IO-DATA LA/T-98
193		 * NEC PC-9801-77,78
194		 */
195		error = ed_probe_NEC77(dev, 0, flags);
196		break;
197
198	case ED_TYPE98_NW98X:
199		/*
200		 * Networld EC/EP-98X
201		 */
202		error = ed_probe_NW98X(dev, 0, flags);
203		break;
204
205	case ED_TYPE98_SB98:
206		/*
207		 * Soliton SB-9801
208		 * Fujikura FN-9801
209		 */
210		error = ed_probe_SB98(dev, 0, flags);
211		break;
212	}
213
214end:
215#ifdef ED_DEBUG
216	device_printf(dev, "ed_cbus_probe: end, error=%d\n", error);
217#endif
218	if (error == 0)
219		error = ed_alloc_irq(dev, 0, 0);
220
221	ed_release_resources(dev);
222	return (error);
223}
224
225static int
226ed_cbus_attach(dev)
227	device_t dev;
228{
229	struct ed_softc *sc = device_get_softc(dev);
230	int flags = device_get_flags(dev);
231	int error;
232
233	if (sc->port_used > 0) {
234		if (ED_TYPE98(flags) == ED_TYPE98_GENERIC)
235			ed_alloc_port(dev, sc->port_rid, sc->port_used);
236		else
237			ed98_alloc_port(dev, sc->port_rid);
238	}
239	if (sc->mem_used)
240		ed_alloc_memory(dev, sc->mem_rid, sc->mem_used);
241
242	ed_alloc_irq(dev, sc->irq_rid, 0);
243
244	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
245	    edintr, sc, &sc->irq_handle);
246	if (error) {
247		ed_release_resources(dev);
248		return (error);
249	}
250
251	return ed_attach(dev);
252}
253
254/*
255 * Interrupt conversion table for EtherEZ98
256 */
257static uint16_t ed_EZ98_intr_val[] = {
258	0,
259	3,
260	5,
261	6,
262	0,
263	9,
264	12,
265	13
266};
267
268static int
269ed_probe_EZ98(device_t dev, int port_rid, int flags)
270{
271	struct ed_softc *sc = device_get_softc(dev);
272	int error;
273	static unsigned short *intr_vals[] = {NULL, ed_EZ98_intr_val};
274
275	error = ed_alloc_port(dev, port_rid, ED_EZ98_IO_PORTS);
276	if (error) {
277		return (error);
278	}
279
280	sc->asic_offset = ED_EZ98_ASIC_OFFSET;
281	sc->nic_offset  = ED_EZ98_NIC_OFFSET;
282
283	return ed_probe_WD80x3_generic(dev, flags, intr_vals);
284}
285
286/*
287 * I/O conversion tables
288 */
289
290/* LGY-98, ICM, C-NET(98)E/L */
291static	bus_addr_t ed98_ioaddr_generic[] = {
292	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
293};
294
295/*
296 *		Definitions for Contec C-NET(98)E/L
297 */
298#define	ED_CNET98EL_ICR         2	/* Interrupt Configuration Register */
299
300#define	ED_CNET98EL_ICR_IRQ3	0x01
301#define	ED_CNET98EL_ICR_IRQ5	0x02
302#define	ED_CNET98EL_ICR_IRQ6	0x04
303#define	ED_CNET98EL_ICR_IRQ12	0x20
304
305#define	ED_CNET98EL_IMR         4	/* Interrupt Mask Register	*/
306#define	ED_CNET98EL_ISR         5	/* Interrupt Status Register	*/
307
308/* EGY-98 */
309static	bus_addr_t ed98_ioaddr_egy98[] = {
310	0,     0x02,  0x04,  0x06,  0x08,  0x0a,  0x0c,  0x0e,
311	0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e
312};
313
314/* SIC-98 */
315static	bus_addr_t ed98_ioaddr_sic98[] = {
316	0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00,
317	0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00
318};
319
320/* LA/T-98, LD-BDN, PC-9801-77, SB-9801 */
321static	bus_addr_t ed98_ioaddr_la98[] = {
322	0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000,
323	0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000,
324	0x0100	/* for NEC 77(see below) */
325};
326
327/*
328 *		Definitions for NEC PC-9801-77
329 */
330#define	ED_NEC77_IRQ		16	/* Interrupt Configuration Register */
331
332#define	ED_NEC77_IRQ3		0x04
333#define	ED_NEC77_IRQ5		0x06
334#define	ED_NEC77_IRQ6		0x08
335#define	ED_NEC77_IRQ12		0x0a
336#define	ED_NEC77_IRQ13		0x02
337
338/*
339 *		Definitions for Soliton SB-9801
340 */
341#define	ED_SB98_CFG		1	/* Board configuration		*/
342
343#define	ED_SB98_CFG_IRQ3	0x00
344#define	ED_SB98_CFG_IRQ5	0x04
345#define	ED_SB98_CFG_IRQ6	0x08
346#define	ED_SB98_CFG_IRQ12	0x0c
347#define	ED_SB98_CFG_ALTPORT	0x40		/* use EXTERNAL media	*/
348#define	ED_SB98_CFG_ENABLE	0xa0		/* enable configuration	*/
349
350#define	ED_SB98_EEPENA		2	/* EEPROM access enable		*/
351
352#define	ED_SB98_EEPENA_DISABLE	0x00
353#define	ED_SB98_EEPENA_ENABLE	0x01
354
355#define	ED_SB98_EEP		3	/* EEPROM access		*/
356
357#define	ED_SB98_EEP_SDA		0x01		/* Serial Data	*/
358#define	ED_SB98_EEP_SCL		0x02		/* Serial Clock	*/
359#define	ED_SB98_EEP_READ	0x01		/* Read Command	*/
360
361#define	ED_SB98_EEP_DELAY	300
362
363#define	ED_SB98_ADDRESS		0x01		/* Station Address(1-6)	*/
364
365#define	ED_SB98_POLARITY	4	/* Polarity			*/
366
367/* PC-9801-108 */
368static	bus_addr_t ed98_ioaddr_nec108[] = {
369	0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e,
370	0x1000, 0x1002, 0x1004, 0x1006, 0x1008, 0x100a, 0x100c, 0x100e
371};
372
373/* C-NET(98) */
374static	bus_addr_t ed98_ioaddr_cnet98[] = {
375	0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e,
376	0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e
377};
378
379/*
380 *		Definitions for Contec C-NET(98)
381 */
382#define	ED_CNET98_MAP_REG0L	0	/* MAPPING register0 Low	*/
383#define	ED_CNET98_MAP_REG1L	1	/* MAPPING register1 Low	*/
384#define	ED_CNET98_MAP_REG2L	2	/* MAPPING register2 Low	*/
385#define	ED_CNET98_MAP_REG3L	3	/* MAPPING register3 Low	*/
386#define	ED_CNET98_MAP_REG0H	4	/* MAPPING register0 Hi		*/
387#define	ED_CNET98_MAP_REG1H	5	/* MAPPING register1 Hi		*/
388#define	ED_CNET98_MAP_REG2H	6	/* MAPPING register2 Hi		*/
389#define	ED_CNET98_MAP_REG3H	7	/* MAPPING register3 Hi		*/
390#define	ED_CNET98_WIN_REG	8	/* Window register		*/
391#define	ED_CNET98_INT_LEV	9	/* Init level register		*/
392
393#define	ED_CNET98_INT_IRQ3	0x01		/* INT 0 */
394#define	ED_CNET98_INT_IRQ5	0x02		/* INT 1 */
395#define	ED_CNET98_INT_IRQ6	0x04		/* INT 2 */
396#define	ED_CNET98_INT_IRQ9	0x08		/* INT 3 */
397#define	ED_CNET98_INT_IRQ12	0x20		/* INT 5 */
398#define	ED_CNET98_INT_IRQ13	0x40		/* INT 6 */
399
400#define	ED_CNET98_INT_REQ	10	/* Init request register	*/
401#define	ED_CNET98_INT_MASK	11	/* Init mask register		*/
402#define	ED_CNET98_INT_STAT	12	/* Init status register		*/
403#define	ED_CNET98_INT_CLR	12	/* Init clear register		*/
404#define	ED_CNET98_RESERVE1	13
405#define	ED_CNET98_RESERVE2	14
406#define	ED_CNET98_RESERVE3	15
407
408/* EC/EP-98X, NC5098 */
409static	bus_addr_t ed98_ioaddr_nw98x[] = {
410	0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
411	0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00,
412	0x1000	/* for EC/EP-98X(see below) */
413};
414
415/*
416 *		Definitions for Networld EC/EP-98X
417 */
418#define	ED_NW98X_IRQ            16	/* Interrupt Configuration Register */
419
420#define	ED_NW98X_IRQ3           0x04
421#define	ED_NW98X_IRQ5           0x06
422#define	ED_NW98X_IRQ6           0x08
423#define	ED_NW98X_IRQ12          0x0a
424#define	ED_NW98X_IRQ13          0x02
425
426/* NC5098 ASIC */
427static bus_addr_t ed98_asic_nc5098[] = {
428/*	DATA    ENADDR						RESET	*/
429	0x0000, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x4000,
430	     0,      0,      0,      0,      0,      0,      0,      0
431};
432
433/*
434 *		Definitions for NextCom NC5098
435 */
436#define	ED_NC5098_ENADDR	1	/* Station Address(1-6)		*/
437
438/*
439 * Allocate a port resource with the given resource id.
440 */
441static int
442ed98_alloc_port(device_t dev, int rid)
443{
444	struct ed_softc *sc = device_get_softc(dev);
445	struct resource *res;
446	int error;
447	bus_addr_t *io_nic, *io_asic, adj;
448	static bus_addr_t io_res[ED_NOVELL_IO_PORTS + 1];
449	int i, n;
450	int offset, reset, data;
451
452	/* Set i/o table for resource manager */
453	io_nic = io_asic = ed98_ioaddr_generic;
454	offset = ED_NOVELL_ASIC_OFFSET;
455	reset = ED_NOVELL_RESET;
456	data  = ED_NOVELL_DATA;
457	n = ED_NOVELL_IO_PORTS;
458
459	switch (sc->type) {
460	case ED_TYPE98_LGY:
461		io_asic = ed98_ioaddr_egy98; /* XXX - Yes, we use egy98 */
462		offset = 0x0200;
463		reset = 8;
464		break;
465
466	case ED_TYPE98_EGY:
467		io_nic = io_asic = ed98_ioaddr_egy98;
468		offset = 0x0200;
469		reset = 8;
470		break;
471
472	case ED_TYPE98_ICM:
473		offset = 0x0100;
474		break;
475
476	case ED_TYPE98_BDN:
477		io_nic = io_asic = ed98_ioaddr_la98;
478		offset = 0x0100;
479		reset = 0x0c;
480		break;
481
482	case ED_TYPE98_SIC:
483		io_nic = io_asic = ed98_ioaddr_sic98;
484		offset = 0x2000;
485		n = 16+1;
486		break;
487
488	case ED_TYPE98_108:
489		io_nic = io_asic = ed98_ioaddr_nec108;
490		offset = 0x0888;	/* XXX - overwritten after */
491		reset = 1;
492		n = 16;	/* XXX - does not set ASIC i/o here */
493		break;
494
495	case ED_TYPE98_LA98:
496		io_nic = io_asic = ed98_ioaddr_la98;
497		offset = 0x0100;
498		break;
499
500	case ED_TYPE98_CNET98EL:
501		offset = 0x0400;
502		data = 0x0e;
503		break;
504
505	case ED_TYPE98_CNET98:
506		/* XXX - Yes, we use generic i/o here */
507		offset = 0x0400;
508		break;
509
510	case ED_TYPE98_NW98X:
511		io_nic = io_asic = ed98_ioaddr_nw98x;
512		offset = 0x1000;
513		break;
514
515	case ED_TYPE98_SB98:
516		io_nic = io_asic = ed98_ioaddr_la98;
517		offset = 0x0400;
518		reset = 7;
519		break;
520
521	case ED_TYPE98_NC5098:
522		io_nic  = ed98_ioaddr_nw98x;
523		io_asic = ed98_asic_nc5098;
524		offset = 0x2000;
525		reset = 7;
526		n = 16+8;	/* XXX */
527		break;
528	}
529
530	bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET);
531	for (i = ED_NOVELL_ASIC_OFFSET; i < ED_NOVELL_IO_PORTS; i++)
532		io_res[i] = io_asic[i - ED_NOVELL_ASIC_OFFSET] + offset;
533
534	res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, io_res, n,
535	    RF_ACTIVE);
536	if (!res)
537		return (ENOENT);
538
539	sc->port_rid = rid;
540	sc->port_res = res;
541	sc->port_used = n;
542
543	/* Re-map i/o table if needed */
544	switch (sc->type) {
545	case ED_TYPE98_LA98:
546	case ED_TYPE98_NW98X:
547		io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
548		n++;
549		break;
550
551	case ED_TYPE98_108:
552		adj = (rman_get_start(res) & 0xf000) / 2;
553		offset = (offset | adj) - rman_get_start(res);
554
555		for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++)
556			io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
557		break;
558
559	case ED_TYPE98_CNET98:
560		io_nic = io_asic = ed98_ioaddr_cnet98;
561		offset = 1;
562
563		bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET);
564		for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++)
565			io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
566		break;
567
568	case ED_TYPE98_NC5098:
569		n = ED_NOVELL_IO_PORTS;
570		break;
571	}
572
573	if (reset != ED_NOVELL_RESET)
574		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_RESET] =
575			io_res[ED_NOVELL_ASIC_OFFSET + reset];
576	if (data  != ED_NOVELL_DATA) {
577		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA] =
578			io_res[ED_NOVELL_ASIC_OFFSET + data];
579#if 0
580		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA + 1] =
581			io_res[ED_NOVELL_ASIC_OFFSET + data + 1];
582#endif
583	}
584
585	error = isa_load_resourcev(res, io_res, n);
586	if (error != 0)
587		return (ENOENT);
588#ifdef ED_DEBUG
589	device_printf(dev, "ed98_alloc_port: i/o ports = %d\n", n);
590	for (i = 0; i < n; i++)
591		printf("%x,", io_res[i]);
592	printf("\n");
593#endif
594	return (0);
595}
596
597static int
598ed98_alloc_memory(dev, rid)
599	device_t dev;
600	int rid;
601{
602	struct ed_softc *sc = device_get_softc(dev);
603	int error;
604	u_long conf_maddr, conf_msize;
605
606	error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &conf_maddr,
607	    &conf_msize);
608	if (error)
609		return (error);
610
611	if ((conf_maddr == 0) || (conf_msize == 0))
612		return (ENXIO);
613
614	error = ed_alloc_memory(dev, rid, (int) conf_msize);
615	if (error)
616		return (error);
617
618	sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res);
619	sc->mem_size  = conf_msize;
620
621	return (0);
622}
623
624/*
625 * Generic probe routine for testing for the existance of a DS8390.
626 *	Must be called after the NIC has just been reset. This routine
627 *	works by looking at certain register values that are guaranteed
628 *	to be initialized a certain way after power-up or reset. Seems
629 *	not to currently work on the 83C690.
630 *
631 * Specifically:
632 *
633 *	Register			reset bits	set bits
634 *	Command Register (CR)		TXP, STA	RD2, STP
635 *	Interrupt Status (ISR)				RST
636 *	Interrupt Mask (IMR)		All bits
637 *	Data Control (DCR)				LAS
638 *	Transmit Config. (TCR)		LB1, LB0
639 *
640 * XXX - We only check the CR register.
641 *
642 * Return 1 if 8390 was found, 0 if not.
643 */
644
645static int
646ed98_probe_generic8390(struct ed_softc *sc)
647{
648	u_char tmp = ed_nic_inb(sc, ED_P0_CR);
649#ifdef DIAGNOSTIC
650	printf("ed?: inb(ED_P0_CR)=%x\n", tmp);
651#endif
652	if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
653	    (ED_CR_RD2 | ED_CR_STP))
654		return (0);
655
656	(void) ed_nic_inb(sc, ED_P0_ISR);
657
658	return (1);
659}
660
661static int
662ed98_probe_Novell(device_t dev, int port_rid, int flags)
663{
664	struct ed_softc *sc = device_get_softc(dev);
665	int error;
666	int n;
667	u_char romdata[ETHER_ADDR_LEN * 2], tmp;
668
669#ifdef ED_DEBUG
670	device_printf(dev, "ed98_probe_Novell: start\n");
671#endif
672	error = ed98_alloc_port(dev, port_rid);
673	if (error)
674		return (error);
675
676	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
677	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
678
679	/* Reset the board */
680#ifdef ED_DEBUG
681	device_printf(dev, "ed98_probe_Novell: reset\n");
682#endif
683	switch (sc->type) {
684#if 1	/* XXX - I'm not sure this is really necessary... */
685	case ED_TYPE98_BDN:
686		tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
687		ed_asic_outb(sc, ED_NOVELL_RESET, (tmp & 0xf0) | 0x08);
688		ed_nic_outb(sc, 0x04, tmp);
689		(void) ed_asic_inb(sc, 0x08);
690		ed_asic_outb(sc, 0x08, tmp);
691		ed_asic_outb(sc, 0x08, tmp & 0x7f);
692		break;
693#endif
694	case ED_TYPE98_NC5098:
695		ed_asic_outb(sc, ED_NOVELL_RESET, 0x00);
696		DELAY(5000);
697		ed_asic_outb(sc, ED_NOVELL_RESET, 0x01);
698		break;
699
700	default:
701		tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
702
703	/*
704	 * I don't know if this is necessary; probably cruft leftover from
705	 * Clarkson packet driver code. Doesn't do a thing on the boards I've
706	 * tested. -DG [note that an outb(0x84, 0) seems to work here, and is
707	 * non-invasive...but some boards don't seem to reset and I don't have
708	 * complete documentation on what the 'right' thing to do is...so we
709	 * do the invasive thing for now. Yuck.]
710	 */
711		ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
712		break;
713	}
714	DELAY(5000);
715
716	/*
717	 * This is needed because some NE clones apparently don't reset the
718	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
719	 * - this makes the probe invasive! ...Done against my better
720	 * judgement. -DLG
721	 */
722	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
723	DELAY(5000);
724
725	/* Make sure that we really have an 8390 based board */
726	if (!ed98_probe_generic8390(sc))
727		return (ENXIO);
728
729	/* Test memory via PIO */
730#ifdef ED_DEBUG
731	device_printf(dev, "ed98_probe_Novell: test memory\n");
732#endif
733	sc->cr_proto = ED_CR_RD2;
734	if (!ed_pio_testmem(sc,  8192, 0, flags) &&
735	    !ed_pio_testmem(sc, 16384, 1, flags))
736		return (ENXIO);
737
738	/* Setup the board type */
739#ifdef ED_DEBUG
740	device_printf(dev, "ed98_probe_Novell: board type\n");
741#endif
742	switch (sc->type) {
743	case ED_TYPE98_BDN:
744		sc->type_str = "LD-BDN";
745		break;
746	case ED_TYPE98_EGY:
747		sc->type_str = "EGY-98";
748		break;
749	case ED_TYPE98_LGY:
750		sc->type_str = "LGY-98";
751		break;
752	case ED_TYPE98_ICM:
753		sc->type_str = "ICM";
754		break;
755	case ED_TYPE98_108:
756		sc->type_str = "PC-9801-108";
757		break;
758	case ED_TYPE98_LA98:
759		sc->type_str = "LA-98";
760		break;
761	case ED_TYPE98_NW98X:
762		sc->type_str = "NW98X";
763		break;
764	case ED_TYPE98_NC5098:
765		sc->type_str = "NC5098";
766		break;
767	default:
768		sc->type_str = NULL;
769		break;
770	}
771
772	/* Get station address */
773	switch (sc->type) {
774	case ED_TYPE98_NC5098:
775		for (n = 0; n < ETHER_ADDR_LEN; n++)
776			sc->arpcom.ac_enaddr[n] =
777				ed_asic_inb(sc, ED_NC5098_ENADDR + n);
778		break;
779
780	default:
781		ed_pio_readmem(sc, 0, romdata, sizeof(romdata));
782		for (n = 0; n < ETHER_ADDR_LEN; n++)
783			sc->arpcom.ac_enaddr[n] =
784				romdata[n * (sc->isa16bit + 1)];
785		break;
786	}
787
788	/* clear any pending interrupts that might have occurred above */
789	ed_nic_outb(sc, ED_P0_ISR, 0xff);
790
791	return (0);
792}
793
794/*
795 * Probe and vendor-specific initialization routine for SIC-98 boards
796 */
797static int
798ed_probe_SIC98(device_t dev, int port_rid, int flags)
799{
800	struct ed_softc *sc = device_get_softc(dev);
801	int error;
802	int i;
803	u_char sum;
804
805	/*
806	 * Setup card RAM and I/O address
807	 * Kernel Virtual to segment C0000-DFFFF????
808	 */
809	error = ed98_alloc_port(dev, port_rid);
810	if (error)
811		return (error);
812
813	sc->asic_offset = ED_SIC_ASIC_OFFSET;
814	sc->nic_offset  = ED_SIC_NIC_OFFSET;
815
816	error = ed98_alloc_memory(dev, 0);
817	if (error)
818		return (error);
819
820	/* Reset card to force it into a known state. */
821	ed_asic_outb(sc, 0, 0x00);
822	DELAY(100);
823	if (ED_TYPE98SUB(flags) == 0) {
824		/* SIC-98/SIU-98 */
825		ed_asic_outb(sc, 0, 0x94);
826		DELAY(100);
827		ed_asic_outb(sc, 0, 0x94);
828	} else {
829		/* SIU-98-D */
830		ed_asic_outb(sc, 0, 0x80);
831		DELAY(100);
832		ed_asic_outb(sc, 0, 0x94);
833		DELAY(100);
834		ed_asic_outb(sc, 0, 0x9e);
835	}
836	DELAY(100);
837
838	/*
839	 * Here we check the card ROM, if the checksum passes, and the
840	 * type code and ethernet address check out, then we know we have
841	 * an SIC card.
842	 */
843	sum = sc->mem_start[6 * 2];
844	for (i = 0; i < ETHER_ADDR_LEN; i++)
845		sum ^= (sc->arpcom.ac_enaddr[i] = sc->mem_start[i * 2]);
846#ifdef ED_DEBUG
847	device_printf(dev, "ed_probe_sic98: got address %6D\n",
848		      sc->arpcom.ac_enaddr, ":");
849#endif
850	if (sum != 0)
851		return (ENXIO);
852	if ((sc->arpcom.ac_enaddr[0] | sc->arpcom.ac_enaddr[1] |
853	     sc->arpcom.ac_enaddr[2]) == 0)
854		return (ENXIO);
855
856	sc->vendor   = ED_VENDOR_SIC;
857	sc->type_str = "SIC98";
858	sc->isa16bit = 1;
859	sc->cr_proto = 0;
860
861	/*
862	 * SIC RAM page 0x0000-0x3fff(or 0x7fff)
863	 */
864	if (ED_TYPE98SUB(flags) == 0)
865		ed_asic_outb(sc, 0, 0x90);
866	else
867		ed_asic_outb(sc, 0, 0x8e);
868	DELAY(100);
869
870	error = ed_clear_memory(dev);
871	if (error)
872		return (error);
873
874	sc->mem_shared = 1;
875	sc->mem_end = sc->mem_start + sc->mem_size;
876
877	/*
878	 * allocate one xmit buffer if < 16k, two buffers otherwise
879	 */
880	if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
881		sc->txb_cnt = 1;
882	else
883		sc->txb_cnt = 2;
884	sc->tx_page_start = 0;
885
886	sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt;
887	sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE;
888
889	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
890
891	return (0);
892}
893
894/*
895 * Contec C-NET(98) series support routines
896 */
897static void
898ed_reset_CNET98(struct ed_softc *sc, int flags)
899{
900	u_int init_addr = ED_CNET98_INIT;
901	u_char tmp;
902
903	/* Choose initial register address */
904	if (ED_TYPE98SUB(flags) != 0) {
905		init_addr = ED_CNET98_INIT2;
906	}
907#ifdef ED_DEBUG
908	printf("ed?: initial register=%x\n", init_addr);
909#endif
910	/*
911	 * Reset the board to force it into a known state.
912	 */
913	outb(init_addr, 0x00);	/* request */
914	DELAY(5000);
915	outb(init_addr, 0x01);	/* cancel */
916	DELAY(5000);
917
918	/*
919	 * Set I/O address(A15-12) and cpu type
920	 *
921	 *   AAAAIXXC(8bit)
922	 *   AAAA: A15-A12,  I: I/O enable, XX: reserved, C: CPU type
923	 *
924	 * CPU type is 1:80286 or higher, 0:not.
925	 * But FreeBSD runs under i386 or higher, thus it must be 1.
926	 */
927	tmp = (rman_get_start(sc->port_res) & 0xf000) >> 8;
928	tmp |= (0x08 | 0x01);
929#ifdef ED_DEBUG
930	printf("ed?: outb(%x, %x)\n", init_addr + 2, tmp);
931#endif
932	outb(init_addr + 2, tmp);
933	DELAY(5000);
934
935	/*
936	 * This is needed because some NE clones apparently don't reset the
937	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
938	 * - this makes the probe invasive! ...Done against my better
939	 * judgement. -DLG
940	 */
941	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
942	DELAY(5000);
943}
944
945static void
946ed_winsel_CNET98(struct ed_softc *sc, u_short bank)
947{
948	u_char mem = (rman_get_start(sc->mem_res) >> 12) & 0xff;
949
950	/*
951	 * Disable window memory
952	 *    bit7 is 0:disable
953	 */
954	ed_asic_outb(sc, ED_CNET98_WIN_REG, mem & 0x7f);
955	DELAY(10);
956
957	/*
958	 * Select window address
959	 *    FreeBSD address 0xf00xxxxx
960	 */
961	ed_asic_outb(sc, ED_CNET98_MAP_REG0L, bank & 0xff);
962	DELAY(10);
963	ed_asic_outb(sc, ED_CNET98_MAP_REG0H, (bank >> 8) & 0xff);
964	DELAY(10);
965	ed_asic_outb(sc, ED_CNET98_MAP_REG1L, 0x00);
966	DELAY(10);
967	ed_asic_outb(sc, ED_CNET98_MAP_REG1H, 0x41);
968	DELAY(10);
969	ed_asic_outb(sc, ED_CNET98_MAP_REG2L, 0x00);
970	DELAY(10);
971	ed_asic_outb(sc, ED_CNET98_MAP_REG2H, 0x42);
972	DELAY(10);
973	ed_asic_outb(sc, ED_CNET98_MAP_REG3L, 0x00);
974	DELAY(10);
975	ed_asic_outb(sc, ED_CNET98_MAP_REG3H, 0x43);
976	DELAY(10);
977
978	/*
979	 * Enable window memory(16Kbyte)
980	 *    bit7 is 1:enable
981	 */
982#ifdef ED_DEBUG
983	printf("ed?: window start address=%x\n", mem);
984#endif
985	ed_asic_outb(sc, ED_CNET98_WIN_REG, mem);
986	DELAY(10);
987}
988
989/*
990 * Probe and vendor-specific initialization routine for C-NET(98) boards
991 */
992static int
993ed_probe_CNET98(device_t dev, int port_rid, int flags)
994{
995	struct ed_softc *sc = device_get_softc(dev);
996	int error;
997	u_char tmp;
998	u_long conf_irq, junk;
999#ifdef DIAGNOSTIC
1000	u_char tmp_s;
1001#endif
1002
1003	error = ed98_alloc_port(dev, port_rid);
1004	if (error)
1005		return (error);
1006
1007	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1008	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1009
1010	error = ed98_alloc_memory(dev, 0);
1011	if (error)
1012		return (error);
1013
1014	/* Check I/O address. 0x[a-f]3d0 are allowed. */
1015	if (((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0)
1016	||  ((rman_get_start(sc->port_res) & 0xf000) < (u_short) 0xa000)) {
1017#ifdef DIAGNOSTIC
1018		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1019			"must be %s for %s\n", rman_get_start(sc->port_res),
1020			"0x[a-f]3d0", "CNET98");
1021#endif
1022		return (ENXIO);
1023	}
1024
1025#ifdef DIAGNOSTIC
1026	/* Check window area address */
1027	tmp_s = rman_get_start(sc->mem_res) >> 12;
1028	if (tmp_s < 0x80) {
1029		device_printf(dev, "Please change window address(0x%lx)\n",
1030		    rman_get_start(sc->mem_res));
1031		return (ENXIO);
1032	}
1033
1034	tmp_s &= 0x0f;
1035	tmp    = rman_get_start(sc->port_res) >> 12;
1036	if ((tmp_s <= tmp) && (tmp < (tmp_s + 4))) {
1037		device_printf(dev, "Please change iobase address(0x%lx) "
1038		    "or window address(0x%lx)\n",
1039		    rman_get_start(sc->port_res),
1040		    rman_get_start(sc->mem_res));
1041		return (ENXIO);
1042	}
1043#endif
1044	/* Reset the board */
1045	ed_reset_CNET98(sc, flags);
1046
1047	/*
1048	 * This is needed because some NE clones apparently don't reset the
1049	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1050	 * - this makes the probe invasive! ...Done against my better
1051	 * judgement. -DLG
1052	 */
1053	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1054	DELAY(5000);
1055
1056	/* Make sure that we really have an 8390 based board */
1057	if (!ed98_probe_generic8390(sc))
1058		return (ENXIO);
1059
1060	/*
1061	 *  Set window ethernet address area
1062	 *    board memory base 0x480000  data 256byte
1063	 */
1064	ed_winsel_CNET98(sc, 0x4800);
1065
1066	/*
1067	 * Get station address from on-board ROM
1068	 */
1069	bcopy(sc->mem_start, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
1070
1071	sc->vendor    = ED_VENDOR_MISC;
1072	sc->type_str  = "CNET98";
1073	sc->isa16bit  = 0;
1074	sc->cr_proto  = ED_CR_RD2;
1075
1076	/*
1077	 * Set window buffer memory area
1078	 *    board memory base 0x400000  data 16kbyte
1079	 */
1080	ed_winsel_CNET98(sc, 0x4000);
1081
1082	error = ed_clear_memory(dev);
1083	if (error)
1084		return (error);
1085
1086	sc->mem_shared = 1;
1087	sc->mem_end = sc->mem_start + sc->mem_size;
1088
1089	sc->txb_cnt = 1;	/* XXX */
1090	sc->tx_page_start = 0;
1091
1092	sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE;
1093	sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE;
1094
1095	sc->mem_ring = sc->mem_start + ED_PAGE_SIZE * ED_TXBUF_SIZE;
1096
1097	/*
1098	 *   Set interrupt level
1099	 */
1100	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1101	if (error)
1102		return (error);
1103
1104	switch (conf_irq) {
1105	case 3:
1106		tmp = ED_CNET98_INT_IRQ3;
1107		break;
1108	case 5:
1109		tmp = ED_CNET98_INT_IRQ5;
1110		break;
1111	case 6:
1112		tmp = ED_CNET98_INT_IRQ6;
1113		break;
1114	case 9:
1115		tmp = ED_CNET98_INT_IRQ9;
1116		break;
1117	case 12:
1118		tmp = ED_CNET98_INT_IRQ12;
1119		break;
1120	case 13:
1121		tmp = ED_CNET98_INT_IRQ13;
1122		break;
1123	default:
1124		device_printf(dev, "Invalid irq configuration (%ld) must be "
1125			"%s for %s\n", conf_irq, "3,5,6,9,12,13", "CNET98");
1126		return (ENXIO);
1127	}
1128	ed_asic_outb(sc, ED_CNET98_INT_LEV, tmp);
1129	DELAY(1000);
1130	/*
1131	 *   Set interrupt mask.
1132	 *     bit7:1 all interrupt mask
1133	 *     bit1:1 timer interrupt mask
1134	 *     bit0:0 NS controler interrupt enable
1135	 */
1136	ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e);
1137	DELAY(1000);
1138
1139	return (0);
1140}
1141
1142/*
1143 * Probe and vendor-specific initialization routine for C-NET(98)E/L boards
1144 */
1145static int
1146ed_probe_CNET98EL(device_t dev, int port_rid, int flags)
1147{
1148	struct ed_softc *sc = device_get_softc(dev);
1149	int error;
1150	int i;
1151	u_char romdata[ETHER_ADDR_LEN * 2], tmp;
1152	u_long conf_irq, junk;
1153
1154	error = ed98_alloc_port(dev, port_rid);
1155	if (error)
1156		return (error);
1157
1158	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1159	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1160
1161	/* Check I/O address. 0x[0-f]3d0 are allowed. */
1162	if ((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) {
1163#ifdef DIAGNOSTIC
1164		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1165			"must be %s for %s\n", rman_get_start(sc->port_res),
1166			"0x?3d0", "CNET98E/L");
1167#endif
1168		return (ENXIO);
1169	}
1170
1171	/* Reset the board */
1172	ed_reset_CNET98(sc, flags);
1173
1174	/*
1175	 * This is needed because some NE clones apparently don't reset the
1176	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1177	 * - this makes the probe invasive! ...Done against my better
1178	 * judgement. -DLG
1179	 */
1180	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1181	DELAY(5000);
1182
1183	/* Make sure that we really have an 8390 based board */
1184	if (!ed98_probe_generic8390(sc))
1185		return (ENXIO);
1186
1187	/* Test memory via PIO */
1188	sc->cr_proto = ED_CR_RD2;
1189	if (!ed_pio_testmem(sc, ED_CNET98EL_PAGE_OFFSET, 1, flags))
1190		return (ENXIO);
1191
1192	/* This looks like a C-NET(98)E/L board. */
1193	sc->type_str = "CNET98E/L";
1194
1195	/*
1196	 * Set IRQ. C-NET(98)E/L only allows a choice of irq 3,5,6.
1197	 */
1198	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1199	if (error)
1200		return (error);
1201
1202	switch (conf_irq) {
1203	case 3:
1204		tmp = ED_CNET98EL_ICR_IRQ3;
1205		break;
1206	case 5:
1207		tmp = ED_CNET98EL_ICR_IRQ5;
1208		break;
1209	case 6:
1210		tmp = ED_CNET98EL_ICR_IRQ6;
1211		break;
1212#if 0
1213	case 12:
1214		tmp = ED_CNET98EL_ICR_IRQ12;
1215		break;
1216#endif
1217	default:
1218		device_printf(dev, "Invalid irq configuration (%ld) must be "
1219			"%s for %s\n", conf_irq, "3,5,6", "CNET98E/L");
1220		return (ENXIO);
1221	}
1222	ed_asic_outb(sc, ED_CNET98EL_ICR, tmp);
1223	ed_asic_outb(sc, ED_CNET98EL_IMR, 0x7e);
1224
1225	/* Get station address from on-board ROM */
1226	ed_pio_readmem(sc, 16384, romdata, sizeof(romdata));
1227	for (i = 0; i < ETHER_ADDR_LEN; i++)
1228		sc->arpcom.ac_enaddr[i] = romdata[i * 2];
1229
1230	/* clear any pending interrupts that might have occurred above */
1231	ed_nic_outb(sc, ED_P0_ISR, 0xff);
1232
1233	return (0);
1234}
1235
1236/*
1237 * Probe and vendor-specific initialization routine for PC-9801-77 boards
1238 */
1239static int
1240ed_probe_NEC77(device_t dev, int port_rid, int flags)
1241{
1242	struct ed_softc *sc = device_get_softc(dev);
1243	int error;
1244	u_char tmp;
1245	u_long conf_irq, junk;
1246
1247	error = ed98_probe_Novell(dev, port_rid, flags);
1248	if (error)
1249		return (error);
1250
1251	/* LA/T-98 does not need IRQ setting. */
1252	if (ED_TYPE98SUB(flags) == 0)
1253		return (0);
1254
1255	/*
1256	 * Set IRQ. PC-9801-77 only allows a choice of irq 3,5,6,12,13.
1257	 */
1258	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1259	if (error)
1260		return (error);
1261
1262	switch (conf_irq) {
1263	case 3:
1264		tmp = ED_NEC77_IRQ3;
1265		break;
1266	case 5:
1267		tmp = ED_NEC77_IRQ5;
1268		break;
1269	case 6:
1270		tmp = ED_NEC77_IRQ6;
1271		break;
1272	case 12:
1273		tmp = ED_NEC77_IRQ12;
1274		break;
1275	case 13:
1276		tmp = ED_NEC77_IRQ13;
1277		break;
1278	default:
1279		device_printf(dev, "Invalid irq configuration (%ld) must be "
1280			"%s for %s\n", conf_irq, "3,5,6,12,13", "PC-9801-77");
1281		return (ENXIO);
1282	}
1283	ed_asic_outb(sc, ED_NEC77_IRQ, tmp);
1284
1285	return (0);
1286}
1287
1288/*
1289 * Probe and vendor-specific initialization routine for EC/EP-98X boards
1290 */
1291static int
1292ed_probe_NW98X(device_t dev, int port_rid, int flags)
1293{
1294	struct ed_softc *sc = device_get_softc(dev);
1295	int error;
1296	u_char tmp;
1297	u_long conf_irq, junk;
1298
1299	error = ed98_probe_Novell(dev, port_rid, flags);
1300	if (error)
1301		return (error);
1302
1303	/* Networld 98X3 does not need IRQ setting. */
1304	if (ED_TYPE98SUB(flags) == 0)
1305		return (0);
1306
1307	/*
1308	 * Set IRQ. EC/EP-98X only allows a choice of irq 3,5,6,12,13.
1309	 */
1310	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1311	if (error)
1312		return (error);
1313
1314	switch (conf_irq) {
1315	case 3:
1316		tmp = ED_NW98X_IRQ3;
1317		break;
1318	case 5:
1319		tmp = ED_NW98X_IRQ5;
1320		break;
1321	case 6:
1322		tmp = ED_NW98X_IRQ6;
1323		break;
1324	case 12:
1325		tmp = ED_NW98X_IRQ12;
1326		break;
1327	case 13:
1328		tmp = ED_NW98X_IRQ13;
1329		break;
1330	default:
1331		device_printf(dev, "Invalid irq configuration (%ld) must be "
1332			"%s for %s\n", conf_irq, "3,5,6,12,13", "EC/EP-98X");
1333		return (ENXIO);
1334	}
1335	ed_asic_outb(sc, ED_NW98X_IRQ, tmp);
1336
1337	return (0);
1338}
1339
1340/*
1341 * Read SB-9801 station address from Serial Two-Wire EEPROM
1342 */
1343static void
1344ed_get_SB98(struct ed_softc *sc)
1345{
1346	int i, j;
1347	u_char mask, val;
1348
1349        /* enable EEPROM acceess */
1350        ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_ENABLE);
1351
1352	/* output start command */
1353	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1354	DELAY(ED_SB98_EEP_DELAY);
1355	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1356	DELAY(ED_SB98_EEP_DELAY);
1357
1358       	/* output address (7bit) */
1359	for (mask = 0x40; mask != 0; mask >>= 1) {
1360		val = 0;
1361		if (ED_SB98_ADDRESS & mask)
1362			val = ED_SB98_EEP_SDA;
1363		ed_asic_outb(sc, ED_SB98_EEP, val);
1364		DELAY(ED_SB98_EEP_DELAY);
1365		ed_asic_outb(sc, ED_SB98_EEP, val | ED_SB98_EEP_SCL);
1366		DELAY(ED_SB98_EEP_DELAY);
1367	}
1368
1369	/* output READ command */
1370	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ);
1371	DELAY(ED_SB98_EEP_DELAY);
1372	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ | ED_SB98_EEP_SCL);
1373	DELAY(ED_SB98_EEP_DELAY);
1374
1375	/* read station address */
1376	for (i = 0; i < ETHER_ADDR_LEN; i++) {
1377		/* output ACK */
1378		ed_asic_outb(sc, ED_SB98_EEP, 0);
1379		DELAY(ED_SB98_EEP_DELAY);
1380		ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1381		DELAY(ED_SB98_EEP_DELAY);
1382
1383		val = 0;
1384		for (j = 0; j < 8; j++) {
1385			ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA);
1386			DELAY(ED_SB98_EEP_DELAY);
1387			ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1388			DELAY(ED_SB98_EEP_DELAY);
1389			val <<= 1;
1390			val |= (ed_asic_inb(sc, ED_SB98_EEP) & ED_SB98_EEP_SDA);
1391			DELAY(ED_SB98_EEP_DELAY);
1392	  	}
1393		sc->arpcom.ac_enaddr[i] = val;
1394	}
1395
1396	/* output Last ACK */
1397        ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA);
1398        DELAY(ED_SB98_EEP_DELAY);
1399        ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1400        DELAY(ED_SB98_EEP_DELAY);
1401
1402	/* output stop command */
1403	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1404	DELAY(ED_SB98_EEP_DELAY);
1405	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1406	DELAY(ED_SB98_EEP_DELAY);
1407
1408	/* disable EEPROM access */
1409	ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_DISABLE);
1410}
1411
1412/*
1413 * Probe and vendor-specific initialization routine for SB-9801 boards
1414 */
1415static int
1416ed_probe_SB98(device_t dev, int port_rid, int flags)
1417{
1418	struct ed_softc *sc = device_get_softc(dev);
1419	int error;
1420	u_char tmp;
1421	u_long conf_irq, junk;
1422
1423	error = ed98_alloc_port(dev, port_rid);
1424	if (error)
1425		return (error);
1426
1427	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1428	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1429
1430	/* Check I/O address. 00d[02468ace] are allowed. */
1431	if ((rman_get_start(sc->port_res) & ~0x000e) != 0x00d0) {
1432#ifdef DIAGNOSTIC
1433		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1434		    "must be %s for %s\n", rman_get_start(sc->port_res),
1435		    "0xd?", "SB9801");
1436#endif
1437		return (ENXIO);
1438	}
1439
1440	/* Write I/O port address and read 4 times */
1441	outb(ED_SB98_IO_INHIBIT, rman_get_start(sc->port_res) & 0xff);
1442	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1443	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1444	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1445	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1446
1447	/*
1448	 * Check IRQ. Soliton SB-9801 only allows a choice of
1449	 * irq 3,5,6,12
1450	 */
1451	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1452	if (error)
1453		return (error);
1454
1455	switch (conf_irq) {
1456	case 3:
1457		tmp = ED_SB98_CFG_IRQ3;
1458		break;
1459	case 5:
1460		tmp = ED_SB98_CFG_IRQ5;
1461		break;
1462	case 6:
1463		tmp = ED_SB98_CFG_IRQ6;
1464		break;
1465	case 12:
1466		tmp = ED_SB98_CFG_IRQ12;
1467		break;
1468	default:
1469		device_printf(dev, "Invalid irq configuration (%ld) must be "
1470			"%s for %s\n", conf_irq, "3,5,6,12", "SB9801");
1471		return (ENXIO);
1472	}
1473
1474	if (flags & ED_FLAGS_DISABLE_TRANCEIVER)
1475		tmp |= ED_SB98_CFG_ALTPORT;
1476	ed_asic_outb(sc, ED_SB98_CFG, ED_SB98_CFG_ENABLE | tmp);
1477	ed_asic_outb(sc, ED_SB98_POLARITY, 0x01);
1478
1479	/* Reset the board. */
1480	ed_asic_outb(sc, ED_NOVELL_RESET, 0x7a);
1481	DELAY(300);
1482	ed_asic_outb(sc, ED_NOVELL_RESET, 0x79);
1483	DELAY(300);
1484
1485	/*
1486	 * This is needed because some NE clones apparently don't reset the
1487	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1488	 * - this makes the probe invasive! ...Done against my better
1489	 * judgement. -DLG
1490	 */
1491	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1492	DELAY(5000);
1493
1494	/* Make sure that we really have an 8390 based board */
1495	if (!ed98_probe_generic8390(sc))
1496		return (ENXIO);
1497
1498	/* Test memory via PIO */
1499	sc->cr_proto = ED_CR_RD2;
1500	if (!ed_pio_testmem(sc, 16384, 1, flags)) {
1501		return (ENXIO);
1502	}
1503
1504	/* This looks like an SB9801 board. */
1505	sc->type_str = "SB9801";
1506
1507	/* Get station address */
1508	ed_get_SB98(sc);
1509
1510	/* clear any pending interrupts that might have occurred above */
1511	ed_nic_outb(sc, ED_P0_ISR, 0xff);
1512
1513	return (0);
1514}
1515
1516/*
1517 * Test the ability to read and write to the NIC memory.
1518 */
1519static int
1520ed_pio_testmem(struct ed_softc *sc, int page_offset, int isa16bit, int flags)
1521{
1522	u_long memsize;
1523	static char test_pattern[32] = "THIS is A memory TEST pattern";
1524	char test_buffer[32];
1525#ifdef DIAGNOSTIC
1526	int page_end;
1527#endif
1528
1529	sc->vendor = ED_VENDOR_NOVELL;
1530	sc->mem_shared = 0;
1531	sc->isa16bit = isa16bit;
1532
1533	/* 8k of memory plus an additional 8k if 16bit */
1534	memsize = (isa16bit ? 16384 : 8192);
1535
1536	/*
1537	 * This prevents packets from being stored in the NIC memory when the
1538	 * readmem routine turns on the start bit in the CR.
1539	 */
1540	ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
1541
1542	/* Initialize DCR for byte/word operations */
1543	if (isa16bit)
1544		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
1545	else
1546		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
1547	ed_nic_outb(sc, ED_P0_PSTART, page_offset / ED_PAGE_SIZE);
1548	ed_nic_outb(sc, ED_P0_PSTOP, (page_offset + memsize) / ED_PAGE_SIZE);
1549#ifdef ED_DEBUG
1550	printf("ed?: ed_pio_testmem: page start=%x, end=%lx",
1551	    page_offset, page_offset + memsize);
1552#endif
1553
1554	/*
1555	 * Write a test pattern. If this fails, then we don't know
1556	 * what this board is.
1557	 */
1558	ed_pio_writemem(sc, test_pattern, page_offset, sizeof(test_pattern));
1559	ed_pio_readmem(sc, page_offset, test_buffer, sizeof(test_pattern));
1560
1561	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
1562#ifdef ED_DEBUG
1563		printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_offset);
1564#endif
1565		return (0);
1566	}
1567
1568#ifdef DIAGNOSTIC
1569	/* Check the bottom. */
1570	page_end = page_offset + memsize - ED_PAGE_SIZE;
1571	ed_pio_writemem(sc, test_pattern, page_end, sizeof(test_pattern));
1572	ed_pio_readmem(sc, page_end, test_buffer, sizeof(test_pattern));
1573
1574	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
1575#ifdef ED_DEBUG
1576		printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_end);
1577#endif
1578		return (0);
1579	}
1580#endif
1581	sc->mem_size = memsize;
1582	sc->mem_start = (char *) page_offset;
1583	sc->mem_end   = sc->mem_start + memsize;
1584	sc->tx_page_start = page_offset / ED_PAGE_SIZE;
1585
1586	/*
1587	 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
1588	 * otherwise).
1589	 */
1590	if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
1591		sc->txb_cnt = 1;
1592	else
1593		sc->txb_cnt = 2;
1594
1595	sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
1596	sc->rec_page_stop  = sc->tx_page_start + memsize / ED_PAGE_SIZE;
1597
1598	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
1599
1600	return (1);
1601}
1602
1603static device_method_t ed_cbus_methods[] = {
1604	/* Device interface */
1605	DEVMETHOD(device_probe,		ed_cbus_probe),
1606	DEVMETHOD(device_attach,	ed_cbus_attach),
1607	DEVMETHOD(device_attach,	ed_detach),
1608
1609	{ 0, 0 }
1610};
1611
1612static driver_t ed_cbus_driver = {
1613	"ed",
1614	ed_cbus_methods,
1615	sizeof(struct ed_softc)
1616};
1617
1618DRIVER_MODULE(ed, isa, ed_cbus_driver, ed_devclass, 0, 0);
1619MODULE_DEPEND(ed, isa, 1, 1, 1);
1620MODULE_DEPEND(ed, ether, 1, 1, 1);
1621