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 <nkristam@nvidia.com>
Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com>
Change-Id: Ib3e02031393e40988074095e5a135bb4e839d7f4
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2543792
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Krishna Thota <kthota@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Bhadram Varka <vbhadram@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
rakesh goyal
2020-06-30 21:20:14 +05:30
committed by mobile promotions
parent 7b040ebf9d
commit 1a2c9a3d94
10 changed files with 253 additions and 103 deletions

View File

@@ -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
*

View File

@@ -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;
};
/**

View File

@@ -25,6 +25,17 @@
#include <osi_common.h>
/**
* @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
*

View File

@@ -24,6 +24,7 @@
#define INCLUDED_CORE_LOCAL_H
#include <osi_core.h>
#include <local_common.h>
/**
* @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;
};
/**

View File

@@ -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 */

View File

@@ -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)
/** @} */
/**

View File

@@ -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;
}

84
osi/core/osi_hal.c Executable file → Normal file
View File

@@ -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",

View File

@@ -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 */

View File

@@ -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);