[qca-nss-drv] Timestamping support for HLOS

Add Timestamping support for the HLOS drivers

Change-Id: I3b69aff0261054fd3d6a616aa05e78c3e0c484d0
Signed-off-by: Rakesh Nair <ranair@codeaurora.org>
diff --git a/Makefile.fsm b/Makefile.fsm
index 5e0538a..6b108d1 100644
--- a/Makefile.fsm
+++ b/Makefile.fsm
@@ -38,7 +38,8 @@
 			nss_eth_rx.o  \
 			nss_wifi.o \
 			nss_wifi_vdev.o \
-			nss_wifi_if.o
+			nss_wifi_if.o \
+			nss_tstamp.o
 
 
 #
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 71e2a85..186d296 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -85,7 +85,7 @@
 #define NSS_MAX_PHYSICAL_INTERFACES 4
 #define NSS_MAX_VIRTUAL_INTERFACES 16
 #define NSS_MAX_TUNNEL_INTERFACES 4
-#define NSS_MAX_SPECIAL_INTERFACES 35
+#define NSS_MAX_SPECIAL_INTERFACES 36
 #define NSS_MAX_WIFI_RADIO_INTERFACES 3
 
 /**
@@ -135,6 +135,7 @@
 #define NSS_LAG2_INTERFACE_NUM (NSS_SPECIAL_IF_START + 32) /* Special IF number for LAG2 */
 #define NSS_LAG3_INTERFACE_NUM (NSS_SPECIAL_IF_START + 33) /* Special IF number for LAG3 */
 #define NSS_L2TPV2_INTERFACE (NSS_SPECIAL_IF_START + 34) /* Special L2TPv2 UDP encap interface */
+#define NSS_TSTAMP_INTERFACE (NSS_SPECIAL_IF_START + 35) /* Special IF number for Tstamp interface */
 
 /**
  * This macro converts format for IPv6 address (from Linux to NSS)
diff --git a/nss_core.h b/nss_core.h
index 1ede789..beac10b 100755
--- a/nss_core.h
+++ b/nss_core.h
@@ -731,6 +731,7 @@
 	uint8_t frequency_handler_id;
 	uint8_t sjack_handler_id;
 	uint8_t capwap_handler_id;
+	uint8_t tstamp_handler_id;
 
 	/* subsystem registration data */
 	struct nss_subsystem_dataplane_register subsys_dp_register[NSS_MAX_NET_INTERFACES];
@@ -962,6 +963,7 @@
 	enum nss_feature_enabled shaping_enabled;	/* Does this core handle shaping ? */
 	enum nss_feature_enabled gmac_enabled[4];	/* Does this core handle GMACs? */
 	enum nss_feature_enabled wifioffload_enabled;   /* Does this core handle WIFI OFFLOAD? */
+	enum nss_feature_enabled tstamp_enabled;	/* Does this core handle timestamping? */
 };
 #endif
 
diff --git a/nss_hal/fsm9010/nss_hal_pvt.c b/nss_hal/fsm9010/nss_hal_pvt.c
index 897ee24..817806e 100644
--- a/nss_hal/fsm9010/nss_hal_pvt.c
+++ b/nss_hal/fsm9010/nss_hal_pvt.c
@@ -191,6 +191,7 @@
 	npd->gmac_enabled[0] = of_property_read_bool(np, "qcom,gmac0-enabled");
 	npd->gmac_enabled[1] = of_property_read_bool(np, "qcom,gmac1-enabled");
 	npd->turbo_frequency = of_property_read_bool(np, "qcom,turbo-frequency");
+	npd->tstamp_enabled = of_property_read_bool(np, "qcom,tstamp-enabled");
 
 	nss_ctx = &nss_top->nss[npd->id];
 	nss_ctx->id = npd->id;
@@ -429,6 +430,11 @@
 		nss_info("%d: NSS shaping is enabled", nss_dev->id);
 	}
 
