]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / bcmsdh_sdmmc.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
17 #include <linux/types.h>
18 #include <linux/netdevice.h>
19 #include <linux/mmc/sdio.h>
20 #include <linux/mmc/core.h>
21 #include <linux/mmc/sdio_func.h>
22 #include <linux/mmc/sdio_ids.h>
23 #include <linux/mmc/card.h>
24 #include <linux/suspend.h>
25 #include <linux/errno.h>
26 #include <linux/sched.h>        /* request_irq() */
27 #include <linux/module.h>
28 #include <linux/platform_device.h>
29 #include <linux/platform_data/brcmfmac-sdio.h>
30 #include <net/cfg80211.h>
31
32 #include <defs.h>
33 #include <brcm_hw_ids.h>
34 #include <brcmu_utils.h>
35 #include <brcmu_wifi.h>
36 #include "sdio_host.h"
37 #include "sdio_chip.h"
38 #include "dhd_dbg.h"
39 #include "dhd_bus.h"
40
41 #define SDIO_VENDOR_ID_BROADCOM         0x02d0
42
43 #define DMA_ALIGN_MASK  0x03
44
45 #define SDIO_FUNC1_BLOCKSIZE            64
46 #define SDIO_FUNC2_BLOCKSIZE            512
47
48 /* devices we support, null terminated */
49 static const struct sdio_device_id brcmf_sdmmc_ids[] = {
50         {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)},
51         {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
52         {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
53         {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
54         {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
55         {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
56                      SDIO_DEVICE_ID_BROADCOM_4335_4339)},
57         { /* end: all zeroes */ },
58 };
59 MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
60
61 static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
62
63
64 bool
65 brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
66 {
67         bool is_err = false;
68 #ifdef CONFIG_PM_SLEEP
69         is_err = atomic_read(&sdiodev->suspend);
70 #endif
71         return is_err;
72 }
73
74 void
75 brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
76 {
77 #ifdef CONFIG_PM_SLEEP
78         int retry = 0;
79         while (atomic_read(&sdiodev->suspend) && retry++ != 30)
80                 wait_event_timeout(*wq, false, HZ/100);
81 #endif
82 }
83
84 static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
85                                             uint regaddr, u8 *byte)
86 {
87         struct sdio_func *sdfunc = sdiodev->func[0];
88         int err_ret;
89
90         /*
91          * Can only directly write to some F0 registers.
92          * Handle F2 enable/disable and Abort command
93          * as a special case.
94          */
95         if (regaddr == SDIO_CCCR_IOEx) {
96                 sdfunc = sdiodev->func[2];
97                 if (sdfunc) {
98                         if (*byte & SDIO_FUNC_ENABLE_2) {
99                                 /* Enable Function 2 */
100                                 err_ret = sdio_enable_func(sdfunc);
101                                 if (err_ret)
102                                         brcmf_err("enable F2 failed:%d\n",
103                                                   err_ret);
104                         } else {
105                                 /* Disable Function 2 */
106                                 err_ret = sdio_disable_func(sdfunc);
107                                 if (err_ret)
108                                         brcmf_err("Disable F2 failed:%d\n",
109                                                   err_ret);
110                         }
111                 }
112         } else if ((regaddr == SDIO_CCCR_ABORT) ||
113                    (regaddr == SDIO_CCCR_IENx)) {
114                 sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
115                                  GFP_KERNEL);
116                 if (!sdfunc)
117                         return -ENOMEM;
118                 sdfunc->num = 0;
119                 sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
120                 kfree(sdfunc);
121         } else if (regaddr < 0xF0) {
122                 brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr);
123                 err_ret = -EPERM;
124         } else {
125                 sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
126         }
127
128         return err_ret;
129 }
130
131 int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
132                              uint regaddr, u8 *byte)
133 {
134         int err_ret;
135
136         brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
137
138         brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
139         if (brcmf_pm_resume_error(sdiodev))
140                 return -EIO;
141
142         if (rw && func == 0) {
143                 /* handle F0 separately */
144                 err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
145         } else {
146                 if (rw) /* CMD52 Write */
147                         sdio_writeb(sdiodev->func[func], *byte, regaddr,
148                                     &err_ret);
149                 else if (func == 0) {
150                         *byte = sdio_f0_readb(sdiodev->func[func], regaddr,
151                                               &err_ret);
152                 } else {
153                         *byte = sdio_readb(sdiodev->func[func], regaddr,
154                                            &err_ret);
155                 }
156         }
157
158         if (err_ret)
159                 brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
160                           rw ? "write" : "read", func, regaddr, *byte, err_ret);
161
162         return err_ret;
163 }
164
165 int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
166                              uint rw, uint func, uint addr, u32 *word,
167                              uint nbytes)
168 {
169         int err_ret = -EIO;
170
171         if (func == 0) {
172                 brcmf_err("Only CMD52 allowed to F0\n");
173                 return -EINVAL;
174         }
175
176         brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
177                   rw, func, addr, nbytes);
178
179         brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
180         if (brcmf_pm_resume_error(sdiodev))
181                 return -EIO;
182
183         if (rw) {               /* CMD52 Write */
184                 if (nbytes == 4)
185                         sdio_writel(sdiodev->func[func], *word, addr,
186                                     &err_ret);
187                 else if (nbytes == 2)
188                         sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
189                                     addr, &err_ret);
190                 else
191                         brcmf_err("Invalid nbytes: %d\n", nbytes);
192         } else {                /* CMD52 Read */
193                 if (nbytes == 4)
194                         *word = sdio_readl(sdiodev->func[func], addr, &err_ret);
195                 else if (nbytes == 2)
196                         *word = sdio_readw(sdiodev->func[func], addr,
197                                            &err_ret) & 0xFFFF;
198                 else
199                         brcmf_err("Invalid nbytes: %d\n", nbytes);
200         }
201
202         if (err_ret)
203                 brcmf_err("Failed to %s word, Err: 0x%08x\n",
204                           rw ? "write" : "read", err_ret);
205
206         return err_ret;
207 }
208
209 static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
210 {
211         /* read 24 bits and return valid 17 bit addr */
212         int i, ret;
213         u32 scratch, regdata;
214         __le32 scratch_le;
215         u8 *ptr = (u8 *)&scratch_le;
216
217         for (i = 0; i < 3; i++) {
218                 regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
219                 if (ret != 0)
220                         brcmf_err("Can't read!\n");
221
222                 *ptr++ = (u8) regdata;
223                 regaddr++;
224         }
225
226         /* Only the lower 17-bits are valid */
227         scratch = le32_to_cpu(scratch_le);
228         scratch &= 0x0001FFFF;
229         return scratch;
230 }
231
232 static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
233 {
234         int err_ret;
235         u32 fbraddr;
236         u8 func;
237
238         brcmf_dbg(SDIO, "\n");
239
240         /* Get the Card's common CIS address */
241         sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
242                                                            SDIO_CCCR_CIS);
243         brcmf_dbg(SDIO, "Card's Common CIS Ptr = 0x%x\n",
244                   sdiodev->func_cis_ptr[0]);
245
246         /* Get the Card's function CIS (for each function) */
247         for (fbraddr = SDIO_FBR_BASE(1), func = 1;
248              func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
249                 sdiodev->func_cis_ptr[func] =
250                     brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
251                 brcmf_dbg(SDIO, "Function %d CIS Ptr = 0x%x\n",
252                           func, sdiodev->func_cis_ptr[func]);
253         }
254
255         /* Enable Function 1 */
256         err_ret = sdio_enable_func(sdiodev->func[1]);
257         if (err_ret)
258                 brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret);
259
260         return false;
261 }
262
263 /*
264  *      Public entry points & extern's
265  */
266 int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
267 {
268         int err_ret = 0;
269
270         brcmf_dbg(SDIO, "\n");
271
272         sdiodev->num_funcs = 2;
273
274         sdio_claim_host(sdiodev->func[1]);
275
276         err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
277         if (err_ret) {
278                 brcmf_err("Failed to set F1 blocksize\n");
279                 goto out;
280         }
281
282         err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
283         if (err_ret) {
284                 brcmf_err("Failed to set F2 blocksize\n");
285                 goto out;
286         }
287
288         brcmf_sdioh_enablefuncs(sdiodev);
289
290 out:
291         sdio_release_host(sdiodev->func[1]);
292         brcmf_dbg(SDIO, "Done\n");
293         return err_ret;
294 }
295
296 void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
297 {
298         brcmf_dbg(SDIO, "\n");
299
300         /* Disable Function 2 */
301         sdio_claim_host(sdiodev->func[2]);
302         sdio_disable_func(sdiodev->func[2]);
303         sdio_release_host(sdiodev->func[2]);
304
305         /* Disable Function 1 */
306         sdio_claim_host(sdiodev->func[1]);
307         sdio_disable_func(sdiodev->func[1]);
308         sdio_release_host(sdiodev->func[1]);
309
310 }
311
312 static int brcmf_ops_sdio_probe(struct sdio_func *func,
313                                 const struct sdio_device_id *id)
314 {
315         int err;
316         struct brcmf_sdio_dev *sdiodev;
317         struct brcmf_bus *bus_if;
318
319         brcmf_dbg(SDIO, "Enter\n");
320         brcmf_dbg(SDIO, "Class=%x\n", func->class);
321         brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
322         brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
323         brcmf_dbg(SDIO, "Function#: %d\n", func->num);
324
325         /* Consume func num 1 but dont do anything with it. */
326         if (func->num == 1)
327                 return 0;
328
329         /* Ignore anything but func 2 */
330         if (func->num != 2)
331                 return -ENODEV;
332
333         bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
334         if (!bus_if)
335                 return -ENOMEM;
336         sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
337         if (!sdiodev) {
338                 kfree(bus_if);
339                 return -ENOMEM;
340         }
341
342         sdiodev->func[0] = func->card->sdio_func[0];
343         sdiodev->func[1] = func->card->sdio_func[0];
344         sdiodev->func[2] = func;
345
346         sdiodev->bus_if = bus_if;
347         bus_if->bus_priv.sdio = sdiodev;
348         dev_set_drvdata(&func->dev, bus_if);
349         dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
350         sdiodev->dev = &sdiodev->func[1]->dev;
351         sdiodev->pdata = brcmfmac_sdio_pdata;
352
353         atomic_set(&sdiodev->suspend, false);
354         init_waitqueue_head(&sdiodev->request_byte_wait);
355         init_waitqueue_head(&sdiodev->request_word_wait);
356         init_waitqueue_head(&sdiodev->request_buffer_wait);
357
358         brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
359         err = brcmf_sdio_probe(sdiodev);
360         if (err) {
361                 brcmf_err("F2 error, probe failed %d...\n", err);
362                 goto fail;
363         }
364         brcmf_dbg(SDIO, "F2 init completed...\n");
365         return 0;
366
367 fail:
368         dev_set_drvdata(&func->dev, NULL);
369         dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
370         kfree(sdiodev);
371         kfree(bus_if);
372         return err;
373 }
374
375 static void brcmf_ops_sdio_remove(struct sdio_func *func)
376 {
377         struct brcmf_bus *bus_if;
378         struct brcmf_sdio_dev *sdiodev;
379
380         brcmf_dbg(SDIO, "Enter\n");
381         brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
382         brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
383         brcmf_dbg(SDIO, "Function: %d\n", func->num);
384
385         if (func->num != 1 && func->num != 2)
386                 return;
387
388         bus_if = dev_get_drvdata(&func->dev);
389         if (bus_if) {
390                 sdiodev = bus_if->bus_priv.sdio;
391                 brcmf_sdio_remove(sdiodev);
392
393                 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
394                 dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
395
396                 kfree(bus_if);
397                 kfree(sdiodev);
398         }
399
400         brcmf_dbg(SDIO, "Exit\n");
401 }
402
403 #ifdef CONFIG_PM_SLEEP
404 static int brcmf_sdio_suspend(struct device *dev)
405 {
406         mmc_pm_flag_t sdio_flags;
407         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
408         struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
409         int ret = 0;
410
411         brcmf_dbg(SDIO, "\n");
412
413         atomic_set(&sdiodev->suspend, true);
414
415         sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
416         if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
417                 brcmf_err("Host can't keep power while suspended\n");
418                 return -EINVAL;
419         }
420
421         ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
422         if (ret) {
423                 brcmf_err("Failed to set pm_flags\n");
424                 return ret;
425         }
426
427         brcmf_sdio_wdtmr_enable(sdiodev, false);
428
429         return ret;
430 }
431
432 static int brcmf_sdio_resume(struct device *dev)
433 {
434         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
435         struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
436
437         brcmf_sdio_wdtmr_enable(sdiodev, true);
438         atomic_set(&sdiodev->suspend, false);
439         return 0;
440 }
441
442 static const struct dev_pm_ops brcmf_sdio_pm_ops = {
443         .suspend        = brcmf_sdio_suspend,
444         .resume         = brcmf_sdio_resume,
445 };
446 #endif  /* CONFIG_PM_SLEEP */
447
448 static struct sdio_driver brcmf_sdmmc_driver = {
449         .probe = brcmf_ops_sdio_probe,
450         .remove = brcmf_ops_sdio_remove,
451         .name = BRCMFMAC_SDIO_PDATA_NAME,
452         .id_table = brcmf_sdmmc_ids,
453 #ifdef CONFIG_PM_SLEEP
454         .drv = {
455                 .pm = &brcmf_sdio_pm_ops,
456         },
457 #endif  /* CONFIG_PM_SLEEP */
458 };
459
460 static int brcmf_sdio_pd_probe(struct platform_device *pdev)
461 {
462         brcmf_dbg(SDIO, "Enter\n");
463
464         brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
465
466         if (brcmfmac_sdio_pdata->power_on)
467                 brcmfmac_sdio_pdata->power_on();
468
469         return 0;
470 }
471
472 static int brcmf_sdio_pd_remove(struct platform_device *pdev)
473 {
474         brcmf_dbg(SDIO, "Enter\n");
475
476         if (brcmfmac_sdio_pdata->power_off)
477                 brcmfmac_sdio_pdata->power_off();
478
479         sdio_unregister_driver(&brcmf_sdmmc_driver);
480
481         return 0;
482 }
483
484 static struct platform_driver brcmf_sdio_pd = {
485         .remove         = brcmf_sdio_pd_remove,
486         .driver         = {
487                 .name   = BRCMFMAC_SDIO_PDATA_NAME,
488                 .owner  = THIS_MODULE,
489         }
490 };
491
492 void brcmf_sdio_register(void)
493 {
494         int ret;
495
496         ret = sdio_register_driver(&brcmf_sdmmc_driver);
497         if (ret)
498                 brcmf_err("sdio_register_driver failed: %d\n", ret);
499 }
500
501 void brcmf_sdio_exit(void)
502 {
503         brcmf_dbg(SDIO, "Enter\n");
504
505         if (brcmfmac_sdio_pdata)
506                 platform_driver_unregister(&brcmf_sdio_pd);
507         else
508                 sdio_unregister_driver(&brcmf_sdmmc_driver);
509 }
510
511 void __init brcmf_sdio_init(void)
512 {
513         int ret;
514
515         brcmf_dbg(SDIO, "Enter\n");
516
517         ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
518         if (ret == -ENODEV)
519                 brcmf_dbg(SDIO, "No platform data available.\n");
520 }