if_bwfm_sdio.c revision 1.1 1 1.1 khorben /* $NetBSD: if_bwfm_sdio.c,v 1.1 2017/11/07 16:30:32 khorben Exp $ */
2 1.1 khorben /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
3 1.1 khorben /*
4 1.1 khorben * Copyright (c) 2010-2016 Broadcom Corporation
5 1.1 khorben * Copyright (c) 2016,2017 Patrick Wildt <patrick (at) blueri.se>
6 1.1 khorben *
7 1.1 khorben * Permission to use, copy, modify, and/or distribute this software for any
8 1.1 khorben * purpose with or without fee is hereby granted, provided that the above
9 1.1 khorben * copyright notice and this permission notice appear in all copies.
10 1.1 khorben *
11 1.1 khorben * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 1.1 khorben * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 1.1 khorben * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 1.1 khorben * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 1.1 khorben * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 1.1 khorben * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 1.1 khorben * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 1.1 khorben */
19 1.1 khorben
20 1.1 khorben #include <sys/param.h>
21 1.1 khorben #include <sys/systm.h>
22 1.1 khorben #include <sys/buf.h>
23 1.1 khorben #include <sys/kernel.h>
24 1.1 khorben #include <sys/malloc.h>
25 1.1 khorben #include <sys/device.h>
26 1.1 khorben #include <sys/queue.h>
27 1.1 khorben #include <sys/socket.h>
28 1.1 khorben #include <sys/mutex.h>
29 1.1 khorben #include <sys/workqueue.h>
30 1.1 khorben #include <sys/pcq.h>
31 1.1 khorben
32 1.1 khorben #include <net/bpf.h>
33 1.1 khorben #include <net/if.h>
34 1.1 khorben #include <net/if_dl.h>
35 1.1 khorben #include <net/if_media.h>
36 1.1 khorben #include <net/if_ether.h>
37 1.1 khorben
38 1.1 khorben #include <netinet/in.h>
39 1.1 khorben
40 1.1 khorben #include <net80211/ieee80211_var.h>
41 1.1 khorben
42 1.1 khorben #include <dev/sdmmc/sdmmcvar.h>
43 1.1 khorben
44 1.1 khorben #include <dev/ic/bwfmvar.h>
45 1.1 khorben #include <dev/ic/bwfmreg.h>
46 1.1 khorben
47 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_CARDCAP 0xf0
48 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02
49 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04
50 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08
51 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_CARDCTRL 0xf1
52 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02
53 1.1 khorben #define BWFM_SDIO_CCCR_BRCM_SEPINT 0xf2
54 1.1 khorben
55 1.1 khorben #ifdef BWFM_DEBUG
56 1.1 khorben #define DPRINTF(x) do { if (bwfm_debug > 0) printf x; } while (0)
57 1.1 khorben #define DPRINTFN(n, x) do { if (bwfm_debug >= (n)) printf x; } while (0)
58 1.1 khorben static int bwfm_debug = 2;
59 1.1 khorben #else
60 1.1 khorben #define DPRINTF(x) do { ; } while (0)
61 1.1 khorben #define DPRINTFN(n, x) do { ; } while (0)
62 1.1 khorben #endif
63 1.1 khorben
64 1.1 khorben #define DEVNAME(sc) device_xname((sc)->sc_sc.sc_dev)
65 1.1 khorben
66 1.1 khorben struct bwfm_sdio_softc {
67 1.1 khorben struct bwfm_softc sc_sc;
68 1.1 khorben struct sdmmc_function **sc_sf;
69 1.1 khorben uint32_t sc_bar0;
70 1.1 khorben };
71 1.1 khorben
72 1.1 khorben int bwfm_sdio_match(device_t, cfdata_t, void *);
73 1.1 khorben void bwfm_sdio_attach(device_t, struct device *, void *);
74 1.1 khorben int bwfm_sdio_detach(device_t, int);
75 1.1 khorben
76 1.1 khorben uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t);
77 1.1 khorben uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t);
78 1.1 khorben void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t,
79 1.1 khorben uint8_t);
80 1.1 khorben void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t,
81 1.1 khorben uint32_t);
82 1.1 khorben
83 1.1 khorben uint32_t bwfm_sdio_buscore_read(struct bwfm_softc *, uint32_t);
84 1.1 khorben void bwfm_sdio_buscore_write(struct bwfm_softc *, uint32_t,
85 1.1 khorben uint32_t);
86 1.1 khorben int bwfm_sdio_buscore_prepare(struct bwfm_softc *);
87 1.1 khorben void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t);
88 1.1 khorben
89 1.1 khorben int bwfm_sdio_txdata(struct bwfm_softc *, struct mbuf *);
90 1.1 khorben int bwfm_sdio_txctl(struct bwfm_softc *, char *, size_t);
91 1.1 khorben int bwfm_sdio_rxctl(struct bwfm_softc *, char *, size_t *);
92 1.1 khorben
93 1.1 khorben struct bwfm_bus_ops bwfm_sdio_bus_ops = {
94 1.1 khorben .bs_init = NULL,
95 1.1 khorben .bs_stop = NULL,
96 1.1 khorben .bs_txdata = bwfm_sdio_txdata,
97 1.1 khorben .bs_txctl = bwfm_sdio_txctl,
98 1.1 khorben .bs_rxctl = bwfm_sdio_rxctl,
99 1.1 khorben };
100 1.1 khorben
101 1.1 khorben struct bwfm_buscore_ops bwfm_sdio_buscore_ops = {
102 1.1 khorben .bc_read = bwfm_sdio_buscore_read,
103 1.1 khorben .bc_write = bwfm_sdio_buscore_write,
104 1.1 khorben .bc_prepare = bwfm_sdio_buscore_prepare,
105 1.1 khorben .bc_reset = NULL,
106 1.1 khorben .bc_setup = NULL,
107 1.1 khorben .bc_activate = bwfm_sdio_buscore_activate,
108 1.1 khorben };
109 1.1 khorben
110 1.1 khorben CFATTACH_DECL_NEW(bwfm_sdio, sizeof(struct bwfm_sdio_softc),
111 1.1 khorben bwfm_sdio_match, bwfm_sdio_attach, bwfm_sdio_detach, NULL);
112 1.1 khorben
113 1.1 khorben int
114 1.1 khorben bwfm_sdio_match(device_t parent, cfdata_t match, void *aux)
115 1.1 khorben {
116 1.1 khorben struct sdmmc_attach_args *saa = aux;
117 1.1 khorben struct sdmmc_function *sf = saa->sf;
118 1.1 khorben struct sdmmc_cis *cis;
119 1.1 khorben
120 1.1 khorben /* Not SDIO. */
121 1.1 khorben if (sf == NULL)
122 1.1 khorben return 0;
123 1.1 khorben
124 1.1 khorben /* Look for Broadcom 433[04]. */
125 1.1 khorben cis = &sf->sc->sc_fn0->cis;
126 1.1 khorben if (cis->manufacturer != 0x02d0 || (cis->product != 0x4330 &&
127 1.1 khorben cis->product != 0x4334))
128 1.1 khorben return 0;
129 1.1 khorben
130 1.1 khorben /* We need both functions, but ... */
131 1.1 khorben if (sf->sc->sc_function_count <= 1)
132 1.1 khorben return 0;
133 1.1 khorben
134 1.1 khorben /* ... only attach for one. */
135 1.1 khorben if (sf->number != 1)
136 1.1 khorben return 0;
137 1.1 khorben
138 1.1 khorben return 1;
139 1.1 khorben }
140 1.1 khorben
141 1.1 khorben void
142 1.1 khorben bwfm_sdio_attach(device_t parent, device_t self, void *aux)
143 1.1 khorben {
144 1.1 khorben struct bwfm_sdio_softc *sc = device_private(self);
145 1.1 khorben struct sdmmc_attach_args *saa = aux;
146 1.1 khorben struct sdmmc_function *sf = saa->sf;
147 1.1 khorben struct bwfm_core *core;
148 1.1 khorben
149 1.1 khorben aprint_naive("\n");
150 1.1 khorben
151 1.1 khorben sc->sc_sf = malloc((sf->sc->sc_function_count + 1) *
152 1.1 khorben sizeof(struct sdmmc_function *), M_DEVBUF, M_WAITOK);
153 1.1 khorben
154 1.1 khorben /* Copy all function pointers. */
155 1.1 khorben SIMPLEQ_FOREACH(sf, &saa->sf->sc->sf_head, sf_list) {
156 1.1 khorben sc->sc_sf[sf->number] = sf;
157 1.1 khorben }
158 1.1 khorben sf = saa->sf;
159 1.1 khorben
160 1.1 khorben /*
161 1.1 khorben * TODO: set block size to 64 for func 1, 512 for func 2.
162 1.1 khorben * We might need to work on the SDMMC stack to be able to set
163 1.1 khorben * a block size per function. Currently the IO code uses the
164 1.1 khorben * SDHC controller's maximum block length.
165 1.1 khorben */
166 1.1 khorben
167 1.1 khorben /* Enable Function 1. */
168 1.1 khorben if (sdmmc_io_function_enable(sc->sc_sf[1]) != 0) {
169 1.1 khorben aprint_error_dev(self, "cannot enable function 1\n");
170 1.1 khorben goto err;
171 1.1 khorben }
172 1.1 khorben
173 1.1 khorben DPRINTFN(2, ("%s: F1 signature read @0x18000000=%x\n", DEVNAME(sc),
174 1.1 khorben bwfm_sdio_read_4(sc, 0x18000000)));
175 1.1 khorben
176 1.1 khorben /* Force PLL off */
177 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR,
178 1.1 khorben BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF |
179 1.1 khorben BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ);
180 1.1 khorben
181 1.1 khorben sc->sc_sc.sc_buscore_ops = &bwfm_sdio_buscore_ops;
182 1.1 khorben if (bwfm_chip_attach(&sc->sc_sc) != 0) {
183 1.1 khorben aprint_error_dev(self, "cannot attach chip\n");
184 1.1 khorben goto err;
185 1.1 khorben }
186 1.1 khorben
187 1.1 khorben /* TODO: drive strength */
188 1.1 khorben
189 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_CCCR_BRCM_CARDCTRL,
190 1.1 khorben bwfm_sdio_read_1(sc, BWFM_SDIO_CCCR_BRCM_CARDCTRL) |
191 1.1 khorben BWFM_SDIO_CCCR_BRCM_CARDCTRL_WLANRESET);
192 1.1 khorben
193 1.1 khorben core = bwfm_chip_get_pmu(&sc->sc_sc);
194 1.1 khorben bwfm_sdio_write_4(sc, core->co_base + BWFM_CHIP_REG_PMUCONTROL,
195 1.1 khorben bwfm_sdio_read_4(sc, core->co_base + BWFM_CHIP_REG_PMUCONTROL) |
196 1.1 khorben (BWFM_CHIP_REG_PMUCONTROL_RES_RELOAD <<
197 1.1 khorben BWFM_CHIP_REG_PMUCONTROL_RES_SHIFT));
198 1.1 khorben
199 1.1 khorben sc->sc_sc.sc_bus_ops = &bwfm_sdio_bus_ops;
200 1.1 khorben sc->sc_sc.sc_proto_ops = &bwfm_proto_bcdc_ops;
201 1.1 khorben bwfm_attach(&sc->sc_sc);
202 1.1 khorben
203 1.1 khorben return;
204 1.1 khorben
205 1.1 khorben err:
206 1.1 khorben free(sc->sc_sf, M_DEVBUF);
207 1.1 khorben }
208 1.1 khorben
209 1.1 khorben int
210 1.1 khorben bwfm_sdio_detach(struct device *self, int flags)
211 1.1 khorben {
212 1.1 khorben struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self;
213 1.1 khorben
214 1.1 khorben bwfm_detach(&sc->sc_sc, flags);
215 1.1 khorben
216 1.1 khorben free(sc->sc_sf, M_DEVBUF);
217 1.1 khorben
218 1.1 khorben return 0;
219 1.1 khorben }
220 1.1 khorben
221 1.1 khorben uint8_t
222 1.1 khorben bwfm_sdio_read_1(struct bwfm_sdio_softc *sc, uint32_t addr)
223 1.1 khorben {
224 1.1 khorben struct sdmmc_function *sf;
225 1.1 khorben uint8_t rv;
226 1.1 khorben
227 1.1 khorben /*
228 1.1 khorben * figure out how to read the register based on address range
229 1.1 khorben * 0x00 ~ 0x7FF: function 0 CCCR and FBR
230 1.1 khorben * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
231 1.1 khorben * The rest: function 1 silicon backplane core registers
232 1.1 khorben */
233 1.1 khorben if ((addr & ~0x7ff) == 0)
234 1.1 khorben sf = sc->sc_sf[0];
235 1.1 khorben else
236 1.1 khorben sf = sc->sc_sf[1];
237 1.1 khorben
238 1.1 khorben rv = sdmmc_io_read_1(sf, addr);
239 1.1 khorben return rv;
240 1.1 khorben }
241 1.1 khorben
242 1.1 khorben uint32_t
243 1.1 khorben bwfm_sdio_read_4(struct bwfm_sdio_softc *sc, uint32_t addr)
244 1.1 khorben {
245 1.1 khorben struct sdmmc_function *sf;
246 1.1 khorben uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK;
247 1.1 khorben uint32_t rv;
248 1.1 khorben
249 1.1 khorben if (sc->sc_bar0 != bar0) {
250 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW,
251 1.1 khorben (bar0 >> 8) & 0x80);
252 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID,
253 1.1 khorben (bar0 >> 16) & 0xff);
254 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH,
255 1.1 khorben (bar0 >> 24) & 0xff);
256 1.1 khorben sc->sc_bar0 = bar0;
257 1.1 khorben }
258 1.1 khorben
259 1.1 khorben addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
260 1.1 khorben addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
261 1.1 khorben
262 1.1 khorben /*
263 1.1 khorben * figure out how to read the register based on address range
264 1.1 khorben * 0x00 ~ 0x7FF: function 0 CCCR and FBR
265 1.1 khorben * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
266 1.1 khorben * The rest: function 1 silicon backplane core registers
267 1.1 khorben */
268 1.1 khorben if ((addr & ~0x7ff) == 0)
269 1.1 khorben sf = sc->sc_sf[0];
270 1.1 khorben else
271 1.1 khorben sf = sc->sc_sf[1];
272 1.1 khorben
273 1.1 khorben rv = sdmmc_io_read_4(sf, addr);
274 1.1 khorben return rv;
275 1.1 khorben }
276 1.1 khorben
277 1.1 khorben void
278 1.1 khorben bwfm_sdio_write_1(struct bwfm_sdio_softc *sc, uint32_t addr, uint8_t data)
279 1.1 khorben {
280 1.1 khorben struct sdmmc_function *sf;
281 1.1 khorben
282 1.1 khorben /*
283 1.1 khorben * figure out how to read the register based on address range
284 1.1 khorben * 0x00 ~ 0x7FF: function 0 CCCR and FBR
285 1.1 khorben * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
286 1.1 khorben * The rest: function 1 silicon backplane core registers
287 1.1 khorben */
288 1.1 khorben if ((addr & ~0x7ff) == 0)
289 1.1 khorben sf = sc->sc_sf[0];
290 1.1 khorben else
291 1.1 khorben sf = sc->sc_sf[1];
292 1.1 khorben
293 1.1 khorben sdmmc_io_write_1(sf, addr, data);
294 1.1 khorben }
295 1.1 khorben
296 1.1 khorben void
297 1.1 khorben bwfm_sdio_write_4(struct bwfm_sdio_softc *sc, uint32_t addr, uint32_t data)
298 1.1 khorben {
299 1.1 khorben struct sdmmc_function *sf;
300 1.1 khorben uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK;
301 1.1 khorben
302 1.1 khorben if (sc->sc_bar0 != bar0) {
303 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW,
304 1.1 khorben (bar0 >> 8) & 0x80);
305 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID,
306 1.1 khorben (bar0 >> 16) & 0xff);
307 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH,
308 1.1 khorben (bar0 >> 24) & 0xff);
309 1.1 khorben sc->sc_bar0 = bar0;
310 1.1 khorben }
311 1.1 khorben
312 1.1 khorben addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
313 1.1 khorben addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
314 1.1 khorben
315 1.1 khorben /*
316 1.1 khorben * figure out how to read the register based on address range
317 1.1 khorben * 0x00 ~ 0x7FF: function 0 CCCR and FBR
318 1.1 khorben * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
319 1.1 khorben * The rest: function 1 silicon backplane core registers
320 1.1 khorben */
321 1.1 khorben if ((addr & ~0x7ff) == 0)
322 1.1 khorben sf = sc->sc_sf[0];
323 1.1 khorben else
324 1.1 khorben sf = sc->sc_sf[1];
325 1.1 khorben
326 1.1 khorben sdmmc_io_write_4(sf, addr, data);
327 1.1 khorben }
328 1.1 khorben
329 1.1 khorben uint32_t
330 1.1 khorben bwfm_sdio_buscore_read(struct bwfm_softc *bwfm, uint32_t reg)
331 1.1 khorben {
332 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
333 1.1 khorben uint32_t val;
334 1.1 khorben
335 1.1 khorben val = bwfm_sdio_read_4(sc, reg);
336 1.1 khorben /* TODO: Workaround for 4335/4339 */
337 1.1 khorben
338 1.1 khorben return val;
339 1.1 khorben }
340 1.1 khorben
341 1.1 khorben void
342 1.1 khorben bwfm_sdio_buscore_write(struct bwfm_softc *bwfm, uint32_t reg, uint32_t val)
343 1.1 khorben {
344 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
345 1.1 khorben bwfm_sdio_write_4(sc, reg, val);
346 1.1 khorben }
347 1.1 khorben
348 1.1 khorben int
349 1.1 khorben bwfm_sdio_buscore_prepare(struct bwfm_softc *bwfm)
350 1.1 khorben {
351 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
352 1.1 khorben uint8_t clkval, clkset, clkmask;
353 1.1 khorben int i;
354 1.1 khorben
355 1.1 khorben clkset = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ |
356 1.1 khorben BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF;
357 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clkset);
358 1.1 khorben
359 1.1 khorben clkmask = BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL |
360 1.1 khorben BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL;
361 1.1 khorben clkval = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR);
362 1.1 khorben
363 1.1 khorben if ((clkval & ~clkmask) != clkset) {
364 1.1 khorben printf("%s: wrote 0x%02x read 0x%02x\n", DEVNAME(sc),
365 1.1 khorben clkset, clkval);
366 1.1 khorben return 1;
367 1.1 khorben }
368 1.1 khorben
369 1.1 khorben for (i = 1000; i > 0; i--) {
370 1.1 khorben clkval = bwfm_sdio_read_1(sc,
371 1.1 khorben BWFM_SDIO_FUNC1_CHIPCLKCSR);
372 1.1 khorben if (clkval & clkmask)
373 1.1 khorben break;
374 1.1 khorben }
375 1.1 khorben if (i == 0) {
376 1.1 khorben printf("%s: timeout on ALPAV wait, clkval 0x%02x\n",
377 1.1 khorben DEVNAME(sc), clkval);
378 1.1 khorben return 1;
379 1.1 khorben }
380 1.1 khorben
381 1.1 khorben clkset = BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF |
382 1.1 khorben BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_ALP;
383 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_CHIPCLKCSR, clkset);
384 1.1 khorben delay(65);
385 1.1 khorben
386 1.1 khorben bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SDIOPULLUP, 0);
387 1.1 khorben
388 1.1 khorben return 0;
389 1.1 khorben }
390 1.1 khorben
391 1.1 khorben void
392 1.1 khorben bwfm_sdio_buscore_activate(struct bwfm_softc *bwfm, uint32_t rstvec)
393 1.1 khorben {
394 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
395 1.1 khorben struct bwfm_core *core;
396 1.1 khorben
397 1.1 khorben core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV);
398 1.1 khorben bwfm_sdio_buscore_write(&sc->sc_sc,
399 1.1 khorben core->co_base + BWFM_SDPCMD_INTSTATUS, 0xFFFFFFFF);
400 1.1 khorben
401 1.1 khorben #if notyet
402 1.1 khorben if (rstvec)
403 1.1 khorben bwfm_sdio_ram_write(&sc->sc_sc, 0, &rstvec, sizeof(rstvec));
404 1.1 khorben #endif
405 1.1 khorben }
406 1.1 khorben
407 1.1 khorben int
408 1.1 khorben bwfm_sdio_txdata(struct bwfm_softc *bwfm, struct mbuf *m)
409 1.1 khorben {
410 1.1 khorben #ifdef BWFM_DEBUG
411 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
412 1.1 khorben #endif
413 1.1 khorben int ret = 1;
414 1.1 khorben
415 1.1 khorben DPRINTFN(2, ("%s: %s\n", DEVNAME(sc), __func__));
416 1.1 khorben
417 1.1 khorben return ret;
418 1.1 khorben }
419 1.1 khorben
420 1.1 khorben int
421 1.1 khorben bwfm_sdio_txctl(struct bwfm_softc *bwfm, char *buf, size_t len)
422 1.1 khorben {
423 1.1 khorben #ifdef BWFM_DEBUG
424 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
425 1.1 khorben #endif
426 1.1 khorben int ret = 1;
427 1.1 khorben
428 1.1 khorben DPRINTFN(2, ("%s: %s\n", DEVNAME(sc), __func__));
429 1.1 khorben
430 1.1 khorben return ret;
431 1.1 khorben }
432 1.1 khorben
433 1.1 khorben int
434 1.1 khorben bwfm_sdio_rxctl(struct bwfm_softc *bwfm, char *buf, size_t *len)
435 1.1 khorben {
436 1.1 khorben #ifdef BWFM_DEBUG
437 1.1 khorben struct bwfm_sdio_softc *sc = (void *)bwfm;
438 1.1 khorben #endif
439 1.1 khorben int ret = 1;
440 1.1 khorben
441 1.1 khorben DPRINTFN(2, ("%s: %s\n", DEVNAME(sc), __func__));
442 1.1 khorben
443 1.1 khorben return ret;
444 1.1 khorben }
445