2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 static inline void ath10k_htc_send_complete_check(struct ath10k_htc_ep *ep,
30 * Check whether HIF has any prior sends that have finished,
31 * have not had the post-processing done.
33 ath10k_hif_send_complete_check(ep->htc->ar, ep->ul_pipe_id, force);
36 static void ath10k_htc_control_tx_complete(struct ath10k *ar,
42 static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
45 struct ath10k_skb_cb *skb_cb;
47 skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
49 ath10k_warn("Unable to allocate ctrl skb\n");
53 skb_reserve(skb, 20); /* FIXME: why 20 bytes? */
54 WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
56 skb_cb = ATH10K_SKB_CB(skb);
57 memset(skb_cb, 0, sizeof(*skb_cb));
59 ath10k_dbg(ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb);
63 static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
66 ath10k_skb_unmap(htc->ar->dev, skb);
67 skb_pull(skb, sizeof(struct ath10k_htc_hdr));
70 static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
73 ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
76 ath10k_htc_restore_tx_skb(ep->htc, skb);
78 if (!ep->ep_ops.ep_tx_complete) {
79 ath10k_warn("no tx handler for eid %d\n", ep->eid);
80 dev_kfree_skb_any(skb);
84 ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
87 /* assumes tx_lock is held */
88 static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep)
90 if (!ep->tx_credit_flow_enabled)
92 if (ep->tx_credits >= ep->tx_credits_per_max_message)
95 ath10k_dbg(ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n",
100 static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
103 struct ath10k_htc_hdr *hdr;
105 hdr = (struct ath10k_htc_hdr *)skb->data;
106 memset(hdr, 0, sizeof(*hdr));
109 hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
111 spin_lock_bh(&ep->htc->tx_lock);
112 hdr->seq_no = ep->seq_no++;
114 if (ath10k_htc_ep_need_credit_update(ep))
115 hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
117 spin_unlock_bh(&ep->htc->tx_lock);
120 static int ath10k_htc_issue_skb(struct ath10k_htc *htc,
121 struct ath10k_htc_ep *ep,
125 struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
128 ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
131 ath10k_htc_prepare_tx_skb(ep, skb);
133 ret = ath10k_skb_map(htc->ar->dev, skb);
137 ret = ath10k_hif_send_head(htc->ar,
147 ath10k_warn("HTC issue failed: %d\n", ret);
149 spin_lock_bh(&htc->tx_lock);
150 ep->tx_credits += credits;
151 spin_unlock_bh(&htc->tx_lock);
153 /* this is the simplest way to handle out-of-resources for non-credit
154 * based endpoints. credit based endpoints can still get -ENOSR, but
155 * this is highly unlikely as credit reservation should prevent that */
157 spin_lock_bh(&htc->tx_lock);
158 __skb_queue_head(&ep->tx_queue, skb);
159 spin_unlock_bh(&htc->tx_lock);
164 skb_cb->is_aborted = true;
165 ath10k_htc_notify_tx_completion(ep, skb);
170 static void ath10k_htc_send_work(struct work_struct *work)
172 struct ath10k_htc_ep *ep = container_of(work,
173 struct ath10k_htc_ep, send_work);
174 struct ath10k_htc *htc = ep->htc;
180 if (ep->ul_is_polled)
181 ath10k_htc_send_complete_check(ep, 0);
183 spin_lock_bh(&htc->tx_lock);
184 skb = __skb_dequeue(&ep->tx_queue);
186 if (ep->tx_credit_flow_enabled) {
187 credits = DIV_ROUND_UP(skb->len,
188 htc->target_credit_size);
189 if (ep->tx_credits < credits) {
190 __skb_queue_head(&ep->tx_queue, skb);
194 spin_unlock_bh(&htc->tx_lock);
199 ret = ath10k_htc_issue_skb(htc, ep, skb, credits);
205 int ath10k_htc_send(struct ath10k_htc *htc,
206 enum ath10k_htc_ep_id eid,
209 struct ath10k_htc_ep *ep = &htc->endpoint[eid];
211 if (htc->ar->state == ATH10K_STATE_WEDGED)
214 if (eid >= ATH10K_HTC_EP_COUNT) {
215 ath10k_warn("Invalid endpoint id: %d\n", eid);
219 spin_lock_bh(&htc->tx_lock);
221 spin_unlock_bh(&htc->tx_lock);
225 __skb_queue_tail(&ep->tx_queue, skb);
226 skb_push(skb, sizeof(struct ath10k_htc_hdr));
227 spin_unlock_bh(&htc->tx_lock);
229 queue_work(htc->ar->workqueue, &ep->send_work);
233 static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
237 struct ath10k_htc *htc = &ar->htc;
238 struct ath10k_htc_ep *ep = &htc->endpoint[eid];
240 ath10k_htc_notify_tx_completion(ep, skb);
241 /* the skb now belongs to the completion handler */
243 /* note: when using TX credit flow, the re-checking of queues happens
244 * when credits flow back from the target. in the non-TX credit case,
245 * we recheck after the packet completes */
246 spin_lock_bh(&htc->tx_lock);
247 if (!ep->tx_credit_flow_enabled && !htc->stopped)
248 queue_work(ar->workqueue, &ep->send_work);
249 spin_unlock_bh(&htc->tx_lock);
254 /* flush endpoint TX queue */
255 static void ath10k_htc_flush_endpoint_tx(struct ath10k_htc *htc,
256 struct ath10k_htc_ep *ep)
259 struct ath10k_skb_cb *skb_cb;
261 spin_lock_bh(&htc->tx_lock);
263 skb = __skb_dequeue(&ep->tx_queue);
267 skb_cb = ATH10K_SKB_CB(skb);
268 skb_cb->is_aborted = true;
269 ath10k_htc_notify_tx_completion(ep, skb);
271 spin_unlock_bh(&htc->tx_lock);
273 cancel_work_sync(&ep->send_work);
281 ath10k_htc_process_credit_report(struct ath10k_htc *htc,
282 const struct ath10k_htc_credit_report *report,
284 enum ath10k_htc_ep_id eid)
286 struct ath10k_htc_ep *ep;
289 if (len % sizeof(*report))
290 ath10k_warn("Uneven credit report len %d", len);
292 n_reports = len / sizeof(*report);
294 spin_lock_bh(&htc->tx_lock);
295 for (i = 0; i < n_reports; i++, report++) {
296 if (report->eid >= ATH10K_HTC_EP_COUNT)
299 ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n",
300 report->eid, report->credits);
302 ep = &htc->endpoint[report->eid];
303 ep->tx_credits += report->credits;
305 if (ep->tx_credits && !skb_queue_empty(&ep->tx_queue))
306 queue_work(htc->ar->workqueue, &ep->send_work);
308 spin_unlock_bh(&htc->tx_lock);
311 static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
314 enum ath10k_htc_ep_id src_eid)
317 struct ath10k_htc_record *record;
322 orig_buffer = buffer;
323 orig_length = length;
326 record = (struct ath10k_htc_record *)buffer;
328 if (length < sizeof(record->hdr)) {
333 if (record->hdr.len > length) {
334 /* no room left in buffer for record */
335 ath10k_warn("Invalid record length: %d\n",
341 switch (record->hdr.id) {
342 case ATH10K_HTC_RECORD_CREDITS:
343 len = sizeof(struct ath10k_htc_credit_report);
344 if (record->hdr.len < len) {
345 ath10k_warn("Credit report too long\n");
349 ath10k_htc_process_credit_report(htc,
350 record->credit_report,
355 ath10k_warn("Unhandled record: id:%d length:%d\n",
356 record->hdr.id, record->hdr.len);
363 /* multiple records may be present in a trailer */
364 buffer += sizeof(record->hdr) + record->hdr.len;
365 length -= sizeof(record->hdr) + record->hdr.len;
369 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "",
370 orig_buffer, orig_length);
375 static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
380 struct ath10k_htc *htc = &ar->htc;
381 struct ath10k_htc_hdr *hdr;
382 struct ath10k_htc_ep *ep;
387 bool trailer_present;
389 hdr = (struct ath10k_htc_hdr *)skb->data;
390 skb_pull(skb, sizeof(*hdr));
394 if (eid >= ATH10K_HTC_EP_COUNT) {
395 ath10k_warn("HTC Rx: invalid eid %d\n", eid);
396 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "",
402 ep = &htc->endpoint[eid];
405 * If this endpoint that received a message from the target has
406 * a to-target HIF pipe whose send completions are polled rather
407 * than interrupt-driven, this is a good point to ask HIF to check
408 * whether it has any completed sends to handle.
410 if (ep->ul_is_polled)
411 ath10k_htc_send_complete_check(ep, 1);
413 payload_len = __le16_to_cpu(hdr->len);
415 if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
416 ath10k_warn("HTC rx frame too long, len: %zu\n",
417 payload_len + sizeof(*hdr));
418 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "",
424 if (skb->len < payload_len) {
425 ath10k_dbg(ATH10K_DBG_HTC,
426 "HTC Rx: insufficient length, got %d, expected %d\n",
427 skb->len, payload_len);
428 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len",
429 "", hdr, sizeof(*hdr));
434 /* get flags to check for trailer */
435 trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
436 if (trailer_present) {
439 trailer_len = hdr->trailer_len;
440 min_len = sizeof(struct ath10k_ath10k_htc_record_hdr);
442 if ((trailer_len < min_len) ||
443 (trailer_len > payload_len)) {
444 ath10k_warn("Invalid trailer length: %d\n",
451 trailer += sizeof(*hdr);
452 trailer += payload_len;
453 trailer -= trailer_len;
454 status = ath10k_htc_process_trailer(htc, trailer,
455 trailer_len, hdr->eid);
459 skb_trim(skb, skb->len - trailer_len);
462 if (((int)payload_len - (int)trailer_len) <= 0)
463 /* zero length packet with trailer data, just drop these */
466 if (eid == ATH10K_HTC_EP_0) {
467 struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
469 switch (__le16_to_cpu(msg->hdr.message_id)) {
471 /* handle HTC control message */
472 if (completion_done(&htc->ctl_resp)) {
474 * this is a fatal error, target should not be
475 * sending unsolicited messages on the ep 0
477 ath10k_warn("HTC rx ctrl still processing\n");
479 complete(&htc->ctl_resp);
483 htc->control_resp_len =
485 ATH10K_HTC_MAX_CTRL_MSG_LEN);
487 memcpy(htc->control_resp_buffer, skb->data,
488 htc->control_resp_len);
490 complete(&htc->ctl_resp);
492 case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
493 htc->htc_ops.target_send_suspend_complete(ar);
498 ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n",
500 ep->ep_ops.ep_rx_complete(ar, skb);
502 /* skb is now owned by the rx completion handler */
510 static void ath10k_htc_control_rx_complete(struct ath10k *ar,
513 /* This is unexpected. FW is not supposed to send regular rx on this
515 ath10k_warn("unexpected htc rx\n");
523 static const char *htc_service_name(enum ath10k_htc_svc_id id)
526 case ATH10K_HTC_SVC_ID_RESERVED:
528 case ATH10K_HTC_SVC_ID_RSVD_CTRL:
530 case ATH10K_HTC_SVC_ID_WMI_CONTROL:
532 case ATH10K_HTC_SVC_ID_WMI_DATA_BE:
534 case ATH10K_HTC_SVC_ID_WMI_DATA_BK:
536 case ATH10K_HTC_SVC_ID_WMI_DATA_VI:
538 case ATH10K_HTC_SVC_ID_WMI_DATA_VO:
540 case ATH10K_HTC_SVC_ID_NMI_CONTROL:
541 return "NMI Control";
542 case ATH10K_HTC_SVC_ID_NMI_DATA:
544 case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
546 case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
553 static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
555 struct ath10k_htc_ep *ep;
558 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
559 ep = &htc->endpoint[i];
560 ep->service_id = ATH10K_HTC_SVC_ID_UNUSED;
561 ep->max_ep_message_len = 0;
562 ep->max_tx_queue_depth = 0;
564 skb_queue_head_init(&ep->tx_queue);
566 ep->tx_credit_flow_enabled = true;
567 INIT_WORK(&ep->send_work, ath10k_htc_send_work);
571 static void ath10k_htc_setup_target_buffer_assignments(struct ath10k_htc *htc)
573 struct ath10k_htc_svc_tx_credits *entry;
575 entry = &htc->service_tx_alloc[0];
578 * for PCIE allocate all credists/HTC buffers to WMI.
579 * no buffers are used/required for data. data always
583 entry->service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
584 entry->credit_allocation = htc->total_transmit_credits;
587 static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
593 for (i = 0; i < ATH10K_HTC_EP_COUNT; i++) {
594 if (htc->service_tx_alloc[i].service_id == service_id)
596 htc->service_tx_alloc[i].credit_allocation;
602 int ath10k_htc_wait_target(struct ath10k_htc *htc)
605 struct ath10k_htc_svc_conn_req conn_req;
606 struct ath10k_htc_svc_conn_resp conn_resp;
607 struct ath10k_htc_msg *msg;
612 INIT_COMPLETION(htc->ctl_resp);
614 status = ath10k_hif_start(htc->ar);
616 ath10k_err("could not start HIF (%d)\n", status);
620 status = wait_for_completion_timeout(&htc->ctl_resp,
621 ATH10K_HTC_WAIT_TIMEOUT_HZ);
626 ath10k_err("ctl_resp never came in (%d)\n", status);
630 if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
631 ath10k_err("Invalid HTC ready msg len:%d\n",
632 htc->control_resp_len);
638 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
639 message_id = __le16_to_cpu(msg->hdr.message_id);
640 credit_count = __le16_to_cpu(msg->ready.credit_count);
641 credit_size = __le16_to_cpu(msg->ready.credit_size);
643 if (message_id != ATH10K_HTC_MSG_READY_ID) {
644 ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id);
649 htc->total_transmit_credits = credit_count;
650 htc->target_credit_size = credit_size;
652 ath10k_dbg(ATH10K_DBG_HTC,
653 "Target ready! transmit resources: %d size:%d\n",
654 htc->total_transmit_credits,
655 htc->target_credit_size);
657 if ((htc->total_transmit_credits == 0) ||
658 (htc->target_credit_size == 0)) {
660 ath10k_err("Invalid credit size received\n");
664 ath10k_htc_setup_target_buffer_assignments(htc);
666 /* setup our pseudo HTC control endpoint connection */
667 memset(&conn_req, 0, sizeof(conn_req));
668 memset(&conn_resp, 0, sizeof(conn_resp));
669 conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
670 conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
671 conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
672 conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
674 /* connect fake service */
675 status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
677 ath10k_err("could not connect to htc service (%d)\n", status);
683 ath10k_hif_stop(htc->ar);
688 int ath10k_htc_connect_service(struct ath10k_htc *htc,
689 struct ath10k_htc_svc_conn_req *conn_req,
690 struct ath10k_htc_svc_conn_resp *conn_resp)
692 struct ath10k_htc_msg *msg;
693 struct ath10k_htc_conn_svc *req_msg;
694 struct ath10k_htc_conn_svc_response resp_msg_dummy;
695 struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy;
696 enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT;
697 struct ath10k_htc_ep *ep;
699 unsigned int max_msg_size = 0;
701 bool disable_credit_flow_ctrl = false;
702 u16 message_id, service_id, flags = 0;
705 /* special case for HTC pseudo control service */
706 if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) {
707 disable_credit_flow_ctrl = true;
708 assigned_eid = ATH10K_HTC_EP_0;
709 max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN;
710 memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy));
714 tx_alloc = ath10k_htc_get_credit_allocation(htc,
715 conn_req->service_id);
717 ath10k_dbg(ATH10K_DBG_BOOT,
718 "boot htc service %s does not allocate target credits\n",
719 htc_service_name(conn_req->service_id));
721 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
723 ath10k_err("Failed to allocate HTC packet\n");
727 length = sizeof(msg->hdr) + sizeof(msg->connect_service);
728 skb_put(skb, length);
729 memset(skb->data, 0, length);
731 msg = (struct ath10k_htc_msg *)skb->data;
732 msg->hdr.message_id =
733 __cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID);
735 flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC);
737 /* Only enable credit flow control for WMI ctrl service */
738 if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) {
739 flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
740 disable_credit_flow_ctrl = true;
743 req_msg = &msg->connect_service;
744 req_msg->flags = __cpu_to_le16(flags);
745 req_msg->service_id = __cpu_to_le16(conn_req->service_id);
747 INIT_COMPLETION(htc->ctl_resp);
749 status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
755 /* wait for response */
756 status = wait_for_completion_timeout(&htc->ctl_resp,
757 ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
761 ath10k_err("Service connect timeout: %d\n", status);
765 /* we controlled the buffer creation, it's aligned */
766 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
767 resp_msg = &msg->connect_service_response;
768 message_id = __le16_to_cpu(msg->hdr.message_id);
769 service_id = __le16_to_cpu(resp_msg->service_id);
771 if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) ||
772 (htc->control_resp_len < sizeof(msg->hdr) +
773 sizeof(msg->connect_service_response))) {
774 ath10k_err("Invalid resp message ID 0x%x", message_id);
778 ath10k_dbg(ATH10K_DBG_HTC,
779 "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n",
780 htc_service_name(service_id),
781 resp_msg->status, resp_msg->eid);
783 conn_resp->connect_resp_code = resp_msg->status;
785 /* check response status */
786 if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) {
787 ath10k_err("HTC Service %s connect request failed: 0x%x)\n",
788 htc_service_name(service_id),
793 assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid;
794 max_msg_size = __le16_to_cpu(resp_msg->max_msg_size);
798 if (assigned_eid >= ATH10K_HTC_EP_COUNT)
801 if (max_msg_size == 0)
804 ep = &htc->endpoint[assigned_eid];
805 ep->eid = assigned_eid;
807 if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED)
810 /* return assigned endpoint to caller */
811 conn_resp->eid = assigned_eid;
812 conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size);
814 /* setup the endpoint */
815 ep->service_id = conn_req->service_id;
816 ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
817 ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
818 ep->tx_credits = tx_alloc;
819 ep->tx_credit_size = htc->target_credit_size;
820 ep->tx_credits_per_max_message = ep->max_ep_message_len /
821 htc->target_credit_size;
823 if (ep->max_ep_message_len % htc->target_credit_size)
824 ep->tx_credits_per_max_message++;
826 /* copy all the callbacks */
827 ep->ep_ops = conn_req->ep_ops;
829 status = ath10k_hif_map_service_to_pipe(htc->ar,
838 ath10k_dbg(ATH10K_DBG_BOOT,
839 "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n",
840 htc_service_name(ep->service_id), ep->ul_pipe_id,
841 ep->dl_pipe_id, ep->eid);
843 ath10k_dbg(ATH10K_DBG_BOOT,
844 "boot htc ep %d ul polled %d dl polled %d\n",
845 ep->eid, ep->ul_is_polled, ep->dl_is_polled);
847 if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
848 ep->tx_credit_flow_enabled = false;
849 ath10k_dbg(ATH10K_DBG_BOOT,
850 "boot htc service '%s' eid %d TX flow control disabled\n",
851 htc_service_name(ep->service_id), assigned_eid);
857 struct sk_buff *ath10k_htc_alloc_skb(int size)
861 skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
863 ath10k_warn("could not allocate HTC tx skb\n");
867 skb_reserve(skb, sizeof(struct ath10k_htc_hdr));
869 /* FW/HTC requires 4-byte aligned streams */
870 if (!IS_ALIGNED((unsigned long)skb->data, 4))
871 ath10k_warn("Unaligned HTC tx skb\n");
876 int ath10k_htc_start(struct ath10k_htc *htc)
880 struct ath10k_htc_msg *msg;
882 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
886 skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext));
887 memset(skb->data, 0, skb->len);
889 msg = (struct ath10k_htc_msg *)skb->data;
890 msg->hdr.message_id =
891 __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID);
893 ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
895 status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
905 * stop HTC communications, i.e. stop interrupt reception, and flush all
908 void ath10k_htc_stop(struct ath10k_htc *htc)
911 struct ath10k_htc_ep *ep;
913 spin_lock_bh(&htc->tx_lock);
915 spin_unlock_bh(&htc->tx_lock);
917 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
918 ep = &htc->endpoint[i];
919 ath10k_htc_flush_endpoint_tx(htc, ep);
922 ath10k_hif_stop(htc->ar);
925 /* registered target arrival callback from the HIF layer */
926 int ath10k_htc_init(struct ath10k *ar)
928 struct ath10k_hif_cb htc_callbacks;
929 struct ath10k_htc_ep *ep = NULL;
930 struct ath10k_htc *htc = &ar->htc;
932 spin_lock_init(&htc->tx_lock);
934 htc->stopped = false;
935 ath10k_htc_reset_endpoint_states(htc);
937 /* setup HIF layer callbacks */
938 htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler;
939 htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler;
942 /* Get HIF default pipe for HTC message exchange */
943 ep = &htc->endpoint[ATH10K_HTC_EP_0];
945 ath10k_hif_set_callbacks(ar, &htc_callbacks);
946 ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id);
948 init_completion(&htc->ctl_resp);