Annotation of sys/dev/cardbus/if_malo_cardbus.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_malo_cardbus.c,v 1.5 2006/11/29 10:37:11 mglocker Exp $ */
2:
3: /*
4: * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
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: #include "bpfilter.h"
20:
21: #include <sys/param.h>
22: #include <sys/mbuf.h>
23: #include <sys/socket.h>
24: #include <sys/systm.h>
25: #include <sys/timeout.h>
26:
27: #include <net/if.h>
28: #include <net/if_media.h>
29:
30: #include <netinet/in.h>
31: #include <netinet/if_ether.h>
32:
33: #include <net80211/ieee80211_var.h>
34: #include <net80211/ieee80211_radiotap.h>
35:
36: #include <dev/pci/pcireg.h>
37: #include <dev/pci/pcivar.h>
38: #include <dev/pci/pcidevs.h>
39:
40: #include <dev/cardbus/cardbusvar.h>
41:
42: #include <dev/ic/malo.h>
43:
44: struct malo_cardbus_softc {
45: struct malo_softc sc_malo;
46:
47: /* cardbus specific goo */
48: cardbus_devfunc_t sc_ct;
49: cardbustag_t sc_tag;
50: void *sc_ih;
51:
52: bus_size_t sc_mapsize1;
53: bus_size_t sc_mapsize2;
54: pcireg_t sc_bar1_val;
55: pcireg_t sc_bar2_val;
56: int sc_intrline;
57: };
58:
59: int malo_cardbus_match(struct device *parent, void *match, void *aux);
60: void malo_cardbus_attach(struct device *parent, struct device *self,
61: void *aux);
62: int malo_cardbus_detach(struct device *self, int flags);
63: void malo_cardbus_setup(struct malo_cardbus_softc *csc);
64: int malo_cardbus_enable(struct malo_softc *sc);
65: void malo_cardbus_disable(struct malo_softc *sc);
66:
67: struct cfattach malo_cardbus_ca = {
68: sizeof (struct malo_cardbus_softc), malo_cardbus_match,
69: malo_cardbus_attach, malo_cardbus_detach
70: };
71:
72: static const struct cardbus_matchid malo_cardbus_devices[] = {
73: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88W8310 },
74: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88W8335_1 },
75: { PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88W8335_2 }
76: };
77:
78: int
79: malo_cardbus_match(struct device *parent, void *match, void *aux)
80: {
81: return (cardbus_matchbyid(aux, malo_cardbus_devices,
82: sizeof (malo_cardbus_devices) / sizeof (malo_cardbus_devices[0])));
83: }
84:
85: void
86: malo_cardbus_attach(struct device *parent, struct device *self, void *aux)
87: {
88: struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)self;
89: struct cardbus_attach_args *ca = aux;
90: struct malo_softc *sc = &csc->sc_malo;
91: cardbus_devfunc_t ct = ca->ca_ct;
92: bus_addr_t base;
93: int error;
94:
95: sc->sc_dmat = ca->ca_dmat;
96: csc->sc_ct = ct;
97: csc->sc_tag = ca->ca_tag;
98: csc->sc_intrline = ca->ca_intrline;
99:
100: /* power management hooks */
101: sc->sc_enable = malo_cardbus_enable;
102: sc->sc_disable = malo_cardbus_disable;
103: #if 0
104: sc->sc_power = malo_cardbus_power;
105: #endif
106:
107: /* map control/status registers */
108: error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
109: CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_mem1_bt,
110: &sc->sc_mem1_bh, &base, &csc->sc_mapsize1);
111: if (error != 0) {
112: printf(": could not map 1st memory space\n");
113: return;
114: }
115: csc->sc_bar1_val = base | CARDBUS_MAPREG_TYPE_MEM;
116:
117: /* map control/status registers */
118: error = Cardbus_mapreg_map(ct, CARDBUS_BASE1_REG,
119: CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_mem2_bt,
120: &sc->sc_mem2_bh, &base, &csc->sc_mapsize2);
121: if (error != 0) {
122: printf(": could not map 2nd memory space\n");
123: Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_mem1_bt,
124: sc->sc_mem1_bh, csc->sc_mapsize1);
125: return;
126: }
127: csc->sc_bar2_val = base | CARDBUS_MAPREG_TYPE_MEM;
128:
129: /* set up the PCI configuration registers */
130: malo_cardbus_setup(csc);
131:
132: printf(": irq %d", csc->sc_intrline);
133:
134: error = malo_attach(sc);
135: if (error != 0)
136: malo_cardbus_detach(&sc->sc_dev, 0);
137:
138: Cardbus_function_disable(ct);
139: }
140:
141: int
142: malo_cardbus_detach(struct device *self, int flags)
143: {
144: struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)self;
145: struct malo_softc *sc = &csc->sc_malo;
146: cardbus_devfunc_t ct = csc->sc_ct;
147: cardbus_chipset_tag_t cc = ct->ct_cc;
148: cardbus_function_tag_t cf = ct->ct_cf;
149: int error;
150:
151: error = malo_detach(sc);
152: if (error != 0)
153: return (error);
154:
155: /* unhook the interrupt handler */
156: if (csc->sc_ih != NULL) {
157: cardbus_intr_disestablish(cc, cf, csc->sc_ih);
158: csc->sc_ih = NULL;
159: }
160:
161: /* release bus space and close window */
162: Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_mem1_bt,
163: sc->sc_mem1_bh, csc->sc_mapsize1);
164: Cardbus_mapreg_unmap(ct, CARDBUS_BASE1_REG, sc->sc_mem2_bt,
165: sc->sc_mem2_bh, csc->sc_mapsize2);
166:
167: return (0);
168: }
169:
170: void
171: malo_cardbus_setup(struct malo_cardbus_softc *csc)
172: {
173: cardbus_devfunc_t ct = csc->sc_ct;
174: cardbus_chipset_tag_t cc = ct->ct_cc;
175: cardbus_function_tag_t cf = ct->ct_cf;
176: pcireg_t reg;
177:
178: /* program the BAR */
179: cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BASE0_REG,
180: csc->sc_bar1_val);
181: cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BASE1_REG,
182: csc->sc_bar2_val);
183:
184: /* make sure the right access type is on the cardbus bridge */
185: (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
186: (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
187:
188: /* enable the appropriate bits in the PCI CSR */
189: reg = cardbus_conf_read(cc, cf, csc->sc_tag,
190: CARDBUS_COMMAND_STATUS_REG);
191: reg |= CARDBUS_COMMAND_MASTER_ENABLE | CARDBUS_COMMAND_MEM_ENABLE;
192: cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG,
193: reg);
194: }
195:
196: int
197: malo_cardbus_enable(struct malo_softc *sc)
198: {
199: struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)sc;
200: cardbus_devfunc_t ct = csc->sc_ct;
201: cardbus_chipset_tag_t cc = ct->ct_cc;
202: cardbus_function_tag_t cf = ct->ct_cf;
203:
204: /* power on the socket */
205: Cardbus_function_enable(ct);
206:
207: /* setup the PCI configuration registers */
208: malo_cardbus_setup(csc);
209:
210: /* map and establish the interrupt handler */
211: csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
212: malo_intr, sc, sc->sc_dev.dv_xname);
213: if (csc->sc_ih == NULL) {
214: printf("%s: could not establish interrupt at %d\n",
215: sc->sc_dev.dv_xname, csc->sc_intrline);
216: Cardbus_function_disable(ct);
217: return (1);
218: }
219:
220: return (0);
221: }
222:
223: void
224: malo_cardbus_disable(struct malo_softc *sc)
225: {
226: struct malo_cardbus_softc *csc = (struct malo_cardbus_softc *)sc;
227: cardbus_devfunc_t ct = csc->sc_ct;
228: cardbus_chipset_tag_t cc = ct->ct_cc;
229: cardbus_function_tag_t cf = ct->ct_cf;
230:
231: /* unhook the interrupt handler */
232: cardbus_intr_disestablish(cc, cf, csc->sc_ih);
233: csc->sc_ih = NULL;
234:
235: /* power down the socket */
236: Cardbus_function_disable(ct);
237: }
CVSweb