1 /*
2  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <qdf_tracepoint.h>
20 
21 #define CREATE_TRACE_POINTS
22 #include "qdf_tracepoint_defs.h"
23 
24 #ifdef WLAN_TRACEPOINTS
qdf_trace_dp_tx_ip_packet(qdf_nbuf_t nbuf,uint8_t * trans_hdr,uint8_t ip_proto,uint16_t ip_id,struct qdf_tso_seg_elem_t * tso_desc,uint64_t latency)25 static void qdf_trace_dp_tx_ip_packet(qdf_nbuf_t nbuf, uint8_t *trans_hdr,
26 				      uint8_t ip_proto, uint16_t ip_id,
27 				      struct qdf_tso_seg_elem_t *tso_desc,
28 				      uint64_t latency)
29 {
30 	if (ip_proto == QDF_NBUF_TRAC_TCP_TYPE &&
31 	    __qdf_trace_dp_tx_comp_tcp_pkt_enabled()) {
32 		qdf_net_tcphdr_t *tcph = (qdf_net_tcphdr_t *)trans_hdr;
33 		uint32_t tcp_seq;
34 
35 		if (tso_desc)
36 			tcp_seq = tso_desc->seg.tso_flags.tcp_seq_num;
37 		else
38 			tcp_seq = qdf_ntohl(tcph->seq);
39 
40 		__qdf_trace_dp_tx_comp_tcp_pkt(nbuf, tcp_seq,
41 					       qdf_ntohl(tcph->ack_seq),
42 					       qdf_ntohs(tcph->source),
43 					       qdf_ntohs(tcph->dest),
44 					       latency);
45 	} else if (ip_proto == QDF_NBUF_TRAC_UDP_TYPE &&
46 		   __qdf_trace_dp_tx_comp_udp_pkt_enabled()) {
47 		qdf_net_udphdr_t *udph = (qdf_net_udphdr_t *)trans_hdr;
48 
49 		__qdf_trace_dp_tx_comp_udp_pkt(nbuf, qdf_ntohs(ip_id),
50 					       qdf_ntohs(udph->src_port),
51 					       qdf_ntohs(udph->dst_port),
52 					       latency);
53 	} else if (__qdf_trace_dp_tx_comp_generic_ip_pkt_enabled()) {
54 		__qdf_trace_dp_tx_comp_generic_ip_pkt(nbuf, ip_proto, ip_id,
55 						      QDF_SWAP_U32(*(uint32_t *)trans_hdr),
56 						      latency);
57 	}
58 }
59 
qdf_trace_dp_rx_ip_packet(qdf_nbuf_t nbuf,uint8_t * trans_hdr,uint8_t ip_proto,uint16_t ip_id,uint64_t latency)60 static void qdf_trace_dp_rx_ip_packet(qdf_nbuf_t nbuf, uint8_t *trans_hdr,
61 				      uint8_t ip_proto, uint16_t ip_id,
62 				      uint64_t latency)
63 {
64 	if (ip_proto == QDF_NBUF_TRAC_TCP_TYPE &&
65 	    __qdf_trace_dp_rx_tcp_pkt_enabled()) {
66 		qdf_net_tcphdr_t *tcph = (qdf_net_tcphdr_t *)trans_hdr;
67 
68 		__qdf_trace_dp_rx_tcp_pkt(nbuf, qdf_ntohl(tcph->seq),
69 					  qdf_ntohl(tcph->ack_seq),
70 					  qdf_ntohs(tcph->source),
71 					  qdf_ntohs(tcph->dest),
72 					  latency);
73 	} else if (ip_proto == QDF_NBUF_TRAC_UDP_TYPE &&
74 		   __qdf_trace_dp_rx_udp_pkt_enabled()) {
75 		qdf_net_udphdr_t *udph = (qdf_net_udphdr_t *)trans_hdr;
76 
77 		__qdf_trace_dp_rx_udp_pkt(nbuf, qdf_ntohs(ip_id),
78 					  qdf_ntohs(udph->src_port),
79 					  qdf_ntohs(udph->dst_port),
80 					  latency);
81 	} else if (__qdf_trace_dp_rx_generic_ip_pkt_enabled()) {
82 		__qdf_trace_dp_rx_generic_ip_pkt(nbuf, ip_proto, ip_id,
83 						 QDF_SWAP_U32(*(uint32_t *)trans_hdr),
84 						 latency);
85 	}
86 }
87 
qdf_trace_dp_packet(qdf_nbuf_t nbuf,enum qdf_proto_dir dir,struct qdf_tso_seg_elem_t * tso_desc,uint64_t enq_time)88 void qdf_trace_dp_packet(qdf_nbuf_t nbuf, enum qdf_proto_dir dir,
89 			 struct qdf_tso_seg_elem_t *tso_desc, uint64_t enq_time)
90 {
91 	uint8_t *data = qdf_nbuf_data(nbuf);
92 	uint64_t latency;
93 	uint16_t ether_type;
94 	uint8_t ip_offset = QDF_NBUF_TRAC_IP_OFFSET;
95 
96 	if (dir == QDF_TX)
97 		latency = (qdf_ktime_to_us(qdf_ktime_real_get()) - enq_time);
98 	else
99 		latency = qdf_nbuf_get_timedelta_us(nbuf);
100 
101 	ether_type = QDF_SWAP_U16(*(uint16_t *)(data +
102 						QDF_NBUF_TRAC_ETH_TYPE_OFFSET));
103 
104 	if (unlikely(ether_type == QDF_ETH_TYPE_8021Q)) {
105 		ether_type = QDF_SWAP_U16(*(uint16_t *)(data +
106 					   QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET));
107 		ip_offset = QDF_NBUF_TRAC_VLAN_IP_OFFSET;
108 	} else if (unlikely(ether_type == QDF_ETH_TYPE_8021AD)) {
109 		ether_type = QDF_SWAP_U16(*(uint16_t *)(data +
110 				    QDF_NBUF_TRAC_DOUBLE_VLAN_ETH_TYPE_OFFSET));
111 		ip_offset = QDF_NBUF_TRAC_DOUBLE_VLAN_IP_OFFSET;
112 	}
113 
114 	switch (ether_type) {
115 	case QDF_NBUF_TRAC_IPV4_ETH_TYPE:
116 	case QDF_NBUF_TRAC_IPV6_ETH_TYPE:
117 	{
118 		uint8_t *net_hdr;
119 		uint8_t *trans_hdr;
120 		uint8_t ip_proto;
121 		uint16_t ip_id = 0;
122 
123 		net_hdr = data + ip_offset;
124 
125 		if (ether_type == QDF_NBUF_TRAC_IPV4_ETH_TYPE) {
126 			ip_proto = ((qdf_net_iphdr_t *)net_hdr)->ip_proto;
127 			ip_id = ((qdf_net_iphdr_t *)net_hdr)->ip_id;
128 			trans_hdr = net_hdr + QDF_NBUF_TRAC_IPV4_HEADER_SIZE;
129 		} else {
130 			ip_proto = ((qdf_net_ipv6hdr_t *)net_hdr)->ipv6_nexthdr;
131 			trans_hdr = net_hdr + QDF_NBUF_TRAC_IPV6_HEADER_SIZE;
132 		}
133 
134 		if (dir == QDF_TX)
135 			qdf_trace_dp_tx_ip_packet(nbuf, trans_hdr, ip_proto,
136 						  ip_id, tso_desc, latency);
137 		else
138 			qdf_trace_dp_rx_ip_packet(nbuf, trans_hdr, ip_proto,
139 						  ip_id, latency);
140 
141 		break;
142 	}
143 	default:
144 		if (dir == QDF_TX && __qdf_trace_dp_tx_comp_pkt_enabled())
145 			__qdf_trace_dp_tx_comp_pkt(nbuf, ether_type, latency);
146 		else if (__qdf_trace_dp_rx_pkt_enabled())
147 			__qdf_trace_dp_rx_pkt(nbuf, ether_type, latency);
148 
149 		break;
150 	}
151 }
152 #endif
153