aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-10-15 09:44:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-10-18 14:06:57 -0400
commit71201496cf1c83c2f20b03d4cd8f3f5ea7c6e85a (patch)
tree72a0fbe22090be34567a9401ae1381cba5bb94fa
parent3f782744f99773889ad698eb3ea8f6bfb2d254d2 (diff)
brcmfmac: determine host controller related variables during probe
Instead of determining the limits for scatter-gather MMC transfer request upon each transmit it is now determined during the probe of the SDIO function. Reviewed-by: Franky Lin <frankyl@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c17
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h4
3 files changed, 28 insertions, 16 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 5dfc96cea364..8c4b506e25bb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -26,7 +26,6 @@
26#include <linux/mmc/sdio.h> 26#include <linux/mmc/sdio.h>
27#include <linux/mmc/sdio_func.h> 27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/card.h> 28#include <linux/mmc/card.h>
29#include <linux/mmc/host.h>
30#include <linux/platform_data/brcmfmac-sdio.h> 29#include <linux/platform_data/brcmfmac-sdio.h>
31 30
32#include <defs.h> 31#include <defs.h>
@@ -331,7 +330,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
331 bool write, u32 addr, struct sk_buff_head *pktlist) 330 bool write, u32 addr, struct sk_buff_head *pktlist)
332{ 331{
333 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; 332 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
334 unsigned int max_blks, max_req_sz, orig_offset, dst_offset; 333 unsigned int max_req_sz, orig_offset, dst_offset;
335 unsigned short max_seg_cnt, seg_sz; 334 unsigned short max_seg_cnt, seg_sz;
336 unsigned char *pkt_data, *orig_data, *dst_data; 335 unsigned char *pkt_data, *orig_data, *dst_data;
337 struct sk_buff *pkt_next = NULL, *local_pkt_next; 336 struct sk_buff *pkt_next = NULL, *local_pkt_next;
@@ -341,7 +340,6 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
341 struct mmc_data mmc_dat; 340 struct mmc_data mmc_dat;
342 struct sg_table st; 341 struct sg_table st;
343 struct scatterlist *sgl; 342 struct scatterlist *sgl;
344 struct mmc_host *host;
345 int ret = 0; 343 int ret = 0;
346 344
347 if (!pktlist->qlen) 345 if (!pktlist->qlen)
@@ -398,17 +396,10 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
398 target_list = &local_list; 396 target_list = &local_list;
399 } 397 }
400 398
401 host = sdiodev->func[fn]->card->host;
402 func_blk_sz = sdiodev->func[fn]->cur_blksize; 399 func_blk_sz = sdiodev->func[fn]->cur_blksize;
403 /* Blocks per command is limited by host count, host transfer 400 max_req_sz = sdiodev->max_request_size;
404 * size and the maximum for IO_RW_EXTENDED of 511 blocks. 401 max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,
405 */ 402 target_list->qlen);
406 max_blks = min_t(unsigned int, host->max_blk_count, 511u);
407 max_req_sz = min_t(unsigned int, host->max_req_size,
408 max_blks * func_blk_sz);
409 max_seg_cnt = min_t(unsigned short, host->max_segs,
410 SG_MAX_SINGLE_ALLOC);
411 max_seg_cnt = min_t(unsigned short, max_seg_cnt, target_list->qlen);
412 seg_sz = target_list->qlen; 403 seg_sz = target_list->qlen;
413 pkt_offset = 0; 404 pkt_offset = 0;
414 pkt_next = target_list->next; 405 pkt_next = target_list->next;
@@ -429,8 +420,8 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
429 while (pkt_next != (struct sk_buff *)target_list) { 420 while (pkt_next != (struct sk_buff *)target_list) {
430 pkt_data = pkt_next->data + pkt_offset; 421 pkt_data = pkt_next->data + pkt_offset;
431 sg_data_sz = pkt_next->len - pkt_offset; 422 sg_data_sz = pkt_next->len - pkt_offset;
432 if (sg_data_sz > host->max_seg_size) 423 if (sg_data_sz > sdiodev->max_segment_size)
433 sg_data_sz = host->max_seg_size; 424 sg_data_sz = sdiodev->max_segment_size;
434 if (sg_data_sz > max_req_sz - req_sz) 425 if (sg_data_sz > max_req_sz - req_sz)
435 sg_data_sz = max_req_sz - req_sz; 426 sg_data_sz = max_req_sz - req_sz;
436 427
@@ -476,7 +467,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
476 addr += req_sz; 467 addr += req_sz;
477 468
478 mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card); 469 mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
479 mmc_wait_for_req(host, &mmc_req); 470 mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
480 471
481 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 472 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
482 if (ret != 0) { 473 if (ret != 0) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 091c905871cc..c768ec2d473d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -21,6 +21,7 @@
21#include <linux/mmc/sdio_func.h> 21#include <linux/mmc/sdio_func.h>
22#include <linux/mmc/sdio_ids.h> 22#include <linux/mmc/sdio_ids.h>
23#include <linux/mmc/card.h> 23#include <linux/mmc/card.h>
24#include <linux/mmc/host.h>
24#include <linux/suspend.h> 25#include <linux/suspend.h>
25#include <linux/errno.h> 26#include <linux/errno.h>
26#include <linux/sched.h> /* request_irq() */ 27#include <linux/sched.h> /* request_irq() */
@@ -315,6 +316,8 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
315 int err; 316 int err;
316 struct brcmf_sdio_dev *sdiodev; 317 struct brcmf_sdio_dev *sdiodev;
317 struct brcmf_bus *bus_if; 318 struct brcmf_bus *bus_if;
319 struct mmc_host *host;
320 uint max_blocks;
318 321
319 brcmf_dbg(SDIO, "Enter\n"); 322 brcmf_dbg(SDIO, "Enter\n");
320 brcmf_dbg(SDIO, "Class=%x\n", func->class); 323 brcmf_dbg(SDIO, "Class=%x\n", func->class);
@@ -361,6 +364,20 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
361 brcmf_err("F2 error, probe failed %d...\n", err); 364 brcmf_err("F2 error, probe failed %d...\n", err);
362 goto fail; 365 goto fail;
363 } 366 }
367
368 /*
369 * determine host related variables after brcmf_sdio_probe()
370 * as func->cur_blksize is properly set and F2 init has been
371 * completed successfully.
372 */
373 host = func->card->host;
374 sdiodev->sg_support = host->max_segs > 1;
375 max_blocks = min_t(uint, host->max_blk_count, 511u);
376 sdiodev->max_request_size = min_t(uint, host->max_req_size,
377 max_blocks * func->cur_blksize);
378 sdiodev->max_segment_count = min_t(uint, host->max_segs,
379 SG_MAX_SINGLE_ALLOC);
380 sdiodev->max_segment_size = host->max_seg_size;
364 brcmf_dbg(SDIO, "F2 init completed...\n"); 381 brcmf_dbg(SDIO, "F2 init completed...\n");
365 return 0; 382 return 0;
366 383
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 2b5407f002e5..59c456f7eb12 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -178,6 +178,10 @@ struct brcmf_sdio_dev {
178 bool irq_en; /* irq enable flags */ 178 bool irq_en; /* irq enable flags */
179 spinlock_t irq_en_lock; 179 spinlock_t irq_en_lock;
180 bool irq_wake; /* irq wake enable flags */ 180 bool irq_wake; /* irq wake enable flags */
181 bool sg_support;
182 uint max_request_size;
183 ushort max_segment_count;
184 uint max_segment_size;
181}; 185};
182 186
183/* Register/deregister interrupt handler. */ 187/* Register/deregister interrupt handler. */