Browse Source

qcacld-3.0: Add support for gpio based strobe to capture tsf

Add configuration for gpio pin used to send strobe to wlan hw.

The host driver will latch the current time and toggle the gpio
to generate a strobe to wlan hw.

The tsf will be latched on detecting the strobe and it will be
made available in a register for sw access.
The wlan fw will read this tsf and report it to driver using tsf event.

Change-Id: I4365d97d22836ddbbd2bf9913d4f723e5a870369
CRs-Fixed: 2495152
Subrat Dash 5 years ago
parent
commit
b1e61b2083

+ 1 - 0
Kbuild

@@ -2306,6 +2306,7 @@ cppflags-$(CONFIG_RX_PN_CHECK_OFFLOAD) += -DCONFIG_RX_PN_CHECK_OFFLOAD
 
 cppflags-$(CONFIG_WLAN_SYNC_TSF_PTP) += -DWLAN_FEATURE_TSF_PTP
 cppflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ) += -DWLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ
+cppflags-$(CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_SYNC) += -DWLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
 cppflags-$(CONFIG_TX_DESC_HI_PRIO_RESERVE) += -DCONFIG_TX_DESC_HI_PRIO_RESERVE
 
 #Enable FW logs through ini

+ 4 - 0
components/fw_offload/core/inc/wlan_fw_offload_main.h

