xref: /linux/drivers/net/wireless/ath/ath10k/htc.c (revision b7019ac550eb3916f34d79db583e9b7ea2524afa)
1 // SPDX-License-Identifier: ISC
2 /*
3  * Copyright (c) 2005-2011 Atheros Communications Inc.
4  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5  */
6 
7 #include "core.h"
8 #include "hif.h"
9 #include "debug.h"
10 
11 /********/
12 /* Send */
13 /********/
14 
15 static void ath10k_htc_control_tx_complete(struct ath10k *ar,
16 					   struct sk_buff *skb)
17 {
18 	kfree_skb(skb);
19 }
20 
21 static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
22 {
23 	struct sk_buff *skb;
24 	struct ath10k_skb_cb *skb_cb;
25 
26 	skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
27 	if (!skb)
28 		return NULL;
29 
30 	skb_reserve(skb, 20); /* FIXME: why 20 bytes? */
31 	WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
32 
33 	skb_cb = ATH10K_SKB_CB(skb);
34 	memset(skb_cb, 0, sizeof(*skb_cb));
35 
36 	ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %pK\n", __func__, skb);
37 	return skb;
38 }
39 
40 static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
41 					     struct sk_buff *skb)
42 {
43 	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
44 
45 	if (htc->ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
46 		dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
47 	skb_pull(skb, sizeof(struct ath10k_htc_hdr));
48 }
49 
50 void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
51 				     struct sk_buff *skb)
52 {
53 	struct ath10k *ar = ep->htc->ar;
54 
55 	ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
56 		   ep->eid, skb);
57 
58 	ath10k_htc_restore_tx_skb(ep->htc, skb);
59 
60 	if (!ep->ep_ops.ep_tx_complete) {
61 		ath10k_warn(ar, "no tx handler for eid %d\n", ep->eid);
62 		dev_kfree_skb_any(skb);
63 		return;
64 	}
65 
66 	ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
67 }
68 EXPORT_SYMBOL(ath10k_htc_notify_tx_completion);
69 
70 static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
71 				      struct sk_buff *skb)
72 {
73 	struct ath10k_htc_hdr *hdr;
74 
75 	hdr = (struct ath10k_htc_hdr *)skb->data;
76 
77 	hdr->eid = ep->eid;
78 	hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
79 	hdr->flags = 0;
80 	if (ep->tx_credit_flow_enabled)
81 		hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
82 
83 	spin_lock_bh(&ep->htc->tx_lock);
84 	hdr->seq_no = ep->seq_no++;
85 	spin_unlock_bh(&ep->htc->tx_lock);
86 }
87 
88 int ath10k_htc_send(struct ath10k_htc *htc,
89 		    enum ath10k_htc_ep_id eid,
90 		    struct sk_buff *skb)
91 {
92 	struct ath10k *ar = htc->ar;
93 	struct ath10k_htc_ep *ep = &htc->endpoint[eid];
94 	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
95 	struct ath10k_hif_sg_item sg_item;
96 	struct device *dev = htc->ar->dev;
97 	int credits = 0;
98 	int ret;
99 
100 	if (htc->ar->state == ATH10K_STATE_WEDGED)
101 		return -ECOMM;
102 
103 	if (eid >= ATH10K_HTC_EP_COUNT) {
104 		ath10k_warn(ar, "Invalid endpoint id: %d\n", eid);
105 		return -ENOENT;
106 	}
107 
108 	skb_push(skb, sizeof(struct ath10k_htc_hdr));
109 
110 	if (ep->tx_credit_flow_enabled) {
111 		credits = DIV_ROUND_UP(skb->len, htc->target_credit_size);
112 		spin_lock_bh(&htc->tx_lock);
113 		if (ep->tx_credits < credits) {
114 			ath10k_dbg(ar, ATH10K_DBG_HTC,
115 				   "htc insufficient credits ep %d required %d available %d\n",
116 				   eid, credits, ep->tx_credits);
117 			spin_unlock_bh(&htc->tx_lock);
118 			ret = -EAGAIN;
119 			goto err_pull;
120 		}
121 		ep->tx_credits -= credits;
122 		ath10k_dbg(ar, ATH10K_DBG_HTC,
123 			   "htc ep %d consumed %d credits (total %d)\n",
124 			   eid, credits, ep->tx_credits);
125 		spin_unlock_bh(&htc->tx_lock);
126 	}
127 
128 	ath10k_htc_prepare_tx_skb(ep, skb);
129 
130 	skb_cb->eid = eid;
131 	if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) {
132 		skb_cb->paddr = dma_map_single(dev, skb->data, skb->len,
133 					       DMA_TO_DEVICE);
134 		ret = dma_mapping_error(dev, skb_cb->paddr);
135 		if (ret) {
136 			ret = -EIO;
137 			goto err_credits;
138 		}
139 	}
140 
141 	sg_item.transfer_id = ep->eid;
142 	sg_item.transfer_context = skb;
143 	sg_item.vaddr = skb->data;
144 	sg_item.paddr = skb_cb->paddr;
145 	sg_item.len = skb->len;
146 
147 	ret = ath10k_hif_tx_sg(htc->ar, ep->ul_pipe_id, &sg_item, 1);
148 	if (ret)
149 		goto err_unmap;
150 
151 	return 0;
152 
153 err_unmap:
154 	if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
155 		dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
156 err_credits:
157 	if (ep->tx_credit_flow_enabled) {
158 		spin_lock_bh(&htc->tx_lock);
159 		ep->tx_credits += credits;
160 		ath10k_dbg(ar, ATH10K_DBG_HTC,
161 			   "htc ep %d reverted %d credits back (total %d)\n",
162 			   eid, credits, ep->tx_credits);
163 		spin_unlock_bh(&htc->tx_lock);
164 
165 		if (ep->ep_ops.ep_tx_credits)
166 			ep->ep_ops.ep_tx_credits(htc->ar);
167 	}
168 err_pull:
169 	skb_pull(skb, sizeof(struct ath10k_htc_hdr));
170 	return ret;
171 }
172 
173 void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
174 {
175 	struct ath10k_htc *htc = &ar->htc;
176 	struct ath10k_skb_cb *skb_cb;
177 	struct ath10k_htc_ep *ep;
178 
179 	if (WARN_ON_ONCE(!skb))
180 		return;
181 
182 	skb_cb = ATH10K_SKB_CB(skb);
183 	ep = &htc->endpoint[skb_cb->eid];
184 
185 	ath10k_htc_notify_tx_completion(ep, skb);
186 	/* the skb now belongs to the completion handler */
187 }
188 EXPORT_SYMBOL(ath10k_htc_tx_completion_handler);
189 
190 /***********/
191 /* Receive */
192 /***********/
193 
194 static void
195 ath10k_htc_process_credit_report(struct ath10k_htc *htc,
196 				 const struct ath10k_htc_credit_report *report,
197 				 int len,
198 				 enum ath10k_htc_ep_id eid)
199 {
200 	struct ath10k *ar = htc->ar;
201 	struct ath10k_htc_ep *ep;
202 	int i, n_reports;
203 
204 	if (len % sizeof(*report))
205 		ath10k_warn(ar, "Uneven credit report len %d", len);
206 
207 	n_reports = len / sizeof(*report);
208 
209 	spin_lock_bh(&htc->tx_lock);
210 	for (i = 0; i < n_reports; i++, report++) {
211 		if (report->eid >= ATH10K_HTC_EP_COUNT)
212 			break;
213 
214 		ep = &htc->endpoint[report->eid];
215 		ep->tx_credits += report->credits;
216 
217 		ath10k_dbg(ar, ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
218 			   report->eid, report->credits, ep->tx_credits);
219 
220 		if (ep->ep_ops.ep_tx_credits) {
221 			spin_unlock_bh(&htc->tx_lock);
222 			ep->ep_ops.ep_tx_credits(htc->ar);
223 			spin_lock_bh(&htc->tx_lock);
224 		}
225 	}
226 	spin_unlock_bh(&htc->tx_lock);
227 }
228 
229 static int
230 ath10k_htc_process_lookahead(struct ath10k_htc *htc,
231 			     const struct ath10k_htc_lookahead_report *report,
232 			     int len,
233 			     enum ath10k_htc_ep_id eid,
234 			     void *next_lookaheads,
235 			     int *next_lookaheads_len)
236 {
237 	struct ath10k *ar = htc->ar;
238 
239 	/* Invalid lookahead flags are actually transmitted by
240 	 * the target in the HTC control message.
241 	 * Since this will happen at every boot we silently ignore
242 	 * the lookahead in this case
243 	 */
244 	if (report->pre_valid != ((~report->post_valid) & 0xFF))
245 		return 0;
246 
247 	if (next_lookaheads && next_lookaheads_len) {
248 		ath10k_dbg(ar, ATH10K_DBG_HTC,
249 			   "htc rx lookahead found pre_valid 0x%x post_valid 0x%x\n",
250 			   report->pre_valid, report->post_valid);
251 
252 		/* look ahead bytes are valid, copy them over */
253 		memcpy((u8 *)next_lookaheads, report->lookahead, 4);
254 
255 		*next_lookaheads_len = 1;
256 	}
257 
258 	return 0;
259 }
260 
261 static int
262 ath10k_htc_process_lookahead_bundle(struct ath10k_htc *htc,
263 				    const struct ath10k_htc_lookahead_bundle *report,
264 				    int len,
265 				    enum ath10k_htc_ep_id eid,
266 				    void *next_lookaheads,
267 				    int *next_lookaheads_len)
268 {
269 	struct ath10k *ar = htc->ar;
270 	int bundle_cnt = len / sizeof(*report);
271 
272 	if (!bundle_cnt || (bundle_cnt > HTC_HOST_MAX_MSG_PER_RX_BUNDLE)) {
273 		ath10k_warn(ar, "Invalid lookahead bundle count: %d\n",
274 			    bundle_cnt);
275 		return -EINVAL;
276 	}
277 
278 	if (next_lookaheads && next_lookaheads_len) {
279 		int i;
280 
281 		for (i = 0; i < bundle_cnt; i++) {
282 			memcpy(((u8 *)next_lookaheads) + 4 * i,
283 			       report->lookahead, 4);
284 			report++;
285 		}
286 
287 		*next_lookaheads_len = bundle_cnt;
288 	}
289 
290 	return 0;
291 }
292 
293 int ath10k_htc_process_trailer(struct ath10k_htc *htc,
294 			       u8 *buffer,
295 			       int length,
296 			       enum ath10k_htc_ep_id src_eid,
297 			       void *next_lookaheads,
298 			       int *next_lookaheads_len)
299 {
300 	struct ath10k_htc_lookahead_bundle *bundle;
301 	struct ath10k *ar = htc->ar;
302 	int status = 0;
303 	struct ath10k_htc_record *record;
304 	u8 *orig_buffer;
305 	int orig_length;
306 	size_t len;
307 
308 	orig_buffer = buffer;
309 	orig_length = length;
310 
311 	while (length > 0) {
312 		record = (struct ath10k_htc_record *)buffer;
313 
314 		if (length < sizeof(record->hdr)) {
315 			status = -EINVAL;
316 			break;
317 		}
318 
319 		if (record->hdr.len > length) {
320 			/* no room left in buffer for record */
321 			ath10k_warn(ar, "Invalid record length: %d\n",
322 				    record->hdr.len);
323 			status = -EINVAL;
324 			break;
325 		}
326 
327 		switch (record->hdr.id) {
328 		case ATH10K_HTC_RECORD_CREDITS:
329 			len = sizeof(struct ath10k_htc_credit_report);
330 			if (record->hdr.len < len) {
331 				ath10k_warn(ar, "Credit report too long\n");
332 				status = -EINVAL;
333 				break;
334 			}
335 			ath10k_htc_process_credit_report(htc,
336 							 record->credit_report,
337 							 record->hdr.len,
338 							 src_eid);
339 			break;
340 		case ATH10K_HTC_RECORD_LOOKAHEAD:
341 			len = sizeof(struct ath10k_htc_lookahead_report);
342 			if (record->hdr.len < len) {
343 				ath10k_warn(ar, "Lookahead report too long\n");
344 				status = -EINVAL;
345 				break;
346 			}
347 			status = ath10k_htc_process_lookahead(htc,
348 							      record->lookahead_report,
349 							      record->hdr.len,
350 							      src_eid,
351 							      next_lookaheads,
352 							      next_lookaheads_len);
353 			break;
354 		case ATH10K_HTC_RECORD_LOOKAHEAD_BUNDLE:
355 			bundle = record->lookahead_bundle;
356 			status = ath10k_htc_process_lookahead_bundle(htc,
357 								     bundle,
358 								     record->hdr.len,
359 								     src_eid,
360 								     next_lookaheads,
361 								     next_lookaheads_len);
362 			break;
363 		default:
364 			ath10k_warn(ar, "Unhandled record: id:%d length:%d\n",
365 				    record->hdr.id, record->hdr.len);
366 			break;
367 		}
368 
369 		if (status)
370 			break;
371 
372 		/* multiple records may be present in a trailer */
373 		buffer += sizeof(record->hdr) + record->hdr.len;
374 		length -= sizeof(record->hdr) + record->hdr.len;
375 	}
376 
377 	if (status)
378 		ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc rx bad trailer", "",
379 				orig_buffer, orig_length);
380 
381 	return status;
382 }
383 EXPORT_SYMBOL(ath10k_htc_process_trailer);
384 
385 void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
386 {
387 	int status = 0;
388 	struct ath10k_htc *htc = &ar->htc;
389 	struct ath10k_htc_hdr *hdr;
390 	struct ath10k_htc_ep *ep;
391 	u16 payload_len;
392 	u32 trailer_len = 0;
393 	size_t min_len;
394 	u8 eid;
395 	bool trailer_present;
396 
397 	hdr = (struct ath10k_htc_hdr *)skb->data;
398 	skb_pull(skb, sizeof(*hdr));
399 
400 	eid = hdr->eid;
401 
402 	if (eid >= ATH10K_HTC_EP_COUNT) {
403 		ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid);
404 		ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "",
405 				hdr, sizeof(*hdr));
406 		goto out;
407 	}
408 
409 	ep = &htc->endpoint[eid];
410 
411 	payload_len = __le16_to_cpu(hdr->len);
412 
413 	if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
414 		ath10k_warn(ar, "HTC rx frame too long, len: %zu\n",
415 			    payload_len + sizeof(*hdr));
416 		ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "",
417 				hdr, sizeof(*hdr));
418 		goto out;
419 	}
420 
421 	if (skb->len < payload_len) {
422 		ath10k_dbg(ar, ATH10K_DBG_HTC,
423 			   "HTC Rx: insufficient length, got %d, expected %d\n",
424 			   skb->len, payload_len);
425 		ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len",
426 				"", hdr, sizeof(*hdr));
427 		goto out;
428 	}
429 
430 	/* get flags to check for trailer */
431 	trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
432 	if (trailer_present) {
433 		u8 *trailer;
434 
435 		trailer_len = hdr->trailer_len;
436 		min_len = sizeof(struct ath10k_ath10k_htc_record_hdr);
437 
438 		if ((trailer_len < min_len) ||
439 		    (trailer_len > payload_len)) {
440 			ath10k_warn(ar, "Invalid trailer length: %d\n",
441 				    trailer_len);
442 			goto out;
443 		}
444 
445 		trailer = (u8 *)hdr;
446 		trailer += sizeof(*hdr);
447 		trailer += payload_len;
448 		trailer -= trailer_len;
449 		status = ath10k_htc_process_trailer(htc, trailer,
450 						    trailer_len, hdr->eid,
451 						    NULL, NULL);
452 		if (status)
453 			goto out;
454 
455 		skb_trim(skb, skb->len - trailer_len);
456 	}
457 
458 	if (((int)payload_len - (int)trailer_len) <= 0)
459 		/* zero length packet with trailer data, just drop these */
460 		goto out;
461 
462 	ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %pK\n",
463 		   eid, skb);
464 	ep->ep_ops.ep_rx_complete(ar, skb);
465 
466 	/* skb is now owned by the rx completion handler */
467 	skb = NULL;
468 out:
469 	kfree_skb(skb);
470 }
471 EXPORT_SYMBOL(ath10k_htc_rx_completion_handler);
472 
473 static void ath10k_htc_control_rx_complete(struct ath10k *ar,
474 					   struct sk_buff *skb)
475 {
476 	struct ath10k_htc *htc = &ar->htc;
477 	struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
478 
479 	switch (__le16_to_cpu(msg->hdr.message_id)) {
480 	case ATH10K_HTC_MSG_READY_ID:
481 	case ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID:
482 		/* handle HTC control message */
483 		if (completion_done(&htc->ctl_resp)) {
484 			/* this is a fatal error, target should not be
485 			 * sending unsolicited messages on the ep 0
486 			 */
487 			ath10k_warn(ar, "HTC rx ctrl still processing\n");
488 			complete(&htc->ctl_resp);
489 			goto out;
490 		}
491 
492 		htc->control_resp_len =
493 			min_t(int, skb->len,
494 			      ATH10K_HTC_MAX_CTRL_MSG_LEN);
495 
496 		memcpy(htc->control_resp_buffer, skb->data,
497 		       htc->control_resp_len);
498 
499 		complete(&htc->ctl_resp);
500 		break;
501 	case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
502 		htc->htc_ops.target_send_suspend_complete(ar);
503 		break;
504 	default:
505 		ath10k_warn(ar, "ignoring unsolicited htc ep0 event\n");
506 		break;
507 	}
508 
509 out:
510 	kfree_skb(skb);
511 }
512 
513 /***************/
514 /* Init/Deinit */
515 /***************/
516 
517 static const char *htc_service_name(enum ath10k_htc_svc_id id)
518 {
519 	switch (id) {
520 	case ATH10K_HTC_SVC_ID_RESERVED:
521 		return "Reserved";
522 	case ATH10K_HTC_SVC_ID_RSVD_CTRL:
523 		return "Control";
524 	case ATH10K_HTC_SVC_ID_WMI_CONTROL:
525 		return "WMI";
526 	case ATH10K_HTC_SVC_ID_WMI_DATA_BE:
527 		return "DATA BE";
528 	case ATH10K_HTC_SVC_ID_WMI_DATA_BK:
529 		return "DATA BK";
530 	case ATH10K_HTC_SVC_ID_WMI_DATA_VI:
531 		return "DATA VI";
532 	case ATH10K_HTC_SVC_ID_WMI_DATA_VO:
533 		return "DATA VO";
534 	case ATH10K_HTC_SVC_ID_NMI_CONTROL:
535 		return "NMI Control";
536 	case ATH10K_HTC_SVC_ID_NMI_DATA:
537 		return "NMI Data";
538 	case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
539 		return "HTT Data";
540 	case ATH10K_HTC_SVC_ID_HTT_DATA2_MSG:
541 		return "HTT Data";
542 	case ATH10K_HTC_SVC_ID_HTT_DATA3_MSG:
543 		return "HTT Data";
544 	case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
545 		return "RAW";
546 	case ATH10K_HTC_SVC_ID_HTT_LOG_MSG:
547 		return "PKTLOG";
548 	}
549 
550 	return "Unknown";
551 }
552 
553 static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
554 {
555 	struct ath10k_htc_ep *ep;
556 	int i;
557 
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;
563 		ep->eid = i;
564 		ep->htc = htc;
565 		ep->tx_credit_flow_enabled = true;
566 	}
567 }
568 
569 static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
570 					   u16 service_id)
571 {
572 	u8 allocation = 0;
573 
574 	/* The WMI control service is the only service with flow control.
575 	 * Let it have all transmit credits.
576 	 */
577 	if (service_id == ATH10K_HTC_SVC_ID_WMI_CONTROL)
578 		allocation = htc->total_transmit_credits;
579 
580 	return allocation;
581 }
582 
583 int ath10k_htc_wait_target(struct ath10k_htc *htc)
584 {
585 	struct ath10k *ar = htc->ar;
586 	int i, status = 0;
587 	unsigned long time_left;
588 	struct ath10k_htc_msg *msg;
589 	u16 message_id;
590 
591 	time_left = wait_for_completion_timeout(&htc->ctl_resp,
592 						ATH10K_HTC_WAIT_TIMEOUT_HZ);
593 	if (!time_left) {
594 		/* Workaround: In some cases the PCI HIF doesn't
595 		 * receive interrupt for the control response message
596 		 * even if the buffer was completed. It is suspected
597 		 * iomap writes unmasking PCI CE irqs aren't propagated
598 		 * properly in KVM PCI-passthrough sometimes.
599 		 */
600 		ath10k_warn(ar, "failed to receive control response completion, polling..\n");
601 
602 		for (i = 0; i < CE_COUNT; i++)
603 			ath10k_hif_send_complete_check(htc->ar, i, 1);
604 
605 		time_left =
606 		wait_for_completion_timeout(&htc->ctl_resp,
607 					    ATH10K_HTC_WAIT_TIMEOUT_HZ);
608 
609 		if (!time_left)
610 			status = -ETIMEDOUT;
611 	}
612 
613 	if (status < 0) {
614 		ath10k_err(ar, "ctl_resp never came in (%d)\n", status);
615 		return status;
616 	}
617 
618 	if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
619 		ath10k_err(ar, "Invalid HTC ready msg len:%d\n",
620 			   htc->control_resp_len);
621 		return -ECOMM;
622 	}
623 
624 	msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
625 	message_id   = __le16_to_cpu(msg->hdr.message_id);
626 
627 	if (message_id != ATH10K_HTC_MSG_READY_ID) {
628 		ath10k_err(ar, "Invalid HTC ready msg: 0x%x\n", message_id);
629 		return -ECOMM;
630 	}
631 
632 	htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
633 	htc->target_credit_size = __le16_to_cpu(msg->ready.credit_size);
634 
635 	ath10k_dbg(ar, ATH10K_DBG_HTC,
636 		   "Target ready! transmit resources: %d size:%d\n",
637 		   htc->total_transmit_credits,
638 		   htc->target_credit_size);
639 
640 	if ((htc->total_transmit_credits == 0) ||
641 	    (htc->target_credit_size == 0)) {
642 		ath10k_err(ar, "Invalid credit size received\n");
643 		return -ECOMM;
644 	}
645 
646 	/* The only way to determine if the ready message is an extended
647 	 * message is from the size.
648 	 */
649 	if (htc->control_resp_len >=
650 	    sizeof(msg->hdr) + sizeof(msg->ready_ext)) {
651 		htc->max_msgs_per_htc_bundle =
652 			min_t(u8, msg->ready_ext.max_msgs_per_htc_bundle,
653 			      HTC_HOST_MAX_MSG_PER_RX_BUNDLE);
654 		ath10k_dbg(ar, ATH10K_DBG_HTC,
655 			   "Extended ready message. RX bundle size: %d\n",
656 			   htc->max_msgs_per_htc_bundle);
657 	}
658 
659 	return 0;
660 }
661 
662 int ath10k_htc_connect_service(struct ath10k_htc *htc,
663 			       struct ath10k_htc_svc_conn_req *conn_req,
664 			       struct ath10k_htc_svc_conn_resp *conn_resp)
665 {
666 	struct ath10k *ar = htc->ar;
667 	struct ath10k_htc_msg *msg;
668 	struct ath10k_htc_conn_svc *req_msg;
669 	struct ath10k_htc_conn_svc_response resp_msg_dummy;
670 	struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy;
671 	enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT;
672 	struct ath10k_htc_ep *ep;
673 	struct sk_buff *skb;
674 	unsigned int max_msg_size = 0;
675 	int length, status;
676 	unsigned long time_left;
677 	bool disable_credit_flow_ctrl = false;
678 	u16 message_id, service_id, flags = 0;
679 	u8 tx_alloc = 0;
680 
681 	/* special case for HTC pseudo control service */
682 	if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) {
683 		disable_credit_flow_ctrl = true;
684 		assigned_eid = ATH10K_HTC_EP_0;
685 		max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN;
686 		memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy));
687 		goto setup;
688 	}
689 
690 	tx_alloc = ath10k_htc_get_credit_allocation(htc,
691 						    conn_req->service_id);
692 	if (!tx_alloc)
693 		ath10k_dbg(ar, ATH10K_DBG_BOOT,
694 			   "boot htc service %s does not allocate target credits\n",
695 			   htc_service_name(conn_req->service_id));
696 
697 	skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
698 	if (!skb) {
699 		ath10k_err(ar, "Failed to allocate HTC packet\n");
700 		return -ENOMEM;
701 	}
702 
703 	length = sizeof(msg->hdr) + sizeof(msg->connect_service);
704 	skb_put(skb, length);
705 	memset(skb->data, 0, length);
706 
707 	msg = (struct ath10k_htc_msg *)skb->data;
708 	msg->hdr.message_id =
709 		__cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID);
710 
711 	flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC);
712 
713 	/* Only enable credit flow control for WMI ctrl service */
714 	if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) {
715 		flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
716 		disable_credit_flow_ctrl = true;
717 	}
718 
719 	req_msg = &msg->connect_service;
720 	req_msg->flags = __cpu_to_le16(flags);
721 	req_msg->service_id = __cpu_to_le16(conn_req->service_id);
722 
723 	reinit_completion(&htc->ctl_resp);
724 
725 	status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
726 	if (status) {
727 		kfree_skb(skb);
728 		return status;
729 	}
730 
731 	/* wait for response */
732 	time_left = wait_for_completion_timeout(&htc->ctl_resp,
733 						ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
734 	if (!time_left) {
735 		ath10k_err(ar, "Service connect timeout\n");
736 		return -ETIMEDOUT;
737 	}
738 
739 	/* we controlled the buffer creation, it's aligned */
740 	msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
741 	resp_msg = &msg->connect_service_response;
742 	message_id = __le16_to_cpu(msg->hdr.message_id);
743 	service_id = __le16_to_cpu(resp_msg->service_id);
744 
745 	if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) ||
746 	    (htc->control_resp_len < sizeof(msg->hdr) +
747 	     sizeof(msg->connect_service_response))) {
748 		ath10k_err(ar, "Invalid resp message ID 0x%x", message_id);
749 		return -EPROTO;
750 	}
751 
752 	ath10k_dbg(ar, ATH10K_DBG_HTC,
753 		   "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n",
754 		   htc_service_name(service_id),
755 		   resp_msg->status, resp_msg->eid);
756 
757 	conn_resp->connect_resp_code = resp_msg->status;
758 
759 	/* check response status */
760 	if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) {
761 		ath10k_err(ar, "HTC Service %s connect request failed: 0x%x)\n",
762 			   htc_service_name(service_id),
763 			   resp_msg->status);
764 		return -EPROTO;
765 	}
766 
767 	assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid;
768 	max_msg_size = __le16_to_cpu(resp_msg->max_msg_size);
769 
770 setup:
771 
772 	if (assigned_eid >= ATH10K_HTC_EP_COUNT)
773 		return -EPROTO;
774 
775 	if (max_msg_size == 0)
776 		return -EPROTO;
777 
778 	ep = &htc->endpoint[assigned_eid];
779 	ep->eid = assigned_eid;
780 
781 	if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED)
782 		return -EPROTO;
783 
784 	/* return assigned endpoint to caller */
785 	conn_resp->eid = assigned_eid;
786 	conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size);
787 
788 	/* setup the endpoint */
789 	ep->service_id = conn_req->service_id;
790 	ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
791 	ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
792 	ep->tx_credits = tx_alloc;
793 
794 	/* copy all the callbacks */
795 	ep->ep_ops = conn_req->ep_ops;
796 
797 	status = ath10k_hif_map_service_to_pipe(htc->ar,
798 						ep->service_id,
799 						&ep->ul_pipe_id,
800 						&ep->dl_pipe_id);
801 	if (status) {
802 		ath10k_warn(ar, "unsupported HTC service id: %d\n",
803 			    ep->service_id);
804 		return status;
805 	}
806 
807 	ath10k_dbg(ar, ATH10K_DBG_BOOT,
808 		   "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n",
809 		   htc_service_name(ep->service_id), ep->ul_pipe_id,
810 		   ep->dl_pipe_id, ep->eid);
811 
812 	if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
813 		ep->tx_credit_flow_enabled = false;
814 		ath10k_dbg(ar, ATH10K_DBG_BOOT,
815 			   "boot htc service '%s' eid %d TX flow control disabled\n",
816 			   htc_service_name(ep->service_id), assigned_eid);
817 	}
818 
819 	return status;
820 }
821 
822 struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size)
823 {
824 	struct sk_buff *skb;
825 
826 	skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
827 	if (!skb)
828 		return NULL;
829 
830 	skb_reserve(skb, sizeof(struct ath10k_htc_hdr));
831 
832 	/* FW/HTC requires 4-byte aligned streams */
833 	if (!IS_ALIGNED((unsigned long)skb->data, 4))
834 		ath10k_warn(ar, "Unaligned HTC tx skb\n");
835 
836 	return skb;
837 }
838 
839 static void ath10k_htc_pktlog_process_rx(struct ath10k *ar, struct sk_buff *skb)
840 {
841 	trace_ath10k_htt_pktlog(ar, skb->data, skb->len);
842 	dev_kfree_skb_any(skb);
843 }
844 
845 static int ath10k_htc_pktlog_connect(struct ath10k *ar)
846 {
847 	struct ath10k_htc_svc_conn_resp conn_resp;
848 	struct ath10k_htc_svc_conn_req conn_req;
849 	int status;
850 
851 	memset(&conn_req, 0, sizeof(conn_req));
852 	memset(&conn_resp, 0, sizeof(conn_resp));
853 
854 	conn_req.ep_ops.ep_tx_complete = NULL;
855 	conn_req.ep_ops.ep_rx_complete = ath10k_htc_pktlog_process_rx;
856 	conn_req.ep_ops.ep_tx_credits = NULL;
857 
858 	/* connect to control service */
859 	conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_LOG_MSG;
860 	status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp);
861 	if (status) {
862 		ath10k_warn(ar, "failed to connect to PKTLOG service: %d\n",
863 			    status);
864 		return status;
865 	}
866 
867 	return 0;
868 }
869 
870 static bool ath10k_htc_pktlog_svc_supported(struct ath10k *ar)
871 {
872 	u8 ul_pipe_id;
873 	u8 dl_pipe_id;
874 	int status;
875 
876 	status = ath10k_hif_map_service_to_pipe(ar, ATH10K_HTC_SVC_ID_HTT_LOG_MSG,
877 						&ul_pipe_id,
878 						&dl_pipe_id);
879 	if (status) {
880 		ath10k_warn(ar, "unsupported HTC service id: %d\n",
881 			    ATH10K_HTC_SVC_ID_HTT_LOG_MSG);
882 
883 		return false;
884 	}
885 
886 	return true;
887 }
888 
889 int ath10k_htc_start(struct ath10k_htc *htc)
890 {
891 	struct ath10k *ar = htc->ar;
892 	struct sk_buff *skb;
893 	int status = 0;
894 	struct ath10k_htc_msg *msg;
895 
896 	skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
897 	if (!skb)
898 		return -ENOMEM;
899 
900 	skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext));
901 	memset(skb->data, 0, skb->len);
902 
903 	msg = (struct ath10k_htc_msg *)skb->data;
904 	msg->hdr.message_id =
905 		__cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID);
906 
907 	if (ar->hif.bus == ATH10K_BUS_SDIO) {
908 		/* Extra setup params used by SDIO */
909 		msg->setup_complete_ext.flags =
910 			__cpu_to_le32(ATH10K_HTC_SETUP_COMPLETE_FLAGS_RX_BNDL_EN);
911 		msg->setup_complete_ext.max_msgs_per_bundled_recv =
912 			htc->max_msgs_per_htc_bundle;
913 	}
914 	ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
915 
916 	status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
917 	if (status) {
918 		kfree_skb(skb);
919 		return status;
920 	}
921 
922 	if (ath10k_htc_pktlog_svc_supported(ar)) {
923 		status = ath10k_htc_pktlog_connect(ar);
924 		if (status) {
925 			ath10k_err(ar, "failed to connect to pktlog: %d\n", status);
926 			return status;
927 		}
928 	}
929 
930 	return 0;
931 }
932 
933 /* registered target arrival callback from the HIF layer */
934 int ath10k_htc_init(struct ath10k *ar)
935 {
936 	int status;
937 	struct ath10k_htc *htc = &ar->htc;
938 	struct ath10k_htc_svc_conn_req conn_req;
939 	struct ath10k_htc_svc_conn_resp conn_resp;
940 
941 	spin_lock_init(&htc->tx_lock);
942 
943 	ath10k_htc_reset_endpoint_states(htc);
944 
945 	htc->ar = ar;
946 
947 	/* setup our pseudo HTC control endpoint connection */
948 	memset(&conn_req, 0, sizeof(conn_req));
949 	memset(&conn_resp, 0, sizeof(conn_resp));
950 	conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
951 	conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
952 	conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
953 	conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
954 
955 	/* connect fake service */
956 	status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
957 	if (status) {
958 		ath10k_err(ar, "could not connect to htc service (%d)\n",
959 			   status);
960 		return status;
961 	}
962 
963 	init_completion(&htc->ctl_resp);
964 
965 	return 0;
966 }
967