From patchwork Tue Aug 16 05:52:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hernan Vargas X-Patchwork-Id: 115119 X-Patchwork-Delegate: gakhil@marvell.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 B7FFDA00C3; Mon, 15 Aug 2022 23:58:46 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 606F842B89; Mon, 15 Aug 2022 23:57:44 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 9A0A2415D7 for ; Mon, 15 Aug 2022 23:57:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660600655; x=1692136655; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pOwILnK3wgmZ81EVrKIBpc/zONvEknwxaVvGJRZIgGU=; b=Au/ESjTelTnBENGHPIWD2kbULij9rQXzfcJiF3rAUIoP5CVbgrl7yz73 IYc5BHpKg0UoNQnXQ/ZfdxifzQ0urcj/WDriOfDGK9bcxsvGM8EFe+0I4 XVrR+gakqOkITTCgqBe0FhmXqzYIwf1GXtrzseBQH5/1nmCLBa6DzfTKu /U6NQl0UsuQPrDGs1mpbhCpKf5Fapor5EeWuKRnh6qq860BnXIjPF9Yt7 zo1usenm4sn/q0Zh/T2R9crwwQM0MCEsBhAu2fxWqsrTOVhxYEZR9s0H1 KcyJfzekLZ6l5XFwgEFlboXWOG3i3voxCL90MqM4HWCmmFnJOGQCtSL6I Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10440"; a="292862715" X-IronPort-AV: E=Sophos;i="5.93,239,1654585200"; d="scan'208";a="292862715" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Aug 2022 14:57:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,239,1654585200"; d="scan'208";a="666826049" Received: from unknown (HELO csl-npg-qt0.la.intel.com) ([10.233.181.103]) by fmsmga008.fm.intel.com with ESMTP; 15 Aug 2022 14:57:34 -0700 From: Hernan Vargas To: dev@dpdk.org, gakhil@marvell.com, trix@redhat.com Cc: nicolas.chautru@intel.com, qi.z.zhang@intel.com, Hernan Vargas Subject: [PATCH v1 11/33] baseband/acc100: update validate LDPC enc/dec Date: Mon, 15 Aug 2022 22:52:36 -0700 Message-Id: <20220816055258.107564-12-hernan.vargas@intel.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220816055258.107564-1-hernan.vargas@intel.com> References: <20220816055258.107564-1-hernan.vargas@intel.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 Update validate functions to check for valid LDPC parameters, handling HARQ and transport blocks. Signed-off-by: Hernan Vargas --- drivers/baseband/acc100/rte_acc100_pmd.c | 297 +++++++++++++++++++++-- 1 file changed, 283 insertions(+), 14 deletions(-) diff --git a/drivers/baseband/acc100/rte_acc100_pmd.c b/drivers/baseband/acc100/rte_acc100_pmd.c index 6c639698db..843431748d 100644 --- a/drivers/baseband/acc100/rte_acc100_pmd.c +++ b/drivers/baseband/acc100/rte_acc100_pmd.c @@ -2407,10 +2407,6 @@ validate_ldpc_enc_op(struct rte_bbdev_enc_op *op, struct acc100_queue *q) if (!validate_op_required(q)) return 0; - if (op->mempool == NULL) { - rte_bbdev_log(ERR, "Invalid mempool pointer"); - return -1; - } if (ldpc_enc->input.data == NULL) { rte_bbdev_log(ERR, "Invalid input pointer"); return -1; @@ -2419,11 +2415,9 @@ validate_ldpc_enc_op(struct rte_bbdev_enc_op *op, struct acc100_queue *q) rte_bbdev_log(ERR, "Invalid output pointer"); return -1; } - if (ldpc_enc->input.length > - RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) { - rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d", - ldpc_enc->input.length, - RTE_BBDEV_LDPC_MAX_CB_SIZE); + if (ldpc_enc->input.length == 0) { + rte_bbdev_log(ERR, "CB size (%u) is null", + ldpc_enc->input.length); return -1; } if ((ldpc_enc->basegraph > 2) || (ldpc_enc->basegraph == 0)) { @@ -2444,13 +2438,107 @@ validate_ldpc_enc_op(struct rte_bbdev_enc_op *op, struct acc100_queue *q) ldpc_enc->code_block_mode); return -1; } + if (ldpc_enc->z_c > 384) { + rte_bbdev_log(ERR, + "Zc (%u) is out of range", + ldpc_enc->z_c); + return -1; + } int K = (ldpc_enc->basegraph == 1 ? 22 : 10) * ldpc_enc->z_c; - if (ldpc_enc->n_filler >= K) { + int N = (ldpc_enc->basegraph == 1 ? ACC100_N_ZC_1 : ACC100_N_ZC_2) + * ldpc_enc->z_c; + int q_m = ldpc_enc->q_m; + int crc24 = 0; + + if (check_bit(op->ldpc_enc.op_flags, + RTE_BBDEV_LDPC_CRC_24A_ATTACH) || + check_bit(op->ldpc_enc.op_flags, + RTE_BBDEV_LDPC_CRC_24B_ATTACH)) + crc24 = 24; + if ((K - ldpc_enc->n_filler) % 8 > 0) { rte_bbdev_log(ERR, - "K and F are not compatible %u %u", + "K - F not byte aligned %u", + K - ldpc_enc->n_filler); + return -1; + } + if (ldpc_enc->n_filler > (K - 2 * ldpc_enc->z_c)) { + rte_bbdev_log(ERR, + "K - F invalid %u %u", K, ldpc_enc->n_filler); return -1; } + if ((ldpc_enc->n_cb > N) || (ldpc_enc->n_cb <= K)) { + rte_bbdev_log(ERR, + "Ncb (%u) is out of range K %d N %d", + ldpc_enc->n_cb, K, N); + return -1; + } + if (!check_bit(op->ldpc_enc.op_flags, + RTE_BBDEV_LDPC_INTERLEAVER_BYPASS) && + ((q_m == 0) || ((q_m > 2) && ((q_m % 2) == 1)) + || (q_m > 8))) { + rte_bbdev_log(ERR, + "Qm (%u) is out of range", + ldpc_enc->q_m); + return -1; + } + if (ldpc_enc->code_block_mode == RTE_BBDEV_CODE_BLOCK) { + if (ldpc_enc->cb_params.e == 0) { + rte_bbdev_log(ERR, + "E is null"); + return -1; + } + if (q_m > 0) { + if (ldpc_enc->cb_params.e % q_m > 0) { + rte_bbdev_log(ERR, + "E not multiple of qm %d", q_m); + return -1; + } + } + if ((ldpc_enc->z_c <= 11) && (ldpc_enc->cb_params.e > 3456)) { + rte_bbdev_log(ERR, + "E too large for small block"); + return -1; + } + if (ldpc_enc->input.length > + RTE_BBDEV_LDPC_MAX_CB_SIZE >> 3) { + rte_bbdev_log(ERR, "CB size (%u) is too big, max: %d", + ldpc_enc->input.length, + RTE_BBDEV_LDPC_MAX_CB_SIZE); + return -1; + } + if (K < (int) (ldpc_enc->input.length * 8 + + ldpc_enc->n_filler) + crc24) { + rte_bbdev_log(ERR, + "K and F not matching input size %u %u %u", + K, ldpc_enc->n_filler, + ldpc_enc->input.length); + return -1; + } + } else { + if ((ldpc_enc->tb_params.c == 0) || + (ldpc_enc->tb_params.ea == 0) || + (ldpc_enc->tb_params.eb == 0)) { + rte_bbdev_log(ERR, + "TB parameter is null"); + return -1; + } + if (q_m > 0) { + if ((ldpc_enc->tb_params.ea % q_m > 0) || + (ldpc_enc->tb_params.eb % q_m > 0)) { + rte_bbdev_log(ERR, + "E not multiple of qm %d", + q_m); + return -1; + } + } + if ((ldpc_enc->z_c <= 11) && (RTE_MAX(ldpc_enc->tb_params.ea, + ldpc_enc->tb_params.eb) > 3456)) { + rte_bbdev_log(ERR, + "E too large for small block"); + return -1; + } + } return 0; } @@ -2463,8 +2551,16 @@ validate_ldpc_dec_op(struct rte_bbdev_dec_op *op, struct acc100_queue *q) if (!validate_op_required(q)) return 0; - if (op->mempool == NULL) { - rte_bbdev_log(ERR, "Invalid mempool pointer"); + if (ldpc_dec->input.data == NULL) { + rte_bbdev_log(ERR, "Invalid input pointer"); + return -1; + } + if (ldpc_dec->hard_output.data == NULL) { + rte_bbdev_log(ERR, "Invalid output pointer"); + return -1; + } + if (ldpc_dec->input.length == 0) { + rte_bbdev_log(ERR, "input is null"); return -1; } if ((ldpc_dec->basegraph > 2) || (ldpc_dec->basegraph == 0)) { @@ -2491,13 +2587,186 @@ validate_ldpc_dec_op(struct rte_bbdev_dec_op *op, struct acc100_queue *q) ldpc_dec->code_block_mode); return -1; } + /* Check Zc is valid value */ + if ((ldpc_dec->z_c > 384) || (ldpc_dec->z_c < 2)) { + rte_bbdev_log(ERR, + "Zc (%u) is out of range", + ldpc_dec->z_c); + return -1; + } + if (ldpc_dec->z_c > 256) { + if ((ldpc_dec->z_c % 32) != 0) { + rte_bbdev_log(ERR, "Invalid Zc %d", ldpc_dec->z_c); + return -1; + } + } else if (ldpc_dec->z_c > 128) { + if ((ldpc_dec->z_c % 16) != 0) { + rte_bbdev_log(ERR, "Invalid Zc %d", ldpc_dec->z_c); + return -1; + } + } else if (ldpc_dec->z_c > 64) { + if ((ldpc_dec->z_c % 8) != 0) { + rte_bbdev_log(ERR, "Invalid Zc %d", ldpc_dec->z_c); + return -1; + } + } else if (ldpc_dec->z_c > 32) { + if ((ldpc_dec->z_c % 4) != 0) { + rte_bbdev_log(ERR, "Invalid Zc %d", ldpc_dec->z_c); + return -1; + } + } else if (ldpc_dec->z_c > 16) { + if ((ldpc_dec->z_c % 2) != 0) { + rte_bbdev_log(ERR, "Invalid Zc %d", ldpc_dec->z_c); + return -1; + } + } int K = (ldpc_dec->basegraph == 1 ? 22 : 10) * ldpc_dec->z_c; - if (ldpc_dec->n_filler >= K) { + int N = (ldpc_dec->basegraph == 1 ? ACC100_N_ZC_1 : ACC100_N_ZC_2) + * ldpc_dec->z_c; + int q_m = ldpc_dec->q_m; + if (ldpc_dec->n_filler >= K - 2 * ldpc_dec->z_c) { rte_bbdev_log(ERR, "K and F are not compatible %u %u", K, ldpc_dec->n_filler); return -1; } + if ((ldpc_dec->n_cb > N) || (ldpc_dec->n_cb <= K)) { + rte_bbdev_log(ERR, + "Ncb (%u) is out of range K %d N %d", + ldpc_dec->n_cb, K, N); + return -1; + } + + if (((q_m == 0) || ((q_m > 2) && ((q_m % 2) == 1)) + || (q_m > 8))) { + rte_bbdev_log(ERR, + "Qm (%u) is out of range", + ldpc_dec->q_m); + return -1; + } + if (ldpc_dec->code_block_mode == RTE_BBDEV_CODE_BLOCK) { + if (ldpc_dec->cb_params.e == 0) { + rte_bbdev_log(ERR, + "E is null"); + return -1; + } + if (ldpc_dec->cb_params.e % q_m > 0) { + rte_bbdev_log(ERR, + "E not multiple of qm %d", q_m); + return -1; + } + if (ldpc_dec->cb_params.e > 512 * ldpc_dec->z_c) { + rte_bbdev_log(ERR, + "E too high"); + return -1; + } + } else { + if ((ldpc_dec->tb_params.c == 0) || + (ldpc_dec->tb_params.ea == 0) || + (ldpc_dec->tb_params.eb == 0)) { + rte_bbdev_log(ERR, + "TB parameter is null"); + return -1; + } + if ((ldpc_dec->tb_params.ea % q_m > 0) || + (ldpc_dec->tb_params.eb % q_m > 0)) { + rte_bbdev_log(ERR, + "E not multiple of qm %d", q_m); + return -1; + } + if ((ldpc_dec->tb_params.ea > 512 * ldpc_dec->z_c) || + (ldpc_dec->tb_params.eb > 512 * ldpc_dec->z_c)) { + rte_bbdev_log(ERR, + "E too high"); + return -1; + } + } + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_DECODE_BYPASS)) { + rte_bbdev_log(ERR, "Avoid LDPC Decode bypass"); + return -1; + } + + /* Avoid HARQ compression for small block size */ + if ((check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION)) + && (K < 2048)) { + op->ldpc_dec.op_flags ^= RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION; + } + uint32_t min_harq_input = check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION) ? 256 : 64; + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE) && + ldpc_dec->harq_combined_input.length < + min_harq_input) { + rte_bbdev_log(ERR, "HARQ input size is too small %d < %d", + ldpc_dec->harq_combined_input.length, + min_harq_input); + return -1; + } + + /* Enforce in-range HARQ input size */ + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) { + uint32_t max_harq_input = RTE_ALIGN_CEIL(ldpc_dec->n_cb - + ldpc_dec->n_filler, 64); + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION)) + max_harq_input = max_harq_input * 3 / 4; + if (ldpc_dec->harq_combined_input.length > max_harq_input) { + rte_bbdev_log(ERR, + "HARQ input size out of range %d > %d, Ncb %d F %d K %d N %d", + ldpc_dec->harq_combined_input.length, + max_harq_input, ldpc_dec->n_cb, + ldpc_dec->n_filler, K, N); + /* Fallback to flush HARQ combine */ + ldpc_dec->harq_combined_input.length = 0; + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) { + op->ldpc_dec.op_flags ^= + RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE; + } + } + } + +#ifdef ACC100_EXT_MEM + /* Enforce in-range HARQ offset */ + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) { + if ((op->ldpc_dec.harq_combined_input.offset >> 10) + >= q->d->ddr_size) { + rte_bbdev_log(ERR, + "HARQin offset out of range %d > %d", + op->ldpc_dec.harq_combined_input.offset, + q->d->ddr_size); + return -1; + } + if ((op->ldpc_dec.harq_combined_input.offset & 0x3FF) > 0) { + rte_bbdev_log(ERR, + "HARQin offset not aligned on 1kB %d", + op->ldpc_dec.harq_combined_input.offset); + return -1; + } + } + if (check_bit(op->ldpc_dec.op_flags, + RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE)) { + if ((op->ldpc_dec.harq_combined_output.offset >> 10) + >= q->d->ddr_size) { + rte_bbdev_log(ERR, + "HARQout offset out of range %d > %d", + op->ldpc_dec.harq_combined_output.offset, + q->d->ddr_size); + return -1; + } + if ((op->ldpc_dec.harq_combined_output.offset & 0x3FF) > 0) { + rte_bbdev_log(ERR, + "HARQout offset not aligned on 1kB %d", + op->ldpc_dec.harq_combined_output.offset); + return -1; + } + } +#endif + return 0; } #endif