diff --git a/include/osi_core.h b/include/osi_core.h index 46b062f..8181c96 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -96,6 +96,13 @@ typedef my_lint_64 nvel64_t; #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) #define OSI_FLOW_CTRL_RX OSI_BIT(1) + +#define OSI_INSTANCE_ID_MBGE0 0 +#define OSI_INSTANCE_ID_MGBE1 1 +#define OSI_INSTANCE_ID_MGBE2 2 +#define OSI_INSTANCE_ID_MGBE3 3 +#define OSI_INSTANCE_ID_EQOS0 4 + #endif /* !OSI_STRIPPED_LIB */ @@ -266,6 +273,9 @@ typedef my_lint_64 nvel64_t; #endif #define OSI_CMD_SUSPEND 53U #define OSI_CMD_RESUME 54U +#ifdef HSI_SUPPORT +#define OSI_CMD_HSI_INJECT_ERR 55U +#endif /** @} */ /** @@ -290,8 +300,8 @@ typedef my_lint_64 nvel64_t; */ #define OSI_CORE_INFO(priv, type, err, loga) \ { \ - osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ - OSI_LOG_INFO, type, err, loga); \ + osi_core->osd_ops.ops_log((priv), __func__, __LINE__, \ + OSI_LOG_INFO, (type), (err), (loga)); \ } #define VLAN_NUM_VID 4096U @@ -414,6 +424,24 @@ extern nveu16_t hsi_reporter_id[]; #define OSI_MACSEC_RX_ICV_ERR 0x1007U #define OSI_MACSEC_REG_VIOL_ERR 0x1008U #define OSI_XPCS_WRITE_FAIL_ERR 0x1009U + +#define OSI_HSI_MGBE0_UE_CODE 0x2A00U +#define OSI_HSI_MGBE1_UE_CODE 0x2A01U +#define OSI_HSI_MGBE2_UE_CODE 0x2A02U +#define OSI_HSI_MGBE3_UE_CODE 0x2A03U +#define OSI_HSI_EQOS0_UE_CODE 0x28ADU + +#define OSI_HSI_MGBE0_CE_CODE 0x2E08U +#define OSI_HSI_MGBE1_CE_CODE 0x2E09U +#define OSI_HSI_MGBE2_CE_CODE 0x2E0AU +#define OSI_HSI_MGBE3_CE_CODE 0x2E0BU +#define OSI_HSI_EQOS0_CE_CODE 0x2DE6U + +#define OSI_HSI_MGBE0_REPORTER_ID 0x8019U +#define OSI_HSI_MGBE1_REPORTER_ID 0x801AU +#define OSI_HSI_MGBE2_REPORTER_ID 0x801BU +#define OSI_HSI_MGBE3_REPORTER_ID 0x801CU +#define OSI_HSI_EQOS0_REPORTER_ID 0x8009U /** @} */ #endif diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 747edfa..9b921ea 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -25,6 +25,7 @@ #include "mgbe_core.h" #include "eqos_core.h" #include "xpcs.h" +#include "macsec.h" static inline nve32_t poll_check(struct osi_core_priv_data *const osi_core, nveu8_t *addr, nveu32_t bit_check, nveu32_t *value) @@ -1408,3 +1409,74 @@ void hw_tsn_init(struct osi_core_priv_data *osi_core, user application should use IOCTL to set CBS as per requirement */ } + +#ifdef HSI_SUPPORT +/** + * @brief hsi_common_error_inject + * + * Algorithm: + * - For macsec HSI: trigger interrupt using MACSEC_*_INTERRUPT_SET_0 register + * - For mmc counter based: trigger interrupt by incrementing count by threshold value + * - For rest: Directly set the error detected as there is no other mean to induce error + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] error_code: Ethernet HSI error code + * + * @note MAC should be init and started. see osi_start_mac() + */ +void hsi_common_error_inject(struct osi_core_priv_data *osi_core, + nveu32_t error_code) +{ + switch (error_code) { + case OSI_INBOUND_BUS_CRC_ERR: + osi_core->mmc.mmc_rx_crc_error = + osi_update_stats_counter(osi_core->mmc.mmc_rx_crc_error, + osi_core->hsi.err_count_threshold); + break; + case OSI_RECEIVE_CHECKSUM_ERR: + osi_core->mmc.mmc_rx_udp_err = + osi_update_stats_counter(osi_core->mmc.mmc_rx_udp_err, + osi_core->hsi.err_count_threshold); + break; + case OSI_MACSEC_RX_CRC_ERR: + osi_writela(osi_core, MACSEC_RX_MAC_CRC_ERROR, + (nveu8_t *)osi_core->macsec_base + + MACSEC_RX_ISR_SET); + break; + case OSI_MACSEC_TX_CRC_ERR: + osi_writela(osi_core, MACSEC_TX_MAC_CRC_ERROR, + (nveu8_t *)osi_core->macsec_base + + MACSEC_TX_ISR_SET); + break; + case OSI_MACSEC_RX_ICV_ERR: + osi_writela(osi_core, MACSEC_RX_ICV_ERROR, + (nveu8_t *)osi_core->macsec_base + + MACSEC_RX_ISR_SET); + break; + case OSI_MACSEC_REG_VIOL_ERR: + osi_writela(osi_core, MACSEC_SECURE_REG_VIOL, + (nveu8_t *)osi_core->macsec_base + + MACSEC_COMMON_ISR_SET); + break; + case OSI_TX_FRAME_ERR: + osi_core->hsi.report_count_err[TX_FRAME_ERR_IDX] = OSI_ENABLE; + osi_core->hsi.err_code[TX_FRAME_ERR_IDX] = OSI_TX_FRAME_ERR; + osi_core->hsi.report_err = OSI_ENABLE; + break; + case OSI_PCS_AUTONEG_ERR: + osi_core->hsi.err_code[AUTONEG_ERR_IDX] = OSI_PCS_AUTONEG_ERR; + osi_core->hsi.report_err = OSI_ENABLE; + osi_core->hsi.report_count_err[AUTONEG_ERR_IDX] = OSI_ENABLE; + break; + case OSI_XPCS_WRITE_FAIL_ERR: + osi_core->hsi.err_code[XPCS_WRITE_FAIL_IDX] = OSI_XPCS_WRITE_FAIL_ERR; + osi_core->hsi.report_err = OSI_ENABLE; + osi_core->hsi.report_count_err[XPCS_WRITE_FAIL_IDX] = OSI_ENABLE; + break; + default: + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Invalid error code\n", (nveu32_t)error_code); + break; + } +} +#endif diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 63721fd..c858835 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -142,4 +142,8 @@ nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core, struct osi_fpe_config *const fpe); void hw_tsn_init(struct osi_core_priv_data *osi_core, nveu32_t est_sel, nveu32_t fpe_sel); +#ifdef HSI_SUPPORT +void hsi_common_error_inject(struct osi_core_priv_data *osi_core, + nveu32_t error_code); +#endif #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 72f21b5..4f0dfcf 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -254,6 +254,9 @@ struct core_ops { /** Interface function called to initialize HSI */ nve32_t (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, const nveu32_t enable); + /** Interface function called to inject error */ + void (*core_hsi_inject_err)(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code); #endif }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 39a29e2..c741b4b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -28,6 +28,7 @@ #include "core_local.h" #include "vlan_filter.h" #include "core_common.h" +#include "macsec.h" #ifdef UPDATED_PAD_CAL /* @@ -1118,6 +1119,46 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, } return 0; } + +/** + * @brief eqos_hsi_inject_err - inject error + * + * @note + * Algorithm: + * - Use error injection method induce error + * + * @param[in, out] osi_core: OSI core private data structure. + * @param[in] type: UE_IDX/CE_IDX + * + * @retval 0 on success + * @retval -1 on failure + */ + +static void eqos_hsi_inject_err(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code) +{ + nveu32_t value; + + switch (error_code) { + case OSI_HSI_EQOS0_CE_CODE: + value = (EQOS_MTL_DBG_CTL_EIEC | EQOS_MTL_DBG_CTL_EIEE); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_DBG_CTL); + break; + case OSI_HSI_EQOS0_UE_CODE: + value = EQOS_MTL_DPP_ECC_EIC_BLEI; + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_DPP_ECC_EIC); + + value = (EQOS_MTL_DBG_CTL_EIEC | EQOS_MTL_DBG_CTL_EIEE); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_DBG_CTL); + break; + default: + hsi_common_error_inject(osi_core, error_code); + break; + } +} #endif /** @@ -4923,5 +4964,6 @@ void eqos_init_core_ops(struct core_ops *ops) #endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT ops->core_hsi_configure = eqos_hsi_configure; + ops->core_hsi_inject_err = eqos_hsi_inject_err; #endif } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 51382b1..c8ed90b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -858,6 +858,11 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #define EQOS_MTL_DPP_CONTROL 0xCE0U #define EQOS_EDPP OSI_BIT(0) #define EQOS_MAC_DPP_FSM_INTERRUPT_STATUS 0x140U +#define EQOS_MTL_DBG_CTL 0xC08U +#define EQOS_MTL_DBG_CTL_EIEC OSI_BIT(18) +#define EQOS_MTL_DBG_CTL_EIEE OSI_BIT(16) +#define EQOS_MTL_DPP_ECC_EIC 0xCE4U +#define EQOS_MTL_DPP_ECC_EIC_BLEI OSI_BIT(0) /** @} */ #endif diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 079de4d..380413e 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -461,4 +461,13 @@ #define INTEGER_LEN 4U #endif /* MACSEC_KEY_PROGRAM */ +#ifdef HSI_SUPPORT +/* Set RX ISR set interrupt status bit */ +#define MACSEC_RX_ISR_SET 0x4050U +/* Set TX ISR set interrupt status bit */ +#define MACSEC_TX_ISR_SET 0x4010U +/* Set Common ISR set interrupt status bit */ +#define MACSEC_COMMON_ISR_SET 0xd05cU +#endif + #endif /* INCLUDED_MACSEC_H */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index e275c05..374fcb4 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -30,6 +30,7 @@ #include "mgbe_mmc.h" #include "vlan_filter.h" #include "core_common.h" +#include "macsec.h" /** * @brief mgbe_calculate_per_queue_fifo - Calculate per queue FIFO size @@ -2303,6 +2304,50 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, fail: return ret; } + +/** + * @brief mgbe_hsi_inject_err - Inject error + * + * Algorithm: Use error injection method to induce error + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] error_code: HSI Error code + * + */ +static void mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code) +{ + const nveu32_t val_ce = (MGBE_MTL_DEBUG_CONTROL_FDBGEN | + MGBE_MTL_DEBUG_CONTROL_DBGMOD | + MGBE_MTL_DEBUG_CONTROL_FIFORDEN | + MGBE_MTL_DEBUG_CONTROL_EIEE | + MGBE_MTL_DEBUG_CONTROL_EIEC); + + const nveu32_t val_ue = (MGBE_MTL_DEBUG_CONTROL_FDBGEN | + MGBE_MTL_DEBUG_CONTROL_DBGMOD | + MGBE_MTL_DEBUG_CONTROL_FIFORDEN | + MGBE_MTL_DEBUG_CONTROL_EIEE); + + switch (error_code) { + case OSI_HSI_MGBE0_CE_CODE: + case OSI_HSI_MGBE1_CE_CODE: + case OSI_HSI_MGBE2_CE_CODE: + case OSI_HSI_MGBE3_CE_CODE: + osi_writela(osi_core, val_ce, (nveu8_t *)osi_core->base + + MGBE_MTL_DEBUG_CONTROL); + break; + case OSI_HSI_MGBE0_UE_CODE: + case OSI_HSI_MGBE1_UE_CODE: + case OSI_HSI_MGBE2_UE_CODE: + case OSI_HSI_MGBE3_UE_CODE: + osi_writela(osi_core, val_ue, (nveu8_t *)osi_core->base + + MGBE_MTL_DEBUG_CONTROL); + break; + default: + hsi_common_error_inject(osi_core, error_code); + break; + } +} #endif /** @@ -4618,5 +4663,6 @@ void mgbe_init_core_ops(struct core_ops *ops) #endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT ops->core_hsi_configure = mgbe_hsi_configure; + ops->core_hsi_inject_err = mgbe_hsi_inject_err; #endif }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index abb4d83..bc13c9f 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -380,6 +380,14 @@ #define MGBE_REGISTER_PARITY_ERR OSI_BIT(5) #define MGBE_CORE_CORRECTABLE_ERR OSI_BIT(4) #define MGBE_CORE_UNCORRECTABLE_ERR OSI_BIT(3) + +#define MGBE_MTL_DEBUG_CONTROL 0x1008U +#define MGBE_MTL_DEBUG_CONTROL_FDBGEN OSI_BIT(0) +#define MGBE_MTL_DEBUG_CONTROL_DBGMOD OSI_BIT(1) +#define MGBE_MTL_DEBUG_CONTROL_FIFORDEN OSI_BIT(10) +#define MGBE_MTL_DEBUG_CONTROL_EIEE OSI_BIT(16) +#define MGBE_MTL_DEBUG_CONTROL_EIEC OSI_BIT(18) + #endif #define MGBE_MAC_SBD_INTR OSI_BIT(2) #define MGBE_WRAP_COMMON_INTR_STATUS 0x8708 diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 0f0fc94..17dd988 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -27,28 +27,25 @@ #ifdef HSI_SUPPORT /** - * @brief hsi_err_code - Arry of error code and reporter ID to be use by - * each Ethernet controller instance - * a condition is met or a timeout occurs - * Below is the data: - * uncorrectable_error_code, correctable_error_code, reporter ID - * hsi_err_code[0] to hsi_err_code[3] for MGBE instance - * hsi_err_code[4] is for EQOS + * @brief hsi_err_code - Array of error code */ nveu32_t hsi_err_code[][2] = { - {0x2A00, 0x2E08}, - {0x2A01, 0x2E09}, - {0x2A02, 0x2E0A}, - {0x2A03, 0x2E0B}, - {0x28AD, 0x2DE6}, + {OSI_HSI_MGBE0_UE_CODE, OSI_HSI_MGBE0_CE_CODE}, + {OSI_HSI_MGBE1_UE_CODE, OSI_HSI_MGBE1_CE_CODE}, + {OSI_HSI_MGBE2_UE_CODE, OSI_HSI_MGBE2_CE_CODE}, + {OSI_HSI_MGBE3_UE_CODE, OSI_HSI_MGBE3_CE_CODE}, + {OSI_HSI_EQOS0_UE_CODE, OSI_HSI_EQOS0_CE_CODE}, }; +/** + * @brief hsi_reporter_id - Array of reporter_id + */ nveu16_t hsi_reporter_id[] = { - 0x8019, - 0x801A, - 0x801B, - 0x801C, - 0x8009, + OSI_HSI_MGBE0_REPORTER_ID, + OSI_HSI_MGBE1_REPORTER_ID, + OSI_HSI_MGBE2_REPORTER_ID, + OSI_HSI_MGBE3_REPORTER_ID, + OSI_HSI_EQOS0_REPORTER_ID, }; #endif diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 1e43274..70fa45a 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2477,6 +2477,10 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_HSI_CONFIGURE: ret = ops_p->core_hsi_configure(osi_core, data->arg1_u32); break; + case OSI_CMD_HSI_INJECT_ERR: + ops_p->core_hsi_inject_err(osi_core, data->arg1_u32); + ret = 0; + break; #endif #ifdef OSI_DEBUG