1 /* $NetBSD: if_ral_pci.c,v 1.13 2009/08/08 20:44:36 matt Exp $ */
2 /* $OpenBSD: if_ral_pci.c,v 1.6 2006/01/09 20:03:43 damien Exp $ */
5 * Copyright (c) 2005, 2006
6 * Damien Bergamini <damien.bergamini@free.fr>
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.
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.
22 * PCI front-end for the Ralink RT2560/RT2561/RT2561S/RT2661 driver.
24 #include <sys/cdefs.h>
25 __KERNEL_RCSID(0, "$NetBSD: if_ral_pci.c,v 1.13 2009/08/08 20:44:36 matt Exp $");
29 #include <sys/param.h>
30 #include <sys/sockio.h>
32 #include <sys/kernel.h>
33 #include <sys/socket.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/device.h>
42 #include <net/if_dl.h>
43 #include <net/if_media.h>
44 #include <net/if_ether.h>
46 #include <netinet/in.h>
48 #include <net80211/ieee80211_var.h>
49 #include <net80211/ieee80211_amrr.h>
50 #include <net80211/ieee80211_rssadapt.h>
51 #include <net80211/ieee80211_radiotap.h>
53 #include <dev/ic/rt2560var.h>
54 #include <dev/ic/rt2661var.h>
56 #include <dev/pci/pcireg.h>
57 #include <dev/pci/pcivar.h>
58 #include <dev/pci/pcidevs.h>
60 static struct ral_opns
{
61 int (*attach
)(void *, int);
62 int (*detach
)(void *);
70 }, ral_rt2661_opns
= {
76 struct ral_pci_softc
{
78 struct rt2560_softc sc_rt2560
;
79 struct rt2661_softc sc_rt2661
;
81 #define sc_sc u.sc_rt2560
83 /* PCI specific goo */
84 struct ral_opns
*sc_opns
;
85 pci_chipset_tag_t sc_pc
;
87 bus_size_t sc_mapsize
;
90 /* Base Address Register */
91 #define RAL_PCI_BAR0 0x10
93 int ral_pci_match(device_t
, cfdata_t
, void *);
94 void ral_pci_attach(device_t
, device_t
, void *);
95 int ral_pci_detach(device_t
, int);
97 CFATTACH_DECL(ral_pci
, sizeof (struct ral_pci_softc
),
98 ral_pci_match
, ral_pci_attach
, ral_pci_detach
, NULL
);
101 ral_pci_match(device_t parent
, cfdata_t cfdata
,
104 struct pci_attach_args
*pa
= aux
;
106 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_RALINK
) {
107 switch (PCI_PRODUCT(pa
->pa_id
)) {
108 case PCI_PRODUCT_RALINK_RT2560
:
109 case PCI_PRODUCT_RALINK_RT2561
:
110 case PCI_PRODUCT_RALINK_RT2561S
:
111 case PCI_PRODUCT_RALINK_RT2661
:
122 ral_pci_attach(device_t parent
, device_t self
, void *aux
)
124 struct ral_pci_softc
*psc
= device_private(self
);
125 struct rt2560_softc
*sc
= &psc
->sc_sc
;
126 struct pci_attach_args
*pa
= aux
;
130 pci_intr_handle_t ih
;
134 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
135 revision
= PCI_REVISION(pa
->pa_class
);
136 aprint_normal(": %s (rev. 0x%02x)\n", devinfo
, revision
);
138 psc
->sc_opns
= (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_RALINK_RT2560
) ?
139 &ral_rt2560_opns
: &ral_rt2661_opns
;
141 sc
->sc_dmat
= pa
->pa_dmat
;
142 psc
->sc_pc
= pa
->pa_pc
;
144 /* enable the appropriate bits in the PCI CSR */
145 reg
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
146 reg
|= PCI_COMMAND_MASTER_ENABLE
| PCI_COMMAND_MEM_ENABLE
;
147 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
, reg
);
148 pa
->pa_flags
|= PCI_FLAGS_MEM_ENABLED
;
150 /* map control/status registers */
151 error
= pci_mapreg_map(pa
, RAL_PCI_BAR0
, PCI_MAPREG_TYPE_MEM
|
152 PCI_MAPREG_MEM_TYPE_32BIT
, 0, &sc
->sc_st
, &sc
->sc_sh
, &base
,
156 aprint_error(": could not map memory space\n");
160 if (pci_intr_map(pa
, &ih
) != 0) {
161 aprint_error(": could not map interrupt\n");
165 intrstr
= pci_intr_string(psc
->sc_pc
, ih
);
166 psc
->sc_ih
= pci_intr_establish(psc
->sc_pc
, ih
, IPL_NET
,
167 psc
->sc_opns
->intr
, sc
);
169 if (psc
->sc_ih
== NULL
) {
170 aprint_error(": could not establish interrupt");
172 aprint_error(" at %s", intrstr
);
176 aprint_normal_dev(&sc
->sc_dev
, "interrupting at %s\n", intrstr
);
178 (*psc
->sc_opns
->attach
)(sc
, PCI_PRODUCT(pa
->pa_id
));
182 ral_pci_detach(device_t self
, int flags
)
184 struct ral_pci_softc
*psc
= device_private(self
);
185 struct rt2560_softc
*sc
= &psc
->sc_sc
;
187 (*psc
->sc_opns
->detach
)(sc
);
188 pci_intr_disestablish(psc
->sc_pc
, psc
->sc_ih
);