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