diff options
author | Franky Lin <frankyl@broadcom.com> | 2013-06-18 07:29:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-18 14:46:51 -0400 |
commit | 354b75bfdbef02739af39acdbf804549c4626816 (patch) | |
tree | b0b595f84bcd50b2064ded2207c13ac051d21bec /drivers/net/wireless/brcm80211 | |
parent | 78b3f1c5be8fdb3c83d21a357b1f8e89f5e18a6b (diff) |
brcmfmac: add sdio sg list support
Add scatter gather list support for better rx glom performance.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 149 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 73 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 82 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 7 |
4 files changed, 137 insertions, 174 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 32a205e0b063..3f8e69c29146 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -22,9 +22,11 @@ | |||
22 | #include <linux/pci_ids.h> | 22 | #include <linux/pci_ids.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
25 | #include <linux/scatterlist.h> | ||
25 | #include <linux/mmc/sdio.h> | 26 | #include <linux/mmc/sdio.h> |
26 | #include <linux/mmc/sdio_func.h> | 27 | #include <linux/mmc/sdio_func.h> |
27 | #include <linux/mmc/card.h> | 28 | #include <linux/mmc/card.h> |
29 | #include <linux/mmc/host.h> | ||
28 | #include <linux/platform_data/brcmfmac-sdio.h> | 30 | #include <linux/platform_data/brcmfmac-sdio.h> |
29 | 31 | ||
30 | #include <defs.h> | 32 | #include <defs.h> |
@@ -316,34 +318,138 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
316 | * caller has already been padded and aligned. | 318 | * caller has already been padded and aligned. |
317 | */ | 319 | */ |
318 | static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | 320 | static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, |
319 | bool write, u32 addr, struct sk_buff *pkt) | 321 | bool write, u32 addr, struct sk_buff_head *pktlist) |
320 | { | 322 | { |
321 | uint len; | 323 | unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; |
324 | unsigned int max_blks, max_req_sz; | ||
325 | unsigned short max_seg_sz, seg_sz; | ||
326 | unsigned char *pkt_data; | ||
327 | struct sk_buff *pkt_next = NULL; | ||
328 | struct mmc_request mmc_req; | ||
329 | struct mmc_command mmc_cmd; | ||
330 | struct mmc_data mmc_dat; | ||
331 | struct sg_table st; | ||
332 | struct scatterlist *sgl; | ||
333 | struct mmc_host *host; | ||
334 | int ret = 0; | ||
335 | |||
336 | if (!pktlist->qlen) | ||
337 | return -EINVAL; | ||
322 | 338 | ||
323 | brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); | 339 | brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); |
324 | if (brcmf_pm_resume_error(sdiodev)) | 340 | if (brcmf_pm_resume_error(sdiodev)) |
325 | return -EIO; | 341 | return -EIO; |
326 | 342 | ||
327 | /* Single skb use the standard mmc interface */ | 343 | /* Single skb use the standard mmc interface */ |
328 | if (!pkt->next) { | 344 | if (pktlist->qlen == 1) { |
329 | len = pkt->len + 3; | 345 | pkt_next = pktlist->next; |
330 | len &= (uint)~3; | 346 | req_sz = pkt_next->len + 3; |
347 | req_sz &= (uint)~3; | ||
331 | 348 | ||
332 | if (write) | 349 | if (write) |
333 | return sdio_memcpy_toio(sdiodev->func[fn], addr, | 350 | return sdio_memcpy_toio(sdiodev->func[fn], addr, |
334 | ((u8 *)(pkt->data)), len); | 351 | ((u8 *)(pkt_next->data)), |
352 | req_sz); | ||
335 | else if (fn == 1) | 353 | else if (fn == 1) |
336 | return sdio_memcpy_fromio(sdiodev->func[fn], | 354 | return sdio_memcpy_fromio(sdiodev->func[fn], |
337 | ((u8 *)(pkt->data)), addr, | 355 | ((u8 *)(pkt_next->data)), |
338 | len); | 356 | addr, req_sz); |
339 | else | 357 | else |
340 | /* function 2 read is FIFO operation */ | 358 | /* function 2 read is FIFO operation */ |
341 | return sdio_readsb(sdiodev->func[fn], | 359 | return sdio_readsb(sdiodev->func[fn], |
342 | ((u8 *)(pkt->data)), addr, len); | 360 | ((u8 *)(pkt_next->data)), addr, |
361 | req_sz); | ||
343 | } | 362 | } |
344 | 363 | ||
345 | brcmf_err("skb chain is not supported yet.\n"); | 364 | host = sdiodev->func[fn]->card->host; |
346 | return -EOPNOTSUPP; | 365 | func_blk_sz = sdiodev->func[fn]->cur_blksize; |
366 | /* Blocks per command is limited by host count, host transfer | ||
367 | * size and the maximum for IO_RW_EXTENDED of 511 blocks. | ||
368 | */ | ||
369 | max_blks = min_t(unsigned int, host->max_blk_count, 511u); | ||
370 | max_req_sz = min_t(unsigned int, host->max_req_size, | ||
371 | max_blks * func_blk_sz); | ||
372 | max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC); | ||
373 | max_seg_sz = min_t(unsigned short, max_seg_sz, pktlist->qlen); | ||
374 | seg_sz = pktlist->qlen; | ||
375 | pkt_offset = 0; | ||
376 | pkt_next = pktlist->next; | ||
377 | |||
378 | if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) | ||
379 | return -ENOMEM; | ||
380 | |||
381 | while (seg_sz) { | ||
382 | req_sz = 0; | ||
383 | sg_cnt = 0; | ||
384 | memset(&mmc_req, 0, sizeof(struct mmc_request)); | ||
385 | memset(&mmc_cmd, 0, sizeof(struct mmc_command)); | ||
386 | memset(&mmc_dat, 0, sizeof(struct mmc_data)); | ||
387 | sgl = st.sgl; | ||
388 | /* prep sg table */ | ||
389 | while (pkt_next != (struct sk_buff *)pktlist) { | ||
390 | pkt_data = pkt_next->data + pkt_offset; | ||
391 | sg_data_sz = pkt_next->len - pkt_offset; | ||
392 | if (sg_data_sz > host->max_seg_size) | ||
393 | sg_data_sz = host->max_seg_size; | ||
394 | if (sg_data_sz > max_req_sz - req_sz) | ||
395 | sg_data_sz = max_req_sz - req_sz; | ||
396 | |||
397 | sg_set_buf(sgl, pkt_data, sg_data_sz); | ||
398 | |||
399 | sg_cnt++; | ||
400 | sgl = sg_next(sgl); | ||
401 | req_sz += sg_data_sz; | ||
402 | pkt_offset += sg_data_sz; | ||
403 | if (pkt_offset == pkt_next->len) { | ||
404 | pkt_offset = 0; | ||
405 | pkt_next = pkt_next->next; | ||
406 | } | ||
407 | |||
408 | if (req_sz >= max_req_sz || sg_cnt >= max_seg_sz) | ||
409 | break; | ||
410 | } | ||
411 | seg_sz -= sg_cnt; | ||
412 | |||
413 | if (req_sz % func_blk_sz != 0) { | ||
414 | brcmf_err("sg request length %u is not %u aligned\n", | ||
415 | req_sz, func_blk_sz); | ||
416 | sg_free_table(&st); | ||
417 | return -ENOTBLK; | ||
418 | } | ||
419 | mmc_dat.sg = st.sgl; | ||
420 | mmc_dat.sg_len = sg_cnt; | ||
421 | mmc_dat.blksz = func_blk_sz; | ||
422 | mmc_dat.blocks = req_sz / func_blk_sz; | ||
423 | mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; | ||
424 | mmc_cmd.opcode = SD_IO_RW_EXTENDED; | ||
425 | mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */ | ||
426 | mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */ | ||
427 | mmc_cmd.arg |= 1<<27; /* block mode */ | ||
428 | /* incrementing addr for function 1 */ | ||
429 | mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0; | ||
430 | mmc_cmd.arg |= (addr & 0x1FFFF) << 9; /* address */ | ||
431 | mmc_cmd.arg |= mmc_dat.blocks & 0x1FF; /* block count */ | ||
432 | mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; | ||
433 | mmc_req.cmd = &mmc_cmd; | ||
434 | mmc_req.data = &mmc_dat; | ||
435 | if (fn == 1) | ||
436 | addr += req_sz; | ||
437 | |||
438 | mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card); | ||
439 | mmc_wait_for_req(host, &mmc_req); | ||
440 | |||
441 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; | ||
442 | if (ret != 0) { | ||
443 | brcmf_err("CMD53 sg block %s failed %d\n", | ||
444 | write ? "write" : "read", ret); | ||
445 | ret = -EIO; | ||
446 | break; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | sg_free_table(&st); | ||
451 | |||
452 | return ret; | ||
347 | } | 453 | } |
348 | 454 | ||
349 | static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, | 455 | static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, |
@@ -400,6 +506,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
400 | { | 506 | { |
401 | uint width; | 507 | uint width; |
402 | int err = 0; | 508 | int err = 0; |
509 | struct sk_buff_head pkt_list; | ||
403 | 510 | ||
404 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", | 511 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", |
405 | fn, addr, pkt->len); | 512 | fn, addr, pkt->len); |
@@ -409,7 +516,10 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
409 | if (err) | 516 | if (err) |
410 | goto done; | 517 | goto done; |
411 | 518 | ||
412 | err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt); | 519 | skb_queue_head_init(&pkt_list); |
520 | skb_queue_tail(&pkt_list, pkt); | ||
521 | err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, &pkt_list); | ||
522 | skb_dequeue_tail(&pkt_list); | ||
413 | 523 | ||
414 | done: | 524 | done: |
415 | return err; | 525 | return err; |
@@ -431,8 +541,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
431 | goto done; | 541 | goto done; |
432 | 542 | ||
433 | incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; | 543 | incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; |
434 | err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr, | 544 | err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq); |
435 | pktq); | ||
436 | 545 | ||
437 | done: | 546 | done: |
438 | return err; | 547 | return err; |
@@ -467,6 +576,7 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
467 | uint width; | 576 | uint width; |
468 | uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | 577 | uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; |
469 | int err = 0; | 578 | int err = 0; |
579 | struct sk_buff_head pkt_list; | ||
470 | 580 | ||
471 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", | 581 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", |
472 | fn, addr, pkt->len); | 582 | fn, addr, pkt->len); |
@@ -489,7 +599,10 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
489 | if (width == 4) | 599 | if (width == 4) |
490 | addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | 600 | addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |
491 | 601 | ||
492 | err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pkt); | 602 | skb_queue_head_init(&pkt_list); |
603 | skb_queue_tail(&pkt_list, pkt); | ||
604 | err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list); | ||
605 | skb_dequeue_tail(&pkt_list); | ||
493 | 606 | ||
494 | done: | 607 | done: |
495 | return err; | 608 | return err; |
@@ -503,6 +616,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, | |||
503 | struct sk_buff *pkt; | 616 | struct sk_buff *pkt; |
504 | u32 sdaddr; | 617 | u32 sdaddr; |
505 | uint dsize; | 618 | uint dsize; |
619 | struct sk_buff_head pkt_list; | ||
506 | 620 | ||
507 | dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); | 621 | dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); |
508 | pkt = dev_alloc_skb(dsize); | 622 | pkt = dev_alloc_skb(dsize); |
@@ -511,6 +625,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, | |||
511 | return -EIO; | 625 | return -EIO; |
512 | } | 626 | } |
513 | pkt->priority = 0; | 627 | pkt->priority = 0; |
628 | skb_queue_head_init(&pkt_list); | ||
514 | 629 | ||
515 | /* Determine initial transfer parameters */ | 630 | /* Determine initial transfer parameters */ |
516 | sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; | 631 | sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; |
@@ -538,8 +653,10 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, | |||
538 | skb_put(pkt, dsize); | 653 | skb_put(pkt, dsize); |
539 | if (write) | 654 | if (write) |
540 | memcpy(pkt->data, data, dsize); | 655 | memcpy(pkt->data, data, dsize); |
656 | skb_queue_tail(&pkt_list, pkt); | ||
541 | bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write, | 657 | bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write, |
542 | sdaddr, pkt); | 658 | sdaddr, &pkt_list); |
659 | skb_dequeue_tail(&pkt_list); | ||
543 | if (bcmerror) { | 660 | if (bcmerror) { |
544 | brcmf_err("membytes transfer failed\n"); | 661 | brcmf_err("membytes transfer failed\n"); |
545 | break; | 662 | break; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 7a3c5bf33e03..289e386f01f6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -211,78 +211,6 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, | |||
211 | return err_ret; | 211 | return err_ret; |
212 | } | 212 | } |
213 | 213 | ||
214 | /* precondition: host controller is claimed */ | ||
215 | static int | ||
216 | brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo, | ||
217 | uint func, uint addr, struct sk_buff *pkt, uint pktlen) | ||
218 | { | ||
219 | int err_ret = 0; | ||
220 | |||
221 | if ((write) && (!fifo)) { | ||
222 | err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, | ||
223 | ((u8 *) (pkt->data)), pktlen); | ||
224 | } else if (write) { | ||
225 | err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, | ||
226 | ((u8 *) (pkt->data)), pktlen); | ||
227 | } else if (fifo) { | ||
228 | err_ret = sdio_readsb(sdiodev->func[func], | ||
229 | ((u8 *) (pkt->data)), addr, pktlen); | ||
230 | } else { | ||
231 | err_ret = sdio_memcpy_fromio(sdiodev->func[func], | ||
232 | ((u8 *) (pkt->data)), | ||
233 | addr, pktlen); | ||
234 | } | ||
235 | |||
236 | return err_ret; | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * This function takes a queue of packets. The packets on the queue | ||
241 | * are assumed to be properly aligned by the caller. | ||
242 | */ | ||
243 | int | ||
244 | brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc, | ||
245 | uint write, uint func, uint addr, | ||
246 | struct sk_buff_head *pktq) | ||
247 | { | ||
248 | bool fifo = (fix_inc == SDIOH_DATA_FIX); | ||
249 | u32 SGCount = 0; | ||
250 | int err_ret = 0; | ||
251 | |||
252 | struct sk_buff *pkt; | ||
253 | |||
254 | brcmf_dbg(SDIO, "Enter\n"); | ||
255 | |||
256 | brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait); | ||
257 | if (brcmf_pm_resume_error(sdiodev)) | ||
258 | return -EIO; | ||
259 | |||
260 | skb_queue_walk(pktq, pkt) { | ||
261 | uint pkt_len = pkt->len; | ||
262 | pkt_len += 3; | ||
263 | pkt_len &= 0xFFFFFFFC; | ||
264 | |||
265 | err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func, | ||
266 | addr, pkt, pkt_len); | ||
267 | if (err_ret) { | ||
268 | brcmf_err("%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", | ||
269 | write ? "TX" : "RX", pkt, SGCount, addr, | ||
270 | pkt_len, err_ret); | ||
271 | } else { | ||
272 | brcmf_dbg(SDIO, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n", | ||
273 | write ? "TX" : "RX", pkt, SGCount, addr, | ||
274 | pkt_len); | ||
275 | } | ||
276 | if (!fifo) | ||
277 | addr += pkt_len; | ||
278 | |||
279 | SGCount++; | ||
280 | } | ||
281 | |||
282 | brcmf_dbg(SDIO, "Exit\n"); | ||
283 | return err_ret; | ||
284 | } | ||
285 | |||
286 | static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) | 214 | static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) |
287 | { | 215 | { |
288 | /* read 24 bits and return valid 17 bit addr */ | 216 | /* read 24 bits and return valid 17 bit addr */ |
@@ -431,7 +359,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
431 | atomic_set(&sdiodev->suspend, false); | 359 | atomic_set(&sdiodev->suspend, false); |
432 | init_waitqueue_head(&sdiodev->request_byte_wait); | 360 | init_waitqueue_head(&sdiodev->request_byte_wait); |
433 | init_waitqueue_head(&sdiodev->request_word_wait); | 361 | init_waitqueue_head(&sdiodev->request_word_wait); |
434 | init_waitqueue_head(&sdiodev->request_chain_wait); | ||
435 | init_waitqueue_head(&sdiodev->request_buffer_wait); | 362 | init_waitqueue_head(&sdiodev->request_buffer_wait); |
436 | 363 | ||
437 | brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); | 364 | brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index cb22f2f51453..264111968320 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -448,8 +448,6 @@ struct brcmf_sdio { | |||
448 | uint rxblen; /* Allocated length of rxbuf */ | 448 | uint rxblen; /* Allocated length of rxbuf */ |
449 | u8 *rxctl; /* Aligned pointer into rxbuf */ | 449 | u8 *rxctl; /* Aligned pointer into rxbuf */ |
450 | u8 *rxctl_orig; /* pointer for freeing rxctl */ | 450 | u8 *rxctl_orig; /* pointer for freeing rxctl */ |
451 | u8 *databuf; /* Buffer for receiving big glom packet */ | ||
452 | u8 *dataptr; /* Aligned pointer into databuf */ | ||
453 | uint rxlen; /* Length of valid data in buffer */ | 451 | uint rxlen; /* Length of valid data in buffer */ |
454 | spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */ | 452 | spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */ |
455 | 453 | ||
@@ -473,8 +471,6 @@ struct brcmf_sdio { | |||
473 | s32 idletime; /* Control for activity timeout */ | 471 | s32 idletime; /* Control for activity timeout */ |
474 | s32 idlecount; /* Activity timeout counter */ | 472 | s32 idlecount; /* Activity timeout counter */ |
475 | s32 idleclock; /* How to set bus driver when idle */ | 473 | s32 idleclock; /* How to set bus driver when idle */ |
476 | s32 sd_rxchain; | ||
477 | bool use_rxchain; /* If brcmf should use PKT chains */ | ||
478 | bool rxflow_mode; /* Rx flow control mode */ | 474 | bool rxflow_mode; /* Rx flow control mode */ |
479 | bool rxflow; /* Is rx flow control on */ | 475 | bool rxflow; /* Is rx flow control on */ |
480 | bool alp_only; /* Don't use HT clock (ALP only) */ | 476 | bool alp_only; /* Don't use HT clock (ALP only) */ |
@@ -1025,29 +1021,6 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) | |||
1025 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; | 1021 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
1026 | } | 1022 | } |
1027 | 1023 | ||
1028 | /* copy a buffer into a pkt buffer chain */ | ||
1029 | static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_sdio *bus, uint len) | ||
1030 | { | ||
1031 | uint n, ret = 0; | ||
1032 | struct sk_buff *p; | ||
1033 | u8 *buf; | ||
1034 | |||
1035 | buf = bus->dataptr; | ||
1036 | |||
1037 | /* copy the data */ | ||
1038 | skb_queue_walk(&bus->glom, p) { | ||
1039 | n = min_t(uint, p->len, len); | ||
1040 | memcpy(p->data, buf, n); | ||
1041 | buf += n; | ||
1042 | len -= n; | ||
1043 | ret += n; | ||
1044 | if (!len) | ||
1045 | break; | ||
1046 | } | ||
1047 | |||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | /* return total length of buffer chain */ | 1024 | /* return total length of buffer chain */ |
1052 | static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus) | 1025 | static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus) |
1053 | { | 1026 | { |
@@ -1201,8 +1174,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1201 | int errcode; | 1174 | int errcode; |
1202 | u8 doff, sfdoff; | 1175 | u8 doff, sfdoff; |
1203 | 1176 | ||
1204 | bool usechain = bus->use_rxchain; | ||
1205 | |||
1206 | struct brcmf_sdio_read rd_new; | 1177 | struct brcmf_sdio_read rd_new; |
1207 | 1178 | ||
1208 | /* If packets, issue read(s) and send up packet chain */ | 1179 | /* If packets, issue read(s) and send up packet chain */ |
@@ -1237,7 +1208,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1237 | if (sublen % BRCMF_SDALIGN) { | 1208 | if (sublen % BRCMF_SDALIGN) { |
1238 | brcmf_err("sublen %d not multiple of %d\n", | 1209 | brcmf_err("sublen %d not multiple of %d\n", |
1239 | sublen, BRCMF_SDALIGN); | 1210 | sublen, BRCMF_SDALIGN); |
1240 | usechain = false; | ||
1241 | } | 1211 | } |
1242 | totlen += sublen; | 1212 | totlen += sublen; |
1243 | 1213 | ||
@@ -1304,27 +1274,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1304 | * packet and and copy into the chain. | 1274 | * packet and and copy into the chain. |
1305 | */ | 1275 | */ |
1306 | sdio_claim_host(bus->sdiodev->func[1]); | 1276 | sdio_claim_host(bus->sdiodev->func[1]); |
1307 | if (usechain) { | 1277 | errcode = brcmf_sdcard_recv_chain(bus->sdiodev, |
1308 | errcode = brcmf_sdcard_recv_chain(bus->sdiodev, | 1278 | bus->sdiodev->sbwad, |
1309 | bus->sdiodev->sbwad, | 1279 | SDIO_FUNC_2, F2SYNC, &bus->glom); |
1310 | SDIO_FUNC_2, F2SYNC, &bus->glom); | ||
1311 | } else if (bus->dataptr) { | ||
1312 | errcode = brcmf_sdcard_recv_buf(bus->sdiodev, | ||
1313 | bus->sdiodev->sbwad, | ||
1314 | SDIO_FUNC_2, F2SYNC, | ||
1315 | bus->dataptr, dlen); | ||
1316 | sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen); | ||
1317 | if (sublen != dlen) { | ||
1318 | brcmf_err("FAILED TO COPY, dlen %d sublen %d\n", | ||
1319 | dlen, sublen); | ||
1320 | errcode = -1; | ||
1321 | } | ||
1322 | pnext = NULL; | ||
1323 | } else { | ||
1324 | brcmf_err("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", | ||
1325 | dlen); | ||
1326 | errcode = -1; | ||
1327 | } | ||
1328 | sdio_release_host(bus->sdiodev->func[1]); | 1280 | sdio_release_host(bus->sdiodev->func[1]); |
1329 | bus->sdcnt.f2rxdata++; | 1281 | bus->sdcnt.f2rxdata++; |
1330 | 1282 | ||
@@ -3527,9 +3479,6 @@ static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus) | |||
3527 | kfree(bus->rxbuf); | 3479 | kfree(bus->rxbuf); |
3528 | bus->rxctl = bus->rxbuf = NULL; | 3480 | bus->rxctl = bus->rxbuf = NULL; |
3529 | bus->rxlen = 0; | 3481 | bus->rxlen = 0; |
3530 | |||
3531 | kfree(bus->databuf); | ||
3532 | bus->databuf = NULL; | ||
3533 | } | 3482 | } |
3534 | 3483 | ||
3535 | static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) | 3484 | static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) |
@@ -3542,29 +3491,10 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) | |||
3542 | ALIGNMENT) + BRCMF_SDALIGN; | 3491 | ALIGNMENT) + BRCMF_SDALIGN; |
3543 | bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); | 3492 | bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); |
3544 | if (!(bus->rxbuf)) | 3493 | if (!(bus->rxbuf)) |
3545 | goto fail; | 3494 | return false; |
3546 | } | ||
3547 | |||
3548 | /* Allocate buffer to receive glomed packet */ | ||
3549 | bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC); | ||
3550 | if (!(bus->databuf)) { | ||
3551 | /* release rxbuf which was already located as above */ | ||
3552 | if (!bus->rxblen) | ||
3553 | kfree(bus->rxbuf); | ||
3554 | goto fail; | ||
3555 | } | 3495 | } |
3556 | 3496 | ||
3557 | /* Align the buffer */ | ||
3558 | if ((unsigned long)bus->databuf % BRCMF_SDALIGN) | ||
3559 | bus->dataptr = bus->databuf + (BRCMF_SDALIGN - | ||
3560 | ((unsigned long)bus->databuf % BRCMF_SDALIGN)); | ||
3561 | else | ||
3562 | bus->dataptr = bus->databuf; | ||
3563 | |||
3564 | return true; | 3497 | return true; |
3565 | |||
3566 | fail: | ||
3567 | return false; | ||
3568 | } | 3498 | } |
3569 | 3499 | ||
3570 | static bool | 3500 | static bool |
@@ -3703,10 +3633,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
3703 | bus->blocksize = bus->sdiodev->func[2]->cur_blksize; | 3633 | bus->blocksize = bus->sdiodev->func[2]->cur_blksize; |
3704 | bus->roundup = min(max_roundup, bus->blocksize); | 3634 | bus->roundup = min(max_roundup, bus->blocksize); |
3705 | 3635 | ||
3706 | /* bus module does not support packet chaining */ | ||
3707 | bus->use_rxchain = false; | ||
3708 | bus->sd_rxchain = false; | ||
3709 | |||
3710 | /* SR state */ | 3636 | /* SR state */ |
3711 | bus->sleeping = false; | 3637 | bus->sleeping = false; |
3712 | bus->sr_enabled = false; | 3638 | bus->sr_enabled = false; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 991c1501f7e1..793df66fe0bf 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | |||
@@ -170,7 +170,6 @@ struct brcmf_sdio_dev { | |||
170 | atomic_t suspend; /* suspend flag */ | 170 | atomic_t suspend; /* suspend flag */ |
171 | wait_queue_head_t request_byte_wait; | 171 | wait_queue_head_t request_byte_wait; |
172 | wait_queue_head_t request_word_wait; | 172 | wait_queue_head_t request_word_wait; |
173 | wait_queue_head_t request_chain_wait; | ||
174 | wait_queue_head_t request_buffer_wait; | 173 | wait_queue_head_t request_buffer_wait; |
175 | struct device *dev; | 174 | struct device *dev; |
176 | struct brcmf_bus *bus_if; | 175 | struct brcmf_bus *bus_if; |
@@ -272,12 +271,6 @@ brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, | |||
272 | uint rw, uint fnc, uint addr, | 271 | uint rw, uint fnc, uint addr, |
273 | u32 *word, uint nbyte); | 272 | u32 *word, uint nbyte); |
274 | 273 | ||
275 | /* read or write any buffer using cmd53 */ | ||
276 | extern int | ||
277 | brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc, | ||
278 | uint write, uint func, uint addr, | ||
279 | struct sk_buff_head *pktq); | ||
280 | |||
281 | /* Watchdog timer interface for pm ops */ | 274 | /* Watchdog timer interface for pm ops */ |
282 | extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, | 275 | extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, |
283 | bool enable); | 276 | bool enable); |