xref: /wlan-dirver/qca-wifi-host-cmn/utils/pktlog/pktlog_internal.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
1 /*
2  * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  *
21  * Permission to use, copy, modify, and/or distribute this software for any
22  * purpose with or without fee is hereby granted, provided that the above
23  * copyright notice and this permission notice appear in all copies.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
26  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
27  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
28  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32  */
33 
34 #ifndef REMOVE_PKT_LOG
35 #include "ol_txrx_types.h"
36 #include "ol_htt_tx_api.h"
37 #include "ol_tx_desc.h"
38 #include "qdf_mem.h"
39 #include "htt.h"
40 #include "htt_internal.h"
41 #include "pktlog_ac_i.h"
42 #include "wma_api.h"
43 #include "wlan_logging_sock_svc.h"
44 
45 #define TX_DESC_ID_LOW_MASK     0xffff
46 #define TX_DESC_ID_LOW_SHIFT    0
47 #define TX_DESC_ID_HIGH_MASK    0xffff0000
48 #define TX_DESC_ID_HIGH_SHIFT   16
49 
50 void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg)
51 {
52 	struct ath_pktlog_buf *log_buf;
53 	int32_t buf_size;
54 	struct ath_pktlog_hdr *log_hdr;
55 	int32_t cur_wr_offset;
56 	char *log_ptr;
57 	struct ath_pktlog_info *pl_info;
58 	uint16_t log_type;
59 	size_t log_size;
60 	uint32_t flags;
61 #ifdef HELIUMPLUS
62 	uint8_t mac_id;
63 #endif
64 
65 	if (!plarg) {
66 		printk("Invalid parg in %s\n", __func__);
67 		return;
68 	}
69 
70 	pl_info = plarg->pl_info;
71 #ifdef HELIUMPLUS
72 	mac_id = plarg->macId;
73 	log_type = plarg->log_type;
74 #else
75 	log_type = plarg->log_type;
76 #endif
77 	log_size = plarg->log_size;
78 	log_buf = pl_info->buf;
79 	flags = plarg->flags;
80 
81 	if (!log_buf) {
82 		printk("Invalid log_buf in %s\n", __func__);
83 		return;
84 	}
85 
86 
87 	buf_size = pl_info->buf_size;
88 	cur_wr_offset = log_buf->wr_offset;
89 	/* Move read offset to the next entry if there is a buffer overlap */
90 	if (log_buf->rd_offset >= 0) {
91 		if ((cur_wr_offset <= log_buf->rd_offset)
92 		    && (cur_wr_offset + sizeof(struct ath_pktlog_hdr)) >
93 		    log_buf->rd_offset) {
94 			PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
95 					  buf_size);
96 		}
97 	} else {
98 		log_buf->rd_offset = cur_wr_offset;
99 	}
100 
101 	log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + cur_wr_offset);
102 
103 	log_hdr->flags = flags;
104 #ifdef HELIUMPLUS
105 	log_hdr->macId = mac_id;
106 	log_hdr->log_type = log_type;
107 #else
108 	log_hdr->log_type = log_type;
109 #endif
110 	log_hdr->size = (uint16_t) log_size;
111 	log_hdr->missed_cnt = plarg->missed_cnt;
112 	log_hdr->timestamp = plarg->timestamp;
113 	log_hdr->type_specific_data = plarg->type_specific_data;
114 	cur_wr_offset += sizeof(*log_hdr);
115 
116 	if ((buf_size - cur_wr_offset) < log_size) {
117 		while ((cur_wr_offset <= log_buf->rd_offset)
118 		       && (log_buf->rd_offset < buf_size)) {
119 			PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf,
120 					  buf_size);
121 		}
122 		cur_wr_offset = 0;
123 	}
124 
125 	while ((cur_wr_offset <= log_buf->rd_offset)
126 	       && (cur_wr_offset + log_size) > log_buf->rd_offset) {
127 		PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, buf_size);
128 	}
129 
130 	log_ptr = &(log_buf->log_data[cur_wr_offset]);
131 	cur_wr_offset += log_hdr->size;
132 
133 	log_buf->wr_offset = ((buf_size - cur_wr_offset) >=
134 			      sizeof(struct ath_pktlog_hdr)) ? cur_wr_offset :
135 			     0;
136 
137 	plarg->buf = log_ptr;
138 }
139 
140 char *pktlog_getbuf(struct pktlog_dev_t *pl_dev,
141 		    struct ath_pktlog_info *pl_info,
142 		    size_t log_size, struct ath_pktlog_hdr *pl_hdr)
143 {
144 	struct ath_pktlog_arg plarg = { 0, };
145 	uint8_t flags = 0;
146 
147 	plarg.pl_info = pl_info;
148 #ifdef HELIUMPLUS
149 	plarg.macId = pl_hdr->macId;
150 	plarg.log_type = pl_hdr->log_type;
151 #else
152 	plarg.log_type = pl_hdr->log_type;
153 #endif
154 	plarg.log_size = log_size;
155 	plarg.flags = pl_hdr->flags;
156 	plarg.missed_cnt = pl_hdr->missed_cnt;
157 	plarg.timestamp = pl_hdr->timestamp;
158 	plarg.type_specific_data = pl_hdr->type_specific_data;
159 
160 	if (flags & PHFLAGS_INTERRUPT_CONTEXT) {
161 		/*
162 		 * We are already in interrupt context, no need to make it
163 		 * intsafe. call the function directly.
164 		 */
165 		pktlog_getbuf_intsafe(&plarg);
166 	} else {
167 		PKTLOG_LOCK(pl_info);
168 		pktlog_getbuf_intsafe(&plarg);
169 		PKTLOG_UNLOCK(pl_info);
170 	}
171 
172 	return plarg.buf;
173 }
174 
175 static struct txctl_frm_hdr frm_hdr;
176 
177 #ifndef HELIUMPLUS
178 static void process_ieee_hdr(void *data)
179 {
180 	uint8_t dir;
181 	struct ieee80211_frame *wh = (struct ieee80211_frame *)(data);
182 
183 	frm_hdr.framectrl = *(uint16_t *) (wh->i_fc);
184 	frm_hdr.seqctrl = *(uint16_t *) (wh->i_seq);
185 	dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK);
186 
187 	if (dir == IEEE80211_FC1_DIR_TODS) {
188 		frm_hdr.bssid_tail =
189 			(wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
190 								      i_addr1
191 								      [QDF_MAC_ADDR_SIZE
192 								       - 1]);
193 		frm_hdr.sa_tail =
194 			(wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
195 								      i_addr2
196 								      [QDF_MAC_ADDR_SIZE
197 								       - 1]);
198 		frm_hdr.da_tail =
199 			(wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
200 								      i_addr3
201 								      [QDF_MAC_ADDR_SIZE
202 								       - 1]);
203 	} else if (dir == IEEE80211_FC1_DIR_FROMDS) {
204 		frm_hdr.bssid_tail =
205 			(wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
206 								      i_addr2
207 								      [QDF_MAC_ADDR_SIZE
208 								       - 1]);
209 		frm_hdr.sa_tail =
210 			(wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
211 								      i_addr3
212 								      [QDF_MAC_ADDR_SIZE
213 								       - 1]);
214 		frm_hdr.da_tail =
215 			(wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
216 								      i_addr1
217 								      [QDF_MAC_ADDR_SIZE
218 								       - 1]);
219 	} else {
220 		frm_hdr.bssid_tail =
221 			(wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
222 								      i_addr3
223 								      [QDF_MAC_ADDR_SIZE
224 								       - 1]);
225 		frm_hdr.sa_tail =
226 			(wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
227 								      i_addr2
228 								      [QDF_MAC_ADDR_SIZE
229 								       - 1]);
230 		frm_hdr.da_tail =
231 			(wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh->
232 								      i_addr1
233 								      [QDF_MAC_ADDR_SIZE
234 								       - 1]);
235 	}
236 }
237 
238 /**
239  * fill_ieee80211_hdr_data() - fill ieee802.11 data header
240  * @txrx_pdev: txrx pdev
241  * @pl_msdu_info: msdu info
242  * @data: data received from event
243  *
244  * Return: none
245  */
246 /* TODO: Platform specific function */
247 static void
248 fill_ieee80211_hdr_data(struct cdp_pdev *pdev,
249 	struct ath_pktlog_msdu_info *pl_msdu_info, void *data)
250 {
251 	uint32_t i;
252 	uint32_t *htt_tx_desc;
253 	struct ol_tx_desc_t *tx_desc;
254 	uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET;
255 	uint16_t tx_desc_id;
256 	uint32_t *msdu_id_info = (uint32_t *)
257 				 ((void *)data + sizeof(struct ath_pktlog_hdr));
258 	uint32_t *msdu_id = (uint32_t *) ((char *)msdu_id_info +
259 					  msdu_id_offset);
260 	uint8_t *addr, *vap_addr;
261 	uint8_t vdev_id;
262 	qdf_nbuf_t netbuf;
263 	uint32_t len;
264 	struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)pdev;
265 
266 
267 	pl_msdu_info->num_msdu = *msdu_id_info;
268 	pl_msdu_info->priv_size = sizeof(uint32_t) *
269 				 pl_msdu_info->num_msdu + sizeof(uint32_t);
270 
271 	if (pl_msdu_info->num_msdu > MAX_PKT_INFO_MSDU_ID) {
272 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
273 			  "%s: Invalid num_msdu count",
274 			  __func__);
275 		qdf_assert(0);
276 		return;
277 	}
278 	for (i = 0; i < pl_msdu_info->num_msdu; i++) {
279 		/*
280 		 * Handle big endianness
281 		 * Increment msdu_id once after retrieving
282 		 * lower 16 bits and uppper 16 bits
283 		 */
284 		if (!(i % 2)) {
285 			tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK)
286 				      >> TX_DESC_ID_LOW_SHIFT);
287 		} else {
288 			tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK)
289 				      >> TX_DESC_ID_HIGH_SHIFT);
290 			msdu_id += 1;
291 		}
292 		if (tx_desc_id >= txrx_pdev->tx_desc.pool_size) {
293 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
294 				"%s: drop due to invalid msdu id = %x",
295 				__func__, tx_desc_id);
296 			return;
297 		}
298 		tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id);
299 		qdf_assert(tx_desc);
300 		netbuf = tx_desc->netbuf;
301 		htt_tx_desc = (uint32_t *) tx_desc->htt_tx_desc;
302 		qdf_assert(htt_tx_desc);
303 
304 		qdf_nbuf_peek_header(netbuf, &addr, &len);
305 
306 		if (len < (2 * QDF_MAC_ADDR_SIZE)) {
307 			qdf_print("TX frame does not have a valid address");
308 			return;
309 		}
310 		/* Adding header information for the TX data frames */
311 		vdev_id = (uint8_t) (*(htt_tx_desc +
312 				       HTT_TX_VDEV_ID_WORD) >>
313 				     HTT_TX_VDEV_ID_SHIFT) &
314 			  HTT_TX_VDEV_ID_MASK;
315 
316 		vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id);
317 
318 		frm_hdr.da_tail = (addr[QDF_MAC_ADDR_SIZE - 2] << 8) |
319 				  (addr[QDF_MAC_ADDR_SIZE - 1]);
320 		frm_hdr.sa_tail =
321 			(addr[2 * QDF_MAC_ADDR_SIZE - 2] << 8) |
322 			(addr[2 * QDF_MAC_ADDR_SIZE - 1]);
323 		if (vap_addr) {
324 			frm_hdr.bssid_tail =
325 				(vap_addr[QDF_MAC_ADDR_SIZE - 2] << 8) |
326 				(vap_addr[QDF_MAC_ADDR_SIZE - 1]);
327 		} else {
328 			frm_hdr.bssid_tail = 0x0000;
329 		}
330 		pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc +
331 						  HTT_TX_MSDU_LEN_DWORD)
332 						& HTT_TX_MSDU_LEN_MASK;
333 		/*
334 		 * Add more information per MSDU
335 		 * e.g., protocol information
336 		 */
337 	}
338 
339 }
340 #endif
341 
342 #ifdef HELIUMPLUS
343 A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
344 {
345 	/*
346 	 * Must include to process different types
347 	 * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
348 	 */
349 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
350 	struct ath_pktlog_hdr pl_hdr;
351 	struct ath_pktlog_info *pl_info;
352 	uint32_t *pl_tgt_hdr;
353 	struct ol_fw_data *fw_data;
354 	uint32_t len;
355 
356 	if (!txrx_pdev) {
357 		printk("Invalid pdev in %s\n", __func__);
358 		return A_ERROR;
359 	}
360 
361 	if (!pl_dev) {
362 		pr_err("Invalid pktlog handle in %s\n", __func__);
363 		qdf_assert(pl_dev);
364 		return A_ERROR;
365 	}
366 
367 	qdf_assert(data);
368 
369 	fw_data = (struct ol_fw_data *)data;
370 	len = fw_data->len;
371 	if (len < (sizeof(uint32_t) *
372 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
373 		len < (sizeof(uint32_t) *
374 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
375 		len < (sizeof(uint32_t) *
376 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
377 		len < (sizeof(uint32_t) *
378 		       (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
379 		len < (sizeof(uint32_t) *
380 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
381 		len < (sizeof(uint32_t) *
382 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
383 		qdf_print("Invalid msdu len in %s", __func__);
384 		qdf_assert(0);
385 		return A_ERROR;
386 	}
387 
388 	pl_tgt_hdr = (uint32_t *)fw_data->data;
389 	/*
390 	 * Makes the short words (16 bits) portable b/w little endian
391 	 * and big endian
392 	 */
393 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
394 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
395 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
396 	pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
397 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
398 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
399 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
400 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
401 		   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
402 		  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
403 	pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
404 		   ATH_PKTLOG_HDR_MAC_ID_MASK) >>
405 		  ATH_PKTLOG_HDR_MAC_ID_SHIFT;
406 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
407 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
408 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
409 	pl_hdr.type_specific_data =
410 		*(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
411 	pl_info = pl_dev->pl_info;
412 
413 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
414 		qdf_assert(0);
415 		return A_ERROR;
416 	}
417 
418 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) {
419 		size_t log_size = sizeof(frm_hdr) + pl_hdr.size;
420 		void *txdesc_hdr_ctl = (void *)
421 		pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
422 		qdf_assert(txdesc_hdr_ctl);
423 		qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t)));
424 
425 		qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr));
426 		qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr),
427 					((void *)fw_data->data +
428 					 sizeof(struct ath_pktlog_hdr)),
429 					 pl_hdr.size);
430 		pl_hdr.size = log_size;
431 		cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
432 						txdesc_hdr_ctl);
433 	}
434 
435 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) {
436 		struct ath_pktlog_tx_status txstat_log;
437 		size_t log_size = pl_hdr.size;
438 
439 		txstat_log.ds_status = (void *)
440 				       pktlog_getbuf(pl_dev, pl_info,
441 						     log_size, &pl_hdr);
442 		qdf_assert(txstat_log.ds_status);
443 		qdf_mem_copy(txstat_log.ds_status,
444 			     ((void *)fw_data->data +
445 			      sizeof(struct ath_pktlog_hdr)),
446 			     pl_hdr.size);
447 		/* TODO: MCL specific API */
448 		cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
449 						txstat_log.ds_status);
450 	}
451 	return A_OK;
452 }
453 #else
454 A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data)
455 {
456 	/*
457 	 * Must include to process different types
458 	 * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
459 	 */
460 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
461 	struct ath_pktlog_hdr pl_hdr;
462 	struct ath_pktlog_info *pl_info;
463 	uint32_t *pl_tgt_hdr;
464 	struct ol_fw_data *fw_data;
465 	uint32_t len;
466 
467 	if (!txrx_pdev) {
468 		qdf_print("Invalid pdev in %s", __func__);
469 		return A_ERROR;
470 	}
471 
472 	if (!pl_dev) {
473 		pr_err("Invalid pktlog handle in %s\n", __func__);
474 		qdf_assert(pl_dev);
475 		return A_ERROR;
476 	}
477 
478 	qdf_assert(data);
479 
480 	fw_data = (struct ol_fw_data *)data;
481 	len = fw_data->len;
482 	if (len < (sizeof(uint32_t) *
483 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
484 		len < (sizeof(uint32_t) *
485 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
486 		len < (sizeof(uint32_t) *
487 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
488 		len < (sizeof(uint32_t) *
489 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
490 		len < (sizeof(uint32_t) *
491 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
492 		qdf_print("Invalid msdu len in %s", __func__);
493 		qdf_assert(0);
494 		return A_ERROR;
495 	}
496 
497 	pl_tgt_hdr = (uint32_t *)fw_data->data;
498 	/*
499 	 * Makes the short words (16 bits) portable b/w little endian
500 	 * and big endian
501 	 */
502 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
503 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
504 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
505 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
506 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
507 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
508 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
509 			   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
510 			  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
511 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
512 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
513 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
514 
515 	pl_info = pl_dev->pl_info;
516 
517 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) {
518 		/* Valid only for the TX CTL */
519 		process_ieee_hdr(fw_data->data + sizeof(pl_hdr));
520 	}
521 
522 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) {
523 		uint32_t desc_id = (uint32_t) *((uint32_t *)(fw_data->data +
524 						 sizeof(pl_hdr)));
525 		uint32_t vdev_id = desc_id;
526 
527 		/* if the pkt log msg is for the bcn frame the vdev id
528 		 * is piggybacked in desc_id and the MSB of the desc ID
529 		 * would be set to FF
530 		 */
531 #define BCN_DESC_ID 0xFF
532 		if ((desc_id >> 24) == BCN_DESC_ID) {
533 			void *data;
534 			uint32_t buf_size;
535 
536 			vdev_id &= 0x00FFFFFF;
537 			/* TODO: MCL specific API */
538 			data = wma_get_beacon_buffer_by_vdev_id(vdev_id,
539 								&buf_size);
540 			if (data) {
541 				/* TODO: platform specific API */
542 				process_ieee_hdr(data);
543 				qdf_mem_free(data);
544 			}
545 		} else {
546 			/*
547 			 * TODO: get the hdr content for mgmt frames from
548 			 * Tx mgmt desc pool
549 			 */
550 		}
551 	}
552 
553 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) {
554 		struct ath_pktlog_txctl txctl_log;
555 		size_t log_size = sizeof(txctl_log.priv);
556 
557 		txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev,
558 								 pl_info,
559 								 log_size,
560 								 &pl_hdr);
561 
562 		if (!txctl_log.txdesc_hdr_ctl) {
563 			printk
564 				("failed to get buf for txctl_log.txdesc_hdr_ctl\n");
565 			return A_ERROR;
566 		}
567 
568 		/*
569 		 * frm hdr is currently Valid only for local frames
570 		 * Add capability to include the fmr hdr for remote frames
571 		 */
572 		txctl_log.priv.frm_hdr = frm_hdr;
573 		qdf_assert(txctl_log.priv.txdesc_ctl);
574 		qdf_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl));
575 		pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl))
576 			       ? sizeof(txctl_log.priv.txdesc_ctl) :
577 			       pl_hdr.size;
578 
579 		if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
580 			qdf_assert(0);
581 			return A_ERROR;
582 		}
583 		qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl,
584 			     ((void *)fw_data->data +
585 			      sizeof(struct ath_pktlog_hdr)),
586 			     pl_hdr.size);
587 		qdf_assert(txctl_log.txdesc_hdr_ctl);
588 		qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv,
589 			     sizeof(txctl_log.priv));
590 		pl_hdr.size = log_size;
591 		cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
592 						txctl_log.txdesc_hdr_ctl);
593 		/* Add Protocol information and HT specific information */
594 	}
595 
596 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) {
597 		struct ath_pktlog_tx_status txstat_log;
598 		size_t log_size = pl_hdr.size;
599 
600 		txstat_log.ds_status = (void *)
601 				       pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
602 		qdf_assert(txstat_log.ds_status);
603 		qdf_mem_copy(txstat_log.ds_status,
604 			     ((void *)fw_data->data +
605 			      sizeof(struct ath_pktlog_hdr)),
606 			     pl_hdr.size);
607 
608 		cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
609 						txstat_log.ds_status);
610 	}
611 
612 	if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) {
613 		struct ath_pktlog_msdu_info pl_msdu_info;
614 		size_t log_size;
615 
616 		qdf_mem_zero(&pl_msdu_info, sizeof(pl_msdu_info));
617 		log_size = sizeof(pl_msdu_info.priv);
618 
619 		if (pl_dev->mt_pktlog_enabled == false)
620 			fill_ieee80211_hdr_data(txrx_pdev,
621 						&pl_msdu_info, fw_data->data);
622 
623 		pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info,
624 							   log_size, &pl_hdr);
625 		qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info,
626 			     ((void *)fw_data->data +
627 			      sizeof(struct ath_pktlog_hdr)),
628 			     sizeof(pl_msdu_info.priv.msdu_id_info));
629 		qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv,
630 			     sizeof(pl_msdu_info.priv));
631 		cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
632 						pl_msdu_info.ath_msdu_info);
633 	}
634 
635 	return A_OK;
636 }
637 #endif
638 
639 /**
640  * process_offload_pktlog() - Process full pktlog events
641  * pdev: abstract pdev handle
642  * data: pktlog buffer
643  *
644  * Return: zero on success, non-zero on failure
645  */
646 A_STATUS
647 process_offload_pktlog(struct cdp_pdev *pdev, void *data)
648 {
649 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
650 	struct ath_pktlog_info *pl_info;
651 	struct ath_pktlog_hdr pl_hdr;
652 	uint32_t *pl_tgt_hdr;
653 	void *txdesc_hdr_ctl = NULL;
654 	size_t log_size = 0;
655 	size_t tmp_log_size = 0;
656 
657 	if (!pl_dev) {
658 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
659 			  "Invalid context in %s\n", __func__);
660 		return A_ERROR;
661 	}
662 
663 	if (!data) {
664 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
665 			  "Invalid data in %s\n", __func__);
666 		return A_ERROR;
667 	}
668 
669 	pl_tgt_hdr = (uint32_t *)data;
670 
671 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
672 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
673 				ATH_PKTLOG_HDR_FLAGS_SHIFT;
674 	pl_hdr.missed_cnt =  (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
675 			ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
676 				ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
677 	pl_hdr.log_type =  (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
678 			ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
679 				ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
680 	pl_hdr.size =  (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
681 			ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
682 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
683 	pl_hdr.type_specific_data = *(pl_tgt_hdr
684 			+ ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
685 
686 	/*
687 	 *  Must include to process different types
688 	 *  TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR
689 	 */
690 	pl_info = pl_dev->pl_info;
691 	tmp_log_size = sizeof(frm_hdr) + pl_hdr.size;
692 	log_size = pl_hdr.size;
693 	txdesc_hdr_ctl =
694 		(void *)pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr);
695 	if (!txdesc_hdr_ctl) {
696 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
697 			  "Failed to allocate pktlog descriptor");
698 		return A_NO_MEMORY;
699 	}
700 	qdf_assert(txdesc_hdr_ctl);
701 	qdf_assert(pl_hdr->size < PKTLOG_MAX_TX_WORDS * sizeof(u_int32_t));
702 	qdf_mem_copy(txdesc_hdr_ctl,
703 		     ((void *)data + sizeof(struct ath_pktlog_hdr)),
704 		     pl_hdr.size);
705 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, txdesc_hdr_ctl);
706 
707 	return A_OK;
708 }
709 
710 /* TODO: hardware dependent function */
711 A_STATUS process_rx_info_remote(void *pdev, void *data)
712 {
713 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
714 	struct ath_pktlog_info *pl_info;
715 	struct htt_host_rx_desc_base *rx_desc;
716 	struct ath_pktlog_hdr pl_hdr;
717 	struct ath_pktlog_rx_info rxstat_log;
718 	size_t log_size;
719 	struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data;
720 	qdf_nbuf_t msdu;
721 
722 	if (!pdev || !r_data || !pl_dev) {
723 		qdf_print("%s: Invalid handle", __func__);
724 		return A_ERROR;
725 	}
726 
727 	pl_info = pl_dev->pl_info;
728 	msdu = r_data->msdu;
729 
730 	while (msdu) {
731 		rx_desc =
732 		   (struct htt_host_rx_desc_base *)(qdf_nbuf_data(msdu)) - 1;
733 		log_size =
734 			sizeof(*rx_desc) - sizeof(struct htt_host_fw_desc_base);
735 
736 		/*
737 		 * Construct the pktlog header pl_hdr
738 		 * Because desc is DMA'd to the host memory
739 		 */
740 		pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
741 		pl_hdr.missed_cnt = 0;
742 #if defined(HELIUMPLUS)
743 		pl_hdr.macId = r_data->mac_id;
744 		pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
745 		pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
746 #else
747 		pl_hdr.log_type = PKTLOG_TYPE_RX_STAT;
748 #endif
749 		pl_hdr.size = sizeof(*rx_desc) -
750 			      sizeof(struct htt_host_fw_desc_base);
751 #if defined(HELIUMPLUS)
752 		pl_hdr.timestamp =
753 			rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
754 		pl_hdr.type_specific_data = 0xDEADAA;
755 #else
756 		pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp;
757 #endif /* !defined(HELIUMPLUS) */
758 		rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
759 							   log_size, &pl_hdr);
760 		qdf_mem_copy(rxstat_log.rx_desc, (void *)rx_desc +
761 			     sizeof(struct htt_host_fw_desc_base), pl_hdr.size);
762 		cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
763 						rxstat_log.rx_desc);
764 		msdu = qdf_nbuf_next(msdu);
765 	}
766 	return A_OK;
767 }
768 
769 #ifdef HELIUMPLUS
770 A_STATUS process_rx_info(void *pdev, void *data)
771 {
772 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
773 	struct ath_pktlog_info *pl_info;
774 	struct ath_pktlog_rx_info rxstat_log;
775 	struct ath_pktlog_hdr pl_hdr;
776 	size_t log_size;
777 	uint32_t *pl_tgt_hdr;
778 	struct ol_fw_data *fw_data;
779 	uint32_t len;
780 
781 	if (!pdev) {
782 		printk("Invalid pdev in %s", __func__);
783 		return A_ERROR;
784 	}
785 
786 	pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
787 	if (!pl_dev) {
788 		printk("Invalid pl_dev in %s", __func__);
789 		return A_ERROR;
790 	}
791 
792 	fw_data = (struct ol_fw_data *)data;
793 	len = fw_data->len;
794 	if (len < (sizeof(uint32_t) *
795 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
796 		len < (sizeof(uint32_t) *
797 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
798 		len < (sizeof(uint32_t) *
799 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
800 		len < (sizeof(uint32_t) *
801 		       (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
802 		len < (sizeof(uint32_t) *
803 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
804 		len < (sizeof(uint32_t) *
805 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
806 		qdf_print("Invalid msdu len in %s", __func__);
807 		qdf_assert(0);
808 		return A_ERROR;
809 	}
810 
811 	pl_info = pl_dev->pl_info;
812 	pl_tgt_hdr = (uint32_t *)fw_data->data;
813 
814 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
815 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
816 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
817 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
818 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
819 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
820 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
821 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
822 			   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
823 			  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
824 	pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
825 			   ATH_PKTLOG_HDR_MAC_ID_MASK) >>
826 			  ATH_PKTLOG_HDR_MAC_ID_SHIFT;
827 	pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
828 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
829 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
830 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
831 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
832 		qdf_assert(0);
833 		return A_ERROR;
834 	}
835 
836 	log_size = pl_hdr.size;
837 	rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
838 						   log_size, &pl_hdr);
839 	qdf_mem_copy(rxstat_log.rx_desc,
840 		     (void *)fw_data->data + sizeof(struct ath_pktlog_hdr),
841 		     pl_hdr.size);
842 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
843 
844 	return A_OK;
845 }
846 
847 #else
848 A_STATUS process_rx_info(void *pdev, void *data)
849 {
850 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
851 	struct ath_pktlog_info *pl_info;
852 	struct ath_pktlog_rx_info rxstat_log;
853 	struct ath_pktlog_hdr pl_hdr;
854 	size_t log_size;
855 	uint32_t *pl_tgt_hdr;
856 	struct ol_fw_data *fw_data;
857 	uint32_t len;
858 
859 	if (!pdev) {
860 		printk("Invalid pdev in %s", __func__);
861 		return A_ERROR;
862 	}
863 
864 	pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev;
865 	if (!pl_dev) {
866 		printk("Invalid pl_dev in %s", __func__);
867 		return A_ERROR;
868 	}
869 
870 	fw_data = (struct ol_fw_data *)data;
871 	len = fw_data->len;
872 	if (len < (sizeof(uint32_t) *
873 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
874 		len < (sizeof(uint32_t) *
875 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
876 		len < (sizeof(uint32_t) *
877 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
878 		len < (sizeof(uint32_t) *
879 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
880 		len < (sizeof(uint32_t) *
881 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
882 		qdf_print("Invalid msdu len in %s", __func__);
883 		qdf_assert(0);
884 		return A_ERROR;
885 	}
886 
887 	pl_info = pl_dev->pl_info;
888 	pl_tgt_hdr = (uint32_t *)fw_data->data;
889 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
890 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
891 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
892 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
893 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
894 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
895 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
896 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
897 				   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
898 				  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
899 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
900 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
901 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
902 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
903 		qdf_assert(0);
904 		return A_ERROR;
905 	}
906 
907 	log_size = pl_hdr.size;
908 	rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
909 						   log_size, &pl_hdr);
910 	qdf_mem_copy(rxstat_log.rx_desc,
911 		     (void *)fw_data->data + sizeof(struct ath_pktlog_hdr),
912 		     pl_hdr.size);
913 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
914 
915 	return A_OK;
916 }
917 #endif
918 
919 #ifdef HELIUMPLUS
920 A_STATUS process_rate_find(void *pdev, void *data)
921 {
922 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
923 	struct ath_pktlog_hdr pl_hdr;
924 	struct ath_pktlog_info *pl_info;
925 	size_t log_size;
926 	uint32_t len;
927 	struct ol_fw_data *fw_data;
928 
929 	/*
930 	 * Will be uncommented when the rate control find
931 	 * for pktlog is implemented in the firmware.
932 	 * Currently derived from the TX PPDU status
933 	 */
934 	struct ath_pktlog_rc_find rcf_log;
935 	uint32_t *pl_tgt_hdr;
936 
937 	if (!pdev || !data || !pl_dev) {
938 		qdf_print("%s: Invalid handle", __func__);
939 		return A_ERROR;
940 	}
941 
942 	fw_data = (struct ol_fw_data *)data;
943 	len = fw_data->len;
944 	if (len < (sizeof(uint32_t) *
945 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
946 		len < (sizeof(uint32_t) *
947 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
948 		len < (sizeof(uint32_t) *
949 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
950 		len < (sizeof(uint32_t) *
951 		       (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
952 		len < (sizeof(uint32_t) *
953 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
954 		len < (sizeof(uint32_t) *
955 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
956 		qdf_print("Invalid msdu len in %s", __func__);
957 		qdf_assert(0);
958 		return A_ERROR;
959 	}
960 
961 	pl_tgt_hdr = (uint32_t *)fw_data->data;
962 	/*
963 	 * Makes the short words (16 bits) portable b/w little endian
964 	 * and big endian
965 	 */
966 
967 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
968 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
969 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
970 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
971 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
972 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
973 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
974 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
975 			   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
976 			  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
977 	pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
978 			   ATH_PKTLOG_HDR_MAC_ID_MASK) >>
979 			  ATH_PKTLOG_HDR_MAC_ID_SHIFT;
980 	pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
981 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
982 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
983 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
984 	pl_info = pl_dev->pl_info;
985 	log_size = pl_hdr.size;
986 	rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
987 					       log_size, &pl_hdr);
988 
989 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
990 		qdf_assert(0);
991 		return A_ERROR;
992 	}
993 	qdf_mem_copy(rcf_log.rcFind,
994 		     ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
995 		     pl_hdr.size);
996 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
997 
998 	return A_OK;
999 }
1000 
1001 #else
1002 A_STATUS process_rate_find(void *pdev, void *data)
1003 {
1004 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1005 	struct ath_pktlog_hdr pl_hdr;
1006 	struct ath_pktlog_info *pl_info;
1007 	size_t log_size;
1008 	uint32_t len;
1009 	struct ol_fw_data *fw_data;
1010 
1011 	/*
1012 	 * Will be uncommented when the rate control find
1013 	 * for pktlog is implemented in the firmware.
1014 	 * Currently derived from the TX PPDU status
1015 	 */
1016 	struct ath_pktlog_rc_find rcf_log;
1017 	uint32_t *pl_tgt_hdr;
1018 
1019 	if (!pdev || !data || !pl_dev) {
1020 		qdf_print("%s: Invalid handle", __func__);
1021 		return A_ERROR;
1022 	}
1023 
1024 	fw_data = (struct ol_fw_data *)data;
1025 	len = fw_data->len;
1026 	if (len < (sizeof(uint32_t) *
1027 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
1028 		len < (sizeof(uint32_t) *
1029 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
1030 		len < (sizeof(uint32_t) *
1031 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
1032 		len < (sizeof(uint32_t) *
1033 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
1034 		len < (sizeof(uint32_t) *
1035 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
1036 		qdf_print("Invalid msdu len in %s", __func__);
1037 		qdf_assert(0);
1038 		return A_ERROR;
1039 	}
1040 
1041 	pl_tgt_hdr = (uint32_t *)fw_data->data;
1042 	/*
1043 	 * Makes the short words (16 bits) portable b/w little endian
1044 	 * and big endian
1045 	 */
1046 
1047 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
1048 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
1049 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
1050 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
1051 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
1052 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
1053 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
1054 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
1055 			   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
1056 			  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
1057 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
1058 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
1059 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
1060 	pl_info = pl_dev->pl_info;
1061 	log_size = pl_hdr.size;
1062 	rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info,
1063 					       log_size, &pl_hdr);
1064 
1065 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
1066 		qdf_assert(0);
1067 		return A_ERROR;
1068 	}
1069 	qdf_mem_copy(rcf_log.rcFind,
1070 		     ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
1071 		     pl_hdr.size);
1072 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind);
1073 
1074 	return A_OK;
1075 }
1076 #endif
1077 
1078 #ifdef HELIUMPLUS
1079 A_STATUS process_sw_event(void *pdev, void *data)
1080 {
1081 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1082 	struct ath_pktlog_hdr pl_hdr;
1083 	struct ath_pktlog_info *pl_info;
1084 	size_t log_size;
1085 	uint32_t len;
1086 	struct ol_fw_data *fw_data;
1087 
1088 	/*
1089 	 * Will be uncommented when the rate control find
1090 	 * for pktlog is implemented in the firmware.
1091 	 * Currently derived from the TX PPDU status
1092 	 */
1093 	struct ath_pktlog_sw_event sw_event;
1094 	uint32_t *pl_tgt_hdr;
1095 
1096 	if (!pdev) {
1097 		qdf_print("Invalid pdev in %s", __func__);
1098 		return A_ERROR;
1099 	}
1100 	if (!data) {
1101 		qdf_print("Invalid data in %s", __func__);
1102 		return A_ERROR;
1103 	}
1104 	if (!pl_dev) {
1105 		qdf_print("Invalid pl_dev in %s", __func__);
1106 		return A_ERROR;
1107 	}
1108 
1109 	fw_data = (struct ol_fw_data *)data;
1110 	len = fw_data->len;
1111 	if (len < (sizeof(uint32_t) *
1112 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
1113 		len < (sizeof(uint32_t) *
1114 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
1115 		len < (sizeof(uint32_t) *
1116 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
1117 		len < (sizeof(uint32_t) *
1118 		       (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
1119 		len < (sizeof(uint32_t) *
1120 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
1121 		len < (sizeof(uint32_t) *
1122 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
1123 		qdf_print("Invalid msdu len in %s", __func__);
1124 		qdf_assert(0);
1125 		return A_ERROR;
1126 	}
1127 
1128 	pl_tgt_hdr = (uint32_t *)fw_data->data;
1129 	/*
1130 	 * Makes the short words (16 bits) portable b/w little endian
1131 	 * and big endian
1132 	 */
1133 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
1134 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
1135 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
1136 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
1137 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
1138 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
1139 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
1140 			   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
1141 			  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
1142 	pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
1143 			   ATH_PKTLOG_HDR_MAC_ID_MASK) >>
1144 			  ATH_PKTLOG_HDR_MAC_ID_SHIFT;
1145 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
1146 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
1147 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
1148 
1149 	pl_hdr.type_specific_data =
1150 		*(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET);
1151 	pl_info = pl_dev->pl_info;
1152 	log_size = pl_hdr.size;
1153 	sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
1154 					       log_size, &pl_hdr);
1155 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
1156 		qdf_assert(0);
1157 		return A_ERROR;
1158 	}
1159 	qdf_mem_copy(sw_event.sw_event,
1160 		     ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
1161 		     pl_hdr.size);
1162 
1163 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
1164 
1165 	return A_OK;
1166 }
1167 
1168 #else
1169 A_STATUS process_sw_event(void *pdev, void *data)
1170 {
1171 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1172 	struct ath_pktlog_hdr pl_hdr;
1173 	struct ath_pktlog_info *pl_info;
1174 	size_t log_size;
1175 	uint32_t len;
1176 	struct ol_fw_data *fw_data;
1177 
1178 	/*
1179 	 * Will be uncommented when the rate control find
1180 	 * for pktlog is implemented in the firmware.
1181 	 * Currently derived from the TX PPDU status
1182 	 */
1183 	struct ath_pktlog_sw_event sw_event;
1184 	uint32_t *pl_tgt_hdr;
1185 
1186 	if (!pdev) {
1187 		qdf_print("Invalid pdev in %s", __func__);
1188 		return A_ERROR;
1189 	}
1190 	if (!data) {
1191 		qdf_print("Invalid data in %s", __func__);
1192 		return A_ERROR;
1193 	}
1194 	if (!pl_dev) {
1195 		qdf_print("Invalid pl_dev in %s", __func__);
1196 		return A_ERROR;
1197 	}
1198 
1199 	fw_data = (struct ol_fw_data *)data;
1200 	len = fw_data->len;
1201 	if (len < (sizeof(uint32_t) *
1202 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
1203 		len < (sizeof(uint32_t) *
1204 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
1205 		len < (sizeof(uint32_t) *
1206 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
1207 		len < (sizeof(uint32_t) *
1208 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
1209 		len < (sizeof(uint32_t) *
1210 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
1211 		qdf_print("Invalid msdu len in %s", __func__);
1212 		qdf_assert(0);
1213 		return A_ERROR;
1214 	}
1215 
1216 	pl_tgt_hdr = (uint32_t *)fw_data->data;
1217 	/*
1218 	 * Makes the short words (16 bits) portable b/w little endian
1219 	 * and big endian
1220 	 */
1221 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
1222 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
1223 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
1224 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
1225 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
1226 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
1227 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
1228 				   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
1229 				  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
1230 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
1231 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
1232 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
1233 	pl_info = pl_dev->pl_info;
1234 	log_size = pl_hdr.size;
1235 	sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info,
1236 					       log_size, &pl_hdr);
1237 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
1238 		qdf_assert(0);
1239 		return A_ERROR;
1240 	}
1241 	qdf_mem_copy(sw_event.sw_event,
1242 		     ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)),
1243 		     pl_hdr.size);
1244 
1245 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event);
1246 
1247 	return A_OK;
1248 }
1249 #endif
1250 
1251 #ifdef HELIUMPLUS
1252 A_STATUS process_rate_update(void *pdev, void *data)
1253 {
1254 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1255 	struct ath_pktlog_hdr pl_hdr;
1256 	size_t log_size;
1257 	struct ath_pktlog_info *pl_info;
1258 	struct ath_pktlog_rc_update rcu_log;
1259 	uint32_t *pl_tgt_hdr;
1260 	struct ol_fw_data *fw_data;
1261 	uint32_t len;
1262 
1263 	if (!pdev || !data || !pl_dev) {
1264 		qdf_print("%s: Invalid handle", __func__);
1265 		return A_ERROR;
1266 	}
1267 
1268 	fw_data = (struct ol_fw_data *)data;
1269 	len = fw_data->len;
1270 	if (len < (sizeof(uint32_t) *
1271 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
1272 		len < (sizeof(uint32_t) *
1273 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
1274 		len < (sizeof(uint32_t) *
1275 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
1276 		len < (sizeof(uint32_t) *
1277 		       (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) ||
1278 		len < (sizeof(uint32_t) *
1279 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
1280 		len < (sizeof(uint32_t) *
1281 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
1282 		qdf_print("Invalid msdu len in %s", __func__);
1283 		qdf_assert(0);
1284 		return A_ERROR;
1285 	}
1286 
1287 	pl_tgt_hdr = (uint32_t *)fw_data->data;
1288 	/*
1289 	 * Makes the short words (16 bits) portable b/w little endian
1290 	 * and big endian
1291 	 */
1292 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
1293 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
1294 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
1295 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
1296 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
1297 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
1298 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
1299 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
1300 			   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
1301 			  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
1302 	pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) &
1303 			   ATH_PKTLOG_HDR_MAC_ID_MASK) >>
1304 			  ATH_PKTLOG_HDR_MAC_ID_SHIFT;
1305 	pl_hdr.flags |= PKTLOG_HDR_SIZE_16;
1306 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
1307 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
1308 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
1309 	log_size = pl_hdr.size;
1310 	pl_info = pl_dev->pl_info;
1311 
1312 	/*
1313 	 * Will be uncommented when the rate control update
1314 	 * for pktlog is implemented in the firmware.
1315 	 * Currently derived from the TX PPDU status
1316 	 */
1317 	rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
1318 						   log_size, &pl_hdr);
1319 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
1320 		qdf_assert(0);
1321 		return A_ERROR;
1322 	}
1323 	qdf_mem_copy(rcu_log.txRateCtrl,
1324 		     ((char *)fw_data->data +
1325 		      sizeof(struct ath_pktlog_hdr)),
1326 		     pl_hdr.size);
1327 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
1328 	return A_OK;
1329 }
1330 
1331 #else
1332 A_STATUS process_rate_update(void *pdev, void *data)
1333 {
1334 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1335 	struct ath_pktlog_hdr pl_hdr;
1336 	size_t log_size;
1337 	struct ath_pktlog_info *pl_info;
1338 	struct ath_pktlog_rc_update rcu_log;
1339 	uint32_t *pl_tgt_hdr;
1340 	struct ol_fw_data *fw_data;
1341 	uint32_t len;
1342 
1343 	if (!pdev || !data || !pl_dev) {
1344 		qdf_print("%s: Invalid handle", __func__);
1345 		return A_ERROR;
1346 	}
1347 
1348 	fw_data = (struct ol_fw_data *)data;
1349 	len = fw_data->len;
1350 	if (len < (sizeof(uint32_t) *
1351 		   (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
1352 		len < (sizeof(uint32_t) *
1353 		       (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
1354 		len < (sizeof(uint32_t) *
1355 		       (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
1356 		len < (sizeof(uint32_t) *
1357 		       (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
1358 		len < (sizeof(uint32_t) *
1359 		       (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) {
1360 		qdf_print("Invalid msdu len in %s", __func__);
1361 		qdf_assert(0);
1362 		return A_ERROR;
1363 	}
1364 
1365 	pl_tgt_hdr = (uint32_t *)fw_data->data;
1366 	/*
1367 	 * Makes the short words (16 bits) portable b/w little endian
1368 	 * and big endian
1369 	 */
1370 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
1371 	pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) &
1372 			ATH_PKTLOG_HDR_FLAGS_MASK) >>
1373 		       ATH_PKTLOG_HDR_FLAGS_SHIFT;
1374 	pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) &
1375 			     ATH_PKTLOG_HDR_MISSED_CNT_MASK) >>
1376 			    ATH_PKTLOG_HDR_MISSED_CNT_SHIFT;
1377 	pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) &
1378 				   ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
1379 				  ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
1380 	pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) &
1381 		       ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT;
1382 	pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
1383 	log_size = pl_hdr.size;
1384 	pl_info = pl_dev->pl_info;
1385 
1386 	/*
1387 	 * Will be uncommented when the rate control update
1388 	 * for pktlog is implemented in the firmware.
1389 	 * Currently derived from the TX PPDU status
1390 	 */
1391 	rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info,
1392 						   log_size, &pl_hdr);
1393 	if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
1394 		qdf_assert(0);
1395 		return A_ERROR;
1396 	}
1397 	qdf_mem_copy(rcu_log.txRateCtrl,
1398 		     ((char *)fw_data->data +
1399 		      sizeof(struct ath_pktlog_hdr)),
1400 		     pl_hdr.size);
1401 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl);
1402 	return A_OK;
1403 }
1404 #endif
1405 
1406 #if  defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
1407 int process_rx_desc_remote(void *pdev, void *data)
1408 {
1409 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1410 	struct ath_pktlog_hdr pl_hdr;
1411 	struct ath_pktlog_rx_info rxstat_log;
1412 	size_t log_size;
1413 	struct ath_pktlog_info *pl_info;
1414 	qdf_nbuf_t log_nbuf = (qdf_nbuf_t)data;
1415 
1416 	pl_info = pl_dev->pl_info;
1417 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
1418 	pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
1419 	pl_hdr.missed_cnt = 0;
1420 	pl_hdr.log_type = 22; /*PKTLOG_TYPE_RX_STATBUF*/
1421 	pl_hdr.size = qdf_nbuf_len(log_nbuf);
1422 	pl_hdr.timestamp = 0;
1423 	log_size = pl_hdr.size;
1424 	rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
1425 						  log_size, &pl_hdr);
1426 
1427 	if (!rxstat_log.rx_desc) {
1428 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
1429 				"%s: Rx descriptor is NULL", __func__);
1430 		return -EFAULT;
1431 	}
1432 
1433 	qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size);
1434 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL,
1435 						rxstat_log.rx_desc);
1436 	return 0;
1437 }
1438 
1439 int
1440 process_pktlog_lite(void *context, void *log_data, uint16_t log_type)
1441 {
1442 	struct pktlog_dev_t *pl_dev = get_pktlog_handle();
1443 	struct ath_pktlog_info *pl_info;
1444 	struct ath_pktlog_hdr pl_hdr;
1445 	struct ath_pktlog_rx_info rxstat_log;
1446 	size_t log_size;
1447 	qdf_nbuf_t log_nbuf = (qdf_nbuf_t)log_data;
1448 
1449 	pl_info = pl_dev->pl_info;
1450 	qdf_mem_zero(&pl_hdr, sizeof(pl_hdr));
1451 	pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S);
1452 	pl_hdr.missed_cnt = 0;
1453 	pl_hdr.log_type = log_type;
1454 	pl_hdr.size = qdf_nbuf_len(log_nbuf);
1455 	pl_hdr.timestamp = 0;
1456 	log_size = pl_hdr.size;
1457 	rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
1458 						   log_size, &pl_hdr);
1459 	if (!rxstat_log.rx_desc) {
1460 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
1461 			"%s: Rx descriptor is NULL", __func__);
1462 		return -EFAULT;
1463 	}
1464 
1465 	qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size);
1466 
1467 	cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc);
1468 	return 0;
1469 }
1470 #else
1471 int process_rx_desc_remote(void *pdev, void *data)
1472 {
1473 	return 0;
1474 }
1475 int
1476 process_pktlog_lite(void *context, void *log_data, uint16_t log_type)
1477 {
1478 	return 0;
1479 }
1480 #endif
1481 #endif /*REMOVE_PKT_LOG */
1482