]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
brcmfmac: Fix race condition in msgbuf ioctl processing.
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / brcm80211 / brcmfmac / bcmsdh.c
CommitLineData
5b435de0
AS
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.h>
21#include <linux/pci_ids.h>
22#include <linux/sched.h>
23#include <linux/completion.h>
354b75bf 24#include <linux/scatterlist.h>
5b435de0 25#include <linux/mmc/sdio.h>
e2dc9eea 26#include <linux/mmc/core.h>
5b435de0
AS
27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/card.h>
e2dc9eea
AS
29#include <linux/mmc/host.h>
30#include <linux/platform_device.h>
668761ac 31#include <linux/platform_data/brcmfmac-sdio.h>
e2dc9eea
AS
32#include <linux/suspend.h>
33#include <linux/errno.h>
34#include <linux/module.h>
35#include <net/cfg80211.h>
5b435de0
AS
36
37#include <defs.h>
38#include <brcm_hw_ids.h>
39#include <brcmu_utils.h>
40#include <brcmu_wifi.h>
568ba389 41#include <chipcommon.h>
5b435de0 42#include <soc.h>
568ba389 43#include "chip.h"
d14f78b9 44#include "bus.h"
a8e8ed34 45#include "debug.h"
888bf76e 46#include "sdio.h"
61f663df 47#include "of.h"
5b435de0
AS
48
49#define SDIOH_API_ACCESS_RETRY_LIMIT 2
50
e49b06ba
AS
51#define DMA_ALIGN_MASK 0x03
52
53#define SDIO_FUNC1_BLOCKSIZE 64
54#define SDIO_FUNC2_BLOCKSIZE 512
71370eb8
AS
55/* Maximum milliseconds to wait for F2 to come up */
56#define SDIO_WAIT_F2RDY 3000
57
af1fa210
AS
58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
60
99824643
AS
61struct brcmf_sdiod_freezer {
62 atomic_t freezing;
63 atomic_t thread_count;
64 u32 frozen_count;
65 wait_queue_head_t thread_freeze;
66 struct completion resumed;
67};
68
af1fa210
AS
69static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
70module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
71MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
668761ac 72
a39be27b 73static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
ba89bf19 74{
5b3c1832
HM
75 struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
76 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
ba89bf19 77
668761ac 78 brcmf_dbg(INTR, "OOB intr triggered\n");
ba89bf19 79
668761ac 80 /* out-of-band interrupt is level-triggered which won't
ba89bf19
FL
81 * be cleared until dpc
82 */
83 if (sdiodev->irq_en) {
84 disable_irq_nosync(irq);
85 sdiodev->irq_en = false;
86 }
87
82d7f3c1 88 brcmf_sdio_isr(sdiodev->bus);
ba89bf19
FL
89
90 return IRQ_HANDLED;
91}
92
a39be27b 93static void brcmf_sdiod_ib_irqhandler(struct sdio_func *func)
5b435de0 94{
5b3c1832
HM
95 struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
96 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
5b435de0 97
668761ac 98 brcmf_dbg(INTR, "IB intr triggered\n");
5b435de0 99
82d7f3c1 100 brcmf_sdio_isr(sdiodev->bus);
5b435de0
AS
101}
102
fbf59108 103/* dummy handler for SDIO function 2 interrupt */
a39be27b 104static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func)
fbf59108
FL
105{
106}
107
a39be27b 108int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
5b435de0 109{
668761ac
HM
110 int ret = 0;
111 u8 data;
568ba389 112 u32 addr, gpiocontrol;
668761ac 113 unsigned long flags;
5b435de0 114
668761ac
HM
115 if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
116 brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
117 sdiodev->pdata->oob_irq_nr);
118 ret = request_irq(sdiodev->pdata->oob_irq_nr,
a39be27b 119 brcmf_sdiod_oob_irqhandler,
668761ac
HM
120 sdiodev->pdata->oob_irq_flags,
121 "brcmf_oob_intr",
122 &sdiodev->func[1]->dev);
123 if (ret != 0) {
124 brcmf_err("request_irq failed %d\n", ret);
125 return ret;
126 }
127 sdiodev->oob_irq_requested = true;
128 spin_lock_init(&sdiodev->irq_en_lock);
129 spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
130 sdiodev->irq_en = true;
131 spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
132
133 ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr);
134 if (ret != 0) {
135 brcmf_err("enable_irq_wake failed %d\n", ret);
136 return ret;
137 }
138 sdiodev->irq_wake = true;
139
140 sdio_claim_host(sdiodev->func[1]);
141
568ba389
HG
142 if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
143 /* assign GPIO to SDIO core */
144 addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
145 gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret);
146 gpiocontrol |= 0x2;
147 brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
148
149 brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
150 &ret);
151 brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
152 brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
153 }
154
668761ac 155 /* must configure SDIO_CCCR_IENx to enable irq */
a39be27b 156 data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
668761ac 157 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
a39be27b 158 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
668761ac
HM
159
160 /* redirect, configure and enable io for interrupt signal */
161 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
162 if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
163 data |= SDIO_SEPINT_ACT_HI;
a39be27b 164 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
668761ac
HM
165
166 sdio_release_host(sdiodev->func[1]);
167 } else {
168 brcmf_dbg(SDIO, "Entering\n");
169 sdio_claim_host(sdiodev->func[1]);
a39be27b
AS
170 sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
171 sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
668761ac
HM
172 sdio_release_host(sdiodev->func[1]);
173 }
5b435de0
AS
174
175 return 0;
176}
177
a39be27b 178int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
5b435de0 179{
c3203374 180 brcmf_dbg(SDIO, "Entering\n");
5b435de0 181
668761ac
HM
182 if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
183 sdio_claim_host(sdiodev->func[1]);
a39be27b
AS
184 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
185 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
668761ac
HM
186 sdio_release_host(sdiodev->func[1]);
187
188 if (sdiodev->oob_irq_requested) {
189 sdiodev->oob_irq_requested = false;
190 if (sdiodev->irq_wake) {
191 disable_irq_wake(sdiodev->pdata->oob_irq_nr);
192 sdiodev->irq_wake = false;
193 }
194 free_irq(sdiodev->pdata->oob_irq_nr,
195 &sdiodev->func[1]->dev);
196 sdiodev->irq_en = false;
197 }
198 } else {
199 sdio_claim_host(sdiodev->func[1]);
200 sdio_release_irq(sdiodev->func[2]);
201 sdio_release_irq(sdiodev->func[1]);
202 sdio_release_host(sdiodev->func[1]);
203 }
5b435de0
AS
204
205 return 0;
206}
207
a1ce7a0d
AS
208void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
209 enum brcmf_sdiod_state state)
210{
211 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
212 state == sdiodev->state)
213 return;
214
215 brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
216 switch (sdiodev->state) {
217 case BRCMF_SDIOD_DATA:
218 /* any other state means bus interface is down */
219 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
220 break;
221 case BRCMF_SDIOD_DOWN:
222 /* transition from DOWN to DATA means bus interface is up */
223 if (state == BRCMF_SDIOD_DATA)
224 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);
225 break;
226 default:
227 break;
228 }
229 sdiodev->state = state;
230}
231
36c4e7e4
AS
232static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
233 uint regaddr, u8 byte)
e49b06ba 234{
e49b06ba
AS
235 int err_ret;
236
237 /*
238 * Can only directly write to some F0 registers.
36c4e7e4 239 * Handle CCCR_IENx and CCCR_ABORT command
e49b06ba
AS
240 * as a special case.
241 */
71370eb8 242 if ((regaddr == SDIO_CCCR_ABORT) ||
36c4e7e4
AS
243 (regaddr == SDIO_CCCR_IENx))
244 sdio_writeb(func, byte, regaddr, &err_ret);
245 else
246 sdio_f0_writeb(func, byte, regaddr, &err_ret);
e49b06ba
AS
247
248 return err_ret;
249}
250
71c60cf2
AS
251static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
252 u32 addr, u8 regsz, void *data, bool write)
e49b06ba 253{
71c60cf2
AS
254 struct sdio_func *func;
255 int ret;
e49b06ba 256
71c60cf2
AS
257 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
258 write, fn, addr, regsz);
e49b06ba 259
71c60cf2
AS
260 /* only allow byte access on F0 */
261 if (WARN_ON(regsz > 1 && !fn))
262 return -EINVAL;
263 func = sdiodev->func[fn];
264
265 switch (regsz) {
266 case sizeof(u8):
267 if (write) {
268 if (fn)
269 sdio_writeb(func, *(u8 *)data, addr, &ret);
270 else
271 ret = brcmf_sdiod_f0_writeb(func, addr,
272 *(u8 *)data);
e49b06ba 273 } else {
71c60cf2
AS
274 if (fn)
275 *(u8 *)data = sdio_readb(func, addr, &ret);
276 else
277 *(u8 *)data = sdio_f0_readb(func, addr, &ret);
e49b06ba 278 }
71c60cf2
AS
279 break;
280 case sizeof(u16):
281 if (write)
282 sdio_writew(func, *(u16 *)data, addr, &ret);
283 else
284 *(u16 *)data = sdio_readw(func, addr, &ret);
285 break;
286 case sizeof(u32):
287 if (write)
288 sdio_writel(func, *(u32 *)data, addr, &ret);
289 else
290 *(u32 *)data = sdio_readl(func, addr, &ret);
291 break;
292 default:
293 brcmf_err("invalid size: %d\n", regsz);
294 break;
e49b06ba
AS
295 }
296
4d1a4f16
AS
297 if (ret)
298 brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
299 write ? "write" : "read", fn, addr, ret);
300
71c60cf2 301 return ret;
e49b06ba
AS
302}
303
71c60cf2
AS
304static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
305 u8 regsz, void *data, bool write)
e49b06ba 306{
4d1a4f16 307 u8 func;
71c60cf2
AS
308 s32 retry = 0;
309 int ret;
e49b06ba 310
a1ce7a0d 311 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
bb350711
AS
312 return -ENOMEDIUM;
313
71c60cf2
AS
314 /*
315 * figure out how to read the register based on address range
316 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
317 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
318 * The rest: function 1 silicon backplane core registers
319 */
320 if ((addr & ~REG_F0_REG_MASK) == 0)
4d1a4f16 321 func = SDIO_FUNC_0;
71c60cf2 322 else
4d1a4f16 323 func = SDIO_FUNC_1;
e49b06ba 324
71c60cf2
AS
325 do {
326 if (!write)
327 memset(data, 0, regsz);
328 /* for retry wait for 1 ms till bus get settled down */
329 if (retry)
330 usleep_range(1000, 2000);
4d1a4f16 331 ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
71c60cf2 332 data, write);
bb350711
AS
333 } while (ret != 0 && ret != -ENOMEDIUM &&
334 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
e49b06ba 335
bb350711 336 if (ret == -ENOMEDIUM)
a1ce7a0d 337 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
4d1a4f16
AS
338 else if (ret != 0) {
339 /*
340 * SleepCSR register access can fail when
341 * waking up the device so reduce this noise
342 * in the logs.
343 */
344 if (addr != SBSDIO_FUNC1_SLEEPCSR)
345 brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
346 write ? "write" : "read", func, addr, ret);
347 else
348 brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
349 write ? "write" : "read", func, addr, ret);
350 }
71c60cf2 351 return ret;
e49b06ba
AS
352}
353
356bae6f 354static int
a39be27b 355brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
5b435de0 356{
7d9cfc28
FL
357 int err = 0, i;
358 u8 addr[3];
7d9cfc28 359
a1ce7a0d 360 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
bb350711
AS
361 return -ENOMEDIUM;
362
7d9cfc28
FL
363 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
364 addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
365 addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
366
367 for (i = 0; i < 3; i++) {
71c60cf2
AS
368 err = brcmf_sdiod_regrw_helper(sdiodev,
369 SBSDIO_FUNC1_SBADDRLOW + i,
370 sizeof(u8), &addr[i], true);
7d9cfc28 371 if (err) {
71c60cf2 372 brcmf_err("failed at addr: 0x%0x\n",
7d9cfc28
FL
373 SBSDIO_FUNC1_SBADDRLOW + i);
374 break;
375 }
376 }
5b435de0
AS
377
378 return err;
379}
380
356bae6f 381static int
a39be27b 382brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
356bae6f
FL
383{
384 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
385 int err = 0;
386
387 if (bar0 != sdiodev->sbwad) {
a39be27b 388 err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
356bae6f
FL
389 if (err)
390 return err;
391
392 sdiodev->sbwad = bar0;
393 }
394
395 *addr &= SBSDIO_SB_OFT_ADDR_MASK;
396
397 if (width == 4)
398 *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
399
400 return 0;
401}
402
a39be27b 403u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
e9b8d91d
FL
404{
405 u8 data;
406 int retval;
407
c3203374 408 brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
71c60cf2
AS
409 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
410 false);
c3203374 411 brcmf_dbg(SDIO, "data:0x%02x\n", data);
e9b8d91d
FL
412
413 if (ret)
414 *ret = retval;
415
416 return data;
417}
418
a39be27b 419u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
e9b8d91d
FL
420{
421 u32 data;
422 int retval;
423
c3203374 424 brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
71c60cf2
AS
425 retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
426 if (retval)
427 goto done;
428 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
429 false);
c3203374 430 brcmf_dbg(SDIO, "data:0x%08x\n", data);
e9b8d91d 431
71c60cf2 432done:
e9b8d91d
FL
433 if (ret)
434 *ret = retval;
435
436 return data;
437}
438
a39be27b 439void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
e9b8d91d
FL
440 u8 data, int *ret)
441{
442 int retval;
443
c3203374 444 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
71c60cf2
AS
445 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
446 true);
e9b8d91d
FL
447 if (ret)
448 *ret = retval;
449}
450
a39be27b 451void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
e9b8d91d
FL
452 u32 data, int *ret)
453{
454 int retval;
455
c3203374 456 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
71c60cf2
AS
457 retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
458 if (retval)
459 goto done;
460 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
461 true);
e9b8d91d 462
71c60cf2 463done:
e9b8d91d
FL
464 if (ret)
465 *ret = retval;
466}
467
a39be27b 468static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
4aef267e
AS
469 bool write, u32 addr, struct sk_buff *pkt)
470{
471 unsigned int req_sz;
bb350711 472 int err;
4aef267e 473
4aef267e
AS
474 /* Single skb use the standard mmc interface */
475 req_sz = pkt->len + 3;
476 req_sz &= (uint)~3;
477
478 if (write)
bb350711
AS
479 err = sdio_memcpy_toio(sdiodev->func[fn], addr,
480 ((u8 *)(pkt->data)), req_sz);
4aef267e 481 else if (fn == 1)
bb350711
AS
482 err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)),
483 addr, req_sz);
4aef267e
AS
484 else
485 /* function 2 read is FIFO operation */
bb350711
AS
486 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
487 req_sz);
488 if (err == -ENOMEDIUM)
a1ce7a0d 489 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
bb350711 490 return err;
4aef267e
AS
491}
492
78b3f1c5 493/**
a39be27b 494 * brcmf_sdiod_sglist_rw - SDIO interface function for block data access
78b3f1c5
FL
495 * @sdiodev: brcmfmac sdio device
496 * @fn: SDIO function number
497 * @write: direction flag
498 * @addr: dongle memory address as source/destination
499 * @pkt: skb pointer
500 *
501 * This function takes the respbonsibility as the interface function to MMC
502 * stack for block data access. It assumes that the skb passed down by the
503 * caller has already been padded and aligned.
504 */
a39be27b
AS
505static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
506 bool write, u32 addr,
507 struct sk_buff_head *pktlist)
78b3f1c5 508{
354b75bf 509 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
71201496 510 unsigned int max_req_sz, orig_offset, dst_offset;
3f782744 511 unsigned short max_seg_cnt, seg_sz;
3b81a680
FL
512 unsigned char *pkt_data, *orig_data, *dst_data;
513 struct sk_buff *pkt_next = NULL, *local_pkt_next;
514 struct sk_buff_head local_list, *target_list;
354b75bf
FL
515 struct mmc_request mmc_req;
516 struct mmc_command mmc_cmd;
517 struct mmc_data mmc_dat;
354b75bf 518 struct scatterlist *sgl;
354b75bf
FL
519 int ret = 0;
520
521 if (!pktlist->qlen)
522 return -EINVAL;
78b3f1c5 523
3b81a680
FL
524 target_list = pktlist;
525 /* for host with broken sg support, prepare a page aligned list */
526 __skb_queue_head_init(&local_list);
527 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
528 req_sz = 0;
529 skb_queue_walk(pktlist, pkt_next)
530 req_sz += pkt_next->len;
531 req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
532 while (req_sz > PAGE_SIZE) {
533 pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
534 if (pkt_next == NULL) {
535 ret = -ENOMEM;
536 goto exit;
537 }
538 __skb_queue_tail(&local_list, pkt_next);
539 req_sz -= PAGE_SIZE;
540 }
541 pkt_next = brcmu_pkt_buf_get_skb(req_sz);
542 if (pkt_next == NULL) {
543 ret = -ENOMEM;
544 goto exit;
545 }
546 __skb_queue_tail(&local_list, pkt_next);
547 target_list = &local_list;
548 }
549
354b75bf 550 func_blk_sz = sdiodev->func[fn]->cur_blksize;
71201496
AS
551 max_req_sz = sdiodev->max_request_size;
552 max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,
553 target_list->qlen);
3b81a680 554 seg_sz = target_list->qlen;
354b75bf 555 pkt_offset = 0;
3b81a680 556 pkt_next = target_list->next;
354b75bf 557
7f9a8dc8
AS
558 memset(&mmc_req, 0, sizeof(struct mmc_request));
559 memset(&mmc_cmd, 0, sizeof(struct mmc_command));
560 memset(&mmc_dat, 0, sizeof(struct mmc_data));
561
af1fa210 562 mmc_dat.sg = sdiodev->sgtable.sgl;
7f9a8dc8
AS
563 mmc_dat.blksz = func_blk_sz;
564 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
565 mmc_cmd.opcode = SD_IO_RW_EXTENDED;
566 mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */
567 mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */
568 mmc_cmd.arg |= 1<<27; /* block mode */
569 /* for function 1 the addr will be incremented */
570 mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
571 mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
572 mmc_req.cmd = &mmc_cmd;
573 mmc_req.data = &mmc_dat;
574
354b75bf
FL
575 while (seg_sz) {
576 req_sz = 0;
577 sg_cnt = 0;
af1fa210 578 sgl = sdiodev->sgtable.sgl;
354b75bf 579 /* prep sg table */
3b81a680 580 while (pkt_next != (struct sk_buff *)target_list) {
354b75bf
FL
581 pkt_data = pkt_next->data + pkt_offset;
582 sg_data_sz = pkt_next->len - pkt_offset;
71201496
AS
583 if (sg_data_sz > sdiodev->max_segment_size)
584 sg_data_sz = sdiodev->max_segment_size;
354b75bf
FL
585 if (sg_data_sz > max_req_sz - req_sz)
586 sg_data_sz = max_req_sz - req_sz;
587
588 sg_set_buf(sgl, pkt_data, sg_data_sz);
589
590 sg_cnt++;
591 sgl = sg_next(sgl);
592 req_sz += sg_data_sz;
593 pkt_offset += sg_data_sz;
594 if (pkt_offset == pkt_next->len) {
595 pkt_offset = 0;
596 pkt_next = pkt_next->next;
597 }
598
3f782744 599 if (req_sz >= max_req_sz || sg_cnt >= max_seg_cnt)
354b75bf
FL
600 break;
601 }
602 seg_sz -= sg_cnt;
603
604 if (req_sz % func_blk_sz != 0) {
605 brcmf_err("sg request length %u is not %u aligned\n",
606 req_sz, func_blk_sz);
3b81a680
FL
607 ret = -ENOTBLK;
608 goto exit;
354b75bf 609 }
7f9a8dc8 610
354b75bf 611 mmc_dat.sg_len = sg_cnt;
354b75bf 612 mmc_dat.blocks = req_sz / func_blk_sz;
354b75bf
FL
613 mmc_cmd.arg |= (addr & 0x1FFFF) << 9; /* address */
614 mmc_cmd.arg |= mmc_dat.blocks & 0x1FF; /* block count */
7f9a8dc8 615 /* incrementing addr for function 1 */
354b75bf
FL
616 if (fn == 1)
617 addr += req_sz;
618
619 mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
71201496 620 mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
354b75bf
FL
621
622 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
bb350711 623 if (ret == -ENOMEDIUM) {
a1ce7a0d 624 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
bb350711
AS
625 break;
626 } else if (ret != 0) {
354b75bf
FL
627 brcmf_err("CMD53 sg block %s failed %d\n",
628 write ? "write" : "read", ret);
629 ret = -EIO;
630 break;
631 }
632 }
633
3b81a680
FL
634 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
635 local_pkt_next = local_list.next;
636 orig_offset = 0;
637 skb_queue_walk(pktlist, pkt_next) {
638 dst_offset = 0;
639 do {
640 req_sz = local_pkt_next->len - orig_offset;
641 req_sz = min_t(uint, pkt_next->len - dst_offset,
642 req_sz);
643 orig_data = local_pkt_next->data + orig_offset;
644 dst_data = pkt_next->data + dst_offset;
645 memcpy(dst_data, orig_data, req_sz);
646 orig_offset += req_sz;
647 dst_offset += req_sz;
648 if (orig_offset == local_pkt_next->len) {
649 orig_offset = 0;
650 local_pkt_next = local_pkt_next->next;
651 }
652 if (dst_offset == pkt_next->len)
653 break;
654 } while (!skb_queue_empty(&local_list));
655 }
656 }
657
658exit:
af1fa210 659 sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
3b81a680
FL
660 while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
661 brcmu_pkt_buf_free_skb(pkt_next);
354b75bf
FL
662
663 return ret;
78b3f1c5
FL
664}
665
a7cdd821 666int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
5adfeb63
AS
667{
668 struct sk_buff *mypkt;
669 int err;
670
671 mypkt = brcmu_pkt_buf_get_skb(nbytes);
672 if (!mypkt) {
5e8149f5 673 brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
5adfeb63
AS
674 nbytes);
675 return -EIO;
676 }
677
a7cdd821 678 err = brcmf_sdiod_recv_pkt(sdiodev, mypkt);
5adfeb63
AS
679 if (!err)
680 memcpy(buf, mypkt->data, nbytes);
681
682 brcmu_pkt_buf_free_skb(mypkt);
683 return err;
684}
685
a7cdd821 686int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
5adfeb63 687{
a7cdd821 688 u32 addr = sdiodev->sbwad;
5adfeb63
AS
689 int err = 0;
690
a7cdd821 691 brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
5adfeb63 692
a7cdd821 693 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
5adfeb63 694 if (err)
7057fd00 695 goto done;
5b435de0 696
a7cdd821 697 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt);
5adfeb63 698
7057fd00 699done:
5adfeb63
AS
700 return err;
701}
702
a7cdd821
AS
703int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
704 struct sk_buff_head *pktq, uint totlen)
5adfeb63 705{
a413e39a
AS
706 struct sk_buff *glom_skb;
707 struct sk_buff *skb;
a7cdd821 708 u32 addr = sdiodev->sbwad;
5adfeb63
AS
709 int err = 0;
710
a7cdd821
AS
711 brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
712 addr, pktq->qlen);
5adfeb63 713
a7cdd821 714 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
5adfeb63 715 if (err)
7057fd00 716 goto done;
5b435de0 717
a413e39a 718 if (pktq->qlen == 1)
a7cdd821
AS
719 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
720 pktq->next);
a413e39a
AS
721 else if (!sdiodev->sg_support) {
722 glom_skb = brcmu_pkt_buf_get_skb(totlen);
723 if (!glom_skb)
724 return -ENOMEM;
a7cdd821
AS
725 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
726 glom_skb);
a413e39a
AS
727 if (err)
728 goto done;
729
730 skb_queue_walk(pktq, skb) {
731 memcpy(skb->data, glom_skb->data, skb->len);
732 skb_pull(glom_skb, skb->len);
733 }
734 } else
a7cdd821
AS
735 err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr,
736 pktq);
5b435de0 737
7057fd00 738done:
5adfeb63 739 return err;
5b435de0
AS
740}
741
a7cdd821 742int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
5adfeb63
AS
743{
744 struct sk_buff *mypkt;
a7cdd821 745 u32 addr = sdiodev->sbwad;
5adfeb63
AS
746 int err;
747
748 mypkt = brcmu_pkt_buf_get_skb(nbytes);
749 if (!mypkt) {
5e8149f5 750 brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
5adfeb63
AS
751 nbytes);
752 return -EIO;
753 }
754
755 memcpy(mypkt->data, buf, nbytes);
4aef267e 756
a7cdd821 757 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
4aef267e 758
fcaac2b1 759 if (!err)
a7cdd821
AS
760 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
761 mypkt);
5adfeb63
AS
762
763 brcmu_pkt_buf_free_skb(mypkt);
764 return err;
765
766}
767
a7cdd821
AS
768int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
769 struct sk_buff_head *pktq)
5b435de0 770{
c8cce1f9 771 struct sk_buff *skb;
a7cdd821 772 u32 addr = sdiodev->sbwad;
fcaac2b1 773 int err;
5b435de0 774
a7cdd821 775 brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
5b435de0 776
a7cdd821 777 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
fcaac2b1
AS
778 if (err)
779 return err;
5b435de0 780
c8cce1f9
AS
781 if (pktq->qlen == 1 || !sdiodev->sg_support)
782 skb_queue_walk(pktq, skb) {
a7cdd821
AS
783 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true,
784 addr, skb);
c8cce1f9
AS
785 if (err)
786 break;
787 }
788 else
a7cdd821
AS
789 err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
790 pktq);
c8cce1f9
AS
791
792 return err;
5b435de0
AS
793}
794
ba540b01 795int
a39be27b
AS
796brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
797 u8 *data, uint size)
5b435de0 798{
ba540b01
FL
799 int bcmerror = 0;
800 struct sk_buff *pkt;
801 u32 sdaddr;
802 uint dsize;
803
804 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
805 pkt = dev_alloc_skb(dsize);
806 if (!pkt) {
807 brcmf_err("dev_alloc_skb failed: len %d\n", dsize);
808 return -EIO;
809 }
810 pkt->priority = 0;
4c6e869d 811
ba540b01
FL
812 /* Determine initial transfer parameters */
813 sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
814 if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
815 dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
816 else
817 dsize = size;
5b435de0 818
ba540b01
FL
819 sdio_claim_host(sdiodev->func[1]);
820
821 /* Do the transfer(s) */
822 while (size) {
823 /* Set the backplane window to include the start address */
a39be27b 824 bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
ba540b01
FL
825 if (bcmerror)
826 break;
827
828 brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
829 write ? "write" : "read", dsize,
830 sdaddr, address & SBSDIO_SBWINDOW_MASK);
831
832 sdaddr &= SBSDIO_SB_OFT_ADDR_MASK;
833 sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
834
835 skb_put(pkt, dsize);
836 if (write)
837 memcpy(pkt->data, data, dsize);
a39be27b
AS
838 bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write,
839 sdaddr, pkt);
ba540b01
FL
840 if (bcmerror) {
841 brcmf_err("membytes transfer failed\n");
842 break;
843 }
844 if (!write)
845 memcpy(data, pkt->data, dsize);
79c868e5 846 skb_trim(pkt, 0);
ba540b01
FL
847
848 /* Adjust for next transfer (if any) */
849 size -= dsize;
850 if (size) {
851 data += dsize;
852 address += dsize;
853 sdaddr = 0;
854 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
855 }
4c6e869d
AS
856 }
857
ba540b01 858 dev_kfree_skb(pkt);
4c6e869d 859
ba540b01 860 /* Return the window to backplane enumeration space for core access */
a39be27b 861 if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad))
ba540b01
FL
862 brcmf_err("FAILED to set window back to 0x%x\n",
863 sdiodev->sbwad);
4c6e869d 864
ba540b01 865 sdio_release_host(sdiodev->func[1]);
4c6e869d 866
ba540b01 867 return bcmerror;
5b435de0
AS
868}
869
a39be27b 870int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
5b435de0
AS
871{
872 char t_func = (char)fn;
c3203374 873 brcmf_dbg(SDIO, "Enter\n");
5b435de0
AS
874
875 /* issue abort cmd52 command through F0 */
71c60cf2
AS
876 brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
877 sizeof(t_func), &t_func, true);
5b435de0 878
c3203374 879 brcmf_dbg(SDIO, "Exit\n");
5b435de0
AS
880 return 0;
881}
882
af1fa210
AS
883static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
884{
885 uint nents;
886 int err;
887
888 if (!sdiodev->sg_support)
889 return;
890
891 nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
892 nents += (nents >> 4) + 1;
893
894 WARN_ON(nents > sdiodev->max_segment_count);
895
896 brcmf_dbg(TRACE, "nents=%d\n", nents);
897 err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
898 if (err < 0) {
899 brcmf_err("allocation failed: disable scatter-gather");
900 sdiodev->sg_support = false;
901 }
902
903 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
904}
905
99824643
AS
906#ifdef CONFIG_PM_SLEEP
907static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
908{
909 sdiodev->freezer = kzalloc(sizeof(*sdiodev->freezer), GFP_KERNEL);
910 if (!sdiodev->freezer)
911 return -ENOMEM;
912 atomic_set(&sdiodev->freezer->thread_count, 0);
913 atomic_set(&sdiodev->freezer->freezing, 0);
914 init_waitqueue_head(&sdiodev->freezer->thread_freeze);
915 init_completion(&sdiodev->freezer->resumed);
916 return 0;
917}
918
919static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
920{
921 if (sdiodev->freezer) {
922 WARN_ON(atomic_read(&sdiodev->freezer->freezing));
923 kfree(sdiodev->freezer);
924 }
925}
926
927static int brcmf_sdiod_freezer_on(struct brcmf_sdio_dev *sdiodev)
928{
929 atomic_t *expect = &sdiodev->freezer->thread_count;
930 int res = 0;
931
932 sdiodev->freezer->frozen_count = 0;
933 reinit_completion(&sdiodev->freezer->resumed);
934 atomic_set(&sdiodev->freezer->freezing, 1);
935 brcmf_sdio_trigger_dpc(sdiodev->bus);
936 wait_event(sdiodev->freezer->thread_freeze,
937 atomic_read(expect) == sdiodev->freezer->frozen_count);
938 sdio_claim_host(sdiodev->func[1]);
939 res = brcmf_sdio_sleep(sdiodev->bus, true);
940 sdio_release_host(sdiodev->func[1]);
941 return res;
942}
943
944static void brcmf_sdiod_freezer_off(struct brcmf_sdio_dev *sdiodev)
945{
946 sdio_claim_host(sdiodev->func[1]);
947 brcmf_sdio_sleep(sdiodev->bus, false);
948 sdio_release_host(sdiodev->func[1]);
949 atomic_set(&sdiodev->freezer->freezing, 0);
950 complete_all(&sdiodev->freezer->resumed);
951}
952
953bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
954{
955 return atomic_read(&sdiodev->freezer->freezing);
956}
957
958void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
959{
960 if (!brcmf_sdiod_freezing(sdiodev))
961 return;
962 sdiodev->freezer->frozen_count++;
963 wake_up(&sdiodev->freezer->thread_freeze);
964 wait_for_completion(&sdiodev->freezer->resumed);
965}
966
967void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
968{
969 atomic_inc(&sdiodev->freezer->thread_count);
970}
971
972void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
973{
974 atomic_dec(&sdiodev->freezer->thread_count);
975}
976#else
977static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
978{
979 return 0;
980}
981
982static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
983{
984}
985#endif /* CONFIG_PM_SLEEP */
986
a39be27b
AS
987static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
988{
a39be27b 989 if (sdiodev->bus) {
9fbe2a6d 990 brcmf_sdio_remove(sdiodev->bus);
a39be27b
AS
991 sdiodev->bus = NULL;
992 }
993
99824643
AS
994 brcmf_sdiod_freezer_detach(sdiodev);
995
a39be27b
AS
996 /* Disable Function 2 */
997 sdio_claim_host(sdiodev->func[2]);
998 sdio_disable_func(sdiodev->func[2]);
999 sdio_release_host(sdiodev->func[2]);
1000
1001 /* Disable Function 1 */
1002 sdio_claim_host(sdiodev->func[1]);
1003 sdio_disable_func(sdiodev->func[1]);
1004 sdio_release_host(sdiodev->func[1]);
1005
af1fa210 1006 sg_free_table(&sdiodev->sgtable);
a39be27b
AS
1007 sdiodev->sbwad = 0;
1008
1009 return 0;
1010}
1011
1012static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
e2dc9eea 1013{
e2dc9eea 1014 struct sdio_func *func;
a39be27b 1015 struct mmc_host *host;
e2dc9eea 1016 uint max_blocks;
a39be27b 1017 int ret = 0;
e2dc9eea
AS
1018
1019 sdiodev->num_funcs = 2;
1020
1021 sdio_claim_host(sdiodev->func[1]);
1022
a39be27b
AS
1023 ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
1024 if (ret) {
e2dc9eea 1025 brcmf_err("Failed to set F1 blocksize\n");
a39be27b 1026 sdio_release_host(sdiodev->func[1]);
e2dc9eea
AS
1027 goto out;
1028 }
a39be27b
AS
1029 ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
1030 if (ret) {
e2dc9eea 1031 brcmf_err("Failed to set F2 blocksize\n");
a39be27b 1032 sdio_release_host(sdiodev->func[1]);
e2dc9eea
AS
1033 goto out;
1034 }
1035
71370eb8
AS
1036 /* increase F2 timeout */
1037 sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY;
1038
463c30b3 1039 /* Enable Function 1 */
a39be27b
AS
1040 ret = sdio_enable_func(sdiodev->func[1]);
1041 sdio_release_host(sdiodev->func[1]);
1042 if (ret) {
1043 brcmf_err("Failed to enable F1: err=%d\n", ret);
463c30b3
AS
1044 goto out;
1045 }
e2dc9eea
AS
1046
1047 /*
a39be27b 1048 * determine host related variables after brcmf_sdiod_probe()
e2dc9eea
AS
1049 * as func->cur_blksize is properly set and F2 init has been
1050 * completed successfully.
1051 */
1052 func = sdiodev->func[2];
1053 host = func->card->host;
1054 sdiodev->sg_support = host->max_segs > 1;
1055 max_blocks = min_t(uint, host->max_blk_count, 511u);
1056 sdiodev->max_request_size = min_t(uint, host->max_req_size,
1057 max_blocks * func->cur_blksize);
1058 sdiodev->max_segment_count = min_t(uint, host->max_segs,
1059 SG_MAX_SINGLE_ALLOC);
1060 sdiodev->max_segment_size = host->max_seg_size;
e49b06ba 1061
af1fa210
AS
1062 /* allocate scatter-gather table. sg support
1063 * will be disabled upon allocation failure.
1064 */
1065 brcmf_sdiod_sgtable_alloc(sdiodev);
1066
99824643
AS
1067 ret = brcmf_sdiod_freezer_attach(sdiodev);
1068 if (ret)
1069 goto out;
1070
e49b06ba 1071 /* try to attach to the target device */
82d7f3c1 1072 sdiodev->bus = brcmf_sdio_probe(sdiodev);
e49b06ba 1073 if (!sdiodev->bus) {
e49b06ba
AS
1074 ret = -ENODEV;
1075 goto out;
1076 }
1077
1078out:
1079 if (ret)
a39be27b 1080 brcmf_sdiod_remove(sdiodev);
e49b06ba
AS
1081
1082 return ret;
1083}
1084
5779ae6a 1085#define BRCMF_SDIO_DEVICE(dev_id) \
8bd61f8d 1086 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, dev_id)}
5779ae6a 1087
e49b06ba
AS
1088/* devices we support, null terminated */
1089static const struct sdio_device_id brcmf_sdmmc_ids[] = {
8bd61f8d
AS
1090 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43143),
1091 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43241),
1092 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4329),
1093 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4330),
1094 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4334),
1095 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340),
1096 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
1097 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
1098 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
1099 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
5779ae6a 1100 { /* end: all zeroes */ }
e49b06ba
AS
1101};
1102MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
1103
1104static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
1105
1106
e2dc9eea
AS
1107static int brcmf_ops_sdio_probe(struct sdio_func *func,
1108 const struct sdio_device_id *id)
1109{
1110 int err;
1111 struct brcmf_sdio_dev *sdiodev;
1112 struct brcmf_bus *bus_if;
1113
1114 brcmf_dbg(SDIO, "Enter\n");
1115 brcmf_dbg(SDIO, "Class=%x\n", func->class);
1116 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
1117 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
1118 brcmf_dbg(SDIO, "Function#: %d\n", func->num);
1119
1120 /* Consume func num 1 but dont do anything with it. */
1121 if (func->num == 1)
1122 return 0;
1123
1124 /* Ignore anything but func 2 */
1125 if (func->num != 2)
1126 return -ENODEV;
1127
1128 bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
1129 if (!bus_if)
1130 return -ENOMEM;
1131 sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
1132 if (!sdiodev) {
1133 kfree(bus_if);
1134 return -ENOMEM;
1135 }
1136
36c4e7e4
AS
1137 /* store refs to functions used. mmc_card does
1138 * not hold the F0 function pointer.
1139 */
1140 sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
1141 sdiodev->func[0]->num = 0;
e2dc9eea
AS
1142 sdiodev->func[1] = func->card->sdio_func[0];
1143 sdiodev->func[2] = func;
1144
1145 sdiodev->bus_if = bus_if;
1146 bus_if->bus_priv.sdio = sdiodev;
943258b6 1147 bus_if->proto_type = BRCMF_PROTO_BCDC;
e2dc9eea
AS
1148 dev_set_drvdata(&func->dev, bus_if);
1149 dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
1150 sdiodev->dev = &sdiodev->func[1]->dev;
1151 sdiodev->pdata = brcmfmac_sdio_pdata;
1152
61f663df
CYT
1153 if (!sdiodev->pdata)
1154 brcmf_of_probe(sdiodev);
1155
330b4e4b
HM
1156#ifdef CONFIG_PM_SLEEP
1157 /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
1158 * is true or when platform data OOB irq is true).
1159 */
1160 if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
1161 ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
8975842b 1162 (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
330b4e4b
HM
1163 bus_if->wowl_supported = true;
1164#endif
1165
a1ce7a0d 1166 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
e2dc9eea 1167
a39be27b
AS
1168 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1169 err = brcmf_sdiod_probe(sdiodev);
e2dc9eea
AS
1170 if (err) {
1171 brcmf_err("F2 error, probe failed %d...\n", err);
1172 goto fail;
1173 }
1174
1175 brcmf_dbg(SDIO, "F2 init completed...\n");
1176 return 0;
1177
1178fail:
1179 dev_set_drvdata(&func->dev, NULL);
1180 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
36c4e7e4 1181 kfree(sdiodev->func[0]);
e2dc9eea
AS
1182 kfree(sdiodev);
1183 kfree(bus_if);
1184 return err;
1185}
1186
1187static void brcmf_ops_sdio_remove(struct sdio_func *func)
1188{
1189 struct brcmf_bus *bus_if;
1190 struct brcmf_sdio_dev *sdiodev;
1191
1192 brcmf_dbg(SDIO, "Enter\n");
1193 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
1194 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
1195 brcmf_dbg(SDIO, "Function: %d\n", func->num);
1196
de6878c8 1197 if (func->num != 1)
e2dc9eea
AS
1198 return;
1199
1200 bus_if = dev_get_drvdata(&func->dev);
1201 if (bus_if) {
1202 sdiodev = bus_if->bus_priv.sdio;
a39be27b 1203 brcmf_sdiod_remove(sdiodev);
e2dc9eea
AS
1204
1205 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
1206 dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
1207
1208 kfree(bus_if);
36c4e7e4 1209 kfree(sdiodev->func[0]);
e2dc9eea
AS
1210 kfree(sdiodev);
1211 }
1212
1213 brcmf_dbg(SDIO, "Exit\n");
1214}
1215
330b4e4b
HM
1216void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1217{
1218 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1219 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1220
1221 brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
1222 sdiodev->wowl_enabled = enabled;
1223}
1224
e2dc9eea 1225#ifdef CONFIG_PM_SLEEP
a39be27b 1226static int brcmf_ops_sdio_suspend(struct device *dev)
e2dc9eea 1227{
99824643 1228 struct sdio_func *func;
8982cd40
AS
1229 struct brcmf_bus *bus_if;
1230 struct brcmf_sdio_dev *sdiodev;
330b4e4b 1231 mmc_pm_flag_t sdio_flags;
e2dc9eea 1232
99824643
AS
1233 func = container_of(dev, struct sdio_func, dev);
1234 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1235 if (func->num != SDIO_FUNC_1)
1236 return 0;
1237
e2dc9eea 1238
8982cd40
AS
1239 bus_if = dev_get_drvdata(dev);
1240 sdiodev = bus_if->bus_priv.sdio;
1241
99824643 1242 brcmf_sdiod_freezer_on(sdiodev);
8982cd40 1243 brcmf_sdio_wd_timer(sdiodev->bus, 0);
3e3831c4 1244
330b4e4b
HM
1245 if (sdiodev->wowl_enabled) {
1246 sdio_flags = MMC_PM_KEEP_POWER;
1247 if (sdiodev->pdata->oob_irq_supported)
1248 enable_irq_wake(sdiodev->pdata->oob_irq_nr);
1249 else
1250 sdio_flags = MMC_PM_WAKE_SDIO_IRQ;
1251 if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
1252 brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
e2dc9eea 1253 }
330b4e4b 1254 return 0;
e2dc9eea
AS
1255}
1256
a39be27b 1257static int brcmf_ops_sdio_resume(struct device *dev)
e2dc9eea
AS
1258{
1259 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1260 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
99824643 1261 struct sdio_func *func = container_of(dev, struct sdio_func, dev);
e2dc9eea 1262
99824643
AS
1263 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1264 if (func->num != SDIO_FUNC_2)
1265 return 0;
1266
1267 brcmf_sdiod_freezer_off(sdiodev);
e2dc9eea
AS
1268 return 0;
1269}
1270
1271static const struct dev_pm_ops brcmf_sdio_pm_ops = {
a39be27b
AS
1272 .suspend = brcmf_ops_sdio_suspend,
1273 .resume = brcmf_ops_sdio_resume,
e2dc9eea
AS
1274};
1275#endif /* CONFIG_PM_SLEEP */
1276
1277static struct sdio_driver brcmf_sdmmc_driver = {
1278 .probe = brcmf_ops_sdio_probe,
1279 .remove = brcmf_ops_sdio_remove,
1280 .name = BRCMFMAC_SDIO_PDATA_NAME,
1281 .id_table = brcmf_sdmmc_ids,
e2dc9eea 1282 .drv = {
0b0acd8c
FL
1283 .owner = THIS_MODULE,
1284#ifdef CONFIG_PM_SLEEP
e2dc9eea 1285 .pm = &brcmf_sdio_pm_ops,
e2dc9eea 1286#endif /* CONFIG_PM_SLEEP */
0b0acd8c 1287 },
e2dc9eea
AS
1288};
1289
c2d23c70 1290static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
e2dc9eea
AS
1291{
1292 brcmf_dbg(SDIO, "Enter\n");
1293
1294 brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
1295
1296 if (brcmfmac_sdio_pdata->power_on)
1297 brcmfmac_sdio_pdata->power_on();
1298
1299 return 0;
1300}
1301
1302static int brcmf_sdio_pd_remove(struct platform_device *pdev)
1303{
1304 brcmf_dbg(SDIO, "Enter\n");
1305
1306 if (brcmfmac_sdio_pdata->power_off)
1307 brcmfmac_sdio_pdata->power_off();
1308
1309 sdio_unregister_driver(&brcmf_sdmmc_driver);
1310
1311 return 0;
1312}
1313
1314static struct platform_driver brcmf_sdio_pd = {
1315 .remove = brcmf_sdio_pd_remove,
1316 .driver = {
1317 .name = BRCMFMAC_SDIO_PDATA_NAME,
e2dc9eea
AS
1318 }
1319};
1320
1321void brcmf_sdio_register(void)
1322{
1323 int ret;
1324
1325 ret = sdio_register_driver(&brcmf_sdmmc_driver);
1326 if (ret)
1327 brcmf_err("sdio_register_driver failed: %d\n", ret);
1328}
1329
1330void brcmf_sdio_exit(void)
1331{
1332 brcmf_dbg(SDIO, "Enter\n");
1333
1334 if (brcmfmac_sdio_pdata)
1335 platform_driver_unregister(&brcmf_sdio_pd);
1336 else
1337 sdio_unregister_driver(&brcmf_sdmmc_driver);
1338}
1339
1340void __init brcmf_sdio_init(void)
1341{
1342 int ret;
1343
1344 brcmf_dbg(SDIO, "Enter\n");
1345
1346 ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
1347 if (ret == -ENODEV)
1348 brcmf_dbg(SDIO, "No platform data available.\n");
1349}