1 /* $OpenBSD: if_ral_cardbus.c,v 1.24 2024/05/24 06:26:47 jsg Exp $ */
2
3 /*-
4 * Copyright (c) 2005-2010 Damien Bergamini <damien.bergamini@free.fr>
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 /*
20 * CardBus front-end for the Ralink RT2560/RT2561/RT2860/RT3090 driver.
21 */
22
23 #include "bpfilter.h"
24
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/timeout.h>
28 #include <sys/device.h>
29
30 #include <machine/bus.h>
31 #include <machine/intr.h>
32
33 #include <net/if.h>
34 #include <net/if_media.h>
35
36 #include <netinet/in.h>
37 #include <netinet/if_ether.h>
38
39 #include <net80211/ieee80211_var.h>
40 #include <net80211/ieee80211_amrr.h>
41 #include <net80211/ieee80211_radiotap.h>
42
43 #include <dev/ic/rt2560var.h>
44 #include <dev/ic/rt2661var.h>
45 #include <dev/ic/rt2860var.h>
46
47 #include <dev/pci/pcireg.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/pci/pcidevs.h>
50
51 #include <dev/cardbus/cardbusvar.h>
52
53 static struct ral_opns {
54 int (*attach)(void *, int);
55 int (*detach)(void *);
56 void (*suspend)(void *);
57 void (*resume)(void *);
58 int (*intr)(void *);
59
60 } ral_rt2560_opns = {
61 rt2560_attach,
62 rt2560_detach,
63 rt2560_suspend,
64 rt2560_wakeup,
65 rt2560_intr
66
67 }, ral_rt2661_opns = {
68 rt2661_attach,
69 rt2661_detach,
70 rt2661_suspend,
71 rt2661_wakeup,
72 rt2661_intr
73
74 }, ral_rt2860_opns = {
75 rt2860_attach,
76 rt2860_detach,
77 rt2860_suspend,
78 rt2860_wakeup,
79 rt2860_intr
80 };
81
82 struct ral_cardbus_softc {
83 union {
84 struct rt2560_softc sc_rt2560;
85 struct rt2661_softc sc_rt2661;
86 struct rt2860_softc sc_rt2860;
87 } u;
88 #define sc_sc u.sc_rt2560
89
90 /* cardbus specific goo */
91 struct ral_opns *sc_opns;
92 cardbus_devfunc_t sc_ct;
93 pcitag_t sc_tag;
94 void *sc_ih;
95 bus_size_t sc_mapsize;
96 pcireg_t sc_bar_val;
97 int sc_intrline;
98 pci_chipset_tag_t sc_pc;
99 };
100
101 int ral_cardbus_match(struct device *, void *, void *);
102 void ral_cardbus_attach(struct device *, struct device *, void *);
103 int ral_cardbus_detach(struct device *, int);
104 int ral_cardbus_activate(struct device *, int);
105
106 const struct cfattach ral_cardbus_ca = {
107 sizeof (struct ral_cardbus_softc), ral_cardbus_match,
108 ral_cardbus_attach, ral_cardbus_detach,
109 ral_cardbus_activate
110 };
111
112 static const struct pci_matchid ral_cardbus_devices[] = {
113 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2560 },
114 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2561 },
115 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2561S },
116 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2661 },
117 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2860 },
118 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2890 },
119 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2760 },
120 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2790 },
121 { PCI_VENDOR_AWT, PCI_PRODUCT_AWT_RT2890 },
122 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_1 },
123 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_2 },
124 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_3 },
125 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_4 },
126 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_5 },
127 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_6 },
128 { PCI_VENDOR_EDIMAX, PCI_PRODUCT_EDIMAX_RT2860_7 },
129 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3062 },
130 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3090 },
131 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3091 },
132 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3092 },
133 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3562 },
134 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3592 },
135 { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT3593 }
136 };
137
138 int ral_cardbus_enable(struct rt2560_softc *);
139 void ral_cardbus_disable(struct rt2560_softc *);
140 void ral_cardbus_setup(struct ral_cardbus_softc *);
141 void ral_cardbus_wakeup(struct ral_cardbus_softc *);
142
143 int
ral_cardbus_match(struct device * parent,void * match,void * aux)144 ral_cardbus_match(struct device *parent, void *match, void *aux)
145 {
146 return (cardbus_matchbyid((struct cardbus_attach_args *)aux,
147 ral_cardbus_devices, nitems(ral_cardbus_devices)));
148 }
149
150 void
ral_cardbus_attach(struct device * parent,struct device * self,void * aux)151 ral_cardbus_attach(struct device *parent, struct device *self, void *aux)
152 {
153 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
154 struct rt2560_softc *sc = &csc->sc_sc;
155 struct cardbus_attach_args *ca = aux;
156 cardbus_devfunc_t ct = ca->ca_ct;
157 bus_addr_t base;
158 int error;
159
160 if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_RALINK) {
161 switch (PCI_PRODUCT(ca->ca_id)) {
162 case PCI_PRODUCT_RALINK_RT2560:
163 csc->sc_opns = &ral_rt2560_opns;
164 break;
165 case PCI_PRODUCT_RALINK_RT2561:
166 case PCI_PRODUCT_RALINK_RT2561S:
167 case PCI_PRODUCT_RALINK_RT2661:
168 csc->sc_opns = &ral_rt2661_opns;
169 break;
170 default:
171 csc->sc_opns = &ral_rt2860_opns;
172 break;
173 }
174 } else {
175 /* all other vendors are RT2860 only */
176 csc->sc_opns = &ral_rt2860_opns;
177 }
178 sc->sc_dmat = ca->ca_dmat;
179 csc->sc_ct = ct;
180 csc->sc_tag = ca->ca_tag;
181 csc->sc_intrline = ca->ca_intrline;
182 csc->sc_pc = ca->ca_pc;
183
184 /* power management hooks */
185 sc->sc_enable = ral_cardbus_enable;
186 sc->sc_disable = ral_cardbus_disable;
187
188 /* map control/status registers */
189 error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
190 PCI_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base,
191 &csc->sc_mapsize);
192 if (error != 0) {
193 printf(": can't map mem space\n");
194 return;
195 }
196
197 csc->sc_bar_val = base | PCI_MAPREG_TYPE_MEM;
198
199 /* set up the PCI configuration registers */
200 ral_cardbus_setup(csc);
201
202 printf(": irq %d", csc->sc_intrline);
203
204 (*csc->sc_opns->attach)(sc, PCI_PRODUCT(ca->ca_id));
205
206 Cardbus_function_disable(ct);
207 }
208
209 int
ral_cardbus_detach(struct device * self,int flags)210 ral_cardbus_detach(struct device *self, int flags)
211 {
212 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
213 struct rt2560_softc *sc = &csc->sc_sc;
214 cardbus_devfunc_t ct = csc->sc_ct;
215 cardbus_chipset_tag_t cc = ct->ct_cc;
216 cardbus_function_tag_t cf = ct->ct_cf;
217 int error;
218
219 error = (*csc->sc_opns->detach)(sc);
220 if (error != 0)
221 return error;
222
223 /* unhook the interrupt handler */
224 if (csc->sc_ih != NULL) {
225 cardbus_intr_disestablish(cc, cf, csc->sc_ih);
226 csc->sc_ih = NULL;
227 }
228
229 /* release bus space and close window */
230 Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_st, sc->sc_sh,
231 csc->sc_mapsize);
232
233 return 0;
234 }
235
236 int
ral_cardbus_activate(struct device * self,int act)237 ral_cardbus_activate(struct device *self, int act)
238 {
239 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
240 struct rt2560_softc *sc = &csc->sc_sc;
241
242 switch (act) {
243 case DVACT_SUSPEND:
244 (*csc->sc_opns->suspend)(sc);
245 break;
246 case DVACT_WAKEUP:
247 ral_cardbus_wakeup(csc);
248 break;
249 }
250
251 return 0;
252 }
253
254 int
ral_cardbus_enable(struct rt2560_softc * sc)255 ral_cardbus_enable(struct rt2560_softc *sc)
256 {
257 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
258 cardbus_devfunc_t ct = csc->sc_ct;
259 cardbus_chipset_tag_t cc = ct->ct_cc;
260 cardbus_function_tag_t cf = ct->ct_cf;
261
262 /* power on the socket */
263 Cardbus_function_enable(ct);
264
265 /* setup the PCI configuration registers */
266 ral_cardbus_setup(csc);
267
268 /* map and establish the interrupt handler */
269 csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
270 csc->sc_opns->intr, sc, sc->sc_dev.dv_xname);
271 if (csc->sc_ih == NULL) {
272 printf("%s: could not establish interrupt at %d\n",
273 sc->sc_dev.dv_xname, csc->sc_intrline);
274 Cardbus_function_disable(ct);
275 return 1;
276 }
277
278 return 0;
279 }
280
281 void
ral_cardbus_disable(struct rt2560_softc * sc)282 ral_cardbus_disable(struct rt2560_softc *sc)
283 {
284 struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)sc;
285 cardbus_devfunc_t ct = csc->sc_ct;
286 cardbus_chipset_tag_t cc = ct->ct_cc;
287 cardbus_function_tag_t cf = ct->ct_cf;
288
289 /* unhook the interrupt handler */
290 cardbus_intr_disestablish(cc, cf, csc->sc_ih);
291 csc->sc_ih = NULL;
292
293 /* power down the socket */
294 Cardbus_function_disable(ct);
295 }
296
297 void
ral_cardbus_setup(struct ral_cardbus_softc * csc)298 ral_cardbus_setup(struct ral_cardbus_softc *csc)
299 {
300 cardbus_devfunc_t ct = csc->sc_ct;
301 cardbus_chipset_tag_t cc = ct->ct_cc;
302 pci_chipset_tag_t pc = csc->sc_pc;
303 cardbus_function_tag_t cf = ct->ct_cf;
304 pcireg_t reg;
305
306 /* program the BAR */
307 pci_conf_write(pc, csc->sc_tag, CARDBUS_BASE0_REG,
308 csc->sc_bar_val);
309
310 /* make sure the right access type is on the cardbus bridge */
311 (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
312 (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
313
314 /* enable the appropriate bits in the PCI CSR */
315 reg = pci_conf_read(pc, csc->sc_tag,
316 PCI_COMMAND_STATUS_REG);
317 reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
318 pci_conf_write(pc, csc->sc_tag, PCI_COMMAND_STATUS_REG,
319 reg);
320 }
321
322 void
ral_cardbus_wakeup(struct ral_cardbus_softc * csc)323 ral_cardbus_wakeup(struct ral_cardbus_softc *csc)
324 {
325 struct rt2560_softc *sc = &csc->sc_sc;
326 int s;
327
328 s = splnet();
329 (*csc->sc_opns->resume)(sc);
330 splx(s);
331 }
332