This source file includes following definitions.
- le_ledma_wrcsr
- le_ledma_rdcsr
- le_ledma_setutp
- le_ledma_setaui
- lemediachange
- lemediastatus
- le_ledma_hwreset
- le_ledma_hwinit
- le_ledma_nocarrier
- lematch_ledma
- leattach_ledma
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
36
37
38
39
40
41 #include "bpfilter.h"
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/mbuf.h>
46 #include <sys/syslog.h>
47 #include <sys/socket.h>
48 #include <sys/device.h>
49 #include <sys/malloc.h>
50
51 #include <net/if.h>
52 #include <net/if_media.h>
53
54 #ifdef INET
55 #include <netinet/in.h>
56 #include <netinet/if_ether.h>
57 #endif
58
59 #include <machine/bus.h>
60 #include <machine/intr.h>
61 #include <machine/autoconf.h>
62
63 #include <dev/sbus/sbusvar.h>
64
65 #include <dev/ic/lsi64854reg.h>
66 #include <dev/ic/lsi64854var.h>
67
68 #include <dev/ic/am7990reg.h>
69 #include <dev/ic/am7990var.h>
70
71
72
73
74 #define LEREG1_RDP 0
75 #define LEREG1_RAP 2
76
77 struct le_softc {
78 struct am7990_softc sc_am7990;
79 bus_space_tag_t sc_bustag;
80 bus_dmamap_t sc_dmamap;
81 bus_space_handle_t sc_reg;
82 struct lsi64854_softc *sc_dma;
83 u_int sc_laddr;
84 };
85
86 #define MEMSIZE (16*1024)
87 #define LEDMA_BOUNDARY (16*1024*1024)
88
89 int lematch_ledma(struct device *, void *, void *);
90 void leattach_ledma(struct device *, struct device *, void *);
91
92
93
94
95
96 void le_ledma_setutp(struct am7990_softc *);
97 void le_ledma_setaui(struct am7990_softc *);
98
99 int lemediachange(struct ifnet *);
100 void lemediastatus(struct ifnet *, struct ifmediareq *);
101
102 struct cfattach le_ledma_ca = {
103 sizeof(struct le_softc), lematch_ledma, leattach_ledma
104 };
105
106 void le_ledma_wrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
107 u_int16_t le_ledma_rdcsr(struct am7990_softc *, u_int16_t);
108 void le_ledma_hwreset(struct am7990_softc *);
109 void le_ledma_hwinit(struct am7990_softc *);
110 void le_ledma_nocarrier(struct am7990_softc *);
111
112 void
113 le_ledma_wrcsr(struct am7990_softc *sc, u_int16_t port, u_int16_t val)
114 {
115 struct le_softc *lesc = (struct le_softc *)sc;
116
117 bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, port);
118 bus_space_barrier(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, 2,
119 BUS_SPACE_BARRIER_WRITE);
120 bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP, val);
121 bus_space_barrier(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP, 2,
122 BUS_SPACE_BARRIER_WRITE);
123
124 #if defined(SUN4M)
125
126
127
128
129
130 if (CPU_ISSUN4M) {
131 volatile u_int16_t discard;
132 discard = bus_space_read_2(lesc->sc_bustag, lesc->sc_reg,
133 LEREG1_RDP);
134 }
135 #endif
136 }
137
138 u_int16_t
139 le_ledma_rdcsr(struct am7990_softc *sc, u_int16_t port)
140 {
141 struct le_softc *lesc = (struct le_softc *)sc;
142
143 bus_space_write_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, port);
144 bus_space_barrier(lesc->sc_bustag, lesc->sc_reg, LEREG1_RAP, 2,
145 BUS_SPACE_BARRIER_WRITE);
146 return (bus_space_read_2(lesc->sc_bustag, lesc->sc_reg, LEREG1_RDP));
147 }
148
149 void
150 le_ledma_setutp(struct am7990_softc *sc)
151 {
152 struct lsi64854_softc *dma = ((struct le_softc *)sc)->sc_dma;
153 u_int32_t csr;
154
155 csr = L64854_GCSR(dma);
156 csr |= E_TP_AUI;
157 L64854_SCSR(dma, csr);
158 delay(20000);
159 }
160
161 void
162 le_ledma_setaui(struct am7990_softc *sc)
163 {
164 struct lsi64854_softc *dma = ((struct le_softc *)sc)->sc_dma;
165 u_int32_t csr;
166
167 csr = L64854_GCSR(dma);
168 csr &= ~E_TP_AUI;
169 L64854_SCSR(dma, csr);
170 delay(20000);
171 }
172
173 int
174 lemediachange(struct ifnet *ifp)
175 {
176 struct am7990_softc *sc = ifp->if_softc;
177 struct ifmedia *ifm = &sc->sc_ifmedia;
178
179 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
180 return (EINVAL);
181
182
183
184
185
186
187
188 switch (IFM_SUBTYPE(ifm->ifm_media)) {
189 case IFM_10_T:
190 le_ledma_setutp(sc);
191 break;
192
193 case IFM_10_5:
194 le_ledma_setaui(sc);
195 break;
196
197 case IFM_AUTO:
198 break;
199
200 default:
201 return (EINVAL);
202 }
203
204 return (0);
205 }
206
207 void
208 lemediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
209 {
210 struct am7990_softc *sc = ifp->if_softc;
211 struct lsi64854_softc *dma = ((struct le_softc *)sc)->sc_dma;
212
213
214
215
216 if (L64854_GCSR(dma) & E_TP_AUI)
217 ifmr->ifm_active = IFM_ETHER|IFM_10_T;
218 else
219 ifmr->ifm_active = IFM_ETHER|IFM_10_5;
220 }
221
222 void
223 le_ledma_hwreset(struct am7990_softc *sc)
224 {
225 struct le_softc *lesc = (struct le_softc *)sc;
226 struct lsi64854_softc *dma = lesc->sc_dma;
227 u_int32_t csr;
228 u_int aui_bit;
229
230
231
232
233 csr = L64854_GCSR(dma);
234 aui_bit = csr & E_TP_AUI;
235 DMA_RESET(dma);
236
237
238 bus_space_write_4(dma->sc_bustag, dma->sc_regs, L64854_REG_ENBAR,
239 lesc->sc_laddr & 0xff000000);
240
241 DMA_ENINTR(dma);
242
243
244
245
246
247 csr = L64854_GCSR(dma);
248 csr |= (E_DSBL_WR_INVAL | aui_bit);
249 L64854_SCSR(dma, csr);
250 delay(20000);
251 }
252
253 void
254 le_ledma_hwinit(struct am7990_softc *sc)
255 {
256
257
258
259
260
261 switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_cur->ifm_media)) {
262 case IFM_10_T:
263 le_ledma_setutp(sc);
264 break;
265
266 case IFM_10_5:
267 le_ledma_setaui(sc);
268 break;
269 }
270 }
271
272 void
273 le_ledma_nocarrier(struct am7990_softc *sc)
274 {
275 struct le_softc *lesc = (struct le_softc *)sc;
276
277
278
279
280
281
282 if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) {
283 switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_media)) {
284 case IFM_10_5:
285 case IFM_AUTO:
286 printf("%s: lost carrier on UTP port"
287 ", switching to AUI port\n", sc->sc_dev.dv_xname);
288 le_ledma_setaui(sc);
289 }
290 } else {
291 switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_media)) {
292 case IFM_10_T:
293 case IFM_AUTO:
294 printf("%s: lost carrier on AUI port"
295 ", switching to UTP port\n", sc->sc_dev.dv_xname);
296 le_ledma_setutp(sc);
297 }
298 }
299 }
300
301 int
302 lematch_ledma(struct device *parent, void *vcf, void *aux)
303 {
304 struct cfdata *cf = vcf;
305 struct sbus_attach_args *sa = aux;
306
307 return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
308 }
309
310
311 void
312 leattach_ledma(struct device *parent, struct device *self, void *aux)
313 {
314 struct sbus_attach_args *sa = aux;
315 struct le_softc *lesc = (struct le_softc *)self;
316 struct lsi64854_softc *lsi = (struct lsi64854_softc *)parent;
317 struct am7990_softc *sc = &lesc->sc_am7990;
318 bus_dma_tag_t dmatag = sa->sa_dmatag;
319 bus_dma_segment_t seg;
320 int rseg, error;
321
322 extern void myetheraddr(u_char *);
323
324 lesc->sc_bustag = sa->sa_bustag;
325
326
327 lesc->sc_dma = lsi;
328 lesc->sc_dma->sc_client = lesc;
329
330
331 if (sbus_bus_map(sa->sa_bustag,
332 sa->sa_slot,
333 sa->sa_offset,
334 sa->sa_size,
335 BUS_SPACE_MAP_LINEAR,
336 0, &lesc->sc_reg) != 0) {
337 printf("%s @ ledma: cannot map registers\n", self->dv_xname);
338 return;
339 }
340
341
342 sc->sc_memsize = MEMSIZE;
343
344
345 if ((error = bus_dmamap_create(dmatag, MEMSIZE, 1, MEMSIZE,
346 LEDMA_BOUNDARY, BUS_DMA_NOWAIT,
347 &lesc->sc_dmamap)) != 0) {
348 printf("%s: DMA map create error %d\n", self->dv_xname, error);
349 return;
350 }
351
352
353 if ((error = bus_dmamem_alloc(dmatag, MEMSIZE, 0, LEDMA_BOUNDARY,
354 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
355 printf("%s @ ledma: DMA buffer alloc error %d\n",
356 self->dv_xname, error);
357 return;
358 }
359
360
361 if ((error = bus_dmamem_map(dmatag, &seg, rseg, MEMSIZE,
362 (caddr_t *)&sc->sc_mem,
363 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
364 printf("%s @ ledma: DMA buffer map error %d\n",
365 self->dv_xname, error);
366 bus_dmamem_free(dmatag, &seg, rseg);
367 return;
368 }
369
370
371 if ((error = bus_dmamap_load(dmatag, lesc->sc_dmamap, sc->sc_mem,
372 MEMSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
373 printf("%s: DMA buffer map load error %d\n",
374 self->dv_xname, error);
375 bus_dmamem_free(dmatag, &seg, rseg);
376 bus_dmamem_unmap(dmatag, sc->sc_mem, MEMSIZE);
377 return;
378 }
379
380 lesc->sc_laddr = lesc->sc_dmamap->dm_segs[0].ds_addr;
381 sc->sc_addr = lesc->sc_laddr & 0xffffff;
382 sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
383
384 ifmedia_init(&sc->sc_ifmedia, 0, lemediachange, lemediastatus);
385 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
386 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5, 0, NULL);
387 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
388 ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO);
389 sc->sc_hasifmedia = 1;
390
391 myetheraddr(sc->sc_arpcom.ac_enaddr);
392
393 sc->sc_copytodesc = am7990_copytobuf_contig;
394 sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
395 sc->sc_copytobuf = am7990_copytobuf_contig;
396 sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
397 sc->sc_zerobuf = am7990_zerobuf_contig;
398
399 sc->sc_rdcsr = le_ledma_rdcsr;
400 sc->sc_wrcsr = le_ledma_wrcsr;
401 sc->sc_hwinit = le_ledma_hwinit;
402 sc->sc_nocarrier = le_ledma_nocarrier;
403 sc->sc_hwreset = le_ledma_hwreset;
404
405
406 if (sa->sa_nintr != 0)
407 (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET, 0,
408 am7990_intr, sc, self->dv_xname);
409
410 am7990_config(&lesc->sc_am7990);
411
412
413 le_ledma_hwreset(sc);
414 }