if_ed_cbus.c revision 158651
1/*-
2 * Copyright (c) 1995, David Greenman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/ed/if_ed_cbus.c 158651 2006-05-16 14:37:58Z phk $
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/socket.h>
33#include <sys/kernel.h>
34
35#include <sys/module.h>
36#include <sys/bus.h>
37#include <machine/bus.h>
38#include <sys/rman.h>
39#include <machine/resource.h>
40
41#include <net/ethernet.h>
42#include <net/if.h>
43#include <net/if_arp.h>
44#include <net/if_media.h>
45#include <net/if_mib.h>
46
47#include <isa/isavar.h>
48
49#include <dev/ed/if_edvar.h>
50#include <dev/ed/if_edreg.h>
51#include <dev/ed/if_ed98.h>
52
53static int ed98_alloc_port(device_t, int);
54static int ed98_alloc_memory(device_t, int);
55static int ed_pio_testmem(struct ed_softc *, int, int, int);
56static int ed_probe_CNET98(device_t, int, int);
57static int ed_probe_CNET98EL(device_t, int, int);
58static int ed_probe_EZ98(device_t, int, int);
59static int ed_probe_NEC77(device_t, int, int);
60static int ed_probe_NW98X(device_t, int, int);
61static int ed_probe_SB98(device_t, int, int);
62static int ed_probe_SIC98(device_t, int, int);
63static int ed98_probe_Novell(device_t, int, int);
64static int ed98_probe_generic8390(struct ed_softc *);
65static void ed_reset_CNET98(struct ed_softc *, int);
66static void ed_winsel_CNET98(struct ed_softc *, u_short);
67static void ed_get_SB98(struct ed_softc *);
68
69static int ed_cbus_probe(device_t);
70static int ed_cbus_attach(device_t);
71
72static struct isa_pnp_id ed_ids[] = {
73/* TODO - list up PnP boards for PC-98 */
74	{ 0,		NULL }
75};
76
77static int
78ed_cbus_probe(device_t dev)
79{
80	struct ed_softc *sc = device_get_softc(dev);
81	int flags = device_get_flags(dev);
82	int error = 0;
83
84	sc->type = ED_TYPE98(flags);
85#ifdef ED_DEBUG
86	device_printf(dev, "ed_cbus_probe: sc->type=%x\n", sc->type);
87#endif
88
89	/* Check isapnp ids */
90	error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids);
91#ifdef ED_DEBUG
92	device_printf(dev, "ed_cbus_probe: ISA_PNP_PROBE returns %d\n", error);
93#endif
94
95	/* If the card had a PnP ID that didn't match any we know about */
96	if (error == ENXIO)
97		goto end;
98
99	/* If we had some other problem. */
100	if (!(error == 0 || error == ENOENT))
101		goto end;
102
103	/* Heuristic probes */
104#ifdef ED_DEBUG
105	device_printf(dev, "ed_cbus_probe: Heuristic probes start\n");
106#endif
107	switch (sc->type) {
108	case ED_TYPE98_GENERIC:
109		/*
110		 * CAUTION!
111		 * sc->type of these boards are overwritten by PC/AT's value.
112		 */
113
114		/*
115		 * SMC EtherEZ98
116		 */
117		error = ed_probe_EZ98(dev, 0, flags);
118		if (error == 0)
119			goto end;
120
121		ed_release_resources(dev);
122
123		/*
124		 * Allied Telesis CenterCom LA-98-T
125		 */
126		error = ed_probe_Novell(dev, 0, flags);
127		if (error == 0) {
128			ed_Novell_read_mac(sc);
129			goto end;
130		}
131		break;
132
133	/*
134	 * NE2000-like boards probe routine
135	 */
136	case ED_TYPE98_BDN:
137		/*
138		 * ELECOM LANEED LD-BDN
139		 * PLANET SMART COM 98 EN-2298
140		 */
141	case ED_TYPE98_LGY:
142		/*
143		 * MELCO LGY-98, IND-SP, IND-SS
144		 * MACNICA NE2098
145		 */
146	case ED_TYPE98_ICM:
147		/*
148		 * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET
149		 * D-Link DE-298P, DE-298
150		 */
151	case ED_TYPE98_EGY:
152		/*
153		 * MELCO EGY-98
154		 * Contec C-NET(98)E-A, C-NET(98)L-A
155		 */
156	case ED_TYPE98_108:
157		/*
158		 * NEC PC-9801-107,108
159		 */
160	case ED_TYPE98_NC5098:
161		/*
162		 * NextCom NC5098
163		 */
164		error = ed98_probe_Novell(dev, 0, flags);
165		break;
166
167	/*
168	 * other boards with special probe routine
169	 */
170	case ED_TYPE98_SIC:
171		/*
172		 * Allied Telesis SIC-98
173		 */
174		error = ed_probe_SIC98(dev, 0, flags);
175		break;
176
177	case ED_TYPE98_CNET98EL:
178		/*
179		 * Contec C-NET(98)E/L
180		 */
181		error = ed_probe_CNET98EL(dev, 0, flags);
182		break;
183
184	case ED_TYPE98_CNET98:
185		/*
186		 * Contec C-NET(98)
187		 */
188		error = ed_probe_CNET98(dev, 0, flags);
189		break;
190
191	case ED_TYPE98_LA98:
192		/*
193		 * IO-DATA LA/T-98
194		 * NEC PC-9801-77,78
195		 */
196		error = ed_probe_NEC77(dev, 0, flags);
197		break;
198
199	case ED_TYPE98_NW98X:
200		/*
201		 * Networld EC/EP-98X
202		 */
203		error = ed_probe_NW98X(dev, 0, flags);
204		break;
205
206	case ED_TYPE98_SB98:
207		/*
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 | INTR_MPSAFE,
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	sc->port_bst = rman_get_bustag(res);
544	sc->port_bsh = rman_get_bushandle(res);
545
546	/* Re-map i/o table if needed */
547	switch (sc->type) {
548	case ED_TYPE98_LA98:
549	case ED_TYPE98_NW98X:
550		io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
551		n++;
552		break;
553
554	case ED_TYPE98_108:
555		adj = (rman_get_start(res) & 0xf000) / 2;
556		offset = (offset | adj) - rman_get_start(res);
557
558		for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++)
559			io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
560		break;
561
562	case ED_TYPE98_CNET98:
563		io_nic = io_asic = ed98_ioaddr_cnet98;
564		offset = 1;
565
566		bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET);
567		for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++)
568			io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset;
569		break;
570
571	case ED_TYPE98_NC5098:
572		n = ED_NOVELL_IO_PORTS;
573		break;
574	}
575
576	if (reset != ED_NOVELL_RESET)
577		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_RESET] =
578			io_res[ED_NOVELL_ASIC_OFFSET + reset];
579	if (data  != ED_NOVELL_DATA) {
580		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA] =
581			io_res[ED_NOVELL_ASIC_OFFSET + data];
582#if 0
583		io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA + 1] =
584			io_res[ED_NOVELL_ASIC_OFFSET + data + 1];
585#endif
586	}
587
588	error = isa_load_resourcev(res, io_res, n);
589	if (error != 0)
590		return (ENOENT);
591#ifdef ED_DEBUG
592	device_printf(dev, "ed98_alloc_port: i/o ports = %d\n", n);
593	for (i = 0; i < n; i++)
594		printf("%x,", io_res[i]);
595	printf("\n");
596#endif
597	return (0);
598}
599
600static int
601ed98_alloc_memory(dev, rid)
602	device_t dev;
603	int rid;
604{
605	struct ed_softc *sc = device_get_softc(dev);
606	int error;
607	u_long conf_maddr, conf_msize;
608
609	error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &conf_maddr,
610	    &conf_msize);
611	if (error)
612		return (error);
613
614	if ((conf_maddr == 0) || (conf_msize == 0))
615		return (ENXIO);
616
617	error = ed_alloc_memory(dev, rid, (int) conf_msize);
618	if (error)
619		return (error);
620
621	sc->mem_start = 0;
622	sc->mem_size  = conf_msize;
623
624	return (0);
625}
626
627/*
628 * Generic probe routine for testing for the existance of a DS8390.
629 *	Must be called after the NIC has just been reset. This routine
630 *	works by looking at certain register values that are guaranteed
631 *	to be initialized a certain way after power-up or reset. Seems
632 *	not to currently work on the 83C690.
633 *
634 * Specifically:
635 *
636 *	Register			reset bits	set bits
637 *	Command Register (CR)		TXP, STA	RD2, STP
638 *	Interrupt Status (ISR)				RST
639 *	Interrupt Mask (IMR)		All bits
640 *	Data Control (DCR)				LAS
641 *	Transmit Config. (TCR)		LB1, LB0
642 *
643 * XXX - We only check the CR register.
644 *
645 * Return 1 if 8390 was found, 0 if not.
646 */
647
648static int
649ed98_probe_generic8390(struct ed_softc *sc)
650{
651	u_char tmp = ed_nic_inb(sc, ED_P0_CR);
652#ifdef DIAGNOSTIC
653	printf("ed?: inb(ED_P0_CR)=%x\n", tmp);
654#endif
655	if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
656	    (ED_CR_RD2 | ED_CR_STP))
657		return (0);
658
659	(void) ed_nic_inb(sc, ED_P0_ISR);
660
661	return (1);
662}
663
664static int
665ed98_probe_Novell(device_t dev, int port_rid, int flags)
666{
667	struct ed_softc *sc = device_get_softc(dev);
668	int error;
669	int n;
670	u_char romdata[ETHER_ADDR_LEN * 2], tmp;
671
672#ifdef ED_DEBUG
673	device_printf(dev, "ed98_probe_Novell: start\n");
674#endif
675	error = ed98_alloc_port(dev, port_rid);
676	if (error)
677		return (error);
678
679	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
680	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
681
682	/* Reset the board */
683#ifdef ED_DEBUG
684	device_printf(dev, "ed98_probe_Novell: reset\n");
685#endif
686	switch (sc->type) {
687#if 1	/* XXX - I'm not sure this is really necessary... */
688	case ED_TYPE98_BDN:
689		tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
690		ed_asic_outb(sc, ED_NOVELL_RESET, (tmp & 0xf0) | 0x08);
691		ed_nic_outb(sc, 0x04, tmp);
692		(void) ed_asic_inb(sc, 0x08);
693		ed_asic_outb(sc, 0x08, tmp);
694		ed_asic_outb(sc, 0x08, tmp & 0x7f);
695		break;
696#endif
697	case ED_TYPE98_NC5098:
698		ed_asic_outb(sc, ED_NOVELL_RESET, 0x00);
699		DELAY(5000);
700		ed_asic_outb(sc, ED_NOVELL_RESET, 0x01);
701		break;
702
703	default:
704		tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
705
706	/*
707	 * I don't know if this is necessary; probably cruft leftover from
708	 * Clarkson packet driver code. Doesn't do a thing on the boards I've
709	 * tested. -DG [note that an outb(0x84, 0) seems to work here, and is
710	 * non-invasive...but some boards don't seem to reset and I don't have
711	 * complete documentation on what the 'right' thing to do is...so we
712	 * do the invasive thing for now. Yuck.]
713	 */
714		ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
715		break;
716	}
717	DELAY(5000);
718
719	/*
720	 * This is needed because some NE clones apparently don't reset the
721	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
722	 * - this makes the probe invasive! ...Done against my better
723	 * judgement. -DLG
724	 */
725	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
726	DELAY(5000);
727
728	/* Make sure that we really have an 8390 based board */
729	if (!ed98_probe_generic8390(sc))
730		return (ENXIO);
731
732	/* Test memory via PIO */
733#ifdef ED_DEBUG
734	device_printf(dev, "ed98_probe_Novell: test memory\n");
735#endif
736	sc->cr_proto = ED_CR_RD2;
737	if (!ed_pio_testmem(sc,  8192, 0, flags) &&
738	    !ed_pio_testmem(sc, 16384, 1, flags))
739		return (ENXIO);
740
741	/* Setup the board type */
742#ifdef ED_DEBUG
743	device_printf(dev, "ed98_probe_Novell: board type\n");
744#endif
745	switch (sc->type) {
746	case ED_TYPE98_BDN:
747		sc->type_str = "LD-BDN";
748		break;
749	case ED_TYPE98_EGY:
750		sc->type_str = "EGY-98";
751		break;
752	case ED_TYPE98_LGY:
753		sc->type_str = "LGY-98";
754		break;
755	case ED_TYPE98_ICM:
756		sc->type_str = "ICM";
757		break;
758	case ED_TYPE98_108:
759		sc->type_str = "PC-9801-108";
760		break;
761	case ED_TYPE98_LA98:
762		sc->type_str = "LA-98";
763		break;
764	case ED_TYPE98_NW98X:
765		sc->type_str = "NW98X";
766		break;
767	case ED_TYPE98_NC5098:
768		sc->type_str = "NC5098";
769		break;
770	default:
771		sc->type_str = NULL;
772		break;
773	}
774
775	/* Get station address */
776	switch (sc->type) {
777	case ED_TYPE98_NC5098:
778		for (n = 0; n < ETHER_ADDR_LEN; n++)
779			sc->enaddr[n] = ed_asic_inb(sc, ED_NC5098_ENADDR + n);
780		break;
781
782	default:
783		ed_pio_readmem(sc, 0, romdata, sizeof(romdata));
784		for (n = 0; n < ETHER_ADDR_LEN; n++)
785			sc->enaddr[n] = 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	sc->sc_write_mbufs = ed_pio_write_mbufs;
793	return (0);
794}
795
796/*
797 * Probe and vendor-specific initialization routine for SIC-98 boards
798 */
799static int
800ed_probe_SIC98(device_t dev, int port_rid, int flags)
801{
802	struct ed_softc *sc = device_get_softc(dev);
803	int error;
804	int i;
805	u_char sum;
806
807	/*
808	 * Setup card RAM and I/O address
809	 * Kernel Virtual to segment C0000-DFFFF????
810	 */
811	error = ed98_alloc_port(dev, port_rid);
812	if (error)
813		return (error);
814
815	sc->asic_offset = ED_SIC_ASIC_OFFSET;
816	sc->nic_offset  = ED_SIC_NIC_OFFSET;
817
818	error = ed98_alloc_memory(dev, 0);
819	if (error)
820		return (error);
821
822	/* Reset card to force it into a known state. */
823	ed_asic_outb(sc, 0, 0x00);
824	DELAY(100);
825	if (ED_TYPE98SUB(flags) == 0) {
826		/* SIC-98/SIU-98 */
827		ed_asic_outb(sc, 0, 0x94);
828		DELAY(100);
829		ed_asic_outb(sc, 0, 0x94);
830	} else {
831		/* SIU-98-D */
832		ed_asic_outb(sc, 0, 0x80);
833		DELAY(100);
834		ed_asic_outb(sc, 0, 0x94);
835		DELAY(100);
836		ed_asic_outb(sc, 0, 0x9e);
837	}
838	DELAY(100);
839
840	/*
841	 * Here we check the card ROM, if the checksum passes, and the
842	 * type code and ethernet address check out, then we know we have
843	 * an SIC card.
844	 */
845	sum = bus_space_read_1(sc->mem_bst, sc->mem_bsh, 6 * 2);
846	for (i = 0; i < ETHER_ADDR_LEN; i++)
847		sum ^= (sc->enaddr[i] =
848		    bus_space_read_1(sc->mem_bst, sc->mem_bsh, i * 2));
849#ifdef ED_DEBUG
850	device_printf(dev, "ed_probe_sic98: got address %6D\n",
851		      sc->enaddr, ":");
852#endif
853	if (sum != 0)
854		return (ENXIO);
855	if ((sc->enaddr[0] | sc->enaddr[1] | sc->enaddr[2]) == 0)
856		return (ENXIO);
857
858	sc->vendor   = ED_VENDOR_SIC;
859	sc->type_str = "SIC98";
860	sc->isa16bit = 1;
861	sc->cr_proto = 0;
862
863	/*
864	 * SIC RAM page 0x0000-0x3fff(or 0x7fff)
865	 */
866	if (ED_TYPE98SUB(flags) == 0)
867		ed_asic_outb(sc, 0, 0x90);
868	else
869		ed_asic_outb(sc, 0, 0x8e);
870	DELAY(100);
871
872	error = ed_clear_memory(dev);
873	if (error)
874		return (error);
875
876	sc->mem_shared = 1;
877	sc->mem_end = sc->mem_start + sc->mem_size;
878
879	/*
880	 * allocate one xmit buffer if < 16k, two buffers otherwise
881	 */
882	if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
883		sc->txb_cnt = 1;
884	else
885		sc->txb_cnt = 2;
886	sc->tx_page_start = 0;
887
888	sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt;
889	sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE;
890
891	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
892
893	sc->sc_write_mbufs = ed_shmem_write_mbufs;
894	return (0);
895}
896
897/*
898 * Contec C-NET(98) series support routines
899 */
900static void
901ed_reset_CNET98(struct ed_softc *sc, int flags)
902{
903	u_int init_addr = ED_CNET98_INIT;
904	u_char tmp;
905
906	/* Choose initial register address */
907	if (ED_TYPE98SUB(flags) != 0) {
908		init_addr = ED_CNET98_INIT2;
909	}
910#ifdef ED_DEBUG
911	printf("ed?: initial register=%x\n", init_addr);
912#endif
913	/*
914	 * Reset the board to force it into a known state.
915	 */
916	outb(init_addr, 0x00);	/* request */
917	DELAY(5000);
918	outb(init_addr, 0x01);	/* cancel */
919	DELAY(5000);
920
921	/*
922	 * Set I/O address(A15-12) and cpu type
923	 *
924	 *   AAAAIXXC(8bit)
925	 *   AAAA: A15-A12,  I: I/O enable, XX: reserved, C: CPU type
926	 *
927	 * CPU type is 1:80286 or higher, 0:not.
928	 * But FreeBSD runs under i386 or higher, thus it must be 1.
929	 */
930	tmp = (rman_get_start(sc->port_res) & 0xf000) >> 8;
931	tmp |= (0x08 | 0x01);
932#ifdef ED_DEBUG
933	printf("ed?: outb(%x, %x)\n", init_addr + 2, tmp);
934#endif
935	outb(init_addr + 2, tmp);
936	DELAY(5000);
937
938	/*
939	 * This is needed because some NE clones apparently don't reset the
940	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
941	 * - this makes the probe invasive! ...Done against my better
942	 * judgement. -DLG
943	 */
944	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
945	DELAY(5000);
946}
947
948static void
949ed_winsel_CNET98(struct ed_softc *sc, u_short bank)
950{
951	u_char mem = (rman_get_start(sc->mem_res) >> 12) & 0xff;
952
953	/*
954	 * Disable window memory
955	 *    bit7 is 0:disable
956	 */
957	ed_asic_outb(sc, ED_CNET98_WIN_REG, mem & 0x7f);
958	DELAY(10);
959
960	/*
961	 * Select window address
962	 *    FreeBSD address 0xf00xxxxx
963	 */
964	ed_asic_outb(sc, ED_CNET98_MAP_REG0L, bank & 0xff);
965	DELAY(10);
966	ed_asic_outb(sc, ED_CNET98_MAP_REG0H, (bank >> 8) & 0xff);
967	DELAY(10);
968	ed_asic_outb(sc, ED_CNET98_MAP_REG1L, 0x00);
969	DELAY(10);
970	ed_asic_outb(sc, ED_CNET98_MAP_REG1H, 0x41);
971	DELAY(10);
972	ed_asic_outb(sc, ED_CNET98_MAP_REG2L, 0x00);
973	DELAY(10);
974	ed_asic_outb(sc, ED_CNET98_MAP_REG2H, 0x42);
975	DELAY(10);
976	ed_asic_outb(sc, ED_CNET98_MAP_REG3L, 0x00);
977	DELAY(10);
978	ed_asic_outb(sc, ED_CNET98_MAP_REG3H, 0x43);
979	DELAY(10);
980
981	/*
982	 * Enable window memory(16Kbyte)
983	 *    bit7 is 1:enable
984	 */
985#ifdef ED_DEBUG
986	printf("ed?: window start address=%x\n", mem);
987#endif
988	ed_asic_outb(sc, ED_CNET98_WIN_REG, mem);
989	DELAY(10);
990}
991
992/*
993 * Probe and vendor-specific initialization routine for C-NET(98) boards
994 */
995static int
996ed_probe_CNET98(device_t dev, int port_rid, int flags)
997{
998	struct ed_softc *sc = device_get_softc(dev);
999	int error;
1000	u_char tmp;
1001	u_long conf_irq, junk;
1002#ifdef DIAGNOSTIC
1003	u_char tmp_s;
1004#endif
1005
1006	error = ed98_alloc_port(dev, port_rid);
1007	if (error)
1008		return (error);
1009
1010	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1011	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1012
1013	error = ed98_alloc_memory(dev, 0);
1014	if (error)
1015		return (error);
1016
1017	/* Check I/O address. 0x[a-f]3d0 are allowed. */
1018	if (((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0)
1019	||  ((rman_get_start(sc->port_res) & 0xf000) < (u_short) 0xa000)) {
1020#ifdef DIAGNOSTIC
1021		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1022			"must be %s for %s\n", rman_get_start(sc->port_res),
1023			"0x[a-f]3d0", "CNET98");
1024#endif
1025		return (ENXIO);
1026	}
1027
1028#ifdef DIAGNOSTIC
1029	/* Check window area address */
1030	tmp_s = rman_get_start(sc->mem_res) >> 12;
1031	if (tmp_s < 0x80) {
1032		device_printf(dev, "Please change window address(0x%lx)\n",
1033		    rman_get_start(sc->mem_res));
1034		return (ENXIO);
1035	}
1036
1037	tmp_s &= 0x0f;
1038	tmp    = rman_get_start(sc->port_res) >> 12;
1039	if ((tmp_s <= tmp) && (tmp < (tmp_s + 4))) {
1040		device_printf(dev, "Please change iobase address(0x%lx) "
1041		    "or window address(0x%lx)\n",
1042		    rman_get_start(sc->port_res),
1043		    rman_get_start(sc->mem_res));
1044		return (ENXIO);
1045	}
1046#endif
1047	/* Reset the board */
1048	ed_reset_CNET98(sc, flags);
1049
1050	/*
1051	 * This is needed because some NE clones apparently don't reset the
1052	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1053	 * - this makes the probe invasive! ...Done against my better
1054	 * judgement. -DLG
1055	 */
1056	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1057	DELAY(5000);
1058
1059	/* Make sure that we really have an 8390 based board */
1060	if (!ed98_probe_generic8390(sc))
1061		return (ENXIO);
1062
1063	/*
1064	 *  Set window ethernet address area
1065	 *    board memory base 0x480000  data 256byte
1066	 */
1067	ed_winsel_CNET98(sc, 0x4800);
1068
1069	/*
1070	 * Get station address from on-board ROM
1071	 */
1072	bus_space_read_region_1(sc->mem_bst, sc->mem_bsh, sc->mem_start,
1073	    sc->enaddr, ETHER_ADDR_LEN);
1074
1075	sc->vendor    = ED_VENDOR_MISC;
1076	sc->type_str  = "CNET98";
1077	sc->isa16bit  = 0;
1078	sc->cr_proto  = ED_CR_RD2;
1079
1080	/*
1081	 * Set window buffer memory area
1082	 *    board memory base 0x400000  data 16kbyte
1083	 */
1084	ed_winsel_CNET98(sc, 0x4000);
1085
1086	error = ed_clear_memory(dev);
1087	if (error)
1088		return (error);
1089
1090	sc->mem_shared = 1;
1091	sc->mem_end = sc->mem_start + sc->mem_size;
1092
1093	sc->txb_cnt = 1;	/* XXX */
1094	sc->tx_page_start = 0;
1095
1096	sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE;
1097	sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE;
1098
1099	sc->mem_ring = sc->mem_start + ED_PAGE_SIZE * ED_TXBUF_SIZE;
1100
1101	/*
1102	 *   Set interrupt level
1103	 */
1104	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1105	if (error)
1106		return (error);
1107
1108	switch (conf_irq) {
1109	case 3:
1110		tmp = ED_CNET98_INT_IRQ3;
1111		break;
1112	case 5:
1113		tmp = ED_CNET98_INT_IRQ5;
1114		break;
1115	case 6:
1116		tmp = ED_CNET98_INT_IRQ6;
1117		break;
1118	case 9:
1119		tmp = ED_CNET98_INT_IRQ9;
1120		break;
1121	case 12:
1122		tmp = ED_CNET98_INT_IRQ12;
1123		break;
1124	case 13:
1125		tmp = ED_CNET98_INT_IRQ13;
1126		break;
1127	default:
1128		device_printf(dev, "Invalid irq configuration (%ld) must be "
1129			"%s for %s\n", conf_irq, "3,5,6,9,12,13", "CNET98");
1130		return (ENXIO);
1131	}
1132	ed_asic_outb(sc, ED_CNET98_INT_LEV, tmp);
1133	DELAY(1000);
1134	/*
1135	 *   Set interrupt mask.
1136	 *     bit7:1 all interrupt mask
1137	 *     bit1:1 timer interrupt mask
1138	 *     bit0:0 NS controler interrupt enable
1139	 */
1140	ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e);
1141	DELAY(1000);
1142
1143	sc->sc_write_mbufs = ed_shmem_write_mbufs;
1144	return (0);
1145}
1146
1147/*
1148 * Probe and vendor-specific initialization routine for C-NET(98)E/L boards
1149 */
1150static int
1151ed_probe_CNET98EL(device_t dev, int port_rid, int flags)
1152{
1153	struct ed_softc *sc = device_get_softc(dev);
1154	int error;
1155	int i;
1156	u_char romdata[ETHER_ADDR_LEN * 2], tmp;
1157	u_long conf_irq, junk;
1158
1159	error = ed98_alloc_port(dev, port_rid);
1160	if (error)
1161		return (error);
1162
1163	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1164	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1165
1166	/* Check I/O address. 0x[0-f]3d0 are allowed. */
1167	if ((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) {
1168#ifdef DIAGNOSTIC
1169		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1170			"must be %s for %s\n", rman_get_start(sc->port_res),
1171			"0x?3d0", "CNET98E/L");
1172#endif
1173		return (ENXIO);
1174	}
1175
1176	/* Reset the board */
1177	ed_reset_CNET98(sc, flags);
1178
1179	/*
1180	 * This is needed because some NE clones apparently don't reset the
1181	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1182	 * - this makes the probe invasive! ...Done against my better
1183	 * judgement. -DLG
1184	 */
1185	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1186	DELAY(5000);
1187
1188	/* Make sure that we really have an 8390 based board */
1189	if (!ed98_probe_generic8390(sc))
1190		return (ENXIO);
1191
1192	/* Test memory via PIO */
1193	sc->cr_proto = ED_CR_RD2;
1194	if (!ed_pio_testmem(sc, ED_CNET98EL_PAGE_OFFSET, 1, flags))
1195		return (ENXIO);
1196
1197	/* This looks like a C-NET(98)E/L board. */
1198	sc->type_str = "CNET98E/L";
1199
1200	/*
1201	 * Set IRQ. C-NET(98)E/L only allows a choice of irq 3,5,6.
1202	 */
1203	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1204	if (error)
1205		return (error);
1206
1207	switch (conf_irq) {
1208	case 3:
1209		tmp = ED_CNET98EL_ICR_IRQ3;
1210		break;
1211	case 5:
1212		tmp = ED_CNET98EL_ICR_IRQ5;
1213		break;
1214	case 6:
1215		tmp = ED_CNET98EL_ICR_IRQ6;
1216		break;
1217#if 0
1218	case 12:
1219		tmp = ED_CNET98EL_ICR_IRQ12;
1220		break;
1221#endif
1222	default:
1223		device_printf(dev, "Invalid irq configuration (%ld) must be "
1224			"%s for %s\n", conf_irq, "3,5,6", "CNET98E/L");
1225		return (ENXIO);
1226	}
1227	ed_asic_outb(sc, ED_CNET98EL_ICR, tmp);
1228	ed_asic_outb(sc, ED_CNET98EL_IMR, 0x7e);
1229
1230	/* Get station address from on-board ROM */
1231	ed_pio_readmem(sc, 16384, romdata, sizeof(romdata));
1232	for (i = 0; i < ETHER_ADDR_LEN; i++)
1233		sc->enaddr[i] = romdata[i * 2];
1234
1235	/* clear any pending interrupts that might have occurred above */
1236	ed_nic_outb(sc, ED_P0_ISR, 0xff);
1237
1238	sc->sc_write_mbufs = ed_pio_write_mbufs;
1239	return (0);
1240}
1241
1242/*
1243 * Probe and vendor-specific initialization routine for PC-9801-77 boards
1244 */
1245static int
1246ed_probe_NEC77(device_t dev, int port_rid, int flags)
1247{
1248	struct ed_softc *sc = device_get_softc(dev);
1249	int error;
1250	u_char tmp;
1251	u_long conf_irq, junk;
1252
1253	error = ed98_probe_Novell(dev, port_rid, flags);
1254	if (error)
1255		return (error);
1256
1257	/* LA/T-98 does not need IRQ setting. */
1258	if (ED_TYPE98SUB(flags) == 0)
1259		return (0);
1260
1261	/*
1262	 * Set IRQ. PC-9801-77 only allows a choice of irq 3,5,6,12,13.
1263	 */
1264	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1265	if (error)
1266		return (error);
1267
1268	switch (conf_irq) {
1269	case 3:
1270		tmp = ED_NEC77_IRQ3;
1271		break;
1272	case 5:
1273		tmp = ED_NEC77_IRQ5;
1274		break;
1275	case 6:
1276		tmp = ED_NEC77_IRQ6;
1277		break;
1278	case 12:
1279		tmp = ED_NEC77_IRQ12;
1280		break;
1281	case 13:
1282		tmp = ED_NEC77_IRQ13;
1283		break;
1284	default:
1285		device_printf(dev, "Invalid irq configuration (%ld) must be "
1286			"%s for %s\n", conf_irq, "3,5,6,12,13", "PC-9801-77");
1287		return (ENXIO);
1288	}
1289	ed_asic_outb(sc, ED_NEC77_IRQ, tmp);
1290
1291	return (0);
1292}
1293
1294/*
1295 * Probe and vendor-specific initialization routine for EC/EP-98X boards
1296 */
1297static int
1298ed_probe_NW98X(device_t dev, int port_rid, int flags)
1299{
1300	struct ed_softc *sc = device_get_softc(dev);
1301	int error;
1302	u_char tmp;
1303	u_long conf_irq, junk;
1304
1305	error = ed98_probe_Novell(dev, port_rid, flags);
1306	if (error)
1307		return (error);
1308
1309	/* Networld 98X3 does not need IRQ setting. */
1310	if (ED_TYPE98SUB(flags) == 0)
1311		return (0);
1312
1313	/*
1314	 * Set IRQ. EC/EP-98X only allows a choice of irq 3,5,6,12,13.
1315	 */
1316	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1317	if (error)
1318		return (error);
1319
1320	switch (conf_irq) {
1321	case 3:
1322		tmp = ED_NW98X_IRQ3;
1323		break;
1324	case 5:
1325		tmp = ED_NW98X_IRQ5;
1326		break;
1327	case 6:
1328		tmp = ED_NW98X_IRQ6;
1329		break;
1330	case 12:
1331		tmp = ED_NW98X_IRQ12;
1332		break;
1333	case 13:
1334		tmp = ED_NW98X_IRQ13;
1335		break;
1336	default:
1337		device_printf(dev, "Invalid irq configuration (%ld) must be "
1338			"%s for %s\n", conf_irq, "3,5,6,12,13", "EC/EP-98X");
1339		return (ENXIO);
1340	}
1341	ed_asic_outb(sc, ED_NW98X_IRQ, tmp);
1342
1343	return (0);
1344}
1345
1346/*
1347 * Read SB-9801 station address from Serial Two-Wire EEPROM
1348 */
1349static void
1350ed_get_SB98(struct ed_softc *sc)
1351{
1352	int i, j;
1353	u_char mask, val;
1354
1355        /* enable EEPROM acceess */
1356        ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_ENABLE);
1357
1358	/* output start command */
1359	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1360	DELAY(ED_SB98_EEP_DELAY);
1361	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1362	DELAY(ED_SB98_EEP_DELAY);
1363
1364       	/* output address (7bit) */
1365	for (mask = 0x40; mask != 0; mask >>= 1) {
1366		val = 0;
1367		if (ED_SB98_ADDRESS & mask)
1368			val = ED_SB98_EEP_SDA;
1369		ed_asic_outb(sc, ED_SB98_EEP, val);
1370		DELAY(ED_SB98_EEP_DELAY);
1371		ed_asic_outb(sc, ED_SB98_EEP, val | ED_SB98_EEP_SCL);
1372		DELAY(ED_SB98_EEP_DELAY);
1373	}
1374
1375	/* output READ command */
1376	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ);
1377	DELAY(ED_SB98_EEP_DELAY);
1378	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ | ED_SB98_EEP_SCL);
1379	DELAY(ED_SB98_EEP_DELAY);
1380
1381	/* read station address */
1382	for (i = 0; i < ETHER_ADDR_LEN; i++) {
1383		/* output ACK */
1384		ed_asic_outb(sc, ED_SB98_EEP, 0);
1385		DELAY(ED_SB98_EEP_DELAY);
1386		ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1387		DELAY(ED_SB98_EEP_DELAY);
1388
1389		val = 0;
1390		for (j = 0; j < 8; j++) {
1391			ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA);
1392			DELAY(ED_SB98_EEP_DELAY);
1393			ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1394			DELAY(ED_SB98_EEP_DELAY);
1395			val <<= 1;
1396			val |= (ed_asic_inb(sc, ED_SB98_EEP) & ED_SB98_EEP_SDA);
1397			DELAY(ED_SB98_EEP_DELAY);
1398	  	}
1399		sc->enaddr[i] = val;
1400	}
1401
1402	/* output Last ACK */
1403        ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA);
1404        DELAY(ED_SB98_EEP_DELAY);
1405        ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1406        DELAY(ED_SB98_EEP_DELAY);
1407
1408	/* output stop command */
1409	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL);
1410	DELAY(ED_SB98_EEP_DELAY);
1411	ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL);
1412	DELAY(ED_SB98_EEP_DELAY);
1413
1414	/* disable EEPROM access */
1415	ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_DISABLE);
1416}
1417
1418/*
1419 * Probe and vendor-specific initialization routine for SB-9801 boards
1420 */
1421static int
1422ed_probe_SB98(device_t dev, int port_rid, int flags)
1423{
1424	struct ed_softc *sc = device_get_softc(dev);
1425	int error;
1426	u_char tmp;
1427	u_long conf_irq, junk;
1428
1429	error = ed98_alloc_port(dev, port_rid);
1430	if (error)
1431		return (error);
1432
1433	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
1434	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
1435
1436	/* Check I/O address. 00d[02468ace] are allowed. */
1437	if ((rman_get_start(sc->port_res) & ~0x000e) != 0x00d0) {
1438#ifdef DIAGNOSTIC
1439		device_printf(dev, "Invalid i/o port configuration (0x%lx) "
1440		    "must be %s for %s\n", rman_get_start(sc->port_res),
1441		    "0xd?", "SB9801");
1442#endif
1443		return (ENXIO);
1444	}
1445
1446	/* Write I/O port address and read 4 times */
1447	outb(ED_SB98_IO_INHIBIT, rman_get_start(sc->port_res) & 0xff);
1448	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1449	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1450	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1451	(void) inb(ED_SB98_IO_INHIBIT); DELAY(300);
1452
1453	/*
1454	 * Check IRQ. Soliton SB-9801 only allows a choice of
1455	 * irq 3,5,6,12
1456	 */
1457	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk);
1458	if (error)
1459		return (error);
1460
1461	switch (conf_irq) {
1462	case 3:
1463		tmp = ED_SB98_CFG_IRQ3;
1464		break;
1465	case 5:
1466		tmp = ED_SB98_CFG_IRQ5;
1467		break;
1468	case 6:
1469		tmp = ED_SB98_CFG_IRQ6;
1470		break;
1471	case 12:
1472		tmp = ED_SB98_CFG_IRQ12;
1473		break;
1474	default:
1475		device_printf(dev, "Invalid irq configuration (%ld) must be "
1476			"%s for %s\n", conf_irq, "3,5,6,12", "SB9801");
1477		return (ENXIO);
1478	}
1479
1480	if (flags & ED_FLAGS_DISABLE_TRANCEIVER)
1481		tmp |= ED_SB98_CFG_ALTPORT;
1482	ed_asic_outb(sc, ED_SB98_CFG, ED_SB98_CFG_ENABLE | tmp);
1483	ed_asic_outb(sc, ED_SB98_POLARITY, 0x01);
1484
1485	/* Reset the board. */
1486	ed_asic_outb(sc, ED_NOVELL_RESET, 0x7a);
1487	DELAY(300);
1488	ed_asic_outb(sc, ED_NOVELL_RESET, 0x79);
1489	DELAY(300);
1490
1491	/*
1492	 * This is needed because some NE clones apparently don't reset the
1493	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
1494	 * - this makes the probe invasive! ...Done against my better
1495	 * judgement. -DLG
1496	 */
1497	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
1498	DELAY(5000);
1499
1500	/* Make sure that we really have an 8390 based board */
1501	if (!ed98_probe_generic8390(sc))
1502		return (ENXIO);
1503
1504	/* Test memory via PIO */
1505	sc->cr_proto = ED_CR_RD2;
1506	if (!ed_pio_testmem(sc, 16384, 1, flags))
1507		return (ENXIO);
1508
1509	/* This looks like an SB9801 board. */
1510	sc->type_str = "SB9801";
1511
1512	/* Get station address */
1513	ed_get_SB98(sc);
1514
1515	/* clear any pending interrupts that might have occurred above */
1516	ed_nic_outb(sc, ED_P0_ISR, 0xff);
1517
1518	sc->sc_write_mbufs = ed_pio_write_mbufs;
1519	return (0);
1520}
1521
1522/*
1523 * Test the ability to read and write to the NIC memory.
1524 */
1525static int
1526ed_pio_testmem(struct ed_softc *sc, int page_offset, int isa16bit, int flags)
1527{
1528	u_long memsize;
1529	static char test_pattern[32] = "THIS is A memory TEST pattern";
1530	char test_buffer[32];
1531#ifdef DIAGNOSTIC
1532	int page_end;
1533#endif
1534
1535	sc->vendor = ED_VENDOR_NOVELL;
1536	sc->mem_shared = 0;
1537	sc->isa16bit = isa16bit;
1538
1539	/* 8k of memory plus an additional 8k if 16bit */
1540	memsize = (isa16bit ? 16384 : 8192);
1541
1542	/*
1543	 * This prevents packets from being stored in the NIC memory when the
1544	 * readmem routine turns on the start bit in the CR.
1545	 */
1546	ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
1547
1548	/* Initialize DCR for byte/word operations */
1549	if (isa16bit)
1550		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
1551	else
1552		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
1553	ed_nic_outb(sc, ED_P0_PSTART, page_offset / ED_PAGE_SIZE);
1554	ed_nic_outb(sc, ED_P0_PSTOP, (page_offset + memsize) / ED_PAGE_SIZE);
1555#ifdef ED_DEBUG
1556	printf("ed?: ed_pio_testmem: page start=%x, end=%lx",
1557	    page_offset, page_offset + memsize);
1558#endif
1559
1560	/*
1561	 * Write a test pattern. If this fails, then we don't know
1562	 * what this board is.
1563	 */
1564	ed_pio_writemem(sc, test_pattern, page_offset, sizeof(test_pattern));
1565	ed_pio_readmem(sc, page_offset, test_buffer, sizeof(test_pattern));
1566
1567	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
1568#ifdef ED_DEBUG
1569		printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_offset);
1570#endif
1571		return (0);
1572	}
1573
1574#ifdef DIAGNOSTIC
1575	/* Check the bottom. */
1576	page_end = page_offset + memsize - ED_PAGE_SIZE;
1577	ed_pio_writemem(sc, test_pattern, page_end, sizeof(test_pattern));
1578	ed_pio_readmem(sc, page_end, test_buffer, sizeof(test_pattern));
1579
1580	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
1581#ifdef ED_DEBUG
1582		printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_end);
1583#endif
1584		return (0);
1585	}
1586#endif
1587	sc->mem_size = memsize;
1588	sc->mem_start = page_offset;
1589	sc->mem_end   = sc->mem_start + memsize;
1590	sc->tx_page_start = page_offset / ED_PAGE_SIZE;
1591
1592	/*
1593	 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
1594	 * otherwise).
1595	 */
1596	if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
1597		sc->txb_cnt = 1;
1598	else
1599		sc->txb_cnt = 2;
1600
1601	sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
1602	sc->rec_page_stop  = sc->tx_page_start + memsize / ED_PAGE_SIZE;
1603
1604	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
1605
1606	return (1);
1607}
1608
1609static device_method_t ed_cbus_methods[] = {
1610	/* Device interface */
1611	DEVMETHOD(device_probe,		ed_cbus_probe),
1612	DEVMETHOD(device_attach,	ed_cbus_attach),
1613	DEVMETHOD(device_detach,	ed_detach),
1614
1615	{ 0, 0 }
1616};
1617
1618static driver_t ed_cbus_driver = {
1619	"ed",
1620	ed_cbus_methods,
1621	sizeof(struct ed_softc)
1622};
1623
1624DRIVER_MODULE(ed, isa, ed_cbus_driver, ed_devclass, 0, 0);
1625MODULE_DEPEND(ed, isa, 1, 1, 1);
1626MODULE_DEPEND(ed, ether, 1, 1, 1);
1627