staging: brcm80211: removed last amd64 compiler warnings
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / brcm80211 / brcmfmac / bcmsdh.c
blobcecb29163f6dabfaedfdb1d8f6c454a90e9903fa
1 /*
2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 /* ****************** SDIO CARD Interface Functions **************************/
18 #include <linux/types.h>
19 #include <linux/netdevice.h>
20 #include <linux/pci_ids.h>
21 #include <linux/sched.h>
23 #include <defs.h>
24 #include <brcm_hw_ids.h>
25 #include <brcmu_utils.h>
26 #include <brcmu_wifi.h>
27 #include <soc.h>
28 #include "bcmsdbus.h" /* common SDIO/controller interface */
29 #include "sbsdio.h" /* BRCM sdio device core */
30 #include "dngl_stats.h"
31 #include "dhd.h"
33 #define SDIOH_API_ACCESS_RETRY_LIMIT 2
35 #define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
36 #define BRCMF_SD_INFO_VAL 0x0002 /* Info */
38 #ifdef BCMDBG
39 #define BRCMF_SD_ERROR(x) \
40 do { \
41 if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \
42 net_ratelimit()) \
43 printk x; \
44 } while (0)
45 #define BRCMF_SD_INFO(x) \
46 do { \
47 if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \
48 net_ratelimit()) \
49 printk x; \
50 } while (0)
51 #else /* BCMDBG */
52 #define BRCMF_SD_ERROR(x)
53 #define BRCMF_SD_INFO(x)
54 #endif /* BCMDBG */
56 const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
58 struct brcmf_sdio_card {
59 bool init_success; /* underlying driver successfully attached */
60 void *sdioh; /* handler for sdioh */
61 u32 vendevid; /* Target Vendor and Device ID on SD bus */
62 bool regfail; /* Save status of last
63 reg_read/reg_write call */
64 u32 sbwad; /* Save backplane window address */
66 /* local copy of bcm sd handler */
67 static struct brcmf_sdio_card *l_card;
69 struct brcmf_sdio_card*
70 brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq)
72 struct brcmf_sdio_card *card;
74 card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC);
75 if (card == NULL) {
76 BRCMF_SD_ERROR(("sdcard_attach: out of memory"));
77 return NULL;
80 /* save the handler locally */
81 l_card = card;
83 card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
84 if (!card->sdioh) {
85 brcmf_sdcard_detach(card);
86 return NULL;
89 card->init_success = true;
91 *regsva = SI_ENUM_BASE;
93 /* Report the BAR, to fix if needed */
94 card->sbwad = SI_ENUM_BASE;
95 return card;
98 int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
100 if (card != NULL) {
101 if (card->sdioh) {
102 brcmf_sdioh_detach(card->sdioh);
103 card->sdioh = NULL;
105 kfree(card);
108 l_card = NULL;
109 return 0;
113 brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
114 void *params, int plen, void *arg, int len, bool set)
116 return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
117 len, set);
120 int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
122 ASSERT(card);
124 return brcmf_sdioh_interrupt_set(card->sdioh, true);
127 int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
129 ASSERT(card);
131 return brcmf_sdioh_interrupt_set(card->sdioh, false);
134 int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
135 void (*fn)(void *), void *argh)
137 ASSERT(card);
139 return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
142 int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
144 ASSERT(card);
146 return brcmf_sdioh_interrupt_deregister(card->sdioh);
149 u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
150 int *err)
152 int status;
153 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
154 s32 retry = 0;
155 #endif
156 u8 data = 0;
158 if (!card)
159 card = l_card;
161 ASSERT(card->init_success);
163 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
164 do {
165 if (retry) /* wait for 1 ms till bus get settled down */
166 udelay(1000);
167 #endif
168 status =
169 brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
170 (u8 *) &data);
171 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
172 } while (status != 0
173 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
174 #endif
175 if (err)
176 *err = status;
178 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
179 __func__, fnc_num, addr, data));
181 return data;
184 void
185 brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
186 u8 data, int *err)
188 int status;
189 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
190 s32 retry = 0;
191 #endif
193 if (!card)
194 card = l_card;
196 ASSERT(card->init_success);
198 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
199 do {
200 if (retry) /* wait for 1 ms till bus get settled down */
201 udelay(1000);
202 #endif
203 status =
204 brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
205 (u8 *) &data);
206 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
207 } while (status != 0
208 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
209 #endif
210 if (err)
211 *err = status;
213 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
214 __func__, fnc_num, addr, data));
217 u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
218 u32 addr, int *err)
220 int status;
221 u32 data = 0;
223 if (!card)
224 card = l_card;
226 ASSERT(card->init_success);
228 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
229 SDIOH_READ, fnc_num, addr, &data, 4);
231 if (err)
232 *err = status;
234 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
235 __func__, fnc_num, addr, data));
237 return data;
240 void
241 brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
242 u32 addr, u32 data, int *err)
244 int status;
246 if (!card)
247 card = l_card;
249 ASSERT(card->init_success);
251 status =
252 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
253 SDIOH_WRITE, fnc_num, addr, &data, 4);
255 if (err)
256 *err = status;
258 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
259 __func__, fnc_num, addr, data));
262 int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
263 uint length)
265 int status;
267 u8 *tmp_buf, *tmp_ptr;
268 u8 *ptr;
269 bool ascii = func & ~0xf;
270 func &= 0x7;
272 if (!card)
273 card = l_card;
275 ASSERT(card->init_success);
276 ASSERT(cis);
277 ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
279 status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
281 if (ascii) {
282 /* Move binary bits to tmp and format them
283 into the provided buffer. */
284 tmp_buf = kmalloc(length, GFP_ATOMIC);
285 if (tmp_buf == NULL) {
286 BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
287 return -ENOMEM;
289 memcpy(tmp_buf, cis, length);
290 for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
291 tmp_ptr++) {
292 ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
293 if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
294 ptr += sprintf((char *)ptr, "\n");
296 kfree(tmp_buf);
299 return status;
302 static int
303 brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
305 int err = 0;
306 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
307 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
308 if (!err)
309 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
310 SBSDIO_FUNC1_SBADDRMID,
311 (address >> 16) & SBSDIO_SBADDRMID_MASK,
312 &err);
313 if (!err)
314 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
315 SBSDIO_FUNC1_SBADDRHIGH,
316 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
317 &err);
319 return err;
322 u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
324 int status;
325 u32 word = 0;
326 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
328 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
330 if (!card)
331 card = l_card;
333 ASSERT(card->init_success);
335 if (bar0 != card->sbwad) {
336 if (brcmf_sdcard_set_sbaddr_window(card, bar0))
337 return 0xFFFFFFFF;
339 card->sbwad = bar0;
342 addr &= SBSDIO_SB_OFT_ADDR_MASK;
343 if (size == 4)
344 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
346 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
347 SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
349 card->regfail = (status != 0);
351 BRCMF_SD_INFO(("u32data = 0x%x\n", word));
353 /* if ok, return appropriately masked word */
354 if (status == 0) {
355 switch (size) {
356 case sizeof(u8):
357 return word & 0xff;
358 case sizeof(u16):
359 return word & 0xffff;
360 case sizeof(u32):
361 return word;
362 default:
363 card->regfail = true;
368 /* otherwise, bad sdio access or invalid size */
369 BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
370 addr, size));
371 return 0xFFFFFFFF;
374 u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
375 u32 data)
377 int status;
378 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
379 int err = 0;
381 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
382 __func__, addr, size * 8, data));
384 if (!card)
385 card = l_card;
387 ASSERT(card->init_success);
389 if (bar0 != card->sbwad) {
390 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
391 if (err)
392 return err;
394 card->sbwad = bar0;
397 addr &= SBSDIO_SB_OFT_ADDR_MASK;
398 if (size == 4)
399 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
400 status =
401 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
402 SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
403 card->regfail = (status != 0);
405 if (status == 0)
406 return 0;
408 BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
409 __func__, data, addr, size));
410 return 0xFFFFFFFF;
413 bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
415 return card->regfail;
419 brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
420 uint flags,
421 u8 *buf, uint nbytes, struct sk_buff *pkt,
422 void (*complete)(void *handle, int status,
423 bool sync_waiting),
424 void *handle)
426 int status;
427 uint incr_fix;
428 uint width;
429 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
430 int err = 0;
432 ASSERT(card);
433 ASSERT(card->init_success);
435 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
436 __func__, fn, addr, nbytes));
438 /* Async not implemented yet */
439 ASSERT(!(flags & SDIO_REQ_ASYNC));
440 if (flags & SDIO_REQ_ASYNC)
441 return -ENOTSUPP;
443 if (bar0 != card->sbwad) {
444 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
445 if (err)
446 return err;
448 card->sbwad = bar0;
451 addr &= SBSDIO_SB_OFT_ADDR_MASK;
453 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
454 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
455 if (width == 4)
456 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
458 status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
459 incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
461 return status;
465 brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
466 uint flags, u8 *buf, uint nbytes, void *pkt,
467 void (*complete)(void *handle, int status,
468 bool sync_waiting),
469 void *handle)
471 uint incr_fix;
472 uint width;
473 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
474 int err = 0;
476 ASSERT(card);
477 ASSERT(card->init_success);
479 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
480 __func__, fn, addr, nbytes));
482 /* Async not implemented yet */
483 ASSERT(!(flags & SDIO_REQ_ASYNC));
484 if (flags & SDIO_REQ_ASYNC)
485 return -ENOTSUPP;
487 if (bar0 != card->sbwad) {
488 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
489 if (err)
490 return err;
492 card->sbwad = bar0;
495 addr &= SBSDIO_SB_OFT_ADDR_MASK;
497 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
498 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
499 if (width == 4)
500 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
502 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
503 incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
506 int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
507 u8 *buf, uint nbytes)
509 ASSERT(card);
510 ASSERT(card->init_success);
511 ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
513 addr &= SBSDIO_SB_OFT_ADDR_MASK;
514 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
516 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
517 SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
518 addr, 4, nbytes, buf, NULL);
521 int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
523 return brcmf_sdioh_abort(card->sdioh, fn);
526 int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
528 card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
529 return card->vendevid;
532 u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
534 if (!card)
535 card = l_card;
537 return card->sbwad;