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