xref: /wlan-driver/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_main.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 various notification handlers which are accessed
22  * internally in pkt_capture component only.
23  */
24 
25 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
26 #include <dp_types.h>
27 #include "htt_ppdu_stats.h"
28 #endif
29 #include "wlan_pkt_capture_main.h"
30 #include "cfg_ucfg_api.h"
31 #include "wlan_pkt_capture_mon_thread.h"
32 #include "wlan_pkt_capture_mgmt_txrx.h"
33 #include "target_if_pkt_capture.h"
34 #include "cdp_txrx_ctrl.h"
35 #include "wlan_pkt_capture_tgt_api.h"
36 #include <cds_ieee80211_common.h>
37 #include "wlan_vdev_mgr_utils_api.h"
38 
39 static struct wlan_objmgr_vdev *gp_pkt_capture_vdev;
40 
41 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
42 wdi_event_subscribe PKT_CAPTURE_TX_SUBSCRIBER;
43 wdi_event_subscribe PKT_CAPTURE_RX_SUBSCRIBER;
44 wdi_event_subscribe PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER;
45 wdi_event_subscribe PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER;
46 wdi_event_subscribe PKT_CAPTURE_PPDU_STATS_SUBSCRIBER;
47 
48 /**
49  * pkt_capture_wdi_event_subscribe() - Subscribe pkt capture callbacks
50  * @psoc: pointer to psoc object
51  *
52  * Return: None
53  */
pkt_capture_wdi_event_subscribe(struct wlan_objmgr_psoc * psoc)54 static void pkt_capture_wdi_event_subscribe(struct wlan_objmgr_psoc *psoc)
55 {
56 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
57 	uint8_t pdev_id = WMI_PDEV_ID_SOC;
58 
59 	/* subscribing for tx data packets */
60 	PKT_CAPTURE_TX_SUBSCRIBER.callback =
61 				pkt_capture_callback;
62 
63 	PKT_CAPTURE_TX_SUBSCRIBER.context = wlan_psoc_get_dp_handle(psoc);
64 
65 	cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_TX_SUBSCRIBER,
66 			  WDI_EVENT_PKT_CAPTURE_TX_DATA);
67 
68 	/* subscribing for rx data packets */
69 	PKT_CAPTURE_RX_SUBSCRIBER.callback =
70 				pkt_capture_callback;
71 
72 	PKT_CAPTURE_RX_SUBSCRIBER.context = wlan_psoc_get_dp_handle(psoc);
73 
74 	cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_RX_SUBSCRIBER,
75 			  WDI_EVENT_PKT_CAPTURE_RX_DATA);
76 
77 	/* subscribe for rx data packets when no peer is there*/
78 	PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER.callback =
79 				pkt_capture_callback;
80 
81 	PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER.context =
82 					wlan_psoc_get_dp_handle(psoc);
83 
84 	cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER,
85 			  WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER);
86 
87 	/* subscribing for offload tx data packets */
88 	PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER.callback =
89 				pkt_capture_callback;
90 
91 	PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER.context =
92 						wlan_psoc_get_dp_handle(psoc);
93 
94 	cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER,
95 			  WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA);
96 
97 	/* subscribe for packet capture mode related ppdu stats */
98 	PKT_CAPTURE_PPDU_STATS_SUBSCRIBER.callback =
99 				pkt_capture_callback;
100 
101 	PKT_CAPTURE_PPDU_STATS_SUBSCRIBER.context =
102 						wlan_psoc_get_dp_handle(psoc);
103 
104 	cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_PPDU_STATS_SUBSCRIBER,
105 			  WDI_EVENT_PKT_CAPTURE_PPDU_STATS);
106 }
107 
108 /**
109  * pkt_capture_wdi_event_unsubscribe() - Unsubscribe pkt capture callbacks
110  * @psoc: pointer to psoc object
111  *
112  * Return: None
113  */
pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc * psoc)114 static void pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc *psoc)
115 {
116 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
117 	uint8_t pdev_id = WMI_PDEV_ID_SOC;
118 
119 	/* unsubscribe ppdu smu stats */
120 	cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_PPDU_STATS_SUBSCRIBER,
121 			    WDI_EVENT_PKT_CAPTURE_PPDU_STATS);
122 
123 	/* unsubscribing for offload tx data packets */
124 	cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_OFFLOAD_TX_SUBSCRIBER,
125 			    WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA);
126 
127 	/* unsubscribe for rx data no peer packets */
128 	cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER,
129 			    WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER);
130 
131 	/* unsubscribing for rx data packets */
132 	cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_RX_SUBSCRIBER,
133 			    WDI_EVENT_PKT_CAPTURE_RX_DATA);
134 
135 	/* unsubscribing for tx data packets */
136 	cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_TX_SUBSCRIBER,
137 			    WDI_EVENT_PKT_CAPTURE_TX_DATA);
138 }
139 
140 enum pkt_capture_mode
pkt_capture_get_pktcap_mode_v2()141 pkt_capture_get_pktcap_mode_v2()
142 {
143 	enum pkt_capture_mode mode = PACKET_CAPTURE_MODE_DISABLE;
144 	struct pkt_capture_vdev_priv *vdev_priv;
145 	struct wlan_objmgr_vdev *vdev;
146 	QDF_STATUS status = QDF_STATUS_SUCCESS;
147 
148 	vdev = pkt_capture_get_vdev();
149 	status = pkt_capture_vdev_get_ref(vdev);
150 	if (QDF_IS_STATUS_ERROR(status))
151 		return PACKET_CAPTURE_MODE_DISABLE;
152 
153 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
154 	if (!vdev_priv)
155 		pkt_capture_err("vdev_priv is NULL");
156 	else
157 		mode = vdev_priv->cfg_params.pkt_capture_mode;
158 
159 	pkt_capture_vdev_put_ref(vdev);
160 	return mode;
161 }
162 
163 #define RX_OFFLOAD_PKT 1
164 #define PPDU_STATS_Q_MAX_SIZE 500
165 
166 static void
pkt_capture_process_rx_data_no_peer(void * soc,uint16_t vdev_id,uint8_t * bssid,uint32_t status,qdf_nbuf_t nbuf)167 pkt_capture_process_rx_data_no_peer(void *soc, uint16_t vdev_id, uint8_t *bssid,
168 				    uint32_t status, qdf_nbuf_t nbuf)
169 {
170 	uint32_t pkt_len, l3_hdr_pad, nbuf_len;
171 	struct dp_soc *psoc = soc;
172 	qdf_nbuf_t msdu;
173 	uint8_t *rx_tlv_hdr;
174 
175 	nbuf_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
176 	rx_tlv_hdr = qdf_nbuf_data(nbuf);
177 	l3_hdr_pad = hal_rx_msdu_end_l3_hdr_padding_get(psoc->hal_soc,
178 							rx_tlv_hdr);
179 	pkt_len = nbuf_len + l3_hdr_pad + psoc->rx_pkt_tlv_size;
180 	qdf_nbuf_set_pktlen(nbuf, pkt_len);
181 
182 	/*
183 	 * Offload rx packets are delivered only to pkt capture component, so
184 	 * can modify the received nbuf, in other cases create a private copy
185 	 * of the received nbuf so that pkt capture component can modify it
186 	 * without altering the original nbuf
187 	 */
188 	if (status == RX_OFFLOAD_PKT)
189 		msdu = nbuf;
190 	else
191 		msdu = qdf_nbuf_copy(nbuf);
192 
193 	if (!msdu)
194 		return;
195 
196 	QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(msdu) = l3_hdr_pad;
197 
198 	qdf_nbuf_pull_head(msdu, l3_hdr_pad + psoc->rx_pkt_tlv_size);
199 	pkt_capture_datapkt_process(
200 			vdev_id, msdu,
201 			TXRX_PROCESS_TYPE_DATA_RX, 0, 0,
202 			TXRX_PKTCAPTURE_PKT_FORMAT_8023,
203 			bssid, psoc, 0);
204 }
205 
206 static void
pkt_capture_process_ppdu_stats(void * log_data)207 pkt_capture_process_ppdu_stats(void *log_data)
208 {
209 	struct wlan_objmgr_vdev *vdev;
210 	struct pkt_capture_vdev_priv *vdev_priv;
211 	struct pkt_capture_ppdu_stats_q_node *q_node;
212 	htt_ppdu_stats_for_smu_tlv *smu;
213 	uint32_t stats_len;
214 	QDF_STATUS status = QDF_STATUS_SUCCESS;
215 
216 	vdev = pkt_capture_get_vdev();
217 	status = pkt_capture_vdev_get_ref(vdev);
218 	if (QDF_IS_STATUS_ERROR(status))
219 		return;
220 
221 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
222 	if (qdf_unlikely(!vdev_priv)) {
223 		pkt_capture_vdev_put_ref(vdev);
224 		return;
225 	}
226 
227 	smu = (htt_ppdu_stats_for_smu_tlv *)log_data;
228 	vdev_priv->tx_nss = smu->nss;
229 
230 	qdf_spin_lock_bh(&vdev_priv->lock_q);
231 	if (qdf_list_size(&vdev_priv->ppdu_stats_q) <
232 					PPDU_STATS_Q_MAX_SIZE) {
233 		qdf_spin_unlock_bh(&vdev_priv->lock_q);
234 		/*
235 		 * win size indicates the size of block ack bitmap, currently
236 		 * we support only 256 bit ba bitmap.
237 		 */
238 		if (smu->win_size > 8) {
239 			pkt_capture_vdev_put_ref(vdev);
240 			pkt_capture_err("win size %d > 8 not supported\n",
241 					smu->win_size);
242 			return;
243 		}
244 
245 		stats_len = sizeof(htt_ppdu_stats_for_smu_tlv) +
246 				smu->win_size * sizeof(uint32_t);
247 
248 		q_node = qdf_mem_malloc(sizeof(*q_node) + stats_len);
249 		if (!q_node) {
250 			pkt_capture_vdev_put_ref(vdev);
251 			pkt_capture_err("stats node and buf allocation fail\n");
252 			return;
253 		}
254 
255 		qdf_mem_copy(q_node->buf, log_data, stats_len);
256 		/* Insert received ppdu stats in queue */
257 		qdf_spin_lock_bh(&vdev_priv->lock_q);
258 		qdf_list_insert_back(&vdev_priv->ppdu_stats_q,
259 				     &q_node->node);
260 	}
261 	qdf_spin_unlock_bh(&vdev_priv->lock_q);
262 	pkt_capture_vdev_put_ref(vdev);
263 }
264 
265 static void
pkt_capture_process_tx_data(void * soc,void * log_data,u_int16_t vdev_id,uint32_t status)266 pkt_capture_process_tx_data(void *soc, void *log_data, u_int16_t vdev_id,
267 			    uint32_t status)
268 {
269 	struct dp_soc *psoc = soc;
270 	uint8_t tid = 0;
271 	uint8_t bssid[QDF_MAC_ADDR_SIZE] = {0};
272 	struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr;
273 	struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0};
274 	struct hal_tx_completion_status tx_comp_status = {0};
275 	struct qdf_tso_seg_elem_t *tso_seg = NULL;
276 	uint32_t txcap_hdr_size =
277 			sizeof(struct pkt_capture_tx_hdr_elem_t);
278 
279 	struct dp_tx_desc_s *desc = log_data;
280 	qdf_nbuf_t netbuf;
281 	int nbuf_len;
282 
283 	hal_tx_comp_get_status(&desc->comp, &tx_comp_status,
284 			       psoc->hal_soc);
285 
286 	if (tx_comp_status.valid)
287 		pktcapture_hdr.ppdu_id = tx_comp_status.ppdu_id;
288 	pktcapture_hdr.timestamp = tx_comp_status.tsf;
289 	pktcapture_hdr.preamble = tx_comp_status.pkt_type;
290 	pktcapture_hdr.mcs = tx_comp_status.mcs;
291 	pktcapture_hdr.bw = tx_comp_status.bw;
292 	/* nss not available */
293 	pktcapture_hdr.nss = 0;
294 	pktcapture_hdr.rssi_comb = tx_comp_status.ack_frame_rssi;
295 	/* update rate from available mcs */
296 	pktcapture_hdr.rate = tx_comp_status.mcs;
297 	pktcapture_hdr.stbc = tx_comp_status.stbc;
298 	pktcapture_hdr.sgi = tx_comp_status.sgi;
299 	pktcapture_hdr.ldpc = tx_comp_status.ldpc;
300 	/* Beamformed not available */
301 	pktcapture_hdr.beamformed = 0;
302 	pktcapture_hdr.framectrl = IEEE80211_FC0_TYPE_DATA |
303 				   (IEEE80211_FC1_DIR_TODS << 8);
304 	pktcapture_hdr.tx_retry_cnt = tx_comp_status.transmit_cnt - 1;
305 	/* seqno not available */
306 	pktcapture_hdr.seqno = 0;
307 	tid = tx_comp_status.tid;
308 	status = tx_comp_status.status;
309 
310 	if (desc->frm_type == dp_tx_frm_tso) {
311 		if (!desc->msdu_ext_desc->tso_desc)
312 			return;
313 		tso_seg = desc->msdu_ext_desc->tso_desc;
314 		nbuf_len = tso_seg->seg.total_len;
315 	} else {
316 		nbuf_len = qdf_nbuf_len(desc->nbuf);
317 	}
318 
319 	netbuf = qdf_nbuf_alloc(NULL,
320 				roundup(nbuf_len + RESERVE_BYTES, 4),
321 				RESERVE_BYTES, 4, false);
322 
323 	if (!netbuf)
324 		return;
325 
326 	qdf_nbuf_put_tail(netbuf, nbuf_len);
327 
328 	if (desc->frm_type == dp_tx_frm_tso) {
329 		uint8_t frag_cnt, num_frags = 0;
330 		int frag_len = 0;
331 		uint32_t tcp_seq_num;
332 		uint16_t ip_len;
333 
334 		if (tso_seg->seg.num_frags > 0)
335 			num_frags = tso_seg->seg.num_frags - 1;
336 
337 		/*Num of frags in a tso seg cannot be less than 2 */
338 		if (num_frags < 1) {
339 			pkt_capture_err("num of frags in tso segment is %d\n",
340 					(num_frags + 1));
341 			qdf_nbuf_free(netbuf);
342 			return;
343 		}
344 
345 		tcp_seq_num = tso_seg->seg.tso_flags.tcp_seq_num;
346 		tcp_seq_num = qdf_cpu_to_be32(tcp_seq_num);
347 
348 		ip_len = tso_seg->seg.tso_flags.ip_len;
349 		ip_len = qdf_cpu_to_be16(ip_len);
350 
351 		for (frag_cnt = 0; frag_cnt <= num_frags; frag_cnt++) {
352 			qdf_mem_copy(
353 			qdf_nbuf_data(netbuf) + frag_len,
354 			tso_seg->seg.tso_frags[frag_cnt].vaddr,
355 			tso_seg->seg.tso_frags[frag_cnt].length);
356 			frag_len +=
357 				tso_seg->seg.tso_frags[frag_cnt].length;
358 		}
359 
360 		qdf_mem_copy((qdf_nbuf_data(netbuf) +
361 			     IPV4_PKT_LEN_OFFSET),
362 			     &ip_len, sizeof(ip_len));
363 		qdf_mem_copy((qdf_nbuf_data(netbuf) +
364 			     IPV4_TCP_SEQ_NUM_OFFSET),
365 			     &tcp_seq_num, sizeof(tcp_seq_num));
366 	} else {
367 		qdf_mem_copy(qdf_nbuf_data(netbuf),
368 			     qdf_nbuf_data(desc->nbuf), nbuf_len);
369 	}
370 
371 	if (qdf_unlikely(qdf_nbuf_headroom(netbuf) < txcap_hdr_size)) {
372 		netbuf = qdf_nbuf_realloc_headroom(netbuf,
373 						   txcap_hdr_size);
374 		if (!netbuf) {
375 			QDF_TRACE(QDF_MODULE_ID_PKT_CAPTURE,
376 				  QDF_TRACE_LEVEL_ERROR,
377 				  FL("No headroom"));
378 			return;
379 		}
380 	}
381 
382 	if (!qdf_nbuf_push_head(netbuf, txcap_hdr_size)) {
383 		QDF_TRACE(QDF_MODULE_ID_PKT_CAPTURE,
384 			  QDF_TRACE_LEVEL_ERROR, FL("No headroom"));
385 		qdf_nbuf_free(netbuf);
386 		return;
387 	}
388 
389 	ptr_pktcapture_hdr =
390 	(struct pkt_capture_tx_hdr_elem_t *)qdf_nbuf_data(netbuf);
391 	qdf_mem_copy(ptr_pktcapture_hdr, &pktcapture_hdr,
392 		     txcap_hdr_size);
393 
394 	pkt_capture_datapkt_process(
395 		vdev_id, netbuf, TXRX_PROCESS_TYPE_DATA_TX_COMPL,
396 		tid, status, TXRX_PKTCAPTURE_PKT_FORMAT_8023,
397 		bssid, NULL, pktcapture_hdr.tx_retry_cnt);
398 }
399 
400 /**
401  * pkt_capture_is_frame_filter_set() - Check frame filter is set
402  * @buf: buffer address
403  * @frame_filter: frame filter address
404  * @direction: frame direction
405  *
406  * Return: true, if filter bit is set
407  *         false, if filter bit is not set
408  */
409 bool
pkt_capture_is_frame_filter_set(qdf_nbuf_t buf,struct pkt_capture_frame_filter * frame_filter,bool direction)410 pkt_capture_is_frame_filter_set(qdf_nbuf_t buf,
411 				struct pkt_capture_frame_filter *frame_filter,
412 				bool direction)
413 {
414 	enum pkt_capture_data_frame_type data_frame_type =
415 		PKT_CAPTURE_DATA_FRAME_TYPE_ALL;
416 
417 	if (qdf_nbuf_is_ipv4_arp_pkt(buf)) {
418 		data_frame_type = PKT_CAPTURE_DATA_FRAME_TYPE_ARP;
419 	} else if (qdf_nbuf_is_ipv4_eapol_pkt(buf)) {
420 		data_frame_type = PKT_CAPTURE_DATA_FRAME_TYPE_EAPOL;
421 	} else if (qdf_nbuf_data_is_tcp_syn(buf)) {
422 		data_frame_type =
423 			PKT_CAPTURE_DATA_FRAME_TYPE_TCP_SYN;
424 	} else if (qdf_nbuf_data_is_tcp_syn_ack(buf)) {
425 		data_frame_type =
426 			PKT_CAPTURE_DATA_FRAME_TYPE_TCP_SYNACK;
427 	} else if (qdf_nbuf_data_is_tcp_syn(buf)) {
428 		data_frame_type =
429 			PKT_CAPTURE_DATA_FRAME_TYPE_TCP_FIN;
430 	} else if (qdf_nbuf_data_is_tcp_syn_ack(buf)) {
431 		data_frame_type =
432 			PKT_CAPTURE_DATA_FRAME_TYPE_TCP_FINACK;
433 	} else if (qdf_nbuf_data_is_tcp_ack(buf)) {
434 		data_frame_type =
435 			PKT_CAPTURE_DATA_FRAME_TYPE_TCP_ACK;
436 	} else if (qdf_nbuf_data_is_tcp_rst(buf)) {
437 		data_frame_type =
438 			PKT_CAPTURE_DATA_FRAME_TYPE_TCP_RST;
439 	} else if (qdf_nbuf_is_ipv4_pkt(buf)) {
440 		if (qdf_nbuf_is_ipv4_dhcp_pkt(buf))
441 			data_frame_type =
442 				PKT_CAPTURE_DATA_FRAME_TYPE_DHCPV4;
443 		else if (qdf_nbuf_is_icmp_pkt(buf))
444 			data_frame_type =
445 				PKT_CAPTURE_DATA_FRAME_TYPE_ICMPV4;
446 		else if (qdf_nbuf_data_is_dns_query(buf))
447 			data_frame_type =
448 				PKT_CAPTURE_DATA_FRAME_TYPE_DNSV4;
449 		else if (qdf_nbuf_data_is_dns_response(buf))
450 			data_frame_type =
451 				PKT_CAPTURE_DATA_FRAME_TYPE_DNSV4;
452 	} else if (qdf_nbuf_is_ipv6_pkt(buf)) {
453 		if (qdf_nbuf_is_ipv6_dhcp_pkt(buf))
454 			data_frame_type =
455 				PKT_CAPTURE_DATA_FRAME_TYPE_DHCPV6;
456 		else if (qdf_nbuf_is_icmpv6_pkt(buf))
457 			data_frame_type =
458 				PKT_CAPTURE_DATA_FRAME_TYPE_ICMPV6;
459 		/* need to add code for
460 		 * PKT_CAPTURE_DATA_FRAME_TYPE_DNSV6
461 		 */
462 	}
463 	/* Add code for
464 	 * PKT_CAPTURE_DATA_FRAME_TYPE_RTP
465 	 * PKT_CAPTURE_DATA_FRAME_TYPE_SIP
466 	 * PKT_CAPTURE_DATA_FRAME_QOS_NULL
467 	 */
468 
469 	if (direction == IEEE80211_FC1_DIR_TODS) {
470 		if (data_frame_type & frame_filter->data_tx_frame_filter)
471 			return true;
472 		else
473 			return false;
474 	} else {
475 		if (data_frame_type & frame_filter->data_rx_frame_filter)
476 			return true;
477 		else
478 			return false;
479 	}
480 }
481 
pkt_capture_callback(void * soc,enum WDI_EVENT event,void * log_data,u_int16_t peer_id,uint32_t status)482 void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
483 			  u_int16_t peer_id, uint32_t status)
484 {
485 	uint8_t bssid[QDF_MAC_ADDR_SIZE] = {0};
486 	struct wlan_objmgr_vdev *vdev;
487 	struct pkt_capture_vdev_priv *vdev_priv;
488 	struct pkt_capture_frame_filter *frame_filter;
489 	uint16_t vdev_id = 0;
490 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
491 
492 	vdev = pkt_capture_get_vdev();
493 	ret = pkt_capture_vdev_get_ref(vdev);
494 	if (QDF_IS_STATUS_ERROR(ret))
495 		return;
496 
497 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
498 	if (!vdev_priv) {
499 		pkt_capture_err("vdev priv is NULL");
500 		pkt_capture_vdev_put_ref(vdev);
501 		return;
502 	}
503 
504 	frame_filter = &vdev_priv->frame_filter;
505 
506 	switch (event) {
507 	case WDI_EVENT_PKT_CAPTURE_TX_DATA:
508 	{
509 		struct dp_tx_desc_s *desc = log_data;
510 
511 		if (!frame_filter->data_tx_frame_filter) {
512 			pkt_capture_vdev_put_ref(vdev);
513 			return;
514 		}
515 
516 		if (frame_filter->data_tx_frame_filter &
517 		    PKT_CAPTURE_DATA_FRAME_TYPE_ALL) {
518 			pkt_capture_process_tx_data(soc, log_data,
519 						    vdev_id, status);
520 		} else if (pkt_capture_is_frame_filter_set(
521 			   desc->nbuf, frame_filter, IEEE80211_FC1_DIR_TODS)) {
522 			pkt_capture_process_tx_data(soc, log_data,
523 						    vdev_id, status);
524 		}
525 		break;
526 	}
527 
528 	case WDI_EVENT_PKT_CAPTURE_RX_DATA:
529 	{
530 		qdf_nbuf_t nbuf = (qdf_nbuf_t)log_data;
531 
532 		if (!frame_filter->data_rx_frame_filter) {
533 			/*
534 			 * Rx offload packets are delivered only to pkt capture
535 			 * component and not to stack so free them.
536 			 */
537 			if (status == RX_OFFLOAD_PKT)
538 				qdf_nbuf_free(nbuf);
539 
540 			pkt_capture_vdev_put_ref(vdev);
541 			return;
542 		}
543 
544 		if (frame_filter->data_rx_frame_filter &
545 		    PKT_CAPTURE_DATA_FRAME_TYPE_ALL) {
546 			pkt_capture_msdu_process_pkts(bssid, log_data,
547 						      vdev_id, soc, status);
548 		} else if (pkt_capture_is_frame_filter_set(
549 			   nbuf, frame_filter, IEEE80211_FC1_DIR_FROMDS)) {
550 			pkt_capture_msdu_process_pkts(bssid, log_data,
551 						      vdev_id, soc, status);
552 		} else {
553 			if (status == RX_OFFLOAD_PKT)
554 				qdf_nbuf_free(nbuf);
555 		}
556 
557 		break;
558 	}
559 
560 	case WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER:
561 	{
562 		qdf_nbuf_t nbuf = (qdf_nbuf_t)log_data;
563 
564 		if (!frame_filter->data_rx_frame_filter) {
565 			/*
566 			 * Rx offload packets are delivered only to pkt capture
567 			 * component and not to stack so free them.
568 			 */
569 			if (status == RX_OFFLOAD_PKT)
570 				qdf_nbuf_free(nbuf);
571 
572 			pkt_capture_vdev_put_ref(vdev);
573 			return;
574 		}
575 
576 		if (frame_filter->data_rx_frame_filter &
577 		    PKT_CAPTURE_DATA_FRAME_TYPE_ALL) {
578 			pkt_capture_process_rx_data_no_peer(soc, vdev_id, bssid,
579 							    status, nbuf);
580 		} else if (pkt_capture_is_frame_filter_set(
581 			   nbuf, frame_filter, IEEE80211_FC1_DIR_FROMDS)) {
582 			pkt_capture_process_rx_data_no_peer(soc, vdev_id, bssid,
583 							    status, nbuf);
584 		} else {
585 			if (status == RX_OFFLOAD_PKT)
586 				qdf_nbuf_free(nbuf);
587 		}
588 
589 		break;
590 	}
591 
592 	case WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA:
593 	{
594 		struct htt_tx_offload_deliver_ind_hdr_t *offload_deliver_msg;
595 		bool is_pkt_during_roam = false;
596 		uint32_t freq = 0;
597 
598 		if (!frame_filter->data_tx_frame_filter) {
599 			pkt_capture_vdev_put_ref(vdev);
600 			return;
601 		}
602 
603 		offload_deliver_msg =
604 		(struct htt_tx_offload_deliver_ind_hdr_t *)log_data;
605 		is_pkt_during_roam =
606 		(offload_deliver_msg->reserved_2 ? true : false);
607 
608 		if (is_pkt_during_roam) {
609 			vdev_id = HTT_INVALID_VDEV;
610 			freq =
611 			(uint32_t)offload_deliver_msg->reserved_3;
612 		} else {
613 			vdev_id = offload_deliver_msg->vdev_id;
614 		}
615 
616 		pkt_capture_offload_deliver_indication_handler(
617 							log_data,
618 							vdev_id, bssid, soc);
619 		break;
620 	}
621 
622 	case WDI_EVENT_PKT_CAPTURE_PPDU_STATS:
623 		pkt_capture_process_ppdu_stats(log_data);
624 		break;
625 
626 	default:
627 		break;
628 	}
629 	pkt_capture_vdev_put_ref(vdev);
630 }
631 
632 #else
pkt_capture_wdi_event_subscribe(struct wlan_objmgr_psoc * psoc)633 static void pkt_capture_wdi_event_subscribe(struct wlan_objmgr_psoc *psoc)
634 {
635 }
636 
pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc * psoc)637 static void pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc *psoc)
638 {
639 }
640 #endif
641 
pkt_capture_get_vdev()642 struct wlan_objmgr_vdev *pkt_capture_get_vdev()
643 {
644 	return gp_pkt_capture_vdev;
645 }
646 
pkt_capture_get_mode(struct wlan_objmgr_psoc * psoc)647 enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc)
648 {
649 	struct pkt_psoc_priv *psoc_priv;
650 
651 	if (!psoc) {
652 		pkt_capture_err("psoc is NULL");
653 		return PACKET_CAPTURE_MODE_DISABLE;
654 	}
655 
656 	psoc_priv = pkt_capture_psoc_get_priv(psoc);
657 	if (!psoc_priv) {
658 		pkt_capture_err("psoc_priv is NULL");
659 		return PACKET_CAPTURE_MODE_DISABLE;
660 	}
661 
662 	return psoc_priv->cfg_param.pkt_capture_mode;
663 }
664 
pkt_capture_is_tx_mgmt_enable(struct wlan_objmgr_pdev * pdev)665 bool pkt_capture_is_tx_mgmt_enable(struct wlan_objmgr_pdev *pdev)
666 {
667 	struct pkt_capture_vdev_priv *vdev_priv;
668 	struct wlan_objmgr_vdev *vdev;
669 	QDF_STATUS status = QDF_STATUS_SUCCESS;
670 	enum pkt_capture_config config;
671 
672 	vdev = pkt_capture_get_vdev();
673 	status = pkt_capture_vdev_get_ref(vdev);
674 	if (QDF_IS_STATUS_ERROR(status)) {
675 		pkt_capture_err("failed to get vdev ref");
676 		return false;
677 	}
678 
679 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
680 	if (!vdev_priv) {
681 		pkt_capture_err("vdev_priv is NULL");
682 		pkt_capture_vdev_put_ref(vdev);
683 		return false;
684 	}
685 
686 	config = pkt_capture_get_pktcap_config(vdev);
687 
688 	if (!(vdev_priv->frame_filter.mgmt_tx_frame_filter &
689 	    PKT_CAPTURE_MGMT_FRAME_TYPE_ALL)) {
690 		if (!(config & PACKET_CAPTURE_CONFIG_QOS_ENABLE)) {
691 			pkt_capture_vdev_put_ref(vdev);
692 			return false;
693 		}
694 	}
695 
696 	pkt_capture_vdev_put_ref(vdev);
697 	return true;
698 }
699 
700 QDF_STATUS
pkt_capture_register_callbacks(struct wlan_objmgr_vdev * vdev,QDF_STATUS (* mon_cb)(void *,qdf_nbuf_t),void * context)701 pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev,
702 			       QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t),
703 			       void *context)
704 {
705 	struct pkt_capture_vdev_priv *vdev_priv;
706 	struct pkt_psoc_priv *psoc_priv;
707 	struct wlan_objmgr_psoc *psoc;
708 	enum pkt_capture_mode mode;
709 	QDF_STATUS status;
710 
711 	if (!vdev) {
712 		pkt_capture_err("vdev is NULL");
713 		return QDF_STATUS_E_INVAL;
714 	}
715 
716 	psoc = wlan_vdev_get_psoc(vdev);
717 	if (!psoc) {
718 		pkt_capture_err("psoc is NULL");
719 		return QDF_STATUS_E_INVAL;
720 	}
721 
722 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
723 	if (!vdev_priv) {
724 		pkt_capture_err("vdev priv is NULL");
725 		return QDF_STATUS_E_INVAL;
726 	}
727 
728 	vdev_priv->cb_ctx->mon_cb = mon_cb;
729 	vdev_priv->cb_ctx->mon_ctx = context;
730 
731 	status = pkt_capture_mgmt_rx_ops(psoc, true);
732 	if (QDF_IS_STATUS_ERROR(status)) {
733 		pkt_capture_err("Failed to register pkt capture mgmt rx ops");
734 		goto mgmt_rx_ops_fail;
735 	}
736 
737 	psoc_priv = pkt_capture_psoc_get_priv(psoc);
738 	if (!psoc_priv) {
739 		pkt_capture_err("psoc_priv is NULL");
740 		return QDF_STATUS_E_INVAL;
741 	}
742 
743 	target_if_pkt_capture_register_tx_ops(&psoc_priv->tx_ops);
744 	target_if_pkt_capture_register_rx_ops(&psoc_priv->rx_ops);
745 	pkt_capture_wdi_event_subscribe(psoc);
746 	pkt_capture_record_channel(vdev);
747 	vdev_priv->curr_freq = vdev->vdev_mlme.des_chan->ch_freq;
748 	vdev_priv->last_freq = vdev_priv->curr_freq;
749 
750 	status = tgt_pkt_capture_register_ev_handler(vdev);
751 	if (QDF_IS_STATUS_ERROR(status))
752 		goto register_ev_handlers_fail;
753 
754 	/*
755 	 * set register event bit so that mon thread will start
756 	 * processing packets in queue.
757 	 */
758 	set_bit(PKT_CAPTURE_REGISTER_EVENT,
759 		&vdev_priv->mon_ctx->mon_event_flag);
760 
761 	mode = pkt_capture_get_mode(psoc);
762 	status = tgt_pkt_capture_send_mode(vdev, mode);
763 	if (QDF_IS_STATUS_ERROR(status)) {
764 		pkt_capture_err("Unable to send packet capture mode to fw");
765 		goto send_mode_fail;
766 	}
767 
768 	qdf_wake_lock_acquire(&vdev_priv->wake_lock,
769 			      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
770 	qdf_runtime_pm_prevent_suspend(&vdev_priv->runtime_lock);
771 
772 	return QDF_STATUS_SUCCESS;
773 
774 send_mode_fail:
775 	tgt_pkt_capture_unregister_ev_handler(vdev);
776 register_ev_handlers_fail:
777 	pkt_capture_mgmt_rx_ops(psoc, false);
778 mgmt_rx_ops_fail:
779 	vdev_priv->cb_ctx->mon_cb = NULL;
780 	vdev_priv->cb_ctx->mon_ctx = NULL;
781 
782 	return status;
783 }
784 
pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev * vdev)785 QDF_STATUS pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev)
786 {
787 	struct pkt_capture_vdev_priv *vdev_priv;
788 	struct wlan_objmgr_psoc *psoc;
789 	QDF_STATUS status;
790 
791 	if (!vdev) {
792 		pkt_capture_err("vdev is NULL");
793 		return QDF_STATUS_E_INVAL;
794 	}
795 
796 	psoc = wlan_vdev_get_psoc(vdev);
797 	if (!psoc) {
798 		pkt_capture_err("psoc is NULL");
799 		return QDF_STATUS_E_INVAL;
800 	}
801 
802 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
803 	if (!vdev_priv) {
804 		pkt_capture_err("vdev priv is NULL");
805 		return QDF_STATUS_E_INVAL;
806 	}
807 
808 	status = tgt_pkt_capture_send_mode(vdev, PACKET_CAPTURE_MODE_DISABLE);
809 	if (QDF_IS_STATUS_ERROR(status))
810 		pkt_capture_err("Unable to send packet capture mode to fw");
811 
812 	/*
813 	 * Clear packet capture register event so that mon thread will
814 	 * stop processing packets in queue.
815 	 */
816 	clear_bit(PKT_CAPTURE_REGISTER_EVENT,
817 		  &vdev_priv->mon_ctx->mon_event_flag);
818 	set_bit(PKT_CAPTURE_RX_POST_EVENT,
819 		&vdev_priv->mon_ctx->mon_event_flag);
820 	reinit_completion(&vdev_priv->mon_ctx->mon_register_event);
821 	wake_up_interruptible(&vdev_priv->mon_ctx->mon_wait_queue);
822 
823 	/*
824 	 * Wait till current packet process completes in mon thread and
825 	 * flush the remaining packet in queue.
826 	 */
827 	wait_for_completion(&vdev_priv->mon_ctx->mon_register_event);
828 	pkt_capture_drop_monpkt(vdev_priv->mon_ctx);
829 
830 	pkt_capture_wdi_event_unsubscribe(psoc);
831 	status = tgt_pkt_capture_unregister_ev_handler(vdev);
832 	if (QDF_IS_STATUS_ERROR(status))
833 		pkt_capture_err("Unable to unregister event handlers");
834 
835 	status = pkt_capture_mgmt_rx_ops(psoc, false);
836 	if (QDF_IS_STATUS_ERROR(status))
837 		pkt_capture_err("Failed to unregister pkt capture mgmt rx ops");
838 
839 	vdev_priv->cb_ctx->mon_cb = NULL;
840 	vdev_priv->cb_ctx->mon_ctx = NULL;
841 
842 	qdf_wake_lock_release(&vdev_priv->wake_lock,
843 			      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
844 	qdf_runtime_pm_allow_suspend(&vdev_priv->runtime_lock);
845 
846 	return QDF_STATUS_SUCCESS;
847 }
848 
pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc * psoc,enum pkt_capture_mode mode)849 void pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc,
850 				 enum pkt_capture_mode mode)
851 {
852 	struct pkt_capture_vdev_priv *vdev_priv;
853 	struct wlan_objmgr_vdev *vdev;
854 
855 	if (!psoc) {
856 		pkt_capture_err("psoc is NULL");
857 		return;
858 	}
859 
860 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc,
861 							QDF_STA_MODE,
862 							WLAN_PKT_CAPTURE_ID);
863 	if (!vdev) {
864 		pkt_capture_err("vdev is NULL");
865 		return;
866 	}
867 
868 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
869 	if (vdev_priv)
870 		vdev_priv->cfg_params.pkt_capture_mode = mode;
871 	else
872 		pkt_capture_err("vdev_priv is NULL");
873 
874 	wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
875 }
876 
877 enum pkt_capture_mode
pkt_capture_get_pktcap_mode(struct wlan_objmgr_psoc * psoc)878 pkt_capture_get_pktcap_mode(struct wlan_objmgr_psoc *psoc)
879 {
880 	enum pkt_capture_mode mode = PACKET_CAPTURE_MODE_DISABLE;
881 	struct pkt_capture_vdev_priv *vdev_priv;
882 	struct wlan_objmgr_vdev *vdev;
883 
884 	if (!psoc) {
885 		pkt_capture_err("psoc is NULL");
886 		return 0;
887 	}
888 
889 	if (!pkt_capture_get_mode(psoc))
890 		return 0;
891 
892 	vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc,
893 							QDF_STA_MODE,
894 							WLAN_PKT_CAPTURE_ID);
895 	if (!vdev)
896 		return 0;
897 
898 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
899 	if (!vdev_priv)
900 		pkt_capture_err("vdev_priv is NULL");
901 	else
902 		mode = vdev_priv->cfg_params.pkt_capture_mode;
903 
904 	wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID);
905 	return mode;
906 }
907 
pkt_capture_set_pktcap_config(struct wlan_objmgr_vdev * vdev,enum pkt_capture_config config)908 void pkt_capture_set_pktcap_config(struct wlan_objmgr_vdev *vdev,
909 				   enum pkt_capture_config config)
910 {
911 	struct pkt_capture_vdev_priv *vdev_priv;
912 
913 	if (!vdev) {
914 		pkt_capture_err("vdev is NULL");
915 		return;
916 	}
917 
918 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
919 	if (vdev_priv)
920 		vdev_priv->cfg_params.pkt_capture_config = config;
921 	else
922 		pkt_capture_err("vdev_priv is NULL");
923 }
924 
925 enum pkt_capture_config
pkt_capture_get_pktcap_config(struct wlan_objmgr_vdev * vdev)926 pkt_capture_get_pktcap_config(struct wlan_objmgr_vdev *vdev)
927 {
928 	enum pkt_capture_config config = 0;
929 	struct pkt_capture_vdev_priv *vdev_priv;
930 
931 	if (!vdev)
932 		return 0;
933 
934 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
935 	if (!vdev_priv)
936 		pkt_capture_err("vdev_priv is NULL");
937 	else
938 		config = vdev_priv->cfg_params.pkt_capture_config;
939 
940 	return config;
941 }
942 
943 /**
944  * pkt_capture_callback_ctx_create() - Create packet capture callback context
945  * @vdev_priv: pointer to packet capture vdev priv obj
946  *
947  * Return: QDF_STATUS
948  */
949 static QDF_STATUS
pkt_capture_callback_ctx_create(struct pkt_capture_vdev_priv * vdev_priv)950 pkt_capture_callback_ctx_create(struct pkt_capture_vdev_priv *vdev_priv)
951 {
952 	struct pkt_capture_cb_context *cb_ctx;
953 
954 	cb_ctx = qdf_mem_malloc(sizeof(*cb_ctx));
955 	if (!cb_ctx)
956 		return QDF_STATUS_E_NOMEM;
957 
958 	vdev_priv->cb_ctx = cb_ctx;
959 
960 	return QDF_STATUS_SUCCESS;
961 }
962 
963 /**
964  * pkt_capture_callback_ctx_destroy() - Destroy packet capture callback context
965  * @vdev_priv: pointer to packet capture vdev priv obj
966  *
967  * Return: None
968  */
969 static void
pkt_capture_callback_ctx_destroy(struct pkt_capture_vdev_priv * vdev_priv)970 pkt_capture_callback_ctx_destroy(struct pkt_capture_vdev_priv *vdev_priv)
971 {
972 	qdf_mem_free(vdev_priv->cb_ctx);
973 }
974 
975 /**
976  * pkt_capture_mon_context_create() - Create packet capture mon context
977  * @vdev_priv: pointer to packet capture vdev priv obj
978  *
979  * This function allocates memory for packet capture mon context
980  *
981  * Return: QDF_STATUS
982  */
983 static QDF_STATUS
pkt_capture_mon_context_create(struct pkt_capture_vdev_priv * vdev_priv)984 pkt_capture_mon_context_create(struct pkt_capture_vdev_priv *vdev_priv)
985 {
986 	struct pkt_capture_mon_context *mon_context;
987 
988 	mon_context = qdf_mem_malloc(sizeof(*mon_context));
989 	if (!mon_context)
990 		return QDF_STATUS_E_NOMEM;
991 
992 	vdev_priv->mon_ctx = mon_context;
993 
994 	return QDF_STATUS_SUCCESS;
995 }
996 
997 /**
998  * pkt_capture_mon_context_destroy() - Destroy packet capture mon context
999  * @vdev_priv: pointer to packet capture vdev priv obj
1000  *
1001  * Free packet capture mon context
1002  *
1003  * Return: None
1004  */
1005 static void
pkt_capture_mon_context_destroy(struct pkt_capture_vdev_priv * vdev_priv)1006 pkt_capture_mon_context_destroy(struct pkt_capture_vdev_priv *vdev_priv)
1007 {
1008 	qdf_mem_free(vdev_priv->mon_ctx);
1009 }
1010 
pkt_capture_drop_nbuf_list(qdf_nbuf_t buf_list)1011 uint32_t pkt_capture_drop_nbuf_list(qdf_nbuf_t buf_list)
1012 {
1013 	qdf_nbuf_t buf, next_buf;
1014 	uint32_t num_dropped = 0;
1015 
1016 	buf = buf_list;
1017 	while (buf) {
1018 		QDF_NBUF_CB_RX_PEER_CACHED_FRM(buf) = 1;
1019 		next_buf = qdf_nbuf_queue_next(buf);
1020 		qdf_nbuf_free(buf);
1021 		buf = next_buf;
1022 		num_dropped++;
1023 	}
1024 	return num_dropped;
1025 }
1026 
1027 /**
1028  * pkt_capture_cfg_init() - Initialize packet capture cfg ini params
1029  * @psoc_priv: psoc private object
1030  *
1031  * Return: None
1032  */
1033 static void
pkt_capture_cfg_init(struct pkt_psoc_priv * psoc_priv)1034 pkt_capture_cfg_init(struct pkt_psoc_priv *psoc_priv)
1035 {
1036 	struct pkt_capture_cfg *cfg_param;
1037 
1038 	cfg_param = &psoc_priv->cfg_param;
1039 
1040 	cfg_param->pkt_capture_mode = cfg_get(psoc_priv->psoc,
1041 					      CFG_PKT_CAPTURE_MODE);
1042 }
1043 
1044 QDF_STATUS
pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev * vdev,void * arg)1045 pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
1046 {
1047 	struct pkt_capture_mon_context *mon_ctx;
1048 	struct pkt_capture_vdev_priv *vdev_priv;
1049 	QDF_STATUS status;
1050 
1051 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1052 	    !pkt_capture_get_mode(wlan_vdev_get_psoc(vdev)))
1053 		return QDF_STATUS_SUCCESS;
1054 
1055 	vdev_priv = qdf_mem_malloc(sizeof(*vdev_priv));
1056 	if (!vdev_priv)
1057 		return QDF_STATUS_E_NOMEM;
1058 
1059 	status = wlan_objmgr_vdev_component_obj_attach(
1060 					vdev,
1061 					WLAN_UMAC_COMP_PKT_CAPTURE,
1062 					vdev_priv, QDF_STATUS_SUCCESS);
1063 	if (QDF_IS_STATUS_ERROR(status)) {
1064 		pkt_capture_err("Failed to attach vdev component obj");
1065 		goto free_vdev_priv;
1066 	}
1067 
1068 	vdev_priv->vdev = vdev;
1069 	gp_pkt_capture_vdev = vdev;
1070 
1071 	status = pkt_capture_callback_ctx_create(vdev_priv);
1072 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1073 		pkt_capture_err("Failed to create callback context");
1074 		goto detach_vdev_priv;
1075 	}
1076 
1077 	status = pkt_capture_mon_context_create(vdev_priv);
1078 	if (QDF_IS_STATUS_ERROR(status)) {
1079 		pkt_capture_err("Failed to create mon context");
1080 		goto destroy_pkt_capture_cb_context;
1081 	}
1082 
1083 	mon_ctx = vdev_priv->mon_ctx;
1084 
1085 	status = pkt_capture_alloc_mon_thread(mon_ctx);
1086 	if (QDF_IS_STATUS_ERROR(status)) {
1087 		pkt_capture_err("Failed to alloc mon thread");
1088 		goto destroy_mon_context;
1089 	}
1090 
1091 	status = pkt_capture_open_mon_thread(mon_ctx);
1092 	if (QDF_IS_STATUS_ERROR(status)) {
1093 		pkt_capture_err("Failed to open mon thread");
1094 		goto open_mon_thread_fail;
1095 	}
1096 	qdf_spinlock_create(&vdev_priv->lock_q);
1097 	qdf_list_create(&vdev_priv->ppdu_stats_q, PPDU_STATS_Q_MAX_SIZE);
1098 	qdf_wake_lock_create(&vdev_priv->wake_lock, "pkt_capture_mode");
1099 	qdf_runtime_lock_init(&vdev_priv->runtime_lock);
1100 
1101 	return status;
1102 
1103 open_mon_thread_fail:
1104 	pkt_capture_free_mon_pkt_freeq(mon_ctx);
1105 destroy_mon_context:
1106 	pkt_capture_mon_context_destroy(vdev_priv);
1107 destroy_pkt_capture_cb_context:
1108 	pkt_capture_callback_ctx_destroy(vdev_priv);
1109 detach_vdev_priv:
1110 	wlan_objmgr_vdev_component_obj_detach(vdev,
1111 					      WLAN_UMAC_COMP_PKT_CAPTURE,
1112 					      vdev_priv);
1113 free_vdev_priv:
1114 	qdf_mem_free(vdev_priv);
1115 	return status;
1116 }
1117 
1118 QDF_STATUS
pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev * vdev,void * arg)1119 pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
1120 {
1121 	struct pkt_capture_vdev_priv *vdev_priv;
1122 	struct pkt_capture_ppdu_stats_q_node *stats_node;
1123 	qdf_list_node_t *node;
1124 	QDF_STATUS status;
1125 
1126 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
1127 	    !pkt_capture_get_mode(wlan_vdev_get_psoc(vdev)))
1128 		return QDF_STATUS_SUCCESS;
1129 
1130 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
1131 	if (!vdev_priv) {
1132 		pkt_capture_err("vdev priv is NULL");
1133 		return QDF_STATUS_E_FAILURE;
1134 	}
1135 
1136 	qdf_runtime_lock_deinit(&vdev_priv->runtime_lock);
1137 	qdf_wake_lock_destroy(&vdev_priv->wake_lock);
1138 
1139 	while (qdf_list_remove_front(&vdev_priv->ppdu_stats_q, &node)
1140 	       == QDF_STATUS_SUCCESS) {
1141 		stats_node = qdf_container_of(
1142 			node, struct pkt_capture_ppdu_stats_q_node, node);
1143 		qdf_mem_free(stats_node);
1144 	}
1145 	qdf_list_destroy(&vdev_priv->ppdu_stats_q);
1146 	qdf_spinlock_destroy(&vdev_priv->lock_q);
1147 
1148 	status = wlan_objmgr_vdev_component_obj_detach(
1149 					vdev,
1150 					WLAN_UMAC_COMP_PKT_CAPTURE,
1151 					vdev_priv);
1152 	if (QDF_IS_STATUS_ERROR(status))
1153 		pkt_capture_err("Failed to detach vdev component obj");
1154 
1155 	pkt_capture_close_mon_thread(vdev_priv->mon_ctx);
1156 	pkt_capture_mon_context_destroy(vdev_priv);
1157 	pkt_capture_callback_ctx_destroy(vdev_priv);
1158 
1159 	qdf_mem_free(vdev_priv);
1160 	gp_pkt_capture_vdev = NULL;
1161 	return status;
1162 }
1163 
1164 QDF_STATUS
pkt_capture_psoc_create_notification(struct wlan_objmgr_psoc * psoc,void * arg)1165 pkt_capture_psoc_create_notification(struct wlan_objmgr_psoc *psoc, void *arg)
1166 {
1167 	struct pkt_psoc_priv *psoc_priv;
1168 	QDF_STATUS status;
1169 
1170 	psoc_priv = qdf_mem_malloc(sizeof(*psoc_priv));
1171 	if (!psoc_priv)
1172 		return QDF_STATUS_E_NOMEM;
1173 
1174 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
1175 				WLAN_UMAC_COMP_PKT_CAPTURE,
1176 				psoc_priv, QDF_STATUS_SUCCESS);
1177 	if (QDF_IS_STATUS_ERROR(status)) {
1178 		pkt_capture_err("Failed to attach psoc component obj");
1179 		goto free_psoc_priv;
1180 	}
1181 
1182 	psoc_priv->psoc = psoc;
1183 	pkt_capture_cfg_init(psoc_priv);
1184 
1185 	return status;
1186 
1187 free_psoc_priv:
1188 	qdf_mem_free(psoc_priv);
1189 	return status;
1190 }
1191 
1192 QDF_STATUS
pkt_capture_psoc_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg)1193 pkt_capture_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg)
1194 {
1195 	struct pkt_psoc_priv *psoc_priv;
1196 	QDF_STATUS status;
1197 
1198 	psoc_priv = pkt_capture_psoc_get_priv(psoc);
1199 	if (!psoc_priv) {
1200 		pkt_capture_err("psoc priv is NULL");
1201 		return QDF_STATUS_E_FAILURE;
1202 	}
1203 
1204 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
1205 					WLAN_UMAC_COMP_PKT_CAPTURE,
1206 					psoc_priv);
1207 	if (QDF_IS_STATUS_ERROR(status)) {
1208 		pkt_capture_err("Failed to detach psoc component obj");
1209 		return status;
1210 	}
1211 
1212 	qdf_mem_free(psoc_priv);
1213 	return status;
1214 }
1215 
pkt_capture_record_channel(struct wlan_objmgr_vdev * vdev)1216 void pkt_capture_record_channel(struct wlan_objmgr_vdev *vdev)
1217 {
1218 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1219 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1220 	struct wlan_channel *des_chan;
1221 	cdp_config_param_type val;
1222 	struct wlan_objmgr_psoc *psoc;
1223 
1224 	psoc = wlan_vdev_get_psoc(vdev);
1225 
1226 	if (!pkt_capture_get_mode(psoc))
1227 		return;
1228 	/*
1229 	 * Record packet capture channel here
1230 	 */
1231 	des_chan = vdev->vdev_mlme.des_chan;
1232 	val.cdp_pdev_param_monitor_chan = des_chan->ch_ieee;
1233 	cdp_txrx_set_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(pdev),
1234 				CDP_MONITOR_CHANNEL, val);
1235 	val.cdp_pdev_param_mon_freq = des_chan->ch_freq;
1236 	cdp_txrx_set_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(pdev),
1237 				CDP_MONITOR_FREQUENCY, val);
1238 }
1239 
pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,struct wlan_objmgr_vdev * vdev)1240 QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
1241 				  struct wlan_objmgr_vdev *vdev)
1242 {
1243 	struct pkt_capture_vdev_priv *vdev_priv;
1244 	struct wlan_objmgr_psoc *psoc;
1245 	enum pkt_capture_mode mode = PACKET_CAPTURE_MODE_DISABLE;
1246 	ol_txrx_soc_handle soc;
1247 	QDF_STATUS status;
1248 	enum pkt_capture_config config = 0;
1249 	bool send_bcn = 0;
1250 	struct vdev_mlme_obj *vdev_mlme;
1251 	uint32_t bcn_interval, nth_beacon_value;
1252 
1253 	if (!vdev) {
1254 		pkt_capture_err("vdev is NULL");
1255 		return QDF_STATUS_E_FAILURE;
1256 	}
1257 
1258 	vdev_priv = pkt_capture_vdev_get_priv(vdev);
1259 	if (!vdev_priv) {
1260 		pkt_capture_err("vdev_priv is NULL");
1261 		return QDF_STATUS_E_FAILURE;
1262 	}
1263 
1264 	psoc = wlan_vdev_get_psoc(vdev);
1265 	if (!psoc) {
1266 		pkt_capture_err("psoc is NULL");
1267 		return QDF_STATUS_E_FAILURE;
1268 	}
1269 
1270 	soc = cds_get_context(QDF_MODULE_ID_SOC);
1271 	if (!soc) {
1272 		pkt_capture_err("Invalid soc");
1273 		return QDF_STATUS_E_FAILURE;
1274 	}
1275 
1276 	if (frame_filter.vendor_attr_to_set &
1277 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE))
1278 		vdev_priv->frame_filter.data_tx_frame_filter =
1279 			frame_filter.data_tx_frame_filter;
1280 
1281 	if (frame_filter.vendor_attr_to_set &
1282 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE))
1283 		vdev_priv->frame_filter.data_rx_frame_filter =
1284 			frame_filter.data_rx_frame_filter;
1285 
1286 	if (frame_filter.vendor_attr_to_set &
1287 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE))
1288 		vdev_priv->frame_filter.mgmt_tx_frame_filter =
1289 			frame_filter.mgmt_tx_frame_filter;
1290 
1291 	if (frame_filter.vendor_attr_to_set &
1292 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE))
1293 		vdev_priv->frame_filter.mgmt_rx_frame_filter =
1294 			frame_filter.mgmt_rx_frame_filter;
1295 
1296 	if (frame_filter.vendor_attr_to_set &
1297 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE))
1298 		vdev_priv->frame_filter.ctrl_tx_frame_filter =
1299 			frame_filter.ctrl_tx_frame_filter;
1300 
1301 	if (frame_filter.vendor_attr_to_set &
1302 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE))
1303 		vdev_priv->frame_filter.ctrl_rx_frame_filter =
1304 			frame_filter.ctrl_rx_frame_filter;
1305 
1306 	if (frame_filter.vendor_attr_to_set &
1307 	    BIT(PKT_CAPTURE_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL)) {
1308 		if (frame_filter.connected_beacon_interval !=
1309 		    vdev_priv->frame_filter.connected_beacon_interval) {
1310 			vdev_priv->frame_filter.connected_beacon_interval =
1311 				frame_filter.connected_beacon_interval;
1312 			send_bcn = 1;
1313 		}
1314 	}
1315 
1316 	if (vdev_priv->frame_filter.mgmt_tx_frame_filter)
1317 		mode |= PACKET_CAPTURE_MODE_MGMT_ONLY;
1318 
1319 	if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
1320 	    PKT_CAPTURE_MGMT_FRAME_TYPE_ALL) {
1321 		mode |= PACKET_CAPTURE_MODE_MGMT_ONLY;
1322 		vdev_priv->frame_filter.mgmt_rx_frame_filter |=
1323 					PKT_CAPTURE_MGMT_CONNECT_BEACON;
1324 		vdev_priv->frame_filter.mgmt_rx_frame_filter |=
1325 					PKT_CAPTURE_MGMT_CONNECT_SCAN_BEACON;
1326 		if (!send_bcn)
1327 			config |= PACKET_CAPTURE_CONFIG_BEACON_ENABLE;
1328 		config |= PACKET_CAPTURE_CONFIG_OFF_CHANNEL_BEACON_ENABLE;
1329 	} else {
1330 		if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
1331 		    PKT_CAPTURE_MGMT_CONNECT_NO_BEACON) {
1332 			mode |= PACKET_CAPTURE_MODE_MGMT_ONLY;
1333 			config |= PACKET_CAPTURE_CONFIG_NO_BEACON_ENABLE;
1334 		}
1335 
1336 		if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
1337 		    PKT_CAPTURE_MGMT_CONNECT_BEACON) {
1338 			if (!send_bcn)
1339 				config |= PACKET_CAPTURE_CONFIG_BEACON_ENABLE;
1340 		}
1341 
1342 		if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
1343 		    PKT_CAPTURE_MGMT_CONNECT_SCAN_BEACON)
1344 			config |=
1345 				PACKET_CAPTURE_CONFIG_OFF_CHANNEL_BEACON_ENABLE;
1346 	}
1347 
1348 	if (vdev_priv->frame_filter.data_tx_frame_filter ||
1349 	    vdev_priv->frame_filter.data_rx_frame_filter)
1350 		mode |= PACKET_CAPTURE_MODE_DATA_ONLY;
1351 
1352 	if (mode != pkt_capture_get_pktcap_mode(psoc)) {
1353 		status = tgt_pkt_capture_send_mode(vdev, mode);
1354 		if (QDF_IS_STATUS_ERROR(status)) {
1355 			pkt_capture_err("Unable to send packet capture mode");
1356 			return status;
1357 		}
1358 
1359 		if (mode & PACKET_CAPTURE_MODE_DATA_ONLY)
1360 			cdp_set_pkt_capture_mode(soc, true);
1361 	}
1362 
1363 	if (vdev_priv->frame_filter.ctrl_tx_frame_filter ||
1364 	    vdev_priv->frame_filter.ctrl_rx_frame_filter)
1365 		config |= PACKET_CAPTURE_CONFIG_TRIGGER_ENABLE;
1366 
1367 	if ((vdev_priv->frame_filter.data_tx_frame_filter &
1368 	    PKT_CAPTURE_DATA_FRAME_TYPE_ALL) ||
1369 	    (vdev_priv->frame_filter.data_tx_frame_filter &
1370 	    PKT_CAPTURE_DATA_FRAME_QOS_NULL))
1371 		config |= PACKET_CAPTURE_CONFIG_QOS_ENABLE;
1372 
1373 	if (config != pkt_capture_get_pktcap_config(vdev)) {
1374 		status = tgt_pkt_capture_send_config(vdev, config);
1375 		if (QDF_IS_STATUS_ERROR(status)) {
1376 			pkt_capture_err("packet capture send config failed");
1377 			return status;
1378 		}
1379 	}
1380 
1381 	if (send_bcn) {
1382 		vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(
1383 							vdev,
1384 							WLAN_UMAC_COMP_MLME);
1385 
1386 		if (!vdev_mlme)
1387 			return QDF_STATUS_E_FAILURE;
1388 
1389 		wlan_util_vdev_mlme_get_param(vdev_mlme,
1390 					      WLAN_MLME_CFG_BEACON_INTERVAL,
1391 					      &bcn_interval);
1392 
1393 		if (bcn_interval &&
1394 		    (vdev_priv->frame_filter.connected_beacon_interval >
1395 		    bcn_interval || vdev_priv->
1396 		    frame_filter.connected_beacon_interval == 0)) {
1397 			nth_beacon_value =
1398 				vdev_priv->
1399 				frame_filter.connected_beacon_interval /
1400 				bcn_interval;
1401 
1402 			status = tgt_pkt_capture_send_beacon_interval(
1403 							vdev,
1404 							nth_beacon_value);
1405 
1406 			if (QDF_IS_STATUS_ERROR(status)) {
1407 				pkt_capture_err("send beacon interval fail");
1408 				return status;
1409 			}
1410 		} else {
1411 			pkt_capture_debug(
1412 			"Failed to set beacon interval %d, it should be >= %d",
1413 			vdev_priv->frame_filter.connected_beacon_interval,
1414 			bcn_interval);
1415 		}
1416 	}
1417 	return QDF_STATUS_SUCCESS;
1418 }
1419