if_ral_cardbus.c revision 1.2.8.2 1 1.2.8.2 skrll /* $NetBSD: if_ral_cardbus.c,v 1.2.8.2 2005/11/10 14:03:54 skrll Exp $ */
2 1.2.8.2 skrll /* $OpenBSD: if_ral_cardbus.c,v 1.5 2005/05/16 01:36:25 brad Exp $ */
3 1.2.8.2 skrll
4 1.2.8.2 skrll /*-
5 1.2.8.2 skrll * Copyright (c) 2005
6 1.2.8.2 skrll * Damien Bergamini <damien.bergamini (at) free.fr>
7 1.2.8.2 skrll *
8 1.2.8.2 skrll * Permission to use, copy, modify, and distribute this software for any
9 1.2.8.2 skrll * purpose with or without fee is hereby granted, provided that the above
10 1.2.8.2 skrll * copyright notice and this permission notice appear in all copies.
11 1.2.8.2 skrll *
12 1.2.8.2 skrll * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 1.2.8.2 skrll * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 1.2.8.2 skrll * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 1.2.8.2 skrll * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 1.2.8.2 skrll * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 1.2.8.2 skrll * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 1.2.8.2 skrll * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 1.2.8.2 skrll */
20 1.2.8.2 skrll
21 1.2.8.2 skrll /*
22 1.2.8.2 skrll * CardBus front-end for the Ralink RT2500 driver.
23 1.2.8.2 skrll */
24 1.2.8.2 skrll
25 1.2.8.2 skrll #include <sys/cdefs.h>
26 1.2.8.2 skrll __KERNEL_RCSID(0, "$NetBSD: if_ral_cardbus.c,v 1.2.8.2 2005/11/10 14:03:54 skrll Exp $");
27 1.2.8.2 skrll
28 1.2.8.2 skrll #include "bpfilter.h"
29 1.2.8.2 skrll
30 1.2.8.2 skrll #include <sys/param.h>
31 1.2.8.2 skrll #include <sys/sockio.h>
32 1.2.8.2 skrll #include <sys/mbuf.h>
33 1.2.8.2 skrll #include <sys/kernel.h>
34 1.2.8.2 skrll #include <sys/socket.h>
35 1.2.8.2 skrll #include <sys/systm.h>
36 1.2.8.2 skrll #include <sys/malloc.h>
37 1.2.8.2 skrll #include <sys/device.h>
38 1.2.8.2 skrll
39 1.2.8.2 skrll #include <machine/bus.h>
40 1.2.8.2 skrll #include <machine/intr.h>
41 1.2.8.2 skrll
42 1.2.8.2 skrll #include <net/if.h>
43 1.2.8.2 skrll #include <net/if_dl.h>
44 1.2.8.2 skrll #include <net/if_ether.h>
45 1.2.8.2 skrll #include <net/if_media.h>
46 1.2.8.2 skrll
47 1.2.8.2 skrll #include <netinet/in.h>
48 1.2.8.2 skrll
49 1.2.8.2 skrll #include <net80211/ieee80211_var.h>
50 1.2.8.2 skrll #include <net80211/ieee80211_rssadapt.h>
51 1.2.8.2 skrll #include <net80211/ieee80211_radiotap.h>
52 1.2.8.2 skrll
53 1.2.8.2 skrll #include <dev/ic/ralvar.h>
54 1.2.8.2 skrll
55 1.2.8.2 skrll #include <dev/pci/pcireg.h>
56 1.2.8.2 skrll #include <dev/pci/pcivar.h>
57 1.2.8.2 skrll #include <dev/pci/pcidevs.h>
58 1.2.8.2 skrll
59 1.2.8.2 skrll #include <dev/cardbus/cardbusvar.h>
60 1.2.8.2 skrll
61 1.2.8.2 skrll struct ral_cardbus_softc {
62 1.2.8.2 skrll struct ral_softc sc_sc;
63 1.2.8.2 skrll
64 1.2.8.2 skrll /* cardbus specific goo */
65 1.2.8.2 skrll cardbus_devfunc_t sc_ct;
66 1.2.8.2 skrll cardbustag_t sc_tag;
67 1.2.8.2 skrll void *sc_ih;
68 1.2.8.2 skrll bus_size_t sc_mapsize;
69 1.2.8.2 skrll pcireg_t sc_bar_val;
70 1.2.8.2 skrll int sc_intrline;
71 1.2.8.2 skrll };
72 1.2.8.2 skrll
73 1.2.8.2 skrll int ral_cardbus_match(struct device *, struct cfdata *, void *);
74 1.2.8.2 skrll void ral_cardbus_attach(struct device *, struct device *, void *);
75 1.2.8.2 skrll int ral_cardbus_detach(struct device *, int);
76 1.2.8.2 skrll
77 1.2.8.2 skrll CFATTACH_DECL(ral_cardbus, sizeof (struct ral_cardbus_softc),
78 1.2.8.2 skrll ral_cardbus_match, ral_cardbus_attach, ral_cardbus_detach, NULL);
79 1.2.8.2 skrll
80 1.2.8.2 skrll int ral_cardbus_enable(struct ral_softc *);
81 1.2.8.2 skrll void ral_cardbus_disable(struct ral_softc *);
82 1.2.8.2 skrll void ral_cardbus_power(struct ral_softc *, int);
83 1.2.8.2 skrll void ral_cardbus_setup(struct ral_cardbus_softc *);
84 1.2.8.2 skrll
85 1.2.8.2 skrll int
86 1.2.8.2 skrll ral_cardbus_match(struct device *parent, struct cfdata *match, void *aux)
87 1.2.8.2 skrll {
88 1.2.8.2 skrll struct cardbus_attach_args *ca = aux;
89 1.2.8.2 skrll
90 1.2.8.2 skrll if (CARDBUS_VENDOR(ca->ca_id) == PCI_VENDOR_RALINK &&
91 1.2.8.2 skrll CARDBUS_PRODUCT(ca->ca_id) == PCI_PRODUCT_RALINK_RT2560)
92 1.2.8.2 skrll return 1;
93 1.2.8.2 skrll
94 1.2.8.2 skrll return 0;
95 1.2.8.2 skrll }
96 1.2.8.2 skrll
97 1.2.8.2 skrll void
98 1.2.8.2 skrll ral_cardbus_attach(struct device *parent, struct device *self, void *aux)
99 1.2.8.2 skrll {
100 1.2.8.2 skrll struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
101 1.2.8.2 skrll struct ral_softc *sc = &csc->sc_sc;
102 1.2.8.2 skrll struct cardbus_attach_args *ca = aux;
103 1.2.8.2 skrll cardbus_devfunc_t ct = ca->ca_ct;
104 1.2.8.2 skrll bus_addr_t base;
105 1.2.8.2 skrll int error;
106 1.2.8.2 skrll
107 1.2.8.2 skrll sc->sc_dmat = ca->ca_dmat;
108 1.2.8.2 skrll csc->sc_ct = ct;
109 1.2.8.2 skrll csc->sc_tag = ca->ca_tag;
110 1.2.8.2 skrll csc->sc_intrline = ca->ca_intrline;
111 1.2.8.2 skrll
112 1.2.8.2 skrll /* power management hooks */
113 1.2.8.2 skrll sc->sc_enable = ral_cardbus_enable;
114 1.2.8.2 skrll sc->sc_disable = ral_cardbus_disable;
115 1.2.8.2 skrll sc->sc_power = ral_cardbus_power;
116 1.2.8.2 skrll
117 1.2.8.2 skrll /* map control/status registers */
118 1.2.8.2 skrll error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
119 1.2.8.2 skrll CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base,
120 1.2.8.2 skrll &csc->sc_mapsize);
121 1.2.8.2 skrll if (error != 0) {
122 1.2.8.2 skrll printf(": could not map memory space\n");
123 1.2.8.2 skrll return;
124 1.2.8.2 skrll }
125 1.2.8.2 skrll
126 1.2.8.2 skrll #if rbus
127 1.2.8.2 skrll #else
128 1.2.8.2 skrll (*cf->cardbus_mem_open)(cc, 0, base, base + csc->sc_mapsize);
129 1.2.8.2 skrll #endif
130 1.2.8.2 skrll
131 1.2.8.2 skrll csc->sc_bar_val = base | CARDBUS_MAPREG_TYPE_MEM;
132 1.2.8.2 skrll
133 1.2.8.2 skrll /* set up the PCI configuration registers */
134 1.2.8.2 skrll ral_cardbus_setup(csc);
135 1.2.8.2 skrll
136 1.2.8.2 skrll printf(": irq %d\n", csc->sc_intrline);
137 1.2.8.2 skrll
138 1.2.8.2 skrll ral_attach(sc);
139 1.2.8.2 skrll
140 1.2.8.2 skrll Cardbus_function_disable(ct);
141 1.2.8.2 skrll }
142 1.2.8.2 skrll
143 1.2.8.2 skrll int
144 1.2.8.2 skrll ral_cardbus_detach(struct device *self, int flags)
145 1.2.8.2 skrll {
146 1.2.8.2 skrll struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
147 1.2.8.2 skrll struct ral_softc *sc = &csc->sc_sc;
148 1.2.8.2 skrll cardbus_devfunc_t ct = csc->sc_ct;
149 1.2.8.2 skrll cardbus_chipset_tag_t cc = ct->ct_cc;
150 1.2.8.2 skrll cardbus_function_tag_t cf = ct->ct_cf;
151 1.2.8.2 skrll int error;
152 1.2.8.2 skrll
153 1.2.8.2 skrll error = ral_detach(sc);
154 1.2.8.2 skrll if (error != 0)
155 1.2.8.2 skrll return error;
156 1.2.8.2 skrll
157 1.2.8.2 skrll /* unhook the interrupt handler */
158 1.2.8.2 skrll if (csc->sc_ih != NULL) {
159 1.2.8.2 skrll cardbus_intr_disestablish(cc, cf, csc->sc_ih);
160 1.2.8.2 skrll csc->sc_ih = NULL;
161 1.2.8.2 skrll }
162 1.2.8.2 skrll
163 1.2.8.2 skrll /* release bus space and close window */
164 1.2.8.2 skrll Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_st, sc->sc_sh,
165 1.2.8.2 skrll csc->sc_mapsize);
166 1.2.8.2 skrll
167 1.2.8.2 skrll return 0;
168 1.2.8.2 skrll }
169 1.2.8.2 skrll
170 1.2.8.2 skrll int
171 1.2.8.2 skrll ral_cardbus_enable(struct ral_softc *sc)
172 1.2.8.2 skrll {
173 1.2.8.2 skrll struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
174 1.2.8.2 skrll cardbus_devfunc_t ct = csc->sc_ct;
175 1.2.8.2 skrll cardbus_chipset_tag_t cc = ct->ct_cc;
176 1.2.8.2 skrll cardbus_function_tag_t cf = ct->ct_cf;
177 1.2.8.2 skrll
178 1.2.8.2 skrll /* power on the socket */
179 1.2.8.2 skrll Cardbus_function_enable(ct);
180 1.2.8.2 skrll
181 1.2.8.2 skrll /* setup the PCI configuration registers */
182 1.2.8.2 skrll ral_cardbus_setup(csc);
183 1.2.8.2 skrll
184 1.2.8.2 skrll /* map and establish the interrupt handler */
185 1.2.8.2 skrll csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
186 1.2.8.2 skrll ral_intr, sc);
187 1.2.8.2 skrll if (csc->sc_ih == NULL) {
188 1.2.8.2 skrll printf("%s: could not establish interrupt at %d\n",
189 1.2.8.2 skrll sc->sc_dev.dv_xname, csc->sc_intrline);
190 1.2.8.2 skrll Cardbus_function_disable(ct);
191 1.2.8.2 skrll return 1;
192 1.2.8.2 skrll }
193 1.2.8.2 skrll
194 1.2.8.2 skrll return 0;
195 1.2.8.2 skrll }
196 1.2.8.2 skrll
197 1.2.8.2 skrll void
198 1.2.8.2 skrll ral_cardbus_disable(struct ral_softc *sc)
199 1.2.8.2 skrll {
200 1.2.8.2 skrll struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
201 1.2.8.2 skrll cardbus_devfunc_t ct = csc->sc_ct;
202 1.2.8.2 skrll cardbus_chipset_tag_t cc = ct->ct_cc;
203 1.2.8.2 skrll cardbus_function_tag_t cf = ct->ct_cf;
204 1.2.8.2 skrll
205 1.2.8.2 skrll /* unhook the interrupt handler */
206 1.2.8.2 skrll cardbus_intr_disestablish(cc, cf, csc->sc_ih);
207 1.2.8.2 skrll csc->sc_ih = NULL;
208 1.2.8.2 skrll
209 1.2.8.2 skrll /* power down the socket */
210 1.2.8.2 skrll Cardbus_function_disable(ct);
211 1.2.8.2 skrll }
212 1.2.8.2 skrll
213 1.2.8.2 skrll void
214 1.2.8.2 skrll ral_cardbus_power(struct ral_softc *sc, int why)
215 1.2.8.2 skrll {
216 1.2.8.2 skrll struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
217 1.2.8.2 skrll
218 1.2.8.2 skrll if (why == PWR_RESUME) {
219 1.2.8.2 skrll /* kick the PCI configuration registers */
220 1.2.8.2 skrll ral_cardbus_setup(csc);
221 1.2.8.2 skrll }
222 1.2.8.2 skrll }
223 1.2.8.2 skrll
224 1.2.8.2 skrll void
225 1.2.8.2 skrll ral_cardbus_setup(struct ral_cardbus_softc *csc)
226 1.2.8.2 skrll {
227 1.2.8.2 skrll cardbus_devfunc_t ct = csc->sc_ct;
228 1.2.8.2 skrll cardbus_chipset_tag_t cc = ct->ct_cc;
229 1.2.8.2 skrll cardbus_function_tag_t cf = ct->ct_cf;
230 1.2.8.2 skrll pcireg_t reg;
231 1.2.8.2 skrll
232 1.2.8.2 skrll /* program the BAR */
233 1.2.8.2 skrll cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BASE0_REG,
234 1.2.8.2 skrll csc->sc_bar_val);
235 1.2.8.2 skrll
236 1.2.8.2 skrll /* make sure the right access type is on the cardbus bridge */
237 1.2.8.2 skrll (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
238 1.2.8.2 skrll (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
239 1.2.8.2 skrll
240 1.2.8.2 skrll /* enable the appropriate bits in the PCI CSR */
241 1.2.8.2 skrll reg = cardbus_conf_read(cc, cf, csc->sc_tag,
242 1.2.8.2 skrll CARDBUS_COMMAND_STATUS_REG);
243 1.2.8.2 skrll reg |= CARDBUS_COMMAND_MASTER_ENABLE | CARDBUS_COMMAND_MEM_ENABLE;
244 1.2.8.2 skrll cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG,
245 1.2.8.2 skrll reg);
246 1.2.8.2 skrll }
247