aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2014-02-27 13:25:00 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-28 14:33:45 -0500
commitaf1fa210f4fc6e304b859b386a3c8a266b1110ab (patch)
tree0ff7c96ae5f50229100a3483ccc5275f9d4711f9
parent4aca7a185aeba4472e7a798e5d834d7702ebbeca (diff)
brcmfmac: use pre-allocated scatter-gather table for txglomming
Instead of allocating a scatter-gather table for every transmit reuse a pre-allocated table. The transmit path will be faster by taking out this allocation. Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@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.c47
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h2
3 files changed, 41 insertions, 16 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 07e7d2520257..9eea7d4dd501 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -53,6 +53,12 @@
53/* Maximum milliseconds to wait for F2 to come up */ 53/* Maximum milliseconds to wait for F2 to come up */
54#define SDIO_WAIT_F2RDY 3000 54#define SDIO_WAIT_F2RDY 3000
55 55
56#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
57#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
58
59static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
60module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
61MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
56 62
57static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id) 63static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
58{ 64{
@@ -487,7 +493,6 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
487 struct mmc_request mmc_req; 493 struct mmc_request mmc_req;
488 struct mmc_command mmc_cmd; 494 struct mmc_command mmc_cmd;
489 struct mmc_data mmc_dat; 495 struct mmc_data mmc_dat;
490 struct sg_table st;
491 struct scatterlist *sgl; 496 struct scatterlist *sgl;
492 int ret = 0; 497 int ret = 0;
493 498
@@ -532,16 +537,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
532 pkt_offset = 0; 537 pkt_offset = 0;
533 pkt_next = target_list->next; 538 pkt_next = target_list->next;
534 539
535 if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
536 ret = -ENOMEM;
537 goto exit;
538 }
539
540 memset(&mmc_req, 0, sizeof(struct mmc_request)); 540 memset(&mmc_req, 0, sizeof(struct mmc_request));
541 memset(&mmc_cmd, 0, sizeof(struct mmc_command)); 541 memset(&mmc_cmd, 0, sizeof(struct mmc_command));
542 memset(&mmc_dat, 0, sizeof(struct mmc_data)); 542 memset(&mmc_dat, 0, sizeof(struct mmc_data));
543 543
544 mmc_dat.sg = st.sgl; 544 mmc_dat.sg = sdiodev->sgtable.sgl;
545 mmc_dat.blksz = func_blk_sz; 545 mmc_dat.blksz = func_blk_sz;
546 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; 546 mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
547 mmc_cmd.opcode = SD_IO_RW_EXTENDED; 547 mmc_cmd.opcode = SD_IO_RW_EXTENDED;
@@ -557,7 +557,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
557 while (seg_sz) { 557 while (seg_sz) {
558 req_sz = 0; 558 req_sz = 0;
559 sg_cnt = 0; 559 sg_cnt = 0;
560 sgl = st.sgl; 560 sgl = sdiodev->sgtable.sgl;
561 /* prep sg table */ 561 /* prep sg table */
562 while (pkt_next != (struct sk_buff *)target_list) { 562 while (pkt_next != (struct sk_buff *)target_list) {
563 pkt_data = pkt_next->data + pkt_offset; 563 pkt_data = pkt_next->data + pkt_offset;
@@ -639,7 +639,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
639 } 639 }
640 640
641exit: 641exit:
642 sg_free_table(&st); 642 sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
643 while ((pkt_next = __skb_dequeue(&local_list)) != NULL) 643 while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
644 brcmu_pkt_buf_free_skb(pkt_next); 644 brcmu_pkt_buf_free_skb(pkt_next);
645 645
@@ -863,6 +863,29 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
863 return 0; 863 return 0;
864} 864}
865 865
866static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
867{
868 uint nents;
869 int err;
870
871 if (!sdiodev->sg_support)
872 return;
873
874 nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
875 nents += (nents >> 4) + 1;
876
877 WARN_ON(nents > sdiodev->max_segment_count);
878
879 brcmf_dbg(TRACE, "nents=%d\n", nents);
880 err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
881 if (err < 0) {
882 brcmf_err("allocation failed: disable scatter-gather");
883 sdiodev->sg_support = false;
884 }
885
886 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
887}
888
866static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 889static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
867{ 890{
868 if (sdiodev->bus) { 891 if (sdiodev->bus) {
@@ -880,6 +903,7 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
880 sdio_disable_func(sdiodev->func[1]); 903 sdio_disable_func(sdiodev->func[1]);
881 sdio_release_host(sdiodev->func[1]); 904 sdio_release_host(sdiodev->func[1]);
882 905
906 sg_free_table(&sdiodev->sgtable);
883 sdiodev->sbwad = 0; 907 sdiodev->sbwad = 0;
884 908
885 return 0; 909 return 0;
@@ -935,6 +959,11 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
935 SG_MAX_SINGLE_ALLOC); 959 SG_MAX_SINGLE_ALLOC);
936 sdiodev->max_segment_size = host->max_seg_size; 960 sdiodev->max_segment_size = host->max_seg_size;
937 961
962 /* allocate scatter-gather table. sg support
963 * will be disabled upon allocation failure.
964 */
965 brcmf_sdiod_sgtable_alloc(sdiodev);
966
938 /* try to attach to the target device */ 967 /* try to attach to the target device */
939 sdiodev->bus = brcmf_sdio_probe(sdiodev); 968 sdiodev->bus = brcmf_sdio_probe(sdiodev);
940 if (!sdiodev->bus) { 969 if (!sdiodev->bus) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index c894ee358153..b5ded8a57cb0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -113,8 +113,6 @@ struct rte_console {
113#define BRCMF_TXBOUND 20 /* Default for max tx frames in 113#define BRCMF_TXBOUND 20 /* Default for max tx frames in
114 one scheduling */ 114 one scheduling */
115 115
116#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
117
118#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ 116#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
119 117
120#define MEMBLOCK 2048 /* Block size used for downloading 118#define MEMBLOCK 2048 /* Block size used for downloading
@@ -511,10 +509,6 @@ static const uint max_roundup = 512;
511 509
512#define ALIGNMENT 4 510#define ALIGNMENT 4
513 511
514static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
515module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
516MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
517
518enum brcmf_sdio_frmtype { 512enum brcmf_sdio_frmtype {
519 BRCMF_SDIO_FT_NORMAL, 513 BRCMF_SDIO_FT_NORMAL,
520 BRCMF_SDIO_FT_SUPER, 514 BRCMF_SDIO_FT_SUPER,
@@ -2321,7 +2315,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2321 __skb_queue_head_init(&pktq); 2315 __skb_queue_head_init(&pktq);
2322 if (bus->txglom) 2316 if (bus->txglom)
2323 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, 2317 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
2324 brcmf_sdio_txglomsz); 2318 bus->sdiodev->txglomsz);
2325 pkt_num = min_t(u32, pkt_num, 2319 pkt_num = min_t(u32, pkt_num,
2326 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)); 2320 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
2327 spin_lock_bh(&bus->txqlock); 2321 spin_lock_bh(&bus->txqlock);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 5e53eb1b2ffa..3deab7959a0d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -180,6 +180,8 @@ struct brcmf_sdio_dev {
180 uint max_request_size; 180 uint max_request_size;
181 ushort max_segment_count; 181 ushort max_segment_count;
182 uint max_segment_size; 182 uint max_segment_size;
183 uint txglomsz;
184 struct sg_table sgtable;
183}; 185};
184 186
185/* sdio core registers */ 187/* sdio core registers */