xref: /wlan-dirver/qca-wifi-host-cmn/htc/htc.c (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
1 /*
2  * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "htc_debug.h"
20 #include "htc_internal.h"
21 #include "htc_credit_history.h"
22 #include "htc_hang_event.h"
23 #include <hif.h>
24 #include <qdf_nbuf.h>           /* qdf_nbuf_t */
25 #include <qdf_types.h>          /* qdf_print */
26 
27 #define MAX_HTC_RX_BUNDLE  2
28 
29 #if defined(WLAN_DEBUG) || defined(DEBUG)
30 static ATH_DEBUG_MASK_DESCRIPTION g_htc_debug_description[] = {
31 	{ATH_DEBUG_SEND, "Send"},
32 	{ATH_DEBUG_RECV, "Recv"},
33 	{ATH_DEBUG_SYNC, "Sync"},
34 	{ATH_DEBUG_DUMP, "Dump Data (RX or TX)"},
35 	{ATH_DEBUG_SETUP, "Setup"},
36 };
37 
38 ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
39 				 "htc",
40 				 "Host Target Communications",
41 				 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO |
42 				 ATH_DEBUG_SETUP,
43 				 ATH_DEBUG_DESCRIPTION_COUNT
44 					 (g_htc_debug_description),
45 				 g_htc_debug_description);
46 
47 #endif
48 
49 #if (defined(WMI_MULTI_MAC_SVC) || defined(QCA_WIFI_QCA8074) || \
50 	defined(QCA_WIFI_QCA6018))
51 static const uint32_t svc_id[] = {WMI_CONTROL_SVC, WMI_CONTROL_SVC_WMAC1,
52 						WMI_CONTROL_SVC_WMAC2};
53 #else
54 static const uint32_t svc_id[] = {WMI_CONTROL_SVC};
55 #endif
56 
57 extern unsigned int htc_credit_flow;
58 
59 static void reset_endpoint_states(HTC_TARGET *target);
60 
61 static void destroy_htc_tx_ctrl_packet(HTC_PACKET *pPacket)
62 {
63 	qdf_nbuf_t netbuf;
64 
65 	netbuf = (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
66 	if (netbuf)
67 		qdf_nbuf_free(netbuf);
68 	qdf_mem_free(pPacket);
69 }
70 
71 static HTC_PACKET *build_htc_tx_ctrl_packet(qdf_device_t osdev)
72 {
73 	HTC_PACKET *pPacket = NULL;
74 	qdf_nbuf_t netbuf;
75 
76 	do {
77 		pPacket = (HTC_PACKET *) qdf_mem_malloc(sizeof(HTC_PACKET));
78 		if (!pPacket)
79 			break;
80 		netbuf = qdf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE,
81 					20, 4, true);
82 		if (!netbuf) {
83 			qdf_mem_free(pPacket);
84 			pPacket = NULL;
85 			break;
86 		}
87 		SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
88 	} while (false);
89 
90 	return pPacket;
91 }
92 
93 void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket)
94 {
95 
96 #ifdef TODO_FIXME
97 	LOCK_HTC(target);
98 	HTC_PACKET_ENQUEUE(&target->ControlBufferTXFreeList, pPacket);
99 	UNLOCK_HTC(target);
100 	/* TODO_FIXME netbufs cannot be RESET! */
101 #else
102 	destroy_htc_tx_ctrl_packet(pPacket);
103 #endif
104 
105 }
106 
107 HTC_PACKET *htc_alloc_control_tx_packet(HTC_TARGET *target)
108 {
109 #ifdef TODO_FIXME
110 	HTC_PACKET *pPacket;
111 
112 	LOCK_HTC(target);
113 	pPacket = htc_packet_dequeue(&target->ControlBufferTXFreeList);
114 	UNLOCK_HTC(target);
115 
116 	return pPacket;
117 #else
118 	return build_htc_tx_ctrl_packet(target->osdev);
119 #endif
120 }
121 
122 /* Set the target failure handling callback */
123 void htc_set_target_failure_callback(HTC_HANDLE HTCHandle,
124 				     HTC_TARGET_FAILURE Callback)
125 {
126 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
127 
128 	target->HTCInitInfo.TargetFailure = Callback;
129 }
130 
131 void htc_dump(HTC_HANDLE HTCHandle, uint8_t CmdId, bool start)
132 {
133 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
134 
135 	hif_dump(target->hif_dev, CmdId, start);
136 }
137 
138 void htc_ce_tasklet_debug_dump(HTC_HANDLE htc_handle)
139 {
140 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
141 
142 	if (!target->hif_dev)
143 		return;
144 
145 	hif_display_stats(target->hif_dev);
146 }
147 
148 /* cleanup the HTC instance */
149 static void htc_cleanup(HTC_TARGET *target)
150 {
151 	HTC_PACKET *pPacket;
152 	int i;
153 	HTC_ENDPOINT *endpoint;
154 	HTC_PACKET_QUEUE *pkt_queue;
155 	qdf_nbuf_t netbuf;
156 
157 	if (target->hif_dev) {
158 		hif_detach_htc(target->hif_dev);
159 		hif_mask_interrupt_call(target->hif_dev);
160 		target->hif_dev = NULL;
161 	}
162 
163 	while (true) {
164 		pPacket = allocate_htc_packet_container(target);
165 		if (!pPacket)
166 			break;
167 		qdf_mem_free(pPacket);
168 	}
169 
170 	LOCK_HTC_TX(target);
171 	pPacket = target->pBundleFreeList;
172 	target->pBundleFreeList = NULL;
173 	UNLOCK_HTC_TX(target);
174 	while (pPacket) {
175 		HTC_PACKET *pPacketTmp = (HTC_PACKET *) pPacket->ListLink.pNext;
176 		netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
177 		if (netbuf)
178 			qdf_nbuf_free(netbuf);
179 		pkt_queue = pPacket->pContext;
180 		if (pkt_queue)
181 			qdf_mem_free(pkt_queue);
182 		qdf_mem_free(pPacket);
183 		pPacket = pPacketTmp;
184 	}
185 
186 #ifdef TODO_FIXME
187 	while (true) {
188 		pPacket = htc_alloc_control_tx_packet(target);
189 		if (!pPacket)
190 			break;
191 		netbuf = (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
192 		if (netbuf)
193 			qdf_nbuf_free(netbuf);
194 		qdf_mem_free(pPacket);
195 	}
196 #endif
197 
198 	htc_flush_endpoint_txlookupQ(target, ENDPOINT_0, true);
199 
200 	qdf_spinlock_destroy(&target->HTCLock);
201 	qdf_spinlock_destroy(&target->HTCRxLock);
202 	qdf_spinlock_destroy(&target->HTCTxLock);
203 	for (i = 0; i < ENDPOINT_MAX; i++) {
204 		endpoint = &target->endpoint[i];
205 		qdf_spinlock_destroy(&endpoint->lookup_queue_lock);
206 	}
207 
208 	/* free our instance */
209 	qdf_mem_free(target);
210 }
211 
212 #ifdef FEATURE_RUNTIME_PM
213 /**
214  * htc_runtime_pm_init(): runtime pm related intialization
215  *
216  * need to initialize a work item.
217  */
218 static void htc_runtime_pm_init(HTC_TARGET *target)
219 {
220 	qdf_create_work(0, &target->queue_kicker, htc_kick_queues, target);
221 }
222 
223 /**
224  * htc_runtime_suspend() - runtime suspend HTC
225  *
226  * @htc_ctx: HTC context pointer
227  *
228  * This is a dummy function for symmetry.
229  *
230  * Return: 0 for success
231  */
232 int htc_runtime_suspend(HTC_HANDLE htc_ctx)
233 {
234 	return 0;
235 }
236 
237 /**
238  * htc_runtime_resume(): resume htc
239  *
240  * The htc message queue needs to be kicked off after
241  * a runtime resume.  Otherwise messages would get stuck.
242  *
243  * @htc_ctx: HTC context pointer
244  *
245  * Return: 0 for success;
246  */
247 int htc_runtime_resume(HTC_HANDLE htc_ctx)
248 {
249 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_ctx);
250 
251 	if (!target)
252 		return 0;
253 
254 	qdf_sched_work(0, &target->queue_kicker);
255 	return 0;
256 }
257 
258 /**
259  * htc_runtime_pm_deinit(): runtime pm related de-intialization
260  *
261  * need to de-initialize the work item.
262  *
263  * @target: HTC target pointer
264  *
265  */
266 static void htc_runtime_pm_deinit(HTC_TARGET *target)
267 {
268 	if (!target)
269 		return;
270 
271 	qdf_destroy_work(0, &target->queue_kicker);
272 }
273 
274 #else
275 static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
276 static inline void htc_runtime_pm_deinit(HTC_TARGET *target) { }
277 #endif
278 
279 #if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
280 static
281 void htc_update_rx_bundle_stats(void *ctx, uint8_t no_of_pkt_in_bundle)
282 {
283 	HTC_TARGET *target = (HTC_TARGET *)ctx;
284 
285 	no_of_pkt_in_bundle--;
286 	if (target && (no_of_pkt_in_bundle < HTC_MAX_MSG_PER_BUNDLE_RX))
287 		target->rx_bundle_stats[no_of_pkt_in_bundle]++;
288 }
289 #else
290 static
291 void htc_update_rx_bundle_stats(void *ctx, uint8_t no_of_pkt_in_bundle)
292 {
293 }
294 #endif
295 
296 /* registered target arrival callback from the HIF layer */
297 HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo,
298 			qdf_device_t osdev, uint32_t con_mode)
299 {
300 	struct hif_msg_callbacks htcCallbacks;
301 	HTC_ENDPOINT *pEndpoint = NULL;
302 	HTC_TARGET *target = NULL;
303 	int i;
304 
305 	if (!ol_sc) {
306 		HTC_ERROR("%s: ol_sc = NULL", __func__);
307 		return NULL;
308 	}
309 	HTC_TRACE("+htc_create ..  HIF :%pK", ol_sc);
310 
311 	A_REGISTER_MODULE_DEBUG_INFO(htc);
312 
313 	target = (HTC_TARGET *) qdf_mem_malloc(sizeof(HTC_TARGET));
314 	if (!target)
315 		return NULL;
316 
317 	htc_runtime_pm_init(target);
318 	htc_credit_history_init();
319 	qdf_spinlock_create(&target->HTCLock);
320 	qdf_spinlock_create(&target->HTCRxLock);
321 	qdf_spinlock_create(&target->HTCTxLock);
322 	for (i = 0; i < ENDPOINT_MAX; i++) {
323 		pEndpoint = &target->endpoint[i];
324 		qdf_spinlock_create(&pEndpoint->lookup_queue_lock);
325 	}
326 	target->is_nodrop_pkt = false;
327 	target->htc_hdr_length_check = false;
328 	target->wmi_ep_count = 1;
329 
330 	do {
331 		qdf_mem_copy(&target->HTCInitInfo, pInfo,
332 			     sizeof(struct htc_init_info));
333 		target->host_handle = pInfo->pContext;
334 		target->osdev = osdev;
335 		target->con_mode = con_mode;
336 
337 		reset_endpoint_states(target);
338 
339 		INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
340 
341 		for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
342 			HTC_PACKET *pPacket = (HTC_PACKET *)
343 					qdf_mem_malloc(sizeof(HTC_PACKET));
344 			if (pPacket)
345 				free_htc_packet_container(target, pPacket);
346 		}
347 
348 #ifdef TODO_FIXME
349 		for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
350 			pPacket = build_htc_tx_ctrl_packet();
351 			if (!pPacket)
352 				break;
353 			htc_free_control_tx_packet(target, pPacket);
354 		}
355 #endif
356 
357 		/* setup HIF layer callbacks */
358 		qdf_mem_zero(&htcCallbacks, sizeof(struct hif_msg_callbacks));
359 		htcCallbacks.Context = target;
360 		htcCallbacks.rxCompletionHandler = htc_rx_completion_handler;
361 		htcCallbacks.txCompletionHandler = htc_tx_completion_handler;
362 		htcCallbacks.txResourceAvailHandler =
363 						 htc_tx_resource_avail_handler;
364 		htcCallbacks.fwEventHandler = htc_fw_event_handler;
365 		htcCallbacks.update_bundle_stats = htc_update_rx_bundle_stats;
366 		target->hif_dev = ol_sc;
367 
368 		/* Get HIF default pipe for HTC message exchange */
369 		pEndpoint = &target->endpoint[ENDPOINT_0];
370 
371 		hif_post_init(target->hif_dev, target, &htcCallbacks);
372 		hif_get_default_pipe(target->hif_dev, &pEndpoint->UL_PipeID,
373 				     &pEndpoint->DL_PipeID);
374 		hif_set_initial_wakeup_cb(target->hif_dev,
375 					  pInfo->target_initial_wakeup_cb,
376 					  pInfo->target_psoc);
377 
378 	} while (false);
379 
380 	htc_recv_init(target);
381 
382 	HTC_TRACE("-htc_create: (0x%pK)", target);
383 
384 	htc_hang_event_notifier_register(target);
385 
386 	return (HTC_HANDLE) target;
387 }
388 
389 void htc_destroy(HTC_HANDLE HTCHandle)
390 {
391 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
392 
393 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
394 			("+htc_destroy ..  Destroying :0x%pK\n", target));
395 	htc_hang_event_notifier_unregister();
396 	hif_stop(htc_get_hif_device(HTCHandle));
397 	if (target)
398 		htc_cleanup(target);
399 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n"));
400 }
401 
402 /* get the low level HIF device for the caller , the caller may wish to do low
403  * level HIF requests
404  */
405 void *htc_get_hif_device(HTC_HANDLE HTCHandle)
406 {
407 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
408 
409 	return target->hif_dev;
410 }
411 
412 static void htc_control_tx_complete(void *Context, HTC_PACKET *pPacket)
413 {
414 	HTC_TARGET *target = (HTC_TARGET *) Context;
415 
416 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
417 			("+-htc_control_tx_complete 0x%pK (l:%d)\n", pPacket,
418 			 pPacket->ActualLength));
419 	htc_free_control_tx_packet(target, pPacket);
420 }
421 
422 /* TODO, this is just a temporary max packet size */
423 #define MAX_MESSAGE_SIZE 1536
424 
425 /**
426  * htc_setup_epping_credit_allocation() - allocate credits/HTC buffers to WMI
427  * @scn: pointer to hif_opaque_softc
428  * @pEntry: pointer to tx credit allocation entry
429  * @credits: number of credits
430  *
431  * Return: None
432  */
433 static void
434 htc_setup_epping_credit_allocation(struct hif_opaque_softc *scn,
435 			   struct htc_service_tx_credit_allocation *pEntry,
436 			   int credits)
437 {
438 	switch (hif_get_bus_type(scn)) {
439 	case QDF_BUS_TYPE_PCI:
440 	case QDF_BUS_TYPE_USB:
441 		pEntry++;
442 		pEntry->service_id = WMI_DATA_BE_SVC;
443 		pEntry->CreditAllocation = (credits >> 1);
444 
445 		pEntry++;
446 		pEntry->service_id = WMI_DATA_BK_SVC;
447 		pEntry->CreditAllocation = (credits >> 1);
448 		break;
449 	case QDF_BUS_TYPE_SDIO:
450 		pEntry++;
451 		pEntry->service_id = WMI_DATA_BE_SVC;
452 		pEntry->CreditAllocation = credits;
453 		break;
454 	default:
455 		break;
456 	}
457 }
458 
459 /**
460  * htc_setup_target_buffer_assignments() - setup target buffer assignments
461  * @target: HTC Target Pointer
462  *
463  * Return: A_STATUS
464  */
465 static
466 A_STATUS htc_setup_target_buffer_assignments(HTC_TARGET *target)
467 {
468 	struct htc_service_tx_credit_allocation *pEntry;
469 	A_STATUS status;
470 	int credits;
471 	int creditsPerMaxMsg;
472 
473 	creditsPerMaxMsg = MAX_MESSAGE_SIZE / target->TargetCreditSize;
474 	if (MAX_MESSAGE_SIZE % target->TargetCreditSize)
475 		creditsPerMaxMsg++;
476 
477 	/* TODO, this should be configured by the caller! */
478 
479 	credits = target->TotalTransmitCredits;
480 	pEntry = &target->ServiceTxAllocTable[0];
481 
482 	status = A_OK;
483 	/*
484 	 * Allocate all credists/HTC buffers to WMI.
485 	 * no buffers are used/required for data. data always
486 	 * remains on host.
487 	 */
488 	if (HTC_IS_EPPING_ENABLED(target->con_mode)) {
489 		pEntry++;
490 		pEntry->service_id = WMI_CONTROL_SVC;
491 		pEntry->CreditAllocation = credits;
492 		/* endpoint ping is a testing tool directly on top of HTC in
493 		 * both target and host sides.
494 		 * In target side, the endppint ping fw has no wlan stack and
495 		 * FW mboxping app directly sits on HTC and it simply drops
496 		 * or loops back TX packets. For rx perf, FW mboxping app
497 		 * generates packets and passes packets to HTC to send to host.
498 		 * There is no WMI message exchanges between host and target
499 		 * in endpoint ping case.
500 		 * In host side, the endpoint ping driver is a Ethernet driver
501 		 * and it directly sits on HTC. Only HIF, HTC, QDF, ADF are
502 		 * used by the endpoint ping driver. There is no wifi stack
503 		 * at all in host side also. For tx perf use case,
504 		 * the user space mboxping app sends the raw packets to endpoint
505 		 * ping driver and it directly forwards to HTC for transmission
506 		 * to stress the bus. For the rx perf, HTC passes the received
507 		 * packets to endpoint ping driver and it is passed to the user
508 		 * space through the Ethernet interface.
509 		 * For credit allocation, in SDIO bus case, only BE service is
510 		 * used for tx/rx perf testing so that all credits are given
511 		 * to BE service. In PCIe and USB bus case, endpoint ping uses
512 		 * both BE and BK services to stress the bus so that the total
513 		 * credits are equally distributed to BE and BK services.
514 		 */
515 
516 		htc_setup_epping_credit_allocation(target->hif_dev,
517 						   pEntry, credits);
518 	} else {
519 		int i;
520 		uint32_t max_wmi_svc = (sizeof(svc_id) / sizeof(uint32_t));
521 
522 		if ((target->wmi_ep_count == 0) ||
523 				(target->wmi_ep_count > max_wmi_svc))
524 			return A_ERROR;
525 
526 		/*
527 		 * Divide credit among number of endpoints for WMI
528 		 */
529 		credits = credits / target->wmi_ep_count;
530 		for (i = 0; i < target->wmi_ep_count; i++) {
531 			status = A_OK;
532 			pEntry++;
533 			pEntry->service_id = svc_id[i];
534 			pEntry->CreditAllocation = credits;
535 		}
536 	}
537 
538 	if (A_SUCCESS(status)) {
539 		int i;
540 
541 		for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
542 			if (target->ServiceTxAllocTable[i].service_id != 0) {
543 				AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
544 						("SVS Index : %d TX : 0x%2.2X : alloc:%d",
545 						 i,
546 						 target->ServiceTxAllocTable[i].
547 						 service_id,
548 						 target->ServiceTxAllocTable[i].
549 						 CreditAllocation));
550 			}
551 		}
552 	}
553 
554 	return status;
555 }
556 
557 uint8_t htc_get_credit_allocation(HTC_TARGET *target, uint16_t service_id)
558 {
559 	uint8_t allocation = 0;
560 	int i;
561 
562 	for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
563 		if (target->ServiceTxAllocTable[i].service_id == service_id) {
564 			allocation =
565 				target->ServiceTxAllocTable[i].CreditAllocation;
566 		}
567 	}
568 
569 	if (0 == allocation) {
570 		AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1,
571 			("HTC Service TX : 0x%2.2X : allocation is zero!\n",
572 				 service_id));
573 	}
574 
575 	return allocation;
576 }
577 
578 QDF_STATUS htc_wait_target(HTC_HANDLE HTCHandle)
579 {
580 	QDF_STATUS status = QDF_STATUS_SUCCESS;
581 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
582 	HTC_READY_EX_MSG *pReadyMsg;
583 	struct htc_service_connect_req connect;
584 	struct htc_service_connect_resp resp;
585 	HTC_READY_MSG *rdy_msg;
586 	uint16_t htc_rdy_msg_id;
587 	uint8_t i = 0;
588 	HTC_PACKET *rx_bundle_packet, *temp_bundle_packet;
589 
590 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
591 			("htc_wait_target - Enter (target:0x%pK)\n", HTCHandle));
592 	AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, ("+HWT\n"));
593 
594 	do {
595 
596 		status = hif_start(target->hif_dev);
597 		if (QDF_IS_STATUS_ERROR(status)) {
598 			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
599 					("hif_start failed\n"));
600 			break;
601 		}
602 
603 		status = htc_wait_recv_ctrl_message(target);
604 
605 		if (QDF_IS_STATUS_ERROR(status))
606 			break;
607 
608 		if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
609 			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
610 					("Invalid HTC Ready Msg Len:%d!\n",
611 					 target->CtrlResponseLength));
612 			status = QDF_STATUS_E_BADMSG;
613 			break;
614 		}
615 
616 		pReadyMsg = (HTC_READY_EX_MSG *) target->CtrlResponseBuffer;
617 
618 		rdy_msg = &pReadyMsg->Version2_0_Info;
619 		htc_rdy_msg_id =
620 			HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
621 		if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
622 			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
623 					("Invalid HTC Ready Msg : 0x%X!\n",
624 					 htc_rdy_msg_id));
625 			status = QDF_STATUS_E_BADMSG;
626 			break;
627 		}
628 
629 		target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg,
630 						HTC_READY_MSG, CREDITCOUNT);
631 		if (target->HTCInitInfo.cfg_wmi_credit_cnt &&
632 			(target->HTCInitInfo.cfg_wmi_credit_cnt <
633 						target->TotalTransmitCredits))
634 			/*
635 			 * If INI configured value is less than FW advertised,
636 			 * then use INI configured value, otherwise use FW
637 			 * advertised.
638 			 */
639 			target->TotalTransmitCredits =
640 				target->HTCInitInfo.cfg_wmi_credit_cnt;
641 
642 		target->TargetCreditSize =
643 			(int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);
644 		target->MaxMsgsPerHTCBundle =
645 			(uint8_t) pReadyMsg->MaxMsgsPerHTCBundle;
646 		UPDATE_ALT_CREDIT(target, pReadyMsg->AltDataCreditSize);
647 		/* for old fw this value is set to 0. But the minimum value
648 		 * should be 1, i.e., no bundling
649 		 */
650 		if (target->MaxMsgsPerHTCBundle < 1)
651 			target->MaxMsgsPerHTCBundle = 1;
652 
653 		AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
654 				("Target Ready! TX resource : %d size:%d, MaxMsgsPerHTCBundle = %d",
655 				 target->TotalTransmitCredits,
656 				 target->TargetCreditSize,
657 				 target->MaxMsgsPerHTCBundle));
658 
659 		if ((0 == target->TotalTransmitCredits)
660 		    || (0 == target->TargetCreditSize)) {
661 			status = QDF_STATUS_E_ABORTED;
662 			break;
663 		}
664 
665 		/* Allocate expected number of RX bundle buffer allocation */
666 		if (HTC_RX_BUNDLE_ENABLED(target)) {
667 			temp_bundle_packet = NULL;
668 			for (i = 0; i < MAX_HTC_RX_BUNDLE; i++) {
669 				rx_bundle_packet =
670 					allocate_htc_bundle_packet(target);
671 				if (rx_bundle_packet)
672 					rx_bundle_packet->ListLink.pNext =
673 						(DL_LIST *)temp_bundle_packet;
674 				else
675 					break;
676 
677 				temp_bundle_packet = rx_bundle_packet;
678 			}
679 			LOCK_HTC_TX(target);
680 			target->pBundleFreeList = temp_bundle_packet;
681 			UNLOCK_HTC_TX(target);
682 		}
683 
684 		/* done processing */
685 		target->CtrlResponseProcessing = false;
686 
687 		htc_setup_target_buffer_assignments(target);
688 
689 		/* setup our pseudo HTC control endpoint connection */
690 		qdf_mem_zero(&connect, sizeof(connect));
691 		qdf_mem_zero(&resp, sizeof(resp));
692 		connect.EpCallbacks.pContext = target;
693 		connect.EpCallbacks.EpTxComplete = htc_control_tx_complete;
694 		connect.EpCallbacks.EpRecv = htc_control_rx_complete;
695 		connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
696 		connect.service_id = HTC_CTRL_RSVD_SVC;
697 
698 		/* connect fake service */
699 		status = htc_connect_service((HTC_HANDLE) target,
700 					     &connect, &resp);
701 
702 	} while (false);
703 
704 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Exit (%d)\n",
705 			status));
706 	AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, ("-HWT\n"));
707 	return status;
708 }
709 
710 /* start HTC, this is called after all services are connected */
711 static A_STATUS htc_config_target_hif_pipe(HTC_TARGET *target)
712 {
713 
714 	return A_OK;
715 }
716 
717 static void reset_endpoint_states(HTC_TARGET *target)
718 {
719 	HTC_ENDPOINT *pEndpoint;
720 	int i;
721 
722 	for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
723 		pEndpoint = &target->endpoint[i];
724 		pEndpoint->service_id = 0;
725 		pEndpoint->MaxMsgLength = 0;
726 		pEndpoint->MaxTxQueueDepth = 0;
727 		pEndpoint->Id = i;
728 		INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
729 		INIT_HTC_PACKET_QUEUE(&pEndpoint->TxLookupQueue);
730 		INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBufferHoldQueue);
731 		pEndpoint->target = target;
732 		pEndpoint->TxCreditFlowEnabled = (bool)htc_credit_flow;
733 		pEndpoint->num_requeues_warn = 0;
734 		pEndpoint->total_num_requeues = 0;
735 		qdf_atomic_init(&pEndpoint->TxProcessCount);
736 	}
737 }
738 
739 /**
740  * htc_start() - Main HTC function to trigger HTC start
741  * @HTCHandle: pointer to HTC handle
742  *
743  * Return: QDF_STATUS_SUCCESS for success or an appropriate QDF_STATUS error
744  */
745 QDF_STATUS htc_start(HTC_HANDLE HTCHandle)
746 {
747 	qdf_nbuf_t netbuf;
748 	QDF_STATUS status = QDF_STATUS_SUCCESS;
749 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
750 	HTC_SETUP_COMPLETE_EX_MSG *pSetupComp;
751 	HTC_PACKET *pSendPacket;
752 
753 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Enter\n"));
754 
755 	do {
756 
757 		htc_config_target_hif_pipe(target);
758 
759 		/* allocate a buffer to send */
760 		pSendPacket = htc_alloc_control_tx_packet(target);
761 		if (!pSendPacket) {
762 			AR_DEBUG_ASSERT(false);
763 			qdf_print("%s: allocControlTxPacket failed",
764 				  __func__);
765 			status = QDF_STATUS_E_NOMEM;
766 			break;
767 		}
768 
769 		netbuf =
770 		   (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
771 		/* assemble setup complete message */
772 		qdf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
773 		pSetupComp =
774 			(HTC_SETUP_COMPLETE_EX_MSG *) qdf_nbuf_data(netbuf);
775 		qdf_mem_zero(pSetupComp, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
776 
777 		HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG,
778 			      MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID);
779 
780 		if (!htc_credit_flow) {
781 			AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
782 					("HTC will not use TX credit flow control"));
783 			pSetupComp->SetupFlags |=
784 				HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW;
785 		} else {
786 			AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
787 					("HTC using TX credit flow control"));
788 		}
789 
790 		if ((hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_SDIO) ||
791 					(hif_get_bus_type(target->hif_dev) ==
792 							 QDF_BUS_TYPE_USB)) {
793 			if (HTC_RX_BUNDLE_ENABLED(target))
794 			pSetupComp->SetupFlags |=
795 				HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
796 			hif_set_bundle_mode(target->hif_dev, true,
797 				HTC_MAX_MSG_PER_BUNDLE_RX);
798 			pSetupComp->MaxMsgsPerBundledRecv = HTC_MAX_MSG_PER_BUNDLE_RX;
799 		}
800 
801 		SET_HTC_PACKET_INFO_TX(pSendPacket,
802 				       NULL,
803 				       (uint8_t *) pSetupComp,
804 				       sizeof(HTC_SETUP_COMPLETE_EX_MSG),
805 				       ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
806 
807 		status = htc_send_pkt((HTC_HANDLE) target, pSendPacket);
808 		if (QDF_IS_STATUS_ERROR(status))
809 			break;
810 	} while (false);
811 
812 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Exit\n"));
813 	return status;
814 }
815 
816 /*flush all queued buffers for surpriseremove case*/
817 void htc_flush_surprise_remove(HTC_HANDLE HTCHandle)
818 {
819 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
820 	int i;
821 	HTC_ENDPOINT *pEndpoint;
822 #ifdef RX_SG_SUPPORT
823 	qdf_nbuf_t netbuf;
824 	qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
825 #endif
826 
827 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_flush_surprise_remove\n"));
828 
829 	/* cleanup endpoints */
830 	for (i = 0; i < ENDPOINT_MAX; i++) {
831 		pEndpoint = &target->endpoint[i];
832 		htc_flush_rx_hold_queue(target, pEndpoint);
833 		htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
834 	}
835 
836 	hif_flush_surprise_remove(target->hif_dev);
837 
838 #ifdef RX_SG_SUPPORT
839 	LOCK_HTC_RX(target);
840 	while ((netbuf = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
841 		qdf_nbuf_free(netbuf);
842 	RESET_RX_SG_CONFIG(target);
843 	UNLOCK_HTC_RX(target);
844 #endif
845 
846 	reset_endpoint_states(target);
847 
848 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_flush_surprise_remove\n"));
849 }
850 
851 /* stop HTC communications, i.e. stop interrupt reception, and flush all queued
852  * buffers
853  */
854 void htc_stop(HTC_HANDLE HTCHandle)
855 {
856 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
857 	int i;
858 	HTC_ENDPOINT *endpoint;
859 #ifdef RX_SG_SUPPORT
860 	qdf_nbuf_t netbuf;
861 	qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
862 #endif
863 
864 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_stop\n"));
865 
866 	htc_runtime_pm_deinit(target);
867 
868 	HTC_INFO("%s: endpoints cleanup\n", __func__);
869 	/* cleanup endpoints */
870 	for (i = 0; i < ENDPOINT_MAX; i++) {
871 		endpoint = &target->endpoint[i];
872 		htc_flush_rx_hold_queue(target, endpoint);
873 		htc_flush_endpoint_tx(target, endpoint, HTC_TX_PACKET_TAG_ALL);
874 		if (endpoint->ul_is_polled) {
875 			qdf_timer_stop(&endpoint->ul_poll_timer);
876 			qdf_timer_free(&endpoint->ul_poll_timer);
877 		}
878 	}
879 
880 	/* Note: htc_flush_endpoint_tx for all endpoints should be called before
881 	 * hif_stop - otherwise htc_tx_completion_handler called from
882 	 * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer,
883 	 * might queue the packet again to HIF Layer - which could cause tx
884 	 * buffer leak
885 	 */
886 
887 	HTC_INFO("%s: stopping hif layer\n", __func__);
888 	hif_stop(target->hif_dev);
889 
890 #ifdef RX_SG_SUPPORT
891 	LOCK_HTC_RX(target);
892 	while ((netbuf = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
893 		qdf_nbuf_free(netbuf);
894 	RESET_RX_SG_CONFIG(target);
895 	UNLOCK_HTC_RX(target);
896 #endif
897 
898 	/**
899 	 * In SSR case, HTC tx completion callback for wmi will be blocked
900 	 * by TARGET_STATUS_RESET and HTC packets will be left unfreed on
901 	 * lookup queue.
902 	 *
903 	 * In case of target failing to send wmi_ready_event, the htc connect
904 	 * msg buffer will be left unmapped and not freed. So calling the
905 	 * completion handler for this buffer will handle this scenario.
906 	 */
907 	HTC_INFO("%s: flush endpoints Tx lookup queue\n", __func__);
908 	for (i = 0; i < ENDPOINT_MAX; i++) {
909 		endpoint = &target->endpoint[i];
910 		if (endpoint->service_id == WMI_CONTROL_SVC)
911 			htc_flush_endpoint_txlookupQ(target, i, false);
912 		else if (endpoint->service_id == HTC_CTRL_RSVD_SVC)
913 			htc_flush_endpoint_txlookupQ(target, i, true);
914 	}
915 	HTC_INFO("%s: resetting endpoints state\n", __func__);
916 
917 	reset_endpoint_states(target);
918 
919 	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop\n"));
920 }
921 
922 void htc_dump_credit_states(HTC_HANDLE HTCHandle)
923 {
924 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
925 	HTC_ENDPOINT *pEndpoint;
926 	int i;
927 
928 	for (i = 0; i < ENDPOINT_MAX; i++) {
929 		pEndpoint = &target->endpoint[i];
930 		if (0 == pEndpoint->service_id)
931 			continue;
932 
933 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
934 			("--- EP : %d  service_id: 0x%X    --------------\n",
935 				 pEndpoint->Id, pEndpoint->service_id));
936 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
937 				(" TxCredits          : %d\n",
938 				 pEndpoint->TxCredits));
939 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
940 				(" TxCreditSize       : %d\n",
941 				 pEndpoint->TxCreditSize));
942 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
943 				(" TxCreditsPerMaxMsg : %d\n",
944 				 pEndpoint->TxCreditsPerMaxMsg));
945 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
946 				(" TxQueueDepth       : %d\n",
947 				 HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
948 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
949 				("----------------------------------------\n"));
950 	}
951 }
952 
953 bool htc_get_endpoint_statistics(HTC_HANDLE HTCHandle,
954 				   HTC_ENDPOINT_ID Endpoint,
955 				   enum htc_endpoint_stat_action Action,
956 				   struct htc_endpoint_stats *pStats)
957 {
958 #ifdef HTC_EP_STAT_PROFILING
959 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
960 	bool clearStats = false;
961 	bool sample = false;
962 
963 	switch (Action) {
964 	case HTC_EP_STAT_SAMPLE:
965 		sample = true;
966 		break;
967 	case HTC_EP_STAT_SAMPLE_AND_CLEAR:
968 		sample = true;
969 		clearStats = true;
970 		break;
971 	case HTC_EP_STAT_CLEAR:
972 		clearStats = true;
973 		break;
974 	default:
975 		break;
976 	}
977 
978 	A_ASSERT(Endpoint < ENDPOINT_MAX);
979 
980 	/* lock out TX and RX while we sample and/or clear */
981 	LOCK_HTC_TX(target);
982 	LOCK_HTC_RX(target);
983 
984 	if (sample) {
985 		A_ASSERT(pStats);
986 		/* return the stats to the caller */
987 		qdf_mem_copy(pStats, &target->endpoint[Endpoint].endpoint_stats,
988 			 sizeof(struct htc_endpoint_stats));
989 	}
990 
991 	if (clearStats) {
992 		/* reset stats */
993 		qdf_mem_zero(&target->endpoint[Endpoint].endpoint_stats,
994 			  sizeof(struct htc_endpoint_stats));
995 	}
996 
997 	UNLOCK_HTC_RX(target);
998 	UNLOCK_HTC_TX(target);
999 
1000 	return true;
1001 #else
1002 	return false;
1003 #endif
1004 }
1005 
1006 void *htc_get_targetdef(HTC_HANDLE htc_handle)
1007 {
1008 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1009 
1010 	return hif_get_targetdef(target->hif_dev);
1011 }
1012 
1013 #ifdef IPA_OFFLOAD
1014 /**
1015  * htc_ipa_get_ce_resource() - get uc resource on lower layer
1016  * @htc_handle: htc context
1017  * @ce_sr_base_paddr: copyengine source ring base physical address
1018  * @ce_sr_ring_size: copyengine source ring size
1019  * @ce_reg_paddr: copyengine register physical address
1020  *
1021  * Return: None
1022  */
1023 void htc_ipa_get_ce_resource(HTC_HANDLE htc_handle,
1024 			     qdf_shared_mem_t **ce_sr,
1025 			     uint32_t *ce_sr_ring_size,
1026 			     qdf_dma_addr_t *ce_reg_paddr)
1027 {
1028 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1029 
1030 	if (target->hif_dev)
1031 		hif_ipa_get_ce_resource(target->hif_dev,
1032 					ce_sr, ce_sr_ring_size, ce_reg_paddr);
1033 }
1034 #endif /* IPA_OFFLOAD */
1035 
1036 #if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
1037 
1038 void htc_dump_bundle_stats(HTC_HANDLE HTCHandle)
1039 {
1040 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1041 	int total, i;
1042 
1043 	total = 0;
1044 	for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
1045 		total += target->rx_bundle_stats[i];
1046 
1047 	if (total) {
1048 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("RX Bundle stats:\n"));
1049 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total RX packets: %d\n",
1050 						total));
1051 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (
1052 				"Number of bundle: Number of packets\n"));
1053 		for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
1054 			AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
1055 					("%10d:%10d(%2d%s)\n", (i+1),
1056 					 target->rx_bundle_stats[i],
1057 					 ((target->rx_bundle_stats[i]*100)/
1058 					  total), "%"));
1059 	}
1060 
1061 
1062 	total = 0;
1063 	for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
1064 		total += target->tx_bundle_stats[i];
1065 
1066 	if (total) {
1067 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("TX Bundle stats:\n"));
1068 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total TX packets: %d\n",
1069 						total));
1070 		AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
1071 				("Number of bundle: Number of packets\n"));
1072 		for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
1073 			AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
1074 					("%10d:%10d(%2d%s)\n", (i+1),
1075 					 target->tx_bundle_stats[i],
1076 					 ((target->tx_bundle_stats[i]*100)/
1077 					  total), "%"));
1078 	}
1079 }
1080 
1081 void htc_clear_bundle_stats(HTC_HANDLE HTCHandle)
1082 {
1083 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1084 
1085 	qdf_mem_zero(&target->rx_bundle_stats, sizeof(target->rx_bundle_stats));
1086 	qdf_mem_zero(&target->tx_bundle_stats, sizeof(target->tx_bundle_stats));
1087 }
1088 #endif
1089 
1090 /**
1091  * htc_vote_link_down - API to vote for link down
1092  * @htc_handle: HTC handle
1093  *
1094  * API for upper layers to call HIF to vote for link down
1095  *
1096  * Return: void
1097  */
1098 void htc_vote_link_down(HTC_HANDLE htc_handle)
1099 {
1100 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1101 
1102 	if (!target->hif_dev)
1103 		return;
1104 
1105 	hif_vote_link_down(target->hif_dev);
1106 }
1107 
1108 /**
1109  * htc_vote_link_up - API to vote for link up
1110  * @htc_handle: HTC Handle
1111  *
1112  * API for upper layers to call HIF to vote for link up
1113  *
1114  * Return: void
1115  */
1116 void htc_vote_link_up(HTC_HANDLE htc_handle)
1117 {
1118 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1119 
1120 	if (!target->hif_dev)
1121 		return;
1122 
1123 	hif_vote_link_up(target->hif_dev);
1124 }
1125 
1126 /**
1127  * htc_can_suspend_link - API to query HIF for link status
1128  * @htc_handle: HTC Handle
1129  *
1130  * API for upper layers to call HIF to query if the link can suspend
1131  *
1132  * Return: void
1133  */
1134 bool htc_can_suspend_link(HTC_HANDLE htc_handle)
1135 {
1136 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1137 
1138 	if (!target->hif_dev)
1139 		return false;
1140 
1141 	return hif_can_suspend_link(target->hif_dev);
1142 }
1143 
1144 #ifdef FEATURE_RUNTIME_PM
1145 int htc_pm_runtime_get(HTC_HANDLE htc_handle)
1146 {
1147 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1148 
1149 	return hif_pm_runtime_get(target->hif_dev,
1150 				  RTPM_ID_HTC);
1151 }
1152 
1153 int htc_pm_runtime_put(HTC_HANDLE htc_handle)
1154 {
1155 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1156 
1157 	return hif_pm_runtime_put(target->hif_dev,
1158 				  RTPM_ID_HTC);
1159 }
1160 #endif
1161 
1162 /**
1163  * htc_set_wmi_endpoint_count: Set number of WMI endpoint
1164  * @htc_handle: HTC handle
1165  * @wmi_ep_count: WMI enpoint count
1166  *
1167  * return: None
1168  */
1169 void htc_set_wmi_endpoint_count(HTC_HANDLE htc_handle, uint8_t wmi_ep_count)
1170 {
1171 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1172 
1173 	target->wmi_ep_count = wmi_ep_count;
1174 }
1175 
1176 /**
1177  * htc_get_wmi_endpoint_count: Get number of WMI endpoint
1178  * @htc_handle: HTC handle
1179  *
1180  * return: WMI enpoint count
1181  */
1182 uint8_t htc_get_wmi_endpoint_count(HTC_HANDLE htc_handle)
1183 {
1184 	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1185 
1186 	return target->wmi_ep_count;
1187 }
1188