void
le_sbdio_attach(device_t parent, device_t self, void *aux)
{
	struct le_sbdio_softc *lesc = device_private(self);
	struct sbdio_attach_args *sa = aux;
	struct lance_softc *sc = &lesc->sc_am7990.lsc;
	bus_dma_segment_t seg;
	int rseg;

	sc->sc_dev = self;
	lesc->sc_dmat = sa->sa_dmat;
	lesc->sc_bst  = sa->sa_bust;

	if (bus_space_map(lesc->sc_bst, sa->sa_addr1, 8 /* XXX */,
	    BUS_SPACE_MAP_LINEAR, &lesc->sc_bsh) != 0) {
		aprint_error(": cannot map registers\n");
		return;
	}

	/* Allocate DMA memory for the chip. */
	if (bus_dmamem_alloc(lesc->sc_dmat, LE_MEMSIZE, 0, 0, &seg, 1, &rseg,
	    BUS_DMA_NOWAIT) != 0) {
		aprint_error(": can't allocate DMA memory\n");
		return;
	}
	if (bus_dmamem_map(lesc->sc_dmat, &seg, rseg, LE_MEMSIZE,
	    (void **)&sc->sc_mem, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) != 0) {
		aprint_error(": can't map DMA memory\n");
		return;
	}
	if (bus_dmamap_create(lesc->sc_dmat, LE_MEMSIZE, 1, LE_MEMSIZE,
	    0, BUS_DMA_NOWAIT, &lesc->sc_dmamap) != 0) {
		aprint_error(": can't create DMA map\n");
		return;
	}
	if (bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmamap, sc->sc_mem,
	    LE_MEMSIZE, NULL, BUS_DMA_NOWAIT) != 0) {
		aprint_error(": can't load DMA map\n");
		return;
	}

	sc->sc_memsize = LE_MEMSIZE;
	sc->sc_addr = lesc->sc_dmamap->dm_segs[0].ds_addr;
	sc->sc_conf3 = LE_C3_BSWP | LE_C3_BCON;
	(*platform.ether_addr)(sc->sc_enaddr);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;
#ifdef LEDEBUG
	sc->sc_debug = 0xff;
