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