staging: brcm80211: removed last typedefs from fullmac
[deliverable/linux.git] / drivers / staging / brcm80211 / brcmfmac / bcmsdh.c
1 /*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
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.
7 *
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.
15 */
16 /* ****************** SDIO CARD Interface Functions **************************/
17
18 #include <linux/types.h>
19 #include <linux/netdevice.h>
20 #include <linux/pci_ids.h>
21 #include <linux/sched.h>
22
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"
32
33 #define SDIOH_API_ACCESS_RETRY_LIMIT 2
34
35 #define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
36 #define BRCMF_SD_INFO_VAL 0x0002 /* Info */
37
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 */
55
56 const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
57
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 */
65 };
66 /* local copy of bcm sd handler */
67 static struct brcmf_sdio_card *l_card;
68
69 struct brcmf_sdio_card*
70 brcmf_sdcard_attach(void *cfghdl, void **regsva, uint irq)
71 {
72 struct brcmf_sdio_card *card;
73
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;
78 }
79
80 /* save the handler locally */
81 l_card = card;
82
83 card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
84 if (!card->sdioh) {
85 brcmf_sdcard_detach(card);
86 return NULL;
87 }
88
89 card->init_success = true;
90
91 *regsva = (u32 *) SI_ENUM_BASE;
92
93 /* Report the BAR, to fix if needed */
94 card->sbwad = SI_ENUM_BASE;
95 return card;
96 }
97
98 int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
99 {
100 if (card != NULL) {
101 if (card->sdioh) {
102 brcmf_sdioh_detach(card->sdioh);
103 card->sdioh = NULL;
104 }
105 kfree(card);
106 }
107
108 l_card = NULL;
109 return 0;
110 }
111
112 int
113 brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
114 void *params, int plen, void *arg, int len, bool set)
115 {
116 return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
117 len, set);
118 }
119
120 bool brcmf_sdcard_intr_query(struct brcmf_sdio_card *card)
121 {
122 int status;
123 bool on;
124
125 ASSERT(card);
126 status = brcmf_sdioh_interrupt_query(card->sdioh, &on);
127 if (status == 0)
128 return false;
129 else
130 return on;
131 }
132
133 int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
134 {
135 ASSERT(card);
136
137 return brcmf_sdioh_interrupt_set(card->sdioh, true);
138 }
139
140 int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
141 {
142 ASSERT(card);
143
144 return brcmf_sdioh_interrupt_set(card->sdioh, false);
145 }
146
147 int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
148 void (*fn)(void *), void *argh)
149 {
150 ASSERT(card);
151
152 return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
153 }
154
155 int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
156 {
157 ASSERT(card);
158
159 return brcmf_sdioh_interrupt_deregister(card->sdioh);
160 }
161
162 int brcmf_sdcard_devremove_reg(struct brcmf_sdio_card *card,
163 void (*fn)(void *), void *argh)
164 {
165 ASSERT(card);
166
167 /* don't support yet */
168 return -ENOTSUPP;
169 }
170
171 u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
172 int *err)
173 {
174 int status;
175 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
176 s32 retry = 0;
177 #endif
178 u8 data = 0;
179
180 if (!card)
181 card = l_card;
182
183 ASSERT(card->init_success);
184
185 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
186 do {
187 if (retry) /* wait for 1 ms till bus get settled down */
188 udelay(1000);
189 #endif
190 status =
191 brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
192 (u8 *) &data);
193 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
194 } while (status != 0
195 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
196 #endif
197 if (err)
198 *err = status;
199
200 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
201 __func__, fnc_num, addr, data));
202
203 return data;
204 }
205
206 void
207 brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
208 u8 data, int *err)
209 {
210 int status;
211 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
212 s32 retry = 0;
213 #endif
214
215 if (!card)
216 card = l_card;
217
218 ASSERT(card->init_success);
219
220 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
221 do {
222 if (retry) /* wait for 1 ms till bus get settled down */
223 udelay(1000);
224 #endif
225 status =
226 brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
227 (u8 *) &data);
228 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
229 } while (status != 0
230 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
231 #endif
232 if (err)
233 *err = status;
234
235 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
236 __func__, fnc_num, addr, data));
237 }
238
239 u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
240 u32 addr, int *err)
241 {
242 int status;
243 u32 data = 0;
244
245 if (!card)
246 card = l_card;
247
248 ASSERT(card->init_success);
249
250 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
251 SDIOH_READ, fnc_num, addr, &data, 4);
252
253 if (err)
254 *err = status;
255
256 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
257 __func__, fnc_num, addr, data));
258
259 return data;
260 }
261
262 void
263 brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
264 u32 addr, u32 data, int *err)
265 {
266 int status;
267
268 if (!card)
269 card = l_card;
270
271 ASSERT(card->init_success);
272
273 status =
274 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
275 SDIOH_WRITE, fnc_num, addr, &data, 4);
276
277 if (err)
278 *err = status;
279
280 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
281 __func__, fnc_num, addr, data));
282 }
283
284 int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
285 uint length)
286 {
287 int status;
288
289 u8 *tmp_buf, *tmp_ptr;
290 u8 *ptr;
291 bool ascii = func & ~0xf;
292 func &= 0x7;
293
294 if (!card)
295 card = l_card;
296
297 ASSERT(card->init_success);
298 ASSERT(cis);
299 ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
300
301 status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
302
303 if (ascii) {
304 /* Move binary bits to tmp and format them
305 into the provided buffer. */
306 tmp_buf = kmalloc(length, GFP_ATOMIC);
307 if (tmp_buf == NULL) {
308 BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
309 return -ENOMEM;
310 }
311 memcpy(tmp_buf, cis, length);
312 for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
313 tmp_ptr++) {
314 ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
315 if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
316 ptr += sprintf((char *)ptr, "\n");
317 }
318 kfree(tmp_buf);
319 }
320
321 return status;
322 }
323
324 static int
325 brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
326 {
327 int err = 0;
328 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
329 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
330 if (!err)
331 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
332 SBSDIO_FUNC1_SBADDRMID,
333 (address >> 16) & SBSDIO_SBADDRMID_MASK,
334 &err);
335 if (!err)
336 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
337 SBSDIO_FUNC1_SBADDRHIGH,
338 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
339 &err);
340
341 return err;
342 }
343
344 u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
345 {
346 int status;
347 u32 word = 0;
348 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
349
350 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
351
352 if (!card)
353 card = l_card;
354
355 ASSERT(card->init_success);
356
357 if (bar0 != card->sbwad) {
358 if (brcmf_sdcard_set_sbaddr_window(card, bar0))
359 return 0xFFFFFFFF;
360
361 card->sbwad = bar0;
362 }
363
364 addr &= SBSDIO_SB_OFT_ADDR_MASK;
365 if (size == 4)
366 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
367
368 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
369 SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
370
371 card->regfail = (status != 0);
372
373 BRCMF_SD_INFO(("u32data = 0x%x\n", word));
374
375 /* if ok, return appropriately masked word */
376 if (status == 0) {
377 switch (size) {
378 case sizeof(u8):
379 return word & 0xff;
380 case sizeof(u16):
381 return word & 0xffff;
382 case sizeof(u32):
383 return word;
384 default:
385 card->regfail = true;
386
387 }
388 }
389
390 /* otherwise, bad sdio access or invalid size */
391 BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
392 addr, size));
393 return 0xFFFFFFFF;
394 }
395
396 u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
397 u32 data)
398 {
399 int status;
400 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
401 int err = 0;
402
403 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
404 __func__, addr, size * 8, data));
405
406 if (!card)
407 card = l_card;
408
409 ASSERT(card->init_success);
410
411 if (bar0 != card->sbwad) {
412 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
413 if (err)
414 return err;
415
416 card->sbwad = bar0;
417 }
418
419 addr &= SBSDIO_SB_OFT_ADDR_MASK;
420 if (size == 4)
421 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
422 status =
423 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
424 SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
425 card->regfail = (status != 0);
426
427 if (status == 0)
428 return 0;
429
430 BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
431 __func__, data, addr, size));
432 return 0xFFFFFFFF;
433 }
434
435 bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
436 {
437 return card->regfail;
438 }
439
440 int
441 brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
442 uint flags,
443 u8 *buf, uint nbytes, struct sk_buff *pkt,
444 void (*complete)(void *handle, int status,
445 bool sync_waiting),
446 void *handle)
447 {
448 int status;
449 uint incr_fix;
450 uint width;
451 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
452 int err = 0;
453
454 ASSERT(card);
455 ASSERT(card->init_success);
456
457 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
458 __func__, fn, addr, nbytes));
459
460 /* Async not implemented yet */
461 ASSERT(!(flags & SDIO_REQ_ASYNC));
462 if (flags & SDIO_REQ_ASYNC)
463 return -ENOTSUPP;
464
465 if (bar0 != card->sbwad) {
466 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
467 if (err)
468 return err;
469
470 card->sbwad = bar0;
471 }
472
473 addr &= SBSDIO_SB_OFT_ADDR_MASK;
474
475 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
476 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
477 if (width == 4)
478 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
479
480 status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
481 incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
482
483 return status;
484 }
485
486 int
487 brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
488 uint flags, u8 *buf, uint nbytes, void *pkt,
489 void (*complete)(void *handle, int status,
490 bool sync_waiting),
491 void *handle)
492 {
493 uint incr_fix;
494 uint width;
495 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
496 int err = 0;
497
498 ASSERT(card);
499 ASSERT(card->init_success);
500
501 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
502 __func__, fn, addr, nbytes));
503
504 /* Async not implemented yet */
505 ASSERT(!(flags & SDIO_REQ_ASYNC));
506 if (flags & SDIO_REQ_ASYNC)
507 return -ENOTSUPP;
508
509 if (bar0 != card->sbwad) {
510 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
511 if (err)
512 return err;
513
514 card->sbwad = bar0;
515 }
516
517 addr &= SBSDIO_SB_OFT_ADDR_MASK;
518
519 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
520 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
521 if (width == 4)
522 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
523
524 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
525 incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
526 }
527
528 int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
529 u8 *buf, uint nbytes)
530 {
531 ASSERT(card);
532 ASSERT(card->init_success);
533 ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
534
535 addr &= SBSDIO_SB_OFT_ADDR_MASK;
536 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
537
538 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
539 SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
540 addr, 4, nbytes, buf, NULL);
541 }
542
543 int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
544 {
545 return brcmf_sdioh_abort(card->sdioh, fn);
546 }
547
548 int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
549 {
550 card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
551 return card->vendevid;
552 }
553
554 uint brcmf_sdcard_query_iofnum(struct brcmf_sdio_card *card)
555 {
556 if (!card)
557 card = l_card;
558
559 return brcmf_sdioh_query_iofnum(card->sdioh);
560 }
561
562 void *brcmf_sdcard_get_sdioh(struct brcmf_sdio_card *card)
563 {
564 ASSERT(card);
565 return card->sdioh;
566 }
567
568 /* Function to pass device-status bits to DHD. */
569 u32 brcmf_sdcard_get_dstatus(struct brcmf_sdio_card *card)
570 {
571 return 0;
572 }
573
574 u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
575 {
576 if (!card)
577 card = l_card;
578
579 return card->sbwad;
580 }
581
582 void brcmf_sdcard_chipinfo(struct brcmf_sdio_card *card, u32 chip, u32 chiprev)
583 {
584 return;
585 }
This page took 0.088408 seconds and 5 git commands to generate.