+	if (npd->tstamp_enabled == NSS_FEATURE_ENABLED) {
+		nss_top->tstamp_handler_id = nss_dev->id;
+		nss_tstamp_register_handler();
+	}
+
 	if (npd->ipv4_enabled == NSS_FEATURE_ENABLED) {
 		nss_top->ipv4_handler_id = nss_dev->id;
 		nss_ipv4_register_handler();
diff --git a/nss_hlos_if.h b/nss_hlos_if.h
index d84cf1d..05ee706 100755
--- a/nss_hlos_if.h
+++ b/nss_hlos_if.h
@@ -328,6 +328,7 @@
 #define H2N_BIT_FLAG_LAST_SEGMENT			0x0008
 
 #define H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM_NONE	0x0010
+#define H2N_BIT_FLAG_TX_TS_REQUIRED 			0x0040
 #define H2N_BIT_FLAG_DISCARD				0x0080
 #define H2N_BIT_FLAG_SEGMENTATION_ENABLE		0x0100
 
diff --git a/nss_phys_if.c b/nss_phys_if.c
index b8af1c2..59f92b2 100644
--- a/nss_phys_if.c
+++ b/nss_phys_if.c
@@ -93,6 +93,7 @@
 	gmac_stats.rx_missed = stats->estats.rx_missed;
 	gmac_stats.fifo_overflows = stats->estats.fifo_overflows;
 	gmac_stats.rx_scatter_errors = stats->estats.rx_scatter_errors;
+	gmac_stats.tx_ts_create_errors = stats->estats.tx_ts_create_errors;
 	gmac_stats.gmac_total_ticks = stats->estats.gmac_total_ticks;
 	gmac_stats.gmac_worst_case_ticks = stats->estats.gmac_worst_case_ticks;
 	gmac_stats.gmac_iterations = stats->estats.gmac_iterations;
@@ -274,6 +275,7 @@
 nss_tx_status_t nss_phys_if_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num)
 {
 	int32_t status;
+	uint16_t flags = 0;
 
 	nss_trace("%p: Phys If Tx packet, id:%d, data=%p", nss_ctx, if_num, os_buf->data);
 
@@ -283,7 +285,12 @@
 		return NSS_TX_FAILURE_NOT_READY;
 	}
 
-	status = nss_core_send_buffer(nss_ctx, if_num, os_buf, NSS_IF_DATA_QUEUE_0, H2N_BUFFER_PACKET, 0);
+	/* Check if we need the packet to be timestamped by GMAC Hardware at Tx */
+	if (unlikely(skb_shinfo(os_buf)->tx_flags & SKBTX_HW_TSTAMP)) {
+		flags |= H2N_BIT_FLAG_TX_TS_REQUIRED;
+	}
+
+	status = nss_core_send_buffer(nss_ctx, if_num, os_buf, NSS_IF_DATA_QUEUE_0, H2N_BUFFER_PACKET, flags);
 	if (unlikely(status != NSS_CORE_STATUS_SUCCESS)) {
 		nss_warning("%p: Unable to enqueue 'Phys If Tx' packet\n", nss_ctx);
 		if (status == NSS_CORE_STATUS_FAILURE_QUEUE) {
diff --git a/nss_phys_if.h b/nss_phys_if.h
index 2fcaa17..59efebf 100644
--- a/nss_phys_if.h
+++ b/nss_phys_if.h
@@ -69,6 +69,7 @@
 	uint32_t rx_missed;		/**< Number of RX packets missed by the DMA */
 	uint32_t fifo_overflows;	/**< Number of RX FIFO overflows signalled by the DMA */
 	uint32_t rx_scatter_errors;	/**< Number of scattered frames received by the DMA */
+	uint32_t tx_ts_create_errors;	/**< Number of tx timestamp creation errors */
 	uint32_t gmac_total_ticks;	/**< Total clock ticks spend inside the GMAC */
 	uint32_t gmac_worst_case_ticks;	/**< Worst case iteration of the GMAC in ticks */
 	uint32_t gmac_iterations;	/**< Number of iterations around the GMAC */
diff --git a/nss_tx_rx_common.h b/nss_tx_rx_common.h
index 95e67f4..7575597 100644
--- a/nss_tx_rx_common.h
+++ b/nss_tx_rx_common.h
@@ -198,6 +198,7 @@
 extern void nss_lso_rx_register_handler(void);
 extern void nss_sjack_register_handler(void);
 extern void nss_wifi_register_handler(void);
+extern void nss_tstamp_register_handler(void);
 
 /*
  * nss_if_msg_handler()