This source file includes following definitions.
- le_ioasic_match
- le_ioasic_attach
- le_ioasic_copytobuf_gap2
- le_ioasic_copyfrombuf_gap2
- le_ioasic_copytobuf_gap16
- le_ioasic_copyfrombuf_gap16
- le_ioasic_zerobuf_gap16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/mbuf.h>
38 #include <sys/syslog.h>
39 #include <sys/socket.h>
40 #include <sys/device.h>
41
42 #include <net/if.h>
43 #include <net/if_media.h>
44
45 #ifdef INET
46 #include <netinet/in.h>
47 #include <netinet/if_ether.h>
48 #endif
49
50 #include <dev/ic/am7990reg.h>
51 #include <dev/ic/am7990var.h>
52
53 #include <dev/tc/if_levar.h>
54 #include <dev/tc/tcvar.h>
55 #include <dev/tc/ioasicreg.h>
56 #include <dev/tc/ioasicvar.h>
57
58 struct le_ioasic_softc {
59 struct am7990_softc sc_am7990;
60 struct lereg1 *sc_r1;
61
62
63 bus_dma_tag_t sc_dmat;
64 bus_dmamap_t sc_dmamap;
65 };
66
67 int le_ioasic_match(struct device *, void *, void *);
68 void le_ioasic_attach(struct device *, struct device *, void *);
69
70 struct cfattach le_ioasic_ca = {
71 sizeof(struct le_softc), le_ioasic_match, le_ioasic_attach
72 };
73
74 void le_ioasic_copytobuf_gap2(struct am7990_softc *, void *,
75 int, int);
76 void le_ioasic_copyfrombuf_gap2(struct am7990_softc *, void *,
77 int, int);
78 void le_ioasic_copytobuf_gap16(struct am7990_softc *, void *,
79 int, int);
80 void le_ioasic_copyfrombuf_gap16(struct am7990_softc *, void *,
81 int, int);
82 void le_ioasic_zerobuf_gap16(struct am7990_softc *, int, int);
83
84 int
85 le_ioasic_match(struct device *parent, void *match, void *aux)
86 {
87 struct ioasicdev_attach_args *d = aux;
88
89 if (strncmp("PMAD-BA ", d->iada_modname, TC_ROM_LLEN) != 0)
90 return 0;
91
92 return 1;
93 }
94
95
96 #define LE_IOASIC_MEMSIZE (128*1024)
97 #define LE_IOASIC_MEMALIGN (128*1024)
98
99 void
100 le_ioasic_attach(struct device *parent, struct device *self, void *aux)
101 {
102 struct le_ioasic_softc *sc = (void *)self;
103 struct ioasicdev_attach_args *d = aux;
104 struct am7990_softc *le = &sc->sc_am7990;
105 bus_space_tag_t ioasic_bst;
106 bus_space_handle_t ioasic_bsh;
107 bus_dma_tag_t dmat;
108 bus_dma_segment_t seg;
109 tc_addr_t tca;
110 u_int32_t ssr;
111 int rseg;
112 caddr_t le_iomem;
113
114 ioasic_bst = ((struct ioasic_softc *)parent)->sc_bst;
115 ioasic_bsh = ((struct ioasic_softc *)parent)->sc_bsh;
116 dmat = sc->sc_dmat = ((struct ioasic_softc *)parent)->sc_dmat;
117
118
119
120 if (bus_dmamem_alloc(dmat, LE_IOASIC_MEMSIZE, LE_IOASIC_MEMALIGN,
121 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
122 printf("can't allocate DMA area for LANCE\n");
123 return;
124 }
125 if (bus_dmamem_map(dmat, &seg, rseg, LE_IOASIC_MEMSIZE,
126 &le_iomem, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
127 printf("can't map DMA area for LANCE\n");
128 bus_dmamem_free(dmat, &seg, rseg);
129 return;
130 }
131
132
133
134 if (bus_dmamap_create(dmat, LE_IOASIC_MEMSIZE, 1,
135 LE_IOASIC_MEMSIZE, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) {
136 printf("can't create DMA map\n");
137 goto bad;
138 }
139 if (bus_dmamap_load(dmat, sc->sc_dmamap,
140 le_iomem, LE_IOASIC_MEMSIZE, NULL, BUS_DMA_NOWAIT)) {
141 printf("can't load DMA map\n");
142 goto bad;
143 }
144
145
146
147 tca = IOASIC_DMA_ADDR(sc->sc_dmamap->dm_segs[0].ds_addr);
148 bus_space_write_4(ioasic_bst, ioasic_bsh, IOASIC_LANCE_DMAPTR, tca);
149 ssr = bus_space_read_4(ioasic_bst, ioasic_bsh, IOASIC_CSR);
150 ssr |= IOASIC_CSR_DMAEN_LANCE;
151 bus_space_write_4(ioasic_bst, ioasic_bsh, IOASIC_CSR, ssr);
152
153 sc->sc_r1 = (struct lereg1 *)
154 TC_DENSE_TO_SPARSE(TC_PHYS_TO_UNCACHED(d->iada_addr));
155 le->sc_mem = (void *)TC_PHYS_TO_UNCACHED(le_iomem);
156 le->sc_copytodesc = le_ioasic_copytobuf_gap2;
157 le->sc_copyfromdesc = le_ioasic_copyfrombuf_gap2;
158 le->sc_copytobuf = le_ioasic_copytobuf_gap16;
159 le->sc_copyfrombuf = le_ioasic_copyfrombuf_gap16;
160 le->sc_zerobuf = le_ioasic_zerobuf_gap16;
161
162 dec_le_common_attach(&sc->sc_am7990,
163 (u_char *)((struct ioasic_softc *)parent)->sc_base
164 + IOASIC_SLOT_2_START);
165
166 ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_NET,
167 am7990_intr, sc);
168 return;
169
170 bad:
171 bus_dmamem_unmap(dmat, le_iomem, LE_IOASIC_MEMSIZE);
172 bus_dmamem_free(dmat, &seg, rseg);
173 }
174
175
176
177
178
179
180
181
182
183
184
185
186
187 void
188 le_ioasic_copytobuf_gap2(struct am7990_softc *sc, void *fromv,
189 int boff, int len)
190 {
191 volatile caddr_t buf = sc->sc_mem;
192 caddr_t from = fromv;
193 volatile u_int16_t *bptr;
194
195 if (boff & 0x1) {
196
197 bptr = ((volatile u_int16_t *)buf) + (boff - 1);
198 *bptr = (*from++ << 8) | (*bptr & 0xff);
199 bptr += 2;
200 len--;
201 } else
202 bptr = ((volatile u_int16_t *)buf) + boff;
203 while (len > 1) {
204 *bptr = (from[1] << 8) | (from[0] & 0xff);
205 bptr += 2;
206 from += 2;
207 len -= 2;
208 }
209 if (len == 1)
210 *bptr = (u_int16_t)*from;
211 }
212
213 void
214 le_ioasic_copyfrombuf_gap2(struct am7990_softc *sc, void *tov,
215 int boff, int len)
216 {
217 volatile caddr_t buf = sc->sc_mem;
218 caddr_t to = tov;
219 volatile u_int16_t *bptr;
220 u_int16_t tmp;
221
222 if (boff & 0x1) {
223
224 bptr = ((volatile u_int16_t *)buf) + (boff - 1);
225 *to++ = (*bptr >> 8) & 0xff;
226 bptr += 2;
227 len--;
228 } else
229 bptr = ((volatile u_int16_t *)buf) + boff;
230 while (len > 1) {
231 tmp = *bptr;
232 *to++ = tmp & 0xff;
233 *to++ = (tmp >> 8) & 0xff;
234 bptr += 2;
235 len -= 2;
236 }
237 if (len == 1)
238 *to = *bptr & 0xff;
239 }
240
241
242
243
244
245
246
247 void
248 le_ioasic_copytobuf_gap16(struct am7990_softc *sc, void *fromv,
249 int boff, int len)
250 {
251 volatile caddr_t buf = sc->sc_mem;
252 caddr_t from = fromv;
253 caddr_t bptr;
254
255 bptr = buf + ((boff << 1) & ~0x1f);
256 boff &= 0xf;
257
258
259
260
261
262 if (boff) {
263 int xfer;
264 xfer = min(len, 16 - boff);
265 bcopy(from, bptr + boff, xfer);
266 from += xfer;
267 bptr += 32;
268 len -= xfer;
269 }
270
271
272 if (len >= 16)
273 switch ((u_long)from & (sizeof(u_int32_t) -1)) {
274 case 2:
275
276 do {
277 u_int32_t *dst = (u_int32_t*)bptr;
278 u_int16_t t0;
279 u_int32_t t1, t2, t3, t4;
280
281
282 t0 = *(u_int16_t*)from;
283 t1 = *(u_int32_t*)(from+2);
284 t2 = *(u_int32_t*)(from+6);
285 t3 = *(u_int32_t*)(from+10);
286 t4 = *(u_int16_t*)(from+14);
287
288
289 dst[0] = t0 | (t1 << 16);
290 dst[1] = (t1 >> 16) | (t2 << 16);
291 dst[2] = (t2 >> 16) | (t3 << 16);
292 dst[3] = (t3 >> 16) | (t4 << 16);
293
294 from += 16;
295 bptr += 32;
296 len -= 16;
297 } while (len >= 16);
298 break;
299
300 case 0:
301 do {
302 u_int32_t *src = (u_int32_t*)from;
303 u_int32_t *dst = (u_int32_t*)bptr;
304 u_int32_t t0, t1, t2, t3;
305
306 t0 = src[0]; t1 = src[1]; t2 = src[2]; t3 = src[3];
307 dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
308
309 from += 16;
310 bptr += 32;
311 len -= 16;
312 } while (len >= 16);
313 break;
314
315 default:
316
317 do {
318 bcopy(from, bptr, 16);
319 from += 16;
320 bptr += 32;
321 len -= 16;
322 } while (len >= 16);
323 break;
324 }
325 if (len)
326 bcopy(from, bptr, len);
327 }
328
329 void
330 le_ioasic_copyfrombuf_gap16(struct am7990_softc *sc, void *tov,
331 int boff, int len)
332 {
333 volatile caddr_t buf = sc->sc_mem;
334 caddr_t to = tov;
335 caddr_t bptr;
336
337 bptr = buf + ((boff << 1) & ~0x1f);
338 boff &= 0xf;
339
340
341 if (boff) {
342 int xfer;
343 xfer = min(len, 16 - boff);
344 bcopy(bptr+boff, to, xfer);
345 to += xfer;
346 bptr += 32;
347 len -= xfer;
348 }
349 if (len >= 16)
350 switch ((u_long)to & (sizeof(u_int32_t) -1)) {
351 case 2:
352
353
354
355
356 do {
357 u_int32_t *src = (u_int32_t*)bptr;
358 u_int32_t t0, t1, t2, t3;
359
360
361 t0 = src[0]; t1 = src[1]; t2 = src[2]; t3 = src[3];
362
363
364 *(u_int16_t *) (to+0) = (u_short) t0;
365 *(u_int32_t *) (to+2) = (t0 >> 16) | (t1 << 16);
366 *(u_int32_t *) (to+6) = (t1 >> 16) | (t2 << 16);
367 *(u_int32_t *) (to+10) = (t2 >> 16) | (t3 << 16);
368 *(u_int16_t *) (to+14) = (t3 >> 16);
369 bptr += 32;
370 to += 16;
371 len -= 16;
372 } while (len > 16);
373 break;
374 case 0:
375
376 do {
377 u_int32_t *src = (u_int32_t*)bptr;
378 u_int32_t *dst = (u_int32_t*)to;
379 u_int32_t t0, t1, t2, t3;
380
381 t0 = src[0]; t1 = src[1]; t2 = src[2]; t3 = src[3];
382 dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
383 to += 16;
384 bptr += 32;
385 len -= 16;
386 } while (len > 16);
387 break;
388
389
390 default:
391 do {
392 bcopy(bptr, to, 16);
393 to += 16;
394 bptr += 32;
395 len -= 16;
396 } while (len > 16);
397 break;
398 }
399 if (len)
400 bcopy(bptr, to, len);
401 }
402
403 void
404 le_ioasic_zerobuf_gap16(struct am7990_softc *sc, int boff, int len)
405 {
406 volatile caddr_t buf = sc->sc_mem;
407 caddr_t bptr;
408 int xfer;
409
410 bptr = buf + ((boff << 1) & ~0x1f);
411 boff &= 0xf;
412 xfer = min(len, 16 - boff);
413 while (len > 0) {
414 bzero(bptr + boff, xfer);
415 bptr += 32;
416 boff = 0;
417 len -= xfer;
418 xfer = min(len, 16);
419 }
420 }