Home | History | Annotate | Line # | Download | only in pci
if_ral_pci.c revision 1.2.8.2
      1 /*	$NetBSD: if_ral_pci.c,v 1.2.8.2 2005/11/10 14:06:01 skrll Exp $ */
      2 /*	$OpenBSD: if_ral_pci.c,v 1.4 2005/02/22 10:41:30 damien Exp $  */
      3 
      4 /*-
      5  * Copyright (c) 2005
      6  *	Damien Bergamini <damien.bergamini (at) free.fr>
      7  *
      8  * Permission to use, copy, modify, and distribute this software for any
      9  * purpose with or without fee is hereby granted, provided that the above
     10  * copyright notice and this permission notice appear in all copies.
     11  *
     12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     19  */
     20 
     21 /*
     22  * PCI front-end for the Ralink RT2500 driver.
     23  */
     24 
     25 #include <sys/cdefs.h>
     26 __KERNEL_RCSID(0, "$NetBSD: if_ral_pci.c,v 1.2.8.2 2005/11/10 14:06:01 skrll Exp $");
     27 
     28 #include "bpfilter.h"
     29 
     30 #include <sys/param.h>
     31 #include <sys/sockio.h>
     32 #include <sys/mbuf.h>
     33 #include <sys/kernel.h>
     34 #include <sys/socket.h>
     35 #include <sys/systm.h>
     36 #include <sys/malloc.h>
     37 #include <sys/device.h>
     38 
     39 #include <machine/bus.h>
     40 #include <machine/intr.h>
     41 
     42 #include <net/if.h>
     43 #include <net/if_dl.h>
     44 #include <net/if_ether.h>
     45 #include <net/if_media.h>
     46 
     47 #include <netinet/in.h>
     48 
     49 #include <net80211/ieee80211_var.h>
     50 #include <net80211/ieee80211_rssadapt.h>
     51 #include <net80211/ieee80211_radiotap.h>
     52 
     53 #include <dev/ic/ralvar.h>
     54 
     55 #include <dev/pci/pcireg.h>
     56 #include <dev/pci/pcivar.h>
     57 #include <dev/pci/pcidevs.h>
     58 
     59 struct ral_pci_softc {
     60 	struct ral_softc	sc_sc;
     61 
     62 	/* PCI specific goo */
     63 	pci_chipset_tag_t	sc_pc;
     64 	void			*sc_ih;
     65 	bus_size_t		sc_mapsize;
     66 };
     67 
     68 /* Base Address Register */
     69 #define RAL_PCI_BAR0	0x10
     70 
     71 int	ral_pci_match(struct device *, struct cfdata *, void *);
     72 void	ral_pci_attach(struct device *, struct device *, void *);
     73 int	ral_pci_detach(struct device *, int);
     74 
     75 CFATTACH_DECL(ral_pci, sizeof (struct ral_pci_softc),
     76 	ral_pci_match, ral_pci_attach, ral_pci_detach, NULL);
     77 
     78 int
     79 ral_pci_match(struct device *parent, struct cfdata *match, void *aux)
     80 {
     81 	struct pci_attach_args *pa = aux;
     82 
     83 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RALINK &&
     84 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RALINK_RT2560)
     85 		return 1;
     86 
     87 	return 0;
     88 }
     89 
     90 void
     91 ral_pci_attach(struct device *parent, struct device *self, void *aux)
     92 {
     93 	struct ral_pci_softc *psc = (struct ral_pci_softc *)self;
     94 	struct ral_softc *sc = &psc->sc_sc;
     95 	struct pci_attach_args *pa = aux;
     96 	const char *intrstr;
     97 	bus_addr_t base;
     98 	pci_intr_handle_t ih;
     99 	pcireg_t reg;
    100 	int error;
    101 
    102 	sc->sc_dmat = pa->pa_dmat;
    103 	psc->sc_pc = pa->pa_pc;
    104 
    105 	/* enable the appropriate bits in the PCI CSR */
    106 	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
    107 	reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
    108 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);
    109 
    110 	/* map control/status registers */
    111 	error = pci_mapreg_map(pa, RAL_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
    112 	    PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_st, &sc->sc_sh, &base,
    113 	    &psc->sc_mapsize);
    114 	if (error != 0) {
    115 		printf(": could not map memory space\n");
    116 		return;
    117 	}
    118 
    119 	if (pci_intr_map(pa, &ih) != 0) {
    120 		printf(": could not map interrupt\n");
    121 		return;
    122 	}
    123 
    124 	intrstr = pci_intr_string(psc->sc_pc, ih);
    125 	psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, ral_intr, sc);
    126 	if (psc->sc_ih == NULL) {
    127 		printf(": could not establish interrupt");
    128 		if (intrstr != NULL)
    129 			printf(" at %s", intrstr);
    130 		printf("\n");
    131 		return;
    132 	}
    133 	printf(": %s\n", intrstr);
    134 
    135 	ral_attach(sc);
    136 }
    137 
    138 int
    139 ral_pci_detach(struct device *self, int flags)
    140 {
    141 	struct ral_pci_softc *psc = (struct ral_pci_softc *)self;
    142 	struct ral_softc *sc = &psc->sc_sc;
    143 
    144 	ral_detach(sc);
    145 	pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
    146 
    147 	return 0;
    148 }
    149