aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl/htc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/htc.c')
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c202
1 files changed, 145 insertions, 57 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 2d721903640b..4849d99cce77 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc. 2 * Copyright (c) 2007-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -22,6 +23,9 @@
22 23
23#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) 24#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
24 25
26/* threshold to re-enable Tx bundling for an AC*/
27#define TX_RESUME_BUNDLE_THRESHOLD 1500
28
25/* Functions for Tx credit handling */ 29/* Functions for Tx credit handling */
26static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, 30static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info,
27 struct htc_endpoint_credit_dist *ep_dist, 31 struct htc_endpoint_credit_dist *ep_dist,
@@ -168,31 +172,29 @@ static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info,
168static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info, 172static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
169 struct list_head *epdist_list) 173 struct list_head *epdist_list)
170{ 174{
171 struct htc_endpoint_credit_dist *cur_dist_list; 175 struct htc_endpoint_credit_dist *cur_list;
172 176
173 list_for_each_entry(cur_dist_list, epdist_list, list) { 177 list_for_each_entry(cur_list, epdist_list, list) {
174 if (cur_dist_list->endpoint == ENDPOINT_0) 178 if (cur_list->endpoint == ENDPOINT_0)
175 continue; 179 continue;
176 180
177 if (cur_dist_list->cred_to_dist > 0) { 181 if (cur_list->cred_to_dist > 0) {
178 cur_dist_list->credits += 182 cur_list->credits += cur_list->cred_to_dist;
179 cur_dist_list->cred_to_dist; 183 cur_list->cred_to_dist = 0;
180 cur_dist_list->cred_to_dist = 0; 184
181 if (cur_dist_list->credits > 185 if (cur_list->credits > cur_list->cred_assngd)
182 cur_dist_list->cred_assngd)
183 ath6kl_credit_reduce(cred_info, 186 ath6kl_credit_reduce(cred_info,
184 cur_dist_list, 187 cur_list,
185 cur_dist_list->cred_assngd); 188 cur_list->cred_assngd);
186 189
187 if (cur_dist_list->credits > 190 if (cur_list->credits > cur_list->cred_norm)
188 cur_dist_list->cred_norm) 191 ath6kl_credit_reduce(cred_info, cur_list,
189 ath6kl_credit_reduce(cred_info, cur_dist_list, 192 cur_list->cred_norm);
190 cur_dist_list->cred_norm);
191 193
192 if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) { 194 if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) {
193 if (cur_dist_list->txq_depth == 0) 195 if (cur_list->txq_depth == 0)
194 ath6kl_credit_reduce(cred_info, 196 ath6kl_credit_reduce(cred_info,
195 cur_dist_list, 0); 197 cur_list, 0);
196 } 198 }
197 } 199 }
198 } 200 }
@@ -460,8 +462,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target,
460 INIT_LIST_HEAD(&tx_compq); 462 INIT_LIST_HEAD(&tx_compq);
461 463
462 ath6kl_dbg(ATH6KL_DBG_HTC, 464 ath6kl_dbg(ATH6KL_DBG_HTC,
463 "htc tx scat complete len %d entries %d\n", 465 "htc tx scat complete len %d entries %d\n",
464 scat_req->len, scat_req->scat_entries); 466 scat_req->len, scat_req->scat_entries);
465 467
466 if (scat_req->status) 468 if (scat_req->status)
467 ath6kl_err("send scatter req failed: %d\n", scat_req->status); 469 ath6kl_err("send scatter req failed: %d\n", scat_req->status);
@@ -599,8 +601,8 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
599 list); 601 list);
600 602
601 ath6kl_dbg(ATH6KL_DBG_HTC, 603 ath6kl_dbg(ATH6KL_DBG_HTC,
602 "htc tx got packet 0x%p queue depth %d\n", 604 "htc tx got packet 0x%p queue depth %d\n",
603 packet, get_queue_depth(&endpoint->txq)); 605 packet, get_queue_depth(&endpoint->txq));
604 606
605 len = CALC_TXRX_PADDED_LEN(target, 607 len = CALC_TXRX_PADDED_LEN(target,
606 packet->act_len + HTC_HDR_LENGTH); 608 packet->act_len + HTC_HDR_LENGTH);
@@ -670,6 +672,7 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
670 struct htc_packet *packet; 672 struct htc_packet *packet;
671 int i, len, rem_scat, cred_pad; 673 int i, len, rem_scat, cred_pad;
672 int status = 0; 674 int status = 0;
675 u8 flags;
673 676
674 rem_scat = target->max_tx_bndl_sz; 677 rem_scat = target->max_tx_bndl_sz;
675 678
@@ -696,9 +699,9 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
696 699
697 scat_req->scat_list[i].packet = packet; 700 scat_req->scat_list[i].packet = packet;
698 /* prepare packet and flag message as part of a send bundle */ 701 /* prepare packet and flag message as part of a send bundle */
699 ath6kl_htc_tx_prep_pkt(packet, 702 flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE;
700 packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE, 703 ath6kl_htc_tx_prep_pkt(packet, flags,
701 cred_pad, packet->info.tx.seqno); 704 cred_pad, packet->info.tx.seqno);
702 /* Make sure the buffer is 4-byte aligned */ 705 /* Make sure the buffer is 4-byte aligned */
703 ath6kl_htc_tx_buf_align(&packet->buf, 706 ath6kl_htc_tx_buf_align(&packet->buf,
704 packet->act_len + HTC_HDR_LENGTH); 707 packet->act_len + HTC_HDR_LENGTH);
@@ -744,6 +747,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
744 struct hif_scatter_req *scat_req = NULL; 747 struct hif_scatter_req *scat_req = NULL;
745 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; 748 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
746 int status; 749 int status;
750 u32 txb_mask;
751 u8 ac = WMM_NUM_AC;
752
753 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
754 (WMI_CONTROL_SVC != endpoint->svc_id))
755 ac = target->dev->ar->ep2ac_map[endpoint->eid];
747 756
748 while (true) { 757 while (true) {
749 status = 0; 758 status = 0;
@@ -759,10 +768,35 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
759 if (!scat_req) { 768 if (!scat_req) {
760 /* no scatter resources */ 769 /* no scatter resources */
761 ath6kl_dbg(ATH6KL_DBG_HTC, 770 ath6kl_dbg(ATH6KL_DBG_HTC,
762 "htc tx no more scatter resources\n"); 771 "htc tx no more scatter resources\n");
763 break; 772 break;
764 } 773 }
765 774
775 if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) {
776 if (WMM_AC_BE == ac)
777 /*
778 * BE, BK have priorities and bit
779 * positions reversed
780 */
781 txb_mask = (1 << WMM_AC_BK);
782 else
783 /*
784 * any AC with priority lower than
785 * itself
786 */
787 txb_mask = ((1 << ac) - 1);
788 /*
789 * when the scatter request resources drop below a
790 * certain threshold, disable Tx bundling for all
791 * AC's with priority lower than the current requesting
792 * AC. Otherwise re-enable Tx bundling for them
793 */
794 if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS)
795 target->tx_bndl_mask &= ~txb_mask;
796 else
797 target->tx_bndl_mask |= txb_mask;
798 }
799
766 ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", 800 ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n",
767 n_scat); 801 n_scat);
768 802
@@ -806,6 +840,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
806 struct htc_packet *packet; 840 struct htc_packet *packet;
807 int bundle_sent; 841 int bundle_sent;
808 int n_pkts_bundle; 842 int n_pkts_bundle;
843 u8 ac = WMM_NUM_AC;
809 844
810 spin_lock_bh(&target->tx_lock); 845 spin_lock_bh(&target->tx_lock);
811 846
@@ -823,6 +858,10 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
823 */ 858 */
824 INIT_LIST_HEAD(&txq); 859 INIT_LIST_HEAD(&txq);
825 860
861 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
862 (WMI_CONTROL_SVC != endpoint->svc_id))
863 ac = target->dev->ar->ep2ac_map[endpoint->eid];
864
826 while (true) { 865 while (true) {
827 866
828 if (list_empty(&endpoint->txq)) 867 if (list_empty(&endpoint->txq))
@@ -840,15 +879,18 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
840 879
841 while (true) { 880 while (true) {
842 /* try to send a bundle on each pass */ 881 /* try to send a bundle on each pass */
843 if ((target->tx_bndl_enable) && 882 if ((target->tx_bndl_mask) &&
844 (get_queue_depth(&txq) >= 883 (get_queue_depth(&txq) >=
845 HTC_MIN_HTC_MSGS_TO_BUNDLE)) { 884 HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
846 int temp1 = 0, temp2 = 0; 885 int temp1 = 0, temp2 = 0;
847 886
848 ath6kl_htc_tx_bundle(endpoint, &txq, 887 /* check if bundling is enabled for an AC */
849 &temp1, &temp2); 888 if (target->tx_bndl_mask & (1 << ac)) {
850 bundle_sent += temp1; 889 ath6kl_htc_tx_bundle(endpoint, &txq,
851 n_pkts_bundle += temp2; 890 &temp1, &temp2);
891 bundle_sent += temp1;
892 n_pkts_bundle += temp2;
893 }
852 } 894 }
853 895
854 if (list_empty(&txq)) 896 if (list_empty(&txq))
@@ -867,6 +909,26 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
867 909
868 endpoint->ep_st.tx_bundles += bundle_sent; 910 endpoint->ep_st.tx_bundles += bundle_sent;
869 endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; 911 endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;
912
913 /*
914 * if an AC has bundling disabled and no tx bundling
915 * has occured continously for a certain number of TX,
916 * enable tx bundling for this AC
917 */
918 if (!bundle_sent) {
919 if (!(target->tx_bndl_mask & (1 << ac)) &&
920 (ac < WMM_NUM_AC)) {
921 if (++target->ac_tx_count[ac] >=
922 TX_RESUME_BUNDLE_THRESHOLD) {
923 target->ac_tx_count[ac] = 0;
924 target->tx_bndl_mask |= (1 << ac);
925 }
926 }
927 } else {
928 /* tx bundling will reset the counter */
929 if (ac < WMM_NUM_AC)
930 target->ac_tx_count[ac] = 0;
931 }
870 } 932 }
871 933
872 endpoint->tx_proc_cnt = 0; 934 endpoint->tx_proc_cnt = 0;
@@ -979,8 +1041,8 @@ static int htc_setup_tx_complete(struct htc_target *target)
979 memcpy(&setup_comp_ext->flags, &flags, 1041 memcpy(&setup_comp_ext->flags, &flags,
980 sizeof(setup_comp_ext->flags)); 1042 sizeof(setup_comp_ext->flags));
981 set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext, 1043 set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
982 sizeof(struct htc_setup_comp_ext_msg), 1044 sizeof(struct htc_setup_comp_ext_msg),
983 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); 1045 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
984 1046
985 } else { 1047 } else {
986 struct htc_setup_comp_msg *setup_comp; 1048 struct htc_setup_comp_msg *setup_comp;
@@ -988,8 +1050,8 @@ static int htc_setup_tx_complete(struct htc_target *target)
988 memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg)); 1050 memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
989 setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID); 1051 setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
990 set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp, 1052 set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
991 sizeof(struct htc_setup_comp_msg), 1053 sizeof(struct htc_setup_comp_msg),
992 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); 1054 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
993 } 1055 }
994 1056
995 /* we want synchronous operation */ 1057 /* we want synchronous operation */
@@ -1088,9 +1150,9 @@ void ath6kl_htc_flush_txep(struct htc_target *target,
1088 packet->status = -ECANCELED; 1150 packet->status = -ECANCELED;
1089 list_del(&packet->list); 1151 list_del(&packet->list);
1090 ath6kl_dbg(ATH6KL_DBG_HTC, 1152 ath6kl_dbg(ATH6KL_DBG_HTC,
1091 "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", 1153 "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n",
1092 packet, packet->act_len, 1154 packet, packet->act_len,
1093 packet->endpoint, packet->info.tx.tag); 1155 packet->endpoint, packet->info.tx.tag);
1094 1156
1095 INIT_LIST_HEAD(&container); 1157 INIT_LIST_HEAD(&container);
1096 list_add_tail(&packet->list, &container); 1158 list_add_tail(&packet->list, &container);
@@ -1490,7 +1552,7 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
1490 1552
1491 if (packets->act_len > 0) { 1553 if (packets->act_len > 0) {
1492 ath6kl_err("htc_ctrl_rx, got message with len:%zu\n", 1554 ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
1493 packets->act_len + HTC_HDR_LENGTH); 1555 packets->act_len + HTC_HDR_LENGTH);
1494 1556
1495 ath6kl_dbg_dump(ATH6KL_DBG_HTC, 1557 ath6kl_dbg_dump(ATH6KL_DBG_HTC,
1496 "htc rx unexpected endpoint 0 message", "", 1558 "htc rx unexpected endpoint 0 message", "",
@@ -1609,8 +1671,8 @@ static int htc_parse_trailer(struct htc_target *target,
1609 } 1671 }
1610 1672
1611 lk_ahd = (struct htc_lookahead_report *) record_buf; 1673 lk_ahd = (struct htc_lookahead_report *) record_buf;
1612 if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) 1674 if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) &&
1613 && next_lk_ahds) { 1675 next_lk_ahds) {
1614 1676
1615 ath6kl_dbg(ATH6KL_DBG_HTC, 1677 ath6kl_dbg(ATH6KL_DBG_HTC,
1616 "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", 1678 "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
@@ -2038,13 +2100,13 @@ fail_rx:
2038 list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) { 2100 list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) {
2039 list_del(&packet->list); 2101 list_del(&packet->list);
2040 htc_reclaim_rxbuf(target, packet, 2102 htc_reclaim_rxbuf(target, packet,
2041 &target->endpoint[packet->endpoint]); 2103 &target->endpoint[packet->endpoint]);
2042 } 2104 }
2043 2105
2044 list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) { 2106 list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) {
2045 list_del(&packet->list); 2107 list_del(&packet->list);
2046 htc_reclaim_rxbuf(target, packet, 2108 htc_reclaim_rxbuf(target, packet,
2047 &target->endpoint[packet->endpoint]); 2109 &target->endpoint[packet->endpoint]);
2048 } 2110 }
2049 2111
2050 return status; 2112 return status;
@@ -2176,11 +2238,11 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
2176 u32 look_ahead; 2238 u32 look_ahead;
2177 2239
2178 if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead, 2240 if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead,
2179 HTC_TARGET_RESPONSE_TIMEOUT)) 2241 HTC_TARGET_RESPONSE_TIMEOUT))
2180 return NULL; 2242 return NULL;
2181 2243
2182 ath6kl_dbg(ATH6KL_DBG_HTC, 2244 ath6kl_dbg(ATH6KL_DBG_HTC,
2183 "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); 2245 "htc rx wait ctrl look_ahead 0x%X\n", look_ahead);
2184 2246
2185 htc_hdr = (struct htc_frame_hdr *)&look_ahead; 2247 htc_hdr = (struct htc_frame_hdr *)&look_ahead;
2186 2248
@@ -2245,7 +2307,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
2245 depth = get_queue_depth(pkt_queue); 2307 depth = get_queue_depth(pkt_queue);
2246 2308
2247 ath6kl_dbg(ATH6KL_DBG_HTC, 2309 ath6kl_dbg(ATH6KL_DBG_HTC,
2248 "htc rx add multiple ep id %d cnt %d len %d\n", 2310 "htc rx add multiple ep id %d cnt %d len %d\n",
2249 first_pkt->endpoint, depth, first_pkt->buf_len); 2311 first_pkt->endpoint, depth, first_pkt->buf_len);
2250 2312
2251 endpoint = &target->endpoint[first_pkt->endpoint]; 2313 endpoint = &target->endpoint[first_pkt->endpoint];
@@ -2271,8 +2333,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
2271 if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { 2333 if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
2272 if (target->ep_waiting == first_pkt->endpoint) { 2334 if (target->ep_waiting == first_pkt->endpoint) {
2273 ath6kl_dbg(ATH6KL_DBG_HTC, 2335 ath6kl_dbg(ATH6KL_DBG_HTC,
2274 "htc rx blocked on ep %d, unblocking\n", 2336 "htc rx blocked on ep %d, unblocking\n",
2275 target->ep_waiting); 2337 target->ep_waiting);
2276 target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; 2338 target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
2277 target->ep_waiting = ENDPOINT_MAX; 2339 target->ep_waiting = ENDPOINT_MAX;
2278 rx_unblock = true; 2340 rx_unblock = true;
@@ -2309,7 +2371,21 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target)
2309 "htc rx flush pkt 0x%p len %d ep %d\n", 2371 "htc rx flush pkt 0x%p len %d ep %d\n",
2310 packet, packet->buf_len, 2372 packet, packet->buf_len,
2311 packet->endpoint); 2373 packet->endpoint);
2312 dev_kfree_skb(packet->pkt_cntxt); 2374 /*
2375 * packets in rx_bufq of endpoint 0 have originally
2376 * been queued from target->free_ctrl_rxbuf where
2377 * packet and packet->buf_start are allocated
2378 * separately using kmalloc(). For other endpoint
2379 * rx_bufq, it is allocated as skb where packet is
2380 * skb->head. Take care of this difference while freeing
2381 * the memory.
2382 */
2383 if (packet->endpoint == ENDPOINT_0) {
2384 kfree(packet->buf_start);
2385 kfree(packet);
2386 } else {
2387 dev_kfree_skb(packet->pkt_cntxt);
2388 }
2313 spin_lock_bh(&target->rx_lock); 2389 spin_lock_bh(&target->rx_lock);
2314 } 2390 }
2315 spin_unlock_bh(&target->rx_lock); 2391 spin_unlock_bh(&target->rx_lock);
@@ -2328,6 +2404,7 @@ int ath6kl_htc_conn_service(struct htc_target *target,
2328 enum htc_endpoint_id assigned_ep = ENDPOINT_MAX; 2404 enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
2329 unsigned int max_msg_sz = 0; 2405 unsigned int max_msg_sz = 0;
2330 int status = 0; 2406 int status = 0;
2407 u16 msg_id;
2331 2408
2332 ath6kl_dbg(ATH6KL_DBG_HTC, 2409 ath6kl_dbg(ATH6KL_DBG_HTC,
2333 "htc connect service target 0x%p service id 0x%x\n", 2410 "htc connect service target 0x%p service id 0x%x\n",
@@ -2371,9 +2448,10 @@ int ath6kl_htc_conn_service(struct htc_target *target,
2371 } 2448 }
2372 2449
2373 resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf; 2450 resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
2451 msg_id = le16_to_cpu(resp_msg->msg_id);
2374 2452
2375 if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID) 2453 if ((msg_id != HTC_MSG_CONN_SVC_RESP_ID) ||
2376 || (rx_pkt->act_len < sizeof(*resp_msg))) { 2454 (rx_pkt->act_len < sizeof(*resp_msg))) {
2377 status = -ENOMEM; 2455 status = -ENOMEM;
2378 goto fail_tx; 2456 goto fail_tx;
2379 } 2457 }
@@ -2420,6 +2498,15 @@ int ath6kl_htc_conn_service(struct htc_target *target,
2420 endpoint->cred_dist.endpoint = assigned_ep; 2498 endpoint->cred_dist.endpoint = assigned_ep;
2421 endpoint->cred_dist.cred_sz = target->tgt_cred_sz; 2499 endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
2422 2500
2501 switch (endpoint->svc_id) {
2502 case WMI_DATA_BK_SVC:
2503 endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3;
2504 break;
2505 default:
2506 endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM;
2507 break;
2508 }
2509
2423 if (conn_req->max_rxmsg_sz) { 2510 if (conn_req->max_rxmsg_sz) {
2424 /* 2511 /*
2425 * Override cred_per_msg calculation, this optimizes 2512 * Override cred_per_msg calculation, this optimizes
@@ -2517,7 +2604,8 @@ static void htc_setup_msg_bndl(struct htc_target *target)
2517 target->max_rx_bndl_sz, target->max_tx_bndl_sz); 2604 target->max_rx_bndl_sz, target->max_tx_bndl_sz);
2518 2605
2519 if (target->max_tx_bndl_sz) 2606 if (target->max_tx_bndl_sz)
2520 target->tx_bndl_enable = true; 2607 /* tx_bndl_mask is enabled per AC, each has 1 bit */
2608 target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1;
2521 2609
2522 if (target->max_rx_bndl_sz) 2610 if (target->max_rx_bndl_sz)
2523 target->rx_bndl_enable = true; 2611 target->rx_bndl_enable = true;
@@ -2532,7 +2620,7 @@ static void htc_setup_msg_bndl(struct htc_target *target)
2532 * padding will spill into the next credit buffer 2620 * padding will spill into the next credit buffer
2533 * which is fatal. 2621 * which is fatal.
2534 */ 2622 */
2535 target->tx_bndl_enable = false; 2623 target->tx_bndl_mask = 0;
2536 } 2624 }
2537} 2625}
2538 2626
@@ -2589,8 +2677,8 @@ int ath6kl_htc_wait_target(struct htc_target *target)
2589 } 2677 }
2590 2678
2591 ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n", 2679 ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n",
2592 (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", 2680 (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
2593 target->htc_tgt_ver); 2681 target->htc_tgt_ver);
2594 2682
2595 if (target->msg_per_bndl_max > 0) 2683 if (target->msg_per_bndl_max > 0)
2596 htc_setup_msg_bndl(target); 2684 htc_setup_msg_bndl(target);
@@ -2784,14 +2872,14 @@ void ath6kl_htc_cleanup(struct htc_target *target)
2784 ath6kl_hif_cleanup_scatter(target->dev->ar); 2872 ath6kl_hif_cleanup_scatter(target->dev->ar);
2785 2873
2786 list_for_each_entry_safe(packet, tmp_packet, 2874 list_for_each_entry_safe(packet, tmp_packet,
2787 &target->free_ctrl_txbuf, list) { 2875 &target->free_ctrl_txbuf, list) {
2788 list_del(&packet->list); 2876 list_del(&packet->list);
2789 kfree(packet->buf_start); 2877 kfree(packet->buf_start);
2790 kfree(packet); 2878 kfree(packet);
2791 } 2879 }
2792 2880
2793 list_for_each_entry_safe(packet, tmp_packet, 2881 list_for_each_entry_safe(packet, tmp_packet,
2794 &target->free_ctrl_rxbuf, list) { 2882 &target->free_ctrl_rxbuf, list) {
2795 list_del(&packet->list); 2883 list_del(&packet->list);
2796 kfree(packet->buf_start); 2884 kfree(packet->buf_start);
2797 kfree(packet); 2885 kfree(packet);