From patchwork Mon Dec 11 17:11:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 135036 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 885C6436C8; Mon, 11 Dec 2023 18:12:34 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D3B5742DDD; Mon, 11 Dec 2023 18:11:38 +0100 (CET) Received: from mail-qk1-f169.google.com (mail-qk1-f169.google.com [209.85.222.169]) by mails.dpdk.org (Postfix) with ESMTP id 44F1042DA3 for ; Mon, 11 Dec 2023 18:11:37 +0100 (CET) Received: by mail-qk1-f169.google.com with SMTP id af79cd13be357-77f408d123bso146713485a.0 for ; Mon, 11 Dec 2023 09:11:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1702314696; x=1702919496; darn=dpdk.org; h=mime-version:references:in-reply-to:message-id:date:subject:to:from :from:to:cc:subject:date:message-id:reply-to; bh=FL1grHKT+Xmx2EA/zQNDiok355sO1wixfqx0xp0u5C0=; b=fCki1XUcJ/ppPJerXCsFj9DiIVGCgEudE1ZboHVAKJoJpN45PU9VS35Tm4Faw2QCDb 8KpzSJPTg1htrPbZiaadTiXxVsDWBIy6JTF7KuLUvuq5w+UJBsVDx6djgueynqk0J6tW QvA9q9+qZNQPkwV1X6MgxqKI/JbQW8FrljXiM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702314696; x=1702919496; h=mime-version:references:in-reply-to:message-id:date:subject:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FL1grHKT+Xmx2EA/zQNDiok355sO1wixfqx0xp0u5C0=; b=C4XDyoG8ZUZGwn7BuoYPMDuK6cvFU+mahM7i355FGY0kO4Xn3v6cKWzJ4Falm1Ogwl WTxWoNuoC/XHl6p4FM4E14ZlVAy0NyJ3Zshy/ZS0fmdSZ0rXPWzh4pQQj9499b98rsrG W0oxwTRPfQhpQ94+V7FpNZo6aP3NcusAnD8tPfVRh0ccHIQ/izwVpbRpYf4Ia+rYzBr5 JNTH3MEH4Dq7t2+KqZdGvkoVsnCOxGMP6z4p4E91XIKjwSrBk1vkKaN/vOo24abTF21u 4i4wyftROIoqfzVETRiDTqsPSiE9ChXzLiP8/SI6Pbv7gBXy2ol3da6bzZfo7gCx4OeN FCJw== X-Gm-Message-State: AOJu0YzSAVCUkjVgTOGDQvDlQnpwbKcmwAZ+vLiCKIvkvCFVQYpC93a4 GR0JHv0a5WBg3KDd15I5A1w3l7jN/0nplsdM2n46pJZsDbSobc+RaEgSJfuGuzjRSuWO4YW9pdc a4J1Ps/rUaHLdse4uG3mYz4a6hvRiCYQgUO1btW2ZSYbqTnBIlAGDwQ3Ro4BZNu2PguE+ X-Google-Smtp-Source: AGHT+IFUzC1dX8uoti9F9H3iCHFipWYaWAhYtxea26KPSCB5d0v7mWq4/0I3Nk2djpSzMEwOywbKsA== X-Received: by 2002:ae9:c00a:0:b0:77b:aa20:8dd with SMTP id u10-20020ae9c00a000000b0077baa2008ddmr2987023qkk.8.1702314695776; Mon, 11 Dec 2023 09:11:35 -0800 (PST) Received: from C02GC2QQMD6T.wifi.broadcom.net ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id qz16-20020a05620a8c1000b0077efdfbd730sm3094581qkn.34.2023.12.11.09.11.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Dec 2023 09:11:35 -0800 (PST) From: Ajit Khaparde To: dev@dpdk.org Subject: [PATCH v3 09/14] net/bnxt: add support for backing store v2 Date: Mon, 11 Dec 2023 09:11:04 -0800 Message-Id: <20231211171109.89716-10-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.39.2 (Apple Git-143) In-Reply-To: <20231211171109.89716-1-ajit.khaparde@broadcom.com> References: <20231211171109.89716-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add backing store v2 changes. The firmware supports the new backing store scheme for P7 and newer devices. To support this, the driver queries the different types of chip contexts the firmware supports and allocates the appropriate size of memory for the firmware and hardware to use. The code then goes ahead and frees up the memory during cleanup. Older P5 device family continues to support the version 1 of backing store. While the P4 device family does not need any backing store memory. Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 69 ++++++- drivers/net/bnxt/bnxt_ethdev.c | 177 ++++++++++++++++-- drivers/net/bnxt/bnxt_hwrm.c | 319 +++++++++++++++++++++++++++++++-- drivers/net/bnxt/bnxt_hwrm.h | 8 + drivers/net/bnxt/bnxt_util.c | 10 ++ drivers/net/bnxt/bnxt_util.h | 1 + 6 files changed, 545 insertions(+), 39 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 3fbdf1ddcc..68c4778dc3 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -81,6 +81,11 @@ #define BROADCOM_DEV_957508_N2100 0x5208 #define BROADCOM_DEV_957414_N225 0x4145 +#define HWRM_SPEC_CODE_1_8_3 0x10803 +#define HWRM_VERSION_1_9_1 0x10901 +#define HWRM_VERSION_1_9_2 0x10903 +#define HWRM_VERSION_1_10_2_13 0x10a020d + #define BNXT_MAX_MTU 9574 #define BNXT_NUM_VLANS 2 #define BNXT_MAX_PKT_LEN (BNXT_MAX_MTU + RTE_ETHER_HDR_LEN +\ @@ -430,16 +435,26 @@ struct bnxt_coal { #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHFT) #define MAX_CTX_PAGES (BNXT_PAGE_SIZE / 8) +#define BNXT_RTE_MEMZONE_FLAG (RTE_MEMZONE_1GB | RTE_MEMZONE_IOVA_CONTIG) + #define PTU_PTE_VALID 0x1UL #define PTU_PTE_LAST 0x2UL #define PTU_PTE_NEXT_TO_LAST 0x4UL +#define BNXT_CTX_MIN 1 +#define BNXT_CTX_INV 0xffff + +#define BNXT_CTX_INIT_VALID(flags) \ + ((flags) & \ + HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_FLAGS_ENABLE_CTX_KIND_INIT) + struct bnxt_ring_mem_info { int nr_pages; int page_size; uint32_t flags; #define BNXT_RMEM_VALID_PTE_FLAG 1 #define BNXT_RMEM_RING_PTE_FLAG 2 +#define BNXT_RMEM_USE_FULL_PAGE_FLAG 4 void **pg_arr; rte_iova_t *dma_arr; @@ -460,7 +475,50 @@ struct bnxt_ctx_pg_info { struct bnxt_ring_mem_info ring_mem; }; +struct bnxt_ctx_mem { + uint16_t type; + uint16_t entry_size; + uint32_t flags; +#define BNXT_CTX_MEM_TYPE_VALID \ + HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_FLAGS_TYPE_VALID + uint32_t instance_bmap; + uint8_t init_value; + uint8_t entry_multiple; + uint16_t init_offset; +#define BNXT_CTX_INIT_INVALID_OFFSET 0xffff + uint32_t max_entries; + uint32_t min_entries; + uint8_t last:1; + uint8_t split_entry_cnt; +#define BNXT_MAX_SPLIT_ENTRY 4 + union { + struct { + uint32_t qp_l2_entries; + uint32_t qp_qp1_entries; + uint32_t qp_fast_qpmd_entries; + }; + uint32_t srq_l2_entries; + uint32_t cq_l2_entries; + uint32_t vnic_entries; + struct { + uint32_t mrav_av_entries; + uint32_t mrav_num_entries_units; + }; + uint32_t split[BNXT_MAX_SPLIT_ENTRY]; + }; + struct bnxt_ctx_pg_info *pg_info; +}; + +#define BNXT_CTX_FLAG_INITED 0x01 + struct bnxt_ctx_mem_info { + struct bnxt_ctx_mem *ctx_arr; + uint32_t supported_types; + uint32_t flags; + uint16_t types; + uint8_t tqm_fp_rings_count; + + /* The following are used for V1 */ uint32_t qp_max_entries; uint16_t qp_min_qp1_entries; uint16_t qp_max_l2_entries; @@ -484,10 +542,6 @@ struct bnxt_ctx_mem_info { uint16_t tim_entry_size; uint32_t tim_max_entries; uint8_t tqm_entries_multiple; - uint8_t tqm_fp_rings_count; - - uint32_t flags; -#define BNXT_CTX_FLAG_INITED 0x01 struct bnxt_ctx_pg_info qp_mem; struct bnxt_ctx_pg_info srq_mem; @@ -739,6 +793,13 @@ struct bnxt { #define BNXT_FW_CAP_TRUFLOW_EN BIT(8) #define BNXT_FW_CAP_VLAN_TX_INSERT BIT(9) #define BNXT_FW_CAP_RX_ALL_PKT_TS BIT(10) +#define BNXT_FW_CAP_BACKING_STORE_V2 BIT(12) +#define BNXT_FW_BACKING_STORE_V2_EN(bp) \ + ((bp)->fw_cap & BNXT_FW_CAP_BACKING_STORE_V2) +#define BNXT_FW_BACKING_STORE_V1_EN(bp) \ + (BNXT_CHIP_P5_P7((bp)) && \ + (bp)->hwrm_spec_code >= HWRM_VERSION_1_9_2 && \ + !BNXT_VF((bp))) #define BNXT_TRUFLOW_EN(bp) ((bp)->fw_cap & BNXT_FW_CAP_TRUFLOW_EN &&\ (bp)->app_id != 0xFF) diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 95f9dd1aa1..004b2df4f4 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -4759,8 +4759,26 @@ static int bnxt_map_pci_bars(struct rte_eth_dev *eth_dev) return 0; } +static void bnxt_init_ctxm_mem(struct bnxt_ctx_mem *ctxm, void *p, int len) +{ + uint8_t init_val = ctxm->init_value; + uint16_t offset = ctxm->init_offset; + uint8_t *p2 = p; + int i; + + if (!init_val) + return; + if (offset == BNXT_CTX_INIT_INVALID_OFFSET) { + memset(p, init_val, len); + return; + } + for (i = 0; i < len; i += ctxm->entry_size) + *(p2 + i + offset) = init_val; +} + static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, struct bnxt_ctx_pg_info *ctx_pg, + struct bnxt_ctx_mem *ctxm, uint32_t mem_size, const char *suffix, uint16_t idx) @@ -4776,8 +4794,8 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, if (!mem_size) return 0; - rmem->nr_pages = RTE_ALIGN_MUL_CEIL(mem_size, BNXT_PAGE_SIZE) / - BNXT_PAGE_SIZE; + rmem->nr_pages = + RTE_ALIGN_MUL_CEIL(mem_size, BNXT_PAGE_SIZE) / BNXT_PAGE_SIZE; rmem->page_size = BNXT_PAGE_SIZE; snprintf(name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_pg_arr%s_%x_%d", @@ -4794,13 +4812,13 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, rmem->pg_arr = ctx_pg->ctx_pg_arr; rmem->dma_arr = ctx_pg->ctx_dma_arr; - rmem->flags = BNXT_RMEM_VALID_PTE_FLAG; + rmem->flags = BNXT_RMEM_VALID_PTE_FLAG | BNXT_RMEM_USE_FULL_PAGE_FLAG; valid_bits = PTU_PTE_VALID; if (rmem->nr_pages > 1) { snprintf(name, RTE_MEMZONE_NAMESIZE, - "bnxt_ctx_pg_tbl%s_%x_%d", + "bnxt_ctxpgtbl%s_%x_%d", suffix, idx, bp->eth_dev->data->port_id); name[RTE_MEMZONE_NAMESIZE - 1] = 0; mz = rte_memzone_lookup(name); @@ -4816,9 +4834,11 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, return -ENOMEM; } - memset(mz->addr, 0, mz->len); + memset(mz->addr, 0xff, mz->len); mz_phys_addr = mz->iova; + if (ctxm != NULL) + bnxt_init_ctxm_mem(ctxm, mz->addr, mz->len); rmem->pg_tbl = mz->addr; rmem->pg_tbl_map = mz_phys_addr; rmem->pg_tbl_mz = mz; @@ -4839,9 +4859,11 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, return -ENOMEM; } - memset(mz->addr, 0, mz->len); + memset(mz->addr, 0xff, mz->len); mz_phys_addr = mz->iova; + if (ctxm != NULL) + bnxt_init_ctxm_mem(ctxm, mz->addr, mz->len); for (sz = 0, i = 0; sz < mem_size; sz += BNXT_PAGE_SIZE, i++) { rmem->pg_arr[i] = ((char *)mz->addr) + sz; rmem->dma_arr[i] = mz_phys_addr + sz; @@ -4866,6 +4888,34 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, return 0; } +static void bnxt_free_ctx_mem_v2(struct bnxt *bp) +{ + uint16_t type; + + for (type = 0; type < bp->ctx->types; type++) { + struct bnxt_ctx_mem *ctxm = &bp->ctx->ctx_arr[type]; + struct bnxt_ctx_pg_info *ctx_pg = ctxm->pg_info; + int i, n = 1; + + if (!ctx_pg) + continue; + if (ctxm->instance_bmap) + n = hweight32(ctxm->instance_bmap); + + for (i = 0; i < n; i++) { + rte_free(ctx_pg[i].ctx_pg_arr); + rte_free(ctx_pg[i].ctx_dma_arr); + rte_memzone_free(ctx_pg[i].ring_mem.mz); + rte_memzone_free(ctx_pg[i].ring_mem.pg_tbl_mz); + } + + rte_free(ctx_pg); + ctxm->pg_info = NULL; + } + rte_free(bp->ctx->ctx_arr); + bp->ctx->ctx_arr = NULL; +} + static void bnxt_free_ctx_mem(struct bnxt *bp) { int i; @@ -4874,6 +4924,12 @@ static void bnxt_free_ctx_mem(struct bnxt *bp) return; bp->ctx->flags &= ~BNXT_CTX_FLAG_INITED; + + if (BNXT_FW_BACKING_STORE_V2_EN(bp)) { + bnxt_free_ctx_mem_v2(bp); + goto free_ctx; + } + rte_free(bp->ctx->qp_mem.ctx_pg_arr); rte_free(bp->ctx->srq_mem.ctx_pg_arr); rte_free(bp->ctx->cq_mem.ctx_pg_arr); @@ -4903,6 +4959,7 @@ static void bnxt_free_ctx_mem(struct bnxt *bp) rte_memzone_free(bp->ctx->tqm_mem[i]->ring_mem.mz); } +free_ctx: rte_free(bp->ctx); bp->ctx = NULL; } @@ -4921,28 +4978,113 @@ static void bnxt_free_ctx_mem(struct bnxt *bp) #define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max) +int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp) +{ + struct bnxt_ctx_mem_info *ctx = bp->ctx; + struct bnxt_ctx_mem *ctx2; + uint16_t type; + int rc = 0; + + ctx2 = &ctx->ctx_arr[0]; + for (type = 0; type < ctx->types && rc == 0; type++) { + struct bnxt_ctx_mem *ctxm = &ctx->ctx_arr[type]; + struct bnxt_ctx_pg_info *ctx_pg; + uint32_t entries, mem_size; + int w = 1; + int i; + + if (ctxm->entry_size == 0) + continue; + + ctx_pg = ctxm->pg_info; + + if (ctxm->instance_bmap) + w = hweight32(ctxm->instance_bmap); + + for (i = 0; i < w && rc == 0; i++) { + char name[RTE_MEMZONE_NAMESIZE] = {0}; + + sprintf(name, "_%d_%d", i, type); + + if (ctxm->entry_multiple) + entries = bnxt_roundup(ctxm->max_entries, + ctxm->entry_multiple); + else + entries = ctxm->max_entries; + + if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_CQ) + entries = ctxm->cq_l2_entries; + else if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_QP) + entries = ctxm->qp_l2_entries; + else if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_MRAV) + entries = ctxm->mrav_av_entries; + else if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_TIM) + entries = ctx2->qp_l2_entries; + entries = clamp_t(uint32_t, entries, ctxm->min_entries, + ctxm->max_entries); + ctx_pg[i].entries = entries; + mem_size = ctxm->entry_size * entries; + PMD_DRV_LOG(DEBUG, + "Type:0x%x instance:%d entries:%d size:%d\n", + ctxm->type, i, ctx_pg[i].entries, mem_size); + rc = bnxt_alloc_ctx_mem_blk(bp, &ctx_pg[i], + ctxm->init_value ? ctxm : NULL, + mem_size, name, i); + } + } + + return rc; +} + int bnxt_alloc_ctx_mem(struct bnxt *bp) { struct bnxt_ctx_pg_info *ctx_pg; struct bnxt_ctx_mem_info *ctx; uint32_t mem_size, ena, entries; + int types = BNXT_CTX_MIN; uint32_t entries_sp, min; - int i, rc; + int i, rc = 0; + + if (!BNXT_FW_BACKING_STORE_V1_EN(bp) && + !BNXT_FW_BACKING_STORE_V2_EN(bp)) + return rc; + + if (BNXT_FW_BACKING_STORE_V2_EN(bp)) { + types = bnxt_hwrm_func_backing_store_types_count(bp); + if (types <= 0) + return types; + } + + rc = bnxt_hwrm_func_backing_store_ctx_alloc(bp, types); + if (rc != 0) + return rc; + + if (bp->ctx->flags & BNXT_CTX_FLAG_INITED) + return 0; + + ctx = bp->ctx; + if (BNXT_FW_BACKING_STORE_V2_EN(bp)) { + rc = bnxt_hwrm_func_backing_store_qcaps_v2(bp); + + for (i = 0 ; i < bp->ctx->types && rc == 0; i++) { + struct bnxt_ctx_mem *ctxm = &ctx->ctx_arr[i]; + + rc = bnxt_hwrm_func_backing_store_cfg_v2(bp, ctxm); + } + goto done; + } rc = bnxt_hwrm_func_backing_store_qcaps(bp); if (rc) { PMD_DRV_LOG(ERR, "Query context mem capability failed\n"); return rc; } - ctx = bp->ctx; - if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED)) - return 0; ctx_pg = &ctx->qp_mem; ctx_pg->entries = ctx->qp_min_qp1_entries + ctx->qp_max_l2_entries; if (ctx->qp_entry_size) { mem_size = ctx->qp_entry_size * ctx_pg->entries; - rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "qp_mem", 0); + rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "qp_mem", 0); if (rc) return rc; } @@ -4951,7 +5093,7 @@ int bnxt_alloc_ctx_mem(struct bnxt *bp) ctx_pg->entries = ctx->srq_max_l2_entries; if (ctx->srq_entry_size) { mem_size = ctx->srq_entry_size * ctx_pg->entries; - rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "srq_mem", 0); + rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "srq_mem", 0); if (rc) return rc; } @@ -4960,7 +5102,7 @@ int bnxt_alloc_ctx_mem(struct bnxt *bp) ctx_pg->entries = ctx->cq_max_l2_entries; if (ctx->cq_entry_size) { mem_size = ctx->cq_entry_size * ctx_pg->entries; - rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "cq_mem", 0); + rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "cq_mem", 0); if (rc) return rc; } @@ -4970,7 +5112,7 @@ int bnxt_alloc_ctx_mem(struct bnxt *bp) ctx->vnic_max_ring_table_entries; if (ctx->vnic_entry_size) { mem_size = ctx->vnic_entry_size * ctx_pg->entries; - rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "vnic_mem", 0); + rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "vnic_mem", 0); if (rc) return rc; } @@ -4979,7 +5121,7 @@ int bnxt_alloc_ctx_mem(struct bnxt *bp) ctx_pg->entries = ctx->stat_max_entries; if (ctx->stat_entry_size) { mem_size = ctx->stat_entry_size * ctx_pg->entries; - rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "stat_mem", 0); + rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "stat_mem", 0); if (rc) return rc; } @@ -5003,8 +5145,8 @@ int bnxt_alloc_ctx_mem(struct bnxt *bp) ctx_pg->entries = i ? entries : entries_sp; if (ctx->tqm_entry_size) { mem_size = ctx->tqm_entry_size * ctx_pg->entries; - rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, - "tqm_mem", i); + rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, + mem_size, "tqm_mem", i); if (rc) return rc; } @@ -5016,6 +5158,7 @@ int bnxt_alloc_ctx_mem(struct bnxt *bp) ena |= FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES; rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); +done: if (rc) PMD_DRV_LOG(ERR, "Failed to configure context mem: rc = %d\n", rc); diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 2d0a7a2731..a2182af036 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -24,10 +24,6 @@ #include "bnxt_vnic.h" #include "hsi_struct_def_dpdk.h" -#define HWRM_SPEC_CODE_1_8_3 0x10803 -#define HWRM_VERSION_1_9_1 0x10901 -#define HWRM_VERSION_1_9_2 0x10903 -#define HWRM_VERSION_1_10_2_13 0x10a020d struct bnxt_plcmodes_cfg { uint32_t flags; uint16_t jumbo_thresh; @@ -35,6 +31,43 @@ struct bnxt_plcmodes_cfg { uint16_t hds_threshold; }; +const char *bnxt_backing_store_types[] = { + "Queue pair", + "Shared receive queue", + "Completion queue", + "Virtual NIC", + "Statistic context", + "Slow-path TQM ring", + "Fast-path TQM ring", + "Unused", + "Unused", + "Unused", + "Unused", + "Unused", + "Unused", + "Unused", + "MR and MAV Context", + "TIM", + "Unused", + "Unused", + "Unused", + "Tx key context", + "Rx key context", + "Mid-path TQM ring", + "SQ Doorbell shadow region", + "RQ Doorbell shadow region", + "SRQ Doorbell shadow region", + "CQ Doorbell shadow region", + "QUIC Tx key context", + "QUIC Rx key context", + "Invalid type", + "Invalid type", + "Invalid type", + "Invalid type", + "Invalid type", + "Invalid type" +}; + static int page_getenum(size_t size) { if (size <= 1 << 4) @@ -894,6 +927,11 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_LINK_ADMIN_STATUS_SUPPORTED) bp->fw_cap |= BNXT_FW_CAP_LINK_ADMIN; + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_BS_V2_SUPPORTED) { + PMD_DRV_LOG(DEBUG, "Backing store v2 supported\n"); + if (BNXT_CHIP_P7(bp)) + bp->fw_cap |= BNXT_FW_CAP_BACKING_STORE_V2; + } if (!(flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VLAN_ACCELERATION_TX_DISABLED)) { bp->fw_cap |= BNXT_FW_CAP_VLAN_TX_INSERT; PMD_DRV_LOG(DEBUG, "VLAN acceleration for TX is enabled\n"); @@ -5461,7 +5499,194 @@ int bnxt_hwrm_set_ring_coal(struct bnxt *bp, return 0; } -#define BNXT_RTE_MEMZONE_FLAG (RTE_MEMZONE_1GB | RTE_MEMZONE_IOVA_CONTIG) +static void bnxt_init_ctx_initializer(struct bnxt_ctx_mem *ctxm, + uint8_t init_val, + uint8_t init_offset, + bool init_mask_set) +{ + ctxm->init_value = init_val; + ctxm->init_offset = BNXT_CTX_INIT_INVALID_OFFSET; + if (init_mask_set) + ctxm->init_offset = init_offset * 4; + else + ctxm->init_value = 0; +} + +static int bnxt_alloc_all_ctx_pg_info(struct bnxt *bp) +{ + struct bnxt_ctx_mem_info *ctx = bp->ctx; + char name[RTE_MEMZONE_NAMESIZE]; + uint16_t type; + + for (type = 0; type < ctx->types; type++) { + struct bnxt_ctx_mem *ctxm = &ctx->ctx_arr[type]; + int n = 1; + + if (!ctxm->max_entries || ctxm->pg_info) + continue; + + if (ctxm->instance_bmap) + n = hweight32(ctxm->instance_bmap); + + sprintf(name, "bnxt_ctx_pgmem_%d_%d", + bp->eth_dev->data->port_id, type); + ctxm->pg_info = rte_malloc(name, sizeof(*ctxm->pg_info) * n, + RTE_CACHE_LINE_SIZE); + if (!ctxm->pg_info) + return -ENOMEM; + } + return 0; +} + +static void bnxt_init_ctx_v2_driver_managed(struct bnxt *bp __rte_unused, + struct bnxt_ctx_mem *ctxm) +{ + switch (ctxm->type) { + case HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_TYPE_SQ_DB_SHADOW: + case HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_TYPE_RQ_DB_SHADOW: + case HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_TYPE_SRQ_DB_SHADOW: + case HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_TYPE_CQ_DB_SHADOW: + /* FALLTHROUGH */ + ctxm->entry_size = 0; + ctxm->min_entries = 1; + ctxm->max_entries = 1; + break; + } +} + +int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp) +{ + struct hwrm_func_backing_store_qcaps_v2_input req = {0}; + struct hwrm_func_backing_store_qcaps_v2_output *resp = + bp->hwrm_cmd_resp_addr; + struct bnxt_ctx_mem_info *ctx = bp->ctx; + uint16_t last_valid_type = BNXT_CTX_INV; + uint16_t last_valid_idx = 0; + uint16_t types, type; + int rc; + + for (types = 0, type = 0; types < bp->ctx->types && type != BNXT_CTX_INV; types++) { + struct bnxt_ctx_mem *ctxm = &bp->ctx->ctx_arr[types]; + uint8_t init_val, init_off, i; + uint32_t *p; + uint32_t flags; + + HWRM_PREP(&req, HWRM_FUNC_BACKING_STORE_QCAPS_V2, BNXT_USE_CHIMP_MB); + req.type = rte_cpu_to_le_16(type); + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + HWRM_CHECK_RESULT(); + + flags = rte_le_to_cpu_32(resp->flags); + type = rte_le_to_cpu_16(resp->next_valid_type); + if (!(flags & HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_FLAGS_TYPE_VALID)) + goto next; + + ctxm->type = rte_le_to_cpu_16(resp->type); + + ctxm->flags = flags; + if (flags & + HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_FLAGS_DRIVER_MANAGED_MEMORY) { + bnxt_init_ctx_v2_driver_managed(bp, ctxm); + goto next; + } + ctxm->entry_size = rte_le_to_cpu_16(resp->entry_size); + + if (ctxm->entry_size == 0) + goto next; + + ctxm->instance_bmap = rte_le_to_cpu_32(resp->instance_bit_map); + ctxm->entry_multiple = resp->entry_multiple; + ctxm->max_entries = rte_le_to_cpu_32(resp->max_num_entries); + ctxm->min_entries = rte_le_to_cpu_32(resp->min_num_entries); + init_val = resp->ctx_init_value; + init_off = resp->ctx_init_offset; + bnxt_init_ctx_initializer(ctxm, init_val, init_off, + BNXT_CTX_INIT_VALID(flags)); + ctxm->split_entry_cnt = RTE_MIN(resp->subtype_valid_cnt, + BNXT_MAX_SPLIT_ENTRY); + for (i = 0, p = &resp->split_entry_0; i < ctxm->split_entry_cnt; + i++, p++) + ctxm->split[i] = rte_le_to_cpu_32(*p); + + PMD_DRV_LOG(DEBUG, + "type:%s size:%d multiple:%d max:%d min:%d split:%d init_val:%d init_off:%d init:%d bmap:0x%x\n", + bnxt_backing_store_types[ctxm->type], ctxm->entry_size, + ctxm->entry_multiple, ctxm->max_entries, ctxm->min_entries, + ctxm->split_entry_cnt, init_val, init_off, + BNXT_CTX_INIT_VALID(flags), ctxm->instance_bmap); + last_valid_type = ctxm->type; + last_valid_idx = types; +next: + HWRM_UNLOCK(); + } + ctx->ctx_arr[last_valid_idx].last = true; + PMD_DRV_LOG(DEBUG, "Last valid type 0x%x\n", last_valid_type); + + rc = bnxt_alloc_all_ctx_pg_info(bp); + if (rc == 0) + rc = bnxt_alloc_ctx_pg_tbls(bp); + return rc; +} + +int bnxt_hwrm_func_backing_store_types_count(struct bnxt *bp) +{ + struct hwrm_func_backing_store_qcaps_v2_input req = {0}; + struct hwrm_func_backing_store_qcaps_v2_output *resp = + bp->hwrm_cmd_resp_addr; + uint16_t type = 0; + int types = 0; + int rc; + + /* Calculate number of valid context types */ + do { + uint32_t flags; + + HWRM_PREP(&req, HWRM_FUNC_BACKING_STORE_QCAPS_V2, BNXT_USE_CHIMP_MB); + req.type = rte_cpu_to_le_16(type); + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + HWRM_CHECK_RESULT(); + + flags = rte_le_to_cpu_32(resp->flags); + type = rte_le_to_cpu_16(resp->next_valid_type); + HWRM_UNLOCK(); + + if (flags & HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_FLAGS_TYPE_VALID) { + PMD_DRV_LOG(DEBUG, "Valid types 0x%x - %s\n", + req.type, bnxt_backing_store_types[req.type]); + types++; + } + } while (type != HWRM_FUNC_BACKING_STORE_QCAPS_V2_OUTPUT_TYPE_INVALID); + PMD_DRV_LOG(DEBUG, "Number of valid types %d\n", types); + + return types; +} + +int bnxt_hwrm_func_backing_store_ctx_alloc(struct bnxt *bp, uint16_t types) +{ + int alloc_len = sizeof(struct bnxt_ctx_mem_info); + + if (!BNXT_CHIP_P5_P7(bp) || + bp->hwrm_spec_code < HWRM_VERSION_1_9_2 || + BNXT_VF(bp) || + bp->ctx) + return 0; + + bp->ctx = rte_zmalloc("bnxt_ctx_mem", alloc_len, + RTE_CACHE_LINE_SIZE); + if (bp->ctx == NULL) + return -ENOMEM; + + alloc_len = sizeof(struct bnxt_ctx_mem) * types; + bp->ctx->ctx_arr = rte_zmalloc("bnxt_ctx_mem_arr", + alloc_len, + RTE_CACHE_LINE_SIZE); + if (bp->ctx->ctx_arr == NULL) + return -ENOMEM; + + bp->ctx->types = types; + return 0; +} + int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) { struct hwrm_func_backing_store_qcaps_input req = {0}; @@ -5469,27 +5694,19 @@ int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) bp->hwrm_cmd_resp_addr; struct bnxt_ctx_pg_info *ctx_pg; struct bnxt_ctx_mem_info *ctx; - int total_alloc_len; int rc, i, tqm_rings; if (!BNXT_CHIP_P5_P7(bp) || bp->hwrm_spec_code < HWRM_VERSION_1_9_2 || BNXT_VF(bp) || - bp->ctx) + bp->ctx->flags & BNXT_CTX_FLAG_INITED) return 0; + ctx = bp->ctx; HWRM_PREP(&req, HWRM_FUNC_BACKING_STORE_QCAPS, BNXT_USE_CHIMP_MB); rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); HWRM_CHECK_RESULT_SILENT(); - total_alloc_len = sizeof(*ctx); - ctx = rte_zmalloc("bnxt_ctx_mem", total_alloc_len, - RTE_CACHE_LINE_SIZE); - if (!ctx) { - rc = -ENOMEM; - goto ctx_err; - } - ctx->qp_max_entries = rte_le_to_cpu_32(resp->qp_max_entries); ctx->qp_min_qp1_entries = rte_le_to_cpu_16(resp->qp_min_qp1_entries); @@ -5500,8 +5717,13 @@ int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) rte_le_to_cpu_16(resp->srq_max_l2_entries); ctx->srq_max_entries = rte_le_to_cpu_32(resp->srq_max_entries); ctx->srq_entry_size = rte_le_to_cpu_16(resp->srq_entry_size); - ctx->cq_max_l2_entries = - rte_le_to_cpu_16(resp->cq_max_l2_entries); + if (BNXT_CHIP_P7(bp)) + ctx->cq_max_l2_entries = + RTE_MIN(BNXT_P7_CQ_MAX_L2_ENT, + rte_le_to_cpu_16(resp->cq_max_l2_entries)); + else + ctx->cq_max_l2_entries = + rte_le_to_cpu_16(resp->cq_max_l2_entries); ctx->cq_max_entries = rte_le_to_cpu_32(resp->cq_max_entries); ctx->cq_entry_size = rte_le_to_cpu_16(resp->cq_entry_size); ctx->vnic_max_vnic_entries = @@ -5555,12 +5777,73 @@ int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) for (i = 0; i < tqm_rings; i++, ctx_pg++) ctx->tqm_mem[i] = ctx_pg; - bp->ctx = ctx; ctx_err: HWRM_UNLOCK(); return rc; } +int bnxt_hwrm_func_backing_store_cfg_v2(struct bnxt *bp, + struct bnxt_ctx_mem *ctxm) +{ + struct hwrm_func_backing_store_cfg_v2_input req = {0}; + struct hwrm_func_backing_store_cfg_v2_output *resp = + bp->hwrm_cmd_resp_addr; + struct bnxt_ctx_pg_info *ctx_pg; + int i, j, k; + uint32_t *p; + int rc = 0; + int w = 1; + int b = 1; + + if (!BNXT_PF(bp)) { + PMD_DRV_LOG(INFO, + "Backing store config V2 can be issued on PF only\n"); + return 0; + } + + if (!(ctxm->flags & BNXT_CTX_MEM_TYPE_VALID) || !ctxm->pg_info) + return 0; + + if (ctxm->instance_bmap) + b = ctxm->instance_bmap; + + w = hweight32(b); + + for (i = 0, j = 0; i < w && rc == 0; i++) { + if (!(b & (1 << i))) + continue; + + HWRM_PREP(&req, HWRM_FUNC_BACKING_STORE_CFG_V2, BNXT_USE_CHIMP_MB); + req.type = rte_cpu_to_le_16(ctxm->type); + req.entry_size = rte_cpu_to_le_16(ctxm->entry_size); + req.subtype_valid_cnt = ctxm->split_entry_cnt; + for (k = 0, p = &req.split_entry_0; k < ctxm->split_entry_cnt; k++) + p[k] = rte_cpu_to_le_32(ctxm->split[k]); + + req.instance = rte_cpu_to_le_16(i); + ctx_pg = &ctxm->pg_info[j++]; + if (!ctx_pg->entries) + goto unlock; + + req.num_entries = rte_cpu_to_le_32(ctx_pg->entries); + bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, + &req.page_size_pbl_level, + &req.page_dir); + PMD_DRV_LOG(DEBUG, + "Backing store config V2 type:%s last %d, instance %d, hw %d\n", + bnxt_backing_store_types[req.type], ctxm->last, j, w); + if (ctxm->last && i == (w - 1)) + req.flags = + rte_cpu_to_le_32(BACKING_STORE_CFG_V2_IN_FLG_CFG_ALL_DONE); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + HWRM_CHECK_RESULT(); +unlock: + HWRM_UNLOCK(); + } + return rc; +} + int bnxt_hwrm_func_backing_store_cfg(struct bnxt *bp, uint32_t enables) { struct hwrm_func_backing_store_cfg_input req = {0}; diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index f9fa6cf73a..3d5194257b 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -60,6 +60,8 @@ struct hwrm_func_qstats_output; HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAM4_LINK_SPEED_MASK #define HWRM_PORT_PHY_CFG_IN_EN_AUTO_LINK_SPEED_MASK \ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK +#define BACKING_STORE_CFG_V2_IN_FLG_CFG_ALL_DONE \ + HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_FLAGS_BS_CFG_ALL_DONE #define HWRM_SPEC_CODE_1_8_4 0x10804 #define HWRM_SPEC_CODE_1_9_0 0x10900 @@ -355,4 +357,10 @@ void bnxt_free_hwrm_tx_ring(struct bnxt *bp, int queue_index); int bnxt_alloc_hwrm_tx_ring(struct bnxt *bp, int queue_index); int bnxt_hwrm_config_host_mtu(struct bnxt *bp); int bnxt_vnic_rss_clear_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic); +int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp); +int bnxt_hwrm_func_backing_store_cfg_v2(struct bnxt *bp, + struct bnxt_ctx_mem *ctxm); +int bnxt_hwrm_func_backing_store_types_count(struct bnxt *bp); +int bnxt_hwrm_func_backing_store_ctx_alloc(struct bnxt *bp, uint16_t types); +int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp); #endif diff --git a/drivers/net/bnxt/bnxt_util.c b/drivers/net/bnxt/bnxt_util.c index 47dd5fa6ff..aa184496c2 100644 --- a/drivers/net/bnxt/bnxt_util.c +++ b/drivers/net/bnxt/bnxt_util.c @@ -27,3 +27,13 @@ void bnxt_eth_hw_addr_random(uint8_t *mac_addr) mac_addr[1] = 0x0a; mac_addr[2] = 0xf7; } + +uint8_t hweight32(uint32_t word32) +{ + uint32_t res = word32 - ((word32 >> 1) & 0x55555555); + + res = (res & 0x33333333) + ((res >> 2) & 0x33333333); + res = (res + (res >> 4)) & 0x0F0F0F0F; + res = res + (res >> 8); + return (res + (res >> 16)) & 0x000000FF; +} diff --git a/drivers/net/bnxt/bnxt_util.h b/drivers/net/bnxt/bnxt_util.h index 7f5b4c160e..b265f5841b 100644 --- a/drivers/net/bnxt/bnxt_util.h +++ b/drivers/net/bnxt/bnxt_util.h @@ -17,4 +17,5 @@ int bnxt_check_zero_bytes(const uint8_t *bytes, int len); void bnxt_eth_hw_addr_random(uint8_t *mac_addr); +uint8_t hweight32(uint32_t word32); #endif /* _BNXT_UTIL_H_ */