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