Annotation of src/sys/dev/isa/if_ef.c, Revision 1.8.2.3
1.8.2.3 ! nathanw 1: /* $NetBSD: if_ef.c,v 1.8.2.2 2001/11/14 19:14:47 nathanw Exp $ */
1.1 pk 2:
3: /*-
4: * Copyright (c) 1998 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Rafal K. Boni.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
1.8.2.2 nathanw 38:
39: #include <sys/cdefs.h>
1.8.2.3 ! nathanw 40: __KERNEL_RCSID(0, "$NetBSD: if_ef.c,v 1.8.2.2 2001/11/14 19:14:47 nathanw Exp $");
1.1 pk 41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/mbuf.h>
45: #include <sys/errno.h>
46: #include <sys/device.h>
47: #include <sys/protosw.h>
48: #include <sys/socket.h>
49:
50: #include <net/if.h>
51: #include <net/if_dl.h>
52: #include <net/if_types.h>
53: #include <net/if_media.h>
54: #include <net/if_ether.h>
55:
56: #include <machine/cpu.h>
57: #include <machine/bus.h>
58: #include <machine/intr.h>
59:
60: #include <dev/isa/isareg.h>
61: #include <dev/isa/isavar.h>
62:
63: #include <dev/ic/i82586reg.h>
64: #include <dev/ic/i82586var.h>
65: #include <dev/isa/if_efreg.h>
66: #include <dev/isa/elink.h>
67:
68: #ifdef EF_DEBUG
69: #define DPRINTF(x) printf x
70: #else
1.2 pk 71: #define DPRINTF(x)
1.1 pk 72: #endif
73:
74: struct ef_softc {
75: struct ie_softc sc_ie;
76:
77: bus_space_tag_t sc_regt; /* space tag for registers */
78: bus_space_handle_t sc_regh; /* space handle for registers */
79:
80: void* sc_ih; /* interrupt handle */
81:
82: u_int8_t card_rev; /* hardware revision */
83: u_int8_t card_type; /* card model -- AUI/BNC or TP */
84: };
85:
1.2 pk 86: int ef_media[] = {
1.1 pk 87: IFM_ETHER | IFM_10_5,
88: IFM_ETHER | IFM_10_2,
89: };
90: #define NEF_MEDIA (sizeof(ef_media) / sizeof(ef_media[0]))
91:
92: int eftp_media[] = {
93: IFM_ETHER | IFM_10_T,
94: };
95: #define NEFTP_MEDIA (sizeof(eftp_media) / sizeof(eftp_media[0]))
96:
97: /* Routines required by the MI i82586 driver API */
98: static void ef_reset __P((struct ie_softc *, int));
99: static void ef_hwinit __P((struct ie_softc *));
1.8.2.1 nathanw 100: static void ef_atten __P((struct ie_softc *, int));
1.1 pk 101: static int ef_intrhook __P((struct ie_softc *, int));
102:
103: static void ef_copyin __P((struct ie_softc *, void *, int, size_t));
104: static void ef_copyout __P((struct ie_softc *, const void *, int, size_t));
105:
106: static u_int16_t ef_read_16 __P((struct ie_softc *, int));
107: static void ef_write_16 __P((struct ie_softc *, int, u_int16_t));
108: static void ef_write_24 __P((struct ie_softc *, int, int));
109:
110: static void ef_mediastatus __P((struct ie_softc *, struct ifmediareq *));
111:
112: /* Local routines */
113: static int ef_port_check __P((bus_space_tag_t, bus_space_handle_t));
114:
115: int ef_match __P((struct device *, struct cfdata *, void *));
116: void ef_attach __P((struct device *, struct device *, void *));
117:
118: /*
119: * This keeps track of which ISAs have been through an ie probe sequence.
120: * A simple static variable isn't enough, since it's conceivable that
121: * a system might have more than one ISA bus.
122: *
123: * The "isa_bus" member is a pointer to the parent ISA bus device struct
1.2 pk 124: * which will unique per ISA bus.
1.1 pk 125: */
126:
127: #define MAXCARDS_PER_ISABUS 8 /* if you have more than 8, you lose */
128:
129: struct ef_isabus {
1.2 pk 130: LIST_ENTRY(ef_isabus) isa_link;
131: struct device *isa_bus;
1.1 pk 132:
1.2 pk 133: int bus_state;
1.1 pk 134:
1.2 pk 135: struct card {
136: bus_addr_t iobase;
137: bus_addr_t maddr;
138: bus_size_t msize;
139: int irq;
140: int available;
141: } isa_cards[MAXCARDS_PER_ISABUS];
1.1 pk 142: };
143:
144: static LIST_HEAD(, ef_isabus) ef_isa_buses;
145: static int ef_isa_buses_inited;
146:
147: static void
148: ef_card_add(
149: struct ef_isabus *bus,
150: bus_addr_t iobase,
151: bus_addr_t maddr,
152: bus_size_t msize,
153: int irq)
154: {
1.2 pk 155: int idx;
1.1 pk 156:
1.2 pk 157: DPRINTF(("Adding 3c507 at 0x%x, IRQ %d, Mem 0x%lx/%ld\n",
158: (u_int) iobase, irq, (u_long) maddr, msize));
1.1 pk 159:
1.2 pk 160: for (idx = 0; idx < MAXCARDS_PER_ISABUS; idx++) {
161: if (bus->isa_cards[idx].available == 0) {
162: bus->isa_cards[idx].iobase = iobase;
163: bus->isa_cards[idx].maddr = maddr;
164: bus->isa_cards[idx].msize = msize;
165: bus->isa_cards[idx].irq = irq;
166: bus->isa_cards[idx].available = 1;
167: break;
168: }
169: }
1.1 pk 170: }
171:
172: /*
173: * 3C507 support routines
174: */
175: static void
176: ef_reset(sc, why)
177: struct ie_softc *sc;
178: int why;
179: {
1.2 pk 180: struct ef_softc* esc = (struct ef_softc *) sc;
1.1 pk 181:
1.2 pk 182: switch (why) {
183: case CHIP_PROBE:
184: /* reset to chip to see if it responds */
185: bus_space_write_1(esc->sc_regt, esc->sc_regh,
186: EF_CTRL, EF_CTRL_RESET);
187: DELAY(100);
188: bus_space_write_1(esc->sc_regt, esc->sc_regh,
189: EF_CTRL, EF_CTRL_NORMAL);
190: DELAY(100);
191: break;
192:
193: case CARD_RESET:
194: /*
195: * this takes around 10sec, and we can get
196: * by quite well w/out it...
197: */
198: break;
199: }
1.1 pk 200: }
201:
202: static void
1.8.2.1 nathanw 203: ef_atten(sc, why)
1.1 pk 204: struct ie_softc *sc;
1.8.2.1 nathanw 205: int why;
1.1 pk 206: {
1.2 pk 207: struct ef_softc* esc = (struct ef_softc *) sc;
208: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_ATTN, 1);
1.1 pk 209: }
210:
211: static void
212: ef_hwinit(sc)
213: struct ie_softc *sc;
214: {
1.2 pk 215: struct ef_softc* esc = (struct ef_softc *) sc;
216: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_ICTRL, 1);
1.1 pk 217: }
218:
219: static int
220: ef_intrhook(sc, where)
221: struct ie_softc *sc;
222: int where;
223: {
1.2 pk 224: unsigned char cr;
225: struct ef_softc* esc = (struct ef_softc *) sc;
1.1 pk 226:
1.2 pk 227: switch (where) {
228: case INTR_ENTER:
229: /* entering ISR: disable, ack card interrupts */
230: cr = bus_space_read_1(esc->sc_regt, esc->sc_regh, EF_CTRL);
231: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_CTRL,
232: cr & ~EF_CTRL_IEN);
233: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_ICTRL, 1);
234: break;
235:
236: case INTR_EXIT:
237: /* exiting ISR: re-enable card interrupts */
238: cr = bus_space_read_1(esc->sc_regt, esc->sc_regh, EF_CTRL);
239: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_CTRL,
240: cr | EF_CTRL_IEN);
241: break;
242:
243: case INTR_LOOP:
244: /* looping in ISR: ack new interrupts */
245: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_ICTRL, 1);
246: break;
1.1 pk 247: }
248:
249: return 1;
250: }
251:
1.2 pk 252: static u_int16_t
1.1 pk 253: ef_read_16 (sc, offset)
254: struct ie_softc *sc;
255: int offset;
256: {
257: bus_space_barrier(sc->bt, sc->bh, offset, 2, BUS_SPACE_BARRIER_READ);
258: return bus_space_read_2(sc->bt, sc->bh, offset);
259: }
260:
1.2 pk 261: static void
1.1 pk 262: ef_copyin (sc, dst, offset, size)
263: struct ie_softc *sc;
264: void *dst;
265: int offset;
266: size_t size;
267: {
1.2 pk 268: int dribble;
269: u_int8_t* bptr = dst;
1.1 pk 270:
1.2 pk 271: bus_space_barrier(sc->bt, sc->bh, offset, size,
272: BUS_SPACE_BARRIER_READ);
1.1 pk 273:
1.2 pk 274: if (offset % 2) {
275: *bptr = bus_space_read_1(sc->bt, sc->bh, offset);
276: offset++; bptr++; size--;
277: }
1.1 pk 278:
1.2 pk 279: dribble = size % 2;
280: bus_space_read_region_2(sc->bt, sc->bh, offset, (u_int16_t *) bptr,
281: size >> 1);
282:
283: if (dribble) {
284: bptr += size - 1;
285: offset += size - 1;
286: *bptr = bus_space_read_1(sc->bt, sc->bh, offset);
287: }
1.1 pk 288: }
289:
1.2 pk 290: static void
1.1 pk 291: ef_copyout (sc, src, offset, size)
292: struct ie_softc *sc;
293: const void *src;
294: int offset;
295: size_t size;
296: {
1.2 pk 297: int dribble;
298: int osize = size;
299: int ooffset = offset;
300: const u_int8_t* bptr = src;
301:
302: if (offset % 2) {
303: bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
304: offset++; bptr++; size--;
305: }
1.1 pk 306:
1.2 pk 307: dribble = size % 2;
308: bus_space_write_region_2(sc->bt, sc->bh, offset, (u_int16_t *)bptr,
309: size >> 1);
310: if (dribble) {
311: bptr += size - 1;
312: offset += size - 1;
313: bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
314: }
1.1 pk 315:
1.2 pk 316: bus_space_barrier(sc->bt, sc->bh, ooffset, osize,
317: BUS_SPACE_BARRIER_WRITE);
1.1 pk 318: }
319:
320: static void
321: ef_write_16 (sc, offset, value)
322: struct ie_softc *sc;
323: int offset;
324: u_int16_t value;
325: {
326: bus_space_write_2(sc->bt, sc->bh, offset, value);
327: bus_space_barrier(sc->bt, sc->bh, offset, 2, BUS_SPACE_BARRIER_WRITE);
328: }
329:
330: static void
331: ef_write_24 (sc, offset, addr)
332: struct ie_softc *sc;
333: int offset, addr;
334: {
1.2 pk 335: bus_space_write_4(sc->bt, sc->bh, offset, addr +
336: (u_long) sc->sc_maddr - (u_long) sc->sc_iobase);
1.1 pk 337: bus_space_barrier(sc->bt, sc->bh, offset, 4, BUS_SPACE_BARRIER_WRITE);
338: }
339:
340: static void
341: ef_mediastatus(sc, ifmr)
1.2 pk 342: struct ie_softc *sc;
343: struct ifmediareq *ifmr;
1.1 pk 344: {
345: struct ifmedia *ifm = &sc->sc_media;
346:
347: /*
1.2 pk 348: * The currently selected media is always the active media.
1.1 pk 349: */
350: ifmr->ifm_active = ifm->ifm_cur->ifm_media;
351: }
352:
353: int
354: ef_match(parent, cf, aux)
355: struct device *parent;
356: struct cfdata *cf;
357: void *aux;
358: {
1.2 pk 359: struct isa_attach_args * const ia = aux;
360:
361: int idx;
362: struct ef_isabus *bus;
363:
364: bus_space_handle_t ioh;
365: bus_space_tag_t iot = ia->ia_iot;
1.1 pk 366:
1.2 pk 367: if (ef_isa_buses_inited == 0) {
368: LIST_INIT(&ef_isa_buses);
369: ef_isa_buses_inited = 1;
370: }
371:
372: /*
373: * Probe this bus if we haven't done so already.
374: */
375: for (bus = ef_isa_buses.lh_first; bus != NULL;
376: bus = bus->isa_link.le_next) {
377: if (bus->isa_bus == parent)
378: break;
379: }
1.1 pk 380:
1.2 pk 381: if (bus == NULL) {
382: bus_addr_t iobase;
1.1 pk 383:
1.2 pk 384: /*
385: * Mark this bus so we don't probe it again.
386: */
387: bus = (struct ef_isabus *)
388: malloc(sizeof(struct ef_isabus), M_DEVBUF, M_NOWAIT);
389: if (bus == NULL)
390: panic("ef_isa_probe: can't allocate state storage for %s",
391: parent->dv_xname);
392:
393: bus->bus_state = 0; /* nothing done yet */
394: bus->isa_bus = parent;
1.1 pk 395:
1.2 pk 396: LIST_INSERT_HEAD(&ef_isa_buses, bus, isa_link);
1.1 pk 397:
1.2 pk 398: if (bus_space_map(iot, ELINK_ID_PORT, 1, 0, &ioh)) {
399: DPRINTF(("3c507 probe: can't map Etherlink ID port\n"));
400: return 0;
401: }
1.1 pk 402:
1.2 pk 403: /*
404: * Reset and put card in CONFIG state without
405: * changing address.
406: */
1.3 pk 407: elink_reset(iot, ioh, parent->dv_unit);
1.2 pk 408: elink_idseq(iot, ioh, ELINK_507_POLY);
409: elink_idseq(iot, ioh, ELINK_507_POLY);
410: bus_space_write_1(iot, ioh, 0, 0xff);
411:
412: /* Unmap the ID port */
413: bus_space_unmap(iot, ioh, 1);
414:
415: bus->bus_state++; /* cards now in CONFIG state */
416:
417: for (iobase = EF_IOBASE_LOW; iobase <= EF_IOBASE_HIGH;
418: iobase += EF_IOSIZE) {
419: /*
420: * Map the 507's port-space for the probe sequence.
421: */
422: if (bus_space_map(iot, iobase, EF_IOSIZE,
423: 0, &ioh) != 0)
424: continue;
425:
426: /* Now look for the 3Com magic bytes */
427:
428: if (ef_port_check(iot, ioh)) {
429: int irq;
430: u_int8_t v;
431: bus_addr_t maddr;
432: bus_addr_t msize;
433: bus_space_handle_t memh;
434:
435: irq = bus_space_read_1(iot, ioh, EF_IRQ) &
436: EF_IRQ_MASK;
437:
438: v = bus_space_read_1(iot, ioh, EF_MADDR);
439: maddr = EF_MADDR_BASE +
440: ((v & EF_MADDR_MASK) << EF_MADDR_SHIFT);
441: msize = ((v & EF_MSIZE_MASK) + 1) *
442: EF_MSIZE_STEP;
443:
444: if (bus_space_map(ia->ia_memt, maddr,
445: msize, 0, &memh) == 0) {
446: ef_card_add(bus, iobase, maddr,
447: msize, irq);
448: bus_space_unmap(ia->ia_memt,
449: memh, msize);
450: }
451: }
452: bus_space_unmap(iot, ioh, EF_IOSIZE);
453: }
1.1 pk 454: }
455:
1.2 pk 456: for (idx = 0; idx < MAXCARDS_PER_ISABUS; idx++) {
457: if (bus->isa_cards[idx].available != 1)
458: continue;
459:
460: if (ia->ia_iobase != IOBASEUNK &&
461: ia->ia_iobase != bus->isa_cards[idx].iobase)
462: continue;
463:
464: if (ia->ia_maddr != MADDRUNK &&
465: ia->ia_maddr != bus->isa_cards[idx].maddr)
466: continue;
467:
468: if (ia->ia_irq != IRQUNK &&
469: ia->ia_irq != bus->isa_cards[idx].irq)
470: continue;
471:
472: break;
473: }
1.1 pk 474:
1.2 pk 475: if (idx == MAXCARDS_PER_ISABUS)
476: return (0);
1.1 pk 477:
1.2 pk 478: bus->isa_cards[idx].available++;
479: ia->ia_iobase = bus->isa_cards[idx].iobase;
480: ia->ia_irq = bus->isa_cards[idx].irq;
481: ia->ia_iosize = EF_IOSIZE;
482: ia->ia_maddr = bus->isa_cards[idx].maddr;
483: ia->ia_msize = bus->isa_cards[idx].msize;
484: return (1);
1.1 pk 485: }
486:
487: void
488: ef_attach(parent, self, aux)
489: struct device *parent;
490: struct device *self;
491: void *aux;
492: {
1.2 pk 493: struct ef_softc *esc = (void *)self;
494: struct ie_softc *sc = &esc->sc_ie;
495: struct isa_attach_args *ia = aux;
496: bus_space_tag_t iot = ia->ia_iot;
497:
498: int i;
499: char version[20];
500: struct ef_isabus *bus;
501: u_int8_t partno[EF_TYPE_LEN];
502: bus_space_handle_t ioh, memh;
503: u_int8_t ethaddr[ETHER_ADDR_LEN];
504:
505: sc->hwinit = ef_hwinit;
506: sc->hwreset = ef_reset;
507: sc->chan_attn = ef_atten;
508: sc->intrhook = ef_intrhook;
1.8 bjh21 509:
510: sc->ie_bus_barrier = NULL;
1.2 pk 511:
512: sc->memcopyin = ef_copyin;
513: sc->memcopyout = ef_copyout;
514: sc->ie_bus_read16 = ef_read_16;
515: sc->ie_bus_write16 = ef_write_16;
516: sc->ie_bus_write24 = ef_write_24;
517:
518: sc->sc_msize = 0;
519:
520: /*
521: * NOP chains don't give any advantage on this card, in fact they
522: * seem to slow it down some. As the doctor says, "if it hurts,
523: * don't do it".
524: */
525: sc->do_xmitnopchain = 0;
1.1 pk 526:
1.2 pk 527: sc->sc_mediachange = NULL;
528: sc->sc_mediastatus = ef_mediastatus;
1.1 pk 529:
1.2 pk 530: /* Find the cards parent bus */
531: for (bus = ef_isa_buses.lh_first; bus != NULL;
532: bus = bus->isa_link.le_next) {
1.1 pk 533:
1.2 pk 534: if (bus->isa_bus == parent)
535: break;
1.1 pk 536: }
537:
1.2 pk 538: if (bus == NULL)
539: panic("%s: Can't find parent bus!", sc->sc_dev.dv_xname);
540:
541:
542: /* If the bus hasn't been transitioned to the RUN state, do so now */
543: if (bus->bus_state == 1) {
544: if (bus_space_map(iot, ELINK_ID_PORT, 1, 0, &ioh) != 0) {
545: DPRINTF(("\n%s: Can't map Elink ID port!\n",
546: sc->sc_dev.dv_xname));
547: return;
548: }
549:
550: bus_space_write_1(ia->ia_iot, ioh, 0, 0x00);
551: elink_idseq(ia->ia_iot, ioh, ELINK_507_POLY);
552: bus_space_write_1(ia->ia_iot, ioh, 0, 0x00);
553: bus_space_unmap(ia->ia_iot, ioh, 1);
1.1 pk 554:
1.2 pk 555: bus->bus_state++;
556: }
557:
558: /* Map i/o space. */
559: if (bus_space_map(ia->ia_iot, ia->ia_iobase,
560: ia->ia_iosize, 0, &ioh) != 0) {
561:
562: DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
563: sc->sc_dev.dv_xname, ia->ia_iobase,
564: ia->ia_iobase + ia->ia_iosize - 1));
565: return;
566: }
1.1 pk 567:
1.2 pk 568: esc->sc_regt = ia->ia_iot;
569: esc->sc_regh = ioh;
1.1 pk 570:
1.2 pk 571: if (bus_space_map(ia->ia_memt, ia->ia_maddr,
572: ia->ia_msize, 0, &memh) != 0) {
1.1 pk 573:
1.2 pk 574: DPRINTF(("\n%s: can't map iomem space 0x%x-0x%x\n",
575: sc->sc_dev.dv_xname, ia->ia_maddr,
576: ia->ia_maddr + ia->ia_msize - 1));
577: bus_space_unmap(ia->ia_iot, ioh, ia->ia_iosize);
578: return;
579: }
1.1 pk 580:
1.2 pk 581: sc->bt = ia->ia_memt;
582: sc->bh = memh;
1.1 pk 583:
1.2 pk 584: sc->sc_msize = ia->ia_msize;
1.6 augustss 585: sc->sc_maddr = (void *)memh;
586: sc->sc_iobase = (char *)sc->sc_maddr + sc->sc_msize - (1 << 24);
1.2 pk 587:
588: /* set up pointers to important on-card control structures */
589: sc->iscp = 0;
590: sc->scb = IE_ISCP_SZ;
591: sc->scp = sc->sc_msize + IE_SCP_ADDR - (1 << 24);
592:
593: sc->buf_area = sc->scb + IE_SCB_SZ;
594: sc->buf_area_sz = sc->sc_msize - IE_ISCP_SZ - IE_SCB_SZ - IE_SCP_SZ;
595:
596: /* zero card memory */
597: bus_space_set_region_1(sc->bt, sc->bh, 0, 0, sc->sc_msize);
598:
599: /* set card to 16-bit bus mode */
1.8.2.3 ! nathanw 600: bus_space_write_1(sc->bt, sc->bh, IE_SCP_BUS_USE((u_long)sc->scp),
! 601: IE_SYSBUS_16BIT);
1.2 pk 602:
603: /* set up pointers to key structures */
604: ef_write_24(sc, IE_SCP_ISCP((u_long)sc->scp), (u_long) sc->iscp);
605: ef_write_16(sc, IE_ISCP_SCB((u_long)sc->iscp), (u_long) sc->scb);
606: ef_write_24(sc, IE_ISCP_BASE((u_long)sc->iscp), (u_long) sc->iscp);
607:
608: /* flush setup of pointers, check if chip answers */
609: bus_space_barrier(sc->bt, sc->bh, 0, sc->sc_msize,
610: BUS_SPACE_BARRIER_WRITE);
611: if (!i82586_proberam(sc)) {
612: DPRINTF(("\n%s: can't talk to i82586!\n",
613: sc->sc_dev.dv_xname));
614: bus_space_unmap(ia->ia_iot, ioh, ia->ia_iosize);
615: bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
616: return;
617: }
1.1 pk 618:
1.2 pk 619: /* set bank 2 for card part number and revision */
620: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_CTRL,
621: EF_CTRL_NRST | EF_CTRL_BNK2);
622:
623: /* card revision is encoded in BCD */
624: i = bus_space_read_1(esc->sc_regt, esc->sc_regh, EF_REV);
625: esc->card_rev = 10 * (i / 16) + (i % 16);
626:
627: for (i = 0; i < EF_TYPE_LEN; i++)
628: partno[i] = bus_space_read_1(esc->sc_regt, esc->sc_regh,
629: EF_TYPE + i);
630:
631: /* use part number to guess if card is TP or AUI/BNC model */
632: esc->card_type = EF_IS_TP(partno) ? EF_CARD_TP : EF_CARD_BNC;
633:
634: /* set bank 0 for ethernet address */
635: bus_space_write_1(esc->sc_regt, esc->sc_regh,
636: EF_CTRL, EF_CTRL_NORMAL);
637:
638: for (i = 0; i < EF_ADDR_LEN; i++)
639: ethaddr[i] = bus_space_read_1(esc->sc_regt, esc->sc_regh,
640: EF_ADDR + i);
641:
642: sprintf(version, "%s, rev. %d",
643: (esc->card_type == EF_CARD_TP) ? "3C507-TP" : "3C507",
644: esc->card_rev);
645:
646: if (esc->card_type == EF_CARD_TP)
647: i82586_attach(sc, version, ethaddr, eftp_media, NEFTP_MEDIA,
648: eftp_media[0]);
649: else {
650: u_int8_t media = bus_space_read_1(esc->sc_regt, esc->sc_regh,
651: EF_MEDIA);
652: media = (media & EF_MEDIA_MASK) >> EF_MEDIA_SHIFT;
1.1 pk 653:
1.2 pk 654: i82586_attach(sc, version, ethaddr, ef_media, NEF_MEDIA,
655: ef_media[media]);
656: }
1.1 pk 657:
1.2 pk 658: /* Clear the interrupt latch just in case. */
659: bus_space_write_1(esc->sc_regt, esc->sc_regh, EF_ICTRL, 1);
1.1 pk 660:
1.2 pk 661: esc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
662: IPL_NET, i82586_intr, sc);
663: if (esc->sc_ih == NULL) {
664: DPRINTF(("\n%s: can't establish interrupt\n",
665: sc->sc_dev.dv_xname));
666: }
1.1 pk 667: }
668:
1.2 pk 669: static int
1.1 pk 670: ef_port_check(iot, ioh)
671: bus_space_tag_t iot;
672: bus_space_handle_t ioh;
673: {
674: int i;
675: u_char ch;
676: u_char* signature = EF_SIGNATURE;
677:
678: for (i = 0; i < strlen(signature); i++) {
679: ch = bus_space_read_1(iot, ioh, i);
680: if (ch != signature[i])
681: return 0;
682: }
1.2 pk 683:
1.1 pk 684: /* If card is mapped in high memory (above 15Meg), we can't use it */
685: ch = bus_space_read_1(iot, ioh, EF_MADDR);
686: if (ch & EF_MADDR_HIGH)
687: return 0; /* XXX: maybe we should panic?? */
688:
689: return 1;
690: }
691:
692: struct cfattach ef_ca = {
693: sizeof(struct ef_softc), ef_match, ef_attach
694: };
695:
CVSweb <webmaster@jp.NetBSD.org>