xref: /netbsd/sys/arch/mac68k/nubus/if_sn_nubus.c (revision c4a72b64)
1 /*	$NetBSD: if_sn_nubus.c,v 1.22 2002/10/02 05:36:38 thorpej Exp $	*/
2 
3 /*
4  * Copyright (C) 1997 Allen Briggs
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Allen Briggs
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "opt_inet.h"
34 
35 #include <sys/param.h>
36 #include <sys/device.h>
37 #include <sys/errno.h>
38 #include <sys/ioctl.h>
39 #include <sys/socket.h>
40 #include <sys/syslog.h>
41 #include <sys/systm.h>
42 
43 #include <net/if.h>
44 #include <net/if_ether.h>
45 
46 #if 0 /* XXX this shouldn't be necessary; else reinsert */
47 #ifdef INET
48 #include <netinet/in.h>
49 #include <netinet/if_inarp.h>
50 #endif
51 #endif
52 
53 #include <machine/bus.h>
54 #include <machine/viareg.h>
55 
56 #include <mac68k/nubus/nubus.h>
57 #include <mac68k/dev/if_snreg.h>
58 #include <mac68k/dev/if_snvar.h>
59 
60 static int	sn_nubus_match __P((struct device *, struct cfdata *, void *));
61 static void	sn_nubus_attach __P((struct device *, struct device *, void *));
62 static int	sn_nb_card_vendor __P((bus_space_tag_t, bus_space_handle_t,
63 		    struct nubus_attach_args *));
64 
65 CFATTACH_DECL(sn_nubus, sizeof(struct sn_softc),
66     sn_nubus_match, sn_nubus_attach, NULL, NULL);
67 
68 
69 static int
70 sn_nubus_match(parent, cf, aux)
71 	struct device *parent;
72 	struct cfdata *cf;
73 	void *aux;
74 {
75 	struct nubus_attach_args *na = (struct nubus_attach_args *) aux;
76 	bus_space_handle_t bsh;
77 	int rv;
78 
79 	if (bus_space_map(na->na_tag,
80 	    NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh))
81 		return (0);
82 
83 	rv = 0;
84 
85 	if (na->category == NUBUS_CATEGORY_NETWORK &&
86 	    na->type == NUBUS_TYPE_ETHERNET) {
87 		switch (sn_nb_card_vendor(na->na_tag, bsh, na)) {
88 		default:
89 			break;
90 
91 		case SN_VENDOR_APPLE:
92 		case SN_VENDOR_APPLE16:
93 		case SN_VENDOR_ASANTELC:
94 		case SN_VENDOR_DAYNA:
95 			rv = 1;
96 			break;
97 		}
98 	}
99 
100 	bus_space_unmap(na->na_tag, bsh, NBMEMSIZE);
101 
102 	return rv;
103 }
104 
105 /*
106  * Install interface into kernel networking data structures
107  */
108 static void
109 sn_nubus_attach(parent, self, aux)
110 	struct device *parent, *self;
111 	void   *aux;
112 {
113 	struct sn_softc *sc = (void *)self;
114 	struct nubus_attach_args *na = (struct nubus_attach_args *)aux;
115 	int i, success, offset;
116 	bus_space_tag_t	bst;
117 	bus_space_handle_t bsh, tmp_bsh;
118 	u_int8_t myaddr[ETHER_ADDR_LEN];
119 	char *cardtype;
120 
121 	(void)(&offset);	/* Work around lame gcc initialization bug */
122 
123 	bst = na->na_tag;
124 	if (bus_space_map(bst, NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh)) {
125 		printf(": failed to map memory space.\n");
126 		return;
127 	}
128 
129 	sc->sc_regt = bst;
130 
131 	cardtype = nubus_get_card_name(bst, bsh, na->fmt);
132 
133 	success = 0;
134 
135 	sc->slotno = na->slot;
136 
137 	switch (sn_nb_card_vendor(bst, bsh, na)) {
138 	case SN_VENDOR_DAYNA:
139 		sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 |
140 		    DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
141 		sc->snr_dcr2 = 0;
142 		sc->bitmode = 1;	/* 32 bit card */
143 
144 		if (bus_space_subregion(bst, bsh,
145 		    0x00180000, SN_REGSIZE, &sc->sc_regh)) {
146 			printf(": failed to map register space.\n");
147 			break;
148 		}
149 
150 		if (bus_space_subregion(bst, bsh,
151 		    0x00ffe004, ETHER_ADDR_LEN, &tmp_bsh)) {
152 			printf(": failed to map ROM space.\n");
153 			break;
154 		}
155 
156 		sn_get_enaddr(bst, tmp_bsh, 0, myaddr);
157 
158 		offset = 2;
159 		success = 1;
160 		break;
161 
162 	case SN_VENDOR_APPLE:
163 		sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 |
164 		    DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
165 		sc->snr_dcr2 = 0;
166 		sc->bitmode = 1; /* 32 bit card */
167 
168 		if (bus_space_subregion(bst, bsh,
169 		    0x0, SN_REGSIZE, &sc->sc_regh)) {
170 			printf(": failed to map register space.\n");
171 			break;
172 		}
173 
174 		if (bus_space_subregion(bst, bsh,
175 		    0x40000, ETHER_ADDR_LEN, &tmp_bsh)) {
176 			printf(": failed to map ROM space.\n");
177 			break;
178 		}
179 
180 		sn_get_enaddr(bst, tmp_bsh, 0, myaddr);
181 
182 		offset = 0;
183 		success = 1;
184 		break;
185 
186 	case SN_VENDOR_APPLE16:
187 		sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 | DCR_EXBUS |
188 		    DCR_DMABLOCK | DCR_PO1 | DCR_RFT16 | DCR_TFT16;
189 		sc->snr_dcr2 = 0;
190 		sc->bitmode = 0; /* 16 bit card */
191 
192 		if (bus_space_subregion(bst, bsh,
193 		    0x0, SN_REGSIZE, &sc->sc_regh)) {
194 			printf(": failed to map register space.\n");
195 			break;
196 		}
197 
198 		if (bus_space_subregion(bst, bsh,
199 		    0x40000, ETHER_ADDR_LEN, &tmp_bsh)) {
200 			printf(": failed to map ROM space.\n");
201 			break;
202 		}
203 
204 		sn_get_enaddr(bst, tmp_bsh, 0, myaddr);
205 
206 		offset = 0;
207 		success = 1;
208 		break;
209 
210 	case SN_VENDOR_ASANTELC: /* Macintosh LC Ethernet Adapter */
211 		sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 |
212 		    DCR_DMABLOCK | DCR_PO1 | DCR_RFT16 | DCR_TFT16;
213 		sc->snr_dcr2 = 0;
214 		sc->bitmode = 0; /* 16 bit card */
215 
216 		if (bus_space_subregion(bst, bsh,
217 		    0x0, SN_REGSIZE, &sc->sc_regh)) {
218 			printf(": failed to map register space.\n");
219 			break;
220 		}
221 
222 		if (bus_space_subregion(bst, bsh,
223 		    0x400000, ETHER_ADDR_LEN, &tmp_bsh)) {
224 			printf(": failed to map ROM space.\n");
225 			break;
226 		}
227 
228 		sn_get_enaddr(bst, tmp_bsh, 0, myaddr);
229 
230 		offset = 0;
231 		success = 1;
232 		break;
233 
234 	default:
235 		/*
236 		 * You can't actually get this default, the snmatch
237 		 * will fail for unknown hardware. If you're adding support
238 		 * for a new card, the following defaults are a
239 		 * good starting point.
240 		 */
241 		sc->snr_dcr = DCR_SYNC | DCR_WAIT0 | DCR_DW32 |
242 		    DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
243 		sc->snr_dcr2 = 0;
244 		success = 0;
245 		printf(": unknown card: attachment incomplete.\n");
246 	}
247 
248 	if (!success) {
249 		bus_space_unmap(bst, bsh, NBMEMSIZE);
250 		return;
251 	}
252 
253 	/* Regs are addressed as words, big endian. */
254 	for (i = 0; i < SN_NREGS; i++) {
255 		sc->sc_reg_map[i] = (bus_size_t)((i * 4) + offset);
256 	}
257 
258 	printf(": %s\n", cardtype);
259 
260 	/* snsetup returns 1 if something fails */
261 	if (snsetup(sc, myaddr)) {
262 		bus_space_unmap(bst, bsh, NBMEMSIZE);
263 		return;
264 	}
265 
266 	add_nubus_intr(sc->slotno, snintr, (void *)sc);
267 
268 	return;
269 }
270 
271 static int
272 sn_nb_card_vendor(bst, bsh, na)
273 	bus_space_tag_t bst;
274 	bus_space_handle_t bsh;
275 	struct nubus_attach_args *na;
276 {
277 	int vendor = SN_VENDOR_UNKNOWN;
278 
279 	switch (na->drsw) {
280 	case NUBUS_DRSW_3COM:
281 		if (na->drhw == NUBUS_DRHW_APPLE_SNT)
282 			vendor = SN_VENDOR_APPLE;
283 		else if (na->drhw == NUBUS_DRHW_APPLE_SN)
284 			vendor = SN_VENDOR_APPLE16;
285 		break;
286 	case NUBUS_DRSW_APPLE:
287 		if (na->drhw == NUBUS_DRHW_ASANTE_LC)
288 			vendor = SN_VENDOR_ASANTELC;
289 		else
290 			vendor = SN_VENDOR_APPLE;
291 		break;
292 	case NUBUS_DRSW_TECHWORKS:
293 		vendor = SN_VENDOR_APPLE;
294 		break;
295 	case NUBUS_DRSW_GATOR:
296 		if (na->drhw == NUBUS_DRHW_KINETICS &&
297 		    strncmp(nubus_get_card_name(bst, bsh, na->fmt),
298 		    "EtherPort", 9) != 0)
299 			vendor = SN_VENDOR_DAYNA;
300 		break;
301 	case NUBUS_DRSW_DAYNA:
302 		vendor = SN_VENDOR_DAYNA;
303 		break;
304 	}
305 
306 	return vendor;
307 }
308