]> git.droids-corp.org - dpdk.git/commitdiff
net/bnxt: support PTP for Thor
authorKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Wed, 2 Oct 2019 01:23:35 +0000 (18:23 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 8 Oct 2019 10:14:30 +0000 (12:14 +0200)
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 Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt.h
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_hwrm.h
drivers/net/bnxt/bnxt_rxr.c
drivers/net/bnxt/bnxt_txr.c
drivers/net/bnxt/hsi_struct_def_dpdk.h

index 310b730e68df4658556a2d8e08aa059cc63228fb..818a49f4616020a6c30df0d4ec21d4ea4cd28dfb 100644 (file)
@@ -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)
index 7c3ef93253aca52c4c8d6f2f1f5e9fee519a1d06..0083ba6e8376dab59d321501f923bc61d3331c4f 100644 (file)
@@ -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;
 }
 
index 7304cbf72ca8270e0b487c3fd001159f13fb58f6..174dc75d54dcc43096394fd22a4248c1695f23ce 100644 (file)
@@ -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;
+}
index db25ad5919c8a53d4ba199184bfed79ab679caf0..0d386952b660e96ac9f4cee82266679de89dbf4d 100644 (file)
@@ -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
index 12313dd53cc0bd2c1d62843367851dab07bed002..28487fb38e64a6261938d925d2750a5684e7da19 100644 (file)
@@ -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);
 
index 35e7166bedf991e1d187e2ffaee0c28e6b9be3bb..172b480b2ea89842463b5355b96ccedff41b2841 100644 (file)
@@ -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;
index bd04fe483862248205873a427f70d6b20ffa3a08..26d12cf20a5014e848033e1d21b3a0c6308a1332 100644 (file)
@@ -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_ */