xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name #include "qdf_types.h"
19*5113495bSYour Name #include "hal_be_hw_headers.h"
20*5113495bSYour Name #include "dp_types.h"
21*5113495bSYour Name #include "hal_be_rx.h"
22*5113495bSYour Name #include "hal_api.h"
23*5113495bSYour Name #include "qdf_trace.h"
24*5113495bSYour Name #include "hal_be_api_mon.h"
25*5113495bSYour Name #include "dp_internal.h"
26*5113495bSYour Name #include "qdf_mem.h"   /* qdf_mem_malloc,free */
27*5113495bSYour Name #include <qdf_flex_mem.h>
28*5113495bSYour Name #include "qdf_nbuf_frag.h"
29*5113495bSYour Name #include "dp_mon.h"
30*5113495bSYour Name #include <dp_rx_mon.h>
31*5113495bSYour Name #include <dp_mon_2.0.h>
32*5113495bSYour Name #include <dp_rx_mon.h>
33*5113495bSYour Name #include <dp_rx_mon_2.0.h>
34*5113495bSYour Name #include <dp_rx.h>
35*5113495bSYour Name #include <dp_be.h>
36*5113495bSYour Name #include <hal_be_api_mon.h>
37*5113495bSYour Name #ifdef QCA_SUPPORT_LITE_MONITOR
38*5113495bSYour Name #include "dp_lite_mon.h"
39*5113495bSYour Name #endif
40*5113495bSYour Name 
41*5113495bSYour Name #define F_MASK 0xFFFF
42*5113495bSYour Name #define TEST_MASK 0xCBF
43*5113495bSYour Name 
44*5113495bSYour Name #ifdef MONITOR_TLV_RECORDING_ENABLE
45*5113495bSYour Name /**
46*5113495bSYour Name  * dp_mon_record_index_update() - update the indexes of dp_mon_tlv_logger
47*5113495bSYour Name  *                                 to store next tlv
48*5113495bSYour Name  *
49*5113495bSYour Name  * @mon_pdev_be: pointer to dp_mon_pdev_be
50*5113495bSYour Name  *
51*5113495bSYour Name  * Return
52*5113495bSYour Name  */
53*5113495bSYour Name void
dp_mon_record_index_update(struct dp_mon_pdev_be * mon_pdev_be)54*5113495bSYour Name dp_mon_record_index_update(struct dp_mon_pdev_be *mon_pdev_be)
55*5113495bSYour Name {
56*5113495bSYour Name 	struct dp_mon_tlv_logger *tlv_log = NULL;
57*5113495bSYour Name 	struct dp_mon_tlv_info *tlv_info = NULL;
58*5113495bSYour Name 
59*5113495bSYour Name 	if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log))
60*5113495bSYour Name 		return;
61*5113495bSYour Name 
62*5113495bSYour Name 	tlv_log = mon_pdev_be->rx_tlv_log;
63*5113495bSYour Name 	if (!tlv_log->tlv_logging_enable || !(tlv_log->buff))
64*5113495bSYour Name 		return;
65*5113495bSYour Name 
66*5113495bSYour Name 	tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff;
67*5113495bSYour Name 
68*5113495bSYour Name 	(tlv_log->curr_ppdu_pos + 1 == MAX_NUM_PPDU_RECORD) ?
69*5113495bSYour Name 		tlv_log->curr_ppdu_pos = 0 :
70*5113495bSYour Name 			tlv_log->curr_ppdu_pos++;
71*5113495bSYour Name 
72*5113495bSYour Name 	tlv_log->wrap_flag = 0;
73*5113495bSYour Name 	tlv_log->ppdu_start_idx = tlv_log->curr_ppdu_pos *
74*5113495bSYour Name 		MAX_TLVS_PER_PPDU;
75*5113495bSYour Name 	tlv_log->mpdu_idx = tlv_log->ppdu_start_idx +
76*5113495bSYour Name 		MAX_PPDU_START_TLV_NUM;
77*5113495bSYour Name 	tlv_log->ppdu_end_idx = tlv_log->mpdu_idx + MAX_MPDU_TLV_NUM;
78*5113495bSYour Name 	tlv_log->max_ppdu_start_idx = tlv_log->ppdu_start_idx +
79*5113495bSYour Name 		MAX_PPDU_START_TLV_NUM - 1;
80*5113495bSYour Name 	tlv_log->max_mpdu_idx = tlv_log->mpdu_idx +
81*5113495bSYour Name 		MAX_MPDU_TLV_NUM - 1;
82*5113495bSYour Name 	tlv_log->max_ppdu_end_idx = tlv_log->ppdu_end_idx +
83*5113495bSYour Name 		MAX_PPDU_END_TLV_NUM - 1;
84*5113495bSYour Name }
85*5113495bSYour Name 
86*5113495bSYour Name /**
87*5113495bSYour Name  * dp_mon_record_tlv() - Store the contents of the tlv in buffer
88*5113495bSYour Name  *
89*5113495bSYour Name  * @mon_pdev_be: pointe to dp_mon_pdev_be
90*5113495bSYour Name  * @ppdu_info: struct hal_rx_ppdu_info
91*5113495bSYour Name  *
92*5113495bSYour Name  * Return
93*5113495bSYour Name  */
94*5113495bSYour Name void
dp_mon_record_tlv(struct dp_mon_pdev_be * mon_pdev_be,struct hal_rx_ppdu_info * ppdu_info)95*5113495bSYour Name dp_mon_record_tlv(struct dp_mon_pdev_be *mon_pdev_be,
96*5113495bSYour Name 		  struct hal_rx_ppdu_info *ppdu_info)
97*5113495bSYour Name {
98*5113495bSYour Name 	struct dp_mon_tlv_logger *tlv_log = NULL;
99*5113495bSYour Name 	struct dp_mon_tlv_info *tlv_info = NULL;
100*5113495bSYour Name 	uint32_t tlv_tag;
101*5113495bSYour Name 	uint16_t *ppdu_start_idx = NULL;
102*5113495bSYour Name 	uint16_t *mpdu_idx = NULL;
103*5113495bSYour Name 	uint16_t *ppdu_end_idx = NULL;
104*5113495bSYour Name 
105*5113495bSYour Name 	if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log))
106*5113495bSYour Name 		return;
107*5113495bSYour Name 
108*5113495bSYour Name 	tlv_log = mon_pdev_be->rx_tlv_log;
109*5113495bSYour Name 	if (!tlv_log->tlv_logging_enable || !(tlv_log->buff))
110*5113495bSYour Name 		return;
111*5113495bSYour Name 
112*5113495bSYour Name 	tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff;
113*5113495bSYour Name 	ppdu_start_idx = &tlv_log->ppdu_start_idx;
114*5113495bSYour Name 	mpdu_idx = &tlv_log->mpdu_idx;
115*5113495bSYour Name 	ppdu_end_idx = &tlv_log->ppdu_end_idx;
116*5113495bSYour Name 
117*5113495bSYour Name 	tlv_tag = ppdu_info->rx_tlv_info.tlv_tag;
118*5113495bSYour Name 	if (ppdu_info->rx_tlv_info.tlv_category == CATEGORY_PPDU_START) {
119*5113495bSYour Name 		tlv_info[*ppdu_start_idx].tlv_tag = tlv_tag;
120*5113495bSYour Name 		switch (tlv_tag) {
121*5113495bSYour Name 		case WIFIRX_PPDU_START_E:
122*5113495bSYour Name 			tlv_info[*ppdu_start_idx].
123*5113495bSYour Name 				data.ppdu_start.ppdu_id =
124*5113495bSYour Name 					ppdu_info->com_info.ppdu_id;
125*5113495bSYour Name 			break;
126*5113495bSYour Name 		case WIFIRX_PPDU_START_USER_INFO_E:
127*5113495bSYour Name 			tlv_info[*ppdu_start_idx].
128*5113495bSYour Name 				data.ppdu_start_user_info.user_id =
129*5113495bSYour Name 					ppdu_info->user_id;
130*5113495bSYour Name 			tlv_info[*ppdu_start_idx].
131*5113495bSYour Name 				data.ppdu_start_user_info.rate_mcs =
132*5113495bSYour Name 					ppdu_info->rx_status.mcs;
133*5113495bSYour Name 			tlv_info[*ppdu_start_idx].
134*5113495bSYour Name 				data.ppdu_start_user_info.nss =
135*5113495bSYour Name 					ppdu_info->rx_status.nss;
136*5113495bSYour Name 			tlv_info[*ppdu_start_idx].
137*5113495bSYour Name 				data.ppdu_start_user_info.reception_type =
138*5113495bSYour Name 					ppdu_info->rx_status.reception_type;
139*5113495bSYour Name 			tlv_info[*ppdu_start_idx].
140*5113495bSYour Name 				data.ppdu_start_user_info.sgi =
141*5113495bSYour Name 					ppdu_info->rx_status.sgi;
142*5113495bSYour Name 			break;
143*5113495bSYour Name 		}
144*5113495bSYour Name 		if (*ppdu_start_idx < tlv_log->max_ppdu_start_idx)
145*5113495bSYour Name 			(*ppdu_start_idx)++;
146*5113495bSYour Name 	} else if (ppdu_info->rx_tlv_info.tlv_category == CATEGORY_MPDU) {
147*5113495bSYour Name 		tlv_info[*mpdu_idx].tlv_tag = tlv_tag;
148*5113495bSYour Name 		switch (tlv_tag) {
149*5113495bSYour Name 		case WIFIRX_MPDU_START_E:
150*5113495bSYour Name 			tlv_info[*mpdu_idx].
151*5113495bSYour Name 				data.mpdu_start.user_id =
152*5113495bSYour Name 					ppdu_info->user_id;
153*5113495bSYour Name 			tlv_info[*mpdu_idx].
154*5113495bSYour Name 				data.mpdu_start.wrap_flag =
155*5113495bSYour Name 					tlv_log->wrap_flag;
156*5113495bSYour Name 			break;
157*5113495bSYour Name 		case WIFIRX_MPDU_END_E:
158*5113495bSYour Name 			tlv_info[*mpdu_idx].
159*5113495bSYour Name 				data.mpdu_end.user_id =
160*5113495bSYour Name 					ppdu_info->user_id;
161*5113495bSYour Name 			tlv_info[*mpdu_idx].
162*5113495bSYour Name 				data.mpdu_end.fcs_err =
163*5113495bSYour Name 					ppdu_info->fcs_err;
164*5113495bSYour Name 			tlv_info[*mpdu_idx].
165*5113495bSYour Name 				data.mpdu_end.wrap_flag =
166*5113495bSYour Name 					tlv_log->wrap_flag;
167*5113495bSYour Name 			break;
168*5113495bSYour Name 		case WIFIRX_HEADER_E:
169*5113495bSYour Name 			tlv_info[*mpdu_idx].
170*5113495bSYour Name 				data.header.wrap_flag =
171*5113495bSYour Name 					tlv_log->wrap_flag;
172*5113495bSYour Name 			break;
173*5113495bSYour Name 		case WIFIRX_MSDU_END_E:
174*5113495bSYour Name 			tlv_info[*mpdu_idx].
175*5113495bSYour Name 				data.msdu_end.user_id =
176*5113495bSYour Name 					ppdu_info->user_id;
177*5113495bSYour Name 			tlv_info[*mpdu_idx].
178*5113495bSYour Name 				data.msdu_end.wrap_flag =
179*5113495bSYour Name 					tlv_log->wrap_flag;
180*5113495bSYour Name 			break;
181*5113495bSYour Name 		case WIFIMON_BUFFER_ADDR_E:
182*5113495bSYour Name 			tlv_info[*mpdu_idx].
183*5113495bSYour Name 				data.mon_buffer_addr.dma_length =
184*5113495bSYour Name 					ppdu_info->packet_info.dma_length;
185*5113495bSYour Name 			tlv_info[*mpdu_idx].
186*5113495bSYour Name 				data.mon_buffer_addr.truncation =
187*5113495bSYour Name 					ppdu_info->packet_info.truncated;
188*5113495bSYour Name 			tlv_info[*mpdu_idx].
189*5113495bSYour Name 				data.mon_buffer_addr.continuation =
190*5113495bSYour Name 					ppdu_info->packet_info.msdu_continuation;
191*5113495bSYour Name 			tlv_info[*mpdu_idx].
192*5113495bSYour Name 				data.mon_buffer_addr.wrap_flag =
193*5113495bSYour Name 					tlv_log->wrap_flag;
194*5113495bSYour Name 			break;
195*5113495bSYour Name 		}
196*5113495bSYour Name 		if (*mpdu_idx < tlv_log->max_mpdu_idx) {
197*5113495bSYour Name 			(*mpdu_idx)++;
198*5113495bSYour Name 		} else {
199*5113495bSYour Name 			*mpdu_idx = *mpdu_idx - MAX_MPDU_TLV_NUM + 1;
200*5113495bSYour Name 			tlv_log->wrap_flag ^= 1;
201*5113495bSYour Name 		}
202*5113495bSYour Name 	} else if (ppdu_info->rx_tlv_info.tlv_category == CATEGORY_PPDU_END) {
203*5113495bSYour Name 		tlv_info[*ppdu_end_idx].tlv_tag = tlv_tag;
204*5113495bSYour Name 		switch (tlv_tag) {
205*5113495bSYour Name 		case WIFIRX_USER_PPDU_END_E:
206*5113495bSYour Name 			break;
207*5113495bSYour Name 		case WIFIRX_PPDU_END_E:
208*5113495bSYour Name 			break;
209*5113495bSYour Name 		case WIFIPHYRX_RSSI_LEGACY_E:
210*5113495bSYour Name 			break;
211*5113495bSYour Name 		case WIFIPHYRX_L_SIG_B_E:
212*5113495bSYour Name 			break;
213*5113495bSYour Name 		case WIFIPHYRX_COMMON_USER_INFO_E:
214*5113495bSYour Name 			break;
215*5113495bSYour Name 		case WIFIPHYRX_DATA_DONE_E:
216*5113495bSYour Name 			break;
217*5113495bSYour Name 		case WIFIPHYRX_PKT_END_PART1_E:
218*5113495bSYour Name 			break;
219*5113495bSYour Name 		case WIFIPHYRX_PKT_END_E:
220*5113495bSYour Name 			break;
221*5113495bSYour Name 		case WIFIRXPCU_PPDU_END_INFO_E:
222*5113495bSYour Name 			break;
223*5113495bSYour Name 		case WIFIRX_PPDU_END_USER_STATS_E:
224*5113495bSYour Name 			break;
225*5113495bSYour Name 		case WIFIRX_PPDU_END_STATUS_DONE_E:
226*5113495bSYour Name 			break;
227*5113495bSYour Name 		}
228*5113495bSYour Name 		if (*ppdu_end_idx < tlv_log->max_ppdu_end_idx)
229*5113495bSYour Name 			(*ppdu_end_idx)++;
230*5113495bSYour Name 	}
231*5113495bSYour Name }
232*5113495bSYour Name 
233*5113495bSYour Name /**
234*5113495bSYour Name  * dp_mon_record_clear_buffer() - Clear the buffer to record next PPDU
235*5113495bSYour Name  *
236*5113495bSYour Name  * @mon_pdev_be: pointer to dp_mon_pdev_be
237*5113495bSYour Name  *
238*5113495bSYour Name  * Return
239*5113495bSYour Name  */
240*5113495bSYour Name void
dp_mon_record_clear_buffer(struct dp_mon_pdev_be * mon_pdev_be)241*5113495bSYour Name dp_mon_record_clear_buffer(struct dp_mon_pdev_be *mon_pdev_be)
242*5113495bSYour Name {
243*5113495bSYour Name 	struct dp_mon_tlv_logger *tlv_log = NULL;
244*5113495bSYour Name 	struct dp_mon_tlv_info *tlv_info = NULL;
245*5113495bSYour Name 
246*5113495bSYour Name 	if (!mon_pdev_be || !(mon_pdev_be->rx_tlv_log))
247*5113495bSYour Name 		return;
248*5113495bSYour Name 
249*5113495bSYour Name 	tlv_log = mon_pdev_be->rx_tlv_log;
250*5113495bSYour Name 	if (!tlv_log->tlv_logging_enable || !(tlv_log->buff))
251*5113495bSYour Name 		return;
252*5113495bSYour Name 
253*5113495bSYour Name 	tlv_info = (struct dp_mon_tlv_info *)tlv_log->buff;
254*5113495bSYour Name 	qdf_mem_zero(&tlv_info[tlv_log->ppdu_start_idx],
255*5113495bSYour Name 		     MAX_TLVS_PER_PPDU * sizeof(struct dp_mon_tlv_info));
256*5113495bSYour Name }
257*5113495bSYour Name #else
258*5113495bSYour Name void
dp_mon_record_index_update(struct dp_mon_pdev_be * mon_pdev_be)259*5113495bSYour Name dp_mon_record_index_update(struct dp_mon_pdev_be *mon_pdev_be)
260*5113495bSYour Name {
261*5113495bSYour Name }
262*5113495bSYour Name 
263*5113495bSYour Name void
dp_mon_record_tlv(struct dp_mon_pdev_be * mon_pdev_be,struct hal_rx_ppdu_info * ppdu_info)264*5113495bSYour Name dp_mon_record_tlv(struct dp_mon_pdev_be *mon_pdev_be,
265*5113495bSYour Name 		  struct hal_rx_ppdu_info *ppdu_info)
266*5113495bSYour Name {
267*5113495bSYour Name }
268*5113495bSYour Name 
269*5113495bSYour Name void
dp_mon_record_clear_buffer(struct dp_mon_pdev_be * mon_pdev_be)270*5113495bSYour Name dp_mon_record_clear_buffer(struct dp_mon_pdev_be *mon_pdev_be)
271*5113495bSYour Name {
272*5113495bSYour Name }
273*5113495bSYour Name 
274*5113495bSYour Name #endif
275*5113495bSYour Name 
276*5113495bSYour Name /**
277*5113495bSYour Name  * dp_rx_mon_update_drop_cnt() - Update drop statistics
278*5113495bSYour Name  *
279*5113495bSYour Name  * @mon_pdev: monitor pdev
280*5113495bSYour Name  * @hal_mon_rx_desc: HAL monitor desc
281*5113495bSYour Name  *
282*5113495bSYour Name  * Return: void
283*5113495bSYour Name  */
284*5113495bSYour Name static inline void
dp_rx_mon_update_drop_cnt(struct dp_mon_pdev * mon_pdev,struct hal_mon_desc * hal_mon_rx_desc)285*5113495bSYour Name dp_rx_mon_update_drop_cnt(struct dp_mon_pdev *mon_pdev,
286*5113495bSYour Name 			  struct hal_mon_desc *hal_mon_rx_desc)
287*5113495bSYour Name {
288*5113495bSYour Name 	mon_pdev->rx_mon_stats.empty_desc_ppdu++;
289*5113495bSYour Name 	mon_pdev->rx_mon_stats.ppdu_drop_cnt +=
290*5113495bSYour Name 		hal_mon_rx_desc->ppdu_drop_count;
291*5113495bSYour Name 	mon_pdev->rx_mon_stats.mpdu_drop_cnt +=
292*5113495bSYour Name 		hal_mon_rx_desc->mpdu_drop_count;
293*5113495bSYour Name 	if (hal_mon_rx_desc->end_of_ppdu_dropped)
294*5113495bSYour Name 		mon_pdev->rx_mon_stats.end_of_ppdu_drop_cnt++;
295*5113495bSYour Name 	mon_pdev->rx_mon_stats.tlv_drop_cnt +=
296*5113495bSYour Name 		hal_mon_rx_desc->tlv_drop_count;
297*5113495bSYour Name }
298*5113495bSYour Name 
299*5113495bSYour Name #ifdef QCA_MONITOR_2_0_PKT_SUPPORT
300*5113495bSYour Name #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) &&\
301*5113495bSYour Name 	defined(WLAN_SUPPORT_RX_TAG_STATISTICS)
302*5113495bSYour Name /** dp_mon_rx_update_rx_protocol_tag_stats() - Update mon protocols's
303*5113495bSYour Name  *					      statistics
304*5113495bSYour Name  * @pdev: pdev handle
305*5113495bSYour Name  * @protocol_index: Protocol index for which the stats should be incremented
306*5113495bSYour Name  * @ring_index: REO ring number from which this tag was received.
307*5113495bSYour Name  *
308*5113495bSYour Name  * Return: void
309*5113495bSYour Name  */
dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev * pdev,uint16_t protocol_index)310*5113495bSYour Name static void dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev,
311*5113495bSYour Name 						   uint16_t protocol_index)
312*5113495bSYour Name {
313*5113495bSYour Name 	pdev->mon_proto_tag_stats[protocol_index].tag_ctr++;
314*5113495bSYour Name }
315*5113495bSYour Name 
316*5113495bSYour Name #ifdef QCA_TEST_MON_PF_TAGS_STATS
317*5113495bSYour Name 
318*5113495bSYour Name static
dp_rx_mon_print_tag_buf(uint8_t * buf,uint16_t room)319*5113495bSYour Name void dp_rx_mon_print_tag_buf(uint8_t *buf, uint16_t room)
320*5113495bSYour Name {
321*5113495bSYour Name 	print_hex_dump(KERN_ERR, "TLV BUFFER: ", DUMP_PREFIX_NONE,
322*5113495bSYour Name 		       32, 2, buf, room, false);
323*5113495bSYour Name }
324*5113495bSYour Name 
325*5113495bSYour Name #else
326*5113495bSYour Name static
dp_rx_mon_print_tag_buf(uint8_t * buf,uint16_t room)327*5113495bSYour Name void dp_rx_mon_print_tag_buf(uint8_t *buf, uint16_t room)
328*5113495bSYour Name {
329*5113495bSYour Name }
330*5113495bSYour Name #endif
331*5113495bSYour Name 
332*5113495bSYour Name void
dp_rx_mon_shift_pf_tag_in_headroom(qdf_nbuf_t nbuf,struct dp_soc * soc,struct hal_rx_ppdu_info * ppdu_info)333*5113495bSYour Name dp_rx_mon_shift_pf_tag_in_headroom(qdf_nbuf_t nbuf, struct dp_soc *soc,
334*5113495bSYour Name 				   struct hal_rx_ppdu_info *ppdu_info)
335*5113495bSYour Name {
336*5113495bSYour Name 	uint32_t room = 0;
337*5113495bSYour Name 	uint16_t msdu_count = 0;
338*5113495bSYour Name 	uint16_t *dp = NULL;
339*5113495bSYour Name 	uint16_t *hp = NULL;
340*5113495bSYour Name 	uint16_t tlv_data_len, total_tlv_len;
341*5113495bSYour Name 	uint32_t bytes = 0;
342*5113495bSYour Name 
343*5113495bSYour Name 	if (qdf_unlikely(!soc)) {
344*5113495bSYour Name 		dp_mon_err("Soc[%pK] Null. Can't update pftag to nbuf headroom",
345*5113495bSYour Name 			   soc);
346*5113495bSYour Name 		return;
347*5113495bSYour Name 	}
348*5113495bSYour Name 
349*5113495bSYour Name 	if (!wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx))
350*5113495bSYour Name 		return;
351*5113495bSYour Name 
352*5113495bSYour Name 	if (qdf_unlikely(!nbuf))
353*5113495bSYour Name 		return;
354*5113495bSYour Name 
355*5113495bSYour Name 	/* Headroom must be have enough space for tlv to be added*/
356*5113495bSYour Name 	if (qdf_unlikely(qdf_nbuf_headroom(nbuf) < DP_RX_MON_TLV_ROOM)) {
357*5113495bSYour Name 		dp_mon_err("Headroom[%d] < DP_RX_MON_TLV_ROOM[%d]",
358*5113495bSYour Name 			   qdf_nbuf_headroom(nbuf), DP_RX_MON_TLV_ROOM);
359*5113495bSYour Name 		return;
360*5113495bSYour Name 	}
361*5113495bSYour Name 
362*5113495bSYour Name 	hp = (uint16_t *)qdf_nbuf_head(nbuf);
363*5113495bSYour Name 	msdu_count = *hp;
364*5113495bSYour Name 
365*5113495bSYour Name 	if (qdf_unlikely(!msdu_count))
366*5113495bSYour Name 		return;
367*5113495bSYour Name 
368*5113495bSYour Name 	dp_mon_debug("msdu_count: %d", msdu_count);
369*5113495bSYour Name 
370*5113495bSYour Name 	room = DP_RX_MON_PF_TAG_LEN_PER_FRAG * msdu_count;
371*5113495bSYour Name 	tlv_data_len = DP_RX_MON_TLV_MSDU_CNT + (room);
372*5113495bSYour Name 	total_tlv_len = DP_RX_MON_TLV_HDR_LEN + tlv_data_len;
373*5113495bSYour Name 
374*5113495bSYour Name 	//1. store space for MARKER
375*5113495bSYour Name 	dp = (uint16_t *)qdf_nbuf_push_head(nbuf, sizeof(uint16_t));
376*5113495bSYour Name 	if (qdf_likely(dp)) {
377*5113495bSYour Name 		*(uint16_t *)dp = DP_RX_MON_TLV_HDR_MARKER;
378*5113495bSYour Name 		bytes += sizeof(uint16_t);
379*5113495bSYour Name 	}
380*5113495bSYour Name 
381*5113495bSYour Name 	//2. store space for total size
382*5113495bSYour Name 	dp = (uint16_t *)qdf_nbuf_push_head(nbuf, sizeof(uint16_t));
383*5113495bSYour Name 	if (qdf_likely(dp)) {
384*5113495bSYour Name 		*(uint16_t *)dp = total_tlv_len;
385*5113495bSYour Name 		bytes += sizeof(uint16_t);
386*5113495bSYour Name 	}
387*5113495bSYour Name 
388*5113495bSYour Name 	//create TLV
389*5113495bSYour Name 	bytes += dp_mon_rx_add_tlv(DP_RX_MON_TLV_PF_ID, tlv_data_len, hp, nbuf);
390*5113495bSYour Name 
391*5113495bSYour Name 	dp_rx_mon_print_tag_buf(qdf_nbuf_data(nbuf), total_tlv_len);
392*5113495bSYour Name 
393*5113495bSYour Name 	qdf_nbuf_pull_head(nbuf, bytes);
394*5113495bSYour Name 
395*5113495bSYour Name }
396*5113495bSYour Name 
397*5113495bSYour Name void
dp_rx_mon_pf_tag_to_buf_headroom_2_0(void * nbuf,struct hal_rx_ppdu_info * ppdu_info,struct dp_pdev * pdev,struct dp_soc * soc)398*5113495bSYour Name dp_rx_mon_pf_tag_to_buf_headroom_2_0(void *nbuf,
399*5113495bSYour Name 				     struct hal_rx_ppdu_info *ppdu_info,
400*5113495bSYour Name 				     struct dp_pdev *pdev, struct dp_soc *soc)
401*5113495bSYour Name {
402*5113495bSYour Name 	uint8_t *nbuf_head = NULL;
403*5113495bSYour Name 	uint8_t user_id;
404*5113495bSYour Name 	struct hal_rx_mon_msdu_info *msdu_info;
405*5113495bSYour Name 	uint16_t flow_id;
406*5113495bSYour Name 	uint16_t cce_metadata;
407*5113495bSYour Name 	uint16_t protocol_tag = 0;
408*5113495bSYour Name 	uint32_t flow_tag;
409*5113495bSYour Name 	uint8_t invalid_cce = 0, invalid_fse = 0;
410*5113495bSYour Name 
411*5113495bSYour Name 	if (qdf_unlikely(!soc)) {
412*5113495bSYour Name 		dp_mon_err("Soc[%pK] Null. Can't update pftag to nbuf headroom",
413*5113495bSYour Name 			   soc);
414*5113495bSYour Name 		return;
415*5113495bSYour Name 	}
416*5113495bSYour Name 
417*5113495bSYour Name 	if (!wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx))
418*5113495bSYour Name 		return;
419*5113495bSYour Name 
420*5113495bSYour Name 	if (qdf_unlikely(!nbuf))
421*5113495bSYour Name 		return;
422*5113495bSYour Name 
423*5113495bSYour Name 	/* Headroom must be have enough space for tlv to be added*/
424*5113495bSYour Name 	if (qdf_unlikely(qdf_nbuf_headroom(nbuf) < DP_RX_MON_TLV_ROOM)) {
425*5113495bSYour Name 		dp_mon_err("Headroom[%d] < DP_RX_MON_TLV_ROOM[%d]",
426*5113495bSYour Name 			   qdf_nbuf_headroom(nbuf), DP_RX_MON_TLV_ROOM);
427*5113495bSYour Name 		return;
428*5113495bSYour Name 	}
429*5113495bSYour Name 
430*5113495bSYour Name 	user_id = ppdu_info->user_id;
431*5113495bSYour Name 	if (qdf_unlikely(user_id >= HAL_MAX_UL_MU_USERS)) {
432*5113495bSYour Name 		dp_mon_debug("Invalid user_id user_id: %d pdev: %pK", user_id, pdev);
433*5113495bSYour Name 		return;
434*5113495bSYour Name 	}
435*5113495bSYour Name 
436*5113495bSYour Name 	msdu_info = &ppdu_info->msdu[user_id];
437*5113495bSYour Name 	flow_id = ppdu_info->rx_msdu_info[user_id].flow_idx;
438*5113495bSYour Name 	cce_metadata = ppdu_info->rx_msdu_info[user_id].cce_metadata -
439*5113495bSYour Name 		       RX_PROTOCOL_TAG_START_OFFSET;
440*5113495bSYour Name 
441*5113495bSYour Name 	flow_tag = ppdu_info->rx_msdu_info[user_id].fse_metadata & F_MASK;
442*5113495bSYour Name 
443*5113495bSYour Name 	if (qdf_unlikely((cce_metadata > RX_PROTOCOL_TAG_MAX - 1) ||
444*5113495bSYour Name 			 (cce_metadata > 0 && cce_metadata < 4))) {
445*5113495bSYour Name 		dp_mon_debug("Invalid user_id cce_metadata: %d pdev: %pK", cce_metadata, pdev);
446*5113495bSYour Name 		invalid_cce = 1;
447*5113495bSYour Name 		protocol_tag = cce_metadata;
448*5113495bSYour Name 	} else {
449*5113495bSYour Name 		protocol_tag = pdev->rx_proto_tag_map[cce_metadata].tag;
450*5113495bSYour Name 		dp_mon_rx_update_rx_protocol_tag_stats(pdev, cce_metadata);
451*5113495bSYour Name 	}
452*5113495bSYour Name 
453*5113495bSYour Name 	if (flow_tag > 0) {
454*5113495bSYour Name 		dp_mon_rx_update_rx_flow_tag_stats(pdev, flow_id);
455*5113495bSYour Name 	} else {
456*5113495bSYour Name 		dp_mon_debug("Invalid flow_tag: %d pdev: %pK ", flow_tag, pdev);
457*5113495bSYour Name 		invalid_fse = 1;
458*5113495bSYour Name 	}
459*5113495bSYour Name 
460*5113495bSYour Name 	if (invalid_cce && invalid_fse)
461*5113495bSYour Name 		return;
462*5113495bSYour Name 
463*5113495bSYour Name 	if (msdu_info->msdu_index >= DP_RX_MON_MAX_MSDU) {
464*5113495bSYour Name 		dp_mon_err("msdu_index causes overflow in headroom");
465*5113495bSYour Name 		return;
466*5113495bSYour Name 	}
467*5113495bSYour Name 
468*5113495bSYour Name 	dp_mon_debug("protocol_tag: %d, cce_metadata: %d, flow_tag: %d",
469*5113495bSYour Name 		     protocol_tag, cce_metadata, flow_tag);
470*5113495bSYour Name 
471*5113495bSYour Name 	dp_mon_debug("msdu_index: %d", msdu_info->msdu_index);
472*5113495bSYour Name 
473*5113495bSYour Name 
474*5113495bSYour Name 	nbuf_head = qdf_nbuf_head(nbuf);
475*5113495bSYour Name 
476*5113495bSYour Name 	*((uint16_t *)nbuf_head) = msdu_info->msdu_index + 1;
477*5113495bSYour Name 	nbuf_head += DP_RX_MON_TLV_MSDU_CNT;
478*5113495bSYour Name 
479*5113495bSYour Name 	nbuf_head += ((msdu_info->msdu_index) * DP_RX_MON_PF_TAG_SIZE);
480*5113495bSYour Name 	if (!invalid_cce)
481*5113495bSYour Name 		*((uint16_t *)nbuf_head) = protocol_tag;
482*5113495bSYour Name 	nbuf_head += sizeof(uint16_t);
483*5113495bSYour Name 	if (!invalid_fse)
484*5113495bSYour Name 		*((uint16_t *)nbuf_head) = flow_tag;
485*5113495bSYour Name }
486*5113495bSYour Name 
487*5113495bSYour Name #else
488*5113495bSYour Name static inline void
dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev * pdev,uint16_t protocol_index)489*5113495bSYour Name dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev,
490*5113495bSYour Name 				       uint16_t protocol_index)
491*5113495bSYour Name {
492*5113495bSYour Name }
493*5113495bSYour Name 
494*5113495bSYour Name static inline
dp_rx_mon_shift_pf_tag_in_headroom(qdf_nbuf_t nbuf,struct dp_soc * soc,struct hal_rx_ppdu_info * ppdu_info)495*5113495bSYour Name void dp_rx_mon_shift_pf_tag_in_headroom(qdf_nbuf_t nbuf, struct dp_soc *soc,
496*5113495bSYour Name 					struct hal_rx_ppdu_info *ppdu_info)
497*5113495bSYour Name {
498*5113495bSYour Name }
499*5113495bSYour Name 
500*5113495bSYour Name static inline
dp_rx_mon_pf_tag_to_buf_headroom_2_0(void * nbuf,struct hal_rx_ppdu_info * ppdu_info,struct dp_pdev * pdev,struct dp_soc * soc)501*5113495bSYour Name void dp_rx_mon_pf_tag_to_buf_headroom_2_0(void *nbuf,
502*5113495bSYour Name 					  struct hal_rx_ppdu_info *ppdu_info,
503*5113495bSYour Name 					  struct dp_pdev *pdev,
504*5113495bSYour Name 					  struct dp_soc *soc)
505*5113495bSYour Name {
506*5113495bSYour Name }
507*5113495bSYour Name 
508*5113495bSYour Name #endif
509*5113495bSYour Name 
510*5113495bSYour Name #ifdef QCA_KMEM_CACHE_SUPPORT
dp_rx_mon_ppdu_info_cache_create(struct dp_pdev * pdev)511*5113495bSYour Name QDF_STATUS dp_rx_mon_ppdu_info_cache_create(struct dp_pdev *pdev)
512*5113495bSYour Name {
513*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
514*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
515*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
516*5113495bSYour Name 	uint16_t obj;
517*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info = NULL;
518*5113495bSYour Name 
519*5113495bSYour Name 	mon_pdev_be->ppdu_info_cache =
520*5113495bSYour Name 		qdf_kmem_cache_create("rx_mon_ppdu_info_cache",
521*5113495bSYour Name 				      sizeof(struct hal_rx_ppdu_info));
522*5113495bSYour Name 
523*5113495bSYour Name 	if (!mon_pdev_be->ppdu_info_cache) {
524*5113495bSYour Name 		dp_mon_err("cache creation failed pdev :%px", pdev);
525*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
526*5113495bSYour Name 	}
527*5113495bSYour Name 
528*5113495bSYour Name 	TAILQ_INIT(&mon_pdev_be->rx_mon_free_queue);
529*5113495bSYour Name 	for (obj = 0; obj < DP_RX_MON_WQ_THRESHOLD; obj++) {
530*5113495bSYour Name 		ppdu_info =  (struct hal_rx_ppdu_info *)qdf_kmem_cache_alloc(mon_pdev_be->ppdu_info_cache);
531*5113495bSYour Name 
532*5113495bSYour Name 		if (ppdu_info) {
533*5113495bSYour Name 			qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info));
534*5113495bSYour Name 			TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_free_queue,
535*5113495bSYour Name 					  ppdu_info,
536*5113495bSYour Name 					  ppdu_free_list_elem);
537*5113495bSYour Name 			mon_pdev_be->total_free_elem++;
538*5113495bSYour Name 		}
539*5113495bSYour Name 	}
540*5113495bSYour Name 	qdf_spinlock_create(&mon_pdev_be->ppdu_info_lock);
541*5113495bSYour Name 
542*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
543*5113495bSYour Name }
544*5113495bSYour Name 
dp_rx_mon_ppdu_info_cache_destroy(struct dp_pdev * pdev)545*5113495bSYour Name void dp_rx_mon_ppdu_info_cache_destroy(struct dp_pdev *pdev)
546*5113495bSYour Name {
547*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
548*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
549*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
550*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info = NULL, *temp_ppdu_info = NULL;
551*5113495bSYour Name 
552*5113495bSYour Name 	qdf_spin_lock(&mon_pdev_be->ppdu_info_lock);
553*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info,
554*5113495bSYour Name 			   &mon_pdev_be->rx_mon_free_queue,
555*5113495bSYour Name 			   ppdu_free_list_elem,
556*5113495bSYour Name 			   temp_ppdu_info) {
557*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev_be->rx_mon_free_queue,
558*5113495bSYour Name 			     ppdu_info, ppdu_free_list_elem);
559*5113495bSYour Name 		if (ppdu_info) {
560*5113495bSYour Name 			mon_pdev_be->total_free_elem--;
561*5113495bSYour Name 			qdf_kmem_cache_free(mon_pdev_be->ppdu_info_cache,
562*5113495bSYour Name 					    ppdu_info);
563*5113495bSYour Name 		}
564*5113495bSYour Name 	}
565*5113495bSYour Name 	qdf_spin_unlock(&mon_pdev_be->ppdu_info_lock);
566*5113495bSYour Name 	dp_mon_debug(" total free element: %d", mon_pdev_be->total_free_elem);
567*5113495bSYour Name 	qdf_kmem_cache_destroy(mon_pdev_be->ppdu_info_cache);
568*5113495bSYour Name }
569*5113495bSYour Name #endif
570*5113495bSYour Name 
dp_rx_mon_init_wq_sm(struct dp_pdev * pdev)571*5113495bSYour Name static QDF_STATUS dp_rx_mon_init_wq_sm(struct dp_pdev *pdev)
572*5113495bSYour Name {
573*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
574*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
575*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
576*5113495bSYour Name 
577*5113495bSYour Name 	qdf_create_work(0, &mon_pdev_be->rx_mon_work,
578*5113495bSYour Name 			dp_rx_mon_process_ppdu, pdev);
579*5113495bSYour Name 	mon_pdev_be->rx_mon_workqueue =
580*5113495bSYour Name 		qdf_alloc_unbound_workqueue("rx_mon_work_queue");
581*5113495bSYour Name 
582*5113495bSYour Name 	if (!mon_pdev_be->rx_mon_workqueue) {
583*5113495bSYour Name 		dp_mon_err("failed to create rxmon wq mon_pdev: %pK", mon_pdev);
584*5113495bSYour Name 		goto fail;
585*5113495bSYour Name 	}
586*5113495bSYour Name 	TAILQ_INIT(&mon_pdev_be->rx_mon_queue);
587*5113495bSYour Name 
588*5113495bSYour Name 	qdf_spinlock_create(&mon_pdev_be->rx_mon_wq_lock);
589*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
590*5113495bSYour Name 
591*5113495bSYour Name fail:
592*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
593*5113495bSYour Name }
594*5113495bSYour Name 
dp_rx_mon_deinit_wq_sm(struct dp_pdev * pdev)595*5113495bSYour Name static QDF_STATUS dp_rx_mon_deinit_wq_sm(struct dp_pdev *pdev)
596*5113495bSYour Name {
597*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
598*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
599*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
600*5113495bSYour Name 
601*5113495bSYour Name 	if (!mon_pdev_be->rx_mon_workqueue)
602*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
603*5113495bSYour Name 
604*5113495bSYour Name 	qdf_err(" total free element: %d", mon_pdev_be->total_free_elem);
605*5113495bSYour Name 	qdf_flush_workqueue(0, mon_pdev_be->rx_mon_workqueue);
606*5113495bSYour Name 	qdf_destroy_workqueue(0, mon_pdev_be->rx_mon_workqueue);
607*5113495bSYour Name 	qdf_flush_work(&mon_pdev_be->rx_mon_work);
608*5113495bSYour Name 	qdf_disable_work(&mon_pdev_be->rx_mon_work);
609*5113495bSYour Name 	dp_rx_mon_drain_wq(pdev);
610*5113495bSYour Name 	mon_pdev_be->rx_mon_workqueue = NULL;
611*5113495bSYour Name 	qdf_spinlock_destroy(&mon_pdev_be->rx_mon_wq_lock);
612*5113495bSYour Name 
613*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
614*5113495bSYour Name }
615*5113495bSYour Name 
616*5113495bSYour Name static
dp_rx_mon_set_zero(qdf_nbuf_t nbuf)617*5113495bSYour Name void dp_rx_mon_set_zero(qdf_nbuf_t nbuf)
618*5113495bSYour Name {
619*5113495bSYour Name 	qdf_mem_zero(qdf_nbuf_head(nbuf), DP_RX_MON_TLV_ROOM);
620*5113495bSYour Name }
621*5113495bSYour Name 
622*5113495bSYour Name /**
623*5113495bSYour Name  * dp_rx_mon_nbuf_add_rx_frag() -  Add frag to SKB
624*5113495bSYour Name  *
625*5113495bSYour Name  * @nbuf: SKB to which frag is going to be added
626*5113495bSYour Name  * @frag: frag to be added to SKB
627*5113495bSYour Name  * @frag_len: frag length
628*5113495bSYour Name  * @offset: frag offset
629*5113495bSYour Name  * @buf_size: buffer size
630*5113495bSYour Name  * @frag_ref: take frag ref
631*5113495bSYour Name  *
632*5113495bSYour Name  * Return: QDF_STATUS
633*5113495bSYour Name  */
634*5113495bSYour Name static inline QDF_STATUS
dp_rx_mon_nbuf_add_rx_frag(qdf_nbuf_t nbuf,qdf_frag_t * frag,uint16_t frag_len,uint16_t offset,uint16_t buf_size,bool frag_ref)635*5113495bSYour Name dp_rx_mon_nbuf_add_rx_frag(qdf_nbuf_t nbuf, qdf_frag_t *frag,
636*5113495bSYour Name 			   uint16_t frag_len, uint16_t offset,
637*5113495bSYour Name 			   uint16_t buf_size, bool frag_ref)
638*5113495bSYour Name {
639*5113495bSYour Name 	uint8_t num_frags;
640*5113495bSYour Name 
641*5113495bSYour Name 	num_frags = qdf_nbuf_get_nr_frags(nbuf);
642*5113495bSYour Name 	if (num_frags < QDF_NBUF_MAX_FRAGS) {
643*5113495bSYour Name 		qdf_nbuf_add_rx_frag(frag, nbuf,
644*5113495bSYour Name 				     offset,
645*5113495bSYour Name 				     frag_len,
646*5113495bSYour Name 				     buf_size,
647*5113495bSYour Name 				     frag_ref);
648*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
649*5113495bSYour Name 	}
650*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
651*5113495bSYour Name }
652*5113495bSYour Name 
653*5113495bSYour Name /**
654*5113495bSYour Name  * dp_rx_mon_handle_mpdu_end() - Process MPDU_END TLV
655*5113495bSYour Name  *
656*5113495bSYour Name  * @ppdu_info: PPDU info
657*5113495bSYour Name  *
658*5113495bSYour Name  * Return: void
659*5113495bSYour Name  */
660*5113495bSYour Name static inline void
dp_rx_mon_handle_mpdu_end(struct hal_rx_ppdu_info * ppdu_info)661*5113495bSYour Name dp_rx_mon_handle_mpdu_end(struct hal_rx_ppdu_info *ppdu_info)
662*5113495bSYour Name {
663*5113495bSYour Name 	struct hal_rx_mon_mpdu_info *mpdu_info, *mpdu_meta;
664*5113495bSYour Name 	qdf_nbuf_t nbuf;
665*5113495bSYour Name 	uint8_t user_id = ppdu_info->user_id;
666*5113495bSYour Name 	uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id];
667*5113495bSYour Name 
668*5113495bSYour Name 	mpdu_info = &ppdu_info->mpdu_info[user_id];
669*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) {
670*5113495bSYour Name 		/* reset mpdu info for next mpdu for same user */
671*5113495bSYour Name 		qdf_mem_zero(mpdu_info, sizeof(*mpdu_info));
672*5113495bSYour Name 		dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d",
673*5113495bSYour Name 			     __LINE__, user_id, mpdu_idx);
674*5113495bSYour Name 		return;
675*5113495bSYour Name 	}
676*5113495bSYour Name 	nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]);
677*5113495bSYour Name 	if (qdf_unlikely(!nbuf)) {
678*5113495bSYour Name 		dp_mon_debug("nbuf is NULL");
679*5113495bSYour Name 		return;
680*5113495bSYour Name 	}
681*5113495bSYour Name 	mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf);
682*5113495bSYour Name 	mpdu_meta->mpdu_length_err = mpdu_info->mpdu_length_err;
683*5113495bSYour Name 	mpdu_meta->fcs_err = mpdu_info->fcs_err;
684*5113495bSYour Name 	mpdu_meta->overflow_err = mpdu_info->overflow_err;
685*5113495bSYour Name 	mpdu_meta->decrypt_err = mpdu_info->decrypt_err;
686*5113495bSYour Name 	mpdu_meta->full_pkt = mpdu_info->full_pkt;
687*5113495bSYour Name 	mpdu_meta->truncated = mpdu_info->truncated;
688*5113495bSYour Name 
689*5113495bSYour Name 	/* reset mpdu info for next mpdu for same user */
690*5113495bSYour Name 	qdf_mem_zero(mpdu_info, sizeof(*mpdu_info));
691*5113495bSYour Name 	ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = false;
692*5113495bSYour Name 	ppdu_info->mpdu_count[user_id]++;
693*5113495bSYour Name }
694*5113495bSYour Name 
695*5113495bSYour Name /**
696*5113495bSYour Name  * dp_rx_mon_handle_mpdu_start() - Process MPDU_START TLV
697*5113495bSYour Name  *
698*5113495bSYour Name  * @ppdu_info: PPDU info
699*5113495bSYour Name  *
700*5113495bSYour Name  * Return: void
701*5113495bSYour Name  */
702*5113495bSYour Name static inline void
dp_rx_mon_handle_mpdu_start(struct hal_rx_ppdu_info * ppdu_info)703*5113495bSYour Name dp_rx_mon_handle_mpdu_start(struct hal_rx_ppdu_info *ppdu_info)
704*5113495bSYour Name {
705*5113495bSYour Name 	struct hal_rx_mon_mpdu_info *mpdu_info, *mpdu_meta;
706*5113495bSYour Name 	qdf_nbuf_t nbuf;
707*5113495bSYour Name 	uint8_t user_id = ppdu_info->user_id;
708*5113495bSYour Name 	uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id];
709*5113495bSYour Name 
710*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) {
711*5113495bSYour Name 		dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d", __LINE__, user_id, mpdu_idx);
712*5113495bSYour Name 		return;
713*5113495bSYour Name 	}
714*5113495bSYour Name 	nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]);
715*5113495bSYour Name 	if (qdf_unlikely(!nbuf)) {
716*5113495bSYour Name 		dp_mon_debug("nbuf is NULL");
717*5113495bSYour Name 		return;
718*5113495bSYour Name 	}
719*5113495bSYour Name 	mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(nbuf);
720*5113495bSYour Name 	mpdu_info = &ppdu_info->mpdu_info[user_id];
721*5113495bSYour Name 	mpdu_meta->decap_type = mpdu_info->decap_type;
722*5113495bSYour Name 	ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true;
723*5113495bSYour Name }
724*5113495bSYour Name 
725*5113495bSYour Name /**
726*5113495bSYour Name  * dp_rx_mon_handle_msdu_end() - Process MSDU_END TLV
727*5113495bSYour Name  *
728*5113495bSYour Name  * @pdev: DP Pdev
729*5113495bSYour Name  * @ppdu_info: PPDU info
730*5113495bSYour Name  *
731*5113495bSYour Name  * Return: void
732*5113495bSYour Name  */
733*5113495bSYour Name static inline void
dp_rx_mon_handle_msdu_end(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)734*5113495bSYour Name dp_rx_mon_handle_msdu_end(struct dp_pdev *pdev,
735*5113495bSYour Name 			  struct hal_rx_ppdu_info *ppdu_info)
736*5113495bSYour Name {
737*5113495bSYour Name 	qdf_nbuf_t nbuf;
738*5113495bSYour Name 	qdf_frag_t addr;
739*5113495bSYour Name 	uint16_t num_frags;
740*5113495bSYour Name 	struct hal_rx_mon_msdu_info *msdu_info;
741*5113495bSYour Name 	struct hal_rx_mon_msdu_info *last_buf_info;
742*5113495bSYour Name 	uint8_t user_id = ppdu_info->user_id;
743*5113495bSYour Name 	uint8_t mpdu_idx = ppdu_info->mpdu_count[user_id];
744*5113495bSYour Name 
745*5113495bSYour Name 	msdu_info = &ppdu_info->msdu[user_id];
746*5113495bSYour Name 	/* update msdu metadata at last buffer of msdu in MPDU */
747*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) {
748*5113495bSYour Name 		/* reset msdu info for next msdu for same user */
749*5113495bSYour Name 		qdf_mem_zero(msdu_info, sizeof(*msdu_info));
750*5113495bSYour Name 		dp_mon_debug(" <%d> nbuf is NULL, return user: %d mpdu_idx: %d",
751*5113495bSYour Name 			     __LINE__, user_id, mpdu_idx);
752*5113495bSYour Name 		return;
753*5113495bSYour Name 	}
754*5113495bSYour Name 	nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]);
755*5113495bSYour Name 	if (qdf_unlikely(!nbuf)) {
756*5113495bSYour Name 		dp_mon_debug("nbuf is NULL");
757*5113495bSYour Name 		return;
758*5113495bSYour Name 	}
759*5113495bSYour Name 	num_frags = qdf_nbuf_get_nr_frags(nbuf);
760*5113495bSYour Name 	if (ppdu_info->mpdu_info[user_id].decap_type ==
761*5113495bSYour Name 			HAL_HW_RX_DECAP_FORMAT_RAW) {
762*5113495bSYour Name 		return;
763*5113495bSYour Name 	}
764*5113495bSYour Name 	/* This points to last buffer of MSDU . update metadata here */
765*5113495bSYour Name 	addr = qdf_nbuf_get_frag_addr(nbuf, num_frags - 1) -
766*5113495bSYour Name 		DP_RX_MON_PACKET_OFFSET;
767*5113495bSYour Name 	last_buf_info = addr;
768*5113495bSYour Name 
769*5113495bSYour Name 	last_buf_info->first_msdu = msdu_info->first_msdu;
770*5113495bSYour Name 	last_buf_info->last_msdu = msdu_info->last_msdu;
771*5113495bSYour Name 	last_buf_info->decap_type = msdu_info->decap_type;
772*5113495bSYour Name 	last_buf_info->msdu_index = msdu_info->msdu_index;
773*5113495bSYour Name 	last_buf_info->user_rssi = msdu_info->user_rssi;
774*5113495bSYour Name 	last_buf_info->reception_type = msdu_info->reception_type;
775*5113495bSYour Name 	last_buf_info->msdu_len = msdu_info->msdu_len;
776*5113495bSYour Name 
777*5113495bSYour Name 	/* If flow classification is enabled,
778*5113495bSYour Name 	 * update protocol and flow tag to buf headroom
779*5113495bSYour Name 	 */
780*5113495bSYour Name 	dp_rx_mon_pf_tag_to_buf_headroom_2_0(nbuf, ppdu_info, pdev, pdev->soc);
781*5113495bSYour Name 
782*5113495bSYour Name 	/* reset msdu info for next msdu for same user */
783*5113495bSYour Name 	qdf_mem_zero(msdu_info, sizeof(*msdu_info));
784*5113495bSYour Name }
785*5113495bSYour Name 
786*5113495bSYour Name /**
787*5113495bSYour Name  * dp_rx_mon_handle_mon_buf_addr() - Process MON BUF ADDR TLV
788*5113495bSYour Name  *
789*5113495bSYour Name  * @pdev: DP Pdev
790*5113495bSYour Name  * @ppdu_info: PPDU info
791*5113495bSYour Name  * @desc_list: desc list head
792*5113495bSYour Name  * @tail: desc list tail
793*5113495bSYour Name  *
794*5113495bSYour Name  * Return: number of buffers reaped
795*5113495bSYour Name  */
796*5113495bSYour Name static inline uint16_t
dp_rx_mon_handle_mon_buf_addr(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,union dp_mon_desc_list_elem_t ** desc_list,union dp_mon_desc_list_elem_t ** tail)797*5113495bSYour Name dp_rx_mon_handle_mon_buf_addr(struct dp_pdev *pdev,
798*5113495bSYour Name 			      struct hal_rx_ppdu_info *ppdu_info,
799*5113495bSYour Name 			      union dp_mon_desc_list_elem_t **desc_list,
800*5113495bSYour Name 			      union dp_mon_desc_list_elem_t **tail)
801*5113495bSYour Name {
802*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
803*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
804*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
805*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
806*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
807*5113495bSYour Name 	struct hal_rx_mon_msdu_info *buf_info;
808*5113495bSYour Name 	struct hal_mon_packet_info *packet_info = &ppdu_info->packet_info;
809*5113495bSYour Name 	struct dp_mon_desc *mon_desc = (struct dp_mon_desc *)(uintptr_t)ppdu_info->packet_info.sw_cookie;
810*5113495bSYour Name 	unsigned long long desc = ppdu_info->packet_info.sw_cookie;
811*5113495bSYour Name 	struct hal_rx_mon_mpdu_info *mpdu_info;
812*5113495bSYour Name 	qdf_nbuf_t nbuf, tmp_nbuf;
813*5113495bSYour Name 	qdf_frag_t addr;
814*5113495bSYour Name 	uint16_t frag_idx = 0;
815*5113495bSYour Name 	uint16_t num_buf_reaped = 0;
816*5113495bSYour Name 	uint8_t user_id = ppdu_info->user_id;
817*5113495bSYour Name 	bool rx_hdr_valid = true;
818*5113495bSYour Name 	uint32_t cookie_2;
819*5113495bSYour Name 
820*5113495bSYour Name 	if (!mon_pdev->monitor_configured &&
821*5113495bSYour Name 	    !dp_lite_mon_is_rx_enabled(mon_pdev)) {
822*5113495bSYour Name 		return num_buf_reaped;
823*5113495bSYour Name 	}
824*5113495bSYour Name 
825*5113495bSYour Name 	if (qdf_unlikely(user_id >= HAL_MAX_UL_MU_USERS ||
826*5113495bSYour Name 			 ppdu_info->hdr_len > DP_RX_MON_MAX_RX_HEADER_LEN))
827*5113495bSYour Name 		rx_hdr_valid = false;
828*5113495bSYour Name 
829*5113495bSYour Name 	cookie_2 = DP_MON_GET_COOKIE(desc);
830*5113495bSYour Name 	mon_desc = DP_MON_GET_DESC(desc);
831*5113495bSYour Name 	qdf_assert_always(mon_desc);
832*5113495bSYour Name 
833*5113495bSYour Name 	if (mon_desc->cookie_2 != cookie_2) {
834*5113495bSYour Name 		mon_pdev->rx_mon_stats.dup_mon_sw_desc++;
835*5113495bSYour Name 		qdf_err("duplicate cookie found mon_desc:%pK", mon_desc);
836*5113495bSYour Name 		qdf_assert_always(0);
837*5113495bSYour Name 	}
838*5113495bSYour Name 
839*5113495bSYour Name 	if (mon_desc->magic != DP_MON_DESC_MAGIC)
840*5113495bSYour Name 		qdf_assert_always(0);
841*5113495bSYour Name 
842*5113495bSYour Name 	/* WAR: sometimes duplicate pkt desc are received
843*5113495bSYour Name 	 * from HW this check gracefully handles
844*5113495bSYour Name 	 * such cases.
845*5113495bSYour Name 	 */
846*5113495bSYour Name 	if ((mon_desc == mon_pdev_be->prev_rxmon_pkt_desc) &&
847*5113495bSYour Name 	    (mon_desc->cookie == mon_pdev_be->prev_rxmon_pkt_cookie)) {
848*5113495bSYour Name 		dp_mon_err("duplicate pkt desc found mon_pdev: %pK mon_desc: %pK cookie: %d",
849*5113495bSYour Name 			   mon_pdev, mon_desc,
850*5113495bSYour Name 			   mon_desc->cookie);
851*5113495bSYour Name 		mon_pdev->rx_mon_stats.dup_mon_buf_cnt++;
852*5113495bSYour Name 		return num_buf_reaped;
853*5113495bSYour Name 	}
854*5113495bSYour Name 	mon_pdev_be->prev_rxmon_pkt_desc = mon_desc;
855*5113495bSYour Name 	mon_pdev_be->prev_rxmon_pkt_cookie = mon_desc->cookie;
856*5113495bSYour Name 
857*5113495bSYour Name 	addr = mon_desc->buf_addr;
858*5113495bSYour Name 	qdf_assert_always(addr);
859*5113495bSYour Name 
860*5113495bSYour Name 	if (!mon_desc->unmapped) {
861*5113495bSYour Name 		qdf_mem_unmap_page(soc->osdev,
862*5113495bSYour Name 				   (qdf_dma_addr_t)mon_desc->paddr,
863*5113495bSYour Name 				   DP_MON_DATA_BUFFER_SIZE,
864*5113495bSYour Name 				   QDF_DMA_FROM_DEVICE);
865*5113495bSYour Name 		mon_desc->unmapped = 1;
866*5113495bSYour Name 	}
867*5113495bSYour Name 	dp_mon_add_to_free_desc_list(desc_list, tail, mon_desc);
868*5113495bSYour Name 	num_buf_reaped++;
869*5113495bSYour Name 
870*5113495bSYour Name 	mon_pdev->rx_mon_stats.pkt_buf_count++;
871*5113495bSYour Name 
872*5113495bSYour Name 	/* if rx hdr is not valid free pkt buffer and return */
873*5113495bSYour Name 	if (qdf_unlikely(!rx_hdr_valid)) {
874*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
875*5113495bSYour Name 		qdf_frag_free(addr);
876*5113495bSYour Name 		return num_buf_reaped;
877*5113495bSYour Name 	}
878*5113495bSYour Name 
879*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->rx_hdr_rcvd[user_id])) {
880*5113495bSYour Name 		/* WAR: RX_HDR is not received for this MPDU, drop this frame */
881*5113495bSYour Name 		mon_pdev->rx_mon_stats.rx_hdr_not_received++;
882*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
883*5113495bSYour Name 		qdf_frag_free(addr);
884*5113495bSYour Name 		return num_buf_reaped;
885*5113495bSYour Name 	}
886*5113495bSYour Name 
887*5113495bSYour Name 	if (packet_info->dma_length >
888*5113495bSYour Name 			(DP_MON_DATA_BUFFER_SIZE - DP_RX_MON_PACKET_OFFSET)) {
889*5113495bSYour Name 		/* WAR: Invalid DMA length is received for this MPDU */
890*5113495bSYour Name 		mon_pdev->rx_mon_stats.invalid_dma_length++;
891*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
892*5113495bSYour Name 		qdf_frag_free(addr);
893*5113495bSYour Name 		return num_buf_reaped;
894*5113495bSYour Name 	}
895*5113495bSYour Name 
896*5113495bSYour Name 	nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]);
897*5113495bSYour Name 	if (qdf_unlikely(!nbuf)) {
898*5113495bSYour Name 		dp_mon_debug("nbuf is NULL");
899*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
900*5113495bSYour Name 		DP_STATS_INC(mon_soc, empty_queue, 1);
901*5113495bSYour Name 		qdf_frag_free(addr);
902*5113495bSYour Name 		return num_buf_reaped;
903*5113495bSYour Name 	}
904*5113495bSYour Name 
905*5113495bSYour Name 	mpdu_info = &ppdu_info->mpdu_info[user_id];
906*5113495bSYour Name 	if (mpdu_info->decap_type == DP_MON_DECAP_FORMAT_INVALID) {
907*5113495bSYour Name 		/* decap type is invalid, drop the frame */
908*5113495bSYour Name 		mon_pdev->rx_mon_stats.mpdu_decap_type_invalid++;
909*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
910*5113495bSYour Name 		mon_pdev->rx_mon_stats.parent_buf_free++;
911*5113495bSYour Name 		qdf_frag_free(addr);
912*5113495bSYour Name 		qdf_nbuf_queue_remove_last(&ppdu_info->mpdu_q[user_id]);
913*5113495bSYour Name 		qdf_nbuf_free(nbuf);
914*5113495bSYour Name 		/* if invalid decap type handling is disabled, assert */
915*5113495bSYour Name 		if (soc->wlan_cfg_ctx->is_handle_invalid_decap_type_disabled) {
916*5113495bSYour Name 			dp_mon_err("Decap type invalid");
917*5113495bSYour Name 			qdf_assert_always(0);
918*5113495bSYour Name 		}
919*5113495bSYour Name 		ppdu_info->rx_hdr_rcvd[user_id] = false;
920*5113495bSYour Name 		return num_buf_reaped;
921*5113495bSYour Name 	}
922*5113495bSYour Name 
923*5113495bSYour Name 	tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf);
924*5113495bSYour Name 
925*5113495bSYour Name 	if (!tmp_nbuf) {
926*5113495bSYour Name 		tmp_nbuf = qdf_nbuf_alloc(pdev->soc->osdev,
927*5113495bSYour Name 					  DP_RX_MON_MAX_MONITOR_HEADER,
928*5113495bSYour Name 					  DP_RX_MON_MAX_MONITOR_HEADER,
929*5113495bSYour Name 					  4, FALSE);
930*5113495bSYour Name 		if (qdf_unlikely(!tmp_nbuf)) {
931*5113495bSYour Name 			dp_mon_err("nbuf is NULL");
932*5113495bSYour Name 			DP_STATS_INC(mon_soc, frag_free, 1);
933*5113495bSYour Name 			mon_pdev->rx_mon_stats.parent_buf_free++;
934*5113495bSYour Name 			qdf_frag_free(addr);
935*5113495bSYour Name 			/* remove this nbuf from queue */
936*5113495bSYour Name 			qdf_nbuf_queue_remove_last(&ppdu_info->mpdu_q[user_id]);
937*5113495bSYour Name 			qdf_nbuf_free(nbuf);
938*5113495bSYour Name 			return num_buf_reaped;
939*5113495bSYour Name 		}
940*5113495bSYour Name 		mon_pdev->rx_mon_stats.parent_buf_alloc++;
941*5113495bSYour Name 		dp_rx_mon_append_nbuf(nbuf, tmp_nbuf);
942*5113495bSYour Name 	}
943*5113495bSYour Name 	mpdu_info->full_pkt = true;
944*5113495bSYour Name 
945*5113495bSYour Name 	if (mpdu_info->decap_type == HAL_HW_RX_DECAP_FORMAT_RAW) {
946*5113495bSYour Name 		if (mpdu_info->first_rx_hdr_rcvd) {
947*5113495bSYour Name 			qdf_nbuf_remove_frag(nbuf, frag_idx, DP_MON_DATA_BUFFER_SIZE);
948*5113495bSYour Name 			dp_rx_mon_nbuf_add_rx_frag(nbuf, addr,
949*5113495bSYour Name 						   packet_info->dma_length,
950*5113495bSYour Name 						   DP_RX_MON_PACKET_OFFSET,
951*5113495bSYour Name 						   DP_MON_DATA_BUFFER_SIZE,
952*5113495bSYour Name 						   false);
953*5113495bSYour Name 			DP_STATS_INC(mon_soc, frag_free, 1);
954*5113495bSYour Name 			mpdu_info->first_rx_hdr_rcvd = false;
955*5113495bSYour Name 		} else {
956*5113495bSYour Name 			dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, addr,
957*5113495bSYour Name 						   packet_info->dma_length,
958*5113495bSYour Name 						   DP_RX_MON_PACKET_OFFSET,
959*5113495bSYour Name 						   DP_MON_DATA_BUFFER_SIZE,
960*5113495bSYour Name 						   false);
961*5113495bSYour Name 			DP_STATS_INC(mon_soc, frag_free, 1);
962*5113495bSYour Name 		}
963*5113495bSYour Name 	} else {
964*5113495bSYour Name 		dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, addr,
965*5113495bSYour Name 					   packet_info->dma_length,
966*5113495bSYour Name 					   DP_RX_MON_PACKET_OFFSET,
967*5113495bSYour Name 					   DP_MON_DATA_BUFFER_SIZE,
968*5113495bSYour Name 					   false);
969*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
970*5113495bSYour Name 		buf_info = addr;
971*5113495bSYour Name 
972*5113495bSYour Name 		if (!ppdu_info->msdu[user_id].first_buffer) {
973*5113495bSYour Name 			buf_info->first_buffer = true;
974*5113495bSYour Name 			ppdu_info->msdu[user_id].first_buffer = true;
975*5113495bSYour Name 		} else {
976*5113495bSYour Name 			buf_info->first_buffer = false;
977*5113495bSYour Name 		}
978*5113495bSYour Name 
979*5113495bSYour Name 		if (packet_info->msdu_continuation)
980*5113495bSYour Name 			buf_info->last_buffer = false;
981*5113495bSYour Name 		else
982*5113495bSYour Name 			buf_info->last_buffer = true;
983*5113495bSYour Name 
984*5113495bSYour Name 		buf_info->frag_len = packet_info->dma_length;
985*5113495bSYour Name 	}
986*5113495bSYour Name 	if (qdf_unlikely(packet_info->truncated))
987*5113495bSYour Name 		mpdu_info->truncated = true;
988*5113495bSYour Name 
989*5113495bSYour Name 	return num_buf_reaped;
990*5113495bSYour Name }
991*5113495bSYour Name 
992*5113495bSYour Name /**
993*5113495bSYour Name  * dp_rx_mon_handle_rx_hdr() - Process RX_HDR TLV
994*5113495bSYour Name  *
995*5113495bSYour Name  * @pdev: DP pdev
996*5113495bSYour Name  * @ppdu_info: PPDU info
997*5113495bSYour Name  * @status_frag: Status frag
998*5113495bSYour Name  *
999*5113495bSYour Name  * Return: void
1000*5113495bSYour Name  */
1001*5113495bSYour Name static inline void
dp_rx_mon_handle_rx_hdr(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,void * status_frag)1002*5113495bSYour Name dp_rx_mon_handle_rx_hdr(struct dp_pdev *pdev,
1003*5113495bSYour Name 			struct hal_rx_ppdu_info *ppdu_info,
1004*5113495bSYour Name 			void *status_frag)
1005*5113495bSYour Name {
1006*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1007*5113495bSYour Name 	qdf_nbuf_t nbuf, tmp_nbuf;
1008*5113495bSYour Name 	uint8_t user_id = ppdu_info->user_id;
1009*5113495bSYour Name 	QDF_STATUS status;
1010*5113495bSYour Name 
1011*5113495bSYour Name 	/* If this is first RX_HEADER for MPDU, allocate skb
1012*5113495bSYour Name 	 * else add frag to already allocated skb
1013*5113495bSYour Name 	 */
1014*5113495bSYour Name 
1015*5113495bSYour Name 	if (!ppdu_info->mpdu_info[user_id].mpdu_start_received) {
1016*5113495bSYour Name 		nbuf = qdf_nbuf_alloc(pdev->soc->osdev,
1017*5113495bSYour Name 				      DP_RX_MON_TLV_ROOM +
1018*5113495bSYour Name 				      DP_RX_MON_MAX_RADIO_TAP_HDR,
1019*5113495bSYour Name 				      DP_RX_MON_TLV_ROOM +
1020*5113495bSYour Name 				      DP_RX_MON_MAX_RADIO_TAP_HDR,
1021*5113495bSYour Name 				      4, FALSE);
1022*5113495bSYour Name 
1023*5113495bSYour Name 		/**
1024*5113495bSYour Name 		  * Set *head_msdu->next as NULL as all msdus are
1025*5113495bSYour Name 		  * mapped via nr frags
1026*5113495bSYour Name 		  **/
1027*5113495bSYour Name 		if (qdf_unlikely(!nbuf)) {
1028*5113495bSYour Name 			dp_mon_debug("malloc failed pdev: %pK ", pdev);
1029*5113495bSYour Name 			return;
1030*5113495bSYour Name 		}
1031*5113495bSYour Name 
1032*5113495bSYour Name 		mon_pdev->rx_mon_stats.parent_buf_alloc++;
1033*5113495bSYour Name 
1034*5113495bSYour Name 		dp_rx_mon_set_zero(nbuf);
1035*5113495bSYour Name 
1036*5113495bSYour Name 		qdf_nbuf_set_next(nbuf, NULL);
1037*5113495bSYour Name 
1038*5113495bSYour Name 		qdf_nbuf_queue_add(&ppdu_info->mpdu_q[user_id], nbuf);
1039*5113495bSYour Name 
1040*5113495bSYour Name 		status = dp_rx_mon_nbuf_add_rx_frag(nbuf, status_frag,
1041*5113495bSYour Name 						    ppdu_info->hdr_len - DP_RX_MON_RX_HDR_OFFSET,
1042*5113495bSYour Name 						    ppdu_info->data - (unsigned char *)status_frag + 4,
1043*5113495bSYour Name 						    DP_MON_DATA_BUFFER_SIZE, true);
1044*5113495bSYour Name 		if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) {
1045*5113495bSYour Name 			dp_mon_err("num_frags exceeding MAX frags");
1046*5113495bSYour Name 			return;
1047*5113495bSYour Name 		}
1048*5113495bSYour Name 		ppdu_info->mpdu_info[ppdu_info->user_id].mpdu_start_received = true;
1049*5113495bSYour Name 		ppdu_info->mpdu_info[user_id].first_rx_hdr_rcvd = true;
1050*5113495bSYour Name 		/* initialize decap type to invalid, this will be set to appropriate
1051*5113495bSYour Name 		 * value once the mpdu start tlv is received
1052*5113495bSYour Name 		 */
1053*5113495bSYour Name 		ppdu_info->mpdu_info[user_id].decap_type = DP_MON_DECAP_FORMAT_INVALID;
1054*5113495bSYour Name 	} else {
1055*5113495bSYour Name 		if (ppdu_info->mpdu_info[user_id].decap_type ==
1056*5113495bSYour Name 				HAL_HW_RX_DECAP_FORMAT_RAW) {
1057*5113495bSYour Name 			return;
1058*5113495bSYour Name 		}
1059*5113495bSYour Name 
1060*5113495bSYour Name 		if (dp_lite_mon_is_rx_enabled(mon_pdev) &&
1061*5113495bSYour Name 				!dp_lite_mon_is_level_msdu(mon_pdev))
1062*5113495bSYour Name 			return;
1063*5113495bSYour Name 
1064*5113495bSYour Name 		nbuf = qdf_nbuf_queue_last(&ppdu_info->mpdu_q[user_id]);
1065*5113495bSYour Name 		if (qdf_unlikely(!nbuf)) {
1066*5113495bSYour Name 			dp_mon_debug("nbuf is NULL");
1067*5113495bSYour Name 			return;
1068*5113495bSYour Name 		}
1069*5113495bSYour Name 
1070*5113495bSYour Name 		tmp_nbuf = qdf_get_nbuf_valid_frag(nbuf);
1071*5113495bSYour Name 
1072*5113495bSYour Name 		if (!tmp_nbuf) {
1073*5113495bSYour Name 			tmp_nbuf = qdf_nbuf_alloc(pdev->soc->osdev,
1074*5113495bSYour Name 						  DP_RX_MON_MAX_MONITOR_HEADER,
1075*5113495bSYour Name 						  DP_RX_MON_MAX_MONITOR_HEADER,
1076*5113495bSYour Name 						  4, FALSE);
1077*5113495bSYour Name 			if (qdf_unlikely(!tmp_nbuf)) {
1078*5113495bSYour Name 				dp_mon_err("nbuf is NULL");
1079*5113495bSYour Name 				qdf_assert_always(0);
1080*5113495bSYour Name 			}
1081*5113495bSYour Name 			mon_pdev->rx_mon_stats.parent_buf_alloc++;
1082*5113495bSYour Name 			dp_rx_mon_append_nbuf(nbuf, tmp_nbuf);
1083*5113495bSYour Name 		}
1084*5113495bSYour Name 		dp_rx_mon_nbuf_add_rx_frag(tmp_nbuf, status_frag,
1085*5113495bSYour Name 					   ppdu_info->hdr_len - DP_RX_MON_RX_HDR_OFFSET,
1086*5113495bSYour Name 					   ppdu_info->data - (unsigned char *)status_frag + 4,
1087*5113495bSYour Name 					   DP_MON_DATA_BUFFER_SIZE,
1088*5113495bSYour Name 					   true);
1089*5113495bSYour Name 	}
1090*5113495bSYour Name 	ppdu_info->rx_hdr_rcvd[user_id] = true;
1091*5113495bSYour Name }
1092*5113495bSYour Name 
1093*5113495bSYour Name /**
1094*5113495bSYour Name  * dp_rx_mon_free_mpdu_queue() - Free MPDU queue
1095*5113495bSYour Name  * @mon_pdev: monitor pdev
1096*5113495bSYour Name  * @ppdu_info: PPDU info
1097*5113495bSYour Name  *
1098*5113495bSYour Name  * Return: Void
1099*5113495bSYour Name  */
1100*5113495bSYour Name 
dp_rx_mon_free_mpdu_queue(struct dp_mon_pdev * mon_pdev,struct hal_rx_ppdu_info * ppdu_info)1101*5113495bSYour Name static void dp_rx_mon_free_mpdu_queue(struct dp_mon_pdev *mon_pdev,
1102*5113495bSYour Name 				      struct hal_rx_ppdu_info *ppdu_info)
1103*5113495bSYour Name {
1104*5113495bSYour Name 	uint8_t user;
1105*5113495bSYour Name 	qdf_nbuf_t mpdu;
1106*5113495bSYour Name 
1107*5113495bSYour Name 	for (user = 0; user < HAL_MAX_UL_MU_USERS; user++) {
1108*5113495bSYour Name 		if (!qdf_nbuf_is_queue_empty(&ppdu_info->mpdu_q[user])) {
1109*5113495bSYour Name 			while ((mpdu = qdf_nbuf_queue_remove(&ppdu_info->mpdu_q[user])) != NULL)
1110*5113495bSYour Name 				dp_mon_free_parent_nbuf(mon_pdev, mpdu);
1111*5113495bSYour Name 		}
1112*5113495bSYour Name 	}
1113*5113495bSYour Name }
1114*5113495bSYour Name 
1115*5113495bSYour Name #ifdef QCA_KMEM_CACHE_SUPPORT
1116*5113495bSYour Name /**
1117*5113495bSYour Name  * dp_rx_mon_get_ppdu_info() - Get PPDU info from freelist
1118*5113495bSYour Name  *
1119*5113495bSYour Name  * @mon_pdev: monitor pdev
1120*5113495bSYour Name  *
1121*5113495bSYour Name  * Return: ppdu_info
1122*5113495bSYour Name  */
1123*5113495bSYour Name struct hal_rx_ppdu_info*
dp_rx_mon_get_ppdu_info(struct dp_mon_pdev * mon_pdev)1124*5113495bSYour Name dp_rx_mon_get_ppdu_info(struct dp_mon_pdev *mon_pdev)
1125*5113495bSYour Name {
1126*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1127*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1128*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info, *temp_ppdu_info;
1129*5113495bSYour Name 
1130*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev_be->ppdu_info_lock);
1131*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info,
1132*5113495bSYour Name 			   &mon_pdev_be->rx_mon_free_queue,
1133*5113495bSYour Name 			   ppdu_free_list_elem,
1134*5113495bSYour Name 			   temp_ppdu_info) {
1135*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev_be->rx_mon_free_queue,
1136*5113495bSYour Name 			     ppdu_info, ppdu_free_list_elem);
1137*5113495bSYour Name 
1138*5113495bSYour Name 		if (ppdu_info) {
1139*5113495bSYour Name 			mon_pdev_be->total_free_elem--;
1140*5113495bSYour Name 			break;
1141*5113495bSYour Name 		}
1142*5113495bSYour Name 	}
1143*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev_be->ppdu_info_lock);
1144*5113495bSYour Name 
1145*5113495bSYour Name 	return ppdu_info;
1146*5113495bSYour Name }
1147*5113495bSYour Name 
1148*5113495bSYour Name void
__dp_rx_mon_free_ppdu_info(struct dp_mon_pdev * mon_pdev,struct hal_rx_ppdu_info * ppdu_info)1149*5113495bSYour Name __dp_rx_mon_free_ppdu_info(struct dp_mon_pdev *mon_pdev,
1150*5113495bSYour Name 			   struct hal_rx_ppdu_info *ppdu_info)
1151*5113495bSYour Name {
1152*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1153*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1154*5113495bSYour Name 
1155*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev_be->ppdu_info_lock);
1156*5113495bSYour Name 	if (ppdu_info) {
1157*5113495bSYour Name 		qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info));
1158*5113495bSYour Name 		TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_free_queue, ppdu_info,
1159*5113495bSYour Name 				  ppdu_free_list_elem);
1160*5113495bSYour Name 		mon_pdev_be->total_free_elem++;
1161*5113495bSYour Name 	}
1162*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev_be->ppdu_info_lock);
1163*5113495bSYour Name }
1164*5113495bSYour Name 
1165*5113495bSYour Name /**
1166*5113495bSYour Name  * dp_rx_mon_free_ppdu_info() - Free PPDU info
1167*5113495bSYour Name  * @pdev: DP pdev
1168*5113495bSYour Name  * @ppdu_info: PPDU info
1169*5113495bSYour Name  *
1170*5113495bSYour Name  * Return: Void
1171*5113495bSYour Name  */
1172*5113495bSYour Name void
dp_rx_mon_free_ppdu_info(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)1173*5113495bSYour Name dp_rx_mon_free_ppdu_info(struct dp_pdev *pdev,
1174*5113495bSYour Name 			 struct hal_rx_ppdu_info *ppdu_info)
1175*5113495bSYour Name {
1176*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1177*5113495bSYour Name 
1178*5113495bSYour Name 	mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev;
1179*5113495bSYour Name 	dp_rx_mon_free_mpdu_queue(mon_pdev, ppdu_info);
1180*5113495bSYour Name 	__dp_rx_mon_free_ppdu_info(mon_pdev, ppdu_info);
1181*5113495bSYour Name }
1182*5113495bSYour Name #endif
1183*5113495bSYour Name 
1184*5113495bSYour Name /**
1185*5113495bSYour Name  * dp_mon_free_parent_nbuf() - Free parent SKB
1186*5113495bSYour Name  *
1187*5113495bSYour Name  * @mon_pdev: monitor pdev
1188*5113495bSYour Name  * @nbuf: SKB to be freed
1189*5113495bSYour Name  *
1190*5113495bSYour Name  * Return: void
1191*5113495bSYour Name  */
dp_mon_free_parent_nbuf(struct dp_mon_pdev * mon_pdev,qdf_nbuf_t nbuf)1192*5113495bSYour Name void dp_mon_free_parent_nbuf(struct dp_mon_pdev *mon_pdev,
1193*5113495bSYour Name 			     qdf_nbuf_t nbuf)
1194*5113495bSYour Name {
1195*5113495bSYour Name 	mon_pdev->rx_mon_stats.parent_buf_free++;
1196*5113495bSYour Name 	qdf_nbuf_free(nbuf);
1197*5113495bSYour Name }
1198*5113495bSYour Name 
dp_rx_mon_drain_wq(struct dp_pdev * pdev)1199*5113495bSYour Name void dp_rx_mon_drain_wq(struct dp_pdev *pdev)
1200*5113495bSYour Name {
1201*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1202*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info = NULL;
1203*5113495bSYour Name 	struct hal_rx_ppdu_info *temp_ppdu_info = NULL;
1204*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
1205*5113495bSYour Name 
1206*5113495bSYour Name 	if (qdf_unlikely(!pdev)) {
1207*5113495bSYour Name 		dp_mon_debug("Pdev is NULL");
1208*5113495bSYour Name 		return;
1209*5113495bSYour Name 	}
1210*5113495bSYour Name 
1211*5113495bSYour Name 	mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev;
1212*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev)) {
1213*5113495bSYour Name 		dp_mon_debug("monitor pdev is NULL");
1214*5113495bSYour Name 		return;
1215*5113495bSYour Name 	}
1216*5113495bSYour Name 
1217*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1218*5113495bSYour Name 
1219*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev_be->rx_mon_wq_lock);
1220*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info,
1221*5113495bSYour Name 			   &mon_pdev_be->rx_mon_queue,
1222*5113495bSYour Name 			   ppdu_list_elem,
1223*5113495bSYour Name 			   temp_ppdu_info) {
1224*5113495bSYour Name 		mon_pdev_be->rx_mon_queue_depth--;
1225*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev_be->rx_mon_queue,
1226*5113495bSYour Name 			     ppdu_info, ppdu_list_elem);
1227*5113495bSYour Name 
1228*5113495bSYour Name 		dp_rx_mon_free_ppdu_info(pdev, ppdu_info);
1229*5113495bSYour Name 	}
1230*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev_be->rx_mon_wq_lock);
1231*5113495bSYour Name }
1232*5113495bSYour Name 
1233*5113495bSYour Name /**
1234*5113495bSYour Name  * dp_rx_mon_deliver_mpdu() - Deliver MPDU to osif layer
1235*5113495bSYour Name  *
1236*5113495bSYour Name  * @mon_pdev: monitor pdev
1237*5113495bSYour Name  * @mpdu: MPDU nbuf
1238*5113495bSYour Name  * @rx_status: monitor status
1239*5113495bSYour Name  *
1240*5113495bSYour Name  * Return: QDF_STATUS
1241*5113495bSYour Name  */
1242*5113495bSYour Name static QDF_STATUS
dp_rx_mon_deliver_mpdu(struct dp_mon_pdev * mon_pdev,qdf_nbuf_t mpdu,struct mon_rx_status * rx_status)1243*5113495bSYour Name dp_rx_mon_deliver_mpdu(struct dp_mon_pdev *mon_pdev,
1244*5113495bSYour Name 		       qdf_nbuf_t mpdu,
1245*5113495bSYour Name 		       struct mon_rx_status *rx_status)
1246*5113495bSYour Name {
1247*5113495bSYour Name 	qdf_nbuf_t nbuf;
1248*5113495bSYour Name 
1249*5113495bSYour Name 	if (mon_pdev->mvdev && mon_pdev->mvdev->monitor_vdev->osif_rx_mon) {
1250*5113495bSYour Name 		mon_pdev->rx_mon_stats.mpdus_buf_to_stack++;
1251*5113495bSYour Name 		nbuf = qdf_nbuf_get_ext_list(mpdu);
1252*5113495bSYour Name 
1253*5113495bSYour Name 		while (nbuf) {
1254*5113495bSYour Name 			mon_pdev->rx_mon_stats.mpdus_buf_to_stack++;
1255*5113495bSYour Name 			nbuf = nbuf->next;
1256*5113495bSYour Name 		}
1257*5113495bSYour Name 		mon_pdev->mvdev->monitor_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev,
1258*5113495bSYour Name 							   mpdu,
1259*5113495bSYour Name 							   rx_status);
1260*5113495bSYour Name 	} else {
1261*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1262*5113495bSYour Name 	}
1263*5113495bSYour Name 
1264*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1265*5113495bSYour Name }
1266*5113495bSYour Name 
1267*5113495bSYour Name /**
1268*5113495bSYour Name  * dp_rx_mon_process_ppdu_info() - Process PPDU info
1269*5113495bSYour Name  * @pdev: DP pdev
1270*5113495bSYour Name  * @ppdu_info: PPDU info
1271*5113495bSYour Name  *
1272*5113495bSYour Name  * Return: Void
1273*5113495bSYour Name  */
1274*5113495bSYour Name static void
dp_rx_mon_process_ppdu_info(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)1275*5113495bSYour Name dp_rx_mon_process_ppdu_info(struct dp_pdev *pdev,
1276*5113495bSYour Name 			    struct hal_rx_ppdu_info *ppdu_info)
1277*5113495bSYour Name {
1278*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev;
1279*5113495bSYour Name 	uint8_t user;
1280*5113495bSYour Name 	qdf_nbuf_t mpdu;
1281*5113495bSYour Name 
1282*5113495bSYour Name 	if (!ppdu_info)
1283*5113495bSYour Name 		return;
1284*5113495bSYour Name 
1285*5113495bSYour Name 	for (user = 0; user < ppdu_info->com_info.num_users; user++) {
1286*5113495bSYour Name 		uint16_t mpdu_count;
1287*5113495bSYour Name 		uint16_t mpdu_idx;
1288*5113495bSYour Name 		struct hal_rx_mon_mpdu_info *mpdu_meta;
1289*5113495bSYour Name 		QDF_STATUS status;
1290*5113495bSYour Name 
1291*5113495bSYour Name 		if (user >= HAL_MAX_UL_MU_USERS) {
1292*5113495bSYour Name 			dp_mon_err("num user exceeds max limit");
1293*5113495bSYour Name 			return;
1294*5113495bSYour Name 		}
1295*5113495bSYour Name 
1296*5113495bSYour Name 		mpdu_count  = ppdu_info->mpdu_count[user];
1297*5113495bSYour Name 		ppdu_info->rx_status.rx_user_status =
1298*5113495bSYour Name 					&ppdu_info->rx_user_status[user];
1299*5113495bSYour Name 		for (mpdu_idx = 0; mpdu_idx < mpdu_count; mpdu_idx++) {
1300*5113495bSYour Name 			mpdu = qdf_nbuf_queue_remove(&ppdu_info->mpdu_q[user]);
1301*5113495bSYour Name 
1302*5113495bSYour Name 			if (!mpdu)
1303*5113495bSYour Name 				continue;
1304*5113495bSYour Name 
1305*5113495bSYour Name 			mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(mpdu);
1306*5113495bSYour Name 
1307*5113495bSYour Name 			ppdu_info->rx_status.rs_fcs_err = mpdu_meta->fcs_err;
1308*5113495bSYour Name 			if (dp_lite_mon_is_rx_enabled(mon_pdev)) {
1309*5113495bSYour Name 				status = dp_lite_mon_rx_mpdu_process(pdev, ppdu_info,
1310*5113495bSYour Name 								     mpdu, mpdu_idx, user);
1311*5113495bSYour Name 				if (status != QDF_STATUS_SUCCESS) {
1312*5113495bSYour Name 					dp_mon_free_parent_nbuf(mon_pdev, mpdu);
1313*5113495bSYour Name 					continue;
1314*5113495bSYour Name 				}
1315*5113495bSYour Name 			} else {
1316*5113495bSYour Name 				if (mpdu_meta->full_pkt) {
1317*5113495bSYour Name 					if (qdf_unlikely(mpdu_meta->truncated)) {
1318*5113495bSYour Name 						dp_mon_free_parent_nbuf(mon_pdev, mpdu);
1319*5113495bSYour Name 						continue;
1320*5113495bSYour Name 					}
1321*5113495bSYour Name 
1322*5113495bSYour Name 					status = dp_rx_mon_handle_full_mon(pdev,
1323*5113495bSYour Name 									   ppdu_info, mpdu);
1324*5113495bSYour Name 					if (status != QDF_STATUS_SUCCESS) {
1325*5113495bSYour Name 						dp_mon_free_parent_nbuf(mon_pdev, mpdu);
1326*5113495bSYour Name 						continue;
1327*5113495bSYour Name 					}
1328*5113495bSYour Name 				} else {
1329*5113495bSYour Name 					dp_mon_free_parent_nbuf(mon_pdev, mpdu);
1330*5113495bSYour Name 					continue;
1331*5113495bSYour Name 				}
1332*5113495bSYour Name 
1333*5113495bSYour Name 				/* reset mpdu metadata and apply radiotap header over MPDU */
1334*5113495bSYour Name 				qdf_mem_zero(mpdu_meta, sizeof(struct hal_rx_mon_mpdu_info));
1335*5113495bSYour Name 				if (!qdf_nbuf_update_radiotap(&ppdu_info->rx_status,
1336*5113495bSYour Name 							      mpdu,
1337*5113495bSYour Name 							      qdf_nbuf_headroom(mpdu))) {
1338*5113495bSYour Name 					dp_mon_err("failed to update radiotap pdev: %pK",
1339*5113495bSYour Name 						   pdev);
1340*5113495bSYour Name 				}
1341*5113495bSYour Name 
1342*5113495bSYour Name 				dp_rx_mon_shift_pf_tag_in_headroom(mpdu,
1343*5113495bSYour Name 								   pdev->soc,
1344*5113495bSYour Name 								   ppdu_info);
1345*5113495bSYour Name 
1346*5113495bSYour Name 				dp_rx_mon_process_dest_pktlog(pdev->soc,
1347*5113495bSYour Name 							      pdev->pdev_id,
1348*5113495bSYour Name 							      mpdu);
1349*5113495bSYour Name 				/* Deliver MPDU to osif layer */
1350*5113495bSYour Name 				status = dp_rx_mon_deliver_mpdu(mon_pdev,
1351*5113495bSYour Name 								mpdu,
1352*5113495bSYour Name 								&ppdu_info->rx_status);
1353*5113495bSYour Name 				if (status != QDF_STATUS_SUCCESS)
1354*5113495bSYour Name 					dp_mon_free_parent_nbuf(mon_pdev, mpdu);
1355*5113495bSYour Name 			}
1356*5113495bSYour Name 			ppdu_info->rx_status.rs_fcs_err = false;
1357*5113495bSYour Name 		}
1358*5113495bSYour Name 	}
1359*5113495bSYour Name 
1360*5113495bSYour Name 	dp_rx_mon_free_mpdu_queue(mon_pdev, ppdu_info);
1361*5113495bSYour Name }
1362*5113495bSYour Name 
1363*5113495bSYour Name /**
1364*5113495bSYour Name  * dp_rx_mon_process_ppdu()-  Deferred monitor processing
1365*5113495bSYour Name  * This workqueue API handles:
1366*5113495bSYour Name  * a. Full monitor
1367*5113495bSYour Name  * b. Lite monitor
1368*5113495bSYour Name  *
1369*5113495bSYour Name  * @context: Opaque work context
1370*5113495bSYour Name  *
1371*5113495bSYour Name  * Return: none
1372*5113495bSYour Name  */
dp_rx_mon_process_ppdu(void * context)1373*5113495bSYour Name void dp_rx_mon_process_ppdu(void *context)
1374*5113495bSYour Name {
1375*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)context;
1376*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1377*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info = NULL;
1378*5113495bSYour Name 	struct hal_rx_ppdu_info *temp_ppdu_info = NULL;
1379*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
1380*5113495bSYour Name 
1381*5113495bSYour Name 	if (qdf_unlikely(!pdev)) {
1382*5113495bSYour Name 		dp_mon_debug("Pdev is NULL");
1383*5113495bSYour Name 		return;
1384*5113495bSYour Name 	}
1385*5113495bSYour Name 
1386*5113495bSYour Name 	mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev;
1387*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev)) {
1388*5113495bSYour Name 		dp_mon_debug("monitor pdev is NULL");
1389*5113495bSYour Name 		return;
1390*5113495bSYour Name 	}
1391*5113495bSYour Name 
1392*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1393*5113495bSYour Name 
1394*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev_be->rx_mon_wq_lock);
1395*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info,
1396*5113495bSYour Name 			   &mon_pdev_be->rx_mon_queue,
1397*5113495bSYour Name 			   ppdu_list_elem, temp_ppdu_info) {
1398*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev_be->rx_mon_queue,
1399*5113495bSYour Name 			     ppdu_info, ppdu_list_elem);
1400*5113495bSYour Name 
1401*5113495bSYour Name 		mon_pdev_be->rx_mon_queue_depth--;
1402*5113495bSYour Name 		dp_rx_mon_process_ppdu_info(pdev, ppdu_info);
1403*5113495bSYour Name 		__dp_rx_mon_free_ppdu_info(mon_pdev, ppdu_info);
1404*5113495bSYour Name 	}
1405*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev_be->rx_mon_wq_lock);
1406*5113495bSYour Name }
1407*5113495bSYour Name 
1408*5113495bSYour Name /**
1409*5113495bSYour Name  * dp_rx_mon_add_ppdu_info_to_wq() - Add PPDU info to workqueue
1410*5113495bSYour Name  *
1411*5113495bSYour Name  * @pdev: monitor pdev
1412*5113495bSYour Name  * @ppdu_info: ppdu info to be added to workqueue
1413*5113495bSYour Name  *
1414*5113495bSYour Name  * Return: SUCCESS or FAILIRE
1415*5113495bSYour Name  */
1416*5113495bSYour Name 
1417*5113495bSYour Name static QDF_STATUS
dp_rx_mon_add_ppdu_info_to_wq(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)1418*5113495bSYour Name dp_rx_mon_add_ppdu_info_to_wq(struct dp_pdev *pdev,
1419*5113495bSYour Name 			      struct hal_rx_ppdu_info *ppdu_info)
1420*5113495bSYour Name {
1421*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = (struct dp_mon_pdev *)pdev->monitor_pdev;
1422*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1423*5113495bSYour Name 		dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1424*5113495bSYour Name 
1425*5113495bSYour Name 	/* Full monitor or lite monitor mode is not enabled, return */
1426*5113495bSYour Name 	if (!mon_pdev->monitor_configured &&
1427*5113495bSYour Name 	    !dp_lite_mon_is_rx_enabled(mon_pdev))
1428*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1429*5113495bSYour Name 
1430*5113495bSYour Name 	if (qdf_likely(ppdu_info)) {
1431*5113495bSYour Name 		if (mon_pdev_be->rx_mon_queue_depth < DP_RX_MON_WQ_THRESHOLD) {
1432*5113495bSYour Name 			qdf_spin_lock_bh(&mon_pdev_be->rx_mon_wq_lock);
1433*5113495bSYour Name 			TAILQ_INSERT_TAIL(&mon_pdev_be->rx_mon_queue,
1434*5113495bSYour Name 					  ppdu_info, ppdu_list_elem);
1435*5113495bSYour Name 			mon_pdev_be->rx_mon_queue_depth++;
1436*5113495bSYour Name 			mon_pdev->rx_mon_stats.total_ppdu_info_enq++;
1437*5113495bSYour Name 		} else {
1438*5113495bSYour Name 			mon_pdev->rx_mon_stats.total_ppdu_info_drop++;
1439*5113495bSYour Name 			dp_rx_mon_free_ppdu_info(pdev, ppdu_info);
1440*5113495bSYour Name 		}
1441*5113495bSYour Name 		qdf_spin_unlock_bh(&mon_pdev_be->rx_mon_wq_lock);
1442*5113495bSYour Name 
1443*5113495bSYour Name 		if (mon_pdev_be->rx_mon_queue_depth > DP_MON_QUEUE_DEPTH_MAX) {
1444*5113495bSYour Name 			qdf_queue_work(0, mon_pdev_be->rx_mon_workqueue,
1445*5113495bSYour Name 				       &mon_pdev_be->rx_mon_work);
1446*5113495bSYour Name 		}
1447*5113495bSYour Name 	}
1448*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1449*5113495bSYour Name }
1450*5113495bSYour Name 
1451*5113495bSYour Name QDF_STATUS
dp_rx_mon_handle_full_mon(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,qdf_nbuf_t mpdu)1452*5113495bSYour Name dp_rx_mon_handle_full_mon(struct dp_pdev *pdev,
1453*5113495bSYour Name 			  struct hal_rx_ppdu_info *ppdu_info,
1454*5113495bSYour Name 			  qdf_nbuf_t mpdu)
1455*5113495bSYour Name {
1456*5113495bSYour Name 	uint32_t wifi_hdr_len, sec_hdr_len, msdu_llc_len,
1457*5113495bSYour Name 		 mpdu_buf_len, decap_hdr_pull_bytes, dir,
1458*5113495bSYour Name 		 is_amsdu, amsdu_pad, frag_size, tot_msdu_len;
1459*5113495bSYour Name 	struct hal_rx_mon_mpdu_info *mpdu_meta;
1460*5113495bSYour Name 	struct hal_rx_mon_msdu_info *msdu_meta;
1461*5113495bSYour Name 	char *hdr_desc;
1462*5113495bSYour Name 	uint8_t num_frags, frag_iter, l2_hdr_offset;
1463*5113495bSYour Name 	struct ieee80211_frame *wh;
1464*5113495bSYour Name 	struct ieee80211_qoscntl *qos;
1465*5113495bSYour Name 	uint32_t hdr_frag_size, frag_page_offset, pad_byte_pholder;
1466*5113495bSYour Name 	qdf_nbuf_t head_msdu, msdu_cur;
1467*5113495bSYour Name 	void *frag_addr;
1468*5113495bSYour Name 	bool prev_msdu_end_received = false;
1469*5113495bSYour Name 	bool is_nbuf_head = true;
1470*5113495bSYour Name 
1471*5113495bSYour Name 	/***************************************************************************
1472*5113495bSYour Name 	 *********************** Non-raw packet ************************************
1473*5113495bSYour Name 	 ---------------------------------------------------------------------------
1474*5113495bSYour Name 	 |      | frag-0   | frag-1    | frag - 2 | frag - 3  | frag - 4 | frag - 5  |
1475*5113495bSYour Name 	 | skb  | rx_hdr-1 | rx_msdu-1 | rx_hdr-2 | rx_msdu-2 | rx_hdr-3 | rx-msdu-3 |
1476*5113495bSYour Name 	 ---------------------------------------------------------------------------
1477*5113495bSYour Name 	 **************************************************************************/
1478*5113495bSYour Name 
1479*5113495bSYour Name 	if (!mpdu) {
1480*5113495bSYour Name 		dp_mon_debug("nbuf is NULL, return");
1481*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1482*5113495bSYour Name 	}
1483*5113495bSYour Name 
1484*5113495bSYour Name 	head_msdu = mpdu;
1485*5113495bSYour Name 
1486*5113495bSYour Name 	mpdu_meta = (struct hal_rx_mon_mpdu_info *)qdf_nbuf_data(mpdu);
1487*5113495bSYour Name 
1488*5113495bSYour Name 	if (mpdu_meta->decap_type == HAL_HW_RX_DECAP_FORMAT_RAW) {
1489*5113495bSYour Name 		if (qdf_unlikely(ppdu_info->rx_status.rs_fcs_err)) {
1490*5113495bSYour Name 			hdr_desc = qdf_nbuf_get_frag_addr(mpdu, 0);
1491*5113495bSYour Name 			wh = (struct ieee80211_frame *)hdr_desc;
1492*5113495bSYour Name 			if ((wh->i_fc[0] & QDF_IEEE80211_FC0_VERSION_MASK) !=
1493*5113495bSYour Name 			    QDF_IEEE80211_FC0_VERSION_0) {
1494*5113495bSYour Name 				DP_STATS_INC(pdev, dropped.mon_ver_err, 1);
1495*5113495bSYour Name 				return QDF_STATUS_E_FAILURE;
1496*5113495bSYour Name 			}
1497*5113495bSYour Name 		}
1498*5113495bSYour Name 		qdf_nbuf_trim_add_frag_size(mpdu,
1499*5113495bSYour Name 					    qdf_nbuf_get_nr_frags(mpdu) - 1,
1500*5113495bSYour Name 					    -HAL_RX_FCS_LEN, 0);
1501*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1502*5113495bSYour Name 	}
1503*5113495bSYour Name 
1504*5113495bSYour Name 	num_frags = qdf_nbuf_get_nr_frags(mpdu);
1505*5113495bSYour Name 	if (qdf_unlikely(num_frags < DP_MON_MIN_FRAGS_FOR_RESTITCH)) {
1506*5113495bSYour Name 		dp_mon_debug("not enough frags(%d) for restitch", num_frags);
1507*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1508*5113495bSYour Name 	}
1509*5113495bSYour Name 
1510*5113495bSYour Name 	l2_hdr_offset = DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
1511*5113495bSYour Name 
1512*5113495bSYour Name 	/* hdr_desc points to 80211 hdr */
1513*5113495bSYour Name 	hdr_desc = qdf_nbuf_get_frag_addr(mpdu, 0);
1514*5113495bSYour Name 
1515*5113495bSYour Name 	/* Calculate Base header size */
1516*5113495bSYour Name 	wifi_hdr_len = sizeof(struct ieee80211_frame);
1517*5113495bSYour Name 	wh = (struct ieee80211_frame *)hdr_desc;
1518*5113495bSYour Name 
1519*5113495bSYour Name 	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1520*5113495bSYour Name 
1521*5113495bSYour Name 	if (dir == IEEE80211_FC1_DIR_DSTODS)
1522*5113495bSYour Name 		wifi_hdr_len += 6;
1523*5113495bSYour Name 
1524*5113495bSYour Name 	is_amsdu = 0;
1525*5113495bSYour Name 	if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
1526*5113495bSYour Name 		qos = (struct ieee80211_qoscntl *)
1527*5113495bSYour Name 			(hdr_desc + wifi_hdr_len);
1528*5113495bSYour Name 		wifi_hdr_len += 2;
1529*5113495bSYour Name 
1530*5113495bSYour Name 		is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
1531*5113495bSYour Name 	}
1532*5113495bSYour Name 
1533*5113495bSYour Name 	/*Calculate security header length based on 'Protected'
1534*5113495bSYour Name 	 * and 'EXT_IV' flag
1535*5113495bSYour Name 	 */
1536*5113495bSYour Name 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1537*5113495bSYour Name 		char *iv = (char *)wh + wifi_hdr_len;
1538*5113495bSYour Name 
1539*5113495bSYour Name 		if (iv[3] & KEY_EXTIV)
1540*5113495bSYour Name 			sec_hdr_len = 8;
1541*5113495bSYour Name 		else
1542*5113495bSYour Name 			sec_hdr_len = 4;
1543*5113495bSYour Name 	} else {
1544*5113495bSYour Name 		sec_hdr_len = 0;
1545*5113495bSYour Name 	}
1546*5113495bSYour Name 	wifi_hdr_len += sec_hdr_len;
1547*5113495bSYour Name 
1548*5113495bSYour Name 	/* MSDU related stuff LLC - AMSDU subframe header etc */
1549*5113495bSYour Name 	msdu_llc_len = is_amsdu ? (DP_RX_MON_DECAP_HDR_SIZE +
1550*5113495bSYour Name 				   DP_RX_MON_LLC_SIZE +
1551*5113495bSYour Name 				   DP_RX_MON_SNAP_SIZE) :
1552*5113495bSYour Name 				   (DP_RX_MON_LLC_SIZE + DP_RX_MON_SNAP_SIZE);
1553*5113495bSYour Name 
1554*5113495bSYour Name 	mpdu_buf_len = wifi_hdr_len + msdu_llc_len;
1555*5113495bSYour Name 
1556*5113495bSYour Name 	/* "Decap" header to remove from MSDU buffer */
1557*5113495bSYour Name 	decap_hdr_pull_bytes = DP_RX_MON_DECAP_HDR_SIZE;
1558*5113495bSYour Name 
1559*5113495bSYour Name 	amsdu_pad = 0;
1560*5113495bSYour Name 	tot_msdu_len = 0;
1561*5113495bSYour Name 	tot_msdu_len = 0;
1562*5113495bSYour Name 
1563*5113495bSYour Name 	/*
1564*5113495bSYour Name 	 * Update protocol and flow tag for MSDU
1565*5113495bSYour Name 	 * update frag index in ctx_idx field.
1566*5113495bSYour Name 	 * Reset head pointer data of nbuf before updating.
1567*5113495bSYour Name 	 */
1568*5113495bSYour Name 	QDF_NBUF_CB_RX_CTX_ID(mpdu) = 0;
1569*5113495bSYour Name 
1570*5113495bSYour Name 	/* Construct destination address */
1571*5113495bSYour Name 	hdr_frag_size = qdf_nbuf_get_frag_size_by_idx(mpdu, 0);
1572*5113495bSYour Name 
1573*5113495bSYour Name 	/* Adjust page frag offset to point to 802.11 header */
1574*5113495bSYour Name 	if (hdr_frag_size > mpdu_buf_len)
1575*5113495bSYour Name 		qdf_nbuf_trim_add_frag_size(head_msdu, 0, -(hdr_frag_size - mpdu_buf_len), 0);
1576*5113495bSYour Name 
1577*5113495bSYour Name 	msdu_meta = (struct hal_rx_mon_msdu_info *)(((void *)qdf_nbuf_get_frag_addr(mpdu, 1)) - DP_RX_MON_PACKET_OFFSET);
1578*5113495bSYour Name 
1579*5113495bSYour Name 	frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 1);
1580*5113495bSYour Name 	pad_byte_pholder =
1581*5113495bSYour Name 		RX_MONITOR_BUFFER_SIZE - (frag_size + DP_RX_MON_PACKET_OFFSET);
1582*5113495bSYour Name 
1583*5113495bSYour Name 	/* Adjust page frag offset to appropriate after decap header */
1584*5113495bSYour Name 	frag_page_offset =
1585*5113495bSYour Name 		decap_hdr_pull_bytes + l2_hdr_offset;
1586*5113495bSYour Name 	qdf_nbuf_move_frag_page_offset(head_msdu, 1, frag_page_offset);
1587*5113495bSYour Name 	frag_size = frag_size - frag_page_offset;
1588*5113495bSYour Name 
1589*5113495bSYour Name 	if (msdu_meta->first_buffer && msdu_meta->last_buffer) {
1590*5113495bSYour Name 		/* MSDU with single buffer */
1591*5113495bSYour Name 		amsdu_pad = frag_size & 0x3;
1592*5113495bSYour Name 		amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
1593*5113495bSYour Name 		if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) {
1594*5113495bSYour Name 			char *frag_addr_temp;
1595*5113495bSYour Name 
1596*5113495bSYour Name 			qdf_nbuf_trim_add_frag_size(mpdu, 1, amsdu_pad, 0);
1597*5113495bSYour Name 			frag_addr_temp =
1598*5113495bSYour Name 				(char *)qdf_nbuf_get_frag_addr(mpdu, 1);
1599*5113495bSYour Name 			frag_addr_temp = (frag_addr_temp +
1600*5113495bSYour Name 					  qdf_nbuf_get_frag_size_by_idx(mpdu, 1)) -
1601*5113495bSYour Name 				amsdu_pad;
1602*5113495bSYour Name 			qdf_mem_zero(frag_addr_temp, amsdu_pad);
1603*5113495bSYour Name 			amsdu_pad = 0;
1604*5113495bSYour Name 		}
1605*5113495bSYour Name 	} else {
1606*5113495bSYour Name 		tot_msdu_len = frag_size;
1607*5113495bSYour Name 		amsdu_pad = 0;
1608*5113495bSYour Name 	}
1609*5113495bSYour Name 
1610*5113495bSYour Name 	pad_byte_pholder = 0;
1611*5113495bSYour Name 	for (msdu_cur = mpdu; msdu_cur;) {
1612*5113495bSYour Name 		/* frag_iter will start from 0 for second skb onwards */
1613*5113495bSYour Name 		if (msdu_cur == mpdu)
1614*5113495bSYour Name 			frag_iter = 2;
1615*5113495bSYour Name 		else
1616*5113495bSYour Name 			frag_iter = 0;
1617*5113495bSYour Name 
1618*5113495bSYour Name 		num_frags = qdf_nbuf_get_nr_frags(msdu_cur);
1619*5113495bSYour Name 
1620*5113495bSYour Name 		for (; frag_iter < num_frags; frag_iter++) {
1621*5113495bSYour Name 			/* Construct destination address
1622*5113495bSYour Name 			 *  ----------------------------------------------------------
1623*5113495bSYour Name 			 * |            | L2_HDR_PAD   |   Decap HDR | Payload | Pad  |
1624*5113495bSYour Name 			 * |            | (First buffer)             |         |      |
1625*5113495bSYour Name 			 * |            |                            /        /       |
1626*5113495bSYour Name 			 * |            >Frag address points here   /        /        |
1627*5113495bSYour Name 			 * |            \                          /        /         |
1628*5113495bSYour Name 			 * |             \ This bytes needs to    /        /          |
1629*5113495bSYour Name 			 * |              \  removed to frame pkt/        /           |
1630*5113495bSYour Name 			 * |               ----------------------        /            |
1631*5113495bSYour Name 			 * |                                     |     /     Add      |
1632*5113495bSYour Name 			 * |                                     |    /   amsdu pad   |
1633*5113495bSYour Name 			 * |   LLC HDR will be added here      <-|    |   Byte for    |
1634*5113495bSYour Name 			 * |        |                            |    |   last frame  |
1635*5113495bSYour Name 			 * |         >Dest addr will point       |    |    if space   |
1636*5113495bSYour Name 			 * |            somewhere in this area   |    |    available  |
1637*5113495bSYour Name 			 * |  And amsdu_pad will be created if   |    |               |
1638*5113495bSYour Name 			 * | dint get added in last buffer       |    |               |
1639*5113495bSYour Name 			 * |       (First Buffer)                |    |               |
1640*5113495bSYour Name 			 *  ----------------------------------------------------------
1641*5113495bSYour Name 			 */
1642*5113495bSYour Name 			/* If previous msdu end has received, modify next frag's offset to point to LLC */
1643*5113495bSYour Name 			if (prev_msdu_end_received) {
1644*5113495bSYour Name 				hdr_frag_size = qdf_nbuf_get_frag_size_by_idx(msdu_cur, frag_iter);
1645*5113495bSYour Name 				/* Adjust page frag offset to point to llc/snap header */
1646*5113495bSYour Name 				if (hdr_frag_size > msdu_llc_len)
1647*5113495bSYour Name 					qdf_nbuf_trim_add_frag_size(msdu_cur, frag_iter, -(hdr_frag_size - msdu_llc_len), 0);
1648*5113495bSYour Name 				prev_msdu_end_received = false;
1649*5113495bSYour Name 				continue;
1650*5113495bSYour Name 			}
1651*5113495bSYour Name 
1652*5113495bSYour Name 			frag_addr =
1653*5113495bSYour Name 				qdf_nbuf_get_frag_addr(msdu_cur, frag_iter) -
1654*5113495bSYour Name 						       DP_RX_MON_PACKET_OFFSET;
1655*5113495bSYour Name 			msdu_meta = (struct hal_rx_mon_msdu_info *)frag_addr;
1656*5113495bSYour Name 
1657*5113495bSYour Name 			/*
1658*5113495bSYour Name 			 * Update protocol and flow tag for MSDU
1659*5113495bSYour Name 			 * update frag index in ctx_idx field
1660*5113495bSYour Name 			 */
1661*5113495bSYour Name 			QDF_NBUF_CB_RX_CTX_ID(msdu_cur) = frag_iter;
1662*5113495bSYour Name 
1663*5113495bSYour Name 			frag_size = qdf_nbuf_get_frag_size_by_idx(msdu_cur,
1664*5113495bSYour Name 					frag_iter);
1665*5113495bSYour Name 
1666*5113495bSYour Name 			/* If Middle buffer, dont add any header */
1667*5113495bSYour Name 			if ((!msdu_meta->first_buffer) &&
1668*5113495bSYour Name 					(!msdu_meta->last_buffer)) {
1669*5113495bSYour Name 				tot_msdu_len += frag_size;
1670*5113495bSYour Name 				amsdu_pad = 0;
1671*5113495bSYour Name 				pad_byte_pholder = 0;
1672*5113495bSYour Name 				continue;
1673*5113495bSYour Name 			}
1674*5113495bSYour Name 
1675*5113495bSYour Name 			/* Calculate if current buffer has placeholder
1676*5113495bSYour Name 			 * to accommodate amsdu pad byte
1677*5113495bSYour Name 			 */
1678*5113495bSYour Name 			pad_byte_pholder =
1679*5113495bSYour Name 				RX_MONITOR_BUFFER_SIZE - (frag_size + DP_RX_MON_PACKET_OFFSET);
1680*5113495bSYour Name 			/*
1681*5113495bSYour Name 			 * We will come here only only three condition:
1682*5113495bSYour Name 			 * 1. Msdu with single Buffer
1683*5113495bSYour Name 			 * 2. First buffer in case MSDU is spread in multiple
1684*5113495bSYour Name 			 *    buffer
1685*5113495bSYour Name 			 * 3. Last buffer in case MSDU is spread in multiple
1686*5113495bSYour Name 			 *    buffer
1687*5113495bSYour Name 			 *
1688*5113495bSYour Name 			 *         First buffER | Last buffer
1689*5113495bSYour Name 			 * Case 1:      1       |     1
1690*5113495bSYour Name 			 * Case 2:      1       |     0
1691*5113495bSYour Name 			 * Case 3:      0       |     1
1692*5113495bSYour Name 			 *
1693*5113495bSYour Name 			 * In 3rd case only l2_hdr_padding byte will be Zero and
1694*5113495bSYour Name 			 * in other case, It will be 2 Bytes.
1695*5113495bSYour Name 			 */
1696*5113495bSYour Name 			if (msdu_meta->first_buffer)
1697*5113495bSYour Name 				l2_hdr_offset =
1698*5113495bSYour Name 					DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
1699*5113495bSYour Name 			else
1700*5113495bSYour Name 				l2_hdr_offset = DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
1701*5113495bSYour Name 
1702*5113495bSYour Name 			if (msdu_meta->first_buffer) {
1703*5113495bSYour Name 				/* Adjust page frag offset to point to 802.11 header */
1704*5113495bSYour Name 				hdr_frag_size = qdf_nbuf_get_frag_size_by_idx(msdu_cur, frag_iter-1);
1705*5113495bSYour Name 				if (hdr_frag_size > (msdu_llc_len + amsdu_pad))
1706*5113495bSYour Name 					qdf_nbuf_trim_add_frag_size(msdu_cur, frag_iter - 1, -(hdr_frag_size - (msdu_llc_len + amsdu_pad)), 0);
1707*5113495bSYour Name 
1708*5113495bSYour Name 				/* Adjust page frag offset to appropriate after decap header */
1709*5113495bSYour Name 				frag_page_offset =
1710*5113495bSYour Name 					(decap_hdr_pull_bytes + l2_hdr_offset);
1711*5113495bSYour Name 				if (frag_size > (decap_hdr_pull_bytes + l2_hdr_offset)) {
1712*5113495bSYour Name 					qdf_nbuf_move_frag_page_offset(msdu_cur, frag_iter, frag_page_offset);
1713*5113495bSYour Name 					frag_size = frag_size - (l2_hdr_offset + decap_hdr_pull_bytes);
1714*5113495bSYour Name 				}
1715*5113495bSYour Name 
1716*5113495bSYour Name 
1717*5113495bSYour Name 				/*
1718*5113495bSYour Name 				 * Calculate new page offset and create hole
1719*5113495bSYour Name 				 * if amsdu_pad required.
1720*5113495bSYour Name 				 */
1721*5113495bSYour Name 				tot_msdu_len = frag_size;
1722*5113495bSYour Name 				/*
1723*5113495bSYour Name 				 * No amsdu padding required for first frame of
1724*5113495bSYour Name 				 * continuation buffer
1725*5113495bSYour Name 				 */
1726*5113495bSYour Name 				if (!msdu_meta->last_buffer) {
1727*5113495bSYour Name 					amsdu_pad = 0;
1728*5113495bSYour Name 					continue;
1729*5113495bSYour Name 				}
1730*5113495bSYour Name 			} else {
1731*5113495bSYour Name 				tot_msdu_len += frag_size;
1732*5113495bSYour Name 			}
1733*5113495bSYour Name 
1734*5113495bSYour Name 			/* Will reach to this place in only two case:
1735*5113495bSYour Name 			 * 1. Single buffer MSDU
1736*5113495bSYour Name 			 * 2. Last buffer of MSDU in case of multiple buf MSDU
1737*5113495bSYour Name 			 */
1738*5113495bSYour Name 
1739*5113495bSYour Name 			/* This flag is used to identify msdu boundary */
1740*5113495bSYour Name 			prev_msdu_end_received = true;
1741*5113495bSYour Name 			/* Check size of buffer if amsdu padding required */
1742*5113495bSYour Name 			amsdu_pad = tot_msdu_len & 0x3;
1743*5113495bSYour Name 			amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
1744*5113495bSYour Name 
1745*5113495bSYour Name 			/* Create placeholder if current buffer can
1746*5113495bSYour Name 			 * accommodate padding.
1747*5113495bSYour Name 			 */
1748*5113495bSYour Name 			if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) {
1749*5113495bSYour Name 				char *frag_addr_temp;
1750*5113495bSYour Name 
1751*5113495bSYour Name 				qdf_nbuf_trim_add_frag_size(msdu_cur,
1752*5113495bSYour Name 						frag_iter,
1753*5113495bSYour Name 						amsdu_pad, 0);
1754*5113495bSYour Name 				frag_addr_temp = (char *)qdf_nbuf_get_frag_addr(msdu_cur,
1755*5113495bSYour Name 						frag_iter);
1756*5113495bSYour Name 				frag_addr_temp = (frag_addr_temp +
1757*5113495bSYour Name 						qdf_nbuf_get_frag_size_by_idx(msdu_cur, frag_iter)) -
1758*5113495bSYour Name 					amsdu_pad;
1759*5113495bSYour Name 				qdf_mem_zero(frag_addr_temp, amsdu_pad);
1760*5113495bSYour Name 				amsdu_pad = 0;
1761*5113495bSYour Name 			}
1762*5113495bSYour Name 
1763*5113495bSYour Name 			/* reset tot_msdu_len */
1764*5113495bSYour Name 			tot_msdu_len = 0;
1765*5113495bSYour Name 		}
1766*5113495bSYour Name 		if (is_nbuf_head) {
1767*5113495bSYour Name 			msdu_cur = qdf_nbuf_get_ext_list(msdu_cur);
1768*5113495bSYour Name 			is_nbuf_head = false;
1769*5113495bSYour Name 		} else {
1770*5113495bSYour Name 			msdu_cur = qdf_nbuf_queue_next(msdu_cur);
1771*5113495bSYour Name 		}
1772*5113495bSYour Name 	}
1773*5113495bSYour Name 
1774*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1775*5113495bSYour Name }
1776*5113495bSYour Name 
1777*5113495bSYour Name static inline int
dp_rx_mon_flush_packet_tlv(struct dp_pdev * pdev,void * buf,uint16_t end_offset,union dp_mon_desc_list_elem_t ** desc_list,union dp_mon_desc_list_elem_t ** tail)1778*5113495bSYour Name dp_rx_mon_flush_packet_tlv(struct dp_pdev *pdev, void *buf, uint16_t end_offset,
1779*5113495bSYour Name 			   union dp_mon_desc_list_elem_t **desc_list,
1780*5113495bSYour Name 			   union dp_mon_desc_list_elem_t **tail)
1781*5113495bSYour Name {
1782*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1783*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1784*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1785*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1786*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1787*5113495bSYour Name 	uint16_t work_done = 0;
1788*5113495bSYour Name 	qdf_frag_t addr;
1789*5113495bSYour Name 	uint8_t *rx_tlv;
1790*5113495bSYour Name 	uint8_t *rx_tlv_start;
1791*5113495bSYour Name 	uint16_t tlv_status = HAL_TLV_STATUS_BUF_DONE;
1792*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info;
1793*5113495bSYour Name 	uint32_t cookie_2;
1794*5113495bSYour Name 
1795*5113495bSYour Name 	if (!buf)
1796*5113495bSYour Name 		return work_done;
1797*5113495bSYour Name 
1798*5113495bSYour Name 	ppdu_info = &mon_pdev->ppdu_info;
1799*5113495bSYour Name 	if (!ppdu_info) {
1800*5113495bSYour Name 		dp_mon_debug("ppdu_info malloc failed pdev: %pK", pdev);
1801*5113495bSYour Name 		return work_done;
1802*5113495bSYour Name 	}
1803*5113495bSYour Name 	qdf_mem_zero(ppdu_info, sizeof(struct hal_rx_ppdu_info));
1804*5113495bSYour Name 	rx_tlv = buf;
1805*5113495bSYour Name 	rx_tlv_start = buf;
1806*5113495bSYour Name 
1807*5113495bSYour Name 	do {
1808*5113495bSYour Name 		tlv_status = hal_rx_status_get_tlv_info(rx_tlv,
1809*5113495bSYour Name 							ppdu_info,
1810*5113495bSYour Name 							pdev->soc->hal_soc,
1811*5113495bSYour Name 							buf);
1812*5113495bSYour Name 
1813*5113495bSYour Name 		if (tlv_status == HAL_TLV_STATUS_MON_BUF_ADDR) {
1814*5113495bSYour Name 			struct dp_mon_desc *mon_desc;
1815*5113495bSYour Name 			unsigned long long desc = ppdu_info->packet_info.sw_cookie;
1816*5113495bSYour Name 
1817*5113495bSYour Name 			cookie_2 = DP_MON_GET_COOKIE(desc);
1818*5113495bSYour Name 			mon_desc = DP_MON_GET_DESC(desc);
1819*5113495bSYour Name 
1820*5113495bSYour Name 			qdf_assert_always(mon_desc);
1821*5113495bSYour Name 
1822*5113495bSYour Name 			if (mon_desc->cookie_2 != cookie_2) {
1823*5113495bSYour Name 				mon_pdev->rx_mon_stats.dup_mon_sw_desc++;
1824*5113495bSYour Name 				qdf_err("duplicate cookie found mon_desc:%pK", mon_desc);
1825*5113495bSYour Name 				qdf_assert_always(0);
1826*5113495bSYour Name 			}
1827*5113495bSYour Name 
1828*5113495bSYour Name 			/* WAR: sometimes duplicate pkt desc are received
1829*5113495bSYour Name 			 * from HW, this check gracefully handles
1830*5113495bSYour Name 			 * such cases.
1831*5113495bSYour Name 			 */
1832*5113495bSYour Name 			if ((mon_desc == mon_pdev_be->prev_rxmon_pkt_desc) &&
1833*5113495bSYour Name 			    (mon_desc->cookie ==
1834*5113495bSYour Name 			     mon_pdev_be->prev_rxmon_pkt_cookie)) {
1835*5113495bSYour Name 				dp_mon_err("duplicate pkt desc found mon_pdev: %pK mon_desc: %pK cookie: %d",
1836*5113495bSYour Name 					   mon_pdev, mon_desc,
1837*5113495bSYour Name 					   mon_desc->cookie);
1838*5113495bSYour Name 				mon_pdev->rx_mon_stats.dup_mon_buf_cnt++;
1839*5113495bSYour Name 				goto end;
1840*5113495bSYour Name 			}
1841*5113495bSYour Name 			mon_pdev_be->prev_rxmon_pkt_desc = mon_desc;
1842*5113495bSYour Name 			mon_pdev_be->prev_rxmon_pkt_cookie = mon_desc->cookie;
1843*5113495bSYour Name 
1844*5113495bSYour Name 			addr = mon_desc->buf_addr;
1845*5113495bSYour Name 
1846*5113495bSYour Name 			if (!mon_desc->unmapped) {
1847*5113495bSYour Name 				qdf_mem_unmap_page(soc->osdev,
1848*5113495bSYour Name 						   (qdf_dma_addr_t)mon_desc->paddr,
1849*5113495bSYour Name 						   DP_MON_DATA_BUFFER_SIZE,
1850*5113495bSYour Name 						   QDF_DMA_FROM_DEVICE);
1851*5113495bSYour Name 				mon_desc->unmapped = 1;
1852*5113495bSYour Name 			}
1853*5113495bSYour Name 			dp_mon_add_to_free_desc_list(desc_list, tail, mon_desc);
1854*5113495bSYour Name 			work_done++;
1855*5113495bSYour Name 
1856*5113495bSYour Name 			if (addr) {
1857*5113495bSYour Name 				qdf_frag_free(addr);
1858*5113495bSYour Name 				DP_STATS_INC(mon_soc, frag_free, 1);
1859*5113495bSYour Name 			}
1860*5113495bSYour Name 		}
1861*5113495bSYour Name 
1862*5113495bSYour Name end:
1863*5113495bSYour Name 		rx_tlv = hal_rx_status_get_next_tlv(rx_tlv, 1);
1864*5113495bSYour Name 
1865*5113495bSYour Name 		if ((rx_tlv - rx_tlv_start) >= (end_offset + 1))
1866*5113495bSYour Name 			break;
1867*5113495bSYour Name 
1868*5113495bSYour Name 	} while ((tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE) ||
1869*5113495bSYour Name 		 (tlv_status == HAL_TLV_STATUS_HEADER) ||
1870*5113495bSYour Name 		 (tlv_status == HAL_TLV_STATUS_MPDU_END) ||
1871*5113495bSYour Name 		 (tlv_status == HAL_TLV_STATUS_MSDU_END) ||
1872*5113495bSYour Name 		 (tlv_status == HAL_TLV_STATUS_MON_BUF_ADDR) ||
1873*5113495bSYour Name 		 (tlv_status == HAL_TLV_STATUS_MPDU_START));
1874*5113495bSYour Name 
1875*5113495bSYour Name 	return work_done;
1876*5113495bSYour Name }
1877*5113495bSYour Name 
1878*5113495bSYour Name #endif
1879*5113495bSYour Name 
1880*5113495bSYour Name /**
1881*5113495bSYour Name  * dp_rx_mon_flush_status_buf_queue() - Flush status buffer queue
1882*5113495bSYour Name  *
1883*5113495bSYour Name  * @pdev: DP pdev handle
1884*5113495bSYour Name  *
1885*5113495bSYour Name  *Return: void
1886*5113495bSYour Name  */
1887*5113495bSYour Name static inline void
dp_rx_mon_flush_status_buf_queue(struct dp_pdev * pdev)1888*5113495bSYour Name dp_rx_mon_flush_status_buf_queue(struct dp_pdev *pdev)
1889*5113495bSYour Name {
1890*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1891*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1892*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1893*5113495bSYour Name 		dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1894*5113495bSYour Name 	union dp_mon_desc_list_elem_t *desc_list = NULL;
1895*5113495bSYour Name 	union dp_mon_desc_list_elem_t *tail = NULL;
1896*5113495bSYour Name 	struct dp_mon_desc *mon_desc;
1897*5113495bSYour Name 	uint16_t idx;
1898*5113495bSYour Name 	void *buf;
1899*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1900*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1901*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
1902*5113495bSYour Name 	uint16_t work_done = 0;
1903*5113495bSYour Name 	uint16_t status_buf_count;
1904*5113495bSYour Name 	uint16_t end_offset = 0;
1905*5113495bSYour Name 
1906*5113495bSYour Name 	if (!mon_pdev_be->desc_count) {
1907*5113495bSYour Name 		dp_mon_info("no of status buffer count is zero: %pK", pdev);
1908*5113495bSYour Name 		return;
1909*5113495bSYour Name 	}
1910*5113495bSYour Name 
1911*5113495bSYour Name 	status_buf_count = mon_pdev_be->desc_count;
1912*5113495bSYour Name 	for (idx = 0; idx < status_buf_count; idx++) {
1913*5113495bSYour Name 		mon_desc = mon_pdev_be->status[idx];
1914*5113495bSYour Name 		if (!mon_desc) {
1915*5113495bSYour Name 			qdf_assert_always(0);
1916*5113495bSYour Name 			return;
1917*5113495bSYour Name 		}
1918*5113495bSYour Name 
1919*5113495bSYour Name 		buf = mon_desc->buf_addr;
1920*5113495bSYour Name 		end_offset = mon_desc->end_offset;
1921*5113495bSYour Name 
1922*5113495bSYour Name 		dp_mon_add_to_free_desc_list(&desc_list, &tail, mon_desc);
1923*5113495bSYour Name 		work_done++;
1924*5113495bSYour Name 
1925*5113495bSYour Name 		work_done += dp_rx_mon_flush_packet_tlv(pdev, buf, end_offset,
1926*5113495bSYour Name 							&desc_list, &tail);
1927*5113495bSYour Name 
1928*5113495bSYour Name 		/* set status buffer pointer to NULL */
1929*5113495bSYour Name 		mon_pdev_be->status[idx] = NULL;
1930*5113495bSYour Name 		mon_pdev_be->desc_count--;
1931*5113495bSYour Name 
1932*5113495bSYour Name 		qdf_frag_free(buf);
1933*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
1934*5113495bSYour Name 	}
1935*5113495bSYour Name 
1936*5113495bSYour Name 	if (work_done) {
1937*5113495bSYour Name 		mon_pdev->rx_mon_stats.mon_rx_bufs_replenished_dest +=
1938*5113495bSYour Name 			work_done;
1939*5113495bSYour Name 		if (desc_list)
1940*5113495bSYour Name 			dp_mon_add_desc_list_to_free_list(soc,
1941*5113495bSYour Name 							  &desc_list, &tail,
1942*5113495bSYour Name 							  rx_mon_desc_pool);
1943*5113495bSYour Name 	}
1944*5113495bSYour Name }
1945*5113495bSYour Name 
1946*5113495bSYour Name /**
1947*5113495bSYour Name  * dp_rx_mon_handle_flush_n_trucated_ppdu() - Handle flush and truncated ppdu
1948*5113495bSYour Name  *
1949*5113495bSYour Name  * @soc: DP soc handle
1950*5113495bSYour Name  * @pdev: pdev handle
1951*5113495bSYour Name  * @mon_desc: mon sw desc
1952*5113495bSYour Name  */
1953*5113495bSYour Name static inline void
dp_rx_mon_handle_flush_n_trucated_ppdu(struct dp_soc * soc,struct dp_pdev * pdev,struct dp_mon_desc * mon_desc)1954*5113495bSYour Name dp_rx_mon_handle_flush_n_trucated_ppdu(struct dp_soc *soc,
1955*5113495bSYour Name 				       struct dp_pdev *pdev,
1956*5113495bSYour Name 				       struct dp_mon_desc *mon_desc)
1957*5113495bSYour Name {
1958*5113495bSYour Name 	union dp_mon_desc_list_elem_t *desc_list = NULL;
1959*5113495bSYour Name 	union dp_mon_desc_list_elem_t *tail = NULL;
1960*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1961*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
1962*5113495bSYour Name 			dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1963*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
1964*5113495bSYour Name 	uint16_t work_done;
1965*5113495bSYour Name 	void *buf;
1966*5113495bSYour Name 	uint16_t end_offset = 0;
1967*5113495bSYour Name 
1968*5113495bSYour Name 	/* Flush status buffers in queue */
1969*5113495bSYour Name 	dp_rx_mon_flush_status_buf_queue(pdev);
1970*5113495bSYour Name 	buf = mon_desc->buf_addr;
1971*5113495bSYour Name 	end_offset = mon_desc->end_offset;
1972*5113495bSYour Name 	dp_mon_add_to_free_desc_list(&desc_list, &tail, mon_desc);
1973*5113495bSYour Name 	work_done = 1;
1974*5113495bSYour Name 	work_done += dp_rx_mon_flush_packet_tlv(pdev, buf, end_offset,
1975*5113495bSYour Name 						&desc_list, &tail);
1976*5113495bSYour Name 	if (buf) {
1977*5113495bSYour Name 		qdf_frag_free(buf);
1978*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
1979*5113495bSYour Name 	}
1980*5113495bSYour Name 
1981*5113495bSYour Name 	if (desc_list)
1982*5113495bSYour Name 		dp_mon_add_desc_list_to_free_list(soc, &desc_list, &tail,
1983*5113495bSYour Name 						  rx_mon_desc_pool);
1984*5113495bSYour Name }
1985*5113495bSYour Name 
dp_rx_mon_append_nbuf(qdf_nbuf_t nbuf,qdf_nbuf_t tmp_nbuf)1986*5113495bSYour Name void dp_rx_mon_append_nbuf(qdf_nbuf_t nbuf, qdf_nbuf_t tmp_nbuf)
1987*5113495bSYour Name {
1988*5113495bSYour Name 	qdf_nbuf_t last_nbuf;
1989*5113495bSYour Name 
1990*5113495bSYour Name 	/*
1991*5113495bSYour Name 	 * If nbuf does not have fraglist, then append tmp_nbuf as fraglist,
1992*5113495bSYour Name 	 * else append tmp_nbuf as next of last_nbuf present in nbuf fraglist.
1993*5113495bSYour Name 	 */
1994*5113495bSYour Name 	if (!qdf_nbuf_has_fraglist(nbuf))
1995*5113495bSYour Name 		qdf_nbuf_append_ext_list(nbuf, tmp_nbuf,
1996*5113495bSYour Name 					 qdf_nbuf_len(tmp_nbuf));
1997*5113495bSYour Name 	else {
1998*5113495bSYour Name 		last_nbuf = qdf_nbuf_get_last_frag_list_nbuf(nbuf);
1999*5113495bSYour Name 
2000*5113495bSYour Name 		if (qdf_likely(last_nbuf))
2001*5113495bSYour Name 			qdf_nbuf_set_next(last_nbuf, tmp_nbuf);
2002*5113495bSYour Name 	}
2003*5113495bSYour Name }
2004*5113495bSYour Name 
2005*5113495bSYour Name static
dp_rx_mon_process_tlv_status(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,void * status_frag,uint16_t tlv_status,union dp_mon_desc_list_elem_t ** desc_list,union dp_mon_desc_list_elem_t ** tail)2006*5113495bSYour Name uint8_t dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
2007*5113495bSYour Name 				     struct hal_rx_ppdu_info *ppdu_info,
2008*5113495bSYour Name 				     void *status_frag,
2009*5113495bSYour Name 				     uint16_t tlv_status,
2010*5113495bSYour Name 				     union dp_mon_desc_list_elem_t **desc_list,
2011*5113495bSYour Name 				     union dp_mon_desc_list_elem_t **tail)
2012*5113495bSYour Name {
2013*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
2014*5113495bSYour Name 	uint8_t user_id = ppdu_info->user_id;
2015*5113495bSYour Name 	uint8_t num_buf_reaped = 0;
2016*5113495bSYour Name 	bool rx_hdr_valid = true;
2017*5113495bSYour Name 
2018*5113495bSYour Name 	if (!mon_pdev->monitor_configured &&
2019*5113495bSYour Name 	    !dp_lite_mon_is_rx_enabled(mon_pdev)) {
2020*5113495bSYour Name 		return num_buf_reaped;
2021*5113495bSYour Name 	}
2022*5113495bSYour Name 
2023*5113495bSYour Name 	/* If user id or rx header len is invalid drop this
2024*5113495bSYour Name 	 * mpdu. However we have to honor buffer address TLV
2025*5113495bSYour Name 	 * for this mpdu to free any associated packet buffer
2026*5113495bSYour Name 	 */
2027*5113495bSYour Name 	if (qdf_unlikely(user_id >= HAL_MAX_UL_MU_USERS ||
2028*5113495bSYour Name 			 ppdu_info->hdr_len > DP_RX_MON_MAX_RX_HEADER_LEN))
2029*5113495bSYour Name 		rx_hdr_valid = false;
2030*5113495bSYour Name 
2031*5113495bSYour Name 	switch (tlv_status) {
2032*5113495bSYour Name 	case HAL_TLV_STATUS_HEADER: {
2033*5113495bSYour Name 		if (qdf_unlikely(!rx_hdr_valid)) {
2034*5113495bSYour Name 			dp_mon_debug("rx hdr invalid userid: %d, len: %d ",
2035*5113495bSYour Name 				     user_id, ppdu_info->hdr_len);
2036*5113495bSYour Name 			mon_pdev->rx_mon_stats.rx_hdr_invalid_cnt++;
2037*5113495bSYour Name 			return num_buf_reaped;
2038*5113495bSYour Name 		}
2039*5113495bSYour Name 		dp_rx_mon_handle_rx_hdr(pdev, ppdu_info, status_frag);
2040*5113495bSYour Name 	}
2041*5113495bSYour Name 	break;
2042*5113495bSYour Name 	case HAL_TLV_STATUS_MON_BUF_ADDR:
2043*5113495bSYour Name 	{
2044*5113495bSYour Name 		num_buf_reaped = dp_rx_mon_handle_mon_buf_addr(pdev, ppdu_info, desc_list, tail);
2045*5113495bSYour Name 	}
2046*5113495bSYour Name 	break;
2047*5113495bSYour Name 	case HAL_TLV_STATUS_MSDU_END:
2048*5113495bSYour Name 	{
2049*5113495bSYour Name 		if (qdf_unlikely(!rx_hdr_valid))
2050*5113495bSYour Name 			break;
2051*5113495bSYour Name 
2052*5113495bSYour Name 		dp_rx_mon_handle_msdu_end(pdev, ppdu_info);
2053*5113495bSYour Name 	}
2054*5113495bSYour Name 	break;
2055*5113495bSYour Name 	case HAL_TLV_STATUS_MPDU_START:
2056*5113495bSYour Name 	{
2057*5113495bSYour Name 		if (qdf_unlikely(!rx_hdr_valid))
2058*5113495bSYour Name 			break;
2059*5113495bSYour Name 
2060*5113495bSYour Name 		dp_rx_mon_handle_mpdu_start(ppdu_info);
2061*5113495bSYour Name 	break;
2062*5113495bSYour Name 	}
2063*5113495bSYour Name 	case HAL_TLV_STATUS_MPDU_END:
2064*5113495bSYour Name 	{
2065*5113495bSYour Name 		if (qdf_unlikely(!rx_hdr_valid))
2066*5113495bSYour Name 			break;
2067*5113495bSYour Name 
2068*5113495bSYour Name 		dp_rx_mon_handle_mpdu_end(ppdu_info);
2069*5113495bSYour Name 	}
2070*5113495bSYour Name 	break;
2071*5113495bSYour Name 	case HAL_TLV_STATUS_MON_DROP:
2072*5113495bSYour Name 	{
2073*5113495bSYour Name 		mon_pdev->rx_mon_stats.ppdu_drop_cnt +=
2074*5113495bSYour Name 			ppdu_info->drop_cnt.ppdu_drop_cnt;
2075*5113495bSYour Name 		mon_pdev->rx_mon_stats.mpdu_drop_cnt +=
2076*5113495bSYour Name 			ppdu_info->drop_cnt.mpdu_drop_cnt;
2077*5113495bSYour Name 		mon_pdev->rx_mon_stats.end_of_ppdu_drop_cnt +=
2078*5113495bSYour Name 			ppdu_info->drop_cnt.end_of_ppdu_drop_cnt;
2079*5113495bSYour Name 		mon_pdev->rx_mon_stats.tlv_drop_cnt +=
2080*5113495bSYour Name 			ppdu_info->drop_cnt.tlv_drop_cnt;
2081*5113495bSYour Name 	}
2082*5113495bSYour Name 	break;
2083*5113495bSYour Name 	}
2084*5113495bSYour Name 	return num_buf_reaped;
2085*5113495bSYour Name }
2086*5113495bSYour Name 
2087*5113495bSYour Name /**
2088*5113495bSYour Name  * dp_rx_mon_process_status_tlv() - Handle mon status process TLV
2089*5113495bSYour Name  *
2090*5113495bSYour Name  * @pdev: DP pdev handle
2091*5113495bSYour Name  *
2092*5113495bSYour Name  * Return
2093*5113495bSYour Name  */
2094*5113495bSYour Name static inline struct hal_rx_ppdu_info *
dp_rx_mon_process_status_tlv(struct dp_pdev * pdev)2095*5113495bSYour Name dp_rx_mon_process_status_tlv(struct dp_pdev *pdev)
2096*5113495bSYour Name {
2097*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2098*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
2099*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
2100*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
2101*5113495bSYour Name 	union dp_mon_desc_list_elem_t *desc_list = NULL;
2102*5113495bSYour Name 	union dp_mon_desc_list_elem_t *tail = NULL;
2103*5113495bSYour Name 	struct dp_mon_desc *mon_desc;
2104*5113495bSYour Name 	uint16_t idx;
2105*5113495bSYour Name 	void *buf;
2106*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info;
2107*5113495bSYour Name 	uint8_t *rx_tlv;
2108*5113495bSYour Name 	uint8_t *rx_tlv_start;
2109*5113495bSYour Name 	uint16_t end_offset = 0;
2110*5113495bSYour Name 	uint16_t tlv_status = HAL_TLV_STATUS_BUF_DONE;
2111*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2112*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2113*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
2114*5113495bSYour Name 	uint16_t work_done = 0;
2115*5113495bSYour Name 	uint16_t status_buf_count;
2116*5113495bSYour Name 
2117*5113495bSYour Name 	if (!mon_pdev_be->desc_count) {
2118*5113495bSYour Name 		dp_mon_err("no of status buffer count is zero: %pK", pdev);
2119*5113495bSYour Name 		return NULL;
2120*5113495bSYour Name 	}
2121*5113495bSYour Name 
2122*5113495bSYour Name 	ppdu_info = dp_rx_mon_get_ppdu_info(mon_pdev);
2123*5113495bSYour Name 
2124*5113495bSYour Name 	if (!ppdu_info) {
2125*5113495bSYour Name 		dp_mon_debug("ppdu_info malloc failed pdev: %pK", pdev);
2126*5113495bSYour Name 		dp_rx_mon_flush_status_buf_queue(pdev);
2127*5113495bSYour Name 		return NULL;
2128*5113495bSYour Name 	}
2129*5113495bSYour Name 
2130*5113495bSYour Name 	mon_pdev->rx_mon_stats.total_ppdu_info_alloc++;
2131*5113495bSYour Name 
2132*5113495bSYour Name 	status_buf_count = mon_pdev_be->desc_count;
2133*5113495bSYour Name 	for (idx = 0; idx < status_buf_count; idx++) {
2134*5113495bSYour Name 		mon_desc = mon_pdev_be->status[idx];
2135*5113495bSYour Name 		if (!mon_desc) {
2136*5113495bSYour Name 			return NULL;
2137*5113495bSYour Name 		}
2138*5113495bSYour Name 
2139*5113495bSYour Name 		buf = mon_desc->buf_addr;
2140*5113495bSYour Name 		end_offset = mon_desc->end_offset;
2141*5113495bSYour Name 
2142*5113495bSYour Name 		dp_mon_add_to_free_desc_list(&desc_list, &tail, mon_desc);
2143*5113495bSYour Name 		work_done++;
2144*5113495bSYour Name 
2145*5113495bSYour Name 		rx_tlv = buf;
2146*5113495bSYour Name 		rx_tlv_start = buf;
2147*5113495bSYour Name 
2148*5113495bSYour Name 		dp_mon_record_clear_buffer(mon_pdev_be);
2149*5113495bSYour Name 
2150*5113495bSYour Name 		do {
2151*5113495bSYour Name 			tlv_status = hal_rx_status_get_tlv_info(rx_tlv,
2152*5113495bSYour Name 								ppdu_info,
2153*5113495bSYour Name 								pdev->soc->hal_soc,
2154*5113495bSYour Name 								buf);
2155*5113495bSYour Name 			dp_mon_record_tlv(mon_pdev_be, ppdu_info);
2156*5113495bSYour Name 			work_done += dp_rx_mon_process_tlv_status(pdev,
2157*5113495bSYour Name 								  ppdu_info,
2158*5113495bSYour Name 								  buf,
2159*5113495bSYour Name 								  tlv_status,
2160*5113495bSYour Name 								  &desc_list,
2161*5113495bSYour Name 								  &tail);
2162*5113495bSYour Name 			rx_tlv = hal_rx_status_get_next_tlv(rx_tlv, 1);
2163*5113495bSYour Name 
2164*5113495bSYour Name 			/* HW provides end_offset (how many bytes HW DMA'ed)
2165*5113495bSYour Name 			 * as part of descriptor, use this as delimiter for
2166*5113495bSYour Name 			 * status buffer
2167*5113495bSYour Name 			 */
2168*5113495bSYour Name 			if ((rx_tlv - rx_tlv_start) >= (end_offset + 1))
2169*5113495bSYour Name 				break;
2170*5113495bSYour Name 
2171*5113495bSYour Name 		} while ((tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE) ||
2172*5113495bSYour Name 			 (tlv_status == HAL_TLV_STATUS_HEADER) ||
2173*5113495bSYour Name 			 (tlv_status == HAL_TLV_STATUS_MPDU_END) ||
2174*5113495bSYour Name 			 (tlv_status == HAL_TLV_STATUS_MSDU_END) ||
2175*5113495bSYour Name 			 (tlv_status == HAL_TLV_STATUS_MON_BUF_ADDR) ||
2176*5113495bSYour Name 			 (tlv_status == HAL_TLV_STATUS_MPDU_START));
2177*5113495bSYour Name 
2178*5113495bSYour Name 		/* set status buffer pointer to NULL */
2179*5113495bSYour Name 		mon_pdev_be->status[idx] = NULL;
2180*5113495bSYour Name 		mon_pdev_be->desc_count--;
2181*5113495bSYour Name 
2182*5113495bSYour Name 		qdf_frag_free(buf);
2183*5113495bSYour Name 		DP_STATS_INC(mon_soc, frag_free, 1);
2184*5113495bSYour Name 		mon_pdev->rx_mon_stats.status_buf_count++;
2185*5113495bSYour Name 		dp_mon_record_index_update(mon_pdev_be);
2186*5113495bSYour Name 	}
2187*5113495bSYour Name 
2188*5113495bSYour Name 	dp_mon_rx_stats_update_rssi_dbm_params(mon_pdev, ppdu_info);
2189*5113495bSYour Name 	if (work_done) {
2190*5113495bSYour Name 		mon_pdev->rx_mon_stats.mon_rx_bufs_replenished_dest +=
2191*5113495bSYour Name 			work_done;
2192*5113495bSYour Name 		if (desc_list)
2193*5113495bSYour Name 			dp_mon_add_desc_list_to_free_list(soc,
2194*5113495bSYour Name 							  &desc_list, &tail,
2195*5113495bSYour Name 							  rx_mon_desc_pool);
2196*5113495bSYour Name 	}
2197*5113495bSYour Name 
2198*5113495bSYour Name 	ppdu_info->rx_status.tsft = ppdu_info->rx_status.tsft +
2199*5113495bSYour Name 				    pdev->timestamp.mlo_offset_lo_us +
2200*5113495bSYour Name 				    ((uint64_t)pdev->timestamp.mlo_offset_hi_us
2201*5113495bSYour Name 				    << 32);
2202*5113495bSYour Name 
2203*5113495bSYour Name 	return ppdu_info;
2204*5113495bSYour Name }
2205*5113495bSYour Name 
2206*5113495bSYour Name /**
2207*5113495bSYour Name  * dp_mon_pdev_flush_desc() - Flush status and packet desc during deinit
2208*5113495bSYour Name  *
2209*5113495bSYour Name  * @pdev: DP pdev handle
2210*5113495bSYour Name  *
2211*5113495bSYour Name  * Return
2212*5113495bSYour Name  */
dp_mon_pdev_flush_desc(struct dp_pdev * pdev)2213*5113495bSYour Name static QDF_STATUS dp_mon_pdev_flush_desc(struct dp_pdev *pdev)
2214*5113495bSYour Name {
2215*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
2216*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
2217*5113495bSYour Name 
2218*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev)) {
2219*5113495bSYour Name 		dp_mon_debug("monitor pdev is NULL");
2220*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2221*5113495bSYour Name 	}
2222*5113495bSYour Name 
2223*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
2224*5113495bSYour Name 
2225*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
2226*5113495bSYour Name 
2227*5113495bSYour Name 	if (mon_pdev_be->desc_count) {
2228*5113495bSYour Name 		mon_pdev->rx_mon_stats.pending_desc_count +=
2229*5113495bSYour Name 						mon_pdev_be->desc_count;
2230*5113495bSYour Name 		dp_rx_mon_flush_status_buf_queue(pdev);
2231*5113495bSYour Name 	}
2232*5113495bSYour Name 
2233*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
2234*5113495bSYour Name 
2235*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2236*5113495bSYour Name }
2237*5113495bSYour Name 
2238*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
2239*5113495bSYour Name #define DP_PEER_ID_MASK 0x3FFF
2240*5113495bSYour Name /**
2241*5113495bSYour Name  * dp_rx_mon_update_peer_id() - Update sw_peer_id with link peer_id
2242*5113495bSYour Name  *
2243*5113495bSYour Name  * @pdev: DP pdev handle
2244*5113495bSYour Name  * @ppdu_info: HAL PPDU Info buffer
2245*5113495bSYour Name  *
2246*5113495bSYour Name  * Return: none
2247*5113495bSYour Name  */
2248*5113495bSYour Name static inline
dp_rx_mon_update_peer_id(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)2249*5113495bSYour Name void dp_rx_mon_update_peer_id(struct dp_pdev *pdev,
2250*5113495bSYour Name 			      struct hal_rx_ppdu_info *ppdu_info)
2251*5113495bSYour Name {
2252*5113495bSYour Name 	uint32_t i;
2253*5113495bSYour Name 	uint16_t peer_id;
2254*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2255*5113495bSYour Name 	uint32_t num_users = ppdu_info->com_info.num_users;
2256*5113495bSYour Name 
2257*5113495bSYour Name 	for (i = 0; i < num_users; i++) {
2258*5113495bSYour Name 		peer_id = ppdu_info->rx_user_status[i].sw_peer_id;
2259*5113495bSYour Name 		if (peer_id == HTT_INVALID_PEER)
2260*5113495bSYour Name 			continue;
2261*5113495bSYour Name 		/*
2262*5113495bSYour Name 		+---------------------------------------------------------------------+
2263*5113495bSYour Name 		| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
2264*5113495bSYour Name 		+---------------------------------------------------------------------+
2265*5113495bSYour Name 		| CHIP ID | ML |                     PEER ID                          |
2266*5113495bSYour Name 		+---------------------------------------------------------------------+
2267*5113495bSYour Name 		*/
2268*5113495bSYour Name 		peer_id &= DP_PEER_ID_MASK;
2269*5113495bSYour Name 		peer_id = dp_get_link_peer_id_by_lmac_id(soc, peer_id,
2270*5113495bSYour Name 							 pdev->lmac_id);
2271*5113495bSYour Name 		ppdu_info->rx_user_status[i].sw_peer_id = peer_id;
2272*5113495bSYour Name 	}
2273*5113495bSYour Name }
2274*5113495bSYour Name #else
2275*5113495bSYour Name static inline
dp_rx_mon_update_peer_id(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)2276*5113495bSYour Name void dp_rx_mon_update_peer_id(struct dp_pdev *pdev,
2277*5113495bSYour Name 			      struct hal_rx_ppdu_info *ppdu_info)
2278*5113495bSYour Name {
2279*5113495bSYour Name }
2280*5113495bSYour Name #endif
2281*5113495bSYour Name 
2282*5113495bSYour Name /*
2283*5113495bSYour Name  * HAL_RX_PKT_TYPE_11A     0 -> CDP_PKT_TYPE_OFDM
2284*5113495bSYour Name  * HAL_RX_PKT_TYPE_11B     1 -> CDP_PKT_TYPE_CCK
2285*5113495bSYour Name  * HAL_RX_PKT_TYPE_11N     2 -> CDP_PKT_TYPE_HT
2286*5113495bSYour Name  * HAL_RX_PKT_TYPE_11AC    3 -> CDP_PKT_TYPE_VHT
2287*5113495bSYour Name  * HAL_RX_PKT_TYPE_11AX    4 -> CDP_PKT_TYPE_HE
2288*5113495bSYour Name  * HAL_RX_PKT_TYPE_11BE    6 -> CDP_PKT_TYPE_EHT
2289*5113495bSYour Name  */
2290*5113495bSYour Name 
2291*5113495bSYour Name static uint32_t const cdp_preamble_type_map[] = {
2292*5113495bSYour Name 	CDP_PKT_TYPE_OFDM,
2293*5113495bSYour Name 	CDP_PKT_TYPE_CCK,
2294*5113495bSYour Name 	CDP_PKT_TYPE_HT,
2295*5113495bSYour Name 	CDP_PKT_TYPE_VHT,
2296*5113495bSYour Name 	CDP_PKT_TYPE_HE,
2297*5113495bSYour Name 	CDP_PKT_TYPE_NO_SUP,
2298*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
2299*5113495bSYour Name 	CDP_PKT_TYPE_EHT,
2300*5113495bSYour Name #endif
2301*5113495bSYour Name 	CDP_PKT_TYPE_MAX,
2302*5113495bSYour Name };
2303*5113495bSYour Name 
2304*5113495bSYour Name /*
2305*5113495bSYour Name  * HAL_RX_RECEPTION_TYPE_SU       -> CDP_RX_TYPE_SU
2306*5113495bSYour Name  * HAL_RX_RECEPTION_TYPE_MU_MIMO  -> CDP_RX_TYPE_MU_MIMO
2307*5113495bSYour Name  * HAL_RX_RECEPTION_TYPE_OFDMA    -> CDP_RX_TYPE_MU_OFDMA
2308*5113495bSYour Name  * HAL_RX_RECEPTION_TYPE_MU_OFDMA -> CDP_RX_TYPE_MU_OFDMA_MIMO
2309*5113495bSYour Name  */
2310*5113495bSYour Name static uint32_t const cdp_reception_type_map[] = {
2311*5113495bSYour Name 	CDP_RX_TYPE_SU,
2312*5113495bSYour Name 	CDP_RX_TYPE_MU_MIMO,
2313*5113495bSYour Name 	CDP_RX_TYPE_MU_OFDMA,
2314*5113495bSYour Name 	CDP_RX_TYPE_MU_OFDMA_MIMO,
2315*5113495bSYour Name };
2316*5113495bSYour Name 
2317*5113495bSYour Name static uint32_t const cdp_mu_dl_up_map[] = {
2318*5113495bSYour Name 	CDP_MU_TYPE_DL,
2319*5113495bSYour Name 	CDP_MU_TYPE_UL,
2320*5113495bSYour Name };
2321*5113495bSYour Name 
2322*5113495bSYour Name static inline void
dp_rx_mu_stats_update(struct hal_rx_ppdu_info * ppdu_info,struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t preamble_type,uint32_t recept_type,uint32_t mu_dl_ul,uint32_t i)2323*5113495bSYour Name dp_rx_mu_stats_update(
2324*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info,
2325*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_sts,
2326*5113495bSYour Name 	uint32_t preamble_type,
2327*5113495bSYour Name 	uint32_t  recept_type,
2328*5113495bSYour Name 	uint32_t  mu_dl_ul,
2329*5113495bSYour Name 	uint32_t i
2330*5113495bSYour Name )
2331*5113495bSYour Name {
2332*5113495bSYour Name 	struct mon_rx_user_status *rx_user_status;
2333*5113495bSYour Name 
2334*5113495bSYour Name 	rx_user_status =  &ppdu_info->rx_user_status[i];
2335*5113495bSYour Name 	rx_mon_sts->mpdu_cnt_fcs_ok[preamble_type][recept_type][mu_dl_ul][i]
2336*5113495bSYour Name 			+= rx_user_status->mpdu_cnt_fcs_ok;
2337*5113495bSYour Name 	rx_mon_sts->mpdu_cnt_fcs_err[preamble_type][recept_type][mu_dl_ul][i]
2338*5113495bSYour Name 			+= rx_user_status->mpdu_cnt_fcs_err;
2339*5113495bSYour Name }
2340*5113495bSYour Name 
2341*5113495bSYour Name static inline void
dp_rx_he_ppdu_stats_update(struct cdp_pdev_mon_stats * stats,struct hal_rx_u_sig_info * u_sig)2342*5113495bSYour Name dp_rx_he_ppdu_stats_update(
2343*5113495bSYour Name 	struct cdp_pdev_mon_stats *stats,
2344*5113495bSYour Name 	struct hal_rx_u_sig_info *u_sig
2345*5113495bSYour Name )
2346*5113495bSYour Name {
2347*5113495bSYour Name 	stats->ppdu_eht_type_mode[u_sig->ppdu_type_comp_mode][u_sig->ul_dl]++;
2348*5113495bSYour Name }
2349*5113495bSYour Name 
2350*5113495bSYour Name static inline void
dp_rx_he_ppdu_stats(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)2351*5113495bSYour Name dp_rx_he_ppdu_stats(struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info)
2352*5113495bSYour Name {
2353*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
2354*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats;
2355*5113495bSYour Name 
2356*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
2357*5113495bSYour Name 	rx_mon_stats = &mon_pdev->rx_mon_stats;
2358*5113495bSYour Name 
2359*5113495bSYour Name 	if (ppdu_info->u_sig_info.ppdu_type_comp_mode < CDP_EHT_TYPE_MODE_MAX &&
2360*5113495bSYour Name 	    ppdu_info->u_sig_info.ul_dl < CDP_MU_TYPE_MAX)
2361*5113495bSYour Name 		dp_rx_he_ppdu_stats_update(
2362*5113495bSYour Name 			rx_mon_stats,
2363*5113495bSYour Name 			&ppdu_info->u_sig_info);
2364*5113495bSYour Name 		else
2365*5113495bSYour Name 			qdf_assert(0);
2366*5113495bSYour Name }
2367*5113495bSYour Name 
2368*5113495bSYour Name static inline void
dp_rx_mu_stats(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)2369*5113495bSYour Name dp_rx_mu_stats(struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info)
2370*5113495bSYour Name {
2371*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
2372*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats;
2373*5113495bSYour Name 	struct mon_rx_status *rx_status;
2374*5113495bSYour Name 	uint32_t preamble_type, reception_type, mu_dl_ul, num_users, i;
2375*5113495bSYour Name 
2376*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
2377*5113495bSYour Name 	rx_mon_stats = &mon_pdev->rx_mon_stats;
2378*5113495bSYour Name 	rx_status = &ppdu_info->rx_status;
2379*5113495bSYour Name 
2380*5113495bSYour Name 	num_users = ppdu_info->com_info.num_users;
2381*5113495bSYour Name 
2382*5113495bSYour Name 	if (rx_status->preamble_type < CDP_PKT_TYPE_MAX)
2383*5113495bSYour Name 		preamble_type = cdp_preamble_type_map[rx_status->preamble_type];
2384*5113495bSYour Name 	else
2385*5113495bSYour Name 		preamble_type = CDP_PKT_TYPE_NO_SUP;
2386*5113495bSYour Name 
2387*5113495bSYour Name 	reception_type = cdp_reception_type_map[rx_status->reception_type];
2388*5113495bSYour Name 	mu_dl_ul = cdp_mu_dl_up_map[rx_status->mu_dl_ul];
2389*5113495bSYour Name 
2390*5113495bSYour Name 	for (i = 0; i < num_users; i++) {
2391*5113495bSYour Name 		if (i >= CDP_MU_SNIF_USER_MAX)
2392*5113495bSYour Name 			return;
2393*5113495bSYour Name 
2394*5113495bSYour Name 		dp_rx_mu_stats_update(ppdu_info, rx_mon_stats, preamble_type,
2395*5113495bSYour Name 				      reception_type, mu_dl_ul, i);
2396*5113495bSYour Name 	}
2397*5113495bSYour Name 
2398*5113495bSYour Name 	if (rx_status->eht_flags)
2399*5113495bSYour Name 		dp_rx_he_ppdu_stats(pdev, ppdu_info);
2400*5113495bSYour Name }
2401*5113495bSYour Name 
2402*5113495bSYour Name static inline uint32_t
dp_rx_mon_srng_process_2_0(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)2403*5113495bSYour Name dp_rx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
2404*5113495bSYour Name 			   uint32_t mac_id, uint32_t quota)
2405*5113495bSYour Name {
2406*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
2407*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
2408*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
2409*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2410*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2411*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
2412*5113495bSYour Name 	hal_soc_handle_t hal_soc = soc->hal_soc;
2413*5113495bSYour Name 	void *rx_mon_dst_ring_desc;
2414*5113495bSYour Name 	void *mon_dst_srng;
2415*5113495bSYour Name 	uint32_t work_done = 0;
2416*5113495bSYour Name 	struct hal_rx_ppdu_info *ppdu_info = NULL;
2417*5113495bSYour Name 	QDF_STATUS status;
2418*5113495bSYour Name 	uint32_t cookie_2;
2419*5113495bSYour Name 	if (!pdev || !hal_soc) {
2420*5113495bSYour Name 		dp_mon_err("%pK: pdev or hal_soc is null, mac_id = %d",
2421*5113495bSYour Name 			   soc, mac_id);
2422*5113495bSYour Name 		return work_done;
2423*5113495bSYour Name 	}
2424*5113495bSYour Name 
2425*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
2426*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
2427*5113495bSYour Name 	mon_dst_srng = soc->rxdma_mon_dst_ring[mac_id].hal_srng;
2428*5113495bSYour Name 
2429*5113495bSYour Name 	if (!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)) {
2430*5113495bSYour Name 		dp_mon_err("%pK: : HAL Monitor Destination Ring Init Failed -- %pK",
2431*5113495bSYour Name 			   soc, mon_dst_srng);
2432*5113495bSYour Name 		return work_done;
2433*5113495bSYour Name 	}
2434*5113495bSYour Name 
2435*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
2436*5113495bSYour Name 
2437*5113495bSYour Name 	if (qdf_unlikely(dp_rx_srng_access_start(int_ctx, soc, mon_dst_srng))) {
2438*5113495bSYour Name 		dp_mon_err("%s %d : HAL Mon Dest Ring access Failed -- %pK",
2439*5113495bSYour Name 			   __func__, __LINE__, mon_dst_srng);
2440*5113495bSYour Name 		qdf_spin_unlock_bh(&mon_pdev->mon_lock);
2441*5113495bSYour Name 		return work_done;
2442*5113495bSYour Name 	}
2443*5113495bSYour Name 
2444*5113495bSYour Name 	while (qdf_likely((rx_mon_dst_ring_desc =
2445*5113495bSYour Name 			  (void *)hal_srng_dst_peek(hal_soc, mon_dst_srng))
2446*5113495bSYour Name 				&& quota--)) {
2447*5113495bSYour Name 		struct hal_mon_desc hal_mon_rx_desc = {0};
2448*5113495bSYour Name 		struct dp_mon_desc *mon_desc;
2449*5113495bSYour Name 		unsigned long long desc;
2450*5113495bSYour Name 		hal_be_get_mon_dest_status(soc->hal_soc,
2451*5113495bSYour Name 					   rx_mon_dst_ring_desc,
2452*5113495bSYour Name 					   &hal_mon_rx_desc);
2453*5113495bSYour Name 		/* If it's empty descriptor, skip processing
2454*5113495bSYour Name 		 * and process next hW desc
2455*5113495bSYour Name 		 */
2456*5113495bSYour Name 		if (hal_mon_rx_desc.empty_descriptor == 1) {
2457*5113495bSYour Name 			dp_mon_debug("empty descriptor found mon_pdev: %pK",
2458*5113495bSYour Name 				     mon_pdev);
2459*5113495bSYour Name 			rx_mon_dst_ring_desc =
2460*5113495bSYour Name 				hal_srng_dst_get_next(hal_soc, mon_dst_srng);
2461*5113495bSYour Name 			dp_rx_mon_update_drop_cnt(mon_pdev, &hal_mon_rx_desc);
2462*5113495bSYour Name 			continue;
2463*5113495bSYour Name 		}
2464*5113495bSYour Name 		desc = hal_mon_rx_desc.buf_addr;
2465*5113495bSYour Name 		cookie_2 = DP_MON_GET_COOKIE(desc);
2466*5113495bSYour Name 		mon_desc = DP_MON_GET_DESC(desc);
2467*5113495bSYour Name 
2468*5113495bSYour Name 		qdf_assert_always(mon_desc);
2469*5113495bSYour Name 
2470*5113495bSYour Name 		if (mon_desc->cookie_2 != cookie_2) {
2471*5113495bSYour Name 			mon_pdev->rx_mon_stats.dup_mon_sw_desc++;
2472*5113495bSYour Name 			qdf_err("duplicate cookie found mon_desc:%pK", mon_desc);
2473*5113495bSYour Name 			qdf_assert_always(0);
2474*5113495bSYour Name 		}
2475*5113495bSYour Name 
2476*5113495bSYour Name 		if ((mon_desc == mon_pdev_be->prev_rxmon_desc) &&
2477*5113495bSYour Name 		    (mon_desc->cookie == mon_pdev_be->prev_rxmon_cookie)) {
2478*5113495bSYour Name 			dp_mon_err("duplicate descritout found mon_pdev: %pK mon_desc: %pK cookie: %d",
2479*5113495bSYour Name 				   mon_pdev, mon_desc, mon_desc->cookie);
2480*5113495bSYour Name 			mon_pdev->rx_mon_stats.dup_mon_buf_cnt++;
2481*5113495bSYour Name 			hal_srng_dst_get_next(hal_soc, mon_dst_srng);
2482*5113495bSYour Name 			continue;
2483*5113495bSYour Name 		}
2484*5113495bSYour Name 		mon_pdev_be->prev_rxmon_desc = mon_desc;
2485*5113495bSYour Name 		mon_pdev_be->prev_rxmon_cookie = mon_desc->cookie;
2486*5113495bSYour Name 
2487*5113495bSYour Name 		if (!mon_desc->unmapped) {
2488*5113495bSYour Name 			qdf_mem_unmap_page(soc->osdev, mon_desc->paddr,
2489*5113495bSYour Name 					   rx_mon_desc_pool->buf_size,
2490*5113495bSYour Name 					   QDF_DMA_FROM_DEVICE);
2491*5113495bSYour Name 			mon_desc->unmapped = 1;
2492*5113495bSYour Name 		}
2493*5113495bSYour Name 		mon_desc->end_offset = hal_mon_rx_desc.end_offset;
2494*5113495bSYour Name 
2495*5113495bSYour Name 		/* Flush and truncated status buffers content
2496*5113495bSYour Name 		 * need to discarded
2497*5113495bSYour Name 		 */
2498*5113495bSYour Name 		if (hal_mon_rx_desc.end_reason == HAL_MON_FLUSH_DETECTED ||
2499*5113495bSYour Name 		    hal_mon_rx_desc.end_reason == HAL_MON_PPDU_TRUNCATED) {
2500*5113495bSYour Name 			dp_mon_debug("end_resaon: %d mon_pdev: %pK",
2501*5113495bSYour Name 				     hal_mon_rx_desc.end_reason, mon_pdev);
2502*5113495bSYour Name 			mon_pdev->rx_mon_stats.status_ppdu_drop++;
2503*5113495bSYour Name 			dp_rx_mon_handle_flush_n_trucated_ppdu(soc,
2504*5113495bSYour Name 							       pdev,
2505*5113495bSYour Name 							       mon_desc);
2506*5113495bSYour Name 			rx_mon_dst_ring_desc = hal_srng_dst_get_next(hal_soc,
2507*5113495bSYour Name 							mon_dst_srng);
2508*5113495bSYour Name 			continue;
2509*5113495bSYour Name 		}
2510*5113495bSYour Name 		if (mon_pdev_be->desc_count >= DP_MON_MAX_STATUS_BUF)
2511*5113495bSYour Name 			qdf_assert_always(0);
2512*5113495bSYour Name 
2513*5113495bSYour Name 		mon_pdev_be->status[mon_pdev_be->desc_count++] = mon_desc;
2514*5113495bSYour Name 
2515*5113495bSYour Name 		rx_mon_dst_ring_desc = hal_srng_dst_get_next(hal_soc, mon_dst_srng);
2516*5113495bSYour Name 
2517*5113495bSYour Name 		dp_rx_process_pktlog_be(soc, pdev, ppdu_info,
2518*5113495bSYour Name 					mon_desc->buf_addr,
2519*5113495bSYour Name 					hal_mon_rx_desc.end_offset);
2520*5113495bSYour Name 
2521*5113495bSYour Name 		if (hal_mon_rx_desc.end_reason == HAL_MON_STATUS_BUFFER_FULL)
2522*5113495bSYour Name 			continue;
2523*5113495bSYour Name 
2524*5113495bSYour Name 		mon_pdev->rx_mon_stats.status_ppdu_done++;
2525*5113495bSYour Name 
2526*5113495bSYour Name 		ppdu_info = dp_rx_mon_process_status_tlv(pdev);
2527*5113495bSYour Name 
2528*5113495bSYour Name 		if (ppdu_info) {
2529*5113495bSYour Name 			mon_pdev->rx_mon_stats.start_user_info_cnt +=
2530*5113495bSYour Name 				ppdu_info->start_user_info_cnt;
2531*5113495bSYour Name 			ppdu_info->start_user_info_cnt = 0;
2532*5113495bSYour Name 
2533*5113495bSYour Name 			mon_pdev->rx_mon_stats.end_user_stats_cnt +=
2534*5113495bSYour Name 				ppdu_info->end_user_stats_cnt;
2535*5113495bSYour Name 			ppdu_info->end_user_stats_cnt = 0;
2536*5113495bSYour Name 
2537*5113495bSYour Name 			dp_rx_mon_update_peer_id(pdev, ppdu_info);
2538*5113495bSYour Name 			dp_rx_mu_stats(pdev, ppdu_info);
2539*5113495bSYour Name 		}
2540*5113495bSYour Name 
2541*5113495bSYour Name 		/* Call enhanced stats update API */
2542*5113495bSYour Name 		if (mon_pdev->enhanced_stats_en && ppdu_info)
2543*5113495bSYour Name 			dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info);
2544*5113495bSYour Name 		else if (dp_cfr_rcc_mode_status(pdev) && ppdu_info)
2545*5113495bSYour Name 			dp_rx_handle_cfr(soc, pdev, ppdu_info);
2546*5113495bSYour Name 
2547*5113495bSYour Name 		dp_rx_mon_update_user_ctrl_frame_stats(pdev, ppdu_info);
2548*5113495bSYour Name 
2549*5113495bSYour Name 		status = dp_rx_mon_add_ppdu_info_to_wq(pdev, ppdu_info);
2550*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
2551*5113495bSYour Name 			if (ppdu_info)
2552*5113495bSYour Name 				dp_rx_mon_free_ppdu_info(pdev, ppdu_info);
2553*5113495bSYour Name 		}
2554*5113495bSYour Name 
2555*5113495bSYour Name 		work_done++;
2556*5113495bSYour Name 
2557*5113495bSYour Name 		/* desc_count should be zero  after PPDU status processing */
2558*5113495bSYour Name 		if (mon_pdev_be->desc_count > 0)
2559*5113495bSYour Name 			qdf_assert_always(0);
2560*5113495bSYour Name 
2561*5113495bSYour Name 		mon_pdev_be->desc_count = 0;
2562*5113495bSYour Name 	}
2563*5113495bSYour Name 	dp_rx_srng_access_end(int_ctx, soc, mon_dst_srng);
2564*5113495bSYour Name 
2565*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
2566*5113495bSYour Name 	dp_mon_info("mac_id: %d, work_done:%d", mac_id, work_done);
2567*5113495bSYour Name 	return work_done;
2568*5113495bSYour Name }
2569*5113495bSYour Name 
2570*5113495bSYour Name uint32_t
dp_rx_mon_process_2_0(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)2571*5113495bSYour Name dp_rx_mon_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
2572*5113495bSYour Name 		      uint32_t mac_id, uint32_t quota)
2573*5113495bSYour Name {
2574*5113495bSYour Name 	uint32_t work_done;
2575*5113495bSYour Name 
2576*5113495bSYour Name 	work_done = dp_rx_mon_srng_process_2_0(soc, int_ctx, mac_id, quota);
2577*5113495bSYour Name 
2578*5113495bSYour Name 	return work_done;
2579*5113495bSYour Name }
2580*5113495bSYour Name 
2581*5113495bSYour Name /**
2582*5113495bSYour Name  * dp_mon_pdev_ext_init_2_0() - Init pdev ext param
2583*5113495bSYour Name  *
2584*5113495bSYour Name  * @pdev: DP pdev handle
2585*5113495bSYour Name  *
2586*5113495bSYour Name  * Return:  QDF_STATUS_SUCCESS: Success
2587*5113495bSYour Name  *          QDF_STATUS_E_FAILURE: failure
2588*5113495bSYour Name  */
dp_mon_pdev_ext_init_2_0(struct dp_pdev * pdev)2589*5113495bSYour Name QDF_STATUS dp_mon_pdev_ext_init_2_0(struct dp_pdev *pdev)
2590*5113495bSYour Name {
2591*5113495bSYour Name 	return dp_rx_mon_init_wq_sm(pdev);
2592*5113495bSYour Name }
2593*5113495bSYour Name 
2594*5113495bSYour Name /**
2595*5113495bSYour Name  * dp_mon_pdev_ext_deinit_2_0() - denit pdev ext param
2596*5113495bSYour Name  *
2597*5113495bSYour Name  * @pdev: DP pdev handle
2598*5113495bSYour Name  *
2599*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS
2600*5113495bSYour Name  */
dp_mon_pdev_ext_deinit_2_0(struct dp_pdev * pdev)2601*5113495bSYour Name QDF_STATUS dp_mon_pdev_ext_deinit_2_0(struct dp_pdev *pdev)
2602*5113495bSYour Name {
2603*5113495bSYour Name 	dp_mon_pdev_flush_desc(pdev);
2604*5113495bSYour Name 
2605*5113495bSYour Name 	return dp_rx_mon_deinit_wq_sm(pdev);
2606*5113495bSYour Name }
2607*5113495bSYour Name 
2608*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
2609*5113495bSYour Name void
dp_rx_mon_populate_ppdu_usr_info_2_0(struct mon_rx_user_status * rx_user_status,struct cdp_rx_stats_ppdu_user * ppdu_user)2610*5113495bSYour Name dp_rx_mon_populate_ppdu_usr_info_2_0(struct mon_rx_user_status *rx_user_status,
2611*5113495bSYour Name 				     struct cdp_rx_stats_ppdu_user *ppdu_user)
2612*5113495bSYour Name {
2613*5113495bSYour Name 	ppdu_user->mpdu_retries = rx_user_status->retry_mpdu;
2614*5113495bSYour Name }
2615*5113495bSYour Name 
2616*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
dp_rx_mon_stats_update_2_0(struct dp_mon_peer * mon_peer,struct cdp_rx_indication_ppdu * ppdu,struct cdp_rx_stats_ppdu_user * ppdu_user)2617*5113495bSYour Name void dp_rx_mon_stats_update_2_0(struct dp_mon_peer *mon_peer,
2618*5113495bSYour Name 				struct cdp_rx_indication_ppdu *ppdu,
2619*5113495bSYour Name 				struct cdp_rx_stats_ppdu_user *ppdu_user)
2620*5113495bSYour Name {
2621*5113495bSYour Name 	uint8_t mcs, preamble, ppdu_type, punc_mode, res_mcs;
2622*5113495bSYour Name 	uint32_t num_msdu;
2623*5113495bSYour Name 
2624*5113495bSYour Name 	preamble = ppdu->u.preamble;
2625*5113495bSYour Name 	ppdu_type = ppdu->u.ppdu_type;
2626*5113495bSYour Name 	num_msdu = ppdu_user->num_msdu;
2627*5113495bSYour Name 	punc_mode = ppdu->punc_bw;
2628*5113495bSYour Name 
2629*5113495bSYour Name 	if (ppdu_type == HAL_RX_TYPE_SU)
2630*5113495bSYour Name 		mcs = ppdu->u.mcs;
2631*5113495bSYour Name 	else
2632*5113495bSYour Name 		mcs = ppdu_user->mcs;
2633*5113495bSYour Name 
2634*5113495bSYour Name 	DP_STATS_INC(mon_peer, rx.mpdu_retry_cnt, ppdu_user->mpdu_retries);
2635*5113495bSYour Name 	DP_STATS_INC(mon_peer, rx.punc_bw[punc_mode], num_msdu);
2636*5113495bSYour Name 
2637*5113495bSYour Name 	if (preamble == DOT11_BE) {
2638*5113495bSYour Name 		res_mcs = (mcs < MAX_MCS_11BE) ? mcs : (MAX_MCS - 1);
2639*5113495bSYour Name 
2640*5113495bSYour Name 		DP_STATS_INC(mon_peer,
2641*5113495bSYour Name 			     rx.pkt_type[preamble].mcs_count[res_mcs], num_msdu);
2642*5113495bSYour Name 		DP_STATS_INCC(mon_peer,
2643*5113495bSYour Name 			      rx.su_be_ppdu_cnt.mcs_count[res_mcs], 1,
2644*5113495bSYour Name 			      (ppdu_type == HAL_RX_TYPE_SU));
2645*5113495bSYour Name 		DP_STATS_INCC(mon_peer,
2646*5113495bSYour Name 			      rx.mu_be_ppdu_cnt[TXRX_TYPE_MU_OFDMA].mcs_count[res_mcs],
2647*5113495bSYour Name 			      1, (ppdu_type == HAL_RX_TYPE_MU_OFDMA));
2648*5113495bSYour Name 		DP_STATS_INCC(mon_peer,
2649*5113495bSYour Name 			      rx.mu_be_ppdu_cnt[TXRX_TYPE_MU_MIMO].mcs_count[res_mcs],
2650*5113495bSYour Name 			      1, (ppdu_type == HAL_RX_TYPE_MU_MIMO));
2651*5113495bSYour Name 	}
2652*5113495bSYour Name }
2653*5113495bSYour Name 
2654*5113495bSYour Name void
dp_rx_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info * hal_ppdu_info,struct cdp_rx_indication_ppdu * ppdu)2655*5113495bSYour Name dp_rx_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info *hal_ppdu_info,
2656*5113495bSYour Name 				 struct cdp_rx_indication_ppdu *ppdu)
2657*5113495bSYour Name {
2658*5113495bSYour Name 	uint16_t puncture_pattern;
2659*5113495bSYour Name 	enum cdp_punctured_modes punc_mode;
2660*5113495bSYour Name 
2661*5113495bSYour Name 	/* Align bw value as per host data structures */
2662*5113495bSYour Name 	if (hal_ppdu_info->rx_status.bw == HAL_FULL_RX_BW_320)
2663*5113495bSYour Name 		ppdu->u.bw = CMN_BW_320MHZ;
2664*5113495bSYour Name 	else
2665*5113495bSYour Name 		ppdu->u.bw = hal_ppdu_info->rx_status.bw;
2666*5113495bSYour Name 	if (hal_ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11BE) {
2667*5113495bSYour Name 		/* Align preamble value as per host data structures */
2668*5113495bSYour Name 		ppdu->u.preamble = DOT11_BE;
2669*5113495bSYour Name 		ppdu->u.stbc = hal_ppdu_info->rx_status.is_stbc;
2670*5113495bSYour Name 		ppdu->u.dcm = hal_ppdu_info->rx_status.dcm;
2671*5113495bSYour Name 	} else {
2672*5113495bSYour Name 		ppdu->u.preamble = hal_ppdu_info->rx_status.preamble_type;
2673*5113495bSYour Name 	}
2674*5113495bSYour Name 
2675*5113495bSYour Name 	puncture_pattern = hal_ppdu_info->rx_status.punctured_pattern;
2676*5113495bSYour Name 	punc_mode = dp_mon_get_puncture_type(puncture_pattern,
2677*5113495bSYour Name 					     ppdu->u.bw);
2678*5113495bSYour Name 	ppdu->punc_bw = punc_mode;
2679*5113495bSYour Name }
2680*5113495bSYour Name #else
dp_rx_mon_stats_update_2_0(struct dp_mon_peer * mon_peer,struct cdp_rx_indication_ppdu * ppdu,struct cdp_rx_stats_ppdu_user * ppdu_user)2681*5113495bSYour Name void dp_rx_mon_stats_update_2_0(struct dp_mon_peer *mon_peer,
2682*5113495bSYour Name 				struct cdp_rx_indication_ppdu *ppdu,
2683*5113495bSYour Name 				struct cdp_rx_stats_ppdu_user *ppdu_user)
2684*5113495bSYour Name {
2685*5113495bSYour Name 	DP_STATS_INC(mon_peer, rx.mpdu_retry_cnt, ppdu_user->mpdu_retries);
2686*5113495bSYour Name }
2687*5113495bSYour Name 
2688*5113495bSYour Name void
dp_rx_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info * hal_ppdu_info,struct cdp_rx_indication_ppdu * ppdu)2689*5113495bSYour Name dp_rx_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info *hal_ppdu_info,
2690*5113495bSYour Name 				 struct cdp_rx_indication_ppdu *ppdu)
2691*5113495bSYour Name {
2692*5113495bSYour Name 	ppdu->punc_bw = NO_PUNCTURE;
2693*5113495bSYour Name }
2694*5113495bSYour Name #endif
dp_mon_rx_print_advanced_stats_2_0(struct dp_soc * soc,struct dp_pdev * pdev)2695*5113495bSYour Name void dp_mon_rx_print_advanced_stats_2_0(struct dp_soc *soc,
2696*5113495bSYour Name 					struct dp_pdev *pdev)
2697*5113495bSYour Name {
2698*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats;
2699*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
2700*5113495bSYour Name 	struct dp_mon_soc *mon_soc = pdev->soc->monitor_soc;
2701*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
2702*5113495bSYour Name 				dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
2703*5113495bSYour Name 
2704*5113495bSYour Name 	rx_mon_stats = &mon_pdev->rx_mon_stats;
2705*5113495bSYour Name 
2706*5113495bSYour Name 	DP_PRINT_STATS("total_ppdu_info_alloc = %d",
2707*5113495bSYour Name 		       rx_mon_stats->total_ppdu_info_alloc);
2708*5113495bSYour Name 	DP_PRINT_STATS("total_ppdu_info_free = %d",
2709*5113495bSYour Name 		       rx_mon_stats->total_ppdu_info_free);
2710*5113495bSYour Name 	DP_PRINT_STATS("total_ppdu_info_enq = %d",
2711*5113495bSYour Name 		       rx_mon_stats->total_ppdu_info_enq);
2712*5113495bSYour Name 	DP_PRINT_STATS("total_ppdu_info_drop = %d",
2713*5113495bSYour Name 		       rx_mon_stats->total_ppdu_info_drop);
2714*5113495bSYour Name 	DP_PRINT_STATS("rx_hdr_not_received = %d",
2715*5113495bSYour Name 		       rx_mon_stats->rx_hdr_not_received);
2716*5113495bSYour Name 	DP_PRINT_STATS("parent_buf_alloc = %d",
2717*5113495bSYour Name 		       rx_mon_stats->parent_buf_alloc);
2718*5113495bSYour Name 	DP_PRINT_STATS("parent_buf_free = %d",
2719*5113495bSYour Name 		       rx_mon_stats->parent_buf_free);
2720*5113495bSYour Name 	DP_PRINT_STATS("mpdus_buf_to_stack = %d",
2721*5113495bSYour Name 		       rx_mon_stats->mpdus_buf_to_stack);
2722*5113495bSYour Name 	DP_PRINT_STATS("frag_alloc = %d",
2723*5113495bSYour Name 		       mon_soc->stats.frag_alloc);
2724*5113495bSYour Name 	DP_PRINT_STATS("total frag_free = %d",
2725*5113495bSYour Name 		       mon_soc->stats.frag_free);
2726*5113495bSYour Name 	DP_PRINT_STATS("frag_free due to empty queue= %d",
2727*5113495bSYour Name 		       mon_soc->stats.empty_queue);
2728*5113495bSYour Name 	DP_PRINT_STATS("status_buf_count = %d",
2729*5113495bSYour Name 		       rx_mon_stats->status_buf_count);
2730*5113495bSYour Name 	DP_PRINT_STATS("pkt_buf_count = %d",
2731*5113495bSYour Name 		       rx_mon_stats->pkt_buf_count);
2732*5113495bSYour Name 	DP_PRINT_STATS("rx_mon_queue_depth= %d",
2733*5113495bSYour Name 		       mon_pdev_be->rx_mon_queue_depth);
2734*5113495bSYour Name 	DP_PRINT_STATS("empty_desc= %d",
2735*5113495bSYour Name 		       mon_pdev->rx_mon_stats.empty_desc_ppdu);
2736*5113495bSYour Name 	DP_PRINT_STATS("mpdu_dropped_due_invalid_decap= %d",
2737*5113495bSYour Name 		       mon_pdev->rx_mon_stats.mpdu_decap_type_invalid);
2738*5113495bSYour Name 	DP_PRINT_STATS("total_free_elem= %d",
2739*5113495bSYour Name 		       mon_pdev_be->total_free_elem);
2740*5113495bSYour Name 	DP_PRINT_STATS("ppdu_drop_cnt= %d",
2741*5113495bSYour Name 		       mon_pdev->rx_mon_stats.ppdu_drop_cnt);
2742*5113495bSYour Name 	DP_PRINT_STATS("mpdu_drop_cnt= %d",
2743*5113495bSYour Name 		       mon_pdev->rx_mon_stats.mpdu_drop_cnt);
2744*5113495bSYour Name 	DP_PRINT_STATS("end_of_ppdu_drop_cnt= %d",
2745*5113495bSYour Name 		       mon_pdev->rx_mon_stats.end_of_ppdu_drop_cnt);
2746*5113495bSYour Name 	DP_PRINT_STATS("tlv_drop_cnt= %d",
2747*5113495bSYour Name 		       mon_pdev->rx_mon_stats.tlv_drop_cnt);
2748*5113495bSYour Name 	DP_PRINT_STATS("rx_hdr_invalid_cnt = %d",
2749*5113495bSYour Name 		       rx_mon_stats->rx_hdr_invalid_cnt);
2750*5113495bSYour Name 	DP_PRINT_STATS("invalid_dma_length Received = %d",
2751*5113495bSYour Name 		       rx_mon_stats->invalid_dma_length);
2752*5113495bSYour Name 	DP_PRINT_STATS("pending_desc_count= %d",
2753*5113495bSYour Name 		       mon_pdev->rx_mon_stats.pending_desc_count);
2754*5113495bSYour Name }
2755*5113495bSYour Name #endif
2756*5113495bSYour Name 
2757*5113495bSYour Name #ifdef WLAN_PKT_CAPTURE_RX_2_0
2758*5113495bSYour Name void
dp_rx_mon_buf_desc_pool_deinit(struct dp_soc * soc)2759*5113495bSYour Name dp_rx_mon_buf_desc_pool_deinit(struct dp_soc *soc)
2760*5113495bSYour Name {
2761*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2762*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2763*5113495bSYour Name 
2764*5113495bSYour Name 	/* Drain page frag cachce before pool deinit */
2765*5113495bSYour Name 	qdf_frag_cache_drain(&mon_soc_be->rx_desc_mon.pf_cache);
2766*5113495bSYour Name 	dp_mon_desc_pool_deinit(&mon_soc_be->rx_desc_mon);
2767*5113495bSYour Name }
2768*5113495bSYour Name 
2769*5113495bSYour Name QDF_STATUS
dp_rx_mon_buf_desc_pool_init(struct dp_soc * soc)2770*5113495bSYour Name dp_rx_mon_buf_desc_pool_init(struct dp_soc *soc)
2771*5113495bSYour Name {
2772*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2773*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2774*5113495bSYour Name 	uint32_t num_entries;
2775*5113495bSYour Name 
2776*5113495bSYour Name 	num_entries =
2777*5113495bSYour Name 		wlan_cfg_get_dp_soc_rx_mon_buf_ring_size(soc->wlan_cfg_ctx);
2778*5113495bSYour Name 	return dp_mon_desc_pool_init(&mon_soc_be->rx_desc_mon, num_entries);
2779*5113495bSYour Name }
2780*5113495bSYour Name 
dp_rx_mon_buf_desc_pool_free(struct dp_soc * soc)2781*5113495bSYour Name void dp_rx_mon_buf_desc_pool_free(struct dp_soc *soc)
2782*5113495bSYour Name {
2783*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2784*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2785*5113495bSYour Name 
2786*5113495bSYour Name 	if (mon_soc)
2787*5113495bSYour Name 		dp_mon_desc_pool_free(soc, &mon_soc_be->rx_desc_mon,
2788*5113495bSYour Name 				      DP_MON_RX_DESC_POOL_TYPE);
2789*5113495bSYour Name }
2790*5113495bSYour Name 
dp_rx_mon_soc_detach_2_0(struct dp_soc * soc,int lmac_id)2791*5113495bSYour Name void dp_rx_mon_soc_detach_2_0(struct dp_soc *soc, int lmac_id)
2792*5113495bSYour Name {
2793*5113495bSYour Name 	dp_rx_mon_buf_desc_pool_free(soc);
2794*5113495bSYour Name 	dp_srng_free(soc, &soc->rxdma_mon_buf_ring[lmac_id]);
2795*5113495bSYour Name }
2796*5113495bSYour Name 
dp_rx_mon_soc_deinit_2_0(struct dp_soc * soc,uint32_t lmac_id)2797*5113495bSYour Name void dp_rx_mon_soc_deinit_2_0(struct dp_soc *soc, uint32_t lmac_id)
2798*5113495bSYour Name {
2799*5113495bSYour Name 	dp_rx_mon_buffers_free(soc);
2800*5113495bSYour Name 	dp_rx_mon_buf_desc_pool_deinit(soc);
2801*5113495bSYour Name 	dp_srng_deinit(soc, &soc->rxdma_mon_buf_ring[lmac_id],
2802*5113495bSYour Name 			RXDMA_MONITOR_BUF, 0);
2803*5113495bSYour Name }
2804*5113495bSYour Name 
2805*5113495bSYour Name QDF_STATUS
dp_rx_mon_buf_desc_pool_alloc(struct dp_soc * soc)2806*5113495bSYour Name dp_rx_mon_buf_desc_pool_alloc(struct dp_soc *soc)
2807*5113495bSYour Name {
2808*5113495bSYour Name 	struct dp_srng *mon_buf_ring;
2809*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool;
2810*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2811*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2812*5113495bSYour Name 	int entries;
2813*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2814*5113495bSYour Name 
2815*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
2816*5113495bSYour Name 
2817*5113495bSYour Name 	entries = wlan_cfg_get_dp_soc_rx_mon_buf_ring_size(soc_cfg_ctx);
2818*5113495bSYour Name 	mon_buf_ring = &soc->rxdma_mon_buf_ring[0];
2819*5113495bSYour Name 
2820*5113495bSYour Name 	rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
2821*5113495bSYour Name 
2822*5113495bSYour Name 	qdf_print("%s:%d rx mon buf desc pool entries: %d", __func__, __LINE__, entries);
2823*5113495bSYour Name 	return dp_mon_desc_pool_alloc(soc, DP_MON_RX_DESC_POOL_TYPE,
2824*5113495bSYour Name 				      entries, rx_mon_desc_pool);
2825*5113495bSYour Name }
2826*5113495bSYour Name 
2827*5113495bSYour Name void
dp_rx_mon_buffers_free(struct dp_soc * soc)2828*5113495bSYour Name dp_rx_mon_buffers_free(struct dp_soc *soc)
2829*5113495bSYour Name {
2830*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool;
2831*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2832*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2833*5113495bSYour Name 
2834*5113495bSYour Name 	rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
2835*5113495bSYour Name 
2836*5113495bSYour Name 	dp_mon_pool_frag_unmap_and_free(soc, rx_mon_desc_pool);
2837*5113495bSYour Name }
2838*5113495bSYour Name 
2839*5113495bSYour Name QDF_STATUS
dp_rx_mon_buffers_alloc(struct dp_soc * soc,uint32_t size)2840*5113495bSYour Name dp_rx_mon_buffers_alloc(struct dp_soc *soc, uint32_t size)
2841*5113495bSYour Name {
2842*5113495bSYour Name 	struct dp_srng *mon_buf_ring;
2843*5113495bSYour Name 	struct dp_mon_desc_pool *rx_mon_desc_pool;
2844*5113495bSYour Name 	union dp_mon_desc_list_elem_t *desc_list = NULL;
2845*5113495bSYour Name 	union dp_mon_desc_list_elem_t *tail = NULL;
2846*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
2847*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
2848*5113495bSYour Name 
2849*5113495bSYour Name 	mon_buf_ring = &soc->rxdma_mon_buf_ring[0];
2850*5113495bSYour Name 
2851*5113495bSYour Name 	rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
2852*5113495bSYour Name 
2853*5113495bSYour Name 	return dp_mon_buffers_replenish(soc, mon_buf_ring,
2854*5113495bSYour Name 					rx_mon_desc_pool,
2855*5113495bSYour Name 					size,
2856*5113495bSYour Name 					&desc_list, &tail, NULL);
2857*5113495bSYour Name }
2858*5113495bSYour Name 
dp_rx_mon_soc_init_2_0(struct dp_soc * soc)2859*5113495bSYour Name QDF_STATUS dp_rx_mon_soc_init_2_0(struct dp_soc *soc)
2860*5113495bSYour Name {
2861*5113495bSYour Name 	if (dp_srng_init(soc, &soc->rxdma_mon_buf_ring[0],
2862*5113495bSYour Name 			 RXDMA_MONITOR_BUF, 0, 0)) {
2863*5113495bSYour Name 		dp_mon_err("%pK: " RNG_ERR "rx_mon_buf_ring", soc);
2864*5113495bSYour Name 		goto fail;
2865*5113495bSYour Name 	}
2866*5113495bSYour Name 
2867*5113495bSYour Name 	if (dp_rx_mon_buf_desc_pool_init(soc)) {
2868*5113495bSYour Name 		dp_mon_err("%pK: " RNG_ERR "rx mon desc pool init", soc);
2869*5113495bSYour Name 		goto fail;
2870*5113495bSYour Name 	}
2871*5113495bSYour Name 
2872*5113495bSYour Name 	/* monitor buffers for src */
2873*5113495bSYour Name 	if (dp_rx_mon_buffers_alloc(soc, DP_MON_RING_FILL_LEVEL_DEFAULT)) {
2874*5113495bSYour Name 		dp_mon_err("%pK: Rx mon buffers allocation failed", soc);
2875*5113495bSYour Name 		goto fail;
2876*5113495bSYour Name 	}
2877*5113495bSYour Name 
2878*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2879*5113495bSYour Name fail:
2880*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
2881*5113495bSYour Name }
2882*5113495bSYour Name 
dp_rx_mon_pdev_htt_srng_setup_2_0(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int mac_for_pdev)2883*5113495bSYour Name QDF_STATUS dp_rx_mon_pdev_htt_srng_setup_2_0(struct dp_soc *soc,
2884*5113495bSYour Name 					    struct dp_pdev *pdev,
2885*5113495bSYour Name 					    int mac_id,
2886*5113495bSYour Name 					    int mac_for_pdev)
2887*5113495bSYour Name {
2888*5113495bSYour Name 	return htt_srng_setup(soc->htt_handle, mac_for_pdev,
2889*5113495bSYour Name 			      soc->rxdma_mon_dst_ring[mac_id].hal_srng,
2890*5113495bSYour Name 			      RXDMA_MONITOR_DST);
2891*5113495bSYour Name }
2892*5113495bSYour Name 
dp_rx_mon_soc_htt_srng_setup_2_0(struct dp_soc * soc,int mac_id)2893*5113495bSYour Name QDF_STATUS dp_rx_mon_soc_htt_srng_setup_2_0(struct dp_soc *soc,
2894*5113495bSYour Name 					    int mac_id)
2895*5113495bSYour Name {
2896*5113495bSYour Name 	hal_set_low_threshold(soc->rxdma_mon_buf_ring[0].hal_srng,
2897*5113495bSYour Name 			      MON_BUF_MIN_ENTRIES << 2);
2898*5113495bSYour Name 	return htt_srng_setup(soc->htt_handle, 0,
2899*5113495bSYour Name 			soc->rxdma_mon_buf_ring[0].hal_srng,
2900*5113495bSYour Name 			RXDMA_MONITOR_BUF);
2901*5113495bSYour Name }
2902*5113495bSYour Name 
dp_rx_mon_pdev_rings_alloc_2_0(struct dp_pdev * pdev,int lmac_id)2903*5113495bSYour Name QDF_STATUS dp_rx_mon_pdev_rings_alloc_2_0(struct dp_pdev *pdev, int lmac_id)
2904*5113495bSYour Name {
2905*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2906*5113495bSYour Name 	int entries;
2907*5113495bSYour Name 	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
2908*5113495bSYour Name 
2909*5113495bSYour Name 	pdev_cfg_ctx = pdev->wlan_cfg_ctx;
2910*5113495bSYour Name 	entries = wlan_cfg_get_dma_rx_mon_dest_ring_size(pdev_cfg_ctx);
2911*5113495bSYour Name 
2912*5113495bSYour Name 	return dp_srng_alloc(soc, &soc->rxdma_mon_dst_ring[lmac_id],
2913*5113495bSYour Name 				  RXDMA_MONITOR_DST, entries, 0);
2914*5113495bSYour Name }
2915*5113495bSYour Name 
dp_rx_mon_pdev_rings_free_2_0(struct dp_pdev * pdev,int lmac_id)2916*5113495bSYour Name void dp_rx_mon_pdev_rings_free_2_0(struct dp_pdev *pdev, int lmac_id)
2917*5113495bSYour Name {
2918*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2919*5113495bSYour Name 
2920*5113495bSYour Name 	dp_srng_free(soc, &soc->rxdma_mon_dst_ring[lmac_id]);
2921*5113495bSYour Name }
2922*5113495bSYour Name 
dp_rx_mon_pdev_rings_init_2_0(struct dp_pdev * pdev,int lmac_id)2923*5113495bSYour Name QDF_STATUS dp_rx_mon_pdev_rings_init_2_0(struct dp_pdev *pdev, int lmac_id)
2924*5113495bSYour Name {
2925*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2926*5113495bSYour Name 
2927*5113495bSYour Name 	return dp_srng_init(soc, &soc->rxdma_mon_dst_ring[lmac_id],
2928*5113495bSYour Name 				 RXDMA_MONITOR_DST, pdev->pdev_id, lmac_id);
2929*5113495bSYour Name }
2930*5113495bSYour Name 
dp_rx_mon_pdev_rings_deinit_2_0(struct dp_pdev * pdev,int lmac_id)2931*5113495bSYour Name void dp_rx_mon_pdev_rings_deinit_2_0(struct dp_pdev *pdev, int lmac_id)
2932*5113495bSYour Name {
2933*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2934*5113495bSYour Name 
2935*5113495bSYour Name 	dp_srng_deinit(soc, &soc->rxdma_mon_dst_ring[lmac_id],
2936*5113495bSYour Name 		       RXDMA_MONITOR_DST, pdev->pdev_id);
2937*5113495bSYour Name }
2938*5113495bSYour Name 
dp_rx_mon_soc_attach_2_0(struct dp_soc * soc,int lmac_id)2939*5113495bSYour Name QDF_STATUS dp_rx_mon_soc_attach_2_0(struct dp_soc *soc, int lmac_id)
2940*5113495bSYour Name {
2941*5113495bSYour Name 	int entries;
2942*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
2943*5113495bSYour Name 
2944*5113495bSYour Name 	entries = wlan_cfg_get_dp_soc_rx_mon_buf_ring_size(soc_cfg_ctx);
2945*5113495bSYour Name 	qdf_print("%s:%d rx mon buf entries: %d", __func__, __LINE__, entries);
2946*5113495bSYour Name 
2947*5113495bSYour Name 	return dp_srng_alloc(soc, &soc->rxdma_mon_buf_ring[lmac_id],
2948*5113495bSYour Name 			  RXDMA_MONITOR_BUF, entries, 0);
2949*5113495bSYour Name }
2950*5113495bSYour Name 
2951*5113495bSYour Name #endif /* WLAN_PKT_CAPTURE_RX_2_0 */
2952