Annotation of sys/dev/eisa/if_fea.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_fea.c,v 1.17 2004/05/12 06:35:10 tedu Exp $ */
2: /* $NetBSD: if_fea.c,v 1.9 1996/10/21 22:31:05 thorpej Exp $ */
3:
4: /*-
5: * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. The name of the author may not be used to endorse or promote products
14: * derived from this software without specific prior written permission
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: *
27: * Id: if_fea.c,v 1.6 1996/06/07 20:02:25 thomas Exp
28: */
29:
30: /*
31: * DEC PDQ FDDI Controller
32: *
33: * This module support the DEFEA EISA FDDI Controller.
34: */
35:
36:
37: #include <sys/param.h>
38: #include <sys/kernel.h>
39: #include <sys/mbuf.h>
40: #include <sys/protosw.h>
41: #include <sys/socket.h>
42: #include <sys/ioctl.h>
43: #include <sys/errno.h>
44: #include <sys/malloc.h>
45: #include <sys/device.h>
46:
47: #include <net/if.h>
48: #include <net/if_types.h>
49: #include <net/if_dl.h>
50: #include <net/route.h>
51:
52: #include "bpfilter.h"
53: #if NBPFILTER > 0
54: #include <net/bpf.h>
55: #endif
56:
57: #ifdef INET
58: #include <netinet/in.h>
59: #include <netinet/in_systm.h>
60: #include <netinet/in_var.h>
61: #include <netinet/ip.h>
62: #include <netinet/if_ether.h>
63: #endif
64:
65: #include <net/if_fddi.h>
66:
67: #include <machine/cpu.h>
68: #include <machine/bus.h>
69:
70: #include <dev/ic/pdqvar.h>
71: #include <dev/ic/pdqreg.h>
72:
73: #include <dev/eisa/eisareg.h>
74: #include <dev/eisa/eisavar.h>
75: #include <dev/eisa/eisadevs.h>
76:
77: /*
78: *
79: */
80:
81: void pdq_eisa_subprobe(bus_space_tag_t, bus_space_handle_t,
82: u_int32_t *, u_int32_t *, u_int32_t *);
83: void pdq_eisa_devinit(pdq_softc_t *);
84: int pdq_eisa_match(struct device *, void *, void *);
85: void pdq_eisa_attach(struct device *, struct device *, void *);
86:
87: #define DEFEA_INTRENABLE 0x8 /* level interrupt */
88: static int pdq_eisa_irqs[4] = { 9, 10, 11, 15 };
89:
90: void
91: pdq_eisa_subprobe(bc, iobase, maddr, msize, irq)
92: bus_space_tag_t bc;
93: bus_space_handle_t iobase;
94: u_int32_t *maddr;
95: u_int32_t *msize;
96: u_int32_t *irq;
97: {
98: if (irq != NULL)
99: *irq = pdq_eisa_irqs[PDQ_OS_IORD_8(bc, iobase,
100: PDQ_EISA_IO_CONFIG_STAT_0) & 3];
101:
102: *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8)
103: | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16);
104: *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8;
105: }
106:
107: void
108: pdq_eisa_devinit(sc)
109: pdq_softc_t *sc;
110: {
111: u_int8_t data;
112: bus_space_tag_t tag;
113:
114: tag = sc->sc_bc;
115:
116: /*
117: * Do the standard initialization for the DEFEA registers.
118: */
119: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_FUNCTION_CTRL, 0x23);
120: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CMP_1_1,
121: (sc->sc_iobase >> 8) & 0xF0);
122: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CMP_0_1,
123: (sc->sc_iobase >> 8) & 0xF0);
124: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_SLOT_CTRL, 0x01);
125: data = PDQ_OS_IORD_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF);
126: #if defined(PDQ_IOMAPPED)
127: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data & ~1);
128: #else
129: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data | 1);
130: #endif
131: data = PDQ_OS_IORD_8(tag, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0);
132: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0,
133: data | DEFEA_INTRENABLE);
134: }
135:
136: int
137: pdq_eisa_match(parent, match, aux)
138: struct device *parent;
139: void *match;
140: void *aux;
141: {
142: struct eisa_attach_args *ea = (struct eisa_attach_args *) aux;
143:
144: if (strncmp(ea->ea_idstring, "DEC300", 6) == 0)
145: return (1);
146: return (0);
147: }
148:
149: void
150: pdq_eisa_attach(parent, self, aux)
151: struct device *parent;
152: struct device *self;
153: void *aux;
154: {
155: pdq_softc_t *sc = (pdq_softc_t *) self;
156: struct eisa_attach_args *ea = (struct eisa_attach_args *) aux;
157: u_int32_t irq, maddr, msize;
158: eisa_intr_handle_t ih;
159: const char *intrstr;
160:
161: sc->sc_iotag = ea->ea_iot;
162: bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ);
163: sc->sc_if.if_flags = 0;
164: sc->sc_if.if_softc = sc;
165:
166: /*
167: * NOTE: sc_bc is an alias for sc_csrtag and sc_membase is
168: * an alias for sc_csrhandle. sc_iobase is used here to
169: * check the card's configuration.
170: */
171:
172: if (bus_space_map(sc->sc_iotag, EISA_SLOT_ADDR(ea->ea_slot),
173: EISA_SLOT_SIZE, 0, &sc->sc_iobase)) {
174: printf("\n%s: failed to map I/O!\n", sc->sc_dev.dv_xname);
175: return;
176: }
177:
178: pdq_eisa_subprobe(sc->sc_iotag, sc->sc_iobase, &maddr, &msize, &irq);
179:
180: #if defined(PDQ_IOMAPPED)
181: sc->sc_csrtag = sc->sc_iotag;
182: sc->sc_csrhandle = sc->sc_iobase;
183: #else
184: if (maddr == 0 || msize == 0) {
185: printf("\n%s: error: memory not enabled! ECU reconfiguration"
186: " required\n", sc->sc_dev.dv_xname);
187: return;
188: }
189:
190: if (bus_space_map(sc->sc_csrtag, maddr, msize, 0, &sc->sc_csrhandle)) {
191: bus_space_unmap(sc->sc_iotag, sc->sc_iobase, EISA_SLOT_SIZE);
192: printf("\n%s: failed to map memory (0x%x-0x%x)!\n",
193: sc->sc_dev.dv_xname, maddr, maddr + msize - 1);
194: return;
195: }
196: #endif
197: pdq_eisa_devinit(sc);
198: sc->sc_pdq = pdq_initialize(sc->sc_bc, sc->sc_membase,
199: sc->sc_if.if_xname, 0, (void *) sc, PDQ_DEFEA);
200: if (sc->sc_pdq == NULL) {
201: printf("%s: initialization failed\n", sc->sc_dev.dv_xname);
202: return;
203: }
204:
205: if (eisa_intr_map(ea->ea_ec, irq, &ih)) {
206: printf("%s: couldn't map interrupt (%d)\n",
207: sc->sc_dev.dv_xname, irq);
208: return;
209: }
210: intrstr = eisa_intr_string(ea->ea_ec, ih);
211: sc->sc_ih = eisa_intr_establish(ea->ea_ec, ih, IST_LEVEL, IPL_NET,
212: (int (*)(void *)) pdq_interrupt, sc->sc_pdq, sc->sc_dev.dv_xname);
213: if (sc->sc_ih == NULL) {
214: printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
215: if (intrstr != NULL)
216: printf(" at %s", intrstr);
217: printf("\n");
218: return;
219: }
220: if (intrstr != NULL)
221: printf(": interrupting at %s\n", intrstr);
222:
223: bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes,
224: sc->sc_arpcom.ac_enaddr, 6);
225:
226: pdq_ifattach(sc, NULL);
227:
228: sc->sc_ats = shutdownhook_establish((void (*)(void *)) pdq_hwreset,
229: sc->sc_pdq);
230: if (sc->sc_ats == NULL)
231: printf("%s: warning: couldn't establish shutdown hook\n",
232: self->dv_xname);
233: #if !defined(PDQ_IOMAPPED)
234: printf("%s: using iomem 0x%x-0x%x\n", sc->sc_dev.dv_xname, maddr,
235: maddr + msize - 1);
236: #endif
237: }
238:
239: struct cfattach fea_ca = {
240: sizeof(pdq_softc_t), pdq_eisa_match, pdq_eisa_attach
241: };
242:
243: struct cfdriver fea_cd = {
244: 0, "fea", DV_IFNET
245: };
CVSweb