Annotation of sys/dev/isa/if_le_isa.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_le_isa.c,v 1.19 2007/06/17 21:20:47 jasper Exp $ */
2: /* $NetBSD: if_le_isa.c,v 1.2 1996/05/12 23:52:56 mycroft Exp $ */
3:
4: /*-
5: * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
6: * Copyright (c) 1992, 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * Ralph Campbell and Rick Macklem.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: *
36: * @(#)if_le.c 8.2 (Berkeley) 11/16/93
37: */
38:
39: #include "bpfilter.h"
40: #include "isadma.h"
41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/mbuf.h>
45: #include <sys/syslog.h>
46: #include <sys/socket.h>
47: #include <sys/device.h>
48:
49: #include <net/if.h>
50: #include <net/if_media.h>
51:
52: #ifdef INET
53: #include <netinet/in.h>
54: #include <netinet/if_ether.h>
55: #endif
56:
57: #include <machine/cpu.h>
58: #include <machine/intr.h>
59:
60: #include <dev/isa/isareg.h>
61: #include <dev/isa/isavar.h>
62: #include <dev/isa/isadmavar.h>
63:
64: #include <dev/ic/am7990reg.h>
65: #include <dev/ic/am7990var.h>
66:
67: #include <dev/isa/if_levar.h>
68:
69: static char *card_type[] =
70: { "unknown", "BICC Isolan", "NE2100", "DEPCA", "PCnet-ISA" };
71:
72: int le_isa_probe(struct device *, void *, void *);
73: void le_isa_attach(struct device *, struct device *, void *);
74:
75: struct cfattach le_isa_ca = {
76: sizeof(struct le_softc), le_isa_probe, le_isa_attach
77: };
78:
79: int depca_isa_probe(struct le_softc *, struct isa_attach_args *);
80: int ne2100_isa_probe(struct le_softc *, struct isa_attach_args *);
81: int bicc_isa_probe(struct le_softc *, struct isa_attach_args *);
82: int lance_isa_probe(struct am7990_softc *);
83:
84: int
85: le_isa_probe(struct device *parent, void *match, void *aux)
86: {
87: struct le_softc *lesc = match;
88: struct isa_attach_args *ia = aux;
89: u_int8_t bogusether[ETHER_ADDR_LEN] = { 255, 255, 255, 255, 255, 255 };
90:
91: #if NISADMA == 0
92: if (ia->ia_drq != DRQUNK) {
93: printf("cannot support dma lance devices\n");
94: return 0;
95: }
96: #endif
97:
98: if (bicc_isa_probe(lesc, ia) == 0 && ne2100_isa_probe(lesc, ia) == 0 &&
99: depca_isa_probe(lesc, ia) == 0)
100: return (0);
101:
102: if (bcmp(lesc->sc_am7990.sc_arpcom.ac_enaddr, bogusether,
103: sizeof(bogusether)) == 0)
104: return (0);
105:
106: return (1);
107: }
108:
109: int
110: depca_isa_probe(struct le_softc *lesc, struct isa_attach_args *ia)
111: {
112: struct am7990_softc *sc = &lesc->sc_am7990;
113: bus_space_tag_t iot = lesc->sc_iot;
114: bus_space_handle_t ioh = lesc->sc_ioh;
115: int iosize = 16;
116: int port;
117:
118: #if 0
119: u_long sum, rom_sum;
120: u_char x;
121: #endif
122: int i;
123:
124: if (bus_space_map(iot, ia->ia_iobase, iosize, 0, &ioh))
125: return (0);
126: lesc->sc_iot = iot;
127: lesc->sc_ioh = ioh;
128: lesc->sc_rap = DEPCA_RAP;
129: lesc->sc_rdp = DEPCA_RDP;
130: lesc->sc_card = DEPCA;
131:
132: if (lance_isa_probe(sc) == 0) {
133: bus_space_unmap(iot, ioh, iosize);
134: return 0;
135: }
136:
137: bus_space_write_1(iot, ioh, DEPCA_CSR, DEPCA_CSR_DUM);
138:
139: /*
140: * Extract the physical MAC address from the ROM.
141: *
142: * The address PROM is 32 bytes wide, and we access it through
143: * a single I/O port. On each read, it rotates to the next
144: * position. We find the ethernet address by looking for a
145: * particular sequence of bytes (0xff, 0x00, 0x55, 0xaa, 0xff,
146: * 0x00, 0x55, 0xaa), and then reading the next 8 bytes (the
147: * ethernet address and a checksum).
148: *
149: * It appears that the PROM can be at one of two locations, so
150: * we just try both.
151: */
152: port = DEPCA_ADP;
153: for (i = 0; i < 32; i++)
154: if (bus_space_read_1(iot, ioh, port) == 0xff &&
155: bus_space_read_1(iot, ioh, port) == 0x00 &&
156: bus_space_read_1(iot, ioh, port) == 0x55 &&
157: bus_space_read_1(iot, ioh, port) == 0xaa &&
158: bus_space_read_1(iot, ioh, port) == 0xff &&
159: bus_space_read_1(iot, ioh, port) == 0x00 &&
160: bus_space_read_1(iot, ioh, port) == 0x55 &&
161: bus_space_read_1(iot, ioh, port) == 0xaa)
162: goto found;
163: port = DEPCA_ADP + 1;
164: for (i = 0; i < 32; i++)
165: if (bus_space_read_1(iot, ioh, port) == 0xff &&
166: bus_space_read_1(iot, ioh, port) == 0x00 &&
167: bus_space_read_1(iot, ioh, port) == 0x55 &&
168: bus_space_read_1(iot, ioh, port) == 0xaa &&
169: bus_space_read_1(iot, ioh, port) == 0xff &&
170: bus_space_read_1(iot, ioh, port) == 0x00 &&
171: bus_space_read_1(iot, ioh, port) == 0x55 &&
172: bus_space_read_1(iot, ioh, port) == 0xaa)
173: goto found;
174: printf("%s: address not found\n", sc->sc_dev.dv_xname);
175: return 0;
176:
177: found:
178: for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
179: sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, port);
180:
181: #if 0
182: sum =
183: (sc->sc_arpcom.ac_enaddr[0] << 2) +
184: (sc->sc_arpcom.ac_enaddr[1] << 10) +
185: (sc->sc_arpcom.ac_enaddr[2] << 1) +
186: (sc->sc_arpcom.ac_enaddr[3] << 9) +
187: (sc->sc_arpcom.ac_enaddr[4] << 0) +
188: (sc->sc_arpcom.ac_enaddr[5] << 8);
189: sum = (sum & 0xffff) + (sum >> 16);
190: sum = (sum & 0xffff) + (sum >> 16);
191:
192: rom_sum = bus_space_read_1(iot, ioh, port);
193: rom_sum |= bus_space_read_1(iot, ioh, port << 8);
194:
195: if (sum != rom_sum) {
196: printf("%s: checksum mismatch; calculated %04x != read %04x",
197: sc->sc_dev.dv_xname, sum, rom_sum);
198: bus_space_unmap(iot, ioh, iosize);
199: return 0;
200: }
201: #endif
202:
203: bus_space_write_1(iot, ioh, DEPCA_CSR, DEPCA_CSR_NORMAL);
204:
205: ia->ia_iosize = iosize;
206: ia->ia_drq = DRQUNK;
207: bus_space_unmap(iot, ioh, ia->ia_iosize);
208: return 1;
209: }
210:
211: int
212: ne2100_isa_probe(struct le_softc *lesc, struct isa_attach_args *ia)
213: {
214: struct am7990_softc *sc = &lesc->sc_am7990;
215: bus_space_tag_t iot = lesc->sc_iot;
216: bus_space_handle_t ioh = lesc->sc_ioh;
217: int iosize = 24;
218: int i;
219:
220: if (bus_space_map(iot, ia->ia_iobase, iosize, 0, &ioh))
221: return (0);
222: lesc->sc_iot = iot;
223: lesc->sc_ioh = ioh;
224: lesc->sc_rap = NE2100_RAP;
225: lesc->sc_rdp = NE2100_RDP;
226: lesc->sc_card = NE2100;
227:
228: if (lance_isa_probe(sc) == 0) {
229: bus_space_unmap(iot, ioh, iosize);
230: return 0;
231: }
232:
233: /*
234: * Extract the physical MAC address from the ROM.
235: */
236: for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
237: sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, i);
238:
239: ia->ia_iosize = iosize;
240: bus_space_unmap(iot, ioh, ia->ia_iosize);
241: return 1;
242: }
243:
244: int
245: bicc_isa_probe(struct le_softc *lesc, struct isa_attach_args *ia)
246: {
247: struct am7990_softc *sc = &lesc->sc_am7990;
248: bus_space_handle_t ioh;
249: bus_space_tag_t iot = ia->ia_iot;
250: int iosize = 16;
251: int i;
252:
253: if (bus_space_map(iot, ia->ia_iobase, iosize, 0, &ioh))
254: return (0);
255: lesc->sc_iot = iot;
256: lesc->sc_ioh = ioh;
257: lesc->sc_rap = BICC_RAP;
258: lesc->sc_rdp = BICC_RDP;
259: lesc->sc_card = BICC;
260:
261: if (lance_isa_probe(sc) == 0) {
262: bus_space_unmap(iot, ioh, iosize);
263: return 0;
264: }
265:
266: /*
267: * Extract the physical MAC address from the ROM.
268: */
269: for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
270: sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, i * 2);
271:
272: ia->ia_iosize = iosize;
273: bus_space_unmap(iot, ioh, ia->ia_iosize);
274: return 1;
275: }
276:
277: /*
278: * Determine which chip is present on the card.
279: */
280: int
281: lance_isa_probe(struct am7990_softc *sc)
282: {
283:
284: /* Stop the LANCE chip and put it in a known state. */
285: le_isa_wrcsr(sc, LE_CSR0, LE_C0_STOP);
286: delay(100);
287:
288: if (le_isa_rdcsr(sc, LE_CSR0) != LE_C0_STOP)
289: return 0;
290:
291: le_isa_wrcsr(sc, LE_CSR3, sc->sc_conf3);
292: return 1;
293: }
294:
295: void
296: le_isa_attach(struct device *parent, struct device *self,
297: void *aux)
298: {
299: struct le_softc *lesc = (void *)self;
300: struct am7990_softc *sc = &lesc->sc_am7990;
301: struct isa_attach_args *ia = aux;
302: bus_space_tag_t iot = ia->ia_iot;
303: bus_space_handle_t ioh;
304:
305: if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh))
306: panic("%s: could not map I/O-ports", sc->sc_dev.dv_xname);
307: lesc->sc_iot = iot;
308: lesc->sc_ioh = ioh;
309:
310: printf(": %s Ethernet\n", card_type[lesc->sc_card]);
311:
312: if (lesc->sc_card == DEPCA) {
313: u_char *mem, val;
314: int i;
315:
316: mem = sc->sc_mem = ISA_HOLE_VADDR(ia->ia_maddr);
317:
318: val = 0xff;
319: for (;;) {
320: for (i = 0; i < ia->ia_msize; i++)
321: mem[i] = val;
322: for (i = 0; i < ia->ia_msize; i++)
323: if (mem[i] != val) {
324: printf("%s: failed to clear memory\n",
325: sc->sc_dev.dv_xname);
326: return;
327: }
328: if (val == 0x00)
329: break;
330: val -= 0x55;
331: }
332:
333: sc->sc_conf3 = LE_C3_ACON;
334: sc->sc_addr = 0;
335: sc->sc_memsize = ia->ia_msize;
336: } else {
337: sc->sc_mem = malloc(16384, M_DEVBUF, M_NOWAIT);
338: if (sc->sc_mem == 0) {
339: printf("%s: couldn't allocate memory for card\n",
340: sc->sc_dev.dv_xname);
341: return;
342: }
343:
344: sc->sc_conf3 = 0;
345: sc->sc_addr = kvtop(sc->sc_mem);
346: sc->sc_memsize = 16384;
347: }
348:
349: sc->sc_copytodesc = am7990_copytobuf_contig;
350: sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
351: sc->sc_copytobuf = am7990_copytobuf_contig;
352: sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
353: sc->sc_zerobuf = am7990_zerobuf_contig;
354:
355: sc->sc_rdcsr = le_isa_rdcsr;
356: sc->sc_wrcsr = le_isa_wrcsr;
357: sc->sc_hwreset = NULL;
358: sc->sc_hwinit = NULL;
359:
360: printf("%s", sc->sc_dev.dv_xname);
361: am7990_config(sc);
362:
363: #if NISADMA > 0
364: if (ia->ia_drq != DRQUNK)
365: isadma_cascade(ia->ia_drq);
366: #endif
367:
368: lesc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
369: IPL_NET, le_isa_intredge, sc, sc->sc_dev.dv_xname);
370: }
CVSweb