22 #include <asm/unaligned.h>
24 #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
32 u16 svc_pri_order[],
int len);
35 #define TX_RESUME_BUNDLE_THRESHOLD 1500
68 if (tot_credits > 4) {
71 ath6kl_credit_deposit(cred_info,
79 ath6kl_credit_deposit(cred_info, cur_ep_dist,
127 count = (count * 3) >> 2;
134 "credit ep %d svc_id %d credits %d per_msg %d norm %d min %d\n",
148 u16 servicepriority[5];
159 ath6kl_htc_set_credit_dist(htc_target, cred_info, servicepriority, 5);
198 ath6kl_credit_reduce(cred_info,
203 ath6kl_credit_reduce(cred_info, cur_list,
208 ath6kl_credit_reduce(cred_info,
259 if (curdist_list == ep_dist)
272 ath6kl_credit_reduce(cred_info, curdist_list,
289 ath6kl_credit_deposit(cred_info, ep_dist, credits);
311 ath6kl_credit_reduce(info, curdist_list, 0);
313 ath6kl_credit_reduce(info,
334 ath6kl_credit_update(cred_info, ep_dist_list);
337 ath6kl_credit_redistribute(cred_info, ep_dist_list);
347 static void ath6kl_htc_tx_buf_align(
u8 **
buf,
unsigned long len)
353 memmove(align_addr, *buf, len);
359 int ctrl0,
int ctrl1)
370 hdr->
ctrl[0] = ctrl0;
371 hdr->
ctrl[1] = ctrl1;
374 static void htc_reclaim_txctrl_buf(
struct htc_target *
target,
392 if (list_empty(buf_list)) {
407 static void htc_tx_comp_update(
struct htc_target *target,
417 ath6kl_err(
"req failed (status:%d, ep:%d, len:%d creds:%d)\n",
419 packet->
info.
tx.cred_used);
422 spin_lock_bh(&target->
tx_lock);
424 packet->
info.
tx.cred_used;
425 endpoint->
cred_dist.txq_depth = get_queue_depth(&endpoint->
txq);
434 spin_unlock_bh(&target->
tx_lock);
437 static void htc_tx_complete(
struct htc_endpoint *endpoint,
444 "htc tx complete ep %d pkts %d\n",
445 endpoint->
eid, get_queue_depth(txq));
450 static void htc_tx_comp_handler(
struct htc_target *target,
459 htc_tx_comp_update(target, endpoint, packet);
460 INIT_LIST_HEAD(&container);
463 htc_tx_complete(endpoint, &container);
466 static void htc_async_tx_scat_complete(
struct htc_target *target,
474 INIT_LIST_HEAD(&tx_compq);
477 "htc tx scat complete len %d entries %d\n",
495 htc_tx_comp_update(target, endpoint, packet);
500 hif_scatter_req_add(target->
dev->ar, scat_req);
503 htc_tx_complete(endpoint, &tx_compq);
506 static int ath6kl_htc_tx_issue(
struct htc_target *target,
511 u32 padded_len, send_len;
521 "htc tx issue len %d seqno %d padded_len %d mbox 0x%X %s\n",
522 send_len, packet->
info.
tx.seqno, padded_len,
523 target->
dev->ar->mbox_info.htc_addr,
524 sync ?
"sync" :
"async");
527 status = hif_read_write_sync(target->
dev->ar,
528 target->
dev->ar->mbox_info.htc_addr,
529 packet->
buf, padded_len,
535 status = hif_write_async(target->
dev->ar,
536 target->
dev->ar->mbox_info.htc_addr,
537 packet->
buf, padded_len,
543 static int htc_check_credits(
struct htc_target *target,
568 "credit not found for ep %d\n",
575 ep->
ep_st.cred_cosumd += *req_cred;
588 ep->
ep_st.cred_low_indicate += 1;
590 "credit we need credits asap\n");
597 static void ath6kl_htc_tx_pkts_get(
struct htc_target *target,
610 if (list_empty(&endpoint->
txq))
616 "htc tx got packet 0x%p queue depth %d\n",
617 packet, get_queue_depth(&endpoint->
txq));
622 if (htc_check_credits(target, endpoint, &flags,
629 list_move_tail(&packet->
list, queue);
632 packet->
info.
tx.cred_used = req_cred;
637 endpoint->
ep_st.tx_issued += 1;
647 static int htc_get_credit_padding(
unsigned int cred_sz,
int *len,
650 int rem_cred, cred_pad;
652 rem_cred = *len % cred_sz;
667 cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred;
669 if ((cred_pad > 0) && (cred_pad <= 255))
678 static int ath6kl_htc_tx_setup_scat_list(
struct htc_target *target,
685 int i, len, rem_scat, cred_pad;
691 for (i = 0; i < n_scat; i++) {
694 if (list_empty(queue))
701 cred_pad = htc_get_credit_padding(target->
tgt_cred_sz,
703 if (cred_pad < 0 || rem_scat < len) {
715 ath6kl_htc_tx_prep_pkt(packet, flags,
716 cred_pad, packet->
info.
tx.seqno);
718 ath6kl_htc_tx_buf_align(&packet->
buf,
723 scat_req->
len += len;
726 "htc tx adding (%d) pkt 0x%p seqno %d len %d remaining %d\n",
727 i, packet, packet->
info.
tx.seqno, len, rem_scat);
736 list_add(&packet->
list, queue);
754 static void ath6kl_htc_tx_bundle(
struct htc_endpoint *endpoint,
756 int *sent_bundle,
int *n_bundle_pkts)
758 struct htc_target *target = endpoint->
target;
760 int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
767 ac = target->
dev->ar->ep2ac_map[endpoint->
eid];
771 n_scat = get_queue_depth(queue);
778 scat_req = hif_scatter_req_get(target->
dev->ar);
783 "htc tx no more scatter resources\n");
799 txb_mask = ((1 <<
ac) - 1);
819 status = ath6kl_htc_tx_setup_scat_list(target, endpoint,
823 hif_scatter_req_add(target->
dev->ar, scat_req);
828 scat_req->
complete = htc_async_tx_scat_complete;
833 "htc tx scatter bytes %d entries %d\n",
841 *sent_bundle = n_sent_bundle;
842 *n_bundle_pkts = tot_pkts_bundle;
849 static void ath6kl_htc_tx_from_queue(
struct htc_target *target,
859 spin_lock_bh(&target->
tx_lock);
864 spin_unlock_bh(&target->
tx_lock);
873 INIT_LIST_HEAD(&txq);
877 ac = target->
dev->ar->ep2ac_map[endpoint->
eid];
881 if (list_empty(&endpoint->
txq))
884 ath6kl_htc_tx_pkts_get(target, endpoint, &txq);
886 if (list_empty(&txq))
889 spin_unlock_bh(&target->
tx_lock);
897 (get_queue_depth(&txq) >=
903 ath6kl_htc_tx_bundle(endpoint, &txq,
905 bundle_sent +=
temp1;
906 n_pkts_bundle +=
temp2;
910 if (list_empty(&txq))
917 ath6kl_htc_tx_prep_pkt(packet, packet->
info.
tx.flags,
918 0, packet->
info.
tx.seqno);
919 status = ath6kl_htc_tx_issue(target, packet);
927 spin_lock_bh(&target->
tx_lock);
929 endpoint->
ep_st.tx_bundles += bundle_sent;
930 endpoint->
ep_st.tx_pkt_bundled += n_pkts_bundle;
954 spin_unlock_bh(&target->
tx_lock);
957 static bool ath6kl_htc_tx_try(
struct htc_target *target,
965 ep_cb = endpoint->
ep_cb;
967 spin_lock_bh(&target->
tx_lock);
968 txq_depth = get_queue_depth(&endpoint->
txq);
969 spin_unlock_bh(&target->
tx_lock);
976 "htc tx overflow ep %d depth %d max %d\n",
977 endpoint->
eid, txq_depth,
980 if (overflow && ep_cb.tx_full) {
981 if (ep_cb.tx_full(endpoint->
target, tx_pkt) ==
983 endpoint->
ep_st.tx_dropped += 1;
988 spin_lock_bh(&target->
tx_lock);
990 spin_unlock_bh(&target->
tx_lock);
992 ath6kl_htc_tx_from_queue(target, endpoint);
997 static void htc_chk_ep_txq(
struct htc_target *target)
1009 endpoint = cred_dist->
htc_ep;
1011 spin_lock_bh(&target->
tx_lock);
1012 if (!list_empty(&endpoint->
txq)) {
1014 "htc creds ep %d credits %d pkts %d\n",
1017 get_queue_depth(&endpoint->
txq));
1018 spin_unlock_bh(&target->
tx_lock);
1026 ath6kl_htc_tx_from_queue(target, endpoint);
1027 spin_lock_bh(&target->
tx_lock);
1029 spin_unlock_bh(&target->
tx_lock);
1033 static int htc_setup_tx_complete(
struct htc_target *target)
1038 send_pkt = htc_get_control_buf(target,
true);
1049 memset(setup_comp_ext, 0,
sizeof(*setup_comp_ext));
1061 sizeof(setup_comp_ext->
flags));
1062 set_htc_pkt_info(send_pkt,
NULL, (
u8 *) setup_comp_ext,
1071 set_htc_pkt_info(send_pkt,
NULL, (
u8 *) setup_comp,
1078 ath6kl_htc_tx_prep_pkt(send_pkt, 0, 0, 0);
1079 status = ath6kl_htc_tx_issue(target, send_pkt);
1081 if (send_pkt !=
NULL)
1082 htc_reclaim_txctrl_buf(target, send_pkt);
1087 static void ath6kl_htc_set_credit_dist(
struct htc_target *target,
1102 if (endpoint->
svc_id == srvc_pri_order[i]) {
1108 if (ep >= ENDPOINT_MAX) {
1115 static int ath6kl_htc_mbox_tx(
struct htc_target *target,
1122 "htc tx ep id %d buf 0x%p len %d\n",
1125 if (packet->
endpoint >= ENDPOINT_MAX) {
1132 if (!ath6kl_htc_tx_try(target, endpoint, packet)) {
1135 INIT_LIST_HEAD(&queue);
1136 list_add(&packet->
list, &queue);
1137 htc_tx_complete(endpoint, &queue);
1144 static void ath6kl_htc_mbox_flush_txep(
struct htc_target *target,
1157 INIT_LIST_HEAD(&discard_q);
1159 spin_lock_bh(&target->
tx_lock);
1163 (tag == packet->
info.
tx.tag))
1164 list_move_tail(&packet->
list, &discard_q);
1167 spin_unlock_bh(&target->
tx_lock);
1173 "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n",
1177 INIT_LIST_HEAD(&container);
1179 htc_tx_complete(endpoint, &container);
1184 static void ath6kl_htc_flush_txep_all(
struct htc_target *target)
1189 dump_cred_dist_stats(target);
1193 if (endpoint->
svc_id == 0)
1200 static void ath6kl_htc_mbox_activity_changed(
struct htc_target *target,
1207 if (endpoint->
svc_id == 0) {
1212 spin_lock_bh(&target->
tx_lock);
1228 get_queue_depth(&endpoint->
txq);
1231 "htc tx activity ctxt 0x%p dist 0x%p\n",
1239 spin_unlock_bh(&target->
tx_lock);
1241 if (dist && !active)
1242 htc_chk_ep_txq(target);
1247 static inline void ath6kl_htc_rx_update_stats(
struct htc_endpoint *endpoint,
1250 endpoint->
ep_st.rx_pkts++;
1251 if (n_look_ahds == 1)
1252 endpoint->
ep_st.rx_lkahds++;
1253 else if (n_look_ahds > 1)
1254 endpoint->
ep_st.rx_bundle_lkahd++;
1257 static inline bool htc_valid_rx_frame_len(
struct htc_target *target,
1260 return (eid == target->
dev->ar->ctrl_ep) ?
1264 static int htc_add_rxbuf(
struct htc_target *target,
struct htc_packet *packet)
1268 INIT_LIST_HEAD(&queue);
1270 return ath6kl_htc_mbox_add_rxbuf_multiple(target, &queue);
1273 static void htc_reclaim_rxbuf(
struct htc_target *target,
1278 htc_rxpkt_reset(packet);
1282 htc_rxpkt_reset(packet);
1283 htc_add_rxbuf((
void *)(target), packet);
1287 static void reclaim_rx_ctrl_buf(
struct htc_target *target,
1295 static int ath6kl_htc_rx_packet(
struct htc_target *target,
1305 if (padded_len > packet->
buf_len) {
1306 ath6kl_err(
"not enough receive space for packet - padlen %d recvlen %d bufferlen %d\n",
1307 padded_len, rx_len, packet->
buf_len);
1312 "htc rx 0x%p hdr 0x%x len %d mbox 0x%x\n",
1313 packet, packet->
info.
rx.exp_hdr,
1314 padded_len, dev->
ar->mbox_info.htc_addr);
1316 status = hif_read_write_sync(dev->
ar,
1317 dev->
ar->mbox_info.htc_addr,
1318 packet->
buf, padded_len,
1331 static void ath6kl_htc_rx_set_indicate(
u32 lk_ahd,
1338 if (!list_empty(&endpoint->
rx_bufq))
1339 packet->
info.
rx.indicat_flags |=
1344 static void ath6kl_htc_rx_chk_water_mark(
struct htc_endpoint *endpoint)
1349 spin_lock_bh(&endpoint->
target->rx_lock);
1350 if (get_queue_depth(&endpoint->
rx_bufq)
1352 spin_unlock_bh(&endpoint->
target->rx_lock);
1356 spin_unlock_bh(&endpoint->
target->rx_lock);
1361 static int ath6kl_htc_rx_setup(
struct htc_target *target,
1369 int status = 0,
j, full_len;
1376 if (!htc_valid_rx_frame_len(target, ep->
eid, full_len)) {
1377 ath6kl_warn(
"Rx buffer requested with invalid length htc_hdr:eid %d, flags 0x%x, len %d\n",
1395 ep->
ep_st.rx_alloc_thresh_hit += 1;
1396 ep->
ep_st.rxalloc_thresh_byte +=
1399 spin_unlock_bh(&target->
rx_lock);
1404 spin_lock_bh(&target->
rx_lock);
1407 if (list_empty(&ep->
rx_bufq)) {
1409 spin_unlock_bh(&target->
rx_lock);
1411 spin_lock_bh(&target->
rx_lock);
1431 packet->
info.
rx.rx_flags = 0;
1432 packet->
info.
rx.indicat_flags = 0;
1453 packet->
info.
rx.exp_hdr = 0xFFFFFFFF;
1456 packet->
info.
rx.exp_hdr = *lk_ahds;
1465 static int ath6kl_htc_rx_alloc(
struct htc_target *target,
1475 spin_lock_bh(&target->
rx_lock);
1477 for (i = 0; i <
msg; i++) {
1481 if (htc_hdr->
eid >= ENDPOINT_MAX) {
1488 if (htc_hdr->
eid != endpoint->
eid) {
1489 ath6kl_err(
"invalid ep in look-ahead: %d should be : %d (index:%d)\n",
1490 htc_hdr->
eid, endpoint->
eid, i);
1496 ath6kl_err(
"payload len %d exceeds max htc : %d !\n",
1503 if (endpoint->
svc_id == 0) {
1525 endpoint->
ep_st.rx_bundle_from_hdr += 1;
1527 "htc rx bundle pkts %d\n",
1534 status = ath6kl_htc_rx_setup(target, endpoint, &lk_ahds[i],
1543 spin_unlock_bh(&target->
rx_lock);
1551 spin_unlock_bh(&target->
rx_lock);
1556 htc_reclaim_rxbuf(target, packet,
1572 reclaim_rx_ctrl_buf(context, packets);
1577 ath6kl_err(
"htc_ctrl_rx, got message with len:%zu\n",
1581 "htc rx unexpected endpoint 0 message",
"",
1586 htc_reclaim_rxbuf(context, packets, &context->
endpoint[0]);
1589 static void htc_proc_cred_rpt(
struct htc_target *target,
1595 int tot_credits = 0,
i;
1598 spin_lock_bh(&target->
tx_lock);
1600 for (i = 0; i < n_entries; i++, rpt++) {
1601 if (rpt->
eid >= ENDPOINT_MAX) {
1603 spin_unlock_bh(&target->
tx_lock);
1610 "credit report ep %d credits %d\n",
1613 endpoint->
ep_st.tx_cred_rpt += 1;
1616 if (from_ep == rpt->
eid) {
1622 endpoint->
ep_st.cred_rpt_from_rx += 1;
1626 endpoint->
ep_st.cred_rpt_ep0 += 1;
1629 endpoint->
ep_st.cred_rpt_from_other += 1;
1646 get_queue_depth(&endpoint->
txq);
1661 spin_unlock_bh(&target->
tx_lock);
1664 htc_chk_ep_txq(target);
1667 static int htc_parse_trailer(
struct htc_target *target,
1669 u8 *record_buf,
u32 *next_lk_ahds,
1677 switch (record->
rec_id) {
1685 htc_proc_cred_rpt(target,
1690 len = record->
len /
sizeof(*lk_ahd);
1701 "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
1708 "htc rx next look ahead",
1709 "", next_lk_ahds, 4);
1715 len = record->
len /
sizeof(*bundle_lkahd_rpt);
1728 "", record_buf, record->
len);
1730 for (i = 0; i < len; i++) {
1732 bundle_lkahd_rpt->
lk_ahd, 4);
1740 ath6kl_err(
"unhandled record: id:%d len:%d\n",
1749 static int htc_proc_trailer(
struct htc_target *target,
1750 u8 *buf,
int len,
u32 *next_lk_ahds,
1777 if (record->
len > len) {
1778 ath6kl_err(
"invalid record len: %d (id:%d) buf has: %d bytes left\n",
1785 status = htc_parse_trailer(target, record, record_buf,
1786 next_lk_ahds, endpoint, n_lk_ahds);
1798 "", orig_buf, orig_len);
1803 static int ath6kl_htc_rx_process_hdr(
struct htc_target *target,
1805 u32 *next_lkahds,
int *n_lkahds)
1821 memcpy((
u8 *)&lk_ahd, packet->
buf,
sizeof(lk_ahd));
1829 packet->
info.
rx.exp_hdr = lk_ahd;
1834 ath6kl_err(
"refreshed hdr payload len (%d) in bundled recv is invalid (hdr: 0x%X)\n",
1835 payload_len, lk_ahd);
1846 ath6kl_err(
"refreshed hdr ep (%d) does not match expected ep (%d)\n",
1853 if (lk_ahd != packet->
info.
rx.exp_hdr) {
1854 ath6kl_err(
"%s(): lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
1855 __func__, packet, packet->
info.
rx.rx_flags);
1857 "", &packet->
info.
rx.exp_hdr, 4);
1859 "", (
u8 *)&lk_ahd,
sizeof(lk_ahd));
1866 htc_hdr->
ctrl[0] > payload_len) {
1867 ath6kl_err(
"%s(): invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
1868 __func__, payload_len, htc_hdr->
ctrl[0]);
1878 status = htc_proc_trailer(target, packet->
buf + HTC_HDR_LENGTH
1879 + payload_len - htc_hdr->
ctrl[0],
1880 htc_hdr->
ctrl[0], next_lkahds,
1900 static void ath6kl_htc_rx_complete(
struct htc_endpoint *endpoint,
1904 "htc rx complete ep %d packet 0x%p\n",
1905 endpoint->
eid, packet);
1909 static int ath6kl_htc_rx_bundle(
struct htc_target *target,
1912 int *n_pkt_fetched,
bool part_bundle)
1917 int n_scat_pkt, status = 0,
i, len;
1919 n_scat_pkt = get_queue_depth(rxq);
1922 if ((get_queue_depth(rxq) - n_scat_pkt) > 0) {
1934 ath6kl_warn(
"%s(): partial bundle detected num:%d , %d\n",
1935 __func__, get_queue_depth(rxq), n_scat_pkt);
1941 "htc rx bundle depth %d pkts %d\n",
1942 get_queue_depth(rxq), n_scat_pkt);
1944 scat_req = hif_scatter_req_get(target->
dev->ar);
1946 if (scat_req ==
NULL)
1949 for (i = 0; i < n_scat_pkt; i++) {
1958 if ((rem_space - pad_len) < 0) {
1959 list_add(&packet->
list, rxq);
1965 if (part_bundle || (i < (n_scat_pkt - 1)))
1971 packet->
info.
rx.rx_flags |=
1986 scat_req->
len = len;
1995 hif_scatter_req_add(target->
dev->ar, scat_req);
2002 static int ath6kl_htc_rx_process_packets(
struct htc_target *target,
2015 status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
2022 if (list_empty(comp_pktq)) {
2028 ath6kl_htc_rx_set_indicate(lk_ahds[0],
2035 packet->
info.
rx.indicat_flags |=
2038 ath6kl_htc_rx_update_stats(ep, *n_lk_ahd);
2041 ep->
ep_st.rx_bundl += 1;
2043 ath6kl_htc_rx_complete(ep, packet);
2049 static int ath6kl_htc_rx_fetch(
struct htc_target *target,
2054 bool part_bundle =
false;
2060 while (!list_empty(rx_pktq)) {
2063 INIT_LIST_HEAD(&tmp_rxq);
2071 status = ath6kl_htc_rx_bundle(target, rx_pktq,
2078 if (!list_empty(rx_pktq))
2081 list_splice_tail_init(&tmp_rxq, comp_pktq);
2084 if (!fetched_pkts) {
2092 if (!list_is_singular(rx_pktq))
2098 packet->
info.
rx.rx_flags |=
2102 status = ath6kl_htc_rx_packet(target, packet,
2105 list_move_tail(&packet->
list, &tmp_rxq);
2110 list_splice_tail_init(&tmp_rxq, comp_pktq);
2125 htc_reclaim_rxbuf(target, packet,
2131 htc_reclaim_rxbuf(target, packet,
2139 u32 msg_look_ahead,
int *num_pkts)
2146 int num_look_ahead = 1;
2150 INIT_LIST_HEAD(&comp_pktq);
2157 look_aheads[0] = msg_look_ahead;
2168 if (
id >= ENDPOINT_MAX) {
2169 ath6kl_err(
"MsgPend, invalid endpoint in look-ahead: %d\n",
2175 INIT_LIST_HEAD(&rx_pktq);
2176 INIT_LIST_HEAD(&comp_pktq);
2182 status = ath6kl_htc_rx_alloc(target, look_aheads,
2183 num_look_ahead, endpoint,
2188 if (get_queue_depth(&rx_pktq) >= 2)
2195 n_fetched += get_queue_depth(&rx_pktq);
2199 status = ath6kl_htc_rx_fetch(target, &rx_pktq, &comp_pktq);
2202 ath6kl_htc_rx_chk_water_mark(endpoint);
2205 status = ath6kl_htc_rx_process_packets(target, &comp_pktq,
2209 if (!num_look_ahead || status)
2223 ath6kl_err(
"failed to get pending recv messages: %d\n",
2229 htc_reclaim_rxbuf(target, packets,
2234 ath6kl_warn(
"host is going to stop blocking receiver for htc_stop\n");
2244 ath6kl_warn(
"host has no rx buffers blocking receiver to prevent overrun\n");
2247 *num_pkts = n_fetched;
2257 static struct htc_packet *htc_wait_for_ctrl_msg(
struct htc_target *target)
2268 "htc rx wait ctrl look_ahead 0x%X\n", look_ahead);
2275 packet = htc_get_control_buf(target,
false);
2280 packet->
info.
rx.rx_flags = 0;
2281 packet->
info.
rx.exp_hdr = look_ahead;
2291 if (ath6kl_htc_rx_packet(target, packet, packet->
act_len))
2295 packet->
status = ath6kl_htc_rx_process_hdr(target, packet,
NULL,
NULL);
2298 ath6kl_err(
"htc_wait_for_ctrl_msg, ath6kl_htc_rx_process_hdr failed (status = %d)\n",
2306 if (packet !=
NULL) {
2307 htc_rxpkt_reset(packet);
2308 reclaim_rx_ctrl_buf(target, packet);
2314 static int ath6kl_htc_mbox_add_rxbuf_multiple(
struct htc_target *target,
2319 bool rx_unblock =
false;
2320 int status = 0,
depth;
2322 if (list_empty(pkt_queue))
2327 if (first_pkt->
endpoint >= ENDPOINT_MAX)
2330 depth = get_queue_depth(pkt_queue);
2333 "htc rx add multiple ep id %d cnt %d len %d\n",
2345 ath6kl_htc_rx_complete(endpoint, packet);
2351 spin_lock_bh(&target->
rx_lock);
2353 list_splice_tail_init(pkt_queue, &endpoint->
rx_bufq);
2359 "htc rx blocked on ep %d, unblocking\n",
2367 spin_unlock_bh(&target->
rx_lock);
2376 static void ath6kl_htc_mbox_flush_rx_buf(
struct htc_target *target)
2388 spin_lock_bh(&target->
rx_lock);
2392 spin_unlock_bh(&target->
rx_lock);
2394 "htc rx flush pkt 0x%p len %d ep %d\n",
2412 spin_lock_bh(&target->
rx_lock);
2414 spin_unlock_bh(&target->
rx_lock);
2418 static int ath6kl_htc_mbox_conn_service(
struct htc_target *target,
2433 "htc connect service target 0x%p service id 0x%x\n",
2434 target, conn_req->
svc_id);
2442 tx_pkt = htc_get_control_buf(target,
true);
2448 memset(conn_msg, 0,
sizeof(*conn_msg));
2453 set_htc_pkt_info(tx_pkt,
NULL, (
u8 *) conn_msg,
2459 ath6kl_htc_tx_prep_pkt(tx_pkt, 0, 0, 0);
2460 status = ath6kl_htc_tx_issue(target, tx_pkt);
2466 rx_pkt = htc_wait_for_ctrl_msg(target);
2477 (rx_pkt->
act_len <
sizeof(*resp_msg))) {
2485 ath6kl_err(
"target failed service 0x%X connect request (status:%d)\n",
2495 if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) {
2500 endpoint = &target->
endpoint[assigned_ep];
2501 endpoint->
eid = assigned_ep;
2521 endpoint->
cred_dist.endpoint = assigned_ep;
2524 switch (endpoint->
svc_id) {
2557 htc_reclaim_txctrl_buf(target, tx_pkt);
2560 htc_rxpkt_reset(rx_pkt);
2561 reclaim_rx_ctrl_buf(target, rx_pkt);
2567 static void reset_ep_state(
struct htc_target *target)
2579 sizeof(endpoint->
ep_st));
2580 INIT_LIST_HEAD(&endpoint->
rx_bufq);
2581 INIT_LIST_HEAD(&endpoint->
txq);
2590 static int ath6kl_htc_mbox_get_rxbuf_num(
struct htc_target *target,
2595 spin_lock_bh(&target->
rx_lock);
2596 num = get_queue_depth(&(target->
endpoint[endpoint].rx_bufq));
2597 spin_unlock_bh(&target->
rx_lock);
2601 static void htc_setup_msg_bndl(
struct htc_target *target)
2607 if (ath6kl_hif_enable_scatter(target->
dev->ar)) {
2617 "htc bundling allowed msg_per_bndl_max %d\n",
2626 ath6kl_dbg(
ATH6KL_DBG_BOOT,
"htc max_rx_bndl_sz %d max_tx_bndl_sz %d\n",
2637 ath6kl_warn(
"credit size: %d is not block aligned! Disabling send bundling\n",
2650 static int ath6kl_htc_mbox_wait_target(
struct htc_target *target)
2660 ath6kl_err(
"HTC doesn't support USB yet. Patience!\n");
2665 packet = htc_wait_for_ctrl_msg(target);
2676 goto fail_wait_target;
2681 goto fail_wait_target;
2688 "htc target ready credits %d size %d\n",
2707 htc_setup_msg_bndl(target);
2710 memset(&connect, 0,
sizeof(connect));
2712 connect.ep_cb.rx = htc_ctrl_rx;
2713 connect.ep_cb.rx_refill =
NULL;
2714 connect.ep_cb.tx_full =
NULL;
2719 status = ath6kl_htc_mbox_conn_service((
void *)target, &connect, &
resp);
2726 ath6kl_hif_cleanup_scatter(target->
dev->ar);
2730 htc_rxpkt_reset(packet);
2731 reclaim_rx_ctrl_buf(target, packet);
2741 static int ath6kl_htc_mbox_start(
struct htc_target *target)
2747 sizeof(target->
dev->irq_proc_reg));
2756 while ((packet = htc_get_control_buf(target,
false)) !=
NULL) {
2757 status = htc_add_rxbuf(target, packet);
2766 dump_cred_dist_stats(target);
2769 status = htc_setup_tx_complete(target);
2778 ath6kl_htc_mbox_stop(target);
2783 static int ath6kl_htc_reset(
struct htc_target *target)
2789 reset_ep_state(target);
2791 block_size = target->
dev->ar->mbox_info.block_size;
2794 (block_size + HTC_HDR_LENGTH) :
2798 packet = kzalloc(
sizeof(*packet),
GFP_KERNEL);
2822 static void ath6kl_htc_mbox_stop(
struct htc_target *target)
2835 ath6kl_htc_flush_txep_all(target);
2837 ath6kl_htc_mbox_flush_rx_buf(target);
2839 ath6kl_htc_reset(target);
2842 static void *ath6kl_htc_mbox_create(
struct ath6kl *
ar)
2844 struct htc_target *target =
NULL;
2847 target = kzalloc(
sizeof(*target),
GFP_KERNEL);
2857 goto err_htc_cleanup;
2868 target->
dev->ar =
ar;
2874 goto err_htc_cleanup;
2876 status = ath6kl_htc_reset(target);
2878 goto err_htc_cleanup;
2883 ath6kl_htc_mbox_cleanup(target);
2889 static void ath6kl_htc_mbox_cleanup(
struct htc_target *target)
2895 ath6kl_hif_cleanup_scatter(target->
dev->ar);
2916 .create = ath6kl_htc_mbox_create,
2917 .wait_target = ath6kl_htc_mbox_wait_target,
2918 .start = ath6kl_htc_mbox_start,
2919 .conn_service = ath6kl_htc_mbox_conn_service,
2920 .tx = ath6kl_htc_mbox_tx,
2921 .stop = ath6kl_htc_mbox_stop,
2922 .cleanup = ath6kl_htc_mbox_cleanup,
2923 .flush_txep = ath6kl_htc_mbox_flush_txep,
2924 .flush_rx_buf = ath6kl_htc_mbox_flush_rx_buf,
2925 .activity_changed = ath6kl_htc_mbox_activity_changed,
2926 .get_rxbuf_num = ath6kl_htc_mbox_get_rxbuf_num,
2927 .add_rxbuf_multiple = ath6kl_htc_mbox_add_rxbuf_multiple,
2928 .credit_setup = ath6kl_htc_mbox_credit_setup,
2933 ar->
htc_ops = &ath6kl_htc_mbox_ops;