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