[v3,15/15] net/bnxt: add PTP support for Thor

Message ID 20191002012335.85324-16-ajit.khaparde@broadcom.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series bnxt patchset to support device error recovery |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Ajit Khaparde Oct. 2, 2019, 1:23 a.m. UTC
  From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>

On Thor, direct access to PTP registers (via GRC) is not supported.
Driver must use HWRM to access the timestamp information.

Vectorized Rx/Tx cannot be enabled if RTE_LIBRTE_IEEE1588=y.
Remove the PTP flags handling code from the vector Rx path.

Add support to read tx timestamp value and the time from the
timesync clock.

On Thor, Rx timestamps are provided directly in the Rx completion
records to the driver. Only 32 bits of the timestamp is present in
the completion. Driver needs to read the current 48 bit free running
timer using the HWRM_PORT_TS_QUERY command and combine the upper
16 bits from the HWRM response with the lower 32 bits in the
Rx completion to produce the 48 bit timestamp for the Rx packet.

Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  8 +++
 drivers/net/bnxt/bnxt_ethdev.c         | 46 +++++++++++---
 drivers/net/bnxt/bnxt_hwrm.c           | 86 ++++++++++++++++++++------
 drivers/net/bnxt/bnxt_hwrm.h           |  2 +
 drivers/net/bnxt/bnxt_rxr.c            | 42 +++++++++++--
 drivers/net/bnxt/bnxt_txr.c            |  7 ++-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 86 ++++++++++++++++++++++++++
 7 files changed, 243 insertions(+), 34 deletions(-)
  

Patch

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 310b730e68..818a49f461 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -189,6 +189,10 @@  struct rte_flow {
 	struct bnxt_vnic_info	*vnic;
 };
 
