From patchwork Sun Jun 13 00:06:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 94115 X-Patchwork-Delegate: ajit.khaparde@broadcom.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5FBB7A0C41; Sun, 13 Jun 2021 02:10:08 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 47A2E41182; Sun, 13 Jun 2021 02:07:31 +0200 (CEST) Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) by mails.dpdk.org (Postfix) with ESMTP id 5BE024119F for ; Sun, 13 Jun 2021 02:07:26 +0200 (CEST) Received: by mail-pg1-f180.google.com with SMTP id y11so5603196pgp.11 for ; Sat, 12 Jun 2021 17:07:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version; bh=7y7IpN6XbpgWlf0cDtF61FM2v3p+A0J6gdCnPxcBgVk=; b=Lk/07h1o7t5BwhLK/ZQjarOYDFXUzOUDoSTO9SIw8bzogR/NrpdNOpZ7pxV9R3M8jv zAjL0DRG/hj0RRqdObNsvdkTehTmP49ElShz3hbVFMZ2A/OBUgH0HZYIa5TItNhFb0vx RInS/1gzPXxT27MYLxG1F5rta65cto8nSO5tk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version; bh=7y7IpN6XbpgWlf0cDtF61FM2v3p+A0J6gdCnPxcBgVk=; b=c61slczSoiHrr8g9Tj5V5fA3vzgSZb+pEFHcwgn3kdqTcYm3PdvZyJjqwiMVLHiQ8n oyxR4FipPg8mQq5DrZYn6q3X6qbL0w8BJzAyqvB2mg5cyXdQhOF60tpf9VrC0Lvlarpa X7Ou3e6asQN20E1PQchGBIYtzmr2jJbGcDSzy4evwYtjdGq3vXHcxI4WnKYgC7apyBgl 1LtV/wJdRBicVjbZmqHKx3+3N/h+rZtbE6pK3wv7kUZqLNAa2+2XgPgJCsuskcc2pRtq 92J0R9ulwy7FznyMKUjhjs09SrGU8PlS+W0UnEpY24+tm6MDAnDcP6SVUXyJOY1TJiy8 tYgA== X-Gm-Message-State: AOAM531negJ9LroEFsqgkiFVE1xOTHW1mceScy7ZVPRBB9mj8VK5rTVS T9C+JHpeScX/wEqsK1z7l7IM3sJBaH6zOICE6rVkTi/n8sdmVxsGFhtmT3iNoJcaLTMDEdksLmT /qI4JOK8LHPPn/8kID1bWjlfX7aA9ucFdjaUn9RqVSlbDrs+WMvwZlmU21pE9VL4= X-Google-Smtp-Source: ABdhPJxmVhjA5yDCOK14PKi4oYQiFfZYvD5Cqrr9m6UUi9V2Hj6bvLRD30F4RXRJ/2IHxoVe+W3Q9w== X-Received: by 2002:a63:d0d:: with SMTP id c13mr10598209pgl.384.1623542844764; Sat, 12 Jun 2021 17:07:24 -0700 (PDT) Received: from localhost.localdomain ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id gg22sm12774609pjb.17.2021.06.12.17.07.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 12 Jun 2021 17:07:24 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: Farah Smith , Randy Schacher , Venkat Duvvuru Date: Sat, 12 Jun 2021 17:06:14 -0700 Message-Id: <20210613000652.28191-21-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20210613000652.28191-1-ajit.khaparde@broadcom.com> References: <20210530085929.29695-1-venkatkumar.duvvuru@broadcom.com> <20210613000652.28191-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: [dpdk-dev] [PATCH v2 20/58] net/bnxt: add WC TCAM management support 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 - Add new API to move WC TCAM regions from the hi pool to the low pool. - Enable shared TCAM get/set functions on Thor. Signed-off-by: Farah Smith Signed-off-by: Randy Schacher Signed-off-by: Venkat Duvvuru Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/tf_core/tf_core.c | 53 +++ drivers/net/bnxt/tf_core/tf_core.h | 39 ++ drivers/net/bnxt/tf_core/tf_device.h | 18 + drivers/net/bnxt/tf_core/tf_device_p4.c | 1 + drivers/net/bnxt/tf_core/tf_device_p58.c | 5 +- drivers/net/bnxt/tf_core/tf_session.c | 41 ++ drivers/net/bnxt/tf_core/tf_session.h | 48 +++ drivers/net/bnxt/tf_core/tf_tcam.c | 2 +- drivers/net/bnxt/tf_core/tf_tcam_shared.c | 468 ++++++++++++++++++++-- drivers/net/bnxt/tf_core/tf_tcam_shared.h | 35 ++ 10 files changed, 673 insertions(+), 37 deletions(-) diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index de2a93646f..73dbee2940 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -917,6 +917,59 @@ tf_free_tcam_entry(struct tf *tfp, return 0; } +#ifdef TF_TCAM_SHARED +int +tf_move_tcam_shared_entries(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + + TF_CHECK_PARMS2(tfp, parms); + + /* Retrieve the session information */ + rc = tf_session_get_session(tfp, &tfs); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup session, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: Failed to lookup device, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + if (dev->ops->tf_dev_move_tcam == NULL) { + rc = -EOPNOTSUPP; + TFP_DRV_LOG(ERR, + "%s: Operation not supported, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + rc = dev->ops->tf_dev_move_tcam(tfp, parms); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: TCAM shared entries move failed, rc:%s\n", + tf_dir_2_str(parms->dir), + strerror(-rc)); + return rc; + } + + return 0; +} +#endif /* TF_TCAM_SHARED */ + int tf_alloc_tbl_entry(struct tf *tfp, struct tf_alloc_tbl_entry_parms *parms) diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h index 39a498122b..95cde2e8eb 100644 --- a/drivers/net/bnxt/tf_core/tf_core.h +++ b/drivers/net/bnxt/tf_core/tf_core.h @@ -1242,6 +1242,10 @@ int tf_free_tbl_scope(struct tf *tfp, * @ref tf_get_tcam_entry * * @ref tf_free_tcam_entry + * +#ifdef TF_TCAM_SHARED + * @ref tf_move_tcam_shared_entries +#endif */ /** @@ -1543,6 +1547,41 @@ struct tf_free_tcam_entry_parms { int tf_free_tcam_entry(struct tf *tfp, struct tf_free_tcam_entry_parms *parms); +#ifdef TF_TCAM_SHARED +/** + * tf_move_tcam_shared_entries parameter definition + */ +struct tf_move_tcam_shared_entries_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] TCAM table type + */ + enum tf_tcam_tbl_type tcam_tbl_type; +}; + +/** + * Move TCAM entries + * + * This API only affects the following TCAM pools within a shared session: + * + * TF_TCAM_TBL_TYPE_WC_TCAM_HIGH + * TF_TCAM_TBL_TYPE_WC_TCAM_LOW + * + * When called, all allocated entries from the high pool will be moved to + * the low pool. Then the allocated entries in the high pool will be + * cleared and freed. + * + * This API is not supported on a non-shared session. + * + * Returns success or failure code. + */ +int tf_move_tcam_shared_entries(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms); + +#endif /* TF_TCAM_SHARED */ /** * @page table Table Access * diff --git a/drivers/net/bnxt/tf_core/tf_device.h b/drivers/net/bnxt/tf_core/tf_device.h index ea4dcfb8e2..48ab17d56b 100644 --- a/drivers/net/bnxt/tf_core/tf_device.h +++ b/drivers/net/bnxt/tf_core/tf_device.h @@ -563,6 +563,24 @@ struct tf_dev_ops { int (*tf_dev_get_tcam)(struct tf *tfp, struct tf_tcam_get_parms *parms); +#ifdef TF_TCAM_SHARED + /** + * Move TCAM shared entries + * + * [in] tfp + * Pointer to TF handle + * + * [in] parms + * Pointer to parameters + * + * returns: + * 0 - Success + * -EINVAL - Error + */ + int (*tf_dev_move_tcam)(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms); +#endif /* TF_TCAM_SHARED */ + /** * Retrieves the tcam resource info. * diff --git a/drivers/net/bnxt/tf_core/tf_device_p4.c b/drivers/net/bnxt/tf_core/tf_device_p4.c index 0d3c35ae3b..67ef765236 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p4.c +++ b/drivers/net/bnxt/tf_core/tf_device_p4.c @@ -272,6 +272,7 @@ const struct tf_dev_ops tf_dev_ops_p4 = { .tf_dev_free_tcam = tf_tcam_shared_free, .tf_dev_set_tcam = tf_tcam_shared_set, .tf_dev_get_tcam = tf_tcam_shared_get, + .tf_dev_move_tcam = tf_tcam_shared_move_p4, #else /* !TF_TCAM_SHARED */ .tf_dev_alloc_tcam = tf_tcam_alloc, .tf_dev_free_tcam = tf_tcam_free, diff --git a/drivers/net/bnxt/tf_core/tf_device_p58.c b/drivers/net/bnxt/tf_core/tf_device_p58.c index 5bf52379a7..fd2703129f 100644 --- a/drivers/net/bnxt/tf_core/tf_device_p58.c +++ b/drivers/net/bnxt/tf_core/tf_device_p58.c @@ -292,8 +292,9 @@ const struct tf_dev_ops tf_dev_ops_p58 = { #ifdef TF_TCAM_SHARED .tf_dev_alloc_tcam = tf_tcam_shared_alloc, .tf_dev_free_tcam = tf_tcam_shared_free, - .tf_dev_set_tcam = tf_tcam_set, - .tf_dev_get_tcam = tf_tcam_get, + .tf_dev_set_tcam = tf_tcam_shared_set, + .tf_dev_get_tcam = tf_tcam_shared_get, + .tf_dev_move_tcam = tf_tcam_shared_move_p58, #else /* !TF_TCAM_SHARED */ .tf_dev_alloc_tcam = tf_tcam_alloc, .tf_dev_free_tcam = tf_tcam_free, diff --git a/drivers/net/bnxt/tf_core/tf_session.c b/drivers/net/bnxt/tf_core/tf_session.c index e6ab518121..70844edb50 100644 --- a/drivers/net/bnxt/tf_core/tf_session.c +++ b/drivers/net/bnxt/tf_core/tf_session.c @@ -945,3 +945,44 @@ tf_session_set_db(struct tf *tfp, return rc; } + +#ifdef TF_TCAM_SHARED + +int +tf_session_get_tcam_shared_db(struct tf *tfp, + void **tcam_shared_db_handle) +{ + struct tf_session *tfs = NULL; + int rc = 0; + + *tcam_shared_db_handle = NULL; + + if (tfp == NULL) + return (-EINVAL); + + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + *tcam_shared_db_handle = tfs->tcam_shared_db_handle; + return rc; +} + +int +tf_session_set_tcam_shared_db(struct tf *tfp, + void *tcam_shared_db_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->tcam_shared_db_handle = tcam_shared_db_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 034a2213a4..c2875f9fa1 100644 --- a/drivers/net/bnxt/tf_core/tf_session.h +++ b/drivers/net/bnxt/tf_core/tf_session.h @@ -159,6 +159,13 @@ struct tf_session { * EM allocator for session */ void *em_pool[TF_DIR_MAX]; + +#ifdef TF_TCAM_SHARED + /** + * tcam db reference for the session + */ + void *tcam_shared_db_handle; +#endif /* TF_TCAM_SHARED */ }; /** @@ -255,6 +262,22 @@ struct tf_session_close_session_parms { * @ref tf_session_get_fw_session_id * * @ref tf_session_get_session_id + * + * @ref tf_session_is_shared_session_creator + * + * @ref tf_session_get_db + * + * @ref tf_session_set_db + * + * @ref tf_session_get_bp + * + * @ref tf_session_is_shared_session + * + * #define TF_SHARED + * @ref tf_session_get_tcam_shared_db + * + * @ref tf_session_set_tcam_shared_db + * #endif */ /** @@ -566,4 +589,29 @@ tf_session_get_bp(struct tf *tfp) { return tfp->bp; } + +/** + * Set the pointer to the tcam shared database + * + * [in] session, pointer to the session + * + * Returns: + * - the pointer to the parent bnxt struct + */ +int +tf_session_set_tcam_shared_db(struct tf *tfp, + void *tcam_shared_db_handle); + +/** + * Get the pointer to the tcam shared database + * + * [in] session, pointer to the session + * + * Returns: + * - the pointer to the parent bnxt struct + */ +int +tf_session_get_tcam_shared_db(struct tf *tfp, + void **tcam_shared_db_handle); + #endif /* _TF_SESSION_H_ */ diff --git a/drivers/net/bnxt/tf_core/tf_tcam.c b/drivers/net/bnxt/tf_core/tf_tcam.c index 7878f8727a..d7e12e00ef 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam.c +++ b/drivers/net/bnxt/tf_core/tf_tcam.c @@ -299,7 +299,7 @@ tf_tcam_alloc(struct tf *tfp, rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr); if (rc) { TFP_DRV_LOG(ERR, - "Failed to get em_ext_db from session, rc:%s\n", + "Failed to get tcam_db from session, rc:%s\n", strerror(-rc)); return rc; } diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.c b/drivers/net/bnxt/tf_core/tf_tcam_shared.c index 17d7fee7a8..0e8cb78f8d 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam_shared.c +++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.c @@ -53,10 +53,34 @@ struct tf_tcam_shared_wc_pool { struct bitalloc *pool; }; +struct tf_tcam_shared_wc_pools { + struct tf_tcam_shared_wc_pool db[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX]; +}; + /** The WC TCAM shared pool declarations - * TODO: add tcam_shared_wc_db */ -struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX]; +/* struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX]; */ + +static int +tf_tcam_shared_create_db(struct tf_tcam_shared_wc_pools **db) +{ + struct tfp_calloc_parms cparms; + int rc = 0; + + cparms.nitems = 1; + cparms.alignment = 0; + cparms.size = sizeof(struct tf_tcam_shared_wc_pools); + rc = tfp_calloc(&cparms); + if (rc) { + TFP_DRV_LOG(ERR, + "TCAM shared db allocation failed (%s)\n", + strerror(-rc)); + return rc; + } + *db = cparms.mem_va; + + return rc; +} /** Create a WC TCAM shared pool */ @@ -64,7 +88,8 @@ static int tf_tcam_shared_create_wc_pool(int dir, enum tf_tcam_shared_wc_pool_id id, int start, - int stride) + int stride, + struct tf_tcam_shared_wc_pools *tcam_shared_wc) { int rc = 0; bool free = true; @@ -84,9 +109,9 @@ tf_tcam_shared_create_wc_pool(int dir, strerror(-rc)); return rc; } - tcam_shared_wc[dir][id].pool = (struct bitalloc *)cparms.mem_va; + tcam_shared_wc->db[dir][id].pool = (struct bitalloc *)cparms.mem_va; - rc = ba_init(tcam_shared_wc[dir][id].pool, + rc = ba_init(tcam_shared_wc->db[dir][id].pool, stride, free); @@ -97,21 +122,27 @@ tf_tcam_shared_create_wc_pool(int dir, return rc; } - tcam_shared_wc[dir][id].info.start = start; - tcam_shared_wc[dir][id].info.stride = stride; + tcam_shared_wc->db[dir][id].info.start = start; + tcam_shared_wc->db[dir][id].info.stride = stride; + return rc; } /** Free a WC TCAM shared pool */ -static void +static int tf_tcam_shared_free_wc_pool(int dir, - enum tf_tcam_shared_wc_pool_id id) + enum tf_tcam_shared_wc_pool_id id, + struct tf_tcam_shared_wc_pools *tcam_shared_wc) { - tcam_shared_wc[dir][id].info.start = 0; - tcam_shared_wc[dir][id].info.stride = 0; + int rc = 0; + TF_CHECK_PARMS1(tcam_shared_wc); + + tcam_shared_wc->db[dir][id].info.start = 0; + tcam_shared_wc->db[dir][id].info.stride = 0; - if (tcam_shared_wc[dir][id].pool) - tfp_free((void *)tcam_shared_wc[dir][id].pool); + if (tcam_shared_wc->db[dir][id].pool) + tfp_free((void *)tcam_shared_wc->db[dir][id].pool); + return rc; } /** Get the number of WC TCAM slices allocated during 1 allocation/free @@ -137,7 +168,7 @@ tf_tcam_shared_get_slices(struct tf *tfp, } static bool -tf_tcam_shared_db_valid(struct tf *tfp, +tf_tcam_db_valid(struct tf *tfp, enum tf_dir dir) { struct tcam_rm_db *tcam_db; @@ -226,6 +257,7 @@ tf_tcam_shared_bind(struct tf *tfp, uint16_t start, stride; uint16_t num_slices; uint16_t hcapi_type; + struct tf_tcam_shared_wc_pools *tcam_shared_wc = NULL; TF_CHECK_PARMS2(tfp, parms); @@ -256,11 +288,14 @@ tf_tcam_shared_bind(struct tf *tfp, if (rc) return rc; + tf_tcam_shared_create_db(&tcam_shared_wc); + + /* If there are WC TCAM entries, create 2 pools each with 1/2 * the total number of entries */ for (dir = 0; dir < TF_DIR_MAX; dir++) { - if (!tf_tcam_shared_db_valid(tfp, dir)) + if (!tf_tcam_db_valid(tfp, dir)) continue; rc = tf_tcam_shared_get_rm_info(tfp, @@ -278,15 +313,19 @@ tf_tcam_shared_bind(struct tf *tfp, stride = info.entry.stride / 2; tf_tcam_shared_create_wc_pool(dir, - TF_TCAM_SHARED_WC_POOL_HI, - start, - stride); + TF_TCAM_SHARED_WC_POOL_HI, + start, + stride, + tcam_shared_wc); start += stride; tf_tcam_shared_create_wc_pool(dir, - TF_TCAM_SHARED_WC_POOL_LO, - start, - stride); + TF_TCAM_SHARED_WC_POOL_LO, + start, + stride, + tcam_shared_wc); + + tf_session_set_tcam_shared_db(tfp, (void *)tcam_shared_wc); } } done: @@ -300,6 +339,8 @@ tf_tcam_shared_unbind(struct tf *tfp) { int rc, dir; struct tf_session *tfs; + void *tcam_shared_db_ptr = NULL; + struct tf_tcam_shared_wc_pools *tcam_shared_wc; TF_CHECK_PARMS1(tfp); @@ -315,6 +356,15 @@ tf_tcam_shared_unbind(struct tf *tfp) if (rc) return rc; + rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tcam_shared_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr; + /* If we are the shared session */ if (tf_session_is_shared_session(tfs)) { @@ -322,9 +372,11 @@ tf_tcam_shared_unbind(struct tf *tfp) */ for (dir = 0; dir < TF_DIR_MAX; dir++) { tf_tcam_shared_free_wc_pool(dir, - TF_TCAM_SHARED_WC_POOL_HI); + TF_TCAM_SHARED_WC_POOL_HI, + tcam_shared_wc); tf_tcam_shared_free_wc_pool(dir, - TF_TCAM_SHARED_WC_POOL_LO); + TF_TCAM_SHARED_WC_POOL_LO, + tcam_shared_wc); } } return 0; @@ -343,6 +395,8 @@ tf_tcam_shared_alloc(struct tf *tfp, struct bitalloc *pool; enum tf_tcam_shared_wc_pool_id id; uint16_t num_slices; + struct tf_tcam_shared_wc_pools *tcam_shared_wc; + void *tcam_shared_db_ptr = NULL; TF_CHECK_PARMS2(tfp, parms); @@ -364,13 +418,22 @@ tf_tcam_shared_alloc(struct tf *tfp, return rc; } - if (!tf_tcam_shared_db_valid(tfp, parms->dir)) { + if (!tf_tcam_db_valid(tfp, parms->dir)) { TFP_DRV_LOG(ERR, "%s: tcam shared pool doesn't exist\n", tf_dir_2_str(parms->dir)); return -ENOMEM; } + rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tcam_shared_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr; + if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH) id = TF_TCAM_SHARED_WC_POOL_HI; else @@ -385,7 +448,7 @@ tf_tcam_shared_alloc(struct tf *tfp, if (rc) return rc; - pool = tcam_shared_wc[parms->dir][id].pool; + pool = tcam_shared_wc->db[parms->dir][id].pool; for (i = 0; i < num_slices; i++) { /* @@ -427,6 +490,8 @@ tf_tcam_shared_free(struct tf *tfp, uint16_t num_slices; uint16_t hcapi_type; struct tf_rm_alloc_info info; + void *tcam_shared_db_ptr = NULL; + struct tf_tcam_shared_wc_pools *tcam_shared_wc; TF_CHECK_PARMS2(tfp, parms); @@ -448,13 +513,23 @@ tf_tcam_shared_free(struct tf *tfp, return rc; } - if (!tf_tcam_shared_db_valid(tfp, parms->dir)) { + if (!tf_tcam_db_valid(tfp, parms->dir)) { TFP_DRV_LOG(ERR, "%s: tcam shared pool doesn't exist\n", tf_dir_2_str(parms->dir)); return -ENOMEM; } + rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tcam_shared_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr; + + if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH) id = TF_TCAM_SHARED_WC_POOL_HI; else @@ -480,8 +555,8 @@ tf_tcam_shared_free(struct tf *tfp, return rc; } - pool = tcam_shared_wc[parms->dir][id].pool; - start = tcam_shared_wc[parms->dir][id].info.start; + pool = tcam_shared_wc->db[parms->dir][id].pool; + start = tcam_shared_wc->db[parms->dir][id].info.start; if (parms->idx % num_slices) { TFP_DRV_LOG(ERR, @@ -548,6 +623,9 @@ tf_tcam_shared_set(struct tf *tfp __rte_unused, enum tf_tcam_shared_wc_pool_id id; uint16_t hcapi_type; struct tf_rm_alloc_info info; + struct tf_tcam_shared_wc_pools *tcam_shared_wc; + void *tcam_shared_db_ptr = NULL; + TF_CHECK_PARMS2(tfp, parms); @@ -568,7 +646,7 @@ tf_tcam_shared_set(struct tf *tfp __rte_unused, return rc; } - if (!tf_tcam_shared_db_valid(tfp, parms->dir)) { + if (!tf_tcam_db_valid(tfp, parms->dir)) { TFP_DRV_LOG(ERR, "%s: tcam shared pool doesn't exist\n", tf_dir_2_str(parms->dir)); @@ -585,8 +663,17 @@ tf_tcam_shared_set(struct tf *tfp __rte_unused, else id = TF_TCAM_SHARED_WC_POOL_LO; - pool = tcam_shared_wc[parms->dir][id].pool; - start = tcam_shared_wc[parms->dir][id].info.start; + rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tcam_shared_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr; + + pool = tcam_shared_wc->db[parms->dir][id].pool; + start = tcam_shared_wc->db[parms->dir][id].info.start; log_idx = parms->idx; phy_idx = parms->idx + start; @@ -656,6 +743,8 @@ tf_tcam_shared_get(struct tf *tfp __rte_unused, enum tf_tcam_shared_wc_pool_id id; uint16_t hcapi_type; struct tf_rm_alloc_info info; + struct tf_tcam_shared_wc_pools *tcam_shared_wc; + void *tcam_shared_db_ptr = NULL; TF_CHECK_PARMS2(tfp, parms); @@ -676,7 +765,7 @@ tf_tcam_shared_get(struct tf *tfp __rte_unused, return rc; } - if (!tf_tcam_shared_db_valid(tfp, parms->dir)) { + if (!tf_tcam_db_valid(tfp, parms->dir)) { TFP_DRV_LOG(ERR, "%s: tcam shared pool doesn't exist\n", tf_dir_2_str(parms->dir)); @@ -692,8 +781,18 @@ tf_tcam_shared_get(struct tf *tfp __rte_unused, else id = TF_TCAM_SHARED_WC_POOL_LO; - pool = tcam_shared_wc[parms->dir][id].pool; - start = tcam_shared_wc[parms->dir][id].info.start; + + rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tcam_shared_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr; + + pool = tcam_shared_wc->db[parms->dir][id].pool; + start = tcam_shared_wc->db[parms->dir][id].info.start; rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices); if (rc) @@ -742,3 +841,304 @@ tf_tcam_shared_get(struct tf *tfp __rte_unused, } return 0; } + +/* Temporary builder defines pulled in here and renamed + */ +#define TF_TMP_MAX_FIELD_BITLEN 512 + +union tf_tmp_field_obj { + uint8_t bytes[(TF_TMP_MAX_FIELD_BITLEN + 7) / 8]; +}; + +#define TF_TMP_MAX_KEY_BITLEN 768 +#define TF_TMP_MAX_KEY_WORDLEN ((TF_TMP_MAX_KEY_BITLEN + 63) / 64) + +union tf_tmp_key { + uint32_t words[(TF_TMP_MAX_KEY_BITLEN + 31) / 32]; + uint8_t bytes[(TF_TMP_MAX_KEY_BITLEN + 7) / 8]; +}; + +/** Move a WC TCAM entry from the high offset to the same low offset + */ +static int +tf_tcam_shared_move_entry(struct tf *tfp, + struct tf_dev_info *dev, + uint16_t hcapi_type, + enum tf_dir dir, + int sphy_idx, + int dphy_idx, + int key_sz_bytes, + int remap_sz_bytes, + uint16_t num_slices) +{ + int rc = 0; + struct tf_tcam_get_parms gparms; + struct tf_tcam_set_parms sparms; + struct tf_tcam_free_parms fparms; + union tf_tmp_key tcam_key_obj; + union tf_tmp_key tcam_key_msk_obj; + union tf_tmp_field_obj tcam_remap_obj; + + memset(&tcam_key_obj, 0, sizeof(tcam_key_obj)); + memset(&tcam_key_msk_obj, 0, sizeof(tcam_key_msk_obj)); + memset(&tcam_remap_obj, 0, sizeof(tcam_remap_obj)); + memset(&gparms, 0, sizeof(gparms)); + + if (num_slices > 1) { + TFP_DRV_LOG(ERR, + "Only single slice supported"); + return -EOPNOTSUPP; + } + + gparms.hcapi_type = hcapi_type; + gparms.dir = dir; + gparms.type = TF_TCAM_TBL_TYPE_WC_TCAM; + gparms.idx = sphy_idx; + gparms.key = (uint8_t *)&tcam_key_obj; + gparms.key_size = key_sz_bytes; + gparms.mask = (uint8_t *)&tcam_key_msk_obj; + gparms.result = (uint8_t *)&tcam_remap_obj; + gparms.result_size = remap_sz_bytes; + + rc = tf_msg_tcam_entry_get(tfp, dev, &gparms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "%s: WC_TCAM_HIGH: phyid(%d) get failed, rc:%s", + tf_dir_2_str(dir), + gparms.idx, + strerror(-rc)); + return rc; + } + + /* Override HI/LO type with parent WC TCAM type */ + sparms.hcapi_type = hcapi_type; + sparms.dir = dir; + sparms.type = TF_TCAM_TBL_TYPE_WC_TCAM; + sparms.idx = dphy_idx; + sparms.key = gparms.key; + sparms.mask = gparms.mask; + sparms.key_size = gparms.key_size; + sparms.result = gparms.result; + sparms.result_size = gparms.result_size; + + rc = tf_msg_tcam_entry_set(tfp, dev, &sparms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "%s: WC_TCAM_LOW phyid(%d) set failed, rc:%s", + tf_dir_2_str(dir), + sparms.idx, + strerror(-rc)); + return rc; + } + + /* Override HI/LO type with parent WC TCAM type */ + fparms.dir = dir; + fparms.type = TF_TCAM_TBL_TYPE_WC_TCAM; + fparms.hcapi_type = hcapi_type; + fparms.idx = sphy_idx; + + rc = tf_msg_tcam_entry_free(tfp, dev, &fparms); + if (rc) { + /* Log error */ + TFP_DRV_LOG(ERR, + "%s: %s: phyid(%d) free failed, rc:%s\n", + tf_dir_2_str(dir), + tf_tcam_tbl_2_str(fparms.type), + sphy_idx, + strerror(-rc)); + return rc; + } + return rc; +} + +/** Move all shared WC TCAM entries from the high pool into the low pool + * and clear out the high pool entries. + */ +static +int tf_tcam_shared_move(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms, + int key_sz_bytes, + int remap_sz_bytes) +{ + int rc; + struct tf_session *tfs; + struct tf_dev_info *dev; + int log_idx; + uint16_t num_slices; + struct bitalloc *hi_pool, *lo_pool; + uint16_t hi_start, lo_start; + enum tf_tcam_shared_wc_pool_id hi_id, lo_id; + uint16_t hcapi_type; + struct tf_rm_alloc_info info; + int hi_cnt, i, j; + struct tf_tcam_shared_wc_pools *tcam_shared_wc; + void *tcam_shared_db_ptr = NULL; + + TF_CHECK_PARMS2(tfp, parms); + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + /* If we aren't the shared session or one of our + * special types + */ + if (!tf_session_is_shared_session(tfs) || + (parms->tcam_tbl_type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH && + parms->tcam_tbl_type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) { + TFP_DRV_LOG(ERR, + "%s: Session must be shared with HI/LO type\n", + tf_dir_2_str(parms->dir)); + return -EOPNOTSUPP; + } + + if (!tf_tcam_db_valid(tfp, parms->dir)) { + TFP_DRV_LOG(ERR, + "%s: tcam shared pool doesn't exist\n", + tf_dir_2_str(parms->dir)); + return -ENOMEM; + } + + /* Retrieve the device information */ + rc = tf_session_get_device(tfs, &dev); + if (rc) { + /* TODO print amazing error */ + return rc; + } + rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices); + if (rc) + return rc; + + rc = tf_tcam_shared_get_rm_info(tfp, + parms->dir, + &hcapi_type, + &info); + if (rc) { + TFP_DRV_LOG(ERR, + "%s: TCAM rm info get failed\n", + tf_dir_2_str(parms->dir)); + return rc; + } + + rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr); + if (rc) { + TFP_DRV_LOG(ERR, + "Failed to get tcam_shared_db from session, rc:%s\n", + strerror(-rc)); + return rc; + } + tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr; + + hi_id = TF_TCAM_SHARED_WC_POOL_HI; + hi_pool = tcam_shared_wc->db[parms->dir][hi_id].pool; + hi_start = tcam_shared_wc->db[parms->dir][hi_id].info.start; + + lo_id = TF_TCAM_SHARED_WC_POOL_LO; + lo_pool = tcam_shared_wc->db[parms->dir][lo_id].pool; + lo_start = tcam_shared_wc->db[parms->dir][lo_id].info.start; + + if (hi_pool == NULL || lo_pool == NULL) + return -ENOMEM; + + /* Get the total count of in use entries in the high pool + */ + hi_cnt = ba_inuse_count(hi_pool); + + /* Copy each valid entry to the same low pool logical offset + */ + for (i = 0; i < hi_cnt; i++) { + /* Go through all the slices + */ + for (j = 0; j < num_slices; j++) { + /* Find next free starting from where we left off + */ + log_idx = ba_find_next_inuse(hi_pool, i); + + if (log_idx < 0) { + TFP_DRV_LOG(ERR, + "Expected a found %s entry %d\n", + tf_pool_2_str(hi_id), + i); + goto done; + } + /* The user should have never allocated from the low + * pool because the move only happens when switching + * from the high to the low pool + */ + if (ba_alloc_index(lo_pool, log_idx) < 0) { + TFP_DRV_LOG(ERR, + "Cannot allocate %s index %d\n", + tf_pool_2_str(lo_id), + i); + goto done; + } + + if (j == 0) { + rc = tf_tcam_shared_move_entry(tfp, dev, + hcapi_type, + parms->dir, + hi_start + log_idx, + lo_start + log_idx, + key_sz_bytes, + remap_sz_bytes, + num_slices); + if (rc) { + TFP_DRV_LOG(ERR, + "Cannot allocate %s index %d\n", + tf_pool_2_str(hi_id), + i); + goto done; + } + ba_free(hi_pool, log_idx); + TFP_DRV_LOG(DEBUG, + "%s: TCAM shared move pool(%s) phyid(%d)\n", + tf_dir_2_str(parms->dir), + tf_pool_2_str(hi_id), + hi_start + log_idx); + TFP_DRV_LOG(DEBUG, + "to pool(%s) phyid(%d)\n", + tf_pool_2_str(lo_id), + lo_start + log_idx); + } + } + } +done: + return rc; +} + +/* Normally, device specific code wouldn't reside here, it belongs + * in a separate device specific function in tf_device_pxx.c. + * But this code is placed here as it is not a long term solution + * and we would like to have this code centrally located for easy + * removal + */ +#define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4 12 +#define TF_TCAM_SHARED_REMAP_SZ_BYTES_P4 4 + +int tf_tcam_shared_move_p4(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms) +{ + int rc = 0; + rc = tf_tcam_shared_move(tfp, + parms, + TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4, + TF_TCAM_SHARED_REMAP_SZ_BYTES_P4); + return rc; +} + +#define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 24 +#define TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 8 + +int tf_tcam_shared_move_p58(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms) +{ + int rc = 0; + rc = tf_tcam_shared_move(tfp, + parms, + TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58, + TF_TCAM_SHARED_REMAP_SZ_BYTES_P58); + return rc; +} diff --git a/drivers/net/bnxt/tf_core/tf_tcam_shared.h b/drivers/net/bnxt/tf_core/tf_tcam_shared.h index fad6e23b4c..5588125470 100644 --- a/drivers/net/bnxt/tf_core/tf_tcam_shared.h +++ b/drivers/net/bnxt/tf_core/tf_tcam_shared.h @@ -124,4 +124,39 @@ int tf_tcam_shared_set(struct tf *tfp, int tf_tcam_shared_get(struct tf *tfp, struct tf_tcam_get_parms *parms); + +/** + * Moves entries from the WC_TCAM_HI to the WC_TCAM_LO shared pools + * for the P4 device. + * + * [in] tfp + * Pointer to the truflow handle + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tcam_shared_move_p4(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms); + +/** + * Moves entries from the WC_TCAM_HI to the WC_TCAM_LO shared pools + * for the P58 device. + * + * [in] tfp + * Pointer to the truflow handle + * + * [in] parms + * Pointer to parameters + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +int tf_tcam_shared_move_p58(struct tf *tfp, + struct tf_move_tcam_shared_entries_parms *parms); + #endif /* _TF_TCAM_SHARED_H */