blob: 67449a235d11719180721096f3673d44a51dcdc2 [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Poddar, Siddarthf1763402016-11-21 15:55:27 +05302 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080028#include "htc_debug.h"
29#include "htc_internal.h"
Yue Mab16cf302016-03-08 18:30:25 -080030#include <hif.h>
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053031#include <qdf_nbuf.h> /* qdf_nbuf_t */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053032#include <qdf_types.h> /* qdf_print */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080033
Poddar, Siddarthf1763402016-11-21 15:55:27 +053034#define MAX_HTC_RX_BUNDLE 2
35
Srinivas Girigowda8a0b6652016-10-19 16:01:31 -070036#if defined(WLAN_DEBUG) || defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080037static ATH_DEBUG_MASK_DESCRIPTION g_htc_debug_description[] = {
38 {ATH_DEBUG_SEND, "Send"},
39 {ATH_DEBUG_RECV, "Recv"},
40 {ATH_DEBUG_SYNC, "Sync"},
41 {ATH_DEBUG_DUMP, "Dump Data (RX or TX)"},
42 {ATH_DEBUG_SETUP, "Setup"},
43};
44
45ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
46 "htc",
47 "Host Target Communications",
48 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO |
49 ATH_DEBUG_SETUP,
50 ATH_DEBUG_DESCRIPTION_COUNT
51 (g_htc_debug_description),
52 g_htc_debug_description);
53
54#endif
55
56extern unsigned int htc_credit_flow;
57
58static void reset_endpoint_states(HTC_TARGET *target);
59
60static void destroy_htc_tx_ctrl_packet(HTC_PACKET *pPacket)
61{
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053062 qdf_nbuf_t netbuf;
63 netbuf = (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
64 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("free ctrl netbuf :0x%p\n", netbuf));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080065 if (netbuf != NULL) {
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053066 qdf_nbuf_free(netbuf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080067 }
68
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053069 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080070}
71
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053072static HTC_PACKET *build_htc_tx_ctrl_packet(qdf_device_t osdev)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080073{
74 HTC_PACKET *pPacket = NULL;
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053075 qdf_nbuf_t netbuf;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080076
77 do {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053078 pPacket = (HTC_PACKET *) qdf_mem_malloc(sizeof(HTC_PACKET));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080079 if (NULL == pPacket) {
80 break;
81 }
Yue Mab16cf302016-03-08 18:30:25 -080082 netbuf = qdf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE,
83 20, 4, true);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080084 if (NULL == netbuf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053085 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080086 pPacket = NULL;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053087 qdf_print("%s: nbuf alloc failed\n", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080088 break;
89 }
90 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
91 ("alloc ctrl netbuf :0x%p \n", netbuf));
92 SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
93 } while (false);
94
95 return pPacket;
96}
97
98void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket)
99{
100
101#ifdef TODO_FIXME
102 LOCK_HTC(target);
103 HTC_PACKET_ENQUEUE(&target->ControlBufferTXFreeList, pPacket);
104 UNLOCK_HTC(target);
105 /* TODO_FIXME netbufs cannot be RESET! */
106#else
107 destroy_htc_tx_ctrl_packet(pPacket);
108#endif
109
110}
111
112HTC_PACKET *htc_alloc_control_tx_packet(HTC_TARGET *target)
113{
114#ifdef TODO_FIXME
115 HTC_PACKET *pPacket;
116
117 LOCK_HTC(target);
118 pPacket = htc_packet_dequeue(&target->ControlBufferTXFreeList);
119 UNLOCK_HTC(target);
120
121 return pPacket;
122#else
123 return build_htc_tx_ctrl_packet(target->osdev);
124#endif
125}
126
127/* Set the target failure handling callback */
128void htc_set_target_failure_callback(HTC_HANDLE HTCHandle,
129 HTC_TARGET_FAILURE Callback)
130{
131 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
132 target->HTCInitInfo.TargetFailure = Callback;
133}
134
135void htc_dump(HTC_HANDLE HTCHandle, uint8_t CmdId, bool start)
136{
137 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
138 hif_dump(target->hif_dev, CmdId, start);
139}
140
141/* cleanup the HTC instance */
142static void htc_cleanup(HTC_TARGET *target)
143{
144 HTC_PACKET *pPacket;
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530145 /* qdf_nbuf_t netbuf; */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800146
147 if (target->hif_dev != NULL) {
148 hif_detach_htc(target->hif_dev);
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530149 hif_mask_interrupt_call(target->hif_dev);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800150 target->hif_dev = NULL;
151 }
152
153 while (true) {
154 pPacket = allocate_htc_packet_container(target);
155 if (NULL == pPacket) {
156 break;
157 }
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530158 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800159 }
160
161 pPacket = target->pBundleFreeList;
162 while (pPacket) {
163 HTC_PACKET *pPacketTmp = (HTC_PACKET *) pPacket->ListLink.pNext;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530164 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800165 pPacket = pPacketTmp;
166 }
167#ifdef TODO_FIXME
168 while (true) {
169 pPacket = htc_alloc_control_tx_packet(target);
170 if (NULL == pPacket) {
171 break;
172 }
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530173 netbuf = (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800174 if (netbuf != NULL) {
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530175 qdf_nbuf_free(netbuf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800176 }
177
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530178 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800179 }
180#endif
181
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530182 qdf_spinlock_destroy(&target->HTCLock);
183 qdf_spinlock_destroy(&target->HTCRxLock);
184 qdf_spinlock_destroy(&target->HTCTxLock);
185 qdf_spinlock_destroy(&target->HTCCreditLock);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800186
187 /* free our instance */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530188 qdf_mem_free(target);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800189}
190
Yue Maec9e71c2016-02-26 18:52:20 -0800191#ifdef FEATURE_RUNTIME_PM
192/**
193 * htc_runtime_pm_init(): runtime pm related intialization
194 *
195 * need to initialize a work item.
196 */
197static void htc_runtime_pm_init(HTC_TARGET *target)
198{
199 qdf_create_work(0, &target->queue_kicker, htc_kick_queues, target);
200}
201
202/**
203 * htc_runtime_suspend() - runtime suspend HTC
204 *
205 * @htc_ctx: HTC context pointer
206 *
207 * This is a dummy function for symmetry.
208 *
209 * Return: 0 for success
210 */
211int htc_runtime_suspend(HTC_HANDLE htc_ctx)
212{
213 return 0;
214}
215
216/**
217 * htc_runtime_resume(): resume htc
218 *
219 * The htc message queue needs to be kicked off after
220 * a runtime resume. Otherwise messages would get stuck.
221 *
222 * @htc_ctx: HTC context pointer
223 *
224 * Return: 0 for success;
225 */
226int htc_runtime_resume(HTC_HANDLE htc_ctx)
227{
228 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_ctx);
229
230 if (target == NULL)
231 return 0;
232
233 qdf_sched_work(0, &target->queue_kicker);
234 return 0;
235}
236#else
237static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
238#endif
239
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800240/* registered target arrival callback from the HIF layer */
Yue Maec9e71c2016-02-26 18:52:20 -0800241HTC_HANDLE htc_create(void *ol_sc, HTC_INIT_INFO *pInfo, qdf_device_t osdev,
242 uint32_t con_mode)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800243{
244 struct hif_msg_callbacks htcCallbacks;
245 HTC_ENDPOINT *pEndpoint = NULL;
246 HTC_TARGET *target = NULL;
247 int i;
248
249 if (ol_sc == NULL) {
250 HTC_ERROR("%s: ol_sc = NULL", __func__);
251 return NULL;
252 }
253 HTC_TRACE("+htc_create .. HIF :%p", ol_sc);
254
255 A_REGISTER_MODULE_DEBUG_INFO(htc);
256
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530257 target = (HTC_TARGET *) qdf_mem_malloc(sizeof(HTC_TARGET));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800258 if (target == NULL) {
259 HTC_ERROR("%s: Unable to allocate memory", __func__);
260 return NULL;
261 }
262
Houston Hoffman47e387b2015-10-20 17:04:42 -0700263 htc_runtime_pm_init(target);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530264 qdf_spinlock_create(&target->HTCLock);
265 qdf_spinlock_create(&target->HTCRxLock);
266 qdf_spinlock_create(&target->HTCTxLock);
267 qdf_spinlock_create(&target->HTCCreditLock);
gbianb417db22016-09-30 17:01:07 +0800268 target->is_nodrop_pkt = false;
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530269 target->wmi_ep_count = 1;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800270
271 do {
Yue Mab16cf302016-03-08 18:30:25 -0800272 qdf_mem_copy(&target->HTCInitInfo, pInfo,
273 sizeof(HTC_INIT_INFO));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800274 target->host_handle = pInfo->pContext;
275 target->osdev = osdev;
Yue Maec9e71c2016-02-26 18:52:20 -0800276 target->con_mode = con_mode;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800277
278 reset_endpoint_states(target);
279
280 INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
281
282 for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
283 HTC_PACKET *pPacket =
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530284 (HTC_PACKET *) qdf_mem_malloc(sizeof(HTC_PACKET));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800285 if (pPacket != NULL) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800286 free_htc_packet_container(target, pPacket);
287 }
288 }
289
290#ifdef TODO_FIXME
291 for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
292 pPacket = build_htc_tx_ctrl_packet();
293 if (NULL == pPacket) {
294 break;
295 }
296 htc_free_control_tx_packet(target, pPacket);
297 }
298#endif
299
300 /* setup HIF layer callbacks */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530301 qdf_mem_zero(&htcCallbacks, sizeof(struct hif_msg_callbacks));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800302 htcCallbacks.Context = target;
303 htcCallbacks.rxCompletionHandler = htc_rx_completion_handler;
304 htcCallbacks.txCompletionHandler = htc_tx_completion_handler;
305 htcCallbacks.txResourceAvailHandler = htc_tx_resource_avail_handler;
306 htcCallbacks.fwEventHandler = htc_fw_event_handler;
307 target->hif_dev = ol_sc;
308
309 /* Get HIF default pipe for HTC message exchange */
Houston Hoffman29573d92015-10-20 17:49:44 -0700310 pEndpoint = &target->endpoint[ENDPOINT_0];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800311
312 hif_post_init(target->hif_dev, target, &htcCallbacks);
313 hif_get_default_pipe(target->hif_dev, &pEndpoint->UL_PipeID,
314 &pEndpoint->DL_PipeID);
315
316 } while (false);
317
318 htc_recv_init(target);
319
320 HTC_TRACE("-htc_create: (0x%p)", target);
321
322 return (HTC_HANDLE) target;
323}
324
325void htc_destroy(HTC_HANDLE HTCHandle)
326{
327 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
328 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
329 ("+htc_destroy .. Destroying :0x%p\n", target));
Karthick Sc3a7a0c2015-10-14 17:56:55 +0530330 hif_stop(htc_get_hif_device(HTCHandle));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800331 if (target)
332 htc_cleanup(target);
333 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n"));
334}
335
336/* get the low level HIF device for the caller , the caller may wish to do low level
337 * HIF requests */
338void *htc_get_hif_device(HTC_HANDLE HTCHandle)
339{
340 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
341 return target->hif_dev;
342}
343
Jeff Johnsonc66399a2016-10-07 13:01:33 -0700344static void htc_control_tx_complete(void *Context, HTC_PACKET *pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800345{
346 HTC_TARGET *target = (HTC_TARGET *) Context;
347 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
348 ("+-htc_control_tx_complete 0x%p (l:%d) \n", pPacket,
349 pPacket->ActualLength));
350 htc_free_control_tx_packet(target, pPacket);
351}
352
353/* TODO, this is just a temporary max packet size */
354#define MAX_MESSAGE_SIZE 1536
355
356/**
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530357 * htc_setup_epping_credit_allocation() - allocate credits/HTC buffers to WMI
358 * @scn: pointer to hif_opaque_softc
359 * @pEntry: pointer to tx credit allocation entry
360 * @credits: number of credits
361 *
362 * Return: None
363 */
364static void
365htc_setup_epping_credit_allocation(struct hif_opaque_softc *scn,
366 HTC_SERVICE_TX_CREDIT_ALLOCATION *pEntry,
367 int credits)
368{
369 switch (hif_get_bus_type(scn)) {
370 case QDF_BUS_TYPE_PCI:
371 pEntry++;
372 pEntry->service_id = WMI_DATA_BE_SVC;
373 pEntry->CreditAllocation = (credits >> 1);
374
375 pEntry++;
376 pEntry->service_id = WMI_DATA_BK_SVC;
377 pEntry->CreditAllocation = (credits >> 1);
378 break;
379 case QDF_BUS_TYPE_SDIO:
380 pEntry++;
381 pEntry->service_id = WMI_DATA_BE_SVC;
382 pEntry->CreditAllocation = credits;
383 break;
384 default:
385 break;
386 }
387 return;
388}
389
390/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800391 * htc_setup_target_buffer_assignments() - setup target buffer assignments
392 * @target: HTC Target Pointer
393 *
394 * Return: A_STATUS
395 */
Jeff Johnsonc66399a2016-10-07 13:01:33 -0700396static
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800397A_STATUS htc_setup_target_buffer_assignments(HTC_TARGET *target)
398{
399 HTC_SERVICE_TX_CREDIT_ALLOCATION *pEntry;
400 A_STATUS status;
401 int credits;
402 int creditsPerMaxMsg;
403
404 creditsPerMaxMsg = MAX_MESSAGE_SIZE / target->TargetCreditSize;
405 if (MAX_MESSAGE_SIZE % target->TargetCreditSize) {
406 creditsPerMaxMsg++;
407 }
408
409 /* TODO, this should be configured by the caller! */
410
411 credits = target->TotalTransmitCredits;
412 pEntry = &target->ServiceTxAllocTable[0];
413
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530414 status = A_OK;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800415 /*
416 * Allocate all credists/HTC buffers to WMI.
417 * no buffers are used/required for data. data always
418 * remains on host.
419 */
Yue Maec9e71c2016-02-26 18:52:20 -0800420 if (HTC_IS_EPPING_ENABLED(target->con_mode)) {
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530421 pEntry++;
422 pEntry->service_id = WMI_CONTROL_SVC;
423 pEntry->CreditAllocation = credits;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800424 /* endpoint ping is a testing tool directly on top of HTC in
425 * both target and host sides.
426 * In target side, the endppint ping fw has no wlan stack and the
427 * FW mboxping app directly sits on HTC and it simply drops
428 * or loops back TX packets. For rx perf, FW mboxping app
429 * generates packets and passes packets to HTC to send to host.
430 * There is no WMI mesage exchanges between host and target
431 * in endpoint ping case.
432 * In host side, the endpoint ping driver is a Ethernet driver
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530433 * and it directly sits on HTC. Only HIF, HTC, QDF, ADF are
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800434 * used by the endpoint ping driver. There is no wifi stack
435 * at all in host side also. For tx perf use case,
436 * the user space mboxping app sends the raw packets to endpoint
437 * ping driver and it directly forwards to HTC for transmission
438 * to stress the bus. For the rx perf, HTC passes the received
439 * packets to endpoint ping driver and it is passed to the user
440 * space through the Ethernet interface.
441 * For credit allocation, in SDIO bus case, only BE service is
442 * used for tx/rx perf testing so that all credits are given
443 * to BE service. In PCIe and USB bus case, endpoint ping uses both
444 * BE and BK services to stress the bus so that the total credits
445 * are equally distributed to BE and BK services.
446 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800447
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530448 htc_setup_epping_credit_allocation(target->hif_dev,
449 pEntry, credits);
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530450 } else {
451 int i;
452 uint32_t svc_id[] = {WMI_CONTROL_SVC, WMI_CONTROL_SVC_WMAC1,
453 WMI_CONTROL_SVC_WMAC2};
454 uint32_t max_wmi_svc = (sizeof(svc_id) / sizeof(uint32_t));
455
456 if ((target->wmi_ep_count == 0) ||
457 (target->wmi_ep_count > max_wmi_svc))
458 return A_ERROR;
459
460 /*
461 * Divide credit among number of endpoints for WMI
462 */
463 credits = credits / target->wmi_ep_count;
464 for (i = 0; i < target->wmi_ep_count; i++) {
465 status = A_OK;
466 pEntry++;
467 pEntry->service_id = svc_id[i];
468 pEntry->CreditAllocation = credits;
469 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800470 }
471
472 if (A_SUCCESS(status)) {
473 int i;
474 for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700475 if (target->ServiceTxAllocTable[i].service_id != 0) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800476 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700477 ("HTC Service Index : %d TX : 0x%2.2X : alloc:%d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800478 i,
479 target->ServiceTxAllocTable[i].
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700480 service_id,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800481 target->ServiceTxAllocTable[i].
482 CreditAllocation));
483 }
484 }
485 }
486
487 return status;
488}
489
Yue Mab16cf302016-03-08 18:30:25 -0800490uint8_t htc_get_credit_allocation(HTC_TARGET *target, uint16_t service_id)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800491{
Yue Mab16cf302016-03-08 18:30:25 -0800492 uint8_t allocation = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800493 int i;
494
495 for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700496 if (target->ServiceTxAllocTable[i].service_id == service_id) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800497 allocation =
498 target->ServiceTxAllocTable[i].CreditAllocation;
499 }
500 }
501
502 if (0 == allocation) {
503 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700504 ("HTC Service TX : 0x%2.2X : allocation is zero!\n",
505 service_id));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800506 }
507
508 return allocation;
509}
510
511A_STATUS htc_wait_target(HTC_HANDLE HTCHandle)
512{
513 A_STATUS status = A_OK;
514 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
515 HTC_READY_EX_MSG *pReadyMsg;
516 HTC_SERVICE_CONNECT_REQ connect;
517 HTC_SERVICE_CONNECT_RESP resp;
518 HTC_READY_MSG *rdy_msg;
Yue Mab16cf302016-03-08 18:30:25 -0800519 uint16_t htc_rdy_msg_id;
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530520 uint8_t i = 0;
521 HTC_PACKET *rx_bundle_packet, *temp_bundle_packet;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800522
523 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530524 ("htc_wait_target - Enter (target:0x%p)\n", HTCHandle));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800525 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n"));
526
527 do {
528
529 status = hif_start(target->hif_dev);
530 if (A_FAILED(status)) {
531 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("hif_start failed\n"));
532 break;
533 }
534
535 status = htc_wait_recv_ctrl_message(target);
536
537 if (A_FAILED(status)) {
538 break;
539 }
540
541 if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
542 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
543 ("Invalid HTC Ready Msg Len:%d! \n",
544 target->CtrlResponseLength));
545 status = A_ECOMM;
546 break;
547 }
548
549 pReadyMsg = (HTC_READY_EX_MSG *) target->CtrlResponseBuffer;
550
551 rdy_msg = &pReadyMsg->Version2_0_Info;
552 htc_rdy_msg_id =
553 HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
554 if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
555 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
556 ("Invalid HTC Ready Msg : 0x%X ! \n",
557 htc_rdy_msg_id));
558 status = A_ECOMM;
559 break;
560 }
561
562 target->TotalTransmitCredits =
563 HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT);
564 target->TargetCreditSize =
565 (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);
566 target->MaxMsgsPerHTCBundle =
Yue Mab16cf302016-03-08 18:30:25 -0800567 (uint8_t) pReadyMsg->MaxMsgsPerHTCBundle;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800568 /* for old fw this value is set to 0. But the minimum value should be 1,
569 * i.e., no bundling */
570 if (target->MaxMsgsPerHTCBundle < 1)
571 target->MaxMsgsPerHTCBundle = 1;
572
573 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
574 ("Target Ready! : transmit resources : %d size:%d, MaxMsgsPerHTCBundle = %d\n",
575 target->TotalTransmitCredits,
576 target->TargetCreditSize,
577 target->MaxMsgsPerHTCBundle));
578
579 if ((0 == target->TotalTransmitCredits)
580 || (0 == target->TargetCreditSize)) {
581 status = A_ECOMM;
582 break;
583 }
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530584
585 /* Allocate expected number of RX bundle buffer allocation */
586 if (HTC_RX_BUNDLE_ENABLED(target)) {
587 temp_bundle_packet = NULL;
588 for (i = 0; i < MAX_HTC_RX_BUNDLE; i++) {
589 rx_bundle_packet =
590 allocate_htc_bundle_packet(target);
591 if (rx_bundle_packet != NULL)
592 rx_bundle_packet->ListLink.pNext =
593 (DL_LIST *)temp_bundle_packet;
594 else
595 break;
596
597 temp_bundle_packet = rx_bundle_packet;
598 }
599 target->pBundleFreeList = temp_bundle_packet;
600 }
601
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800602 /* done processing */
603 target->CtrlResponseProcessing = false;
604
605 htc_setup_target_buffer_assignments(target);
606
607 /* setup our pseudo HTC control endpoint connection */
Yue Mab16cf302016-03-08 18:30:25 -0800608 qdf_mem_zero(&connect, sizeof(connect));
609 qdf_mem_zero(&resp, sizeof(resp));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800610 connect.EpCallbacks.pContext = target;
611 connect.EpCallbacks.EpTxComplete = htc_control_tx_complete;
612 connect.EpCallbacks.EpRecv = htc_control_rx_complete;
613 connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700614 connect.service_id = HTC_CTRL_RSVD_SVC;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800615
616 /* connect fake service */
617 status = htc_connect_service((HTC_HANDLE) target,
618 &connect, &resp);
619
620 } while (false);
621
622 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Exit (%d)\n", status));
623 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n"));
624 return status;
625}
626
627/* start HTC, this is called after all services are connected */
628static A_STATUS htc_config_target_hif_pipe(HTC_TARGET *target)
629{
630
631 return A_OK;
632}
633
634static void reset_endpoint_states(HTC_TARGET *target)
635{
636 HTC_ENDPOINT *pEndpoint;
637 int i;
638
639 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700640 pEndpoint = &target->endpoint[i];
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700641 pEndpoint->service_id = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800642 pEndpoint->MaxMsgLength = 0;
643 pEndpoint->MaxTxQueueDepth = 0;
644 pEndpoint->Id = i;
645 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
646 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxLookupQueue);
647 INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBufferHoldQueue);
648 pEndpoint->target = target;
Yue Mab16cf302016-03-08 18:30:25 -0800649 pEndpoint->TxCreditFlowEnabled = (bool)htc_credit_flow;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530650 qdf_atomic_init(&pEndpoint->TxProcessCount);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800651 }
652}
653
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700654/**
655 * htc_start() - Main HTC function to trigger HTC start
656 * @HTCHandle: pointer to HTC handle
657 *
658 * Return: A_OK for success or an appropriate A_STATUS error
659 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800660A_STATUS htc_start(HTC_HANDLE HTCHandle)
661{
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530662 qdf_nbuf_t netbuf;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800663 A_STATUS status = A_OK;
664 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
665 HTC_SETUP_COMPLETE_EX_MSG *pSetupComp;
666 HTC_PACKET *pSendPacket;
667
668 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Enter\n"));
669
670 do {
671
672 htc_config_target_hif_pipe(target);
673
674 /* allocate a buffer to send */
675 pSendPacket = htc_alloc_control_tx_packet(target);
676 if (NULL == pSendPacket) {
677 AR_DEBUG_ASSERT(false);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530678 qdf_print("%s: allocControlTxPacket failed\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800679 __func__);
680 status = A_NO_MEMORY;
681 break;
682 }
683
684 netbuf =
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530685 (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800686 /* assemble setup complete message */
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530687 qdf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800688 pSetupComp =
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530689 (HTC_SETUP_COMPLETE_EX_MSG *) qdf_nbuf_data(netbuf);
Yue Mab16cf302016-03-08 18:30:25 -0800690 qdf_mem_zero(pSetupComp, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800691
692 HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG,
693 MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID);
694
695 if (!htc_credit_flow) {
696 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
697 ("HTC will not use TX credit flow control\n"));
698 pSetupComp->SetupFlags |=
699 HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW;
700 } else {
701 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
702 ("HTC using TX credit flow control\n"));
703 }
704
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700705 if ((hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_SDIO) ||
706 (hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_USB)) {
707 if (HTC_RX_BUNDLE_ENABLED(target))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800708 pSetupComp->SetupFlags |=
709 HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700710 hif_set_bundle_mode(target->hif_dev, true,
711 HTC_MAX_MSG_PER_BUNDLE_RX);
712 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800713
714 SET_HTC_PACKET_INFO_TX(pSendPacket,
715 NULL,
Yue Mab16cf302016-03-08 18:30:25 -0800716 (uint8_t *) pSetupComp,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800717 sizeof(HTC_SETUP_COMPLETE_EX_MSG),
718 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
719
720 status = htc_send_pkt((HTC_HANDLE) target, pSendPacket);
721 if (A_FAILED(status)) {
722 break;
723 }
724
725 } while (false);
726
727 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Exit\n"));
728 return status;
729}
730
731/*flush all queued buffers for surpriseremove case*/
732void htc_flush_surprise_remove(HTC_HANDLE HTCHandle)
733{
734 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
735 int i;
736 HTC_ENDPOINT *pEndpoint;
737#ifdef RX_SG_SUPPORT
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530738 qdf_nbuf_t netbuf;
739 qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800740#endif
741
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530742 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_flush_surprise_remove\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800743
744 /* cleanup endpoints */
745 for (i = 0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700746 pEndpoint = &target->endpoint[i];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800747 htc_flush_rx_hold_queue(target, pEndpoint);
748 htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
749 }
750
751 hif_flush_surprise_remove(target->hif_dev);
752
753#ifdef RX_SG_SUPPORT
754 LOCK_HTC_RX(target);
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530755 while ((netbuf = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
756 qdf_nbuf_free(netbuf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800757 RESET_RX_SG_CONFIG(target);
758 UNLOCK_HTC_RX(target);
759#endif
760
761 reset_endpoint_states(target);
762
763 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_flush_surprise_remove \n"));
764}
765
766/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
767void htc_stop(HTC_HANDLE HTCHandle)
768{
769 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
770 int i;
771 HTC_ENDPOINT *pEndpoint;
772#ifdef RX_SG_SUPPORT
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530773 qdf_nbuf_t netbuf;
774 qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800775#endif
776
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530777 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_stop\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800778
779 /* cleanup endpoints */
780 for (i = 0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700781 pEndpoint = &target->endpoint[i];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800782 htc_flush_rx_hold_queue(target, pEndpoint);
783 htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
784 if (pEndpoint->ul_is_polled) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530785 qdf_timer_stop(&pEndpoint->ul_poll_timer);
786 qdf_timer_free(&pEndpoint->ul_poll_timer);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800787 }
788 }
789
790 /* Note: htc_flush_endpoint_tx for all endpoints should be called before
791 * hif_stop - otherwise htc_tx_completion_handler called from
792 * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer,
793 * might queue the packet again to HIF Layer - which could cause tx
794 * buffer leak
795 */
796
797 hif_stop(target->hif_dev);
798
799#ifdef RX_SG_SUPPORT
800 LOCK_HTC_RX(target);
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530801 while ((netbuf = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
802 qdf_nbuf_free(netbuf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800803 RESET_RX_SG_CONFIG(target);
804 UNLOCK_HTC_RX(target);
805#endif
806
807 reset_endpoint_states(target);
808
Houston Hoffman47e387b2015-10-20 17:04:42 -0700809 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop\n"));
810}
811
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800812void htc_dump_credit_states(HTC_HANDLE HTCHandle)
813{
814 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
815 HTC_ENDPOINT *pEndpoint;
816 int i;
817
818 for (i = 0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700819 pEndpoint = &target->endpoint[i];
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700820 if (0 == pEndpoint->service_id)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800821 continue;
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700822
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800823 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700824 ("--- EP : %d service_id: 0x%X --------------\n",
825 pEndpoint->Id, pEndpoint->service_id));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800826 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700827 (" TxCredits : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800828 pEndpoint->TxCredits));
829 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700830 (" TxCreditSize : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800831 pEndpoint->TxCreditSize));
832 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700833 (" TxCreditsPerMaxMsg : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800834 pEndpoint->TxCreditsPerMaxMsg));
835 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700836 (" TxQueueDepth : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800837 HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
838 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
839 ("----------------------------------------------------\n"));
840 }
841}
842
Yue Mab16cf302016-03-08 18:30:25 -0800843bool htc_get_endpoint_statistics(HTC_HANDLE HTCHandle,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800844 HTC_ENDPOINT_ID Endpoint,
845 HTC_ENDPOINT_STAT_ACTION Action,
846 HTC_ENDPOINT_STATS *pStats)
847{
848#ifdef HTC_EP_STAT_PROFILING
849 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
Yue Mab16cf302016-03-08 18:30:25 -0800850 bool clearStats = false;
851 bool sample = false;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800852
853 switch (Action) {
854 case HTC_EP_STAT_SAMPLE:
855 sample = true;
856 break;
857 case HTC_EP_STAT_SAMPLE_AND_CLEAR:
858 sample = true;
859 clearStats = true;
860 break;
861 case HTC_EP_STAT_CLEAR:
862 clearStats = true;
863 break;
864 default:
865 break;
866 }
867
868 A_ASSERT(Endpoint < ENDPOINT_MAX);
869
870 /* lock out TX and RX while we sample and/or clear */
871 LOCK_HTC_TX(target);
872 LOCK_HTC_RX(target);
873
874 if (sample) {
875 A_ASSERT(pStats != NULL);
876 /* return the stats to the caller */
Yue Mab16cf302016-03-08 18:30:25 -0800877 qdf_mem_copy(pStats, &target->endpoint[Endpoint].endpoint_stats,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800878 sizeof(HTC_ENDPOINT_STATS));
879 }
880
881 if (clearStats) {
882 /* reset stats */
Yue Mab16cf302016-03-08 18:30:25 -0800883 qdf_mem_zero(&target->endpoint[Endpoint].endpoint_stats,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800884 sizeof(HTC_ENDPOINT_STATS));
885 }
886
887 UNLOCK_HTC_RX(target);
888 UNLOCK_HTC_TX(target);
889
890 return true;
891#else
892 return false;
893#endif
894}
895
896void *htc_get_targetdef(HTC_HANDLE htc_handle)
897{
898 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
899
900 return hif_get_targetdef(target->hif_dev);
901}
902
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800903#ifdef IPA_OFFLOAD
Leo Changd85f78d2015-11-13 10:55:34 -0800904/**
905 * htc_ipa_get_ce_resource() - get uc resource on lower layer
906 * @htc_handle: htc context
907 * @ce_sr_base_paddr: copyengine source ring base physical address
908 * @ce_sr_ring_size: copyengine source ring size
909 * @ce_reg_paddr: copyengine register physical address
910 *
911 * Return: None
912 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800913void htc_ipa_get_ce_resource(HTC_HANDLE htc_handle,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530914 qdf_dma_addr_t *ce_sr_base_paddr,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800915 uint32_t *ce_sr_ring_size,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530916 qdf_dma_addr_t *ce_reg_paddr)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800917{
918 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
919
920 if (target->hif_dev != NULL) {
921 hif_ipa_get_ce_resource(target->hif_dev,
922 ce_sr_base_paddr,
923 ce_sr_ring_size, ce_reg_paddr);
924 }
925}
926#endif /* IPA_OFFLOAD */
Komal Seelamf8600682016-02-02 18:17:13 +0530927
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530928#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
929
930void htc_dump_bundle_stats(HTC_HANDLE HTCHandle)
931{
932 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
933 int total, i;
934
935 total = 0;
936 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
937 total += target->rx_bundle_stats[i];
938
939 if (total) {
940 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("RX Bundle stats:\n"));
941 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total RX packets: %d\n",
942 total));
943 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (
944 "Number of bundle: Number of packets\n"));
945 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
946 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
947 ("%10d:%10d(%2d%s)\n", (i+1),
948 target->rx_bundle_stats[i],
949 ((target->rx_bundle_stats[i]*100)/
950 total), "%"));
951 }
952
953
954 total = 0;
955 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
956 total += target->tx_bundle_stats[i];
957
958 if (total) {
959 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("TX Bundle stats:\n"));
960 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total TX packets: %d\n",
961 total));
962 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
963 ("Number of bundle: Number of packets\n"));
964 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
965 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
966 ("%10d:%10d(%2d%s)\n", (i+1),
967 target->tx_bundle_stats[i],
968 ((target->tx_bundle_stats[i]*100)/
969 total), "%"));
970 }
971}
972
973void htc_clear_bundle_stats(HTC_HANDLE HTCHandle)
974{
975 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
976
977 qdf_mem_zero(&target->rx_bundle_stats, sizeof(target->rx_bundle_stats));
978 qdf_mem_zero(&target->tx_bundle_stats, sizeof(target->tx_bundle_stats));
979}
980#endif
981
Komal Seelamf8600682016-02-02 18:17:13 +0530982/**
983 * htc_vote_link_down - API to vote for link down
984 * @htc_handle: HTC handle
985 *
986 * API for upper layers to call HIF to vote for link down
987 *
988 * Return: void
989 */
990void htc_vote_link_down(HTC_HANDLE htc_handle)
991{
992 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
993
994 if (!target->hif_dev)
995 return;
996
997 hif_vote_link_down(target->hif_dev);
998}
999
1000/**
1001 * htc_vote_link_up - API to vote for link up
1002 * @htc_handle: HTC Handle
1003 *
1004 * API for upper layers to call HIF to vote for link up
1005 *
1006 * Return: void
1007 */
1008void htc_vote_link_up(HTC_HANDLE htc_handle)
1009{
1010 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1011
1012 if (!target->hif_dev)
1013 return;
1014
1015 hif_vote_link_up(target->hif_dev);
1016}
1017
1018/**
1019 * htc_can_suspend_link - API to query HIF for link status
1020 * @htc_handle: HTC Handle
1021 *
1022 * API for upper layers to call HIF to query if the link can suspend
1023 *
1024 * Return: void
1025 */
1026bool htc_can_suspend_link(HTC_HANDLE htc_handle)
1027{
1028 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1029
1030 if (!target->hif_dev)
1031 return false;
1032
1033 return hif_can_suspend_link(target->hif_dev);
1034}
Houston Hoffman4d9b0802016-07-20 10:10:35 -07001035
1036#ifdef FEATURE_RUNTIME_PM
1037int htc_pm_runtime_get(HTC_HANDLE htc_handle)
1038{
1039 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1040
1041 HTC_INFO("%s: %pS\n", __func__, (void *)_RET_IP_);
1042 return hif_pm_runtime_get(target->hif_dev);
1043}
1044
1045int htc_pm_runtime_put(HTC_HANDLE htc_handle)
1046{
1047 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1048
1049 HTC_INFO("%s: %pS\n", __func__, (void *)_RET_IP_);
1050 return hif_pm_runtime_put(target->hif_dev);
1051}
1052#endif
Kiran Venkatappae17e3b62017-02-10 16:31:49 +05301053
1054/**
1055 * htc_set_wmi_endpoint_count: Set number of WMI endpoint
1056 * @htc_handle: HTC handle
1057 * @wmi_ep_count: WMI enpoint count
1058 *
1059 * return: None
1060 */
1061void htc_set_wmi_endpoint_count(HTC_HANDLE htc_handle, uint8_t wmi_ep_count)
1062{
1063 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1064
1065 target->wmi_ep_count = wmi_ep_count;
1066}
1067
1068/**
1069 * htc_get_wmi_endpoint_count: Get number of WMI endpoint
1070 * @htc_handle: HTC handle
1071 *
1072 * return: WMI enpoint count
1073 */
1074uint8_t htc_get_wmi_endpoint_count(HTC_HANDLE htc_handle)
1075{
1076 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1077
1078 return target->wmi_ep_count;
1079}