blob: 9db6f11b522794bddd6151a0e1f913635c8eb6b5 [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Madhvapathi Srirambfb01122019-01-07 09:17:29 +05302 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003 *
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08004 * 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
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080019#include "htc_debug.h"
20#include "htc_internal.h"
Rachit Kankane1bc11492018-01-24 18:48:17 +053021#include "htc_credit_history.h"
Yue Mab16cf302016-03-08 18:30:25 -080022#include <hif.h>
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053023#include <qdf_nbuf.h> /* qdf_nbuf_t */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053024#include <qdf_types.h> /* qdf_print */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080025
Poddar, Siddarthf1763402016-11-21 15:55:27 +053026#define MAX_HTC_RX_BUNDLE 2
27
Srinivas Girigowda8a0b6652016-10-19 16:01:31 -070028#if defined(WLAN_DEBUG) || defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080029static ATH_DEBUG_MASK_DESCRIPTION g_htc_debug_description[] = {
30 {ATH_DEBUG_SEND, "Send"},
31 {ATH_DEBUG_RECV, "Recv"},
32 {ATH_DEBUG_SYNC, "Sync"},
33 {ATH_DEBUG_DUMP, "Dump Data (RX or TX)"},
34 {ATH_DEBUG_SETUP, "Setup"},
35};
36
37ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
38 "htc",
39 "Host Target Communications",
40 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO |
41 ATH_DEBUG_SETUP,
42 ATH_DEBUG_DESCRIPTION_COUNT
43 (g_htc_debug_description),
44 g_htc_debug_description);
45
46#endif
47
Vevek Venkatesanbd2837222019-06-28 18:30:08 +053048#if (defined(WMI_MULTI_MAC_SVC) || defined(QCA_WIFI_QCA8074) || \
Basamma Yakkanahallib85768e2019-04-27 05:24:00 +053049 defined(QCA_WIFI_QCA6018))
Pratik Gandhi78461502018-02-05 17:22:41 +053050static const uint32_t svc_id[] = {WMI_CONTROL_SVC, WMI_CONTROL_SVC_WMAC1,
51 WMI_CONTROL_SVC_WMAC2};
52#else
53static const uint32_t svc_id[] = {WMI_CONTROL_SVC};
54#endif
55
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080056extern 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;
Manikandan Mohane3e209e2017-04-13 20:19:26 -070063
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053064 netbuf = (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
Jeff Johnson5a6cc792019-03-18 09:47:18 -070065 if (netbuf)
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053066 qdf_nbuf_free(netbuf);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053067 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080068}
69
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053070static HTC_PACKET *build_htc_tx_ctrl_packet(qdf_device_t osdev)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080071{
72 HTC_PACKET *pPacket = NULL;
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053073 qdf_nbuf_t netbuf;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080074
75 do {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053076 pPacket = (HTC_PACKET *) qdf_mem_malloc(sizeof(HTC_PACKET));
Jeff Johnson5a6cc792019-03-18 09:47:18 -070077 if (!pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080078 break;
Yue Mab16cf302016-03-08 18:30:25 -080079 netbuf = qdf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE,
80 20, 4, true);
Jeff Johnson5a6cc792019-03-18 09:47:18 -070081 if (!netbuf) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053082 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080083 pPacket = NULL;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080084 break;
85 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080086 SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
87 } while (false);
88
89 return pPacket;
90}
91
92void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket)
93{
94
95#ifdef TODO_FIXME
96 LOCK_HTC(target);
97 HTC_PACKET_ENQUEUE(&target->ControlBufferTXFreeList, pPacket);
98 UNLOCK_HTC(target);
99 /* TODO_FIXME netbufs cannot be RESET! */
100#else
101 destroy_htc_tx_ctrl_packet(pPacket);
102#endif
103
104}
105
106HTC_PACKET *htc_alloc_control_tx_packet(HTC_TARGET *target)
107{
108#ifdef TODO_FIXME
109 HTC_PACKET *pPacket;
110
111 LOCK_HTC(target);
112 pPacket = htc_packet_dequeue(&target->ControlBufferTXFreeList);
113 UNLOCK_HTC(target);
114
115 return pPacket;
116#else
117 return build_htc_tx_ctrl_packet(target->osdev);
118#endif
119}
120
121/* Set the target failure handling callback */
122void htc_set_target_failure_callback(HTC_HANDLE HTCHandle,
123 HTC_TARGET_FAILURE Callback)
124{
125 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700126
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800127 target->HTCInitInfo.TargetFailure = Callback;
128}
129
130void htc_dump(HTC_HANDLE HTCHandle, uint8_t CmdId, bool start)
131{
132 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700133
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800134 hif_dump(target->hif_dev, CmdId, start);
135}
136
137/* cleanup the HTC instance */
138static void htc_cleanup(HTC_TARGET *target)
139{
140 HTC_PACKET *pPacket;
Govind Singhc505cdc2017-05-16 12:15:51 +0530141 int i;
142 HTC_ENDPOINT *endpoint;
wadesongfbf643a2017-10-14 09:11:34 +0800143 HTC_PACKET_QUEUE *pkt_queue;
144 qdf_nbuf_t netbuf;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800145
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700146 if (target->hif_dev) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800147 hif_detach_htc(target->hif_dev);
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530148 hif_mask_interrupt_call(target->hif_dev);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800149 target->hif_dev = NULL;
150 }
151
152 while (true) {
153 pPacket = allocate_htc_packet_container(target);
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700154 if (!pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800155 break;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530156 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800157 }
158
wadesongfbf643a2017-10-14 09:11:34 +0800159 LOCK_HTC_TX(target);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800160 pPacket = target->pBundleFreeList;
wadesongfbf643a2017-10-14 09:11:34 +0800161 target->pBundleFreeList = NULL;
162 UNLOCK_HTC_TX(target);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800163 while (pPacket) {
164 HTC_PACKET *pPacketTmp = (HTC_PACKET *) pPacket->ListLink.pNext;
wadesongfbf643a2017-10-14 09:11:34 +0800165 netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
166 if (netbuf)
167 qdf_nbuf_free(netbuf);
168 pkt_queue = pPacket->pContext;
169 if (pkt_queue)
170 qdf_mem_free(pkt_queue);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530171 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800172 pPacket = pPacketTmp;
173 }
wadesongfbf643a2017-10-14 09:11:34 +0800174
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800175#ifdef TODO_FIXME
176 while (true) {
177 pPacket = htc_alloc_control_tx_packet(target);
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700178 if (!pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800179 break;
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530180 netbuf = (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket);
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700181 if (netbuf)
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530182 qdf_nbuf_free(netbuf);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530183 qdf_mem_free(pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800184 }
185#endif
186
Zhang Qianedaa3872018-07-04 20:02:53 +0800187 htc_flush_endpoint_txlookupQ(target, ENDPOINT_0, true);
Alok Kumar9bd81522018-05-30 13:07:13 +0530188
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530189 qdf_spinlock_destroy(&target->HTCLock);
190 qdf_spinlock_destroy(&target->HTCRxLock);
191 qdf_spinlock_destroy(&target->HTCTxLock);
Govind Singhc505cdc2017-05-16 12:15:51 +0530192 for (i = 0; i < ENDPOINT_MAX; i++) {
193 endpoint = &target->endpoint[i];
194 qdf_spinlock_destroy(&endpoint->lookup_queue_lock);
195 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800196
197 /* free our instance */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530198 qdf_mem_free(target);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800199}
200
Yue Maec9e71c2016-02-26 18:52:20 -0800201#ifdef FEATURE_RUNTIME_PM
202/**
203 * htc_runtime_pm_init(): runtime pm related intialization
204 *
205 * need to initialize a work item.
206 */
207static void htc_runtime_pm_init(HTC_TARGET *target)
208{
209 qdf_create_work(0, &target->queue_kicker, htc_kick_queues, target);
210}
211
212/**
213 * htc_runtime_suspend() - runtime suspend HTC
214 *
215 * @htc_ctx: HTC context pointer
216 *
217 * This is a dummy function for symmetry.
218 *
219 * Return: 0 for success
220 */
221int htc_runtime_suspend(HTC_HANDLE htc_ctx)
222{
223 return 0;
224}
225
226/**
227 * htc_runtime_resume(): resume htc
228 *
229 * The htc message queue needs to be kicked off after
230 * a runtime resume. Otherwise messages would get stuck.
231 *
232 * @htc_ctx: HTC context pointer
233 *
234 * Return: 0 for success;
235 */
236int htc_runtime_resume(HTC_HANDLE htc_ctx)
237{
238 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_ctx);
239
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700240 if (!target)
Yue Maec9e71c2016-02-26 18:52:20 -0800241 return 0;
242
243 qdf_sched_work(0, &target->queue_kicker);
244 return 0;
245}
246#else
247static inline void htc_runtime_pm_init(HTC_TARGET *target) { }
248#endif
249
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800250/* registered target arrival callback from the HIF layer */
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700251HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo,
252 qdf_device_t osdev, uint32_t con_mode)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800253{
254 struct hif_msg_callbacks htcCallbacks;
255 HTC_ENDPOINT *pEndpoint = NULL;
256 HTC_TARGET *target = NULL;
257 int i;
258
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700259 if (!ol_sc) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800260 HTC_ERROR("%s: ol_sc = NULL", __func__);
261 return NULL;
262 }
Jeff Johnsona79b1112017-09-18 10:12:02 -0700263 HTC_TRACE("+htc_create .. HIF :%pK", ol_sc);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800264
265 A_REGISTER_MODULE_DEBUG_INFO(htc);
266
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530267 target = (HTC_TARGET *) qdf_mem_malloc(sizeof(HTC_TARGET));
Madhvapathi Srirambfb01122019-01-07 09:17:29 +0530268 if (!target)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800269 return NULL;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800270
Houston Hoffman47e387b2015-10-20 17:04:42 -0700271 htc_runtime_pm_init(target);
Rachit Kankane1bc11492018-01-24 18:48:17 +0530272 htc_credit_history_init();
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530273 qdf_spinlock_create(&target->HTCLock);
274 qdf_spinlock_create(&target->HTCRxLock);
275 qdf_spinlock_create(&target->HTCTxLock);
Govind Singhc505cdc2017-05-16 12:15:51 +0530276 for (i = 0; i < ENDPOINT_MAX; i++) {
277 pEndpoint = &target->endpoint[i];
278 qdf_spinlock_create(&pEndpoint->lookup_queue_lock);
279 }
gbianb417db22016-09-30 17:01:07 +0800280 target->is_nodrop_pkt = false;
Rakshith Suresh Patkar5aeabd62018-12-04 21:12:00 +0530281 target->htc_hdr_length_check = false;
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530282 target->wmi_ep_count = 1;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800283
284 do {
Yue Mab16cf302016-03-08 18:30:25 -0800285 qdf_mem_copy(&target->HTCInitInfo, pInfo,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700286 sizeof(struct htc_init_info));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800287 target->host_handle = pInfo->pContext;
288 target->osdev = osdev;
Yue Maec9e71c2016-02-26 18:52:20 -0800289 target->con_mode = con_mode;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800290
291 reset_endpoint_states(target);
292
293 INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
294
295 for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700296 HTC_PACKET *pPacket = (HTC_PACKET *)
297 qdf_mem_malloc(sizeof(HTC_PACKET));
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700298 if (pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800299 free_htc_packet_container(target, pPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800300 }
301
302#ifdef TODO_FIXME
303 for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
304 pPacket = build_htc_tx_ctrl_packet();
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700305 if (!pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800306 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800307 htc_free_control_tx_packet(target, pPacket);
308 }
309#endif
310
311 /* setup HIF layer callbacks */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530312 qdf_mem_zero(&htcCallbacks, sizeof(struct hif_msg_callbacks));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800313 htcCallbacks.Context = target;
314 htcCallbacks.rxCompletionHandler = htc_rx_completion_handler;
315 htcCallbacks.txCompletionHandler = htc_tx_completion_handler;
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700316 htcCallbacks.txResourceAvailHandler =
317 htc_tx_resource_avail_handler;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800318 htcCallbacks.fwEventHandler = htc_fw_event_handler;
319 target->hif_dev = ol_sc;
320
321 /* Get HIF default pipe for HTC message exchange */
Houston Hoffman29573d92015-10-20 17:49:44 -0700322 pEndpoint = &target->endpoint[ENDPOINT_0];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800323
324 hif_post_init(target->hif_dev, target, &htcCallbacks);
325 hif_get_default_pipe(target->hif_dev, &pEndpoint->UL_PipeID,
326 &pEndpoint->DL_PipeID);
Dustin Brownbbba9172017-10-04 17:03:56 -0700327 hif_set_initial_wakeup_cb(target->hif_dev,
328 pInfo->target_initial_wakeup_cb,
329 pInfo->target_psoc);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800330
331 } while (false);
332
333 htc_recv_init(target);
334
Jeff Johnsona79b1112017-09-18 10:12:02 -0700335 HTC_TRACE("-htc_create: (0x%pK)", target);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800336
337 return (HTC_HANDLE) target;
338}
339
340void htc_destroy(HTC_HANDLE HTCHandle)
341{
342 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700343
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800344 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
Jeff Johnsona79b1112017-09-18 10:12:02 -0700345 ("+htc_destroy .. Destroying :0x%pK\n", target));
Karthick Sc3a7a0c2015-10-14 17:56:55 +0530346 hif_stop(htc_get_hif_device(HTCHandle));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800347 if (target)
348 htc_cleanup(target);
349 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_destroy\n"));
350}
351
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700352/* get the low level HIF device for the caller , the caller may wish to do low
353 * level HIF requests
354 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800355void *htc_get_hif_device(HTC_HANDLE HTCHandle)
356{
357 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700358
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800359 return target->hif_dev;
360}
361
Jeff Johnsonc66399a2016-10-07 13:01:33 -0700362static void htc_control_tx_complete(void *Context, HTC_PACKET *pPacket)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800363{
364 HTC_TARGET *target = (HTC_TARGET *) Context;
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700365
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800366 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
Jeff Johnsona79b1112017-09-18 10:12:02 -0700367 ("+-htc_control_tx_complete 0x%pK (l:%d)\n", pPacket,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800368 pPacket->ActualLength));
369 htc_free_control_tx_packet(target, pPacket);
370}
371
372/* TODO, this is just a temporary max packet size */
373#define MAX_MESSAGE_SIZE 1536
374
375/**
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530376 * htc_setup_epping_credit_allocation() - allocate credits/HTC buffers to WMI
377 * @scn: pointer to hif_opaque_softc
378 * @pEntry: pointer to tx credit allocation entry
379 * @credits: number of credits
380 *
381 * Return: None
382 */
383static void
384htc_setup_epping_credit_allocation(struct hif_opaque_softc *scn,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700385 struct htc_service_tx_credit_allocation *pEntry,
386 int credits)
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530387{
388 switch (hif_get_bus_type(scn)) {
389 case QDF_BUS_TYPE_PCI:
Ajit Pal Singh47f2d052018-08-10 15:21:54 +0530390 case QDF_BUS_TYPE_USB:
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530391 pEntry++;
392 pEntry->service_id = WMI_DATA_BE_SVC;
393 pEntry->CreditAllocation = (credits >> 1);
394
395 pEntry++;
396 pEntry->service_id = WMI_DATA_BK_SVC;
397 pEntry->CreditAllocation = (credits >> 1);
398 break;
399 case QDF_BUS_TYPE_SDIO:
400 pEntry++;
401 pEntry->service_id = WMI_DATA_BE_SVC;
402 pEntry->CreditAllocation = credits;
403 break;
404 default:
405 break;
406 }
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530407}
408
409/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800410 * htc_setup_target_buffer_assignments() - setup target buffer assignments
411 * @target: HTC Target Pointer
412 *
413 * Return: A_STATUS
414 */
Jeff Johnsonc66399a2016-10-07 13:01:33 -0700415static
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800416A_STATUS htc_setup_target_buffer_assignments(HTC_TARGET *target)
417{
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700418 struct htc_service_tx_credit_allocation *pEntry;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800419 A_STATUS status;
420 int credits;
421 int creditsPerMaxMsg;
422
423 creditsPerMaxMsg = MAX_MESSAGE_SIZE / target->TargetCreditSize;
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700424 if (MAX_MESSAGE_SIZE % target->TargetCreditSize)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800425 creditsPerMaxMsg++;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800426
427 /* TODO, this should be configured by the caller! */
428
429 credits = target->TotalTransmitCredits;
430 pEntry = &target->ServiceTxAllocTable[0];
431
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530432 status = A_OK;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800433 /*
434 * Allocate all credists/HTC buffers to WMI.
435 * no buffers are used/required for data. data always
436 * remains on host.
437 */
Yue Maec9e71c2016-02-26 18:52:20 -0800438 if (HTC_IS_EPPING_ENABLED(target->con_mode)) {
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530439 pEntry++;
440 pEntry->service_id = WMI_CONTROL_SVC;
441 pEntry->CreditAllocation = credits;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800442 /* endpoint ping is a testing tool directly on top of HTC in
443 * both target and host sides.
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700444 * In target side, the endppint ping fw has no wlan stack and
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800445 * FW mboxping app directly sits on HTC and it simply drops
446 * or loops back TX packets. For rx perf, FW mboxping app
447 * generates packets and passes packets to HTC to send to host.
Jeff Johnson4b253f02018-05-12 11:34:43 -0700448 * There is no WMI message exchanges between host and target
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800449 * in endpoint ping case.
450 * In host side, the endpoint ping driver is a Ethernet driver
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530451 * and it directly sits on HTC. Only HIF, HTC, QDF, ADF are
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800452 * used by the endpoint ping driver. There is no wifi stack
453 * at all in host side also. For tx perf use case,
454 * the user space mboxping app sends the raw packets to endpoint
455 * ping driver and it directly forwards to HTC for transmission
456 * to stress the bus. For the rx perf, HTC passes the received
457 * packets to endpoint ping driver and it is passed to the user
458 * space through the Ethernet interface.
459 * For credit allocation, in SDIO bus case, only BE service is
460 * used for tx/rx perf testing so that all credits are given
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700461 * to BE service. In PCIe and USB bus case, endpoint ping uses
462 * both BE and BK services to stress the bus so that the total
463 * credits are equally distributed to BE and BK services.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800464 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800465
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530466 htc_setup_epping_credit_allocation(target->hif_dev,
467 pEntry, credits);
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530468 } else {
469 int i;
Kiran Venkatappae17e3b62017-02-10 16:31:49 +0530470 uint32_t max_wmi_svc = (sizeof(svc_id) / sizeof(uint32_t));
471
472 if ((target->wmi_ep_count == 0) ||
473 (target->wmi_ep_count > max_wmi_svc))
474 return A_ERROR;
475
476 /*
477 * Divide credit among number of endpoints for WMI
478 */
479 credits = credits / target->wmi_ep_count;
480 for (i = 0; i < target->wmi_ep_count; i++) {
481 status = A_OK;
482 pEntry++;
483 pEntry->service_id = svc_id[i];
484 pEntry->CreditAllocation = credits;
485 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800486 }
487
488 if (A_SUCCESS(status)) {
489 int i;
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700490
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800491 for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700492 if (target->ServiceTxAllocTable[i].service_id != 0) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800493 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
Rajeev Kumar885f2752018-01-18 14:55:17 -0800494 ("SVS Index : %d TX : 0x%2.2X : alloc:%d",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800495 i,
496 target->ServiceTxAllocTable[i].
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700497 service_id,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800498 target->ServiceTxAllocTable[i].
499 CreditAllocation));
500 }
501 }
502 }
503
504 return status;
505}
506
Yue Mab16cf302016-03-08 18:30:25 -0800507uint8_t htc_get_credit_allocation(HTC_TARGET *target, uint16_t service_id)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800508{
Yue Mab16cf302016-03-08 18:30:25 -0800509 uint8_t allocation = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800510 int i;
511
512 for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) {
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700513 if (target->ServiceTxAllocTable[i].service_id == service_id) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800514 allocation =
515 target->ServiceTxAllocTable[i].CreditAllocation;
516 }
517 }
518
519 if (0 == allocation) {
Srinivas Girigowda38ee3052017-03-10 16:00:40 -0800520 AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700521 ("HTC Service TX : 0x%2.2X : allocation is zero!\n",
522 service_id));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800523 }
524
525 return allocation;
526}
527
Rakesh Pillai13146452017-06-22 12:52:31 +0530528QDF_STATUS htc_wait_target(HTC_HANDLE HTCHandle)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800529{
Rakesh Pillai13146452017-06-22 12:52:31 +0530530 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800531 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
532 HTC_READY_EX_MSG *pReadyMsg;
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700533 struct htc_service_connect_req connect;
534 struct htc_service_connect_resp resp;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800535 HTC_READY_MSG *rdy_msg;
Yue Mab16cf302016-03-08 18:30:25 -0800536 uint16_t htc_rdy_msg_id;
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530537 uint8_t i = 0;
538 HTC_PACKET *rx_bundle_packet, *temp_bundle_packet;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800539
540 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
Jeff Johnsona79b1112017-09-18 10:12:02 -0700541 ("htc_wait_target - Enter (target:0x%pK)\n", HTCHandle));
Srinivas Girigowda38ee3052017-03-10 16:00:40 -0800542 AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, ("+HWT\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800543
544 do {
545
546 status = hif_start(target->hif_dev);
Rakesh Pillai13146452017-06-22 12:52:31 +0530547 if (QDF_IS_STATUS_ERROR(status)) {
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700548 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
549 ("hif_start failed\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800550 break;
551 }
552
553 status = htc_wait_recv_ctrl_message(target);
554
Rakesh Pillai13146452017-06-22 12:52:31 +0530555 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800556 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800557
558 if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
559 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700560 ("Invalid HTC Ready Msg Len:%d!\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800561 target->CtrlResponseLength));
Rakesh Pillai13146452017-06-22 12:52:31 +0530562 status = QDF_STATUS_E_BADMSG;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800563 break;
564 }
565
566 pReadyMsg = (HTC_READY_EX_MSG *) target->CtrlResponseBuffer;
567
568 rdy_msg = &pReadyMsg->Version2_0_Info;
569 htc_rdy_msg_id =
570 HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
571 if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
572 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700573 ("Invalid HTC Ready Msg : 0x%X!\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800574 htc_rdy_msg_id));
Rakesh Pillai13146452017-06-22 12:52:31 +0530575 status = QDF_STATUS_E_BADMSG;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800576 break;
577 }
578
Manjunathappa Prakash0159f812019-03-27 15:23:38 -0700579 target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg,
580 HTC_READY_MSG, CREDITCOUNT);
581 if (target->HTCInitInfo.cfg_wmi_credit_cnt &&
582 (target->HTCInitInfo.cfg_wmi_credit_cnt <
583 target->TotalTransmitCredits))
584 /*
585 * If INI configured value is less than FW advertised,
586 * then use INI configured value, otherwise use FW
587 * advertised.
588 */
589 target->TotalTransmitCredits =
590 target->HTCInitInfo.cfg_wmi_credit_cnt;
591
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800592 target->TargetCreditSize =
593 (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);
594 target->MaxMsgsPerHTCBundle =
Yue Mab16cf302016-03-08 18:30:25 -0800595 (uint8_t) pReadyMsg->MaxMsgsPerHTCBundle;
Chris Guo37cf36d2017-07-06 18:56:32 +0800596 UPDATE_ALT_CREDIT(target, pReadyMsg->AltDataCreditSize);
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700597 /* for old fw this value is set to 0. But the minimum value
598 * should be 1, i.e., no bundling
599 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800600 if (target->MaxMsgsPerHTCBundle < 1)
601 target->MaxMsgsPerHTCBundle = 1;
602
603 AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
Rajeev Kumar885f2752018-01-18 14:55:17 -0800604 ("Target Ready! TX resource : %d size:%d, MaxMsgsPerHTCBundle = %d",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800605 target->TotalTransmitCredits,
606 target->TargetCreditSize,
607 target->MaxMsgsPerHTCBundle));
608
609 if ((0 == target->TotalTransmitCredits)
610 || (0 == target->TargetCreditSize)) {
Rakesh Pillai13146452017-06-22 12:52:31 +0530611 status = QDF_STATUS_E_ABORTED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800612 break;
613 }
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530614
615 /* Allocate expected number of RX bundle buffer allocation */
616 if (HTC_RX_BUNDLE_ENABLED(target)) {
617 temp_bundle_packet = NULL;
618 for (i = 0; i < MAX_HTC_RX_BUNDLE; i++) {
619 rx_bundle_packet =
620 allocate_htc_bundle_packet(target);
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700621 if (rx_bundle_packet)
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530622 rx_bundle_packet->ListLink.pNext =
623 (DL_LIST *)temp_bundle_packet;
624 else
625 break;
626
627 temp_bundle_packet = rx_bundle_packet;
628 }
wadesongfbf643a2017-10-14 09:11:34 +0800629 LOCK_HTC_TX(target);
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530630 target->pBundleFreeList = temp_bundle_packet;
wadesongfbf643a2017-10-14 09:11:34 +0800631 UNLOCK_HTC_TX(target);
Poddar, Siddarthf1763402016-11-21 15:55:27 +0530632 }
633
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800634 /* done processing */
635 target->CtrlResponseProcessing = false;
636
637 htc_setup_target_buffer_assignments(target);
638
639 /* setup our pseudo HTC control endpoint connection */
Yue Mab16cf302016-03-08 18:30:25 -0800640 qdf_mem_zero(&connect, sizeof(connect));
641 qdf_mem_zero(&resp, sizeof(resp));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800642 connect.EpCallbacks.pContext = target;
643 connect.EpCallbacks.EpTxComplete = htc_control_tx_complete;
644 connect.EpCallbacks.EpRecv = htc_control_rx_complete;
645 connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700646 connect.service_id = HTC_CTRL_RSVD_SVC;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800647
648 /* connect fake service */
649 status = htc_connect_service((HTC_HANDLE) target,
650 &connect, &resp);
651
652 } while (false);
653
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700654 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Exit (%d)\n",
655 status));
Srinivas Girigowda38ee3052017-03-10 16:00:40 -0800656 AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, ("-HWT\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800657 return status;
658}
659
660/* start HTC, this is called after all services are connected */
661static A_STATUS htc_config_target_hif_pipe(HTC_TARGET *target)
662{
663
664 return A_OK;
665}
666
667static void reset_endpoint_states(HTC_TARGET *target)
668{
669 HTC_ENDPOINT *pEndpoint;
670 int i;
671
672 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700673 pEndpoint = &target->endpoint[i];
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700674 pEndpoint->service_id = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800675 pEndpoint->MaxMsgLength = 0;
676 pEndpoint->MaxTxQueueDepth = 0;
677 pEndpoint->Id = i;
678 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
679 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxLookupQueue);
680 INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBufferHoldQueue);
681 pEndpoint->target = target;
Yue Mab16cf302016-03-08 18:30:25 -0800682 pEndpoint->TxCreditFlowEnabled = (bool)htc_credit_flow;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530683 qdf_atomic_init(&pEndpoint->TxProcessCount);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800684 }
685}
686
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700687/**
688 * htc_start() - Main HTC function to trigger HTC start
689 * @HTCHandle: pointer to HTC handle
690 *
Rakesh Pillai13146452017-06-22 12:52:31 +0530691 * Return: QDF_STATUS_SUCCESS for success or an appropriate QDF_STATUS error
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700692 */
Rakesh Pillai13146452017-06-22 12:52:31 +0530693QDF_STATUS htc_start(HTC_HANDLE HTCHandle)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800694{
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530695 qdf_nbuf_t netbuf;
Rakesh Pillai13146452017-06-22 12:52:31 +0530696 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800697 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
698 HTC_SETUP_COMPLETE_EX_MSG *pSetupComp;
699 HTC_PACKET *pSendPacket;
700
701 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Enter\n"));
702
703 do {
704
705 htc_config_target_hif_pipe(target);
706
707 /* allocate a buffer to send */
708 pSendPacket = htc_alloc_control_tx_packet(target);
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700709 if (!pSendPacket) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800710 AR_DEBUG_ASSERT(false);
Aditya Sathish648ce112018-07-02 16:41:39 +0530711 qdf_print("%s: allocControlTxPacket failed",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800712 __func__);
Rakesh Pillai13146452017-06-22 12:52:31 +0530713 status = QDF_STATUS_E_NOMEM;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800714 break;
715 }
716
717 netbuf =
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530718 (qdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800719 /* assemble setup complete message */
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530720 qdf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800721 pSetupComp =
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530722 (HTC_SETUP_COMPLETE_EX_MSG *) qdf_nbuf_data(netbuf);
Yue Mab16cf302016-03-08 18:30:25 -0800723 qdf_mem_zero(pSetupComp, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800724
725 HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG,
726 MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID);
727
728 if (!htc_credit_flow) {
Manjunathappa Prakash85b801e2018-08-14 18:18:10 -0700729 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
Rajeev Kumar885f2752018-01-18 14:55:17 -0800730 ("HTC will not use TX credit flow control"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800731 pSetupComp->SetupFlags |=
732 HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW;
733 } else {
Manjunathappa Prakash85b801e2018-08-14 18:18:10 -0700734 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
Rajeev Kumar885f2752018-01-18 14:55:17 -0800735 ("HTC using TX credit flow control"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800736 }
737
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700738 if ((hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_SDIO) ||
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700739 (hif_get_bus_type(target->hif_dev) ==
740 QDF_BUS_TYPE_USB)) {
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700741 if (HTC_RX_BUNDLE_ENABLED(target))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800742 pSetupComp->SetupFlags |=
743 HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700744 hif_set_bundle_mode(target->hif_dev, true,
745 HTC_MAX_MSG_PER_BUNDLE_RX);
Ajit Pal Singhed6f03b2019-01-25 12:16:14 +0530746 pSetupComp->MaxMsgsPerBundledRecv = HTC_MAX_MSG_PER_BUNDLE_RX;
Mohit Khanna0f6194e2016-05-17 15:30:44 -0700747 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800748
749 SET_HTC_PACKET_INFO_TX(pSendPacket,
750 NULL,
Yue Mab16cf302016-03-08 18:30:25 -0800751 (uint8_t *) pSetupComp,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800752 sizeof(HTC_SETUP_COMPLETE_EX_MSG),
753 ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
754
755 status = htc_send_pkt((HTC_HANDLE) target, pSendPacket);
Rakesh Pillai13146452017-06-22 12:52:31 +0530756 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800757 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800758 } while (false);
759
760 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Exit\n"));
761 return status;
762}
763
764/*flush all queued buffers for surpriseremove case*/
765void htc_flush_surprise_remove(HTC_HANDLE HTCHandle)
766{
767 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
768 int i;
769 HTC_ENDPOINT *pEndpoint;
770#ifdef RX_SG_SUPPORT
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530771 qdf_nbuf_t netbuf;
772 qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800773#endif
774
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530775 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_flush_surprise_remove\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800776
777 /* cleanup endpoints */
778 for (i = 0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700779 pEndpoint = &target->endpoint[i];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800780 htc_flush_rx_hold_queue(target, pEndpoint);
781 htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
782 }
783
784 hif_flush_surprise_remove(target->hif_dev);
785
786#ifdef RX_SG_SUPPORT
787 LOCK_HTC_RX(target);
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530788 while ((netbuf = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
789 qdf_nbuf_free(netbuf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800790 RESET_RX_SG_CONFIG(target);
791 UNLOCK_HTC_RX(target);
792#endif
793
794 reset_endpoint_states(target);
795
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700796 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_flush_surprise_remove\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800797}
798
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700799/* stop HTC communications, i.e. stop interrupt reception, and flush all queued
800 * buffers
801 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800802void htc_stop(HTC_HANDLE HTCHandle)
803{
804 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
805 int i;
806 HTC_ENDPOINT *pEndpoint;
807#ifdef RX_SG_SUPPORT
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530808 qdf_nbuf_t netbuf;
809 qdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800810#endif
811
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530812 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_stop\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800813
Vevek Venkatesan9448b3a2019-05-28 12:47:20 +0530814 HTC_INFO("%s: endpoints cleanup\n", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800815 /* cleanup endpoints */
816 for (i = 0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700817 pEndpoint = &target->endpoint[i];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800818 htc_flush_rx_hold_queue(target, pEndpoint);
819 htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL);
820 if (pEndpoint->ul_is_polled) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530821 qdf_timer_stop(&pEndpoint->ul_poll_timer);
822 qdf_timer_free(&pEndpoint->ul_poll_timer);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800823 }
824 }
825
826 /* Note: htc_flush_endpoint_tx for all endpoints should be called before
827 * hif_stop - otherwise htc_tx_completion_handler called from
828 * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer,
829 * might queue the packet again to HIF Layer - which could cause tx
830 * buffer leak
831 */
832
Vevek Venkatesan9448b3a2019-05-28 12:47:20 +0530833 HTC_INFO("%s: stopping hif layer\n", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800834 hif_stop(target->hif_dev);
835
836#ifdef RX_SG_SUPPORT
837 LOCK_HTC_RX(target);
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530838 while ((netbuf = qdf_nbuf_queue_remove(rx_sg_queue)) != NULL)
839 qdf_nbuf_free(netbuf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800840 RESET_RX_SG_CONFIG(target);
841 UNLOCK_HTC_RX(target);
842#endif
843
Zhang Qianedaa3872018-07-04 20:02:53 +0800844 /**
845 * In SSR case, HTC tx completion callback for wmi will be blocked
846 * by TARGET_STATUS_RESET and HTC packets will be left unfreed on
847 * lookup queue.
848 */
Vevek Venkatesan9448b3a2019-05-28 12:47:20 +0530849 HTC_INFO("%s: flush endpoints Tx lookup queue\n", __func__);
Zhang Qianedaa3872018-07-04 20:02:53 +0800850 for (i = 0; i < ENDPOINT_MAX; i++) {
851 pEndpoint = &target->endpoint[i];
852 if (pEndpoint->service_id == WMI_CONTROL_SVC)
853 htc_flush_endpoint_txlookupQ(target, i, false);
854 }
Vevek Venkatesan9448b3a2019-05-28 12:47:20 +0530855 HTC_INFO("%s: resetting endpoints state\n", __func__);
Zhang Qianedaa3872018-07-04 20:02:53 +0800856
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800857 reset_endpoint_states(target);
858
Houston Hoffman47e387b2015-10-20 17:04:42 -0700859 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop\n"));
860}
861
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800862void htc_dump_credit_states(HTC_HANDLE HTCHandle)
863{
864 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
865 HTC_ENDPOINT *pEndpoint;
866 int i;
867
868 for (i = 0; i < ENDPOINT_MAX; i++) {
Houston Hoffman29573d92015-10-20 17:49:44 -0700869 pEndpoint = &target->endpoint[i];
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700870 if (0 == pEndpoint->service_id)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800871 continue;
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700872
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800873 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700874 ("--- EP : %d service_id: 0x%X --------------\n",
875 pEndpoint->Id, pEndpoint->service_id));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800876 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700877 (" TxCredits : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800878 pEndpoint->TxCredits));
879 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700880 (" TxCreditSize : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800881 pEndpoint->TxCreditSize));
882 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700883 (" TxCreditsPerMaxMsg : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800884 pEndpoint->TxCreditsPerMaxMsg));
885 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700886 (" TxQueueDepth : %d\n",
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800887 HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
888 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700889 ("----------------------------------------\n"));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800890 }
891}
892
Yue Mab16cf302016-03-08 18:30:25 -0800893bool htc_get_endpoint_statistics(HTC_HANDLE HTCHandle,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800894 HTC_ENDPOINT_ID Endpoint,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700895 enum htc_endpoint_stat_action Action,
896 struct htc_endpoint_stats *pStats)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800897{
898#ifdef HTC_EP_STAT_PROFILING
899 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
Yue Mab16cf302016-03-08 18:30:25 -0800900 bool clearStats = false;
901 bool sample = false;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800902
903 switch (Action) {
904 case HTC_EP_STAT_SAMPLE:
905 sample = true;
906 break;
907 case HTC_EP_STAT_SAMPLE_AND_CLEAR:
908 sample = true;
909 clearStats = true;
910 break;
911 case HTC_EP_STAT_CLEAR:
912 clearStats = true;
913 break;
914 default:
915 break;
916 }
917
918 A_ASSERT(Endpoint < ENDPOINT_MAX);
919
920 /* lock out TX and RX while we sample and/or clear */
921 LOCK_HTC_TX(target);
922 LOCK_HTC_RX(target);
923
924 if (sample) {
Jeff Johnson5a6cc792019-03-18 09:47:18 -0700925 A_ASSERT(pStats);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800926 /* return the stats to the caller */
Yue Mab16cf302016-03-08 18:30:25 -0800927 qdf_mem_copy(pStats, &target->endpoint[Endpoint].endpoint_stats,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700928 sizeof(struct htc_endpoint_stats));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800929 }
930
931 if (clearStats) {
932 /* reset stats */
Yue Mab16cf302016-03-08 18:30:25 -0800933 qdf_mem_zero(&target->endpoint[Endpoint].endpoint_stats,
Manikandan Mohane3e209e2017-04-13 20:19:26 -0700934 sizeof(struct htc_endpoint_stats));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800935 }
936
937 UNLOCK_HTC_RX(target);
938 UNLOCK_HTC_TX(target);
939
940 return true;
941#else
942 return false;
943#endif
944}
945
946void *htc_get_targetdef(HTC_HANDLE htc_handle)
947{
948 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
949
950 return hif_get_targetdef(target->hif_dev);
951}
952
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800953#ifdef IPA_OFFLOAD
Leo Changd85f78d2015-11-13 10:55:34 -0800954/**
955 * htc_ipa_get_ce_resource() - get uc resource on lower layer
956 * @htc_handle: htc context
957 * @ce_sr_base_paddr: copyengine source ring base physical address
958 * @ce_sr_ring_size: copyengine source ring size
959 * @ce_reg_paddr: copyengine register physical address
960 *
961 * Return: None
962 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800963void htc_ipa_get_ce_resource(HTC_HANDLE htc_handle,
Sravan Kumar Kairam58e0adf2018-02-27 18:37:40 +0530964 qdf_shared_mem_t **ce_sr,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800965 uint32_t *ce_sr_ring_size,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530966 qdf_dma_addr_t *ce_reg_paddr)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800967{
968 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
969
Sravan Kumar Kairam58e0adf2018-02-27 18:37:40 +0530970 if (target->hif_dev)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800971 hif_ipa_get_ce_resource(target->hif_dev,
Sravan Kumar Kairam58e0adf2018-02-27 18:37:40 +0530972 ce_sr, ce_sr_ring_size, ce_reg_paddr);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800973}
974#endif /* IPA_OFFLOAD */
Komal Seelamf8600682016-02-02 18:17:13 +0530975
Poddar, Siddarthdf030092016-04-28 11:41:57 +0530976#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
977
978void htc_dump_bundle_stats(HTC_HANDLE HTCHandle)
979{
980 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
981 int total, i;
982
983 total = 0;
984 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
985 total += target->rx_bundle_stats[i];
986
987 if (total) {
988 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("RX Bundle stats:\n"));
989 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total RX packets: %d\n",
990 total));
991 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (
992 "Number of bundle: Number of packets\n"));
993 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_RX; i++)
994 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
995 ("%10d:%10d(%2d%s)\n", (i+1),
996 target->rx_bundle_stats[i],
997 ((target->rx_bundle_stats[i]*100)/
998 total), "%"));
999 }
1000
1001
1002 total = 0;
1003 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
1004 total += target->tx_bundle_stats[i];
1005
1006 if (total) {
1007 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("TX Bundle stats:\n"));
1008 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("Total TX packets: %d\n",
1009 total));
1010 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
1011 ("Number of bundle: Number of packets\n"));
1012 for (i = 0; i < HTC_MAX_MSG_PER_BUNDLE_TX; i++)
1013 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
1014 ("%10d:%10d(%2d%s)\n", (i+1),
1015 target->tx_bundle_stats[i],
1016 ((target->tx_bundle_stats[i]*100)/
1017 total), "%"));
1018 }
1019}
1020
1021void htc_clear_bundle_stats(HTC_HANDLE HTCHandle)
1022{
1023 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1024
1025 qdf_mem_zero(&target->rx_bundle_stats, sizeof(target->rx_bundle_stats));
1026 qdf_mem_zero(&target->tx_bundle_stats, sizeof(target->tx_bundle_stats));
1027}
1028#endif
1029
Komal Seelamf8600682016-02-02 18:17:13 +05301030/**
1031 * htc_vote_link_down - API to vote for link down
1032 * @htc_handle: HTC handle
1033 *
1034 * API for upper layers to call HIF to vote for link down
1035 *
1036 * Return: void
1037 */
1038void htc_vote_link_down(HTC_HANDLE htc_handle)
1039{
1040 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1041
1042 if (!target->hif_dev)
1043 return;
1044
1045 hif_vote_link_down(target->hif_dev);
1046}
1047
1048/**
1049 * htc_vote_link_up - API to vote for link up
1050 * @htc_handle: HTC Handle
1051 *
1052 * API for upper layers to call HIF to vote for link up
1053 *
1054 * Return: void
1055 */
1056void htc_vote_link_up(HTC_HANDLE htc_handle)
1057{
1058 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1059
1060 if (!target->hif_dev)
1061 return;
1062
1063 hif_vote_link_up(target->hif_dev);
1064}
1065
1066/**
1067 * htc_can_suspend_link - API to query HIF for link status
1068 * @htc_handle: HTC Handle
1069 *
1070 * API for upper layers to call HIF to query if the link can suspend
1071 *
1072 * Return: void
1073 */
1074bool htc_can_suspend_link(HTC_HANDLE htc_handle)
1075{
1076 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1077
1078 if (!target->hif_dev)
1079 return false;
1080
1081 return hif_can_suspend_link(target->hif_dev);
1082}
Houston Hoffman4d9b0802016-07-20 10:10:35 -07001083
1084#ifdef FEATURE_RUNTIME_PM
1085int htc_pm_runtime_get(HTC_HANDLE htc_handle)
1086{
1087 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1088
Houston Hoffman4d9b0802016-07-20 10:10:35 -07001089 return hif_pm_runtime_get(target->hif_dev);
1090}
1091
1092int htc_pm_runtime_put(HTC_HANDLE htc_handle)
1093{
1094 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1095
Houston Hoffman4d9b0802016-07-20 10:10:35 -07001096 return hif_pm_runtime_put(target->hif_dev);
1097}
1098#endif
Kiran Venkatappae17e3b62017-02-10 16:31:49 +05301099
1100/**
1101 * htc_set_wmi_endpoint_count: Set number of WMI endpoint
1102 * @htc_handle: HTC handle
1103 * @wmi_ep_count: WMI enpoint count
1104 *
1105 * return: None
1106 */
1107void htc_set_wmi_endpoint_count(HTC_HANDLE htc_handle, uint8_t wmi_ep_count)
1108{
1109 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1110
1111 target->wmi_ep_count = wmi_ep_count;
1112}
1113
1114/**
1115 * htc_get_wmi_endpoint_count: Get number of WMI endpoint
1116 * @htc_handle: HTC handle
1117 *
1118 * return: WMI enpoint count
1119 */
1120uint8_t htc_get_wmi_endpoint_count(HTC_HANDLE htc_handle)
1121{
1122 HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle);
1123
1124 return target->wmi_ep_count;
1125}