From d808e1a3cb9dd16c0d8ab0588fc157e6f070505f Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Tue, 9 Jul 2024 21:11:01 +0000 Subject: [PATCH 1/7] nvethernetrm: Add support for COE in MGBE Bug 4748432 Change-Id: Ia37c54d162c6bd480fe3e875bfc50dbe5de02928 Signed-off-by: Srinivas Ramachandran Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3298865 Reviewed-by: Igor Mitsyanko --- include/ivc_core.h | 2 + include/osi_common.h | 32 ++++++++ include/osi_core.h | 10 +++ include/osi_dma.h | 5 ++ include/osi_macsec.h | 137 ++++++++++++++++++++++++++++++- osi/core/common_macsec.c | 81 ++++++++++++++++++ osi/core/core_local.h | 2 + osi/core/ivc_core.c | 63 ++++++++++++++ osi/core/mgbe_core.c | 63 ++++++++++++++ osi/core/mgbe_core.h | 31 +++++++ osi/core/osi_hal.c | 9 ++ osi/dma/mgbe_dma.h | 1 + osi/dma/osi_dma.c | 10 +++ osi/nvmacsecrm/macsec.c | 173 +++++++++++++++++++++++++++++++++++++++ osi/nvmacsecrm/macsec.h | 21 +++++ 15 files changed, 639 insertions(+), 1 deletion(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 7670696..a847023 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -49,6 +49,8 @@ typedef enum { handle_irq_macsec, lut_config_macsec, kt_config_macsec, + coe_lc_macsec, + coe_config_macsec, cipher_config, loopback_config_macsec, config_macsec, diff --git a/include/osi_common.h b/include/osi_common.h index b1ff684..e252630 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -309,6 +309,38 @@ #endif /* OSI_STRIPPED_LIB */ /** @} */ +#define OSI_MGBE_COE_NUM_RX_FRAMES 4U +struct osi_mgbe_coe { + /** Rx frame buffer virt addr for 4 frames */ + nveu64_t rx_fb_addr[OSI_MGBE_COE_NUM_RX_FRAMES]; + /** Rx frame buffer phys addr for 4 frames */ + nveu64_t rx_fb_addr_phys[OSI_MGBE_COE_NUM_RX_FRAMES]; + /** Rx pkt info buffer virt addr */ + nveu64_t rx_pib_addr; + /** Rx pkt info buffer phys addr */ + nveu64_t rx_pib_addr_phys; + /** Rx pkt info buffer ring size */ + nveu32_t rx_pib_sz; + /** VDMA enabled for COE */ + nveu32_t vdma; + /** PDMA enabled for COE */ + nveu32_t pdma; +}; + +/** + * @brief COE pkt info buffer + */ +struct osi_mgbe_coe_pib { + /** pkt info buf 0 */ + nveu32_t pib0; + /** pkt info buf 1 */ + nveu32_t pib1; + /** pkt info buf 2 */ + nveu32_t pib2; + /** pkt info buf 3 */ + nveu32_t pib3; +}; + /** * @addtogroup OSI-DEBUG helper macros * diff --git a/include/osi_core.h b/include/osi_core.h index 80fe2bb..34d14c7 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -511,6 +511,10 @@ typedef my_lint_64 nvel64_t; */ #define OSI_CMD_READ_HSI_ERR 57U #endif /* HSI_SUPPORT */ +/** + * @brief Command to config camera over eth logic + */ +#define OSI_CMD_GMSL_COE_CONFIG 58U /** @} */ #ifdef LOG_OSI @@ -1569,6 +1573,8 @@ struct osi_ioctl { struct osi_core_tx_ts tx_ts; /** PTP TSC data */ struct osi_core_ptp_tsc_data ptp_tsc; + /** COE config data */ + struct osi_mgbe_coe mgbe_coe; }; /** @@ -1860,6 +1866,10 @@ struct osi_core_priv_data { nveu32_t pre_sil; /** rCHlist bookkeeping **/ struct rchlist_index rch_index[RCHLIST_SIZE]; + /** Flag which decides COE is enabled(1) or disabled(0) */ + nveu32_t coe_enable; + /** cfg structure for COE */ + struct osi_mgbe_coe mgbe_coe; /** Parameter indicates the current operating speed */ nve32_t speed; /** PCS BASE-R FEC enable */ diff --git a/include/osi_dma.h b/include/osi_dma.h index cd52c7e..20e0baa 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -624,6 +624,7 @@ struct osi_tx_ring { nveu32_t skip_dmb; }; + #ifndef OSI_STRIPPED_LIB /** * @brief osi_xtra_dma_stat_counters - OSI DMA extra stats counters @@ -739,6 +740,10 @@ struct osi_dma_priv_data { #endif /* !OSI_STRIPPED_LIB */ /** Receive Interrupt Watchdog Timer Count Units. Max value is NVETHERNETCL_PIF$UINT_MAX */ nveu32_t rx_riwt; + /** Flag which decides COE is enabled(1) or disabled(0) */ + nveu32_t coe_enable; + /** cfg structure for COE */ + struct osi_mgbe_coe mgbe_coe; /** Flag which decides riwt is * NVETHERNETCL_PIF$OSI_ENABLE or * NVETHERNETCL_PIF$OSI_DISABLE diff --git a/include/osi_macsec.h b/include/osi_macsec.h index a2ffec8..027eaa8 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -71,6 +71,14 @@ * @brief Maximum bype pattern match */ #define OSI_LUT_BYTE_PATTERN_MAX 4U +/** @brief COE LUT max bytes for pattern match */ +#define OSI_COE_LUT_BYTE_PATTERN_MAX 2U +/** @brief LUT byte pattern offset range 0-63 */ +#define OSI_COE_LUT_OFFSET_MAX 32U +/** @brief COE LUT entry valid */ +#define OSI_COE_LUT_ENTRY_VALID 1U +/** @brief One bit for each nibble in COE_LUT_BYTE_PATTERN */ +#define OSI_COE_LUT_BYTE_MASK_MAX 0xFU /** @brief LUT byte pattern offset range 0-63 */ #define OSI_LUT_BYTE_PATTERN_MAX_OFFSET 63U /** @brief VLAN PCP range 0-7 */ @@ -87,8 +95,10 @@ #define OSI_LUT_SEL_SC_STATE 3U /** @brief flag to select SA_STATE LUT */ #define OSI_LUT_SEL_SA_STATE 4U +/** @brief flag to select COE LUT */ +#define OSI_LUT_SEL_COE 5U /** @brief maximum LUTs to select */ -#define OSI_LUT_SEL_MAX 4U +#define OSI_LUT_SEL_MAX 5U /** @brief Flag indicating which bytes of DA is valid */ #define OSI_LUT_FLAGS_DA_VALID (OSI_BIT(0) | OSI_BIT(1) | OSI_BIT(2) |\ OSI_BIT(3) | OSI_BIT(4) | OSI_BIT(5)) @@ -145,6 +155,8 @@ /** @brief LUT write operation */ #define OSI_LUT_WRITE 1U #define OSI_RW_MAX 1U +/** @brief COE LUT max valid entries */ +#define OSI_COE_LUT_MAX_INDEX 8U /** @brief Maximum bypass lut table index */ #define OSI_BYP_LUT_MAX_INDEX 31U /** @brief Maximum bypass lut table index for T26X */ @@ -330,6 +342,20 @@ struct osi_lut_inputs { nveu32_t vlan_id; }; +/** + * @brief MACSEC COE LUT entry inputs structure + */ +struct osi_coe_lut_inout { + /** 2-Byte pattern to compare from SOF */ + nveu8_t byte_pattern[OSI_COE_LUT_BYTE_PATTERN_MAX]; + /** Offset for 2-Byte pattern to compare */ + nveu32_t offset; + /** Mask bits for each 4-bit nibble in 2-Byte pattern to compare */ + nveu32_t byte_pattern_mask; + /** valid */ + nveu32_t valid; +}; + /** * @brief MACSEC LUT config data structure */ @@ -350,6 +376,8 @@ struct osi_macsec_lut_config { * for more details refer from NVETHERNETRM_PIF$OSI_LUT_FLAGS_DA_VALID to * NVETHERNETRM_PIF$OSI_LUT_FLAGS_ENTRY_VALID */ nveu32_t flags; + /** COE LUT input/output */ + struct osi_coe_lut_inout coe_lut_inout; /** LUT inputs to use */ struct osi_lut_inputs lut_in; /** SCI LUT outputs @@ -414,6 +442,12 @@ struct osi_macsec_core_ops { nveu32_t mtu, nveu8_t *const mac_addr); /** macsec de-init */ nve32_t (*deinit)(struct osi_core_priv_data *const osi_core); + /** macsec coe config */ + nve32_t (*coe_config)(struct osi_core_priv_data *const osi_core, + nveu32_t coe_enable, nveu32_t coe_hdr_offset); + /** macsec coe LC threshold */ + nve32_t (*coe_lc)(struct osi_core_priv_data *const osi_core, + nveu32_t ch, nveu32_t lc1, nveu32_t lc2); /** Macsec irq handler */ void (*handle_irq)(struct osi_core_priv_data *const osi_core); /** macsec lut config */ @@ -556,6 +590,107 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, nveu32_t mtu, nveu8_t *const macsec_vf_mac); +/** COE */ +#define OSI_MACSEC_COE_MAX_LC 0x3FFFU + +/** + * @brief + * Description: Configure MACSEC COE engine + * + * @param[in] osi_core: A pointer to the osi_core_priv_data structure + * * Range: A non-null pointer to NVETHERNETRM_PIF$osi_core_priv_data structure. + * @param[in] coe_enable: A flag variable to indicate COE logic is enabled/disabled + * * Range: Binary value to indicate COE logic is enabled/disabled. + * @param[in] coe_hdr_offset: Variable to indicate offset from SOF where COE header is present + * * Range: Within first 64B of the packet + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @return + * - 0 on Successful configuration of MACSEC COE engine + * - -1 on MACSEC operations being NULL + * - -1 on failure to configure COE engine of MACSEC controller + * + * @usage + * - Allowed context for the API call + * - Interrupt handler: No + * - Signal handler: No + * - Thread safe: No + * - Async/Sync: Sync + * - Required Privileges: None + * - API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: Yes + * + */ +#ifndef DOXYGEN_ICD +/** + * + * Traceability Details: + * - SWUD_ID: NET_SWUD_TAG_NVETHERNETRM_035 + * + **/ +#else +/** + * + * @dir + * - forward + */ +#endif +nve32_t osi_macsec_coe_config(struct osi_core_priv_data *const osi_core, + nveu32_t coe_enable, nveu32_t coe_hdr_offset); + +/** + * @brief + * Description: Configure MACSEC COE Line counters + * + * @param[in] osi_core: A pointer to the osi_core_priv_data structure + * * Range: A non-null pointer to NVETHERNETRM_PIF$osi_core_priv_data structure. + * @param[in] ch: Channel number + * * Range: 0-47 + * @param[in] lc1: Line counter threshold 1 + * * Range: 1-255 + * @param[in] lc1: Line counter threshold 1 + * * Range: 1-255 + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @return + * - 0 on Successful configuration of MACSEC COE line counters + * - -1 on MACSEC operations being NULL + * - -1 on failure to configure COE engine + * + * @usage + * - Allowed context for the API call + * - Interrupt handler: No + * - Signal handler: No + * - Thread safe: No + * - Async/Sync: Sync + * - Required Privileges: None + * - API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: Yes + * + */ +#ifndef DOXYGEN_ICD +/** + * + * Traceability Details: + * - SWUD_ID: NET_SWUD_TAG_NVETHERNETRM_035 + * + **/ +#else +/** + * + * @dir + * - forward + */ +#endif +nve32_t osi_macsec_coe_lc(struct osi_core_priv_data *const osi_core, + nveu32_t ch, nveu32_t lc1, nveu32_t lc2); + /** * @brief * Description: De-Initialize the macsec controller diff --git a/osi/core/common_macsec.c b/osi/core/common_macsec.c index 2db1b2d..a5c1314 100644 --- a/osi/core/common_macsec.c +++ b/osi/core/common_macsec.c @@ -153,6 +153,87 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, return ret; } +/** + * @brief osi_macsec_coe_config - Configure the COE engine in MACSec controller + * + * @note + * Algorithm: + * - Return -1 if osi core or ops is null + * - Configure the COE engine based on args provided + * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. + * - TraceID: *********** + * + * @param[in] osi_core: OSI core private data structure + * @param[in] coe_enable: Flag variable to enable COE + * @param[in] coe_hdr_offset: COE header offset + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure + */ +nve32_t osi_macsec_coe_config(struct osi_core_priv_data *const osi_core, + nveu32_t coe_enable, nveu32_t coe_hdr_offset) +{ + nve32_t ret = -1; + const struct core_local *l_core = (struct core_local *)(void *)osi_core; + + if ((osi_core != OSI_NULL) && (l_core->macsec_ops != OSI_NULL) && + (l_core->macsec_ops->coe_config != OSI_NULL)) { + ret = l_core->macsec_ops->coe_config(osi_core, coe_enable, coe_hdr_offset); + } + + return ret; +} + +/** + * @brief osi_macsec_coe_lc - Configure the COE engine line counter thresholds + * + * @note + * Algorithm: + * - Return -1 if osi core or ops is null + * - Configure the COE engine based on args provided + * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. + * - TraceID: *********** + * + * @param[in] osi_core: OSI core private data structure + * @param[in] ch: Channel number + * @param[in] lc1: Line counter threshold 1 + * @param[in] lc2: Line counter threshold 2 + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure + */ +nve32_t osi_macsec_coe_lc(struct osi_core_priv_data *const osi_core, + nveu32_t ch, nveu32_t lc1, nveu32_t lc2) +{ + nve32_t ret = -1; + const struct core_local *l_core = (struct core_local *)(void *)osi_core; + + if ((osi_core != OSI_NULL) && (l_core->macsec_ops != OSI_NULL) && + (l_core->macsec_ops->coe_lc != OSI_NULL)) { + ret = l_core->macsec_ops->coe_lc(osi_core, ch, lc1, lc2); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "osi_macsec_coe_lc: ret \n", ret); + } + + return ret; +} + /** * @brief osi_macsec_deinit - De-Initialize the macsec controller * diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 0a70377..93bc522 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -177,6 +177,8 @@ struct core_ops { void (*macsec_config_mac)(struct osi_core_priv_data *const osi_core, const nveu32_t enable); #endif /* MACSEC_SUPPORT */ + nve32_t (*config_coe_buf)(struct osi_core_priv_data *const osi_core, + struct osi_mgbe_coe mgbe_coe); #ifndef OSI_STRIPPED_LIB /** Called to configure the MTL to forward/drop tx status */ nve32_t (*config_tx_status)(struct osi_core_priv_data *const osi_core, diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 78bbd10..b6f5272 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -454,6 +454,7 @@ static nve32_t ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_cor return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } + /** * @brief ivc_macsec_lut_config - LUT config. * @@ -550,6 +551,66 @@ static nve32_t ivc_macsec_init(struct osi_core_priv_data *const osi_core, return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } +/** + * @brief ivc_macsec_coe_lc - Update the Line counter threshold + * for the COE logic in macsec controller + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] ch: VDMA channel number. + * @param[in] lc1: Line count for first sub-frame. + * @param[in] lc2: Line count for all other sub-frames. + * + * @retval 0 on Success + * @retval -1 on Failure + */ +static nve32_t ivc_macsec_coe_lc(struct osi_core_priv_data *const osi_core, + nveu32_t ch, nveu32_t lc1, nveu32_t lc2) +{ + ivc_msg_common_t msg; + nveu32_t index = 0; + + osi_memset(&msg, 0, sizeof(msg)); + + msg.cmd = coe_lc_macsec; + msg.args.arguments[index] = ch; + index++; + msg.args.arguments[index] = lc1; + index++; + msg.args.arguments[index] = lc2; + index++; + msg.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); +} + +/** + * @brief ivc_macsec_coe_config - Enable/disable the COE logic in macsec controller + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] coe_enable: enable/disable flag. + * @param[in] coe_hdr_offset: Header offset for the COE header from SOF. + * + * @retval 0 on Success + * @retval -1 on Failure + */ +static nve32_t ivc_macsec_coe_config(struct osi_core_priv_data *const osi_core, + nveu32_t coe_enable, nveu32_t coe_hdr_offset) +{ + ivc_msg_common_t msg; + nveu32_t index = 0; + + osi_memset(&msg, 0, sizeof(msg)); + + msg.cmd = coe_config_macsec; + msg.args.arguments[index] = coe_enable; + index++; + msg.args.arguments[index] = coe_hdr_offset; + index++; + msg.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); +} + /** * @brief ivc_init_macsec_ops - Initialize IVC core operations. * @@ -567,6 +628,8 @@ void ivc_init_macsec_ops(void *macsecops) ops->deinit = ivc_macsec_deinit; ops->handle_irq = ivc_macsec_handle_irq; ops->lut_config = ivc_macsec_lut_config; + ops->coe_config = ivc_macsec_coe_config; + ops->coe_lc = ivc_macsec_coe_lc; #ifdef MACSEC_KEY_PROGRAM ops->kt_config = ivc_macsec_kt_config; #endif /* MACSEC_KEY_PROGRAM */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index d59b857..6ddff5a 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4841,6 +4841,68 @@ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, } #endif /* MACSEC_SUPPORT */ +static nve32_t mgbe_config_coe_buf(struct osi_core_priv_data *const osi_core, + struct osi_mgbe_coe mgbe_coe) +{ + nve32_t ret = 0; + nveu32_t val = 0; + nveu32_t i; + + if (osi_core->mac == OSI_MAC_HW_MGBE_T26X) { + /* TODO: Need to enable VLAN tag stripping as SPH feature needs untagged frame only */ + /* Configure MAC_Ext_Cfg1 register for SPH offsets */ + val = osi_readl((nveu8_t *)osi_core->base + + MGBE_MAC_EXT_CFG1); + val |= MGBE_MAC_EXT_CFG1_SAVE; + val |= (MGBE_MAC_EXT_CFG1_COE_SAVO << MGBE_MAC_EXT_CFG1_COE_SAVO_SHIFT); + val |= MGBE_MAC_EXT_CFG1_COE_SPLM; + val |= MGBE_MAC_EXT_CFG1_COE_SPLOFST; + osi_writel(val, (nveu8_t *)osi_core->base + + MGBE_MAC_EXT_CFG1); + /* Configure MTL_Rx_SPKT_CTRL register for COE header offset */ + val = osi_readl((nveu8_t *)osi_core->base + + MGBE_MTL_RX_SPKT_CTRL); + val |= MGBE_MTL_RX_SPKT_CTRL_COE_HDROS; + osi_writel(val, (nveu8_t *)osi_core->base + + MGBE_MTL_RX_SPKT_CTRL); + /* Configure the MGBE wrapper for pktinfo cntr */ + val = osi_readl((nveu8_t *)osi_core->base + + MGBE_WRAP_COE_PKTINFO_CNTR_INTR_MASK_0); + val = OSI_BIT(mgbe_coe.pdma); + osi_writel(val, (nveu8_t *)osi_core->base + + MGBE_WRAP_COE_PKTINFO_CNTR_INTR_MASK_0); + /* configure the Rx Frame buffers */ + for (i = 0;i < OSI_MGBE_COE_NUM_RX_FRAMES; i++) { + val = H32(mgbe_coe.rx_fb_addr_phys[i]) & + MGBE_COE_RXFRAMEBUF_HI_MASK; + ret = mgbe_dma_indir_addr_write(osi_core, + MGBE_COE_MSEL_RXFRAMEBUF_HI, + mgbe_coe.vdma, val); + val = L32(mgbe_coe.rx_fb_addr_phys[i]) & + MGBE_COE_RXFRAMEBUF_LO_MASK; + ret = mgbe_dma_indir_addr_write(osi_core, + MGBE_COE_MSEL_RXFRAMEBUF_LO_BASE + i, + mgbe_coe.vdma, val); + } + /* configure the Rx pkt info buffers */ + val = L32(mgbe_coe.rx_pib_addr_phys) & + MGBE_COE_RXPKTINFO_BUF_LO_MASK; + val |= mgbe_coe.rx_pib_sz & + MGBE_COE_PIB_SIZE_MASK; + ret = mgbe_dma_indir_addr_write(osi_core, + MGBE_COE_MSEL_RXPKTINFOBUF_LO, + mgbe_coe.pdma, val); + val = H32(mgbe_coe.rx_pib_addr_phys) & + MGBE_COE_RXPKTINFO_BUF_HI_MASK; + ret = mgbe_dma_indir_addr_write(osi_core, + MGBE_COE_MSEL_RXPKTINFOBUF_HI, + mgbe_coe.pdma, val); + } + + + return ret; +} + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -4873,6 +4935,7 @@ void mgbe_init_core_ops(struct core_ops *ops) #ifdef MACSEC_SUPPORT ops->macsec_config_mac = mgbe_config_for_macsec; #endif + ops->config_coe_buf = mgbe_config_coe_buf; ops->config_l3l4_filters = mgbe_config_l3l4_filters; #ifndef OSI_STRIPPED_LIB ops->config_tx_status = mgbe_config_tx_status; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index eca893d..501923f 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -380,6 +380,9 @@ #define MGBE_MAC_ISR 0x00B0 #define MGBE_MAC_IER 0x00B4 #define MGBE_MAC_EXT_CNF 0x0140 +#define MGBE_WRAP_COE_PKTINFO_CNTR_INTR_MASK_0 0xE0C0U +#define MGBE_MTL_RX_SPKT_CTRL 0x10a8 +#define MGBE_MAC_EXT_CFG1 0x144U #define MGBE_MDIO_SCCD 0x0204 #define MGBE_MDIO_SCCA 0x0200 #define MGBE_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) @@ -417,6 +420,17 @@ #define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 #define MGBE_T26X_WRAP_COMMON_INTR_ENABLE 0x880C +/* COE registers */ +#define MGBE_MTL_RX_SPKT_CTRL_COE_HDROS 0x8U +#define MGBE_MAC_EXT_CFG1_SAVE OSI_BIT(24) +/* For COE - image payload starts after AVTP hdr which is 32B + 8B for the COE HDR. + * The 2B added is because HW calculates offset from start of Ethtype field. + */ +#define MGBE_MAC_EXT_CFG1_COE_SAVO (2U + 32U + 8U) +#define MGBE_MAC_EXT_CFG1_COE_SAVO_SHIFT 16U +#define MGBE_MAC_EXT_CFG1_COE_SPLM OSI_BIT(8) +#define MGBE_MAC_EXT_CFG1_COE_SPLOFST MGBE_MAC_EXT_CFG1_COE_SAVO + #ifdef HSI_SUPPORT #define MGBE_REGISTER_PARITY_ERR OSI_BIT(5) #define MGBE_CORE_CORRECTABLE_ERR OSI_BIT(4) @@ -685,6 +699,23 @@ /* TX timestamp */ #define MGBE_MAC_TSS_TXTSC OSI_BIT(15) /* MGBE DMA IND CTRL register field masks */ +#define MGBE_COE_MSEL_RXFRAMEBUF_HI 0xFU +#define MGBE_COE_MSEL_RXFRAMEBUF_LO_BASE 0x10U +#define MGBE_COE_MSEL_RXPKTINFOBUF_HI 0x8U +#define MGBE_COE_MSEL_RXPKTINFOBUF_LO 0x9U +#define MGBE_COE_MSEL_RXPKTINFOBUF_CURR 0xAU +#define MGBE_COE_RXPKTINFO_BUF_HI_MASK 0xFFFFU +#define MGBE_COE_RXPKTINFO_BUF_LO_MASK 0xFFFFFFF0U +#define MGBE_COE_RXFRAMEBUF_HI_MASK 0xFFFFU +#define MGBE_COE_RXFRAMEBUF_LO_MASK 0xFFFFF000U +#define MGBE_COE_PIB_SIZE_256 0x0U +#define MGBE_COE_PIB_SIZE_512 0x1U +#define MGBE_COE_PIB_SIZE_2048 0x2U +#define MGBE_COE_PIB_SIZE_4096 0x3U +#define MGBE_COE_PIB_SIZE_MASK 0x3U +#define L32(data) ((nveu32_t)((data) & 0xFFFFFFFFU)) +#define H32(data) ((nveu32_t)(((data) & 0xFFFFFFFF00000000UL) >> 32UL)) + #define MGBE_DMA_INDIR_CTRL_MSEL_MASK (OSI_BIT(24) | OSI_BIT(25) | \ OSI_BIT(26) | OSI_BIT(27) | \ OSI_BIT(28)) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 92c4777..aacfc45 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -3311,6 +3311,15 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, apply_dynamic_cfg(osi_core); break; + case OSI_CMD_GMSL_COE_CONFIG: +#ifdef OSI_RM_FTRACE + ethernet_server_cmd_log("OSI_CMD_GMSL_COE_CONFIG"); +#endif + ret = ops_p->config_coe_buf(osi_core, data->mgbe_coe); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: OSI_CMD_GMSL_COE_CONFIG ret: \n", + (nveul64_t)ret); + break; default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 888d7c2..a7ea795 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -69,6 +69,7 @@ * @brief Values defined for the MGBE registers * @{ */ +#define MGBE_DMA_CHX_CTRL_SPH OSI_BIT(24) #define MGBE_DMA_CHX_RX_WDT_RWT_MASK 0xFFU #define MGBE_DMA_CHX_RX_WDT_RWTU 2048U #define MGBE_DMA_CHX_RX_WDT_RWTU_2048_CYCLE 0x3000U diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 04e19f8..faf4185 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -602,6 +602,16 @@ static nve32_t init_dma_channel(const struct osi_dma_priv_data *const osi_dma, chx_ctrl_reg[osi_dma->mac]); } if (osi_dma->mac == OSI_MAC_HW_MGBE_T26X) { + /* if COE is enabled - then enable split header + * and program related registers. + */ + val = osi_dma_readl((nveu8_t *)osi_dma->base + + chx_ctrl_reg[osi_dma->mac]); + if (osi_dma->coe_enable) { + val |= MGBE_DMA_CHX_CTRL_SPH; + } + osi_dma_writel(val, (nveu8_t *)osi_dma->base + + chx_ctrl_reg[osi_dma->mac]); /* Find VDMA to PDMA mapping */ ret = vdma_to_pdma_map(osi_dma, dma_chan, &pdma_chan); if (ret != 0) { diff --git a/osi/nvmacsecrm/macsec.c b/osi/nvmacsecrm/macsec.c index 8f65ad6..eed2b76 100644 --- a/osi/nvmacsecrm/macsec.c +++ b/osi/nvmacsecrm/macsec.c @@ -1960,6 +1960,64 @@ static void sa_state_lut_read(struct osi_core_priv_data *const osi_core, return; } +/** + * @brief coe_lut_read - Read COE LUT + * + * @note + * Algorithm: + * - Read COE lut data to lut_config + * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. + * - TraceID: *********** + * + * @param[in] osi_core: OSI core private data structure. + * @param[out] lut_config: Update the lut_config from h/w registers + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure + */ +static nve32_t coe_lut_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + nve32_t ret = 0; + + read_lut_data(osi_core, lut_data); + + switch (lut_config->table_config.ctlr_sel) { + case OSI_CTLR_SEL_RX: + lut_config->coe_lut_inout.valid = (lut_data[0] >> COE_LUT_VALID) & OSI_COE_LUT_ENTRY_VALID; + lut_config->coe_lut_inout.offset = ((lut_data[0] >> + COE_LUT_OFFSET_SHIFT) & + COE_LUT_OFFSET_MASK); + lut_config->coe_lut_inout.byte_pattern_mask = ((lut_data[0] >> + COE_LUT_MASK_SHIFT) & + COE_LUT_MASK_MASK); + lut_config->coe_lut_inout.byte_pattern[1] = ((lut_data[0] >> + COE_LUT_BYTE_PATTERN1_SHIFT) & + COE_LUT_BYTE_PATTERN_MASK); + lut_config->coe_lut_inout.byte_pattern[0] = ((lut_data[0] >> + COE_LUT_BYTE_PATTERN0_SHIFT) & + COE_LUT_BYTE_PATTERN_MASK); + break; + default: + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Invalid controller selected for COE LUT\n", 0ULL); + ret = -1; + break; + } + + /* Lookup output */ + return ret; +} + /** * @brief lut_data_read - Read different types of LUT data * @@ -2006,6 +2064,9 @@ static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, case OSI_LUT_SEL_SA_STATE: sa_state_lut_read(osi_core, lut_config); break; + case OSI_LUT_SEL_COE: + ret = coe_lut_read(osi_core, lut_config); + break; default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unsupported LUT\n", 0ULL); @@ -2149,6 +2210,25 @@ static void sa_state_lut_config(struct osi_core_priv_data *const osi_core, commit_lut_data(osi_core, lut_data); } +static nve32_t coe_lut_config(struct osi_core_priv_data *const osi_core, + const struct osi_macsec_lut_config *const lut_config) +{ + nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + nve32_t ret = 0; + + const struct osi_coe_lut_inout *coe = &lut_config->coe_lut_inout; + + lut_data[0] |= ((coe->byte_pattern[1] << COE_LUT_BYTE_PATTERN1_SHIFT) | + (coe->byte_pattern[0] << COE_LUT_BYTE_PATTERN0_SHIFT) | + (coe->byte_pattern_mask << COE_LUT_MASK_SHIFT) | + (coe->offset << COE_LUT_OFFSET_SHIFT) | + OSI_COE_LUT_ENTRY_VALID); + + commit_lut_data(osi_core, lut_data); + + return ret; +} + /** * @brief sc_state_lut_config - update lut_data from lut_config sc_state * @@ -3182,6 +3262,9 @@ static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, case OSI_LUT_SEL_SA_STATE: sa_state_lut_config(osi_core, lut_config); break; + case OSI_LUT_SEL_COE: + ret = coe_lut_config(osi_core, lut_config); + break; default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unsupported LUT\n", 0ULL); @@ -3224,6 +3307,17 @@ static nve32_t validate_lut_conf(struct osi_core_priv_data *const osi_core, }; /* Validate LUT config */ + if ((lut_config->lut_sel == OSI_LUT_SEL_COE) && + (lut_config->table_config.index >= OSI_COE_LUT_MAX_INDEX)) { + MACSEC_LOG("Validating LUT config failed. ctrl: %hu," + " rw: %hu, index: %hu, lut_sel: %hu", + lut_config->table_config.ctlr_sel, + lut_config->table_config.rw, + lut_config->table_config.index, lut_config->lut_sel); + ret = -1; + goto exit; + } + if ((lut_config->table_config.ctlr_sel > OSI_CTLR_SEL_MAX) || (lut_config->table_config.rw > OSI_RW_MAX) || (lut_config->table_config.index > lut_max_index[osi_core->macsec]) || @@ -4577,6 +4671,83 @@ exit: return ret; } +/** + * @brief macsec_coe_lc - Configure the COE line counter registers + * + * @note + * Algorithm: + * - Programs the MACSec COE line counter regiter with the lc thresholds for given channel + * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. + * - TraceID: *********** + * + * @param[in] osi_core: OSI core private data structure. used param macsec_base + * @param[in] ch: Channel number + * @param[in] lc1: Line counter threshold 1 + * @param[in] lc2: Line counter threshold 2 + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 + */ +static nve32_t macsec_coe_lc(struct osi_core_priv_data *const osi_core, + nveu32_t ch, nveu32_t lc1, nveu32_t lc2) +{ + nveu32_t val = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nve32_t ret = 0; + + val = MACSEC_COE_LINE_CNTR_EN; + val |= (lc1 & MACSEC_COE_LC_THRESH_MASK); + val |= (lc2 & MACSEC_COE_LC_THRESH_MASK) << MACSEC_COE_LC2_THRESH_SHIFT; + osi_macsec_writela(osi_core, val, addr + MACSEC_COE_LINE_CNTR(ch)); + + return ret; +} + +/** + * @brief macsec_coe_config - Configure the COE logic in MACSec controller + * + * @note + * Algorithm: + * - Programs the MACSec COE config register with COE enable and header offset + * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. + * - TraceID: *********** + * + * @param[in] osi_core: OSI core private data structure. used param macsec_base + * @param[in] coe_enable: Flag variable to enable/disable COE + * @param[in] coe_hdr_offset: The offset for the COE header from SOF + * + * @pre MACSEC needs to be out of reset and proper clock configured. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 + */ +static nve32_t macsec_coe_config(struct osi_core_priv_data *const osi_core, + nveu32_t coe_enable, nveu32_t coe_hdr_offset) +{ + nveu32_t val = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nve32_t ret = 0; + + val = coe_enable & MACSEC_COE_ENABLE_MASK; + val |= (coe_enable & MACSEC_COE_ENABLE_MASK) << MACSEC_COE_SEQ_CHK_SHIFT; + val |= (coe_hdr_offset & MACSEC_COE_HDROFST_MASK) << MACSEC_COE_HDROFST_SHIFT; + osi_macsec_writela(osi_core, val, addr + MACSEC_COE_CONFIG); + + return ret; +} + /** * @brief macsec_deinit - Deinitializes the macsec * @@ -6231,6 +6402,8 @@ void macsec_init_ops(void *macsecops) ops->init = macsec_initialize; ops->deinit = macsec_deinit; + ops->coe_config = macsec_coe_config, + ops->coe_lc = macsec_coe_lc, ops->handle_irq = macsec_handle_irq; ops->lut_config = macsec_lut_config; #ifdef MACSEC_KEY_PROGRAM diff --git a/osi/nvmacsecrm/macsec.h b/osi/nvmacsecrm/macsec.h index ea8daf9..25c1125 100644 --- a/osi/nvmacsecrm/macsec.h +++ b/osi/nvmacsecrm/macsec.h @@ -137,6 +137,27 @@ #define MACSEC_TX_SOT_DELAY 0xE010 #define MACSEC_RX_MTU_LEN 0xE014 #define MACSEC_RX_SOT_DELAY 0xE01C + +/** COE */ +#define MACSEC_COE_LINE_CNTR_EN OSI_BIT(31) +#define MACSEC_COE_LC_THRESH_MASK 0x3FFF +#define MACSEC_COE_LC2_THRESH_SHIFT 16 +#define MACSEC_COE_ENABLE_MASK 0x1 +#define MACSEC_COE_SEQ_CHK_SHIFT 1 +#define MACSEC_COE_HDROFST_MASK 0x3F +#define MACSEC_COE_HDROFST_SHIFT 16 +#define COE_LUT_BYTE_PATTERN_MASK 0xFF +#define COE_LUT_BYTE_PATTERN1_SHIFT 18 +#define COE_LUT_BYTE_PATTERN0_SHIFT 10 +#define COE_LUT_MASK_MASK 0xF +#define COE_LUT_MASK_SHIFT 6 +#define COE_LUT_OFFSET_MASK 0x1F +#define COE_LUT_OFFSET_SHIFT 1 +#define COE_LUT_VALID 0 + +#define MACSEC_COE_CONFIG 0xA000 +#define MACSEC_COE_LINE_CNTR(x) ((0xA004) + ((x) * 4U)) + /** @} */ #ifdef MACSEC_KEY_PROGRAM From b5a2453a2693e699e3a71bf2e4375e9b08fe0348 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Sat, 15 Feb 2025 00:47:32 +0000 Subject: [PATCH 2/7] COE: disable macsec controlled port check for VF By default, don't enable controlled port on the VF mac. COE logic requires macsec controller enabled, but does not need secure channel for the VF MAC. JIRA CT26X-1917 Change-Id: I05d18adfdb1c243d05ab04463ddf33015b785acd Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3303545 Tested-by: Srinivas Ramachandran Reviewed-by: Srinivas Ramachandran --- osi/nvmacsecrm/macsec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/osi/nvmacsecrm/macsec.c b/osi/nvmacsecrm/macsec.c index 6bccba6..6a35601 100644 --- a/osi/nvmacsecrm/macsec.c +++ b/osi/nvmacsecrm/macsec.c @@ -5302,6 +5302,7 @@ static nve32_t macsec_initialize(struct osi_core_priv_data *const osi_core, nveu } osi_core->macsec_initialized = OSI_ENABLE; + return ret; upd_byp_sci_lut: ret = upd_byp_rx_lut_with_vf_mac(osi_core, macsec_vf_mac); From b8fe432eea330682d48c6b1eb1abf090ffc522c8 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Wed, 19 Feb 2025 04:33:35 +0000 Subject: [PATCH 3/7] coe: Disable seq num check in macsec for COE HSB does not use proper seq. num currently. Every SOF is supposed to start with seq 0 in COE header. BUt HSB preserves last value incorrectly. This is resulting in frame errors being reported by macsec. Till HSB FPGA can be updated, disable seq. check for GTC. JIRA CT26X-1895 Change-Id: I654fbe6faab187ea416b38d01c30694ce1df0ee2 Signed-off-by: Srinivas Ramachandran Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3305644 --- osi/nvmacsecrm/macsec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osi/nvmacsecrm/macsec.c b/osi/nvmacsecrm/macsec.c index 6a35601..a157ed0 100644 --- a/osi/nvmacsecrm/macsec.c +++ b/osi/nvmacsecrm/macsec.c @@ -4741,7 +4741,9 @@ static nve32_t macsec_coe_config(struct osi_core_priv_data *const osi_core, nve32_t ret = 0; val = coe_enable & MACSEC_COE_ENABLE_MASK; - val |= (coe_enable & MACSEC_COE_ENABLE_MASK) << MACSEC_COE_SEQ_CHK_SHIFT; + /* TODO - re-enable seq num check for production. This is just till HSB FPGA can be + * fixed to use proper starting seq for every SOF. */ + //val |= (coe_enable & MACSEC_COE_ENABLE_MASK) << MACSEC_COE_SEQ_CHK_SHIFT; val |= (coe_hdr_offset & MACSEC_COE_HDROFST_MASK) << MACSEC_COE_HDROFST_SHIFT; osi_macsec_writela(osi_core, val, addr + MACSEC_COE_CONFIG); From 7c79f9d11d5775bf9037bfe70c1b82a3bba3715a Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Sun, 9 Mar 2025 08:30:26 +0000 Subject: [PATCH 4/7] mask MACSEC Rx IRQ Signed-off-by: Igor Mitsyanko Change-Id: Ic992955fdf5b0adba45db4bdff5f09ed93c2cae3 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3316134 --- osi/nvmacsecrm/macsec.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osi/nvmacsecrm/macsec.c b/osi/nvmacsecrm/macsec.c index a157ed0..dddcbe8 100644 --- a/osi/nvmacsecrm/macsec.c +++ b/osi/nvmacsecrm/macsec.c @@ -5100,20 +5100,21 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 val = osi_macsec_readla(osi_core, addr + rx_imr_reg[macsec]); MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); - +/* val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | RX_REPLAY_ERROR_INT_EN | MACSEC_RX_MTU_CHECK_FAIL_INT_EN | MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | MACSEC_RX_PN_EXHAUSTED_INT_EN - ); + );*/ + val = 0U; osi_macsec_writela(osi_core, val, addr + rx_imr_reg[macsec]); MACSEC_LOG("Write MACSEC_RX_IMR: 0x%x\n", val); val = osi_macsec_readla(osi_core, addr + common_imr_reg[macsec]); MACSEC_LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); - val |= (MACSEC_RX_UNINIT_KEY_SLOT_INT_EN | - MACSEC_RX_LKUP_MISS_INT_EN | + val |= (/*MACSEC_RX_UNINIT_KEY_SLOT_INT_EN | + MACSEC_RX_LKUP_MISS_INT_EN |*/ MACSEC_TX_UNINIT_KEY_SLOT_INT_EN | MACSEC_TX_LKUP_MISS_INT_EN); osi_macsec_writela(osi_core, val, addr + common_imr_reg[macsec]); @@ -5274,13 +5275,15 @@ static nve32_t macsec_initialize(struct osi_core_priv_data *const osi_core, nveu /* Enabling interrupts only related to HSI */ val = osi_macsec_readla(osi_core, addr + rx_imr_reg[macsec]); MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); - val |= (MACSEC_RX_ICV_ERROR_INT_EN | - MACSEC_RX_MAC_CRC_ERROR_INT_EN); + //val |= (MACSEC_RX_ICV_ERROR_INT_EN | + // MACSEC_RX_MAC_CRC_ERROR_INT_EN); + val = 0U; MACSEC_LOG("Write MACSEC_RX_IMR: 0x%x\n", val); osi_macsec_writela(osi_core, val, addr + rx_imr_reg[macsec]); val = osi_macsec_readla(osi_core, addr + common_imr_reg[macsec]); - val |= MACSEC_SECURE_REG_VIOL_INT_EN; + //val |= MACSEC_SECURE_REG_VIOL_INT_EN; + val = 0U; osi_macsec_writela(osi_core, val, addr + common_imr_reg[macsec]); /* Set AES mode From 9aa28e802d6658ac31c8588fa8abbede83700105 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Sat, 29 Mar 2025 18:04:17 +0000 Subject: [PATCH 5/7] osi: coe: do not use CoE channels The MGBE driver logic should not use Camera Over Ethernet DMA channels for normal Rx/Tx. Track which channels are CoE channels separately from normal channels. In some cases MTL queue number is used in place of DMA channel, as it is assumed by a driver that DMA channel maps 1:1 to MTL queue number. Fix such cases to make sure CoE channels are not selected for Tx by a driver and are not part of RSS or multicasting. Change-Id: I18da9a3e51168c9e3c95278beb179b44e8647f36 Signed-off-by: Igor Mitsyanko Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3330334 Reviewed-by: svcacv --- include/osi_core.h | 2 + include/osi_dma.h | 6 ++ osi/core/mgbe_core.c | 42 +++++++++++--- osi/dma/osi_dma.c | 132 +++++++++++++++++++++++++++++++------------ 4 files changed, 136 insertions(+), 46 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 925de15..b49d43d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1304,6 +1304,8 @@ struct osi_vm_irq_data { * valid values are from 0 to NVETHERNETRM_PIF$OSI_EQOS_MAX_NUM_CHANS-1 for eqos * and 0 to NVETHERNETRM_PIF$OSI_MGBE_MAX_NUM_CHANS-1 */ nveu32_t vm_chans[OSI_MGBE_MAX_NUM_CHANS]; + /** If the IRQ is used for Camera Over Ethernet (handled by camera CPU) */ + nveu8_t is_coe; }; /** diff --git a/include/osi_dma.h b/include/osi_dma.h index 266c70d..80be170 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -724,6 +724,12 @@ struct osi_dma_priv_data { * Valid array size is num_dma_chans */ nveu32_t dma_chans[OSI_MGBE_MAX_NUM_CHANS]; + /** Number of channels enabled in MAC used for Camera Over Ethernet + */ + nveu32_t num_dma_chans_coe; + /** Array of DMA channels which are managed by camera CPU. + */ + nveu8_t dma_chans_coe[OSI_MGBE_MAX_NUM_CHANS]; /** DMA Rx channel buffer length at HW level. Max value is related to mtu based * on equation documented in sequence diagram of osi_set_rx_buf_len() */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 90ac6d7..9aeba0b 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2162,7 +2162,7 @@ static nve32_t mgbe_config_flow_control(struct osi_core_priv_data *const osi_cor * @brief pcs_configure_fsm - Configure FSM for XPCS/XLGPCS * * @note - * Algorithm: enable/disable the FSM timeout safety feature + * Algorithm: enable/disable the FSM timeout safety feature * * @param[in, out] osi_core: OSI core private data structure. * @param[in] enable: OSI_ENABLE for Enabling FSM timeout safety feature, else disable @@ -2482,6 +2482,24 @@ static nve32_t mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, #endif #endif +static inline nveu32_t +mgbe_core_chan_is_coe(const struct osi_core_priv_data * const osi_core, + nveu32_t chan_id) +{ + for (nveu32_t irqn = 0U; irqn < osi_core->num_vm_irqs; irqn++) { + if (osi_core->irq_data[irqn].is_coe == 0U) + continue; + + for (nveu32_t ch = 0U; ch < osi_core->irq_data[irqn].num_vm_chans; ch++) { + if (osi_core->irq_data[irqn].vm_chans[ch] == chan_id) { + return 1U; + } + } + } + + return 0U; +} + /** * @brief mgbe_configure_mac - Configure MAC * @@ -2555,13 +2573,14 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) (nveu8_t *)osi_core->base + MGBE_MAC_RQC1R); value |= MGBE_MAC_RQC1R_MCBCQEN; /* Set MCBCQ to highest enabled RX queue index */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - if ((max_queue < osi_core->mtl_queues[i]) && - (osi_core->mtl_queues[i] < OSI_MGBE_MAX_NUM_QUEUES)) { + for (i = 0; i < osi_core->num_dma_chans; i++) { + if ((max_queue < osi_core->dma_chans[i]) && + (osi_core->dma_chans[i] < OSI_MGBE_MAX_NUM_QUEUES)) { /* Update max queue number */ - max_queue = osi_core->mtl_queues[i]; + max_queue = osi_core->dma_chans[i]; } } + value &= ~(MGBE_MAC_RQC1R_MCBCQ); value |= (max_queue << MGBE_MAC_RQC1R_MCBCQ_SHIFT); osi_writela(osi_core, value, @@ -3074,15 +3093,20 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core) * Since this is a local function this will always return sucess, * so no need to check for return value */ + if (mgbe_core_chan_is_coe(osi_core, osi_core->mtl_queues[qinx])) { + ret = hw_config_fw_err_pkts(osi_core, + osi_core->mtl_queues[qinx], OSI_DISABLE); + } else { + ret = hw_config_fw_err_pkts(osi_core, + osi_core->mtl_queues[qinx], OSI_ENABLE); + } #ifndef OSI_STRIPPED_LIB - ret = hw_config_fw_err_pkts(osi_core, osi_core->mtl_queues[qinx], OSI_ENABLE); if (ret < 0) { goto fail; } #else - (void)hw_config_fw_err_pkts(osi_core, osi_core->mtl_queues[qinx], OSI_ENABLE); -#endif /* !OSI_STRIPPED_LIB */ - + (void)ret; +#endif } /* configure MGBE MAC HW */ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 4baa8fa..b63dd1a 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -266,6 +266,36 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) return ret; } +/** + * @brief Function to validate array of CoE DMA channels. + * + * @param[in] osi_dma: OSI DMA private data structure. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes + * + * @retval 0 on Success + * @retval -1 on Failure + */ +static inline nve32_t validate_coe_dma_chans(struct osi_dma_priv_data *osi_dma) +{ + const struct dma_local *const l_dma = (struct dma_local *)(void *)osi_dma; + nveu32_t i = 0U; + nve32_t ret = 0; + for (i = 0; i < osi_dma->num_dma_chans_coe; i++) { + if (osi_dma->dma_chans_coe[i] > l_dma->num_max_chans) { + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, + "Invalid CoE DMA channel number:\n", + osi_dma->dma_chans_coe[i]); + ret = -1; + } + } + return ret; +} + #ifndef OSI_STRIPPED_LIB /** * @brief Function to validate function pointers. @@ -516,6 +546,37 @@ static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu osi_dma_writel(val, (nveu8_t *)osi_dma->base + rx_dma_reg[local_mac]); } +static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma, + nveu32_t dma_chan) +{ + const nveu32_t chan_mask[OSI_MAX_MAC_IP_TYPES] = {0xFU, 0xFU, 0x3FU}; + const nveu32_t local_mac = osi_dma->mac % OSI_MAX_MAC_IP_TYPES; + // Added bitwise with 0xFF to avoid CERT INT30-C error + nveu32_t chan = ((dma_chan & chan_mask[local_mac]) & (0xFFU)); + const nveu32_t dma_tx_reg[OSI_MAX_MAC_IP_TYPES] = { + EQOS_DMA_CHX_TX_CTRL(chan), + MGBE_DMA_CHX_TX_CTRL(chan), + MGBE_DMA_CHX_TX_CTRL(chan) + }; + const nveu32_t dma_rx_reg[OSI_MAX_MAC_IP_TYPES] = { + EQOS_DMA_CHX_RX_CTRL(chan), + MGBE_DMA_CHX_RX_CTRL(chan), + MGBE_DMA_CHX_RX_CTRL(chan) + }; + nveu32_t val; + + /* Stop Tx DMA */ + val = osi_dma_readl((nveu8_t *)osi_dma->base + dma_tx_reg[osi_dma->mac]); + val &= ~OSI_BIT(0); + osi_dma_writel(val, (nveu8_t *)osi_dma->base + dma_tx_reg[osi_dma->mac]); + + /* Stop Rx DMA */ + val = osi_dma_readl((nveu8_t *)osi_dma->base + dma_rx_reg[osi_dma->mac]); + val &= ~OSI_BIT(0); + val |= OSI_BIT(31); + osi_dma_writel(val, (nveu8_t *)osi_dma->base + dma_rx_reg[osi_dma->mac]); +} + static nve32_t init_dma_channel(const struct osi_dma_priv_data *const osi_dma, nveu32_t dma_chan) { @@ -526,6 +587,7 @@ static nve32_t init_dma_channel(const struct osi_dma_priv_data *const osi_dma, // Added bitwise with 0xFF to avoid CERT INT30-C error nveu32_t chan = ((dma_chan & chan_mask[local_mac]) & (0xFFU)); nveu32_t riwt = osi_dma->rx_riwt & 0xFFFU; + const nveu32_t total_num_chans = osi_dma->num_dma_chans + osi_dma->num_dma_chans_coe; const nveu32_t intr_en_reg[OSI_MAX_MAC_IP_TYPES] = { EQOS_DMA_CHX_INTR_ENA(chan), MGBE_DMA_CHX_INTR_ENA(chan), @@ -558,7 +620,7 @@ static nve32_t init_dma_channel(const struct osi_dma_priv_data *const osi_dma, const nveu32_t rx_pbl[2] = { EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED, ((Q_SZ_DEPTH(MGBE_RXQ_SIZE/OSI_MGBE_MAX_NUM_QUEUES) / - osi_dma->num_dma_chans) / 2U) + total_num_chans) / 2U) }; const nveu32_t rwt_val[OSI_MAX_MAC_IP_TYPES] = { (((riwt * (EQOS_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / @@ -583,7 +645,7 @@ static nve32_t init_dma_channel(const struct osi_dma_priv_data *const osi_dma, (DMA_CHX_TX_CTRL_OSP | DMA_CHX_TX_CTRL_TSE), DMA_CHX_TX_CTRL_TSE }; - const nveu32_t owrq = (MGBE_DMA_CHX_RX_CNTRL2_OWRQ_MCHAN / osi_dma->num_dma_chans); + const nveu32_t owrq = (MGBE_DMA_CHX_RX_CNTRL2_OWRQ_MCHAN / total_num_chans); const nveu32_t owrq_arr[OSI_MGBE_T23X_MAX_NUM_CHANS] = { MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SCHAN, owrq, owrq, owrq, owrq, owrq, owrq, owrq, owrq, owrq @@ -799,14 +861,16 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) } if ((osi_dma->num_dma_chans == 0U) || - (osi_dma->num_dma_chans > l_dma->num_max_chans)) { + (osi_dma->num_dma_chans > l_dma->num_max_chans) || + (osi_dma->num_dma_chans_coe > l_dma->num_max_chans)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid number of DMA channels\n", 0ULL); ret = -1; goto fail; } - if (validate_dma_chans(osi_dma) < 0) { + if ((validate_dma_chans(osi_dma) < 0) || + (validate_coe_dma_chans(osi_dma) < 0)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA channels validation failed\n", 0ULL); ret = -1; @@ -826,6 +890,18 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) } } + /* Init DMA engine settings for CoE channels, but don't start the DMA */ + for (i = 0; i < osi_dma->num_dma_chans_coe; i++) { + ret = init_dma_channel(osi_dma, osi_dma->dma_chans_coe[i]); + if (ret < 0) { + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, + "DMA: Init CoE DMA channel failed\n", 0ULL); + goto fail; + } + + stop_dma(osi_dma, osi_dma->dma_chans_coe[i]); + } + set_default_ptp_config(osi_dma); fail: #ifdef OSI_CL_FTRACE @@ -834,37 +910,6 @@ fail: return ret; } -static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma, - nveu32_t dma_chan) -{ - const nveu32_t chan_mask[OSI_MAX_MAC_IP_TYPES] = {0xFU, 0xFU, 0x3FU}; - const nveu32_t local_mac = osi_dma->mac % OSI_MAX_MAC_IP_TYPES; - // Added bitwise with 0xFF to avoid CERT INT30-C error - nveu32_t chan = ((dma_chan & chan_mask[local_mac]) & (0xFFU)); - const nveu32_t dma_tx_reg[OSI_MAX_MAC_IP_TYPES] = { - EQOS_DMA_CHX_TX_CTRL(chan), - MGBE_DMA_CHX_TX_CTRL(chan), - MGBE_DMA_CHX_TX_CTRL(chan) - }; - const nveu32_t dma_rx_reg[OSI_MAX_MAC_IP_TYPES] = { - EQOS_DMA_CHX_RX_CTRL(chan), - MGBE_DMA_CHX_RX_CTRL(chan), - MGBE_DMA_CHX_RX_CTRL(chan) - }; - nveu32_t val; - - /* Stop Tx DMA */ - val = osi_dma_readl((nveu8_t *)osi_dma->base + dma_tx_reg[osi_dma->mac]); - val &= ~OSI_BIT(0); - osi_dma_writel(val, (nveu8_t *)osi_dma->base + dma_tx_reg[osi_dma->mac]); - - /* Stop Rx DMA */ - val = osi_dma_readl((nveu8_t *)osi_dma->base + dma_rx_reg[osi_dma->mac]); - val &= ~OSI_BIT(0); - val |= OSI_BIT(31); - 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) @@ -934,8 +979,15 @@ static inline void set_rx_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); } + + for (i = 0; i < osi_dma->num_dma_chans_coe; i++) { + chan = osi_dma->dma_chans_coe[i]; + + set_rx_riit_dma(osi_dma, chan, 0U); + } return; } @@ -953,14 +1005,16 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) goto fail; } - if (osi_dma->num_dma_chans > l_dma->num_max_chans) { + if ((osi_dma->num_dma_chans > l_dma->num_max_chans) || + (osi_dma->num_dma_chans_coe > l_dma->num_max_chans)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid number of DMA channels\n", 0ULL); ret = -1; goto fail; } - if (validate_dma_chans(osi_dma) < 0) { + if ((validate_dma_chans(osi_dma) < 0) || + (validate_coe_dma_chans(osi_dma) < 0)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA channels validation failed\n", 0ULL); ret = -1; @@ -971,6 +1025,10 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) stop_dma(osi_dma, osi_dma->dma_chans[i]); } + for (i = 0; i < osi_dma->num_dma_chans_coe; i++) { + stop_dma(osi_dma, osi_dma->dma_chans_coe[i]); + } + fail: #ifdef OSI_CL_FTRACE slogf(0, 2, "%s : Function Exit\n", __func__); From b41d40ece9610acc3d0b6cf8fd6cba299860ddfc Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Fri, 6 Jun 2025 15:57:16 -0700 Subject: [PATCH 6/7] Revert "coe: Disable seq num check in macsec for COE" This reverts commit b8fe432eea330682d48c6b1eb1abf090ffc522c8. Reason for revert: HSB FW has been updated to include resetting the frame number for every SOF. This has been verified with Eagle AIO modules with HSB FW FPGA version=0x2505 datecode=0xf1a72011 CT26X-1921 Change-Id: I67f83a2d7de93187276266689d34d68f8c551f7e Signed-off-by: Srinivas Ramachandran Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3381926 --- osi/nvmacsecrm/macsec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osi/nvmacsecrm/macsec.c b/osi/nvmacsecrm/macsec.c index 54625af..169f80a 100644 --- a/osi/nvmacsecrm/macsec.c +++ b/osi/nvmacsecrm/macsec.c @@ -4748,9 +4748,7 @@ static nve32_t macsec_coe_config(struct osi_core_priv_data *const osi_core, nve32_t ret = 0; val = coe_enable & MACSEC_COE_ENABLE_MASK; - /* TODO - re-enable seq num check for production. This is just till HSB FPGA can be - * fixed to use proper starting seq for every SOF. */ - //val |= (coe_enable & MACSEC_COE_ENABLE_MASK) << MACSEC_COE_SEQ_CHK_SHIFT; + val |= (coe_enable & MACSEC_COE_ENABLE_MASK) << MACSEC_COE_SEQ_CHK_SHIFT; val |= (coe_hdr_offset & MACSEC_COE_HDROFST_MASK) << MACSEC_COE_HDROFST_SHIFT; osi_macsec_writela(osi_core, val, addr + MACSEC_COE_CONFIG); From 949b3e962e806db8dcf5e3025628e3f40fa46d83 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Sat, 21 Jun 2025 07:57:28 +0000 Subject: [PATCH 7/7] macsec: cleanup for release Cleanup code to prepare for rel-38 release branch integration. Change-Id: I2aff4cd730a6a2ad1e17f58fed4e37023ffd4391 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3390116 Tested-by: Igor Mitsyanko Reviewed-by: Igor Mitsyanko --- osi/core/common_macsec.c | 2 -- osi/nvmacsecrm/macsec.c | 17 +++++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/osi/core/common_macsec.c b/osi/core/common_macsec.c index 10641f8..3f090df 100644 --- a/osi/core/common_macsec.c +++ b/osi/core/common_macsec.c @@ -227,8 +227,6 @@ nve32_t osi_macsec_coe_lc(struct osi_core_priv_data *const osi_core, if ((osi_core != OSI_NULL) && (l_core->macsec_ops != OSI_NULL) && (l_core->macsec_ops->coe_lc != OSI_NULL)) { ret = l_core->macsec_ops->coe_lc(osi_core, ch, lc1, lc2); - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "osi_macsec_coe_lc: ret \n", ret); } return ret; diff --git a/osi/nvmacsecrm/macsec.c b/osi/nvmacsecrm/macsec.c index 169f80a..29c1a2f 100644 --- a/osi/nvmacsecrm/macsec.c +++ b/osi/nvmacsecrm/macsec.c @@ -5105,21 +5105,20 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 val = osi_macsec_readla(osi_core, addr + rx_imr_reg[macsec]); MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); -/* + val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | RX_REPLAY_ERROR_INT_EN | MACSEC_RX_MTU_CHECK_FAIL_INT_EN | MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | MACSEC_RX_PN_EXHAUSTED_INT_EN - );*/ - val = 0U; + ); osi_macsec_writela(osi_core, val, addr + rx_imr_reg[macsec]); MACSEC_LOG("Write MACSEC_RX_IMR: 0x%x\n", val); val = osi_macsec_readla(osi_core, addr + common_imr_reg[macsec]); MACSEC_LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); - val |= (/*MACSEC_RX_UNINIT_KEY_SLOT_INT_EN | - MACSEC_RX_LKUP_MISS_INT_EN |*/ + val |= (MACSEC_RX_UNINIT_KEY_SLOT_INT_EN | + MACSEC_RX_LKUP_MISS_INT_EN | MACSEC_TX_UNINIT_KEY_SLOT_INT_EN | MACSEC_TX_LKUP_MISS_INT_EN); osi_macsec_writela(osi_core, val, addr + common_imr_reg[macsec]); @@ -5280,15 +5279,13 @@ static nve32_t macsec_initialize(struct osi_core_priv_data *const osi_core, nveu /* Enabling interrupts only related to HSI */ val = osi_macsec_readla(osi_core, addr + rx_imr_reg[macsec]); MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); - //val |= (MACSEC_RX_ICV_ERROR_INT_EN | - // MACSEC_RX_MAC_CRC_ERROR_INT_EN); - val = 0U; + val |= (MACSEC_RX_ICV_ERROR_INT_EN | + MACSEC_RX_MAC_CRC_ERROR_INT_EN); MACSEC_LOG("Write MACSEC_RX_IMR: 0x%x\n", val); osi_macsec_writela(osi_core, val, addr + rx_imr_reg[macsec]); val = osi_macsec_readla(osi_core, addr + common_imr_reg[macsec]); - //val |= MACSEC_SECURE_REG_VIOL_INT_EN; - val = 0U; + val |= MACSEC_SECURE_REG_VIOL_INT_EN; osi_macsec_writela(osi_core, val, addr + common_imr_reg[macsec]); /* Set AES mode