if_ed_cbus.c revision 191234
1112125Ssam/*-
2112125Ssam * Copyright (c) 1995, David Greenman
3139749Simp * All rights reserved.
4112125Ssam *
5112125Ssam * Redistribution and use in source and binary forms, with or without
6112125Ssam * modification, are permitted provided that the following conditions
7112125Ssam * are met:
8112125Ssam * 1. Redistributions of source code must retain the above copyright
9112125Ssam *    notice unmodified, this list of conditions, and the following
10112125Ssam *    disclaimer.
11112125Ssam * 2. Redistributions in binary form must reproduce the above copyright
12112125Ssam *    notice, this list of conditions and the following disclaimer in the
13112125Ssam *    documentation and/or other materials provided with the distribution.
14112125Ssam *
15112125Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16112125Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17112125Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18112125Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19112125Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20112125Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21112125Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22112125Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23112125Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24112125Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25112125Ssam * SUCH DAMAGE.
26112125Ssam *
27112125Ssam * $FreeBSD: head/sys/dev/ed/if_ed_cbus.c 191234 2009-04-18 03:10:28Z imp $
28112125Ssam */
29112125Ssam
30112125Ssam#include <sys/param.h>
31112125Ssam#include <sys/systm.h>
32112125Ssam#include <sys/socket.h>
33112125Ssam#include <sys/kernel.h>
34119418Sobrien
35119418Sobrien#include <sys/module.h>
36119418Sobrien#include <sys/bus.h>
37112125Ssam#include <machine/bus.h>
38112125Ssam#include <sys/rman.h>
39112125Ssam#include <machine/resource.h>
40112125Ssam
41112125Ssam#include <net/ethernet.h>
42112125Ssam#include <net/if.h>
43112125Ssam#include <net/if_arp.h>
44112125Ssam#include <net/if_media.h>
45112125Ssam#include <net/if_mib.h>
46112125Ssam
47112125Ssam#include <isa/isavar.h>
48112125Ssam
49112125Ssam#include <dev/ed/if_edvar.h>
50112125Ssam#include <dev/ed/if_edreg.h>
51112125Ssam#include <dev/ed/if_ed98.h>
52112125Ssam
53112125Ssamstatic int ed98_alloc_port(device_t, int);
54112125Ssamstatic int ed98_alloc_memory(device_t, int);
55112125Ssamstatic int ed_pio_testmem(struct ed_softc *, int, int, int);
56112125Ssamstatic int ed_probe_CNET98(device_t, int, int);
57112125Ssamstatic int ed_probe_CNET98EL(device_t, int, int);
58112125Ssamstatic int ed_probe_EZ98(device_t, int, int);
59112125Ssamstatic int ed_probe_NEC77(device_t, int, int);
60112125Ssamstatic int ed_probe_NW98X(device_t, int, int);
61112125Ssamstatic int ed_probe_SB98(device_t, int, int);
62112125Ssamstatic int ed_probe_SIC98(device_t, int, int);
63112125Ssamstatic int ed98_probe_Novell(device_t, int, int);
64112125Ssamstatic int ed98_probe_generic8390(struct ed_softc *);
65112125Ssamstatic void ed_reset_CNET98(struct ed_softc *, int);
66112125Ssamstatic void ed_winsel_CNET98(struct ed_softc *, u_short);
67112125Ssamstatic void ed_get_SB98(struct ed_softc *);
68112125Ssam
69112125Ssamstatic int ed_cbus_probe(device_t);
70112125Ssamstatic int ed_cbus_attach(device_t);
71112125Ssam
72112125Ssamstatic struct isa_pnp_id ed_ids[] = {
73227309Sed/* TODO - list up PnP boards for PC-98 */
74227309Sed	{ 0,		NULL }
75112125Ssam};
76116815Ssam
77112125Ssamstatic int
78112125Ssamed_cbus_probe(device_t dev)
79112125Ssam{
80112125Ssam	struct ed_softc *sc = device_get_softc(dev);
81112125Ssam	int flags = device_get_flags(dev);
82112125Ssam	int error = 0;
83112125Ssam
84112125Ssam	sc->type = ED_TYPE98(flags);
85112125Ssam#ifdef ED_DEBUG
86112125Ssam	device_printf(dev, "ed_cbus_probe: sc->type=%x\n", sc->type);
87112125Ssam#endif
88112125Ssam
89112125Ssam	/* Check isapnp ids */
90112125Ssam	error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids);
91112125Ssam#ifdef ED_DEBUG
92112125Ssam	device_printf(dev, "ed_cbus_probe: ISA_PNP_PROBE returns %d\n", error);
93112125Ssam#endif
94112125Ssam
95112125Ssam	/* If the card had a PnP ID that didn't match any we know about */
96112125Ssam	if (error == ENXIO)
97112125Ssam		goto end;
98116815Ssam
99116815Ssam	/* If we had some other problem. */
100116815Ssam	if (!(error == 0 || error == ENOENT))
101119137Ssam		goto end;
102116815Ssam
103112125Ssam	/* Heuristic probes */
104112125Ssam#ifdef ED_DEBUG
105112125Ssam	device_printf(dev, "ed_cbus_probe: Heuristic probes start\n");
106112125Ssam#endif
107112125Ssam	switch (sc->type) {
108112125Ssam	case ED_TYPE98_GENERIC:
109112125Ssam		/*
110112125Ssam		 * CAUTION!
111112125Ssam		 * sc->type of these boards are overwritten by PC/AT's value.
112112125Ssam		 */
113112125Ssam
114112125Ssam		/*
115112125Ssam		 * SMC EtherEZ98
116112125Ssam		 */
117112125Ssam		error = ed_probe_EZ98(dev, 0, flags);
118116815Ssam		if (error == 0)
119112125Ssam			goto end;
120112125Ssam
121112125Ssam		ed_release_resources(dev);
122112125Ssam
123112125Ssam		/*
124112125Ssam		 * Allied Telesis CenterCom LA-98-T
125112125Ssam		 */
126112125Ssam		error = ed_probe_Novell(dev, 0, flags);
127112125Ssam		if (error == 0) {
128112125Ssam			ed_Novell_read_mac(sc);
129112125Ssam			goto end;
130112125Ssam		}
131112125Ssam		break;
132112125Ssam
133112125Ssam	/*
134112125Ssam	 * NE2000-like boards probe routine
135112125Ssam	 */
136112125Ssam	case ED_TYPE98_BDN:
137112125Ssam		/*
138112125Ssam		 * ELECOM LANEED LD-BDN
139112125Ssam		 * PLANET SMART COM 98 EN-2298
140112125Ssam		 */
141112125Ssam	case ED_TYPE98_LGY:
142112125Ssam		/*
143112125Ssam		 * MELCO LGY-98, IND-SP, IND-SS
144112125Ssam		 * MACNICA NE2098
145112125Ssam		 */
146112125Ssam	case ED_TYPE98_ICM:
147112125Ssam		/*
148116815Ssam		 * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET
149116815Ssam		 * D-Link DE-298P, DE-298
150116815Ssam		 */
151116815Ssam	case ED_TYPE98_EGY:
152116815Ssam		/*
153116815Ssam		 * MELCO EGY-98
154116815Ssam		 * Contec C-NET(98)E-A, C-NET(98)L-A
155256381Smarkm		 */
156116815Ssam	case ED_TYPE98_108:
157116815Ssam		/*
158112125Ssam		 * NEC PC-9801-107,108
159112125Ssam		 */
160112125Ssam	case ED_TYPE98_NC5098:
161112125Ssam		/*
162112125Ssam		 * NextCom NC5098
163112125Ssam		 */
164112125Ssam		error = ed98_probe_Novell(dev, 0, flags);
165112125Ssam		break;
166112125Ssam
167112125Ssam	/*
168112125Ssam	 * other boards with special probe routine
169112125Ssam	 */
170112125Ssam	case ED_TYPE98_SIC:
171112125Ssam		/*
172112125Ssam		 * Allied Telesis SIC-98
173112125Ssam		 */
174112125Ssam		error = ed_probe_SIC98(dev, 0, flags);
175112125Ssam		break;
176112125Ssam
177112125Ssam	case ED_TYPE98_CNET98EL:
178112125Ssam		/*
179112125Ssam		 * Contec C-NET(98)E/L
180112125Ssam		 */
181112125Ssam		error = ed_probe_CNET98EL(dev, 0, flags);
182112125Ssam		break;
183112125Ssam
184112125Ssam	case ED_TYPE98_CNET98:
185112125Ssam		/*
186112125Ssam		 * Contec C-NET(98)
187112125Ssam		 */
188112125Ssam		error = ed_probe_CNET98(dev, 0, flags);
189112125Ssam		break;
190112125Ssam
191112125Ssam	case ED_TYPE98_LA98:
192112125Ssam		/*
193112125Ssam		 * IO-DATA LA/T-98
194112125Ssam		 * NEC PC-9801-77,78
195112125Ssam		 */
196112125Ssam		error = ed_probe_NEC77(dev, 0, flags);
197112125Ssam		break;
198112125Ssam
199112125Ssam	case ED_TYPE98_NW98X:
200112125Ssam		/*
201112125Ssam		 * Networld EC/EP-98X
202112125Ssam		 */
203112125Ssam		error = ed_probe_NW98X(dev, 0, flags);
204112125Ssam		break;
205112125Ssam
206112125Ssam	case ED_TYPE98_SB98:
207112125Ssam		/*
208112125Ssam		 * Soliton SB-9801
209112125Ssam		 * Fujikura FN-9801
210112125Ssam		 */
211112125Ssam		error = ed_probe_SB98(dev, 0, flags);
212112125Ssam		break;
213112125Ssam	}
214112125Ssam
215112125Ssamend:
216112125Ssam#ifdef ED_DEBUG
217112125Ssam	device_printf(dev, "ed_cbus_probe: end, error=%d\n", error);
218112125Ssam#endif
219112125Ssam	if (error == 0)
220112125Ssam		error = ed_alloc_irq(dev, 0, 0);
221112125Ssam
222112125Ssam	ed_release_resources(dev);
223112125Ssam	return (error);
224112125Ssam}
225112125Ssam
226112125Ssamstatic int
227112125Ssamed_cbus_attach(dev)
228112125Ssam	device_t dev;
229112125Ssam{
230112125Ssam	struct ed_softc *sc = device_get_softc(dev);
231112125Ssam	int flags = device_get_flags(dev);
232112125Ssam	int error;
233112125Ssam
234112125Ssam	if (sc->port_used > 0) {
235112125Ssam		if (ED_TYPE98(flags) == ED_TYPE98_GENERIC)
236112125Ssam			ed_alloc_port(dev, sc->port_rid, sc->port_used);
237112125Ssam		else
238112125Ssam			ed98_alloc_port(dev, sc->port_rid);
239112125Ssam	}
240112125Ssam	if (sc->mem_used)
241112125Ssam		ed_alloc_memory(dev, sc->mem_rid, sc->mem_used);
242112125Ssam
243112125Ssam	ed_alloc_irq(dev, sc->irq_rid, 0);
244112125Ssam
245112125Ssam	if (sc->sc_media_ioctl == NULL)
246112125Ssam		ed_gen_ifmedia_init(sc);
247112125Ssam	error = ed_attach(dev);
248112125Ssam	if (error) {
249112125Ssam		ed_release_resources(dev);
250112125Ssam		return (error);
251112125Ssam	}
252112125Ssam	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
253112125Ssam	    NULL, edintr, sc, &sc->irq_handle);
254112125Ssam	if (error)
255112125Ssam		ed_release_resources(dev);
256112125Ssam	return (error);
257112125Ssam}
258112125Ssam
259112125Ssam/*
260112125Ssam * Interrupt conversion table for EtherEZ98
261112125Ssam */
262112125Ssamstatic uint16_t ed_EZ98_intr_val[] = {
263112125Ssam	0,
264112125Ssam	3,
265112125Ssam	5,
266112125Ssam	6,
267112125Ssam	0,
268112125Ssam	9,
269112125Ssam	12,
270112125Ssam	13
271112125Ssam};
272112125Ssam
273112125Ssamstatic int
274112125Ssamed_probe_EZ98(device_t dev, int port_rid, int flags)
275112125Ssam{
276112125Ssam	struct ed_softc *sc = device_get_softc(dev);
277112125Ssam	int error;
278112125Ssam	static unsigned short *intr_vals[] = {NULL, ed_EZ98_intr_val};
279112125Ssam
280112125Ssam	error = ed_alloc_port(dev, port_rid, ED_EZ98_IO_PORTS);
281112125Ssam	if (error) {
282112125Ssam		return (error);
283112125Ssam	}
284112125Ssam
285112125Ssam	sc->asic_offset = ED_EZ98_ASIC_OFFSET;
286112125Ssam	sc->nic_offset  = ED_EZ98_NIC_OFFSET;
287112125Ssam
288112125Ssam	return ed_probe_WD80x3_generic(dev, flags, intr_vals);
289112125Ssam}
290112125Ssam
291112125Ssam/*
292112125Ssam * I/O conversion tables
293112125Ssam */
294112125Ssam
295112125Ssam/* LGY-98, ICM, C-NET(98)E/L */
296112125Ssamstatic	bus_addr_t ed98_ioaddr_generic[] = {
297112125Ssam	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
298112125Ssam};
299112125Ssam
300112125Ssam/*
301112125Ssam *		Definitions for Contec C-NET(98)E/L
302112125Ssam */
303112125Ssam#define	ED_CNET98EL_ICR         2	/* Interrupt Configuration Register */
304112125Ssam
305112125Ssam#define	ED_CNET98EL_ICR_IRQ3	0x01
306112125Ssam#define	ED_CNET98EL_ICR_IRQ5	0x02
307112125Ssam#define	ED_CNET98EL_ICR_IRQ6	0x04
308112125Ssam#define	ED_CNET98EL_ICR_IRQ12	0x20
309112125Ssam
310112125Ssam#define	ED_CNET98EL_IMR         4	/* Interrupt Mask Register	*/
311112125Ssam#define	ED_CNET98EL_ISR         5	/* Interrupt Status Register	*/
312112125Ssam
313112125Ssam/* EGY-98 */
314112125Ssamstatic	bus_addr_t ed98_ioaddr_egy98[] = {
315112125Ssam	0,     0x02,  0x04,  0x06,  0x08,  0x0a,  0x0c,  0x0e,
316112125Ssam	0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e
317112125Ssam};
318112125Ssam
319112125Ssam/* SIC-98 */
320112125Ssamstatic	bus_addr_t ed98_ioaddr_sic98[] = {
321112125Ssam	0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00,
322112125Ssam	0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00
323112125Ssam};
324112125Ssam
325112125Ssam/* LA/T-98, LD-BDN, PC-9801-77, SB-9801 */
326112125Ssamstatic	bus_addr_t ed98_ioaddr_la98[] = {
327112125Ssam	0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000,
328112125Ssam	0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000,
329112125Ssam	0x0100	/* for NEC 77(see below) */
330112125Ssam};
331112125Ssam
332112125Ssam/*
333112125Ssam *		Definitions for NEC PC-9801-77
334112125Ssam */
335112125Ssam#define	ED_NEC77_IRQ		16	/* Interrupt Configuration Register */
336112125Ssam
337112125Ssam#define	ED_NEC77_IRQ3		0x04
338112125Ssam#define	ED_NEC77_IRQ5		0x06
339112125Ssam#define	ED_NEC77_IRQ6		0x08
340112125Ssam#define	ED_NEC77_IRQ12		0x0a
341112125Ssam#define	ED_NEC77_IRQ13		0x02
342112125Ssam
343112125Ssam/*
344112125Ssam *		Definitions for Soliton SB-9801
345112125Ssam */
346112125Ssam#define	ED_SB98_CFG		1	/* Board configuration		*/
347112125Ssam
348112125Ssam#define	ED_SB98_CFG_IRQ3	0x00
349112125Ssam#define	ED_SB98_CFG_IRQ5	0x04
350112125Ssam#define	ED_SB98_CFG_IRQ6	0x08
351112125Ssam#define	ED_SB98_CFG_IRQ12	0x0c
352112125Ssam#define	ED_SB98_CFG_ALTPORT	0x40		/* use EXTERNAL media	*/
353112125Ssam#define	ED_SB98_CFG_ENABLE	0xa0		/* enable configuration	*/
354112125Ssam
355112125Ssam#define	ED_SB98_EEPENA		2	/* EEPROM access enable		*/
356112125Ssam
357112125Ssam#define	ED_SB98_EEPENA_DISABLE	0x00
358112125Ssam#define	ED_SB98_EEPENA_ENABLE	0x01
359112125Ssam
360112125Ssam#define	ED_SB98_EEP		3	/* EEPROM access		*/
361112125Ssam
362112125Ssam#define	ED_SB98_EEP_SDA		0x01		/* Serial Data	*/
363249582Sgabor#define	ED_SB98_EEP_SCL		0x02		/* Serial Clock	*/
364112125Ssam#define	ED_SB98_EEP_READ	0x01		/* Read Command	*/
365112125Ssam
366112125Ssam#define	ED_SB98_EEP_DELAY	300
367112125Ssam
368112125Ssam#define	ED_SB98_ADDRESS		0x01		/* Station Address(1-6)	*/
369112125Ssam
370112125Ssam#define	ED_SB98_POLARITY	4	/* Polarity			*/
371112125Ssam
372112125Ssam/* PC-9801-108 */
373112125Ssamstatic	bus_addr_t ed98_ioaddr_nec108[] = {
374112125Ssam	0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e,
375112125Ssam	0x1000, 0x1002, 0x1004, 0x1006, 0x1008, 0x100a, 0x100c, 0x100e
376112125Ssam};
377112125Ssam
378112125Ssam/* C-NET(98) */
379112125Ssamstatic	bus_addr_t ed98_ioaddr_cnet98[] = {
380112125Ssam	0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e,
381112125Ssam	0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e
382112125Ssam};
383112125Ssam
384112125Ssam/*
385112125Ssam *		Definitions for Contec C-NET(98)
386112125Ssam */
387112125Ssam#define	ED_CNET98_MAP_REG0L	0	/* MAPPING register0 Low	*/
388112125Ssam#define	ED_CNET98_MAP_REG1L	1	/* MAPPING register1 Low	*/
389112125Ssam#define	ED_CNET98_MAP_REG2L	2	/* MAPPING register2 Low	*/
390112125Ssam#define	ED_CNET98_MAP_REG3L	3	/* MAPPING register3 Low	*/
391112125Ssam#define	ED_CNET98_MAP_REG0H	4	/* MAPPING register0 Hi		*/
392112125Ssam#define	ED_CNET98_MAP_REG1H	5	/* MAPPING register1 Hi		*/
393112125Ssam#define	ED_CNET98_MAP_REG2H	6	/* MAPPING register2 Hi		*/
394112125Ssam#define	ED_CNET98_MAP_REG3H	7	/* MAPPING register3 Hi		*/
395112125Ssam#define	ED_CNET98_WIN_REG	8	/* Window register		*/
396112125Ssam#define	ED_CNET98_INT_LEV	9	/* Init level register		*/
397112125Ssam
398112125Ssam#define	ED_CNET98_INT_IRQ3	0x01		/* INT 0 */
399112125Ssam#define	ED_CNET98_INT_IRQ5	0x02		/* INT 1 */
400112125Ssam#define	ED_CNET98_INT_IRQ6	0x04		/* INT 2 */
401112125Ssam#define	ED_CNET98_INT_IRQ9	0x08		/* INT 3 */
402112125Ssam#define	ED_CNET98_INT_IRQ12	0x20		/* INT 5 */
403112125Ssam#define	ED_CNET98_INT_IRQ13	0x40		/* INT 6 */
404112125Ssam
405241394Skevlo#define	ED_CNET98_INT_REQ	10	/* Init request register	*/
406112125Ssam#define	ED_CNET98_INT_MASK	11	/* Init mask register		*/
407112125Ssam#define	ED_CNET98_INT_STAT	12	/* Init status register		*/
408112125Ssam#define	ED_CNET98_INT_CLR	12	/* Init clear register		*/
409#define	ED_CNET98_RESERVE1	13
410#define	ED_CNET98_RESERVE2	14
411#define	ED_CNET98_RESERVE3	15
412
413/* EC/EP-98X, NC5098 */
414static	bus_addr_t ed98_ioaddr_nw98x[] = {
415	0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
416	0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00,
417	0x1000	/* for EC/EP-98X(see below) */
418};
419
420/*
421 *		Definitions for Networld EC/EP-98X
422 */
423#define	ED_NW98X_IRQ            16	/* Interrupt Configuration Register */
424
425#define	ED_NW98X_IRQ3           0x04
426#define	ED_NW98X_IRQ5           0x06
427#define	ED_NW98X_IRQ6           0x08
428#define	ED_NW98X_IRQ12          0x0a
429#define	ED_NW98X_IRQ13          0x02
430
431/* NC5098 ASIC */
432static bus_addr_t ed98_asic_nc5098[] = {
433/*	DATA    ENADDR						RESET	*/
434	0x0000, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x4000,
435	     0,      0,      0,      0,      0,      0,      0,      0
436};
437
438/*
439 *		Definitions for NextCom NC5098
440 */
441#define	ED_NC5098_ENADDR	1	/* Station Address(1-6)		*/
442
443/*
444 * Allocate a port resource with the given resource id.
445 */
446static int
447ed98_alloc_port(device_t dev, int rid)
448{
449	struct ed_softc *sc = device_get_softc(dev);
450	struct resource *res;
451	int error;
452	bus_addr_t *io_nic, *io_asic, adj;
453	static bus_addr_t io_res[ED_NOVELL_IO_PORTS + 1];
454	int i, n;
455	int offset, reset, data;
456
457	/* Set i/o table for resource manager */
458	io_nic = io_asic = ed98_ioaddr_generic;
459	offset = ED_NOVELL_ASIC_OFFSET;
460	reset = ED_NOVELL_RESET;
461	data  = ED_NOVELL_DATA;
462	n = ED_NOVELL_IO_PORTS;
463
464	switch (sc->type) {
465	case ED_TYPE98_LGY:
466		io_asic = ed98_ioaddr_egy98; /* XXX - Yes, we use egy98 */
467		offset = 0x0200;
468		reset = 8;
469		break;
470
471	case ED_TYPE98_EGY:
472		io_nic = io_asic = ed98_ioaddr_egy98;
473		offset = 0x0200;
474		reset = 8;
475		break;
476
477	case ED_TYPE98_ICM:
478		offset = 0x0100;
479		break;
480
481	case ED_TYPE98_BDN:
482		io_nic = io_asic = ed98_ioaddr_la98;
483		offset = 0x0100;
484		reset = 0x0c;
485		break;
486
487	case ED_TYPE98_SIC:
488		io_nic = io_asic = ed98_ioaddr_sic98;
489		offset = 0x2000;
490		n = 16+1;
491		break;
492
493	case ED_TYPE98_108:
494		io_nic = io_asic = ed98_ioaddr_nec108;
495		offset = 0x0888;	/* XXX - overwritten after */
496		reset = 1;
497		n = 16;	/* XXX - does not set ASIC i/o here */
498		break;
499
500	case ED_TYPE98_LA98:
501		io_nic = io_asic = ed98_ioaddr_la98;
502		offset = 0x0100;
503		break;
504
505	case ED_TYPE98_CNET98EL:
506		offset = 0x0400;
507		data = 0x0e;
508		break;
509
510	case ED_TYPE98_CNET98:
511		/* XXX - Yes, we use generic i/o here */
512		offset = 0x0400;
513		break;
514
515	case ED_TYPE98_NW98X:
516		io_nic = io_asic = ed98_ioaddr_nw98x;
517		offset = 0x1000;
518		break;
519
520	case ED_TYPE98_SB98:
521		io_nic = io_asic = ed98_ioaddr_la98;
522		offset = 0x0400;
523		reset = 7;
524		break;
525
526	case ED_TYPE98_NC5098:
527		io_nic  = ed98_ioaddr_nw98x;
528		io_asic = ed98_asic_nc5098;
529		offset = 0x2000;
530		reset = 7;
531		n = 16+8;	/* XXX */
532		break;
533	}
534
535	bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET);
536	for (i = ED_NOVELL_ASIC_OFFSET; i < ED_NOVELL_IO_PORTS; i++)
537		io_res[i] = io_asic[i - ED_NOVELL_ASIC_OFFSET] + offset;
538
539	res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, io_res, n,
540	    RF_ACTIVE);
541	if (!res)
542		return (ENOENT);
543
544	sc->port_rid = rid;
545	sc->port_res = res;
546	sc->port_used = n;
547	sc->port_bst = rman_get_bustag(res);
548	sc->port_bsh = rman_get_bushandle(res);
549
550	/* Re-map i/o table if needed */
551	switch (sc->type) {
552	case ED_TYPE98_LA98:
553	case ED_TYPE98_NW98X:
554		io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
555		n++;
556		break;
557
558	case ED_TYPE98_108:
559		adj = (rman_get_start(res) & 0xf000) / 2;
560		offset = (offset | adj) - rman_get_start(res);
561
562		for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++)
563			io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
564		break;
565
566	case ED_TYPE98_CNET98:
567		io_nic = io_asic = ed98_ioaddr_cnet98;
568		offset = 1;
569
570		bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET);
571		for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++)
572			io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
573		break;
574
575	case ED_TYPE98_NC5098:
576		n = ED_NOVELL_IO_PORTS;
577		break;
578	}
579
580	if (reset != ED_NOVELL_RESET)
581		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_RESET] =
582			io_res[ED_NOVELL_ASIC_OFFSET + reset];
583	if (data  != ED_NOVELL_DATA) {
584		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA] =
585			io_res[ED_NOVELL_ASIC_OFFSET + data];
586#if 0
587		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA + 1] =
588			io_res[ED_NOVELL_ASIC_OFFSET + data + 1];
589#endif
590	}
591
592	error = isa_load_resourcev(res, io_res, n);
593	if (error != 0)
594		return (ENOENT);
595#ifdef ED_DEBUG
596	device_printf(dev, "ed98_alloc_port: i/o ports = %d\n", n);
597	for (i = 0; i < n; i++)
598		printf("%x,", io_res[i]);
599	printf("\n");
600#endif
601	return (0);
602}
603
604static int
605ed98_alloc_memory(dev, rid)
606	device_t dev;
607	int rid;
608{
609	struct ed_softc *sc = device_get_softc(dev);
610	int error;
611	u_long conf_maddr, conf_msize;
612
613	error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &conf_maddr,
614	    &conf_msize);
615	if (error)
616		return (error);
617
618	if ((conf_maddr == 0) || (conf_msize == 0))
619		return (ENXIO);
620
621	error = ed_alloc_memory(dev, rid, (int) conf_msize);
622	if (error)
623		return (error);
624
625	sc->mem_start = 0;
626	sc->mem_size  = conf_msize;
627
628	return (0);
629}
630
631/*
632 * Generic probe routine for testing for the existance of a DS8390.
633 *	Must be called after the NIC has just been reset. This routine
634 *	works by looking at certain register values that are guaranteed
635 *	to be initialized a certain way after power-up or reset. Seems
636 *	not to currently work on the 83C690.
637 *
638 * Specifically:
639 *
640 *	Register			reset bits	set bits
641 *	Command Register (CR)		TXP, STA	RD2, STP
642 *	Interrupt Status (ISR)				RST
643 *	Interrupt Mask (IMR)		All bits
644 *	Data Control (DCR)				LAS
645 *	Transmit Config. (TCR)		LB1, LB0
646 *
647 * XXX - We only check the CR register.
648 *
649 * Return 1 if 8390 was found, 0 if not.
650 */
651
652static int
653ed98_probe_generic8390(struct ed_softc *sc)
654{
655	u_char tmp = ed_nic_inb(sc, ED_P0_CR);
656#ifdef DIAGNOSTIC
657	printf("ed?: inb(ED_P0_CR)=%x\n", tmp);
658#endif
659	if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
660	    (ED_CR_RD2 | ED_CR_STP))
661		return (0);
662
663	(void) ed_nic_inb(sc, ED_P0_ISR);
664
665	return (1);
666}
667
668static int
669ed98_probe_Novell(device_t dev, int port_rid, int flags)
670{
671	struct ed_softc *sc = device_get_softc(dev);
672	int error;
673	int n;
674	u_char romdata[ETHER_ADDR_LEN * 2], tmp;
675
676#ifdef ED_DEBUG
677	device_printf(dev, "ed98_probe_Novell: start\n");
678#endif
679	error = ed98_alloc_port(dev, port_rid);
680	if (error)
681		return (error);
682
683	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
684	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
685
686	/* Reset the board */
687#ifdef ED_DEBUG
688	device_printf(dev, "ed98_probe_Novell: reset\n");
689#endif
690	switch (sc->type) {
691#if 1	/* XXX - I'm not sure this is really necessary... */
692	case ED_TYPE98_BDN:
693		tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
694		ed_asic_outb(sc, ED_NOVELL_RESET, (tmp & 0xf0) | 0x08);
695		ed_nic_outb(sc, 0x04, tmp);
696		(void) ed_asic_inb(sc, 0x08);
697		ed_asic_outb(sc, 0x08, tmp);
698		ed_asic_outb(sc, 0x08, tmp & 0x7f);
699		break;
700#endif
701	case ED_TYPE98_NC5098:
702		ed_asic_outb(sc, ED_NOVELL_RESET, 0x00);
703		DELAY(5000);
704		ed_asic_outb(sc, ED_NOVELL_RESET, 0x01);
705		break;
706
707	default:
708		tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
709
710	/*
711	 * I don't know if this is necessary; probably cruft leftover from
712	 * Clarkson packet driver code. Doesn't do a thing on the boards I've
713	 * tested. -DG [note that an outb(0x84, 0) seems to work here, and is
714	 * non-invasive...but some boards don't seem to reset and I don't have
715	 * complete documentation on what the 'right' thing to do is...so we
716	 * do the invasive thing for now. Yuck.]
717	 */
718		ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
719		break;
720	}
721	DELAY(5000);
722
723	/*
724	 * This is needed because some NE clones apparently don't reset the
725	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
726	 * - this makes the probe invasive! ...Done against my better
727	 * judgement. -DLG
728	 */
729	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
730	DELAY(5000);
731
732	/* Make sure that we really have an 8390 based board */
733	if (!ed98_probe_generic8390(sc))
734		return (ENXIO);
735
736	/* Test memory via PIO */
737#ifdef ED_DEBUG
738	device_printf(dev, "ed98_probe_Novell: test memory\n");
739#endif
740	sc->cr_proto = ED_CR_RD2;
741	if (!ed_pio_testmem(sc,  8192, 0, flags) &&
742	    !ed_pio_testmem(sc, 16384, 1, flags))
743		return (ENXIO);
744
745	/* Setup the board type */
746#ifdef ED_DEBUG
747	device_printf(dev, "ed98_probe_Novell: board type\n");
748#endif
749	switch (sc->type) {
750	case ED_TYPE98_BDN:
751		sc->type_str = "LD-BDN";
752		break;
753	case ED_TYPE98_EGY:
754		sc->type_str = "EGY-98";
755		break;
756	case ED_TYPE98_LGY:
757		sc->type_str = "LGY-98";
758		break;
759	case ED_TYPE98_ICM:
760		sc->type_str = "ICM";
761		break;
762	case ED_TYPE98_108:
763		sc->type_str = "PC-9801-108";
764		break;
765	case ED_TYPE98_LA98:
766		sc->type_str = "LA-98";
767		break;
768	case ED_TYPE98_NW98X:
769		sc->type_str = "NW98X";
770		break;
771	case ED_TYPE98_NC5098:
772		sc->type_str = "NC5098";
773		break;
774	default:
775		sc->type_str = NULL;
776		break;
777	}
778
779	/* Get station address */
780	switch (sc->type) {
781	case ED_TYPE98_NC5098:
782		for (n = 0; n < ETHER_ADDR_LEN; n++)
783			sc->enaddr[n] = ed_asic_inb(sc, ED_NC5098_ENADDR + n);
784		break;
785
786	default:
787		ed_pio_readmem(sc, 0, romdata, sizeof(romdata));
788		for (n = 0; n < ETHER_ADDR_LEN; n++)
789			sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)];
790		break;
791	}
792
793	/* clear any pending interrupts that might have occurred above */
794	ed_nic_outb(sc, ED_P0_ISR, 0xff);
795
796	sc->sc_write_mbufs = ed_pio_write_mbufs;
797	return (0);
798}
799
800/*
801 * Probe and vendor-specific initialization routine for SIC-98 boards
802 */
803static int
804ed_probe_SIC98(device_t dev, int port_rid, int flags)
805{
806	struct ed_softc *sc = device_get_softc(dev);
807	int error;
808	int i;
809	u_char sum;
810
811	/*
812	 * Setup card RAM and I/O address
813	 * Kernel Virtual to segment C0000-DFFFF????
814	 */
815	error = ed98_alloc_port(dev, port_rid);
816	if (error)
817		return (error);
818
819	sc->asic_offset = ED_SIC_ASIC_OFFSET;
820	sc->nic_offset  = ED_SIC_NIC_OFFSET;
821
822	error = ed98_alloc_memory(dev, 0);
823	if (error)
824		return (error);
825
826	/* Reset card to force it into a known state. */
827	ed_asic_outb(sc, 0, 0x00);
828	DELAY(100);
829	if (ED_TYPE98SUB(flags) == 0) {
830		/* SIC-98/SIU-98 */
831		ed_asic_outb(sc, 0, 0x94);
832		DELAY(100);
833		ed_asic_outb(sc, 0, 0x94);
834	} else {
835		/* SIU-98-D */
836		ed_asic_outb(sc, 0, 0x80);
837		DELAY(100);
838		ed_asic_outb(sc, 0, 0x94);
839		DELAY(100);
840		ed_asic_outb(sc, 0, 0x9e);
841	}
842	DELAY(100);
843
844	/*
845	 * Here we check the card ROM, if the checksum passes, and the
846	 * type code and ethernet address check out, then we know we have
847	 * an SIC card.
848	 */
849	sum = bus_space_read_1(sc->mem_bst, sc->mem_bsh, 6 * 2);
850	for (i = 0; i < ETHER_ADDR_LEN; i++)
851		sum ^= (sc->enaddr[i] =
852		    bus_space_read_1(sc->mem_bst, sc->mem_bsh, i * 2));
853#ifdef ED_DEBUG
854	device_printf(dev, "ed_probe_sic98: got address %6D\n",
855		      sc->enaddr, ":");
856#endif
857	if (sum != 0)
858		return (ENXIO);
859	if ((sc->enaddr[0] | sc->enaddr[1] | sc->enaddr[2]) == 0)
860		return (ENXIO);
861
862	sc->vendor   = ED_VENDOR_SIC;
863	sc->type_str = "SIC98";
864	sc->isa16bit = 1;
865	sc->cr_proto = 0;
866
867	/*
868	 * SIC RAM page 0x0000-0x3fff(or 0x7fff)
869	 */
870	if (ED_TYPE98SUB(flags) == 0)
871		ed_asic_outb(sc, 0, 0x90);
872	else
873		ed_asic_outb(sc, 0, 0x8e);
874	DELAY(100);
875
876	error = ed_clear_memory(dev);
877	if (error)
878		return (error);
879
880	sc->mem_shared = 1;
881	sc->mem_end = sc->mem_start + sc->mem_size;
882
883	/*
884	 * allocate one xmit buffer if < 16k, two buffers otherwise
885	 */
886	if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
887		sc->txb_cnt = 1;
888	else
889		sc->txb_cnt = 2;
890	sc->tx_page_start = 0;
891
892	sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt;
893	sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE;
894
895	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
896
897	sc->sc_write_mbufs = ed_shmem_write_mbufs;
898	return (0);
899}
900
901/*
902 * Contec C-NET(98) series support routines
903 */
904static void
905ed_reset_CNET98(struct ed_softc *sc, int flags)
906{
907	u_int init_addr = ED_CNET98_INIT;
908	u_char tmp;
909
910	/* Choose initial register address */
911	if (ED_TYPE98SUB(flags) != 0) {
912		init_addr = ED_CNET98_INIT2;
913	}
914#ifdef ED_DEBUG
915	printf("ed?: initial register=%x\n", init_addr);
916#endif
917	/*
918	 * Reset the board to force it into a known state.
919	 */
920	outb(init_addr, 0x00);	/* request */
921	DELAY(5000);
922	outb(init_addr, 0x01);	/* cancel */
923	DELAY(5000);
924
925	/*
926	 * Set I/O address(A15-12) and cpu type
927	 *
928	 *   AAAAIXXC(8bit)
929	 *   AAAA: A15-A12,  I: I/O enable, XX: reserved, C: CPU type
930	 *
931	 * CPU type is 1:80286 or higher, 0:not.
932	 * But FreeBSD runs under i386 or higher, thus it must be 1.
933	 */
934	tmp = (rman_get_start(sc->port_res) & 0xf000) >> 8;
935	tmp |= (0x08 | 0x01);
936#ifdef ED_DEBUG
937	printf("ed?: outb(%x, %x)\n", init_addr + 2, tmp);
938#endif
939	outb(init_addr + 2, tmp);
940	DELAY(5000);
941
942	/*
943	 * This is needed because some NE clones apparently don't reset the
944	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
945	 * - this makes the probe invasive! ...Done against my better
946	 * judgement. -DLG
947	 */
948	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
949	DELAY(5000);
950}
951
952static void
953ed_winsel_CNET98(struct ed_softc *sc, u_short bank)
954{
955	u_char mem = (rman_get_start(sc->mem_res) >> 12) & 0xff;
956
957	/*
958	 * Disable window memory
959	 *    bit7 is 0:disable
960	 */
961	ed_asic_outb(sc, ED_CNET98_WIN_REG, mem & 0x7f);
962	DELAY(10);
963
964	/*
965	 * Select window address
966	 *    FreeBSD address 0xf00xxxxx
967	 */
968	ed_asic_outb(sc, ED_CNET98_MAP_REG0L, bank & 0xff);
969	DELAY(10);
970	ed_asic_outb(sc, ED_CNET98_MAP_REG0H, (bank >> 8) & 0xff);
971	DELAY(10);
972	ed_asic_outb(sc, ED_CNET98_MAP_REG1L, 0x00);
973	DELAY(10);
974	ed_asic_outb(sc, ED_CNET98_MAP_REG1H, 0x41);
975	DELAY(10);
976	ed_asic_outb(sc, ED_CNET98_MAP_REG2L, 0x00);
977	DELAY(10);
978	ed_asic_outb(sc, ED_CNET98_MAP_REG2H, 0x42);
979	DELAY(10);
980	ed_asic_outb(sc, ED_CNET98_MAP_REG3L, 0x00);
981	DELAY(10);
982	ed_asic_outb(sc, ED_CNET98_MAP_REG3H, 0x43);
983	DELAY(10);
984
985	/*
986	 * Enable window memory(16Kbyte)
987	 *    bit7 is 1:enable
988	 */
989#ifdef ED_DEBUG
990	printf("ed?: window start address=%x\n", mem);
991#endif
992	ed_asic_outb(sc, ED_CNET98_WIN_REG, mem);
993	DELAY(10);
994}
995
996/*
997 * Probe and vendor-specific initialization routine for C-NET(98) boards
998 */
999static int
1000ed_probe_CNET98(device_t dev, int port_rid, int flags)
1001{
1002	struct ed_softc *sc = device_get_softc(dev);
1003	int error;
1004	u_char tmp;
1005	u_long conf_irq, junk;
1006#ifdef DIAGNOSTIC
1007	u_char tmp_s;
1008#endif
1009
1010	error = ed98_alloc_port(dev, port_rid);
1011	if (error)
1012		return (error);
1013
1014	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1015	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1016
1017	error = ed98_alloc_memory(dev, 0);
1018	if (error)
1019		return (error);
1020
1021	/* Check I/O address. 0x[a-f]3d0 are allowed. */
1022	if (((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0)
1023	||  ((rman_get_start(sc->port_res) & 0xf000) < (u_short) 0xa000)) {
1024#ifdef DIAGNOSTIC
1025		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1026			"must be %s for %s\n", rman_get_start(sc->port_res),
1027			"0x[a-f]3d0", "CNET98");
1028#endif
1029		return (ENXIO);
1030	}
1031
1032#ifdef DIAGNOSTIC
1033	/* Check window area address */
1034	tmp_s = rman_get_start(sc->mem_res) >> 12;
1035	if (tmp_s < 0x80) {
1036		device_printf(dev, "Please change window address(0x%lx)\n",
1037		    rman_get_start(sc->mem_res));
1038		return (ENXIO);
1039	}
1040
1041	tmp_s &= 0x0f;
1042	tmp    = rman_get_start(sc->port_res) >> 12;
1043	if ((tmp_s <= tmp) && (tmp < (tmp_s + 4))) {
1044		device_printf(dev, "Please change iobase address(0x%lx) "
1045		    "or window address(0x%lx)\n",
1046		    rman_get_start(sc->port_res),
1047		    rman_get_start(sc->mem_res));
1048		return (ENXIO);
1049	}
1050#endif
1051	/* Reset the board */
1052	ed_reset_CNET98(sc, flags);
1053
1054	/*
1055	 * This is needed because some NE clones apparently don't reset the
1056	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1057	 * - this makes the probe invasive! ...Done against my better
1058	 * judgement. -DLG
1059	 */
1060	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1061	DELAY(5000);
1062
1063	/* Make sure that we really have an 8390 based board */
1064	if (!ed98_probe_generic8390(sc))
1065		return (ENXIO);
1066
1067	/*
1068	 *  Set window ethernet address area
1069	 *    board memory base 0x480000  data 256byte
1070	 */
1071	ed_winsel_CNET98(sc, 0x4800);
1072
1073	/*
1074	 * Get station address from on-board ROM
1075	 */
1076	bus_space_read_region_1(sc->mem_bst, sc->mem_bsh, sc->mem_start,
1077	    sc->enaddr, ETHER_ADDR_LEN);
1078
1079	sc->vendor    = ED_VENDOR_MISC;
1080	sc->type_str  = "CNET98";
1081	sc->isa16bit  = 0;
1082	sc->cr_proto  = ED_CR_RD2;
1083
1084	/*
1085	 * Set window buffer memory area
1086	 *    board memory base 0x400000  data 16kbyte
1087	 */
1088	ed_winsel_CNET98(sc, 0x4000);
1089
1090	error = ed_clear_memory(dev);
1091	if (error)
1092		return (error);
1093
1094	sc->mem_shared = 1;
1095	sc->mem_end = sc->mem_start + sc->mem_size;
1096
1097	sc->txb_cnt = 1;	/* XXX */
1098	sc->tx_page_start = 0;
1099
1100	sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE;
1101	sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE;
1102
1103	sc->mem_ring = sc->mem_start + ED_PAGE_SIZE * ED_TXBUF_SIZE;
1104
1105	/*
1106	 *   Set interrupt level
1107	 */
1108	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1109	if (error)
1110		return (error);
1111
1112	switch (conf_irq) {
1113	case 3:
1114		tmp = ED_CNET98_INT_IRQ3;
1115		break;
1116	case 5:
1117		tmp = ED_CNET98_INT_IRQ5;
1118		break;
1119	case 6:
1120		tmp = ED_CNET98_INT_IRQ6;
1121		break;
1122	case 9:
1123		tmp = ED_CNET98_INT_IRQ9;
1124		break;
1125	case 12:
1126		tmp = ED_CNET98_INT_IRQ12;
1127		break;
1128	case 13:
1129		tmp = ED_CNET98_INT_IRQ13;
1130		break;
1131	default:
1132		device_printf(dev, "Invalid irq configuration (%ld) must be "
1133			"%s for %s\n", conf_irq, "3,5,6,9,12,13", "CNET98");
1134		return (ENXIO);
1135	}
1136	ed_asic_outb(sc, ED_CNET98_INT_LEV, tmp);
1137	DELAY(1000);
1138	/*
1139	 *   Set interrupt mask.
1140	 *     bit7:1 all interrupt mask
1141	 *     bit1:1 timer interrupt mask
1142	 *     bit0:0 NS controler interrupt enable
1143	 */
1144	ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e);
1145	DELAY(1000);
1146
1147	sc->sc_write_mbufs = ed_shmem_write_mbufs;
1148	return (0);
1149}
1150
1151/*
1152 * Probe and vendor-specific initialization routine for C-NET(98)E/L boards
1153 */
1154static int
1155ed_probe_CNET98EL(device_t dev, int port_rid, int flags)
1156{
1157	struct ed_softc *sc = device_get_softc(dev);
1158	int error;
1159	int i;
1160	u_char romdata[ETHER_ADDR_LEN * 2], tmp;
1161	u_long conf_irq, junk;
1162
1163	error = ed98_alloc_port(dev, port_rid);
1164	if (error)
1165		return (error);
1166
1167	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1168	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1169
1170	/* Check I/O address. 0x[0-f]3d0 are allowed. */
1171	if ((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) {
1172#ifdef DIAGNOSTIC
1173		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1174			"must be %s for %s\n", rman_get_start(sc->port_res),
1175			"0x?3d0", "CNET98E/L");
1176#endif
1177		return (ENXIO);
1178	}
1179
1180	/* Reset the board */
1181	ed_reset_CNET98(sc, flags);
1182
1183	/*
1184	 * This is needed because some NE clones apparently don't reset the
1185	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1186	 * - this makes the probe invasive! ...Done against my better
1187	 * judgement. -DLG
1188	 */
1189	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1190	DELAY(5000);
1191
1192	/* Make sure that we really have an 8390 based board */
1193	if (!ed98_probe_generic8390(sc))
1194		return (ENXIO);
1195
1196	/* Test memory via PIO */
1197	sc->cr_proto = ED_CR_RD2;
1198	if (!ed_pio_testmem(sc, ED_CNET98EL_PAGE_OFFSET, 1, flags))
1199		return (ENXIO);
1200
1201	/* This looks like a C-NET(98)E/L board. */
1202	sc->type_str = "CNET98E/L";
1203
1204	/*
1205	 * Set IRQ. C-NET(98)E/L only allows a choice of irq 3,5,6.
1206	 */
1207	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1208	if (error)
1209		return (error);
1210
1211	switch (conf_irq) {
1212	case 3:
1213		tmp = ED_CNET98EL_ICR_IRQ3;
1214		break;
1215	case 5:
1216		tmp = ED_CNET98EL_ICR_IRQ5;
1217		break;
1218	case 6:
1219		tmp = ED_CNET98EL_ICR_IRQ6;
1220		break;
1221#if 0
1222	case 12:
1223		tmp = ED_CNET98EL_ICR_IRQ12;
1224		break;
1225#endif
1226	default:
1227		device_printf(dev, "Invalid irq configuration (%ld) must be "
1228			"%s for %s\n", conf_irq, "3,5,6", "CNET98E/L");
1229		return (ENXIO);
1230	}
1231	ed_asic_outb(sc, ED_CNET98EL_ICR, tmp);
1232	ed_asic_outb(sc, ED_CNET98EL_IMR, 0x7e);
1233
1234	/* Get station address from on-board ROM */
1235	ed_pio_readmem(sc, 16384, romdata, sizeof(romdata));
1236	for (i = 0; i < ETHER_ADDR_LEN; i++)
1237		sc->enaddr[i] = romdata[i * 2];
1238
1239	/* clear any pending interrupts that might have occurred above */
1240	ed_nic_outb(sc, ED_P0_ISR, 0xff);
1241
1242	sc->sc_write_mbufs = ed_pio_write_mbufs;
1243	return (0);
1244}
1245
1246/*
1247 * Probe and vendor-specific initialization routine for PC-9801-77 boards
1248 */
1249static int
1250ed_probe_NEC77(device_t dev, int port_rid, int flags)
1251{
1252	struct ed_softc *sc = device_get_softc(dev);
1253	int error;
1254	u_char tmp;
1255	u_long conf_irq, junk;
1256
1257	error = ed98_probe_Novell(dev, port_rid, flags);
1258	if (error)
1259		return (error);
1260
1261	/* LA/T-98 does not need IRQ setting. */
1262	if (ED_TYPE98SUB(flags) == 0)
1263		return (0);
1264
1265	/*
1266	 * Set IRQ. PC-9801-77 only allows a choice of irq 3,5,6,12,13.
1267	 */
1268	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1269	if (error)
1270		return (error);
1271
1272	switch (conf_irq) {
1273	case 3:
1274		tmp = ED_NEC77_IRQ3;
1275		break;
1276	case 5:
1277		tmp = ED_NEC77_IRQ5;
1278		break;
1279	case 6:
1280		tmp = ED_NEC77_IRQ6;
1281		break;
1282	case 12:
1283		tmp = ED_NEC77_IRQ12;
1284		break;
1285	case 13:
1286		tmp = ED_NEC77_IRQ13;
1287		break;
1288	default:
1289		device_printf(dev, "Invalid irq configuration (%ld) must be "
1290			"%s for %s\n", conf_irq, "3,5,6,12,13", "PC-9801-77");
1291		return (ENXIO);
1292	}
1293	ed_asic_outb(sc, ED_NEC77_IRQ, tmp);
1294
1295	return (0);
1296}
1297
1298/*
1299 * Probe and vendor-specific initialization routine for EC/EP-98X boards
1300 */
1301static int
1302ed_probe_NW98X(device_t dev, int port_rid, int flags)
1303{
1304	struct ed_softc *sc = device_get_softc(dev);
1305	int error;
1306	u_char tmp;
1307	u_long conf_irq, junk;
1308
1309	error = ed98_probe_Novell(dev, port_rid, flags);
1310	if (error)
1311		return (error);
1312
1313	/* Networld 98X3 does not need IRQ setting. */
1314	if (ED_TYPE98SUB(flags) == 0)
1315		return (0);
1316
1317	/*
1318	 * Set IRQ. EC/EP-98X only allows a choice of irq 3,5,6,12,13.
1319	 */
1320	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1321	if (error)
1322		return (error);
1323
1324	switch (conf_irq) {
1325	case 3:
1326		tmp = ED_NW98X_IRQ3;
1327		break;
1328	case 5:
1329		tmp = ED_NW98X_IRQ5;
1330		break;
1331	case 6:
1332		tmp = ED_NW98X_IRQ6;
1333		break;
1334	case 12:
1335		tmp = ED_NW98X_IRQ12;
1336		break;
1337	case 13:
1338		tmp = ED_NW98X_IRQ13;
1339		break;
1340	default:
1341		device_printf(dev, "Invalid irq configuration (%ld) must be "
1342			"%s for %s\n", conf_irq, "3,5,6,12,13", "EC/EP-98X");
1343		return (ENXIO);
1344	}
1345	ed_asic_outb(sc, ED_NW98X_IRQ, tmp);
1346
1347	return (0);
1348}
1349
1350/*
1351 * Read SB-9801 station address from Serial Two-Wire EEPROM
1352 */
1353static void
1354ed_get_SB98(struct ed_softc *sc)
1355{
1356	int i, j;
1357	u_char mask, val;
1358
1359        /* enable EEPROM acceess */
1360        ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_ENABLE);
1361
1362	/* output start command */
1363	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1364	DELAY(ED_SB98_EEP_DELAY);
1365	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1366	DELAY(ED_SB98_EEP_DELAY);
1367
1368       	/* output address (7bit) */
1369	for (mask = 0x40; mask != 0; mask >>= 1) {
1370		val = 0;
1371		if (ED_SB98_ADDRESS & mask)
1372			val = ED_SB98_EEP_SDA;
1373		ed_asic_outb(sc, ED_SB98_EEP, val);
1374		DELAY(ED_SB98_EEP_DELAY);
1375		ed_asic_outb(sc, ED_SB98_EEP, val | ED_SB98_EEP_SCL);
1376		DELAY(ED_SB98_EEP_DELAY);
1377	}
1378
1379	/* output READ command */
1380	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ);
1381	DELAY(ED_SB98_EEP_DELAY);
1382	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ | ED_SB98_EEP_SCL);
1383	DELAY(ED_SB98_EEP_DELAY);
1384
1385	/* read station address */
1386	for (i = 0; i < ETHER_ADDR_LEN; i++) {
1387		/* output ACK */
1388		ed_asic_outb(sc, ED_SB98_EEP, 0);
1389		DELAY(ED_SB98_EEP_DELAY);
1390		ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1391		DELAY(ED_SB98_EEP_DELAY);
1392
1393		val = 0;
1394		for (j = 0; j < 8; j++) {
1395			ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA);
1396			DELAY(ED_SB98_EEP_DELAY);
1397			ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1398			DELAY(ED_SB98_EEP_DELAY);
1399			val <<= 1;
1400			val |= (ed_asic_inb(sc, ED_SB98_EEP) & ED_SB98_EEP_SDA);
1401			DELAY(ED_SB98_EEP_DELAY);
1402	  	}
1403		sc->enaddr[i] = val;
1404	}
1405
1406	/* output Last ACK */
1407        ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA);
1408        DELAY(ED_SB98_EEP_DELAY);
1409        ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1410        DELAY(ED_SB98_EEP_DELAY);
1411
1412	/* output stop command */
1413	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1414	DELAY(ED_SB98_EEP_DELAY);
1415	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1416	DELAY(ED_SB98_EEP_DELAY);
1417
1418	/* disable EEPROM access */
1419	ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_DISABLE);
1420}
1421
1422/*
1423 * Probe and vendor-specific initialization routine for SB-9801 boards
1424 */
1425static int
1426ed_probe_SB98(device_t dev, int port_rid, int flags)
1427{
1428	struct ed_softc *sc = device_get_softc(dev);
1429	int error;
1430	u_char tmp;
1431	u_long conf_irq, junk;
1432
1433	error = ed98_alloc_port(dev, port_rid);
1434	if (error)
1435		return (error);
1436
1437	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1438	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1439
1440	/* Check I/O address. 00d[02468ace] are allowed. */
1441	if ((rman_get_start(sc->port_res) & ~0x000e) != 0x00d0) {
1442#ifdef DIAGNOSTIC
1443		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1444		    "must be %s for %s\n", rman_get_start(sc->port_res),
1445		    "0xd?", "SB9801");
1446#endif
1447		return (ENXIO);
1448	}
1449
1450	/* Write I/O port address and read 4 times */
1451	outb(ED_SB98_IO_INHIBIT, rman_get_start(sc->port_res) & 0xff);
1452	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1453	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1454	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1455	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1456
1457	/*
1458	 * Check IRQ. Soliton SB-9801 only allows a choice of
1459	 * irq 3,5,6,12
1460	 */
1461	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1462	if (error)
1463		return (error);
1464
1465	switch (conf_irq) {
1466	case 3:
1467		tmp = ED_SB98_CFG_IRQ3;
1468		break;
1469	case 5:
1470		tmp = ED_SB98_CFG_IRQ5;
1471		break;
1472	case 6:
1473		tmp = ED_SB98_CFG_IRQ6;
1474		break;
1475	case 12:
1476		tmp = ED_SB98_CFG_IRQ12;
1477		break;
1478	default:
1479		device_printf(dev, "Invalid irq configuration (%ld) must be "
1480			"%s for %s\n", conf_irq, "3,5,6,12", "SB9801");
1481		return (ENXIO);
1482	}
1483
1484	if (flags & ED_FLAGS_DISABLE_TRANCEIVER)
1485		tmp |= ED_SB98_CFG_ALTPORT;
1486	ed_asic_outb(sc, ED_SB98_CFG, ED_SB98_CFG_ENABLE | tmp);
1487	ed_asic_outb(sc, ED_SB98_POLARITY, 0x01);
1488
1489	/* Reset the board. */
1490	ed_asic_outb(sc, ED_NOVELL_RESET, 0x7a);
1491	DELAY(300);
1492	ed_asic_outb(sc, ED_NOVELL_RESET, 0x79);
1493	DELAY(300);
1494
1495	/*
1496	 * This is needed because some NE clones apparently don't reset the
1497	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1498	 * - this makes the probe invasive! ...Done against my better
1499	 * judgement. -DLG
1500	 */
1501	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1502	DELAY(5000);
1503
1504	/* Make sure that we really have an 8390 based board */
1505	if (!ed98_probe_generic8390(sc))
1506		return (ENXIO);
1507
1508	/* Test memory via PIO */
1509	sc->cr_proto = ED_CR_RD2;
1510	if (!ed_pio_testmem(sc, 16384, 1, flags))
1511		return (ENXIO);
1512
1513	/* This looks like an SB9801 board. */
1514	sc->type_str = "SB9801";
1515
1516	/* Get station address */
1517	ed_get_SB98(sc);
1518
1519	/* clear any pending interrupts that might have occurred above */
1520	ed_nic_outb(sc, ED_P0_ISR, 0xff);
1521
1522	sc->sc_write_mbufs = ed_pio_write_mbufs;
1523	return (0);
1524}
1525
1526/*
1527 * Test the ability to read and write to the NIC memory.
1528 */
1529static int
1530ed_pio_testmem(struct ed_softc *sc, int page_offset, int isa16bit, int flags)
1531{
1532	u_long memsize;
1533	static char test_pattern[32] = "THIS is A memory TEST pattern";
1534	char test_buffer[32];
1535#ifdef DIAGNOSTIC
1536	int page_end;
1537#endif
1538
1539	sc->vendor = ED_VENDOR_NOVELL;
1540	sc->mem_shared = 0;
1541	sc->isa16bit = isa16bit;
1542
1543	/* 8k of memory plus an additional 8k if 16bit */
1544	memsize = (isa16bit ? 16384 : 8192);
1545
1546	/*
1547	 * This prevents packets from being stored in the NIC memory when the
1548	 * readmem routine turns on the start bit in the CR.
1549	 */
1550	ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
1551
1552	/* Initialize DCR for byte/word operations */
1553	if (isa16bit)
1554		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
1555	else
1556		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
1557	ed_nic_outb(sc, ED_P0_PSTART, page_offset / ED_PAGE_SIZE);
1558	ed_nic_outb(sc, ED_P0_PSTOP, (page_offset + memsize) / ED_PAGE_SIZE);
1559#ifdef ED_DEBUG
1560	printf("ed?: ed_pio_testmem: page start=%x, end=%lx",
1561	    page_offset, page_offset + memsize);
1562#endif
1563
1564	/*
1565	 * Write a test pattern. If this fails, then we don't know
1566	 * what this board is.
1567	 */
1568	ed_pio_writemem(sc, test_pattern, page_offset, sizeof(test_pattern));
1569	ed_pio_readmem(sc, page_offset, test_buffer, sizeof(test_pattern));
1570
1571	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
1572#ifdef ED_DEBUG
1573		printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_offset);
1574#endif
1575		return (0);
1576	}
1577
1578#ifdef DIAGNOSTIC
1579	/* Check the bottom. */
1580	page_end = page_offset + memsize - ED_PAGE_SIZE;
1581	ed_pio_writemem(sc, test_pattern, page_end, sizeof(test_pattern));
1582	ed_pio_readmem(sc, page_end, test_buffer, sizeof(test_pattern));
1583
1584	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
1585#ifdef ED_DEBUG
1586		printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_end);
1587#endif
1588		return (0);
1589	}
1590#endif
1591	sc->mem_size = memsize;
1592	sc->mem_start = page_offset;
1593	sc->mem_end   = sc->mem_start + memsize;
1594	sc->tx_page_start = page_offset / ED_PAGE_SIZE;
1595
1596	/*
1597	 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
1598	 * otherwise).
1599	 */
1600	if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
1601		sc->txb_cnt = 1;
1602	else
1603		sc->txb_cnt = 2;
1604
1605	sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
1606	sc->rec_page_stop  = sc->tx_page_start + memsize / ED_PAGE_SIZE;
1607
1608	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
1609
1610	return (1);
1611}
1612
1613static device_method_t ed_cbus_methods[] = {
1614	/* Device interface */
1615	DEVMETHOD(device_probe,		ed_cbus_probe),
1616	DEVMETHOD(device_attach,	ed_cbus_attach),
1617	DEVMETHOD(device_detach,	ed_detach),
1618
1619	{ 0, 0 }
1620};
1621
1622static driver_t ed_cbus_driver = {
1623	"ed",
1624	ed_cbus_methods,
1625	sizeof(struct ed_softc)
1626};
1627
1628DRIVER_MODULE(ed, isa, ed_cbus_driver, ed_devclass, 0, 0);
1629MODULE_DEPEND(ed, isa, 1, 1, 1);
1630MODULE_DEPEND(ed, ether, 1, 1, 1);
1631