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