Forráskód Böngészése

qcacld-3.0: Add support to update tsf timestamp in data packet

Add support to update tsf timestamp on driver entry and
exit in data packet. This helps debug latency issue in
XR usecases.

Change-Id: I49d190a55b7ab3081225b7a226f1bbe4f717a20f
CRs-Fixed: 3090104
Nirav Shah 3 éve
szülő
commit
1caaa01a17

+ 9 - 0
Kbuild

@@ -423,6 +423,10 @@ ifeq ($(CONFIG_WLAN_SYSFS_DP_STATS), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_txrx_stats_console.o
 endif
 
+ifeq ($(CONFIG_DP_PKT_ADD_TIMESTAMP), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_add_timestamp.o
+endif
+
 ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_fw_state.o
 endif
@@ -915,6 +919,10 @@ ifeq ($(CONFIG_IPA_OFFLOAD), y)
 QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_ipa.o
 endif
 
+ifeq ($(CONFIG_DP_PKT_ADD_TIMESTAMP), y)
+QDF_OBJS += $(QDF_LINUX_OBJ_DIR)/qdf_pkt_add_timestamp.o
+endif
+
 # enable CPU hotplug support if SMP is enabled
 ifeq ($(CONFIG_SMP), y)
 	QDF_OBJS += $(QDF_OBJ_DIR)/qdf_cpuhp.o
@@ -3147,6 +3155,7 @@ cppflags-$(CONFIG_WLAN_FREQ_LIST) += -DCONFIG_WLAN_FREQ_LIST
 cppflags-$(CONFIG_WIFI_MONITOR_SUPPORT) += -DWIFI_MONITOR_SUPPORT
 cppflags-$(CONFIG_QCA_MONITOR_PKT_SUPPORT) += -DQCA_MONITOR_PKT_SUPPORT
 cppflags-$(CONFIG_MONITOR_MODULARIZED_ENABLE) += -DMONITOR_MODULARIZED_ENABLE
+cppflags-$(CONFIG_DP_PKT_ADD_TIMESTAMP) += -DCONFIG_DP_PKT_ADD_TIMESTAMP
 
 ifeq ($(CONFIG_LEAK_DETECTION), y)
 cppflags-y += \

+ 1 - 0
configs/default_defconfig

@@ -342,6 +342,7 @@ endif
 	CONFIG_WLAN_DUMP_IN_PROGRESS := y
 	CONFIG_WLAN_BMISS := y
 	CONFIG_WLAN_FREQ_LIST := y
+	CONFIG_DP_PKT_ADD_TIMESTAMP := y
 endif
 
 CONFIG_WLAN_POWER_DEBUG := y

+ 21 - 0
core/hdd/inc/wlan_hdd_tsf.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -267,6 +268,18 @@ bool hdd_tsf_is_tsf64_tx_set(struct hdd_context *hdd);
  */
 int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time);
 #endif
+
+/**
+ * hdd_get_tsf_time() - get tsf time for system time
+ *
+ * @adapter_ctx: adapter context
+ * @input_time: input system time
+ * @tsf_time: tsf time for system time
+ *
+ * Return: qdf status
+ */
+QDF_STATUS hdd_get_tsf_time(void *adapter_ctx, uint64_t input_time,
+			    uint64_t *tsf_time);
 #else
 static inline int hdd_start_tsf_sync(struct hdd_adapter *adapter)
 {
@@ -288,6 +301,14 @@ bool hdd_tsf_is_tsf64_tx_set(struct hdd_context *hdd)
 {
 	return FALSE;
 }
+
+static inline
+QDF_STATUS hdd_get_tsf_time(void *adapter_ctx, uint64_t input_time,
+			    uint64_t *tsf_time)
+{
+	*tsf_time = 0;
+	return QDF_STATUS_E_NOSUPPORT;
+}
 #endif
 
 #ifdef WLAN_FEATURE_TSF_PTP

+ 27 - 1
core/hdd/inc/wlan_hdd_tx_rx.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -32,6 +32,7 @@
 #include <linux/skbuff.h>
 #include "cdp_txrx_flow_ctrl_legacy.h"
 #include <qdf_tracepoint.h>
+#include <qdf_pkt_add_timestamp.h>
 
 struct hdd_netif_queue_history;
 struct hdd_context;
@@ -601,4 +602,29 @@ static inline bool hdd_rx_pkt_tracepoints_enabled(void)
 		qdf_trace_dp_rx_udp_pkt_enabled() ||
 		qdf_trace_dp_rx_pkt_enabled());
 }
