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