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