diff --git a/include/osi_common.h b/include/osi_common.h index 60676b8..b4c59da 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -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 diff --git a/include/osi_dma.h b/include/osi_dma.h index 0797d05..9dd0553 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -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 diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index feed4ac..41c222c 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -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) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index a35c985..3731496 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -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