Annotation of sys/arch/sparc/dev/if_le.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: if_le.c,v 1.29 2007/05/29 09:54:09 sobrado Exp $ */
! 2: /* $NetBSD: if_le.c,v 1.50 1997/09/09 20:54:48 pk Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
! 6: * Copyright (c) 1996
! 7: * The President and Fellows of Harvard College. All rights reserved.
! 8: * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
! 9: * Copyright (c) 1992, 1993
! 10: * The Regents of the University of California. All rights reserved.
! 11: *
! 12: * This code is derived from software contributed to Berkeley by
! 13: * Ralph Campbell and Rick Macklem.
! 14: *
! 15: * Redistribution and use in source and binary forms, with or without
! 16: * modification, are permitted provided that the following conditions
! 17: * are met:
! 18: * 1. Redistributions of source code must retain the above copyright
! 19: * notice, this list of conditions and the following disclaimer.
! 20: * 2. Redistributions in binary form must reproduce the above copyright
! 21: * notice, this list of conditions and the following disclaimer in the
! 22: * documentation and/or other materials provided with the distribution.
! 23: * 3. All advertising materials mentioning features or use of this software
! 24: * must display the following acknowledgement:
! 25: * This product includes software developed by Aaron Brown and
! 26: * Harvard University.
! 27: * This product includes software developed for the NetBSD Project
! 28: * by Jason R. Thorpe.
! 29: * 4. Neither the name of the University nor the names of its contributors
! 30: * may be used to endorse or promote products derived from this software
! 31: * without specific prior written permission.
! 32: *
! 33: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 34: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 35: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 36: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 37: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 38: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 39: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 40: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 41: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 42: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 43: * SUCH DAMAGE.
! 44: *
! 45: * @(#)if_le.c 8.2 (Berkeley) 11/16/93
! 46: */
! 47:
! 48: #include "bpfilter.h"
! 49:
! 50: #include <sys/param.h>
! 51: #include <sys/systm.h>
! 52: #include <sys/mbuf.h>
! 53: #include <sys/syslog.h>
! 54: #include <sys/socket.h>
! 55: #include <sys/device.h>
! 56: #include <sys/malloc.h>
! 57:
! 58: #include <net/if.h>
! 59: #include <net/if_media.h>
! 60:
! 61: #ifdef INET
! 62: #include <netinet/in.h>
! 63: #include <netinet/if_ether.h>
! 64: #endif
! 65:
! 66: #include <machine/autoconf.h>
! 67: #include <machine/cpu.h>
! 68:
! 69: #include <sparc/dev/sbusvar.h>
! 70: #include <sparc/dev/dmareg.h>
! 71: #include <sparc/dev/dmavar.h>
! 72: #include <sparc/dev/lebuffervar.h>
! 73:
! 74: #include <dev/ic/am7990reg.h>
! 75: #include <dev/ic/am7990var.h>
! 76:
! 77: #include <sparc/dev/if_lereg.h>
! 78: #include <sparc/dev/if_levar.h>
! 79:
! 80: #ifdef solbourne
! 81: #include <sparc/sparc/asm.h>
! 82: #include <machine/idt.h>
! 83: #include <machine/kap.h>
! 84: #endif
! 85:
! 86: int lematch(struct device *, void *, void *);
! 87: void leattach(struct device *, struct device *, void *);
! 88:
! 89: /*
! 90: * ifmedia interfaces
! 91: */
! 92: int lemediachange(struct ifnet *);
! 93: void lemediastatus(struct ifnet *, struct ifmediareq *);
! 94:
! 95: #if defined(SUN4M)
! 96: /*
! 97: * media change methods (only for sun4m)
! 98: */
! 99: void lesetutp(struct am7990_softc *);
! 100: void lesetaui(struct am7990_softc *);
! 101: #endif /* SUN4M */
! 102:
! 103: #if defined(SUN4M) /* XXX */
! 104: int myleintr(void *);
! 105: int ledmaintr(struct dma_softc *);
! 106:
! 107: int
! 108: myleintr(arg)
! 109: void *arg;
! 110: {
! 111: register struct le_softc *lesc = arg;
! 112: static int dodrain=0;
! 113:
! 114: if (lesc->sc_dma->sc_regs->csr & D_ERR_PEND) {
! 115: dodrain = 1;
! 116: return ledmaintr(lesc->sc_dma);
! 117: }
! 118:
! 119: if (dodrain) { /* XXX - is this necessary with D_DSBL_WRINVAL on? */
! 120: int i = 10;
! 121: while (i-- > 0 && (lesc->sc_dma->sc_regs->csr & D_DRAINING))
! 122: delay(1);
! 123: }
! 124:
! 125: return (am7990_intr(arg));
! 126: }
! 127: #endif
! 128:
! 129: struct cfattach le_ca = {
! 130: sizeof(struct le_softc), lematch, leattach
! 131: };
! 132:
! 133: hide void lewrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
! 134: hide u_int16_t lerdcsr(struct am7990_softc *, u_int16_t);
! 135: hide void lehwreset(struct am7990_softc *);
! 136: hide void lehwinit(struct am7990_softc *);
! 137: #if defined(SUN4M)
! 138: hide void lenocarrier(struct am7990_softc *);
! 139: #endif
! 140: #if defined(solbourne)
! 141: hide void kap_copytobuf(struct am7990_softc *, void *, int, int);
! 142: hide void kap_copyfrombuf(struct am7990_softc *, void *, int, int);
! 143: #endif
! 144:
! 145: hide void
! 146: lewrcsr(sc, port, val)
! 147: struct am7990_softc *sc;
! 148: u_int16_t port, val;
! 149: {
! 150: register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
! 151: #if defined(SUN4M)
! 152: volatile u_int16_t discard;
! 153: #endif
! 154:
! 155: ler1->ler1_rap = port;
! 156: ler1->ler1_rdp = val;
! 157: #if defined(SUN4M)
! 158: /*
! 159: * We need to flush the SBus->MBus write buffers. This can most
! 160: * easily be accomplished by reading back the register that we
! 161: * just wrote (thanks to Chris Torek for this solution).
! 162: */
! 163: if (CPU_ISSUN4M)
! 164: discard = ler1->ler1_rdp;
! 165: #endif
! 166: }
! 167:
! 168: hide u_int16_t
! 169: lerdcsr(sc, port)
! 170: struct am7990_softc *sc;
! 171: u_int16_t port;
! 172: {
! 173: register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
! 174: u_int16_t val;
! 175:
! 176: ler1->ler1_rap = port;
! 177: val = ler1->ler1_rdp;
! 178: return (val);
! 179: }
! 180:
! 181: #if defined(SUN4M)
! 182: void
! 183: lesetutp(sc)
! 184: struct am7990_softc *sc;
! 185: {
! 186: struct le_softc *lesc = (struct le_softc *)sc;
! 187: u_int32_t csr;
! 188: int tries = 5;
! 189:
! 190: while (--tries) {
! 191: csr = lesc->sc_dma->sc_regs->csr;
! 192: csr |= E_TP_AUI;
! 193: lesc->sc_dma->sc_regs->csr = csr;
! 194: delay(20000); /* must not touch le for 20ms */
! 195: if (lesc->sc_dma->sc_regs->csr & E_TP_AUI)
! 196: return;
! 197: }
! 198: }
! 199:
! 200: void
! 201: lesetaui(sc)
! 202: struct am7990_softc *sc;
! 203: {
! 204: struct le_softc *lesc = (struct le_softc *)sc;
! 205: u_int32_t csr;
! 206: int tries = 5;
! 207:
! 208: while (--tries) {
! 209: csr = lesc->sc_dma->sc_regs->csr;
! 210: csr &= ~E_TP_AUI;
! 211: lesc->sc_dma->sc_regs->csr = csr;
! 212: delay(20000); /* must not touch le for 20ms */
! 213: if ((lesc->sc_dma->sc_regs->csr & E_TP_AUI) == 0)
! 214: return;
! 215: }
! 216: }
! 217: #endif
! 218:
! 219: int
! 220: lemediachange(ifp)
! 221: struct ifnet *ifp;
! 222: {
! 223: struct am7990_softc *sc = ifp->if_softc;
! 224: struct ifmedia *ifm = &sc->sc_ifmedia;
! 225: #if defined(SUN4M)
! 226: struct le_softc *lesc = (struct le_softc *)sc;
! 227: #endif
! 228:
! 229: if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
! 230: return (EINVAL);
! 231:
! 232: /*
! 233: * Switch to the selected media. If autoselect is
! 234: * set, we don't really have to do anything. We'll
! 235: * switch to the other media when we detect loss of
! 236: * carrier.
! 237: */
! 238: switch (IFM_SUBTYPE(ifm->ifm_media)) {
! 239: #if defined(SUN4M)
! 240: case IFM_10_T:
! 241: if (CPU_ISSUN4M && lesc->sc_dma)
! 242: lesetutp(sc);
! 243: else
! 244: return (EOPNOTSUPP);
! 245: break;
! 246:
! 247: case IFM_AUTO:
! 248: if (CPU_ISSUN4M && lesc->sc_dma)
! 249: return (0);
! 250: else
! 251: return (EOPNOTSUPP);
! 252: break;
! 253: #endif
! 254:
! 255: case IFM_10_5:
! 256: #if defined(SUN4M)
! 257: if (CPU_ISSUN4M && lesc->sc_dma)
! 258: lesetaui(sc);
! 259: #else
! 260: return (0);
! 261: #endif
! 262: break;
! 263:
! 264:
! 265: default:
! 266: return (EINVAL);
! 267: }
! 268:
! 269: return (0);
! 270: }
! 271:
! 272: void
! 273: lemediastatus(ifp, ifmr)
! 274: struct ifnet *ifp;
! 275: struct ifmediareq *ifmr;
! 276: {
! 277: #if defined(SUN4M)
! 278: struct am7990_softc *sc = ifp->if_softc;
! 279: struct le_softc *lesc = (struct le_softc *)sc;
! 280:
! 281: if (lesc->sc_dma == NULL) {
! 282: if (lesc->sc_lebufchild)
! 283: ifmr->ifm_active = IFM_ETHER | IFM_10_T;
! 284: else
! 285: ifmr->ifm_active = IFM_ETHER | IFM_10_5;
! 286: return;
! 287: }
! 288:
! 289: if (CPU_ISSUN4M) {
! 290: /*
! 291: * Notify the world which media we're currently using.
! 292: */
! 293: if (lesc->sc_dma->sc_regs->csr & E_TP_AUI)
! 294: ifmr->ifm_active = IFM_ETHER | IFM_10_T;
! 295: else
! 296: ifmr->ifm_active = IFM_ETHER | IFM_10_5;
! 297: }
! 298: else
! 299: ifmr->ifm_active = IFM_ETHER | IFM_10_5;
! 300: #else
! 301: ifmr->ifm_active = IFM_ETHER | IFM_10_5;
! 302: #endif
! 303: }
! 304:
! 305: hide void
! 306: lehwreset(sc)
! 307: struct am7990_softc *sc;
! 308: {
! 309: #if defined(SUN4M)
! 310: struct le_softc *lesc = (struct le_softc *)sc;
! 311:
! 312: /*
! 313: * Reset DMA channel.
! 314: */
! 315: if (CPU_ISSUN4M && lesc->sc_dma) {
! 316: u_int32_t aui;
! 317:
! 318: aui = lesc->sc_dma->sc_regs->csr & E_TP_AUI;
! 319: DMA_RESET(lesc->sc_dma);
! 320: lesc->sc_dma->sc_regs->en_bar = lesc->sc_laddr & 0xff000000;
! 321: DMA_ENINTR(lesc->sc_dma);
! 322: #define D_DSBL_WRINVAL D_DSBL_SCSI_DRN /* XXX: fix dmareg.h */
! 323: /* Disable E-cache invalidates on chip writes */
! 324: lesc->sc_dma->sc_regs->csr |= D_DSBL_WRINVAL | aui;
! 325: delay(20000); /* must not touch le for 20ms */
! 326: }
! 327: #endif
! 328: }
! 329:
! 330: hide void
! 331: lehwinit(sc)
! 332: struct am7990_softc *sc;
! 333: {
! 334: #if defined(SUN4M)
! 335: struct le_softc *lesc = (struct le_softc *)sc;
! 336:
! 337: if (CPU_ISSUN4M && lesc->sc_dma) {
! 338: switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_cur->ifm_media)) {
! 339: case IFM_10_T:
! 340: lesetutp(sc);
! 341: break;
! 342:
! 343: case IFM_10_5:
! 344: lesetaui(sc);
! 345: break;
! 346:
! 347: case IFM_AUTO:
! 348: lesetutp(sc);
! 349: break;
! 350:
! 351: default: /* XXX shouldn't happen */
! 352: lesetutp(sc);
! 353: break;
! 354: }
! 355: }
! 356: #endif
! 357: }
! 358:
! 359: #if defined(SUN4M)
! 360: hide void
! 361: lenocarrier(sc)
! 362: struct am7990_softc *sc;
! 363: {
! 364: struct le_softc *lesc = (struct le_softc *)sc;
! 365:
! 366: if (lesc->sc_dma) {
! 367: /*
! 368: * Check if the user has requested a certain cable type, and
! 369: * if so, honor that request.
! 370: */
! 371: if (lesc->sc_dma->sc_regs->csr & E_TP_AUI) {
! 372: switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_media)) {
! 373: case IFM_10_5:
! 374: case IFM_AUTO:
! 375: printf("%s: lost carrier on UTP port"
! 376: ", switching to AUI port\n",
! 377: sc->sc_dev.dv_xname);
! 378: lesetaui(sc);
! 379: }
! 380: } else {
! 381: switch (IFM_SUBTYPE(sc->sc_ifmedia.ifm_media)) {
! 382: case IFM_10_T:
! 383: case IFM_AUTO:
! 384: printf("%s: lost carrier on AUI port"
! 385: ", switching to UTP port\n",
! 386: sc->sc_dev.dv_xname);
! 387: lesetutp(sc);
! 388: }
! 389: }
! 390: }
! 391: }
! 392: #endif
! 393:
! 394: int
! 395: lematch(parent, vcf, aux)
! 396: struct device *parent;
! 397: void *vcf, *aux;
! 398: {
! 399: struct cfdata *cf = vcf;
! 400: struct confargs *ca = aux;
! 401: register struct romaux *ra = &ca->ca_ra;
! 402:
! 403: if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
! 404: return (0);
! 405: #if defined(solbourne)
! 406: if (CPU_ISKAP) {
! 407: return (ca->ca_bustype == BUS_OBIO);
! 408: }
! 409: #endif
! 410: #if defined(SUN4C) || defined(SUN4M)
! 411: if (ca->ca_bustype == BUS_SBUS) {
! 412: if (!sbus_testdma((struct sbus_softc *)parent, ca))
! 413: return (0);
! 414: return (1);
! 415: }
! 416: #endif
! 417:
! 418: return (probeget(ra->ra_vaddr, 2) != -1);
! 419: }
! 420:
! 421: void
! 422: leattach(parent, self, aux)
! 423: struct device *parent, *self;
! 424: void *aux;
! 425: {
! 426: struct le_softc *lesc = (struct le_softc *)self;
! 427: struct am7990_softc *sc = &lesc->sc_am7990;
! 428: struct confargs *ca = aux;
! 429: int pri;
! 430: struct bootpath *bp;
! 431: #if defined(SUN4C) || defined(SUN4M)
! 432: int sbuschild = strncmp(parent->dv_xname, "sbus", 4) == 0;
! 433: int lebufchild = strncmp(parent->dv_xname, "lebuffer", 8) == 0;
! 434: int dmachild = strncmp(parent->dv_xname, "ledma", 5) == 0;
! 435: struct lebuf_softc *lebuf;
! 436: #endif
! 437:
! 438: /* XXX the following declarations should be elsewhere */
! 439: extern void myetheraddr(u_char *);
! 440:
! 441: if (ca->ca_ra.ra_nintr != 1) {
! 442: printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
! 443: return;
! 444: }
! 445: pri = ca->ca_ra.ra_intr[0].int_pri;
! 446: printf(" pri %d", pri);
! 447:
! 448: sc->sc_hasifmedia = 1;
! 449: #if defined(SUN4C) || defined(SUN4M)
! 450: lesc->sc_lebufchild = lebufchild;
! 451: #endif
! 452:
! 453: lesc->sc_r1 = (struct lereg1 *)
! 454: mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct lereg1));
! 455:
! 456: #if defined(SUN4C) || defined(SUN4M)
! 457: lebuf = NULL;
! 458: if (lebufchild) {
! 459: lebuf = (struct lebuf_softc *)parent;
! 460: } else if (sbuschild) {
! 461: extern struct cfdriver lebuffer_cd;
! 462: struct lebuf_softc *lebufsc;
! 463: int i;
! 464:
! 465: for (i = 0; i < lebuffer_cd.cd_ndevs; i++) {
! 466: lebufsc = (struct lebuf_softc *)lebuffer_cd.cd_devs[i];
! 467: if (lebufsc == NULL || lebufsc->attached != 0)
! 468: continue;
! 469:
! 470: lebuf = lebufsc;
! 471: break;
! 472: }
! 473: }
! 474: if (lebuf != NULL) {
! 475: sc->sc_mem = lebuf->sc_buffer;
! 476: sc->sc_memsize = lebuf->sc_bufsiz;
! 477: sc->sc_addr = 0; /* Lance view is offset by buffer location */
! 478: lebuf->attached = 1;
! 479:
! 480: /* That old black magic... */
! 481: sc->sc_conf3 = getpropint(ca->ca_ra.ra_node,
! 482: "busmaster-regval",
! 483: LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);
! 484: } else
! 485: #endif
! 486: {
! 487: u_long laddr;
! 488:
! 489: #if defined(solbourne)
! 490: if (CPU_ISKAP && ca->ca_bustype == BUS_OBIO) {
! 491: /*
! 492: * Use the fixed buffer allocated in pmap_bootstrap().
! 493: * for now, until I get the iCU translation to work...
! 494: */
! 495: extern vaddr_t lance_va;
! 496:
! 497: laddr = PTW1_TO_PHYS(lance_va);
! 498: sc->sc_mem = (void *)PHYS_TO_PTW2(laddr);
! 499:
! 500: /* disable ICU translations for ethernet */
! 501: sta(ICU_TER, ASI_PHYS_IO,
! 502: lda(ICU_TER, ASI_PHYS_IO) & ~TER_ETHERNET);
! 503:
! 504: /* stash the high 15 bits of the physical address */
! 505: sta(SE_BASE + 0x18, ASI_PHYS_IO,
! 506: laddr & 0xfffe0000);
! 507: } /* else */
! 508: #endif /* solbourne */
! 509: #if defined(SUN4) || defined(SUN4C) || defined(SUN4M)
! 510: #if defined(SUN4C) || defined(SUN4M)
! 511: if (sbuschild && CPU_ISSUN4M)
! 512: laddr = (u_long)dvma_malloc_space(MEMSIZE,
! 513: &sc->sc_mem, M_NOWAIT, M_SPACE_D24);
! 514: else
! 515: #endif
! 516: laddr = (u_long)dvma_malloc(MEMSIZE,
! 517: &sc->sc_mem, M_NOWAIT);
! 518: #endif /* SUN4 || SUN4C || SUN4M */
! 519: #if defined (SUN4M)
! 520: if ((laddr & 0xffffff) >= (laddr & 0xffffff) + MEMSIZE)
! 521: panic("if_le: Lance buffer crosses 16MB boundary");
! 522: #endif
! 523: #if defined(solbourne)
! 524: if (CPU_ISKAP && ca->ca_bustype == BUS_OBIO)
! 525: sc->sc_addr = laddr & 0x01ffff;
! 526: else
! 527: #endif
! 528: sc->sc_addr = laddr & 0xffffff;
! 529: sc->sc_memsize = MEMSIZE;
! 530: #if defined(solbourne)
! 531: if (CPU_ISKAP && ca->ca_bustype == BUS_OBIO)
! 532: sc->sc_conf3 = LE_C3_BSWP;
! 533: else
! 534: #endif
! 535: sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
! 536: #if defined(SUN4C) || defined(SUN4M)
! 537: if (dmachild) {
! 538: lesc->sc_dma = (struct dma_softc *)parent;
! 539: lesc->sc_dma->sc_le = lesc;
! 540: lesc->sc_laddr = laddr;
! 541: }
! 542: #endif
! 543: }
! 544:
! 545: bp = ca->ca_ra.ra_bp;
! 546: switch (ca->ca_bustype) {
! 547: #if defined(SUN4C) || defined(SUN4M)
! 548: #define SAME_LANCE(bp, ca) \
! 549: ((bp->val[0] == ca->ca_slot && bp->val[1] == ca->ca_offset) || \
! 550: (bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit))
! 551:
! 552: case BUS_SBUS:
! 553: if (bp != NULL && strcmp(bp->name, le_cd.cd_name) == 0 &&
! 554: SAME_LANCE(bp, ca))
! 555: bp->dev = &sc->sc_dev;
! 556: break;
! 557: #endif /* SUN4C || SUN4M */
! 558:
! 559: default:
! 560: if (bp != NULL && strcmp(bp->name, le_cd.cd_name) == 0 &&
! 561: sc->sc_dev.dv_unit == bp->val[1])
! 562: bp->dev = &sc->sc_dev;
! 563: break;
! 564: }
! 565:
! 566: myetheraddr(sc->sc_arpcom.ac_enaddr);
! 567:
! 568: sc->sc_copytodesc = am7990_copytobuf_contig;
! 569: sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
! 570: sc->sc_copytobuf = am7990_copytobuf_contig;
! 571: sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
! 572: sc->sc_zerobuf = am7990_zerobuf_contig;
! 573:
! 574: sc->sc_rdcsr = lerdcsr;
! 575: sc->sc_wrcsr = lewrcsr;
! 576: sc->sc_hwinit = lehwinit;
! 577: #if defined(SUN4M)
! 578: if (CPU_ISSUN4M)
! 579: sc->sc_nocarrier = lenocarrier;
! 580: #endif
! 581: sc->sc_hwreset = lehwreset;
! 582:
! 583: ifmedia_init(&sc->sc_ifmedia, 0, lemediachange, lemediastatus);
! 584: #if defined(SUN4C) || defined(SUN4M)
! 585: if (lebufchild) {
! 586: ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
! 587: ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T);
! 588: } else
! 589: #endif
! 590: #if defined(SUN4M)
! 591: if (CPU_ISSUN4M && lesc->sc_dma) {
! 592: ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
! 593: ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5, 0, NULL);
! 594: ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
! 595: ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO);
! 596: } else
! 597: #endif
! 598: {
! 599: ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5, 0, NULL);
! 600: ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5);
! 601: }
! 602:
! 603: am7990_config(sc);
! 604:
! 605: #if defined(solbourne)
! 606: if (CPU_ISKAP && ca->ca_bustype == BUS_OBIO) {
! 607: sc->sc_copytodesc = kap_copytobuf;
! 608: sc->sc_copyfromdesc = kap_copyfrombuf;
! 609:
! 610: sc->sc_initaddr = 1 << 23 | (sc->sc_initaddr & 0x01ffff);
! 611: sc->sc_rmdaddr = 1 << 23 | (sc->sc_rmdaddr & 0x01ffff);
! 612: sc->sc_tmdaddr = 1 << 23 | (sc->sc_tmdaddr & 0x01ffff);
! 613: }
! 614: #endif
! 615:
! 616: lesc->sc_ih.ih_fun = am7990_intr;
! 617: #if defined(SUN4M) /*XXX*/
! 618: if (CPU_ISSUN4M && lesc->sc_dma)
! 619: lesc->sc_ih.ih_fun = myleintr;
! 620: #endif
! 621: lesc->sc_ih.ih_arg = sc;
! 622: intr_establish(pri, &lesc->sc_ih, IPL_NET, self->dv_xname);
! 623:
! 624: /* now initialize DMA */
! 625: lehwreset(sc);
! 626: }
! 627:
! 628: #if defined(solbourne)
! 629: hide void
! 630: kap_copytobuf(struct am7990_softc *sc, void *to, int boff, int len)
! 631: {
! 632: return (am7990_copytobuf_contig(sc, to, boff & ~(1 << 23), len));
! 633: }
! 634: hide void
! 635: kap_copyfrombuf(struct am7990_softc *sc, void *from, int boff, int len)
! 636: {
! 637: return (am7990_copyfrombuf_contig(sc, from, boff & ~(1 << 23), len));
! 638: }
! 639: #endif
CVSweb