@@ -178,6 +178,7 @@ struct wlan_fwol_neighbor_report_cfg {
  * @is_rate_limit_enabled: Enable/disable RA rate limited
  * @tsf_gpio_pin: TSF GPIO Pin config
  * @tsf_irq_host_gpio_pin: TSF GPIO Pin config
+ * @tsf_sync_host_gpio_pin: TSF Sync GPIO Pin config
  * @tsf_ptp_options: TSF Plus feature options config
  * @lprx_enable: LPRx feature enable config
  * @sae_enable: SAE feature enable config
@@ -219,6 +220,9 @@ struct wlan_fwol_cfg {
 #ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ
 	uint32_t tsf_irq_host_gpio_pin;
 #endif
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+	uint32_t tsf_sync_host_gpio_pin;
+#endif
 #endif
 #endif
 	bool lprx_enable;

+ 28 - 0
components/fw_offload/core/src/wlan_fw_offload_main.c

@@ -411,6 +411,33 @@ ucfg_fwol_fetch_tsf_irq_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
 {
 }
 #endif
+
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+/**
+ * ucfg_fwol_fetch_tsf_sync_host_gpio_pin: Populate the
+ * tsf_sync_host_gpio_pin from cfg
+ * @psoc: The global psoc handler
+ * @fwol_cfg: The cfg structure
+ *
+ * This function is used to populate the cfg value of host platform
+ * gpio pin configured to drive tsf sync interrupt pin on wlan chip.
+ *
+ * Return: none
+ */
+static void
+ucfg_fwol_fetch_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				       struct wlan_fwol_cfg *fwol_cfg)
+{
+	fwol_cfg->tsf_sync_host_gpio_pin =
+		cfg_get(psoc, CFG_SET_TSF_SYNC_HOST_GPIO_PIN);
+}
+#else
+static void
+ucfg_fwol_fetch_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				       struct wlan_fwol_cfg *fwol_cfg)
+{
+}
+#endif
 /**
  * ucfg_fwol_init_sae_cfg: Populate the sae control config from cfg
  * @psoc: The global psoc handler
@@ -504,6 +531,7 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
 	ucfg_fwol_fetch_ra_filter(psoc, fwol_cfg);
 	ucfg_fwol_fetch_tsf_gpio_pin(psoc, fwol_cfg);
 	ucfg_fwol_fetch_tsf_irq_host_gpio_pin(psoc, fwol_cfg);
+	ucfg_fwol_fetch_tsf_sync_host_gpio_pin(psoc, fwol_cfg);
 	ucfg_fwol_fetch_dhcp_server_settings(psoc, fwol_cfg);
 
 	return status;

+ 35 - 0
components/fw_offload/dispatcher/inc/cfg_fwol_generic.h

@@ -462,6 +462,40 @@
 #define __CFG_SET_TSF_IRQ_HOST_GPIO_PIN
 #endif
 
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+/*
+ * <ini>
+ * gtsf_sync_host_gpio_pin
+ * @Min: 0
+ * @Max: 254
+ * @Default: 255
+ *
+ * TSF sync GPIO pin of host platform
+ *
+ * The driver will use this gpio on host platform
+ * to drive the TSF sync pin on wlan chip.
+ * Toggling this gpio  will generate a strobe to fw
+ * for latching TSF.
+ *
+ * Related: None
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_SET_TSF_SYNC_HOST_GPIO_PIN CFG_INI_UINT( \
+		"gtsf_sync_host_gpio_pin", \
+		0, \
+		254, \
+		255, \
+		CFG_VALUE_OR_DEFAULT, \
+		"TSF sync GPIO pin of host platform")
+
+#define __CFG_SET_TSF_SYNC_HOST_GPIO_PIN CFG(CFG_SET_TSF_SYNC_HOST_GPIO_PIN)
+#else
+#define __CFG_SET_TSF_SYNC_HOST_GPIO_PIN
+#endif
+
 #if defined(WLAN_FEATURE_TSF) && defined(WLAN_FEATURE_TSF_PLUS)
 /* <ini>
  * gtsf_ptp_options: TSF Plus feature options
@@ -687,6 +721,7 @@
 	CFG(CFG_RA_FILTER_ENABLE) \
 	CFG(CFG_SET_TSF_GPIO_PIN) \
 	__CFG_SET_TSF_IRQ_HOST_GPIO_PIN \
+	__CFG_SET_TSF_SYNC_HOST_GPIO_PIN \
 	__CFG_SET_TSF_PTP_OPT \
 	CFG(CFG_LPRX) \
 	__CFG_IS_SAE_ENABLED \

+ 13 - 0
components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h

@@ -317,6 +317,19 @@ ucfg_fwol_get_tsf_irq_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
 				    uint32_t *tsf_irq_host_gpio_pin);
 #endif
 
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+/**
+ * ucfg_fwol_get_tsf_sync_host_gpio_pin() - Assigns tsf_sync_host_gpio_pin value
+ * @psoc: pointer to the psoc object
+ *
+ * Return: QDF Status
+ */
+
+QDF_STATUS
+ucfg_fwol_get_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *tsf_irq_host_gpio_pin);
+#endif
+
 #ifdef DHCP_SERVER_OFFLOAD
 /**
  * ucfg_fwol_get_enable_dhcp_server_offload()-Assign enable_dhcp_server_offload

+ 21 - 0
components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c

@@ -578,6 +578,27 @@ ucfg_fwol_get_tsf_irq_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+#endif
+
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+QDF_STATUS
+ucfg_fwol_get_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc,
+				     uint32_t *tsf_sync_host_gpio_pin)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL obj");
+		*tsf_sync_host_gpio_pin =
+			cfg_default(CFG_SET_TSF_SYNC_HOST_GPIO_PIN);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*tsf_sync_host_gpio_pin = fwol_obj->cfg.tsf_sync_host_gpio_pin;
+	return QDF_STATUS_SUCCESS;
+}
+
 #endif
 #endif
 #else

+ 3 - 2
configs/genoa.usb.debug_defconfig

@@ -31,11 +31,12 @@ ifeq ($(CONFIG_DEBUG_FS), y)
 endif
 
 ifeq ($(CONFIG_NETWORK_PHY_TIMESTAMPING), y)
-	CONFIG_WLAN_SYNC_TSF_PLUS := y
 	CONFIG_WLAN_SYNC_TSF_PTP := y
-	CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ := y
 endif
 
+CONFIG_WLAN_SYNC_TSF_PLUS := y
+CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_SYNC := y
+
 # Features gets enabled on slub debug
 CONFIG_WLAN_DEBUG_CRASH_INJECT := y
 CONFIG_FEATURE_MEMDUMP_ENABLE := y

+ 3 - 2
configs/genoa.usb.perf_defconfig

@@ -36,11 +36,12 @@ CONFIG_LEAK_DETECTION := n
 endif
 
 ifeq ($(CONFIG_NETWORK_PHY_TIMESTAMPING), y)
-	CONFIG_WLAN_SYNC_TSF_PLUS := y
 	CONFIG_WLAN_SYNC_TSF_PTP := y
-	CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ := y
 endif
 
+CONFIG_WLAN_SYNC_TSF_PLUS := y
+CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_SYNC := y
+
 CONFIG_ENABLE_SIZE_OPTIMIZE := y
 
 # configure log buffer size

+ 4 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1153,6 +1153,7 @@ struct hdd_context;
  * @vdev_id: Unique identifier assigned to the vdev
  * @event_flags: a bitmap of hdd_adapter_flags
  * @mic_work: mic work information
+ * @gpio_tsf_sync_work: work to sync send TSF CAP WMI command
  *
  */
 struct hdd_adapter {
@@ -1293,6 +1294,9 @@ struct hdd_adapter {
 	int continuous_error_count;
 	/* to indicate whether tsf_sync has been initialized */
 	qdf_atomic_t tsf_sync_ready_flag;
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+	qdf_work_t gpio_tsf_sync_work;
+#endif
 #endif /* WLAN_FEATURE_TSF_PLUS */
 #endif
 

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

@@ -161,15 +161,6 @@ static inline int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
 #endif
 
 #if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF)
-/**
- * hdd_tsf_is_ptp_enabled() - check ini configuration
- * @hdd: pointer to hdd context
- *
- * This function checks tsf configuration for ptp
- *
- * Return: true on enable, false on disable
- */
-bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd);
 /**
  * hdd_tsf_is_tx_set() - check ini configuration
  * @hdd: pointer to hdd context

+ 237 - 40
core/hdd/src/wlan_hdd_tsf.c

@@ -27,17 +27,27 @@
 #include "wlan_fwol_ucfg_api.h"
 #include <qca_vendor.h>
 #include <linux/errqueue.h>
-#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ
+#if defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ) || \
+	defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC)
 #include <linux/gpio.h>
-static int tsf_gpio_irq_num = -1;
 #endif
+
 #include "ol_txrx_api.h"
 
+#ifdef WLAN_FEATURE_TSF_PLUS
+#ifndef WLAN_FEATURE_TSF_PLUS_NOIRQ
+#ifndef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+static int tsf_gpio_irq_num = -1;
+#endif
+#endif
+#endif
 static struct completion tsf_sync_get_completion_evt;
 #define WLAN_TSF_SYNC_GET_TIMEOUT 2000
 #define WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS 500
 #define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100
 #define WLAN_HDD_SOFTAP_INTERVEL_TIMES 100
+#define OUTPUT_HIGH 1
+#define OUTPUT_LOW 0
 
 #ifdef WLAN_FEATURE_TSF_PLUS
 #ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ
@@ -61,8 +71,11 @@ enum hdd_tsf_op_result {
 };
 
 #ifdef WLAN_FEATURE_TSF_PLUS
+#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
+#define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 1
+#else
 #define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 9
-
+#endif
 static inline void hdd_set_th_sync_status(struct hdd_adapter *adapter,
 					  bool initialized)
 {
@@ -130,7 +143,9 @@ static bool hdd_tsf_is_initialized(struct hdd_adapter *adapter)
 	return true;
 }
 
-#if defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) && defined(WLAN_FEATURE_TSF_PLUS)
+#if (defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) && \
+	defined(WLAN_FEATURE_TSF_PLUS)) || \
+	defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC)
 /**
  * hdd_tsf_reset_gpio() - Reset TSF GPIO used for host timer sync
  * @adapter: pointer to adapter
@@ -207,7 +222,7 @@ static QDF_STATUS hdd_tsf_set_gpio(struct hdd_context *hdd_ctx)
 #endif
 
 #ifdef WLAN_FEATURE_TSF_PLUS
-bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd)
+static bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd)
 {
 	uint32_t tsf_ptp_options;
 
@@ -272,6 +287,142 @@ bool hdd_tsf_is_tsf64_tx_set(struct hdd_context *hdd)
 	else
 		return false;
 }
+#else
+
+static bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd)
+{
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+static inline
+uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx)
+{
+	return hdd_tsf_is_raw_set(hdd_ctx) ?
+		ktime_get_ns() : ktime_get_real_ns();
+}
+#endif
+
+#if defined(WLAN_FEATURE_TSF_PLUS) && \
+	defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC)
+static void
+hdd_update_host_time(struct hdd_adapter *adapter)
+{
+	struct hdd_context *hdd_ctx;
+	u64 host_time;
+	char *name = NULL;
+
+	hdd_ctx = adapter->hdd_ctx;
+
+	if (!hdd_tsf_is_initialized(adapter)) {
+		hdd_err("tsf is not init, exit");
+		return;
+	}
+
+	host_time = hdd_get_monotonic_host_time(hdd_ctx);
+	hdd_update_timestamp(adapter, 0, host_time);
+	name = adapter->dev->name;
+
+	hdd_debug("iface: %s - host_time: %llu",
+		  (!name ? "none" : name), host_time);
+}
+
+static
+void hdd_tsf_ext_gpio_sync_work(void *data)
+{
+	QDF_STATUS status;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+	uint32_t tsf_sync_gpio_pin = TSF_GPIO_PIN_INVALID;
+
+	adapter = data;
+	hdd_ctx = adapter->hdd_ctx;
+	status = ucfg_fwol_get_tsf_sync_host_gpio_pin(hdd_ctx->psoc,
+						      &tsf_sync_gpio_pin);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("tsf sync gpio host pin error");
+		return;
+	}
+	gpio_set_value(tsf_sync_gpio_pin, OUTPUT_HIGH);
+	hdd_update_host_time(adapter);
+	usleep_range(50, 100);
+	gpio_set_value(tsf_sync_gpio_pin, OUTPUT_LOW);
+
+	status = wma_cli_set_command((int)adapter->vdev_id,
+				     (int)GEN_PARAM_CAPTURE_TSF,
+				     adapter->vdev_id, GEN_CMD);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("cap tsf fail");
+		qdf_mc_timer_stop(&adapter->host_capture_req_timer);
+		qdf_mc_timer_destroy(&adapter->host_capture_req_timer);
+	}
+}
+
+static void
+hdd_tsf_gpio_sync_work_init(struct hdd_adapter *adapter)
+{
+	qdf_create_work(0, &adapter->gpio_tsf_sync_work,
+			hdd_tsf_ext_gpio_sync_work, adapter);
+}
+
+static void
+hdd_tsf_gpio_sync_work_deinit(struct hdd_adapter *adapter)
+{
+	qdf_destroy_work(0, &adapter->gpio_tsf_sync_work);
+}
+
+static void
+hdd_tsf_stop_ext_gpio_sync(struct hdd_adapter *adapter)
+{
+	qdf_cancel_work(&adapter->gpio_tsf_sync_work);
+}
+
+static void
+hdd_tsf_start_ext_gpio_sync(struct hdd_adapter *adapter)
+{
+	qdf_sched_work(0, &adapter->gpio_tsf_sync_work);
+}
+
+static bool hdd_tsf_cap_sync_send(struct hdd_adapter *adapter)
+{
+	hdd_tsf_start_ext_gpio_sync(adapter);
+	return true;
+}
+#elif defined(WLAN_FEATURE_TSF_PLUS) && \
+	!defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC)
+static void
+hdd_tsf_gpio_sync_work_init(struct hdd_adapter *adapter)
+{
+}
+
+static void
+hdd_tsf_gpio_sync_work_deinit(struct hdd_adapter *adapter)
+{
+}
+
+static void
+hdd_tsf_stop_ext_gpio_sync(struct hdd_adapter *adapter)
+{
+}
+
+static void
+hdd_tsf_start_ext_gpio_sync(struct hdd_adapter *adapter)
+{
+}
+
+static bool
+hdd_tsf_cap_sync_send(struct hdd_adapter *adapter)
+{
+	hdd_tsf_start_ext_gpio_sync(adapter);
+	return false;
+}
+
+#else
+static bool hdd_tsf_cap_sync_send(struct hdd_adapter *adapter)
+{
+	return false;
+}
 #endif
 
 static enum hdd_tsf_op_result hdd_capture_tsf_internal(
@@ -325,6 +476,10 @@ static enum hdd_tsf_op_result hdd_capture_tsf_internal(
 
 	buf[0] = TSF_RETURN;
 	init_completion(&tsf_sync_get_completion_evt);
+
+	if (hdd_tsf_cap_sync_send(adapter))
+		return HDD_TSF_OP_SUCC;
+
 	ret = wma_cli_set_command((int)adapter->vdev_id,
 				  (int)GEN_PARAM_CAPTURE_TSF,
 				  adapter->vdev_id, GEN_CMD);
@@ -414,7 +569,8 @@ static enum hdd_tsf_op_result hdd_indicate_tsf_internal(
 /* to distinguish 32-bit overflow case, this inverval should:
  * equal or less than (1/2 * OVERFLOW_INDICATOR32 us)
  */
-#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ
+#if defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ) || \
+	defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC)
 #define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 2
 #else
 #define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 10
