blob: 03a7f378f87c4b17137b727daf1042d9d24f8925 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Rajeev Kumar15cf7ab2017-01-21 15:52:36 -08002 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -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
28/*
29 *
30 * Permission to use, copy, modify, and/or distribute this software for any
31 * purpose with or without fee is hereby granted, provided that the above
32 * copyright notice and this permission notice appear in all copies.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
35 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
37 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
39 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
40 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 */
42
43#ifndef REMOVE_PKT_LOG
Anurag Chouhan600c3a02016-03-01 10:33:54 +053044#include "qdf_mem.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080045#include "athdefs.h"
46#include "pktlog_ac_i.h"
47#include "cds_api.h"
48#include "wma_types.h"
Nirav Shah7f337db2016-05-25 10:49:02 +053049#include "htc.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050
51wdi_event_subscribe PKTLOG_TX_SUBSCRIBER;
52wdi_event_subscribe PKTLOG_RX_SUBSCRIBER;
53wdi_event_subscribe PKTLOG_RX_REMOTE_SUBSCRIBER;
54wdi_event_subscribe PKTLOG_RCFIND_SUBSCRIBER;
55wdi_event_subscribe PKTLOG_RCUPDATE_SUBSCRIBER;
Nirav Shahdcc4c872016-07-28 11:35:26 +053056wdi_event_subscribe PKTLOG_SW_EVENT_SUBSCRIBER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057
58struct ol_pl_arch_dep_funcs ol_pl_funcs = {
59 .pktlog_init = pktlog_init,
60 .pktlog_enable = pktlog_enable,
61 .pktlog_setsize = pktlog_setsize,
62 .pktlog_disable = pktlog_disable, /* valid for f/w disable */
63};
64
65struct ol_pktlog_dev_t ol_pl_dev = {
66 .pl_funcs = &ol_pl_funcs,
67};
68
Komal Seelam3d202862016-02-24 18:43:24 +053069void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle,
70 struct hif_opaque_softc *scn)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071{
72 ol_pl_dev.scn = (ol_ath_generic_softc_handle) scn;
73 *pl_handle = &ol_pl_dev;
74}
75
76static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types,
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080077 WMI_CMD_ID cmd_id, bool ini_triggered,
78 uint8_t user_triggered)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079{
Rajeev Kumar15cf7ab2017-01-21 15:52:36 -080080 struct scheduler_msg msg = { 0 };
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053081 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080082 struct ath_pktlog_wmi_params *param;
83
Anurag Chouhan600c3a02016-03-01 10:33:54 +053084 param = qdf_mem_malloc(sizeof(struct ath_pktlog_wmi_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085
86 if (!param)
87 return A_NO_MEMORY;
88
89 param->cmd_id = cmd_id;
90 param->pktlog_event = event_types;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080091 param->ini_triggered = ini_triggered;
92 param->user_triggered = user_triggered;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080093
94 msg.type = WMA_PKTLOG_ENABLE_REQ;
95 msg.bodyptr = param;
96 msg.bodyval = 0;
97
Rajeev Kumar15cf7ab2017-01-21 15:52:36 -080098 status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530100 if (status != QDF_STATUS_SUCCESS) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530101 qdf_mem_free(param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102 return A_ERROR;
103 }
104
105 return A_OK;
106}
107
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800108static inline A_STATUS
109pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state,
110 bool ini_triggered, uint8_t user_triggered)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800111{
112 uint32_t types = 0;
113
114 if (log_state & ATH_PKTLOG_TX)
115 types |= WMI_PKTLOG_EVENT_TX;
116
117 if (log_state & ATH_PKTLOG_RX)
118 types |= WMI_PKTLOG_EVENT_RX;
119
120 if (log_state & ATH_PKTLOG_RCFIND)
121 types |= WMI_PKTLOG_EVENT_RCF;
122
123 if (log_state & ATH_PKTLOG_RCUPDATE)
124 types |= WMI_PKTLOG_EVENT_RCU;
125
Nirav Shahdcc4c872016-07-28 11:35:26 +0530126 if (log_state & ATH_PKTLOG_SW_EVENT)
127 types |= WMI_PKTLOG_EVENT_SW;
128
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800129 return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID,
130 ini_triggered, user_triggered);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800131}
132
133static inline A_STATUS
134wdi_pktlog_subscribe(struct ol_txrx_pdev_t *txrx_pdev, int32_t log_state)
135{
136 if (!txrx_pdev) {
137 printk("Invalid pdev in %s\n", __func__);
138 return A_ERROR;
139 }
140 if (log_state & ATH_PKTLOG_TX) {
141 if (wdi_event_sub(txrx_pdev,
142 &PKTLOG_TX_SUBSCRIBER, WDI_EVENT_TX_STATUS)) {
143 return A_ERROR;
144 }
145 }
146 if (log_state & ATH_PKTLOG_RX) {
147 if (wdi_event_sub(txrx_pdev,
148 &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) {
149 return A_ERROR;
150 }
151 if (wdi_event_sub(txrx_pdev,
152 &PKTLOG_RX_REMOTE_SUBSCRIBER,
153 WDI_EVENT_RX_DESC_REMOTE)) {
154 return A_ERROR;
155 }
156 }
157 if (log_state & ATH_PKTLOG_RCFIND) {
158 if (wdi_event_sub(txrx_pdev,
159 &PKTLOG_RCFIND_SUBSCRIBER,
160 WDI_EVENT_RATE_FIND)) {
161 return A_ERROR;
162 }
163 }
164 if (log_state & ATH_PKTLOG_RCUPDATE) {
165 if (wdi_event_sub(txrx_pdev,
166 &PKTLOG_RCUPDATE_SUBSCRIBER,
167 WDI_EVENT_RATE_UPDATE)) {
168 return A_ERROR;
169 }
170 }
Nirav Shahdcc4c872016-07-28 11:35:26 +0530171 if (log_state & ATH_PKTLOG_SW_EVENT) {
172 if (wdi_event_sub(txrx_pdev,
173 &PKTLOG_SW_EVENT_SUBSCRIBER,
174 WDI_EVENT_SW_EVENT)) {
175 return A_ERROR;
176 }
177 }
178
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 return A_OK;
180}
181
182void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data)
183{
184 switch (event) {
185 case WDI_EVENT_TX_STATUS:
186 {
187 /*
188 * process TX message
189 */
190 if (process_tx_info(pdev, log_data)) {
191 printk("Unable to process TX info\n");
192 return;
193 }
194 break;
195 }
196 case WDI_EVENT_RX_DESC:
197 {
198 /*
199 * process RX message for local frames
200 */
201 if (process_rx_info(pdev, log_data)) {
202 printk("Unable to process RX info\n");
203 return;
204 }
205 break;
206 }
207 case WDI_EVENT_RX_DESC_REMOTE:
208 {
209 /*
210 * process RX message for remote frames
211 */
212 if (process_rx_info_remote(pdev, log_data)) {
213 printk("Unable to process RX info\n");
214 return;
215 }
216 break;
217 }
218 case WDI_EVENT_RATE_FIND:
219 {
220 /*
221 * process RATE_FIND message
222 */
223 if (process_rate_find(pdev, log_data)) {
224 printk("Unable to process RC_FIND info\n");
225 return;
226 }
227 break;
228 }
229 case WDI_EVENT_RATE_UPDATE:
230 {
231 /*
232 * process RATE_UPDATE message
233 */
234 if (process_rate_update(pdev, log_data)) {
235 printk("Unable to process RC_UPDATE\n");
236 return;
237 }
238 break;
239 }
Nirav Shahdcc4c872016-07-28 11:35:26 +0530240 case WDI_EVENT_SW_EVENT:
241 {
242 /*
243 * process SW EVENT message
244 */
245 if (process_sw_event(pdev, log_data)) {
246 printk("Unable to process SW_EVENT\n");
247 return;
248 }
249 break;
250 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251 default:
252 break;
253 }
254}
255
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800256A_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state)
258{
259 if (log_state & ATH_PKTLOG_TX) {
260 if (wdi_event_unsub(txrx_pdev,
261 &PKTLOG_TX_SUBSCRIBER,
262 WDI_EVENT_TX_STATUS)) {
263 return A_ERROR;
264 }
265 }
266 if (log_state & ATH_PKTLOG_RX) {
267 if (wdi_event_unsub(txrx_pdev,
268 &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) {
269 return A_ERROR;
270 }
271 if (wdi_event_unsub(txrx_pdev,
272 &PKTLOG_RX_REMOTE_SUBSCRIBER,
273 WDI_EVENT_RX_DESC_REMOTE)) {
274 return A_ERROR;
275 }
276 }
277 if (log_state & ATH_PKTLOG_RCFIND) {
278 if (wdi_event_unsub(txrx_pdev,
279 &PKTLOG_RCFIND_SUBSCRIBER,
280 WDI_EVENT_RATE_FIND)) {
281 return A_ERROR;
282 }
283 }
284 if (log_state & ATH_PKTLOG_RCUPDATE) {
285 if (wdi_event_unsub(txrx_pdev,
286 &PKTLOG_RCUPDATE_SUBSCRIBER,
287 WDI_EVENT_RATE_UPDATE)) {
288 return A_ERROR;
289 }
290 }
Nirav Shahdcc4c872016-07-28 11:35:26 +0530291 if (log_state & ATH_PKTLOG_RCUPDATE) {
292 if (wdi_event_unsub(txrx_pdev,
293 &PKTLOG_SW_EVENT_SUBSCRIBER,
294 WDI_EVENT_SW_EVENT)) {
295 return A_ERROR;
296 }
297 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298 return A_OK;
299}
300
Komal Seelam3d202862016-02-24 18:43:24 +0530301int pktlog_disable(struct hif_opaque_softc *scn)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302{
303 struct ol_txrx_pdev_t *txrx_pdev =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530304 cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305 struct ol_pktlog_dev_t *pl_dev;
306 struct ath_pktlog_info *pl_info;
307
308 if (txrx_pdev == NULL ||
309 txrx_pdev->pl_dev == NULL ||
310 txrx_pdev->pl_dev->pl_info == NULL)
311 return -EFAULT;
312
313 pl_dev = txrx_pdev->pl_dev;
314 pl_info = pl_dev->pl_info;
315
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800316 if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID, 0, 0)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800317 printk("Failed to disable pktlog in target\n");
318 return -1;
319 }
320
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800321 if (pl_dev->is_pktlog_cb_subscribed &&
322 wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323 printk("Cannot unsubscribe pktlog from the WDI\n");
324 return -1;
325 }
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800326 pl_dev->is_pktlog_cb_subscribed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 return 0;
328}
329
Komal Seelam3d202862016-02-24 18:43:24 +0530330void pktlog_init(struct hif_opaque_softc *scn)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331{
332 struct ath_pktlog_info *pl_info;
333 ol_txrx_pdev_handle pdev_txrx_handle;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530334 pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800335
336 if (pdev_txrx_handle == NULL ||
337 pdev_txrx_handle->pl_dev == NULL ||
338 pdev_txrx_handle->pl_dev->pl_info == NULL)
339 return;
340
341 pl_info = pdev_txrx_handle->pl_dev->pl_info;
342
343 OS_MEMZERO(pl_info, sizeof(*pl_info));
344 PKTLOG_LOCK_INIT(pl_info);
345
346 pl_info->buf_size = PKTLOG_DEFAULT_BUFSIZE;
347 pl_info->buf = NULL;
348 pl_info->log_state = 0;
349 pl_info->sack_thr = PKTLOG_DEFAULT_SACK_THR;
350 pl_info->tail_length = PKTLOG_DEFAULT_TAIL_LENGTH;
351 pl_info->thruput_thresh = PKTLOG_DEFAULT_THRUPUT_THRESH;
352 pl_info->per_thresh = PKTLOG_DEFAULT_PER_THRESH;
353 pl_info->phyerr_thresh = PKTLOG_DEFAULT_PHYERR_THRESH;
354 pl_info->trigger_interval = PKTLOG_DEFAULT_TRIGGER_INTERVAL;
355 pl_info->pktlen = 0;
356 pl_info->start_time_thruput = 0;
357 pl_info->start_time_per = 0;
Poddar, Siddartheefe3482016-09-21 18:12:59 +0530358 pdev_txrx_handle->pl_dev->vendor_cmd_send = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359
360 PKTLOG_TX_SUBSCRIBER.callback = pktlog_callback;
361 PKTLOG_RX_SUBSCRIBER.callback = pktlog_callback;
362 PKTLOG_RX_REMOTE_SUBSCRIBER.callback = pktlog_callback;
363 PKTLOG_RCFIND_SUBSCRIBER.callback = pktlog_callback;
364 PKTLOG_RCUPDATE_SUBSCRIBER.callback = pktlog_callback;
Nirav Shahdcc4c872016-07-28 11:35:26 +0530365 PKTLOG_SW_EVENT_SUBSCRIBER.callback = pktlog_callback;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366}
367
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800368int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state,
Poddar, Siddartheefe3482016-09-21 18:12:59 +0530369 bool ini_triggered, uint8_t user_triggered,
370 uint32_t is_iwpriv_command)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800371{
372 struct ol_pktlog_dev_t *pl_dev;
373 struct ath_pktlog_info *pl_info;
374 struct ol_txrx_pdev_t *txrx_pdev;
375 int error;
376
377 if (!scn) {
378 printk("%s: Invalid scn context\n", __func__);
379 ASSERT(0);
380 return -1;
381 }
382
Anurag Chouhan6d760662016-02-20 16:05:43 +0530383 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 if (!txrx_pdev) {
385 printk("%s: Invalid txrx_pdev context\n", __func__);
386 ASSERT(0);
387 return -1;
388 }
389
390 pl_dev = txrx_pdev->pl_dev;
391 if (!pl_dev) {
392 printk("%s: Invalid pktlog context\n", __func__);
393 ASSERT(0);
394 return -1;
395 }
396
397 pl_info = pl_dev->pl_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398
399 if (!pl_info)
400 return 0;
401
Poddar, Siddartheefe3482016-09-21 18:12:59 +0530402 /* is_iwpriv_command : 0 indicates its a vendor command
403 * log_state: 0 indicates pktlog disable command
404 * vendor_cmd_send flag; false means no vendor pktlog enable
405 * command was sent previously
406 */
407 if (is_iwpriv_command == 0 && log_state == 0 &&
408 pl_dev->vendor_cmd_send == false)
409 return 0;
410
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800411 if (!pl_dev->tgt_pktlog_alloced) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412 if (pl_info->buf == NULL) {
413 error = pktlog_alloc_buf(scn);
414
415 if (error != 0)
416 return error;
417
418 if (!pl_info->buf) {
419 printk("%s: pktlog buf alloc failed\n",
420 __func__);
421 ASSERT(0);
422 return -1;
423 }
424
425 }
426
427 pl_info->buf->bufhdr.version = CUR_PKTLOG_VER;
428 pl_info->buf->bufhdr.magic_num = PKTLOG_MAGIC_NUM;
429 pl_info->buf->wr_offset = 0;
430 pl_info->buf->rd_offset = -1;
431 /* These below variables are used by per packet stats*/
432 pl_info->buf->bytes_written = 0;
433 pl_info->buf->msg_index = 1;
434 pl_info->buf->offset = PKTLOG_READ_OFFSET;
435
436 pl_info->start_time_thruput = os_get_timestamp();
437 pl_info->start_time_per = pl_info->start_time_thruput;
438
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800439 pl_dev->tgt_pktlog_alloced = true;
440 }
441
442 if (log_state != 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800443 /* WDI subscribe */
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800444 if ((!pl_dev->is_pktlog_cb_subscribed) &&
445 wdi_pktlog_subscribe(txrx_pdev, log_state)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446 printk("Unable to subscribe to the WDI %s\n", __func__);
447 return -1;
448 }
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800449 pl_dev->is_pktlog_cb_subscribed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450 /* WMI command to enable pktlog on the firmware */
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800451 if (pktlog_enable_tgt(scn, log_state, ini_triggered,
452 user_triggered)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 printk("Device cannot be enabled, %s\n", __func__);
454 return -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 }
Poddar, Siddartheefe3482016-09-21 18:12:59 +0530456
457 if (is_iwpriv_command == 0)
458 pl_dev->vendor_cmd_send = true;
Poddar, Siddarth49fb4d72016-09-21 16:56:32 +0530459 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 pl_dev->pl_funcs->pktlog_disable(scn);
Poddar, Siddartheefe3482016-09-21 18:12:59 +0530461 if (is_iwpriv_command == 0)
462 pl_dev->vendor_cmd_send = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 }
464
465 pl_info->log_state = log_state;
466 return 0;
467}
468
Komal Seelam3d202862016-02-24 18:43:24 +0530469int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470{
471 ol_txrx_pdev_handle pdev_txrx_handle =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530472 cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800473 struct ol_pktlog_dev_t *pl_dev;
474 struct ath_pktlog_info *pl_info;
475
476 if (pdev_txrx_handle == NULL ||
477 pdev_txrx_handle->pl_dev == NULL ||
478 pdev_txrx_handle->pl_dev->pl_info == NULL)
479 return -EFAULT;
480
481 pl_dev = pdev_txrx_handle->pl_dev;
482 pl_info = pl_dev->pl_info;
483
484 if (size < 0)
485 return -EINVAL;
486
Poddar, Siddarth176c4362016-10-03 12:25:00 +0530487 if (size == pl_info->buf_size) {
488 qdf_print("%s: Pktlog Buff Size is already of same size.",
489 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 return 0;
Poddar, Siddarth176c4362016-10-03 12:25:00 +0530491 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492
493 if (pl_info->log_state) {
Poddar, Siddarth176c4362016-10-03 12:25:00 +0530494 qdf_print("%s: Logging should be disabled before changing"
495 "buffer size.", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 return -EINVAL;
497 }
498
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800499 if (pl_info->buf != NULL) {
500 if (pl_dev->is_pktlog_cb_subscribed &&
501 wdi_pktlog_unsubscribe(pdev_txrx_handle,
502 pl_info->log_state)) {
503 printk("Cannot unsubscribe pktlog from the WDI\n");
504 return -EFAULT;
505 }
Houston Hoffman8c485042017-02-08 13:40:21 -0800506 pktlog_release_buf(pdev_txrx_handle);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800507 pl_dev->is_pktlog_cb_subscribed = false;
508 pl_dev->tgt_pktlog_alloced = false;
509 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510
Poddar, Siddarth176c4362016-10-03 12:25:00 +0530511 if (size != 0) {
512 qdf_print("%s: New Pktlog Buff Size is %d\n", __func__, size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513 pl_info->buf_size = size;
Poddar, Siddarth176c4362016-10-03 12:25:00 +0530514 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800515
516 return 0;
517}
Nirav Shah7f337db2016-05-25 10:49:02 +0530518
519/**
520 * pktlog_process_fw_msg() - process packetlog message
521 * @buff: buffer
522 *
523 * Return: None
524 */
525void pktlog_process_fw_msg(uint32_t *buff)
526{
527 uint32_t *pl_hdr;
528 uint32_t log_type;
529 struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
530
531 if (!txrx_pdev) {
532 qdf_print("%s: txrx_pdev is NULL", __func__);
533 return;
534 }
535
536 pl_hdr = buff;
537 log_type =
538 (*(pl_hdr + 1) & ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
539 ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
540 if ((log_type == PKTLOG_TYPE_TX_CTRL)
541 || (log_type == PKTLOG_TYPE_TX_STAT)
542 || (log_type == PKTLOG_TYPE_TX_MSDU_ID)
543 || (log_type == PKTLOG_TYPE_TX_FRM_HDR)
544 || (log_type == PKTLOG_TYPE_TX_VIRT_ADDR))
545 wdi_event_handler(WDI_EVENT_TX_STATUS,
546 txrx_pdev, pl_hdr);
547 else if (log_type == PKTLOG_TYPE_RC_FIND)
548 wdi_event_handler(WDI_EVENT_RATE_FIND,
549 txrx_pdev, pl_hdr);
550 else if (log_type == PKTLOG_TYPE_RC_UPDATE)
551 wdi_event_handler(WDI_EVENT_RATE_UPDATE,
552 txrx_pdev, pl_hdr);
553 else if (log_type == PKTLOG_TYPE_RX_STAT)
554 wdi_event_handler(WDI_EVENT_RX_DESC,
555 txrx_pdev, pl_hdr);
Nirav Shahdcc4c872016-07-28 11:35:26 +0530556 else if (log_type == PKTLOG_TYPE_SW_EVENT)
557 wdi_event_handler(WDI_EVENT_SW_EVENT,
558 txrx_pdev, pl_hdr);
Nirav Shah7f337db2016-05-25 10:49:02 +0530559
560}
561
Jeff Johnson3320c7f2016-11-22 16:00:45 -0800562#if defined(QCA_WIFI_3_0_ADRASTEA)
Nirav Shah7f337db2016-05-25 10:49:02 +0530563/**
564 * pktlog_t2h_msg_handler() - Target to host message handler
565 * @context: pdev context
566 * @pkt: HTC packet
567 *
568 * Return: None
569 */
Jeff Johnson3320c7f2016-11-22 16:00:45 -0800570static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt)
Nirav Shah7f337db2016-05-25 10:49:02 +0530571{
572 struct ol_pktlog_dev_t *pdev = (struct ol_pktlog_dev_t *)context;
573 qdf_nbuf_t pktlog_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
574 uint32_t *msg_word;
575
576 /* check for successful message reception */
577 if (pkt->Status != A_OK) {
578 if (pkt->Status != A_ECANCELED)
579 pdev->htc_err_cnt++;
580 qdf_nbuf_free(pktlog_t2h_msg);
581 return;
582 }
583
584 /* confirm alignment */
585 qdf_assert((((unsigned long)qdf_nbuf_data(pktlog_t2h_msg)) & 0x3) == 0);
586
587 msg_word = (uint32_t *) qdf_nbuf_data(pktlog_t2h_msg);
588 pktlog_process_fw_msg(msg_word);
589
590 qdf_nbuf_free(pktlog_t2h_msg);
591}
592
593/**
594 * pktlog_tx_resume_handler() - resume callback
595 * @context: pdev context
596 *
597 * Return: None
598 */
Jeff Johnson3320c7f2016-11-22 16:00:45 -0800599static void pktlog_tx_resume_handler(void *context)
Nirav Shah7f337db2016-05-25 10:49:02 +0530600{
601 qdf_print("%s: Not expected", __func__);
602 qdf_assert(0);
603}
604
605/**
606 * pktlog_h2t_send_complete() - send complete indication
607 * @context: pdev context
608 * @htc_pkt: HTC packet
609 *
610 * Return: None
611 */
Jeff Johnson3320c7f2016-11-22 16:00:45 -0800612static void pktlog_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
Nirav Shah7f337db2016-05-25 10:49:02 +0530613{
614 qdf_print("%s: Not expected", __func__);
615 qdf_assert(0);
616}
617
618/**
619 * pktlog_h2t_full() - queue full indication
620 * @context: pdev context
621 * @pkt: HTC packet
622 *
623 * Return: HTC action
624 */
Jeff Johnson3320c7f2016-11-22 16:00:45 -0800625static HTC_SEND_FULL_ACTION pktlog_h2t_full(void *context, HTC_PACKET *pkt)
Nirav Shah7f337db2016-05-25 10:49:02 +0530626{
627 return HTC_SEND_FULL_KEEP;
628}
629
630/**
631 * pktlog_htc_connect_service() - create new endpoint for packetlog
632 * @pdev - pktlog pdev
633 *
634 * Return: 0 for success/failure
635 */
Jeff Johnson3320c7f2016-11-22 16:00:45 -0800636static int pktlog_htc_connect_service(struct ol_pktlog_dev_t *pdev)
Nirav Shah7f337db2016-05-25 10:49:02 +0530637{
638 HTC_SERVICE_CONNECT_REQ connect;
639 HTC_SERVICE_CONNECT_RESP response;
640 A_STATUS status;
641
642 qdf_mem_set(&connect, sizeof(connect), 0);
643 qdf_mem_set(&response, sizeof(response), 0);
644
645 connect.pMetaData = NULL;
646 connect.MetaDataLength = 0;
647 connect.EpCallbacks.pContext = pdev;
648 connect.EpCallbacks.EpTxComplete = pktlog_h2t_send_complete;
649 connect.EpCallbacks.EpTxCompleteMultiple = NULL;
650 connect.EpCallbacks.EpRecv = pktlog_t2h_msg_handler;
651 connect.EpCallbacks.ep_resume_tx_queue = pktlog_tx_resume_handler;
652
653 /* rx buffers currently are provided by HIF, not by EpRecvRefill */
654 connect.EpCallbacks.EpRecvRefill = NULL;
655 connect.EpCallbacks.RecvRefillWaterMark = 1;
656 /* N/A, fill is done by HIF */
657
658 connect.EpCallbacks.EpSendFull = pktlog_h2t_full;
659 /*
660 * Specify how deep to let a queue get before htc_send_pkt will
661 * call the EpSendFull function due to excessive send queue depth.
662 */
663 connect.MaxSendQueueDepth = PKTLOG_MAX_SEND_QUEUE_DEPTH;
664
665 /* disable flow control for HTT data message service */
666 connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
667
668 /* connect to control service */
669 connect.service_id = PACKET_LOG_SVC;
670
671 status = htc_connect_service(pdev->htc_pdev, &connect, &response);
672
673 if (status != A_OK) {
674 pdev->mt_pktlog_enabled = false;
675 return -EIO; /* failure */
676 }
677
678 pdev->htc_endpoint = response.Endpoint;
679 pdev->mt_pktlog_enabled = true;
680
681 return 0; /* success */
682}
683
Nirav Shah7f337db2016-05-25 10:49:02 +0530684/**
685 * pktlog_htc_attach() - attach pktlog HTC service
686 *
687 * Return: 0 for success/failure
688 */
689int pktlog_htc_attach(void)
690{
691 struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
692 struct ol_pktlog_dev_t *pdev = NULL;
693 void *htc_pdev = cds_get_context(QDF_MODULE_ID_HTC);
694
695 if ((!txrx_pdev) || (!txrx_pdev->pl_dev) || (!htc_pdev))
696 return -EINVAL;
697
698 pdev = txrx_pdev->pl_dev;
699 pdev->htc_pdev = htc_pdev;
700 return pktlog_htc_connect_service(pdev);
701}
702#else
703int pktlog_htc_attach(void)
704{
705 struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
706 struct ol_pktlog_dev_t *pdev = NULL;
707
708 if (!txrx_pdev)
709 return -EINVAL;
710 pdev = txrx_pdev->pl_dev;
711 pdev->mt_pktlog_enabled = false;
712 return 0;
713}
714#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715#endif /* REMOVE_PKT_LOG */