osi: add idle timer window interrupt support

Ported from -
https://git-master.nvidia.com/r/c/nvethernet-docs/+/2963541

Bug 4246781

Change-Id: I89554a105be26958e17878b299aaadb13c39c130
Signed-off-by: Mahesh Patil <maheshp@nvidia.com>
Signed-off-by: Michael Hsu <mhsu@nvidia.com>
This commit is contained in:
Mahesh Patil
2023-08-17 11:38:51 -07:00
committed by Bhadram Varka
parent be2b32250c
commit 28b35b22c1
4 changed files with 105 additions and 8 deletions

View File

@@ -51,6 +51,8 @@
#define OSI_LOCKED 0x1U
/** @brief Number of Nano seconds per second */
#define OSI_NSEC_PER_SEC 1000000000ULL
#define OSI_MGBE_MAX_RX_RIIT_NSEC 17500U
#define OSI_MGBE_MIN_RX_RIIT_NSEC 535U
#ifndef OSI_STRIPPED_LIB
#define OSI_MAX_RX_COALESCE_USEC 1020U
#define OSI_EQOS_MIN_RX_COALESCE_USEC 5U
@@ -223,6 +225,8 @@
/** @brief Maximum number of queues in MGBE */
#define OSI_MGBE_MAX_NUM_QUEUES 10U
#define OSI_EQOS_XP_MAX_CHANS 4U
/* max riit DT configs for supported speeds */
#define OSI_MGBE_MAX_NUM_RIIT 4U
/**
* @brief Maximum number of Secure Channels supported

View File

@@ -59,6 +59,7 @@
#define OSI_ONE_MEGA_HZ 1000000U
/** @brief MAX ULLONG value */
#define OSI_ULLONG_MAX (~0ULL)
#define OSI_MSEC_PER_SEC 1000U
/* Compiler hints for branch prediction */
#define osi_likely(x) __builtin_expect(!!(x), 1)
@@ -268,6 +269,7 @@
#define OSI_DMA_IOCTL_CMD_STRUCTS_DUMP 2U
#define OSI_DMA_IOCTL_CMD_DEBUG_INTR_CONFIG 3U
#endif /* OSI_DEBUG */
#define OSI_DMA_IOCTL_CMD_RX_RIIT_CONFIG 4U
/** @} */
/**
@@ -321,6 +323,16 @@ struct osi_pkt_err_stats {
};
#endif /* !OSI_STRIPPED_LIB */
/**
* @brief RX RIIT value for speed
*/
struct osi_rx_riit {
/** speed */
nveu32_t speed;
/** riit value */
nveu32_t riit;
};
/**
* @brief Receive Descriptor
*/
@@ -664,7 +676,7 @@ struct osd_dma_ops {
#endif /* OSI_DEBUG */
};
#ifdef OSI_DEBUG
//#ifdef OSI_DEBUG
/**
* @brief The OSI DMA IOCTL data structure.
*/
@@ -674,7 +686,7 @@ struct osi_dma_ioctl_data {
/** IOCTL command argument */
nveu32_t arg_u32;
};
#endif /* OSI_DEBUG */
//#endif /* OSI_DEBUG */
/**
* @brief The OSI DMA private data structure.
@@ -728,6 +740,12 @@ struct osi_dma_priv_data {
* NVETHERNETCL_PIF$OSI_DISABLE
*/
nveu32_t use_riwt;
/** Receive Interrupt Idle Timer in nsec */
struct osi_rx_riit rx_riit[OSI_MGBE_MAX_NUM_RIIT];
/** num of rx riit configs for different speeds */
nveu32_t num_of_riit;
/** Flag which decides riit is enabled(1) or disabled(0) */
nveu32_t use_riit;
/** Max no of pkts to be received before triggering Rx interrupt.
* Max value is NVETHERNETCL_PIF$UINT_MAX
*/
@@ -779,9 +797,9 @@ struct osi_dma_priv_data {
* NVETHENETCL_PIF$OSI_PTP_SYNC_TWOSTEP - two step mode
*/
nveu32_t ptp_flag;
#ifdef OSI_DEBUG
/** OSI DMA IOCTL data */
struct osi_dma_ioctl_data ioctl_data;
#ifdef OSI_DEBUG
/** Flag to enable/disable descriptor dump */
nveu32_t enable_desc_dump;
#endif /* OSI_DEBUG */
@@ -1451,7 +1469,7 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma);
nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma,
nveu32_t chan, nveu32_t tx_rx, nveu32_t en_dis);
#ifdef OSI_DEBUG
//#ifdef OSI_DEBUG
/**
* @brief
* Description: OSI DMA IOCTL
@@ -1475,7 +1493,7 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma,
* @retval -1 on failure - invalid ioctl command within osi data structure
*/
nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma);
#endif /* OSI_DEBUG */
//#endif /* OSI_DEBUG */
#ifndef OSI_STRIPPED_LIB
/**
* @brief

View File

@@ -73,6 +73,12 @@
#define MGBE_DMA_CHX_RX_WDT_RWTU 2048U
#define MGBE_DMA_CHX_RX_WDT_RWTU_2048_CYCLE 0x3000U
#define MGBE_DMA_CHX_RX_WDT_RWTU_MASK 0x3000U
#define MGBE_DMA_CHX_RX_WDT_ITW_MASK 0x7C000000U
#define MGBE_DMA_CHX_RX_WDT_ITW_SHIFT 26U
#define MGBE_DMA_CHX_RX_WDT_ITW_MAX 0x1FU
#define MGBE_DMA_CHX_RX_WDT_ITW_DEFAULT 1100U
#define MGBE_DMA_CHX_RX_WDT_ITCU 256U
#ifdef OSI_DEBUG
#define MGBE_DMA_CHX_INTR_TBUE OSI_BIT(2)
#define MGBE_DMA_CHX_INTR_RBUE OSI_BIT(7)

View File

@@ -672,7 +672,7 @@ static nve32_t init_dma_channel(const struct osi_dma_priv_data *const osi_dma,
val &= ~DMA_CHX_RX_WDT_RWT_MASK;
val |= rwt_val[osi_dma->mac];
osi_dma_writel(val, (nveu8_t *)osi_dma->base +
rx_wdt_reg[osi_dma->mac]);
rx_wdt_reg[osi_dma->mac]);
val = osi_dma_readl((nveu8_t *)osi_dma->base +
rx_wdt_reg[osi_dma->mac]);
@@ -852,6 +852,71 @@ static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma,
osi_dma_writel(val, (nveu8_t *)osi_dma->base + dma_rx_reg[osi_dma->mac]);
}
static inline void set_rx_riit_dma(
const struct osi_dma_priv_data *const osi_dma,
nveu32_t chan, nveu32_t riit)
{
const nveu32_t rx_wdt_reg[OSI_MAX_MAC_IP_TYPES] = {
EQOS_DMA_CHX_RX_WDT(chan),
MGBE_DMA_CHX_RX_WDT(chan),
MGBE_DMA_CHX_RX_WDT(chan)
};
/* riit is in ns */
const nveu32_t itw_val = {
(((riit * ((nveu32_t)MGBE_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) /
(MGBE_DMA_CHX_RX_WDT_ITCU * OSI_MSEC_PER_SEC))
& MGBE_DMA_CHX_RX_WDT_ITW_MAX)
};
nveu32_t val;
if (osi_dma->use_riit != OSI_DISABLE &&
osi_dma->mac == OSI_MAC_HW_MGBE_T26X) {
val = osi_dma_readl((nveu8_t *)osi_dma->base +
rx_wdt_reg[osi_dma->mac]);
val &= ~MGBE_DMA_CHX_RX_WDT_ITW_MASK;
val |= (itw_val << MGBE_DMA_CHX_RX_WDT_ITW_SHIFT);
osi_dma_writel(val, (nveu8_t *)osi_dma->base +
rx_wdt_reg[osi_dma->mac]);
}
return;
}
static inline void set_rx_riit(
const struct osi_dma_priv_data *const osi_dma, nveu32_t speed)
{
nveu32_t i, chan, riit;
nveu32_t found =OSI_DISABLE;
for (i = 0; i < osi_dma->num_of_riit; i++) {
if (osi_dma->rx_riit[i].speed == speed) {
riit = osi_dma->rx_riit[i].riit;
found = OSI_ENABLE;
break;
}
}
if (found != OSI_ENABLE) {
/* use default ~1us value */
riit = MGBE_DMA_CHX_RX_WDT_ITW_DEFAULT;
OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID,
"Invalid speed value, using default riit 1us\n",
speed);
}
/* riit is in nsec */
if ((riit > (osi_dma->rx_riwt * OSI_MSEC_PER_SEC))) {
OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID,
"Invalid riit value, using default 1us\n", riit);
}
for (i = 0; i < osi_dma->num_dma_chans; i++) {
chan = osi_dma->dma_chans[i];
set_rx_riit_dma(osi_dma, chan, riit);
}
return;
}
nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma)
{
struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma;
@@ -1333,7 +1398,7 @@ fail:
return ret;
}
#ifdef OSI_DEBUG
nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma)
{
struct dma_local *l_dma = (struct dma_local *)osi_dma;
@@ -1349,6 +1414,7 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma)
data = &osi_dma->ioctl_data;
switch (data->cmd) {
#ifdef OSI_DEBUG
case OSI_DMA_IOCTL_CMD_REG_DUMP:
reg_dump(osi_dma);
break;
@@ -1358,6 +1424,10 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma)
case OSI_DMA_IOCTL_CMD_DEBUG_INTR_CONFIG:
l_dma->ops_p->debug_intr_config(osi_dma);
break;
#endif /* OSI_DEBUG */
case OSI_DMA_IOCTL_CMD_RX_RIIT_CONFIG:
set_rx_riit(osi_dma, data->arg_u32);
break;
default:
OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID,
"DMA: Invalid IOCTL command", 0ULL);
@@ -1369,7 +1439,6 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma)
#endif /* OSI_CL_FTRACE */
return 0;
}
#endif /* OSI_DEBUG */
#ifndef OSI_STRIPPED_LIB