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