From 1a2c9a3d949f3704550b0d2d4d5d24c274a0bbab Mon Sep 17 00:00:00 2001 From: rakesh goyal Date: Tue, 30 Jun 2020 21:20:14 +0530 Subject: [PATCH] osi: common: Add support for MGBE 2 step timestamp - OSI DMA -- During Trasnmit: --- For EQOS/MGBE one steps PTP Reads TS and update in TX done structure. --- For MGBE 2 steps PTP or 1 step slave, update flags TS_POLL and update pkt_id as unique ID to be used for polling by OSD after Common interrupt handling. packet_id = MSB 4 bits channel_number and LSB 6-bits, local index of PTP TS FIFO. -- On transmit complete --- If TS is part of Tx done context set OSI_TXDONE_CX_TS --- If TS is not part of Tx done context and delayed set OSI_TXDONE_CX_TS_DELAY. - OSI Core -- On Common interrupt: --- If MGBE_ISR_TSIS is set, read time stamp to internal array from HW fifo, until it is completely read or array is full. --- Provide an IOCTL OSI_CMD_GET_TX_TS, to read TS for the specified pkt_id from OSD via structure osi_core_tx_ts --- Provide an IOCTL OSI_CMD_FREE_TS, to free TS for the specified pkt_id from OSD path Bug 200603265 Signed-off-by: Nagarjuna Kristam Signed-off-by: Rakesh Goyal Change-Id: Ib3e02031393e40988074095e5a135bb4e839d7f4 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2543792 Tested-by: mobile promotions Reviewed-by: svc_kernel_abi Reviewed-by: Sachin Nikam Reviewed-by: Krishna Thota Reviewed-by: mobile promotions Reviewed-by: Bhadram Varka GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 39 ++++++++++ include/osi_dma.h | 6 ++ osi/common/include/local_common.h | 11 +++ osi/core/core_local.h | 10 +++ osi/core/mgbe_core.c | 68 ++++++++++++++++- osi/core/mgbe_core.h | 8 ++ osi/core/osi_core.c | 3 + osi/core/osi_hal.c | 84 +++++++++++++++++++++ osi/dma/dma_local.h | 6 ++ osi/dma/osi_dma_txrx.c | 121 ++++++------------------------ 10 files changed, 253 insertions(+), 103 deletions(-) mode change 100755 => 100644 osi/core/osi_hal.c diff --git a/include/osi_core.h b/include/osi_core.h index 3677557..86cdcbd 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -80,6 +80,7 @@ typedef my_lint_64 nvel64_t; #define OSI_MAC_TCR_CSC OSI_BIT(19) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) +#define OSI_MAC_TCR_TXTSSMIS OSI_BIT(31) /** @} */ /** @@ -205,6 +206,8 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_CONFIG_FPE 39U #define OSI_CMD_READ_REG 40U #define OSI_CMD_WRITE_REG 41U +#define OSI_CMD_GET_TX_TS 42U +#define OSI_CMD_FREE_TS 43U /** @} */ /** @@ -1025,6 +1028,24 @@ struct osi_macsec_irq_stats { }; #endif /* MACSEC_SUPPORT */ +/** + * @brief Core time stamp data strcuture + */ +struct osi_core_tx_ts { + /** Pointer to next item in the link */ + struct osi_core_tx_ts *next; + /** Pointer to prev item in the link */ + struct osi_core_tx_ts *prev; + /** Packet ID for corresponding timestamp */ + nveu32_t pkt_id; + /** Time in seconds */ + nveu32_t sec; + /** Time in nano seconds */ + nveu32_t nsec; + /** Variable which says if pkt_id is in use or not */ + nveu32_t in_use; +}; + /** * @brief OSI Core data structure for runtime commands. */ @@ -1071,6 +1092,8 @@ struct osi_ioctl { struct osi_fpe_config fpe; /** PTP configuration settings */ struct osi_ptp_config ptp_config; + /** TX Timestamp structure */ + struct osi_core_tx_ts tx_ts; }; /** @@ -2181,6 +2204,14 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * Configuration FPE register and preemptable queue * fpe - FPE configuration structure * + * - OSI_CMD_GET_TX_TS + * Command to get TX timestamp for PTP packet + * ts - OSI core timestamp structure + * + * - OSI_CMD_FREE_TS + * Command to free old timestamp for PTP packet + * chan - DMA channel number +1. 0 will be used for onestep + * * @param[in] osi_core: OSI core private data structure. * @param[in] data: void pointer pointing to osi_ioctl * @@ -2365,6 +2396,14 @@ struct osi_core_priv_data *osi_get_core(void); * Configuration FPE register and preemptable queue * fpe - FPE configuration structure * + * - OSI_CMD_GET_TX_TS + * Command to get TX timestamp for PTP packet + * ts - OSI core timestamp structure + * + * - OSI_CMD_FREE_TS + * Command to free old timestamp for PTP packet + * chan - DMA channel number +1. 0 will be used for onestep + * * @param[in] osi_core: OSI core private data structure. * @param[in] data: void pointer pointing to osi_ioctl * diff --git a/include/osi_dma.h b/include/osi_dma.h index 58432a2..c46cf85 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -157,6 +157,8 @@ #define OSI_TXDONE_CX_ERROR OSI_BIT(1) /** Flag to indicate the availability of time stamp */ #define OSI_TXDONE_CX_TS OSI_BIT(2) +/** Flag to indicate the delayed availability of time stamp */ +#define OSI_TXDONE_CX_TS_DELAYED OSI_BIT(3) /** @} */ /** @@ -363,6 +365,8 @@ struct osi_tx_swcx { * is a paged buffer/linear buffer * Bit 1 PTP hwtime form timestamp registers */ unsigned int flags; + /** Packet id of packet for which TX timestamp needed */ + unsigned int pktid; }; /** @@ -410,6 +414,8 @@ struct osi_txdone_pkt_cx { /** TS captured for the tx packet and this is valid only when the PTP * bit is set in fields */ nveul64_t ns; + /** Passing packet id to map TX time to packet */ + unsigned int pktid; }; /** diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 9251d95..134cae0 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -25,6 +25,17 @@ #include +/** + * @brief TX timestamp helper MACROS + * @{ + */ +#define CHAN_START_POSITION 6U +#define PKT_ID_CNT ((nveu32_t)1 << CHAN_START_POSITION) +/* First 6 bytes of idx and last 4 bytes of chan(+1 to avoid pkt_id to be 0) */ +#define GET_TX_TS_PKTID(idx, c) (((++(idx)) & (PKT_ID_CNT - 1U)) | \ + (((c) + 1U) << CHAN_START_POSITION)) +/** @} */ + /** *@brief div_u64_rem - updates remainder and returns Quotient * diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 1ea5ef2..366dbdc 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -24,6 +24,7 @@ #define INCLUDED_CORE_LOCAL_H #include +#include /** * @brief Maximum number of OSI core instances. @@ -37,6 +38,11 @@ */ #define MAX_INTERFACE_OPS 2U +/** + * @brief Maximum number of timestamps stored in OSI from HW FIFO. + */ +#define MAX_TX_TS_CNT (PKT_ID_CNT * OSI_MGBE_MAX_NUM_CHANS) + /** * interface core ops */ @@ -273,12 +279,16 @@ struct core_local { struct core_ops *ops_p; /** interface core local operations variable */ struct if_core_ops *if_ops_p; + /** structure to store tx time stamps */ + struct osi_core_tx_ts ts[MAX_TX_TS_CNT]; /** Flag to represent initialization done or not */ nveu32_t init_done; /** Flag to represent infterface initialization done or not */ nveu32_t if_init_done; /** Magic number to validate osi core pointer */ nveu64_t magic_num; + /** This is the head node for PTP packet ID queue */ + struct osi_core_tx_ts tx_ts_head; }; /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index fe29e92..9b7d4f4 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2642,9 +2642,9 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* Enable MAC nve32_terrupts */ /* Read MAC IMR Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); - /* RGSMIIIM - RGMII/SMII nve32_terrupt Enable */ + /* RGSMIIIM - RGMII/SMII interrupt and TSIE Enable */ /* TODO: LPI need to be enabled during EEE implementation */ - value |= MGBE_IMR_RGSMIIIE; + value |= (MGBE_IMR_RGSMIIIE | MGBE_IMR_TSIE); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* Enable common interrupt at wrapper level */ @@ -3193,6 +3193,28 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) osi_core->base + MGBE_MAC_FPE_CTS); } +/** + * @brief Get free timestamp index from TS array by validating in_use param + * + * @param[in] l_core: Core local private data structure. + * + * @retval Free timestamp index. + * + * @post If timestamp index is MAX_TX_TS_CNT, then its no free count index + * is available. + */ +static inline nveu32_t get_free_ts_idx(struct core_local *l_core) +{ + nveu32_t i; + + for (i = 0; i < MAX_TX_TS_CNT; i++) { + if (l_core->ts[i].in_use == OSI_NONE) { + break; + } + } + return i; +} + /** * @brief mgbe_handle_mac_intrs - Handle MAC interrupts * @@ -3207,8 +3229,9 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, nveu32_t dma_isr) { - unsigned int mac_isr = 0; - unsigned int mac_ier = 0; + struct core_local *l_core = (struct core_local *)osi_core; + nveu32_t mac_isr = 0; + nveu32_t mac_ier = 0; mac_isr = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MAC_ISR); @@ -3225,6 +3248,43 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, mac_isr &= ~MGBE_MAC_IMR_FPEIS; } + osi_writela(osi_core, mac_isr, + (unsigned char *)osi_core->base + MGBE_MAC_ISR); + if ((mac_isr & MGBE_ISR_TSIS) == MGBE_ISR_TSIS) { + struct osi_core_tx_ts *head = &l_core->tx_ts_head; + + /* TXTSC bit should get reset when all timestamp read */ + while (((osi_readla(osi_core, (nveu8_t *)osi_core->base + + MGBE_MAC_TSS) & + MGBE_MAC_TSS_TXTSC) == MGBE_MAC_TSS_TXTSC)) { + nveu32_t i = get_free_ts_idx(l_core); + + if (i == MAX_TX_TS_CNT) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "TS queue is full\n", i); + break; + } + + l_core->ts[i].nsec = osi_readla(osi_core, + (nveu8_t *)osi_core->base + + MGBE_MAC_TSNSSEC); + + l_core->ts[i].in_use = OSI_ENABLE; + l_core->ts[i].pkt_id = osi_readla(osi_core, + (nveu8_t *)osi_core->base + + MGBE_MAC_TSPKID); + l_core->ts[i].sec = osi_readla(osi_core, + (nveu8_t *)osi_core->base + + MGBE_MAC_TSSEC); + /* Add time stamp to end of list */ + l_core->ts[i].next = head->prev->next; + head->prev->next = &l_core->ts[i]; + l_core->ts[i].prev = head->prev; + head->prev = &l_core->ts[i]; + } + } + mac_isr &= ~MGBE_ISR_TSIS; + osi_writela(osi_core, mac_isr, (unsigned char *)osi_core->base + MGBE_MAC_ISR); /* TODO: Duplex/speed settigs - Its not same as EQOS for MGBE */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index f3c803a..b606811 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -106,6 +106,10 @@ #define MGBE_MAC_STSUR 0x0D10 #define MGBE_MAC_STNSUR 0x0D14 #define MGBE_MAC_TAR 0x0D18 +#define MGBE_MAC_TSS 0x0D20 +#define MGBE_MAC_TSNSSEC 0x0D30 +#define MGBE_MAC_TSSEC 0x0D34 +#define MGBE_MAC_TSPKID 0x0D38 #define MGBE_MAC_PTO_CR 0x0DC0 #define MGBE_MAC_PIDR0 0x0DC4 #define MGBE_MAC_PIDR1 0x0DC8 @@ -450,8 +454,10 @@ OSI_BIT(25) | OSI_BIT(24)) #define MGBE_MAC_RQC4R_PMCBCQ_SHIFT 24U #define MGBE_IMR_RGSMIIIE OSI_BIT(0) +#define MGBE_IMR_TSIE OSI_BIT(12) #define MGBE_IMR_FPEIE OSI_BIT(15) #define MGBE_MAC_IMR_FPEIS OSI_BIT(16) +#define MGBE_ISR_TSIS OSI_BIT(12) #define MGBE_DMA_ISR_MTLIS OSI_BIT(16) #define MGBE_DMA_ISR_MACIS OSI_BIT(17) #define MGBE_DMA_ISR_DCH0_DCH15_MASK 0xFFU @@ -662,6 +668,8 @@ #define MGBE_MAC_SBD_INTR OSI_BIT(2) #define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) #define MGBE_MAC_EXT_CNF_EIPG 0x1U +/* TX timestamp */ +#define MGBE_MAC_TSS_TXTSC OSI_BIT(15) /** @} */ /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index be73b6c..f8821d0 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -122,6 +122,9 @@ struct osi_core_priv_data *osi_get_core(void) g_core[i].magic_num = (nveu64_t)&g_core[i].osi_core; + g_core[i].tx_ts_head.prev = &g_core[i].tx_ts_head; + g_core[i].tx_ts_head.next = &g_core[i].tx_ts_head; + return &g_core[i].osi_core; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c old mode 100755 new mode 100644 index c836d64..3875a58 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1362,6 +1362,80 @@ static nve32_t config_fpe(struct osi_core_priv_data *osi_core, return l_core->ops_p->hw_config_fpe(osi_core, fpe); } +/** + * @brief Free stale timestamps for channel + * + * Algorithm: + * - Check for if any timestamp for input channel id + * - if yes, reset node to 0x0 for reuse. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] chan: 1 for DMA channel 0, 2 for dma channel 1,... + * 0 is used for onestep. + */ +static inline void free_tx_ts(struct osi_core_priv_data *osi_core, + nveu32_t chan) +{ + struct core_local *l_core = (struct core_local *)osi_core; + struct osi_core_tx_ts *head = &l_core->tx_ts_head; + struct osi_core_tx_ts *temp = l_core->tx_ts_head.next; + nveu32_t count = 0U; + + while ((temp != head) && (count < MAX_TX_TS_CNT)) { + if (((temp->pkt_id >> CHAN_START_POSITION) & chan) == chan) { + temp->next->prev = temp->prev; + temp->prev->next = temp->next; + /* reset in_use for temp node from the link */ + temp->in_use = OSI_DISABLE; + } + count++; + temp = temp->next; + } +} + +/** + * @brief Parses internal ts structure array and update time stamp if packet + * id matches. + * Algorithm: + * - Check for if any timestamp with packet ID in list and valid + * - update sec and nsec in timestamp structure + * - reset node to reuse for next call + * + * @param[in] osi_core: OSI core private data structure. + * @param[in,out] ts: osi core ts structure, pkt_id is input and time is output. + * + * @retval 0 on success + * @retval -1 any other failure. + */ +static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, + struct osi_core_tx_ts *ts) +{ + struct core_local *l_core = (struct core_local *)osi_core; + struct osi_core_tx_ts *temp = l_core->tx_ts_head.next; + struct osi_core_tx_ts *head = &l_core->tx_ts_head; + nve32_t ret = -1; + nveu32_t count = 0U; + + while ((temp != head) && (count < MAX_TX_TS_CNT)) { + if ((temp->pkt_id == ts->pkt_id) && + (temp->in_use != OSI_NONE)) { + ts->sec = temp->sec; + ts->nsec = temp->nsec; + /* remove temp node from the link */ + temp->next->prev = temp->prev; + temp->prev->next = temp->next; + /* Clear in_use fields */ + temp->in_use = OSI_DISABLE; + ret = 0; + break; + } + count++; + temp = temp->next; + } + + return ret; +} + nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, struct osi_ioctl *data) { @@ -1561,6 +1635,16 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = ops_p->write_reg(osi_core, (nve32_t) data->arg1_u32, (nve32_t) data->arg2_u32); break; + + case OSI_CMD_GET_TX_TS: + ret = get_tx_ts(osi_core, &data->tx_ts); + break; + + case OSI_CMD_FREE_TS: + free_tx_ts(osi_core, data->arg1_u32); + ret = 0; + break; + default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 4d1d794..04450ca 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -123,6 +123,12 @@ struct dma_local { struct osi_dma_priv_data osi_dma; /** DMA channel operations */ struct dma_chan_ops *ops_p; + /** + * PacketID for PTP TS. + * MSB 4-bits of channel number and LSB 6-bits of local + * index(PKT_ID_CNT). + */ + nveu32_t pkt_id; /** Flag to represent OSI DMA software init done */ nveu32_t init_done; /** Holds the MAC version of MAC controller */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d583ee0..8cd3abf 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -25,6 +25,7 @@ #include "hw_desc.h" #include "../osi/common/common.h" #include "mgbe_dma.h" +#include "local_common.h" static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; @@ -507,102 +508,6 @@ static inline nve32_t validate_tx_completions_arg( return 0; } -/** - * @brief poll_for_ts_update - Poll for TXTSC bit set for timestamp capture - * - * Algorithm: This routine will be invoked by get_mac_tx_timestamp to poll - * on TXTSC bit to get set or timedout. - * - * @param[in] addr: Base address - * @param[in] chan: Current counter value - * - * @retval -1 on failure - * @retval 0 on success - */ -static inline int poll_for_ts_update(struct osi_dma_priv_data *osi_dma, - unsigned int *count) -{ - unsigned int retry = OSI_POLL_COUNT; - unsigned int val = 0U; - - while (*count < retry) { - /* Read and Check TXTSC in MAC_Timestamp_Control register */ - val = osi_readl((unsigned char *)osi_dma->base + - MGBE_MAC_TSS); - if ((val & MGBE_MAC_TSS_TXTSC) == MGBE_MAC_TSS_TXTSC) { - return 0; - } - (*count)++; - osi_dma->osd_ops.udelay(OSI_DELAY_1US); - } - - return -1; -} - -/** - * @brief get_mac_tx_timestamp - get TX timestamp from timestamp capture - * registers - * - * Algorithm: This routine will be invoked on TX_DONE interrupt and if hw - * timestamp capture enabled for that descriptor. SW will check for Packet - * id maching with dma channel number as for same DMA all tx are FIFO. If match - * update hwtimestamp into local variables. - * - * @param[in] osi: OSI private data structure. - * @param[in] tx_desc: Pointer to tranmit descriptor. - * @param[out] txdone_pkt_cx: Pointer to txdone packet descriptor to be filled - * @param[in] chan: Rx channel number. - * - */ -static void get_mac_tx_timestamp(struct osi_dma_priv_data *osi_dma, - struct osi_tx_desc *tx_desc, - struct osi_txdone_pkt_cx *txdone_pkt_cx, - unsigned int chan) -{ - unsigned char *addr = (unsigned char *)osi_dma->base; - int ret = -1; - int found = 1; - unsigned int count = 0; - unsigned long long var = 0; - - ret = poll_for_ts_update(osi_dma, &count); - if (ret < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "timestamp done failed\n", 0ULL); - found = 0; - } - - /* check if pkt id is also correct for pkt. current implemtation - * use dma channel index as pktid, we will use pktid from index 0 to - * max DMA channels -1 */ - while (found == 1) { - if (((osi_readl(addr + MGBE_MAC_TS_PID) & - MGBE_MAC_TS_PID_MASK) == chan)) { - txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS; - txdone_pkt_cx->ns = osi_readl(addr + MGBE_MAC_TS_NSEC); - txdone_pkt_cx->ns &= MGBE_MAC_TS_NSEC_MASK; - var = osi_readl(addr + MGBE_MAC_TS_SEC); - if (OSI_NSEC_PER_SEC > (OSI_ULLONG_MAX / var)) { - /* Will not hit this case */ - } else if ((OSI_ULLONG_MAX - (var * OSI_NSEC_PER_SEC)) < - txdone_pkt_cx->ns) { - /* Will not hit this case */ - } else { - txdone_pkt_cx->ns += var * OSI_NSEC_PER_SEC; - } - - found = 0; - } else { - OSI_DMA_INFO(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "packet ID mismatch \n", 0ULL); - ret = poll_for_ts_update(osi_dma, &count); - if (ret < 0) { - found = 0; - } - } - } -} - /** * @brief is_ptp_twostep_or_slave_mode - check for dut in ptp 2step or slave * mode @@ -697,10 +602,12 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, } else if (((tx_swcx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP) && // if not master in onestep mode + /* TODO: Is this check needed and can be removed ? */ (is_ptp_twostep_or_slave_mode(osi_dma->ptp_flag) == OSI_ENABLE) && ((tx_desc->tdes3 & TDES3_CTXT) == 0U)) { - get_mac_tx_timestamp(osi_dma, tx_desc, txdone_pkt_cx, chan); + txdone_pkt_cx->pktid = tx_swcx->pktid; + txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS_DELAYED; } else { /* Do nothing here */ } @@ -993,6 +900,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, struct dma_chan_ops *ops, nveu32_t chan) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; struct osi_tx_pkt_cx *tx_pkt_cx = OSI_NULL; struct osi_tx_desc *first_desc = OSI_NULL; struct osi_tx_desc *last_desc = OSI_NULL; @@ -1000,6 +908,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_tx_desc *cx_desc = OSI_NULL; nve32_t cntx_desc_consumed; + nveu32_t pkt_id = 0x0U; nveu32_t desc_cnt = 0U; nveu64_t tailptr, tmp; nveu32_t entry = 0U; @@ -1043,8 +952,15 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, (osi_dma->mac == OSI_MAC_HW_MGBE)) { /* mark packet id valid */ tx_desc->tdes3 |= TDES3_PIDV; - /* Packet id */ - tx_desc->tdes0 = chan; + if ((osi_dma->ptp_flag & OSI_PTP_SYNC_ONESTEP) == + OSI_PTP_SYNC_ONESTEP) { + /* packet ID for Onestep is 0x0 always */ + pkt_id = OSI_NONE; + } else { + pkt_id = GET_TX_TS_PKTID(l_dma->pkt_id, chan); + } + /* update packet id */ + tx_desc->tdes0 = pkt_id; } INCR_TX_DESC_INDEX(entry, 1U); @@ -1058,6 +974,13 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* Fill first descriptor */ fill_first_desc(tx_ring, tx_pkt_cx, tx_desc, tx_swcx, osi_dma->ptp_flag); + if (((tx_pkt_cx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP) && + (osi_dma->mac == OSI_MAC_HW_MGBE)) { + /* save packet id for first desc, time stamp will be with + * first FD only + */ + tx_swcx->pktid = pkt_id; + } INCR_TX_DESC_INDEX(entry, 1U);