|
@@ -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,
|