Lines Matching +full:num +full:- +full:txq

2  * Copyright (c) 2007-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
21 #include "hif-ops.h"
26 #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
36 /* threshold to re-enable Tx bundling for an AC*/
45 ep_dist->endpoint, credits); in ath6kl_credit_deposit()
47 ep_dist->credits += credits; in ath6kl_credit_deposit()
48 ep_dist->cred_assngd += credits; in ath6kl_credit_deposit()
49 cred_info->cur_free_credits -= credits; in ath6kl_credit_deposit()
61 cred_info->cur_free_credits = tot_credits; in ath6kl_credit_init()
62 cred_info->total_avail_credits = tot_credits; in ath6kl_credit_init()
65 if (cur_ep_dist->endpoint == ENDPOINT_0) in ath6kl_credit_init()
68 cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg; in ath6kl_credit_init()
71 if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) || in ath6kl_credit_init()
72 (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) { in ath6kl_credit_init()
75 cur_ep_dist->cred_min); in ath6kl_credit_init()
76 cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; in ath6kl_credit_init()
80 if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) { in ath6kl_credit_init()
82 cur_ep_dist->cred_min); in ath6kl_credit_init()
87 cur_ep_dist->dist_flags |= HTC_EP_ACTIVE; in ath6kl_credit_init()
107 cred_info->lowestpri_ep_dist = cur_ep_dist->list; in ath6kl_credit_init()
109 WARN_ON(cred_info->cur_free_credits <= 0); in ath6kl_credit_init()
112 if (cur_ep_dist->endpoint == ENDPOINT_0) in ath6kl_credit_init()
115 if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) { in ath6kl_credit_init()
116 cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg; in ath6kl_credit_init()
126 count = (cred_info->cur_free_credits / in ath6kl_credit_init()
127 cur_ep_dist->cred_per_msg) in ath6kl_credit_init()
128 * cur_ep_dist->cred_per_msg; in ath6kl_credit_init()
130 count = max(count, cur_ep_dist->cred_per_msg); in ath6kl_credit_init()
131 cur_ep_dist->cred_norm = count; in ath6kl_credit_init()
136 cur_ep_dist->endpoint, in ath6kl_credit_init()
137 cur_ep_dist->svc_id, in ath6kl_credit_init()
138 cur_ep_dist->credits, in ath6kl_credit_init()
139 cur_ep_dist->cred_per_msg, in ath6kl_credit_init()
140 cur_ep_dist->cred_norm, in ath6kl_credit_init()
141 cur_ep_dist->cred_min); in ath6kl_credit_init()
173 ep_dist->endpoint, limit); in ath6kl_credit_reduce()
175 ep_dist->cred_assngd = limit; in ath6kl_credit_reduce()
177 if (ep_dist->credits <= limit) in ath6kl_credit_reduce()
180 credits = ep_dist->credits - limit; in ath6kl_credit_reduce()
181 ep_dist->credits -= credits; in ath6kl_credit_reduce()
182 cred_info->cur_free_credits += credits; in ath6kl_credit_reduce()
191 if (cur_list->endpoint == ENDPOINT_0) in ath6kl_credit_update()
194 if (cur_list->cred_to_dist > 0) { in ath6kl_credit_update()
195 cur_list->credits += cur_list->cred_to_dist; in ath6kl_credit_update()
196 cur_list->cred_to_dist = 0; in ath6kl_credit_update()
198 if (cur_list->credits > cur_list->cred_assngd) in ath6kl_credit_update()
201 cur_list->cred_assngd); in ath6kl_credit_update()
203 if (cur_list->credits > cur_list->cred_norm) in ath6kl_credit_update()
205 cur_list->cred_norm); in ath6kl_credit_update()
207 if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) { in ath6kl_credit_update()
208 if (cur_list->txq_depth == 0) in ath6kl_credit_update()
227 if (ep_dist->svc_id == WMI_CONTROL_SVC) in ath6kl_credit_seek()
230 if ((ep_dist->svc_id == WMI_DATA_VI_SVC) || in ath6kl_credit_seek()
231 (ep_dist->svc_id == WMI_DATA_VO_SVC)) in ath6kl_credit_seek()
232 if ((ep_dist->cred_assngd >= ep_dist->cred_norm)) in ath6kl_credit_seek()
242 credits = min(cred_info->cur_free_credits, ep_dist->seek_cred); in ath6kl_credit_seek()
244 if (credits >= ep_dist->seek_cred) in ath6kl_credit_seek()
258 &cred_info->lowestpri_ep_dist, in ath6kl_credit_seek()
263 need = ep_dist->seek_cred - cred_info->cur_free_credits; in ath6kl_credit_seek()
265 if ((curdist_list->cred_assngd - need) >= in ath6kl_credit_seek()
266 curdist_list->cred_min) { in ath6kl_credit_seek()
274 curdist_list->cred_assngd - need); in ath6kl_credit_seek()
276 if (cred_info->cur_free_credits >= in ath6kl_credit_seek()
277 ep_dist->seek_cred) in ath6kl_credit_seek()
281 if (curdist_list->endpoint == ENDPOINT_0) in ath6kl_credit_seek()
285 credits = min(cred_info->cur_free_credits, ep_dist->seek_cred); in ath6kl_credit_seek()
292 ep_dist->seek_cred = 0; in ath6kl_credit_seek()
302 if (curdist_list->endpoint == ENDPOINT_0) in ath6kl_credit_redistribute()
305 if ((curdist_list->svc_id == WMI_DATA_BK_SVC) || in ath6kl_credit_redistribute()
306 (curdist_list->svc_id == WMI_DATA_BE_SVC)) in ath6kl_credit_redistribute()
307 curdist_list->dist_flags |= HTC_EP_ACTIVE; in ath6kl_credit_redistribute()
309 if ((curdist_list->svc_id != WMI_CONTROL_SVC) && in ath6kl_credit_redistribute()
310 !(curdist_list->dist_flags & HTC_EP_ACTIVE)) { in ath6kl_credit_redistribute()
311 if (curdist_list->txq_depth == 0) in ath6kl_credit_redistribute()
316 curdist_list->cred_min); in ath6kl_credit_redistribute()
344 WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits); in ath6kl_credit_distribute()
345 WARN_ON(cred_info->cur_free_credits < 0); in ath6kl_credit_distribute()
353 align_addr = PTR_ALIGN(*buf - 4, 4); in ath6kl_htc_tx_buf_align()
364 packet->buf -= HTC_HDR_LENGTH; in ath6kl_htc_tx_prep_pkt()
365 hdr = (struct htc_frame_hdr *)packet->buf; in ath6kl_htc_tx_prep_pkt()
367 put_unaligned_le16(packet->act_len, &hdr->payld_len); in ath6kl_htc_tx_prep_pkt()
368 hdr->flags = flags; in ath6kl_htc_tx_prep_pkt()
369 hdr->eid = packet->endpoint; in ath6kl_htc_tx_prep_pkt()
370 hdr->ctrl[0] = ctrl0; in ath6kl_htc_tx_prep_pkt()
371 hdr->ctrl[1] = ctrl1; in ath6kl_htc_tx_prep_pkt()
377 spin_lock_bh(&target->htc_lock); in htc_reclaim_txctrl_buf()
378 list_add_tail(&pkt->list, &target->free_ctrl_txbuf); in htc_reclaim_txctrl_buf()
379 spin_unlock_bh(&target->htc_lock); in htc_reclaim_txctrl_buf()
388 buf_list = tx ? &target->free_ctrl_txbuf : &target->free_ctrl_rxbuf; in htc_get_control_buf()
390 spin_lock_bh(&target->htc_lock); in htc_get_control_buf()
393 spin_unlock_bh(&target->htc_lock); in htc_get_control_buf()
398 list_del(&packet->list); in htc_get_control_buf()
399 spin_unlock_bh(&target->htc_lock); in htc_get_control_buf()
402 packet->buf = packet->buf_start + HTC_HDR_LENGTH; in htc_get_control_buf()
411 packet->completion = NULL; in htc_tx_comp_update()
412 packet->buf += HTC_HDR_LENGTH; in htc_tx_comp_update()
414 if (!packet->status) in htc_tx_comp_update()
418 packet->status, packet->endpoint, packet->act_len, in htc_tx_comp_update()
419 packet->info.tx.cred_used); in htc_tx_comp_update()
422 spin_lock_bh(&target->tx_lock); in htc_tx_comp_update()
423 endpoint->cred_dist.cred_to_dist += in htc_tx_comp_update()
424 packet->info.tx.cred_used; in htc_tx_comp_update()
425 endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq); in htc_tx_comp_update()
428 target->credit_info, &target->cred_dist_list); in htc_tx_comp_update()
430 ath6kl_credit_distribute(target->credit_info, in htc_tx_comp_update()
431 &target->cred_dist_list, in htc_tx_comp_update()
434 spin_unlock_bh(&target->tx_lock); in htc_tx_comp_update()
438 struct list_head *txq) in htc_tx_complete() argument
440 if (list_empty(txq)) in htc_tx_complete()
445 endpoint->eid, get_queue_depth(txq)); in htc_tx_complete()
447 ath6kl_tx_complete(endpoint->target, txq); in htc_tx_complete()
453 struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint]; in htc_tx_comp_handler()
457 packet->info.tx.seqno); in htc_tx_comp_handler()
461 list_add_tail(&packet->list, &container); in htc_tx_comp_handler()
478 scat_req->len, scat_req->scat_entries); in htc_async_tx_scat_complete()
480 if (scat_req->status) in htc_async_tx_scat_complete()
481 ath6kl_err("send scatter req failed: %d\n", scat_req->status); in htc_async_tx_scat_complete()
483 packet = scat_req->scat_list[0].packet; in htc_async_tx_scat_complete()
484 endpoint = &target->endpoint[packet->endpoint]; in htc_async_tx_scat_complete()
487 for (i = 0; i < scat_req->scat_entries; i++) { in htc_async_tx_scat_complete()
488 packet = scat_req->scat_list[i].packet; in htc_async_tx_scat_complete()
494 packet->status = scat_req->status; in htc_async_tx_scat_complete()
496 list_add_tail(&packet->list, &tx_compq); in htc_async_tx_scat_complete()
500 hif_scatter_req_add(target->dev->ar, scat_req); in htc_async_tx_scat_complete()
513 if (!packet->completion) in ath6kl_htc_tx_issue()
516 send_len = packet->act_len + HTC_HDR_LENGTH; in ath6kl_htc_tx_issue()
522 send_len, packet->info.tx.seqno, padded_len, in ath6kl_htc_tx_issue()
523 target->dev->ar->mbox_info.htc_addr, in ath6kl_htc_tx_issue()
527 status = hif_read_write_sync(target->dev->ar, in ath6kl_htc_tx_issue()
528 target->dev->ar->mbox_info.htc_addr, in ath6kl_htc_tx_issue()
529 packet->buf, padded_len, in ath6kl_htc_tx_issue()
532 packet->status = status; in ath6kl_htc_tx_issue()
533 packet->buf += HTC_HDR_LENGTH; in ath6kl_htc_tx_issue()
535 status = hif_write_async(target->dev->ar, in ath6kl_htc_tx_issue()
536 target->dev->ar->mbox_info.htc_addr, in ath6kl_htc_tx_issue()
537 packet->buf, padded_len, in ath6kl_htc_tx_issue()
540 trace_ath6kl_htc_tx(status, packet->endpoint, packet->buf, send_len); in ath6kl_htc_tx_issue()
550 *req_cred = (len > target->tgt_cred_sz) ? in htc_check_credits()
551 DIV_ROUND_UP(len, target->tgt_cred_sz) : 1; in htc_check_credits()
554 *req_cred, ep->cred_dist.credits); in htc_check_credits()
556 if (ep->cred_dist.credits < *req_cred) { in htc_check_credits()
558 return -EINVAL; in htc_check_credits()
561 ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits; in htc_check_credits()
563 ath6kl_credit_seek(target->credit_info, &ep->cred_dist); in htc_check_credits()
565 ep->cred_dist.seek_cred = 0; in htc_check_credits()
567 if (ep->cred_dist.credits < *req_cred) { in htc_check_credits()
571 return -EINVAL; in htc_check_credits()
575 ep->cred_dist.credits -= *req_cred; in htc_check_credits()
576 ep->ep_st.cred_cosumd += *req_cred; in htc_check_credits()
579 if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) { in htc_check_credits()
580 ep->cred_dist.seek_cred = in htc_check_credits()
581 ep->cred_dist.cred_per_msg - ep->cred_dist.credits; in htc_check_credits()
583 ath6kl_credit_seek(target->credit_info, &ep->cred_dist); in htc_check_credits()
586 if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) { in htc_check_credits()
589 ep->ep_st.cred_low_indicate += 1; in htc_check_credits()
610 if (list_empty(&endpoint->txq)) in ath6kl_htc_tx_pkts_get()
612 packet = list_first_entry(&endpoint->txq, struct htc_packet, in ath6kl_htc_tx_pkts_get()
617 packet, get_queue_depth(&endpoint->txq)); in ath6kl_htc_tx_pkts_get()
620 packet->act_len + HTC_HDR_LENGTH); in ath6kl_htc_tx_pkts_get()
623 packet->endpoint, len, &req_cred)) in ath6kl_htc_tx_pkts_get()
627 packet = list_first_entry(&endpoint->txq, struct htc_packet, in ath6kl_htc_tx_pkts_get()
629 list_move_tail(&packet->list, queue); in ath6kl_htc_tx_pkts_get()
632 packet->info.tx.cred_used = req_cred; in ath6kl_htc_tx_pkts_get()
635 packet->completion = htc_tx_comp_handler; in ath6kl_htc_tx_pkts_get()
636 packet->context = target; in ath6kl_htc_tx_pkts_get()
637 endpoint->ep_st.tx_issued += 1; in ath6kl_htc_tx_pkts_get()
640 packet->info.tx.flags = flags; in ath6kl_htc_tx_pkts_get()
641 packet->info.tx.seqno = endpoint->seqno; in ath6kl_htc_tx_pkts_get()
642 endpoint->seqno++; in ath6kl_htc_tx_pkts_get()
658 if (!(ep->conn_flags & HTC_FLGS_TX_BNDL_PAD_EN)) in htc_get_credit_padding()
659 return -1; in htc_get_credit_padding()
667 cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred; in htc_get_credit_padding()
672 /* The amount of padding is too large, send as non-bundled */ in htc_get_credit_padding()
673 return -1; in htc_get_credit_padding()
689 rem_scat = target->max_tx_bndl_sz; in ath6kl_htc_tx_setup_scat_list()
692 scat_req->scat_list[i].packet = NULL; in ath6kl_htc_tx_setup_scat_list()
699 packet->act_len + HTC_HDR_LENGTH); in ath6kl_htc_tx_setup_scat_list()
701 cred_pad = htc_get_credit_padding(target->tgt_cred_sz, in ath6kl_htc_tx_setup_scat_list()
704 status = -ENOSPC; in ath6kl_htc_tx_setup_scat_list()
708 rem_scat -= len; in ath6kl_htc_tx_setup_scat_list()
710 list_del(&packet->list); in ath6kl_htc_tx_setup_scat_list()
712 scat_req->scat_list[i].packet = packet; in ath6kl_htc_tx_setup_scat_list()
714 flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE; in ath6kl_htc_tx_setup_scat_list()
716 cred_pad, packet->info.tx.seqno); in ath6kl_htc_tx_setup_scat_list()
717 /* Make sure the buffer is 4-byte aligned */ in ath6kl_htc_tx_setup_scat_list()
718 ath6kl_htc_tx_buf_align(&packet->buf, in ath6kl_htc_tx_setup_scat_list()
719 packet->act_len + HTC_HDR_LENGTH); in ath6kl_htc_tx_setup_scat_list()
720 scat_req->scat_list[i].buf = packet->buf; in ath6kl_htc_tx_setup_scat_list()
721 scat_req->scat_list[i].len = len; in ath6kl_htc_tx_setup_scat_list()
723 scat_req->len += len; in ath6kl_htc_tx_setup_scat_list()
724 scat_req->scat_entries++; in ath6kl_htc_tx_setup_scat_list()
727 i, packet, packet->info.tx.seqno, len, rem_scat); in ath6kl_htc_tx_setup_scat_list()
731 if (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE) { in ath6kl_htc_tx_setup_scat_list()
732 for (i = scat_req->scat_entries - 1; i >= 0; i--) { in ath6kl_htc_tx_setup_scat_list()
733 packet = scat_req->scat_list[i].packet; in ath6kl_htc_tx_setup_scat_list()
735 packet->buf += HTC_HDR_LENGTH; in ath6kl_htc_tx_setup_scat_list()
736 list_add(&packet->list, queue); in ath6kl_htc_tx_setup_scat_list()
739 return -EAGAIN; in ath6kl_htc_tx_setup_scat_list()
758 struct htc_target *target = endpoint->target; in ath6kl_htc_tx_bundle()
766 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) && in ath6kl_htc_tx_bundle()
767 (WMI_CONTROL_SVC != endpoint->svc_id)) in ath6kl_htc_tx_bundle()
768 ac = target->dev->ar->ep2ac_map[endpoint->eid]; in ath6kl_htc_tx_bundle()
773 n_scat = min(n_scat, target->msg_per_bndl_max); in ath6kl_htc_tx_bundle()
779 scat_req = hif_scatter_req_get(target->dev->ar); in ath6kl_htc_tx_bundle()
800 txb_mask = ((1 << ac) - 1); in ath6kl_htc_tx_bundle()
806 * AC. Otherwise re-enable Tx bundling for them in ath6kl_htc_tx_bundle()
808 if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) in ath6kl_htc_tx_bundle()
809 target->tx_bndl_mask &= ~txb_mask; in ath6kl_htc_tx_bundle()
811 target->tx_bndl_mask |= txb_mask; in ath6kl_htc_tx_bundle()
817 scat_req->len = 0; in ath6kl_htc_tx_bundle()
818 scat_req->scat_entries = 0; in ath6kl_htc_tx_bundle()
823 if (status == -EAGAIN) { in ath6kl_htc_tx_bundle()
824 hif_scatter_req_add(target->dev->ar, scat_req); in ath6kl_htc_tx_bundle()
829 scat_req->complete = htc_async_tx_scat_complete; in ath6kl_htc_tx_bundle()
831 tot_pkts_bundle += scat_req->scat_entries; in ath6kl_htc_tx_bundle()
835 scat_req->len, scat_req->scat_entries); in ath6kl_htc_tx_bundle()
837 for (i = 0; i < scat_req->scat_entries; i++) { in ath6kl_htc_tx_bundle()
838 packet = scat_req->scat_list[i].packet; in ath6kl_htc_tx_bundle()
839 trace_ath6kl_htc_tx(packet->status, packet->endpoint, in ath6kl_htc_tx_bundle()
840 packet->buf, packet->act_len); in ath6kl_htc_tx_bundle()
843 ath6kl_hif_submit_scat_req(target->dev, scat_req, false); in ath6kl_htc_tx_bundle()
860 struct list_head txq; in ath6kl_htc_tx_from_queue() local
867 spin_lock_bh(&target->tx_lock); in ath6kl_htc_tx_from_queue()
869 endpoint->tx_proc_cnt++; in ath6kl_htc_tx_from_queue()
870 if (endpoint->tx_proc_cnt > 1) { in ath6kl_htc_tx_from_queue()
871 endpoint->tx_proc_cnt--; in ath6kl_htc_tx_from_queue()
872 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_tx_from_queue()
881 INIT_LIST_HEAD(&txq); in ath6kl_htc_tx_from_queue()
883 if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) && in ath6kl_htc_tx_from_queue()
884 (WMI_CONTROL_SVC != endpoint->svc_id)) in ath6kl_htc_tx_from_queue()
885 ac = target->dev->ar->ep2ac_map[endpoint->eid]; in ath6kl_htc_tx_from_queue()
888 if (list_empty(&endpoint->txq)) in ath6kl_htc_tx_from_queue()
891 ath6kl_htc_tx_pkts_get(target, endpoint, &txq); in ath6kl_htc_tx_from_queue()
893 if (list_empty(&txq)) in ath6kl_htc_tx_from_queue()
896 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_tx_from_queue()
903 if ((target->tx_bndl_mask) && in ath6kl_htc_tx_from_queue()
904 (get_queue_depth(&txq) >= in ath6kl_htc_tx_from_queue()
909 if (target->tx_bndl_mask & (1 << ac)) { in ath6kl_htc_tx_from_queue()
910 ath6kl_htc_tx_bundle(endpoint, &txq, in ath6kl_htc_tx_from_queue()
917 if (list_empty(&txq)) in ath6kl_htc_tx_from_queue()
920 packet = list_first_entry(&txq, struct htc_packet, in ath6kl_htc_tx_from_queue()
922 list_del(&packet->list); in ath6kl_htc_tx_from_queue()
924 ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags, in ath6kl_htc_tx_from_queue()
925 0, packet->info.tx.seqno); in ath6kl_htc_tx_from_queue()
929 packet->status = status; in ath6kl_htc_tx_from_queue()
930 packet->completion(packet->context, packet); in ath6kl_htc_tx_from_queue()
934 spin_lock_bh(&target->tx_lock); in ath6kl_htc_tx_from_queue()
936 endpoint->ep_st.tx_bundles += bundle_sent; in ath6kl_htc_tx_from_queue()
937 endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; in ath6kl_htc_tx_from_queue()
945 if (!(target->tx_bndl_mask & (1 << ac)) && in ath6kl_htc_tx_from_queue()
947 if (++target->ac_tx_count[ac] >= in ath6kl_htc_tx_from_queue()
949 target->ac_tx_count[ac] = 0; in ath6kl_htc_tx_from_queue()
950 target->tx_bndl_mask |= (1 << ac); in ath6kl_htc_tx_from_queue()
956 target->ac_tx_count[ac] = 0; in ath6kl_htc_tx_from_queue()
960 endpoint->tx_proc_cnt = 0; in ath6kl_htc_tx_from_queue()
961 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_tx_from_queue()
972 ep_cb = endpoint->ep_cb; in ath6kl_htc_tx_try()
974 spin_lock_bh(&target->tx_lock); in ath6kl_htc_tx_try()
975 txq_depth = get_queue_depth(&endpoint->txq); in ath6kl_htc_tx_try()
976 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_tx_try()
978 if (txq_depth >= endpoint->max_txq_depth) in ath6kl_htc_tx_try()
984 endpoint->eid, txq_depth, in ath6kl_htc_tx_try()
985 endpoint->max_txq_depth); in ath6kl_htc_tx_try()
988 if (ep_cb.tx_full(endpoint->target, tx_pkt) == in ath6kl_htc_tx_try()
990 endpoint->ep_st.tx_dropped += 1; in ath6kl_htc_tx_try()
995 spin_lock_bh(&target->tx_lock); in ath6kl_htc_tx_try()
996 list_add_tail(&tx_pkt->list, &endpoint->txq); in ath6kl_htc_tx_try()
997 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_tx_try()
1012 * distribution list is not dynamic (cannot be re-ordered) and we in htc_chk_ep_txq()
1015 list_for_each_entry(cred_dist, &target->cred_dist_list, list) { in htc_chk_ep_txq()
1016 endpoint = cred_dist->htc_ep; in htc_chk_ep_txq()
1018 spin_lock_bh(&target->tx_lock); in htc_chk_ep_txq()
1019 if (!list_empty(&endpoint->txq)) { in htc_chk_ep_txq()
1022 cred_dist->endpoint, in htc_chk_ep_txq()
1023 endpoint->cred_dist.credits, in htc_chk_ep_txq()
1024 get_queue_depth(&endpoint->txq)); in htc_chk_ep_txq()
1025 spin_unlock_bh(&target->tx_lock); in htc_chk_ep_txq()
1034 spin_lock_bh(&target->tx_lock); in htc_chk_ep_txq()
1036 spin_unlock_bh(&target->tx_lock); in htc_chk_ep_txq()
1048 return -ENOMEM; in htc_setup_tx_complete()
1050 if (target->htc_tgt_ver >= HTC_VERSION_2P1) { in htc_setup_tx_complete()
1055 (struct htc_setup_comp_ext_msg *)send_pkt->buf; in htc_setup_tx_complete()
1057 setup_comp_ext->msg_id = in htc_setup_tx_complete()
1060 if (target->msg_per_bndl_max > 0) { in htc_setup_tx_complete()
1063 setup_comp_ext->msg_per_rxbndl = in htc_setup_tx_complete()
1064 target->msg_per_bndl_max; in htc_setup_tx_complete()
1067 memcpy(&setup_comp_ext->flags, &flags, in htc_setup_tx_complete()
1068 sizeof(setup_comp_ext->flags)); in htc_setup_tx_complete()
1075 setup_comp = (struct htc_setup_comp_msg *)send_pkt->buf; in htc_setup_tx_complete()
1077 setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID); in htc_setup_tx_complete()
1084 send_pkt->completion = NULL; in htc_setup_tx_complete()
1099 target->credit_info = credit_info; in ath6kl_htc_set_credit_dist()
1101 list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list, in ath6kl_htc_set_credit_dist()
1102 &target->cred_dist_list); in ath6kl_htc_set_credit_dist()
1106 endpoint = &target->endpoint[ep]; in ath6kl_htc_set_credit_dist()
1107 if (endpoint->svc_id == srvc_pri_order[i]) { in ath6kl_htc_set_credit_dist()
1108 list_add_tail(&endpoint->cred_dist.list, in ath6kl_htc_set_credit_dist()
1109 &target->cred_dist_list); in ath6kl_htc_set_credit_dist()
1128 packet->endpoint, packet->buf, packet->act_len); in ath6kl_htc_mbox_tx()
1130 if (packet->endpoint >= ENDPOINT_MAX) { in ath6kl_htc_mbox_tx()
1132 return -EINVAL; in ath6kl_htc_mbox_tx()
1135 endpoint = &target->endpoint[packet->endpoint]; in ath6kl_htc_mbox_tx()
1138 packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ? in ath6kl_htc_mbox_tx()
1139 -ECANCELED : -ENOSPC; in ath6kl_htc_mbox_tx()
1141 list_add(&packet->list, &queue); in ath6kl_htc_mbox_tx()
1154 struct htc_endpoint *endpoint = &target->endpoint[eid]; in ath6kl_htc_mbox_flush_txep()
1156 if (!endpoint->svc_id) { in ath6kl_htc_mbox_flush_txep()
1164 spin_lock_bh(&target->tx_lock); in ath6kl_htc_mbox_flush_txep()
1166 list_for_each_entry_safe(packet, tmp_pkt, &endpoint->txq, list) { in ath6kl_htc_mbox_flush_txep()
1168 (tag == packet->info.tx.tag)) in ath6kl_htc_mbox_flush_txep()
1169 list_move_tail(&packet->list, &discard_q); in ath6kl_htc_mbox_flush_txep()
1172 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_mbox_flush_txep()
1175 packet->status = -ECANCELED; in ath6kl_htc_mbox_flush_txep()
1176 list_del(&packet->list); in ath6kl_htc_mbox_flush_txep()
1179 packet, packet->act_len, in ath6kl_htc_mbox_flush_txep()
1180 packet->endpoint, packet->info.tx.tag); in ath6kl_htc_mbox_flush_txep()
1183 list_add_tail(&packet->list, &container); in ath6kl_htc_mbox_flush_txep()
1196 endpoint = &target->endpoint[i]; in ath6kl_htc_flush_txep_all()
1197 if (endpoint->svc_id == 0) in ath6kl_htc_flush_txep_all()
1208 struct htc_endpoint *endpoint = &target->endpoint[eid]; in ath6kl_htc_mbox_activity_changed()
1211 if (endpoint->svc_id == 0) { in ath6kl_htc_mbox_activity_changed()
1216 spin_lock_bh(&target->tx_lock); in ath6kl_htc_mbox_activity_changed()
1219 if (!(endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE)) { in ath6kl_htc_mbox_activity_changed()
1220 endpoint->cred_dist.dist_flags |= HTC_EP_ACTIVE; in ath6kl_htc_mbox_activity_changed()
1224 if (endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE) { in ath6kl_htc_mbox_activity_changed()
1225 endpoint->cred_dist.dist_flags &= ~HTC_EP_ACTIVE; in ath6kl_htc_mbox_activity_changed()
1231 endpoint->cred_dist.txq_depth = in ath6kl_htc_mbox_activity_changed()
1232 get_queue_depth(&endpoint->txq); in ath6kl_htc_mbox_activity_changed()
1236 target->credit_info, &target->cred_dist_list); in ath6kl_htc_mbox_activity_changed()
1238 ath6kl_credit_distribute(target->credit_info, in ath6kl_htc_mbox_activity_changed()
1239 &target->cred_dist_list, in ath6kl_htc_mbox_activity_changed()
1243 spin_unlock_bh(&target->tx_lock); in ath6kl_htc_mbox_activity_changed()
1254 endpoint->ep_st.rx_pkts++; in ath6kl_htc_rx_update_stats()
1256 endpoint->ep_st.rx_lkahds++; in ath6kl_htc_rx_update_stats()
1258 endpoint->ep_st.rx_bundle_lkahd++; in ath6kl_htc_rx_update_stats()
1264 return (eid == target->dev->ar->ctrl_ep) ? in htc_valid_rx_frame_len()
1273 list_add_tail(&packet->list, &queue); in htc_add_rxbuf()
1281 if (packet->info.rx.rx_flags & HTC_RX_PKT_NO_RECYCLE) { in htc_reclaim_rxbuf()
1283 packet->status = -ECANCELED; in htc_reclaim_rxbuf()
1284 ep->ep_cb.rx(ep->target, packet); in htc_reclaim_rxbuf()
1294 spin_lock_bh(&target->htc_lock); in reclaim_rx_ctrl_buf()
1295 list_add_tail(&packet->list, &target->free_ctrl_rxbuf); in reclaim_rx_ctrl_buf()
1296 spin_unlock_bh(&target->htc_lock); in reclaim_rx_ctrl_buf()
1303 struct ath6kl_device *dev = target->dev; in ath6kl_htc_rx_packet()
1309 if (padded_len > packet->buf_len) { in ath6kl_htc_rx_packet()
1310 ath6kl_err("not enough receive space for packet - padlen %d recvlen %d bufferlen %d\n", in ath6kl_htc_rx_packet()
1311 padded_len, rx_len, packet->buf_len); in ath6kl_htc_rx_packet()
1312 return -ENOMEM; in ath6kl_htc_rx_packet()
1317 packet, packet->info.rx.exp_hdr, in ath6kl_htc_rx_packet()
1318 padded_len, dev->ar->mbox_info.htc_addr); in ath6kl_htc_rx_packet()
1320 status = hif_read_write_sync(dev->ar, in ath6kl_htc_rx_packet()
1321 dev->ar->mbox_info.htc_addr, in ath6kl_htc_rx_packet()
1322 packet->buf, padded_len, in ath6kl_htc_rx_packet()
1325 packet->status = status; in ath6kl_htc_rx_packet()
1332 * "hint" that there are more single-packets to fetch
1341 if (htc_hdr->eid == packet->endpoint) { in ath6kl_htc_rx_set_indicate()
1342 if (!list_empty(&endpoint->rx_bufq)) in ath6kl_htc_rx_set_indicate()
1343 packet->info.rx.indicat_flags |= in ath6kl_htc_rx_set_indicate()
1350 struct htc_ep_callbacks ep_cb = endpoint->ep_cb; in ath6kl_htc_rx_chk_water_mark()
1353 spin_lock_bh(&endpoint->target->rx_lock); in ath6kl_htc_rx_chk_water_mark()
1354 if (get_queue_depth(&endpoint->rx_bufq) in ath6kl_htc_rx_chk_water_mark()
1356 spin_unlock_bh(&endpoint->target->rx_lock); in ath6kl_htc_rx_chk_water_mark()
1357 ep_cb.rx_refill(endpoint->target, endpoint->eid); in ath6kl_htc_rx_chk_water_mark()
1360 spin_unlock_bh(&endpoint->target->rx_lock); in ath6kl_htc_rx_chk_water_mark()
1377 le16_to_cpu(htc_hdr->payld_len) + in ath6kl_htc_rx_setup()
1380 if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) { in ath6kl_htc_rx_setup()
1382 htc_hdr->eid, htc_hdr->flags, in ath6kl_htc_rx_setup()
1383 le16_to_cpu(htc_hdr->payld_len)); in ath6kl_htc_rx_setup()
1384 return -EINVAL; in ath6kl_htc_rx_setup()
1387 ep_cb = ep->ep_cb; in ath6kl_htc_rx_setup()
1398 ep->ep_st.rx_alloc_thresh_hit += 1; in ath6kl_htc_rx_setup()
1399 ep->ep_st.rxalloc_thresh_byte += in ath6kl_htc_rx_setup()
1400 le16_to_cpu(htc_hdr->payld_len); in ath6kl_htc_rx_setup()
1402 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_rx_setup()
1405 packet = ep_cb.rx_allocthresh(ep->target, ep->eid, in ath6kl_htc_rx_setup()
1407 spin_lock_bh(&target->rx_lock); in ath6kl_htc_rx_setup()
1410 if (list_empty(&ep->rx_bufq)) { in ath6kl_htc_rx_setup()
1412 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_rx_setup()
1413 ep_cb.rx_refill(ep->target, ep->eid); in ath6kl_htc_rx_setup()
1414 spin_lock_bh(&target->rx_lock); in ath6kl_htc_rx_setup()
1418 if (list_empty(&ep->rx_bufq)) { in ath6kl_htc_rx_setup()
1421 packet = list_first_entry(&ep->rx_bufq, in ath6kl_htc_rx_setup()
1423 list_del(&packet->list); in ath6kl_htc_rx_setup()
1428 target->rx_st_flags |= HTC_RECV_WAIT_BUFFERS; in ath6kl_htc_rx_setup()
1429 target->ep_waiting = ep->eid; in ath6kl_htc_rx_setup()
1430 return -ENOSPC; in ath6kl_htc_rx_setup()
1434 packet->info.rx.rx_flags = 0; in ath6kl_htc_rx_setup()
1435 packet->info.rx.indicat_flags = 0; in ath6kl_htc_rx_setup()
1436 packet->status = 0; in ath6kl_htc_rx_setup()
1444 packet->info.rx.rx_flags |= HTC_RX_PKT_NO_RECYCLE; in ath6kl_htc_rx_setup()
1447 list_add_tail(&packet->list, queue); in ath6kl_htc_rx_setup()
1449 if (target->htc_flags & HTC_OP_STATE_STOPPING) { in ath6kl_htc_rx_setup()
1450 status = -ECANCELED; in ath6kl_htc_rx_setup()
1455 packet->info.rx.rx_flags |= HTC_RX_PKT_REFRESH_HDR; in ath6kl_htc_rx_setup()
1456 packet->info.rx.exp_hdr = 0xFFFFFFFF; in ath6kl_htc_rx_setup()
1459 packet->info.rx.exp_hdr = *lk_ahds; in ath6kl_htc_rx_setup()
1461 packet->act_len = le16_to_cpu(htc_hdr->payld_len) + in ath6kl_htc_rx_setup()
1478 spin_lock_bh(&target->rx_lock); in ath6kl_htc_rx_alloc()
1483 if (htc_hdr->eid >= ENDPOINT_MAX) { in ath6kl_htc_rx_alloc()
1484 ath6kl_err("invalid ep in look-ahead: %d\n", in ath6kl_htc_rx_alloc()
1485 htc_hdr->eid); in ath6kl_htc_rx_alloc()
1486 status = -ENOMEM; in ath6kl_htc_rx_alloc()
1490 if (htc_hdr->eid != endpoint->eid) { in ath6kl_htc_rx_alloc()
1491 ath6kl_err("invalid ep in look-ahead: %d should be : %d (index:%d)\n", in ath6kl_htc_rx_alloc()
1492 htc_hdr->eid, endpoint->eid, i); in ath6kl_htc_rx_alloc()
1493 status = -ENOMEM; in ath6kl_htc_rx_alloc()
1497 if (le16_to_cpu(htc_hdr->payld_len) > HTC_MAX_PAYLOAD_LENGTH) { in ath6kl_htc_rx_alloc()
1499 htc_hdr->payld_len, in ath6kl_htc_rx_alloc()
1501 status = -ENOMEM; in ath6kl_htc_rx_alloc()
1505 if (endpoint->svc_id == 0) { in ath6kl_htc_rx_alloc()
1506 ath6kl_err("ep %d is not connected !\n", htc_hdr->eid); in ath6kl_htc_rx_alloc()
1507 status = -ENOMEM; in ath6kl_htc_rx_alloc()
1511 if (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) { in ath6kl_htc_rx_alloc()
1517 n_msg = (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) >> in ath6kl_htc_rx_alloc()
1522 if (n_msg > target->msg_per_bndl_max) { in ath6kl_htc_rx_alloc()
1523 status = -ENOMEM; in ath6kl_htc_rx_alloc()
1527 endpoint->ep_st.rx_bundle_from_hdr += 1; in ath6kl_htc_rx_alloc()
1544 if (status == -ENOSPC) { in ath6kl_htc_rx_alloc()
1545 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_rx_alloc()
1553 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_rx_alloc()
1557 list_del(&packet->list); in ath6kl_htc_rx_alloc()
1559 &target->endpoint[packet->endpoint]); in ath6kl_htc_rx_alloc()
1568 if (packets->endpoint != ENDPOINT_0) { in htc_ctrl_rx()
1573 if (packets->status == -ECANCELED) { in htc_ctrl_rx()
1578 if (packets->act_len > 0) { in htc_ctrl_rx()
1580 packets->act_len + HTC_HDR_LENGTH); in htc_ctrl_rx()
1584 packets->buf - HTC_HDR_LENGTH, in htc_ctrl_rx()
1585 packets->act_len + HTC_HDR_LENGTH); in htc_ctrl_rx()
1588 htc_reclaim_rxbuf(context, packets, &context->endpoint[0]); in htc_ctrl_rx()
1600 spin_lock_bh(&target->tx_lock); in htc_proc_cred_rpt()
1603 if (rpt->eid >= ENDPOINT_MAX) { in htc_proc_cred_rpt()
1605 spin_unlock_bh(&target->tx_lock); in htc_proc_cred_rpt()
1609 endpoint = &target->endpoint[rpt->eid]; in htc_proc_cred_rpt()
1613 rpt->eid, rpt->credits); in htc_proc_cred_rpt()
1615 endpoint->ep_st.tx_cred_rpt += 1; in htc_proc_cred_rpt()
1616 endpoint->ep_st.cred_retnd += rpt->credits; in htc_proc_cred_rpt()
1618 if (from_ep == rpt->eid) { in htc_proc_cred_rpt()
1623 endpoint->ep_st.cred_from_rx += rpt->credits; in htc_proc_cred_rpt()
1624 endpoint->ep_st.cred_rpt_from_rx += 1; in htc_proc_cred_rpt()
1627 endpoint->ep_st.cred_from_ep0 += rpt->credits; in htc_proc_cred_rpt()
1628 endpoint->ep_st.cred_rpt_ep0 += 1; in htc_proc_cred_rpt()
1630 endpoint->ep_st.cred_from_other += rpt->credits; in htc_proc_cred_rpt()
1631 endpoint->ep_st.cred_rpt_from_other += 1; in htc_proc_cred_rpt()
1634 if (rpt->eid == ENDPOINT_0) in htc_proc_cred_rpt()
1636 endpoint->cred_dist.credits += rpt->credits; in htc_proc_cred_rpt()
1638 endpoint->cred_dist.cred_to_dist += rpt->credits; in htc_proc_cred_rpt()
1647 endpoint->cred_dist.txq_depth = in htc_proc_cred_rpt()
1648 get_queue_depth(&endpoint->txq); in htc_proc_cred_rpt()
1650 tot_credits += rpt->credits; in htc_proc_cred_rpt()
1658 ath6kl_credit_distribute(target->credit_info, in htc_proc_cred_rpt()
1659 &target->cred_dist_list, in htc_proc_cred_rpt()
1663 spin_unlock_bh(&target->tx_lock); in htc_proc_cred_rpt()
1679 switch (record->rec_id) { in htc_parse_trailer()
1681 len = record->len / sizeof(struct htc_credit_report); in htc_parse_trailer()
1684 return -EINVAL; in htc_parse_trailer()
1692 len = record->len / sizeof(*lk_ahd); in htc_parse_trailer()
1695 return -EINVAL; in htc_parse_trailer()
1699 if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) && in htc_parse_trailer()
1703 lk_ahd->pre_valid, lk_ahd->post_valid); in htc_parse_trailer()
1706 memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4); in htc_parse_trailer()
1716 len = record->len / sizeof(*bundle_lkahd_rpt); in htc_parse_trailer()
1719 return -EINVAL; in htc_parse_trailer()
1729 "", record_buf, record->len); in htc_parse_trailer()
1733 bundle_lkahd_rpt->lk_ahd, 4); in htc_parse_trailer()
1742 record->rec_id, record->len); in htc_parse_trailer()
1768 status = -ENOMEM; in htc_proc_trailer()
1773 len -= sizeof(struct htc_record_hdr); in htc_proc_trailer()
1776 if (record->len > len) { in htc_proc_trailer()
1778 record->len, record->rec_id, len); in htc_proc_trailer()
1779 status = -ENOMEM; in htc_proc_trailer()
1791 buf += record->len; in htc_proc_trailer()
1792 len -= record->len; in htc_proc_trailer()
1809 struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)packet->buf; in ath6kl_htc_rx_process_hdr()
1818 payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len)); in ath6kl_htc_rx_process_hdr()
1820 memcpy((u8 *)&lk_ahd, packet->buf, sizeof(lk_ahd)); in ath6kl_htc_rx_process_hdr()
1822 if (packet->info.rx.rx_flags & HTC_RX_PKT_REFRESH_HDR) { in ath6kl_htc_rx_process_hdr()
1828 packet->info.rx.exp_hdr = lk_ahd; in ath6kl_htc_rx_process_hdr()
1829 packet->act_len = payload_len + HTC_HDR_LENGTH; in ath6kl_htc_rx_process_hdr()
1832 if (packet->act_len > packet->buf_len) { in ath6kl_htc_rx_process_hdr()
1839 packet->act_len = min(packet->act_len, packet->buf_len); in ath6kl_htc_rx_process_hdr()
1840 status = -ENOMEM; in ath6kl_htc_rx_process_hdr()
1844 if (packet->endpoint != htc_hdr->eid) { in ath6kl_htc_rx_process_hdr()
1846 htc_hdr->eid, packet->endpoint); in ath6kl_htc_rx_process_hdr()
1847 status = -ENOMEM; in ath6kl_htc_rx_process_hdr()
1852 if (lk_ahd != packet->info.rx.exp_hdr) { in ath6kl_htc_rx_process_hdr()
1854 __func__, packet, packet->info.rx.rx_flags); in ath6kl_htc_rx_process_hdr()
1856 "", &packet->info.rx.exp_hdr, 4); in ath6kl_htc_rx_process_hdr()
1859 status = -ENOMEM; in ath6kl_htc_rx_process_hdr()
1863 if (htc_hdr->flags & HTC_FLG_RX_TRAILER) { in ath6kl_htc_rx_process_hdr()
1864 if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) || in ath6kl_htc_rx_process_hdr()
1865 htc_hdr->ctrl[0] > payload_len) { in ath6kl_htc_rx_process_hdr()
1867 __func__, payload_len, htc_hdr->ctrl[0]); in ath6kl_htc_rx_process_hdr()
1868 status = -ENOMEM; in ath6kl_htc_rx_process_hdr()
1872 if (packet->info.rx.rx_flags & HTC_RX_PKT_IGNORE_LOOKAHEAD) { in ath6kl_htc_rx_process_hdr()
1877 status = htc_proc_trailer(target, packet->buf + HTC_HDR_LENGTH in ath6kl_htc_rx_process_hdr()
1878 + payload_len - htc_hdr->ctrl[0], in ath6kl_htc_rx_process_hdr()
1879 htc_hdr->ctrl[0], next_lkahds, in ath6kl_htc_rx_process_hdr()
1880 n_lkahds, packet->endpoint); in ath6kl_htc_rx_process_hdr()
1885 packet->act_len -= htc_hdr->ctrl[0]; in ath6kl_htc_rx_process_hdr()
1888 packet->buf += HTC_HDR_LENGTH; in ath6kl_htc_rx_process_hdr()
1889 packet->act_len -= HTC_HDR_LENGTH; in ath6kl_htc_rx_process_hdr()
1894 "", packet->buf, packet->act_len); in ath6kl_htc_rx_process_hdr()
1904 endpoint->eid, packet); in ath6kl_htc_rx_complete()
1906 endpoint->ep_cb.rx(endpoint->target, packet); in ath6kl_htc_rx_complete()
1916 int rem_space = target->max_rx_bndl_sz; in ath6kl_htc_rx_bundle()
1920 n_scat_pkt = min(n_scat_pkt, target->msg_per_bndl_max); in ath6kl_htc_rx_bundle()
1922 if ((get_queue_depth(rxq) - n_scat_pkt) > 0) { in ath6kl_htc_rx_bundle()
1934 ath6kl_warn("%s(): partial bundle detected num:%d , %d\n", in ath6kl_htc_rx_bundle()
1944 scat_req = hif_scatter_req_get(target->dev->ar); in ath6kl_htc_rx_bundle()
1953 list_del(&packet->list); in ath6kl_htc_rx_bundle()
1956 packet->act_len); in ath6kl_htc_rx_bundle()
1958 if ((rem_space - pad_len) < 0) { in ath6kl_htc_rx_bundle()
1959 list_add(&packet->list, rxq); in ath6kl_htc_rx_bundle()
1963 rem_space -= pad_len; in ath6kl_htc_rx_bundle()
1965 if (part_bundle || (i < (n_scat_pkt - 1))) in ath6kl_htc_rx_bundle()
1967 * Packet 0..n-1 cannot be checked for look-aheads in ath6kl_htc_rx_bundle()
1971 packet->info.rx.rx_flags |= in ath6kl_htc_rx_bundle()
1975 scat_req->scat_list[i].buf = packet->buf; in ath6kl_htc_rx_bundle()
1976 scat_req->scat_list[i].len = pad_len; in ath6kl_htc_rx_bundle()
1978 packet->info.rx.rx_flags |= HTC_RX_PKT_PART_OF_BUNDLE; in ath6kl_htc_rx_bundle()
1980 list_add_tail(&packet->list, sync_compq); in ath6kl_htc_rx_bundle()
1982 WARN_ON(!scat_req->scat_list[i].len); in ath6kl_htc_rx_bundle()
1983 len += scat_req->scat_list[i].len; in ath6kl_htc_rx_bundle()
1986 scat_req->len = len; in ath6kl_htc_rx_bundle()
1987 scat_req->scat_entries = i; in ath6kl_htc_rx_bundle()
1989 status = ath6kl_hif_submit_scat_req(target->dev, scat_req, true); in ath6kl_htc_rx_bundle()
1995 hif_scatter_req_add(target->dev->ar, scat_req); in ath6kl_htc_rx_bundle()
2012 ep = &target->endpoint[packet->endpoint]; in ath6kl_htc_rx_process_packets()
2014 trace_ath6kl_htc_rx(packet->status, packet->endpoint, in ath6kl_htc_rx_process_packets()
2015 packet->buf, packet->act_len); in ath6kl_htc_rx_process_packets()
2023 list_del(&packet->list); in ath6kl_htc_rx_process_packets()
2038 packet->info.rx.indicat_flags |= in ath6kl_htc_rx_process_packets()
2043 if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE) in ath6kl_htc_rx_process_packets()
2044 ep->ep_st.rx_bundl += 1; in ath6kl_htc_rx_process_packets()
2068 if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) { in ath6kl_htc_rx_fetch()
2092 packet->completion = NULL; in ath6kl_htc_rx_fetch()
2100 packet->info.rx.rx_flags |= in ath6kl_htc_rx_fetch()
2105 packet->act_len); in ath6kl_htc_rx_fetch()
2107 list_move_tail(&packet->list, &tmp_rxq); in ath6kl_htc_rx_fetch()
2126 list_del(&packet->list); in ath6kl_htc_rx_fetch()
2128 &target->endpoint[packet->endpoint]); in ath6kl_htc_rx_fetch()
2132 list_del(&packet->list); in ath6kl_htc_rx_fetch()
2134 &target->endpoint[packet->endpoint]); in ath6kl_htc_rx_fetch()
2166 id = ((struct htc_frame_hdr *)&look_aheads[0])->eid; in ath6kl_htc_rxmsg_pending_handler()
2167 endpoint = &target->endpoint[id]; in ath6kl_htc_rxmsg_pending_handler()
2170 ath6kl_err("MsgPend, invalid endpoint in look-ahead: %d\n", in ath6kl_htc_rxmsg_pending_handler()
2172 status = -ENOMEM; in ath6kl_htc_rxmsg_pending_handler()
2192 * re-check again in ath6kl_htc_rxmsg_pending_handler()
2194 target->chk_irq_status_cnt = 1; in ath6kl_htc_rxmsg_pending_handler()
2216 * flag that we should re-check IRQ status registers again in ath6kl_htc_rxmsg_pending_handler()
2220 target->chk_irq_status_cnt = 1; in ath6kl_htc_rxmsg_pending_handler()
2224 if (status != -ECANCELED) in ath6kl_htc_rxmsg_pending_handler()
2230 list_del(&packets->list); in ath6kl_htc_rxmsg_pending_handler()
2232 &target->endpoint[packets->endpoint]); in ath6kl_htc_rxmsg_pending_handler()
2235 if (target->htc_flags & HTC_OP_STATE_STOPPING) { in ath6kl_htc_rxmsg_pending_handler()
2237 ath6kl_hif_rx_control(target->dev, false); in ath6kl_htc_rxmsg_pending_handler()
2245 if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { in ath6kl_htc_rxmsg_pending_handler()
2247 ath6kl_hif_rx_control(target->dev, false); in ath6kl_htc_rxmsg_pending_handler()
2264 if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead.word, in htc_wait_for_ctrl_msg()
2279 packet->info.rx.rx_flags = 0; in htc_wait_for_ctrl_msg()
2280 packet->info.rx.exp_hdr = look_ahead.word; in htc_wait_for_ctrl_msg()
2281 packet->act_len = le16_to_cpu(look_ahead.payld_len) + HTC_HDR_LENGTH; in htc_wait_for_ctrl_msg()
2283 if (packet->act_len > packet->buf_len) in htc_wait_for_ctrl_msg()
2287 packet->completion = NULL; in htc_wait_for_ctrl_msg()
2290 if (ath6kl_htc_rx_packet(target, packet, packet->act_len)) in htc_wait_for_ctrl_msg()
2293 trace_ath6kl_htc_rx(packet->status, packet->endpoint, in htc_wait_for_ctrl_msg()
2294 packet->buf, packet->act_len); in htc_wait_for_ctrl_msg()
2297 packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL); in htc_wait_for_ctrl_msg()
2299 if (packet->status) { in htc_wait_for_ctrl_msg()
2301 packet->status); in htc_wait_for_ctrl_msg()
2325 return -ENOMEM; in ath6kl_htc_mbox_add_rxbuf_multiple()
2329 if (first_pkt->endpoint >= ENDPOINT_MAX) in ath6kl_htc_mbox_add_rxbuf_multiple()
2336 first_pkt->endpoint, depth, first_pkt->buf_len); in ath6kl_htc_mbox_add_rxbuf_multiple()
2338 endpoint = &target->endpoint[first_pkt->endpoint]; in ath6kl_htc_mbox_add_rxbuf_multiple()
2340 if (target->htc_flags & HTC_OP_STATE_STOPPING) { in ath6kl_htc_mbox_add_rxbuf_multiple()
2345 packet->status = -ECANCELED; in ath6kl_htc_mbox_add_rxbuf_multiple()
2346 list_del(&packet->list); in ath6kl_htc_mbox_add_rxbuf_multiple()
2353 spin_lock_bh(&target->rx_lock); in ath6kl_htc_mbox_add_rxbuf_multiple()
2355 list_splice_tail_init(pkt_queue, &endpoint->rx_bufq); in ath6kl_htc_mbox_add_rxbuf_multiple()
2358 if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { in ath6kl_htc_mbox_add_rxbuf_multiple()
2359 if (target->ep_waiting == first_pkt->endpoint) { in ath6kl_htc_mbox_add_rxbuf_multiple()
2362 target->ep_waiting); in ath6kl_htc_mbox_add_rxbuf_multiple()
2363 target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; in ath6kl_htc_mbox_add_rxbuf_multiple()
2364 target->ep_waiting = ENDPOINT_MAX; in ath6kl_htc_mbox_add_rxbuf_multiple()
2369 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_mbox_add_rxbuf_multiple()
2371 if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING)) in ath6kl_htc_mbox_add_rxbuf_multiple()
2373 ath6kl_hif_rx_control(target->dev, true); in ath6kl_htc_mbox_add_rxbuf_multiple()
2385 endpoint = &target->endpoint[i]; in ath6kl_htc_mbox_flush_rx_buf()
2386 if (!endpoint->svc_id) in ath6kl_htc_mbox_flush_rx_buf()
2390 spin_lock_bh(&target->rx_lock); in ath6kl_htc_mbox_flush_rx_buf()
2392 &endpoint->rx_bufq, list) { in ath6kl_htc_mbox_flush_rx_buf()
2393 list_del(&packet->list); in ath6kl_htc_mbox_flush_rx_buf()
2394 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_mbox_flush_rx_buf()
2397 packet, packet->buf_len, in ath6kl_htc_mbox_flush_rx_buf()
2398 packet->endpoint); in ath6kl_htc_mbox_flush_rx_buf()
2401 * been queued from target->free_ctrl_rxbuf where in ath6kl_htc_mbox_flush_rx_buf()
2402 * packet and packet->buf_start are allocated in ath6kl_htc_mbox_flush_rx_buf()
2405 * skb->head. Take care of this difference while freeing in ath6kl_htc_mbox_flush_rx_buf()
2408 if (packet->endpoint == ENDPOINT_0) { in ath6kl_htc_mbox_flush_rx_buf()
2409 kfree(packet->buf_start); in ath6kl_htc_mbox_flush_rx_buf()
2412 dev_kfree_skb(packet->pkt_cntxt); in ath6kl_htc_mbox_flush_rx_buf()
2414 spin_lock_bh(&target->rx_lock); in ath6kl_htc_mbox_flush_rx_buf()
2416 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_mbox_flush_rx_buf()
2436 target, conn_req->svc_id); in ath6kl_htc_mbox_conn_service()
2438 if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) { in ath6kl_htc_mbox_conn_service()
2447 return -ENOMEM; in ath6kl_htc_mbox_conn_service()
2449 conn_msg = (struct htc_conn_service_msg *)tx_pkt->buf; in ath6kl_htc_mbox_conn_service()
2451 conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID); in ath6kl_htc_mbox_conn_service()
2452 conn_msg->svc_id = cpu_to_le16(conn_req->svc_id); in ath6kl_htc_mbox_conn_service()
2453 conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags); in ath6kl_htc_mbox_conn_service()
2456 sizeof(*conn_msg) + conn_msg->svc_meta_len, in ath6kl_htc_mbox_conn_service()
2460 tx_pkt->completion = NULL; in ath6kl_htc_mbox_conn_service()
2471 status = -ENOMEM; in ath6kl_htc_mbox_conn_service()
2475 resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf; in ath6kl_htc_mbox_conn_service()
2476 msg_id = le16_to_cpu(resp_msg->msg_id); in ath6kl_htc_mbox_conn_service()
2479 (rx_pkt->act_len < sizeof(*resp_msg))) { in ath6kl_htc_mbox_conn_service()
2480 status = -ENOMEM; in ath6kl_htc_mbox_conn_service()
2484 conn_resp->resp_code = resp_msg->status; in ath6kl_htc_mbox_conn_service()
2486 if (resp_msg->status != HTC_SERVICE_SUCCESS) { in ath6kl_htc_mbox_conn_service()
2488 resp_msg->svc_id, resp_msg->status); in ath6kl_htc_mbox_conn_service()
2489 status = -ENOMEM; in ath6kl_htc_mbox_conn_service()
2493 assigned_ep = (enum htc_endpoint_id)resp_msg->eid; in ath6kl_htc_mbox_conn_service()
2494 max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz); in ath6kl_htc_mbox_conn_service()
2499 status = -ENOMEM; in ath6kl_htc_mbox_conn_service()
2503 endpoint = &target->endpoint[assigned_ep]; in ath6kl_htc_mbox_conn_service()
2504 endpoint->eid = assigned_ep; in ath6kl_htc_mbox_conn_service()
2505 if (endpoint->svc_id) { in ath6kl_htc_mbox_conn_service()
2506 status = -ENOMEM; in ath6kl_htc_mbox_conn_service()
2511 conn_resp->endpoint = assigned_ep; in ath6kl_htc_mbox_conn_service()
2512 conn_resp->len_max = max_msg_sz; in ath6kl_htc_mbox_conn_service()
2517 endpoint->svc_id = conn_req->svc_id; in ath6kl_htc_mbox_conn_service()
2519 endpoint->max_txq_depth = conn_req->max_txq_depth; in ath6kl_htc_mbox_conn_service()
2520 endpoint->len_max = max_msg_sz; in ath6kl_htc_mbox_conn_service()
2521 endpoint->ep_cb = conn_req->ep_cb; in ath6kl_htc_mbox_conn_service()
2522 endpoint->cred_dist.svc_id = conn_req->svc_id; in ath6kl_htc_mbox_conn_service()
2523 endpoint->cred_dist.htc_ep = endpoint; in ath6kl_htc_mbox_conn_service()
2524 endpoint->cred_dist.endpoint = assigned_ep; in ath6kl_htc_mbox_conn_service()
2525 endpoint->cred_dist.cred_sz = target->tgt_cred_sz; in ath6kl_htc_mbox_conn_service()
2527 switch (endpoint->svc_id) { in ath6kl_htc_mbox_conn_service()
2529 endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3; in ath6kl_htc_mbox_conn_service()
2532 endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM; in ath6kl_htc_mbox_conn_service()
2536 if (conn_req->max_rxmsg_sz) { in ath6kl_htc_mbox_conn_service()
2539 * the credit-low indications since the host will actually in ath6kl_htc_mbox_conn_service()
2542 if (conn_req->max_rxmsg_sz > max_msg_sz) { in ath6kl_htc_mbox_conn_service()
2543 status = -ENOMEM; in ath6kl_htc_mbox_conn_service()
2546 endpoint->cred_dist.cred_per_msg = in ath6kl_htc_mbox_conn_service()
2547 conn_req->max_rxmsg_sz / target->tgt_cred_sz; in ath6kl_htc_mbox_conn_service()
2549 endpoint->cred_dist.cred_per_msg = in ath6kl_htc_mbox_conn_service()
2550 max_msg_sz / target->tgt_cred_sz; in ath6kl_htc_mbox_conn_service()
2552 if (!endpoint->cred_dist.cred_per_msg) in ath6kl_htc_mbox_conn_service()
2553 endpoint->cred_dist.cred_per_msg = 1; in ath6kl_htc_mbox_conn_service()
2556 endpoint->conn_flags = conn_req->flags; in ath6kl_htc_mbox_conn_service()
2576 endpoint = &target->endpoint[i]; in reset_ep_state()
2577 memset(&endpoint->cred_dist, 0, sizeof(endpoint->cred_dist)); in reset_ep_state()
2578 endpoint->svc_id = 0; in reset_ep_state()
2579 endpoint->len_max = 0; in reset_ep_state()
2580 endpoint->max_txq_depth = 0; in reset_ep_state()
2581 memset(&endpoint->ep_st, 0, in reset_ep_state()
2582 sizeof(endpoint->ep_st)); in reset_ep_state()
2583 INIT_LIST_HEAD(&endpoint->rx_bufq); in reset_ep_state()
2584 INIT_LIST_HEAD(&endpoint->txq); in reset_ep_state()
2585 endpoint->target = target; in reset_ep_state()
2590 INIT_LIST_HEAD(&target->cred_dist_list); in reset_ep_state()
2596 int num; in ath6kl_htc_mbox_get_rxbuf_num() local
2598 spin_lock_bh(&target->rx_lock); in ath6kl_htc_mbox_get_rxbuf_num()
2599 num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq)); in ath6kl_htc_mbox_get_rxbuf_num()
2600 spin_unlock_bh(&target->rx_lock); in ath6kl_htc_mbox_get_rxbuf_num()
2601 return num; in ath6kl_htc_mbox_get_rxbuf_num()
2607 target->msg_per_bndl_max = min(HTC_HOST_MAX_MSG_PER_BUNDLE, in htc_setup_msg_bndl()
2608 target->msg_per_bndl_max); in htc_setup_msg_bndl()
2610 if (ath6kl_hif_enable_scatter(target->dev->ar)) { in htc_setup_msg_bndl()
2611 target->msg_per_bndl_max = 0; in htc_setup_msg_bndl()
2616 target->msg_per_bndl_max = min(target->max_scat_entries, in htc_setup_msg_bndl()
2617 target->msg_per_bndl_max); in htc_setup_msg_bndl()
2621 target->msg_per_bndl_max); in htc_setup_msg_bndl()
2624 target->max_rx_bndl_sz = target->max_xfer_szper_scatreq; in htc_setup_msg_bndl()
2626 target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH, in htc_setup_msg_bndl()
2627 target->max_xfer_szper_scatreq); in htc_setup_msg_bndl()
2630 target->max_rx_bndl_sz, target->max_tx_bndl_sz); in htc_setup_msg_bndl()
2632 if (target->max_tx_bndl_sz) in htc_setup_msg_bndl()
2634 target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1; in htc_setup_msg_bndl()
2636 if (target->max_rx_bndl_sz) in htc_setup_msg_bndl()
2637 target->rx_bndl_enable = true; in htc_setup_msg_bndl()
2639 if ((target->tgt_cred_sz % target->block_sz) != 0) { in htc_setup_msg_bndl()
2641 target->tgt_cred_sz); in htc_setup_msg_bndl()
2649 target->tx_bndl_mask = 0; in htc_setup_msg_bndl()
2665 return -ENOMEM; in ath6kl_htc_mbox_wait_target()
2668 rdy_msg = (struct htc_ready_ext_msg *)packet->buf; in ath6kl_htc_mbox_wait_target()
2670 if ((le16_to_cpu(rdy_msg->ver2_0_info.msg_id) != HTC_MSG_READY_ID) || in ath6kl_htc_mbox_wait_target()
2671 (packet->act_len < sizeof(struct htc_ready_msg))) { in ath6kl_htc_mbox_wait_target()
2672 status = -ENOMEM; in ath6kl_htc_mbox_wait_target()
2676 if (!rdy_msg->ver2_0_info.cred_cnt || !rdy_msg->ver2_0_info.cred_sz) { in ath6kl_htc_mbox_wait_target()
2677 status = -ENOMEM; in ath6kl_htc_mbox_wait_target()
2681 target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt); in ath6kl_htc_mbox_wait_target()
2682 target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz); in ath6kl_htc_mbox_wait_target()
2686 target->tgt_creds, target->tgt_cred_sz); in ath6kl_htc_mbox_wait_target()
2689 if (packet->act_len >= sizeof(struct htc_ready_ext_msg)) { in ath6kl_htc_mbox_wait_target()
2691 target->htc_tgt_ver = rdy_msg->htc_ver; in ath6kl_htc_mbox_wait_target()
2692 target->msg_per_bndl_max = rdy_msg->msg_per_htc_bndl; in ath6kl_htc_mbox_wait_target()
2695 target->htc_tgt_ver = HTC_VERSION_2P0; in ath6kl_htc_mbox_wait_target()
2696 target->msg_per_bndl_max = 0; in ath6kl_htc_mbox_wait_target()
2700 (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", in ath6kl_htc_mbox_wait_target()
2701 target->htc_tgt_ver); in ath6kl_htc_mbox_wait_target()
2703 if (target->msg_per_bndl_max > 0) in ath6kl_htc_mbox_wait_target()
2723 ath6kl_hif_cleanup_scatter(target->dev->ar); in ath6kl_htc_mbox_wait_target()
2743 memset(&target->dev->irq_proc_reg, 0, in ath6kl_htc_mbox_start()
2744 sizeof(target->dev->irq_proc_reg)); in ath6kl_htc_mbox_start()
2747 ath6kl_hif_disable_intrs(target->dev); in ath6kl_htc_mbox_start()
2749 target->htc_flags = 0; in ath6kl_htc_mbox_start()
2750 target->rx_st_flags = 0; in ath6kl_htc_mbox_start()
2760 ath6kl_credit_init(target->credit_info, &target->cred_dist_list, in ath6kl_htc_mbox_start()
2761 target->tgt_creds); in ath6kl_htc_mbox_start()
2772 status = ath6kl_hif_unmask_intrs(target->dev); in ath6kl_htc_mbox_start()
2788 block_size = target->dev->ar->mbox_info.block_size; in ath6kl_htc_reset()
2797 return -ENOMEM; in ath6kl_htc_reset()
2799 packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL); in ath6kl_htc_reset()
2800 if (!packet->buf_start) { in ath6kl_htc_reset()
2802 return -ENOMEM; in ath6kl_htc_reset()
2805 packet->buf_len = ctrl_bufsz; in ath6kl_htc_reset()
2807 packet->act_len = 0; in ath6kl_htc_reset()
2808 packet->buf = packet->buf_start; in ath6kl_htc_reset()
2809 packet->endpoint = ENDPOINT_0; in ath6kl_htc_reset()
2810 list_add_tail(&packet->list, &target->free_ctrl_rxbuf); in ath6kl_htc_reset()
2812 list_add_tail(&packet->list, &target->free_ctrl_txbuf); in ath6kl_htc_reset()
2822 spin_lock_bh(&target->htc_lock); in ath6kl_htc_mbox_stop()
2823 target->htc_flags |= HTC_OP_STATE_STOPPING; in ath6kl_htc_mbox_stop()
2824 spin_unlock_bh(&target->htc_lock); in ath6kl_htc_mbox_stop()
2831 ath6kl_hif_mask_intrs(target->dev); in ath6kl_htc_mbox_stop()
2851 target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL); in ath6kl_htc_mbox_create()
2852 if (!target->dev) { in ath6kl_htc_mbox_create()
2858 spin_lock_init(&target->htc_lock); in ath6kl_htc_mbox_create()
2859 spin_lock_init(&target->rx_lock); in ath6kl_htc_mbox_create()
2860 spin_lock_init(&target->tx_lock); in ath6kl_htc_mbox_create()
2862 INIT_LIST_HEAD(&target->free_ctrl_txbuf); in ath6kl_htc_mbox_create()
2863 INIT_LIST_HEAD(&target->free_ctrl_rxbuf); in ath6kl_htc_mbox_create()
2864 INIT_LIST_HEAD(&target->cred_dist_list); in ath6kl_htc_mbox_create()
2866 target->dev->ar = ar; in ath6kl_htc_mbox_create()
2867 target->dev->htc_cnxt = target; in ath6kl_htc_mbox_create()
2868 target->ep_waiting = ENDPOINT_MAX; in ath6kl_htc_mbox_create()
2870 status = ath6kl_hif_setup(target->dev); in ath6kl_htc_mbox_create()
2891 ath6kl_hif_cleanup_scatter(target->dev->ar); in ath6kl_htc_mbox_cleanup()
2894 &target->free_ctrl_txbuf, list) { in ath6kl_htc_mbox_cleanup()
2895 list_del(&packet->list); in ath6kl_htc_mbox_cleanup()
2896 kfree(packet->buf_start); in ath6kl_htc_mbox_cleanup()
2901 &target->free_ctrl_rxbuf, list) { in ath6kl_htc_mbox_cleanup()
2902 list_del(&packet->list); in ath6kl_htc_mbox_cleanup()
2903 kfree(packet->buf_start); in ath6kl_htc_mbox_cleanup()
2907 kfree(target->dev); in ath6kl_htc_mbox_cleanup()
2929 ar->htc_ops = &ath6kl_htc_mbox_ops; in ath6kl_htc_mbox_attach()