root/dev/cardbus/if_malo_cardbus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. malo_cardbus_match
  2. malo_cardbus_attach
  3. malo_cardbus_detach
  4. malo_cardbus_setup
  5. malo_cardbus_enable
  6. malo_cardbus_disable

    1 /*      $OpenBSD: if_malo_cardbus.c,v 1.5 2006/11/29 10:37:11 mglocker Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include "bpfilter.h"
   20 
   21 #include <sys/param.h>
   22 #include <sys/mbuf.h>
   23 #include <sys/socket.h>
   24 #include <sys/systm.h>
   25 #include <sys/timeout.h>
   26 
   27 #include <net/if.h>
   28 #include <net/if_media.h>
   29 
   30 #include <netinet/in.h>
   31 #include <netinet/if_ether.h>
   32 
   33 #include <net80211/ieee80211_var.h>
   34 #include <net80211/ieee80211_radiotap.h>
   35 
   36 #include <dev/pci/pcireg.h>
   37 #include <dev/pci/pcivar.h>
   38 #include <dev/pci/pcidevs.h>
   39 
   40 #include <dev/cardbus/cardbusvar.h>
   41 
   42 #include <dev/ic/malo.h>
   43 
   44 struct malo_cardbus_softc {
   45         struct malo_softc       sc_malo;
   46 
   47         /* cardbus specific goo */
   48         cardbus_devfunc_t       sc_ct;
   49         cardbustag_t            sc_tag;
   50         void                    *sc_ih;
   51 
   52         bus_size_t              sc_mapsize1;
   53         bus_size_t              sc_mapsize2;
   54         pcireg_t                sc_bar1_val;
   55         pcireg_t                sc_bar2_val;
   56         int                     sc_intrline;
   57 };
   58 
   59 int     malo_cardbus_match(struct device *parent, void *match, void *aux);
   60 void    malo_cardbus_attach(struct device *parent, struct device *self,
   61             void *aux);
   62 int     malo_cardbus_detach(struct device *self, int flags);
   63 void    malo_cardbus_setup(struct malo_cardbus_softc *csc);
   64 int     malo_cardbus_enable(struct malo_softc *sc);
   65 void    malo_cardbus_disable(struct malo_softc *sc);
   66 
   67 struct cfattach malo_cardbus_ca = {
   68         sizeof (struct malo_cardbus_softc), malo_cardbus_match,
   69         malo_cardbus_attach, malo_cardbus_detach
   70 };
   71 
   72 static const struct cardbus_matchid malo_cardbus_devices[] = {
   73         { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88W8310 },
   74         { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88W8335_1 },
   75         { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88W8335_2 }
   76 };
   77 
   78 int
   79 malo_cardbus_match(struct device *parent, void *match, void *aux)
   80 {
   81         return (cardbus_matchbyid(aux, malo_cardbus_devices,
   82             sizeof (malo_cardbus_devices) / sizeof (malo_cardbus_devices[0])));
   83 }
   84 
   85 void
   86 malo_cardbus_attach(struct device *parent, struct device *self, void *aux)
   87 {
   88         struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)self;
   89         struct cardbus_attach_args *ca = aux;
   90         struct malo_softc *sc = &csc->sc_malo;
   91         cardbus_devfunc_t ct = ca->ca_ct;
   92         bus_addr_t base;
   93         int error;
   94 
   95         sc->sc_dmat = ca->ca_dmat;
   96         csc->sc_ct = ct;
   97         csc->sc_tag = ca->ca_tag;
   98         csc->sc_intrline = ca->ca_intrline;
   99 
  100         /* power management hooks */
  101         sc->sc_enable = malo_cardbus_enable;
  102         sc->sc_disable = malo_cardbus_disable;
  103 #if 0
  104         sc->sc_power = malo_cardbus_power;
  105 #endif
  106 
  107         /* map control/status registers */
  108         error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
  109             CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_mem1_bt,
  110             &sc->sc_mem1_bh, &base, &csc->sc_mapsize1);
  111         if (error != 0) {
  112                 printf(": could not map 1st memory space\n");
  113                 return;
  114         }
  115         csc->sc_bar1_val = base | CARDBUS_MAPREG_TYPE_MEM;
  116 
  117         /* map control/status registers */
  118         error = Cardbus_mapreg_map(ct, CARDBUS_BASE1_REG,
  119             CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_mem2_bt,
  120             &sc->sc_mem2_bh, &base, &csc->sc_mapsize2);
  121         if (error != 0) {
  122                 printf(": could not map 2nd memory space\n");
  123                 Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_mem1_bt,
  124                     sc->sc_mem1_bh, csc->sc_mapsize1);
  125                 return;
  126         }
  127         csc->sc_bar2_val = base | CARDBUS_MAPREG_TYPE_MEM;
  128 
  129         /* set up the PCI configuration registers */
  130         malo_cardbus_setup(csc);
  131 
  132         printf(": irq %d", csc->sc_intrline);
  133 
  134         error = malo_attach(sc);
  135         if (error != 0)
  136                 malo_cardbus_detach(&sc->sc_dev, 0);
  137 
  138         Cardbus_function_disable(ct);
  139 }
  140 
  141 int
  142 malo_cardbus_detach(struct device *self, int flags)
  143 {
  144         struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)self;
  145         struct malo_softc *sc = &csc->sc_malo;
  146         cardbus_devfunc_t ct = csc->sc_ct;
  147         cardbus_chipset_tag_t cc = ct->ct_cc;
  148         cardbus_function_tag_t cf = ct->ct_cf;
  149         int error;
  150 
  151         error = malo_detach(sc);
  152         if (error != 0)
  153                 return (error);
  154 
  155         /* unhook the interrupt handler */
  156         if (csc->sc_ih != NULL) {
  157                 cardbus_intr_disestablish(cc, cf, csc->sc_ih);
  158                 csc->sc_ih = NULL;
  159         }
  160 
  161         /* release bus space and close window */
  162         Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_mem1_bt,
  163             sc->sc_mem1_bh, csc->sc_mapsize1);
  164         Cardbus_mapreg_unmap(ct, CARDBUS_BASE1_REG, sc->sc_mem2_bt,
  165             sc->sc_mem2_bh, csc->sc_mapsize2);
  166 
  167         return (0);
  168 }
  169 
  170 void
  171 malo_cardbus_setup(struct malo_cardbus_softc *csc)
  172 {
  173         cardbus_devfunc_t ct = csc->sc_ct;
  174         cardbus_chipset_tag_t cc = ct->ct_cc;
  175         cardbus_function_tag_t cf = ct->ct_cf;
  176         pcireg_t reg;
  177 
  178         /* program the BAR */
  179         cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BASE0_REG,
  180             csc->sc_bar1_val);
  181         cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BASE1_REG,
  182             csc->sc_bar2_val);
  183 
  184         /* make sure the right access type is on the cardbus bridge */
  185         (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
  186         (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
  187 
  188         /* enable the appropriate bits in the PCI CSR */
  189         reg = cardbus_conf_read(cc, cf, csc->sc_tag,
  190             CARDBUS_COMMAND_STATUS_REG);
  191         reg |= CARDBUS_COMMAND_MASTER_ENABLE | CARDBUS_COMMAND_MEM_ENABLE;
  192         cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG,
  193             reg);
  194 }
  195 
  196 int
  197 malo_cardbus_enable(struct malo_softc *sc)
  198 {
  199         struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)sc;
  200         cardbus_devfunc_t ct = csc->sc_ct;
  201         cardbus_chipset_tag_t cc = ct->ct_cc;
  202         cardbus_function_tag_t cf = ct->ct_cf;
  203 
  204         /* power on the socket */
  205         Cardbus_function_enable(ct);
  206 
  207         /* setup the PCI configuration registers */
  208         malo_cardbus_setup(csc);
  209 
  210         /* map and establish the interrupt handler */
  211         csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
  212             malo_intr, sc, sc->sc_dev.dv_xname);
  213         if (csc->sc_ih == NULL) {
  214                 printf("%s: could not establish interrupt at %d\n",
  215                     sc->sc_dev.dv_xname, csc->sc_intrline);
  216                 Cardbus_function_disable(ct);
  217                 return (1);
  218         }
  219 
  220         return (0);
  221 }
  222 
  223 void
  224 malo_cardbus_disable(struct malo_softc *sc)
  225 {
  226         struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)sc;
  227         cardbus_devfunc_t ct = csc->sc_ct;
  228         cardbus_chipset_tag_t cc = ct->ct_cc;
  229         cardbus_function_tag_t cf = ct->ct_cf;
  230 
  231         /* unhook the interrupt handler */
  232         cardbus_intr_disestablish(cc, cf, csc->sc_ih);
  233         csc->sc_ih = NULL;
  234 
  235         /* power down the socket */
  236         Cardbus_function_disable(ct);
  237 }

/* [<][>][^][v][top][bottom][index][help] */