From patchwork Thu Jun 1 19:55:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 127878 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BFF0042C07; Thu, 1 Jun 2023 21:56:19 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A56D942D40; Thu, 1 Jun 2023 21:55:47 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 848B24282D for ; Thu, 1 Jun 2023 21:55:43 +0200 (CEST) Received: from localhost.localdomain (unknown [78.109.69.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id E97B1E12CB; Thu, 1 Jun 2023 23:55:42 +0400 (+04) From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Ferruh Yigit , Denis Pryazhennikov , Viacheslav Galaktionov , Andy Moreton Subject: [PATCH 05/34] common/sfc_efx/base: add API to get HW table desc Date: Thu, 1 Jun 2023 23:55:09 +0400 Message-Id: <20230601195538.8265-6-ivan.malov@arknetworks.am> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230601195538.8265-1-ivan.malov@arknetworks.am> References: <20230601195538.8265-1-ivan.malov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Denis Pryazhennikov Table's descriptor and fields' descriptors can be taken by table ID using a new API. In the near future, only the CT table is planned to be used, so only fields that are required for these purposes were added to the efx. Signed-off-by: Denis Pryazhennikov Reviewed-by: Viacheslav Galaktionov Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 67 +++++++ drivers/common/sfc_efx/base/efx_table.c | 256 ++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 3 + 3 files changed, 326 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index ac6b58b2a4..cf157e17d6 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -5099,6 +5099,73 @@ efx_table_list( __in unsigned int n_table_ids, __out_opt unsigned int *n_table_ids_writtenp); +LIBEFX_API +extern __checkReturn size_t +efx_table_supported_num_get( + __in void); + +LIBEFX_API +extern __checkReturn boolean_t +efx_table_is_supported( + __in efx_table_id_t table_id); + +/* Unique IDs for table fields */ +typedef enum efx_table_field_id_e { + EFX_TABLE_FIELD_ID_UNUSED = 0x0, + EFX_TABLE_FIELD_ID_COUNTER_ID = 0xa, + EFX_TABLE_FIELD_ID_ETHER_TYPE = 0x1c, + EFX_TABLE_FIELD_ID_SRC_IP = 0x1d, + EFX_TABLE_FIELD_ID_DST_IP = 0x1e, + EFX_TABLE_FIELD_ID_IP_PROTO = 0x20, + EFX_TABLE_FIELD_ID_SRC_PORT = 0x21, + EFX_TABLE_FIELD_ID_DST_PORT = 0x22, + EFX_TABLE_FIELD_ID_NAT_PORT = 0x7a, + EFX_TABLE_FIELD_ID_NAT_IP = 0x7b, + EFX_TABLE_FIELD_ID_NAT_DIR = 0x7c, + EFX_TABLE_FIELD_ID_CT_MARK = 0x7d, +} efx_table_field_id_t; + +/* Table fields mask types */ +typedef enum efx_table_field_mask_type_e { + EFX_TABLE_FIELD_MASK_NEVER = 0x0, + EFX_TABLE_FIELD_MASK_EXACT = 0x1, +} efx_table_field_mask_type_t; + +typedef struct efx_table_field_desc_s { + efx_table_field_id_t field_id; + uint16_t lbn; + uint16_t width; + efx_table_field_mask_type_t mask_type; + uint8_t scheme; +} efx_table_field_descriptor_t; + +/* Types of HW tables */ +typedef enum efx_table_type_e { + /* Exact match to all key fields of table entry. */ + EFX_TABLE_TYPE_BCAM = 0x2, +} efx_table_type_t; + +typedef struct efx_table_descriptor_s { + efx_table_type_t type; + uint16_t key_width; + uint16_t resp_width; + /* Number of key's fields to match data */ + uint16_t n_key_fields; + /* Number of fields in match response */ + uint16_t n_resp_fields; +} efx_table_descriptor_t; + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_table_describe( + __in efx_nic_t *enp, + __in efx_table_id_t table_id, + __in uint32_t field_offset, + __out_opt efx_table_descriptor_t *table_descp, + __out_ecount_opt(*n_fields_descsp) efx_table_field_descriptor_t *fields_descs, + __in unsigned int n_field_descs, + __out_opt unsigned int *n_field_descs_writtenp); + #ifdef __cplusplus } #endif diff --git a/drivers/common/sfc_efx/base/efx_table.c b/drivers/common/sfc_efx/base/efx_table.c index 7cfdfea36e..115d86502f 100644 --- a/drivers/common/sfc_efx/base/efx_table.c +++ b/drivers/common/sfc_efx/base/efx_table.c @@ -6,6 +6,11 @@ #include "efx.h" #include "efx_impl.h" +/* List of HW tables that have support in efx */ +static const efx_table_id_t efx_supported_table_ids[] = { + EFX_TABLE_ID_CONNTRACK, +}; + __checkReturn efx_rc_t efx_table_list( __in efx_nic_t *enp, @@ -80,6 +85,257 @@ efx_table_list( return (0); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn size_t +efx_table_supported_num_get( + __in void) +{ + return EFX_ARRAY_SIZE(efx_supported_table_ids); +} + + __checkReturn boolean_t +efx_table_is_supported( + __in efx_table_id_t table_id) +{ + size_t i; + + for (i = 0; i < efx_table_supported_num_get(); i++) { + if (efx_supported_table_ids[i] == table_id) + return B_TRUE; + } + + return B_FALSE; +} + +static __checkReturn efx_rc_t +efx_table_ct_desc_fields_check( + __in_ecount(n_fields_descs) efx_table_field_descriptor_t *fields_descsp, + __in unsigned int n_fields_descs) +{ + unsigned int i; + efx_rc_t rc; + + for (i = 0; i < n_fields_descs; i++) { + switch (fields_descsp[i].field_id) { + case EFX_TABLE_FIELD_ID_ETHER_TYPE: + case EFX_TABLE_FIELD_ID_SRC_IP: + case EFX_TABLE_FIELD_ID_DST_IP: + case EFX_TABLE_FIELD_ID_IP_PROTO: + case EFX_TABLE_FIELD_ID_SRC_PORT: + case EFX_TABLE_FIELD_ID_DST_PORT: + if (fields_descsp[i].mask_type != EFX_TABLE_FIELD_MASK_EXACT) { + rc = EINVAL; + goto fail1; + } + break; + /* + * TODO: + * All fields in the CT table have EXACT mask. + * All the response field descriptors must have the EXACT mask. + * In the current implementation, only the Ethertype, source and + * destination IP address, IP protocol, and source and destination IP + * are used for the lookup by the key. + * FW could use the NEVER mask for the fields in the key that are not + * used for the lookup. + * As an alternative, a new mask could be added for these fields, + * like EXACT_NOT_USED. + */ + default: + if ((fields_descsp[i].mask_type != EFX_TABLE_FIELD_MASK_NEVER) && + (fields_descsp[i].mask_type != EFX_TABLE_FIELD_MASK_EXACT)) { + rc = EINVAL; + goto fail2; + } + break; + } + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + +static __checkReturn efx_rc_t +efx_table_desc_fields_check( + __in efx_table_id_t table_id, + __in_ecount(n_fields_descs) efx_table_field_descriptor_t *fields_descsp, + __in unsigned int n_fields_descs) +{ + efx_rc_t rc; + + switch (table_id) { + case EFX_TABLE_ID_CONNTRACK: + rc = efx_table_ct_desc_fields_check(fields_descsp, n_fields_descs); + if (rc != 0) + goto fail1; + break; + default: + break; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + +static void +efx_table_desc_fields_get( + __in const efx_mcdi_req_t *req, + __out_ecount(n_fields_descs) efx_table_field_descriptor_t *fields_descsp, + __in unsigned int n_fields_descs) +{ + unsigned int i; + + for (i = 0; i < n_fields_descs; i++) { + fields_descsp[i].field_id = (efx_table_field_id_t) + MCDI_OUT_INDEXED_QWORD_FIELD(*req, + TABLE_DESCRIPTOR_OUT_FIELDS, i, TABLE_FIELD_DESCR_FIELD_ID); + + fields_descsp[i].lbn = + MCDI_OUT_INDEXED_QWORD_FIELD(*req, + TABLE_DESCRIPTOR_OUT_FIELDS, i, TABLE_FIELD_DESCR_LBN); + + fields_descsp[i].width = + MCDI_OUT_INDEXED_QWORD_FIELD(*req, + TABLE_DESCRIPTOR_OUT_FIELDS, i, TABLE_FIELD_DESCR_WIDTH); + + fields_descsp[i].mask_type = (efx_table_field_mask_type_t) + MCDI_OUT_INDEXED_QWORD_FIELD(*req, + TABLE_DESCRIPTOR_OUT_FIELDS, i, TABLE_FIELD_DESCR_MASK_TYPE); + + fields_descsp[i].scheme = + MCDI_OUT_INDEXED_QWORD_FIELD(*req, + TABLE_DESCRIPTOR_OUT_FIELDS, i, TABLE_FIELD_DESCR_SCHEME); + } +} + + __checkReturn efx_rc_t +efx_table_describe( + __in efx_nic_t *enp, + __in efx_table_id_t table_id, + __in uint32_t field_offset, + __out_opt efx_table_descriptor_t *table_descp, + __out_ecount_opt(n_field_descs) efx_table_field_descriptor_t *fields_descs, + __in unsigned int n_field_descs, + __out_opt unsigned int *n_field_descs_writtenp) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + unsigned int n_entries; + efx_mcdi_req_t req; + unsigned int i; + efx_rc_t rc; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_TABLE_DESCRIPTOR_IN_LEN, + MC_CMD_TABLE_DESCRIPTOR_OUT_LENMAX_MCDI2); + + /* Ensure EFX and MCDI use same values for table types */ + EFX_STATIC_ASSERT(EFX_TABLE_TYPE_BCAM == MC_CMD_TABLE_DESCRIPTOR_OUT_TYPE_BCAM); + + /* Ensure EFX and MCDI use same values for table fields */ + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_UNUSED == TABLE_FIELD_ID_UNUSED); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_COUNTER_ID == TABLE_FIELD_ID_COUNTER_ID); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_ETHER_TYPE == TABLE_FIELD_ID_ETHER_TYPE); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_SRC_IP == TABLE_FIELD_ID_SRC_IP); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_DST_IP == TABLE_FIELD_ID_DST_IP); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_IP_PROTO == TABLE_FIELD_ID_IP_PROTO); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_SRC_PORT == TABLE_FIELD_ID_SRC_PORT); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_DST_PORT == TABLE_FIELD_ID_DST_PORT); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_NAT_PORT == TABLE_FIELD_ID_NAT_PORT); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_NAT_IP == TABLE_FIELD_ID_NAT_IP); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_NAT_DIR == TABLE_FIELD_ID_NAT_DIR); + EFX_STATIC_ASSERT(EFX_TABLE_FIELD_ID_CT_MARK == TABLE_FIELD_ID_CT_MARK); + + if (encp->enc_table_api_supported == B_FALSE) { + rc = ENOTSUP; + goto fail1; + } + + if (!efx_table_is_supported(table_id)) { + rc = ENOTSUP; + goto fail2; + } + + if ((n_field_descs != 0) && + ((fields_descs == NULL) || (n_field_descs_writtenp == NULL))) { + rc = EINVAL; + goto fail3; + } + + req.emr_cmd = MC_CMD_TABLE_DESCRIPTOR; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_TABLE_DESCRIPTOR_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_TABLE_DESCRIPTOR_OUT_LENMAX_MCDI2; + + MCDI_IN_SET_DWORD(req, TABLE_DESCRIPTOR_IN_TABLE_ID, (uint32_t)table_id); + MCDI_IN_SET_DWORD(req, TABLE_DESCRIPTOR_IN_FIRST_FIELDS_INDEX, field_offset); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail4; + } + + if (req.emr_out_length_used < MC_CMD_TABLE_DESCRIPTOR_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail5; + } + + if (table_descp != NULL) { + table_descp->type = (efx_table_type_t)MCDI_OUT_WORD( + req, TABLE_DESCRIPTOR_OUT_TYPE); + table_descp->key_width = MCDI_OUT_WORD( + req, TABLE_DESCRIPTOR_OUT_KEY_WIDTH); + table_descp->resp_width = MCDI_OUT_WORD( + req, TABLE_DESCRIPTOR_OUT_RESP_WIDTH); + table_descp->n_key_fields = MCDI_OUT_WORD( + req, TABLE_DESCRIPTOR_OUT_N_KEY_FIELDS); + table_descp->n_resp_fields = MCDI_OUT_WORD( + req, TABLE_DESCRIPTOR_OUT_N_RESP_FIELDS); + } + + n_entries = MC_CMD_TABLE_DESCRIPTOR_OUT_FIELDS_NUM(req.emr_out_length_used); + + if (fields_descs != NULL) { + if (n_entries > n_field_descs) { + rc = ENOMEM; + goto fail6; + } + + efx_table_desc_fields_get(&req, fields_descs, n_entries); + rc = efx_table_desc_fields_check(table_id, fields_descs, n_entries); + if (rc != 0) + goto fail7; + } + + if (n_field_descs_writtenp != NULL) + *n_field_descs_writtenp = n_entries; + + return (0); + +fail7: + EFSYS_PROBE(fail7); +fail6: + EFSYS_PROBE(fail6); fail5: EFSYS_PROBE(fail5); fail4: diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 7c92c1ae09..189dd4fdaf 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -233,7 +233,10 @@ INTERNAL { efx_sram_buf_tbl_clear; efx_sram_buf_tbl_set; + efx_table_describe; + efx_table_is_supported; efx_table_list; + efx_table_supported_num_get; efx_tunnel_config_clear; efx_tunnel_config_udp_add;