From 14ed3f8c2d922bdf63e0884f1d1e7e996cebae11 Mon Sep 17 00:00:00 2001 From: Surabhi Vishnoi Date: Wed, 21 Apr 2021 17:24:51 +0530 Subject: [PATCH] qcacld-3.0: Add support for TSO frames in packet capture mode Currently, TSO frames are not handled in packet capture mode. Add support to handle TSO frames. Change-Id: Ib901defcd369b01a33c87ca888ad80fe5fd086c7 CRs-Fixed: 2932138 --- .../core/src/wlan_pkt_capture_main.c | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/components/pkt_capture/core/src/wlan_pkt_capture_main.c index 80162a16b9f8..2d3046ba443e 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_main.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_main.c @@ -137,6 +137,7 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr; struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0}; struct hal_tx_completion_status tx_comp_status = {0}; + struct qdf_tso_seg_elem_t *tso_seg = NULL; uint32_t txcap_hdr_size = sizeof(struct pkt_capture_tx_hdr_elem_t); @@ -173,7 +174,15 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, tid = tx_comp_status.tid; status = tx_comp_status.status; - nbuf_len = qdf_nbuf_len(desc->nbuf); + if (desc->frm_type == dp_tx_frm_tso) { + if (!desc->tso_desc) + return; + tso_seg = desc->tso_desc; + nbuf_len = tso_seg->seg.total_len; + } else { + nbuf_len = qdf_nbuf_len(desc->nbuf); + } + netbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4), RESERVE_BYTES, 4, false); @@ -183,8 +192,48 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data, qdf_nbuf_put_tail(netbuf, nbuf_len); - qdf_mem_copy(qdf_nbuf_data(netbuf), - qdf_nbuf_data(desc->nbuf), nbuf_len); + if (desc->frm_type == dp_tx_frm_tso) { + uint8_t frag_cnt, num_frags = 0; + int frag_len = 0; + uint32_t tcp_seq_num; + uint16_t ip_len; + + if (tso_seg->seg.num_frags > 0) + num_frags = tso_seg->seg.num_frags - 1; + + /*Num of frags in a tso seg cannot be less than 2 */ + if (num_frags < 1) { + pkt_capture_err("num of frags in tso segment is %d\n", + (num_frags + 1)); + qdf_nbuf_free(netbuf); + return; + } + + tcp_seq_num = tso_seg->seg.tso_flags.tcp_seq_num; + tcp_seq_num = qdf_cpu_to_be32(tcp_seq_num); + + ip_len = tso_seg->seg.tso_flags.ip_len; + ip_len = qdf_cpu_to_be16(ip_len); + + for (frag_cnt = 0; frag_cnt <= num_frags; frag_cnt++) { + qdf_mem_copy( + qdf_nbuf_data(netbuf) + frag_len, + tso_seg->seg.tso_frags[frag_cnt].vaddr, + tso_seg->seg.tso_frags[frag_cnt].length); + frag_len += + tso_seg->seg.tso_frags[frag_cnt].length; + } + + qdf_mem_copy((qdf_nbuf_data(netbuf) + + IPV4_PKT_LEN_OFFSET), + &ip_len, sizeof(ip_len)); + qdf_mem_copy((qdf_nbuf_data(netbuf) + + IPV4_TCP_SEQ_NUM_OFFSET), + &tcp_seq_num, sizeof(tcp_seq_num)); + } else { + qdf_mem_copy(qdf_nbuf_data(netbuf), + qdf_nbuf_data(desc->nbuf), nbuf_len); + } if (qdf_unlikely(qdf_nbuf_headroom(netbuf) < txcap_hdr_size)) { netbuf = qdf_nbuf_realloc_headroom(netbuf,