xref: /wlan-driver/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2020, 2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 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 /**
21  * DOC: Implement mgmt txrx APIs which shall be used internally only
22  * in pkt_capture component.
23  * Note: These APIs should be never accessed out of pkt_capture component.
24  */
25 
26 #include "wlan_pkt_capture_main.h"
27 #include "wlan_pkt_capture_priv.h"
28 #include "wlan_pkt_capture_mgmt_txrx.h"
29 #include "wlan_mlme_main.h"
30 #include "wlan_lmac_if_api.h"
31 #include "wlan_mgmt_txrx_utils_api.h"
32 #include "wlan_utility.h"
33 #include "cds_ieee80211_common.h"
34 #include "cdp_txrx_ctrl.h"
35 
36 enum pkt_capture_tx_status
pkt_capture_mgmt_status_map(uint8_t status)37 pkt_capture_mgmt_status_map(uint8_t status)
38 {
39 	enum pkt_capture_tx_status tx_status;
40 
41 	switch (status) {
42 	case WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK:
43 		tx_status = pkt_capture_tx_status_ok;
44 		break;
45 	case WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK:
46 		tx_status = pkt_capture_tx_status_no_ack;
47 		break;
48 	default:
49 		tx_status = pkt_capture_tx_status_discard;
50 	break;
51 	}
52 
53 	return tx_status;
54 }
55 
56 /**
57  * pkt_capture_mgmtpkt_cb() - callback to process management packets
58  * for pkt capture mode
59  * @context: vdev handler
60  * @ppdev: unused param
61  * @nbuf_list: netbuf list
62  * @vdev_id: vdev id for which packet is captured
63  * @tid:  tid number
64  * @ch_freq: channel frequency
65  * @pkt_format: Frame format
66  * @bssid:
67  * @tx_retry_cnt: tx retry count
68  *
69  * Return: none
70  */
71 static void
pkt_capture_mgmtpkt_cb(void * context,void * ppdev,void * nbuf_list,uint8_t vdev_id,uint8_t tid,uint16_t ch_freq,bool pkt_format,uint8_t * bssid,uint8_t tx_retry_cnt)72 pkt_capture_mgmtpkt_cb(void *context, void *ppdev, void *nbuf_list,
73 		       uint8_t vdev_id, uint8_t tid, uint16_t ch_freq,
74 		       bool pkt_format, uint8_t *bssid, uint8_t tx_retry_cnt)
75 {
76 	struct pkt_capture_vdev_priv *vdev_priv;
77 	struct wlan_objmgr_psoc *psoc = context;
78 	struct pkt_capture_cb_context *cb_ctx;
79 	struct wlan_objmgr_vdev *vdev;
80 	qdf_nbuf_t msdu, next_buf;
81 	uint32_t drop_count;
82 
83 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc,
84 							QDF_STA_MODE,
85 							WLAN_PKT_CAPTURE_ID);
86 	if (!vdev) {
87 		pkt_capture_err("vdev is NULL");
88 		goto free_buf;
89 	}
90 
91 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
92 	if (!vdev_priv) {
93 		pkt_capture_err("packet capture vdev priv is NULL");
94 		goto release_vdev_ref;
95 	}
96 
97 	cb_ctx = vdev_priv->cb_ctx;
98 	if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) {
99 		pkt_capture_err("mon cb params are NULL");
100 		goto release_vdev_ref;
101 	}
102 
103 	msdu = nbuf_list;
104 	while (msdu) {
105 		next_buf = qdf_nbuf_queue_next(msdu);
106 		qdf_nbuf_set_next(msdu, NULL);   /* Add NULL terminator */
107 		pkt_capture_mon(cb_ctx, msdu, vdev, ch_freq);
108 		msdu = next_buf;
109 	}
110 
111 	wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
112 	return;
113 
114 release_vdev_ref:
115 	wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
116 free_buf:
117 	drop_count = pkt_capture_drop_nbuf_list(nbuf_list);
118 	pkt_capture_debug("Dropped frames %u", drop_count);
119 }
120 
121 /**
122  * pkt_capture_mgmtpkt_process() - process management packets
123  * for pkt capture mode
124  * @psoc: pointer to psoc object
125  * @txrx_status: mon_rx_status to update radiotap header
126  * @nbuf: netbuf
127  * @status: Tx status
128  *
129  * Return: QDF_STATUS Enumeration
130  */
131 static QDF_STATUS
pkt_capture_mgmtpkt_process(struct wlan_objmgr_psoc * psoc,struct mon_rx_status * txrx_status,qdf_nbuf_t nbuf,uint8_t status)132 pkt_capture_mgmtpkt_process(struct wlan_objmgr_psoc *psoc,
133 			    struct mon_rx_status *txrx_status,
134 			    qdf_nbuf_t nbuf, uint8_t status)
135 {
136 	struct wlan_objmgr_vdev *vdev;
137 	struct pkt_capture_mon_pkt *pkt;
138 	uint32_t headroom;
139 	uint8_t type, sub_type;
140 	struct ieee80211_frame *wh;
141 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
142 	struct wlan_objmgr_pdev *pdev;
143 	cdp_config_param_type val;
144 	tSirMacAuthFrameBody *auth;
145 	struct pkt_capture_vdev_priv *vdev_priv;
146 
147 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc,
148 							QDF_STA_MODE,
149 							WLAN_PKT_CAPTURE_ID);
150 
151 	if (!vdev) {
152 		pkt_capture_err("vdev is NULL");
153 		return QDF_STATUS_E_FAILURE;
154 	}
155 
156 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
157 	if (!vdev_priv) {
158 		pkt_capture_err("packet capture vdev priv is NULL");
159 		return QDF_STATUS_E_FAILURE;
160 	}
161 
162 	pdev = wlan_vdev_get_pdev(vdev);
163 	if (!pdev) {
164 		pkt_capture_err("pdev is NULL");
165 		return QDF_STATUS_E_FAILURE;
166 	}
167 
168 	wh = (struct ieee80211_frame *)(qdf_nbuf_data(nbuf));
169 	type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
170 	sub_type = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
171 
172 	/*
173 	 *  Update channel only if successful AUTH Resp is received.
174 	 *  This is done so that EAPOL M1 data frame have correct
175 	 *  channel
176 	 */
177 	if ((type == IEEE80211_FC0_TYPE_MGT) &&
178 	    (sub_type == MGMT_SUBTYPE_AUTH)) {
179 		uint8_t chan = wlan_freq_to_chan(txrx_status->chan_freq);
180 
181 		auth = (tSirMacAuthFrameBody *)(qdf_nbuf_data(nbuf) +
182 			sizeof(tSirMacMgmtHdr));
183 
184 		if (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_2 ||
185 		    auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4) {
186 			if (auth->authStatusCode == STATUS_SUCCESS) {
187 				val.cdp_pdev_param_monitor_chan = chan;
188 				cdp_txrx_set_pdev_param(
189 					soc, wlan_objmgr_pdev_get_pdev_id(pdev),
190 					CDP_MONITOR_CHANNEL, val);
191 
192 				val.cdp_pdev_param_mon_freq =
193 							txrx_status->chan_freq;
194 				cdp_txrx_set_pdev_param(
195 					soc, wlan_objmgr_pdev_get_pdev_id(pdev),
196 					CDP_MONITOR_FREQUENCY, val);
197 			}
198 		}
199 	}
200 
201 	/*
202 	 *  Update channel to last connected channel in case of assoc/reassoc
203 	 *  response failure and save current chan in case of success
204 	 */
205 	if ((type == IEEE80211_FC0_TYPE_MGT) &&
206 	    ((sub_type == MGMT_SUBTYPE_ASSOC_RESP) ||
207 	    (sub_type == MGMT_SUBTYPE_REASSOC_RESP))) {
208 		if (qdf_nbuf_len(nbuf) < (sizeof(tSirMacMgmtHdr) +
209 		   SIR_MAC_ASSOC_RSP_STATUS_CODE_OFFSET)) {
210 			pkt_capture_err("Packet length is less than expected");
211 			qdf_nbuf_free(nbuf);
212 			return QDF_STATUS_E_FAILURE;
213 		}
214 
215 		status = (uint16_t)(*(qdf_nbuf_data(nbuf) +
216 			 sizeof(tSirMacMgmtHdr) +
217 			 SIR_MAC_ASSOC_RSP_STATUS_CODE_OFFSET));
218 
219 		if (status == STATUS_SUCCESS) {
220 			vdev_priv->last_freq = vdev_priv->curr_freq;
221 			vdev_priv->curr_freq = txrx_status->chan_freq;
222 		} else {
223 			uint8_t chan_num;
224 
225 			chan_num = wlan_reg_freq_to_chan(pdev,
226 							 vdev_priv->last_freq);
227 
228 			val.cdp_pdev_param_monitor_chan = chan_num;
229 			cdp_txrx_set_pdev_param(
230 				soc, wlan_objmgr_pdev_get_pdev_id(pdev),
231 				CDP_MONITOR_CHANNEL, val);
232 
233 			val.cdp_pdev_param_mon_freq = vdev_priv->last_freq;
234 			cdp_txrx_set_pdev_param(
235 				soc, wlan_objmgr_pdev_get_pdev_id(pdev),
236 				CDP_MONITOR_FREQUENCY, val);
237 
238 			vdev_priv->curr_freq = vdev_priv->last_freq;
239 		}
240 	}
241 
242 	/*
243 	 * Calculate the headroom and adjust head to prepare radiotap header
244 	 */
245 	headroom = qdf_nbuf_headroom(nbuf);
246 	qdf_nbuf_update_radiotap(txrx_status, nbuf, headroom);
247 
248 	pkt = pkt_capture_alloc_mon_pkt(vdev);
249 	if (!pkt) {
250 		wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
251 		return QDF_STATUS_E_FAILURE;
252 	}
253 
254 	pkt->callback = pkt_capture_mgmtpkt_cb;
255 	pkt->context = psoc;
256 	pkt->monpkt = nbuf;
257 	pkt->vdev_id = WLAN_INVALID_VDEV_ID;
258 	pkt->tid = WLAN_INVALID_TID;
259 	pkt->status = txrx_status->chan_freq;
260 	pkt->pkt_format = PKTCAPTURE_PKT_FORMAT_80211;
261 	pkt_capture_indicate_monpkt(vdev, pkt);
262 
263 	wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
264 	return QDF_STATUS_SUCCESS;
265 }
266 
267 /**
268  * pkt_capture_is_rmf_enabled - API to check if rmf is enabled or not
269  * @pdev: pointer to pdev object
270  * @psoc: pointer to psoc object
271  * @addr: mac address
272  */
273 static bool
pkt_capture_is_rmf_enabled(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_psoc * psoc,uint8_t * addr)274 pkt_capture_is_rmf_enabled(struct wlan_objmgr_pdev *pdev,
275 			   struct wlan_objmgr_psoc *psoc,
276 			   uint8_t *addr)
277 {
278 	struct pkt_psoc_priv *psoc_priv;
279 	struct wlan_objmgr_vdev *vdev;
280 	uint8_t vdev_id;
281 	int rmf_enabled;
282 
283 	psoc_priv = pkt_capture_psoc_get_priv(psoc);
284 	if (!psoc_priv) {
285 		pkt_capture_err("psoc priv is NULL");
286 		return false;
287 	}
288 
289 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev,
290 							 addr,
291 							 WLAN_PKT_CAPTURE_ID);
292 	if (!vdev) {
293 		pkt_capture_err("vdev is NULL");
294 		return false;
295 	}
296 
297 	vdev_id = wlan_vdev_get_id(vdev);
298 	wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
299 
300 	rmf_enabled = psoc_priv->cb_obj.get_rmf_status(vdev_id);
301 	if (rmf_enabled < 0) {
302 		pkt_capture_err("unable to get rmf status");
303 		return false;
304 	}
305 
306 	return true;
307 }
308 
309 /**
310  * pkt_capture_process_rmf_frame - process rmf frame
311  * @pdev: pointer to pdev object
312  * @psoc: pointer to psoc object
313  * @nbuf: netbuf
314  */
315 static QDF_STATUS
pkt_capture_process_rmf_frame(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_psoc * psoc,qdf_nbuf_t nbuf)316 pkt_capture_process_rmf_frame(struct wlan_objmgr_pdev *pdev,
317 			      struct wlan_objmgr_psoc *psoc,
318 			      qdf_nbuf_t nbuf)
319 {
320 	tpSirMacFrameCtl pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf));
321 	uint8_t mic_len, hdr_len, pdev_id;
322 	struct ieee80211_frame *wh;
323 	uint8_t *orig_hdr;
324 
325 	wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf);
326 
327 	if (!QDF_IS_ADDR_BROADCAST(wh->i_addr1) &&
328 	    !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
329 		if (pfc->wep) {
330 			QDF_STATUS status;
331 
332 			orig_hdr = (uint8_t *)qdf_nbuf_data(nbuf);
333 			pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
334 			status = mlme_get_peer_mic_len(psoc, pdev_id,
335 						       wh->i_addr1,
336 						       &mic_len,
337 						       &hdr_len);
338 			if (QDF_IS_STATUS_ERROR(status)) {
339 				pkt_capture_err("Failed to get mic hdr");
340 				return QDF_STATUS_E_FAILURE;
341 			}
342 
343 			/* Strip privacy headers (and trailer)
344 			 * for a received frame
345 			 */
346 			qdf_mem_move(orig_hdr + hdr_len, wh, sizeof(*wh));
347 			qdf_nbuf_pull_head(nbuf, hdr_len);
348 			qdf_nbuf_trim_tail(nbuf, mic_len);
349 		}
350 	} else {
351 		qdf_nbuf_trim_tail(nbuf, IEEE80211_MMIE_LEN);
352 	}
353 
354 	return QDF_STATUS_SUCCESS;
355 }
356 
357 QDF_STATUS
pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev * pdev,struct mgmt_offload_event_params * params,qdf_nbuf_t nbuf,uint8_t status)358 pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev,
359 				 struct mgmt_offload_event_params *params,
360 				 qdf_nbuf_t nbuf,
361 				 uint8_t status)
362 {
363 	struct mon_rx_status txrx_status = {0};
364 	struct wlan_objmgr_psoc *psoc;
365 	tpSirMacFrameCtl pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf));
366 	struct ieee80211_frame *wh;
367 	uint16_t rate;
368 
369 	psoc = wlan_pdev_get_psoc(pdev);
370 	if (!psoc) {
371 		pkt_capture_err("psoc is NULL");
372 		return QDF_STATUS_E_FAILURE;
373 	}
374 
375 	wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf);
376 
377 	if ((pfc->type == IEEE80211_FC0_TYPE_MGT) &&
378 	    (pfc->subType == SIR_MAC_MGMT_DISASSOC ||
379 	     pfc->subType == SIR_MAC_MGMT_DEAUTH ||
380 	     pfc->subType == SIR_MAC_MGMT_ACTION)) {
381 		if (pkt_capture_is_rmf_enabled(pdev, psoc, wh->i_addr2)) {
382 			QDF_STATUS status;
383 
384 			status = pkt_capture_process_rmf_frame(pdev, psoc,
385 							       nbuf);
386 			if (QDF_IS_STATUS_ERROR(status))
387 				return status;
388 		}
389 	}
390 
391 	txrx_status.tsft = (u_int64_t)params->tsf_l32;
392 	txrx_status.chan_num = wlan_reg_freq_to_chan(pdev, params->chan_freq);
393 	txrx_status.chan_freq = params->chan_freq;
394 	if (params->rssi == INVALID_RSSI_FOR_TX)
395 		/* RSSI -128 is invalid rssi for TX, make it 0 here,
396 		 * will be normalized during radiotap updation
397 		 */
398 		txrx_status.ant_signal_db = 0;
399 	else
400 		txrx_status.ant_signal_db = params->rssi;
401 
402 	txrx_status.rssi_comb = txrx_status.ant_signal_db;
403 	txrx_status.nr_ant = 1;
404 	rate = params->rate_kbps * 2;
405 	/* params->rate is in Kbps, convert into Mbps */
406 	txrx_status.rate = (uint8_t)(rate / 1000);
407 
408 	txrx_status.rtap_flags |=
409 		((txrx_status.rate == 12 /* Mbps */) ? BIT(1) : 0);
410 
411 	if (txrx_status.rate == 12)
412 		txrx_status.ofdm_flag = 1;
413 	else
414 		txrx_status.cck_flag = 1;
415 
416 	txrx_status.tx_status = status;
417 	txrx_status.tx_retry_cnt = params->tx_retry_cnt;
418 	txrx_status.add_rtap_ext = true;
419 
420 	wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf);
421 	wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
422 
423 	return pkt_capture_mgmtpkt_process(psoc, &txrx_status,
424 					   nbuf, status);
425 }
426 
pkt_capture_mgmt_tx(struct wlan_objmgr_pdev * pdev,qdf_nbuf_t nbuf,uint16_t chan_freq,uint8_t preamble_type)427 void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev,
428 			 qdf_nbuf_t nbuf,
429 			 uint16_t chan_freq,
430 			 uint8_t preamble_type)
431 {
432 	struct mgmt_offload_event_params params = {0};
433 	tpSirMacFrameCtl pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf));
434 	struct pkt_capture_vdev_priv *vdev_priv;
435 	struct wlan_objmgr_vdev *vdev;
436 	qdf_nbuf_t wbuf;
437 	int nbuf_len;
438 	QDF_STATUS status = QDF_STATUS_SUCCESS;
439 
440 	if (!pdev) {
441 		pkt_capture_err("pdev is NULL");
442 		return;
443 	}
444 
445 	vdev = pkt_capture_get_vdev();
446 	status = pkt_capture_vdev_get_ref(vdev);
447 	if (QDF_IS_STATUS_ERROR(status)) {
448 		pkt_capture_err("failed to get vdev ref");
449 		return;
450 	}
451 
452 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
453 	if (!vdev_priv) {
454 		pkt_capture_err("packet capture vdev priv is NULL");
455 		pkt_capture_vdev_put_ref(vdev);
456 		return;
457 	}
458 
459 	if (pfc->type == IEEE80211_FC0_TYPE_MGT &&
460 	    !(vdev_priv->frame_filter.mgmt_tx_frame_filter &
461 	    PKT_CAPTURE_MGMT_FRAME_TYPE_ALL))
462 		goto exit;
463 
464 	if (pfc->type == IEEE80211_FC0_TYPE_CTL &&
465 	    !vdev_priv->frame_filter.ctrl_tx_frame_filter)
466 		goto exit;
467 
468 	nbuf_len = qdf_nbuf_len(nbuf);
469 	wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4),
470 			      RESERVE_BYTES, 4, false);
471 	if (!wbuf) {
472 		pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)",
473 				nbuf_len);
474 		goto exit;
475 	}
476 
477 	qdf_nbuf_put_tail(wbuf, nbuf_len);
478 	qdf_mem_copy(qdf_nbuf_data(wbuf), qdf_nbuf_data(nbuf), nbuf_len);
479 
480 	params.chan_freq = chan_freq;
481 	/*
482 	 * Filling Tpc in rssi field.
483 	 * As Tpc is not available, filling with default value of tpc
484 	 */
485 	params.rssi = 0;
486 	/* Assigning the local timestamp as TSF timestamp is not available*/
487 	params.tsf_l32 = (uint32_t)jiffies;
488 
489 	if (preamble_type == (1 << WMI_RATE_PREAMBLE_CCK))
490 		params.rate_kbps = 1000; /* Rate is 1 Mbps for CCK */
491 	else
492 		params.rate_kbps = 6000; /* Rate is 6 Mbps for OFDM */
493 
494 	/*
495 	 * The mgmt tx packet is send to mon interface before tx completion.
496 	 * we do not have status for this packet, using magic number(0xFF)
497 	 * as status for mgmt tx packet
498 	 */
499 	if (QDF_STATUS_SUCCESS !=
500 		pkt_capture_process_mgmt_tx_data(pdev, &params, wbuf, 0xFF))
501 		qdf_nbuf_free(wbuf);
502 exit:
503 	pkt_capture_vdev_put_ref(vdev);
504 }
505 
506 void
pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev * pdev,uint32_t desc_id,uint32_t status,struct mgmt_offload_event_params * params)507 pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev,
508 			       uint32_t desc_id,
509 			       uint32_t status,
510 			       struct mgmt_offload_event_params *params)
511 {
512 	struct pkt_capture_vdev_priv *vdev_priv;
513 	struct wlan_objmgr_vdev *vdev;
514 	tpSirMacFrameCtl pfc;
515 	qdf_nbuf_t wbuf, nbuf;
516 	int nbuf_len;
517 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
518 
519 	if (!pdev) {
520 		pkt_capture_err("pdev is NULL");
521 		return;
522 	}
523 
524 	vdev = pkt_capture_get_vdev();
525 	ret = pkt_capture_vdev_get_ref(vdev);
526 	if (QDF_IS_STATUS_ERROR(ret)) {
527 		pkt_capture_err("failed to get vdev ref");
528 		return;
529 	}
530 
531 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
532 	if (!vdev_priv) {
533 		pkt_capture_err("packet capture vdev priv is NULL");
534 		pkt_capture_vdev_put_ref(vdev);
535 		return;
536 	}
537 
538 	nbuf = mgmt_txrx_get_nbuf(pdev, desc_id);
539 	if (!nbuf)
540 		goto exit;
541 
542 	pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf));
543 	if (pfc->type == IEEE80211_FC0_TYPE_MGT &&
544 	    !(vdev_priv->frame_filter.mgmt_tx_frame_filter &
545 	    PKT_CAPTURE_MGMT_FRAME_TYPE_ALL))
546 		goto exit;
547 
548 	if (pfc->type == IEEE80211_FC0_TYPE_CTL &&
549 	    !vdev_priv->frame_filter.ctrl_tx_frame_filter)
550 		goto exit;
551 
552 	nbuf_len = qdf_nbuf_len(nbuf);
553 	wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4),
554 			      RESERVE_BYTES, 4, false);
555 	if (!wbuf) {
556 		pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)",
557 				nbuf_len);
558 		goto exit;
559 	}
560 
561 	qdf_nbuf_put_tail(wbuf, nbuf_len);
562 	qdf_mem_copy(qdf_nbuf_data(wbuf), qdf_nbuf_data(nbuf), nbuf_len);
563 
564 	if (QDF_STATUS_SUCCESS !=
565 		pkt_capture_process_mgmt_tx_data(
566 					pdev, params, wbuf,
567 					pkt_capture_mgmt_status_map(status)))
568 		qdf_nbuf_free(wbuf);
569 
570 exit:
571 	pkt_capture_vdev_put_ref(vdev);
572 }
573 
574 /**
575  * pkt_capture_is_beacon_forward_enable() - API to check whether particular
576  * beacon needs to be forwarded on mon interface based on vendor command
577  * @vdev: vdev object
578  * @wbuf: netbuf
579  *
580  * Return: bool
581  */
582 static bool
pkt_capture_is_beacon_forward_enable(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t wbuf)583 pkt_capture_is_beacon_forward_enable(struct wlan_objmgr_vdev *vdev,
584 				     qdf_nbuf_t wbuf)
585 {
586 	struct pkt_capture_vdev_priv *vdev_priv;
587 	struct qdf_mac_addr connected_bssid = {0};
588 	tpSirMacMgmtHdr mac_hdr;
589 	bool my_beacon = false;
590 
591 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
592 	if (!vdev_priv) {
593 		pkt_capture_err("packet capture vdev priv is NULL");
594 		return false;
595 	}
596 
597 	mac_hdr = (tpSirMacMgmtHdr)(qdf_nbuf_data(wbuf));
598 	wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid);
599 
600 	if (qdf_is_macaddr_equal((struct qdf_mac_addr *)mac_hdr->bssId,
601 				 &connected_bssid))
602 		my_beacon = true;
603 
604 	if (((vdev_priv->frame_filter.mgmt_rx_frame_filter &
605 	    PKT_CAPTURE_MGMT_CONNECT_BEACON) ||
606 	    vdev_priv->frame_filter.connected_beacon_interval) && my_beacon)
607 		return true;
608 
609 	if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
610 	    PKT_CAPTURE_MGMT_CONNECT_SCAN_BEACON && !my_beacon)
611 		return true;
612 
613 	return false;
614 }
615 
616 #ifdef DP_MON_RSSI_IN_DBM
617 #define PKT_CAPTURE_FILL_RSSI(rx_params) \
618 ((rx_params)->snr + NORMALIZED_TO_NOISE_FLOOR)
619 #else
620 #define PKT_CAPTURE_FILL_RSSI(rx_status) \
621 ((rx_params)->snr)
622 #endif
623 
624 /**
625  * pkt_capture_mgmt_rx_data_cb() -  process management rx packets
626  * @psoc: psoc object
627  * @peer: Peer object
628  * @wbuf: netbuf
629  * @rx_params: mgmt rx event params
630  * @frm_type: frame type
631  *
632  * Return: none
633  */
634 static QDF_STATUS
pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_peer * peer,qdf_nbuf_t wbuf,struct mgmt_rx_event_params * rx_params,enum mgmt_frame_type frm_type)635 pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc,
636 			    struct wlan_objmgr_peer *peer,
637 			    qdf_nbuf_t wbuf,
638 			    struct mgmt_rx_event_params *rx_params,
639 			    enum mgmt_frame_type frm_type)
640 {
641 	struct mon_rx_status txrx_status = {0};
642 	struct pkt_capture_vdev_priv *vdev_priv;
643 	struct ieee80211_frame *wh;
644 	tpSirMacFrameCtl pfc;
645 	qdf_nbuf_t nbuf;
646 	int buf_len;
647 	struct wlan_objmgr_vdev *vdev;
648 	struct wlan_objmgr_pdev *pdev;
649 	QDF_STATUS status = QDF_STATUS_SUCCESS;
650 
651 	vdev = pkt_capture_get_vdev();
652 	status = pkt_capture_vdev_get_ref(vdev);
653 	if (QDF_IS_STATUS_ERROR(status)) {
654 		pkt_capture_err("failed to get vdev ref");
655 		qdf_nbuf_free(wbuf);
656 		return QDF_STATUS_E_FAILURE;
657 	}
658 
659 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
660 	if (!vdev_priv) {
661 		pkt_capture_err("packet capture vdev priv is NULL");
662 		pkt_capture_vdev_put_ref(vdev);
663 		qdf_nbuf_free(wbuf);
664 		return QDF_STATUS_E_FAILURE;
665 	}
666 
667 	pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(wbuf));
668 
669 	if (pfc->type == SIR_MAC_CTRL_FRAME  &&
670 	    !vdev_priv->frame_filter.ctrl_rx_frame_filter)
671 		goto exit;
672 
673 	if (pfc->type == SIR_MAC_MGMT_FRAME  &&
674 	    !vdev_priv->frame_filter.mgmt_rx_frame_filter)
675 		goto exit;
676 
677 	if (pfc->type == SIR_MAC_MGMT_FRAME) {
678 		if (pfc->subType == SIR_MAC_MGMT_BEACON) {
679 			if (!pkt_capture_is_beacon_forward_enable(vdev, wbuf))
680 				goto exit;
681 		} else {
682 			if (!((vdev_priv->frame_filter.mgmt_rx_frame_filter &
683 			    PKT_CAPTURE_MGMT_FRAME_TYPE_ALL) ||
684 			    (vdev_priv->frame_filter.mgmt_rx_frame_filter &
685 			    PKT_CAPTURE_MGMT_CONNECT_NO_BEACON)))
686 				goto exit;
687 		}
688 	}
689 
690 	buf_len = qdf_nbuf_len(wbuf);
691 	nbuf = qdf_nbuf_alloc(NULL, roundup(
692 				  buf_len + RESERVE_BYTES, 4),
693 				  RESERVE_BYTES, 4, false);
694 	if (!nbuf) {
695 		pkt_capture_vdev_put_ref(vdev);
696 		qdf_nbuf_free(wbuf);
697 		return QDF_STATUS_E_FAILURE;
698 	}
699 
700 	qdf_nbuf_put_tail(nbuf, buf_len);
701 	qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_data(wbuf), buf_len);
702 
703 	qdf_nbuf_free(wbuf);
704 
705 	pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf));
706 	wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf);
707 
708 	pdev = wlan_vdev_get_pdev(vdev);
709 	pkt_capture_vdev_put_ref(vdev);
710 
711 	if ((pfc->type == IEEE80211_FC0_TYPE_MGT) &&
712 	    (pfc->subType == SIR_MAC_MGMT_DISASSOC ||
713 	     pfc->subType == SIR_MAC_MGMT_DEAUTH ||
714 	     pfc->subType == SIR_MAC_MGMT_ACTION)) {
715 		if (pkt_capture_is_rmf_enabled(pdev, psoc, wh->i_addr1)) {
716 			QDF_STATUS status;
717 
718 			status = pkt_capture_process_rmf_frame(pdev, psoc,
719 							       nbuf);
720 			if (QDF_IS_STATUS_ERROR(status))
721 				return status;
722 		}
723 	}
724 
725 	txrx_status.tsft = (u_int64_t)rx_params->tsf_l32;
726 	txrx_status.chan_num = rx_params->channel;
727 	txrx_status.chan_freq = rx_params->chan_freq;
728 	/* rx_params->rate is in Kbps, convert into Mbps */
729 	txrx_status.rate = (rx_params->rate / 1000);
730 	txrx_status.ant_signal_db = rx_params->snr;
731 	txrx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR;
732 	txrx_status.rssi_comb = PKT_CAPTURE_FILL_RSSI(rx_params);
733 	txrx_status.nr_ant = 1;
734 	txrx_status.rtap_flags |=
735 		((txrx_status.rate == 6 /* Mbps */) ? BIT(1) : 0);
736 
737 	if (rx_params->phy_mode != PKTCAPTURE_RATECODE_CCK)
738 		txrx_status.ofdm_flag = 1;
739 	else
740 		txrx_status.cck_flag = 1;
741 
742 	/* Convert rate from Mbps to 500 Kbps */
743 	txrx_status.rate = txrx_status.rate * 2;
744 
745 	wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf);
746 	wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
747 
748 	if (QDF_STATUS_SUCCESS !=
749 		pkt_capture_mgmtpkt_process(psoc, &txrx_status, nbuf, 0))
750 		qdf_nbuf_free(nbuf);
751 
752 	return QDF_STATUS_SUCCESS;
753 exit:
754 	pkt_capture_vdev_put_ref(vdev);
755 	qdf_nbuf_free(wbuf);
756 	return QDF_STATUS_SUCCESS;
757 }
758 
pkt_capture_mgmt_rx_ops(struct wlan_objmgr_psoc * psoc,bool is_register)759 QDF_STATUS pkt_capture_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc,
760 				   bool is_register)
761 {
762 	struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2];
763 	QDF_STATUS status;
764 	int num_of_entries;
765 
766 	frm_cb_info[0].frm_type = MGMT_FRAME_TYPE_ALL;
767 	frm_cb_info[0].mgmt_rx_cb = pkt_capture_mgmt_rx_data_cb;
768 	frm_cb_info[1].frm_type = MGMT_CTRL_FRAME;
769 	frm_cb_info[1].mgmt_rx_cb = pkt_capture_mgmt_rx_data_cb;
770 	num_of_entries = 2;
771 
772 	if (is_register)
773 		status = wlan_mgmt_txrx_register_rx_cb(
774 					psoc, WLAN_UMAC_COMP_PKT_CAPTURE,
775 					frm_cb_info, num_of_entries);
776 	else
777 		status = wlan_mgmt_txrx_deregister_rx_cb(
778 					psoc, WLAN_UMAC_COMP_PKT_CAPTURE,
779 					frm_cb_info, num_of_entries);
780 
781 	return status;
782 }
783