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