+
+#ifdef CONFIG_DP_PKT_ADD_TIMESTAMP
+
+/**
+ * hdd_pkt_add_timestamp() - add timestamp in data payload
+ *
+ * @adapter - adapter context
+ * @index - timestamp index which decides offset in payload
+ * @time - time to update in payload
+ * @skb - socket buffer
+ *
+ * Return: none
+ */
+void hdd_pkt_add_timestamp(struct hdd_adapter *adapter,
+			   enum qdf_pkt_timestamp_index index, uint64_t time,
+			   struct sk_buff *skb);
+#else
+static inline
+void hdd_pkt_add_timestamp(struct hdd_adapter *adapter,
+			   enum qdf_pkt_timestamp_index index, uint64_t time,
+			   struct sk_buff *skb)
+{
+}
+#endif
+
 #endif /* end #if !defined(WLAN_HDD_TX_RX_H) */

+ 2 - 1
core/hdd/src/wlan_hdd_assoc.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1279,6 +1279,7 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter,
 
 	txrx_ops.tx.tx_comp = hdd_sta_notify_tx_comp_cb;
 	txrx_ops.tx.tx = NULL;
+	txrx_ops.get_tsf_time = hdd_get_tsf_time;
 	cdp_vdev_register(soc, adapter->vdev_id, (ol_osif_vdev_handle)adapter,
 			  &txrx_ops);
 	if (!txrx_ops.tx.tx) {

+ 9 - 1
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -49,6 +49,7 @@
 #include "wlan_hdd_sta_info.h"
 #include "ol_defines.h"
 #include <wlan_hdd_sar_limits.h>
+#include "wlan_hdd_tsf.h"
 
 /* Preprocessor definitions and constants */
 #undef QCA_HDD_SAP_DUMP_SK_BUFF
@@ -727,6 +728,9 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 
 	wlan_hdd_classify_pkt(skb);
 
+	hdd_pkt_add_timestamp(adapter, QDF_PKT_TX_DRIVER_ENTRY,
+			      qdf_get_log_timestamp(), skb);
+
 	if (QDF_IS_STATUS_ERROR(hdd_softap_validate_peer_state(adapter, skb)))
 		goto drop_pkt;
 
@@ -1196,6 +1200,9 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf)
 			continue;
 		}
 
+		hdd_pkt_add_timestamp(adapter, QDF_PKT_RX_DRIVER_EXIT,
+				      qdf_get_log_timestamp(), skb);
+
 		hdd_event_eapol_log(skb, QDF_RX);
 		qdf_dp_trace_log_pkt(adapter->vdev_id,
 				     skb, QDF_RX, QDF_TRACE_DEFAULT_PDEV_ID);
@@ -1381,6 +1388,7 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
 		txrx_ops.rx.rx_flush = NULL;
 	}
 