@@ -446,6 +602,7 @@ enum hdd_tsf_op_result __hdd_start_tsf_sync(struct hdd_adapter *adapter)
 		return HDD_TSF_OP_FAIL;
 	}
 
+	hdd_tsf_gpio_sync_work_init(adapter);
 	ret = qdf_mc_timer_start(&adapter->host_target_sync_timer,
 				 WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS);
 	if (ret != QDF_STATUS_SUCCESS && ret != QDF_STATUS_E_ALREADY) {
@@ -470,6 +627,8 @@ enum hdd_tsf_op_result __hdd_stop_tsf_sync(struct hdd_adapter *adapter)
 		hdd_err("Failed to stop timer, ret: %d", ret);
 		return HDD_TSF_OP_FAIL;
 	}
+	hdd_tsf_stop_ext_gpio_sync(adapter);
+	hdd_tsf_gpio_sync_work_deinit(adapter);
 	return HDD_TSF_OP_SUCC;
 }
 
@@ -733,13 +892,6 @@ static inline int32_t hdd_get_soctime_from_tsf64time(
 	return ret;
 }
 
-static inline
-uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx)
-{
-	return hdd_tsf_is_raw_set(hdd_ctx) ?
-		ktime_get_ns() : ktime_get_real_ns();
-}
-
 static void hdd_capture_tsf_timer_expired_handler(void *arg)
 {
 	uint32_t tsf_op_resp;
@@ -753,6 +905,7 @@ static void hdd_capture_tsf_timer_expired_handler(void *arg)
 }
 
 #ifndef WLAN_FEATURE_TSF_PLUS_NOIRQ