#endif
	sc->sc_rdcsr = le_sbdio_rdcsr;
	sc->sc_wrcsr = le_sbdio_wrcsr;

	am7990_config(&lesc->sc_am7990);
	intr_establish(sa->sa_irq, am7990_intr, sc);
}
Пример #2
0
/* ARGSUSED */
void
le_pcc_attach(device_t parent, device_t self, void *aux)
{
    struct le_softc *lsc;
    struct lance_softc *sc;
    struct pcc_attach_args *pa;
    bus_dma_segment_t seg;
    int rseg;

    lsc = device_private(self);
    sc = &lsc->sc_am7990.lsc;
    sc->sc_dev = self;
    pa = aux;

    /* Map control registers. */
    lsc->sc_bust = pa->pa_bust;
    bus_space_map(pa->pa_bust, pa->pa_offset, 4, 0, &lsc->sc_bush);

    /* Get contiguous DMA-able memory for the lance */
    if (bus_dmamem_alloc(pa->pa_dmat, ether_data_buff_size, PAGE_SIZE, 0,
                         &seg, 1, &rseg,
                         BUS_DMA_NOWAIT | BUS_DMA_ONBOARD_RAM | BUS_DMA_24BIT)) {
        aprint_error(": Failed to allocate ether buffer\n");
        return;
    }
    if (bus_dmamem_map(pa->pa_dmat, &seg, rseg, ether_data_buff_size,
                       (void **)&sc->sc_mem, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
        aprint_error(": Failed to map ether buffer\n");
        bus_dmamem_free(pa->pa_dmat, &seg, rseg);
        return;
    }
    sc->sc_addr = seg.ds_addr;
    sc->sc_memsize = ether_data_buff_size;
    sc->sc_conf3 = LE_C3_BSWP;

    memcpy(sc->sc_enaddr, mvme_ea, ETHER_ADDR_LEN);

    sc->sc_copytodesc = lance_copytobuf_contig;
    sc->sc_copyfromdesc = lance_copyfrombuf_contig;
    sc->sc_copytobuf = lance_copytobuf_contig;
    sc->sc_copyfrombuf = lance_copyfrombuf_contig;
    sc->sc_zerobuf = lance_zerobuf_contig;

    sc->sc_rdcsr = le_pcc_rdcsr;
    sc->sc_wrcsr = le_pcc_wrcsr;
    sc->sc_hwinit = NULL;

    am7990_config(&lsc->sc_am7990);

    evcnt_attach_dynamic(&lsc->sc_evcnt, EVCNT_TYPE_INTR,
                         pccintr_evcnt(pa->pa_ipl), "ether", device_xname(self));

    pccintr_establish(PCCV_LE, am7990_intr, pa->pa_ipl, sc, &lsc->sc_evcnt);

    pcc_reg_write(sys_pcc, PCCREG_LANCE_INTR_CTRL,
                  pa->pa_ipl | PCC_IENABLE);
}
Пример #3
0
void
le_isapnp_attach(struct device *parent, struct device *self, void *aux)
{
	struct le_softc *lesc = (void *)self;
	struct isa_attach_args *ia = aux;
	struct am7990_softc *sc = &lesc->sc_am7990;
	bus_space_tag_t iot = lesc->sc_iot;
	bus_space_handle_t ioh = lesc->sc_ioh;
	int i;

	lesc->sc_iot = iot = ia->ia_iot;
	lesc->sc_ioh = ioh = ia->ipa_io[0].h;
	lesc->sc_rap = NE2100_RAP;
	lesc->sc_rdp = NE2100_RDP;
	lesc->sc_card = NE2100;

	/*
	 * Extract the physical MAC address from the ROM.
	 */
	for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++)
		sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(iot, ioh, i);

	sc->sc_mem = malloc(16384, M_DEVBUF, M_NOWAIT);
	if (sc->sc_mem == 0) {
		printf(": couldn't allocate memory for card\n");
		return;
	}

	sc->sc_conf3 = 0;
	sc->sc_addr = kvtop(sc->sc_mem);
	sc->sc_memsize = 16384;

	sc->sc_copytodesc = am7990_copytobuf_contig;
	sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
	sc->sc_copytobuf = am7990_copytobuf_contig;
	sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
	sc->sc_zerobuf = am7990_zerobuf_contig;

	sc->sc_rdcsr = le_isa_rdcsr;
	sc->sc_wrcsr = le_isa_wrcsr;
	sc->sc_hwreset = NULL;
	sc->sc_hwinit = NULL;

	am7990_config(sc);

#if NISADMA > 0
	if (ia->ia_drq != DRQUNK)
		isadma_cascade(ia->ia_drq);
#endif

	lesc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
	    IPL_NET, le_isa_intredge, sc, sc->sc_dev.dv_xname);
}
Пример #4
0
void
le_attach(device_t parent, device_t self, void *aux)
{
	struct le_softc *lesc = device_private(self);
	struct lance_softc *sc = &lesc->sc_am7990.lsc;
	struct hb_attach_args *ha = aux;
	const uint8_t *p;

	sc->sc_dev = self;
	lesc->sc_r1 = (void *)(ha->ha_address);

	if (ISIIOPA(ha->ha_address)) {
		sc->sc_mem = (u_char *)(lance_mem_phys);
		p = idrom_addr + 0x10;
	} else {
		sc->sc_mem = lesc->sc_r1 - 0x10000;
		p = (const uint8_t *)(lesc->sc_r1 + 0x8010);
	}

	sc->sc_memsize = 0x4000;	/* 16K */
	sc->sc_addr = lance_mem_phys & 0x00ffffff;
	sc->sc_conf3 = LE_C3_BSWP|LE_C3_BCON;

	sc->sc_enaddr[0] = (*p++ << 4);
	sc->sc_enaddr[0] |= *p++ & 0x0f;
	sc->sc_enaddr[1] = (*p++ << 4);
	sc->sc_enaddr[1] |= *p++ & 0x0f;
	sc->sc_enaddr[2] = (*p++ << 4);
	sc->sc_enaddr[2] |= *p++ & 0x0f;
	sc->sc_enaddr[3] = (*p++ << 4);
	sc->sc_enaddr[3] |= *p++ & 0x0f;
	sc->sc_enaddr[4] = (*p++ << 4);
	sc->sc_enaddr[4] |= *p++ & 0x0f;
	sc->sc_enaddr[5] = (*p++ << 4);
	sc->sc_enaddr[5] |= *p++ & 0x0f;

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = lerdcsr;
	sc->sc_wrcsr = lewrcsr;
	sc->sc_hwinit = NULL;

	am7990_config(&lesc->sc_am7990);
}
Пример #5
0
void
leattach_lebuffer(struct device *parent, struct device *self, void *aux)
{
	struct sbus_attach_args *sa = aux;
	struct le_softc *lesc = (struct le_softc *)self;
	struct am7990_softc *sc = &lesc->sc_am7990;
	struct lebuf_softc *lebuf = (struct lebuf_softc *)parent;
	/* XXX the following declarations should be elsewhere */
	extern void myetheraddr(u_char *);

	lesc->sc_bustag = sa->sa_bustag;
	lesc->sc_dmatag = sa->sa_dmatag;

	if (sbus_bus_map(sa->sa_bustag,
	    sa->sa_slot, sa->sa_offset, sa->sa_size,
	    0, 0, &lesc->sc_reg)) {
		printf(": cannot map registers\n");
		return;
	}

	sc->sc_mem = lebuf->sc_buffer;
	sc->sc_memsize = lebuf->sc_bufsiz;
	sc->sc_addr = 0; /* Lance view is offset by buffer location */
	lebuf->attached = 1;

	/* That old black magic... */
	sc->sc_conf3 = getpropint(sa->sa_node, "busmaster-regval",
	    LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);

	myetheraddr(sc->sc_arpcom.ac_enaddr);

	sc->sc_copytodesc = am7990_copytobuf_contig;
	sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
	sc->sc_copytobuf = am7990_copytobuf_contig;
	sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
	sc->sc_zerobuf = am7990_zerobuf_contig;

	sc->sc_rdcsr = le_lebuffer_rdcsr;
	sc->sc_wrcsr = le_lebuffer_wrcsr;

	am7990_config(&lesc->sc_am7990);

	/* Establish interrupt handler */
	if (sa->sa_nintr != 0)
		(void)bus_intr_establish(lesc->sc_bustag, sa->sa_pri,
		    IPL_NET, 0, am7990_intr, sc, self->dv_xname);
}
Пример #6
0
void
dec_le_common_attach(struct am7990_softc *sc, u_char *eap)
{
	int i;

	sc->sc_rdcsr = le_dec_rdcsr;
	sc->sc_wrcsr = le_dec_wrcsr;
	sc->sc_hwinit = NULL;

	sc->sc_conf3 = 0;
	sc->sc_addr = 0;
	sc->sc_memsize = 65536;

	/*
	 * Get the ethernet address out of rom
	 */
	for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++) {
		sc->sc_arpcom.ac_enaddr[i] = *eap;
		eap += 4;
	}

	am7990_config(sc);
}
Пример #7
0
static int
le_lebuffer_attach(device_t dev)
{
	struct le_lebuffer_softc *lesc;
	struct lance_softc *sc;
	int error, i;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am7990.lsc;

	LE_LOCK_INIT(sc, device_get_nameunit(dev));

	/*
	 * The "register space" of the parent is just a buffer where the
	 * the LANCE descriptor rings and the RX/TX buffers can be stored.
	 */
	i = 0;
	lesc->sc_bres = bus_alloc_resource_any(device_get_parent(dev),
	    SYS_RES_MEMORY, &i, RF_ACTIVE);
	if (lesc->sc_bres == NULL) {
		device_printf(dev, "cannot allocate LANCE buffer\n");
		error = ENXIO;
		goto fail_mtx;
	}

	/* Allocate LANCE registers. */
	i = 0;
	lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate LANCE registers\n");
		error = ENXIO;
		goto fail_bres;
	}

	/* Allocate LANCE interrupt. */
	i = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_rres;
	}

	/*
	 * LANCE view is offset by buffer location.
	 * Note that we don't use sc->sc_mem.
	 */
	sc->sc_addr = 0;
	sc->sc_memsize = rman_get_size(lesc->sc_bres);
	sc->sc_flags = 0;

	/* That old black magic... */
	if (OF_getprop(ofw_bus_get_node(dev), "busmaster-regval",
	    &sc->sc_conf3, sizeof(sc->sc_conf3)) == -1)
		sc->sc_conf3 = LE_C3_ACON | LE_C3_BCON;
	/*
	 * Make sure LE_C3_BSWP is cleared so that for cards where
	 * that flag actually works le_lebuffer_copy{from,to}buf()
	 * don't fail...
	 */
	sc->sc_conf3 &= ~LE_C3_BSWP;

	OF_getetheraddr(dev, sc->sc_enaddr);

	sc->sc_copytodesc = le_lebuffer_copytodesc;
	sc->sc_copyfromdesc = le_lebuffer_copyfromdesc;
	sc->sc_copytobuf = le_lebuffer_copytobuf;
	sc->sc_copyfrombuf = le_lebuffer_copyfrombuf;
	sc->sc_zerobuf = le_lebuffer_zerobuf;

	sc->sc_rdcsr = le_lebuffer_rdcsr;
	sc->sc_wrcsr = le_lebuffer_wrcsr;
	sc->sc_hwreset = NULL;
	sc->sc_hwinit = NULL;
	sc->sc_hwintr = NULL;
	sc->sc_nocarrier = NULL;
	sc->sc_mediachange = NULL;
	sc->sc_mediastatus = NULL;
	sc->sc_supmedia = le_lebuffer_media;
	sc->sc_nsupmedia = NLEMEDIA;
	sc->sc_defaultmedia = le_lebuffer_media[0];

	error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am7990\n");
		goto fail_ires;
	}

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, am7990_intr, sc, &lesc->sc_ih);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am7990;
	}

	return (0);

 fail_am7990:
	am7990_detach(&lesc->sc_am7990);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ,
	    rman_get_rid(lesc->sc_ires), lesc->sc_ires);
 fail_rres:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(lesc->sc_rres), lesc->sc_rres);
 fail_bres:
	bus_release_resource(device_get_parent(dev), SYS_RES_MEMORY,
	    rman_get_rid(lesc->sc_bres), lesc->sc_bres);
 fail_mtx:
	LE_LOCK_DESTROY(sc);
	return (error);
}
Пример #8
0
static int
le_isa_attach(device_t dev)
{
	struct le_isa_softc *lesc;
	struct lance_softc *sc;
	bus_size_t macstart, rap, rdp;
	int error, i, macstride;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am7990.lsc;

	lesc->sc_rrid = 0;
	switch (ISA_PNP_PROBE(device_get_parent(dev), dev, le_isa_ids)) {
	case 0:
		lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
		    &lesc->sc_rrid, RF_ACTIVE);
		rap = PCNET_RAP;
		rdp = PCNET_RDP;
		macstart = 0;
		macstride = 1;
		break;
	case ENOENT:
		for (i = 0; i < NELEM(le_isa_params); i++) {
			if (le_isa_probe_legacy(dev, &le_isa_params[i]) == 0) {
				lesc->sc_rres = bus_alloc_resource(dev,
				    SYS_RES_IOPORT, &lesc->sc_rrid, 0, ~0,
				    le_isa_params[i].iosize, RF_ACTIVE);
				rap = le_isa_params[i].rap;
				rdp = le_isa_params[i].rdp;
				macstart = le_isa_params[i].macstart;
				macstride = le_isa_params[i].macstride;
				goto found;
			}
		}
		/* FALLTHROUGH */
	case ENXIO:
	default:
		device_printf(dev, "cannot determine chip\n");
		error = ENXIO;
		goto fail_mtx;
	}

 found:
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
	lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);
	lesc->sc_rap = rap;
	lesc->sc_rdp = rdp;

	lesc->sc_drid = 0;
	if ((lesc->sc_dres = bus_alloc_resource_any(dev, SYS_RES_DRQ,
	    &lesc->sc_drid, RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate DMA channel\n");
		error = ENXIO;
		goto fail_rres;
	}

	lesc->sc_irid = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_dres;
	}

	error = bus_dma_tag_create(
	    NULL,			/* parent */
	    1, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_24BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
	    0,				/* nsegments */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_pdmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate parent DMA tag\n");
		goto fail_ires;
	}

	sc->sc_memsize = LE_ISA_MEMSIZE;
	/*
	 * For Am79C90, Am79C961 and Am79C961A the init block must be 2-byte
	 * aligned and the ring descriptors must be 8-byte aligned.
	 */
	error = bus_dma_tag_create(
	    lesc->sc_pdmat,		/* parent */
	    8, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_24BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->sc_memsize,		/* maxsize */
	    1,				/* nsegments */
	    sc->sc_memsize,		/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_dmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate buffer DMA tag\n");
		goto fail_pdtag;
	}

	error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
	    BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
	if (error != 0) {
		device_printf(dev, "cannot allocate DMA buffer memory\n");
		goto fail_dtag;
	}

	sc->sc_addr = 0;
	error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
	    sc->sc_memsize, le_isa_dma_callback, sc, 0);
	if (error != 0 || sc->sc_addr == 0) {
                device_printf(dev, "cannot load DMA buffer map\n");
		goto fail_dmem;
	}

	isa_dmacascade(rman_get_start(lesc->sc_dres));

	sc->sc_flags = 0;
	sc->sc_conf3 = 0;

	/*
	 * Extract the physical MAC address from the ROM.
	 */
	for (i = 0; i < sizeof(sc->sc_enaddr); i++)
		sc->sc_enaddr[i] =  bus_space_read_1(lesc->sc_regt,
		    lesc->sc_regh, macstart + i * macstride);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_isa_rdcsr;
	sc->sc_wrcsr = le_isa_wrcsr;
	sc->sc_hwreset = NULL;
	sc->sc_hwinit = NULL;
	sc->sc_hwintr = NULL;
	sc->sc_nocarrier = NULL;
	sc->sc_mediachange = NULL;
	sc->sc_mediastatus = NULL;
	sc->sc_supmedia = NULL;

	error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am7990\n");
		goto fail_dmap;
	}

	ifq_set_cpuid(&sc->ifp->if_snd, rman_get_cpuid(lesc->sc_ires));

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE,
	    am7990_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am7990;
	}

	return (0);

 fail_am7990:
	am7990_detach(&lesc->sc_am7990);
 fail_dmap:
	bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
 fail_dmem:
	bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
 fail_dtag:
	bus_dma_tag_destroy(lesc->sc_dmat);
 fail_pdtag:
	bus_dma_tag_destroy(lesc->sc_pdmat);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
 fail_dres:
	bus_release_resource(dev, SYS_RES_DRQ, lesc->sc_drid, lesc->sc_dres);
 fail_rres:
	bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
 fail_mtx:
	return (error);
}
Пример #9
0
void
le_fwio_attach(struct device *parent, struct device *self, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
	struct le_fwio_softc *lsc = (struct le_fwio_softc *)self;
	struct lance_softc *sc = &lsc->sc_am7990.lsc;
	unsigned int vec;
	uint32_t *esar;
	int i;

	vec = faa->faa_vecbase + FBIC_DEVIRQ1 * 4;
	printf(" vec %d", vec);

	/*
	 * Map registers.
	 */

	lsc->sc_rdp = (volatile uint16_t *)
	    vax_map_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
	lsc->sc_rap = lsc->sc_rdp + 2;

	/*
	 * Register access functions.
	 */

	sc->sc_rdcsr = le_fwio_rdcsr;
	sc->sc_wrcsr = le_fwio_wrcsr;

	/*
	 * Map buffers.
	 */

	sc->sc_mem = (void *)uvm_km_valloc(kernel_map, FWIO_LANCE_BUF_SIZE);
	if (sc->sc_mem == NULL) {
		vax_unmap_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
		printf(": can't map buffers\n");
		return;
	}

	ioaccess((vaddr_t)sc->sc_mem, faa->faa_base +
	    FWIO_LANCE_BUF_OFFSET, FWIO_LANCE_BUF_SIZE >> VAX_PGSHIFT);

	sc->sc_addr = FWIO_LANCE_BUF_OFFSET;
	sc->sc_memsize = FWIO_LANCE_BUF_SIZE;
	sc->sc_conf3 = 0;

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	/*
	 * Get the Ethernet address from the Station Address ROM.
	 */

	esar = (uint32_t *)vax_map_physmem(faa->faa_base + FWIO_ESAR_OFFSET, 1);
	for (i = 0; i < 6; i++)
		sc->sc_arpcom.ac_enaddr[i] =
		    (esar[i] & FWIO_ESAR_MASK) >> FWIO_ESAR_SHIFT;
	vax_unmap_physmem((vaddr_t)esar, 1);

	/*
	 * Register interrupt handler.
	 */

	if (mbus_intr_establish(vec, IPL_NET, le_fwio_intr, sc,
	    self->dv_xname) != 0) {
		vax_unmap_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
		uvm_km_free(kernel_map, (vaddr_t)sc->sc_mem,
		    FWIO_LANCE_BUF_SIZE);
		printf(": can't establish interrupt\n");
		return;
	}

	/*
	 * Complete attachment.
	 */

	am7990_config(&lsc->sc_am7990);
}
Пример #10
0
void
leattach_ledma(device_t parent, device_t self, void *aux)
{
	struct le_softc *lesc = device_private(self);
	struct lance_softc *sc = &lesc->sc_am7990.lsc;
	struct lsi64854_softc *lsi = device_private(parent);
	struct sbus_attach_args *sa = aux;
	bus_dma_tag_t dmatag = sa->sa_dmatag;
	bus_dma_segment_t seg;
	int rseg, error;

	sc->sc_dev = self;
	lesc->sc_bustag = sa->sa_bustag;

	/* Establish link to `ledma' device */
	lesc->sc_dma = lsi;
	lesc->sc_dma->sc_client = lesc;

	/* Map device registers */
	if (sbus_bus_map(sa->sa_bustag,
			 sa->sa_slot,
			 sa->sa_offset,
			 sa->sa_size,
			 0, &lesc->sc_reg) != 0) {
		aprint_error(": cannot map registers\n");
		return;
	}

	/* Allocate buffer memory */
	sc->sc_memsize = MEMSIZE;

	/* Get a DMA handle */
	if ((error = bus_dmamap_create(dmatag, MEMSIZE, 1, MEMSIZE,
					LEDMA_BOUNDARY, BUS_DMA_NOWAIT,
					&lesc->sc_dmamap)) != 0) {
		aprint_error(": DMA map create error %d\n", error);
		return;
	}

	/* Allocate DMA buffer */
	if ((error = bus_dmamem_alloc(dmatag, MEMSIZE, 0, LEDMA_BOUNDARY,
				 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
		aprint_error(": DMA buffer alloc error %d\n",error);
		return;
	}

	/* Map DMA buffer into kernel space */
	if ((error = bus_dmamem_map(dmatag, &seg, rseg, MEMSIZE,
			       (void **)&sc->sc_mem,
			       BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		aprint_error(": DMA buffer map error %d\n", error);
		bus_dmamem_free(dmatag, &seg, rseg);
		return;
	}

	/* Load DMA buffer */
	if ((error = bus_dmamap_load(dmatag, lesc->sc_dmamap, sc->sc_mem,
			MEMSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		aprint_error(": DMA buffer map load error %d\n", error);
		bus_dmamem_free(dmatag, &seg, rseg);
		bus_dmamem_unmap(dmatag, sc->sc_mem, MEMSIZE);
		return;
	}

	lesc->sc_laddr = lesc->sc_dmamap->dm_segs[0].ds_addr;
	sc->sc_addr = lesc->sc_laddr & 0xffffff;
	sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;


	/* Assume SBus is grandparent */
	lesc->sc_sd.sd_reset = (void *)lance_reset;
	sbus_establish(&lesc->sc_sd, parent);

	sc->sc_mediachange = lemediachange;
	sc->sc_mediastatus = lemediastatus;
	sc->sc_supmedia = lemedia;
	sc->sc_nsupmedia = NLEMEDIA;
	sc->sc_defaultmedia = IFM_ETHER|IFM_AUTO;

	prom_getether(sa->sa_node, sc->sc_enaddr);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = lerdcsr;
	sc->sc_wrcsr = lewrcsr;
	sc->sc_hwinit = lehwinit;
	sc->sc_nocarrier = lenocarrier;
	sc->sc_hwreset = lehwreset;

	/* Establish interrupt handler */
	if (sa->sa_nintr != 0)
		(void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET,
					 am7990_intr, sc);

	am7990_config(&lesc->sc_am7990);

	/* now initialize DMA */
	lehwreset(sc);
}
Пример #11
0
static int
le_dma_attach(device_t dev)
{
	struct le_dma_softc *lesc;
	struct lsi64854_softc *dma;
	struct lance_softc *sc;
	int error, i;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am7990.lsc;

	LE_LOCK_INIT(sc, device_get_nameunit(dev));

	/*
	 * Establish link to `ledma' device.
	 * XXX hackery.
	 */
	dma = (struct lsi64854_softc *)device_get_softc(device_get_parent(dev));
	lesc->sc_dma = dma;
	lesc->sc_dma->sc_client = lesc;

	i = 0;
	lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate registers\n");
		error = ENXIO;
		goto fail_mtx;
	}

	i = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_rres;
	}

	/* Attach the DMA engine. */
	error = lsi64854_attach(dma);
	if (error != 0) {
		device_printf(dev, "lsi64854_attach failed\n");
		goto fail_ires;
	}

	sc->sc_memsize = LEDMA_MEMSIZE;
	error = bus_dma_tag_create(
	    dma->sc_parent_dmat,	/* parent */
	    LEDMA_ALIGNMENT,		/* alignment */
	    LEDMA_BOUNDARY,		/* boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->sc_memsize,		/* maxsize */
	    1,				/* nsegments */
	    sc->sc_memsize,		/* maxsegsize */
	    0,				/* flags */
	    NULL, NULL,			/* lockfunc, lockarg */
	    &lesc->sc_dmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate buffer DMA tag\n");
		goto fail_lsi;
	}

	error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
	    BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
	if (error != 0) {
		device_printf(dev, "cannot allocate DMA buffer memory\n");
		goto fail_dtag;
	}

	lesc->sc_laddr = 0;
	error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
	    sc->sc_memsize, le_dma_dma_callback, lesc, 0);
	if (error != 0 || lesc->sc_laddr == 0) {
		device_printf(dev, "cannot load DMA buffer map\n");
		goto fail_dmem;
	}

	sc->sc_addr = lesc->sc_laddr & 0xffffff;
	sc->sc_flags = 0;
	sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;

	sc->sc_mediachange = le_dma_supmediachange;
	sc->sc_mediastatus = le_dma_supmediastatus;
	sc->sc_supmedia = le_dma_supmedia;
	sc->sc_nsupmedia = nitems(le_dma_supmedia);
	sc->sc_defaultmedia = le_dma_supmedia[0];

	OF_getetheraddr(dev, sc->sc_enaddr);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_dma_rdcsr;
	sc->sc_wrcsr = le_dma_wrcsr;
	sc->sc_hwreset = le_dma_hwreset;
	sc->sc_hwintr = le_dma_hwintr;
	sc->sc_nocarrier = le_dma_nocarrier;

	error = am7990_config(&lesc->sc_am7990, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am7990\n");
		goto fail_dmap;
	}

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, am7990_intr, sc, &lesc->sc_ih);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am7990;
	}

	return (0);

 fail_am7990:
	am7990_detach(&lesc->sc_am7990);
 fail_dmap:
	bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
 fail_dmem:
	bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
 fail_dtag:
	bus_dma_tag_destroy(lesc->sc_dmat);
 fail_lsi:
	lsi64854_detach(dma);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires),
	    lesc->sc_ires);
 fail_rres:
	bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres),
	    lesc->sc_rres);
 fail_mtx:
	LE_LOCK_DESTROY(sc);
	return (error);
}
Пример #12
0
void
leattach_sbus(struct device *parent, struct device *self, void *aux)
{
	struct sbus_attach_args *sa = aux;
	struct le_softc *lesc = (struct le_softc *)self;
	struct lance_softc *sc = &lesc->sc_am7990.lsc;
	bus_dma_tag_t dmatag;
	/* XXX the following declarations should be elsewhere */
	extern void myetheraddr(u_char *);
	extern struct cfdriver lebuffer_cd;

	lesc->sc_bustag = sa->sa_bustag;
	lesc->sc_dmatag = dmatag = sa->sa_dmatag;

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
	    BUS_SPACE_MAP_LINEAR, 0, &lesc->sc_reg) != 0) {
		printf(": cannot map registers\n");
		return;
	}

	/*
	 * Look for an "unallocated" lebuffer and pair it with
	 * this `le' device on the assumption that we're on
	 * a pre-historic ROM that doesn't establish le<=>lebuffer
	 * parent-child relationships.
	 */
	if (lebuffer_cd.cd_ndevs != 0) {
		struct lebuf_softc *lebuf;
		int i;

		for (i = 0; i < lebuffer_cd.cd_ndevs; i++) {
			lebuf = (struct lebuf_softc *)lebuffer_cd.cd_devs[i];
			if (lebuf == NULL || lebuf->attached != 0)
				continue;

			sc->sc_mem = lebuf->sc_buffer;
			sc->sc_memsize = lebuf->sc_bufsiz;
			/* Lance view is offset by buffer location */
			sc->sc_addr = 0;
			lebuf->attached = 1;

			/* That old black magic... */
			sc->sc_conf3 = getpropint(sa->sa_node,
			    "busmaster-regval",
			    LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);
			break;
		}
	}

	if (sc->sc_mem == 0) {
		bus_dma_segment_t seg;
		int rseg, error;

		/* Get a DMA handle */
		if ((error = bus_dmamap_create(dmatag, MEMSIZE, 1, MEMSIZE, 0,
		     BUS_DMA_NOWAIT|BUS_DMA_24BIT, &lesc->sc_dmamap)) != 0) {
			printf(": DMA map create error %d\n", error);
			return;
		}

		/* Allocate DMA buffer */
		if ((error = bus_dmamem_alloc(dmatag, MEMSIZE, 0, 0,
		     &seg, 1, &rseg, BUS_DMA_NOWAIT|BUS_DMA_24BIT)) != 0){
			printf(": DMA buffer allocation error %d\n", error);
			return;
		}

		/* Map DMA buffer into kernel space */
		if ((error = bus_dmamem_map(dmatag, &seg, rseg, MEMSIZE,
		     (caddr_t *)&sc->sc_mem,
		     BUS_DMA_NOWAIT|BUS_DMA_COHERENT|BUS_DMA_24BIT)) != 0) {
			printf(": DMA buffer map error %d\n", error);
			bus_dmamem_free(lesc->sc_dmatag, &seg, rseg);
			return;
		}

		/* Load DMA buffer */
		if ((error = bus_dmamap_load(dmatag, lesc->sc_dmamap, sc->sc_mem,
		    MEMSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT|BUS_DMA_24BIT)) != 0) {
			printf(": DMA buffer map load error %d\n", error);
			bus_dmamem_free(dmatag, &seg, rseg);
			bus_dmamem_unmap(dmatag, sc->sc_mem, MEMSIZE);
			return;
		}

		sc->sc_addr = lesc->sc_dmamap->dm_segs[0].ds_addr & 0xffffff;
		sc->sc_memsize = MEMSIZE;
		sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
	}

	myetheraddr(sc->sc_arpcom.ac_enaddr);

	sc->sc_supmedia = lemedia;
	sc->sc_nsupmedia = nitems(lemedia);
	sc->sc_defaultmedia = sc->sc_supmedia[sc->sc_nsupmedia - 1];

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_sbus_rdcsr;
	sc->sc_wrcsr = le_sbus_wrcsr;

	am7990_config(&lesc->sc_am7990);

	/* Establish interrupt handler */
	if (sa->sa_nintr != 0)
		(void)bus_intr_establish(lesc->sc_bustag, sa->sa_pri,
		    IPL_NET, 0, am7990_intr, sc, self->dv_xname);
}
Пример #13
0
void
leattach_ledma(struct device *parent, struct device *self, void *aux)
{
	struct sbus_attach_args *sa = aux;
	struct le_softc *lesc = (struct le_softc *)self;
	struct lsi64854_softc *lsi = (struct lsi64854_softc *)parent;
	struct lance_softc *sc = &lesc->sc_am7990.lsc;
	bus_dma_tag_t dmatag = sa->sa_dmatag;
	bus_dma_segment_t seg;
	int rseg, error;
	/* XXX the following declarations should be elsewhere */
	extern void myetheraddr(u_char *);

	lesc->sc_bustag = sa->sa_bustag;

	/* Establish link to `ledma' device */
	lesc->sc_dma = lsi;
	lesc->sc_dma->sc_client = lesc;

	/* Map device registers */
	if (sbus_bus_map(sa->sa_bustag,
			   sa->sa_slot,
			   sa->sa_offset,
			   sa->sa_size,
			   BUS_SPACE_MAP_LINEAR,
			   0, &lesc->sc_reg) != 0) {
		printf("%s @ ledma: cannot map registers\n", self->dv_xname);
		return;
	}

	/* Allocate buffer memory */
	sc->sc_memsize = MEMSIZE;

	/* Get a DMA handle */
	if ((error = bus_dmamap_create(dmatag, MEMSIZE, 1, MEMSIZE,
					LEDMA_BOUNDARY, BUS_DMA_NOWAIT,
					&lesc->sc_dmamap)) != 0) {
		printf("%s: DMA map create error %d\n", self->dv_xname, error);
		return;
	}

	/* Allocate DMA buffer */
	if ((error = bus_dmamem_alloc(dmatag, MEMSIZE, 0, LEDMA_BOUNDARY,
				 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
		printf("%s @ ledma: DMA buffer alloc error %d\n",
			self->dv_xname, error);
		return;
	}

	/* Map DMA buffer into kernel space */
	if ((error = bus_dmamem_map(dmatag, &seg, rseg, MEMSIZE,
			       (caddr_t *)&sc->sc_mem,
			       BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		printf("%s @ ledma: DMA buffer map error %d\n",
			self->dv_xname, error);
		bus_dmamem_free(dmatag, &seg, rseg);
		return;
	}

	/* Load DMA buffer */
	if ((error = bus_dmamap_load(dmatag, lesc->sc_dmamap, sc->sc_mem,
			MEMSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		printf("%s: DMA buffer map load error %d\n",
			self->dv_xname, error);
		bus_dmamem_free(dmatag, &seg, rseg);
		bus_dmamem_unmap(dmatag, sc->sc_mem, MEMSIZE);
		return;
	}

	lesc->sc_laddr = lesc->sc_dmamap->dm_segs[0].ds_addr;
	sc->sc_addr = lesc->sc_laddr & 0xffffff;
	sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;

	myetheraddr(sc->sc_arpcom.ac_enaddr);

	sc->sc_mediachange = lemediachange;
	sc->sc_mediastatus = lemediastatus;
	sc->sc_supmedia = lemedia;
	sc->sc_nsupmedia = nitems(lemedia);
	sc->sc_defaultmedia = sc->sc_supmedia[sc->sc_nsupmedia - 1];

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_ledma_rdcsr;
	sc->sc_wrcsr = le_ledma_wrcsr;
	sc->sc_hwinit = le_ledma_hwinit;
	sc->sc_nocarrier = le_ledma_nocarrier;
	sc->sc_hwreset = le_ledma_hwreset;

	/* Establish interrupt handler */
	if (sa->sa_nintr != 0)
		(void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET, 0,
					 am7990_intr, sc, self->dv_xname);

	am7990_config(&lesc->sc_am7990);

	/* now initialize DMA */
	le_ledma_hwreset(sc);
}