aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorFranky Lin <frankyl@broadcom.com>2013-06-18 07:29:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-18 14:46:51 -0400
commit354b75bfdbef02739af39acdbf804549c4626816 (patch)
treeb0b595f84bcd50b2064ded2207c13ac051d21bec /drivers/net/wireless/brcm80211
parent78b3f1c5be8fdb3c83d21a357b1f8e89f5e18a6b (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.c149
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c73
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c82
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h7
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 */
318static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, 320static 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
349static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, 455static 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
414done: 524done:
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
437done: 546done:
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
494done: 607done:
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 */
215static int
216brcmf_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 */
243int
244brcmf_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
286static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) 214static 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 */
1029static 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 */
1052static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus) 1025static 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
3535static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) 3484static 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
3566fail:
3567 return false;
3568} 3498}
3569 3499
3570static bool 3500static 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 */
276extern int
277brcmf_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 */
282extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, 275extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
283 bool enable); 276 bool enable);