/* $NetBSD: if_fxp_cardbus.c,v 1.5 1999/12/12 17:46:37 thorpej Exp $ */ /* * Copyright (c) 1999 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to * The NetBSD Foundation by Johan Danielsson. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "opt_inet.h" #include "opt_ns.h" #include "bpfilter.h" #include "rnd.h" #include #include #include #include #include #include #include #include #include #if NRND > 0 #include #endif #include #include #include #include #include #if NBPFILTER > 0 #include #endif #ifdef INET #include #include #endif #ifdef NS #include #include #endif #include #include #include #include #include #include #include #include #include #include static int fxp_cardbus_match __P((struct device *, struct cfdata *, void *)); static void fxp_cardbus_attach __P((struct device *, struct device *, void *)); static void fxp_cardbus_setup __P((struct fxp_softc *sc)); static int fxp_cardbus_enable __P((struct fxp_softc *sc)); static void fxp_cardbus_disable __P((struct fxp_softc *sc)); struct fxp_cardbus_softc { struct fxp_softc sc; cardbus_devfunc_t ct; pcireg_t base0_reg; pcireg_t base1_reg; bus_size_t size; }; struct cfattach fxp_cardbus_ca = { sizeof(struct fxp_cardbus_softc), fxp_cardbus_match, fxp_cardbus_attach }; #ifdef CBB_DEBUG #define DPRINTF(X) printf X #else #define DPRINTF(X) #endif static int fxp_cardbus_match(parent, match, aux) struct device *parent; struct cfdata *match; void *aux; { /* should check CIS */ struct cardbus_attach_args *ca = aux; if (CARDBUS_VENDOR(ca->ca_id) != CARDBUS_VENDOR_INTEL) return (0); switch (CARDBUS_PRODUCT(ca->ca_id)) { case CARDBUS_PRODUCT_INTEL_82557: return (1); } return (0); } static void fxp_cardbus_attach(parent, self, aux) struct device *parent, *self; void *aux; { struct fxp_softc *sc = (struct fxp_softc*)self; struct fxp_cardbus_softc *csc = (struct fxp_cardbus_softc*)self; struct cardbus_attach_args *ca = aux; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; bus_addr_t adr; bus_size_t size; csc->ct = ca->ca_ct; /* * Map control/status registers. */ if(Cardbus_mapreg_map(csc->ct, CARDBUS_BASE0_REG, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, &adr, &size) == 0) { csc->base0_reg = adr; sc->sc_st = memt; sc->sc_sh = memh; csc->size = size; } else if(Cardbus_mapreg_map(csc->ct, CARDBUS_BASE1_REG, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, &adr, &size) == 0) { csc->base1_reg = adr | 1; sc->sc_st = iot; sc->sc_sh = ioh; csc->size = size; } else panic("%s: failed to allocate mem and io space", __FUNCTION__); sc->sc_dmat = ca->ca_dmat; sc->sc_enable = fxp_cardbus_enable; sc->sc_disable = fxp_cardbus_disable; sc->sc_enabled = 0; fxp_enable(sc); fxp_attach(sc); fxp_disable(sc); } static void fxp_cardbus_setup(struct fxp_softc *sc) { struct fxp_cardbus_softc *csc = (struct fxp_cardbus_softc*)sc; struct cardbus_softc *psc = (struct cardbus_softc *)sc->sc_dev.dv_parent; cardbus_chipset_tag_t cc = psc->sc_cc; cardbus_function_tag_t cf = psc->sc_cf; pcireg_t command; cardbustag_t tag = cardbus_make_tag(cc, cf, csc->ct->ct_bus, csc->ct->ct_dev, csc->ct->ct_func); command = Cardbus_conf_read(csc->ct, tag, CARDBUS_COMMAND_STATUS_REG); if(csc->base0_reg) { Cardbus_conf_write(csc->ct, tag, CARDBUS_BASE0_REG, csc->base0_reg); (cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE); command |= CARDBUS_COMMAND_MEM_ENABLE | CARDBUS_COMMAND_MASTER_ENABLE; } else if(csc->base1_reg) { Cardbus_conf_write(csc->ct, tag, CARDBUS_BASE1_REG, csc->base1_reg); (cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE); command |= (CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MASTER_ENABLE); } /* enable the card */ Cardbus_conf_write(csc->ct, tag, CARDBUS_COMMAND_STATUS_REG, command); } static int fxp_cardbus_enable(struct fxp_softc *sc) { struct fxp_cardbus_softc *csc = (struct fxp_cardbus_softc*)sc; struct cardbus_softc *psc = (struct cardbus_softc *)sc->sc_dev.dv_parent; cardbus_chipset_tag_t cc = psc->sc_cc; cardbus_function_tag_t cf = psc->sc_cf; Cardbus_function_enable(csc->ct); fxp_cardbus_setup(sc); /* Map and establish the interrupt. */ sc->sc_ih = cardbus_intr_establish(cc, cf, psc->sc_intrline, IPL_NET, fxp_intr, sc); if (NULL == sc->sc_ih) { printf("%s: couldn't establish interrupt\n", sc->sc_dev.dv_xname); return 1; } printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname, psc->sc_intrline); return 0; } static void fxp_cardbus_disable(struct fxp_softc *sc) { struct cardbus_softc *psc = (struct cardbus_softc *)sc->sc_dev.dv_parent; cardbus_chipset_tag_t cc = psc->sc_cc; cardbus_function_tag_t cf = psc->sc_cf; cardbus_intr_disestablish(cc, cf, sc->sc_ih); /* remove intr handler */ Cardbus_function_disable(((struct fxp_cardbus_softc*)sc)->ct); }