Implement acl table entry write/read/delete operations by dtb channel. Signed-off-by: Bingbin Chen --- drivers/net/zxdh/zxdh_np.c | 915 ++++++++++++++++++++++++++++++++++++- drivers/net/zxdh/zxdh_np.h | 31 ++ 2 files changed, 945 insertions(+), 1 deletion(-) diff --git a/drivers/net/zxdh/zxdh_np.c b/drivers/net/zxdh/zxdh_np.c index 230a1d44be..9de3e2f406 100644 --- a/drivers/net/zxdh/zxdh_np.c +++ b/drivers/net/zxdh/zxdh_np.c @@ -678,6 +678,11 @@ zxdh_np_get_hash_entry_mask(uint32_t entry_size, uint32_t entry_pos) #define GET_ZCELL_CRC_VAL(zcell_id, crc16_val) \ (((crc16_val) >> (zcell_id)) & (ZXDH_SE_RAM_DEPTH - 1)) +#define ZXDH_COMM_DM_TO_X(d, m) ((d) & ~(m)) +#define ZXDH_COMM_DM_TO_Y(d, m) (~(d) & ~(m)) +#define ZXDH_COMM_XY_TO_MASK(x, y) (~(x) & ~(y)) +#define ZXDH_COMM_XY_TO_DATA(x, y) (x) + static uint32_t zxdh_np_comm_mutex_create(ZXDH_MUTEX_T *p_mutex) { @@ -4102,6 +4107,65 @@ zxdh_np_hash_soft_uninstall(uint32_t dev_id) return rc; } +static uint32_t +zxdh_np_acl_cfg_get(uint32_t dev_id, ZXDH_ACL_CFG_EX_T **p_acl_cfg) +{ + if (g_p_acl_ex_cfg[dev_id] == NULL) { + PMD_DRV_LOG(ERR, "%s fail, etcam_is not init!", __func__); + RTE_ASSERT(0); + return ZXDH_ACL_RC_ETCAMID_NOT_INIT; + } + + *p_acl_cfg = g_p_acl_ex_cfg[dev_id]; + + return ZXDH_OK; +} + +static uint32_t +zxdh_np_acl_res_destroy(uint32_t dev_id) +{ + uint32_t table_id = 0; + uint32_t as_enable = 0; + ZXDH_ACL_CFG_EX_T *p_acl_cfg = NULL; + ZXDH_ACL_TBL_CFG_T *p_tbl_cfg = NULL; + + zxdh_np_acl_cfg_get(dev_id, &p_acl_cfg); + + if (!p_acl_cfg->acl_etcamids.is_valid) { + PMD_DRV_LOG(DEBUG, "etcam is not init!"); + return ZXDH_OK; + } + + for (table_id = ZXDH_ACL_TBL_ID_MIN; table_id <= ZXDH_ACL_TBL_ID_MAX; table_id++) { + p_tbl_cfg = p_acl_cfg->acl_tbls + table_id; + if (!p_tbl_cfg->is_used) { + PMD_DRV_LOG(DEBUG, "table_id[ %d ] is not used!", table_id); + continue; + } + + zxdh_comm_rb_destroy(&p_tbl_cfg->acl_rb); + + as_enable = p_tbl_cfg->as_enable; + if (as_enable) { + if (p_tbl_cfg->as_rslt_buff) { + rte_free(p_tbl_cfg->as_rslt_buff); + p_tbl_cfg->as_rslt_buff = NULL; + } + } + + if (p_tbl_cfg->block_array) { + rte_free(p_tbl_cfg->block_array); + p_tbl_cfg->block_array = NULL; + } + + p_tbl_cfg->is_used = 0; + } + + p_acl_cfg->acl_etcamids.is_valid = 0; + + return ZXDH_OK; +} + int zxdh_np_online_uninit(uint32_t dev_id, char *port_name, @@ -4118,6 +4182,7 @@ zxdh_np_online_uninit(uint32_t dev_id, if (rc != ZXDH_OK) PMD_DRV_LOG(ERR, "zxdh_np_hash_soft_uninstall error! "); + zxdh_np_acl_res_destroy(dev_id); zxdh_np_dtb_mgr_destroy(dev_id); zxdh_np_sdt_mgr_destroy(dev_id); zxdh_np_dev_del(dev_id); @@ -4327,6 +4392,70 @@ zxdh_np_dtb_se_alg_zcam_data_write(uint32_t dev_id, return rc; } +static uint32_t +zxdh_np_dtb_etcam_write_entry_data(uint32_t dev_id, + uint32_t block_idx, + uint32_t row_or_col_msk, + uint32_t vben, + uint32_t reg_tcam_flag, + uint32_t flush, + uint32_t rd_wr, + uint32_t wr_mode, + uint32_t data_or_mask, + uint32_t ram_addr, + uint32_t vbit, + uint8_t *p_data, + ZXDH_DTB_ENTRY_T *p_entry) +{ + uint32_t rc = ZXDH_OK; + uint32_t i = 0; + uint32_t offset = 0; + uint8_t *p_temp = NULL; + + uint8_t buff[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + + ZXDH_DTB_ETCAM_TABLE_FORM_T dtb_etcam_form_info = {0}; + + dtb_etcam_form_info.valid = 1; + dtb_etcam_form_info.type_mode = ZXDH_DTB_TABLE_MODE_ETCAM; + dtb_etcam_form_info.block_sel = block_idx; + dtb_etcam_form_info.init_en = 0; + dtb_etcam_form_info.row_or_col_msk = row_or_col_msk; + dtb_etcam_form_info.vben = vben; + dtb_etcam_form_info.reg_tcam_flag = reg_tcam_flag; + dtb_etcam_form_info.uload = flush; + dtb_etcam_form_info.rd_wr = rd_wr; + dtb_etcam_form_info.wr_mode = wr_mode; + dtb_etcam_form_info.data_or_mask = data_or_mask; + dtb_etcam_form_info.addr = ram_addr; + dtb_etcam_form_info.vbit = vbit; + + p_entry->data_in_cmd_flag = 0; + p_entry->data_size = ZXDH_DTB_LEN_POS_SETP * (ZXDH_DTB_ETCAM_LEN_SIZE - 1); + + rc = zxdh_np_dtb_write_table_cmd(dev_id, ZXDH_DTB_TABLE_ETCAM, + &dtb_etcam_form_info, p_entry->cmd); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_write_table_cmd"); + + p_temp = p_data; + + for (i = 0; i < ZXDH_ETCAM_RAM_NUM; i++) { + offset = i * ((uint32_t)ZXDH_ETCAM_WIDTH_MIN / 8); + + if ((wr_mode >> (ZXDH_ETCAM_RAM_NUM - 1 - i)) & 0x1) { + rte_memcpy(buff + offset, p_temp, ZXDH_ETCAM_WIDTH_MIN / 8); + p_temp += ZXDH_ETCAM_WIDTH_MIN / 8; + } + } + + zxdh_np_comm_swap((uint8_t *)buff, ZXDH_DTB_LEN_POS_SETP * (ZXDH_DTB_ETCAM_LEN_SIZE - 1)); + + rte_memcpy(p_entry->data, buff, + ZXDH_DTB_LEN_POS_SETP * (ZXDH_DTB_ETCAM_LEN_SIZE - 1)); + + return rc; +} + static uint32_t zxdh_np_dtb_smmu0_dump_info_write(uint32_t dev_id, uint32_t base_addr, @@ -4385,6 +4514,35 @@ zxdh_np_dtb_zcam_dump_info_write(uint32_t dev_id, return rc; } +static uint32_t +zxdh_np_dtb_etcam_dump_info_write(uint32_t dev_id, + ZXDH_ETCAM_DUMP_INFO_T *p_etcam_dump_info, + uint32_t addr_high32, + uint32_t addr_low32, + uint32_t *p_dump_info) +{ + uint32_t rc = ZXDH_OK; + + ZXDH_DTB_ETCAM_DUMP_FORM_T dtb_etcam_dump_form_info = {0}; + + dtb_etcam_dump_form_info.valid = 1; + dtb_etcam_dump_form_info.up_type = ZXDH_DTB_DUMP_MODE_ETCAM; + dtb_etcam_dump_form_info.block_sel = p_etcam_dump_info->block_sel; + dtb_etcam_dump_form_info.addr = p_etcam_dump_info->addr; + dtb_etcam_dump_form_info.rd_mode = p_etcam_dump_info->rd_mode; + dtb_etcam_dump_form_info.data_or_mask = p_etcam_dump_info->data_or_mask; + dtb_etcam_dump_form_info.tb_depth = p_etcam_dump_info->tb_depth; + dtb_etcam_dump_form_info.tb_width = p_etcam_dump_info->tb_width; + dtb_etcam_dump_form_info.tb_dst_addr_h = addr_high32; + dtb_etcam_dump_form_info.tb_dst_addr_l = addr_low32; + + rc = zxdh_np_dtb_write_dump_cmd(dev_id, ZXDH_DTB_DUMP_ETCAM, + &dtb_etcam_dump_form_info, p_dump_info); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_write_dump_cmd"); + + return rc; +} + static void zxdh_np_dtb_zcam_dump_entry(uint32_t dev_id, uint32_t addr, @@ -4404,6 +4562,38 @@ zxdh_np_dtb_zcam_dump_entry(uint32_t dev_id, p_entry->data_in_cmd_flag = 1; } +static void +zxdh_np_dtb_smmu0_dump_entry(uint32_t dev_id, + uint32_t base_addr, + uint32_t depth, + uint32_t addr_high32, + uint32_t addr_low32, + ZXDH_DTB_ENTRY_T *p_entry) +{ + zxdh_np_dtb_smmu0_dump_info_write(dev_id, + base_addr, + depth, + addr_high32, + addr_low32, + (uint32_t *)p_entry->cmd); + p_entry->data_in_cmd_flag = 1; +} + +static void +zxdh_np_dtb_etcam_dump_entry(uint32_t dev_id, + ZXDH_ETCAM_DUMP_INFO_T *p_etcam_dump_info, + uint32_t addr_high32, + uint32_t addr_low32, + ZXDH_DTB_ENTRY_T *p_entry) +{ + zxdh_np_dtb_etcam_dump_info_write(dev_id, + p_etcam_dump_info, + addr_high32, + addr_low32, + (uint32_t *)p_entry->cmd); + p_entry->data_in_cmd_flag = 1; +} + static uint32_t zxdh_np_dtb_se_smmu0_ind_write(uint32_t dev_id, uint32_t base_addr, @@ -4412,7 +4602,7 @@ zxdh_np_dtb_se_smmu0_ind_write(uint32_t dev_id, uint32_t *p_data, ZXDH_DTB_ENTRY_T *p_entry) { - uint32_t temp_idx; + uint32_t temp_idx = 0; uint32_t dtb_ind_addr; uint32_t rc; @@ -5872,6 +6062,327 @@ zxdh_np_dtb_hash_one_entry(uint32_t dev_id, return rc; } +static void +zxdh_np_acl_hdw_addr_get(ZXDH_ACL_TBL_CFG_T *p_tbl_cfg, uint32_t handle, + uint32_t *p_block_idx, uint32_t *p_addr, uint32_t *p_wr_mask) +{ + uint32_t block_entry_num = 0; + uint32_t entry_pos = 0; + + block_entry_num = ZXDH_ACL_ENTRY_MAX_GET(p_tbl_cfg->key_mode, 1); + *p_block_idx = p_tbl_cfg->block_array[handle / block_entry_num]; + *p_addr = (handle % block_entry_num) / (1U << p_tbl_cfg->key_mode); + entry_pos = (handle % block_entry_num) % (1U << p_tbl_cfg->key_mode); + *p_wr_mask = (((1U << (8U >> (p_tbl_cfg->key_mode))) - 1) << + ((8U >> (p_tbl_cfg->key_mode)) * (entry_pos))) & 0xFF; +} + +static void +zxdh_np_etcam_dm_to_xy(ZXDH_ETCAM_ENTRY_T *p_dm, + ZXDH_ETCAM_ENTRY_T *p_xy, + uint32_t len) +{ + uint32_t i = 0; + + RTE_ASSERT(p_dm->p_data && p_dm->p_mask && p_xy->p_data && p_xy->p_mask); + + for (i = 0; i < len; i++) { + p_xy->p_data[i] = ZXDH_COMM_DM_TO_X(p_dm->p_data[i], p_dm->p_mask[i]); + p_xy->p_mask[i] = ZXDH_COMM_DM_TO_Y(p_dm->p_data[i], p_dm->p_mask[i]); + } +} + +static uint32_t +zxdh_np_eram_opr_mode_get(uint32_t as_mode) +{ + uint32_t opr_mode = 0; + + switch (as_mode) { + case ZXDH_ERAM128_TBL_128b: + { + opr_mode = ZXDH_ERAM128_OPR_128b; + break; + } + case ZXDH_ERAM128_TBL_64b: + { + opr_mode = ZXDH_ERAM128_OPR_64b; + break; + } + case ZXDH_ERAM128_TBL_1b: + { + opr_mode = ZXDH_ERAM128_OPR_1b; + break; + } + default: + { + break; + } + } + + return opr_mode; +} + +static uint32_t +zxdh_np_dtb_etcam_entry_add(uint32_t dev_id, + uint32_t addr, + uint32_t block_idx, + uint32_t wr_mask, + uint32_t opr_type, + ZXDH_ETCAM_ENTRY_T *p_entry, + ZXDH_DTB_ENTRY_T *p_entry_data, + ZXDH_DTB_ENTRY_T *p_entry_mask) +{ + uint32_t rc = ZXDH_OK; + uint8_t temp_data[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + uint8_t temp_mask[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + ZXDH_ETCAM_ENTRY_T entry_xy = {0}; + + RTE_ASSERT(p_entry->p_data && p_entry->p_mask); + + entry_xy.p_data = temp_data; + entry_xy.p_mask = temp_mask; + + if (opr_type == ZXDH_ETCAM_OPR_DM) { + zxdh_np_etcam_dm_to_xy(p_entry, &entry_xy, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry->mode)); + } else { + rte_memcpy(entry_xy.p_data, p_entry->p_data, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry->mode)); + rte_memcpy(entry_xy.p_mask, p_entry->p_mask, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry->mode)); + } + + rc = zxdh_np_dtb_etcam_write_entry_data(dev_id, block_idx, 0, 1, 0, 0, 0, + wr_mask, ZXDH_ETCAM_DTYPE_DATA, addr, 0, entry_xy.p_data, p_entry_data); + + rc = zxdh_np_dtb_etcam_write_entry_data(dev_id, block_idx, 0, 1, 0, 0, 0, + wr_mask, ZXDH_ETCAM_DTYPE_MASK, addr, 0xFF, entry_xy.p_mask, p_entry_mask); + + return rc; +} + +static uint32_t +zxdh_np_dtb_acl_delete(uint32_t dev_id, + uint32_t sdt_no, + ZXDH_ACL_ENTRY_EX_T *p_acl_entry, + ZXDH_DTB_ENTRY_T *p_dtb_data_entry, + ZXDH_DTB_ENTRY_T *p_dtb_mask_entry, + ZXDH_DTB_ENTRY_T *p_dtb_as_entry) +{ + uint32_t rc = ZXDH_OK; + uint32_t as_eram_baddr = 0; + uint32_t as_enable = 0; + uint32_t etcam_table_id = 0; + uint32_t etcam_as_mode = 0; + uint32_t opr_mode = 0; + uint32_t block_idx = 0; + uint32_t ram_addr = 0; + uint32_t etcam_wr_mask = 0; + uint8_t temp_data[ZXDH_ETCAM_WIDTH_MAX / 8]; + uint8_t temp_mask[ZXDH_ETCAM_WIDTH_MAX / 8]; + uint8_t temp_buf[16] = {0}; + + ZXDH_SDT_TBL_ETCAM_T sdt_acl = {0}; + ZXDH_ACL_CFG_EX_T *p_acl_cfg = NULL; + ZXDH_ACL_TBL_CFG_T *p_tbl_cfg = NULL; + ZXDH_ETCAM_ENTRY_T etcam_entry = {0}; + + rc = zxdh_np_soft_sdt_tbl_get(dev_id, sdt_no, &sdt_acl); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_soft_sdt_tbl_get"); + + etcam_as_mode = sdt_acl.as_rsp_mode; + etcam_table_id = sdt_acl.etcam_table_id; + as_enable = sdt_acl.as_en; + as_eram_baddr = sdt_acl.as_eram_baddr; + + zxdh_np_acl_cfg_get(dev_id, &p_acl_cfg); + + p_tbl_cfg = p_acl_cfg->acl_tbls + etcam_table_id; + if (!p_tbl_cfg->is_used) { + PMD_DRV_LOG(ERR, "table[ %d ] is not init!", etcam_table_id); + RTE_ASSERT(0); + return ZXDH_ACL_RC_TBL_NOT_INIT; + } + + zxdh_np_acl_hdw_addr_get(p_tbl_cfg, p_acl_entry->pri, + &block_idx, &ram_addr, &etcam_wr_mask); + + memset(temp_data, 0xff, ZXDH_ETCAM_WIDTH_MAX / 8); + memset(temp_mask, 0, ZXDH_ETCAM_WIDTH_MAX / 8); + etcam_entry.mode = p_tbl_cfg->key_mode; + etcam_entry.p_data = temp_data; + etcam_entry.p_mask = temp_mask; + rc = zxdh_np_dtb_etcam_entry_add(dev_id, + ram_addr, + block_idx, + etcam_wr_mask, + ZXDH_ETCAM_OPR_DM, + &etcam_entry, + p_dtb_data_entry, + p_dtb_mask_entry); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_etcam_entry_add"); + + if (as_enable) { + memset(temp_buf, 0, sizeof(temp_buf)); + opr_mode = zxdh_np_eram_opr_mode_get(etcam_as_mode); + rc = zxdh_np_dtb_se_smmu0_ind_write(dev_id, + as_eram_baddr, + p_acl_entry->pri, + opr_mode, + (uint32_t *)temp_buf, + p_dtb_as_entry); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_se_smmu0_ind_write"); + } + + return rc; +} + +static uint32_t +zxdh_np_dtb_acl_insert(uint32_t dev_id, + uint32_t sdt_no, + ZXDH_ACL_ENTRY_EX_T *p_acl_entry, + ZXDH_DTB_ENTRY_T *p_dtb_data_entry, + ZXDH_DTB_ENTRY_T *p_dtb_mask_entry, + ZXDH_DTB_ENTRY_T *p_dtb_as_entry) +{ + uint32_t rc = ZXDH_OK; + uint32_t as_eram_baddr = 0; + uint32_t as_enable = 0; + uint32_t etcam_table_id = 0; + uint32_t etcam_as_mode = 0; + uint32_t opr_mode = 0; + uint32_t block_idx = 0; + uint32_t ram_addr = 0; + uint32_t etcam_wr_mask = 0; + + ZXDH_SDT_TBL_ETCAM_T sdt_acl = {0}; + ZXDH_ACL_CFG_EX_T *p_acl_cfg = NULL; + ZXDH_ACL_TBL_CFG_T *p_tbl_cfg = NULL; + ZXDH_ETCAM_ENTRY_T etcam_entry = {0}; + + rc = zxdh_np_soft_sdt_tbl_get(dev_id, sdt_no, &sdt_acl); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_soft_sdt_tbl_get"); + + etcam_as_mode = sdt_acl.as_rsp_mode; + etcam_table_id = sdt_acl.etcam_table_id; + as_enable = sdt_acl.as_en; + as_eram_baddr = sdt_acl.as_eram_baddr; + + zxdh_np_acl_cfg_get(dev_id, &p_acl_cfg); + + p_tbl_cfg = p_acl_cfg->acl_tbls + etcam_table_id; + if (!p_tbl_cfg->is_used) { + PMD_DRV_LOG(ERR, "table[ %d ] is not init!", etcam_table_id); + RTE_ASSERT(0); + return ZXDH_ACL_RC_TBL_NOT_INIT; + } + + zxdh_np_acl_hdw_addr_get(p_tbl_cfg, p_acl_entry->pri, + &block_idx, &ram_addr, &etcam_wr_mask); + + etcam_entry.mode = p_tbl_cfg->key_mode; + etcam_entry.p_data = p_acl_entry->key_data; + etcam_entry.p_mask = p_acl_entry->key_mask; + + rc = zxdh_np_dtb_etcam_entry_add(dev_id, + ram_addr, + block_idx, + etcam_wr_mask, + ZXDH_ETCAM_OPR_DM, + &etcam_entry, + p_dtb_data_entry, + p_dtb_mask_entry); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_etcam_entry_add"); + + if (as_enable) { + opr_mode = zxdh_np_eram_opr_mode_get(etcam_as_mode); + rc = zxdh_np_dtb_se_smmu0_ind_write(dev_id, + as_eram_baddr, + p_acl_entry->pri, + opr_mode, + (uint32_t *)p_acl_entry->p_as_rslt, + p_dtb_as_entry); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_se_smmu0_ind_write"); + } + + return rc; +} + +static uint32_t +zxdh_np_dtb_acl_one_entry(uint32_t dev_id, + uint32_t sdt_no, + uint32_t del_en, + void *p_data, + uint32_t *p_dtb_len, + uint8_t *p_data_buff) +{ + uint32_t rc = ZXDH_OK; + uint32_t addr_offset = 0; + ZXDH_ACL_ENTRY_EX_T acl_entry = {0}; + ZXDH_DTB_ACL_ENTRY_INFO_T *p_entry = NULL; + + uint8_t data_buff[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + uint8_t mask_buff[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + uint8_t data_cmd_buff[ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8] = {0}; + uint8_t mask_cmd_buff[ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8] = {0}; + uint8_t as_cmd_buff[ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8] = {0}; + uint32_t as_data_buff[4] = {0}; + + ZXDH_DTB_ENTRY_T dtb_data_entry = {0}; + ZXDH_DTB_ENTRY_T dtb_mask_entry = {0}; + ZXDH_DTB_ENTRY_T dtb_as_entry = {0}; + + dtb_data_entry.cmd = data_cmd_buff; + dtb_data_entry.data = data_buff; + dtb_mask_entry.cmd = mask_cmd_buff; + dtb_mask_entry.data = mask_buff; + dtb_as_entry.cmd = as_cmd_buff; + dtb_as_entry.data = (uint8_t *)as_data_buff; + + p_entry = (ZXDH_DTB_ACL_ENTRY_INFO_T *)p_data; + acl_entry.pri = p_entry->handle; + acl_entry.key_data = p_entry->key_data; + acl_entry.key_mask = p_entry->key_mask; + acl_entry.p_as_rslt = p_entry->p_as_rslt; + if (del_en) { + rc = zxdh_np_dtb_acl_delete(dev_id, + sdt_no, + &acl_entry, + &dtb_data_entry, + &dtb_mask_entry, + &dtb_as_entry); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_acl_delete"); + } else { + rc = zxdh_np_dtb_acl_insert(dev_id, + sdt_no, + &acl_entry, + &dtb_data_entry, + &dtb_mask_entry, + &dtb_as_entry); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_acl_insert"); + } + + addr_offset = (*p_dtb_len) * ZXDH_DTB_LEN_POS_SETP; + *p_dtb_len += ZXDH_DTB_ETCAM_LEN_SIZE; + + rc = zxdh_np_dtb_data_write(p_data_buff, addr_offset, &dtb_data_entry); + + addr_offset = (*p_dtb_len) * ZXDH_DTB_LEN_POS_SETP; + *p_dtb_len += ZXDH_DTB_ETCAM_LEN_SIZE; + + rc = zxdh_np_dtb_data_write(p_data_buff, addr_offset, &dtb_mask_entry); + + addr_offset = (*p_dtb_len) * ZXDH_DTB_LEN_POS_SETP; + if (dtb_as_entry.data_in_cmd_flag) + *p_dtb_len += 1; + else + *p_dtb_len += 2; + + rc = zxdh_np_dtb_data_write(p_data_buff, addr_offset, &dtb_as_entry); + + return ZXDH_OK; +} + int zxdh_np_dtb_table_entry_write(uint32_t dev_id, uint32_t queue_id, @@ -5918,6 +6429,12 @@ zxdh_np_dtb_table_entry_write(uint32_t dev_id, pentry->p_entry_data, &one_dtb_len, &dtb_one_entry); break; } + case ZXDH_SDT_TBLT_ETCAM: + { + rc = zxdh_np_dtb_acl_one_entry(dev_id, sdt_no, ZXDH_DTB_ITEM_ADD_OR_UPDATE, + pentry->p_entry_data, &dtb_len, p_data_buff); + continue; + } default: { PMD_DRV_LOG(ERR, "SDT table_type[ %d ] is invalid!", tbl_type); @@ -7031,6 +7548,393 @@ zxdh_np_dtb_hash_data_get(uint32_t dev_id, return rc; } +static void +dtb_etcam_dump_data_len(uint32_t etcam_key_mode, + uint32_t *p_etcam_dump_len, + uint32_t *p_etcam_dump_inerval) +{ + uint32_t dump_data_len = 0; + uint8_t etcam_dump_inerval = 0; + + if (ZXDH_ETCAM_KEY_640b == etcam_key_mode) { + dump_data_len = 5 * ZXDH_DTB_LEN_POS_SETP; + etcam_dump_inerval = 0; + } else if (ZXDH_ETCAM_KEY_320b == etcam_key_mode) { + dump_data_len = 3 * ZXDH_DTB_LEN_POS_SETP; + etcam_dump_inerval = 8; + } else if (ZXDH_ETCAM_KEY_160b == etcam_key_mode) { + dump_data_len = 2 * ZXDH_DTB_LEN_POS_SETP; + etcam_dump_inerval = 12; + } else if (ZXDH_ETCAM_KEY_80b == etcam_key_mode) { + dump_data_len = 1 * ZXDH_DTB_LEN_POS_SETP; + etcam_dump_inerval = 6; + } + + *p_etcam_dump_len = dump_data_len; + *p_etcam_dump_inerval = etcam_dump_inerval; +} + +static void +zxdh_np_dtb_get_etcam_xy_from_dump_data(uint8_t *p_data, + uint8_t *p_mask, + uint32_t etcam_dump_len, + uint32_t etcam_dump_inerval, + ZXDH_ETCAM_ENTRY_T *p_entry_xy) +{ + uint8_t *p_entry_data = NULL; + uint8_t *p_entry_mask = NULL; + + zxdh_np_comm_swap(p_data, etcam_dump_len); + zxdh_np_comm_swap(p_mask, etcam_dump_len); + + p_entry_data = p_data + etcam_dump_inerval; + p_entry_mask = p_mask + etcam_dump_inerval; + + rte_memcpy(p_entry_xy->p_data, p_entry_data, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry_xy->mode)); + rte_memcpy(p_entry_xy->p_mask, p_entry_mask, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry_xy->mode)); +} + + +static void +zxdh_np_etcam_xy_to_dm(ZXDH_ETCAM_ENTRY_T *p_dm, + ZXDH_ETCAM_ENTRY_T *p_xy, + uint32_t len) +{ + uint32_t i = 0; + + RTE_ASSERT(p_dm->p_data && p_dm->p_mask && p_xy->p_data && p_xy->p_mask); + + for (i = 0; i < len; i++) { + p_dm->p_data[i] = ZXDH_COMM_XY_TO_DATA(p_xy->p_data[i], p_xy->p_mask[i]); + p_dm->p_mask[i] = ZXDH_COMM_XY_TO_MASK(p_xy->p_data[i], p_xy->p_mask[i]); + } +} + +static uint32_t +zxdh_np_dtb_etcam_entry_get(uint32_t dev_id, + uint32_t queue_id, + uint32_t block_idx, + uint32_t addr, + uint32_t rd_mode, + uint32_t opr_type, + uint32_t as_en, + uint32_t as_eram_baddr, + uint32_t as_eram_index, + uint32_t as_rsp_mode, + ZXDH_ETCAM_ENTRY_T *p_entry, + uint8_t *p_as_rslt) +{ + uint32_t rc = ZXDH_OK; + + uint32_t etcam_key_mode = 0; + + uint8_t temp_data[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + uint8_t temp_mask[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + ZXDH_ETCAM_ENTRY_T entry_xy = {0}; + + uint32_t etcam_data_dst_phy_haddr = 0; + uint32_t etcam_data_dst_phy_laddr = 0; + uint32_t etcam_mask_dst_phy_haddr = 0; + uint32_t etcam_mask_dst_phy_laddr = 0; + uint32_t as_rst_dst_phy_haddr = 0; + uint32_t as_rst_dst_phy_laddr = 0; + + uint32_t dump_element_id = 0; + uint32_t etcam_dump_one_data_len = 0; + uint32_t etcam_dump_inerval = 0; + uint32_t dtb_desc_addr_offset = 0; + uint32_t dump_data_len = 0; + uint32_t dtb_desc_len = 0; + + uint32_t eram_dump_base_addr = 0; + uint32_t row_index = 0; + uint32_t col_index = 0; + + uint8_t *p_data = NULL; + uint8_t *p_mask = NULL; + uint8_t *p_rst = NULL; + uint8_t *temp_dump_out_data = NULL; + uint8_t *dump_info_buff = NULL; + ZXDH_ETCAM_DUMP_INFO_T etcam_dump_info = {0}; + ZXDH_DTB_ENTRY_T dtb_dump_entry = {0}; + uint8_t cmd_buff[ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8] = {0}; + + dtb_dump_entry.cmd = cmd_buff; + + entry_xy.p_data = temp_data; + entry_xy.p_mask = temp_mask; + + etcam_key_mode = p_entry->mode; + + etcam_dump_info.block_sel = block_idx; + etcam_dump_info.addr = addr; + etcam_dump_info.tb_width = 3 - etcam_key_mode; + etcam_dump_info.rd_mode = rd_mode; + etcam_dump_info.tb_depth = 1; + + rc = zxdh_np_dtb_tab_up_free_item_get(dev_id, queue_id, &dump_element_id); + if (rc != ZXDH_OK) { + PMD_DRV_LOG(ERR, "zxdh_np_dtb_tab_up_free_item_get failed!"); + return ZXDH_RC_DTB_QUEUE_ITEM_SW_EMPTY; + } + + dtb_etcam_dump_data_len(etcam_key_mode, &etcam_dump_one_data_len, &etcam_dump_inerval); + + etcam_dump_info.data_or_mask = ZXDH_ETCAM_DTYPE_DATA; + zxdh_np_dtb_tab_up_item_offset_addr_get(dev_id, + queue_id, + dump_element_id, + dump_data_len, + &etcam_data_dst_phy_haddr, + &etcam_data_dst_phy_laddr); + + zxdh_np_dtb_etcam_dump_entry(dev_id, + &etcam_dump_info, + etcam_data_dst_phy_haddr, + etcam_data_dst_phy_laddr, + &dtb_dump_entry); + + dump_info_buff = (uint8_t *)rte_zmalloc(NULL, ZXDH_DTB_TABLE_DUMP_INFO_BUFF_SIZE, 0); + if (dump_info_buff == NULL) { + PMD_DRV_LOG(ERR, "%s point null!", __func__); + return ZXDH_PAR_CHK_POINT_NULL; + } + + zxdh_np_dtb_data_write(dump_info_buff, dtb_desc_addr_offset, &dtb_dump_entry); + memset(cmd_buff, 0, ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8); + dtb_desc_len += 1; + dtb_desc_addr_offset += ZXDH_DTB_LEN_POS_SETP; + dump_data_len += etcam_dump_one_data_len; + + etcam_dump_info.data_or_mask = ZXDH_ETCAM_DTYPE_MASK; + zxdh_np_dtb_tab_up_item_offset_addr_get(dev_id, + queue_id, + dump_element_id, + dump_data_len, + &etcam_mask_dst_phy_haddr, + &etcam_mask_dst_phy_laddr); + + zxdh_np_dtb_etcam_dump_entry(dev_id, + &etcam_dump_info, + etcam_mask_dst_phy_haddr, + etcam_mask_dst_phy_laddr, + &dtb_dump_entry); + zxdh_np_dtb_data_write(dump_info_buff, dtb_desc_addr_offset, &dtb_dump_entry); + memset(cmd_buff, 0, ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8); + dtb_desc_len += 1; + dtb_desc_addr_offset += ZXDH_DTB_LEN_POS_SETP; + dump_data_len += etcam_dump_one_data_len; + + if (as_en) { + zxdh_np_eram_index_cal(as_rsp_mode, as_eram_index, &row_index, &col_index); + + eram_dump_base_addr = as_eram_baddr + row_index; + zxdh_np_dtb_tab_up_item_offset_addr_get(dev_id, + queue_id, + dump_element_id, + dump_data_len, + &as_rst_dst_phy_haddr, + &as_rst_dst_phy_laddr); + + zxdh_np_dtb_smmu0_dump_entry(dev_id, + eram_dump_base_addr, + 1, + as_rst_dst_phy_haddr, + as_rst_dst_phy_laddr, + &dtb_dump_entry); + zxdh_np_dtb_data_write(dump_info_buff, dtb_desc_addr_offset, &dtb_dump_entry); + memset(cmd_buff, 0, ZXDH_DTB_TABLE_CMD_SIZE_BIT / 8); + dtb_desc_len += 1; + dtb_desc_addr_offset += ZXDH_DTB_LEN_POS_SETP; + dump_data_len += ZXDH_DTB_LEN_POS_SETP; + } + + temp_dump_out_data = (uint8_t *)rte_zmalloc(NULL, dump_data_len, 0); + if (temp_dump_out_data == NULL) { + PMD_DRV_LOG(ERR, "%s point null!", __func__); + rte_free(dump_info_buff); + return ZXDH_PAR_CHK_POINT_NULL; + } + p_data = temp_dump_out_data; + + rc = zxdh_np_dtb_write_dump_desc_info(dev_id, + queue_id, + dump_element_id, + (uint32_t *)dump_info_buff, + dump_data_len / 4, + dtb_desc_len * 4, + (uint32_t *)temp_dump_out_data); + + p_data = temp_dump_out_data; + p_mask = p_data + etcam_dump_one_data_len; + + zxdh_np_dtb_get_etcam_xy_from_dump_data(p_data, + p_mask, + etcam_dump_one_data_len, + etcam_dump_inerval, + &entry_xy); + + if (opr_type == ZXDH_ETCAM_OPR_DM) { + zxdh_np_etcam_xy_to_dm(p_entry, &entry_xy, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry->mode)); + } else { + rte_memcpy(p_entry->p_data, entry_xy.p_data, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry->mode)); + rte_memcpy(p_entry->p_mask, entry_xy.p_mask, + ZXDH_ETCAM_ENTRY_SIZE_GET(p_entry->mode)); + } + + if (as_en) { + p_rst = p_mask + etcam_dump_one_data_len; + rte_memcpy(p_as_rslt, p_rst, (128 / 8)); + } + + rte_free(dump_info_buff); + rte_free(temp_dump_out_data); + + return rc; +} + +static uint32_t +zxdh_np_etcam_entry_cmp(ZXDH_ETCAM_ENTRY_T *p_entry_dm, ZXDH_ETCAM_ENTRY_T *p_entry_xy) +{ + uint32_t data_mask_len = 0; + uint8_t temp_data[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + uint8_t temp_mask[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + ZXDH_ETCAM_ENTRY_T entry_xy_temp = {0}; + + entry_xy_temp.mode = p_entry_dm->mode; + entry_xy_temp.p_data = temp_data; + entry_xy_temp.p_mask = temp_mask; + + data_mask_len = ZXDH_ETCAM_ENTRY_SIZE_GET(entry_xy_temp.mode); + + zxdh_np_etcam_dm_to_xy(p_entry_dm, &entry_xy_temp, data_mask_len); + + if ((memcmp(entry_xy_temp.p_data, p_entry_xy->p_data, data_mask_len) != 0) || + (memcmp(entry_xy_temp.p_mask, p_entry_xy->p_mask, data_mask_len) != 0)) { + return ZXDH_ERR; + } + + return ZXDH_OK; +} + +static uint32_t +zxdh_np_dtb_acl_data_get(uint32_t dev_id, + uint32_t queue_id, + uint32_t sdt_no, + ZXDH_DTB_ACL_ENTRY_INFO_T *p_dump_acl_entry) +{ + uint32_t rc = ZXDH_OK; + uint32_t block_idx = 0; + uint32_t ram_addr = 0; + uint32_t etcam_wr_mode = 0; + uint32_t etcam_key_mode = 0; + uint32_t etcam_table_id = 0; + uint32_t as_enable = 0; + uint32_t as_eram_baddr = 0; + uint32_t etcam_as_mode = 0; + uint32_t row_index = 0; + uint32_t col_index = 0; + + ZXDH_ETCAM_ENTRY_T etcam_entry_dm = {0}; + ZXDH_ETCAM_ENTRY_T etcam_entry_xy = {0}; + uint32_t as_eram_data[4] = {0}; + uint8_t temp_data[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + uint8_t temp_mask[ZXDH_ETCAM_WIDTH_MAX / 8] = {0}; + + ZXDH_ACL_CFG_EX_T *p_acl_cfg = NULL; + ZXDH_ACL_TBL_CFG_T *p_tbl_cfg = NULL; + + ZXDH_SDT_TBL_ETCAM_T sdt_etcam_info = {0}; + + rc = zxdh_np_soft_sdt_tbl_get(dev_id, sdt_no, &sdt_etcam_info); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_soft_sdt_tbl_get"); + etcam_key_mode = sdt_etcam_info.etcam_key_mode; + etcam_as_mode = sdt_etcam_info.as_rsp_mode; + etcam_table_id = sdt_etcam_info.etcam_table_id; + as_enable = sdt_etcam_info.as_en; + as_eram_baddr = sdt_etcam_info.as_eram_baddr; + + etcam_entry_xy.mode = etcam_key_mode; + etcam_entry_xy.p_data = temp_data; + etcam_entry_xy.p_mask = temp_mask; + etcam_entry_dm.mode = etcam_key_mode; + etcam_entry_dm.p_data = p_dump_acl_entry->key_data; + etcam_entry_dm.p_mask = p_dump_acl_entry->key_mask; + + zxdh_np_acl_cfg_get(dev_id, &p_acl_cfg); + + p_tbl_cfg = p_acl_cfg->acl_tbls + etcam_table_id; + + if (!p_tbl_cfg->is_used) { + PMD_DRV_LOG(ERR, "table[ %d ] is not init!", etcam_table_id); + RTE_ASSERT(0); + return ZXDH_ACL_RC_TBL_NOT_INIT; + } + + zxdh_np_acl_hdw_addr_get(p_tbl_cfg, p_dump_acl_entry->handle, + &block_idx, &ram_addr, &etcam_wr_mode); + + rc = zxdh_np_dtb_etcam_entry_get(dev_id, + queue_id, + block_idx, + ram_addr, + etcam_wr_mode, + ZXDH_ETCAM_OPR_XY, + as_enable, + as_eram_baddr, + p_dump_acl_entry->handle, + etcam_as_mode, + &etcam_entry_xy, + (uint8_t *)as_eram_data); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_etcam_entry_get"); + + if (zxdh_np_etcam_entry_cmp(&etcam_entry_dm, &etcam_entry_xy) == 0) { + PMD_DRV_LOG(DEBUG, "Acl table[ %d ] search in hardware success: handle[ 0x%x ]," + "block[ %d ], ram_addr[ %d ], rd_mode[ %x ].", + p_tbl_cfg->table_id, p_dump_acl_entry->handle, block_idx, + ram_addr, etcam_wr_mode); + } else { + PMD_DRV_LOG(DEBUG, "Acl table[ %d ] search in hardware fail: handle[ 0x%x ]," + "block[ %d ], ram_addr[ %d ], rd_mode[ %x ].", + p_tbl_cfg->table_id, p_dump_acl_entry->handle, block_idx, + ram_addr, etcam_wr_mode); + + return ZXDH_ERR; + } + + if (as_enable) { + zxdh_np_eram_index_cal(etcam_as_mode, p_dump_acl_entry->handle, + &row_index, &col_index); + switch (etcam_as_mode) { + case ZXDH_ERAM128_TBL_128b: + { + rte_memcpy(p_dump_acl_entry->p_as_rslt, as_eram_data, (128 / 8)); + break; + } + + case ZXDH_ERAM128_TBL_64b: + { + rte_memcpy(p_dump_acl_entry->p_as_rslt, as_eram_data + + ((1 - col_index) << 1), (64 / 8)); + break; + } + + case ZXDH_ERAM128_TBL_1b: + { + ZXDH_COMM_UINT32_GET_BITS(*(uint32_t *)p_dump_acl_entry->p_as_rslt, + *(as_eram_data + (3 - col_index / 32)), (col_index % 32), 1); + break; + } + } + } + + return rc; +} + int zxdh_np_dtb_table_entry_get(uint32_t dev_id, uint32_t queue_id, @@ -7081,6 +7985,15 @@ zxdh_np_dtb_table_entry_get(uint32_t dev_id, ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_hash_data_get"); break; } + case ZXDH_SDT_TBLT_ETCAM: + { + rc = zxdh_np_dtb_acl_data_get(dev_id, + queue_id, + sdt_no, + (ZXDH_DTB_ACL_ENTRY_INFO_T *)get_entry->p_entry_data); + ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_dtb_acl_data_get"); + break; + } default: { PMD_DRV_LOG(ERR, "SDT table_type[ %d ] is invalid!", tbl_type); diff --git a/drivers/net/zxdh/zxdh_np.h b/drivers/net/zxdh/zxdh_np.h index 2ba9554684..08a9b3c3a6 100644 --- a/drivers/net/zxdh/zxdh_np.h +++ b/drivers/net/zxdh/zxdh_np.h @@ -1295,6 +1295,24 @@ typedef enum zxdh_dtb_dump_zcam_width_e { ZXDH_DTB_DUMP_ZCAM_RSV = 3, } ZXDH_DTB_DUMP_ZCAM_WIDTH_E; +typedef enum zxdh_etcam_opr_type_e { + ZXDH_ETCAM_OPR_DM = 0, + ZXDH_ETCAM_OPR_XY = 1, +} ZXDH_ETCAM_OPR_TYPE_E; + +typedef enum zxdh_etcam_data_type_e { + ZXDH_ETCAM_DTYPE_MASK = 0, + ZXDH_ETCAM_DTYPE_DATA = 1, +} ZXDH_ETCAM_DATA_TYPE_E; + +typedef enum zxdh_etcam_entry_mode_e { + ZXDH_ETCAM_KEY_640b = 0, + ZXDH_ETCAM_KEY_320b = 1, + ZXDH_ETCAM_KEY_160b = 2, + ZXDH_ETCAM_KEY_80b = 3, + ZXDH_ETCAM_KEY_INVALID, +} ZXDH_ETCAM_ENTRY_MODE_E; + typedef struct zxdh_dtb_lpm_entry_t { uint32_t dtb_len0; uint8_t *p_data_buff0; @@ -1309,6 +1327,19 @@ typedef struct zxdh_dtb_entry_t { uint32_t data_size; } ZXDH_DTB_ENTRY_T; +typedef struct zxdh_etcam_entry_t { + uint32_t mode; + uint8_t *p_data; + uint8_t *p_mask; +} ZXDH_ETCAM_ENTRY_T; + +typedef struct zxdh_dtb_acl_entry_info_t { + uint32_t handle; + uint8_t *key_data; + uint8_t *key_mask; + uint8_t *p_as_rslt; +} ZXDH_DTB_ACL_ENTRY_INFO_T; + typedef struct zxdh_dtb_eram_table_form_t { uint32_t valid; uint32_t type_mode; -- 2.27.0