+#ifndef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
 static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg)
 {
 	struct hdd_adapter *adapter;
@@ -788,6 +941,7 @@ static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 #endif
+#endif
 
 void hdd_capture_req_timer_expired_handler(void *arg)
 {
@@ -1424,14 +1578,10 @@ static inline int __hdd_indicate_tsf(struct hdd_adapter *adapter,
 	return 0;
 }
 
-#ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ
+#if defined(WLAN_FEATURE_TSF_PLUS_NOIRQ)
 static inline
 enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
 {
-	if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) {
-		hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini");
-		return HDD_TSF_OP_FAIL;
-	}
 
 	if (hdd_tsf_is_tx_set(hdd_ctx))
 		ol_register_timestamp_callback(hdd_tx_timestamp);
@@ -1446,9 +1596,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 	qdf_mc_timer_t *cap_timer;
 	struct hdd_adapter *adapter, *adapternode_ptr, *next_ptr;
 
-	if (!hdd_tsf_is_ptp_enabled(hdd_ctx))
-		return HDD_TSF_OP_SUCC;
-
 	if (hdd_tsf_is_tx_set(hdd_ctx))
 		ol_deregister_timestamp_callback();
 
@@ -1476,20 +1623,79 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 
 	return HDD_TSF_OP_SUCC;
 }
-#else
-#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ
+
+#elif defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC)
 static
 enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
 {
 	int ret;
 	QDF_STATUS status;
-	uint32_t tsf_irq_gpio_pin = TSF_GPIO_PIN_INVALID;
+	uint32_t tsf_sync_gpio_pin = TSF_GPIO_PIN_INVALID;
+
+	status = ucfg_fwol_get_tsf_sync_host_gpio_pin(hdd_ctx->psoc,
+						      &tsf_sync_gpio_pin);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("tsf gpio irq host pin error");
+		goto fail;
+	}
 
-	if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) {
-		hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini");
+	if (tsf_sync_gpio_pin == TSF_GPIO_PIN_INVALID) {
+		hdd_err("gpio host pin is invalid");
 		goto fail;
 	}
 
+	ret = gpio_request(tsf_sync_gpio_pin, "wlan_tsf");
+	if (ret) {
+		hdd_err("gpio host pin is invalid");
+		goto fail;
+	}
+
+	ret = gpio_direction_output(tsf_sync_gpio_pin, OUTPUT_LOW);
+	if (ret) {
+		hdd_err("gpio host pin is invalid");
+		goto fail_free_gpio;
+	}
+
+	if (hdd_tsf_is_tx_set(hdd_ctx))
+		ol_register_timestamp_callback(hdd_tx_timestamp);
+
+	return HDD_TSF_OP_SUCC;
+
+fail_free_gpio:
+	gpio_free(tsf_sync_gpio_pin);
+fail:
+	return HDD_TSF_OP_FAIL;
+}
+
+static
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
+{
+	QDF_STATUS status;
+	uint32_t tsf_sync_gpio_pin = TSF_GPIO_PIN_INVALID;
+
+	status = ucfg_fwol_get_tsf_sync_host_gpio_pin(hdd_ctx->psoc,
+						      &tsf_sync_gpio_pin);
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_INVAL;
+
+	if (tsf_sync_gpio_pin == TSF_GPIO_PIN_INVALID)
+		return QDF_STATUS_E_INVAL;
+
+	if (hdd_tsf_is_tx_set(hdd_ctx))
+		ol_deregister_timestamp_callback();
+
+	gpio_free(tsf_sync_gpio_pin);
+	return HDD_TSF_OP_SUCC;
+}
+
+#elif defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ)
+static
+enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
+{
+	int ret;
+	QDF_STATUS status;
+	uint32_t tsf_irq_gpio_pin = TSF_GPIO_PIN_INVALID;
+
 	status = ucfg_fwol_get_tsf_irq_host_gpio_pin(hdd_ctx->psoc,
 						     &tsf_irq_gpio_pin);
 	if (QDF_IS_STATUS_ERROR(status)) {
@@ -1547,9 +1753,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 	QDF_STATUS status;
 	uint32_t tsf_irq_gpio_pin = TSF_GPIO_PIN_INVALID;
 
-	if (!hdd_tsf_is_ptp_enabled(hdd_ctx))
-		return HDD_TSF_OP_SUCC;
-
 	status = ucfg_fwol_get_tsf_irq_host_gpio_pin(hdd_ctx->psoc,
 						     &tsf_irq_gpio_pin);
 	if (QDF_IS_STATUS_ERROR(status))
@@ -1569,17 +1772,13 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 
 	return HDD_TSF_OP_SUCC;
 }
+
 #else
 static inline
 enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx)
 {
 	int ret;
 
-	if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) {
-		hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini");
-		return HDD_TSF_OP_FAIL;
-	}
-
 	ret = cnss_common_register_tsf_captured_handler(
 			hdd_ctx->parent_dev,
 			hdd_tsf_captured_irq_handler,
@@ -1599,9 +1798,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 {
 	int ret;
 
-	if (!hdd_tsf_is_ptp_enabled(hdd_ctx))
-		return HDD_TSF_OP_SUCC;
-
 	if (hdd_tsf_is_tx_set(hdd_ctx))
 		ol_deregister_timestamp_callback();
 
@@ -1618,7 +1814,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx)
 }
 #endif
 
-#endif
 void hdd_tsf_notify_wlan_state_change(struct hdd_adapter *adapter,
 				      eConnectionState old_state,
 				      eConnectionState new_state)
@@ -2119,7 +2314,8 @@ void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx)
 	if (wlan_hdd_tsf_plus_init(hdd_ctx) != HDD_TSF_OP_SUCC)
 		goto fail;
 
-	wlan_hdd_phc_init(hdd_ctx);
+	if (hdd_tsf_is_ptp_enabled(hdd_ctx))
+		wlan_hdd_phc_init(hdd_ctx);
 
 	return;
 
@@ -2135,7 +2331,8 @@ void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx)
 	if (!qdf_atomic_read(&hdd_ctx->tsf_ready_flag))
 		return;
 
-	wlan_hdd_phc_deinit(hdd_ctx);
+	if (hdd_tsf_is_ptp_enabled(hdd_ctx))
+		wlan_hdd_phc_deinit(hdd_ctx);
 	wlan_hdd_tsf_plus_deinit(hdd_ctx);
 	qdf_atomic_set(&hdd_ctx->tsf_ready_flag, 0);
 	qdf_atomic_set(&hdd_ctx->cap_tsf_flag, 0);