From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D7CF9A0548; Mon, 20 Sep 2021 09:42:44 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8B21041102; Mon, 20 Sep 2021 09:42:32 +0200 (CEST) Received: from relay.smtp-ext.broadcom.com (lpdvsmtp11.broadcom.com [192.19.166.231]) by mails.dpdk.org (Postfix) with ESMTP id 010F1410F4 for ; Mon, 20 Sep 2021 09:42:27 +0200 (CEST) Received: from S60.dhcp.broadcom.net (unknown [10.123.66.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by relay.smtp-ext.broadcom.com (Postfix) with ESMTPS id 109FA46C66; Mon, 20 Sep 2021 00:42:24 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 relay.smtp-ext.broadcom.com 109FA46C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1632123746; bh=rMC/w8gheyPMw683XWfWRx+U00GHNxxTJEXuj/ffkwQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e/9dS7bDYQXBn+vJAXx/B79fzUFDiAFc1y8vahh01b/sdCGLSHCSrRG72Qgq54Erz TD8ScN3u3E/9iPCLpESWtdoFr/Yoyrq0jj5LyGMS5PMesBaZY466GkDuIEAmgMzUZK 4atQbu4KqIDFpn9KUh8Qzy5J/IT98ftfNzRN/NU4= From: Venkat Duvvuru To: dev@dpdk.org Cc: Farah Smith Date: Mon, 20 Sep 2021 13:12:05 +0530 Message-Id: <20210920074214.23747-5-venkatkumar.duvvuru@broadcom.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210920074214.23747-1-venkatkumar.duvvuru@broadcom.com> References: <20210908050643.9989-1-venkatkumar.duvvuru@broadcom.com> <20210920074214.23747-1-venkatkumar.duvvuru@broadcom.com> Subject: [dpdk-dev] [PATCH v4 04/13] net/bnxt: add SRAM manager model 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 Sender: "dev" From: Farah Smith The SRAM manager supports allocation and free of variable sized records within SRAM memory. These record sizes are 8, 16, 32, or 64B. The SRAM manager algorithm will not fragment memory during run time. Previous implementation only included fixed size 64B records regardless of the size required. Signed-off-by: Farah Smith Reviewed-by: Shahaji Bhosle Reviewed-by: Peter Spreadborough Acked-by: Ajit Khaparde --- drivers/net/bnxt/tf_core/ll.c | 3 + drivers/net/bnxt/tf_core/ll.h | 50 +- drivers/net/bnxt/tf_core/meson.build | 2 + drivers/net/bnxt/tf_core/tf_core.c | 104 ++- drivers/net/bnxt/tf_core/tf_core.h | 48 +- drivers/net/bnxt/tf_core/tf_device.c | 40 +- drivers/net/bnxt/tf_core/tf_device.h | 133 ++- drivers/net/bnxt/tf_core/tf_device_p4.c | 75 +- drivers/net/bnxt/tf_core/tf_device_p4.h | 50 +- drivers/net/bnxt/tf_core/tf_device_p58.c | 105 ++- drivers/net/bnxt/tf_core/tf_device_p58.h | 60 +- drivers/net/bnxt/tf_core/tf_msg.c | 2 +- drivers/net/bnxt/tf_core/tf_rm.c | 46 +- drivers/net/bnxt/tf_core/tf_rm.h | 62 +- drivers/net/bnxt/tf_core/tf_session.c | 56 ++ drivers/net/bnxt/tf_core/tf_session.h | 58 +- drivers/net/bnxt/tf_core/tf_sram_mgr.c | 971 ++++++++++++++++++++++ drivers/net/bnxt/tf_core/tf_sram_mgr.h | 317 +++++++ drivers/net/bnxt/tf_core/tf_tbl.c | 186 +---- drivers/net/bnxt/tf_core/tf_tbl.h | 15 +- drivers/net/bnxt/tf_core/tf_tbl_sram.c | 713 ++++++++++++++++ drivers/net/bnxt/tf_core/tf_tbl_sram.h | 154 ++++ drivers/net/bnxt/tf_core/tf_tcam.c | 10 +- drivers/net/bnxt/tf_core/tf_tcam.h | 7 + drivers/net/bnxt/tf_core/tf_tcam_shared.c | 28 +- drivers/net/bnxt/tf_core/tf_util.c | 10 + drivers/net/bnxt/tf_ulp/bnxt_ulp.c | 23 + 27 files changed, 2976 insertions(+), 352 deletions(-) create mode 100644 drivers/net/bnxt/tf_core/tf_sram_mgr.c create mode 100644 drivers/net/bnxt/tf_core/tf_sram_mgr.h create mode 100644 drivers/net/bnxt/tf_core/tf_tbl_sram.c create mode 100644 drivers/net/bnxt/tf_core/tf_tbl_sram.h diff --git a/drivers/net/bnxt/tf_core/ll.c b/drivers/net/bnxt/tf_core/ll.c index cd168a7970..f2bdff6b9e 100644 --- a/drivers/net/bnxt/tf_core/ll.c +++ b/drivers/net/bnxt/tf_core/ll.c @@ -13,6 +13,7 @@ void ll_init(struct ll *ll) { ll->head = NULL; ll->tail = NULL; + ll->cnt = 0; } /* insert entry in linked list */ @@ -30,6 +31,7 @@ void ll_insert(struct ll *ll, entry->next->prev = entry; ll->head = entry->next->prev; } + ll->cnt++; } /* delete entry from linked list */ @@ -49,4 +51,5 @@ void ll_delete(struct ll *ll, entry->prev->next = entry->next; entry->next->prev = entry->prev; } + ll->cnt--; } diff --git a/drivers/net/bnxt/tf_core/ll.h b/drivers/net/bnxt/tf_core/ll.h index 239478b4f8..9cf8f64ec2 100644 --- a/drivers/net/bnxt/tf_core/ll.h +++ b/drivers/net/bnxt/tf_core/ll.h @@ -8,6 +8,8 @@ #ifndef _LL_H_ #define _LL_H_ +#include + /* linked list entry */ struct ll_entry { struct ll_entry *prev; @@ -18,6 +20,7 @@ struct ll_entry { struct ll { struct ll_entry *head; struct ll_entry *tail; + uint32_t cnt; }; /** @@ -28,7 +31,7 @@ struct ll { void ll_init(struct ll *ll); /** - * Linked list insert + * Linked list insert head * * [in] ll, linked list where element is inserted * [in] entry, entry to be added @@ -43,4 +46,49 @@ void ll_insert(struct ll *ll, struct ll_entry *entry); */ void ll_delete(struct ll *ll, struct ll_entry *entry); +/** + * Linked list return next entry without deleting it + * + * Useful in performing search + * + * [in] Entry in the list + */ +static inline struct ll_entry *ll_next(struct ll_entry *entry) +{ + return entry->next; +} + +/** + * Linked list return the head of the list without removing it + * + * Useful in performing search + * + * [in] ll, linked list + */ +static inline struct ll_entry *ll_head(struct ll *ll) +{ + return ll->head; +} + +/** + * Linked list return the tail of the list without removing it + * + * Useful in performing search + * + * [in] ll, linked list + */ +static inline struct ll_entry *ll_tail(struct ll *ll) +{ + return ll->tail; +} + +/** + * Linked list return the number of entries in the list + * + * [in] ll, linked list + */ +static inline uint32_t ll_cnt(struct ll *ll) +{ + return ll->cnt; +} #endif /* _LL_H_ */ diff --git a/drivers/net/bnxt/tf_core/meson.build b/drivers/net/bnxt/tf_core/meson.build index f28e77ec2e..206935d18a 100644 --- a/drivers/net/bnxt/tf_core/meson.build +++ b/drivers/net/bnxt/tf_core/meson.build @@ -16,6 +16,8 @@ sources += files( 'stack.c', 'tf_rm.c', 'tf_tbl.c', + 'tf_tbl_sram.c', + 'tf_sram_mgr.c', 'tf_em_common.c', 'tf_em_host.c', 'tf_em_internal.c', diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index 5458f76e2d..936102c804 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -1079,17 +1079,16 @@ tf_alloc_tbl_entry(struct tf *tfp, strerror(-rc)); return rc; } - - } else { - if (dev->ops->tf_dev_alloc_tbl == NULL) { - rc = -EOPNOTSUPP; + } else if (dev->ops->tf_dev_is_sram_managed(tfp, parms->type)) { + rc = dev->ops->tf_dev_alloc_sram_tbl(tfp, &aparms); + if (rc) { TFP_DRV_LOG(ERR, - "%s: Operation not supported, rc:%s\n", + "%s: SRAM table allocation failed, rc:%s\n", tf_dir_2_str(parms->dir), strerror(-rc)); - return -EOPNOTSUPP; + return rc; } - + } else { rc = dev->ops->tf_dev_alloc_tbl(tfp, &aparms); if (rc) { TFP_DRV_LOG(ERR, @@ -1162,15 +1161,16 @@ tf_free_tbl_entry(struct tf *tfp, strerror(-rc)); return rc; } - } else { - if (dev->ops->tf_dev_free_tbl == NULL) { - rc = -EOPNOTSUPP; + } else if (dev->ops->tf_dev_is_sram_managed(tfp, parms->type)) { + rc = dev->ops->tf_dev_free_sram_tbl(tfp, &fparms); + if (rc) { TFP_DRV_LOG(ERR, - "%s: Operation not supported, rc:%s\n", + "%s: SRAM table free failed, rc:%s\n", tf_dir_2_str(parms->dir), strerror(-rc)); - return -EOPNOTSUPP; + return rc; } + } else { rc = dev->ops->tf_dev_free_tbl(tfp, &fparms); if (rc) { @@ -1181,7 +1181,6 @@ tf_free_tbl_entry(struct tf *tfp, return rc; } } - return 0; } @@ -1244,6 +1243,15 @@ tf_set_tbl_entry(struct tf *tfp, strerror(-rc)); return rc; } + } else if (dev->ops->tf_dev_is_sram_managed(tfp, parms->type)) { + rc = dev->ops->tf_dev_set_sram_tbl(tfp, &sparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: SRAM table set failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } } else { if (dev->ops->tf_dev_set_tbl == NULL) { rc = -EOPNOTSUPP; @@ -1300,28 +1308,39 @@ tf_get_tbl_entry(struct tf *tfp, strerror(-rc)); return rc; } - - if (dev->ops->tf_dev_get_tbl == NULL) { - rc = -EOPNOTSUPP; - TFP_DRV_LOG(ERR, - "%s: Operation not supported, rc:%s\n", - tf_dir_2_str(parms->dir), - strerror(-rc)); - return -EOPNOTSUPP; - } - gparms.dir = parms->dir; gparms.type = parms->type; gparms.data = parms->data; gparms.data_sz_in_bytes = parms->data_sz_in_bytes; gparms.idx = parms->idx; - rc = dev->ops->tf_dev_get_tbl(tfp, &gparms); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: Table get failed, rc:%s\n", - tf_dir_2_str(parms->dir), - strerror(-rc)); - return rc; + + if (dev->ops->tf_dev_is_sram_managed(tfp, parms->type)) { + rc = dev->ops->tf_dev_get_sram_tbl(tfp, &gparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: SRAM table get failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + } else { + if (dev->ops->tf_dev_get_tbl == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return -EOPNOTSUPP; + } + + rc = dev->ops->tf_dev_get_tbl(tfp, &gparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Table get failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } } return rc; @@ -1361,6 +1380,13 @@ tf_bulk_get_tbl_entry(struct tf *tfp, return rc; } + bparms.dir = parms->dir; + bparms.type = parms->type; + bparms.starting_idx = parms->starting_idx; + bparms.num_entries = parms->num_entries; + bparms.entry_sz_in_bytes = parms->entry_sz_in_bytes; + bparms.physical_mem_addr = parms->physical_mem_addr; + if (parms->type == TF_TBL_TYPE_EXT) { /* Not supported, yet */ rc = -EOPNOTSUPP; @@ -1370,10 +1396,17 @@ tf_bulk_get_tbl_entry(struct tf *tfp, strerror(-rc)); return rc; + } else if (dev->ops->tf_dev_is_sram_managed(tfp, parms->type)) { + rc = dev->ops->tf_dev_get_bulk_sram_tbl(tfp, &bparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: SRAM table bulk get failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + } + return rc; } - /* Internal table type processing */ - if (dev->ops->tf_dev_get_bulk_tbl == NULL) { rc = -EOPNOTSUPP; TFP_DRV_LOG(ERR, @@ -1383,12 +1416,6 @@ tf_bulk_get_tbl_entry(struct tf *tfp, return -EOPNOTSUPP; } - bparms.dir = parms->dir; - bparms.type = parms->type; - bparms.starting_idx = parms->starting_idx; - bparms.num_entries = parms->num_entries; - bparms.entry_sz_in_bytes = parms->entry_sz_in_bytes; - bparms.physical_mem_addr = parms->physical_mem_addr; rc = dev->ops->tf_dev_get_bulk_tbl(tfp, &bparms); if (rc) { TFP_DRV_LOG(ERR, @@ -1397,7 +1424,6 @@ tf_bulk_get_tbl_entry(struct tf *tfp, strerror(-rc)); return rc; } - return rc; } diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h index af8d13bd7e..fb02c2b161 100644 --- a/drivers/net/bnxt/tf_core/tf_core.h +++ b/drivers/net/bnxt/tf_core/tf_core.h @@ -65,6 +65,16 @@ enum tf_ext_mem_chan_type { TF_EXT_MEM_CHAN_TYPE_MAX }; +/** + * WC TCAM number of slice per row that devices supported + */ +enum tf_wc_num_slice { + TF_WC_TCAM_1_SLICE_PER_ROW = 1, + TF_WC_TCAM_2_SLICE_PER_ROW = 2, + TF_WC_TCAM_4_SLICE_PER_ROW = 4, + TF_WC_TCAM_8_SLICE_PER_ROW = 8, +}; + /** * EEM record AR helper * @@ -670,6 +680,13 @@ struct tf_open_session_parms { */ void *bp; + /** + * [in] + * + * The number of slices per row for WC TCAM entry. + */ + enum tf_wc_num_slice wc_num_slices; + /** * [out] shared_session_creator * @@ -734,8 +751,6 @@ int tf_open_session(struct tf *tfp, /** * General internal resource info * - * TODO: remove tf_rm_new_entry structure and use this structure - * internally. */ struct tf_resource_info { uint16_t start; @@ -1656,12 +1671,7 @@ struct tf_alloc_tbl_entry_parms { * entry of the indicated type for this TruFlow session. * * Allocates an index table record. This function will attempt to - * allocate an entry or search an index table for a matching entry if - * search is enabled (only the shadow copy of the table is accessed). - * - * If search is not enabled, the first available free entry is - * returned. If search is enabled and a matching entry to entry_data - * is found hit is set to TRUE and success is returned. + * allocate an index table entry. * * External types: * @@ -1670,8 +1680,8 @@ struct tf_alloc_tbl_entry_parms { * Allocates an external index table action record. * * NOTE: - * Implementation of the internals of this function will be a stack with push - * and pop. + * Implementation of the internals of the external function will be a stack with + * push and pop. * * Returns success or failure code. */ @@ -1707,20 +1717,15 @@ struct tf_free_tbl_entry_parms { * * Internal types: * - * If session has shadow_copy enabled the shadow DB is searched and if - * found the element ref_cnt is decremented. If ref_cnt goes to - * zero then the element is returned to the session pool. - * - * If the session does not have a shadow DB the element is free'ed and - * given back to the session pool. + * The element is freed and given back to the session pool. * * External types: * - * Free's an external index table action record. + * Frees an external index table action record. * * NOTE: - * Implementation of the internals of this function will be a stack with push - * and pop. + * Implementation of the internals of the external table will be a stack with + * push and pop. * * Returns success or failure code. */ @@ -1764,9 +1769,8 @@ struct tf_set_tbl_entry_parms { /** * set index table entry * - * Used to insert an application programmed index table entry into a - * previous allocated table location. A shadow copy of the table - * is maintained (if enabled) (only for internal objects) + * Used to set an application programmed index table entry into a + * previous allocated table location. * * Returns success or failure code. */ diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c index 498e668b16..25a7166bbb 100644 --- a/drivers/net/bnxt/tf_core/tf_device.c +++ b/drivers/net/bnxt/tf_core/tf_device.c @@ -11,10 +11,14 @@ #include "tf_rm.h" #ifdef TF_TCAM_SHARED #include "tf_tcam_shared.h" +#include "tf_tbl_sram.h" #endif /* TF_TCAM_SHARED */ struct tf; +/* Number of slices per row for WC TCAM */ +uint16_t g_wc_num_slices_per_row = TF_WC_TCAM_1_SLICE_PER_ROW; + /* Forward declarations */ static int tf_dev_unbind_p4(struct tf *tfp); static int tf_dev_unbind_p58(struct tf *tfp); @@ -83,7 +87,8 @@ static int tf_dev_bind_p4(struct tf *tfp, bool shadow_copy, struct tf_session_resources *resources, - struct tf_dev_info *dev_handle) + struct tf_dev_info *dev_handle, + enum tf_wc_num_slice wc_num_slices) { int rc; int frc; @@ -131,7 +136,6 @@ tf_dev_bind_p4(struct tf *tfp, if (rsv_cnt) { tbl_cfg.num_elements = TF_TBL_TYPE_MAX; tbl_cfg.cfg = tf_tbl_p4; - tbl_cfg.shadow_copy = shadow_copy; tbl_cfg.resources = resources; rc = tf_tbl_bind(tfp, &tbl_cfg); if (rc) { @@ -151,6 +155,7 @@ tf_dev_bind_p4(struct tf *tfp, tcam_cfg.cfg = tf_tcam_p4; tcam_cfg.shadow_copy = shadow_copy; tcam_cfg.resources = resources; + tcam_cfg.wc_num_slices = wc_num_slices; #ifdef TF_TCAM_SHARED rc = tf_tcam_shared_bind(tfp, &tcam_cfg); #else /* !TF_TCAM_SHARED */ @@ -369,7 +374,8 @@ static int tf_dev_bind_p58(struct tf *tfp, bool shadow_copy, struct tf_session_resources *resources, - struct tf_dev_info *dev_handle) + struct tf_dev_info *dev_handle, + enum tf_wc_num_slice wc_num_slices) { int rc; int frc; @@ -414,7 +420,6 @@ tf_dev_bind_p58(struct tf *tfp, if (rsv_cnt) { tbl_cfg.num_elements = TF_TBL_TYPE_MAX; tbl_cfg.cfg = tf_tbl_p58; - tbl_cfg.shadow_copy = shadow_copy; tbl_cfg.resources = resources; rc = tf_tbl_bind(tfp, &tbl_cfg); if (rc) { @@ -423,6 +428,13 @@ tf_dev_bind_p58(struct tf *tfp, goto fail; } no_rsv_flag = false; + + rc = tf_tbl_sram_bind(tfp); + if (rc) { + TFP_DRV_LOG(ERR, + "SRAM table initialization failure\n"); + goto fail; + } } rsv_cnt = tf_dev_reservation_check(TF_TCAM_TBL_TYPE_MAX, @@ -433,6 +445,7 @@ tf_dev_bind_p58(struct tf *tfp, tcam_cfg.cfg = tf_tcam_p58; tcam_cfg.shadow_copy = shadow_copy; tcam_cfg.resources = resources; + tcam_cfg.wc_num_slices = wc_num_slices; #ifdef TF_TCAM_SHARED rc = tf_tcam_shared_bind(tfp, &tcam_cfg); #else /* !TF_TCAM_SHARED */ @@ -565,6 +578,18 @@ tf_dev_unbind_p58(struct tf *tfp) fail = true; } + /* Unbind the SRAM table prior to table as the table manager + * owns and frees the table DB while the SRAM table manager owns + * and manages it's internal data structures. SRAM table manager + * relies on the table rm_db to exist. + */ + rc = tf_tbl_sram_unbind(tfp); + if (rc) { + TFP_DRV_LOG(ERR, + "Device unbind failed, SRAM table\n"); + fail = true; + } + rc = tf_tbl_unbind(tfp); if (rc) { TFP_DRV_LOG(INFO, @@ -606,6 +631,7 @@ tf_dev_bind(struct tf *tfp __rte_unused, enum tf_device_type type, bool shadow_copy, struct tf_session_resources *resources, + uint16_t wc_num_slices, struct tf_dev_info *dev_handle) { switch (type) { @@ -615,13 +641,15 @@ tf_dev_bind(struct tf *tfp __rte_unused, return tf_dev_bind_p4(tfp, shadow_copy, resources, - dev_handle); + dev_handle, + wc_num_slices); case TF_DEVICE_TYPE_THOR: dev_handle->type = type; return tf_dev_bind_p58(tfp, shadow_copy, resources, - dev_handle); + dev_handle, + wc_num_slices); default: TFP_DRV_LOG(ERR, "No such device\n"); diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h index b43cfc6925..9b0c037db0 100644 --- a/drivers/net/bnxt/tf_core/tf_device.h +++ b/drivers/net/bnxt/tf_core/tf_device.h @@ -57,6 +57,9 @@ struct tf_dev_info { * [in] resources * Pointer to resource allocation information * + * [in] wc_num_slices + * Number of slices per row for WC + * * [out] dev_handle * Device handle * @@ -69,6 +72,7 @@ int tf_dev_bind(struct tf *tfp, enum tf_device_type type, bool shadow_copy, struct tf_session_resources *resources, + uint16_t wc_num_slices, struct tf_dev_info *dev_handle); /** @@ -139,6 +143,23 @@ struct tf_dev_ops { uint16_t resource_id, const char **resource_str); + /** + * Set the WC TCAM slice information that the device + * supports. + * + * [in] tfp + * Pointer to TF handle + * + * [in] num_slices_per_row + * Number of slices per row the device supports + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_set_tcam_slice_info)(struct tf *tfp, + enum tf_wc_num_slice num_slices_per_row); + /** * Retrieves the WC TCAM slice information that the device * supports. @@ -241,6 +262,22 @@ struct tf_dev_ops { int (*tf_dev_get_ident_resc_info)(struct tf *tfp, struct tf_identifier_resource_info *parms); + /** + * Indicates whether the index table type is SRAM managed + * + * [in] tfp + * Pointer to TF handle + * + * [in] type + * Truflow index table type, e.g. TF_TYPE_FULL_ACT_RECORD + * + * Returns + * - (0) if the table is not managed by the SRAM manager + * - (1) if the table is managed by the SRAM manager + */ + bool (*tf_dev_is_sram_managed)(struct tf *tfp, + enum tf_tbl_type tbl_type); + /** * Get SRAM table information. * @@ -289,6 +326,25 @@ struct tf_dev_ops { int (*tf_dev_alloc_tbl)(struct tf *tfp, struct tf_tbl_alloc_parms *parms); + /** + * Allocation of an SRAM index table type element. + * + * This API allocates the specified table type element from a + * device specific table type DB. The allocated element is + * returned. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to table allocation parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_alloc_sram_tbl)(struct tf *tfp, + struct tf_tbl_alloc_parms *parms); /** * Allocation of a external table type element. * @@ -327,7 +383,24 @@ struct tf_dev_ops { */ int (*tf_dev_free_tbl)(struct tf *tfp, struct tf_tbl_free_parms *parms); - + /** + * Free of an SRAM table type element. + * + * This API free's a previous allocated table type element from a + * device specific table type DB. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to table free parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_free_sram_tbl)(struct tf *tfp, + struct tf_tbl_free_parms *parms); /** * Free of a external table type element. * @@ -385,6 +458,25 @@ struct tf_dev_ops { int (*tf_dev_set_ext_tbl)(struct tf *tfp, struct tf_tbl_set_parms *parms); + /** + * Sets the specified SRAM table type element. + * + * This API sets the specified element data by invoking the + * firmware. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to table set parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_set_sram_tbl)(struct tf *tfp, + struct tf_tbl_set_parms *parms); + /** * Retrieves the specified table type element. * @@ -404,6 +496,25 @@ struct tf_dev_ops { int (*tf_dev_get_tbl)(struct tf *tfp, struct tf_tbl_get_parms *parms); + /** + * Retrieves the specified SRAM table type element. + * + * This API retrieves the specified element data by invoking the + * firmware. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to table get parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_get_sram_tbl)(struct tf *tfp, + struct tf_tbl_get_parms *parms); + /** * Retrieves the specified table type element using 'bulk' * mechanism. @@ -424,6 +535,26 @@ struct tf_dev_ops { int (*tf_dev_get_bulk_tbl)(struct tf *tfp, struct tf_tbl_get_bulk_parms *parms); + /** + * Retrieves the specified SRAM table type element using 'bulk' + * mechanism. + * + * This API retrieves the specified element data by invoking the + * firmware. + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to table get bulk parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ + int (*tf_dev_get_bulk_sram_tbl)(struct tf *tfp, + struct tf_tbl_get_bulk_parms *parms); + /** * Gets the increment value to add to the shared session resource * start offset by for each count in the "stride" diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c index 2e7ccec123..826cd0cdbc 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.c +++ b/drivers/net/bnxt/tf_core/tf_device_p4.c @@ -118,14 +118,48 @@ tf_dev_p4_get_resource_str(struct tf *tfp __rte_unused, } /** - * Device specific function that retrieves the WC TCAM slices the + * Device specific function that set the WC TCAM slices the * device supports. * * [in] tfp * Pointer to TF handle * - * [out] slice_size - * Pointer to the WC TCAM slice size + * [in] num_slices_per_row + * The WC TCAM row slice configuration + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +static int +tf_dev_p4_set_tcam_slice_info(struct tf *tfp __rte_unused, + enum tf_wc_num_slice num_slices_per_row) +{ + switch (num_slices_per_row) { + case TF_WC_TCAM_1_SLICE_PER_ROW: + case TF_WC_TCAM_2_SLICE_PER_ROW: + case TF_WC_TCAM_4_SLICE_PER_ROW: + g_wc_num_slices_per_row = num_slices_per_row; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * Device specific function that retrieves the TCAM slices the + * device supports. + * + * [in] tfp + * Pointer to TF handle + * + * [in] type + * TF TCAM type + * + * [in] key_sz + * The key size * * [out] num_slices_per_row * Pointer to the WC TCAM row slice configuration @@ -141,11 +175,10 @@ tf_dev_p4_get_tcam_slice_info(struct tf *tfp __rte_unused, uint16_t *num_slices_per_row) { /* Single slice support */ -#define CFA_P4_WC_TCAM_SLICES_PER_ROW 1 #define CFA_P4_WC_TCAM_SLICE_SIZE 12 if (type == TF_TCAM_TBL_TYPE_WC_TCAM) { - *num_slices_per_row = CFA_P4_WC_TCAM_SLICES_PER_ROW; + *num_slices_per_row = g_wc_num_slices_per_row; if (key_sz > *num_slices_per_row * CFA_P4_WC_TCAM_SLICE_SIZE) return -ENOTSUP; } else { /* for other type of tcam */ @@ -220,26 +253,51 @@ static int tf_dev_p4_word_align(uint16_t size) return ((((size) + 31) >> 5) * 4); } +/** + * Indicates whether the index table type is SRAM managed + * + * [in] tfp + * Pointer to TF handle + * + * [in] type + * Truflow index table type, e.g. TF_TYPE_FULL_ACT_RECORD + * + * Returns + * - (0) if the table is not managed by the SRAM manager + * - (1) if the table is managed by the SRAM manager + */ +static bool tf_dev_p4_is_sram_managed(struct tf *tfp __rte_unused, + enum tf_tbl_type type __rte_unused) +{ + return false; +} /** * Truflow P4 device specific functions */ const struct tf_dev_ops tf_dev_ops_p4_init = { .tf_dev_get_max_types = tf_dev_p4_get_max_types, .tf_dev_get_resource_str = tf_dev_p4_get_resource_str, + .tf_dev_set_tcam_slice_info = tf_dev_p4_set_tcam_slice_info, .tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info, .tf_dev_alloc_ident = NULL, .tf_dev_free_ident = NULL, .tf_dev_search_ident = NULL, .tf_dev_get_ident_resc_info = NULL, .tf_dev_get_tbl_info = NULL, + .tf_dev_is_sram_managed = tf_dev_p4_is_sram_managed, .tf_dev_alloc_ext_tbl = NULL, .tf_dev_alloc_tbl = NULL, + .tf_dev_alloc_sram_tbl = NULL, .tf_dev_free_ext_tbl = NULL, .tf_dev_free_tbl = NULL, + .tf_dev_free_sram_tbl = NULL, .tf_dev_set_tbl = NULL, .tf_dev_set_ext_tbl = NULL, + .tf_dev_set_sram_tbl = NULL, .tf_dev_get_tbl = NULL, + .tf_dev_get_sram_tbl = NULL, .tf_dev_get_bulk_tbl = NULL, + .tf_dev_get_bulk_sram_tbl = NULL, .tf_dev_get_shared_tbl_increment = tf_dev_p4_get_shared_tbl_increment, .tf_dev_get_tbl_resc_info = NULL, .tf_dev_alloc_tcam = NULL, @@ -271,20 +329,27 @@ const struct tf_dev_ops tf_dev_ops_p4_init = { const struct tf_dev_ops tf_dev_ops_p4 = { .tf_dev_get_max_types = tf_dev_p4_get_max_types, .tf_dev_get_resource_str = tf_dev_p4_get_resource_str, + .tf_dev_set_tcam_slice_info = tf_dev_p4_set_tcam_slice_info, .tf_dev_get_tcam_slice_info = tf_dev_p4_get_tcam_slice_info, .tf_dev_alloc_ident = tf_ident_alloc, .tf_dev_free_ident = tf_ident_free, .tf_dev_search_ident = tf_ident_search, .tf_dev_get_ident_resc_info = tf_ident_get_resc_info, .tf_dev_get_tbl_info = NULL, + .tf_dev_is_sram_managed = tf_dev_p4_is_sram_managed, .tf_dev_alloc_tbl = tf_tbl_alloc, .tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc, + .tf_dev_alloc_sram_tbl = tf_tbl_alloc, .tf_dev_free_tbl = tf_tbl_free, .tf_dev_free_ext_tbl = tf_tbl_ext_free, + .tf_dev_free_sram_tbl = tf_tbl_free, .tf_dev_set_tbl = tf_tbl_set, .tf_dev_set_ext_tbl = tf_tbl_ext_common_set, + .tf_dev_set_sram_tbl = NULL, .tf_dev_get_tbl = tf_tbl_get, + .tf_dev_get_sram_tbl = NULL, .tf_dev_get_bulk_tbl = tf_tbl_bulk_get, + .tf_dev_get_bulk_sram_tbl = NULL, .tf_dev_get_shared_tbl_increment = tf_dev_p4_get_shared_tbl_increment, .tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info, #ifdef TF_TCAM_SHARED diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.h b/drivers/net/bnxt/tf_core/tf_device_p4.h index a73ba3cd70..c1357913f1 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.h +++ b/drivers/net/bnxt/tf_core/tf_device_p4.h @@ -15,101 +15,101 @@ struct tf_rm_element_cfg tf_ident_p4[TF_IDENT_TYPE_MAX] = { [TF_IDENT_TYPE_L2_CTXT_HIGH] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_L2_CTXT_REMAP_HIGH, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_L2_CTXT_LOW] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_L2_CTXT_REMAP_LOW, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_PROF_FUNC] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_PROF_FUNC, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_WC_PROF] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_WC_TCAM_PROF_ID, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_EM_PROF] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_EM_PROF_ID, - 0, 0, 0 + 0, 0 }, }; struct tf_rm_element_cfg tf_tcam_p4[TF_TCAM_TBL_TYPE_MAX] = { [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_HIGH, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_L2_CTXT_TCAM_LOW, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_PROF_TCAM] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_PROF_TCAM, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_WC_TCAM] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_WC_TCAM, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_SP_TCAM] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_SP_TCAM, - 0, 0, 0 + 0, 0 }, }; struct tf_rm_element_cfg tf_tbl_p4[TF_TBL_TYPE_MAX] = { [TF_TBL_TYPE_FULL_ACT_RECORD] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_FULL_ACTION, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_MCAST_GROUPS] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_MCG, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_ENCAP_8B] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_ENCAP_8B, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_ENCAP_16B] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_ENCAP_16B, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_ENCAP_64B] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_ENCAP_64B, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_SP_SMAC] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_SP_MAC, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_SP_MAC_IPV4, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_SP_SMAC_IPV6] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_SP_MAC_IPV6, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_STATS_64] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_COUNTER_64B, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_ACT_MODIFY_IPV4] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_NAT_IPV4, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_METER_PROF] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_METER_PROF, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_METER_INST] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_METER, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_MIRROR_CONFIG] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_MIRROR, - 0, 0, 0 + 0, 0 }, }; @@ -117,14 +117,14 @@ struct tf_rm_element_cfg tf_tbl_p4[TF_TBL_TYPE_MAX] = { struct tf_rm_element_cfg tf_em_ext_p4[TF_EM_TBL_TYPE_MAX] = { [TF_EM_TBL_TYPE_TBL_SCOPE] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P4_TBL_SCOPE, - 0, 0, 0 + 0, 0 }, }; struct tf_rm_element_cfg tf_em_int_p4[TF_EM_TBL_TYPE_MAX] = { [TF_EM_TBL_TYPE_EM_RECORD] = { TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P4_EM_REC, - 0, 0, 0 + 0, 0 }, }; diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c index a492c62bff..47d7836a58 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.c +++ b/drivers/net/bnxt/tf_core/tf_device_p58.c @@ -17,6 +17,7 @@ #include "tf_if_tbl.h" #include "tfp.h" #include "tf_msg_common.h" +#include "tf_tbl_sram.h" #define TF_DEV_P58_PARIF_MAX 16 #define TF_DEV_P58_PF_MASK 0xfUL @@ -105,14 +106,48 @@ tf_dev_p58_get_resource_str(struct tf *tfp __rte_unused, } /** - * Device specific function that retrieves the WC TCAM slices the + * Device specific function that set the WC TCAM slices the * device supports. * * [in] tfp * Pointer to TF handle * - * [out] slice_size - * Pointer to the WC TCAM slice size + * [in] num_slices_per_row + * The WC TCAM row slice configuration + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +static int +tf_dev_p58_set_tcam_slice_info(struct tf *tfp __rte_unused, + enum tf_wc_num_slice num_slices_per_row) +{ + switch (num_slices_per_row) { + case TF_WC_TCAM_1_SLICE_PER_ROW: + case TF_WC_TCAM_2_SLICE_PER_ROW: + case TF_WC_TCAM_4_SLICE_PER_ROW: + g_wc_num_slices_per_row = num_slices_per_row; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * Device specific function that retrieves the TCAM slices the + * device supports. + * + * [in] tfp + * Pointer to TF handle + * + * [in] type + * TF TCAM type + * + * [in] key_sz + * The key size * * [out] num_slices_per_row * Pointer to the WC TCAM row slice configuration @@ -123,16 +158,13 @@ tf_dev_p58_get_resource_str(struct tf *tfp __rte_unused, */ static int tf_dev_p58_get_tcam_slice_info(struct tf *tfp __rte_unused, - enum tf_tcam_tbl_type type, - uint16_t key_sz, - uint16_t *num_slices_per_row) + enum tf_tcam_tbl_type type, + uint16_t key_sz, + uint16_t *num_slices_per_row) { -#define CFA_P58_WC_TCAM_SLICES_PER_ROW 1 #define CFA_P58_WC_TCAM_SLICE_SIZE 24 - if (type == TF_TCAM_TBL_TYPE_WC_TCAM) { - /* only support single slice key size now */ - *num_slices_per_row = CFA_P58_WC_TCAM_SLICES_PER_ROW; + *num_slices_per_row = g_wc_num_slices_per_row; if (key_sz > *num_slices_per_row * CFA_P58_WC_TCAM_SLICE_SIZE) return -ENOTSUP; } else { /* for other type of tcam */ @@ -194,6 +226,44 @@ static int tf_dev_p58_get_shared_tbl_increment(struct tf *tfp __rte_unused, return 0; } +/** + * Indicates whether the index table type is SRAM managed + * + * [in] tfp + * Pointer to TF handle + * + * [in] type + * Truflow index table type, e.g. TF_TYPE_FULL_ACT_RECORD + * + * Returns + * - (0) if the table is not managed by the SRAM manager + * - (1) if the table is managed by the SRAM manager + */ +static bool tf_dev_p58_is_sram_managed(struct tf *tfp __rte_unused, + enum tf_tbl_type type) +{ + switch (type) { + case TF_TBL_TYPE_FULL_ACT_RECORD: + case TF_TBL_TYPE_COMPACT_ACT_RECORD: + case TF_TBL_TYPE_ACT_ENCAP_8B: + case TF_TBL_TYPE_ACT_ENCAP_16B: + case TF_TBL_TYPE_ACT_ENCAP_32B: + case TF_TBL_TYPE_ACT_ENCAP_64B: + case TF_TBL_TYPE_ACT_SP_SMAC: + case TF_TBL_TYPE_ACT_SP_SMAC_IPV4: + case TF_TBL_TYPE_ACT_SP_SMAC_IPV6: + case TF_TBL_TYPE_ACT_STATS_64: + case TF_TBL_TYPE_ACT_MODIFY_IPV4: + case TF_TBL_TYPE_ACT_MODIFY_8B: + case TF_TBL_TYPE_ACT_MODIFY_16B: + case TF_TBL_TYPE_ACT_MODIFY_32B: + case TF_TBL_TYPE_ACT_MODIFY_64B: + return true; + default: + return false; + } +} + #define TF_DEV_P58_BANK_SZ_64B 2048 /** * Get SRAM table information. @@ -265,26 +335,34 @@ static int tf_dev_p58_get_sram_tbl_info(struct tf *tfp __rte_unused, } return 0; } + /** * Truflow P58 device specific functions */ const struct tf_dev_ops tf_dev_ops_p58_init = { .tf_dev_get_max_types = tf_dev_p58_get_max_types, .tf_dev_get_resource_str = tf_dev_p58_get_resource_str, + .tf_dev_set_tcam_slice_info = tf_dev_p58_set_tcam_slice_info, .tf_dev_get_tcam_slice_info = tf_dev_p58_get_tcam_slice_info, .tf_dev_alloc_ident = NULL, .tf_dev_free_ident = NULL, .tf_dev_search_ident = NULL, .tf_dev_get_ident_resc_info = NULL, .tf_dev_get_tbl_info = NULL, + .tf_dev_is_sram_managed = tf_dev_p58_is_sram_managed, .tf_dev_alloc_ext_tbl = NULL, .tf_dev_alloc_tbl = NULL, + .tf_dev_alloc_sram_tbl = NULL, .tf_dev_free_ext_tbl = NULL, .tf_dev_free_tbl = NULL, + .tf_dev_free_sram_tbl = NULL, .tf_dev_set_tbl = NULL, .tf_dev_set_ext_tbl = NULL, + .tf_dev_set_sram_tbl = NULL, .tf_dev_get_tbl = NULL, + .tf_dev_get_sram_tbl = NULL, .tf_dev_get_bulk_tbl = NULL, + .tf_dev_get_bulk_sram_tbl = NULL, .tf_dev_get_shared_tbl_increment = tf_dev_p58_get_shared_tbl_increment, .tf_dev_get_tbl_resc_info = NULL, .tf_dev_alloc_tcam = NULL, @@ -316,20 +394,27 @@ const struct tf_dev_ops tf_dev_ops_p58_init = { const struct tf_dev_ops tf_dev_ops_p58 = { .tf_dev_get_max_types = tf_dev_p58_get_max_types, .tf_dev_get_resource_str = tf_dev_p58_get_resource_str, + .tf_dev_set_tcam_slice_info = tf_dev_p58_set_tcam_slice_info, .tf_dev_get_tcam_slice_info = tf_dev_p58_get_tcam_slice_info, .tf_dev_alloc_ident = tf_ident_alloc, .tf_dev_free_ident = tf_ident_free, .tf_dev_search_ident = tf_ident_search, .tf_dev_get_ident_resc_info = tf_ident_get_resc_info, + .tf_dev_is_sram_managed = tf_dev_p58_is_sram_managed, .tf_dev_get_tbl_info = tf_dev_p58_get_sram_tbl_info, .tf_dev_alloc_tbl = tf_tbl_alloc, + .tf_dev_alloc_sram_tbl = tf_tbl_sram_alloc, .tf_dev_alloc_ext_tbl = tf_tbl_ext_alloc, .tf_dev_free_tbl = tf_tbl_free, .tf_dev_free_ext_tbl = tf_tbl_ext_free, + .tf_dev_free_sram_tbl = tf_tbl_sram_free, .tf_dev_set_tbl = tf_tbl_set, .tf_dev_set_ext_tbl = tf_tbl_ext_common_set, + .tf_dev_set_sram_tbl = tf_tbl_sram_set, .tf_dev_get_tbl = tf_tbl_get, + .tf_dev_get_sram_tbl = tf_tbl_sram_get, .tf_dev_get_bulk_tbl = tf_tbl_bulk_get, + .tf_dev_get_bulk_sram_tbl = tf_tbl_sram_bulk_get, .tf_dev_get_shared_tbl_increment = tf_dev_p58_get_shared_tbl_increment, .tf_dev_get_tbl_resc_info = tf_tbl_get_resc_info, #ifdef TF_TCAM_SHARED diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.h b/drivers/net/bnxt/tf_core/tf_device_p58.h index 8c2e07aa34..3e8759f2df 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.h +++ b/drivers/net/bnxt/tf_core/tf_device_p58.h @@ -15,107 +15,107 @@ struct tf_rm_element_cfg tf_ident_p58[TF_IDENT_TYPE_MAX] = { [TF_IDENT_TYPE_L2_CTXT_HIGH] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_L2_CTXT_REMAP_HIGH, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_L2_CTXT_LOW] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_L2_CTXT_REMAP_LOW, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_PROF_FUNC] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_PROF_FUNC, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_WC_PROF] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_WC_TCAM_PROF_ID, - 0, 0, 0 + 0, 0 }, [TF_IDENT_TYPE_EM_PROF] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_EM_PROF_ID, - 0, 0, 0 + 0, 0 }, }; struct tf_rm_element_cfg tf_tcam_p58[TF_TCAM_TBL_TYPE_MAX] = { [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_HIGH, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_L2_CTXT_TCAM_LOW, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_PROF_TCAM] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_PROF_TCAM, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_WC_TCAM] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_WC_TCAM, - 0, 0, 0 + 0, 0 }, [TF_TCAM_TBL_TYPE_VEB_TCAM] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_VEB_TCAM, - 0, 0, 0 + 0, 0 }, }; struct tf_rm_element_cfg tf_tbl_p58[TF_TBL_TYPE_MAX] = { [TF_TBL_TYPE_EM_FKB] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_EM_FKB, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_WC_FKB] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_WC_FKB, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_METER_PROF] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_METER_PROF, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_METER_INST] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_METER, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_METER_DROP_CNT] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_METER_DROP_CNT, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_MIRROR_CONFIG] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_MIRROR, - 0, 0, 0 + 0, 0 }, [TF_TBL_TYPE_METADATA] = { TF_RM_ELEM_CFG_HCAPI_BA, CFA_RESOURCE_TYPE_P58_METADATA, - 0, 0, 0 + 0, 0 }, /* Policy - ARs in bank 1 */ [TF_TBL_TYPE_FULL_ACT_RECORD] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1, - .slices = 1, + .slices = 4, }, [TF_TBL_TYPE_COMPACT_ACT_RECORD] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_FULL_ACT_RECORD, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_1, - .slices = 1, + .slices = 8, }, /* Policy - Encaps in bank 2 */ [TF_TBL_TYPE_ACT_ENCAP_8B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2, - .slices = 1, + .slices = 8, }, [TF_TBL_TYPE_ACT_ENCAP_16B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2, - .slices = 1, + .slices = 4, }, [TF_TBL_TYPE_ACT_ENCAP_32B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2, - .slices = 1, + .slices = 2, }, [TF_TBL_TYPE_ACT_ENCAP_64B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, @@ -128,19 +128,19 @@ struct tf_rm_element_cfg tf_tbl_p58[TF_TBL_TYPE_MAX] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2, - .slices = 1, + .slices = 8, }, [TF_TBL_TYPE_ACT_MODIFY_16B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2, - .slices = 1, + .slices = 4, }, [TF_TBL_TYPE_ACT_MODIFY_32B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_ENCAP_8B, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_2, - .slices = 1, + .slices = 2, }, [TF_TBL_TYPE_ACT_MODIFY_64B] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, @@ -152,32 +152,32 @@ struct tf_rm_element_cfg tf_tbl_p58[TF_TBL_TYPE_MAX] = { [TF_TBL_TYPE_ACT_SP_SMAC] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0, - .slices = 1, + .slices = 8, }, [TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_SP_SMAC, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0, - .slices = 1, + .slices = 4, }, [TF_TBL_TYPE_ACT_SP_SMAC_IPV6] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_CHILD, .parent_subtype = TF_TBL_TYPE_ACT_SP_SMAC, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_0, - .slices = 1, + .slices = 2, }, /* Policy - Stats in bank 3 */ [TF_TBL_TYPE_ACT_STATS_64] = { .cfg_type = TF_RM_ELEM_CFG_HCAPI_BA_PARENT, .hcapi_type = CFA_RESOURCE_TYPE_P58_SRAM_BANK_3, - .slices = 1, + .slices = 8, }, }; struct tf_rm_element_cfg tf_em_int_p58[TF_EM_TBL_TYPE_MAX] = { [TF_EM_TBL_TYPE_EM_RECORD] = { TF_RM_ELEM_CFG_HCAPI, CFA_RESOURCE_TYPE_P58_EM_REC, - 0, 0, 0 + 0, 0 }, }; diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index e07d9168be..0fbb2fe837 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -2231,7 +2231,7 @@ tf_msg_get_if_tbl_entry(struct tf *tfp, if (rc != 0) return rc; - tfp_memcpy(params->data, resp.data, req.size); + tfp_memcpy(¶ms->data[0], resp.data, req.size); return 0; } diff --git a/drivers/net/bnxt/tf_core/tf_rm.c b/drivers/net/bnxt/tf_core/tf_rm.c index 0a46e2a343..03c958a7d6 100644 --- a/drivers/net/bnxt/tf_core/tf_rm.c +++ b/drivers/net/bnxt/tf_core/tf_rm.c @@ -34,6 +34,12 @@ struct tf_rm_element { */ uint16_t hcapi_type; + /** + * Resource slices. How many slices will fit in the + * resource pool chunk size. + */ + uint8_t slices; + /** * HCAPI RM allocated range information for the element. */ @@ -356,12 +362,15 @@ tf_rm_check_residuals(struct tf_rm_new_db *rm_db, * - - Failure if negative */ static int -tf_rm_update_parent_reservations(struct tf_rm_element_cfg *cfg, +tf_rm_update_parent_reservations(struct tf *tfp, + struct tf_dev_info *dev, + struct tf_rm_element_cfg *cfg, uint16_t *alloc_cnt, uint16_t num_elements, uint16_t *req_cnt) { int parent, child; + const char *type_str; /* Search through all the elements */ for (parent = 0; parent < num_elements; parent++) { @@ -377,15 +386,25 @@ tf_rm_update_parent_reservations(struct tf_rm_element_cfg *cfg, if (alloc_cnt[parent] % cfg[parent].slices) combined_cnt++; + if (alloc_cnt[parent]) { + dev->ops->tf_dev_get_resource_str(tfp, + cfg[parent].hcapi_type, + &type_str); + } + /* Search again through all the elements */ for (child = 0; child < num_elements; child++) { /* If this is one of my children */ if (cfg[child].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD && - cfg[child].parent_subtype == parent) { + cfg[child].parent_subtype == parent && + alloc_cnt[child]) { uint16_t cnt = 0; RTE_ASSERT(cfg[child].slices); + dev->ops->tf_dev_get_resource_str(tfp, + cfg[child].hcapi_type, + &type_str); /* Increment the parents combined count * with each child's count adjusted for * number of slices per RM allocated item. @@ -479,7 +498,7 @@ tf_rm_create_db(struct tf *tfp, /* Update the req_cnt based upon the element configuration */ - tf_rm_update_parent_reservations(parms->cfg, + tf_rm_update_parent_reservations(tfp, dev, parms->cfg, parms->alloc_cnt, parms->num_elements, req_cnt); @@ -594,6 +613,7 @@ tf_rm_create_db(struct tf *tfp, db[i].cfg_type = cfg->cfg_type; db[i].hcapi_type = cfg->hcapi_type; + db[i].slices = cfg->slices; /* Save the parent subtype for later use to find the pool */ @@ -1271,6 +1291,26 @@ tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms) return 0; } +int +tf_rm_get_slices(struct tf_rm_get_slices_parms *parms) +{ + struct tf_rm_new_db *rm_db; + enum tf_rm_elem_cfg_type cfg_type; + + TF_CHECK_PARMS2(parms, parms->rm_db); + rm_db = (struct tf_rm_new_db *)parms->rm_db; + TF_CHECK_PARMS1(rm_db->db); + + cfg_type = rm_db->db[parms->subtype].cfg_type; + + /* Bail out if not controlled by HCAPI */ + if (cfg_type == TF_RM_ELEM_CFG_NULL) + return -ENOTSUP; + + *parms->slices = rm_db->db[parms->subtype].slices; + + return 0; +} int tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms) diff --git a/drivers/net/bnxt/tf_core/tf_rm.h b/drivers/net/bnxt/tf_core/tf_rm.h index 8b984112e8..da7d0c7211 100644 --- a/drivers/net/bnxt/tf_core/tf_rm.h +++ b/drivers/net/bnxt/tf_core/tf_rm.h @@ -43,16 +43,6 @@ struct tf; * support module, not called directly. */ -/** - * Resource reservation single entry result. Used when accessing HCAPI - * RM on the firmware. - */ -struct tf_rm_new_entry { - /** Starting index of the allocated resource */ - uint16_t start; - /** Number of allocated elements */ - uint16_t stride; -}; /** * RM Element configuration enumeration. Used by the Device to @@ -114,10 +104,6 @@ struct tf_rm_element_cfg { */ enum tf_rm_elem_cfg_type cfg_type; - /* If a HCAPI to TF type conversion is required then TF type - * can be added here. - */ - /** * HCAPI RM Type for the element. Used for TF to HCAPI type * conversion. @@ -125,28 +111,19 @@ struct tf_rm_element_cfg { uint16_t hcapi_type; /** - * if cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD + * if cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD/PARENT * * Parent Truflow module subtype associated with this resource type. */ uint16_t parent_subtype; /** - * if cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD + * if cfg_type == TF_RM_ELEM_CFG_HCAPI_BA_CHILD/PARENT * * Resource slices. How many slices will fit in the * resource pool chunk size. */ uint8_t slices; - - /** - * Pool element divider count - * If 0 or 1, there is 1:1 correspondence between the RM - * BA pool resource element and the HCAPI RM firmware - * resource. If > 1, the RM BA pool element has a 1:n - * correspondence to the HCAPI RM firmware resource. - */ - uint8_t divider; }; /** @@ -160,7 +137,7 @@ struct tf_rm_alloc_info { * In case of dynamic allocation support this would have * to be changed to linked list of tf_rm_entry instead. */ - struct tf_rm_new_entry entry; + struct tf_resource_info entry; }; /** @@ -331,6 +308,25 @@ struct tf_rm_get_hcapi_parms { */ uint16_t *hcapi_type; }; +/** + * Get Slices parameters for a single element + */ +struct tf_rm_get_slices_parms { + /** + * [in] RM DB Handle + */ + void *rm_db; + /** + * [in] TF subtype indicates which DB entry to perform the + * action on. (e.g. TF_TBL_TYPE_FULL_ACTION subtype of module + * TF_MODULE_TYPE_TABLE) + */ + uint16_t subtype; + /** + * [in/out] Pointer to number of slices for the given type + */ + uint16_t *slices; +}; /** * Get InUse count parameters for single element @@ -394,6 +390,8 @@ struct tf_rm_check_indexes_in_range_parms { * @ref tf_rm_get_hcapi_type * * @ref tf_rm_get_inuse_count + * + * @ref tf_rm_get_slice_size */ /** @@ -571,5 +569,17 @@ int tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms); int tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms); +/** + * Get the number of slices per resource bit allocator for the resource type + * + * [in] parms + * Pointer to get inuse parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int +tf_rm_get_slices(struct tf_rm_get_slices_parms *parms); #endif /* TF_RM_NEW_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c index 90b65c59e6..3e6664e9f2 100644 --- a/drivers/net/bnxt/tf_core/tf_session.c +++ b/drivers/net/bnxt/tf_core/tf_session.c @@ -202,6 +202,7 @@ tf_session_create(struct tf *tfp, parms->open_cfg->device_type, session->shadow_copy, &parms->open_cfg->resources, + parms->open_cfg->wc_num_slices, &session->dev); /* Logging handled by dev_bind */ @@ -705,6 +706,22 @@ tf_session_get_session(struct tf *tfp, return rc; } +int tf_session_get(struct tf *tfp, + struct tf_session **tfs, + struct tf_dev_info **tfd) +{ + int rc; + rc = tf_session_get_session_internal(tfp, tfs); + + /* Logging done by tf_session_get_session_internal */ + if (rc) + return rc; + + rc = tf_session_get_device(*tfs, tfd); + + return rc; +} + struct tf_session_client * tf_session_get_session_client(struct tf_session *tfs, union tf_session_client_id session_client_id) @@ -1012,4 +1029,43 @@ tf_session_set_tcam_shared_db(struct tf *tfp, tfs->tcam_shared_db_handle = tcam_shared_db_handle; return rc; } + +int +tf_session_get_sram_db(struct tf *tfp, + void **sram_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + *sram_handle = NULL; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + *sram_handle = tfs->sram_handle; + return rc; +} + +int +tf_session_set_sram_db(struct tf *tfp, + void *sram_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + tfs->sram_handle = sram_handle; + return rc; +} + #endif /* TF_TCAM_SHARED */ diff --git a/drivers/net/bnxt/tf_core/tf_session.h b/drivers/net/bnxt/tf_core/tf_session.h index d68421cd13..c1d7f70060 100644 --- a/drivers/net/bnxt/tf_core/tf_session.h +++ b/drivers/net/bnxt/tf_core/tf_session.h @@ -166,6 +166,10 @@ struct tf_session { */ void *tcam_shared_db_handle; #endif /* TF_TCAM_SHARED */ + /** + * SRAM db reference for the session + */ + void *sram_handle; }; /** @@ -278,6 +282,10 @@ struct tf_session_close_session_parms { * * @ref tf_session_set_tcam_shared_db * #endif + * + * @ref tf_session_get_sram_db + * + * @ref tf_session_set_sram_db */ /** @@ -435,11 +443,11 @@ tf_session_find_session_client_by_fid(struct tf_session *tfs, /** * Looks up the device information from the TF Session. * - * [in] tfp - * Pointer to TF handle + * [in] tfs + * Pointer to session handle * * [out] tfd - * Pointer pointer to the device + * Pointer to the device * * Returns * - (0) if successful. @@ -448,6 +456,26 @@ tf_session_find_session_client_by_fid(struct tf_session *tfs, int tf_session_get_device(struct tf_session *tfs, struct tf_dev_info **tfd); +/** + * Returns the session and the device from the tfp. + * + * [in] tfp + * Pointer to TF handle + * + * [out] tfs + * Pointer to the session + * + * [out] tfd + * Pointer to the device + + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_session_get(struct tf *tfp, + struct tf_session **tfs, + struct tf_dev_info **tfd); + /** * Looks up the FW Session id the requested TF handle. * @@ -614,4 +642,28 @@ int tf_session_get_tcam_shared_db(struct tf *tfp, void **tcam_shared_db_handle); +/** + * Set the pointer to the SRAM database + * + * [in] session, pointer to the session + * + * Returns: + * - the pointer to the parent bnxt struct + */ +int +tf_session_set_sram_db(struct tf *tfp, + void *sram_handle); + +/** + * Get the pointer to the SRAM database + * + * [in] session, pointer to the session + * + * Returns: + * - the pointer to the parent bnxt struct + */ +int +tf_session_get_sram_db(struct tf *tfp, + void **sram_handle); + #endif /* _TF_SESSION_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_sram_mgr.c b/drivers/net/bnxt/tf_core/tf_sram_mgr.c new file mode 100644 index 0000000000..f633a78b25 --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_sram_mgr.c @@ -0,0 +1,971 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Broadcom + * All rights reserved. + */ +#include +#include +#include "tf_sram_mgr.h" +#include "tf_core.h" +#include "tf_rm.h" +#include "tf_common.h" +#include "assert.h" +#include "tf_util.h" +#include "tfp.h" +#if (STATS_CLEAR_ON_READ_SUPPORT == 0) +#include "tf_msg.h" +#endif +/*************************** + * Internal Data Structures + ***************************/ + +/** + * TF SRAM block info + * + * Contains all the information about a particular 64B SRAM + * block and the slices within it. + */ +struct tf_sram_block { + /* Previous block + */ + struct tf_sram_block *prev; + /* Next block + */ + struct tf_sram_block *next; + + /** Bitmap indicating which slices are in use + * If a bit is set, it indicates the slice + * in the row is in use. + */ + uint8_t in_use_mask; + + /** Block id - this is a 64B offset + */ + uint16_t block_id; +}; + +/** + * TF SRAM block list + * + * List of 64B SRAM blocks used for fixed size slices (8, 16, 32, 64B) + */ +struct tf_sram_slice_list { + /** Pointer to head of linked list of blocks. + */ + struct tf_sram_block *head; + + /** Pointer to tail of linked list of blocks. + */ + struct tf_sram_block *tail; + + /** Total count of blocks + */ + uint32_t cnt; + + /** First non-full block in the list + */ + struct tf_sram_block *first_not_full_block; + + /** Entry slice size for this list + */ + enum tf_sram_slice_size size; +}; + + +/** + * TF SRAM bank info consists of lists of different slice sizes per bank + */ +struct tf_sram_bank_info { + struct tf_sram_slice_list slice[TF_SRAM_SLICE_SIZE_MAX]; +}; + +/** + * SRAM banks consist of SRAM bank information + */ +struct tf_sram_bank { + struct tf_sram_bank_info bank[TF_SRAM_BANK_ID_MAX]; +}; + +/** + * SRAM banks consist of SRAM bank information + */ +struct tf_sram { + struct tf_sram_bank dir[TF_DIR_MAX]; +}; + +/********************** + * Internal functions + **********************/ + +/** + * Get slice size in string format + */ +const char +*tf_sram_slice_2_str(enum tf_sram_slice_size slice_size) +{ + switch (slice_size) { + case TF_SRAM_SLICE_SIZE_8B: + return "8B slice"; + case TF_SRAM_SLICE_SIZE_16B: + return "16B slice"; + case TF_SRAM_SLICE_SIZE_32B: + return "32B slice"; + case TF_SRAM_SLICE_SIZE_64B: + return "64B slice"; + default: + return "Invalid slice size"; + } +} + +/** + * Get bank in string format + */ +const char +*tf_sram_bank_2_str(enum tf_sram_bank_id bank_id) +{ + switch (bank_id) { + case TF_SRAM_BANK_ID_0: + return "bank_0"; + case TF_SRAM_BANK_ID_1: + return "bank_1"; + case TF_SRAM_BANK_ID_2: + return "bank_2"; + case TF_SRAM_BANK_ID_3: + return "bank_3"; + default: + return "Invalid bank_id"; + } +} + +/** + * TF SRAM get slice list + */ +static int +tf_sram_get_slice_list(struct tf_sram *sram, + struct tf_sram_slice_list **slice_list, + enum tf_sram_slice_size slice_size, + enum tf_dir dir, + enum tf_sram_bank_id bank_id) +{ + int rc = 0; + + TF_CHECK_PARMS2(sram, slice_list); + + *slice_list = &sram->dir[dir].bank[bank_id].slice[slice_size]; + + return rc; +} + +uint16_t tf_sram_bank_2_base_offset[TF_SRAM_BANK_ID_MAX] = { + 0, + 2048, + 4096, + 6144 +}; + +/** + * Translate a block id and bank_id to an 8B offset + */ +static void +tf_sram_block_id_2_offset(enum tf_sram_bank_id bank_id, uint16_t block_id, + uint16_t *offset) +{ + *offset = (block_id + tf_sram_bank_2_base_offset[bank_id]) << 3; +} + +/** + * Translates an 8B offset and bank_id to a block_id + */ +static void +tf_sram_offset_2_block_id(enum tf_sram_bank_id bank_id, uint16_t offset, + uint16_t *block_id, uint16_t *slice_offset) +{ + *slice_offset = offset & 0x7; + *block_id = ((offset & ~0x7) >> 3) - + tf_sram_bank_2_base_offset[bank_id]; +} + +/** + * Find a matching block_id within the slice list + */ +static struct tf_sram_block +*tf_sram_find_block(uint16_t block_id, struct tf_sram_slice_list *slice_list) +{ + uint32_t cnt; + struct tf_sram_block *block; + + cnt = slice_list->cnt; + block = slice_list->head; + + while (cnt > 0 && block) { + if (block->block_id == block_id) + return block; + block = block->next; + cnt--; + } + return NULL; +} + +/** + * Given the current block get the next block within the slice list + * + * List is not changed. + */ +static struct tf_sram_block +*tf_sram_get_next_block(struct tf_sram_block *block) +{ + struct tf_sram_block *nblock; + + if (block != NULL) + nblock = block->next; + else + nblock = NULL; + return nblock; +} + +/** + * Free an allocated slice from a block and if the block is empty, + * return an indication so that the block can be freed. + */ +static int +tf_sram_free_slice(enum tf_sram_slice_size slice_size, + uint16_t slice_offset, struct tf_sram_block *block, + bool *block_is_empty) +{ + int rc = 0; + uint8_t shift; + uint8_t slice_mask = 0; + + TF_CHECK_PARMS2(block, block_is_empty); + + switch (slice_size) { + case TF_SRAM_SLICE_SIZE_8B: + shift = slice_offset >> 0; + assert(shift < 8); + slice_mask = 1 << shift; + break; + + case TF_SRAM_SLICE_SIZE_16B: + shift = slice_offset >> 1; + assert(shift < 4); + slice_mask = 1 << shift; + break; + + case TF_SRAM_SLICE_SIZE_32B: + shift = slice_offset >> 2; + assert(shift < 2); + slice_mask = 1 << shift; + break; + + case TF_SRAM_SLICE_SIZE_64B: + default: + shift = slice_offset >> 0; + assert(shift < 1); + slice_mask = 1 << shift; + break; + } + + if ((block->in_use_mask & slice_mask) == 0) { + rc = -EINVAL; + TFP_DRV_LOG(ERR, "block_id(0x%x) slice(%d) was not allocated\n", + block->block_id, slice_offset); + return rc; + } + + block->in_use_mask &= ~slice_mask; + + if (block->in_use_mask == 0) + *block_is_empty = true; + else + *block_is_empty = false; + + return rc; +} + +/** + * TF SRAM get next slice + * + * Gets the next slice_offset available in the block + * and updates the in_use_mask. + */ +static int +tf_sram_get_next_slice_in_block(struct tf_sram_block *block, + enum tf_sram_slice_size slice_size, + uint16_t *slice_offset, + bool *block_is_full) +{ + int rc, free_id = -1; + uint8_t shift, max_slices, mask, i, full_mask; + + TF_CHECK_PARMS3(block, slice_offset, block_is_full); + + switch (slice_size) { + case TF_SRAM_SLICE_SIZE_8B: + shift = 0; + max_slices = 8; + full_mask = 0xff; + break; + case TF_SRAM_SLICE_SIZE_16B: + shift = 1; + max_slices = 4; + full_mask = 0xf; + break; + case TF_SRAM_SLICE_SIZE_32B: + shift = 2; + max_slices = 2; + full_mask = 0x3; + break; + case TF_SRAM_SLICE_SIZE_64B: + default: + shift = 0; + max_slices = 1; + full_mask = 1; + break; + } + + mask = block->in_use_mask; + + for (i = 0; i < max_slices; i++) { + if ((mask & 1) == 0) { + free_id = i; + block->in_use_mask |= 1 << free_id; + break; + } + mask = mask >> 1; + } + + if (block->in_use_mask == full_mask) + *block_is_full = true; + else + *block_is_full = false; + + + if (free_id >= 0) { + *slice_offset = free_id << shift; + rc = 0; + } else { + *slice_offset = 0; + rc = -ENOMEM; + } + + return rc; +} + +/** + * TF SRAM get indication as to whether the slice offset is + * allocated in the block. + * + */ +static int +tf_sram_is_slice_allocated_in_block(struct tf_sram_block *block, + enum tf_sram_slice_size slice_size, + uint16_t slice_offset, + bool *is_allocated) +{ + int rc = 0; + uint8_t shift; + uint8_t slice_mask = 0; + + TF_CHECK_PARMS2(block, is_allocated); + + *is_allocated = false; + + switch (slice_size) { + case TF_SRAM_SLICE_SIZE_8B: + shift = slice_offset >> 0; + assert(shift < 8); + slice_mask = 1 << shift; + break; + + case TF_SRAM_SLICE_SIZE_16B: + shift = slice_offset >> 1; + assert(shift < 4); + slice_mask = 1 << shift; + break; + + case TF_SRAM_SLICE_SIZE_32B: + shift = slice_offset >> 2; + assert(shift < 2); + slice_mask = 1 << shift; + break; + + case TF_SRAM_SLICE_SIZE_64B: + default: + shift = slice_offset >> 0; + assert(shift < 1); + slice_mask = 1 << shift; + break; + } + + if ((block->in_use_mask & slice_mask) == 0) { + TFP_DRV_LOG(ERR, "block_id(0x%x) slice(%d) was not allocated\n", + block->block_id, slice_offset); + *is_allocated = false; + } else { + *is_allocated = true; + } + + return rc; +} + +/** + * Initialize slice list + */ +static void +tf_sram_init_slice_list(struct tf_sram_slice_list *slice_list, + enum tf_sram_slice_size slice_size) +{ + slice_list->head = NULL; + slice_list->tail = NULL; + slice_list->cnt = 0; + slice_list->size = slice_size; +} + +/** + * Get the block count + */ +static uint32_t +tf_sram_get_block_cnt(struct tf_sram_slice_list *slice_list) +{ + return slice_list->cnt; +} + + +/** + * Free a block data structure - does not free to the RM + */ +static void +tf_sram_free_block(struct tf_sram_slice_list *slice_list, + struct tf_sram_block *block) +{ + if (slice_list->head == block && slice_list->tail == block) { + slice_list->head = NULL; + slice_list->tail = NULL; + } else if (slice_list->head == block) { + slice_list->head = block->next; + slice_list->head->prev = NULL; + } else if (slice_list->tail == block) { + slice_list->tail = block->prev; + slice_list->tail->next = NULL; + } else { + block->prev->next = block->next; + block->next->prev = block->prev; + } + tfp_free(block); + slice_list->cnt--; +} +/** + * Free the entire slice_list + */ +static void +tf_sram_free_slice_list(struct tf_sram_slice_list *slice_list) +{ + uint32_t i, block_cnt; + struct tf_sram_block *nblock, *block; + + block_cnt = tf_sram_get_block_cnt(slice_list); + block = slice_list->head; + + for (i = 0; i < block_cnt; i++) { + nblock = block->next; + tf_sram_free_block(slice_list, block); + block = nblock; + } +} + +/** + * Allocate a single SRAM block from memory and add it to the slice list + */ +static struct tf_sram_block +*tf_sram_alloc_block(struct tf_sram_slice_list *slice_list, + uint16_t block_id) +{ + struct tf_sram_block *block; + struct tfp_calloc_parms cparms; + int rc; + + cparms.nitems = 1; + cparms.size = sizeof(struct tf_sram_block); + cparms.alignment = 0; + rc = tfp_calloc(&cparms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "Failed to allocate block, rc:%s\n", + strerror(-rc)); + return NULL; + } + block = (struct tf_sram_block *)cparms.mem_va; + block->block_id = block_id; + + if (slice_list->head == NULL) { + slice_list->head = block; + slice_list->tail = block; + block->next = NULL; + block->prev = NULL; + } else { + block->next = slice_list->head; + block->prev = NULL; + block->next->prev = block; + slice_list->head = block->next->prev; + } + slice_list->cnt++; + return block; +} + +/** + * Find the first not full block in the slice list + */ +static void +tf_sram_find_first_not_full_block(struct tf_sram_slice_list *slice_list, + enum tf_sram_slice_size slice_size, + struct tf_sram_block **first_not_full_block) +{ + struct tf_sram_block *block = slice_list->head; + uint8_t slice_mask, mask; + + switch (slice_size) { + case TF_SRAM_SLICE_SIZE_8B: + slice_mask = 0xff; + break; + + case TF_SRAM_SLICE_SIZE_16B: + slice_mask = 0xf; + break; + + case TF_SRAM_SLICE_SIZE_32B: + slice_mask = 0x3; + break; + + case TF_SRAM_SLICE_SIZE_64B: + default: + slice_mask = 0x1; + break; + } + + *first_not_full_block = NULL; + + while (block) { + mask = block->in_use_mask & slice_mask; + if (mask != slice_mask) { + *first_not_full_block = block; + break; + } + block = block->next; + } +} +static void +tf_sram_dump_block(struct tf_sram_block *block) +{ + TFP_DRV_LOG(INFO, "block_id(0x%x) in_use_mask(0x%02x)\n", + block->block_id, + block->in_use_mask); +} + +/********************** + * External functions + **********************/ +int +tf_sram_mgr_bind(void **sram_handle) +{ + int rc = 0; + enum tf_sram_bank_id bank_id; + enum tf_sram_slice_size slice_size; + struct tf_sram *sram; + struct tf_sram_slice_list *slice_list; + enum tf_dir dir; + struct tfp_calloc_parms cparms; + + TF_CHECK_PARMS1(sram_handle); + + cparms.nitems = 1; + cparms.size = sizeof(struct tf_sram); + cparms.alignment = 0; + rc = tfp_calloc(&cparms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "Failed to allocate SRAM mgmt data, rc:%s\n", + strerror(-rc)); + return rc; + } + sram = (struct tf_sram *)cparms.mem_va; + + /* For each direction + */ + for (dir = 0; dir < TF_DIR_MAX; dir++) { + /* For each bank + */ + for (bank_id = TF_SRAM_BANK_ID_0; + bank_id < TF_SRAM_BANK_ID_MAX; + bank_id++) { + /* Create each sized slice empty list + */ + for (slice_size = TF_SRAM_SLICE_SIZE_8B; + slice_size < TF_SRAM_SLICE_SIZE_MAX; + slice_size++) { + rc = tf_sram_get_slice_list(sram, &slice_list, + slice_size, dir, + bank_id); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "No SRAM slice list, rc:%s\n", + strerror(-rc)); + return rc; + } + tf_sram_init_slice_list(slice_list, slice_size); + } + } + } + + *sram_handle = sram; + + return rc; +} + +int +tf_sram_mgr_unbind(void *sram_handle) +{ + int rc = 0; + struct tf_sram *sram; + enum tf_sram_bank_id bank_id; + enum tf_sram_slice_size slice_size; + enum tf_dir dir; + struct tf_sram_slice_list *slice_list; + + TF_CHECK_PARMS1(sram_handle); + + sram = (struct tf_sram *)sram_handle; + + for (dir = 0; dir < TF_DIR_MAX; dir++) { + /* For each bank + */ + for (bank_id = TF_SRAM_BANK_ID_0; + bank_id < TF_SRAM_BANK_ID_MAX; + bank_id++) { + /* For each slice size + */ + for (slice_size = TF_SRAM_SLICE_SIZE_8B; + slice_size < TF_SRAM_SLICE_SIZE_MAX; + slice_size++) { + rc = tf_sram_get_slice_list(sram, &slice_list, + slice_size, dir, + bank_id); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "No SRAM slice list, rc:%s\n", + strerror(-rc)); + return rc; + } + if (tf_sram_get_block_cnt(slice_list)) + tf_sram_free_slice_list(slice_list); + } + } + } + + tfp_free(sram); + sram_handle = NULL; + + /* Freeing of the RM resources is handled by the table manager */ + return rc; +} + +int tf_sram_mgr_alloc(void *sram_handle, + struct tf_sram_mgr_alloc_parms *parms) +{ + int rc = 0; + struct tf_sram *sram; + struct tf_sram_slice_list *slice_list; + uint16_t block_id, slice_offset = 0; + uint32_t index; + struct tf_sram_block *block; + struct tf_rm_allocate_parms aparms = { 0 }; + bool block_is_full; + uint16_t block_offset; + + TF_CHECK_PARMS3(sram_handle, parms, parms->sram_offset); + + sram = (struct tf_sram *)sram_handle; + + /* Check the current slice list + */ + rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size, + parms->dir, parms->bank_id); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "No SRAM slice list, rc:%s\n", + strerror(-rc)); + return rc; + } + + /* If the list is empty or all entries are full allocate a new block + */ + if (!slice_list->first_not_full_block) { + /* Allocate and insert a new block + */ + aparms.index = &index; + aparms.subtype = parms->tbl_type; + aparms.rm_db = parms->rm_db; + rc = tf_rm_allocate(&aparms); + if (rc) + return rc; + + block_id = index; + block = tf_sram_alloc_block(slice_list, block_id); + } else { + /* Block exists + */ + block = + (struct tf_sram_block *)(slice_list->first_not_full_block); + } + rc = tf_sram_get_next_slice_in_block(block, + parms->slice_size, + &slice_offset, + &block_is_full); + + /* Find the new first non-full block in the list + */ + tf_sram_find_first_not_full_block(slice_list, + parms->slice_size, + &slice_list->first_not_full_block); + + tf_sram_block_id_2_offset(parms->bank_id, block->block_id, + &block_offset); + + *parms->sram_offset = block_offset + slice_offset; + return rc; +} + +int +tf_sram_mgr_free(void *sram_handle, + struct tf_sram_mgr_free_parms *parms) +{ + int rc = 0; + struct tf_sram *sram; + struct tf_sram_slice_list *slice_list; + uint16_t block_id, slice_offset; + struct tf_sram_block *block; + bool block_is_empty; + struct tf_rm_free_parms fparms = { 0 }; + + TF_CHECK_PARMS2(sram_handle, parms); + + sram = (struct tf_sram *)sram_handle; + + /* Check the current slice list + */ + rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size, + parms->dir, parms->bank_id); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "No SRAM slice list, rc:%s\n", + strerror(-rc)); + return rc; + } + + /* Determine the block id and slice offset from the SRAM offset + */ + tf_sram_offset_2_block_id(parms->bank_id, parms->sram_offset, &block_id, + &slice_offset); + + /* Search the list of blocks for the matching block id + */ + block = tf_sram_find_block(block_id, slice_list); + if (block == NULL) { + TFP_DRV_LOG(ERR, "block not found 0x%x\n", block_id); + return rc; + } + + /* If found, search for the matching SRAM slice in use. + */ + rc = tf_sram_free_slice(parms->slice_size, slice_offset, + block, &block_is_empty); + if (rc) { + TFP_DRV_LOG(ERR, "Error freeing slice (%s)\n", strerror(-rc)); + return rc; + } +#if (STATS_CLEAR_ON_READ_SUPPORT == 0) + /* If this is a counter, clear it. In the future we need to switch to + * using the special access registers on Thor to automatically clear on + * read. + */ + /* If this is counter table, clear the entry on free */ + if (parms->tbl_type == TF_TBL_TYPE_ACT_STATS_64) { + uint8_t data[8] = { 0 }; + uint16_t hcapi_type = 0; + struct tf_rm_get_hcapi_parms hparms = { 0 }; + + /* Get the hcapi type */ + hparms.rm_db = parms->rm_db; + hparms.subtype = parms->tbl_type; + hparms.hcapi_type = &hcapi_type; + rc = tf_rm_get_hcapi_type(&hparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Failed type lookup, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->tbl_type), + strerror(-rc)); + return rc; + } + /* Clear the counter + */ + rc = tf_msg_set_tbl_entry(parms->tfp, + parms->dir, + hcapi_type, + sizeof(data), + data, + parms->sram_offset); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Set failed, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->tbl_type), + strerror(-rc)); + return rc; + } + } +#endif + /* If the block is empty, free the block to the RM + */ + if (block_is_empty) { + fparms.rm_db = parms->rm_db; + fparms.subtype = parms->tbl_type; + fparms.index = block_id; + rc = tf_rm_free(&fparms); + + if (rc) { + TFP_DRV_LOG(ERR, "Free block_id(%d) failed error(%s)\n", + block_id, strerror(-rc)); + } + /* Free local entry regardless + */ + tf_sram_free_block(slice_list, block); + + /* Find the next non-full block in the list + */ + tf_sram_find_first_not_full_block(slice_list, + parms->slice_size, + &slice_list->first_not_full_block); + } + + return rc; +} + +int +tf_sram_mgr_dump(void *sram_handle, + struct tf_sram_mgr_dump_parms *parms) +{ + int rc = 0; + struct tf_sram *sram; + struct tf_sram_slice_list *slice_list; + uint32_t block_cnt, i; + struct tf_sram_block *block; + + TF_CHECK_PARMS2(sram_handle, parms); + + sram = (struct tf_sram *)sram_handle; + + rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size, + parms->dir, parms->bank_id); + if (rc) + return rc; + + if (slice_list->cnt || slice_list->first_not_full_block) { + TFP_DRV_LOG(INFO, "\n********** %s: %s: %s ***********\n", + tf_sram_bank_2_str(parms->bank_id), + tf_dir_2_str(parms->dir), + tf_sram_slice_2_str(parms->slice_size)); + + block_cnt = tf_sram_get_block_cnt(slice_list); + TFP_DRV_LOG(INFO, "block_cnt(%d)\n", block_cnt); + if (slice_list->first_not_full_block) + TFP_DRV_LOG(INFO, "first_not_full_block(0x%x)\n", + slice_list->first_not_full_block->block_id); + block = slice_list->head; + for (i = 0; i < block_cnt; i++) { + tf_sram_dump_block(block); + block = tf_sram_get_next_block(block); + } + TFP_DRV_LOG(INFO, "*********************************\n"); + } + return rc; +} +/** + * Validate an SRAM Slice is allocated + * + * Validate whether the SRAM slice is allocated + * + * [in] sram_handle + * Pointer to SRAM handle + * + * [in] parms + * Pointer to the SRAM alloc parameters + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + */ +int tf_sram_mgr_is_allocated(void *sram_handle, + struct tf_sram_mgr_is_allocated_parms *parms) +{ + int rc = 0; + struct tf_sram *sram; + struct tf_sram_slice_list *slice_list; + uint16_t block_id, slice_offset; + struct tf_sram_block *block; + + TF_CHECK_PARMS3(sram_handle, parms, parms->is_allocated); + + sram = (struct tf_sram *)sram_handle; + + /* Check the current slice list + */ + rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size, + parms->dir, parms->bank_id); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "No SRAM slice list, rc:%s\n", + strerror(-rc)); + return rc; + } + + /* If the list is empty, then it cannot be allocated + */ + if (!slice_list->cnt) { + TFP_DRV_LOG(ERR, "List is empty for %s:%s:%s\n", + tf_dir_2_str(parms->dir), + tf_sram_slice_2_str(parms->slice_size), + tf_sram_bank_2_str(parms->bank_id)); + + parms->is_allocated = false; + goto done; + } + + /* Determine the block id and slice offset from the SRAM offset + */ + tf_sram_offset_2_block_id(parms->bank_id, parms->sram_offset, &block_id, + &slice_offset); + + /* Search the list of blocks for the matching block id + */ + block = tf_sram_find_block(block_id, slice_list); + if (block == NULL) { + TFP_DRV_LOG(ERR, "block not found in list 0x%x\n", + parms->sram_offset); + parms->is_allocated = false; + goto done; + } + + rc = tf_sram_is_slice_allocated_in_block(block, + parms->slice_size, + slice_offset, + parms->is_allocated); +done: + return rc; +} diff --git a/drivers/net/bnxt/tf_core/tf_sram_mgr.h b/drivers/net/bnxt/tf_core/tf_sram_mgr.h new file mode 100644 index 0000000000..4abe3fb468 --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_sram_mgr.h @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Broadcom + * All rights reserved. + */ + +#ifndef _TF_SRAM_MGR_H_ +#define _TF_SRAM_MGR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tf_core.h" +#include "tf_rm.h" + +/* When special access registers are used to access the SRAM, stats can be + * automatically cleared on read by the hardware. This requires additional + * support to be added in the firmware to use these registers for statistics. + * The support entails using the special access registers to read the stats. + * These are stored in bank 3 currently but may move depending upon the + * policy defined in tf_device_p58.h + */ +#define STATS_CLEAR_ON_READ_SUPPORT 0 + +#define TF_SRAM_MGR_BLOCK_SZ_BYTES 64 +#define TF_SRAM_MGR_MIN_SLICE_BYTES 8 +/** + * Bank identifier + */ +enum tf_sram_bank_id { + TF_SRAM_BANK_ID_0, /**< SRAM Bank 0 id */ + TF_SRAM_BANK_ID_1, /**< SRAM Bank 1 id */ + TF_SRAM_BANK_ID_2, /**< SRAM Bank 2 id */ + TF_SRAM_BANK_ID_3, /**< SRAM Bank 3 id */ + TF_SRAM_BANK_ID_MAX /**< SRAM Bank index limit */ +}; + +/** + * TF slice size. + * + * A slice is part of a 64B row + * + * Each slice is a multiple of 8B + */ +enum tf_sram_slice_size { + TF_SRAM_SLICE_SIZE_8B, /**< 8 byte SRAM slice */ + TF_SRAM_SLICE_SIZE_16B, /**< 16 byte SRAM slice */ + TF_SRAM_SLICE_SIZE_32B, /**< 32 byte SRAM slice */ + TF_SRAM_SLICE_SIZE_64B, /**< 64 byte SRAM slice */ + TF_SRAM_SLICE_SIZE_MAX /**< slice limit */ +}; + + +/** Initialize the SRAM slice manager + * + * The SRAM slice manager manages slices within 64B rows. Slices are of size + * tf_sram_slice_size. This function provides a handle to the SRAM manager + * data. + * + * SRAM manager data may dynamically allocate data upon initialization if + * running on the host. + * + * [in/out] sram_handle + * Pointer to SRAM handle + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + * Returns the handle for the SRAM slice manager + */ +int tf_sram_mgr_bind(void **sram_handle); + +/** Uninitialize the SRAM slice manager + * + * Frees any dynamically allocated data structures for SRAM slice management. + * + * [in] sram_handle + * Pointer to SRAM handle + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + */ +int tf_sram_mgr_unbind(void *sram_handle); + +/** + * tf_sram_mgr_alloc_parms parameter definition + */ +struct tf_sram_mgr_alloc_parms { + /** + * [in] dir + */ + enum tf_dir dir; + /** + * [in] bank + * + * the SRAM bank to allocate from + */ + enum tf_sram_bank_id bank_id; + /** + * [in] slice_size + * + * the slice size to allocate + */ + enum tf_sram_slice_size slice_size; + /** + * [in/out] sram_slice + * + * A pointer to be filled with an 8B sram slice offset + */ + uint16_t *sram_offset; + /** + * [in] RM DB Handle required for RM allocation + */ + void *rm_db; + /** + * [in] tf table type + */ + enum tf_tbl_type tbl_type; +}; + +/** + * Allocate an SRAM Slice + * + * Allocate an SRAM slice from the indicated bank. If successful an 8B SRAM + * offset will be returned. Slices are variable sized. This may result in + * a row being allocated from the RM SRAM bank pool if required. + * + * [in] sram_handle + * Pointer to SRAM handle + * + * [in] parms + * Pointer to the SRAM alloc parameters + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + */ +int tf_sram_mgr_alloc(void *sram_handle, + struct tf_sram_mgr_alloc_parms *parms); +/** + * tf_sram_mgr_free_parms parameter definition + */ +struct tf_sram_mgr_free_parms { + /** + * [in] dir + */ + enum tf_dir dir; + /** + * [in] bank + * + * the SRAM bank to free to + */ + enum tf_sram_bank_id bank_id; + /** + * [in] slice_size + * + * the slice size to be returned + */ + enum tf_sram_slice_size slice_size; + /** + * [in] sram_offset + * + * the SRAM slice offset (8B) to be returned + */ + uint16_t sram_offset; + /** + * [in] RM DB Handle required for RM free + */ + void *rm_db; + /** + * [in] tf table type + */ + enum tf_tbl_type tbl_type; +#if (STATS_CLEAR_ON_READ_SUPPORT == 0) + /** + * [in] tfp + * + * A pointer to the tf handle + */ + void *tfp; +#endif +}; + +/** + * Free an SRAM Slice + * + * Free an SRAM slice to the indicated bank. This may result in a 64B row + * being returned to the RM SRAM bank pool. + * + * [in] sram_handle + * Pointer to SRAM handle + * + * [in] parms + * Pointer to the SRAM free parameters + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + */ +int tf_sram_mgr_free(void *sram_handle, + struct tf_sram_mgr_free_parms *parms); + +/** + * tf_sram_mgr_dump_parms parameter definition + */ +struct tf_sram_mgr_dump_parms { + /** + * [in] dir + */ + enum tf_dir dir; + /** + * [in] bank + * + * the SRAM bank to dump + */ + enum tf_sram_bank_id bank_id; + /** + * [in] slice_size + * + * the slice size list to be dumped + */ + enum tf_sram_slice_size slice_size; +}; + +/** + * Dump a slice list + * + * Dump the slice list given the SRAM bank and the slice size + * + * [in] sram_handle + * Pointer to SRAM handle + * + * [in] parms + * Pointer to the SRAM free parameters + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + */ +int tf_sram_mgr_dump(void *sram_handle, + struct tf_sram_mgr_dump_parms *parms); + +/** + * tf_sram_mgr_is_allocated_parms parameter definition + */ +struct tf_sram_mgr_is_allocated_parms { + /** + * [in] dir + */ + enum tf_dir dir; + /** + * [in] bank + * + * the SRAM bank to allocate from + */ + enum tf_sram_bank_id bank_id; + /** + * [in] slice_size + * + * the slice size which was allocated + */ + enum tf_sram_slice_size slice_size; + /** + * [in] sram_offset + * + * The sram slice offset to validate + */ + uint16_t sram_offset; + /** + * [in/out] is_allocated + * + * Pointer passed in to be filled with indication of allocation + */ + bool *is_allocated; +}; + +/** + * Validate an SRAM Slice is allocated + * + * Validate whether the SRAM slice is allocated + * + * [in] sram_handle + * Pointer to SRAM handle + * + * [in] parms + * Pointer to the SRAM alloc parameters + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + */ +int tf_sram_mgr_is_allocated(void *sram_handle, + struct tf_sram_mgr_is_allocated_parms *parms); + +/** + * Given the slice size, return a char string + */ +const char +*tf_sram_slice_2_str(enum tf_sram_slice_size slice_size); + +/** + * Given the bank_id, return a char string + */ +const char +*tf_sram_bank_2_str(enum tf_sram_bank_id bank_id); + +#endif /* _TF_SRAM_MGR_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_tbl.c b/drivers/net/bnxt/tf_core/tf_tbl.c index 7011edcd78..0a8720e7b6 100644 --- a/drivers/net/bnxt/tf_core/tf_tbl.c +++ b/drivers/net/bnxt/tf_core/tf_tbl.c @@ -16,20 +16,11 @@ #include "tf_session.h" #include "tf_device.h" -#define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) { \ - *(new_idx) = (((idx) + (base)) << (shift)); \ -} - -#define TF_TBL_PTR_TO_RM(new_idx, idx, base, shift) { \ - *(new_idx) = (((idx) >> (shift)) - (base)); \ -} - struct tf; -/** - * Shadow init flag, set on bind and cleared on unbind - */ -static uint8_t shadow_init; +#define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) { \ + *(new_idx) = (((idx) + (base)) << (shift)); \ +} int tf_tbl_bind(struct tf *tfp, @@ -121,8 +112,6 @@ tf_tbl_unbind(struct tf *tfp) tbl_db->tbl_db[i] = NULL; } - shadow_init = 0; - return 0; } @@ -135,7 +124,6 @@ tf_tbl_alloc(struct tf *tfp __rte_unused, struct tf_rm_allocate_parms aparms = { 0 }; struct tf_session *tfs; struct tf_dev_info *dev; - uint16_t base = 0, shift = 0; struct tbl_rm_db *tbl_db; void *tbl_db_ptr = NULL; @@ -154,28 +142,12 @@ tf_tbl_alloc(struct tf *tfp __rte_unused, rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); if (rc) { TFP_DRV_LOG(ERR, - "Failed to get em_ext_db from session, rc:%s\n", + "Failed to get tbl_db from session, rc:%s\n", strerror(-rc)); return rc; } tbl_db = (struct tbl_rm_db *)tbl_db_ptr; - /* Only get table info if required for the device */ - if (dev->ops->tf_dev_get_tbl_info) { - rc = dev->ops->tf_dev_get_tbl_info(tfp, - tbl_db->tbl_db[parms->dir], - parms->type, - &base, - &shift); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: Failed to get table info:%d\n", - tf_dir_2_str(parms->dir), - parms->type); - return rc; - } - } - /* Allocate requested element */ aparms.rm_db = tbl_db->tbl_db[parms->dir]; aparms.subtype = parms->type; @@ -183,13 +155,12 @@ tf_tbl_alloc(struct tf *tfp __rte_unused, rc = tf_rm_allocate(&aparms); if (rc) { TFP_DRV_LOG(ERR, - "%s: Failed allocate, type:%d\n", + "%s: Failed allocate, type:%s\n", tf_dir_2_str(parms->dir), - parms->type); + tf_tbl_type_2_str(parms->type)); return rc; } - TF_TBL_RM_TO_PTR(&idx, idx, base, shift); *parms->idx = idx; return 0; @@ -205,7 +176,6 @@ tf_tbl_free(struct tf *tfp __rte_unused, int allocated = 0; struct tf_session *tfs; struct tf_dev_info *dev; - uint16_t base = 0, shift = 0; struct tbl_rm_db *tbl_db; void *tbl_db_ptr = NULL; @@ -230,28 +200,10 @@ tf_tbl_free(struct tf *tfp __rte_unused, } tbl_db = (struct tbl_rm_db *)tbl_db_ptr; - /* Only get table info if required for the device */ - if (dev->ops->tf_dev_get_tbl_info) { - rc = dev->ops->tf_dev_get_tbl_info(tfp, - tbl_db->tbl_db[parms->dir], - parms->type, - &base, - &shift); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: Failed to get table info:%d\n", - tf_dir_2_str(parms->dir), - parms->type); - return rc; - } - } - /* Check if element is in use */ aparms.rm_db = tbl_db->tbl_db[parms->dir]; aparms.subtype = parms->type; - - TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift); - + aparms.index = parms->idx; aparms.allocated = &allocated; rc = tf_rm_is_allocated(&aparms); if (rc) @@ -259,9 +211,9 @@ tf_tbl_free(struct tf *tfp __rte_unused, if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { TFP_DRV_LOG(ERR, - "%s: Entry already free, type:%d, index:%d\n", + "%s: Entry already free, type:%s, index:%d\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), parms->idx); return -EINVAL; } @@ -279,9 +231,9 @@ tf_tbl_free(struct tf *tfp __rte_unused, rc = tf_rm_get_hcapi_type(&hparms); if (rc) { TFP_DRV_LOG(ERR, - "%s, Failed type lookup, type:%d, rc:%s\n", + "%s, Failed type lookup, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -295,9 +247,9 @@ tf_tbl_free(struct tf *tfp __rte_unused, parms->idx); if (rc) { TFP_DRV_LOG(ERR, - "%s, Set failed, type:%d, rc:%s\n", + "%s, Set failed, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -306,15 +258,13 @@ tf_tbl_free(struct tf *tfp __rte_unused, /* Free requested element */ fparms.rm_db = tbl_db->tbl_db[parms->dir]; fparms.subtype = parms->type; - - TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift); - + fparms.index = parms->idx; rc = tf_rm_free(&fparms); if (rc) { TFP_DRV_LOG(ERR, - "%s: Free failed, type:%d, index:%d\n", + "%s: Free failed, type:%s, index:%d\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), parms->idx); return rc; } @@ -333,7 +283,6 @@ tf_tbl_set(struct tf *tfp, struct tf_rm_get_hcapi_parms hparms = { 0 }; struct tf_session *tfs; struct tf_dev_info *dev; - uint16_t base = 0, shift = 0; struct tbl_rm_db *tbl_db; void *tbl_db_ptr = NULL; @@ -358,21 +307,6 @@ tf_tbl_set(struct tf *tfp, } tbl_db = (struct tbl_rm_db *)tbl_db_ptr; - /* Only get table info if required for the device */ - if (dev->ops->tf_dev_get_tbl_info) { - rc = dev->ops->tf_dev_get_tbl_info(tfp, - tbl_db->tbl_db[parms->dir], - parms->type, - &base, - &shift); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: Failed to get table info:%d\n", - tf_dir_2_str(parms->dir), - parms->type); - return rc; - } - } /* Do not check meter drop counter because it is not allocated * resources @@ -381,19 +315,18 @@ tf_tbl_set(struct tf *tfp, /* Verify that the entry has been previously allocated */ aparms.rm_db = tbl_db->tbl_db[parms->dir]; aparms.subtype = parms->type; - TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift); - aparms.allocated = &allocated; + aparms.index = parms->idx; rc = tf_rm_is_allocated(&aparms); if (rc) return rc; if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { TFP_DRV_LOG(ERR, - "%s, Invalid or not allocated index, type:%d, idx:%d\n", - tf_dir_2_str(parms->dir), - parms->type, - parms->idx); + "%s, Invalid or not allocated, type:%s, idx:%d\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + parms->idx); return -EINVAL; } } @@ -405,9 +338,9 @@ tf_tbl_set(struct tf *tfp, rc = tf_rm_get_hcapi_type(&hparms); if (rc) { TFP_DRV_LOG(ERR, - "%s, Failed type lookup, type:%d, rc:%s\n", + "%s, Failed type lookup, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -420,9 +353,9 @@ tf_tbl_set(struct tf *tfp, parms->idx); if (rc) { TFP_DRV_LOG(ERR, - "%s, Set failed, type:%d, rc:%s\n", + "%s, Set failed, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -441,7 +374,6 @@ tf_tbl_get(struct tf *tfp, struct tf_rm_get_hcapi_parms hparms = { 0 }; struct tf_session *tfs; struct tf_dev_info *dev; - uint16_t base = 0, shift = 0; struct tbl_rm_db *tbl_db; void *tbl_db_ptr = NULL; @@ -466,22 +398,6 @@ tf_tbl_get(struct tf *tfp, } tbl_db = (struct tbl_rm_db *)tbl_db_ptr; - /* Only get table info if required for the device */ - if (dev->ops->tf_dev_get_tbl_info) { - rc = dev->ops->tf_dev_get_tbl_info(tfp, - tbl_db->tbl_db[parms->dir], - parms->type, - &base, - &shift); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: Failed to get table info:%d\n", - tf_dir_2_str(parms->dir), - parms->type); - return rc; - } - } - /* Do not check meter drop counter because it is not allocated * resources. */ @@ -489,8 +405,7 @@ tf_tbl_get(struct tf *tfp, /* Verify that the entry has been previously allocated */ aparms.rm_db = tbl_db->tbl_db[parms->dir]; aparms.subtype = parms->type; - TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift); - + aparms.index = parms->idx; aparms.allocated = &allocated; rc = tf_rm_is_allocated(&aparms); if (rc) @@ -498,9 +413,9 @@ tf_tbl_get(struct tf *tfp, if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) { TFP_DRV_LOG(ERR, - "%s, Invalid or not allocated index, type:%d, idx:%d\n", + "%s, Invalid or not allocated index, type:%s, idx:%d\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), parms->idx); return -EINVAL; } @@ -513,9 +428,9 @@ tf_tbl_get(struct tf *tfp, rc = tf_rm_get_hcapi_type(&hparms); if (rc) { TFP_DRV_LOG(ERR, - "%s, Failed type lookup, type:%d, rc:%s\n", + "%s, Failed type lookup, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -529,9 +444,9 @@ tf_tbl_get(struct tf *tfp, parms->idx); if (rc) { TFP_DRV_LOG(ERR, - "%s, Get failed, type:%d, rc:%s\n", + "%s, Get failed, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -549,7 +464,6 @@ tf_tbl_bulk_get(struct tf *tfp, struct tf_rm_check_indexes_in_range_parms cparms = { 0 }; struct tf_session *tfs; struct tf_dev_info *dev; - uint16_t base = 0, shift = 0; struct tbl_rm_db *tbl_db; void *tbl_db_ptr = NULL; @@ -574,40 +488,21 @@ tf_tbl_bulk_get(struct tf *tfp, } tbl_db = (struct tbl_rm_db *)tbl_db_ptr; - /* Only get table info if required for the device */ - if (dev->ops->tf_dev_get_tbl_info) { - rc = dev->ops->tf_dev_get_tbl_info(tfp, - tbl_db->tbl_db[parms->dir], - parms->type, - &base, - &shift); - if (rc) { - TFP_DRV_LOG(ERR, - "%s: Failed to get table info:%d\n", - tf_dir_2_str(parms->dir), - parms->type); - return rc; - } - } - /* Verify that the entries are in the range of reserved resources. */ cparms.rm_db = tbl_db->tbl_db[parms->dir]; cparms.subtype = parms->type; - - TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx, - base, shift); - cparms.num_entries = parms->num_entries; + cparms.starting_index = parms->starting_idx; rc = tf_rm_check_indexes_in_range(&cparms); if (rc) { TFP_DRV_LOG(ERR, "%s, Invalid or %d index starting from %d" - " not in range, type:%d", + " not in range, type:%s", tf_dir_2_str(parms->dir), parms->starting_idx, parms->num_entries, - parms->type); + tf_tbl_type_2_str(parms->type)); return rc; } @@ -617,9 +512,9 @@ tf_tbl_bulk_get(struct tf *tfp, rc = tf_rm_get_hcapi_type(&hparms); if (rc) { TFP_DRV_LOG(ERR, - "%s, Failed type lookup, type:%d, rc:%s\n", + "%s, Failed type lookup, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); return rc; } @@ -634,9 +529,9 @@ tf_tbl_bulk_get(struct tf *tfp, parms->physical_mem_addr); if (rc) { TFP_DRV_LOG(ERR, - "%s, Bulk get failed, type:%d, rc:%s\n", + "%s, Bulk get failed, type:%s, rc:%s\n", tf_dir_2_str(parms->dir), - parms->type, + tf_tbl_type_2_str(parms->type), strerror(-rc)); } @@ -653,9 +548,9 @@ tf_tbl_get_resc_info(struct tf *tfp, struct tf_rm_get_alloc_info_parms ainfo; void *tbl_db_ptr = NULL; struct tbl_rm_db *tbl_db; - uint16_t base = 0, shift = 0; struct tf_dev_info *dev; struct tf_session *tfs; + uint16_t base = 0, shift = 0; TF_CHECK_PARMS2(tfp, tbl); @@ -677,7 +572,6 @@ tf_tbl_get_resc_info(struct tf *tfp, tbl_db = (struct tbl_rm_db *)tbl_db_ptr; - /* check if reserved resource for WC is multiple of num_slices */ for (d = 0; d < TF_DIR_MAX; d++) { ainfo.rm_db = tbl_db->tbl_db[d]; dinfo = tbl[d].info; diff --git a/drivers/net/bnxt/tf_core/tf_tbl.h b/drivers/net/bnxt/tf_core/tf_tbl.h index 7e1107ffe7..2483718e5d 100644 --- a/drivers/net/bnxt/tf_core/tf_tbl.h +++ b/drivers/net/bnxt/tf_core/tf_tbl.h @@ -28,14 +28,6 @@ struct tf_tbl_cfg_parms { * Table Type element configuration array */ struct tf_rm_element_cfg *cfg; - /** - * Shadow table type configuration array - */ - struct tf_shadow_tbl_cfg *shadow_cfg; - /** - * Boolean controlling the request shadow copy. - */ - bool shadow_copy; /** * Session resource allocations */ @@ -197,8 +189,6 @@ struct tbl_rm_db { * * @ref tf_tbl_free * - * @ref tf_tbl_alloc_search - * * @ref tf_tbl_set * * @ref tf_tbl_get @@ -255,10 +245,7 @@ int tf_tbl_alloc(struct tf *tfp, struct tf_tbl_alloc_parms *parms); /** - * Free's the requested table type and returns it to the DB. If shadow - * DB is enabled its searched first and if found the element refcount - * is decremented. If refcount goes to 0 then its returned to the - * table type DB. + * Frees the requested table type and returns it to the DB. * * [in] tfp * Pointer to TF handle, used for HCAPI communication diff --git a/drivers/net/bnxt/tf_core/tf_tbl_sram.c b/drivers/net/bnxt/tf_core/tf_tbl_sram.c new file mode 100644 index 0000000000..ea10afecb6 --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_tbl_sram.c @@ -0,0 +1,713 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Broadcom + * All rights reserved. + */ + +/* Truflow Table APIs and supporting code */ + +#include + +#include "tf_tbl.h" +#include "tf_tbl_sram.h" +#include "tf_sram_mgr.h" +#include "tf_common.h" +#include "tf_rm.h" +#include "tf_util.h" +#include "tf_msg.h" +#include "tfp.h" +#include "tf_session.h" +#include "tf_device.h" +#include "cfa_resource_types.h" + +#define DBG_SRAM 0 + +/** + * tf_sram_tbl_get_info_parms parameter definition + */ +struct tf_tbl_sram_get_info_parms { + /** + * [in] table RM database + */ + void *rm_db; + /** + * [in] Receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] table_type + * + * the TF index table type + */ + enum tf_tbl_type tbl_type; + /** + * [out] bank + * + * The SRAM bank associated with the type + */ + enum tf_sram_bank_id bank_id; + /** + * [out] slice_size + * + * the slice size for the indicated table type + */ + enum tf_sram_slice_size slice_size; +}; + +/** + * Translate HCAPI type to SRAM Manager bank + */ +const uint16_t tf_tbl_sram_hcapi_2_bank[CFA_RESOURCE_TYPE_P58_LAST] = { + [CFA_RESOURCE_TYPE_P58_SRAM_BANK_0] = TF_SRAM_BANK_ID_0, + [CFA_RESOURCE_TYPE_P58_SRAM_BANK_1] = TF_SRAM_BANK_ID_1, + [CFA_RESOURCE_TYPE_P58_SRAM_BANK_2] = TF_SRAM_BANK_ID_2, + [CFA_RESOURCE_TYPE_P58_SRAM_BANK_3] = TF_SRAM_BANK_ID_3 +}; + +#define TF_TBL_SRAM_SLICES_MAX \ + (TF_SRAM_MGR_BLOCK_SZ_BYTES / TF_SRAM_MGR_MIN_SLICE_BYTES) +/** + * Translate HCAPI type to SRAM Manager bank + */ +const uint8_t tf_tbl_sram_slices_2_size[TF_TBL_SRAM_SLICES_MAX + 1] = { + [0] = TF_SRAM_SLICE_SIZE_64B, /* if 0 slices assume 1 64B block */ + [1] = TF_SRAM_SLICE_SIZE_64B, /* 1 slice per 64B block */ + [2] = TF_SRAM_SLICE_SIZE_32B, /* 2 slices per 64B block */ + [4] = TF_SRAM_SLICE_SIZE_16B, /* 4 slices per 64B block */ + [8] = TF_SRAM_SLICE_SIZE_8B /* 8 slices per 64B block */ +}; + +/** + * Get SRAM Table Information for a given index table type + * + * + * [in] sram_handle + * Pointer to SRAM handle + * + * [in] parms + * Pointer to the SRAM get info parameters + * + * Returns + * - (0) if successful + * - (-EINVAL) on failure + * + */ +static int tf_tbl_sram_get_info(struct tf_tbl_sram_get_info_parms *parms) +{ + int rc = 0; + uint16_t hcapi_type; + uint16_t slices; + struct tf_rm_get_hcapi_parms hparms; + struct tf_rm_get_slices_parms sparms; + + hparms.rm_db = parms->rm_db; + hparms.subtype = parms->tbl_type; + hparms.hcapi_type = &hcapi_type; + + rc = tf_rm_get_hcapi_type(&hparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get hcapi_type %s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->tbl_type), + strerror(-rc)); + return rc; + } + parms->bank_id = tf_tbl_sram_hcapi_2_bank[hcapi_type]; + + sparms.rm_db = parms->rm_db; + sparms.subtype = parms->tbl_type; + sparms.slices = &slices; + + rc = tf_rm_get_slices(&sparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get slice cnt %s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->tbl_type), + strerror(-rc)); + return rc; + } + if (slices) + parms->slice_size = tf_tbl_sram_slices_2_size[slices]; + + TFP_DRV_LOG(INFO, + "(%s) bank(%s) slice_size(%s)\n", + tf_tbl_type_2_str(parms->tbl_type), + tf_sram_bank_2_str(parms->bank_id), + tf_sram_slice_2_str(parms->slice_size)); + return rc; +} + +int +tf_tbl_sram_bind(struct tf *tfp __rte_unused) +{ + int rc = 0; + void *sram_handle = NULL; + + TF_CHECK_PARMS1(tfp); + + rc = tf_sram_mgr_bind(&sram_handle); + + tf_session_set_sram_db(tfp, sram_handle); + + TFP_DRV_LOG(INFO, + "SRAM Table - initialized\n"); + + return rc; +} + +int +tf_tbl_sram_unbind(struct tf *tfp __rte_unused) +{ + int rc = 0; + void *sram_handle = NULL; + + TF_CHECK_PARMS1(tfp); + + rc = tf_session_get_sram_db(tfp, &sram_handle); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get sram_handle from session, rc:%s\n", + strerror(-rc)); + return rc; + } + if (sram_handle) + rc = tf_sram_mgr_unbind(sram_handle); + + TFP_DRV_LOG(INFO, + "SRAM Table - deinitialized\n"); + return rc; +} + +int +tf_tbl_sram_alloc(struct tf *tfp, + struct tf_tbl_alloc_parms *parms) +{ + int rc; + uint16_t idx; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tf_tbl_sram_get_info_parms iparms = { 0 }; + struct tf_sram_mgr_alloc_parms aparms = { 0 }; + struct tbl_rm_db *tbl_db; + void *tbl_db_ptr = NULL; + void *sram_handle = NULL; + + TF_CHECK_PARMS2(tfp, parms); + + /* Retrieve the session information */ + rc = tf_session_get(tfp, &tfs, &dev); + if (rc) + return rc; + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tbl_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + + tbl_db = (struct tbl_rm_db *)tbl_db_ptr; + + rc = tf_session_get_sram_db(tfp, &sram_handle); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get sram_handle from session, rc:%s\n", + strerror(-rc)); + return rc; + } + + iparms.rm_db = tbl_db->tbl_db[parms->dir]; + iparms.dir = parms->dir; + iparms.tbl_type = parms->type; + + rc = tf_tbl_sram_get_info(&iparms); + + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get SRAM info %s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type)); + return rc; + } + + aparms.dir = parms->dir; + aparms.bank_id = iparms.bank_id; + aparms.slice_size = iparms.slice_size; + aparms.sram_offset = &idx; + aparms.tbl_type = parms->type; + aparms.rm_db = tbl_db->tbl_db[parms->dir]; + + rc = tf_sram_mgr_alloc(sram_handle, &aparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to allocate SRAM table:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type)); + return rc; + } + *parms->idx = idx; + +#if (DBG_SRAM == 1) + { + struct tf_sram_mgr_dump_parms dparms; + + dparms.dir = parms->dir; + dparms.bank_id = iparms.bank_id; + dparms.slice_size = iparms.slice_size; + + rc = tf_sram_mgr_dump(sram_handle, &dparms); + } +#endif + + return rc; +} + +int +tf_tbl_sram_free(struct tf *tfp __rte_unused, + struct tf_tbl_free_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tbl_rm_db *tbl_db; + void *tbl_db_ptr = NULL; + struct tf_tbl_sram_get_info_parms iparms = { 0 }; + struct tf_sram_mgr_free_parms fparms = { 0 }; + struct tf_sram_mgr_is_allocated_parms aparms = { 0 }; + bool allocated = false; + void *sram_handle = NULL; + + TF_CHECK_PARMS2(tfp, parms); + + /* Retrieve the session information */ + rc = tf_session_get(tfp, &tfs, &dev); + if (rc) + return rc; + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tbl_db = (struct tbl_rm_db *)tbl_db_ptr; + + rc = tf_session_get_sram_db(tfp, &sram_handle); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get sram_handle from session, rc:%s\n", + strerror(-rc)); + return rc; + } + + iparms.rm_db = tbl_db->tbl_db[parms->dir]; + iparms.dir = parms->dir; + iparms.tbl_type = parms->type; + + rc = tf_tbl_sram_get_info(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get table info:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type)); + return rc; + } + +#if (DBG_SRAM == 1) + { + struct tf_sram_mgr_dump_parms dparms; + + printf("%s: %s: %s\n", tf_dir_2_str(parms->dir), + tf_sram_slice_2_str(iparms.slice_size), + tf_sram_bank_2_str(iparms.bank_id)); + + dparms.dir = parms->dir; + dparms.bank_id = iparms.bank_id; + dparms.slice_size = iparms.slice_size; + + rc = tf_sram_mgr_dump(sram_handle, &dparms); + } +#endif + + aparms.sram_offset = parms->idx; + aparms.slice_size = iparms.slice_size; + aparms.bank_id = iparms.bank_id; + aparms.dir = parms->dir; + aparms.is_allocated = &allocated; + + rc = tf_sram_mgr_is_allocated(sram_handle, &aparms); + if (rc || !allocated) { + TFP_DRV_LOG(ERR, + "%s: Free of invalid entry:%s idx(%d):(%s)\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + parms->idx, + strerror(-rc)); + rc = -ENOMEM; + return rc; + } + + fparms.rm_db = tbl_db->tbl_db[parms->dir]; + fparms.tbl_type = parms->type; + fparms.sram_offset = parms->idx; + fparms.slice_size = iparms.slice_size; + fparms.bank_id = iparms.bank_id; + fparms.dir = parms->dir; +#if (STATS_CLEAR_ON_READ_SUPPORT == 0) + fparms.tfp = tfp; +#endif + rc = tf_sram_mgr_free(sram_handle, &fparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to free entry:%s idx(%d)\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + parms->idx); + return rc; + } + + +#if (DBG_SRAM == 1) + { + struct tf_sram_mgr_dump_parms dparms; + + printf("%s: %s: %s\n", tf_dir_2_str(parms->dir), + tf_sram_slice_2_str(iparms.slice_size), + tf_sram_bank_2_str(iparms.bank_id)); + + dparms.dir = parms->dir; + dparms.bank_id = iparms.bank_id; + dparms.slice_size = iparms.slice_size; + + rc = tf_sram_mgr_dump(sram_handle, &dparms); + } +#endif + return rc; +} + +int +tf_tbl_sram_set(struct tf *tfp, + struct tf_tbl_set_parms *parms) +{ + int rc; + bool allocated = 0; + uint16_t hcapi_type; + struct tf_rm_get_hcapi_parms hparms = { 0 }; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tbl_rm_db *tbl_db; + void *tbl_db_ptr = NULL; + struct tf_tbl_sram_get_info_parms iparms = { 0 }; + struct tf_sram_mgr_is_allocated_parms aparms = { 0 }; + void *sram_handle = NULL; + + + TF_CHECK_PARMS3(tfp, parms, parms->data); + + /* Retrieve the session information */ + rc = tf_session_get(tfp, &tfs, &dev); + if (rc) + return rc; + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tbl_db = (struct tbl_rm_db *)tbl_db_ptr; + + rc = tf_session_get_sram_db(tfp, &sram_handle); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get sram_handle from session, rc:%s\n", + strerror(-rc)); + return rc; + } + + iparms.rm_db = tbl_db->tbl_db[parms->dir]; + iparms.dir = parms->dir; + iparms.tbl_type = parms->type; + + rc = tf_tbl_sram_get_info(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get table info:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type)); + return rc; + } + + aparms.sram_offset = parms->idx; + aparms.slice_size = iparms.slice_size; + aparms.bank_id = iparms.bank_id; + aparms.dir = parms->dir; + aparms.is_allocated = &allocated; + rc = tf_sram_mgr_is_allocated(sram_handle, &aparms); + if (rc || !allocated) { + TFP_DRV_LOG(ERR, + "%s: Entry not allocated:%s idx(%d):(%s)\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + parms->idx, + strerror(-rc)); + rc = -ENOMEM; + return rc; + } + + /* Set the entry */ + hparms.rm_db = tbl_db->tbl_db[parms->dir]; + hparms.subtype = parms->type; + hparms.hcapi_type = &hcapi_type; + rc = tf_rm_get_hcapi_type(&hparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Failed type lookup, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + strerror(-rc)); + return rc; + } + + rc = tf_msg_set_tbl_entry(tfp, + parms->dir, + hcapi_type, + parms->data_sz_in_bytes, + parms->data, + parms->idx); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Set failed, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + strerror(-rc)); + return rc; + } + return rc; +} + +int +tf_tbl_sram_get(struct tf *tfp, + struct tf_tbl_get_parms *parms) +{ + int rc; + uint16_t hcapi_type; + bool allocated = 0; + struct tf_rm_get_hcapi_parms hparms = { 0 }; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tbl_rm_db *tbl_db; + void *tbl_db_ptr = NULL; + struct tf_tbl_sram_get_info_parms iparms = { 0 }; + struct tf_sram_mgr_is_allocated_parms aparms = { 0 }; + void *sram_handle = NULL; + + TF_CHECK_PARMS3(tfp, parms, parms->data); + + /* Retrieve the session information */ + rc = tf_session_get(tfp, &tfs, &dev); + if (rc) + return rc; + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tbl_db = (struct tbl_rm_db *)tbl_db_ptr; + + rc = tf_session_get_sram_db(tfp, &sram_handle); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get sram_handle from session, rc:%s\n", + strerror(-rc)); + return rc; + } + + iparms.rm_db = tbl_db->tbl_db[parms->dir]; + iparms.dir = parms->dir; + iparms.tbl_type = parms->type; + + rc = tf_tbl_sram_get_info(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get table info:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type)); + return rc; + } + + aparms.sram_offset = parms->idx; + aparms.slice_size = iparms.slice_size; + aparms.bank_id = iparms.bank_id; + aparms.dir = parms->dir; + aparms.is_allocated = &allocated; + + rc = tf_sram_mgr_is_allocated(sram_handle, &aparms); + if (rc || !allocated) { + TFP_DRV_LOG(ERR, + "%s: Entry not allocated:%s idx(%d):(%s)\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + parms->idx, + strerror(-rc)); + rc = -ENOMEM; + return rc; + } + + /* Get the entry */ + hparms.rm_db = tbl_db->tbl_db[parms->dir]; + hparms.subtype = parms->type; + hparms.hcapi_type = &hcapi_type; + rc = tf_rm_get_hcapi_type(&hparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Failed type lookup, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + strerror(-rc)); + return rc; + } + + /* Get the entry */ + rc = tf_msg_get_tbl_entry(tfp, + parms->dir, + hcapi_type, + parms->data_sz_in_bytes, + parms->data, + parms->idx); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Get failed, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + strerror(-rc)); + return rc; + } + return rc; +} + +int +tf_tbl_sram_bulk_get(struct tf *tfp, + struct tf_tbl_get_bulk_parms *parms) +{ + int rc; + uint16_t hcapi_type; + struct tf_rm_get_hcapi_parms hparms = { 0 }; + struct tf_tbl_sram_get_info_parms iparms = { 0 }; + struct tf_session *tfs; + struct tf_dev_info *dev; + struct tbl_rm_db *tbl_db; + void *tbl_db_ptr = NULL; + uint16_t idx; + struct tf_sram_mgr_is_allocated_parms aparms = { 0 }; + bool allocated = false; + void *sram_handle = NULL; + + TF_CHECK_PARMS2(tfp, parms); + + /* Retrieve the session information */ + rc = tf_session_get(tfp, &tfs, &dev); + if (rc) + return rc; + + rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get em_ext_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tbl_db = (struct tbl_rm_db *)tbl_db_ptr; + + rc = tf_session_get_sram_db(tfp, &sram_handle); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get sram_handle from session, rc:%s\n", + strerror(-rc)); + return rc; + } + + iparms.rm_db = tbl_db->tbl_db[parms->dir]; + iparms.dir = parms->dir; + iparms.tbl_type = parms->type; + + rc = tf_tbl_sram_get_info(&iparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to get table info:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type)); + return rc; + } + + /* Validate the start offset and the end offset is allocated + * This API is only used for statistics. 8 Byte entry allocation + * is used to verify + */ + aparms.sram_offset = parms->starting_idx; + aparms.slice_size = iparms.slice_size; + aparms.bank_id = iparms.bank_id; + aparms.dir = parms->dir; + aparms.is_allocated = &allocated; + rc = tf_sram_mgr_is_allocated(sram_handle, &aparms); + if (rc || !allocated) { + TFP_DRV_LOG(ERR, + "%s: Entry not allocated:%s starting_idx(%d):(%s)\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + parms->starting_idx, + strerror(-rc)); + rc = -ENOMEM; + return rc; + } + idx = parms->starting_idx + parms->num_entries - 1; + aparms.sram_offset = idx; + rc = tf_sram_mgr_is_allocated(sram_handle, &aparms); + if (rc || !allocated) { + TFP_DRV_LOG(ERR, + "%s: Entry not allocated:%s last_idx(%d):(%s)\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + idx, + strerror(-rc)); + rc = -ENOMEM; + return rc; + } + + hparms.rm_db = tbl_db->tbl_db[parms->dir]; + hparms.subtype = parms->type; + hparms.hcapi_type = &hcapi_type; + rc = tf_rm_get_hcapi_type(&hparms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Failed type lookup, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + strerror(-rc)); + return rc; + } + + /* Get the entries */ + rc = tf_msg_bulk_get_tbl_entry(tfp, + parms->dir, + hcapi_type, + parms->starting_idx, + parms->num_entries, + parms->entry_sz_in_bytes, + parms->physical_mem_addr); + if (rc) { + TFP_DRV_LOG(ERR, + "%s, Bulk get failed, type:%s, rc:%s\n", + tf_dir_2_str(parms->dir), + tf_tbl_type_2_str(parms->type), + strerror(-rc)); + } + return rc; +} diff --git a/drivers/net/bnxt/tf_core/tf_tbl_sram.h b/drivers/net/bnxt/tf_core/tf_tbl_sram.h new file mode 100644 index 0000000000..32001e34a9 --- /dev/null +++ b/drivers/net/bnxt/tf_core/tf_tbl_sram.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Broadcom + * All rights reserved. + */ + +#ifndef TF_TBL_SRAM_H_ +#define TF_TBL_SRAM_H_ + +#include "tf_core.h" +#include "stack.h" + + +/** + * The SRAM Table module provides processing of managed SRAM types. + */ + + +/** + * @page tblsram SRAM Table + * + * @ref tf_tbl_sram_bind + * + * @ref tf_tbl_sram_unbind + * + * @ref tf_tbl_sram_alloc + * + * @ref tf_tbl_sram_free + * + * @ref tf_tbl_sram_set + * + * @ref tf_tbl_sram_get + * + * @ref tf_tbl_sram_bulk_get + */ + +/** + * Initializes the Table module with the requested DBs. Must be + * invoked as the first thing before any of the access functions. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table configuration parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_bind(struct tf *tfp); + +/** + * Cleans up the private DBs and releases all the data. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_unbind(struct tf *tfp); + +/** + * Allocates the requested table type from the internal RM DB. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table allocation parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_alloc(struct tf *tfp, + struct tf_tbl_alloc_parms *parms); + +/** + * Free's the requested table type and returns it to the DB. If shadow + * DB is enabled its searched first and if found the element refcount + * is decremented. If refcount goes to 0 then its returned to the + * table type DB. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table free parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_free(struct tf *tfp, + struct tf_tbl_free_parms *parms); + + +/** + * Configures the requested element by sending a firmware request which + * then installs it into the device internal structures. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table set parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_set(struct tf *tfp, + struct tf_tbl_set_parms *parms); + +/** + * Retrieves the requested element by sending a firmware request to get + * the element. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table get parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_get(struct tf *tfp, + struct tf_tbl_get_parms *parms); + +/** + * Retrieves bulk block of elements by sending a firmware request to + * get the elements. + * + * [in] tfp + * Pointer to TF handle, used for HCAPI communication + * + * [in] parms + * Pointer to Table get bulk parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tbl_sram_bulk_get(struct tf *tfp, + struct tf_tbl_get_bulk_parms *parms); + +#endif /* TF_TBL_SRAM_H */ diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c index 45206c5992..806af3070a 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.c +++ b/drivers/net/bnxt/tf_core/tf_tcam.c @@ -43,7 +43,7 @@ tf_tcam_bind(struct tf *tfp, struct tf_shadow_tcam_free_db_parms fshadow; struct tf_shadow_tcam_cfg_parms shadow_cfg; struct tf_shadow_tcam_create_db_parms shadow_cdb; - uint16_t num_slices = 1; + uint16_t num_slices = parms->wc_num_slices; struct tf_session *tfs; struct tf_dev_info *dev; struct tcam_rm_db *tcam_db; @@ -61,7 +61,7 @@ tf_tcam_bind(struct tf *tfp, if (rc) return rc; - if (dev->ops->tf_dev_get_tcam_slice_info == NULL) { + if (dev->ops->tf_dev_set_tcam_slice_info == NULL) { rc = -EOPNOTSUPP; TFP_DRV_LOG(ERR, "Operation not supported, rc:%s\n", @@ -69,10 +69,8 @@ tf_tcam_bind(struct tf *tfp, return rc; } - rc = dev->ops->tf_dev_get_tcam_slice_info(tfp, - TF_TCAM_TBL_TYPE_WC_TCAM, - 0, - &num_slices); + rc = dev->ops->tf_dev_set_tcam_slice_info(tfp, + num_slices); if (rc) return rc; diff --git a/drivers/net/bnxt/tf_core/tf_tcam.h b/drivers/net/bnxt/tf_core/tf_tcam.h index bed17af6ae..b1e7a92b0b 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.h +++ b/drivers/net/bnxt/tf_core/tf_tcam.h @@ -12,6 +12,9 @@ * The TCAM module provides processing of Internal TCAM types. */ +/* Number of slices per row for WC TCAM */ +extern uint16_t g_wc_num_slices_per_row; + /** * TCAM configuration parameters */ @@ -36,6 +39,10 @@ struct tf_tcam_cfg_parms { * Session resource allocations */ struct tf_session_resources *resources; + /** + * WC number of slices per row. + */ + enum tf_wc_num_slice wc_num_slices; }; /** diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.c b/drivers/net/bnxt/tf_core/tf_tcam_shared.c index 83b6fbd5fb..c120c6f577 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam_shared.c +++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.c @@ -279,18 +279,6 @@ tf_tcam_shared_bind(struct tf *tfp, if (rc) return rc; - rc = tf_tcam_shared_get_slices(tfp, - dev, - &num_slices); - if (rc) - return rc; - - if (num_slices > 1) { - TFP_DRV_LOG(ERR, - "Only single slice supported\n"); - return -EOPNOTSUPP; - } - tf_tcam_shared_create_db(&tcam_shared_wc); @@ -330,6 +318,18 @@ tf_tcam_shared_bind(struct tf *tfp, tf_session_set_tcam_shared_db(tfp, (void *)tcam_shared_wc); } + + rc = tf_tcam_shared_get_slices(tfp, + dev, + &num_slices); + if (rc) + return rc; + + if (num_slices > 1) { + TFP_DRV_LOG(ERR, + "Only single slice supported\n"); + return -EOPNOTSUPP; + } } done: return rc; @@ -972,9 +972,9 @@ tf_tcam_shared_move_entry(struct tf *tfp, sparms.idx = dphy_idx; sparms.key = gparms.key; sparms.mask = gparms.mask; - sparms.key_size = gparms.key_size; + sparms.key_size = key_sz_bytes; sparms.result = gparms.result; - sparms.result_size = gparms.result_size; + sparms.result_size = remap_sz_bytes; rc = tf_msg_tcam_entry_set(tfp, dev, &sparms); if (rc) { diff --git a/drivers/net/bnxt/tf_core/tf_util.c b/drivers/net/bnxt/tf_core/tf_util.c index d100399d0a..c1b9be0755 100644 --- a/drivers/net/bnxt/tf_core/tf_util.c +++ b/drivers/net/bnxt/tf_core/tf_util.c @@ -76,6 +76,8 @@ tf_tbl_type_2_str(enum tf_tbl_type tbl_type) switch (tbl_type) { case TF_TBL_TYPE_FULL_ACT_RECORD: return "Full Action record"; + case TF_TBL_TYPE_COMPACT_ACT_RECORD: + return "Compact Action record"; case TF_TBL_TYPE_MCAST_GROUPS: return "Multicast Groups"; case TF_TBL_TYPE_ACT_ENCAP_8B: @@ -96,6 +98,14 @@ tf_tbl_type_2_str(enum tf_tbl_type tbl_type) return "Stats 64B"; case TF_TBL_TYPE_ACT_MODIFY_IPV4: return "Modify IPv4"; + case TF_TBL_TYPE_ACT_MODIFY_8B: + return "Modify 8B"; + case TF_TBL_TYPE_ACT_MODIFY_16B: + return "Modify 16B"; + case TF_TBL_TYPE_ACT_MODIFY_32B: + return "Modify 32B"; + case TF_TBL_TYPE_ACT_MODIFY_64B: + return "Modify 64B"; case TF_TBL_TYPE_METER_PROF: return "Meter Profile"; case TF_TBL_TYPE_METER_INST: diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c index dbf85e4eda..183bae66c5 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c @@ -384,6 +384,7 @@ ulp_ctx_shared_session_open(struct bnxt *bp, size_t copy_nbytes; uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST; int32_t rc = 0; + uint8_t app_id; /* only perform this if shared session is enabled. */ if (!bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) @@ -422,6 +423,12 @@ ulp_ctx_shared_session_open(struct bnxt *bp, if (rc) return rc; + rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id); + if (rc) { + BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n"); + return -EINVAL; + } + rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id); if (rc) { BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n"); @@ -445,6 +452,10 @@ ulp_ctx_shared_session_open(struct bnxt *bp, parms.shadow_copy = true; parms.bp = bp; + if (app_id == 0 || app_id == 3) + parms.wc_num_slices = TF_WC_TCAM_2_SLICE_PER_ROW; + else + parms.wc_num_slices = TF_WC_TCAM_1_SLICE_PER_ROW; /* * Open the session here, but the collect the resources during the @@ -516,6 +527,7 @@ ulp_ctx_session_open(struct bnxt *bp, struct tf_open_session_parms params; struct tf_session_resources *resources; uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST; + uint8_t app_id; memset(¶ms, 0, sizeof(params)); @@ -529,6 +541,12 @@ ulp_ctx_session_open(struct bnxt *bp, params.shadow_copy = true; + rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id); + if (rc) { + BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n"); + return -EINVAL; + } + rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id); if (rc) { BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n"); @@ -556,6 +574,11 @@ ulp_ctx_session_open(struct bnxt *bp, return rc; params.bp = bp; + if (app_id == 0 || app_id == 3) + params.wc_num_slices = TF_WC_TCAM_2_SLICE_PER_ROW; + else + params.wc_num_slices = TF_WC_TCAM_1_SLICE_PER_ROW; + rc = tf_open_session(&bp->tfp, ¶ms); if (rc) { BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n", -- 2.17.1