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