+#define BNXT_PTP_FLAGS_PATH_TX		0x0
+#define BNXT_PTP_FLAGS_PATH_RX		0x1
+#define BNXT_PTP_FLAGS_CURRENT_TIME	0x2
+
 struct bnxt_ptp_cfg {
 #define BNXT_GRCPF_REG_WINDOW_BASE_OUT  0x400
 #define BNXT_GRCPF_REG_SYNC_TIME        0x480
@@ -234,6 +238,9 @@  struct bnxt_ptp_cfg {
 	uint32_t			rx_mapped_regs[BNXT_PTP_RX_REGS];
 	uint32_t			tx_regs[BNXT_PTP_TX_REGS];
 	uint32_t			tx_mapped_regs[BNXT_PTP_TX_REGS];
+
+	/* On Thor, the Rx timestamp is present in the Rx completion record */
+	uint64_t			rx_timestamp;
 };
 
 struct bnxt_coal {
@@ -428,6 +435,7 @@  struct bnxt {
 #define BNXT_FLAG_EXT_STATS_SUPPORTED		BIT(22)
 #define BNXT_FLAG_NEW_RM			BIT(23)
 #define BNXT_FLAG_INIT_DONE			BIT(24)
+#define BNXT_FLAG_FW_CAP_ONE_STEP_TX_TS		BIT(25)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR(bp)		((bp)->port_partition_type)
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7c3ef93253..0083ba6e83 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -740,6 +740,7 @@  static eth_rx_burst_t
 bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
 {
 #ifdef RTE_ARCH_X86
+#ifndef RTE_LIBRTE_IEEE1588
 	/*
 	 * Vector mode receive can be enabled only if scatter rx is not
 	 * in use and rx offloads are limited to VLAN stripping and
@@ -766,6 +767,7 @@  bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
 		    eth_dev->data->port_id,
 		    eth_dev->data->scattered_rx,
 		    eth_dev->data->dev_conf.rxmode.offloads);
+#endif
 #endif
 	return bnxt_recv_pkts;
 }
@@ -774,6 +776,7 @@  static eth_tx_burst_t
 bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev)
 {
 #ifdef RTE_ARCH_X86
+#ifndef RTE_LIBRTE_IEEE1588
 	/*
 	 * Vector mode transmit can be enabled only if not using scatter rx
 	 * or tx offloads.
@@ -791,6 +794,7 @@  bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev)
 		    eth_dev->data->port_id,
 		    eth_dev->data->scattered_rx,
 		    eth_dev->data->dev_conf.txmode.offloads);
+#endif
 #endif
 	return bnxt_xmit_pkts;
 }
@@ -3223,18 +3227,24 @@  bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
 static int
 bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
 {
-	uint64_t ns, systime_cycles;
 	struct bnxt *bp = dev->data->dev_private;
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+	uint64_t ns, systime_cycles = 0;
+	int rc = 0;
 
 	if (!ptp)
 		return 0;
 
-	systime_cycles = bnxt_cc_read(bp);
+	if (BNXT_CHIP_THOR(bp))
+		rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
+					     &systime_cycles);
+	else
+		systime_cycles = bnxt_cc_read(bp);
+
 	ns = rte_timecounter_update(&ptp->tc, systime_cycles);
 	*ts = rte_ns_to_timespec(ns);
 
-	return 0;
+	return rc;
 }
 static int
 bnxt_timesync_enable(struct rte_eth_dev *dev)
@@ -3242,6 +3252,7 @@  bnxt_timesync_enable(struct rte_eth_dev *dev)
 	struct bnxt *bp = dev->data->dev_private;
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
 	uint32_t shift = 0;
+	int rc;
 
 	if (!ptp)
 		return 0;
@@ -3250,8 +3261,9 @@  bnxt_timesync_enable(struct rte_eth_dev *dev)
 	ptp->tx_tstamp_en = 1;
 	ptp->rxctl = BNXT_PTP_MSG_EVENTS;
 
-	if (!bnxt_hwrm_ptp_cfg(bp))
-		bnxt_map_ptp_regs(bp);
+	rc = bnxt_hwrm_ptp_cfg(bp);
+	if (rc)
+		return rc;
 
 	memset(&ptp->tc, 0, sizeof(struct rte_timecounter));
 	memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
@@ -3269,6 +3281,9 @@  bnxt_timesync_enable(struct rte_eth_dev *dev)
 	ptp->tx_tstamp_tc.cc_shift = shift;
 	ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
 
+	if (!BNXT_CHIP_THOR(bp))
+		bnxt_map_ptp_regs(bp);
+
 	return 0;
 }
 
@@ -3287,7 +3302,8 @@  bnxt_timesync_disable(struct rte_eth_dev *dev)
 
 	bnxt_hwrm_ptp_cfg(bp);
 
-	bnxt_unmap_ptp_regs(bp);
+	if (!BNXT_CHIP_THOR(bp))
+		bnxt_unmap_ptp_regs(bp);
 
 	return 0;
 }
@@ -3305,7 +3321,11 @@  bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
 	if (!ptp)
 		return 0;
 
-	bnxt_get_rx_ts(bp, &rx_tstamp_cycles);
+	if (BNXT_CHIP_THOR(bp))
+		rx_tstamp_cycles = ptp->rx_timestamp;
+	else
+		bnxt_get_rx_ts(bp, &rx_tstamp_cycles);
+
 	ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles);
 	*timestamp = rte_ns_to_timespec(ns);
 	return  0;
@@ -3319,15 +3339,21 @@  bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
 	uint64_t tx_tstamp_cycles = 0;
 	uint64_t ns;
+	int rc = 0;
 
 	if (!ptp)
 		return 0;
 
-	bnxt_get_tx_ts(bp, &tx_tstamp_cycles);
+	if (BNXT_CHIP_THOR(bp))
+		rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_PATH_TX,
+					     &tx_tstamp_cycles);
+	else
+		rc = bnxt_get_tx_ts(bp, &tx_tstamp_cycles);
+
 	ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles);
 	*timestamp = rte_ns_to_timespec(ns);
 
-	return 0;
+	return rc;
 }
 
 static int
@@ -4574,6 +4600,8 @@  bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev)
 		}
 	}
 
+	rte_free(bp->ptp_cfg);
+	bp->ptp_cfg = NULL;
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7304cbf72c..174dc75d54 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -506,31 +506,37 @@  static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT();
 
-	if (!(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS))
+	if (!BNXT_CHIP_THOR(bp) &&
+	    !(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS))
 		return 0;
 
+	if (resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_ONE_STEP_TX_TS)
+		bp->flags |= BNXT_FLAG_FW_CAP_ONE_STEP_TX_TS;
+
 	ptp = rte_zmalloc("ptp_cfg", sizeof(*ptp), 0);
 	if (!ptp)
 		return -ENOMEM;
 
-	ptp->rx_regs[BNXT_PTP_RX_TS_L] =
-		rte_le_to_cpu_32(resp->rx_ts_reg_off_lower);
-	ptp->rx_regs[BNXT_PTP_RX_TS_H] =
-		rte_le_to_cpu_32(resp->rx_ts_reg_off_upper);
-	ptp->rx_regs[BNXT_PTP_RX_SEQ] =
-		rte_le_to_cpu_32(resp->rx_ts_reg_off_seq_id);
-	ptp->rx_regs[BNXT_PTP_RX_FIFO] =
-		rte_le_to_cpu_32(resp->rx_ts_reg_off_fifo);
-	ptp->rx_regs[BNXT_PTP_RX_FIFO_ADV] =
-		rte_le_to_cpu_32(resp->rx_ts_reg_off_fifo_adv);
-	ptp->tx_regs[BNXT_PTP_TX_TS_L] =
-		rte_le_to_cpu_32(resp->tx_ts_reg_off_lower);
-	ptp->tx_regs[BNXT_PTP_TX_TS_H] =
-		rte_le_to_cpu_32(resp->tx_ts_reg_off_upper);
-	ptp->tx_regs[BNXT_PTP_TX_SEQ] =
-		rte_le_to_cpu_32(resp->tx_ts_reg_off_seq_id);
-	ptp->tx_regs[BNXT_PTP_TX_FIFO] =
-		rte_le_to_cpu_32(resp->tx_ts_reg_off_fifo);
+	if (!BNXT_CHIP_THOR(bp)) {
+		ptp->rx_regs[BNXT_PTP_RX_TS_L] =
+			rte_le_to_cpu_32(resp->rx_ts_reg_off_lower);
+		ptp->rx_regs[BNXT_PTP_RX_TS_H] =
+			rte_le_to_cpu_32(resp->rx_ts_reg_off_upper);
+		ptp->rx_regs[BNXT_PTP_RX_SEQ] =
+			rte_le_to_cpu_32(resp->rx_ts_reg_off_seq_id);
+		ptp->rx_regs[BNXT_PTP_RX_FIFO] =
+			rte_le_to_cpu_32(resp->rx_ts_reg_off_fifo);
+		ptp->rx_regs[BNXT_PTP_RX_FIFO_ADV] =
+			rte_le_to_cpu_32(resp->rx_ts_reg_off_fifo_adv);
+		ptp->tx_regs[BNXT_PTP_TX_TS_L] =
+			rte_le_to_cpu_32(resp->tx_ts_reg_off_lower);
+		ptp->tx_regs[BNXT_PTP_TX_TS_H] =
+			rte_le_to_cpu_32(resp->tx_ts_reg_off_upper);
+		ptp->tx_regs[BNXT_PTP_TX_SEQ] =
+			rte_le_to_cpu_32(resp->tx_ts_reg_off_seq_id);
+		ptp->tx_regs[BNXT_PTP_TX_FIFO] =
+			rte_le_to_cpu_32(resp->tx_ts_reg_off_fifo);
+	}
 
 	ptp->bp = bp;
 	bp->ptp_cfg = ptp;
@@ -4834,3 +4840,45 @@  int bnxt_hwrm_fw_reset(struct bnxt *bp)
 
 	return rc;
 }
+
+int bnxt_hwrm_port_ts_query(struct bnxt *bp, uint8_t path, uint64_t *timestamp)
+{
+	struct hwrm_port_ts_query_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_ts_query_input req = {0};
+	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+	uint32_t flags = 0;
+	int rc;
+
+	if (!ptp)
+		return 0;
+
+	HWRM_PREP(req, PORT_TS_QUERY, BNXT_USE_CHIMP_MB);
+
+	switch (path) {
+	case BNXT_PTP_FLAGS_PATH_TX:
+		flags |= HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_TX;
+		break;
+	case BNXT_PTP_FLAGS_PATH_RX:
+		flags |= HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_RX;
+		break;
+	case BNXT_PTP_FLAGS_CURRENT_TIME:
+		flags |= HWRM_PORT_TS_QUERY_INPUT_FLAGS_CURRENT_TIME;
+		break;
+	}
+
+	req.flags = rte_cpu_to_le_32(flags);
+	req.port_id = rte_cpu_to_le_16(bp->pf.port_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+	HWRM_CHECK_RESULT();
+
+	if (timestamp) {
+		*timestamp = rte_le_to_cpu_32(resp->ptp_msg_ts[0]);
+		*timestamp |=
+			(uint64_t)(rte_le_to_cpu_32(resp->ptp_msg_ts[1])) << 32;
+	}
+	HWRM_UNLOCK();
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index db25ad5919..0d386952b6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -206,4 +206,6 @@  int bnxt_hwrm_set_mac(struct bnxt *bp);
 int bnxt_hwrm_if_change(struct bnxt *bp, bool state);
 int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp);
 int bnxt_hwrm_fw_reset(struct bnxt *bp);
+int bnxt_hwrm_port_ts_query(struct bnxt *bp, uint8_t path,
+			    uint64_t *timestamp);
 #endif
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 12313dd53c..28487fb38e 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -17,6 +17,9 @@ 
 #include "bnxt_rxr.h"
 #include "bnxt_rxq.h"
 #include "hsi_struct_def_dpdk.h"
+#ifdef RTE_LIBRTE_IEEE1588
+#include "bnxt_hwrm.h"
+#endif
 
 /*
  * RX Ring handling
@@ -348,6 +351,30 @@  bnxt_parse_pkt_type(struct rx_pkt_cmpl *rxcmp, struct rx_pkt_cmpl_hi *rxcmp1)
 	return pkt_type;
 }
 
+#ifdef RTE_LIBRTE_IEEE1588
+static void
+bnxt_get_rx_ts_thor(struct bnxt *bp, uint32_t rx_ts_cmpl)
+{
+	uint64_t systime_cycles = 0;
+
+	if (!BNXT_CHIP_THOR(bp))
+		return;
+
+	/* On Thor, Rx timestamps are provided directly in the
+	 * Rx completion records to the driver. Only 32 bits of
+	 * the timestamp is present in the completion. Driver needs
+	 * to read the current 48 bit free running timer using the
+	 * HWRM_PORT_TS_QUERY command and combine the upper 16 bits
+	 * from the HWRM response with the lower 32 bits in the
+	 * Rx completion to produce the 48 bit timestamp for the Rx packet
+	 */
+	bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
+				&systime_cycles);
+	bp->ptp_cfg->rx_timestamp = (systime_cycles & 0xFFFF00000000);
+	bp->ptp_cfg->rx_timestamp |= rx_ts_cmpl;
+}
+#endif
+
 static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 			    struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
 {
@@ -363,6 +390,7 @@  static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint8_t agg_buf = 0;
 	uint16_t cmp_type;
 	uint32_t flags2_f = 0;
+	uint16_t flags_type;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -418,18 +446,22 @@  static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	mbuf->data_len = mbuf->pkt_len;
 	mbuf->port = rxq->port_id;
 	mbuf->ol_flags = 0;
-	if (rxcmp->flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) {
+
+	flags_type = rte_le_to_cpu_16(rxcmp->flags_type);
+	if (flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) {
 		mbuf->hash.rss = rxcmp->rss_hash;
 		mbuf->ol_flags |= PKT_RX_RSS_HASH;
 	} else {
 		mbuf->hash.fdir.id = rxcmp1->cfa_code;
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
-
-	if ((rxcmp->flags_type & rte_cpu_to_le_16(RX_PKT_CMPL_FLAGS_MASK)) ==
-	     RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP)
+#ifdef RTE_LIBRTE_IEEE1588
+	if (unlikely((flags_type & RX_PKT_CMPL_FLAGS_MASK) ==
+		     RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP)) {
 		mbuf->ol_flags |= PKT_RX_IEEE1588_PTP | PKT_RX_IEEE1588_TMST;
-
+		bnxt_get_rx_ts_thor(rxq->bp, rxcmp1->reorder);
+	}
+#endif
 	if (agg_buf)
 		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
 
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 35e7166bed..172b480b2e 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -155,7 +155,7 @@  static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 				PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM |
 				PKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM |
 				PKT_TX_TUNNEL_GRE | PKT_TX_TUNNEL_VXLAN |
-				PKT_TX_TUNNEL_GENEVE))
+				PKT_TX_TUNNEL_GENEVE | PKT_TX_IEEE1588_TMST))
 		long_bd = true;
 
 	nr_bds = long_bd + tx_pkt->nb_segs;
@@ -324,6 +324,11 @@  static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 			/* IP CSO */
 			txbd1->lflags |= TX_BD_LONG_LFLAGS_T_IP_CHKSUM;
 			txbd1->mss = 0;
+		} else if ((tx_pkt->ol_flags & PKT_TX_IEEE1588_TMST) ==
+			   PKT_TX_IEEE1588_TMST) {
+			/* PTP */
+			txbd1->lflags |= TX_BD_LONG_LFLAGS_STAMP;
+			txbd1->mss = 0;
 		}
 	} else {
 		txbd->flags_type |= TX_BD_SHORT_TYPE_TX_BD_SHORT;
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index bd04fe4838..26d12cf20a 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -33777,4 +33777,90 @@  struct hwrm_fw_reset_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/**********************
+ * hwrm_port_ts_query *
+ ***********************/
+
+
+/* hwrm_port_ts_query_input (size:192b/24B) */
+struct hwrm_port_ts_query_input {
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/*
+	 * The completion ring to send the completion event on. This should
+	 * be the NQ ID returned from the `nq_alloc` HWRM command.
+	 */
+	uint16_t	cmpl_ring;
+	/*
+	 * The sequence ID is used by the driver for tracking multiple
+	 * commands. This ID is treated as opaque data by the firmware and
+	 * the value is returned in the `hwrm_resp_hdr` upon completion.
+	 */
+	uint16_t	seq_id;
+	/*
+	 * The target ID of the command:
+	 * * 0x0-0xFFF8 - The function ID
+	 * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors
+	 * * 0xFFFD - Reserved for user-space HWRM interface
+	 * * 0xFFFF - HWRM
+	 */
+	uint16_t	target_id;
+	/*
+	 * A physical address pointer pointing to a host buffer that the
+	 * command's response data will be written. This can be either a host
+	 * physical address (HPA) or a guest physical address (GPA) and must
+	 * point to a physically contiguous block of memory.
+	 */
+	uint64_t	resp_addr;
+	uint32_t	flags;
+	/*
+	 * Enumeration denoting the RX, TX type of the resource.
+	 * This enumeration is used for resources that are similar for both
+	 * TX and RX paths of the chip.
+	 */
+	#define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH		0x1UL
+	/* tx path */
+	#define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_TX		0x0UL
+	/* rx path */
+	#define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_RX		0x1UL
+	#define HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_LAST	\
+		HWRM_PORT_TS_QUERY_INPUT_FLAGS_PATH_RX
+	/*
+	 * If set, the response includes the current value of the free
+	 * running timer.
+	 */
+	#define HWRM_PORT_TS_QUERY_INPUT_FLAGS_CURRENT_TIME	0x2UL
+	/* Port ID of port that is being queried. */
+	uint16_t	port_id;
+	uint8_t		unused_0[2];
+} __attribute__((packed));
+
+/* hwrm_port_ts_query_output (size:192b/24B) */
+struct hwrm_port_ts_query_output {
+	/* The specific error status for the command. */
+	uint16_t	error_code;
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/* The sequence ID from the original command. */
+	uint16_t	seq_id;
+	/* The length of the response data in number of bytes. */
+	uint16_t	resp_len;
+	/*
+	 * Timestamp value of PTP message captured, or current value of
+	 * free running timer.
+	 */
+	uint32_t	ptp_msg_ts[2];
+	/* Sequence ID of the PTP message captured. */
+	uint16_t	ptp_msg_seqid;
+	uint8_t		unused_0[5];
+	/*
+	 * This field is used in Output records to indicate that the output
+	 * is completely written to RAM.  This field should be read as '1'
+	 * to indicate that the output has been completely written.
+	 * When writing a command completion or response to an internal processor,
+	 * the order of writes has to be such that this field is written last.
+	 */
+	uint8_t		valid;
+} __attribute__((packed));
+
 #endif /* _HSI_STRUCT_DEF_DPDK_H_ */