diff options
| author | Arend van Spriel <arend@broadcom.com> | 2013-10-15 09:44:49 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2013-10-18 14:06:57 -0400 |
| commit | 71201496cf1c83c2f20b03d4cd8f3f5ea7c6e85a (patch) | |
| tree | 72a0fbe22090be34567a9401ae1381cba5bb94fa | |
| parent | 3f782744f99773889ad698eb3ea8f6bfb2d254d2 (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.c | 23 | ||||
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 17 | ||||
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 4 |
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. */ |
