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 078AD436BE; Sun, 10 Dec 2023 02:32:57 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CDBB540E8A; Sun, 10 Dec 2023 02:31:56 +0100 (CET) Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) by mails.dpdk.org (Postfix) with ESMTP id F2A0C40DF5 for ; Sun, 10 Dec 2023 02:31:53 +0100 (CET) Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-28670a7ba84so2610228a91.2 for ; Sat, 09 Dec 2023 17:31:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1702171913; x=1702776713; 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=7zBbSA7qtGrUJSq3mkiNazYkyidz8PpvMHR3Wkr6MzU=; b=OPGmEolzTSixBhPbd9fc58ffIs0CcTgZIAhhfUa5opUuhuLHwyhPfhAGgsOfzCo5Jf xiszOfAfRlEFmDVY28Q8JEbavFSv9NsLpB4psrIVEbxjORyZaRF+CPk7fInq57tccD+G hbM6UwmCCkzU6AkBLJA+hfU0rpbEEVmaCtyNE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702171913; x=1702776713; 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=7zBbSA7qtGrUJSq3mkiNazYkyidz8PpvMHR3Wkr6MzU=; b=soC6Cr2IWLisSTOfHDv4dtGksNC4MVUN/q9pjqQyOffEsirTx6hIgGi9TiJBCqs6Xq Lf+tlpXUcvbjQQY2WLTbud1pi6ObT9uLKpYD9Uz+zSPrkxD0hHKcpyiUYTDkUY1U+QVE VNsr8MdZgiF4vYZTqmLIPFBSGIlC3YIH/BpzSm286i/epmbfN7RpO2SSGrrYqDjZs8sc AiCE9hUKhJDa1QJ1ktwQbbo2/MLRbs3abP8vRFZ7vMfuAbvS4Hiw0QbD0Z5Yjq8kE+IR JO9IqvoDNGZUsv5D8KIpyJMKcGjnek1+5Wl+Y1ynGntmOCF7TSJ3P6a6Otg1prrLz8W3 RpKQ== X-Gm-Message-State: AOJu0YwKlt7rTGg7udE9zbKpoaMTPi/BCysmDIs6XT+YaY33g26m3Nb4 LFlfEXJg4oUnZ2D5z/Q1YVksmMeQyLxr8hJR+2F0bdE0QKPvIf/EuZEAsaGOiBbOG24e1sDd2X3 CQ51DeYctAPspYVtQxFZVaYFpiRTbR8yCh7u7zak3N05Q6L/aMwqo2uA3I8w1613VDAE3 X-Google-Smtp-Source: AGHT+IFckeKV0P+7xTATeng0XkpBGiDDIwz+hwTWjy1iv7lFnAKuqtm3qxp0y7ah5eMiLoriHeg9GQ== X-Received: by 2002:a05:6a20:9706:b0:18d:b43:78f9 with SMTP id hr6-20020a056a20970600b0018d0b4378f9mr876677pzc.39.1702171912046; Sat, 09 Dec 2023 17:31:52 -0800 (PST) Received: from localhost.localdomain ([2605:a601:a780:1400:6d20:fff:e413:282a]) by smtp.gmail.com with ESMTPSA id q3-20020a170902f78300b001d083fed5f3sm4006050pln.60.2023.12.09.17.31.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 Dec 2023 17:31:51 -0800 (PST) From: Ajit Khaparde To: dev@dpdk.org Subject: [PATCH v2 09/14] net/bnxt: add support for backing store v2 Date: Sat, 9 Dec 2023 17:24:50 -0800 Message-Id: <20231210012455.20229-10-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.39.2 (Apple Git-143) In-Reply-To: <20231210012455.20229-1-ajit.khaparde@broadcom.com> References: <20231210012455.20229-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="0000000000003911cc060c1dc8bc" 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 --0000000000003911cc060c1dc8bc Content-Transfer-Encoding: 8bit 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 | 321 +++++++++++++++++++++++++++++++-- drivers/net/bnxt/bnxt_hwrm.h | 8 + drivers/net/bnxt/bnxt_util.c | 10 + drivers/net/bnxt/bnxt_util.h | 1 + 6 files changed, 547 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 c585373ba3..5810e0a2a9 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..dda3d3a6ac 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,196 @@ 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(); + if (rc != 0) + return rc; + + 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 +5696,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 +5719,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 +5779,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_ */ -- 2.39.2 (Apple Git-143) --0000000000003911cc060c1dc8bc Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 pZEyqKnwS1lKCzjX7mV5W955rFsFxChdAKfw0HilwtqdY24mhy62+GeaEkD0gYIj1tCmw9gnQToc K+0s7xEunfR9pBrzmOwS3OQbcP0nJ8SmQ8R+reroH6LYuFpaqK1rgQIDAQABo4IB2zCCAdcwDgYD VR0PAQH/BAQDAgWgMIGjBggrBgEFBQcBAQSBljCBkzBOBggrBgEFBQcwAoZCaHR0cDovL3NlY3Vy ZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQvZ3NnY2NyM3BlcnNvbmFsc2lnbjJjYTIwMjAuY3J0MEEG CCsGAQUFBzABhjVodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9nc2djY3IzcGVyc29uYWxzaWdu MmNhMjAyMDBNBgNVHSAERjBEMEIGCisGAQQBoDIBKAowNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93 d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCQYDVR0TBAIwADBJBgNVHR8EQjBAMD6gPKA6 hjhodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjNwZXJzb25hbHNpZ24yY2EyMDIwLmNy bDAlBgNVHREEHjAcgRphaml0LmtoYXBhcmRlQGJyb2FkY29tLmNvbTATBgNVHSUEDDAKBggrBgEF BQcDBDAfBgNVHSMEGDAWgBSWM9HmWBdbNHWKgVZk1b5I3qGPzzAdBgNVHQ4EFgQUbrcTuh0mr2qP xYdtyDgFeRIiE/gwDQYJKoZIhvcNAQELBQADggEBALrc1TljKrDhXicOaZlzIQyqOEkKAZ324i8X OwzA0n2EcPGmMZvgARurvanSLD3mLeeuyq1feCcjfGM1CJFh4+EY7EkbFbpVPOIdstSBhbnAJnOl aC/q0wTndKoC/xXBhXOZB8YL/Zq4ZclQLMUO6xi/fFRyHviI5/IrosdrpniXFJ9ukJoOXtvdrEF+ KlMYg/Deg9xo3wddCqQIsztHSkR4XaANdn+dbLRQpctZ13BY1lim4uz5bYn3M0IxyZWkQ1JuPHCK aRJv0SfR88PoI4RB7NCEHqFwARTj1KvFPQi8pK/YISFydZYbZrxQdyWDidqm4wSuJfpE6i0cWvCd u50xggJtMIICaQIBATBrMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNh MTEwLwYDVQQDEyhHbG9iYWxTaWduIEdDQyBSMyBQZXJzb25hbFNpZ24gMiBDQSAyMDIwAgwM2Vrj 4nZK0WWosNswDQYJYIZIAWUDBAIBBQCggdQwLwYJKoZIhvcNAQkEMSIEIHYGp+C+CH/7kIK9MnO3 UI+FZXJLqLJqZ3yDdmqieyVCMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkF MQ8XDTIzMTIxMDAxMzE1M1owaQYJKoZIhvcNAQkPMVwwWjALBglghkgBZQMEASowCwYJYIZIAWUD BAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzALBgkqhkiG9w0BAQowCwYJKoZIhvcNAQEHMAsG CWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQCgyyxzDdefVFCDghT+opmUpsTemMSqcxb1Qhba V3EQ2cKLegKes4U7CBt4pepOvHfSLpg+LsP/HWIksvlW33WhfOoao9l2dp6Q0YrhpbWsUs8xVM/Z YYMpPL5TzmLpcLkRg4YuIweiEAgNgPi5UTukugqVTRd/6fSOIvzcIrOxSUm4haTeMEbFTu2MwoTw zNSj1XFP9+T2jbjYY0W4IVZZU+lrN4g1tQwWg/gAa6c+oYW1QN9zRAusSuMbFjBJwPTl3jLgCNBP 5ZnztFtcwReWYUJ5fEHm8PEw8x9SFwajRH3TfI1o5Sl7fneBpU1AzP/pH0n8H5tsC3oZDYspHy+r --0000000000003911cc060c1dc8bc--