From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 27643A0563; Wed, 15 Apr 2020 10:22:03 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 977EF1D586; Wed, 15 Apr 2020 10:19:52 +0200 (CEST) Received: from mail-pl1-f196.google.com (mail-pl1-f196.google.com [209.85.214.196]) by dpdk.org (Postfix) with ESMTP id C54841D583 for ; Wed, 15 Apr 2020 10:19:50 +0200 (CEST) Received: by mail-pl1-f196.google.com with SMTP id h11so973916plr.11 for ; Wed, 15 Apr 2020 01:19:50 -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; bh=SgvtKQB2HI74qZyFpIoaCj1jaT72/mSxYFN8O056Kj8=; b=OWwZzp77klM3kotHZp/puyDhTCj/X1HJTszbJoqs5+1d5QwGDgAcG3FGc3wTdsuQZ+ zKVUik6zyj4b942hdvixjLPbqR2moxXqwGhMVHYdHL5lUN2YbQl8SxMlI+vaNZbl+Elc fJ1o6q6Lb6d/8SZleCQ50ay+WhUzdMJM3VZzY= 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; bh=SgvtKQB2HI74qZyFpIoaCj1jaT72/mSxYFN8O056Kj8=; b=EkKwtfZS8wb8dwRa2asZYCaF9Rp4H6tBpIAmiXxZemI+2hP3psI/s2pMZ/zxxz8O4c TPpYfuCNsBBVwXji6E9JGzyBzQkmdxCqhqG5EHgQDIal6mLsl59hhqY44IaSTf+l/LNe 5/gV64aIruWddqwVOHIzN4UblfC+wtmUPWC0ChLtFGEFvzlxQwImYHVeAG5n0WckylHm TzuJ0ykMrz/hmmyV5qQsH22V0PFnVbIePkWoYkTcSbggg8+uydkw3C6IMx5cFk3z4QNS kAXWfdSHF6MOYyYb5deStVJkaobR3UO9j37keFYyRm9h2ixRW74yEV7siLAXaIBwTBuL ygGg== X-Gm-Message-State: AGi0PuZzKd9oFD4NzRQ7lsr/mfelBmnv84JQkj947EzAAZJyH+xbjJXb eSakpEzIJf6o7ChoDmEKa9bipZlAJAPLP2NlaqlqWCnZtndIEZTPZODpNze5xHdjm3Hgu9erEwh Q2NnK3+JP4LFgKat9DNkWiEmWz6GsZl7O6RqIqTYolkglw4GbRQl1+I52NNNrxyWNd/wg X-Google-Smtp-Source: APiQypL1MmhpkdDtzDr5ZKRnKMWX6DGarnjHazey94ws1eSdMmgrA6rHL5laSm+GLv4frtVbiAKNqA== X-Received: by 2002:a17:902:148:: with SMTP id 66mr3895851plb.148.1586938789338; Wed, 15 Apr 2020 01:19:49 -0700 (PDT) Received: from S60.dhcp.broadcom.net ([192.19.234.250]) by smtp.gmail.com with ESMTPSA id fy21sm3819019pjb.25.2020.04.15.01.19.47 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Apr 2020 01:19:48 -0700 (PDT) From: Venkat Duvvuru To: dev@dpdk.org Cc: Shahaji Bhosle , Jay Ding Date: Wed, 15 Apr 2020 13:48:47 +0530 Message-Id: <1586938751-32808-11-git-send-email-venkatkumar.duvvuru@broadcom.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1586938751-32808-1-git-send-email-venkatkumar.duvvuru@broadcom.com> References: <1586852011-37536-1-git-send-email-venkatkumar.duvvuru@broadcom.com> <1586938751-32808-1-git-send-email-venkatkumar.duvvuru@broadcom.com> Subject: [dpdk-dev] [PATCH v4 10/34] net/bnxt: add tf core TCAM support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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: Shahaji Bhosle - Add TruFlow TCAM public API functions - Add TCAM support functions as well as public APIs. Signed-off-by: Shahaji Bhosle Signed-off-by: Jay Ding Reviewed-by: Randy Schacher Reviewed-by: Ajit Kumar Khaparde --- drivers/net/bnxt/tf_core/tf_core.c | 163 ++++++++++++++++++++++++++ drivers/net/bnxt/tf_core/tf_core.h | 227 +++++++++++++++++++++++++++++++++++++ drivers/net/bnxt/tf_core/tf_msg.c | 159 ++++++++++++++++++++++++++ drivers/net/bnxt/tf_core/tf_msg.h | 30 +++++ 4 files changed, 579 insertions(+) diff --git a/drivers/net/bnxt/tf_core/tf_core.c b/drivers/net/bnxt/tf_core/tf_core.c index 7b027f7..39f4a11 100644 --- a/drivers/net/bnxt/tf_core/tf_core.c +++ b/drivers/net/bnxt/tf_core/tf_core.c @@ -440,3 +440,166 @@ int tf_free_identifier(struct tf *tfp, return 0; } + +int +tf_alloc_tcam_entry(struct tf *tfp, + struct tf_alloc_tcam_entry_parms *parms) +{ + int rc; + int index; + struct tf_session *tfs; + struct bitalloc *session_pool; + + if (parms == NULL || tfp == NULL) + return -EINVAL; + + if (tfp->session == NULL || tfp->session->core_data == NULL) { + PMD_DRV_LOG(ERR, "%s: session error\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + tfs = (struct tf_session *)(tfp->session->core_data); + + rc = tf_rm_lookup_tcam_type_pool(tfs, + parms->dir, + parms->tcam_tbl_type, + &session_pool); + /* Error logging handled by tf_rm_lookup_tcam_type_pool */ + if (rc) + return rc; + + index = ba_alloc(session_pool); + if (index == BA_FAIL) { + PMD_DRV_LOG(ERR, "%s: %s: No resource available\n", + tf_dir_2_str(parms->dir), + tf_tcam_tbl_2_str(parms->tcam_tbl_type)); + return -ENOMEM; + } + + parms->idx = index; + return 0; +} + +int +tf_set_tcam_entry(struct tf *tfp, + struct tf_set_tcam_entry_parms *parms) +{ + int rc; + int id; + struct tf_session *tfs; + struct bitalloc *session_pool; + + if (tfp == NULL || parms == NULL) { + PMD_DRV_LOG(ERR, "Invalid parameters\n"); + return -EINVAL; + } + + if (tfp->session == NULL || tfp->session->core_data == NULL) { + PMD_DRV_LOG(ERR, + "%s, Session info invalid\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + tfs = (struct tf_session *)(tfp->session->core_data); + + /* + * Each tcam send msg function should check for key sizes range + */ + + rc = tf_rm_lookup_tcam_type_pool(tfs, + parms->dir, + parms->tcam_tbl_type, + &session_pool); + /* Error logging handled by tf_rm_lookup_tcam_type_pool */ + if (rc) + return rc; + + + /* Verify that the entry has been previously allocated */ + id = ba_inuse(session_pool, parms->idx); + if (id != 1) { + PMD_DRV_LOG(ERR, + "%s: %s: Invalid or not allocated index, idx:%d\n", + tf_dir_2_str(parms->dir), + tf_tcam_tbl_2_str(parms->tcam_tbl_type), + parms->idx); + return -EINVAL; + } + + rc = tf_msg_tcam_entry_set(tfp, parms); + + return rc; +} + +int +tf_get_tcam_entry(struct tf *tfp __rte_unused, + struct tf_get_tcam_entry_parms *parms __rte_unused) +{ + int rc = -EOPNOTSUPP; + + if (tfp == NULL || parms == NULL) { + PMD_DRV_LOG(ERR, "Invalid parameters\n"); + return -EINVAL; + } + + if (tfp->session == NULL || tfp->session->core_data == NULL) { + PMD_DRV_LOG(ERR, + "%s, Session info invalid\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + return rc; +} + +int +tf_free_tcam_entry(struct tf *tfp, + struct tf_free_tcam_entry_parms *parms) +{ + int rc; + struct tf_session *tfs; + struct bitalloc *session_pool; + + if (parms == NULL || tfp == NULL) + return -EINVAL; + + if (tfp->session == NULL || tfp->session->core_data == NULL) { + PMD_DRV_LOG(ERR, "%s: Session error\n", + tf_dir_2_str(parms->dir)); + return -EINVAL; + } + + tfs = (struct tf_session *)(tfp->session->core_data); + + rc = tf_rm_lookup_tcam_type_pool(tfs, + parms->dir, + parms->tcam_tbl_type, + &session_pool); + /* Error logging handled by tf_rm_lookup_tcam_type_pool */ + if (rc) + return rc; + + rc = ba_inuse(session_pool, (int)parms->idx); + if (rc == BA_FAIL || rc == BA_ENTRY_FREE) { + PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free", + tf_dir_2_str(parms->dir), + tf_tcam_tbl_2_str(parms->tcam_tbl_type), + parms->idx); + return -EINVAL; + } + + ba_free(session_pool, (int)parms->idx); + + rc = tf_msg_tcam_entry_free(tfp, parms); + if (rc) { + /* Log error */ + PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed", + tf_dir_2_str(parms->dir), + tf_tcam_tbl_2_str(parms->tcam_tbl_type), + parms->idx); + } + + return rc; +} diff --git a/drivers/net/bnxt/tf_core/tf_core.h b/drivers/net/bnxt/tf_core/tf_core.h index afad9ea..1431d06 100644 --- a/drivers/net/bnxt/tf_core/tf_core.h +++ b/drivers/net/bnxt/tf_core/tf_core.h @@ -472,6 +472,233 @@ enum tf_tcam_tbl_type { }; /** + * @page tcam TCAM Access + * + * @ref tf_alloc_tcam_entry + * + * @ref tf_set_tcam_entry + * + * @ref tf_get_tcam_entry + * + * @ref tf_free_tcam_entry + */ + +/** tf_alloc_tcam_entry parameter definition + */ +struct tf_alloc_tcam_entry_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] TCAM table type + */ + enum tf_tcam_tbl_type tcam_tbl_type; + /** + * [in] Enable search for matching entry + */ + uint8_t search_enable; + /** + * [in] Key data to match on (if search) + */ + uint8_t *key; + /** + * [in] key size in bits (if search) + */ + uint16_t key_sz_in_bits; + /** + * [in] Mask data to match on (if search) + */ + uint8_t *mask; + /** + * [in] Priority of entry requested (definition TBD) + */ + uint32_t priority; + /** + * [out] If search, set if matching entry found + */ + uint8_t hit; + /** + * [out] Current refcnt after allocation + */ + uint16_t ref_cnt; + /** + * [out] Idx allocated + * + */ + uint16_t idx; +}; + +/** allocate TCAM entry + * + * Allocate a TCAM entry - one of these types: + * + * L2 Context + * Profile TCAM + * WC TCAM + * VEB TCAM + * + * This function allocates a TCAM table record. This function + * will attempt to allocate a TCAM table entry from the session + * owned TCAM entries or search a shadow copy of the TCAM table for a + * matching entry if search is enabled. Key, mask and result must match for + * hit to be set. Only TruFlow core data is accessed. + * A hash table to entry mapping is maintained for search purposes. If + * search is not enabled, the first available free entry is returned based + * on priority and alloc_cnt is set to 1. If search is enabled and a matching + * entry to entry_data is found, hit is set to TRUE and alloc_cnt is set to 1. + * RefCnt is also returned. + * + * Also returns success or failure code. + */ +int tf_alloc_tcam_entry(struct tf *tfp, + struct tf_alloc_tcam_entry_parms *parms); + +/** tf_set_tcam_entry parameter definition + */ +struct tf_set_tcam_entry_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] TCAM table type + */ + enum tf_tcam_tbl_type tcam_tbl_type; + /** + * [in] base index of the entry to program + */ + uint16_t idx; + /** + * [in] struct containing key + */ + uint8_t *key; + /** + * [in] struct containing mask fields + */ + uint8_t *mask; + /** + * [in] key size in bits (if search) + */ + uint16_t key_sz_in_bits; + /** + * [in] struct containing result + */ + uint8_t *result; + /** + * [in] struct containing result size in bits + */ + uint16_t result_sz_in_bits; +}; + +/** set TCAM entry + * + * Program a TCAM table entry for a TruFlow session. + * + * If the entry has not been allocated, an error will be returned. + * + * Returns success or failure code. + */ +int tf_set_tcam_entry(struct tf *tfp, + struct tf_set_tcam_entry_parms *parms); + +/** tf_get_tcam_entry parameter definition + */ +struct tf_get_tcam_entry_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] TCAM table type + */ + enum tf_tcam_tbl_type tcam_tbl_type; + /** + * [in] index of the entry to get + */ + uint16_t idx; + /** + * [out] struct containing key + */ + uint8_t *key; + /** + * [out] struct containing mask fields + */ + uint8_t *mask; + /** + * [out] key size in bits + */ + uint16_t key_sz_in_bits; + /** + * [out] struct containing result + */ + uint8_t *result; + /** + * [out] struct containing result size in bits + */ + uint16_t result_sz_in_bits; +}; + +/** get TCAM entry + * + * Program a TCAM table entry for a TruFlow session. + * + * If the entry has not been allocated, an error will be returned. + * + * Returns success or failure code. + */ +int tf_get_tcam_entry(struct tf *tfp, + struct tf_get_tcam_entry_parms *parms); + +/** tf_free_tcam_entry parameter definition + */ +struct tf_free_tcam_entry_parms { + /** + * [in] receive or transmit direction + */ + enum tf_dir dir; + /** + * [in] TCAM table type + */ + enum tf_tcam_tbl_type tcam_tbl_type; + /** + * [in] Index to free + */ + uint16_t idx; + /** + * [out] reference count after free + */ + uint16_t ref_cnt; +}; + +/** free TCAM entry + * + * Free TCAM entry. + * + * Firmware checks to ensure the TCAM entries are owned by the TruFlow + * session. TCAM entry will be invalidated. All-ones mask. + * writes to hw. + * + * WCTCAM profile id of 0 must be used to invalidate an entry. + * + * Returns success or failure code. + */ +int tf_free_tcam_entry(struct tf *tfp, + struct tf_free_tcam_entry_parms *parms); + +/** + * @page table Table Access + * + * @ref tf_alloc_tbl_entry + * + * @ref tf_free_tbl_entry + * + * @ref tf_set_tbl_entry + * + * @ref tf_get_tbl_entry + */ + +/** * Enumeration of TruFlow table types. A table type is used to identify a * resource object. * diff --git a/drivers/net/bnxt/tf_core/tf_msg.c b/drivers/net/bnxt/tf_core/tf_msg.c index c44f96f..9d17440 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.c +++ b/drivers/net/bnxt/tf_core/tf_msg.c @@ -106,6 +106,39 @@ struct tf_msg_dma_buf { uint64_t pa_addr; }; +static int +tf_tcam_tbl_2_hwrm(enum tf_tcam_tbl_type tcam_type, + uint32_t *hwrm_type) +{ + int rc = 0; + + switch (tcam_type) { + case TF_TCAM_TBL_TYPE_L2_CTXT_TCAM: + *hwrm_type = TF_DEV_DATA_TYPE_TF_L2_CTX_ENTRY; + break; + case TF_TCAM_TBL_TYPE_PROF_TCAM: + *hwrm_type = TF_DEV_DATA_TYPE_TF_PROF_TCAM_ENTRY; + break; + case TF_TCAM_TBL_TYPE_WC_TCAM: + *hwrm_type = TF_DEV_DATA_TYPE_TF_WC_ENTRY; + break; + case TF_TCAM_TBL_TYPE_VEB_TCAM: + rc = -EOPNOTSUPP; + break; + case TF_TCAM_TBL_TYPE_SP_TCAM: + rc = -EOPNOTSUPP; + break; + case TF_TCAM_TBL_TYPE_CT_RULE_TCAM: + rc = -EOPNOTSUPP; + break; + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + /** * Sends session open request to TF Firmware */ @@ -835,3 +868,129 @@ tf_msg_session_sram_resc_flush(struct tf *tfp, return tfp_le_to_cpu_32(parms.tf_resp_code); } + +#define TF_BYTES_PER_SLICE(tfp) 12 +#define NUM_SLICES(tfp, bytes) \ + (((bytes) + TF_BYTES_PER_SLICE(tfp) - 1) / TF_BYTES_PER_SLICE(tfp)) + +static int +tf_msg_get_dma_buf(struct tf_msg_dma_buf *buf, int size) +{ + struct tfp_calloc_parms alloc_parms; + int rc; + + /* Allocate session */ + alloc_parms.nitems = 1; + alloc_parms.size = size; + alloc_parms.alignment = 0; + rc = tfp_calloc(&alloc_parms); + if (rc) { + /* Log error */ + PMD_DRV_LOG(ERR, + "Failed to allocate tcam dma entry, rc:%d\n", + rc); + return -ENOMEM; + } + + buf->pa_addr = (uintptr_t)alloc_parms.mem_pa; + buf->va_addr = alloc_parms.mem_va; + + return 0; +} + +int +tf_msg_tcam_entry_set(struct tf *tfp, + struct tf_set_tcam_entry_parms *parms) +{ + int rc; + struct tfp_send_msg_parms mparms = { 0 }; + struct hwrm_tf_tcam_set_input req = { 0 }; + struct hwrm_tf_tcam_set_output resp = { 0 }; + uint16_t key_bytes = + TF_BITS2BYTES_WORD_ALIGN(parms->key_sz_in_bits); + uint16_t result_bytes = + TF_BITS2BYTES_WORD_ALIGN(parms->result_sz_in_bits); + struct tf_msg_dma_buf buf = { 0 }; + uint8_t *data = NULL; + int data_size = 0; + + rc = tf_tcam_tbl_2_hwrm(parms->tcam_tbl_type, &req.type); + if (rc != 0) + return rc; + + req.idx = tfp_cpu_to_le_16(parms->idx); + if (parms->dir == TF_DIR_TX) + req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX; + + req.key_size = key_bytes; + req.mask_offset = key_bytes; + /* Result follows after key and mask, thus multiply by 2 */ + req.result_offset = 2 * key_bytes; + req.result_size = result_bytes; + data_size = 2 * req.key_size + req.result_size; + + if (data_size <= TF_PCI_BUF_SIZE_MAX) { + /* use pci buffer */ + data = &req.dev_data[0]; + } else { + /* use dma buffer */ + req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA; + rc = tf_msg_get_dma_buf(&buf, data_size); + if (rc != 0) + return rc; + data = buf.va_addr; + memcpy(&req.dev_data[0], &buf.pa_addr, sizeof(buf.pa_addr)); + } + + memcpy(&data[0], parms->key, key_bytes); + memcpy(&data[key_bytes], parms->mask, key_bytes); + memcpy(&data[req.result_offset], parms->result, result_bytes); + + mparms.tf_type = HWRM_TF_TCAM_SET; + mparms.req_data = (uint32_t *)&req; + mparms.req_size = sizeof(req); + mparms.resp_data = (uint32_t *)&resp; + mparms.resp_size = sizeof(resp); + mparms.mailbox = TF_KONG_MB; + + rc = tfp_send_msg_direct(tfp, + &mparms); + if (rc) + return rc; + + if (buf.va_addr != NULL) + tfp_free(buf.va_addr); + + return rc; +} + +int +tf_msg_tcam_entry_free(struct tf *tfp, + struct tf_free_tcam_entry_parms *in_parms) +{ + int rc; + struct hwrm_tf_tcam_free_input req = { 0 }; + struct hwrm_tf_tcam_free_output resp = { 0 }; + struct tfp_send_msg_parms parms = { 0 }; + + /* Populate the request */ + rc = tf_tcam_tbl_2_hwrm(in_parms->tcam_tbl_type, &req.type); + if (rc != 0) + return rc; + + req.count = 1; + req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx); + if (in_parms->dir == TF_DIR_TX) + req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX; + + parms.tf_type = HWRM_TF_TCAM_FREE; + parms.req_data = (uint32_t *)&req; + parms.req_size = sizeof(req); + parms.resp_data = (uint32_t *)&resp; + parms.resp_size = sizeof(resp); + parms.mailbox = TF_KONG_MB; + + rc = tfp_send_msg_direct(tfp, + &parms); + return rc; +} diff --git a/drivers/net/bnxt/tf_core/tf_msg.h b/drivers/net/bnxt/tf_core/tf_msg.h index 057de84..fa74d78 100644 --- a/drivers/net/bnxt/tf_core/tf_msg.h +++ b/drivers/net/bnxt/tf_core/tf_msg.h @@ -120,4 +120,34 @@ int tf_msg_session_sram_resc_flush(struct tf *tfp, enum tf_dir dir, struct tf_rm_entry *sram_entry); +/** + * Sends tcam entry 'set' to the Firmware. + * + * [in] tfp + * Pointer to session handle + * + * [in] parms + * Pointer to set parameters + * + * Returns: + * 0 on Success else internal Truflow error + */ +int tf_msg_tcam_entry_set(struct tf *tfp, + struct tf_set_tcam_entry_parms *parms); + +/** + * Sends tcam entry 'free' to the Firmware. + * + * [in] tfp + * Pointer to session handle + * + * [in] parms + * Pointer to free parameters + * + * Returns: + * 0 on Success else internal Truflow error + */ +int tf_msg_tcam_entry_free(struct tf *tfp, + struct tf_free_tcam_entry_parms *parms); + #endif /* _TF_MSG_H_ */ -- 2.7.4