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 #include <wlan_pkt_capture_data_txrx.h>
26 #include <wlan_pkt_capture_main.h>
27 #include <enet.h>
28 #include <wlan_reg_services_api.h>
29 #include <cds_ieee80211_common.h>
30 #include <ol_txrx_htt_api.h>
31 #include "wlan_policy_mgr_ucfg.h"
32 #include "hal_rx.h"
33 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
34 #include "dp_internal.h"
35 #include "cds_utils.h"
36 #include "htt_ppdu_stats.h"
37 #include <cdp_txrx_ctrl.h>
38 #endif
39
40 #define RESERVE_BYTES (100)
41
42 /**
43 * pkt_capture_txrx_status_map() - map Tx status for data packets
44 * with packet capture Tx status
45 * @status: Tx status
46 *
47 * Return: pkt_capture_tx_status enum
48 */
49 static enum pkt_capture_tx_status
pkt_capture_txrx_status_map(uint8_t status)50 pkt_capture_txrx_status_map(uint8_t status)
51 {
52 enum pkt_capture_tx_status tx_status;
53
54 switch (status) {
55 case htt_tx_status_ok:
56 tx_status = pkt_capture_tx_status_ok;
57 break;
58 case htt_tx_status_no_ack:
59 tx_status = pkt_capture_tx_status_no_ack;
60 break;
61 default:
62 tx_status = pkt_capture_tx_status_discard;
63 break;
64 }
65
66 return tx_status;
67 }
68
69 /**
70 * pkt_capture_get_tx_rate() - get tx rate for tx packet
71 * @preamble_type: preamble type
72 * @rate: rate code
73 * @preamble: preamble
74 *
75 * Return: rate
76 */
pkt_capture_get_tx_rate(uint8_t preamble_type,uint8_t rate,uint8_t * preamble)77 static unsigned char pkt_capture_get_tx_rate(
78 uint8_t preamble_type,
79 uint8_t rate,
80 uint8_t *preamble)
81 {
82 char ret = 0x0;
83 *preamble = LONG_PREAMBLE;
84
85 if (preamble_type == 0) {
86 switch (rate) {
87 case 0x0:
88 ret = 0x60;
89 break;
90 case 0x1:
91 ret = 0x30;
92 break;
93 case 0x2:
94 ret = 0x18;
95 break;
96 case 0x3:
97 ret = 0x0c;
98 break;
99 case 0x4:
100 ret = 0x6c;
101 break;
102 case 0x5:
103 ret = 0x48;
104 break;
105 case 0x6:
106 ret = 0x24;
107 break;
108 case 0x7:
109 ret = 0x12;
110 break;
111 default:
112 break;
113 }
114 } else if (preamble_type == 1) {
115 switch (rate) {
116 case 0x0:
117 ret = 0x16;
118 *preamble = LONG_PREAMBLE;
119 break;
120 case 0x1:
121 ret = 0xB;
122 *preamble = LONG_PREAMBLE;
123 break;
124 case 0x2:
125 ret = 0x4;
126 *preamble = LONG_PREAMBLE;
127 break;
128 case 0x3:
129 ret = 0x2;
130 *preamble = LONG_PREAMBLE;
131 break;
132 case 0x4:
133 ret = 0x16;
134 *preamble = SHORT_PREAMBLE;
135 break;
136 case 0x5:
137 ret = 0xB;
138 *preamble = SHORT_PREAMBLE;
139 break;
140 case 0x6:
141 ret = 0x4;
142 *preamble = SHORT_PREAMBLE;
143 break;
144 default:
145 break;
146 }
147 } else {
148 qdf_print("Invalid rate info\n");
149 }
150 return ret;
151 }
152
153 /**
154 * pkt_capture_tx_get_phy_info() - get phy info for tx packets for pkt
155 * capture mode(normal tx + offloaded tx) to prepare radiotap header
156 * @pktcapture_hdr: tx data header
157 * @tx_status: tx status to be updated with phy info
158 *
159 * Return: none
160 */
pkt_capture_tx_get_phy_info(struct pkt_capture_tx_hdr_elem_t * pktcapture_hdr,struct mon_rx_status * tx_status)161 static void pkt_capture_tx_get_phy_info(
162 struct pkt_capture_tx_hdr_elem_t *pktcapture_hdr,
163 struct mon_rx_status *tx_status)
164 {
165 uint8_t preamble = 0;
166 uint8_t preamble_type = pktcapture_hdr->preamble;
167 uint8_t mcs = 0;
168
169 switch (preamble_type) {
170 case 0x0:
171 case 0x1:
172 /* legacy */
173 tx_status->rate = pkt_capture_get_tx_rate(
174 preamble_type,
175 pktcapture_hdr->rate,
176 &preamble);
177 break;
178 case 0x2:
179 tx_status->ht_flags = 1;
180 if (pktcapture_hdr->nss == 2)
181 mcs = 8 + pktcapture_hdr->mcs;
182 else
183 mcs = pktcapture_hdr->mcs;
184
185 tx_status->ht_mcs = mcs;
186 break;
187 case 0x3:
188 tx_status->vht_flags = 1;
189 mcs = pktcapture_hdr->mcs;
190 tx_status->vht_flag_values3[0] =
191 mcs << 0x4 | (pktcapture_hdr->nss);
192 tx_status->vht_flag_values2 = pktcapture_hdr->bw;
193 break;
194 case 0x4:
195 tx_status->he_flags = 1;
196 tx_status->he_data1 |=
197 IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
198 IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN |
199 IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN |
200 IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN;
201 tx_status->he_data2 |= IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN;
202 tx_status->he_data3 |= (pktcapture_hdr->mcs << 0x8) |
203 (pktcapture_hdr->ldpc << 0xd) |
204 (pktcapture_hdr->stbc << 0xf);
205 tx_status->he_data5 |=
206 (pktcapture_hdr->bw | (pktcapture_hdr->sgi << 0x4));
207 tx_status->he_data6 |= pktcapture_hdr->nss;
208 default:
209 break;
210 }
211
212 if (preamble_type != HAL_TX_PKT_TYPE_11B)
213 tx_status->ofdm_flag = 1;
214 else
215 tx_status->cck_flag = 1;
216
217 tx_status->mcs = mcs;
218 tx_status->bw = pktcapture_hdr->bw;
219 tx_status->nr_ant = pktcapture_hdr->nss;
220 tx_status->nss = pktcapture_hdr->nss;
221 tx_status->is_stbc = pktcapture_hdr->stbc;
222 tx_status->sgi = pktcapture_hdr->sgi;
223 tx_status->ldpc = pktcapture_hdr->ldpc;
224 tx_status->beamformed = pktcapture_hdr->beamformed;
225 tx_status->rtap_flags |= ((preamble == 1) ? BIT(1) : 0);
226 }
227
228 #ifndef WLAN_FEATURE_PKT_CAPTURE_V2
229 /**
230 * pkt_capture_update_tx_status() - tx status for tx packets, for
231 * pkt capture mode(normal tx + offloaded tx) to prepare radiotap header
232 * @pdev: device handler
233 * @tx_status: tx status to be updated
234 * @pktcapture_hdr: tx data header
235 *
236 * Return: none
237 */
238 static void
pkt_capture_update_tx_status(htt_pdev_handle pdev,struct mon_rx_status * tx_status,struct pkt_capture_tx_hdr_elem_t * pktcapture_hdr)239 pkt_capture_update_tx_status(
240 htt_pdev_handle pdev,
241 struct mon_rx_status *tx_status,
242 struct pkt_capture_tx_hdr_elem_t *pktcapture_hdr)
243 {
244 struct mon_channel *ch_info = &pdev->mon_ch_info;
245
246 tx_status->tsft = (u_int64_t)(pktcapture_hdr->timestamp);
247 tx_status->chan_freq = ch_info->ch_freq;
248 tx_status->chan_num = ch_info->ch_num;
249
250 pkt_capture_tx_get_phy_info(pktcapture_hdr, tx_status);
251
252 if (pktcapture_hdr->preamble == 0)
253 tx_status->ofdm_flag = 1;
254 else if (pktcapture_hdr->preamble == 1)
255 tx_status->cck_flag = 1;
256
257 tx_status->ant_signal_db = pktcapture_hdr->rssi_comb;
258 tx_status->rssi_comb = pktcapture_hdr->rssi_comb;
259 tx_status->tx_status = pktcapture_hdr->status;
260 tx_status->tx_retry_cnt = pktcapture_hdr->tx_retry_cnt;
261 tx_status->add_rtap_ext = true;
262 }
263 #else
264 static void
pkt_capture_update_tx_status(void * context,struct mon_rx_status * tx_status,struct pkt_capture_tx_hdr_elem_t * pktcapture_hdr)265 pkt_capture_update_tx_status(
266 void *context,
267 struct mon_rx_status *tx_status,
268 struct pkt_capture_tx_hdr_elem_t *pktcapture_hdr)
269 {
270 struct pkt_capture_vdev_priv *vdev_priv;
271 struct wlan_objmgr_vdev *vdev = context;
272 htt_ppdu_stats_for_smu_tlv *smu;
273 struct wlan_objmgr_psoc *psoc;
274 struct pkt_capture_ppdu_stats_q_node *q_node;
275 qdf_list_node_t *node;
276 cdp_config_param_type val;
277 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
278 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
279
280 psoc = wlan_vdev_get_psoc(vdev);
281 if (!psoc) {
282 pkt_capture_err("Failed to get psoc");
283 return;
284 }
285
286 if (!pdev) {
287 pkt_capture_err("pdev is NULL");
288 return;
289 }
290
291 if (!cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(pdev),
292 CDP_MONITOR_CHANNEL, &val))
293 tx_status->chan_num = val.cdp_pdev_param_monitor_chan;
294
295 if (!cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(pdev),
296 CDP_MONITOR_FREQUENCY, &val))
297 tx_status->chan_freq = val.cdp_pdev_param_mon_freq;
298
299 vdev_priv = pkt_capture_vdev_get_priv(vdev);
300 if (qdf_unlikely(!vdev_priv))
301 goto skip_ppdu_stats;
302
303 /* Fill the nss received from ppdu_stats */
304 pktcapture_hdr->nss = vdev_priv->tx_nss;
305
306 /* Remove the ppdu stats from front of list and fill it in tx_status */
307 qdf_spin_lock_bh(&vdev_priv->lock_q);
308 if (QDF_STATUS_SUCCESS ==
309 qdf_list_remove_front(&vdev_priv->ppdu_stats_q, &node)) {
310 qdf_spin_unlock_bh(&vdev_priv->lock_q);
311 q_node = qdf_container_of(
312 node, struct pkt_capture_ppdu_stats_q_node, node);
313 smu = (htt_ppdu_stats_for_smu_tlv *)(q_node->buf);
314 tx_status->prev_ppdu_id = smu->ppdu_id;
315 tx_status->start_seq = smu->start_seq;
316 tx_status->tid = smu->tid_num;
317
318 if (smu->win_size == 8)
319 qdf_mem_copy(tx_status->ba_bitmap, smu->ba_bitmap,
320 8 * sizeof(uint32_t));
321 else if (smu->win_size == 2)
322 qdf_mem_copy(tx_status->ba_bitmap, smu->ba_bitmap,
323 2 * sizeof(uint32_t));
324
325 qdf_mem_free(q_node);
326 } else {
327 qdf_spin_unlock_bh(&vdev_priv->lock_q);
328 }
329
330 skip_ppdu_stats:
331 pkt_capture_tx_get_phy_info(pktcapture_hdr, tx_status);
332
333 tx_status->tsft = (u_int64_t)(pktcapture_hdr->timestamp);
334 tx_status->ant_signal_db = pktcapture_hdr->rssi_comb;
335 tx_status->rssi_comb = pktcapture_hdr->rssi_comb;
336 tx_status->tx_status = pktcapture_hdr->status;
337 tx_status->tx_retry_cnt = pktcapture_hdr->tx_retry_cnt;
338 tx_status->ppdu_id = pktcapture_hdr->ppdu_id;
339 tx_status->add_rtap_ext = true;
340 tx_status->add_rtap_ext2 = true;
341 }
342 #endif
343
344 #ifndef WLAN_FEATURE_PKT_CAPTURE_V2
345 /**
346 * pkt_capture_rx_convert8023to80211() - convert 802.3 packet to 802.11
347 * format from rx desc
348 * @bssid: bssid
349 * @msdu: netbuf
350 * @desc: rx desc
351 *
352 * Return: none
353 */
354 static void
pkt_capture_rx_convert8023to80211(uint8_t * bssid,qdf_nbuf_t msdu,void * desc)355 pkt_capture_rx_convert8023to80211(uint8_t *bssid, qdf_nbuf_t msdu, void *desc)
356 {
357 struct ethernet_hdr_t *eth_hdr;
358 struct llc_snap_hdr_t *llc_hdr;
359 struct ieee80211_frame *wh;
360 uint8_t hdsize, new_hdsize;
361 struct ieee80211_qoscntl *qos_cntl;
362 uint16_t seq_no;
363 uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) +
364 sizeof(struct llc_snap_hdr_t)];
365 const uint8_t ethernet_II_llc_snap_header_prefix[] = {
366 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
367 uint16_t ether_type;
368
369 struct htt_host_rx_desc_base *rx_desc = desc;
370
371 eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
372 hdsize = sizeof(struct ethernet_hdr_t);
373 wh = (struct ieee80211_frame *)localbuf;
374
375 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
376 *(uint16_t *)wh->i_dur = 0;
377
378 new_hdsize = 0;
379
380 /* DA , BSSID , SA */
381 qdf_mem_copy(wh->i_addr1, eth_hdr->dest_addr,
382 QDF_MAC_ADDR_SIZE);
383 qdf_mem_copy(wh->i_addr2, bssid,
384 QDF_MAC_ADDR_SIZE);
385 qdf_mem_copy(wh->i_addr3, eth_hdr->src_addr,
386 QDF_MAC_ADDR_SIZE);
387
388 wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
389
390 if (rx_desc->attention.more_data)
391 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
392
393 if (rx_desc->attention.power_mgmt)
394 wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT;
395
396 if (rx_desc->attention.fragment)
397 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
398
399 if (rx_desc->attention.order)
400 wh->i_fc[1] |= IEEE80211_FC1_ORDER;
401
402 if (rx_desc->mpdu_start.retry)
403 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
404
405 seq_no = rx_desc->mpdu_start.seq_num;
406 seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) & IEEE80211_SEQ_SEQ_MASK;
407 qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no));
408
409 new_hdsize = sizeof(struct ieee80211_frame);
410
411 if (rx_desc->attention.non_qos == 0) {
412 qos_cntl =
413 (struct ieee80211_qoscntl *)(localbuf + new_hdsize);
414 qos_cntl->i_qos[0] =
415 (rx_desc->mpdu_start.tid & IEEE80211_QOS_TID);
416 wh->i_fc[0] |= QDF_IEEE80211_FC0_SUBTYPE_QOS;
417
418 qos_cntl->i_qos[1] = 0;
419 new_hdsize += sizeof(struct ieee80211_qoscntl);
420 }
421
422 /*
423 * Prepare llc Header
424 */
425 llc_hdr = (struct llc_snap_hdr_t *)(localbuf + new_hdsize);
426 ether_type = (eth_hdr->ethertype[0] << 8) |
427 (eth_hdr->ethertype[1]);
428 if (ether_type >= ETH_P_802_3_MIN) {
429 qdf_mem_copy(llc_hdr,
430 ethernet_II_llc_snap_header_prefix,
431 sizeof
432 (ethernet_II_llc_snap_header_prefix));
433 if (ether_type == ETHERTYPE_AARP ||
434 ether_type == ETHERTYPE_IPX) {
435 llc_hdr->org_code[2] =
436 BTEP_SNAP_ORGCODE_2;
437 /* 0xf8; bridge tunnel header */
438 }
439 llc_hdr->ethertype[0] = eth_hdr->ethertype[0];
440 llc_hdr->ethertype[1] = eth_hdr->ethertype[1];
441 new_hdsize += sizeof(struct llc_snap_hdr_t);
442 }
443
444 /*
445 * Remove 802.3 Header by adjusting the head
446 */
447 qdf_nbuf_pull_head(msdu, hdsize);
448
449 /*
450 * Adjust the head and prepare 802.11 Header
451 */
452 qdf_nbuf_push_head(msdu, new_hdsize);
453 qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize);
454 }
455 #else
456 static void
pkt_capture_rx_convert8023to80211(hal_soc_handle_t hal_soc_hdl,qdf_nbuf_t msdu,void * desc)457 pkt_capture_rx_convert8023to80211(hal_soc_handle_t hal_soc_hdl,
458 qdf_nbuf_t msdu, void *desc)
459 {
460 struct ethernet_hdr_t *eth_hdr;
461 struct llc_snap_hdr_t *llc_hdr;
462 struct ieee80211_frame *wh;
463 uint8_t *pwh;
464 uint8_t hdsize, new_hdsize;
465 struct ieee80211_qoscntl *qos_cntl;
466 static uint8_t first_msdu_hdr[sizeof(struct ieee80211_frame)];
467 uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) +
468 sizeof(struct llc_snap_hdr_t)];
469 const uint8_t ethernet_II_llc_snap_header_prefix[] = {
470 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
471 uint16_t ether_type;
472
473 uint32_t tid = 0;
474
475 eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
476 hdsize = sizeof(struct ethernet_hdr_t);
477
478 wh = (struct ieee80211_frame *)localbuf;
479
480 new_hdsize = sizeof(struct ieee80211_frame);
481
482 /*
483 * Only first msdu in mpdu has rx_tlv_hdr(802.11 hdr) filled by HW, so
484 * copy the 802.11 hdr to all other msdu's which are received in
485 * single mpdu from first msdu.
486 */
487 if (qdf_nbuf_is_rx_chfrag_start(msdu)) {
488 pwh = hal_rx_desc_get_80211_hdr(hal_soc_hdl, desc);
489 qdf_mem_copy(first_msdu_hdr, pwh,
490 sizeof(struct ieee80211_frame));
491 }
492
493 qdf_mem_copy(localbuf, first_msdu_hdr, new_hdsize);
494
495 /* Flush the cached 802.11 hdr once last msdu in mpdu is received */
496 if (qdf_nbuf_is_rx_chfrag_end(msdu))
497 qdf_mem_zero(first_msdu_hdr, sizeof(struct ieee80211_frame));
498
499 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
500 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
501
502 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
503 qos_cntl =
504 (struct ieee80211_qoscntl *)(localbuf + new_hdsize);
505 tid = hal_rx_mpdu_start_tid_get(hal_soc_hdl, desc);
506 qos_cntl->i_qos[0] = (tid & IEEE80211_QOS_TID);
507 wh->i_fc[0] |= QDF_IEEE80211_FC0_SUBTYPE_QOS;
508
509 qos_cntl->i_qos[1] = 0;
510 new_hdsize += sizeof(struct ieee80211_qoscntl);
511 }
512
513 /*
514 * Prepare llc Header
515 */
516
517 llc_hdr = (struct llc_snap_hdr_t *)(localbuf + new_hdsize);
518 ether_type = (eth_hdr->ethertype[0] << 8) |
519 (eth_hdr->ethertype[1]);
520 if (ether_type >= ETH_P_802_3_MIN) {
521 qdf_mem_copy(llc_hdr,
522 ethernet_II_llc_snap_header_prefix,
523 sizeof
524 (ethernet_II_llc_snap_header_prefix));
525 if (ether_type == ETHERTYPE_AARP ||
526 ether_type == ETHERTYPE_IPX) {
527 llc_hdr->org_code[2] =
528 BTEP_SNAP_ORGCODE_2;
529 /* 0xf8; bridge tunnel header */
530 }
531 llc_hdr->ethertype[0] = eth_hdr->ethertype[0];
532 llc_hdr->ethertype[1] = eth_hdr->ethertype[1];
533 new_hdsize += sizeof(struct llc_snap_hdr_t);
534 }
535
536 /*
537 * Remove 802.3 Header by adjusting the head
538 */
539 qdf_nbuf_pull_head(msdu, hdsize);
540
541 /*
542 * Adjust the head and prepare 802.11 Header
543 */
544 qdf_nbuf_push_head(msdu, new_hdsize);
545 qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize);
546 }
547 #endif
548
pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu)549 void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu)
550 {
551 while (head_msdu) {
552 qdf_nbuf_t msdu = head_msdu;
553
554 head_msdu = qdf_nbuf_next(head_msdu);
555 qdf_nbuf_free(msdu);
556 }
557 }
558
pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg)559 bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg)
560 {
561 uint32_t *msg_word;
562
563 msg_word = (uint32_t *)qdf_nbuf_data(rx_ind_msg);
564
565 /* check if it is for offloaded data pkt */
566 return HTT_RX_IN_ORD_PADDR_IND_PKT_CAPTURE_MODE_IS_MONITOR_SET
567 (*(msg_word + 1));
568 }
569
570 #ifndef WLAN_FEATURE_PKT_CAPTURE_V2
pkt_capture_msdu_process_pkts(uint8_t * bssid,qdf_nbuf_t head_msdu,uint8_t vdev_id,htt_pdev_handle pdev,uint16_t status)571 void pkt_capture_msdu_process_pkts(
572 uint8_t *bssid,
573 qdf_nbuf_t head_msdu, uint8_t vdev_id,
574 htt_pdev_handle pdev, uint16_t status)
575 {
576 qdf_nbuf_t loop_msdu, pktcapture_msdu;
577 qdf_nbuf_t msdu, prev = NULL;
578
579 pktcapture_msdu = NULL;
580 loop_msdu = head_msdu;
581 while (loop_msdu) {
582 msdu = qdf_nbuf_copy(loop_msdu);
583
584 if (msdu) {
585 qdf_nbuf_push_head(msdu,
586 HTT_RX_STD_DESC_RESERVATION);
587 qdf_nbuf_set_next(msdu, NULL);
588
589 if (!(pktcapture_msdu)) {
590 pktcapture_msdu = msdu;
591 prev = msdu;
592 } else {
593 qdf_nbuf_set_next(prev, msdu);
594 prev = msdu;
595 }
596 }
597 loop_msdu = qdf_nbuf_next(loop_msdu);
598 }
599
600 if (!pktcapture_msdu)
601 return;
602
603 pkt_capture_datapkt_process(
604 vdev_id, pktcapture_msdu,
605 TXRX_PROCESS_TYPE_DATA_RX, 0, 0,
606 TXRX_PKTCAPTURE_PKT_FORMAT_8023,
607 bssid, pdev, 0);
608 }
609 #else
610 #define RX_OFFLOAD_PKT 1
pkt_capture_msdu_process_pkts(uint8_t * bssid,qdf_nbuf_t head_msdu,uint8_t vdev_id,void * psoc,uint16_t status)611 void pkt_capture_msdu_process_pkts(
612 uint8_t *bssid, qdf_nbuf_t head_msdu,
613 uint8_t vdev_id, void *psoc, uint16_t status)
614 {
615 qdf_nbuf_t loop_msdu, pktcapture_msdu, offload_msdu = NULL;
616 qdf_nbuf_t msdu, prev = NULL;
617
618 pktcapture_msdu = NULL;
619 loop_msdu = head_msdu;
620 while (loop_msdu) {
621 msdu = qdf_nbuf_copy(loop_msdu);
622
623 if (msdu) {
624 qdf_nbuf_set_next(msdu, NULL);
625
626 if (!(pktcapture_msdu)) {
627 pktcapture_msdu = msdu;
628 prev = msdu;
629 } else {
630 qdf_nbuf_set_next(prev, msdu);
631 prev = msdu;
632 }
633 }
634 if (status == RX_OFFLOAD_PKT)
635 offload_msdu = loop_msdu;
636 loop_msdu = qdf_nbuf_next(loop_msdu);
637
638 /* Free offload msdu as it is delivered only to pkt capture */
639 if (offload_msdu) {
640 qdf_nbuf_free(offload_msdu);
641 offload_msdu = NULL;
642 }
643 }
644
645 if (!pktcapture_msdu)
646 return;
647
648 pkt_capture_datapkt_process(
649 vdev_id, pktcapture_msdu,
650 TXRX_PROCESS_TYPE_DATA_RX, 0, 0,
651 TXRX_PKTCAPTURE_PKT_FORMAT_8023,
652 bssid, psoc, 0);
653 }
654 #endif
655
656 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
657 /**
658 * pkt_capture_dp_rx_skip_tlvs() - Skip TLVs len + L2 hdr_offset, save in nbuf
659 * @soc: DP soc context
660 * @nbuf: nbuf to be updated
661 * @l3_padding: l3_padding
662 *
663 * Return: None
664 */
pkt_capture_dp_rx_skip_tlvs(struct dp_soc * soc,qdf_nbuf_t nbuf,uint32_t l3_padding)665 static void pkt_capture_dp_rx_skip_tlvs(struct dp_soc *soc, qdf_nbuf_t nbuf,
666 uint32_t l3_padding)
667 {
668 QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(nbuf) = l3_padding;
669 qdf_nbuf_pull_head(nbuf, l3_padding + soc->rx_pkt_tlv_size);
670 }
671
672 /**
673 * pkt_capture_rx_get_phy_info() - Get phy info
674 * @context: objmgr vdev
675 * @psoc: dp_soc handle
676 * @rx_tlv_hdr: Pointer to struct rx_pkt_tlvs
677 * @rx_status: Pointer to struct mon_rx_status
678 *
679 * Return: none
680 */
pkt_capture_rx_get_phy_info(void * context,void * psoc,uint8_t * rx_tlv_hdr,struct mon_rx_status * rx_status)681 static void pkt_capture_rx_get_phy_info(void *context, void *psoc,
682 uint8_t *rx_tlv_hdr,
683 struct mon_rx_status *rx_status)
684 {
685 uint8_t preamble = 0;
686 uint8_t preamble_type;
687 uint16_t mcs = 0, nss = 0, sgi = 0, bw = 0;
688 uint8_t beamformed = 0;
689 bool is_stbc = 0, ldpc = 0;
690 struct dp_soc *soc = psoc;
691 hal_soc_handle_t hal_soc;
692 struct wlan_objmgr_vdev *vdev = context;
693 struct pkt_capture_vdev_priv *vdev_priv;
694
695 hal_soc = soc->hal_soc;
696 preamble_type = hal_rx_tlv_get_pkt_type(hal_soc, rx_tlv_hdr);
697 nss = hal_rx_msdu_start_nss_get(hal_soc, rx_tlv_hdr); /* NSS */
698 bw = hal_rx_tlv_bw_get(hal_soc, rx_tlv_hdr);
699 mcs = hal_rx_tlv_rate_mcs_get(hal_soc, rx_tlv_hdr);
700 sgi = hal_rx_tlv_sgi_get(hal_soc, rx_tlv_hdr);
701 vdev_priv = pkt_capture_vdev_get_priv(vdev);
702
703 switch (preamble_type) {
704 case HAL_RX_PKT_TYPE_11A:
705 case HAL_RX_PKT_TYPE_11B:
706 /* legacy */
707 rx_status->rate = pkt_capture_get_tx_rate(
708 preamble_type,
709 mcs,
710 &preamble);
711 rx_status->mcs = mcs;
712 break;
713 case HAL_RX_PKT_TYPE_11N:
714 rx_status->ht_flags = 1;
715 if (nss == 2)
716 mcs = 8 + mcs;
717 rx_status->ht_mcs = mcs;
718 break;
719 case HAL_RX_PKT_TYPE_11AC:
720 sgi = vdev_priv->rx_vht_sgi;
721 rx_status->vht_flags = 1;
722 rx_status->vht_flag_values3[0] = mcs << 0x4 | nss;
723 bw = vdev->vdev_mlme.des_chan->ch_width;
724 rx_status->vht_flag_values2 = bw;
725 break;
726 case HAL_RX_PKT_TYPE_11AX:
727 rx_status->he_flags = 1;
728 rx_status->he_data1 |=
729 IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
730 IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN;
731 rx_status->he_data2 |= IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN;
732 rx_status->he_data3 |= mcs << 0x8;
733
734 /* Map uCode SGI values to Radiotap header
735 * as per Radiotap header expectation.
736 *
737 * uCode has:
738 * enum 0 0_8_us_sgi
739 * enum 1 0_4_us_sgi
740 * enum 2 1_6_us_sgi
741 * enum 3 3_2_us_sgi
742 *
743 * Radiotap header expectation:
744 * enum 0 0_8_us_sgi
745 * enum 1 1_6_us_sgi
746 * enum 2 3_2_us_sgi
747 */
748 if (sgi == HE_GI_1_6)
749 sgi = HE_GI_RADIOTAP_1_6;
750 else if (sgi == HE_GI_3_2)
751 sgi = HE_GI_RADIOTAP_3_2;
752
753 rx_status->he_data5 |= (bw | (sgi << 0x4));
754 rx_status->he_data6 |= nss;
755 default:
756 break;
757 }
758
759 if (preamble_type != HAL_RX_PKT_TYPE_11B)
760 rx_status->ofdm_flag = 1;
761 else
762 rx_status->cck_flag = 1;
763
764 rx_status->bw = bw;
765 rx_status->nr_ant = nss;
766 rx_status->nss = nss;
767 /* is_stbc not available */
768 rx_status->is_stbc = is_stbc;
769 rx_status->sgi = sgi;
770 /* ldpc not available */
771 rx_status->ldpc = ldpc;
772 /* beamformed not available */
773 rx_status->beamformed = beamformed;
774 rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0);
775 }
776
777 /**
778 * pkt_capture_get_rx_rtap_flags() - Get radiotap flags
779 * @flags: Pointer to struct hal_rx_pkt_capture_flags
780 *
781 * Return: Bitmapped radiotap flags.
782 */
783 static
pkt_capture_get_rx_rtap_flags(struct hal_rx_pkt_capture_flags * flags)784 uint8_t pkt_capture_get_rx_rtap_flags(struct hal_rx_pkt_capture_flags *flags)
785 {
786 uint8_t rtap_flags = 0;
787
788 /* WEP40 || WEP104 || WEP128 */
789 if (flags->encrypt_type == 0 ||
790 flags->encrypt_type == 1 ||
791 flags->encrypt_type == 3)
792 rtap_flags |= BIT(2);
793
794 /* IEEE80211_RADIOTAP_F_FRAG */
795 if (flags->fragment_flag)
796 rtap_flags |= BIT(3);
797
798 /* IEEE80211_RADIOTAP_F_FCS */
799 rtap_flags |= BIT(4);
800
801 /* IEEE80211_RADIOTAP_F_BADFCS */
802 if (flags->fcs_err)
803 rtap_flags |= BIT(6);
804
805 return rtap_flags;
806 }
807
808 /**
809 * pkt_capture_rx_mon_get_rx_status() - Get rx status
810 * @context: objmgr vdev
811 * @dp_soc: dp_soc handle
812 * @desc: Pointer to struct rx_pkt_tlvs
813 * @rx_status: Pointer to struct mon_rx_status
814 *
815 * Return: none
816 */
pkt_capture_rx_mon_get_rx_status(void * context,void * dp_soc,void * desc,struct mon_rx_status * rx_status)817 static void pkt_capture_rx_mon_get_rx_status(void *context, void *dp_soc,
818 void *desc,
819 struct mon_rx_status *rx_status)
820 {
821 uint8_t *rx_tlv_hdr = desc;
822 struct dp_soc *soc = dp_soc;
823 struct hal_rx_pkt_capture_flags flags = {0};
824 struct wlan_objmgr_vdev *vdev = context;
825 uint8_t primary_chan_num;
826 uint32_t center_chan_freq;
827 struct wlan_objmgr_psoc *psoc;
828 struct wlan_objmgr_pdev *pdev;
829 enum reg_wifi_band band;
830
831 psoc = wlan_vdev_get_psoc(vdev);
832 if (!psoc) {
833 pkt_capture_err("Failed to get psoc");
834 return;
835 }
836
837 hal_rx_tlv_get_pkt_capture_flags(soc->hal_soc, (uint8_t *)rx_tlv_hdr,
838 &flags);
839
840 rx_status->rtap_flags |= pkt_capture_get_rx_rtap_flags(&flags);
841 rx_status->ant_signal_db = flags.rssi_comb;
842 rx_status->rssi_comb = flags.rssi_comb;
843 rx_status->tsft = flags.tsft;
844 primary_chan_num = flags.chan_freq;
845 center_chan_freq = flags.chan_freq >> 16;
846 rx_status->chan_num = primary_chan_num;
847 band = wlan_reg_freq_to_band(center_chan_freq);
848
849 pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_PKT_CAPTURE_ID);
850 if (!pdev) {
851 pkt_capture_err("Failed to get pdev");
852 return;
853 }
854
855 rx_status->chan_freq =
856 wlan_reg_chan_band_to_freq(pdev, primary_chan_num, BIT(band));
857 wlan_objmgr_pdev_release_ref(pdev, WLAN_PKT_CAPTURE_ID);
858
859 pkt_capture_rx_get_phy_info(context, dp_soc, desc, rx_status);
860 }
861 #endif
862
863 #ifndef WLAN_FEATURE_PKT_CAPTURE_V2
864 /**
865 * pkt_capture_rx_data_cb(): callback to process data rx packets
866 * for pkt capture mode. (normal rx + offloaded rx)
867 * @context: objmgr vdev
868 * @ppdev: device handler
869 * @nbuf_list: netbuf list
870 * @vdev_id: vdev id for which packet is captured
871 * @tid: tid number
872 * @status: Tx status
873 * @pkt_format: Frame format
874 * @bssid: bssid
875 * @tx_retry_cnt: tx retry count
876 *
877 * Return: none
878 */
879 static void
pkt_capture_rx_data_cb(void * context,void * ppdev,void * nbuf_list,uint8_t vdev_id,uint8_t tid,uint16_t status,bool pkt_format,uint8_t * bssid,uint8_t tx_retry_cnt)880 pkt_capture_rx_data_cb(
881 void *context, void *ppdev, void *nbuf_list,
882 uint8_t vdev_id, uint8_t tid,
883 uint16_t status, bool pkt_format,
884 uint8_t *bssid, uint8_t tx_retry_cnt)
885 {
886 struct pkt_capture_vdev_priv *vdev_priv;
887 qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list;
888 struct wlan_objmgr_vdev *vdev;
889 htt_pdev_handle pdev = ppdev;
890 struct pkt_capture_cb_context *cb_ctx;
891 qdf_nbuf_t msdu, next_buf;
892 uint8_t drop_count;
893 struct htt_host_rx_desc_base *rx_desc;
894 struct mon_rx_status rx_status = {0};
895 uint32_t headroom;
896 static uint8_t preamble_type, rssi_comb;
897 static uint32_t vht_sig_a_1;
898 static uint32_t vht_sig_a_2;
899 QDF_STATUS status = QDF_STATUS_SUCCESS;
900
901 vdev = pkt_capture_get_vdev();
902 status = pkt_capture_vdev_get_ref(vdev);
903 if (QDF_IS_STATUS_ERROR(status))
904 goto free_buf;
905
906 vdev_priv = pkt_capture_vdev_get_priv(vdev);
907 cb_ctx = vdev_priv->cb_ctx;
908 if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) {
909 pkt_capture_vdev_put_ref(vdev);
910 goto free_buf;
911 }
912
913 msdu = buf_list;
914 while (msdu) {
915 struct ethernet_hdr_t *eth_hdr;
916
917 next_buf = qdf_nbuf_queue_next(msdu);
918 qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */
919
920 rx_desc = htt_rx_desc(msdu);
921
922 /*
923 * Only the first mpdu has valid preamble type, so use it
924 * till the last mpdu is reached
925 */
926 if (rx_desc->attention.first_mpdu) {
927 rssi_comb = rx_desc->ppdu_start.rssi_comb;
928 preamble_type = rx_desc->ppdu_start.preamble_type;
929 if (preamble_type == 8 || preamble_type == 9 ||
930 preamble_type == 0x0c || preamble_type == 0x0d) {
931 vht_sig_a_1 = VHT_SIG_A_1(rx_desc);
932 vht_sig_a_2 = VHT_SIG_A_2(rx_desc);
933 }
934 } else {
935 rx_desc->ppdu_start.rssi_comb = rssi_comb;
936 rx_desc->ppdu_start.preamble_type = preamble_type;
937 if (preamble_type == 8 || preamble_type == 9 ||
938 preamble_type == 0x0c || preamble_type == 0x0d) {
939 VHT_SIG_A_1(rx_desc) = vht_sig_a_1;
940 VHT_SIG_A_2(rx_desc) = vht_sig_a_2;
941 }
942 }
943
944 if (rx_desc->attention.last_mpdu) {
945 rssi_comb = 0;
946 preamble_type = 0;
947 vht_sig_a_1 = 0;
948 vht_sig_a_2 = 0;
949 }
950
951 qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
952
953 /*
954 * Get the channel info and update the rx status
955 */
956
957 /* need to update this to fill rx_status*/
958 htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status);
959 rx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR;
960
961 /* clear IEEE80211_RADIOTAP_F_FCS flag*/
962 rx_status.rtap_flags &= ~(BIT(4));
963 rx_status.rtap_flags &= ~(BIT(2));
964
965 /*
966 * convert 802.3 header format into 802.11 format
967 */
968 if (vdev_id == HTT_INVALID_VDEV) {
969 eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
970 qdf_mem_copy(bssid, eth_hdr->src_addr,
971 QDF_MAC_ADDR_SIZE);
972 }
973
974 pkt_capture_rx_convert8023to80211(bssid, msdu, rx_desc);
975
976 /*
977 * Calculate the headroom and adjust head
978 * to prepare radiotap header.
979 */
980 headroom = qdf_nbuf_headroom(msdu);
981 qdf_nbuf_update_radiotap(&rx_status, msdu, headroom);
982 pkt_capture_mon(cb_ctx, msdu, vdev, 0);
983 msdu = next_buf;
984 }
985
986 pkt_capture_vdev_put_ref(vdev);
987 return;
988
989 free_buf:
990 drop_count = pkt_capture_drop_nbuf_list(buf_list);
991 }
992 #else
993 /**
994 * pkt_capture_rx_data_cb(): callback to process data rx packets
995 * for pkt capture mode. (normal rx + offloaded rx)
996 * @context: objmgr vdev
997 * @psoc: dp_soc handle
998 * @nbuf_list: netbuf list
999 * @vdev_id: vdev id for which packet is captured
1000 * @tid: tid number
1001 * @status: Tx status
1002 * @pkt_format: Frame format
1003 * @bssid: bssid
1004 * @tx_retry_cnt: tx retry count
1005 *
1006 * Return: none
1007 */
1008 static void
pkt_capture_rx_data_cb(void * context,void * psoc,void * nbuf_list,uint8_t vdev_id,uint8_t tid,uint16_t status,bool pkt_format,uint8_t * bssid,uint8_t tx_retry_cnt)1009 pkt_capture_rx_data_cb(
1010 void *context, void *psoc, void *nbuf_list,
1011 uint8_t vdev_id, uint8_t tid,
1012 uint16_t status, bool pkt_format,
1013 uint8_t *bssid, uint8_t tx_retry_cnt)
1014 {
1015 struct pkt_capture_vdev_priv *vdev_priv;
1016 qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list;
1017 struct wlan_objmgr_vdev *vdev;
1018 struct pkt_capture_cb_context *cb_ctx;
1019 qdf_nbuf_t msdu, next_buf;
1020 uint8_t drop_count;
1021 struct mon_rx_status rx_status = {0};
1022 uint32_t headroom;
1023 uint8_t *rx_tlv_hdr = NULL;
1024 struct dp_soc *soc = psoc;
1025 hal_soc_handle_t hal_soc;
1026 struct hal_rx_msdu_metadata msdu_metadata;
1027 QDF_STATUS ret = QDF_STATUS_SUCCESS;
1028
1029 vdev = pkt_capture_get_vdev();
1030 ret = pkt_capture_vdev_get_ref(vdev);
1031 if (QDF_IS_STATUS_ERROR(ret))
1032 goto free_buf;
1033
1034 vdev_priv = pkt_capture_vdev_get_priv(vdev);
1035 cb_ctx = vdev_priv->cb_ctx;
1036 if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) {
1037 pkt_capture_vdev_put_ref(vdev);
1038 goto free_buf;
1039 }
1040
1041 hal_soc = soc->hal_soc;
1042 msdu = buf_list;
1043 while (msdu) {
1044 struct ethernet_hdr_t *eth_hdr;
1045
1046 /* push the tlvs to get rx_tlv_hdr pointer */
1047 qdf_nbuf_push_head(msdu, soc->rx_pkt_tlv_size +
1048 QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(msdu));
1049
1050 rx_tlv_hdr = qdf_nbuf_data(msdu);
1051 hal_rx_msdu_metadata_get(hal_soc, rx_tlv_hdr, &msdu_metadata);
1052 /* Pull rx_tlv_hdr */
1053 pkt_capture_dp_rx_skip_tlvs(soc, msdu,
1054 msdu_metadata.l3_hdr_pad);
1055
1056 next_buf = qdf_nbuf_queue_next(msdu);
1057 qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */
1058
1059 /*
1060 * Get the channel info and update the rx status
1061 */
1062
1063 /* need to update this to fill rx_status*/
1064 pkt_capture_rx_mon_get_rx_status(vdev, psoc,
1065 rx_tlv_hdr, &rx_status);
1066
1067 /* clear IEEE80211_RADIOTAP_F_FCS flag*/
1068 rx_status.rtap_flags &= ~(BIT(4));
1069 rx_status.rtap_flags &= ~(BIT(2));
1070
1071 /*
1072 * convert 802.3 header format into 802.11 format
1073 */
1074 if (vdev_id == HTT_INVALID_VDEV) {
1075 eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
1076 qdf_mem_copy(bssid, eth_hdr->src_addr,
1077 QDF_MAC_ADDR_SIZE);
1078 }
1079
1080 pkt_capture_rx_convert8023to80211(hal_soc, msdu, rx_tlv_hdr);
1081
1082 /*
1083 * Calculate the headroom and adjust head
1084 * to prepare radiotap header.
1085 */
1086 headroom = qdf_nbuf_headroom(msdu);
1087 qdf_nbuf_update_radiotap(&rx_status, msdu, headroom);
1088 pkt_capture_mon(cb_ctx, msdu, vdev, 0);
1089 msdu = next_buf;
1090 }
1091
1092 pkt_capture_vdev_put_ref(vdev);
1093 return;
1094
1095 free_buf:
1096 drop_count = pkt_capture_drop_nbuf_list(buf_list);
1097 }
1098
1099 #endif
1100
1101 #ifndef WLAN_FEATURE_PKT_CAPTURE_V2
1102 /**
1103 * pkt_capture_tx_data_cb() - process data tx and rx packets
1104 * for pkt capture mode. (normal tx/rx + offloaded tx/rx)
1105 * @context: capture context (unused)
1106 * @ppdev: pdev handle
1107 * @nbuf_list: netbuf list
1108 * @vdev_id: vdev id for which packet is captured
1109 * @tid: tid number
1110 * @status: Tx status
1111 * @pkt_format: Frame format
1112 * @bssid: bssid
1113 * @tx_retry_cnt: tx retry count
1114 *
1115 * Return: none
1116 */
1117 static void
pkt_capture_tx_data_cb(void * context,void * ppdev,void * nbuf_list,uint8_t vdev_id,uint8_t tid,uint16_t status,bool pkt_format,uint8_t * bssid,uint8_t tx_retry_cnt)1118 pkt_capture_tx_data_cb(
1119 void *context, void *ppdev, void *nbuf_list, uint8_t vdev_id,
1120 uint8_t tid, uint16_t status, bool pkt_format,
1121 uint8_t *bssid, uint8_t tx_retry_cnt)
1122 {
1123 qdf_nbuf_t msdu, next_buf;
1124 struct pkt_capture_vdev_priv *vdev_priv;
1125 struct wlan_objmgr_vdev *vdev;
1126 htt_pdev_handle pdev = ppdev;
1127 struct pkt_capture_cb_context *cb_ctx;
1128 uint8_t drop_count;
1129 struct htt_tx_data_hdr_information *cmpl_desc = NULL;
1130 struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0};
1131 struct ethernet_hdr_t *eth_hdr;
1132 struct llc_snap_hdr_t *llc_hdr;
1133 struct ieee80211_frame *wh;
1134 uint8_t hdsize, new_hdsize;
1135 struct ieee80211_qoscntl *qos_cntl;
1136 uint16_t ether_type;
1137 uint32_t headroom;
1138 uint16_t seq_no, fc_ctrl;
1139 struct mon_rx_status tx_status = {0};
1140 QDF_STATUS status = QDF_STATUS_SUCCESS;
1141 uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) +
1142 sizeof(struct llc_snap_hdr_t)];
1143 const uint8_t ethernet_II_llc_snap_header_prefix[] = {
1144 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
1145
1146 vdev = pkt_capture_get_vdev();
1147 status = pkt_capture_vdev_get_ref(vdev);
1148 if (QDF_IS_STATUS_ERROR(status))
1149 goto free_buf;
1150
1151 vdev_priv = pkt_capture_vdev_get_priv(vdev);
1152 cb_ctx = vdev_priv->cb_ctx;
1153 if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) {
1154 pkt_capture_vdev_put_ref(vdev);
1155 goto free_buf;
1156 }
1157
1158 msdu = nbuf_list;
1159 while (msdu) {
1160 next_buf = qdf_nbuf_queue_next(msdu);
1161 qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */
1162
1163 cmpl_desc = (struct htt_tx_data_hdr_information *)
1164 (qdf_nbuf_data(msdu));
1165
1166 pktcapture_hdr.timestamp = cmpl_desc->phy_timestamp_l32;
1167 pktcapture_hdr.preamble = cmpl_desc->preamble;
1168 pktcapture_hdr.mcs = cmpl_desc->mcs;
1169 pktcapture_hdr.bw = cmpl_desc->bw;
1170 pktcapture_hdr.nss = cmpl_desc->nss;
1171 pktcapture_hdr.rssi_comb = cmpl_desc->rssi;
1172 pktcapture_hdr.rate = cmpl_desc->rate;
1173 pktcapture_hdr.stbc = cmpl_desc->stbc;
1174 pktcapture_hdr.sgi = cmpl_desc->sgi;
1175 pktcapture_hdr.ldpc = cmpl_desc->ldpc;
1176 pktcapture_hdr.beamformed = cmpl_desc->beamformed;
1177 pktcapture_hdr.status = status;
1178 pktcapture_hdr.tx_retry_cnt = tx_retry_cnt;
1179
1180 qdf_nbuf_pull_head(
1181 msdu,
1182 sizeof(struct htt_tx_data_hdr_information));
1183
1184 if (pkt_format == TXRX_PKTCAPTURE_PKT_FORMAT_8023) {
1185 eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
1186 hdsize = sizeof(struct ethernet_hdr_t);
1187 wh = (struct ieee80211_frame *)localbuf;
1188
1189 *(uint16_t *)wh->i_dur = 0;
1190
1191 new_hdsize = 0;
1192
1193 if (vdev_id == HTT_INVALID_VDEV)
1194 qdf_mem_copy(bssid, eth_hdr->dest_addr,
1195 QDF_MAC_ADDR_SIZE);
1196
1197 /* BSSID , SA , DA */
1198 qdf_mem_copy(wh->i_addr1, bssid,
1199 QDF_MAC_ADDR_SIZE);
1200 qdf_mem_copy(wh->i_addr2, eth_hdr->src_addr,
1201 QDF_MAC_ADDR_SIZE);
1202 qdf_mem_copy(wh->i_addr3, eth_hdr->dest_addr,
1203 QDF_MAC_ADDR_SIZE);
1204
1205 seq_no = cmpl_desc->seqno;
1206 seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) &
1207 IEEE80211_SEQ_SEQ_MASK;
1208 fc_ctrl = cmpl_desc->framectrl;
1209 qdf_mem_copy(wh->i_fc, &fc_ctrl, sizeof(fc_ctrl));
1210 qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no));
1211
1212 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1213
1214 new_hdsize = sizeof(struct ieee80211_frame);
1215
1216 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
1217 qos_cntl = (struct ieee80211_qoscntl *)
1218 (localbuf + new_hdsize);
1219 qos_cntl->i_qos[0] =
1220 (tid & IEEE80211_QOS_TID);
1221 qos_cntl->i_qos[1] = 0;
1222 new_hdsize += sizeof(struct ieee80211_qoscntl);
1223 }
1224 /*
1225 * Prepare llc Header
1226 */
1227 llc_hdr = (struct llc_snap_hdr_t *)
1228 (localbuf + new_hdsize);
1229 ether_type = (eth_hdr->ethertype[0] << 8) |
1230 (eth_hdr->ethertype[1]);
1231 if (ether_type >= ETH_P_802_3_MIN) {
1232 qdf_mem_copy(
1233 llc_hdr,
1234 ethernet_II_llc_snap_header_prefix,
1235 sizeof
1236 (ethernet_II_llc_snap_header_prefix));
1237 if (ether_type == ETHERTYPE_AARP ||
1238 ether_type == ETHERTYPE_IPX) {
1239 llc_hdr->org_code[2] =
1240 BTEP_SNAP_ORGCODE_2;
1241 /* 0xf8; bridge tunnel header */
1242 }
1243 llc_hdr->ethertype[0] = eth_hdr->ethertype[0];
1244 llc_hdr->ethertype[1] = eth_hdr->ethertype[1];
1245 new_hdsize += sizeof(struct llc_snap_hdr_t);
1246 }
1247
1248 /*
1249 * Remove 802.3 Header by adjusting the head
1250 */
1251 qdf_nbuf_pull_head(msdu, hdsize);
1252
1253 /*
1254 * Adjust the head and prepare 802.11 Header
1255 */
1256 qdf_nbuf_push_head(msdu, new_hdsize);
1257 qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize);
1258 }
1259
1260 pkt_capture_update_tx_status(
1261 pdev,
1262 &tx_status,
1263 &pktcapture_hdr);
1264 /*
1265 * Calculate the headroom and adjust head
1266 * to prepare radiotap header.
1267 */
1268 headroom = qdf_nbuf_headroom(msdu);
1269 qdf_nbuf_update_radiotap(&tx_status, msdu, headroom);
1270 pkt_capture_mon(cb_ctx, msdu, vdev, 0);
1271 msdu = next_buf;
1272 }
1273 pkt_capture_vdev_put_ref(vdev);
1274 return;
1275
1276 free_buf:
1277 drop_count = pkt_capture_drop_nbuf_list(nbuf_list);
1278 }
1279 #else
1280 /**
1281 * pkt_capture_get_vdev_bss_peer_mac_addr() - API to get bss peer mac address
1282 * @vdev: objmgr vdev
1283 * @bss_peer_mac_address: bss peer mac address
1284 *.
1285 * Helper function to get bss peer mac address
1286 *
1287 * Return: if success pmo vdev ctx else NULL
1288 */
pkt_capture_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bss_peer_mac_address)1289 static QDF_STATUS pkt_capture_get_vdev_bss_peer_mac_addr(
1290 struct wlan_objmgr_vdev *vdev,
1291 struct qdf_mac_addr *bss_peer_mac_address)
1292 {
1293 struct wlan_objmgr_peer *peer;
1294
1295 if (!vdev) {
1296 qdf_print("vdev is null");
1297 return QDF_STATUS_E_INVAL;
1298 }
1299
1300 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_PKT_CAPTURE_ID);
1301 if (!peer) {
1302 qdf_print("peer is null");
1303 return QDF_STATUS_E_INVAL;
1304 }
1305 wlan_peer_obj_lock(peer);
1306 qdf_mem_copy(bss_peer_mac_address->bytes, wlan_peer_get_macaddr(peer),
1307 QDF_MAC_ADDR_SIZE);
1308 wlan_peer_obj_unlock(peer);
1309
1310 wlan_objmgr_peer_release_ref(peer, WLAN_PKT_CAPTURE_ID);
1311
1312 return QDF_STATUS_SUCCESS;
1313 }
1314
1315 static void
pkt_capture_tx_data_cb(void * context,void * ppdev,void * nbuf_list,uint8_t vdev_id,uint8_t tid,uint16_t status,bool pkt_format,uint8_t * bssid,uint8_t tx_retry_cnt)1316 pkt_capture_tx_data_cb(
1317 void *context, void *ppdev, void *nbuf_list, uint8_t vdev_id,
1318 uint8_t tid, uint16_t status, bool pkt_format,
1319 uint8_t *bssid, uint8_t tx_retry_cnt)
1320 {
1321 qdf_nbuf_t msdu, next_buf;
1322 struct pkt_capture_vdev_priv *vdev_priv;
1323 struct wlan_objmgr_vdev *vdev;
1324 struct pkt_capture_cb_context *cb_ctx;
1325 uint8_t drop_count;
1326 struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr = NULL;
1327 struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0};
1328 uint32_t txcap_hdr_size = sizeof(struct pkt_capture_tx_hdr_elem_t);
1329 struct ethernet_hdr_t *eth_hdr;
1330 struct llc_snap_hdr_t *llc_hdr;
1331 struct ieee80211_frame *wh;
1332 uint8_t hdsize, new_hdsize;
1333 struct ieee80211_qoscntl *qos_cntl;
1334 uint16_t ether_type;
1335 uint32_t headroom;
1336 uint16_t seq_no, fc_ctrl;
1337 struct mon_rx_status tx_status = {0};
1338 QDF_STATUS ret = QDF_STATUS_SUCCESS;
1339 uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) +
1340 sizeof(struct llc_snap_hdr_t)];
1341 const uint8_t ethernet_II_llc_snap_header_prefix[] = {
1342 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
1343 struct qdf_mac_addr bss_peer_mac_address;
1344
1345 vdev = pkt_capture_get_vdev();
1346 ret = pkt_capture_vdev_get_ref(vdev);
1347 if (QDF_IS_STATUS_ERROR(ret))
1348 goto free_buf;
1349
1350 vdev_priv = pkt_capture_vdev_get_priv(vdev);
1351 cb_ctx = vdev_priv->cb_ctx;
1352 if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) {
1353 pkt_capture_vdev_put_ref(vdev);
1354 goto free_buf;
1355 }
1356
1357 msdu = nbuf_list;
1358 while (msdu) {
1359 next_buf = qdf_nbuf_queue_next(msdu);
1360 qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */
1361
1362 ptr_pktcapture_hdr = (struct pkt_capture_tx_hdr_elem_t *)
1363 (qdf_nbuf_data(msdu));
1364
1365 qdf_mem_copy(&pktcapture_hdr, ptr_pktcapture_hdr,
1366 txcap_hdr_size);
1367 pktcapture_hdr.status = status;
1368
1369 qdf_nbuf_pull_head(msdu, txcap_hdr_size);
1370
1371 if (pkt_format == TXRX_PKTCAPTURE_PKT_FORMAT_8023) {
1372 eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
1373 hdsize = sizeof(struct ethernet_hdr_t);
1374 wh = (struct ieee80211_frame *)localbuf;
1375
1376 *(uint16_t *)wh->i_dur = 0;
1377
1378 new_hdsize = 0;
1379
1380 pkt_capture_get_vdev_bss_peer_mac_addr(
1381 vdev,
1382 &bss_peer_mac_address);
1383 qdf_mem_copy(bssid, bss_peer_mac_address.bytes,
1384 QDF_MAC_ADDR_SIZE);
1385 if (vdev_id == HTT_INVALID_VDEV)
1386 qdf_mem_copy(bssid, eth_hdr->dest_addr,
1387 QDF_MAC_ADDR_SIZE);
1388
1389 /* BSSID , SA , DA */
1390 qdf_mem_copy(wh->i_addr1, bssid,
1391 QDF_MAC_ADDR_SIZE);
1392 qdf_mem_copy(wh->i_addr2, eth_hdr->src_addr,
1393 QDF_MAC_ADDR_SIZE);
1394 qdf_mem_copy(wh->i_addr3, eth_hdr->dest_addr,
1395 QDF_MAC_ADDR_SIZE);
1396
1397 seq_no = pktcapture_hdr.seqno;
1398 seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) &
1399 IEEE80211_SEQ_SEQ_MASK;
1400 fc_ctrl = pktcapture_hdr.framectrl;
1401 qdf_mem_copy(wh->i_fc, &fc_ctrl, sizeof(fc_ctrl));
1402 qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no));
1403
1404 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1405
1406 if (tx_retry_cnt)
1407 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
1408
1409 new_hdsize = sizeof(struct ieee80211_frame);
1410
1411 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
1412 qos_cntl = (struct ieee80211_qoscntl *)
1413 (localbuf + new_hdsize);
1414 qos_cntl->i_qos[0] =
1415 (tid & IEEE80211_QOS_TID);
1416 qos_cntl->i_qos[1] = 0;
1417 new_hdsize += sizeof(struct ieee80211_qoscntl);
1418 }
1419 /*
1420 * Prepare llc Header
1421 */
1422 llc_hdr = (struct llc_snap_hdr_t *)
1423 (localbuf + new_hdsize);
1424 ether_type = (eth_hdr->ethertype[0] << 8) |
1425 (eth_hdr->ethertype[1]);
1426 if (ether_type >= ETH_P_802_3_MIN) {
1427 qdf_mem_copy(
1428 llc_hdr,
1429 ethernet_II_llc_snap_header_prefix,
1430 sizeof
1431 (ethernet_II_llc_snap_header_prefix));
1432 if (ether_type == ETHERTYPE_AARP ||
1433 ether_type == ETHERTYPE_IPX) {
1434 llc_hdr->org_code[2] =
1435 BTEP_SNAP_ORGCODE_2;
1436 /* 0xf8; bridge tunnel header */
1437 }
1438 llc_hdr->ethertype[0] = eth_hdr->ethertype[0];
1439 llc_hdr->ethertype[1] = eth_hdr->ethertype[1];
1440 new_hdsize += sizeof(struct llc_snap_hdr_t);
1441 }
1442
1443 /*
1444 * Remove 802.3 Header by adjusting the head
1445 */
1446 qdf_nbuf_pull_head(msdu, hdsize);
1447
1448 /*
1449 * Adjust the head and prepare 802.11 Header
1450 */
1451 qdf_nbuf_push_head(msdu, new_hdsize);
1452 qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize);
1453 }
1454
1455 pkt_capture_update_tx_status(
1456 vdev,
1457 &tx_status,
1458 &pktcapture_hdr);
1459 /*
1460 * Calculate the headroom and adjust head
1461 * to prepare radiotap header.
1462 */
1463 headroom = qdf_nbuf_headroom(msdu);
1464 qdf_nbuf_update_radiotap(&tx_status, msdu, headroom);
1465 pkt_capture_mon(cb_ctx, msdu, vdev, 0);
1466 msdu = next_buf;
1467 }
1468 pkt_capture_vdev_put_ref(vdev);
1469 return;
1470
1471 free_buf:
1472 drop_count = pkt_capture_drop_nbuf_list(nbuf_list);
1473 }
1474 #endif
1475
pkt_capture_datapkt_process(uint8_t vdev_id,qdf_nbuf_t mon_buf_list,enum pkt_capture_data_process_type type,uint8_t tid,uint8_t status,bool pkt_format,uint8_t * bssid,void * pdev,uint8_t tx_retry_cnt)1476 void pkt_capture_datapkt_process(
1477 uint8_t vdev_id,
1478 qdf_nbuf_t mon_buf_list,
1479 enum pkt_capture_data_process_type type,
1480 uint8_t tid, uint8_t status, bool pkt_format,
1481 uint8_t *bssid, void *pdev,
1482 uint8_t tx_retry_cnt)
1483 {
1484 uint8_t drop_count;
1485 struct pkt_capture_mon_pkt *pkt;
1486 pkt_capture_mon_thread_cb callback = NULL;
1487 struct wlan_objmgr_vdev *vdev;
1488 QDF_STATUS ret = QDF_STATUS_SUCCESS;
1489
1490 status = pkt_capture_txrx_status_map(status);
1491 vdev = pkt_capture_get_vdev();
1492 ret = pkt_capture_vdev_get_ref(vdev);
1493 if (QDF_IS_STATUS_ERROR(ret))
1494 goto drop_rx_buf;
1495
1496 switch (type) {
1497 case TXRX_PROCESS_TYPE_DATA_RX:
1498 callback = pkt_capture_rx_data_cb;
1499 break;
1500 case TXRX_PROCESS_TYPE_DATA_TX:
1501 case TXRX_PROCESS_TYPE_DATA_TX_COMPL:
1502 callback = pkt_capture_tx_data_cb;
1503 break;
1504 default:
1505 pkt_capture_vdev_put_ref(vdev);
1506 goto drop_rx_buf;
1507 }
1508
1509 pkt = pkt_capture_alloc_mon_pkt(vdev);
1510 if (!pkt) {
1511 pkt_capture_vdev_put_ref(vdev);
1512 goto drop_rx_buf;
1513 }
1514
1515 pkt->callback = callback;
1516 pkt->context = NULL;
1517 pkt->pdev = (void *)pdev;
1518 pkt->monpkt = (void *)mon_buf_list;
1519 pkt->vdev_id = vdev_id;
1520 pkt->tid = tid;
1521 pkt->status = status;
1522 pkt->pkt_format = pkt_format;
1523 qdf_mem_copy(pkt->bssid, bssid, QDF_MAC_ADDR_SIZE);
1524 pkt->tx_retry_cnt = tx_retry_cnt;
1525 pkt_capture_indicate_monpkt(vdev, pkt);
1526 pkt_capture_vdev_put_ref(vdev);
1527 return;
1528
1529 drop_rx_buf:
1530 drop_count = pkt_capture_drop_nbuf_list(mon_buf_list);
1531 }
1532
pkt_capture_tx_get_txcomplete_data_hdr(uint32_t * msg_word,int num_msdus)1533 struct htt_tx_data_hdr_information *pkt_capture_tx_get_txcomplete_data_hdr(
1534 uint32_t *msg_word,
1535 int num_msdus)
1536 {
1537 int offset_dwords;
1538 u_int32_t has_tx_tsf;
1539 u_int32_t has_retry;
1540 u_int32_t has_ack_rssi;
1541 u_int32_t has_tx_tsf64;
1542 u_int32_t has_tx_compl_payload;
1543 struct htt_tx_compl_ind_append_retries *retry_list = NULL;
1544 struct htt_tx_data_hdr_information *txcomplete_data_hrd_list = NULL;
1545
1546 has_tx_compl_payload = HTT_TX_COMPL_IND_APPEND4_GET(*msg_word);
1547 if (num_msdus <= 0 || !has_tx_compl_payload)
1548 return NULL;
1549
1550 offset_dwords = 1 + ((num_msdus + 1) >> 1);
1551
1552 has_retry = HTT_TX_COMPL_IND_APPEND_GET(*msg_word);
1553 if (has_retry) {
1554 int retry_index = 0;
1555 int width_for_each_retry =
1556 (sizeof(struct htt_tx_compl_ind_append_retries) +
1557 3) >> 2;
1558
1559 retry_list = (struct htt_tx_compl_ind_append_retries *)
1560 (msg_word + offset_dwords);
1561 while (retry_list) {
1562 if (retry_list[retry_index++].flag == 0)
1563 break;
1564 }
1565 offset_dwords += retry_index * width_for_each_retry;
1566 }
1567 has_tx_tsf = HTT_TX_COMPL_IND_APPEND1_GET(*msg_word);
1568 if (has_tx_tsf) {
1569 int width_for_each_tsf =
1570 (sizeof(struct htt_tx_compl_ind_append_tx_tstamp)) >> 2;
1571 offset_dwords += width_for_each_tsf * num_msdus;
1572 }
1573
1574 has_ack_rssi = HTT_TX_COMPL_IND_APPEND2_GET(*msg_word);
1575 if (has_ack_rssi)
1576 offset_dwords += ((num_msdus + 1) >> 1);
1577
1578 has_tx_tsf64 = HTT_TX_COMPL_IND_APPEND3_GET(*msg_word);
1579 if (has_tx_tsf64)
1580 offset_dwords += (num_msdus << 1);
1581
1582 txcomplete_data_hrd_list = (struct htt_tx_data_hdr_information *)
1583 (msg_word + offset_dwords);
1584
1585 return txcomplete_data_hrd_list;
1586 }
1587
1588 #ifndef WLAN_FEATURE_PKT_CAPTURE_V2
pkt_capture_offload_deliver_indication_handler(void * msg,uint8_t vdev_id,uint8_t * bssid,htt_pdev_handle pdev)1589 void pkt_capture_offload_deliver_indication_handler(
1590 void *msg, uint8_t vdev_id,
1591 uint8_t *bssid, htt_pdev_handle pdev)
1592 {
1593 int nbuf_len;
1594 qdf_nbuf_t netbuf;
1595 uint8_t status;
1596 uint8_t tid = 0;
1597 bool pkt_format;
1598 u_int32_t *msg_word = (u_int32_t *)msg;
1599 u_int8_t *buf = (u_int8_t *)msg;
1600 struct htt_tx_data_hdr_information *txhdr;
1601 struct htt_tx_offload_deliver_ind_hdr_t *offload_deliver_msg;
1602
1603 offload_deliver_msg = (struct htt_tx_offload_deliver_ind_hdr_t *)msg;
1604
1605 txhdr = (struct htt_tx_data_hdr_information *)
1606 (msg_word + 1);
1607
1608 nbuf_len = offload_deliver_msg->tx_mpdu_bytes;
1609
1610 netbuf = qdf_nbuf_alloc(NULL,
1611 roundup(nbuf_len + RESERVE_BYTES, 4),
1612 RESERVE_BYTES, 4, false);
1613
1614 if (!netbuf)
1615 return;
1616
1617 qdf_nbuf_put_tail(netbuf, nbuf_len);
1618
1619 qdf_mem_copy(qdf_nbuf_data(netbuf),
1620 buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t),
1621 nbuf_len);
1622
1623 qdf_nbuf_push_head(
1624 netbuf,
1625 sizeof(struct htt_tx_data_hdr_information));
1626
1627 qdf_mem_copy(qdf_nbuf_data(netbuf), txhdr,
1628 sizeof(struct htt_tx_data_hdr_information));
1629
1630 status = offload_deliver_msg->status;
1631 pkt_format = offload_deliver_msg->format;
1632 tid = offload_deliver_msg->tid_num;
1633
1634 pkt_capture_datapkt_process(
1635 vdev_id,
1636 netbuf, TXRX_PROCESS_TYPE_DATA_TX,
1637 tid, status, pkt_format, bssid, pdev,
1638 offload_deliver_msg->tx_retry_cnt);
1639 }
1640 #else
pkt_capture_offload_deliver_indication_handler(void * msg,uint8_t vdev_id,uint8_t * bssid,void * soc)1641 void pkt_capture_offload_deliver_indication_handler(
1642 void *msg, uint8_t vdev_id,
1643 uint8_t *bssid, void *soc)
1644 {
1645 int nbuf_len;
1646 qdf_nbuf_t netbuf;
1647 uint8_t status;
1648 uint8_t tid = 0;
1649 bool pkt_format;
1650 u_int8_t *buf = (u_int8_t *)msg;
1651 struct htt_tx_offload_deliver_ind_hdr_t *offload_deliver_msg;
1652
1653 struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr;
1654 struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0};
1655 uint32_t txcap_hdr_size = sizeof(struct pkt_capture_tx_hdr_elem_t);
1656 struct wlan_objmgr_vdev *vdev;
1657 struct pkt_capture_vdev_priv *vdev_priv;
1658 struct pkt_capture_frame_filter *frame_filter;
1659 QDF_STATUS ret = QDF_STATUS_SUCCESS;
1660
1661 offload_deliver_msg = (struct htt_tx_offload_deliver_ind_hdr_t *)msg;
1662
1663 vdev = pkt_capture_get_vdev();
1664 ret = pkt_capture_vdev_get_ref(vdev);
1665 if (QDF_IS_STATUS_ERROR(ret))
1666 return;
1667
1668 vdev_priv = pkt_capture_vdev_get_priv(vdev);
1669 if (!vdev_priv) {
1670 pkt_capture_err("vdev priv is NULL");
1671 pkt_capture_vdev_put_ref(vdev);
1672 return;
1673 }
1674
1675 frame_filter = &vdev_priv->frame_filter;
1676
1677 nbuf_len = offload_deliver_msg->tx_mpdu_bytes;
1678 netbuf = qdf_nbuf_alloc(NULL,
1679 roundup(nbuf_len + RESERVE_BYTES, 4),
1680 RESERVE_BYTES, 4, false);
1681 if (!netbuf) {
1682 pkt_capture_vdev_put_ref(vdev);
1683 return;
1684 }
1685
1686 qdf_nbuf_put_tail(netbuf, nbuf_len);
1687
1688 qdf_mem_copy(qdf_nbuf_data(netbuf),
1689 buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t),
1690 nbuf_len);
1691
1692 if (!(frame_filter->data_tx_frame_filter &
1693 PKT_CAPTURE_DATA_FRAME_TYPE_ALL) &&
1694 !pkt_capture_is_frame_filter_set(
1695 netbuf, frame_filter, IEEE80211_FC1_DIR_TODS)) {
1696 qdf_nbuf_free(netbuf);
1697 pkt_capture_vdev_put_ref(vdev);
1698 return;
1699 }
1700
1701 pktcapture_hdr.timestamp = offload_deliver_msg->phy_timestamp_l32;
1702 pktcapture_hdr.preamble = offload_deliver_msg->preamble;
1703 pktcapture_hdr.mcs = offload_deliver_msg->mcs;
1704 pktcapture_hdr.bw = offload_deliver_msg->bw;
1705 pktcapture_hdr.nss = offload_deliver_msg->nss;
1706 pktcapture_hdr.rssi_comb = offload_deliver_msg->rssi;
1707 pktcapture_hdr.rate = offload_deliver_msg->rate;
1708 pktcapture_hdr.stbc = offload_deliver_msg->stbc;
1709 pktcapture_hdr.sgi = offload_deliver_msg->sgi;
1710 pktcapture_hdr.ldpc = offload_deliver_msg->ldpc;
1711 /* Beamformed not available */
1712 pktcapture_hdr.beamformed = 0;
1713 pktcapture_hdr.framectrl = offload_deliver_msg->framectrl;
1714 pktcapture_hdr.tx_retry_cnt = offload_deliver_msg->tx_retry_cnt;
1715 pktcapture_hdr.seqno = offload_deliver_msg->seqno;
1716 tid = offload_deliver_msg->tid_num;
1717 status = offload_deliver_msg->status;
1718 pkt_format = offload_deliver_msg->format;
1719
1720 qdf_nbuf_push_head(netbuf, txcap_hdr_size);
1721
1722 ptr_pktcapture_hdr =
1723 (struct pkt_capture_tx_hdr_elem_t *)qdf_nbuf_data(netbuf);
1724
1725 qdf_mem_copy(ptr_pktcapture_hdr, &pktcapture_hdr, txcap_hdr_size);
1726
1727 pkt_capture_datapkt_process(
1728 vdev_id,
1729 netbuf, TXRX_PROCESS_TYPE_DATA_TX,
1730 tid, status, pkt_format, bssid, soc,
1731 offload_deliver_msg->tx_retry_cnt);
1732
1733 pkt_capture_vdev_put_ref(vdev);
1734 }
1735 #endif
1736