Esempio n. 1
0
void
gemattach_sbus(struct device *parent, struct device *self, void *aux)
{
	struct sbus_attach_args *sa = aux;
	struct gem_sbus_softc *gsc = (void *)self;
	struct gem_softc *sc = &gsc->gsc_gem;
	/* XXX the following declarations should be elsewhere */
	extern void myetheraddr(u_char *);

	/* Pass on the bus tags */
	sc->sc_bustag = sa->sa_bustag;
	sc->sc_dmatag = sa->sa_dmatag;

	if (sa->sa_nreg < 2) {
		printf("%s: only %d register sets\n",
			self->dv_xname, sa->sa_nreg);
		return;
	}

	/*
	 * Map two register banks:
	 *
	 *	bank 0: status, config, reset
	 *	bank 1: various gem parts
	 *
	 */
	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
			 (bus_addr_t)sa->sa_reg[0].sbr_offset,
			 (bus_size_t)sa->sa_reg[0].sbr_size, 0, 0,
			 &sc->sc_h2) != 0) {
		printf("%s: cannot map registers\n", self->dv_xname);
		return;
	}
	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
			 (bus_addr_t)sa->sa_reg[1].sbr_offset,
			 (bus_size_t)sa->sa_reg[1].sbr_size, 0, 0,
			 &sc->sc_h1) != 0) {
		printf("%s: cannot map registers\n", self->dv_xname);
		return;
	}

	if (OF_getprop(sa->sa_node, "local-mac-address",
	    sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
		myetheraddr(sc->sc_arpcom.ac_enaddr);

	/*
	 * SBUS config
	 */
	bus_space_write_4(sa->sa_bustag, sc->sc_h2, GEM_SBUS_CONFIG,
	    GEM_SBUS_CFG_PARITY|GEM_SBUS_CFG_BMODE64);

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

	gem_config(sc);
}
Esempio n. 2
0
void
gemattach_sbus(struct device *parent, struct device *self, void *aux)
{
	struct confargs *ca = aux;
	struct gem_sbus_softc *gsc = (void *)self;
	struct gem_softc *sc = &gsc->gsc_gem;
	/* XXX the following declaration should be elsewhere */
	extern void myetheraddr(u_char *);

	/* Pass on the bus tags */
	gsc->gsc_rr = ca->ca_ra.ra_reg[0];
	sc->sc_bustag = &gsc->gsc_rr;
	sc->sc_dmatag = iommu_dmatag;

	if (ca->ca_ra.ra_nintr < 1) {
                printf(": no interrupt\n");
                return;
        }

	if (ca->ca_ra.ra_nreg < 2) {
                printf(": only %d register sets\n", ca->ca_ra.ra_nreg);
		return;
	}

	sc->sc_variant = GEM_SUN_GEM;

	/*
	 * Map two register banks:
	 *
	 *	bank 0: status, config, reset
	 *	bank 1: various gem parts
	 *
	 */
	if (bus_space_map(&ca->ca_ra.ra_reg[0], 0,
	    ca->ca_ra.ra_reg[0].rr_len, 0, &sc->sc_h2)) {
		printf(": can't map registers\n");
		return;
	}
	if (bus_space_map(&ca->ca_ra.ra_reg[1], 0,
	    ca->ca_ra.ra_reg[1].rr_len, 0, &sc->sc_h1)) {
		printf(": can't map registers\n");
		return;
	}

	if (getprop(ca->ca_ra.ra_node, "local-mac-address",
	    sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
		myetheraddr(sc->sc_arpcom.ac_enaddr);

	/*
	 * SBUS config
	 */
	(void) bus_space_read_4(sc->sc_bustag, sc->sc_h2, GEM_SBUS_RESET);
	delay(100);
	bus_space_write_4(sc->sc_bustag, sc->sc_h2, GEM_SBUS_CONFIG,
	    GEM_SBUS_CFG_BSIZE32);

	/* Establish interrupt handler */
	gsc->gsc_ih.ih_fun = gem_intr;
	gsc->gsc_ih.ih_arg = sc;
	intr_establish(ca->ca_ra.ra_intr[0].int_pri, &gsc->gsc_ih,
	    IPL_NET, self->dv_xname);

	gem_config(sc);
}
Esempio n. 3
0
void
gem_attach_pci(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct gem_pci_softc *gsc = (void *)self;
	struct gem_softc *sc = &gsc->gsc_gem;
	pci_intr_handle_t ih;
#ifdef __sparc64__
	/* XXX the following declarations should be elsewhere */
	extern void myetheraddr(u_char *);
#endif
	const char *intrstr = NULL;
	int type, gotenaddr = 0;

	gsc->gsc_pc = pa->pa_pc;

	if (pa->pa_memt) {
		type = PCI_MAPREG_TYPE_MEM;
		sc->sc_bustag = pa->pa_memt;
	} else {
		type = PCI_MAPREG_TYPE_IO;
		sc->sc_bustag = pa->pa_iot;
	}

	sc->sc_dmatag = pa->pa_dmat;

	sc->sc_pci = 1; /* XXXXX should all be done in bus_dma. */

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_SUN_GEMNETWORK:
		sc->sc_variant = GEM_SUN_GEM;
		break;
	case PCI_PRODUCT_SUN_ERINETWORK:
		sc->sc_variant = GEM_SUN_ERI;
		break;
	case PCI_PRODUCT_APPLE_K2_GMAC:
		sc->sc_variant = GEM_APPLE_K2_GMAC;
		break;
	default:
		sc->sc_variant = GEM_APPLE_GMAC;
	}

#define PCI_GEM_BASEADDR	0x10
	if (pci_mapreg_map(pa, PCI_GEM_BASEADDR, type, 0,
	    &gsc->gsc_memt, &gsc->gsc_memh, NULL, &gsc->gsc_memsize, 0) != 0) {
		printf(": can't map registers\n");
		return;
	}

	sc->sc_bustag = gsc->gsc_memt;
	sc->sc_h1 = gsc->gsc_memh;

	if (bus_space_subregion(sc->sc_bustag, sc->sc_h1,
	    GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE, &sc->sc_h2)) {
		printf(": unable to create bank 2 subregion\n");
		bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize);
		return;
	}

	if (gem_pci_enaddr(sc, pa) == 0)
		gotenaddr = 1;

#ifdef __sparc64__
	if (!gotenaddr) {
		if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
		    sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
			myetheraddr(sc->sc_arpcom.ac_enaddr);
		gotenaddr = 1;
	}
#endif
#ifdef __powerpc__
	if (!gotenaddr) {
		pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr);
		gotenaddr = 1;
	}
#endif

	sc->sc_burst = 16;	/* XXX */

	if (pci_intr_map(pa, &ih) != 0) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	gsc->gsc_ih = pci_intr_establish(pa->pa_pc,
	    ih, IPL_NET, gem_intr, sc, self->dv_xname);
	if (gsc->gsc_ih == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize);
		return;
	}

	printf(": %s", intrstr);

	/*
	 * call the main configure
	 */
	gem_config(sc);
}