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