+	txrx_ops.get_tsf_time = hdd_get_tsf_time;
 	cdp_vdev_register(soc,
 			  adapter->vdev_id,
 			  (ol_osif_vdev_handle)adapter,

+ 3 - 0
core/hdd/src/wlan_hdd_sysfs.c

@@ -78,6 +78,7 @@
 #include <wlan_hdd_sysfs_swlm.h>
 #include <wlan_hdd_sysfs_dump_in_progress.h>
 #include <wlan_hdd_sysfs_txrx_stats_console.h>
+#include <wlan_hdd_sysfs_add_timestamp.h>
 #include "wma_api.h"
 #include "wlan_hdd_eht.h"
 #include <wlan_hdd_sysfs_bmiss.h>
@@ -856,12 +857,14 @@ void hdd_create_sysfs_files(struct hdd_context *hdd_ctx)
 		hdd_sysfs_create_wakeup_logs_to_console();
 		hdd_sysfs_dp_txrx_stats_sysfs_create(driver_kobject);
 		hdd_sysfs_get_valid_freq_for_power_create(driver_kobject);
+		hdd_sysfs_dp_pkt_add_ts_create(driver_kobject);
 	}
 }
 
 void hdd_destroy_sysfs_files(void)
 {
 	if  (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) {
+		hdd_sysfs_dp_pkt_add_ts_destroy(driver_kobject);
 		hdd_sysfs_get_valid_freq_for_power_destroy(driver_kobject);
 		hdd_sysfs_dp_txrx_stats_sysfs_destroy(driver_kobject);
 		hdd_sysfs_destroy_wakeup_logs_to_console();

+ 220 - 0
core/hdd/src/wlan_hdd_sysfs_add_timestamp.c

@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved..
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_add_timestamp.c
+ *
+ * Implementation for creating sysfs files:
+ *
+ * dp_pkt_add_ts
+ */
+
+#include <wlan_hdd_includes.h>
+#include "osif_psoc_sync.h"
+#include <wlan_hdd_sysfs.h>
+#include <wlan_hdd_sysfs_add_timestamp.h>
+#include "qdf_trace.h"
+
+#define MAX_USER_COMMAND_SIZE_TIMESTAMP 512
+
+static int hdd_set_dp_pkt_add_ts_info(char *in_str)
+{
+	char *str, *token, *substr, *subtoken;
+	enum qdf_pkt_supported_proto proto;
+	uint16_t port, offset;
+	int ret;
+
+	str = in_str;
+	while (1) {
+		token = strsep(&str, ",");
+		if (!token)
+			break;
+
+		substr = token;
+
+		/* get protocol */
+		subtoken = strsep(&substr, ":");
+		if (!subtoken)
+			return -EINVAL;
+
+		if (strncmp(subtoken, "TCP", 3) == 0) {
+			proto = QDF_PKT_PROTO_TCP;
+		} else if (strncmp(subtoken, "UDP", 3) == 0) {
+			proto = QDF_PKT_PROTO_UDP;
+		} else {
+			hdd_err("protocol not supported");
+			return -EINVAL;
+		}
+
+		/* get destination port value */
+		subtoken = strsep(&substr, ":");
+		if (!subtoken)
+			return -EINVAL;
+
+		ret = kstrtou16(subtoken, 0, &port);
+		if (ret) {
+			hdd_err("Invalid port value ret %d", ret);
+			return -EINVAL;
+		}
+
+		if (port < 1 || port > 65535) {
+			hdd_err("port not valid");
+			return -EINVAL;
+		}
+
+		/* get offset */
+		subtoken = strsep(&substr, ":");
+		if (!subtoken)
+			return -EINVAL;
+
+		ret = kstrtou16(subtoken, 0, &offset);
+		if (ret) {
+			hdd_err("Invalid offset value ret %d", ret);
+			return -EINVAL;
+		}
+
+		ret = qdf_set_dp_pkt_add_ts_info(proto, port, offset);
+		if (ret) {
+			hdd_err("pkt info set failed");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static ssize_t
+__hdd_sysfs_dp_pkt_add_ts_store(struct hdd_context *hdd_ctx,
+				struct kobj_attribute *attr,
+				char const *buf, size_t count)
+{
+	char buf_local[MAX_USER_COMMAND_SIZE_TIMESTAMP + 1];
+	char *str;
+	int ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+	if (ret) {
+		hdd_err_rl("invalid input");
+		return ret;
+	}
+
+	str = skip_spaces(buf_local);
+	if (strlen(str) == 0) {
+		qdf_clear_dp_pkt_add_ts_info();
+		return count;
+	}
+
+	qdf_clear_dp_pkt_add_ts_info();
+	ret = hdd_set_dp_pkt_add_ts_info(str);
+	if (ret)
+		hdd_err("all protocol do not set successfully");
+	return count;
+}
+
+static ssize_t hdd_sysfs_dp_pkt_add_ts_store(struct kobject *kobj,
+					     struct kobj_attribute *attr,
+					     char const *buf, size_t count)
+{
+	struct osif_psoc_sync *psoc_sync;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	ssize_t errno_size;
+	int ret;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
+					     &psoc_sync);
+	if (errno_size)
+		return errno_size;
+
+	errno_size = __hdd_sysfs_dp_pkt_add_ts_store(hdd_ctx, attr,
+						     buf, count);
+
+	osif_psoc_sync_op_stop(psoc_sync);
+
+	return errno_size;
+}
+
+static ssize_t
+__hdd_sysfs_dp_pkt_add_ts_show(struct hdd_context *hdd_ctx,
+			       struct kobj_attribute *attr, char *buf)
+{
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	return qdf_show_dp_pkt_add_ts_info(buf, PAGE_SIZE);
+}
+
+static ssize_t hdd_sysfs_dp_pkt_add_ts_show(struct kobject *kobj,
+					    struct kobj_attribute *attr,
+					    char *buf)
+{
+	struct osif_psoc_sync *psoc_sync;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	ssize_t errno_size;
+	int ret;
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy),
+					     &psoc_sync);
+	if (errno_size)
+		return errno_size;
+
+	errno_size = __hdd_sysfs_dp_pkt_add_ts_show(hdd_ctx, attr, buf);
+
+	osif_psoc_sync_op_stop(psoc_sync);
+
+	return errno_size;
+}
+
+static struct kobj_attribute dp_pkt_add_ts_attribute =
+	__ATTR(dp_pkt_add_ts, 0660, hdd_sysfs_dp_pkt_add_ts_show,
+	       hdd_sysfs_dp_pkt_add_ts_store);
+
+int hdd_sysfs_dp_pkt_add_ts_create(struct kobject *driver_kobject)
+{
+	int error;
+
+	if (!driver_kobject) {
+		hdd_err("could not get driver kobject!");
+		return -EINVAL;
+	}
+
+	error = sysfs_create_file(driver_kobject,
+				  &dp_pkt_add_ts_attribute.attr);
+	if (error)
+		hdd_err("could not create dp_pkt_add_ts sysfs file");
+
+	return error;
+}
+
+void
+hdd_sysfs_dp_pkt_add_ts_destroy(struct kobject *driver_kobject)
+{
+	if (!driver_kobject) {
+		hdd_err("could not get driver kobject!");
+		return;
+	}
+	sysfs_remove_file(driver_kobject, &dp_pkt_add_ts_attribute.attr);
+}

+ 67 - 0
core/hdd/src/wlan_hdd_sysfs_add_timestamp.h

@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved..
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_sysfs_add_timestamp.h
+ *
+ * Implementation for creating sysfs files:
+ *
+ * dp_pkt_add_ts
+ */
+
+#ifndef _WLAN_HDD_SYSFS_DP_PKT_ADD_TIMESTAMP_H
+#define _WLAN_HDD_SYSFS_DP_PKT_ADD_TIMESTAMP_H
+
+#include <qdf_pkt_add_timestamp.h>
+
+#if defined(WLAN_SYSFS) && defined(CONFIG_DP_PKT_ADD_TIMESTAMP)
+
+/**
+ * hdd_sysfs_dp_pkt_add_ts_create() - API to create dp trace related files
+ * @driver_kobject: sysfs driver kobject
+ *
+ * file path: /sys/kernel/wifi/dp_pkt_add_ts
+ *
+ * usage:
+ *      <protocol>:<destination port>:<offset in data>
+ *      echo "TCP:5210:50,UDP:5110:50" > dp_pkt_add_ts (add protocol)
+ *      echo "" > dp_pkt_add_ts (clear protocol)
+ *
+ * Return: 0 on success and errno on failure
+ */
+int hdd_sysfs_dp_pkt_add_ts_create(struct kobject *driver_kobject);
+
+/**
+ * hdd_sysfs_dp_pkt_add_ts_destroy() -
+ *   API to destroy dp trace related files
+ *
+ * Return: none
+ */
+void
+hdd_sysfs_dp_pkt_add_ts_destroy(struct kobject *driver_kobject);
+#else
+static inline int
+hdd_sysfs_dp_pkt_add_ts_create(struct kobject *driver_kobject)
+{
+	return 0;
+}
+
+static inline void
+hdd_sysfs_dp_pkt_add_ts_destroy(struct kobject *driver_kobject)
+{
+}
+#endif
+#endif /* #ifndef _WLAN_HDD_SYSFS_DP_PKT_ADD_TIMESTAMP_H */

+ 29 - 1
core/hdd/src/wlan_hdd_tsf.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1006,6 +1006,33 @@ hdd_get_tsftime_from_qtime(struct hdd_adapter *adapter, uint64_t qtime,
 	return ret;
 }
 
+QDF_STATUS hdd_get_tsf_time(void *adapter_ctx, uint64_t input_time,
+			    uint64_t *tsf_time)
+{
+	struct hdd_adapter *adapter;
+	uint64_t tsf_sync_qtime, qtime;
+
+	/* Sanity check on inputs */
+	if (unlikely((!adapter_ctx) || (!input_time))) {
+		hdd_err("Invalid param passed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = (struct hdd_adapter *)adapter_ctx;
+	if (unlikely(adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+		hdd_err("Magic cookie(%x) for adapter sanity verification is invalid",
+			adapter->magic);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	tsf_sync_qtime = adapter->last_tsf_sync_soc_time;
+	tsf_sync_qtime = qdf_do_div(tsf_sync_qtime, NSEC_PER_USEC);
+
+	qtime = qdf_log_timestamp_to_usecs(input_time);
+	hdd_get_tsftime_from_qtime(adapter, qtime, tsf_sync_qtime, tsf_time);
+	return QDF_STATUS_SUCCESS;
+}
+
 static void hdd_capture_tsf_timer_expired_handler(void *arg)
 {
 	uint32_t tsf_op_resp;
@@ -2050,6 +2077,7 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 {
 	return HDD_TSF_OP_SUCC;
 }
+
 #endif /* WLAN_FEATURE_TSF_PLUS */
 
 int hdd_capture_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len)

+ 21 - 0
core/hdd/src/wlan_hdd_tx_rx.c

@@ -1064,6 +1064,20 @@ static void hdd_mark_icmp_req_to_fw(struct hdd_context *hdd_ctx,
 }
 #endif
 
+#ifdef CONFIG_DP_PKT_ADD_TIMESTAMP
+void hdd_pkt_add_timestamp(struct hdd_adapter *adapter,
+			   enum qdf_pkt_timestamp_index index, uint64_t time,
+			   struct sk_buff *skb)
+{
+	if (unlikely(qdf_is_dp_pkt_timestamp_enabled())) {
+		uint64_t tsf_time;
+
+		hdd_get_tsf_time(adapter, time, &tsf_time);
+		qdf_add_dp_pkt_timestamp(skb, index, tsf_time);
+	}
+}
+#endif
+
 /**
  * __hdd_hard_start_xmit() - Transmit a frame
  * @skb: pointer to OS packet (sk_buff)
@@ -1160,6 +1174,9 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
 		hdd_mark_icmp_req_to_fw(hdd_ctx, skb);
 	}
 
+	hdd_pkt_add_timestamp(adapter, QDF_PKT_TX_DRIVER_ENTRY,
+			      qdf_get_log_timestamp(), skb);
+
 	/* track connectivity stats */
 	if (adapter->pkt_type_bitmap)
 		hdd_tx_rx_collect_connectivity_stats_info(skb, adapter,
@@ -2652,6 +2669,10 @@ QDF_STATUS hdd_rx_packet_cbk(void *adapter_context,
 				is_dhcp = true;
 			}
 		}
+
+		hdd_pkt_add_timestamp(adapter, QDF_PKT_RX_DRIVER_EXIT,
+				      qdf_get_log_timestamp(), skb);
+
 		/* track connectivity stats */
 		if (adapter->pkt_type_bitmap)
 			hdd_tx_rx_collect_connectivity_stats_info(skb, adapter,