Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ath6kl: prioritize Tx bundling based on AC priorities

Tx bundling is the more efficient use of SDIO bus and allows more packet
transfers with fewer bus transactions, and is a way to improve overall
throughput. However, Tx bundling has only 4 scatter request resources available.
When there are multiple traffic streams of different priorities, it's possible
that lower priority traffic may hog all the scatter requests and lock out the
higher prioirty traffic from bundling.
Tx bundling is now enabled per AC. When an AC do a scatter request and
the remaining scatter request resources is lower than a configurable
threshold, it will disable Tx bundling for all AC's of lower priorities.
When an AC has Tx bundling disabled and has no Tx bundles sent in a
consecutive and configurable number of packets, Tx bundling will be re-enabled
for that AC.

Signed-off-by: Chilam Ng <chilamng@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>

authored by

Chilam Ng and committed by
Kalle Valo
b29072cc 1b2df407

+80 -8
+2
drivers/net/wireless/ath/ath6kl/hif.h
··· 198 198 u8 *virt_dma_buf; 199 199 200 200 struct hif_scatter_item scat_list[1]; 201 + 202 + u32 scat_q_depth; 201 203 }; 202 204 203 205 struct ath6kl_irq_proc_registers {
+70 -7
drivers/net/wireless/ath/ath6kl/htc.c
··· 23 23 24 24 #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) 25 25 26 + /* threshold to re-enable Tx bundling for an AC*/ 27 + #define TX_RESUME_BUNDLE_THRESHOLD 1500 28 + 26 29 /* Functions for Tx credit handling */ 27 30 static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, 28 31 struct htc_endpoint_credit_dist *ep_dist, ··· 748 745 struct hif_scatter_req *scat_req = NULL; 749 746 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; 750 747 int status; 748 + u32 txb_mask; 749 + u8 ac = WMM_NUM_AC; 750 + 751 + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || 752 + (WMI_CONTROL_SVC != endpoint->svc_id)) 753 + ac = target->dev->ar->ep2ac_map[endpoint->eid]; 751 754 752 755 while (true) { 753 756 status = 0; ··· 771 762 ath6kl_dbg(ATH6KL_DBG_HTC, 772 763 "htc tx no more scatter resources\n"); 773 764 break; 765 + } 766 + 767 + if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) { 768 + if (WMM_AC_BE == ac) 769 + /* 770 + * BE, BK have priorities and bit 771 + * positions reversed 772 + */ 773 + txb_mask = (1 << WMM_AC_BK); 774 + else 775 + /* 776 + * any AC with priority lower than 777 + * itself 778 + */ 779 + txb_mask = ((1 << ac) - 1); 780 + /* 781 + * when the scatter request resources drop below a 782 + * certain threshold, disable Tx bundling for all 783 + * AC's with priority lower than the current requesting 784 + * AC. Otherwise re-enable Tx bundling for them 785 + */ 786 + if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) 787 + target->tx_bndl_mask &= ~txb_mask; 788 + else 789 + target->tx_bndl_mask |= txb_mask; 774 790 } 775 791 776 792 ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", ··· 841 807 struct htc_packet *packet; 842 808 int bundle_sent; 843 809 int n_pkts_bundle; 810 + u8 ac = WMM_NUM_AC; 844 811 845 812 spin_lock_bh(&target->tx_lock); 846 813 ··· 858 823 * as we have enough credits. 859 824 */ 860 825 INIT_LIST_HEAD(&txq); 826 + 827 + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || 828 + (WMI_CONTROL_SVC != endpoint->svc_id)) 829 + ac = target->dev->ar->ep2ac_map[endpoint->eid]; 861 830 862 831 while (true) { 863 832 ··· 880 841 881 842 while (true) { 882 843 /* try to send a bundle on each pass */ 883 - if ((target->tx_bndl_enable) && 844 + if ((target->tx_bndl_mask) && 884 845 (get_queue_depth(&txq) >= 885 846 HTC_MIN_HTC_MSGS_TO_BUNDLE)) { 886 847 int temp1 = 0, temp2 = 0; 887 848 888 - ath6kl_htc_tx_bundle(endpoint, &txq, 889 - &temp1, &temp2); 890 - bundle_sent += temp1; 891 - n_pkts_bundle += temp2; 849 + /* check if bundling is enabled for an AC */ 850 + if (target->tx_bndl_mask & (1 << ac)) { 851 + ath6kl_htc_tx_bundle(endpoint, &txq, 852 + &temp1, &temp2); 853 + bundle_sent += temp1; 854 + n_pkts_bundle += temp2; 855 + } 892 856 } 893 857 894 858 if (list_empty(&txq)) ··· 910 868 911 869 endpoint->ep_st.tx_bundles += bundle_sent; 912 870 endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; 871 + 872 + /* 873 + * if an AC has bundling disabled and no tx bundling 874 + * has occured continously for a certain number of TX, 875 + * enable tx bundling for this AC 876 + */ 877 + if (!bundle_sent) { 878 + if (!(target->tx_bndl_mask & (1 << ac)) && 879 + (ac < WMM_NUM_AC)) { 880 + if (++target->ac_tx_count[ac] >= 881 + TX_RESUME_BUNDLE_THRESHOLD) { 882 + target->ac_tx_count[ac] = 0; 883 + target->tx_bndl_mask |= (1 << ac); 884 + } 885 + } 886 + } else { 887 + /* tx bundling will reset the counter */ 888 + if (ac < WMM_NUM_AC) 889 + target->ac_tx_count[ac] = 0; 890 + } 913 891 } 914 892 915 893 endpoint->tx_proc_cnt = 0; ··· 2580 2518 target->max_rx_bndl_sz, target->max_tx_bndl_sz); 2581 2519 2582 2520 if (target->max_tx_bndl_sz) 2583 - target->tx_bndl_enable = true; 2521 + /* tx_bndl_mask is enabled per AC, each has 1 bit */ 2522 + target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1; 2584 2523 2585 2524 if (target->max_rx_bndl_sz) 2586 2525 target->rx_bndl_enable = true; ··· 2596 2533 * padding will spill into the next credit buffer 2597 2534 * which is fatal. 2598 2535 */ 2599 - target->tx_bndl_enable = false; 2536 + target->tx_bndl_mask = 0; 2600 2537 } 2601 2538 } 2602 2539
+6 -1
drivers/net/wireless/ath/ath6kl/htc.h
··· 88 88 #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) 89 89 #define WMI_MAX_SERVICES 5 90 90 91 + #define WMM_NUM_AC 4 92 + 91 93 /* reserved and used to flush ALL packets */ 92 94 #define HTC_TX_PACKET_TAG_ALL 0 93 95 #define HTC_SERVICE_TX_PACKET_TAG 1 ··· 534 532 /* max messages per bundle for HTC */ 535 533 int msg_per_bndl_max; 536 534 537 - bool tx_bndl_enable; 535 + u32 tx_bndl_mask; 538 536 int rx_bndl_enable; 539 537 int max_rx_bndl_sz; 540 538 int max_tx_bndl_sz; ··· 546 544 int max_xfer_szper_scatreq; 547 545 548 546 int chk_irq_status_cnt; 547 + 548 + /* counts the number of Tx without bundling continously per AC */ 549 + u32 ac_tx_count[WMM_NUM_AC]; 549 550 }; 550 551 551 552 void *ath6kl_htc_create(struct ath6kl *ar);
+2
drivers/net/wireless/ath/ath6kl/sdio.c
··· 602 602 node = list_first_entry(&ar_sdio->scat_req, 603 603 struct hif_scatter_req, list); 604 604 list_del(&node->list); 605 + 606 + node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req); 605 607 } 606 608 607 609 spin_unlock_bh(&ar_sdio->scat_lock);