if_le.c revision 1.2.2.2 1 1.2.2.2 bouyer /* $NetBSD: if_le.c,v 1.2.2.2 2000/11/20 20:14:11 bouyer Exp $ */
2 1.2.2.2 bouyer
3 1.2.2.2 bouyer /*-
4 1.2.2.2 bouyer * Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
5 1.2.2.2 bouyer * All rights reserved.
6 1.2.2.2 bouyer *
7 1.2.2.2 bouyer * This code is derived from software contributed to The NetBSD Foundation
8 1.2.2.2 bouyer * by Adam Glass, Gordon W. Ross and Wayne Knowles
9 1.2.2.2 bouyer *
10 1.2.2.2 bouyer * Redistribution and use in source and binary forms, with or without
11 1.2.2.2 bouyer * modification, are permitted provided that the following conditions
12 1.2.2.2 bouyer * are met:
13 1.2.2.2 bouyer * 1. Redistributions of source code must retain the above copyright
14 1.2.2.2 bouyer * notice, this list of conditions and the following disclaimer.
15 1.2.2.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
16 1.2.2.2 bouyer * notice, this list of conditions and the following disclaimer in the
17 1.2.2.2 bouyer * documentation and/or other materials provided with the distribution.
18 1.2.2.2 bouyer * 3. All advertising materials mentioning features or use of this software
19 1.2.2.2 bouyer * must display the following acknowledgement:
20 1.2.2.2 bouyer * This product includes software developed by the NetBSD
21 1.2.2.2 bouyer * Foundation, Inc. and its contributors.
22 1.2.2.2 bouyer * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.2.2.2 bouyer * contributors may be used to endorse or promote products derived
24 1.2.2.2 bouyer * from this software without specific prior written permission.
25 1.2.2.2 bouyer *
26 1.2.2.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.2.2.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.2.2.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.2.2.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.2.2.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.2.2.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.2.2.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.2.2.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.2.2.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.2.2.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.2.2.2 bouyer * POSSIBILITY OF SUCH DAMAGE.
37 1.2.2.2 bouyer */
38 1.2.2.2 bouyer
39 1.2.2.2 bouyer #include "opt_inet.h"
40 1.2.2.2 bouyer #include "bpfilter.h"
41 1.2.2.2 bouyer
42 1.2.2.2 bouyer #include <sys/param.h>
43 1.2.2.2 bouyer #include <sys/systm.h>
44 1.2.2.2 bouyer #include <sys/mbuf.h>
45 1.2.2.2 bouyer #include <sys/syslog.h>
46 1.2.2.2 bouyer #include <sys/socket.h>
47 1.2.2.2 bouyer #include <sys/device.h>
48 1.2.2.2 bouyer
49 1.2.2.2 bouyer #include <net/if.h>
50 1.2.2.2 bouyer #include <net/if_ether.h>
51 1.2.2.2 bouyer #include <net/if_media.h>
52 1.2.2.2 bouyer
53 1.2.2.2 bouyer #ifdef INET
54 1.2.2.2 bouyer #include <netinet/in.h>
55 1.2.2.2 bouyer #include <netinet/if_inarp.h>
56 1.2.2.2 bouyer #endif
57 1.2.2.2 bouyer
58 1.2.2.2 bouyer #include <machine/cpu.h>
59 1.2.2.2 bouyer #include <machine/mainboard.h>
60 1.2.2.2 bouyer #include <machine/autoconf.h>
61 1.2.2.2 bouyer #include <machine/bus.h>
62 1.2.2.2 bouyer
63 1.2.2.2 bouyer #include <dev/ic/lancereg.h>
64 1.2.2.2 bouyer #include <dev/ic/lancevar.h>
65 1.2.2.2 bouyer #include <dev/ic/am7990reg.h>
66 1.2.2.2 bouyer #include <dev/ic/am7990var.h>
67 1.2.2.2 bouyer
68 1.2.2.2 bouyer /*
69 1.2.2.2 bouyer * LANCE registers.
70 1.2.2.2 bouyer */
71 1.2.2.2 bouyer
72 1.2.2.2 bouyer #define LEREG1_RDP 2 /* Offset to LANCE data register */
73 1.2.2.2 bouyer #define LEREG1_RAP 6 /* Offset to LANCE address register */
74 1.2.2.2 bouyer
75 1.2.2.2 bouyer /*
76 1.2.2.2 bouyer * Ethernet software status per interface.
77 1.2.2.2 bouyer * The real stuff is in dev/ic/am7990var.h
78 1.2.2.2 bouyer */
79 1.2.2.2 bouyer struct le_softc {
80 1.2.2.2 bouyer struct am7990_softc sc_am7990; /* glue to MI code */
81 1.2.2.2 bouyer bus_space_tag_t sc_bustag;
82 1.2.2.2 bouyer bus_dma_tag_t sc_dmatag;
83 1.2.2.2 bouyer bus_space_handle_t sc_reg; /* LANCE registers */
84 1.2.2.2 bouyer bus_dmamap_t sc_dmamap;
85 1.2.2.2 bouyer struct evcnt sc_intrcnt; /* Interrupt event counter */
86 1.2.2.2 bouyer };
87 1.2.2.2 bouyer
88 1.2.2.2 bouyer static int le_match __P((struct device *, struct cfdata *, void *));
89 1.2.2.2 bouyer static void le_attach __P((struct device *, struct device *, void *));
90 1.2.2.2 bouyer
91 1.2.2.2 bouyer struct cfattach le_ca = {
92 1.2.2.2 bouyer sizeof(struct le_softc), le_match, le_attach
93 1.2.2.2 bouyer };
94 1.2.2.2 bouyer
95 1.2.2.2 bouyer #if defined(_KERNEL) && !defined(_LKM)
96 1.2.2.2 bouyer #include "opt_ddb.h"
97 1.2.2.2 bouyer #endif
98 1.2.2.2 bouyer
99 1.2.2.2 bouyer #ifdef DDB
100 1.2.2.2 bouyer #define integrate
101 1.2.2.2 bouyer #define hide
102 1.2.2.2 bouyer #else
103 1.2.2.2 bouyer #define integrate static __inline
104 1.2.2.2 bouyer #define hide static
105 1.2.2.2 bouyer #endif
106 1.2.2.2 bouyer
107 1.2.2.2 bouyer int le_intr __P((void *));
108 1.2.2.2 bouyer
109 1.2.2.2 bouyer hide void lewrcsr __P((struct lance_softc *, u_int16_t, u_int16_t));
110 1.2.2.2 bouyer hide u_int16_t lerdcsr __P((struct lance_softc *, u_int16_t));
111 1.2.2.2 bouyer
112 1.2.2.2 bouyer hide void
113 1.2.2.2 bouyer lewrcsr(sc, port, val)
114 1.2.2.2 bouyer struct lance_softc *sc;
115 1.2.2.2 bouyer u_int16_t port, val;
116 1.2.2.2 bouyer {
117 1.2.2.2 bouyer struct le_softc *lesc = (struct le_softc *)sc;
118 1.2.2.2 bouyer
119 1.2.2.2 bouyer bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, port);
120 1.2.2.2 bouyer bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP, val);
121 1.2.2.2 bouyer }
122 1.2.2.2 bouyer
123 1.2.2.2 bouyer hide u_int16_t
124 1.2.2.2 bouyer lerdcsr(sc, port)
125 1.2.2.2 bouyer struct lance_softc *sc;
126 1.2.2.2 bouyer u_int16_t port;
127 1.2.2.2 bouyer {
128 1.2.2.2 bouyer struct le_softc *lesc = (struct le_softc *)sc;
129 1.2.2.2 bouyer
130 1.2.2.2 bouyer bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, port);
131 1.2.2.2 bouyer return (bus_space_read_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP));
132 1.2.2.2 bouyer }
133 1.2.2.2 bouyer
134 1.2.2.2 bouyer int
135 1.2.2.2 bouyer le_match(parent, cf, aux)
136 1.2.2.2 bouyer struct device *parent;
137 1.2.2.2 bouyer struct cfdata *cf;
138 1.2.2.2 bouyer void *aux;
139 1.2.2.2 bouyer {
140 1.2.2.2 bouyer struct confargs *ca = aux;
141 1.2.2.2 bouyer int addr;
142 1.2.2.2 bouyer
143 1.2.2.2 bouyer if (strcmp(ca->ca_name, "le"))
144 1.2.2.2 bouyer return 0;
145 1.2.2.2 bouyer
146 1.2.2.2 bouyer switch(cf->cf_unit) {
147 1.2.2.2 bouyer
148 1.2.2.2 bouyer case 0:
149 1.2.2.2 bouyer addr = LANCE_PORT;
150 1.2.2.2 bouyer break;
151 1.2.2.2 bouyer default:
152 1.2.2.2 bouyer return 0;
153 1.2.2.2 bouyer }
154 1.2.2.2 bouyer
155 1.2.2.2 bouyer if (badaddr((void *)addr, 1))
156 1.2.2.2 bouyer return 0;
157 1.2.2.2 bouyer
158 1.2.2.2 bouyer return 1;
159 1.2.2.2 bouyer }
160 1.2.2.2 bouyer
161 1.2.2.2 bouyer #define LE_MEMSIZE (32*1024)
162 1.2.2.2 bouyer
163 1.2.2.2 bouyer void
164 1.2.2.2 bouyer le_attach(parent, self, aux)
165 1.2.2.2 bouyer struct device *parent, *self;
166 1.2.2.2 bouyer void *aux;
167 1.2.2.2 bouyer {
168 1.2.2.2 bouyer struct le_softc *lesc = (struct le_softc *)self;
169 1.2.2.2 bouyer struct lance_softc *sc = &lesc->sc_am7990.lsc;
170 1.2.2.2 bouyer struct confargs *ca = aux;
171 1.2.2.2 bouyer
172 1.2.2.2 bouyer bus_dma_tag_t dmat;
173 1.2.2.2 bouyer bus_dma_segment_t seg;
174 1.2.2.2 bouyer int rseg;
175 1.2.2.2 bouyer
176 1.2.2.2 bouyer /*struct confargs *ca = aux;*/
177 1.2.2.2 bouyer u_char *id;
178 1.2.2.2 bouyer int i;
179 1.2.2.2 bouyer caddr_t kvaddr;
180 1.2.2.2 bouyer
181 1.2.2.2 bouyer switch (sc->sc_dev.dv_unit) {
182 1.2.2.2 bouyer case 0:
183 1.2.2.2 bouyer id = (u_char *)(ETHER_ID);
184 1.2.2.2 bouyer break;
185 1.2.2.2 bouyer default:
186 1.2.2.2 bouyer panic("le_attach");
187 1.2.2.2 bouyer }
188 1.2.2.2 bouyer
189 1.2.2.2 bouyer lesc->sc_bustag = ca->ca_bustag;
190 1.2.2.2 bouyer dmat = lesc->sc_dmatag = ca->ca_dmatag;
191 1.2.2.2 bouyer
192 1.2.2.2 bouyer if (bus_space_map(ca->ca_bustag, ca->ca_addr,
193 1.2.2.2 bouyer 8, /* size */
194 1.2.2.2 bouyer BUS_SPACE_MAP_LINEAR,
195 1.2.2.2 bouyer &lesc->sc_reg) != 0) {
196 1.2.2.2 bouyer printf(": cannot map registers\n");
197 1.2.2.2 bouyer return;
198 1.2.2.2 bouyer }
199 1.2.2.2 bouyer
200 1.2.2.2 bouyer /*
201 1.2.2.2 bouyer * Allocate a physically contiguous DMA area for the chip.
202 1.2.2.2 bouyer */
203 1.2.2.2 bouyer if (bus_dmamem_alloc(dmat, LE_MEMSIZE, 0, 0, &seg, 1,
204 1.2.2.2 bouyer &rseg, BUS_DMA_NOWAIT)) {
205 1.2.2.2 bouyer printf(": can't allocate DMA area\n");
206 1.2.2.2 bouyer return;
207 1.2.2.2 bouyer }
208 1.2.2.2 bouyer /* Map pages into kernel memory */
209 1.2.2.2 bouyer if (bus_dmamem_map(dmat, &seg, rseg, LE_MEMSIZE,
210 1.2.2.2 bouyer &kvaddr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
211 1.2.2.2 bouyer printf(": can't map DMA area\n");
212 1.2.2.2 bouyer bus_dmamem_free(dmat, &seg, rseg);
213 1.2.2.2 bouyer return;
214 1.2.2.2 bouyer }
215 1.2.2.2 bouyer /* Build DMA map so we can get physical address */
216 1.2.2.2 bouyer if (bus_dmamap_create(dmat, LE_MEMSIZE, 1, LE_MEMSIZE,
217 1.2.2.2 bouyer 0, BUS_DMA_NOWAIT, &lesc->sc_dmamap)) {
218 1.2.2.2 bouyer printf(": can't create DMA map\n");
219 1.2.2.2 bouyer goto bad;
220 1.2.2.2 bouyer }
221 1.2.2.2 bouyer if (bus_dmamap_load(dmat, lesc->sc_dmamap, kvaddr, LE_MEMSIZE,
222 1.2.2.2 bouyer NULL, BUS_DMA_NOWAIT)) {
223 1.2.2.2 bouyer printf(": can't load DMA map\n");
224 1.2.2.2 bouyer goto bad;
225 1.2.2.2 bouyer }
226 1.2.2.2 bouyer
227 1.2.2.2 bouyer sc->sc_memsize = LE_MEMSIZE; /* 16K Buffer space*/
228 1.2.2.2 bouyer sc->sc_mem = (void *) MIPS_PHYS_TO_KSEG1(kvaddr);
229 1.2.2.2 bouyer sc->sc_addr = lesc->sc_dmamap->dm_segs[0].ds_addr;
230 1.2.2.2 bouyer
231 1.2.2.2 bouyer sc->sc_conf3 = LE_C3_BSWP;
232 1.2.2.2 bouyer
233 1.2.2.2 bouyer /* Copy Ethernet hardware address from NVRAM */
234 1.2.2.2 bouyer for (i=0; i < 6; i++)
235 1.2.2.2 bouyer sc->sc_enaddr[i] = id[i*4+3]; /* XXX */
236 1.2.2.2 bouyer
237 1.2.2.2 bouyer sc->sc_copytodesc = lance_copytobuf_contig;
238 1.2.2.2 bouyer sc->sc_copyfromdesc = lance_copyfrombuf_contig;
239 1.2.2.2 bouyer sc->sc_copytobuf = lance_copytobuf_contig;
240 1.2.2.2 bouyer sc->sc_copyfrombuf = lance_copyfrombuf_contig;
241 1.2.2.2 bouyer sc->sc_zerobuf = lance_zerobuf_contig;
242 1.2.2.2 bouyer
243 1.2.2.2 bouyer sc->sc_rdcsr = lerdcsr;
244 1.2.2.2 bouyer sc->sc_wrcsr = lewrcsr;
245 1.2.2.2 bouyer sc->sc_hwinit = NULL;
246 1.2.2.2 bouyer
247 1.2.2.2 bouyer evcnt_attach_dynamic(&lesc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
248 1.2.2.2 bouyer self->dv_xname, "intr");
249 1.2.2.2 bouyer bus_intr_establish(lesc->sc_bustag, SYS_INTR_ETHER, 0, 0,
250 1.2.2.2 bouyer le_intr, lesc);
251 1.2.2.2 bouyer
252 1.2.2.2 bouyer am7990_config(&lesc->sc_am7990);
253 1.2.2.2 bouyer return;
254 1.2.2.2 bouyer
255 1.2.2.2 bouyer bad:
256 1.2.2.2 bouyer bus_dmamem_unmap(dmat, kvaddr, LE_MEMSIZE);
257 1.2.2.2 bouyer bus_dmamem_free(dmat, &seg, rseg);
258 1.2.2.2 bouyer }
259 1.2.2.2 bouyer
260 1.2.2.2 bouyer int
261 1.2.2.2 bouyer le_intr(arg)
262 1.2.2.2 bouyer void *arg;
263 1.2.2.2 bouyer {
264 1.2.2.2 bouyer struct le_softc *lesc = arg;
265 1.2.2.2 bouyer
266 1.2.2.2 bouyer lesc->sc_intrcnt.ev_count++;
267 1.2.2.2 bouyer return am7990_intr(&lesc->sc_am7990);
268 1.2.2.2 bouyer }
269