1 /* 2 * Copyright (c) 2021-2022 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 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 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 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_ms(qdf_ktime_real_get()) - enq_time); 98 else 99 latency = qdf_nbuf_get_timedelta_ms(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