xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/monitor/dp_rx_mon.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #include "hal_hw_headers.h"
21*5113495bSYour Name #include "dp_types.h"
22*5113495bSYour Name #include "dp_rx.h"
23*5113495bSYour Name #include "dp_peer.h"
24*5113495bSYour Name #include "hal_rx.h"
25*5113495bSYour Name #include "hal_api.h"
26*5113495bSYour Name #include "qdf_trace.h"
27*5113495bSYour Name #include "qdf_nbuf.h"
28*5113495bSYour Name #include "hal_api_mon.h"
29*5113495bSYour Name #include "dp_internal.h"
30*5113495bSYour Name #include "qdf_mem.h"   /* qdf_mem_malloc,free */
31*5113495bSYour Name #include "dp_htt.h"
32*5113495bSYour Name #include "dp_mon.h"
33*5113495bSYour Name #include "dp_rx_mon.h"
34*5113495bSYour Name 
35*5113495bSYour Name #include "htt.h"
36*5113495bSYour Name #ifdef FEATURE_PERPKT_INFO
37*5113495bSYour Name #include "dp_ratetable.h"
38*5113495bSYour Name #endif
39*5113495bSYour Name 
40*5113495bSYour Name #ifndef IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK
41*5113495bSYour Name #define IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK 0xe0
42*5113495bSYour Name #endif
43*5113495bSYour Name 
44*5113495bSYour Name #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
45*5113495bSYour Name void
dp_rx_mon_handle_cfr_mu_info(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)46*5113495bSYour Name dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev,
47*5113495bSYour Name 			     struct hal_rx_ppdu_info *ppdu_info,
48*5113495bSYour Name 			     struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
49*5113495bSYour Name {
50*5113495bSYour Name 	struct dp_peer *peer;
51*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
52*5113495bSYour Name 	struct mon_rx_user_status *rx_user_status;
53*5113495bSYour Name 	struct cdp_rx_stats_ppdu_user *rx_stats_peruser;
54*5113495bSYour Name 	uint32_t num_users;
55*5113495bSYour Name 	int user_id;
56*5113495bSYour Name 	uint16_t sw_peer_id;
57*5113495bSYour Name 
58*5113495bSYour Name 	num_users = ppdu_info->com_info.num_users;
59*5113495bSYour Name 	for (user_id = 0; user_id < num_users; user_id++) {
60*5113495bSYour Name 		if (user_id >= OFDMA_NUM_USERS)
61*5113495bSYour Name 			return;
62*5113495bSYour Name 
63*5113495bSYour Name 		rx_user_status =  &ppdu_info->rx_user_status[user_id];
64*5113495bSYour Name 		rx_stats_peruser = &cdp_rx_ppdu->user[user_id];
65*5113495bSYour Name 		sw_peer_id = rx_user_status->sw_peer_id;
66*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(soc, sw_peer_id,
67*5113495bSYour Name 					     DP_MOD_ID_RX_PPDU_STATS);
68*5113495bSYour Name 		if (!peer) {
69*5113495bSYour Name 			rx_stats_peruser->peer_id = HTT_INVALID_PEER;
70*5113495bSYour Name 			continue;
71*5113495bSYour Name 		}
72*5113495bSYour Name 
73*5113495bSYour Name 		qdf_mem_copy(rx_stats_peruser->mac_addr,
74*5113495bSYour Name 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
75*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
76*5113495bSYour Name 	}
77*5113495bSYour Name }
78*5113495bSYour Name 
79*5113495bSYour Name void
dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)80*5113495bSYour Name dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev,
81*5113495bSYour Name 				 struct hal_rx_ppdu_info *ppdu_info,
82*5113495bSYour Name 				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
83*5113495bSYour Name {
84*5113495bSYour Name 	struct dp_peer *peer;
85*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
86*5113495bSYour Name 	int chain;
87*5113495bSYour Name 	uint16_t sw_peer_id;
88*5113495bSYour Name 	struct mon_rx_user_status *rx_user_status;
89*5113495bSYour Name 	uint32_t num_users = ppdu_info->com_info.num_users;
90*5113495bSYour Name 
91*5113495bSYour Name 	cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id;
92*5113495bSYour Name 	cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft;
93*5113495bSYour Name 	cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type;
94*5113495bSYour Name 
95*5113495bSYour Name 	for (chain = 0; chain < MAX_CHAIN; chain++)
96*5113495bSYour Name 		cdp_rx_ppdu->per_chain_rssi[chain] =
97*5113495bSYour Name 			ppdu_info->rx_status.rssi[chain];
98*5113495bSYour Name 
99*5113495bSYour Name 	cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size;
100*5113495bSYour Name 	cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed;
101*5113495bSYour Name 	cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc;
102*5113495bSYour Name 
103*5113495bSYour Name 	if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) &&
104*5113495bSYour Name 	    (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC))
105*5113495bSYour Name 		cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US;
106*5113495bSYour Name 	else
107*5113495bSYour Name 		cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi;
108*5113495bSYour Name 
109*5113495bSYour Name 	if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) {
110*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc;
111*5113495bSYour Name 	} else if (ppdu_info->rx_status.preamble_type ==
112*5113495bSYour Name 			HAL_RX_PKT_TYPE_11AX) {
113*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >>
114*5113495bSYour Name 				       QDF_MON_STATUS_STBC_SHIFT) & 0x1;
115*5113495bSYour Name 		cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >>
116*5113495bSYour Name 				      QDF_MON_STATUS_DCM_SHIFT) & 0x1;
117*5113495bSYour Name 	}
118*5113495bSYour Name 
119*5113495bSYour Name 	qdf_assert_always(num_users <= CDP_MU_MAX_USERS);
120*5113495bSYour Name 	dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu);
121*5113495bSYour Name 	rx_user_status = &ppdu_info->rx_user_status[num_users - 1];
122*5113495bSYour Name 	sw_peer_id = rx_user_status->sw_peer_id;
123*5113495bSYour Name 	cdp_rx_ppdu->num_users = num_users;
124*5113495bSYour Name 	peer = dp_peer_get_ref_by_id(soc, sw_peer_id, DP_MOD_ID_RX_PPDU_STATS);
125*5113495bSYour Name 	if (!peer) {
126*5113495bSYour Name 		cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
127*5113495bSYour Name 		return;
128*5113495bSYour Name 	}
129*5113495bSYour Name 
130*5113495bSYour Name 	cdp_rx_ppdu->peer_id = peer->peer_id;
131*5113495bSYour Name 	cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id;
132*5113495bSYour Name 
133*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
134*5113495bSYour Name }
135*5113495bSYour Name 
136*5113495bSYour Name bool
dp_cfr_rcc_mode_status(struct dp_pdev * pdev)137*5113495bSYour Name dp_cfr_rcc_mode_status(struct dp_pdev *pdev)
138*5113495bSYour Name {
139*5113495bSYour Name 	return pdev->cfr_rcc_mode;
140*5113495bSYour Name }
141*5113495bSYour Name 
142*5113495bSYour Name void
dp_rx_mon_populate_cfr_info(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)143*5113495bSYour Name dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev,
144*5113495bSYour Name 			    struct hal_rx_ppdu_info *ppdu_info,
145*5113495bSYour Name 			    struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
146*5113495bSYour Name {
147*5113495bSYour Name 	struct cdp_rx_ppdu_cfr_info *cfr_info;
148*5113495bSYour Name 
149*5113495bSYour Name 	if (!qdf_unlikely(dp_cfr_rcc_mode_status(pdev)))
150*5113495bSYour Name 		return;
151*5113495bSYour Name 
152*5113495bSYour Name 	cfr_info = &cdp_rx_ppdu->cfr_info;
153*5113495bSYour Name 
154*5113495bSYour Name 	cfr_info->bb_captured_channel
155*5113495bSYour Name 		= ppdu_info->cfr_info.bb_captured_channel;
156*5113495bSYour Name 	cfr_info->bb_captured_timeout
157*5113495bSYour Name 		= ppdu_info->cfr_info.bb_captured_timeout;
158*5113495bSYour Name 	cfr_info->bb_captured_reason
159*5113495bSYour Name 		= ppdu_info->cfr_info.bb_captured_reason;
160*5113495bSYour Name 	cfr_info->rx_location_info_valid
161*5113495bSYour Name 		= ppdu_info->cfr_info.rx_location_info_valid;
162*5113495bSYour Name 	cfr_info->chan_capture_status
163*5113495bSYour Name 		= ppdu_info->cfr_info.chan_capture_status;
164*5113495bSYour Name 	cfr_info->rtt_che_buffer_pointer_high8
165*5113495bSYour Name 		= ppdu_info->cfr_info.rtt_che_buffer_pointer_high8;
166*5113495bSYour Name 	cfr_info->rtt_che_buffer_pointer_low32
167*5113495bSYour Name 		= ppdu_info->cfr_info.rtt_che_buffer_pointer_low32;
168*5113495bSYour Name 	cfr_info->rtt_cfo_measurement
169*5113495bSYour Name 		= (int16_t)ppdu_info->cfr_info.rtt_cfo_measurement;
170*5113495bSYour Name 	cfr_info->agc_gain_info0
171*5113495bSYour Name 		= ppdu_info->cfr_info.agc_gain_info0;
172*5113495bSYour Name 	cfr_info->agc_gain_info1
173*5113495bSYour Name 		= ppdu_info->cfr_info.agc_gain_info1;
174*5113495bSYour Name 	cfr_info->agc_gain_info2
175*5113495bSYour Name 		= ppdu_info->cfr_info.agc_gain_info2;
176*5113495bSYour Name 	cfr_info->agc_gain_info3
177*5113495bSYour Name 		= ppdu_info->cfr_info.agc_gain_info3;
178*5113495bSYour Name 	cfr_info->rx_start_ts
179*5113495bSYour Name 		= ppdu_info->cfr_info.rx_start_ts;
180*5113495bSYour Name 	cfr_info->mcs_rate
181*5113495bSYour Name 		= ppdu_info->cfr_info.mcs_rate;
182*5113495bSYour Name 	cfr_info->gi_type
183*5113495bSYour Name 		= ppdu_info->cfr_info.gi_type;
184*5113495bSYour Name }
185*5113495bSYour Name 
186*5113495bSYour Name void
dp_update_cfr_dbg_stats(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)187*5113495bSYour Name dp_update_cfr_dbg_stats(struct dp_pdev *pdev,
188*5113495bSYour Name 			struct hal_rx_ppdu_info *ppdu_info)
189*5113495bSYour Name {
190*5113495bSYour Name 	struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info;
191*5113495bSYour Name 
192*5113495bSYour Name 	DP_STATS_INC(pdev,
193*5113495bSYour Name 		     rcc.chan_capture_status[cfr->chan_capture_status], 1);
194*5113495bSYour Name 	if (cfr->rx_location_info_valid) {
195*5113495bSYour Name 		DP_STATS_INC(pdev, rcc.rx_loc_info_valid_cnt, 1);
196*5113495bSYour Name 		if (cfr->bb_captured_channel) {
197*5113495bSYour Name 			DP_STATS_INC(pdev, rcc.bb_captured_channel_cnt, 1);
198*5113495bSYour Name 			DP_STATS_INC(pdev,
199*5113495bSYour Name 				     rcc.reason_cnt[cfr->bb_captured_reason],
200*5113495bSYour Name 				     1);
201*5113495bSYour Name 		} else if (cfr->bb_captured_timeout) {
202*5113495bSYour Name 			DP_STATS_INC(pdev, rcc.bb_captured_timeout_cnt, 1);
203*5113495bSYour Name 			DP_STATS_INC(pdev,
204*5113495bSYour Name 				     rcc.reason_cnt[cfr->bb_captured_reason],
205*5113495bSYour Name 				     1);
206*5113495bSYour Name 		}
207*5113495bSYour Name 	}
208*5113495bSYour Name }
209*5113495bSYour Name 
210*5113495bSYour Name void
dp_rx_handle_cfr(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)211*5113495bSYour Name dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev,
212*5113495bSYour Name 		 struct hal_rx_ppdu_info *ppdu_info)
213*5113495bSYour Name {
214*5113495bSYour Name 	qdf_nbuf_t ppdu_nbuf;
215*5113495bSYour Name 	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
216*5113495bSYour Name 
217*5113495bSYour Name 	dp_update_cfr_dbg_stats(pdev, ppdu_info);
218*5113495bSYour Name 	if (!ppdu_info->cfr_info.bb_captured_channel)
219*5113495bSYour Name 		return;
220*5113495bSYour Name 
221*5113495bSYour Name 	ppdu_nbuf = qdf_nbuf_alloc(soc->osdev,
222*5113495bSYour Name 				   sizeof(struct cdp_rx_indication_ppdu),
223*5113495bSYour Name 				   0,
224*5113495bSYour Name 				   0,
225*5113495bSYour Name 				   FALSE);
226*5113495bSYour Name 	if (ppdu_nbuf) {
227*5113495bSYour Name 		cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
228*5113495bSYour Name 
229*5113495bSYour Name 		dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu);
230*5113495bSYour Name 		dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu);
231*5113495bSYour Name 		qdf_nbuf_put_tail(ppdu_nbuf,
232*5113495bSYour Name 				  sizeof(struct cdp_rx_indication_ppdu));
233*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc,
234*5113495bSYour Name 				     ppdu_nbuf, HTT_INVALID_PEER,
235*5113495bSYour Name 				     WDI_NO_VAL, pdev->pdev_id);
236*5113495bSYour Name 	}
237*5113495bSYour Name }
238*5113495bSYour Name 
239*5113495bSYour Name void
dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)240*5113495bSYour Name dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev,
241*5113495bSYour Name 				 struct hal_rx_ppdu_info *ppdu_info,
242*5113495bSYour Name 				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
243*5113495bSYour Name {
244*5113495bSYour Name 	if (!dp_cfr_rcc_mode_status(pdev))
245*5113495bSYour Name 		return;
246*5113495bSYour Name 
247*5113495bSYour Name 	if (ppdu_info->cfr_info.bb_captured_channel)
248*5113495bSYour Name 		dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu);
249*5113495bSYour Name }
250*5113495bSYour Name 
251*5113495bSYour Name /**
252*5113495bSYour Name  * dp_bb_captured_chan_status() - Get the bb_captured_channel status
253*5113495bSYour Name  * @pdev: pdev ctx
254*5113495bSYour Name  * @ppdu_info: structure for rx ppdu ring
255*5113495bSYour Name  *
256*5113495bSYour Name  * Return: Success/ Failure
257*5113495bSYour Name  */
258*5113495bSYour Name static inline QDF_STATUS
dp_bb_captured_chan_status(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)259*5113495bSYour Name dp_bb_captured_chan_status(struct dp_pdev *pdev,
260*5113495bSYour Name 			   struct hal_rx_ppdu_info *ppdu_info)
261*5113495bSYour Name {
262*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
263*5113495bSYour Name 	struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info;
264*5113495bSYour Name 
265*5113495bSYour Name 	if (dp_cfr_rcc_mode_status(pdev)) {
266*5113495bSYour Name 		if (cfr->bb_captured_channel)
267*5113495bSYour Name 			status = QDF_STATUS_SUCCESS;
268*5113495bSYour Name 	}
269*5113495bSYour Name 
270*5113495bSYour Name 	return status;
271*5113495bSYour Name }
272*5113495bSYour Name #else
273*5113495bSYour Name static inline QDF_STATUS
dp_bb_captured_chan_status(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)274*5113495bSYour Name dp_bb_captured_chan_status(struct dp_pdev *pdev,
275*5113495bSYour Name 			   struct hal_rx_ppdu_info *ppdu_info)
276*5113495bSYour Name {
277*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
278*5113495bSYour Name }
279*5113495bSYour Name #endif /* WLAN_CFR_ENABLE */
280*5113495bSYour Name 
281*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
282*5113495bSYour Name #ifdef QCA_RSSI_DB2DBM
283*5113495bSYour Name /**
284*5113495bSYour Name  * dp_rx_mon_rf_index_conv() - this function will convert BB index to RF
285*5113495bSYour Name  *			index in the rssi_chain[chain][bw] array
286*5113495bSYour Name  *
287*5113495bSYour Name  * @chain: BB chain index
288*5113495bSYour Name  * @mon_pdev: pdev structure
289*5113495bSYour Name  *
290*5113495bSYour Name  * Return: return RF chain index
291*5113495bSYour Name  *
292*5113495bSYour Name  * Computation:
293*5113495bSYour Name  *  3 Bytes of xbar_config are used for RF to BB mapping
294*5113495bSYour Name  *  Samples of xbar_config,
295*5113495bSYour Name  *
296*5113495bSYour Name  * If xbar_config is 0x688FAC(hex):
297*5113495bSYour Name  *     RF chains 0-3 are connected to BB chains 4-7
298*5113495bSYour Name  *     RF chains 4-7 are connected to BB chains 0-3
299*5113495bSYour Name  *     here,
300*5113495bSYour Name  *     bits 0 to 2 = 4, maps BB chain 4 for RF chain 0
301*5113495bSYour Name  *     bits 3 to 5 = 5, maps BB chain 5 for RF chain 1
302*5113495bSYour Name  *     bits 6 to 8 = 6, maps BB chain 6 for RF chain 2
303*5113495bSYour Name  *     bits 9 to 11 = 7, maps BB chain 7 for RF chain 3
304*5113495bSYour Name  *     bits 12 to 14 = 0, maps BB chain 0 for RF chain 4
305*5113495bSYour Name  *     bits 15 to 17 = 1, maps BB chain 1 for RF chain 5
306*5113495bSYour Name  *     bits 18 to 20 = 2, maps BB chain 2 for RF chain 6
307*5113495bSYour Name  *     bits 21 to 23 = 3, maps BB chain 3 for RF chain 7
308*5113495bSYour Name  */
dp_rx_mon_rf_index_conv(uint8_t chain,struct dp_mon_pdev * mon_pdev)309*5113495bSYour Name static uint8_t dp_rx_mon_rf_index_conv(uint8_t chain,
310*5113495bSYour Name 				       struct dp_mon_pdev *mon_pdev)
311*5113495bSYour Name {
312*5113495bSYour Name 	uint32_t xbar_config = mon_pdev->rssi_offsets.xbar_config;
313*5113495bSYour Name 
314*5113495bSYour Name 	if (mon_pdev->rssi_dbm_conv_support && xbar_config)
315*5113495bSYour Name 		return ((xbar_config >> (3 * chain)) & 0x07);
316*5113495bSYour Name 	return chain;
317*5113495bSYour Name }
318*5113495bSYour Name #else
dp_rx_mon_rf_index_conv(uint8_t chain,struct dp_mon_pdev * mon_pdev)319*5113495bSYour Name static uint8_t dp_rx_mon_rf_index_conv(uint8_t chain,
320*5113495bSYour Name 				       struct dp_mon_pdev *mon_pdev)
321*5113495bSYour Name {
322*5113495bSYour Name 	return chain;
323*5113495bSYour Name }
324*5113495bSYour Name #endif
325*5113495bSYour Name void
dp_rx_populate_rx_rssi_chain(struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu,struct dp_pdev * pdev)326*5113495bSYour Name dp_rx_populate_rx_rssi_chain(struct hal_rx_ppdu_info *ppdu_info,
327*5113495bSYour Name 			     struct cdp_rx_indication_ppdu *cdp_rx_ppdu,
328*5113495bSYour Name 			     struct dp_pdev *pdev)
329*5113495bSYour Name {
330*5113495bSYour Name 	uint8_t chain, bw;
331*5113495bSYour Name 	uint8_t rssi;
332*5113495bSYour Name 	uint8_t chain_rf;
333*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
334*5113495bSYour Name 
335*5113495bSYour Name 	for (chain = 0; chain < SS_COUNT; chain++) {
336*5113495bSYour Name 		for (bw = 0; bw < MAX_BW; bw++) {
337*5113495bSYour Name 			chain_rf = dp_rx_mon_rf_index_conv(chain, mon_pdev);
338*5113495bSYour Name 			rssi = ppdu_info->rx_status.rssi_chain[chain_rf][bw];
339*5113495bSYour Name 			if (rssi != DP_RSSI_INVAL)
340*5113495bSYour Name 				cdp_rx_ppdu->rssi_chain[chain_rf][bw] = rssi;
341*5113495bSYour Name 			else
342*5113495bSYour Name 				cdp_rx_ppdu->rssi_chain[chain_rf][bw] = 0;
343*5113495bSYour Name 		}
344*5113495bSYour Name 	}
345*5113495bSYour Name }
346*5113495bSYour Name 
347*5113495bSYour Name void
dp_rx_populate_su_evm_details(struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)348*5113495bSYour Name dp_rx_populate_su_evm_details(struct hal_rx_ppdu_info *ppdu_info,
349*5113495bSYour Name 			      struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
350*5113495bSYour Name {
351*5113495bSYour Name 	uint16_t pilot_evm;
352*5113495bSYour Name 	uint16_t nss_count;
353*5113495bSYour Name 	uint16_t pilot_count;
354*5113495bSYour Name 
355*5113495bSYour Name 	nss_count = ppdu_info->evm_info.nss_count;
356*5113495bSYour Name 	pilot_count = ppdu_info->evm_info.pilot_count;
357*5113495bSYour Name 
358*5113495bSYour Name 	if ((nss_count * pilot_count) > DP_RX_MAX_SU_EVM_COUNT) {
359*5113495bSYour Name 		qdf_debug("pilot evm count is more than expected");
360*5113495bSYour Name 		return;
361*5113495bSYour Name 	}
362*5113495bSYour Name 	cdp_rx_ppdu->evm_info.pilot_count = pilot_count;
363*5113495bSYour Name 	cdp_rx_ppdu->evm_info.nss_count = nss_count;
364*5113495bSYour Name 
365*5113495bSYour Name 	/* Populate evm for pilot_evm  = nss_count*pilot_count */
366*5113495bSYour Name 	for (pilot_evm = 0; pilot_evm < nss_count * pilot_count; pilot_evm++) {
367*5113495bSYour Name 		cdp_rx_ppdu->evm_info.pilot_evm[pilot_evm] =
368*5113495bSYour Name 			ppdu_info->evm_info.pilot_evm[pilot_evm];
369*5113495bSYour Name 	}
370*5113495bSYour Name }
371*5113495bSYour Name 
372*5113495bSYour Name /**
373*5113495bSYour Name  * dp_rx_inc_rusize_cnt() - increment pdev stats based on RU size
374*5113495bSYour Name  * @pdev: pdev ctx
375*5113495bSYour Name  * @rx_user_status: mon rx user status
376*5113495bSYour Name  *
377*5113495bSYour Name  * Return: bool
378*5113495bSYour Name  */
379*5113495bSYour Name static inline bool
dp_rx_inc_rusize_cnt(struct dp_pdev * pdev,struct mon_rx_user_status * rx_user_status)380*5113495bSYour Name dp_rx_inc_rusize_cnt(struct dp_pdev *pdev,
381*5113495bSYour Name 		     struct mon_rx_user_status *rx_user_status)
382*5113495bSYour Name {
383*5113495bSYour Name 	uint32_t ru_size;
384*5113495bSYour Name 	bool is_data;
385*5113495bSYour Name 
386*5113495bSYour Name 	ru_size = rx_user_status->ofdma_ru_size;
387*5113495bSYour Name 
388*5113495bSYour Name 	if (dp_is_subtype_data(rx_user_status->frame_control)) {
389*5113495bSYour Name 		DP_STATS_INC(pdev,
390*5113495bSYour Name 			     ul_ofdma.data_rx_ru_size[ru_size], 1);
391*5113495bSYour Name 		is_data = true;
392*5113495bSYour Name 	} else {
393*5113495bSYour Name 		DP_STATS_INC(pdev,
394*5113495bSYour Name 			     ul_ofdma.nondata_rx_ru_size[ru_size], 1);
395*5113495bSYour Name 		is_data = false;
396*5113495bSYour Name 	}
397*5113495bSYour Name 
398*5113495bSYour Name 	return is_data;
399*5113495bSYour Name }
400*5113495bSYour Name 
401*5113495bSYour Name /**
402*5113495bSYour Name  * dp_rx_populate_cdp_indication_ppdu_user() - Populate per user cdp indication
403*5113495bSYour Name  * @pdev: pdev ctx
404*5113495bSYour Name  * @ppdu_info: ppdu info structure from ppdu ring
405*5113495bSYour Name  * @cdp_rx_ppdu: Rx PPDU indication structure
406*5113495bSYour Name  *
407*5113495bSYour Name  * Return: none
408*5113495bSYour Name  */
409*5113495bSYour Name static void
dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)410*5113495bSYour Name dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev,
411*5113495bSYour Name 					struct hal_rx_ppdu_info *ppdu_info,
412*5113495bSYour Name 					struct cdp_rx_indication_ppdu
413*5113495bSYour Name 					*cdp_rx_ppdu)
414*5113495bSYour Name {
415*5113495bSYour Name 	struct dp_peer *peer;
416*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
417*5113495bSYour Name 	int i;
418*5113495bSYour Name 	struct mon_rx_user_status *rx_user_status;
419*5113495bSYour Name 	struct mon_rx_user_info *rx_user_info;
420*5113495bSYour Name 	struct cdp_rx_stats_ppdu_user *rx_stats_peruser;
421*5113495bSYour Name 	int ru_size;
422*5113495bSYour Name 	bool is_data = false;
423*5113495bSYour Name 	uint32_t num_users;
424*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
425*5113495bSYour Name 	uint16_t sw_peer_id;
426*5113495bSYour Name 
427*5113495bSYour Name 	num_users = ppdu_info->com_info.num_users;
428*5113495bSYour Name 	for (i = 0; i < num_users; i++) {
429*5113495bSYour Name 		if (i >= OFDMA_NUM_USERS)
430*5113495bSYour Name 			return;
431*5113495bSYour Name 
432*5113495bSYour Name 		rx_user_status =  &ppdu_info->rx_user_status[i];
433*5113495bSYour Name 		rx_user_info = &ppdu_info->rx_user_info[i];
434*5113495bSYour Name 		rx_stats_peruser = &cdp_rx_ppdu->user[i];
435*5113495bSYour Name 
436*5113495bSYour Name 		sw_peer_id = rx_user_status->sw_peer_id;
437*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(soc, sw_peer_id,
438*5113495bSYour Name 					     DP_MOD_ID_RX_PPDU_STATS);
439*5113495bSYour Name 		if (qdf_unlikely(!peer)) {
440*5113495bSYour Name 			rx_stats_peruser->peer_id = HTT_INVALID_PEER;
441*5113495bSYour Name 			continue;
442*5113495bSYour Name 		}
443*5113495bSYour Name 		rx_stats_peruser->is_bss_peer = peer->bss_peer;
444*5113495bSYour Name 
445*5113495bSYour Name 		rx_stats_peruser->first_data_seq_ctrl =
446*5113495bSYour Name 			rx_user_status->first_data_seq_ctrl;
447*5113495bSYour Name 
448*5113495bSYour Name 		rx_stats_peruser->frame_control_info_valid =
449*5113495bSYour Name 			rx_user_status->frame_control_info_valid;
450*5113495bSYour Name 		rx_stats_peruser->frame_control =
451*5113495bSYour Name 			rx_user_status->frame_control;
452*5113495bSYour Name 
453*5113495bSYour Name 		rx_stats_peruser->qos_control_info_valid =
454*5113495bSYour Name 			rx_user_info->qos_control_info_valid;
455*5113495bSYour Name 		rx_stats_peruser->qos_control =
456*5113495bSYour Name 			rx_user_info->qos_control;
457*5113495bSYour Name 		rx_stats_peruser->tcp_msdu_count =
458*5113495bSYour Name 			rx_user_status->tcp_msdu_count;
459*5113495bSYour Name 		rx_stats_peruser->udp_msdu_count =
460*5113495bSYour Name 			rx_user_status->udp_msdu_count;
461*5113495bSYour Name 		rx_stats_peruser->other_msdu_count =
462*5113495bSYour Name 			rx_user_status->other_msdu_count;
463*5113495bSYour Name 
464*5113495bSYour Name 		rx_stats_peruser->num_msdu =
465*5113495bSYour Name 			rx_stats_peruser->tcp_msdu_count +
466*5113495bSYour Name 			rx_stats_peruser->udp_msdu_count +
467*5113495bSYour Name 			rx_stats_peruser->other_msdu_count;
468*5113495bSYour Name 
469*5113495bSYour Name 		rx_stats_peruser->preamble_type =
470*5113495bSYour Name 				cdp_rx_ppdu->u.preamble;
471*5113495bSYour Name 		rx_stats_peruser->mpdu_cnt_fcs_ok =
472*5113495bSYour Name 			rx_user_status->mpdu_cnt_fcs_ok;
473*5113495bSYour Name 		rx_stats_peruser->mpdu_cnt_fcs_err =
474*5113495bSYour Name 			rx_user_status->mpdu_cnt_fcs_err;
475*5113495bSYour Name 		qdf_mem_copy(&rx_stats_peruser->mpdu_fcs_ok_bitmap,
476*5113495bSYour Name 			     &rx_user_status->mpdu_fcs_ok_bitmap,
477*5113495bSYour Name 			     HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
478*5113495bSYour Name 			     sizeof(rx_user_status->mpdu_fcs_ok_bitmap[0]));
479*5113495bSYour Name 		rx_stats_peruser->mpdu_ok_byte_count =
480*5113495bSYour Name 			rx_user_status->mpdu_ok_byte_count;
481*5113495bSYour Name 		rx_stats_peruser->mpdu_err_byte_count =
482*5113495bSYour Name 			rx_user_status->mpdu_err_byte_count;
483*5113495bSYour Name 
484*5113495bSYour Name 		cdp_rx_ppdu->num_mpdu += rx_user_status->mpdu_cnt_fcs_ok;
485*5113495bSYour Name 		cdp_rx_ppdu->num_msdu += rx_stats_peruser->num_msdu;
486*5113495bSYour Name 		rx_stats_peruser->retries =
487*5113495bSYour Name 			CDP_FC_IS_RETRY_SET(rx_stats_peruser->frame_control) ?
488*5113495bSYour Name 			rx_stats_peruser->mpdu_cnt_fcs_ok : 0;
489*5113495bSYour Name 		cdp_rx_ppdu->retries += rx_stats_peruser->retries;
490*5113495bSYour Name 
491*5113495bSYour Name 		if (rx_stats_peruser->mpdu_cnt_fcs_ok > 1)
492*5113495bSYour Name 			rx_stats_peruser->is_ampdu = 1;
493*5113495bSYour Name 		else
494*5113495bSYour Name 			rx_stats_peruser->is_ampdu = 0;
495*5113495bSYour Name 
496*5113495bSYour Name 		rx_stats_peruser->tid = ppdu_info->rx_status.tid;
497*5113495bSYour Name 
498*5113495bSYour Name 		qdf_mem_copy(rx_stats_peruser->mac_addr,
499*5113495bSYour Name 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
500*5113495bSYour Name 		rx_stats_peruser->peer_id = peer->peer_id;
501*5113495bSYour Name 		cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id;
502*5113495bSYour Name 		rx_stats_peruser->vdev_id = peer->vdev->vdev_id;
503*5113495bSYour Name 		rx_stats_peruser->mu_ul_info_valid = 0;
504*5113495bSYour Name 
505*5113495bSYour Name 		mon_ops = dp_mon_ops_get(soc);
506*5113495bSYour Name 		if (mon_ops && mon_ops->mon_rx_populate_ppdu_usr_info)
507*5113495bSYour Name 			mon_ops->mon_rx_populate_ppdu_usr_info(rx_user_status,
508*5113495bSYour Name 							       rx_stats_peruser);
509*5113495bSYour Name 
510*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
511*5113495bSYour Name 		if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA ||
512*5113495bSYour Name 		    cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) {
513*5113495bSYour Name 			if (rx_user_status->mu_ul_info_valid) {
514*5113495bSYour Name 				rx_stats_peruser->nss = rx_user_status->nss;
515*5113495bSYour Name 				cdp_rx_ppdu->usr_nss_sum += rx_stats_peruser->nss;
516*5113495bSYour Name 				rx_stats_peruser->mcs = rx_user_status->mcs;
517*5113495bSYour Name 				rx_stats_peruser->mu_ul_info_valid =
518*5113495bSYour Name 					rx_user_status->mu_ul_info_valid;
519*5113495bSYour Name 				rx_stats_peruser->ofdma_ru_start_index =
520*5113495bSYour Name 					rx_user_status->ofdma_ru_start_index;
521*5113495bSYour Name 				rx_stats_peruser->ofdma_ru_width =
522*5113495bSYour Name 					rx_user_status->ofdma_ru_width;
523*5113495bSYour Name 				cdp_rx_ppdu->usr_ru_tones_sum +=
524*5113495bSYour Name 					rx_stats_peruser->ofdma_ru_width;
525*5113495bSYour Name 				rx_stats_peruser->user_index = i;
526*5113495bSYour Name 				ru_size = rx_user_status->ofdma_ru_size;
527*5113495bSYour Name 				/*
528*5113495bSYour Name 				 * max RU size will be equal to
529*5113495bSYour Name 				 * HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2
530*5113495bSYour Name 				 */
531*5113495bSYour Name 				if (qdf_unlikely(ru_size >= OFDMA_NUM_RU_SIZE)) {
532*5113495bSYour Name 					dp_err("invalid ru_size %d", ru_size);
533*5113495bSYour Name 					return;
534*5113495bSYour Name 				}
535*5113495bSYour Name 				is_data = dp_rx_inc_rusize_cnt(pdev,
536*5113495bSYour Name 							       rx_user_status);
537*5113495bSYour Name 			}
538*5113495bSYour Name 			if (is_data) {
539*5113495bSYour Name 				/* counter to get number of MU OFDMA */
540*5113495bSYour Name 				pdev->stats.ul_ofdma.data_rx_ppdu++;
541*5113495bSYour Name 				pdev->stats.ul_ofdma.data_users[num_users]++;
542*5113495bSYour Name 			}
543*5113495bSYour Name 		}
544*5113495bSYour Name 	}
545*5113495bSYour Name }
546*5113495bSYour Name 
547*5113495bSYour Name /**
548*5113495bSYour Name  * dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure
549*5113495bSYour Name  * @pdev: pdev ctx
550*5113495bSYour Name  * @ppdu_info: ppdu info structure from ppdu ring
551*5113495bSYour Name  * @cdp_rx_ppdu: Rx PPDU indication structure
552*5113495bSYour Name  *
553*5113495bSYour Name  * Return: none
554*5113495bSYour Name  */
555*5113495bSYour Name static void
dp_rx_populate_cdp_indication_ppdu(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)556*5113495bSYour Name dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
557*5113495bSYour Name 				   struct hal_rx_ppdu_info *ppdu_info,
558*5113495bSYour Name 				   struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
559*5113495bSYour Name {
560*5113495bSYour Name 	struct dp_peer *peer;
561*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
562*5113495bSYour Name 	uint32_t i;
563*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
564*5113495bSYour Name 	uint16_t sw_peer_id;
565*5113495bSYour Name 	struct mon_rx_user_status *rx_user_status;
566*5113495bSYour Name 	uint32_t num_users = ppdu_info->com_info.num_users;
567*5113495bSYour Name 
568*5113495bSYour Name 	cdp_rx_ppdu->first_data_seq_ctrl =
569*5113495bSYour Name 		ppdu_info->rx_status.first_data_seq_ctrl;
570*5113495bSYour Name 	cdp_rx_ppdu->frame_ctrl =
571*5113495bSYour Name 		ppdu_info->rx_status.frame_control;
572*5113495bSYour Name 	cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count;
573*5113495bSYour Name 	cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count;
574*5113495bSYour Name 	cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count;
575*5113495bSYour Name 	/* num mpdu is consolidated and added together in num user loop */
576*5113495bSYour Name 	cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok;
577*5113495bSYour Name 	/* num msdu is consolidated and added together in num user loop */
578*5113495bSYour Name 	cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count +
579*5113495bSYour Name 				 cdp_rx_ppdu->udp_msdu_count +
580*5113495bSYour Name 				 cdp_rx_ppdu->other_msdu_count);
581*5113495bSYour Name 
582*5113495bSYour Name 	cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ?
583*5113495bSYour Name 		ppdu_info->com_info.mpdu_cnt_fcs_ok : 0;
584*5113495bSYour Name 
585*5113495bSYour Name 	if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1)
586*5113495bSYour Name 		cdp_rx_ppdu->is_ampdu = 1;
587*5113495bSYour Name 	else
588*5113495bSYour Name 		cdp_rx_ppdu->is_ampdu = 0;
589*5113495bSYour Name 	cdp_rx_ppdu->tid = ppdu_info->rx_status.tid;
590*5113495bSYour Name 
591*5113495bSYour Name 	qdf_assert_always(num_users <= CDP_MU_MAX_USERS);
592*5113495bSYour Name 	rx_user_status = &ppdu_info->rx_user_status[num_users - 1];
593*5113495bSYour Name 	sw_peer_id = rx_user_status->sw_peer_id;
594*5113495bSYour Name 	peer = dp_peer_get_ref_by_id(soc, sw_peer_id,
595*5113495bSYour Name 				     DP_MOD_ID_RX_PPDU_STATS);
596*5113495bSYour Name 	if (qdf_unlikely(!peer)) {
597*5113495bSYour Name 		cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
598*5113495bSYour Name 		cdp_rx_ppdu->num_users = 0;
599*5113495bSYour Name 		goto end;
600*5113495bSYour Name 	}
601*5113495bSYour Name 
602*5113495bSYour Name 	qdf_mem_copy(cdp_rx_ppdu->mac_addr,
603*5113495bSYour Name 		     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
604*5113495bSYour Name 	cdp_rx_ppdu->peer_id = peer->peer_id;
605*5113495bSYour Name 	cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id;
606*5113495bSYour Name 
607*5113495bSYour Name 	cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id;
608*5113495bSYour Name 	cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len;
609*5113495bSYour Name 	cdp_rx_ppdu->duration = ppdu_info->rx_status.duration;
610*5113495bSYour Name 	cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss;
611*5113495bSYour Name 	cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs;
612*5113495bSYour Name 	if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) &&
613*5113495bSYour Name 	    (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC))
614*5113495bSYour Name 		cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US;
615*5113495bSYour Name 	else
616*5113495bSYour Name 		cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi;
617*5113495bSYour Name 	cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc;
618*5113495bSYour Name 	cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type;
619*5113495bSYour Name 	cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >>
620*5113495bSYour Name 				   QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3;
621*5113495bSYour Name 	cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb;
622*5113495bSYour Name 	cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft;
623*5113495bSYour Name 	cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num;
624*5113495bSYour Name 	cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed;
625*5113495bSYour Name 	cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len;
626*5113495bSYour Name 	cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate;
627*5113495bSYour Name 	cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size;
628*5113495bSYour Name 
629*5113495bSYour Name 	if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) {
630*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc;
631*5113495bSYour Name 	} else if (ppdu_info->rx_status.preamble_type ==
632*5113495bSYour Name 			HAL_RX_PKT_TYPE_11AX) {
633*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >>
634*5113495bSYour Name 				       QDF_MON_STATUS_STBC_SHIFT) & 0x1;
635*5113495bSYour Name 		cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >>
636*5113495bSYour Name 				      QDF_MON_STATUS_DCM_SHIFT) & 0x1;
637*5113495bSYour Name 	}
638*5113495bSYour Name 	dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu, pdev);
639*5113495bSYour Name 	dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu);
640*5113495bSYour Name 	cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna;
641*5113495bSYour Name 
642*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
643*5113495bSYour Name 	if (mon_ops && mon_ops->mon_rx_populate_ppdu_info)
644*5113495bSYour Name 		mon_ops->mon_rx_populate_ppdu_info(ppdu_info,
645*5113495bSYour Name 						   cdp_rx_ppdu);
646*5113495bSYour Name 
647*5113495bSYour Name 	cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor;
648*5113495bSYour Name 	for (i = 0; i < MAX_CHAIN; i++)
649*5113495bSYour Name 		cdp_rx_ppdu->per_chain_rssi[i] = ppdu_info->rx_status.rssi[i];
650*5113495bSYour Name 
651*5113495bSYour Name 	cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast;
652*5113495bSYour Name 
653*5113495bSYour Name 	cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users;
654*5113495bSYour Name 
655*5113495bSYour Name 	dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu);
656*5113495bSYour Name 
657*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
658*5113495bSYour Name 
659*5113495bSYour Name 	return;
660*5113495bSYour Name end:
661*5113495bSYour Name 	dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, cdp_rx_ppdu);
662*5113495bSYour Name }
663*5113495bSYour Name 
664*5113495bSYour Name /*
665*5113495bSYour Name  * dp_mon_eval_avg_rate_filter() - Evaluates rate value against filter
666*5113495bSYour Name  * @peer: dp peer
667*5113495bSYour Name  * @ratekbps: last packet rate in kbps
668*5113495bSYour Name  * @avg_rate: average rate for which new rate is to be evaluated
669*5113495bSYour Name  *
670*5113495bSYour Name  * Return: true when average need to be evaluated else false
671*5113495bSYour Name  */
672*5113495bSYour Name static inline bool
dp_mon_eval_avg_rate_filter(struct dp_peer * peer,uint32_t ratekbps,uint32_t avg_rate)673*5113495bSYour Name dp_mon_eval_avg_rate_filter(struct dp_peer *peer, uint32_t ratekbps,
674*5113495bSYour Name 			    uint32_t avg_rate) {
675*5113495bSYour Name 	uint16_t filter_val = 0;
676*5113495bSYour Name 
677*5113495bSYour Name 	if (qdf_unlikely(!peer || !peer->vdev ||
678*5113495bSYour Name 			  !peer->vdev->pdev->soc->wlan_cfg_ctx)) {
679*5113495bSYour Name 		return true;
680*5113495bSYour Name 	}
681*5113495bSYour Name 
682*5113495bSYour Name 	filter_val =
683*5113495bSYour Name 		peer->vdev->pdev->soc->wlan_cfg_ctx->avg_rate_stats_filter_val;
684*5113495bSYour Name 
685*5113495bSYour Name 	if (!filter_val || avg_rate < filter_val || ratekbps > filter_val) {
686*5113495bSYour Name 		return true;
687*5113495bSYour Name 	}
688*5113495bSYour Name 	return false;
689*5113495bSYour Name }
690*5113495bSYour Name 
691*5113495bSYour Name /**
692*5113495bSYour Name  * dp_rx_rate_stats_update() - Update per-peer rate statistics
693*5113495bSYour Name  * @peer: Datapath peer handle
694*5113495bSYour Name  * @ppdu: PPDU Descriptor
695*5113495bSYour Name  * @user: user index
696*5113495bSYour Name  *
697*5113495bSYour Name  * Return: None
698*5113495bSYour Name  */
dp_rx_rate_stats_update(struct dp_peer * peer,struct cdp_rx_indication_ppdu * ppdu,uint32_t user)699*5113495bSYour Name static inline void dp_rx_rate_stats_update(struct dp_peer *peer,
700*5113495bSYour Name 					   struct cdp_rx_indication_ppdu *ppdu,
701*5113495bSYour Name 					   uint32_t user)
702*5113495bSYour Name {
703*5113495bSYour Name 	uint32_t ratekbps = 0;
704*5113495bSYour Name 	uint32_t ppdu_rx_rate = 0;
705*5113495bSYour Name 	uint32_t nss = 0;
706*5113495bSYour Name 	uint8_t mcs = 0;
707*5113495bSYour Name 	uint32_t rix;
708*5113495bSYour Name 	uint16_t ratecode = 0;
709*5113495bSYour Name 	struct cdp_rx_stats_ppdu_user *ppdu_user = NULL;
710*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
711*5113495bSYour Name 
712*5113495bSYour Name 	if (!peer || !ppdu)
713*5113495bSYour Name 		return;
714*5113495bSYour Name 
715*5113495bSYour Name 	mon_peer = peer->monitor_peer;
716*5113495bSYour Name 	ppdu_user = &ppdu->user[user];
717*5113495bSYour Name 
718*5113495bSYour Name 	if (!mon_peer)
719*5113495bSYour Name 		return;
720*5113495bSYour Name 
721*5113495bSYour Name 	if (ppdu->u.ppdu_type != HAL_RX_TYPE_SU) {
722*5113495bSYour Name 		if (ppdu_user->nss == 0)
723*5113495bSYour Name 			nss = 0;
724*5113495bSYour Name 		else
725*5113495bSYour Name 			nss = ppdu_user->nss - 1;
726*5113495bSYour Name 		mcs = ppdu_user->mcs;
727*5113495bSYour Name 
728*5113495bSYour Name 		mon_peer->stats.rx.nss_info = ppdu_user->nss;
729*5113495bSYour Name 		mon_peer->stats.rx.mcs_info = ppdu_user->mcs;
730*5113495bSYour Name 	} else {
731*5113495bSYour Name 		if (ppdu->u.nss == 0)
732*5113495bSYour Name 			nss = 0;
733*5113495bSYour Name 		else
734*5113495bSYour Name 			nss = ppdu->u.nss - 1;
735*5113495bSYour Name 		mcs = ppdu->u.mcs;
736*5113495bSYour Name 
737*5113495bSYour Name 		mon_peer->stats.rx.nss_info = ppdu->u.nss;
738*5113495bSYour Name 		mon_peer->stats.rx.mcs_info = ppdu->u.mcs;
739*5113495bSYour Name 	}
740*5113495bSYour Name 
741*5113495bSYour Name 	ratekbps = dp_getrateindex(ppdu->u.gi,
742*5113495bSYour Name 				   mcs,
743*5113495bSYour Name 				   nss,
744*5113495bSYour Name 				   ppdu->u.preamble,
745*5113495bSYour Name 				   ppdu->u.bw,
746*5113495bSYour Name 				   ppdu->punc_bw,
747*5113495bSYour Name 				   &rix,
748*5113495bSYour Name 				   &ratecode);
749*5113495bSYour Name 
750*5113495bSYour Name 	if (!ratekbps) {
751*5113495bSYour Name 		ppdu->rix = 0;
752*5113495bSYour Name 		ppdu_user->rix = 0;
753*5113495bSYour Name 		ppdu->rx_ratekbps = 0;
754*5113495bSYour Name 		ppdu->rx_ratecode = 0;
755*5113495bSYour Name 		ppdu_user->rx_ratekbps = 0;
756*5113495bSYour Name 		return;
757*5113495bSYour Name 	}
758*5113495bSYour Name 
759*5113495bSYour Name 	mon_peer->stats.rx.bw_info = ppdu->u.bw;
760*5113495bSYour Name 	mon_peer->stats.rx.gi_info = ppdu->u.gi;
761*5113495bSYour Name 	mon_peer->stats.rx.preamble_info = ppdu->u.preamble;
762*5113495bSYour Name 
763*5113495bSYour Name 	ppdu->rix = rix;
764*5113495bSYour Name 	ppdu_user->rix = rix;
765*5113495bSYour Name 	DP_STATS_UPD(mon_peer, rx.last_rx_rate, ratekbps);
766*5113495bSYour Name 	if (qdf_likely(dp_mon_eval_avg_rate_filter(peer, ratekbps,
767*5113495bSYour Name 					mon_peer->stats.rx.avg_rx_rate))) {
768*5113495bSYour Name 		mon_peer->stats.rx.avg_rx_rate =
769*5113495bSYour Name 			dp_ath_rate_lpf(mon_peer->stats.rx.avg_rx_rate,
770*5113495bSYour Name 					ratekbps);
771*5113495bSYour Name 	}
772*5113495bSYour Name 	ppdu_rx_rate = dp_ath_rate_out(mon_peer->stats.rx.avg_rx_rate);
773*5113495bSYour Name 	DP_STATS_UPD(mon_peer, rx.rnd_avg_rx_rate, ppdu_rx_rate);
774*5113495bSYour Name 	ppdu->rx_ratekbps = ratekbps;
775*5113495bSYour Name 	ppdu->rx_ratecode = ratecode;
776*5113495bSYour Name 	ppdu_user->rx_ratekbps = ratekbps;
777*5113495bSYour Name 
778*5113495bSYour Name 	if (peer->vdev)
779*5113495bSYour Name 		peer->vdev->stats.rx.last_rx_rate = ratekbps;
780*5113495bSYour Name }
781*5113495bSYour Name 
782*5113495bSYour Name #ifdef WLAN_CONFIG_TELEMETRY_AGENT
783*5113495bSYour Name static void
dp_ppdu_desc_user_rx_time_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_rx_indication_ppdu * ppdu_desc,struct cdp_rx_stats_ppdu_user * user)784*5113495bSYour Name dp_ppdu_desc_user_rx_time_update(struct dp_pdev *pdev,
785*5113495bSYour Name 				 struct dp_peer *peer,
786*5113495bSYour Name 				 struct cdp_rx_indication_ppdu *ppdu_desc,
787*5113495bSYour Name 				 struct cdp_rx_stats_ppdu_user *user)
788*5113495bSYour Name {
789*5113495bSYour Name 	uint32_t nss_ru_width_sum = 0;
790*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
791*5113495bSYour Name 	uint8_t ac = 0;
792*5113495bSYour Name 
793*5113495bSYour Name 	if (!pdev || !ppdu_desc || !user || !peer)
794*5113495bSYour Name 		return;
795*5113495bSYour Name 
796*5113495bSYour Name 	nss_ru_width_sum = ppdu_desc->usr_nss_sum * ppdu_desc->usr_ru_tones_sum;
797*5113495bSYour Name 	if (!nss_ru_width_sum)
798*5113495bSYour Name 		nss_ru_width_sum = 1;
799*5113495bSYour Name 
800*5113495bSYour Name 	if (ppdu_desc->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA ||
801*5113495bSYour Name 	    ppdu_desc->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) {
802*5113495bSYour Name 		user->rx_time_us = (ppdu_desc->duration *
803*5113495bSYour Name 				    user->nss * user->ofdma_ru_width) /
804*5113495bSYour Name 				    nss_ru_width_sum;
805*5113495bSYour Name 	} else {
806*5113495bSYour Name 		user->rx_time_us = ppdu_desc->duration;
807*5113495bSYour Name 	}
808*5113495bSYour Name 
809*5113495bSYour Name 	mon_peer = peer->monitor_peer;
810*5113495bSYour Name 	if (qdf_unlikely(!mon_peer))
811*5113495bSYour Name 		return;
812*5113495bSYour Name 
813*5113495bSYour Name 	ac = TID_TO_WME_AC(user->tid);
814*5113495bSYour Name 	DP_STATS_INC(mon_peer, airtime_stats.rx_airtime_consumption[ac].consumption,
815*5113495bSYour Name 		     user->rx_time_us);
816*5113495bSYour Name }
817*5113495bSYour Name 
818*5113495bSYour Name /**
819*5113495bSYour Name  * dp_rx_mon_update_user_deter_stats() - Update per-peer deterministic stats
820*5113495bSYour Name  * @pdev: Datapath pdev handle
821*5113495bSYour Name  * @peer: Datapath peer handle
822*5113495bSYour Name  * @ppdu: PPDU Descriptor
823*5113495bSYour Name  * @user: Per user RX stats
824*5113495bSYour Name  *
825*5113495bSYour Name  * Return: None
826*5113495bSYour Name  */
827*5113495bSYour Name static inline
dp_rx_mon_update_user_deter_stats(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_rx_indication_ppdu * ppdu,struct cdp_rx_stats_ppdu_user * user)828*5113495bSYour Name void dp_rx_mon_update_user_deter_stats(struct dp_pdev *pdev,
829*5113495bSYour Name 				       struct dp_peer *peer,
830*5113495bSYour Name 				       struct cdp_rx_indication_ppdu *ppdu,
831*5113495bSYour Name 				       struct cdp_rx_stats_ppdu_user *user)
832*5113495bSYour Name {
833*5113495bSYour Name 	struct dp_mon_peer *mon_peer;
834*5113495bSYour Name 	uint8_t tid;
835*5113495bSYour Name 
836*5113495bSYour Name 	if (!pdev || !ppdu || !user || !peer)
837*5113495bSYour Name 		return;
838*5113495bSYour Name 
839*5113495bSYour Name 	if (!dp_is_subtype_data(ppdu->frame_ctrl))
840*5113495bSYour Name 		return;
841*5113495bSYour Name 
842*5113495bSYour Name 	if (ppdu->u.ppdu_type != HAL_RX_TYPE_SU)
843*5113495bSYour Name 		return;
844*5113495bSYour Name 
845*5113495bSYour Name 	mon_peer = peer->monitor_peer;
846*5113495bSYour Name 	if (!mon_peer)
847*5113495bSYour Name 		return;
848*5113495bSYour Name 
849*5113495bSYour Name 	tid = user->tid;
850*5113495bSYour Name 	if (tid >= CDP_DATA_TID_MAX)
851*5113495bSYour Name 		return;
852*5113495bSYour Name 
853*5113495bSYour Name 	DP_STATS_INC(mon_peer,
854*5113495bSYour Name 		     deter_stats.deter[tid].rx_det.mode_cnt,
855*5113495bSYour Name 		     1);
856*5113495bSYour Name 	DP_STATS_UPD(mon_peer,
857*5113495bSYour Name 		     deter_stats.deter[tid].rx_det.avg_rate,
858*5113495bSYour Name 		     mon_peer->stats.rx.avg_rx_rate);
859*5113495bSYour Name }
860*5113495bSYour Name 
861*5113495bSYour Name /**
862*5113495bSYour Name  * dp_rx_mon_update_pdev_deter_stats() - Update pdev deterministic stats
863*5113495bSYour Name  * @pdev: Datapath pdev handle
864*5113495bSYour Name  * @ppdu: PPDU Descriptor
865*5113495bSYour Name  *
866*5113495bSYour Name  * Return: None
867*5113495bSYour Name  */
868*5113495bSYour Name static inline
dp_rx_mon_update_pdev_deter_stats(struct dp_pdev * pdev,struct cdp_rx_indication_ppdu * ppdu)869*5113495bSYour Name void dp_rx_mon_update_pdev_deter_stats(struct dp_pdev *pdev,
870*5113495bSYour Name 				       struct cdp_rx_indication_ppdu *ppdu)
871*5113495bSYour Name {
872*5113495bSYour Name 	if (!dp_is_subtype_data(ppdu->frame_ctrl))
873*5113495bSYour Name 		return;
874*5113495bSYour Name 
875*5113495bSYour Name 	DP_STATS_INC(pdev,
876*5113495bSYour Name 		     deter_stats.rx_su_cnt,
877*5113495bSYour Name 		     1);
878*5113495bSYour Name }
879*5113495bSYour Name #else
880*5113495bSYour Name static inline void
dp_ppdu_desc_user_rx_time_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_rx_indication_ppdu * ppdu_desc,struct cdp_rx_stats_ppdu_user * user)881*5113495bSYour Name dp_ppdu_desc_user_rx_time_update(struct dp_pdev *pdev,
882*5113495bSYour Name 				 struct dp_peer *peer,
883*5113495bSYour Name 				 struct cdp_rx_indication_ppdu *ppdu_desc,
884*5113495bSYour Name 				 struct cdp_rx_stats_ppdu_user *user)
885*5113495bSYour Name { }
886*5113495bSYour Name 
887*5113495bSYour Name static inline
dp_rx_mon_update_user_deter_stats(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_rx_indication_ppdu * ppdu,struct cdp_rx_stats_ppdu_user * user)888*5113495bSYour Name void dp_rx_mon_update_user_deter_stats(struct dp_pdev *pdev,
889*5113495bSYour Name 				       struct dp_peer *peer,
890*5113495bSYour Name 				       struct cdp_rx_indication_ppdu *ppdu,
891*5113495bSYour Name 				       struct cdp_rx_stats_ppdu_user *user)
892*5113495bSYour Name { }
893*5113495bSYour Name 
894*5113495bSYour Name static inline
dp_rx_mon_update_pdev_deter_stats(struct dp_pdev * pdev,struct cdp_rx_indication_ppdu * ppdu)895*5113495bSYour Name void dp_rx_mon_update_pdev_deter_stats(struct dp_pdev *pdev,
896*5113495bSYour Name 				       struct cdp_rx_indication_ppdu *ppdu)
897*5113495bSYour Name { }
898*5113495bSYour Name #endif
899*5113495bSYour Name 
dp_rx_stats_update(struct dp_pdev * pdev,struct cdp_rx_indication_ppdu * ppdu)900*5113495bSYour Name static void dp_rx_stats_update(struct dp_pdev *pdev,
901*5113495bSYour Name 			       struct cdp_rx_indication_ppdu *ppdu)
902*5113495bSYour Name {
903*5113495bSYour Name 	struct dp_soc *soc = NULL;
904*5113495bSYour Name 	uint8_t mcs, preamble, ac = 0, nss, ppdu_type, res_mcs = 0;
905*5113495bSYour Name 	uint32_t num_msdu;
906*5113495bSYour Name 	struct dp_peer *peer;
907*5113495bSYour Name 	struct dp_mon_peer *mon_peer;
908*5113495bSYour Name 	struct cdp_rx_stats_ppdu_user *ppdu_user;
909*5113495bSYour Name 	uint32_t i;
910*5113495bSYour Name 	enum cdp_mu_packet_type mu_pkt_type;
911*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
912*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = NULL;
913*5113495bSYour Name 	uint64_t byte_count;
914*5113495bSYour Name 	bool is_preamble_valid = true;
915*5113495bSYour Name 
916*5113495bSYour Name 	if (qdf_likely(pdev))
917*5113495bSYour Name 		soc = pdev->soc;
918*5113495bSYour Name 	else
919*5113495bSYour Name 		return;
920*5113495bSYour Name 
921*5113495bSYour Name 	if (qdf_likely(!soc) || soc->process_rx_status)
922*5113495bSYour Name 		return;
923*5113495bSYour Name 
924*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
925*5113495bSYour Name 
926*5113495bSYour Name 	preamble = ppdu->u.preamble;
927*5113495bSYour Name 	ppdu_type = ppdu->u.ppdu_type;
928*5113495bSYour Name 
929*5113495bSYour Name 	for (i = 0; i < ppdu->num_users && i < CDP_MU_MAX_USERS; i++) {
930*5113495bSYour Name 		peer = NULL;
931*5113495bSYour Name 		ppdu_user = &ppdu->user[i];
932*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(soc, ppdu_user->peer_id,
933*5113495bSYour Name 					     DP_MOD_ID_RX_PPDU_STATS);
934*5113495bSYour Name 
935*5113495bSYour Name 		if (qdf_unlikely(!peer))
936*5113495bSYour Name 			mon_peer = mon_pdev->invalid_mon_peer;
937*5113495bSYour Name 		else
938*5113495bSYour Name 			mon_peer = peer->monitor_peer;
939*5113495bSYour Name 
940*5113495bSYour Name 		if (qdf_unlikely(!mon_peer)) {
941*5113495bSYour Name 			if (peer)
942*5113495bSYour Name 				dp_peer_unref_delete(peer,
943*5113495bSYour Name 						     DP_MOD_ID_RX_PPDU_STATS);
944*5113495bSYour Name 
945*5113495bSYour Name 			continue;
946*5113495bSYour Name 		}
947*5113495bSYour Name 
948*5113495bSYour Name 		if ((preamble == DOT11_A) || (preamble == DOT11_B))
949*5113495bSYour Name 			ppdu->u.nss = 1;
950*5113495bSYour Name 
951*5113495bSYour Name 		if (ppdu_type == HAL_RX_TYPE_SU) {
952*5113495bSYour Name 			mcs = ppdu->u.mcs;
953*5113495bSYour Name 			nss = ppdu->u.nss;
954*5113495bSYour Name 		} else {
955*5113495bSYour Name 			mcs = ppdu_user->mcs;
956*5113495bSYour Name 			nss = ppdu_user->nss;
957*5113495bSYour Name 		}
958*5113495bSYour Name 
959*5113495bSYour Name 		num_msdu = ppdu_user->num_msdu;
960*5113495bSYour Name 		byte_count = ppdu_user->mpdu_ok_byte_count +
961*5113495bSYour Name 			ppdu_user->mpdu_err_byte_count;
962*5113495bSYour Name 
963*5113495bSYour Name 		DP_STATS_UPD(mon_peer, rx.snr, ppdu->rssi);
964*5113495bSYour Name 
965*5113495bSYour Name 		if (qdf_unlikely(mon_peer->stats.rx.avg_snr == CDP_INVALID_SNR))
966*5113495bSYour Name 			mon_peer->stats.rx.avg_snr =
967*5113495bSYour Name 				CDP_SNR_IN(mon_peer->stats.rx.snr);
968*5113495bSYour Name 		else
969*5113495bSYour Name 			CDP_SNR_UPDATE_AVG(mon_peer->stats.rx.avg_snr,
970*5113495bSYour Name 					   mon_peer->stats.rx.snr);
971*5113495bSYour Name 
972*5113495bSYour Name 		if (ppdu_type == HAL_RX_TYPE_SU) {
973*5113495bSYour Name 			if (nss) {
974*5113495bSYour Name 				DP_STATS_INC(mon_peer, rx.nss[nss - 1], num_msdu);
975*5113495bSYour Name 				DP_STATS_INC(mon_peer, rx.ppdu_nss[nss - 1], 1);
976*5113495bSYour Name 			}
977*5113495bSYour Name 
978*5113495bSYour Name 			DP_STATS_INC(mon_peer, rx.mpdu_cnt_fcs_ok,
979*5113495bSYour Name 				     ppdu_user->mpdu_cnt_fcs_ok);
980*5113495bSYour Name 			DP_STATS_INC(mon_peer, rx.mpdu_cnt_fcs_err,
981*5113495bSYour Name 				     ppdu_user->mpdu_cnt_fcs_err);
982*5113495bSYour Name 		}
983*5113495bSYour Name 
984*5113495bSYour Name 		if (ppdu_type >= HAL_RX_TYPE_MU_MIMO &&
985*5113495bSYour Name 		    ppdu_type <= HAL_RX_TYPE_MU_OFDMA) {
986*5113495bSYour Name 			if (ppdu_type == HAL_RX_TYPE_MU_MIMO)
987*5113495bSYour Name 				mu_pkt_type = TXRX_TYPE_MU_MIMO;
988*5113495bSYour Name 			else
989*5113495bSYour Name 				mu_pkt_type = TXRX_TYPE_MU_OFDMA;
990*5113495bSYour Name 
991*5113495bSYour Name 			if (qdf_likely(nss)) {
992*5113495bSYour Name 				DP_STATS_INC(mon_peer, rx.nss[nss - 1], num_msdu);
993*5113495bSYour Name 				DP_STATS_INC(mon_peer,
994*5113495bSYour Name 					rx.rx_mu[mu_pkt_type].ppdu_nss[nss - 1],
995*5113495bSYour Name 					1);
996*5113495bSYour Name 			}
997*5113495bSYour Name 
998*5113495bSYour Name 			DP_STATS_INC(mon_peer,
999*5113495bSYour Name 				     rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_ok,
1000*5113495bSYour Name 				     ppdu_user->mpdu_cnt_fcs_ok);
1001*5113495bSYour Name 			DP_STATS_INC(mon_peer,
1002*5113495bSYour Name 				     rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_err,
1003*5113495bSYour Name 				     ppdu_user->mpdu_cnt_fcs_err);
1004*5113495bSYour Name 		}
1005*5113495bSYour Name 
1006*5113495bSYour Name 		DP_STATS_INC(mon_peer, rx.sgi_count[ppdu->u.gi], num_msdu);
1007*5113495bSYour Name 		DP_STATS_INC(mon_peer, rx.bw[ppdu->u.bw], num_msdu);
1008*5113495bSYour Name 		DP_STATS_INC(mon_peer, rx.reception_type[ppdu->u.ppdu_type],
1009*5113495bSYour Name 			     num_msdu);
1010*5113495bSYour Name 		DP_STATS_INC(mon_peer, rx.ppdu_cnt[ppdu->u.ppdu_type], 1);
1011*5113495bSYour Name 		DP_STATS_INCC(mon_peer, rx.ampdu_cnt, num_msdu,
1012*5113495bSYour Name 			      ppdu_user->is_ampdu);
1013*5113495bSYour Name 		DP_STATS_INCC(mon_peer, rx.non_ampdu_cnt, num_msdu,
1014*5113495bSYour Name 			      !(ppdu_user->is_ampdu));
1015*5113495bSYour Name 		DP_STATS_UPD(mon_peer, rx.rx_rate, mcs);
1016*5113495bSYour Name 
1017*5113495bSYour Name 		switch (preamble) {
1018*5113495bSYour Name 		case DOT11_A:
1019*5113495bSYour Name 			res_mcs = (mcs < MAX_MCS_11A) ? mcs : (MAX_MCS - 1);
1020*5113495bSYour Name 		break;
1021*5113495bSYour Name 		case DOT11_B:
1022*5113495bSYour Name 			res_mcs = (mcs < MAX_MCS_11B) ? mcs : (MAX_MCS - 1);
1023*5113495bSYour Name 		break;
1024*5113495bSYour Name 		case DOT11_N:
1025*5113495bSYour Name 			res_mcs = (mcs < MAX_MCS_11N) ? mcs : (MAX_MCS - 1);
1026*5113495bSYour Name 		break;
1027*5113495bSYour Name 		case DOT11_AC:
1028*5113495bSYour Name 			res_mcs = (mcs < MAX_MCS_11AC) ? mcs : (MAX_MCS - 1);
1029*5113495bSYour Name 		break;
1030*5113495bSYour Name 		case DOT11_AX:
1031*5113495bSYour Name 			res_mcs = (mcs < MAX_MCS_11AX) ? mcs : (MAX_MCS - 1);
1032*5113495bSYour Name 		break;
1033*5113495bSYour Name 		default:
1034*5113495bSYour Name 			is_preamble_valid = false;
1035*5113495bSYour Name 		}
1036*5113495bSYour Name 
1037*5113495bSYour Name 		DP_STATS_INCC(mon_peer,
1038*5113495bSYour Name 			      rx.pkt_type[preamble].mcs_count[res_mcs], num_msdu,
1039*5113495bSYour Name 			      is_preamble_valid);
1040*5113495bSYour Name 
1041*5113495bSYour Name 		if (preamble == DOT11_AX) {
1042*5113495bSYour Name 			DP_STATS_INCC(mon_peer,
1043*5113495bSYour Name 				      rx.su_ax_ppdu_cnt.mcs_count[res_mcs], 1,
1044*5113495bSYour Name 				      (ppdu_type == HAL_RX_TYPE_SU));
1045*5113495bSYour Name 			DP_STATS_INCC(mon_peer,
1046*5113495bSYour Name 				      rx.rx_mu[TXRX_TYPE_MU_OFDMA].ppdu.mcs_count[res_mcs],
1047*5113495bSYour Name 				      1, (ppdu_type == HAL_RX_TYPE_MU_OFDMA));
1048*5113495bSYour Name 			DP_STATS_INCC(mon_peer,
1049*5113495bSYour Name 				      rx.rx_mu[TXRX_TYPE_MU_MIMO].ppdu.mcs_count[res_mcs],
1050*5113495bSYour Name 				      1, (ppdu_type == HAL_RX_TYPE_MU_MIMO));
1051*5113495bSYour Name 		}
1052*5113495bSYour Name 
1053*5113495bSYour Name 		/*
1054*5113495bSYour Name 		 * If invalid TID, it could be a non-qos frame, hence do not
1055*5113495bSYour Name 		 * update any AC counters
1056*5113495bSYour Name 		 */
1057*5113495bSYour Name 		ac = TID_TO_WME_AC(ppdu_user->tid);
1058*5113495bSYour Name 
1059*5113495bSYour Name 		if (qdf_likely(ppdu->tid != HAL_TID_INVALID)) {
1060*5113495bSYour Name 			DP_STATS_INC(mon_peer, rx.wme_ac_type[ac], num_msdu);
1061*5113495bSYour Name 			DP_STATS_INC(mon_peer, rx.wme_ac_type_bytes[ac],
1062*5113495bSYour Name 				     byte_count);
1063*5113495bSYour Name 		}
1064*5113495bSYour Name 
1065*5113495bSYour Name 		DP_STATS_INC(mon_peer, rx.rx_ppdus, 1);
1066*5113495bSYour Name 		DP_STATS_INC(mon_peer, rx.rx_mpdus,
1067*5113495bSYour Name 			(ppdu_user->mpdu_cnt_fcs_ok + ppdu_user->mpdu_cnt_fcs_err));
1068*5113495bSYour Name 
1069*5113495bSYour Name 		mon_ops = dp_mon_ops_get(soc);
1070*5113495bSYour Name 		if (qdf_likely(mon_ops && mon_ops->mon_rx_stats_update))
1071*5113495bSYour Name 			mon_ops->mon_rx_stats_update(mon_peer, ppdu, ppdu_user);
1072*5113495bSYour Name 
1073*5113495bSYour Name 		if (qdf_unlikely(!peer))
1074*5113495bSYour Name 			continue;
1075*5113495bSYour Name 
1076*5113495bSYour Name 		dp_peer_stats_notify(pdev, peer);
1077*5113495bSYour Name 		DP_STATS_UPD(mon_peer, rx.last_snr, ppdu->rssi);
1078*5113495bSYour Name 
1079*5113495bSYour Name 		dp_peer_qos_stats_notify(pdev, ppdu_user);
1080*5113495bSYour Name 
1081*5113495bSYour Name 		if (dp_is_subtype_data(ppdu->frame_ctrl))
1082*5113495bSYour Name 			dp_rx_rate_stats_update(peer, ppdu, i);
1083*5113495bSYour Name 
1084*5113495bSYour Name 		dp_send_stats_event(pdev, peer, ppdu_user->peer_id);
1085*5113495bSYour Name 
1086*5113495bSYour Name 		dp_ppdu_desc_user_rx_time_update(pdev, peer, ppdu, ppdu_user);
1087*5113495bSYour Name 
1088*5113495bSYour Name 		if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx))
1089*5113495bSYour Name 			dp_rx_mon_update_user_deter_stats(pdev, peer,
1090*5113495bSYour Name 							  ppdu, ppdu_user);
1091*5113495bSYour Name 
1092*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
1093*5113495bSYour Name 	}
1094*5113495bSYour Name }
1095*5113495bSYour Name 
1096*5113495bSYour Name void
dp_rx_handle_ppdu_stats(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)1097*5113495bSYour Name dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
1098*5113495bSYour Name 			struct hal_rx_ppdu_info *ppdu_info)
1099*5113495bSYour Name {
1100*5113495bSYour Name 	qdf_nbuf_t ppdu_nbuf;
1101*5113495bSYour Name 	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
1102*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1103*5113495bSYour Name 	uint64_t size = 0;
1104*5113495bSYour Name 	uint8_t num_users = 0;
1105*5113495bSYour Name 
1106*5113495bSYour Name 	/*
1107*5113495bSYour Name 	 * Do not allocate if fcs error,
1108*5113495bSYour Name 	 * ast idx invalid / fctl invalid
1109*5113495bSYour Name 	 *
1110*5113495bSYour Name 	 * In CFR RCC mode - PPDU status TLVs of error pkts are also needed
1111*5113495bSYour Name 	 */
1112*5113495bSYour Name 	if (qdf_unlikely(ppdu_info->com_info.mpdu_cnt_fcs_ok == 0))
1113*5113495bSYour Name 		return;
1114*5113495bSYour Name 
1115*5113495bSYour Name 	if (qdf_unlikely(mon_pdev->neighbour_peers_added)) {
1116*5113495bSYour Name 		if (ppdu_info->nac_info.fc_valid &&
1117*5113495bSYour Name 		    ppdu_info->nac_info.to_ds_flag &&
1118*5113495bSYour Name 		    ppdu_info->nac_info.mac_addr2_valid) {
1119*5113495bSYour Name 			struct dp_neighbour_peer *peer = NULL;
1120*5113495bSYour Name 			uint8_t rssi = ppdu_info->rx_status.rssi_comb;
1121*5113495bSYour Name 
1122*5113495bSYour Name 			qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex);
1123*5113495bSYour Name 			if (mon_pdev->neighbour_peers_added) {
1124*5113495bSYour Name 				TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list,
1125*5113495bSYour Name 					      neighbour_peer_list_elem) {
1126*5113495bSYour Name 					if (!qdf_mem_cmp(&peer->neighbour_peers_macaddr,
1127*5113495bSYour Name 							 &ppdu_info->nac_info.mac_addr2,
1128*5113495bSYour Name 							 QDF_MAC_ADDR_SIZE)) {
1129*5113495bSYour Name 						peer->rssi = rssi;
1130*5113495bSYour Name 						break;
1131*5113495bSYour Name 					}
1132*5113495bSYour Name 				}
1133*5113495bSYour Name 			}
1134*5113495bSYour Name 			qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
1135*5113495bSYour Name 		} else {
1136*5113495bSYour Name 			dp_info("Neighbour peers RSSI update failed! fc_valid = %d, to_ds_flag = %d and mac_addr2_valid = %d",
1137*5113495bSYour Name 					ppdu_info->nac_info.fc_valid,
1138*5113495bSYour Name 					ppdu_info->nac_info.to_ds_flag,
1139*5113495bSYour Name 					ppdu_info->nac_info.mac_addr2_valid);
1140*5113495bSYour Name 		}
1141*5113495bSYour Name 	}
1142*5113495bSYour Name 
1143*5113495bSYour Name 	/* need not generate wdi event when mcopy, cfr rcc mode and
1144*5113495bSYour Name 	 * enhanced stats are not enabled
1145*5113495bSYour Name 	 */
1146*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev->mcopy_mode &&
1147*5113495bSYour Name 			 !mon_pdev->enhanced_stats_en &&
1148*5113495bSYour Name 			 !dp_cfr_rcc_mode_status(pdev)))
1149*5113495bSYour Name 		return;
1150*5113495bSYour Name 
1151*5113495bSYour Name 	if (qdf_unlikely(dp_cfr_rcc_mode_status(pdev)))
1152*5113495bSYour Name 		dp_update_cfr_dbg_stats(pdev, ppdu_info);
1153*5113495bSYour Name 
1154*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->rx_status.frame_control_info_valid ||
1155*5113495bSYour Name 			 ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID)) {
1156*5113495bSYour Name 		if (!(mon_pdev->mcopy_mode ||
1157*5113495bSYour Name 		      (dp_bb_captured_chan_status(pdev, ppdu_info) ==
1158*5113495bSYour Name 		       QDF_STATUS_SUCCESS)))
1159*5113495bSYour Name 			return;
1160*5113495bSYour Name 	}
1161*5113495bSYour Name 	num_users = ppdu_info->com_info.num_users;
1162*5113495bSYour Name 	qdf_assert_always(num_users <= CDP_MU_MAX_USERS);
1163*5113495bSYour Name 	size = sizeof(struct cdp_rx_indication_ppdu) +
1164*5113495bSYour Name 		num_users * sizeof(struct cdp_rx_stats_ppdu_user);
1165*5113495bSYour Name 	ppdu_nbuf = qdf_nbuf_alloc(soc->osdev,
1166*5113495bSYour Name 				   size,
1167*5113495bSYour Name 				   0, 0, FALSE);
1168*5113495bSYour Name 	if (qdf_likely(ppdu_nbuf)) {
1169*5113495bSYour Name 		cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(ppdu_nbuf);
1170*5113495bSYour Name 
1171*5113495bSYour Name 		qdf_mem_zero(cdp_rx_ppdu, size);
1172*5113495bSYour Name 		dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu);
1173*5113495bSYour Name 		dp_rx_populate_cdp_indication_ppdu(pdev,
1174*5113495bSYour Name 						   ppdu_info, cdp_rx_ppdu);
1175*5113495bSYour Name 		if (!qdf_unlikely(qdf_nbuf_put_tail(ppdu_nbuf,
1176*5113495bSYour Name 				       sizeof(struct cdp_rx_indication_ppdu))))
1177*5113495bSYour Name 			return;
1178*5113495bSYour Name 
1179*5113495bSYour Name 		if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) {
1180*5113495bSYour Name 			if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_SU)
1181*5113495bSYour Name 				dp_rx_mon_update_pdev_deter_stats(pdev,
1182*5113495bSYour Name 								  cdp_rx_ppdu);
1183*5113495bSYour Name 		}
1184*5113495bSYour Name 
1185*5113495bSYour Name 		dp_rx_stats_update(pdev, cdp_rx_ppdu);
1186*5113495bSYour Name 
1187*5113495bSYour Name 		if (qdf_unlikely(cdp_rx_ppdu->peer_id != HTT_INVALID_PEER)) {
1188*5113495bSYour Name 			dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC,
1189*5113495bSYour Name 					     soc, ppdu_nbuf,
1190*5113495bSYour Name 					     cdp_rx_ppdu->peer_id,
1191*5113495bSYour Name 					     WDI_NO_VAL, pdev->pdev_id);
1192*5113495bSYour Name 		} else if (qdf_unlikely(mon_pdev->mcopy_mode || dp_cfr_rcc_mode_status(pdev))) {
1193*5113495bSYour Name 			dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc,
1194*5113495bSYour Name 					     ppdu_nbuf, HTT_INVALID_PEER,
1195*5113495bSYour Name 					     WDI_NO_VAL, pdev->pdev_id);
1196*5113495bSYour Name 		} else {
1197*5113495bSYour Name 			qdf_nbuf_free(ppdu_nbuf);
1198*5113495bSYour Name 		}
1199*5113495bSYour Name 	}
1200*5113495bSYour Name }
1201*5113495bSYour Name #endif/* QCA_ENHANCED_STATS_SUPPORT */
1202*5113495bSYour Name 
1203*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
1204*5113495bSYour Name #define RX_PHYERR_MASK_GET64(_val1, _val2) (((uint64_t)(_val2) << 32) | (_val1))
1205*5113495bSYour Name /**
1206*5113495bSYour Name  * dp_rx_populate_cdp_indication_ppdu_undecoded_metadata() - Populate cdp
1207*5113495bSYour Name  * rx indication structure
1208*5113495bSYour Name  * @pdev: pdev ctx
1209*5113495bSYour Name  * @ppdu_info: ppdu info structure from ppdu ring
1210*5113495bSYour Name  * @cdp_rx_ppdu: Rx PPDU indication structure
1211*5113495bSYour Name  *
1212*5113495bSYour Name  * Return: none
1213*5113495bSYour Name  */
1214*5113495bSYour Name static void
dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,struct cdp_rx_indication_ppdu * cdp_rx_ppdu)1215*5113495bSYour Name dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(struct dp_pdev *pdev,
1216*5113495bSYour Name 				struct hal_rx_ppdu_info *ppdu_info,
1217*5113495bSYour Name 				struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
1218*5113495bSYour Name {
1219*5113495bSYour Name 	uint32_t chain;
1220*5113495bSYour Name 
1221*5113495bSYour Name 	cdp_rx_ppdu->phyrx_abort = ppdu_info->rx_status.phyrx_abort;
1222*5113495bSYour Name 	cdp_rx_ppdu->phyrx_abort_reason =
1223*5113495bSYour Name 		ppdu_info->rx_status.phyrx_abort_reason;
1224*5113495bSYour Name 
1225*5113495bSYour Name 	cdp_rx_ppdu->first_data_seq_ctrl =
1226*5113495bSYour Name 		ppdu_info->rx_status.first_data_seq_ctrl;
1227*5113495bSYour Name 	cdp_rx_ppdu->frame_ctrl =
1228*5113495bSYour Name 		ppdu_info->rx_status.frame_control;
1229*5113495bSYour Name 	cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count;
1230*5113495bSYour Name 	cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count;
1231*5113495bSYour Name 	cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count;
1232*5113495bSYour Name 	cdp_rx_ppdu->u.preamble = ppdu_info->rx_status.preamble_type;
1233*5113495bSYour Name 	cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok;
1234*5113495bSYour Name 	cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count +
1235*5113495bSYour Name 				 cdp_rx_ppdu->udp_msdu_count +
1236*5113495bSYour Name 				 cdp_rx_ppdu->other_msdu_count);
1237*5113495bSYour Name 
1238*5113495bSYour Name 	cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ?
1239*5113495bSYour Name 		ppdu_info->com_info.mpdu_cnt_fcs_ok : 0;
1240*5113495bSYour Name 
1241*5113495bSYour Name 	if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1)
1242*5113495bSYour Name 		cdp_rx_ppdu->is_ampdu = 1;
1243*5113495bSYour Name 	else
1244*5113495bSYour Name 		cdp_rx_ppdu->is_ampdu = 0;
1245*5113495bSYour Name 	cdp_rx_ppdu->tid = ppdu_info->rx_status.tid;
1246*5113495bSYour Name 
1247*5113495bSYour Name 	cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id;
1248*5113495bSYour Name 	cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len;
1249*5113495bSYour Name 	cdp_rx_ppdu->duration = ppdu_info->rx_status.duration;
1250*5113495bSYour Name 	cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw;
1251*5113495bSYour Name 	cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss;
1252*5113495bSYour Name 	cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs;
1253*5113495bSYour Name 	if (ppdu_info->rx_status.sgi == VHT_SGI_NYSM &&
1254*5113495bSYour Name 	    ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)
1255*5113495bSYour Name 		cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US;
1256*5113495bSYour Name 	else
1257*5113495bSYour Name 		cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi;
1258*5113495bSYour Name 
1259*5113495bSYour Name 	cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc;
1260*5113495bSYour Name 	cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type;
1261*5113495bSYour Name 	cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >>
1262*5113495bSYour Name 				   QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3;
1263*5113495bSYour Name 
1264*5113495bSYour Name 	cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb;
1265*5113495bSYour Name 	cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft;
1266*5113495bSYour Name 	cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num;
1267*5113495bSYour Name 	cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed;
1268*5113495bSYour Name 	cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len;
1269*5113495bSYour Name 	cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate;
1270*5113495bSYour Name 	cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size;
1271*5113495bSYour Name 
1272*5113495bSYour Name 	if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) {
1273*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc;
1274*5113495bSYour Name 		cdp_rx_ppdu->vht_no_txop_ps =
1275*5113495bSYour Name 			ppdu_info->rx_status.vht_no_txop_ps;
1276*5113495bSYour Name 		cdp_rx_ppdu->vht_crc = ppdu_info->rx_status.vht_crc;
1277*5113495bSYour Name 		cdp_rx_ppdu->group_id = ppdu_info->rx_status.vht_flag_values5;
1278*5113495bSYour Name 	} else if (ppdu_info->rx_status.preamble_type ==
1279*5113495bSYour Name 			HAL_RX_PKT_TYPE_11AX) {
1280*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >>
1281*5113495bSYour Name 				       QDF_MON_STATUS_STBC_SHIFT) & 0x1;
1282*5113495bSYour Name 		cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >>
1283*5113495bSYour Name 				      QDF_MON_STATUS_DCM_SHIFT) & 0x1;
1284*5113495bSYour Name 	} else {
1285*5113495bSYour Name 		cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.ht_stbc;
1286*5113495bSYour Name 		cdp_rx_ppdu->ht_length = ppdu_info->rx_status.ht_length;
1287*5113495bSYour Name 		cdp_rx_ppdu->ht_smoothing = ppdu_info->rx_status.smoothing;
1288*5113495bSYour Name 		cdp_rx_ppdu->ht_not_sounding =
1289*5113495bSYour Name 			ppdu_info->rx_status.not_sounding;
1290*5113495bSYour Name 		cdp_rx_ppdu->ht_aggregation = ppdu_info->rx_status.aggregation;
1291*5113495bSYour Name 		cdp_rx_ppdu->ht_stbc = ppdu_info->rx_status.ht_stbc;
1292*5113495bSYour Name 		cdp_rx_ppdu->ht_crc = ppdu_info->rx_status.ht_crc;
1293*5113495bSYour Name 	}
1294*5113495bSYour Name 
1295*5113495bSYour Name 	cdp_rx_ppdu->l_sig_length = ppdu_info->rx_status.l_sig_length;
1296*5113495bSYour Name 	cdp_rx_ppdu->l_sig_a_parity = ppdu_info->rx_status.l_sig_a_parity;
1297*5113495bSYour Name 	cdp_rx_ppdu->l_sig_a_pkt_type = ppdu_info->rx_status.l_sig_a_pkt_type;
1298*5113495bSYour Name 
1299*5113495bSYour Name 	if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) {
1300*5113495bSYour Name 		cdp_rx_ppdu->he_crc = ppdu_info->rx_status.he_crc;
1301*5113495bSYour Name 		cdp_rx_ppdu->bss_color_id =
1302*5113495bSYour Name 			ppdu_info->rx_status.he_data3 & 0x3F;
1303*5113495bSYour Name 		cdp_rx_ppdu->beam_change = (ppdu_info->rx_status.he_data3 >>
1304*5113495bSYour Name 				QDF_MON_STATUS_BEAM_CHANGE_SHIFT) & 0x1;
1305*5113495bSYour Name 		cdp_rx_ppdu->dl_ul_flag = (ppdu_info->rx_status.he_data3 >>
1306*5113495bSYour Name 		QDF_MON_STATUS_DL_UL_SHIFT) & 0x1;
1307*5113495bSYour Name 		cdp_rx_ppdu->ldpc_extra_sym = (ppdu_info->rx_status.he_data3 >>
1308*5113495bSYour Name 				QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT) & 0x1;
1309*5113495bSYour Name 		cdp_rx_ppdu->special_reuse =
1310*5113495bSYour Name 			ppdu_info->rx_status.he_data4 & 0xF;
1311*5113495bSYour Name 		cdp_rx_ppdu->ltf_sym = (ppdu_info->rx_status.he_data5 >>
1312*5113495bSYour Name 				QDF_MON_STATUS_HE_LTF_SYM_SHIFT) & 0x7;
1313*5113495bSYour Name 		cdp_rx_ppdu->txbf = (ppdu_info->rx_status.he_data5 >>
1314*5113495bSYour Name 				QDF_MON_STATUS_TXBF_SHIFT) & 0x1;
1315*5113495bSYour Name 		cdp_rx_ppdu->pe_disambiguity = (ppdu_info->rx_status.he_data5 >>
1316*5113495bSYour Name 				QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT) & 0x1;
1317*5113495bSYour Name 		cdp_rx_ppdu->pre_fec_pad = (ppdu_info->rx_status.he_data5 >>
1318*5113495bSYour Name 				QDF_MON_STATUS_PRE_FEC_PAD_SHIFT) & 0x3;
1319*5113495bSYour Name 		cdp_rx_ppdu->dopplar = (ppdu_info->rx_status.he_data6 >>
1320*5113495bSYour Name 				QDF_MON_STATUS_DOPPLER_SHIFT) & 0x1;
1321*5113495bSYour Name 		cdp_rx_ppdu->txop_duration = (ppdu_info->rx_status.he_data6 >>
1322*5113495bSYour Name 				QDF_MON_STATUS_TXOP_SHIFT) & 0x7F;
1323*5113495bSYour Name 		cdp_rx_ppdu->sig_b_mcs = ppdu_info->rx_status.he_flags1 & 0x7;
1324*5113495bSYour Name 		cdp_rx_ppdu->sig_b_dcm = (ppdu_info->rx_status.he_flags1 >>
1325*5113495bSYour Name 				QDF_MON_STATUS_DCM_FLAG_1_SHIFT) & 0x1;
1326*5113495bSYour Name 		cdp_rx_ppdu->sig_b_sym = (ppdu_info->rx_status.he_flags2 >>
1327*5113495bSYour Name 				QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT) & 0xF;
1328*5113495bSYour Name 		cdp_rx_ppdu->sig_b_comp = (ppdu_info->rx_status.he_flags2 >>
1329*5113495bSYour Name 			QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT) & 0x1;
1330*5113495bSYour Name 	}
1331*5113495bSYour Name 	dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu, pdev);
1332*5113495bSYour Name 	dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu);
1333*5113495bSYour Name 	cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna;
1334*5113495bSYour Name 
1335*5113495bSYour Name 	cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor;
1336*5113495bSYour Name 	for (chain = 0; chain < MAX_CHAIN; chain++)
1337*5113495bSYour Name 		cdp_rx_ppdu->per_chain_rssi[chain] =
1338*5113495bSYour Name 			ppdu_info->rx_status.rssi[chain];
1339*5113495bSYour Name 
1340*5113495bSYour Name 	cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast;
1341*5113495bSYour Name 
1342*5113495bSYour Name 	cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users;
1343*5113495bSYour Name 
1344*5113495bSYour Name 	dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu);
1345*5113495bSYour Name }
1346*5113495bSYour Name 
1347*5113495bSYour Name /**
1348*5113495bSYour Name  * dp_rx_is_valid_undecoded_frame() - Check unencoded frame received valid
1349*5113495bSYour Name  * or not against configured error mask
1350*5113495bSYour Name  * @err_mask: configured err mask
1351*5113495bSYour Name  * @err_code: Received error reason code for phy abort
1352*5113495bSYour Name  *
1353*5113495bSYour Name  * Return: true / false
1354*5113495bSYour Name  */
1355*5113495bSYour Name static inline bool
dp_rx_is_valid_undecoded_frame(uint64_t err_mask,uint8_t err_code)1356*5113495bSYour Name dp_rx_is_valid_undecoded_frame(uint64_t err_mask, uint8_t err_code)
1357*5113495bSYour Name {
1358*5113495bSYour Name 	if (err_code < CDP_PHYRX_ERR_MAX &&
1359*5113495bSYour Name 	    (err_mask & (1ULL << err_code)))
1360*5113495bSYour Name 		return true;
1361*5113495bSYour Name 
1362*5113495bSYour Name 	return false;
1363*5113495bSYour Name }
1364*5113495bSYour Name 
1365*5113495bSYour Name void
dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)1366*5113495bSYour Name dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc *soc, struct dp_pdev *pdev,
1367*5113495bSYour Name 				     struct hal_rx_ppdu_info *ppdu_info)
1368*5113495bSYour Name {
1369*5113495bSYour Name 	qdf_nbuf_t ppdu_nbuf;
1370*5113495bSYour Name 	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
1371*5113495bSYour Name 	uint8_t abort_reason = 0;
1372*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1373*5113495bSYour Name 	uint64_t mask64;
1374*5113495bSYour Name 
1375*5113495bSYour Name 	 /* Return if RX_ABORT not set */
1376*5113495bSYour Name 	if (ppdu_info->rx_status.phyrx_abort == 0)
1377*5113495bSYour Name 		return;
1378*5113495bSYour Name 
1379*5113495bSYour Name 	mask64 = RX_PHYERR_MASK_GET64(mon_pdev->phyrx_error_mask,
1380*5113495bSYour Name 				      mon_pdev->phyrx_error_mask_cont);
1381*5113495bSYour Name 	abort_reason = ppdu_info->rx_status.phyrx_abort_reason;
1382*5113495bSYour Name 
1383*5113495bSYour Name 	if (!dp_rx_is_valid_undecoded_frame(mask64, abort_reason))
1384*5113495bSYour Name 		return;
1385*5113495bSYour Name 
1386*5113495bSYour Name 	ppdu_nbuf = qdf_nbuf_alloc(soc->osdev,
1387*5113495bSYour Name 				   sizeof(struct cdp_rx_indication_ppdu),
1388*5113495bSYour Name 				   0, 0, FALSE);
1389*5113495bSYour Name 	if (ppdu_nbuf) {
1390*5113495bSYour Name 		cdp_rx_ppdu = ((struct cdp_rx_indication_ppdu *)
1391*5113495bSYour Name 				qdf_nbuf_data(ppdu_nbuf));
1392*5113495bSYour Name 
1393*5113495bSYour Name 		qdf_mem_zero(cdp_rx_ppdu,
1394*5113495bSYour Name 			     sizeof(struct cdp_rx_indication_ppdu));
1395*5113495bSYour Name 		dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(pdev,
1396*5113495bSYour Name 				ppdu_info, cdp_rx_ppdu);
1397*5113495bSYour Name 
1398*5113495bSYour Name 		if (!qdf_nbuf_put_tail(ppdu_nbuf,
1399*5113495bSYour Name 				       sizeof(struct cdp_rx_indication_ppdu))) {
1400*5113495bSYour Name 			return;
1401*5113495bSYour Name 		}
1402*5113495bSYour Name 
1403*5113495bSYour Name 		mon_pdev->rx_mon_stats.rx_undecoded_count++;
1404*5113495bSYour Name 		mon_pdev->rx_mon_stats.rx_undecoded_error[abort_reason] += 1;
1405*5113495bSYour Name 
1406*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC_UNDECODED_METADATA,
1407*5113495bSYour Name 				     soc, ppdu_nbuf, HTT_INVALID_PEER,
1408*5113495bSYour Name 				     WDI_NO_VAL, pdev->pdev_id);
1409*5113495bSYour Name 	}
1410*5113495bSYour Name }
1411*5113495bSYour Name #endif/* QCA_UNDECODED_METADATA_SUPPORT */
1412*5113495bSYour Name 
1413*5113495bSYour Name #ifdef QCA_MCOPY_SUPPORT
1414*5113495bSYour Name QDF_STATUS
dp_rx_handle_mcopy_mode(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,qdf_nbuf_t nbuf,uint8_t fcs_ok_mpdu_cnt,bool deliver_frame)1415*5113495bSYour Name dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
1416*5113495bSYour Name 			struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf,
1417*5113495bSYour Name 			uint8_t fcs_ok_mpdu_cnt, bool deliver_frame)
1418*5113495bSYour Name {
1419*5113495bSYour Name 	uint16_t size = 0;
1420*5113495bSYour Name 	struct ieee80211_frame *wh;
1421*5113495bSYour Name 	uint32_t *nbuf_data;
1422*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1423*5113495bSYour Name 
1424*5113495bSYour Name 	if (!ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload)
1425*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1426*5113495bSYour Name 
1427*5113495bSYour Name 	/* For M_COPY mode only one msdu per ppdu is sent to upper layer*/
1428*5113495bSYour Name 	if (mon_pdev->mcopy_mode == M_COPY) {
1429*5113495bSYour Name 		if (mon_pdev->m_copy_id.rx_ppdu_id == ppdu_info->com_info.ppdu_id)
1430*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
1431*5113495bSYour Name 	}
1432*5113495bSYour Name 
1433*5113495bSYour Name 	wh = (struct ieee80211_frame *)(ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload + 4);
1434*5113495bSYour Name 
1435*5113495bSYour Name 	size = (ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload -
1436*5113495bSYour Name 				qdf_nbuf_data(nbuf));
1437*5113495bSYour Name 
1438*5113495bSYour Name 	if (qdf_nbuf_pull_head(nbuf, size) == NULL)
1439*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1440*5113495bSYour Name 
1441*5113495bSYour Name 	if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1442*5113495bSYour Name 	     IEEE80211_FC0_TYPE_MGT) ||
1443*5113495bSYour Name 	     ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1444*5113495bSYour Name 	     IEEE80211_FC0_TYPE_CTL)) {
1445*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1446*5113495bSYour Name 	}
1447*5113495bSYour Name 
1448*5113495bSYour Name 	nbuf_data = (uint32_t *)qdf_nbuf_data(nbuf);
1449*5113495bSYour Name 	*nbuf_data = mon_pdev->ppdu_info.com_info.ppdu_id;
1450*5113495bSYour Name 	/* only retain RX MSDU payload in the skb */
1451*5113495bSYour Name 	qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].payload_len);
1452*5113495bSYour Name 	if (deliver_frame) {
1453*5113495bSYour Name 		mon_pdev->m_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id;
1454*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc,
1455*5113495bSYour Name 				     nbuf, HTT_INVALID_PEER,
1456*5113495bSYour Name 				     WDI_NO_VAL, pdev->pdev_id);
1457*5113495bSYour Name 	}
1458*5113495bSYour Name 	return QDF_STATUS_E_ALREADY;
1459*5113495bSYour Name }
1460*5113495bSYour Name 
1461*5113495bSYour Name void
dp_rx_mcopy_handle_last_mpdu(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,qdf_nbuf_t status_nbuf)1462*5113495bSYour Name dp_rx_mcopy_handle_last_mpdu(struct dp_soc *soc, struct dp_pdev *pdev,
1463*5113495bSYour Name 			     struct hal_rx_ppdu_info *ppdu_info,
1464*5113495bSYour Name 			     qdf_nbuf_t status_nbuf)
1465*5113495bSYour Name {
1466*5113495bSYour Name 	QDF_STATUS mcopy_status;
1467*5113495bSYour Name 	qdf_nbuf_t nbuf_clone = NULL;
1468*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1469*5113495bSYour Name 
1470*5113495bSYour Name 	/* If the MPDU end tlv and RX header are received in different buffers,
1471*5113495bSYour Name 	 * process the RX header based on fcs status.
1472*5113495bSYour Name 	 */
1473*5113495bSYour Name 	if (mon_pdev->mcopy_status_nbuf) {
1474*5113495bSYour Name 		/* For M_COPY mode only one msdu per ppdu is sent to upper layer*/
1475*5113495bSYour Name 		if (mon_pdev->mcopy_mode == M_COPY) {
1476*5113495bSYour Name 			if (mon_pdev->m_copy_id.rx_ppdu_id ==
1477*5113495bSYour Name 			    ppdu_info->com_info.ppdu_id)
1478*5113495bSYour Name 				goto end1;
1479*5113495bSYour Name 		}
1480*5113495bSYour Name 
1481*5113495bSYour Name 		if (ppdu_info->is_fcs_passed) {
1482*5113495bSYour Name 			nbuf_clone = qdf_nbuf_clone(mon_pdev->mcopy_status_nbuf);
1483*5113495bSYour Name 			if (!nbuf_clone) {
1484*5113495bSYour Name 				QDF_TRACE(QDF_MODULE_ID_TXRX,
1485*5113495bSYour Name 					  QDF_TRACE_LEVEL_ERROR,
1486*5113495bSYour Name 					  "Failed to clone nbuf");
1487*5113495bSYour Name 				goto end1;
1488*5113495bSYour Name 			}
1489*5113495bSYour Name 
1490*5113495bSYour Name 			mon_pdev->m_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id;
1491*5113495bSYour Name 			dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc,
1492*5113495bSYour Name 					     nbuf_clone,
1493*5113495bSYour Name 					     HTT_INVALID_PEER,
1494*5113495bSYour Name 					     WDI_NO_VAL, pdev->pdev_id);
1495*5113495bSYour Name 			ppdu_info->is_fcs_passed = false;
1496*5113495bSYour Name 		}
1497*5113495bSYour Name end1:
1498*5113495bSYour Name 		qdf_nbuf_free(mon_pdev->mcopy_status_nbuf);
1499*5113495bSYour Name 		mon_pdev->mcopy_status_nbuf = NULL;
1500*5113495bSYour Name 	}
1501*5113495bSYour Name 
1502*5113495bSYour Name 	/* If the MPDU end tlv and RX header are received in different buffers,
1503*5113495bSYour Name 	 * preserve the RX header as the fcs status will be received in MPDU
1504*5113495bSYour Name 	 * end tlv in next buffer. So, cache the buffer to be processd in next
1505*5113495bSYour Name 	 * iteration
1506*5113495bSYour Name 	 */
1507*5113495bSYour Name 	if ((ppdu_info->fcs_ok_cnt + ppdu_info->fcs_err_cnt) !=
1508*5113495bSYour Name 	    ppdu_info->com_info.mpdu_cnt) {
1509*5113495bSYour Name 		mon_pdev->mcopy_status_nbuf = qdf_nbuf_clone(status_nbuf);
1510*5113495bSYour Name 		if (mon_pdev->mcopy_status_nbuf) {
1511*5113495bSYour Name 			mcopy_status = dp_rx_handle_mcopy_mode(
1512*5113495bSYour Name 							soc, pdev,
1513*5113495bSYour Name 							ppdu_info,
1514*5113495bSYour Name 							mon_pdev->mcopy_status_nbuf,
1515*5113495bSYour Name 							ppdu_info->fcs_ok_cnt,
1516*5113495bSYour Name 							false);
1517*5113495bSYour Name 			if (mcopy_status == QDF_STATUS_SUCCESS) {
1518*5113495bSYour Name 				qdf_nbuf_free(mon_pdev->mcopy_status_nbuf);
1519*5113495bSYour Name 				mon_pdev->mcopy_status_nbuf = NULL;
1520*5113495bSYour Name 			}
1521*5113495bSYour Name 		}
1522*5113495bSYour Name 	}
1523*5113495bSYour Name }
1524*5113495bSYour Name 
1525*5113495bSYour Name void
dp_rx_mcopy_process_ppdu_info(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,uint32_t tlv_status)1526*5113495bSYour Name dp_rx_mcopy_process_ppdu_info(struct dp_pdev *pdev,
1527*5113495bSYour Name 			      struct hal_rx_ppdu_info *ppdu_info,
1528*5113495bSYour Name 			      uint32_t tlv_status)
1529*5113495bSYour Name {
1530*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1531*5113495bSYour Name 
1532*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev->mcopy_mode))
1533*5113495bSYour Name 		return;
1534*5113495bSYour Name 
1535*5113495bSYour Name 	/* The fcs status is received in MPDU end tlv. If the RX header
1536*5113495bSYour Name 	 * and its MPDU end tlv are received in different status buffer then
1537*5113495bSYour Name 	 * to process that header ppdu_info->is_fcs_passed is used.
1538*5113495bSYour Name 	 * If end tlv is received in next status buffer then com_info.mpdu_cnt
1539*5113495bSYour Name 	 * will be 0 at the time of receiving MPDU end tlv and we update the
1540*5113495bSYour Name 	 * is_fcs_passed flag based on ppdu_info->fcs_err.
1541*5113495bSYour Name 	 */
1542*5113495bSYour Name 	if (tlv_status != HAL_TLV_STATUS_MPDU_END)
1543*5113495bSYour Name 		return;
1544*5113495bSYour Name 
1545*5113495bSYour Name 	if (!ppdu_info->fcs_err) {
1546*5113495bSYour Name 		if (ppdu_info->fcs_ok_cnt >
1547*5113495bSYour Name 		    HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER) {
1548*5113495bSYour Name 			dp_err("No. of MPDUs(%d) per status buff exceeded",
1549*5113495bSYour Name 					ppdu_info->fcs_ok_cnt);
1550*5113495bSYour Name 			return;
1551*5113495bSYour Name 		}
1552*5113495bSYour Name 		if (ppdu_info->com_info.mpdu_cnt)
1553*5113495bSYour Name 			ppdu_info->fcs_ok_cnt++;
1554*5113495bSYour Name 		else
1555*5113495bSYour Name 			ppdu_info->is_fcs_passed = true;
1556*5113495bSYour Name 	} else {
1557*5113495bSYour Name 		if (ppdu_info->com_info.mpdu_cnt)
1558*5113495bSYour Name 			ppdu_info->fcs_err_cnt++;
1559*5113495bSYour Name 		else
1560*5113495bSYour Name 			ppdu_info->is_fcs_passed = false;
1561*5113495bSYour Name 	}
1562*5113495bSYour Name }
1563*5113495bSYour Name 
1564*5113495bSYour Name void
dp_rx_process_mcopy_mode(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,uint32_t tlv_status,qdf_nbuf_t status_nbuf)1565*5113495bSYour Name dp_rx_process_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
1566*5113495bSYour Name 			 struct hal_rx_ppdu_info *ppdu_info,
1567*5113495bSYour Name 			 uint32_t tlv_status,
1568*5113495bSYour Name 			 qdf_nbuf_t status_nbuf)
1569*5113495bSYour Name {
1570*5113495bSYour Name 	QDF_STATUS mcopy_status;
1571*5113495bSYour Name 	qdf_nbuf_t nbuf_clone = NULL;
1572*5113495bSYour Name 	uint8_t fcs_ok_mpdu_cnt = 0;
1573*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1574*5113495bSYour Name 
1575*5113495bSYour Name 	dp_rx_mcopy_handle_last_mpdu(soc, pdev, ppdu_info, status_nbuf);
1576*5113495bSYour Name 
1577*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->com_info.mpdu_cnt))
1578*5113495bSYour Name 		goto end;
1579*5113495bSYour Name 
1580*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info->fcs_ok_cnt))
1581*5113495bSYour Name 		goto end;
1582*5113495bSYour Name 
1583*5113495bSYour Name 	/* For M_COPY mode only one msdu per ppdu is sent to upper layer*/
1584*5113495bSYour Name 	if (mon_pdev->mcopy_mode == M_COPY)
1585*5113495bSYour Name 		ppdu_info->fcs_ok_cnt = 1;
1586*5113495bSYour Name 
1587*5113495bSYour Name 	while (fcs_ok_mpdu_cnt < ppdu_info->fcs_ok_cnt) {
1588*5113495bSYour Name 		nbuf_clone = qdf_nbuf_clone(status_nbuf);
1589*5113495bSYour Name 		if (!nbuf_clone) {
1590*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1591*5113495bSYour Name 				  "Failed to clone nbuf");
1592*5113495bSYour Name 			goto end;
1593*5113495bSYour Name 		}
1594*5113495bSYour Name 
1595*5113495bSYour Name 		mcopy_status = dp_rx_handle_mcopy_mode(soc, pdev,
1596*5113495bSYour Name 						       ppdu_info,
1597*5113495bSYour Name 						       nbuf_clone,
1598*5113495bSYour Name 						       fcs_ok_mpdu_cnt,
1599*5113495bSYour Name 						       true);
1600*5113495bSYour Name 
1601*5113495bSYour Name 		if (mcopy_status == QDF_STATUS_SUCCESS)
1602*5113495bSYour Name 			qdf_nbuf_free(nbuf_clone);
1603*5113495bSYour Name 
1604*5113495bSYour Name 		fcs_ok_mpdu_cnt++;
1605*5113495bSYour Name 	}
1606*5113495bSYour Name end:
1607*5113495bSYour Name 	qdf_nbuf_free(status_nbuf);
1608*5113495bSYour Name 	ppdu_info->fcs_ok_cnt = 0;
1609*5113495bSYour Name 	ppdu_info->fcs_err_cnt = 0;
1610*5113495bSYour Name 	ppdu_info->com_info.mpdu_cnt = 0;
1611*5113495bSYour Name 	qdf_mem_zero(&ppdu_info->ppdu_msdu_info,
1612*5113495bSYour Name 		     HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER
1613*5113495bSYour Name 		     * sizeof(struct hal_rx_msdu_payload_info));
1614*5113495bSYour Name }
1615*5113495bSYour Name #endif /* QCA_MCOPY_SUPPORT */
1616*5113495bSYour Name 
1617*5113495bSYour Name int
dp_rx_handle_smart_mesh_mode(struct dp_soc * soc,struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,qdf_nbuf_t nbuf)1618*5113495bSYour Name dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
1619*5113495bSYour Name 			      struct hal_rx_ppdu_info *ppdu_info,
1620*5113495bSYour Name 			      qdf_nbuf_t nbuf)
1621*5113495bSYour Name {
1622*5113495bSYour Name 	uint8_t size = 0;
1623*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
1624*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1625*5113495bSYour Name 
1626*5113495bSYour Name 	if (!mon_pdev->mvdev) {
1627*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1628*5113495bSYour Name 			  "[%s]:[%d] Monitor vdev is NULL !!",
1629*5113495bSYour Name 			  __func__, __LINE__);
1630*5113495bSYour Name 		return 1;
1631*5113495bSYour Name 	}
1632*5113495bSYour Name 
1633*5113495bSYour Name 	mon_vdev = mon_pdev->mvdev->monitor_vdev;
1634*5113495bSYour Name 
1635*5113495bSYour Name 	if (!ppdu_info->msdu_info.first_msdu_payload) {
1636*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1637*5113495bSYour Name 			  "[%s]:[%d] First msdu payload not present",
1638*5113495bSYour Name 			  __func__, __LINE__);
1639*5113495bSYour Name 		return 1;
1640*5113495bSYour Name 	}
1641*5113495bSYour Name 
1642*5113495bSYour Name 	/* Adding 4 bytes to get to start of 802.11 frame after phy_ppdu_id */
1643*5113495bSYour Name 	size = (ppdu_info->msdu_info.first_msdu_payload -
1644*5113495bSYour Name 		qdf_nbuf_data(nbuf)) + 4;
1645*5113495bSYour Name 	ppdu_info->msdu_info.first_msdu_payload = NULL;
1646*5113495bSYour Name 
1647*5113495bSYour Name 	if (!qdf_nbuf_pull_head(nbuf, size)) {
1648*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1649*5113495bSYour Name 			  "[%s]:[%d] No header present",
1650*5113495bSYour Name 			  __func__, __LINE__);
1651*5113495bSYour Name 		return 1;
1652*5113495bSYour Name 	}
1653*5113495bSYour Name 
1654*5113495bSYour Name 	/* Only retain RX MSDU payload in the skb */
1655*5113495bSYour Name 	qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) -
1656*5113495bSYour Name 			   ppdu_info->msdu_info.payload_len);
1657*5113495bSYour Name 	if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, nbuf,
1658*5113495bSYour Name 				      qdf_nbuf_headroom(nbuf))) {
1659*5113495bSYour Name 		DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1);
1660*5113495bSYour Name 		return 1;
1661*5113495bSYour Name 	}
1662*5113495bSYour Name 
1663*5113495bSYour Name 	mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev,
1664*5113495bSYour Name 			      nbuf, NULL);
1665*5113495bSYour Name 	mon_pdev->ppdu_info.rx_status.monitor_direct_used = 0;
1666*5113495bSYour Name 	return 0;
1667*5113495bSYour Name }
1668*5113495bSYour Name 
1669*5113495bSYour Name #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
1670*5113495bSYour Name /**
1671*5113495bSYour Name  * dp_rx_mon_stitch_mpdu() - Stich MPDU from MSDU
1672*5113495bSYour Name  * @mon_pdev: mon_pdev handle
1673*5113495bSYour Name  * @tail: 1st MSDU of next MPDU
1674*5113495bSYour Name  *
1675*5113495bSYour Name  * Return: mpdu buf
1676*5113495bSYour Name  */
1677*5113495bSYour Name static qdf_nbuf_t
dp_rx_mon_stitch_mpdu(struct dp_mon_pdev * mon_pdev,qdf_nbuf_t tail)1678*5113495bSYour Name dp_rx_mon_stitch_mpdu(struct dp_mon_pdev *mon_pdev, qdf_nbuf_t tail)
1679*5113495bSYour Name {
1680*5113495bSYour Name 	qdf_nbuf_t head, nbuf, next;
1681*5113495bSYour Name 	qdf_nbuf_t mpdu_buf = NULL, head_frag_list = NULL;
1682*5113495bSYour Name 	uint32_t is_first_frag, frag_list_sum_len = 0;
1683*5113495bSYour Name 
1684*5113495bSYour Name 	if (!(qdf_nbuf_is_queue_empty(&mon_pdev->msdu_queue))) {
1685*5113495bSYour Name 		head = qdf_nbuf_queue_remove(&mon_pdev->msdu_queue);
1686*5113495bSYour Name 		nbuf = head;
1687*5113495bSYour Name 		mpdu_buf = qdf_nbuf_copy(head);
1688*5113495bSYour Name 		if (qdf_unlikely(!mpdu_buf))
1689*5113495bSYour Name 			goto fail;
1690*5113495bSYour Name 
1691*5113495bSYour Name 		is_first_frag = 1;
1692*5113495bSYour Name 
1693*5113495bSYour Name 		while (nbuf) {
1694*5113495bSYour Name 			/* Find the 1st msdu to append in mpdu_buf->frag_list */
1695*5113495bSYour Name 			if (nbuf != head && is_first_frag) {
1696*5113495bSYour Name 				is_first_frag = 0;
1697*5113495bSYour Name 				head_frag_list  = nbuf;
1698*5113495bSYour Name 			}
1699*5113495bSYour Name 
1700*5113495bSYour Name 			/* calculate frag_list length */
1701*5113495bSYour Name 			if (!is_first_frag)
1702*5113495bSYour Name 				frag_list_sum_len += qdf_nbuf_len(nbuf);
1703*5113495bSYour Name 
1704*5113495bSYour Name 			if (qdf_nbuf_queue_first(&mon_pdev->msdu_queue) == tail)
1705*5113495bSYour Name 				break;
1706*5113495bSYour Name 
1707*5113495bSYour Name 			next = qdf_nbuf_queue_remove(&mon_pdev->msdu_queue);
1708*5113495bSYour Name 			qdf_nbuf_set_next(nbuf, next);
1709*5113495bSYour Name 			nbuf = next;
1710*5113495bSYour Name 		}
1711*5113495bSYour Name 
1712*5113495bSYour Name 		qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list,
1713*5113495bSYour Name 					 frag_list_sum_len);
1714*5113495bSYour Name 		qdf_nbuf_free(head);
1715*5113495bSYour Name 	}
1716*5113495bSYour Name 
1717*5113495bSYour Name 	return mpdu_buf;
1718*5113495bSYour Name 
1719*5113495bSYour Name fail:
1720*5113495bSYour Name 	dp_err_rl("nbuf copy failed len: %d Q1: %d Q2: %d", qdf_nbuf_len(nbuf),
1721*5113495bSYour Name 		  qdf_nbuf_queue_len(&mon_pdev->msdu_queue),
1722*5113495bSYour Name 		  qdf_nbuf_queue_len(&mon_pdev->mpdu_queue));
1723*5113495bSYour Name 
1724*5113495bSYour Name 	/* Drop all MSDU of MPDU */
1725*5113495bSYour Name 	while (nbuf) {
1726*5113495bSYour Name 		qdf_nbuf_free(nbuf);
1727*5113495bSYour Name 		if (qdf_nbuf_queue_first(&mon_pdev->msdu_queue) == tail)
1728*5113495bSYour Name 			break;
1729*5113495bSYour Name 		nbuf = qdf_nbuf_queue_remove(&mon_pdev->msdu_queue);
1730*5113495bSYour Name 	}
1731*5113495bSYour Name 
1732*5113495bSYour Name 	return NULL;
1733*5113495bSYour Name }
1734*5113495bSYour Name 
1735*5113495bSYour Name /**
1736*5113495bSYour Name  * dp_rx_mon_send_mpdu() - Send MPDU to stack
1737*5113495bSYour Name  * @pdev: DP pdev handle
1738*5113495bSYour Name  * @mon_pdev: mon_pdev handle
1739*5113495bSYour Name  * @mpdu_buf: buffer to submit
1740*5113495bSYour Name  *
1741*5113495bSYour Name  * Return: None
1742*5113495bSYour Name  */
1743*5113495bSYour Name static inline void
dp_rx_mon_send_mpdu(struct dp_pdev * pdev,struct dp_mon_pdev * mon_pdev,qdf_nbuf_t mpdu_buf)1744*5113495bSYour Name dp_rx_mon_send_mpdu(struct dp_pdev *pdev, struct dp_mon_pdev *mon_pdev,
1745*5113495bSYour Name 		    qdf_nbuf_t mpdu_buf)
1746*5113495bSYour Name {
1747*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
1748*5113495bSYour Name 
1749*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev->mvdev)) {
1750*5113495bSYour Name 		dp_info_rl("Monitor vdev is NULL !!");
1751*5113495bSYour Name 		qdf_nbuf_free(mpdu_buf);
1752*5113495bSYour Name 		return;
1753*5113495bSYour Name 	}
1754*5113495bSYour Name 
1755*5113495bSYour Name 	mon_pdev->ppdu_info.rx_status.ppdu_id =
1756*5113495bSYour Name 			mon_pdev->ppdu_info.com_info.ppdu_id;
1757*5113495bSYour Name 	mon_pdev->ppdu_info.rx_status.device_id = pdev->soc->device_id;
1758*5113495bSYour Name 	mon_pdev->ppdu_info.rx_status.chan_noise_floor =
1759*5113495bSYour Name 			pdev->chan_noise_floor;
1760*5113495bSYour Name 
1761*5113495bSYour Name 	if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, mpdu_buf,
1762*5113495bSYour Name 				      qdf_nbuf_headroom(mpdu_buf))) {
1763*5113495bSYour Name 		DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1);
1764*5113495bSYour Name 		qdf_nbuf_free(mpdu_buf);
1765*5113495bSYour Name 		dp_err("radiotap_update_err");
1766*5113495bSYour Name 		return;
1767*5113495bSYour Name 	}
1768*5113495bSYour Name 
1769*5113495bSYour Name 	mon_vdev = mon_pdev->mvdev->monitor_vdev;
1770*5113495bSYour Name 	if (qdf_likely(mon_vdev && mon_vdev->osif_rx_mon))
1771*5113495bSYour Name 		mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev,
1772*5113495bSYour Name 				      mpdu_buf, NULL);
1773*5113495bSYour Name 	else
1774*5113495bSYour Name 		qdf_nbuf_free(mpdu_buf);
1775*5113495bSYour Name }
1776*5113495bSYour Name 
dp_rx_handle_local_pkt_capture(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info,qdf_nbuf_t nbuf,uint32_t tlv_status)1777*5113495bSYour Name int dp_rx_handle_local_pkt_capture(struct dp_pdev *pdev,
1778*5113495bSYour Name 				   struct hal_rx_ppdu_info *ppdu_info,
1779*5113495bSYour Name 				   qdf_nbuf_t nbuf, uint32_t tlv_status)
1780*5113495bSYour Name {
1781*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1782*5113495bSYour Name 	qdf_nbuf_t buf, last;
1783*5113495bSYour Name 	uint16_t size;
1784*5113495bSYour Name 
1785*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->lpc_lock);
1786*5113495bSYour Name 	switch (tlv_status) {
1787*5113495bSYour Name 	case HAL_TLV_STATUS_MPDU_START:
1788*5113495bSYour Name 	{
1789*5113495bSYour Name 		/* Only Add MPDU to queue if multiple MPDUs present in PPDU */
1790*5113495bSYour Name 		if (qdf_unlikely(mon_pdev->first_mpdu)) {
1791*5113495bSYour Name 			mon_pdev->first_mpdu = false;
1792*5113495bSYour Name 			break;
1793*5113495bSYour Name 		}
1794*5113495bSYour Name 
1795*5113495bSYour Name 		/* last nbuf of queue points to 1st MSDU of next MPDU */
1796*5113495bSYour Name 		last = qdf_nbuf_queue_last(&mon_pdev->msdu_queue);
1797*5113495bSYour Name 		buf = dp_rx_mon_stitch_mpdu(mon_pdev, last);
1798*5113495bSYour Name 		/* Add MPDU to queue */
1799*5113495bSYour Name 		if (qdf_likely(buf))
1800*5113495bSYour Name 			qdf_nbuf_queue_add(&mon_pdev->mpdu_queue, buf);
1801*5113495bSYour Name 		break;
1802*5113495bSYour Name 	}
1803*5113495bSYour Name 
1804*5113495bSYour Name 	case HAL_TLV_STATUS_HEADER:
1805*5113495bSYour Name 	{
1806*5113495bSYour Name 		buf = qdf_nbuf_clone(nbuf);
1807*5113495bSYour Name 		if (qdf_unlikely(!buf))
1808*5113495bSYour Name 			break;
1809*5113495bSYour Name 
1810*5113495bSYour Name 		/* Adding 8 bytes to get to start of 802.11 frame
1811*5113495bSYour Name 		 * after phy_ppdu_id
1812*5113495bSYour Name 		 */
1813*5113495bSYour Name 		size = (ppdu_info->msdu_info.first_msdu_payload -
1814*5113495bSYour Name 			qdf_nbuf_data(buf)) + mon_pdev->phy_ppdu_id_size;
1815*5113495bSYour Name 
1816*5113495bSYour Name 		if (qdf_unlikely(!qdf_nbuf_pull_head(buf, size))) {
1817*5113495bSYour Name 			qdf_nbuf_free(buf);
1818*5113495bSYour Name 			dp_info("No header present");
1819*5113495bSYour Name 			break;
1820*5113495bSYour Name 		}
1821*5113495bSYour Name 
1822*5113495bSYour Name 		/* Only retain RX MSDU payload in the skb */
1823*5113495bSYour Name 		qdf_nbuf_trim_tail(buf, qdf_nbuf_len(buf) -
1824*5113495bSYour Name 				ppdu_info->msdu_info.payload_len +
1825*5113495bSYour Name 				mon_pdev->phy_ppdu_id_size);
1826*5113495bSYour Name 
1827*5113495bSYour Name 		/* Add MSDU to Queue */
1828*5113495bSYour Name 		qdf_nbuf_queue_add(&mon_pdev->msdu_queue, buf);
1829*5113495bSYour Name 		break;
1830*5113495bSYour Name 	}
1831*5113495bSYour Name 
1832*5113495bSYour Name 	case HAL_TLV_STATUS_PPDU_DONE:
1833*5113495bSYour Name 	{
1834*5113495bSYour Name 		while ((buf = qdf_nbuf_queue_remove(&mon_pdev->mpdu_queue)))
1835*5113495bSYour Name 			dp_rx_mon_send_mpdu(pdev, mon_pdev, buf);
1836*5113495bSYour Name 
1837*5113495bSYour Name 		/* Stich and send Last MPDU of PPDU */
1838*5113495bSYour Name 		buf = dp_rx_mon_stitch_mpdu(mon_pdev, NULL);
1839*5113495bSYour Name 		if (buf)
1840*5113495bSYour Name 			dp_rx_mon_send_mpdu(pdev, mon_pdev, buf);
1841*5113495bSYour Name 
1842*5113495bSYour Name 		mon_pdev->first_mpdu = true;
1843*5113495bSYour Name 		break;
1844*5113495bSYour Name 	}
1845*5113495bSYour Name 
1846*5113495bSYour Name 	default:
1847*5113495bSYour Name 		break;
1848*5113495bSYour Name 	}
1849*5113495bSYour Name 
1850*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->lpc_lock);
1851*5113495bSYour Name 
1852*5113495bSYour Name 	return 0;
1853*5113495bSYour Name }
1854*5113495bSYour Name #endif
1855*5113495bSYour Name 
1856*5113495bSYour Name qdf_nbuf_t
dp_rx_nbuf_prepare(struct dp_soc * soc,struct dp_pdev * pdev)1857*5113495bSYour Name dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev)
1858*5113495bSYour Name {
1859*5113495bSYour Name 	uint8_t *buf;
1860*5113495bSYour Name 	int32_t nbuf_retry_count;
1861*5113495bSYour Name 	QDF_STATUS ret;
1862*5113495bSYour Name 	qdf_nbuf_t nbuf = NULL;
1863*5113495bSYour Name 
1864*5113495bSYour Name 	for (nbuf_retry_count = 0; nbuf_retry_count <
1865*5113495bSYour Name 		QDF_NBUF_ALLOC_MAP_RETRY_THRESHOLD;
1866*5113495bSYour Name 			nbuf_retry_count++) {
1867*5113495bSYour Name 		/* Allocate a new skb using alloc_skb */
1868*5113495bSYour Name 		nbuf = qdf_nbuf_alloc_no_recycler(RX_MON_STATUS_BUF_SIZE,
1869*5113495bSYour Name 						  RX_MON_STATUS_BUF_RESERVATION,
1870*5113495bSYour Name 						  RX_DATA_BUFFER_ALIGNMENT);
1871*5113495bSYour Name 
1872*5113495bSYour Name 		if (!nbuf) {
1873*5113495bSYour Name 			DP_STATS_INC(pdev, replenish.nbuf_alloc_fail, 1);
1874*5113495bSYour Name 			continue;
1875*5113495bSYour Name 		}
1876*5113495bSYour Name 
1877*5113495bSYour Name 		buf = qdf_nbuf_data(nbuf);
1878*5113495bSYour Name 
1879*5113495bSYour Name 		memset(buf, 0, RX_MON_STATUS_BUF_SIZE);
1880*5113495bSYour Name 
1881*5113495bSYour Name 		ret = qdf_nbuf_map_nbytes_single(soc->osdev, nbuf,
1882*5113495bSYour Name 						 QDF_DMA_FROM_DEVICE,
1883*5113495bSYour Name 						 RX_MON_STATUS_BUF_SIZE);
1884*5113495bSYour Name 
1885*5113495bSYour Name 		/* nbuf map failed */
1886*5113495bSYour Name 		if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret))) {
1887*5113495bSYour Name 			qdf_nbuf_free(nbuf);
1888*5113495bSYour Name 			DP_STATS_INC(pdev, replenish.map_err, 1);
1889*5113495bSYour Name 			continue;
1890*5113495bSYour Name 		}
1891*5113495bSYour Name 		/* qdf_nbuf alloc and map succeeded */
1892*5113495bSYour Name 		break;
1893*5113495bSYour Name 	}
1894*5113495bSYour Name 
1895*5113495bSYour Name 	/* qdf_nbuf still alloc or map failed */
1896*5113495bSYour Name 	if (qdf_unlikely(nbuf_retry_count >=
1897*5113495bSYour Name 			QDF_NBUF_ALLOC_MAP_RETRY_THRESHOLD))
1898*5113495bSYour Name 		return NULL;
1899*5113495bSYour Name 
1900*5113495bSYour Name 	return nbuf;
1901*5113495bSYour Name }
1902*5113495bSYour Name 
1903*5113495bSYour Name #ifndef DISABLE_MON_CONFIG
1904*5113495bSYour Name uint32_t
dp_mon_process(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)1905*5113495bSYour Name dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
1906*5113495bSYour Name 	       uint32_t mac_id, uint32_t quota)
1907*5113495bSYour Name {
1908*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1909*5113495bSYour Name 
1910*5113495bSYour Name 	if (mon_soc && mon_soc->mon_rx_process)
1911*5113495bSYour Name 		return mon_soc->mon_rx_process(soc, int_ctx,
1912*5113495bSYour Name 					       mac_id, quota);
1913*5113495bSYour Name 	return 0;
1914*5113495bSYour Name }
1915*5113495bSYour Name #else
1916*5113495bSYour Name uint32_t
dp_mon_process(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)1917*5113495bSYour Name dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
1918*5113495bSYour Name 	       uint32_t mac_id, uint32_t quota)
1919*5113495bSYour Name {
1920*5113495bSYour Name 	return 0;
1921*5113495bSYour Name }
1922*5113495bSYour Name #endif
1923*5113495bSYour Name 
1924*5113495bSYour Name /**
1925*5113495bSYour Name  * dp_send_mgmt_packet_to_stack(): send indicataion to upper layers
1926*5113495bSYour Name  *
1927*5113495bSYour Name  * @soc: soc handle
1928*5113495bSYour Name  * @nbuf: Mgmt packet
1929*5113495bSYour Name  * @pdev: pdev handle
1930*5113495bSYour Name  *
1931*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success
1932*5113495bSYour Name  *         QDF_STATUS_E_INVAL in error
1933*5113495bSYour Name  */
1934*5113495bSYour Name #ifdef QCA_MCOPY_SUPPORT
1935*5113495bSYour Name static inline QDF_STATUS
dp_send_mgmt_packet_to_stack(struct dp_soc * soc,qdf_nbuf_t nbuf,struct dp_pdev * pdev)1936*5113495bSYour Name dp_send_mgmt_packet_to_stack(struct dp_soc *soc,
1937*5113495bSYour Name 			     qdf_nbuf_t nbuf,
1938*5113495bSYour Name 			     struct dp_pdev *pdev)
1939*5113495bSYour Name {
1940*5113495bSYour Name 	uint32_t *nbuf_data;
1941*5113495bSYour Name 	struct ieee80211_frame *wh;
1942*5113495bSYour Name 	qdf_frag_t addr;
1943*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1944*5113495bSYour Name 
1945*5113495bSYour Name 	if (!nbuf)
1946*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1947*5113495bSYour Name 
1948*5113495bSYour Name 	/* Get addr pointing to80211 header */
1949*5113495bSYour Name 	addr = dp_rx_mon_get_nbuf_80211_hdr(nbuf);
1950*5113495bSYour Name 	if (qdf_unlikely(!addr)) {
1951*5113495bSYour Name 		qdf_nbuf_free(nbuf);
1952*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1953*5113495bSYour Name 	}
1954*5113495bSYour Name 
1955*5113495bSYour Name 	/*check if this is not a mgmt packet*/
1956*5113495bSYour Name 	wh = (struct ieee80211_frame *)addr;
1957*5113495bSYour Name 	if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
1958*5113495bSYour Name 	     IEEE80211_FC0_TYPE_MGT) &&
1959*5113495bSYour Name 	     ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
1960*5113495bSYour Name 	     IEEE80211_FC0_TYPE_CTL)) {
1961*5113495bSYour Name 		qdf_nbuf_free(nbuf);
1962*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1963*5113495bSYour Name 	}
1964*5113495bSYour Name 	nbuf_data = (uint32_t *)qdf_nbuf_push_head(nbuf, 4);
1965*5113495bSYour Name 	if (!nbuf_data) {
1966*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_DP,
1967*5113495bSYour Name 			  QDF_TRACE_LEVEL_ERROR,
1968*5113495bSYour Name 			  FL("No headroom"));
1969*5113495bSYour Name 		qdf_nbuf_free(nbuf);
1970*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1971*5113495bSYour Name 	}
1972*5113495bSYour Name 	*nbuf_data = mon_pdev->ppdu_info.com_info.ppdu_id;
1973*5113495bSYour Name 
1974*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_RX_MGMT_CTRL, soc, nbuf,
1975*5113495bSYour Name 			     HTT_INVALID_PEER,
1976*5113495bSYour Name 			     WDI_NO_VAL, pdev->pdev_id);
1977*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1978*5113495bSYour Name }
1979*5113495bSYour Name #else
1980*5113495bSYour Name static inline QDF_STATUS
dp_send_mgmt_packet_to_stack(struct dp_soc * soc,qdf_nbuf_t nbuf,struct dp_pdev * pdev)1981*5113495bSYour Name dp_send_mgmt_packet_to_stack(struct dp_soc *soc,
1982*5113495bSYour Name 			     qdf_nbuf_t nbuf,
1983*5113495bSYour Name 			     struct dp_pdev *pdev)
1984*5113495bSYour Name {
1985*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1986*5113495bSYour Name }
1987*5113495bSYour Name #endif /* QCA_MCOPY_SUPPORT */
1988*5113495bSYour Name 
dp_rx_mon_process_dest_pktlog(struct dp_soc * soc,uint32_t mac_id,qdf_nbuf_t mpdu)1989*5113495bSYour Name QDF_STATUS dp_rx_mon_process_dest_pktlog(struct dp_soc *soc,
1990*5113495bSYour Name 					 uint32_t mac_id,
1991*5113495bSYour Name 					 qdf_nbuf_t mpdu)
1992*5113495bSYour Name {
1993*5113495bSYour Name 	uint32_t event, msdu_timestamp = 0;
1994*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
1995*5113495bSYour Name 	void *data;
1996*5113495bSYour Name 	struct ieee80211_frame *wh;
1997*5113495bSYour Name 	uint8_t type, subtype;
1998*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1999*5113495bSYour Name 
2000*5113495bSYour Name 	if (!pdev)
2001*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2002*5113495bSYour Name 
2003*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
2004*5113495bSYour Name 
2005*5113495bSYour Name 	if (mon_pdev->rx_pktlog_cbf) {
2006*5113495bSYour Name 		if (qdf_nbuf_get_nr_frags(mpdu))
2007*5113495bSYour Name 			data = qdf_nbuf_get_frag_addr(mpdu, 0);
2008*5113495bSYour Name 		else
2009*5113495bSYour Name 			data = qdf_nbuf_data(mpdu);
2010*5113495bSYour Name 
2011*5113495bSYour Name 		/* CBF logging required, doesn't matter if it is a full mode
2012*5113495bSYour Name 		 * or lite mode.
2013*5113495bSYour Name 		 * Need to look for mpdu with:
2014*5113495bSYour Name 		 * TYPE = ACTION, SUBTYPE = NO ACK in the header
2015*5113495bSYour Name 		 */
2016*5113495bSYour Name 		event = WDI_EVENT_RX_CBF;
2017*5113495bSYour Name 
2018*5113495bSYour Name 		wh = (struct ieee80211_frame *)data;
2019*5113495bSYour Name 		type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2020*5113495bSYour Name 		subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2021*5113495bSYour Name 		if (type == IEEE80211_FC0_TYPE_MGT &&
2022*5113495bSYour Name 		    subtype == IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK) {
2023*5113495bSYour Name 			msdu_timestamp = mon_pdev->ppdu_info.rx_status.tsft;
2024*5113495bSYour Name 			dp_rx_populate_cbf_hdr(soc,
2025*5113495bSYour Name 					       mac_id, event,
2026*5113495bSYour Name 					       mpdu,
2027*5113495bSYour Name 					       msdu_timestamp);
2028*5113495bSYour Name 		}
2029*5113495bSYour Name 	}
2030*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2031*5113495bSYour Name }
2032*5113495bSYour Name 
dp_rx_mon_deliver(struct dp_soc * soc,uint32_t mac_id,qdf_nbuf_t head_msdu,qdf_nbuf_t tail_msdu)2033*5113495bSYour Name QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
2034*5113495bSYour Name 			     qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu)
2035*5113495bSYour Name {
2036*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
2037*5113495bSYour Name 	struct cdp_mon_status *rs;
2038*5113495bSYour Name 	qdf_nbuf_t mon_skb, skb_next;
2039*5113495bSYour Name 	qdf_nbuf_t mon_mpdu = NULL;
2040*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
2041*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
2042*5113495bSYour Name 
2043*5113495bSYour Name 	if (!pdev)
2044*5113495bSYour Name 		goto mon_deliver_fail;
2045*5113495bSYour Name 
2046*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
2047*5113495bSYour Name 	rs = &mon_pdev->rx_mon_recv_status;
2048*5113495bSYour Name 
2049*5113495bSYour Name 	if (!mon_pdev->mvdev && !mon_pdev->mcopy_mode &&
2050*5113495bSYour Name 	    !mon_pdev->rx_pktlog_cbf)
2051*5113495bSYour Name 		goto mon_deliver_fail;
2052*5113495bSYour Name 
2053*5113495bSYour Name 	/* restitch mon MPDU for delivery via monitor interface */
2054*5113495bSYour Name 	mon_mpdu = dp_rx_mon_restitch_mpdu(soc, mac_id, head_msdu,
2055*5113495bSYour Name 					   tail_msdu, rs);
2056*5113495bSYour Name 
2057*5113495bSYour Name 	/* If MPDU restitch fails, free buffers*/
2058*5113495bSYour Name 	if (!mon_mpdu) {
2059*5113495bSYour Name 		dp_info("MPDU restitch failed, free buffers");
2060*5113495bSYour Name 		goto mon_deliver_fail;
2061*5113495bSYour Name 	}
2062*5113495bSYour Name 
2063*5113495bSYour Name 	dp_rx_mon_process_dest_pktlog(soc, mac_id, mon_mpdu);
2064*5113495bSYour Name 
2065*5113495bSYour Name 	/* monitor vap cannot be present when mcopy is enabled
2066*5113495bSYour Name 	 * hence same skb can be consumed
2067*5113495bSYour Name 	 */
2068*5113495bSYour Name 	if (mon_pdev->mcopy_mode)
2069*5113495bSYour Name 		return dp_send_mgmt_packet_to_stack(soc, mon_mpdu, pdev);
2070*5113495bSYour Name 
2071*5113495bSYour Name 	if (mon_pdev->mvdev &&
2072*5113495bSYour Name 	    mon_pdev->mvdev->osif_vdev &&
2073*5113495bSYour Name 	    mon_pdev->mvdev->monitor_vdev &&
2074*5113495bSYour Name 	    mon_pdev->mvdev->monitor_vdev->osif_rx_mon) {
2075*5113495bSYour Name 		mon_vdev = mon_pdev->mvdev->monitor_vdev;
2076*5113495bSYour Name 
2077*5113495bSYour Name 		mon_pdev->ppdu_info.rx_status.ppdu_id =
2078*5113495bSYour Name 			mon_pdev->ppdu_info.com_info.ppdu_id;
2079*5113495bSYour Name 		mon_pdev->ppdu_info.rx_status.device_id = soc->device_id;
2080*5113495bSYour Name 		mon_pdev->ppdu_info.rx_status.chan_noise_floor =
2081*5113495bSYour Name 			pdev->chan_noise_floor;
2082*5113495bSYour Name 		dp_handle_tx_capture(soc, pdev, mon_mpdu);
2083*5113495bSYour Name 
2084*5113495bSYour Name 		if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status,
2085*5113495bSYour Name 					      mon_mpdu,
2086*5113495bSYour Name 					      qdf_nbuf_headroom(mon_mpdu))) {
2087*5113495bSYour Name 			DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1);
2088*5113495bSYour Name 			qdf_nbuf_free(mon_mpdu);
2089*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2090*5113495bSYour Name 		}
2091*5113495bSYour Name 
2092*5113495bSYour Name 		dp_rx_mon_update_pf_tag_to_buf_headroom(soc, mon_mpdu);
2093*5113495bSYour Name 		mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev,
2094*5113495bSYour Name 				      mon_mpdu,
2095*5113495bSYour Name 				      &mon_pdev->ppdu_info.rx_status);
2096*5113495bSYour Name 	} else {
2097*5113495bSYour Name 		dp_rx_mon_dest_debug("%pK: mon_mpdu=%pK monitor_vdev %pK osif_vdev %pK"
2098*5113495bSYour Name 				     , soc, mon_mpdu, mon_pdev->mvdev,
2099*5113495bSYour Name 				     (mon_pdev->mvdev ? mon_pdev->mvdev->osif_vdev
2100*5113495bSYour Name 				     : NULL));
2101*5113495bSYour Name 		qdf_nbuf_free(mon_mpdu);
2102*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2103*5113495bSYour Name 	}
2104*5113495bSYour Name 
2105*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2106*5113495bSYour Name 
2107*5113495bSYour Name mon_deliver_fail:
2108*5113495bSYour Name 	mon_skb = head_msdu;
2109*5113495bSYour Name 	while (mon_skb) {
2110*5113495bSYour Name 		skb_next = qdf_nbuf_next(mon_skb);
2111*5113495bSYour Name 
2112*5113495bSYour Name 		 dp_rx_mon_dest_debug("%pK: [%s][%d] mon_skb=%pK len %u",
2113*5113495bSYour Name 				      soc,  __func__, __LINE__, mon_skb, mon_skb->len);
2114*5113495bSYour Name 
2115*5113495bSYour Name 		qdf_nbuf_free(mon_skb);
2116*5113495bSYour Name 		mon_skb = skb_next;
2117*5113495bSYour Name 	}
2118*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
2119*5113495bSYour Name }
2120*5113495bSYour Name 
dp_rx_mon_deliver_non_std(struct dp_soc * soc,uint32_t mac_id)2121*5113495bSYour Name QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc,
2122*5113495bSYour Name 				     uint32_t mac_id)
2123*5113495bSYour Name {
2124*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
2125*5113495bSYour Name 	ol_txrx_rx_mon_fp osif_rx_mon;
2126*5113495bSYour Name 	qdf_nbuf_t dummy_msdu;
2127*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
2128*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
2129*5113495bSYour Name 
2130*5113495bSYour Name 	/* Sanity checking */
2131*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev)
2132*5113495bSYour Name 		goto mon_deliver_non_std_fail;
2133*5113495bSYour Name 
2134*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
2135*5113495bSYour Name 
2136*5113495bSYour Name 	if (!mon_pdev->mvdev || !mon_pdev->mvdev ||
2137*5113495bSYour Name 	    !mon_pdev->mvdev->monitor_vdev ||
2138*5113495bSYour Name 	    !mon_pdev->mvdev->monitor_vdev->osif_rx_mon)
2139*5113495bSYour Name 		goto mon_deliver_non_std_fail;
2140*5113495bSYour Name 
2141*5113495bSYour Name 	mon_vdev = mon_pdev->mvdev->monitor_vdev;
2142*5113495bSYour Name 	/* Generate a dummy skb_buff */
2143*5113495bSYour Name 	osif_rx_mon = mon_vdev->osif_rx_mon;
2144*5113495bSYour Name 	dummy_msdu = qdf_nbuf_alloc(soc->osdev, MAX_MONITOR_HEADER,
2145*5113495bSYour Name 				    MAX_MONITOR_HEADER, 4, FALSE);
2146*5113495bSYour Name 	if (!dummy_msdu)
2147*5113495bSYour Name 		goto allocate_dummy_msdu_fail;
2148*5113495bSYour Name 
2149*5113495bSYour Name 	qdf_nbuf_set_pktlen(dummy_msdu, 0);
2150*5113495bSYour Name 	qdf_nbuf_set_next(dummy_msdu, NULL);
2151*5113495bSYour Name 
2152*5113495bSYour Name 	mon_pdev->ppdu_info.rx_status.ppdu_id =
2153*5113495bSYour Name 		mon_pdev->ppdu_info.com_info.ppdu_id;
2154*5113495bSYour Name 
2155*5113495bSYour Name 	/* Apply the radio header to this dummy skb */
2156*5113495bSYour Name 	if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, dummy_msdu,
2157*5113495bSYour Name 				      qdf_nbuf_headroom(dummy_msdu))) {
2158*5113495bSYour Name 		DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1);
2159*5113495bSYour Name 		qdf_nbuf_free(dummy_msdu);
2160*5113495bSYour Name 		goto mon_deliver_non_std_fail;
2161*5113495bSYour Name 	}
2162*5113495bSYour Name 
2163*5113495bSYour Name 	/* deliver to the user layer application */
2164*5113495bSYour Name 	osif_rx_mon(mon_pdev->mvdev->osif_vdev,
2165*5113495bSYour Name 		    dummy_msdu, NULL);
2166*5113495bSYour Name 
2167*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2168*5113495bSYour Name 
2169*5113495bSYour Name allocate_dummy_msdu_fail:
2170*5113495bSYour Name 		 dp_rx_mon_dest_debug("%pK: mon_skb=%pK ",
2171*5113495bSYour Name 				      soc, dummy_msdu);
2172*5113495bSYour Name 
2173*5113495bSYour Name mon_deliver_non_std_fail:
2174*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
2175*5113495bSYour Name }
2176*5113495bSYour Name 
2177*5113495bSYour Name /**
2178*5113495bSYour Name  * dp_rx_process_peer_based_pktlog() - Process Rx pktlog if peer based
2179*5113495bSYour Name  *                                     filtering enabled
2180*5113495bSYour Name  * @soc: core txrx main context
2181*5113495bSYour Name  * @ppdu_info: Structure for rx ppdu info
2182*5113495bSYour Name  * @status_nbuf: Qdf nbuf abstraction for linux skb
2183*5113495bSYour Name  * @pdev_id: mac_id/pdev_id correspondinggly for MCL and WIN
2184*5113495bSYour Name  *
2185*5113495bSYour Name  * Return: none
2186*5113495bSYour Name  */
2187*5113495bSYour Name void
dp_rx_process_peer_based_pktlog(struct dp_soc * soc,struct hal_rx_ppdu_info * ppdu_info,qdf_nbuf_t status_nbuf,uint32_t pdev_id)2188*5113495bSYour Name dp_rx_process_peer_based_pktlog(struct dp_soc *soc,
2189*5113495bSYour Name 				struct hal_rx_ppdu_info *ppdu_info,
2190*5113495bSYour Name 				qdf_nbuf_t status_nbuf, uint32_t pdev_id)
2191*5113495bSYour Name {
2192*5113495bSYour Name 	struct dp_peer *peer;
2193*5113495bSYour Name 	struct mon_rx_user_status *rx_user_status;
2194*5113495bSYour Name 	uint32_t num_users = ppdu_info->com_info.num_users;
2195*5113495bSYour Name 	uint16_t sw_peer_id;
2196*5113495bSYour Name 
2197*5113495bSYour Name 	/* Sanity check for num_users */
2198*5113495bSYour Name 	if (!num_users)
2199*5113495bSYour Name 		return;
2200*5113495bSYour Name 
2201*5113495bSYour Name 	qdf_assert_always(num_users <= CDP_MU_MAX_USERS);
2202*5113495bSYour Name 	rx_user_status = &ppdu_info->rx_user_status[num_users - 1];
2203*5113495bSYour Name 
2204*5113495bSYour Name 	sw_peer_id = rx_user_status->sw_peer_id;
2205*5113495bSYour Name 
2206*5113495bSYour Name 	peer = dp_peer_get_ref_by_id(soc, sw_peer_id,
2207*5113495bSYour Name 				     DP_MOD_ID_RX_PPDU_STATS);
2208*5113495bSYour Name 
2209*5113495bSYour Name 	if (!peer)
2210*5113495bSYour Name 		return;
2211*5113495bSYour Name 
2212*5113495bSYour Name 	if ((peer->peer_id != HTT_INVALID_PEER) && (peer->monitor_peer) &&
2213*5113495bSYour Name 	    (peer->monitor_peer->peer_based_pktlog_filter)) {
2214*5113495bSYour Name 		dp_wdi_event_handler(
2215*5113495bSYour Name 				     WDI_EVENT_RX_DESC, soc,
2216*5113495bSYour Name 				     status_nbuf,
2217*5113495bSYour Name 				     peer->peer_id,
2218*5113495bSYour Name 				     WDI_NO_VAL, pdev_id);
2219*5113495bSYour Name 	}
2220*5113495bSYour Name 	dp_peer_unref_delete(peer,
2221*5113495bSYour Name 			     DP_MOD_ID_RX_PPDU_STATS);
2222*5113495bSYour Name }
2223*5113495bSYour Name 
2224*5113495bSYour Name uint32_t
dp_mon_rx_add_tlv(uint8_t id,uint16_t len,void * value,qdf_nbuf_t mpdu_nbuf)2225*5113495bSYour Name dp_mon_rx_add_tlv(uint8_t id, uint16_t len, void *value, qdf_nbuf_t mpdu_nbuf)
2226*5113495bSYour Name {
2227*5113495bSYour Name 	uint8_t *dest = NULL;
2228*5113495bSYour Name 	uint32_t num_bytes_pushed = 0;
2229*5113495bSYour Name 
2230*5113495bSYour Name 	/* Add tlv id field */
2231*5113495bSYour Name 	dest = qdf_nbuf_push_head(mpdu_nbuf, sizeof(uint8_t));
2232*5113495bSYour Name 	if (qdf_likely(dest)) {
2233*5113495bSYour Name 		*((uint8_t *)dest) = id;
2234*5113495bSYour Name 		num_bytes_pushed += sizeof(uint8_t);
2235*5113495bSYour Name 	}
2236*5113495bSYour Name 
2237*5113495bSYour Name 	/* Add tlv len field */
2238*5113495bSYour Name 	dest = qdf_nbuf_push_head(mpdu_nbuf, sizeof(uint16_t));
2239*5113495bSYour Name 	if (qdf_likely(dest)) {
2240*5113495bSYour Name 		*((uint16_t *)dest) = len;
2241*5113495bSYour Name 		num_bytes_pushed += sizeof(uint16_t);
2242*5113495bSYour Name 	}
2243*5113495bSYour Name 
2244*5113495bSYour Name 	/* Add tlv value field */
2245*5113495bSYour Name 	dest = qdf_nbuf_push_head(mpdu_nbuf, len);
2246*5113495bSYour Name 	if (qdf_likely(dest)) {
2247*5113495bSYour Name 		qdf_mem_copy(dest, value, len);
2248*5113495bSYour Name 		num_bytes_pushed += len;
2249*5113495bSYour Name 	}
2250*5113495bSYour Name 
2251*5113495bSYour Name 	return num_bytes_pushed;
2252*5113495bSYour Name }
2253*5113495bSYour Name 
2254*5113495bSYour Name void
dp_mon_rx_stats_update_rssi_dbm_params(struct dp_mon_pdev * mon_pdev,struct hal_rx_ppdu_info * ppdu_info)2255*5113495bSYour Name dp_mon_rx_stats_update_rssi_dbm_params(struct dp_mon_pdev *mon_pdev,
2256*5113495bSYour Name 				       struct hal_rx_ppdu_info *ppdu_info)
2257*5113495bSYour Name {
2258*5113495bSYour Name 	ppdu_info->rx_status.rssi_offset = mon_pdev->rssi_offsets.rssi_offset;
2259*5113495bSYour Name 	ppdu_info->rx_status.rssi_dbm_conv_support =
2260*5113495bSYour Name 				mon_pdev->rssi_dbm_conv_support;
2261*5113495bSYour Name 	ppdu_info->rx_status.chan_noise_floor =
2262*5113495bSYour Name 		mon_pdev->rssi_offsets.rssi_offset;
2263*5113495bSYour Name }
2264*5113495bSYour Name 
2265*5113495bSYour Name #ifdef WLAN_SUPPORT_CTRL_FRAME_STATS
dp_rx_mon_update_user_ctrl_frame_stats(struct dp_pdev * pdev,struct hal_rx_ppdu_info * ppdu_info)2266*5113495bSYour Name void dp_rx_mon_update_user_ctrl_frame_stats(struct dp_pdev *pdev,
2267*5113495bSYour Name 					    struct hal_rx_ppdu_info *ppdu_info)
2268*5113495bSYour Name {
2269*5113495bSYour Name 	struct dp_peer *peer;
2270*5113495bSYour Name 	struct dp_mon_peer *mon_peer;
2271*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2272*5113495bSYour Name 	uint16_t fc, sw_peer_id;
2273*5113495bSYour Name 	uint8_t i;
2274*5113495bSYour Name 
2275*5113495bSYour Name 	if (qdf_unlikely(!ppdu_info))
2276*5113495bSYour Name 		return;
2277*5113495bSYour Name 
2278*5113495bSYour Name 	fc = ppdu_info->nac_info.frame_control;
2279*5113495bSYour Name 	if (qdf_likely((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_TYPE_MASK) !=
2280*5113495bSYour Name 	    QDF_IEEE80211_FC0_TYPE_CTL))
2281*5113495bSYour Name 		return;
2282*5113495bSYour Name 
2283*5113495bSYour Name 	for (i = 0; i < ppdu_info->com_info.num_users; i++) {
2284*5113495bSYour Name 		sw_peer_id = ppdu_info->rx_user_status[i].sw_peer_id;
2285*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(soc, sw_peer_id,
2286*5113495bSYour Name 					     DP_MOD_ID_RX_PPDU_STATS);
2287*5113495bSYour Name 		if (qdf_unlikely(!peer))
2288*5113495bSYour Name 			continue;
2289*5113495bSYour Name 		mon_peer = peer->monitor_peer;
2290*5113495bSYour Name 		if (qdf_unlikely(!mon_peer)) {
2291*5113495bSYour Name 			dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
2292*5113495bSYour Name 			continue;
2293*5113495bSYour Name 		}
2294*5113495bSYour Name 		DP_STATS_INCC(mon_peer, rx.ndpa_cnt, 1,
2295*5113495bSYour Name 			      ppdu_info->ctrl_frm_info[i].ndpa);
2296*5113495bSYour Name 		DP_STATS_INCC(mon_peer, rx.bar_cnt, 1,
2297*5113495bSYour Name 			      ppdu_info->ctrl_frm_info[i].bar);
2298*5113495bSYour Name 
2299*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
2300*5113495bSYour Name 	}
2301*5113495bSYour Name }
2302*5113495bSYour Name #endif /* WLAN_SUPPORT_CTRL_FRAME_STATS */
2303