[v1,4/5] baseband/fpga_5gnr_fec: enable validate LDPC enc/dec

Message ID 20220509201734.946900-5-hernan.vargas@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series baseband/fpga_5gnr: maintenance changes to fpga_5gnr PMD |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Vargas, Hernan May 9, 2022, 8:17 p.m. UTC
  Enable validate_ldpc_enc_op and validate_ldpc_dec_op

Signed-off-by: Hernan <hernan.vargas@intel.com>
---
 .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 490 ++++++++++++++----
 1 file changed, 384 insertions(+), 106 deletions(-)
  

Comments

Chautru, Nicolas May 9, 2022, 9:04 p.m. UTC | #1
> -----Original Message-----
> From: Vargas, Hernan <hernan.vargas@intel.com>
> Sent: Monday, May 9, 2022 1:18 PM
> To: dev@dpdk.org; gakhil@marvell.com; trix@redhat.com
> Cc: Chautru, Nicolas <nicolas.chautru@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Vargas, Hernan <hernan.vargas@intel.com>
> Subject: [PATCH v1 4/5] baseband/fpga_5gnr_fec: enable validate LDPC
> enc/dec
> 
> Enable validate_ldpc_enc_op and validate_ldpc_dec_op
> 
> Signed-off-by: Hernan <hernan.vargas@intel.com>
> ---
>  .../fpga_5gnr_fec/rte_fpga_5gnr_fec.c         | 490 ++++++++++++++----
>  1 file changed, 384 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> index 2d4b58067d..8fdb44c94a 100644
> --- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> +++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
> @@ -1032,23 +1032,11 @@ fpga_dma_desc_ld_fill(struct rte_bbdev_dec_op
> *op,
>  	return 0;
>  }
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
>  /* Validates LDPC encoder parameters */ -static int -validate_enc_op(struct
> rte_bbdev_enc_op *op __rte_unused)
> +static inline int
> +validate_ldpc_enc_op(struct rte_bbdev_enc_op *op)
>  {
>  	struct rte_bbdev_op_ldpc_enc *ldpc_enc = &op->ldpc_enc;
> -	struct rte_bbdev_op_enc_ldpc_cb_params *cb = NULL;
> -	struct rte_bbdev_op_enc_ldpc_tb_params *tb = NULL;
> -
> -
> -	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 (op->mempool == NULL) {
>  		rte_bbdev_log(ERR, "Invalid mempool pointer"); @@ -
> 1062,140 +1050,437 @@ validate_enc_op(struct rte_bbdev_enc_op *op
> __rte_unused)
>  		rte_bbdev_log(ERR, "Invalid output pointer");
>  		return -1;
>  	}
> +	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)) {
>  		rte_bbdev_log(ERR,
> -				"basegraph (%u) is out of range 1 <= value <=
> 2",
> +				"BG (%u) is out of range 1 <= value <= 2",
>  				ldpc_enc->basegraph);
>  		return -1;
>  	}
> +	if (ldpc_enc->rv_index > 3) {
> +		rte_bbdev_log(ERR,
> +				"rv_index (%u) is out of range 0 <= value <=
> 3",
> +				ldpc_enc->rv_index);
> +		return -1;
> +	}
>  	if (ldpc_enc->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
>  		rte_bbdev_log(ERR,
> -				"code_block_mode (%u) is out of range 0:Tb
> 1:CB",
> +				"code_block_mode (%u) is out of range 0 <=
> value <= 1",
>  				ldpc_enc->code_block_mode);
>  		return -1;
>  	}
> 
> -	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> -		tb = &ldpc_enc->tb_params;
> -		if (tb->c == 0) {
> -			rte_bbdev_log(ERR,
> -					"c (%u) is out of range 1 <= value <=
> %u",
> -					tb->c,
> RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
> +	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;
> +	}
> +	int z_c = ldpc_enc->z_c;
> +	/* Check Zc is valid value */
> +	if ((z_c > 384) || (z_c < 4)) {
> +		rte_bbdev_log(ERR, "Zc (%u) is out of range", z_c);
> +		return -1;
> +	}
> +	if (z_c > 256) {
> +		if ((z_c % 32) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if (tb->cab > tb->c) {
> -			rte_bbdev_log(ERR,
> -					"cab (%u) is greater than c (%u)",
> -					tb->cab, tb->c);
> +	} else if (z_c > 128) {
> +		if ((z_c % 16) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if ((tb->ea < RTE_BBDEV_LDPC_MIN_CB_SIZE)
> -				&& tb->r < tb->cab) {
> -			rte_bbdev_log(ERR,
> -					"ea (%u) is less than %u or it is not
> even",
> -					tb->ea,
> RTE_BBDEV_LDPC_MIN_CB_SIZE);
> +	} else if (z_c > 64) {
> +		if ((z_c % 8) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if ((tb->eb < RTE_BBDEV_LDPC_MIN_CB_SIZE)
> -				&& tb->c > tb->cab) {
> -			rte_bbdev_log(ERR,
> -					"eb (%u) is less than %u",
> -					tb->eb,
> RTE_BBDEV_LDPC_MIN_CB_SIZE);
> +	} else if (z_c > 32) {
> +		if ((z_c % 4) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if (tb->r > (tb->c - 1)) {
> -			rte_bbdev_log(ERR,
> -					"r (%u) is greater than c - 1 (%u)",
> -					tb->r, tb->c - 1);
> +	} else if (z_c > 16) {
> +		if ((z_c % 2) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -	} else {
> -		cb = &ldpc_enc->cb_params;
> -		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
> -			rte_bbdev_log(ERR,
> -					"e (%u) is less than %u or it is not
> even",
> -					cb->e,
> RTE_BBDEV_LDPC_MIN_CB_SIZE);
> +	}
> +
> +	int n_filler = ldpc_enc->n_filler;
> +	int K = (ldpc_enc->basegraph == 1 ? 22 : 10) * ldpc_enc->z_c;
> +	int Kp = K - n_filler;
> +	int q_m = ldpc_enc->q_m;
> +	int n_cb = ldpc_enc->n_cb;
> +	int N = (ldpc_enc->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
> +	int k0 = k0 = get_k0(n_cb, z_c, ldpc_enc->basegraph,
> +			ldpc_enc->rv_index);

There is a typo here. And the same one below. 

> +	int crc24 = 0;
> +	int32_t L, Lcb, cw, cw_rm;
> +	int32_t e = ldpc_enc->cb_params.e;
> +	if (check_bit(op->ldpc_enc.op_flags,
> +			RTE_BBDEV_LDPC_CRC_24B_ATTACH))
> +		crc24 = 24;
> +
> +	if (K < (int) (ldpc_enc->input.length * 8 + n_filler) + crc24) {
> +		rte_bbdev_log(ERR, "K and F not matching input size %u %u
> %u",
> +				K, n_filler, ldpc_enc->input.length);
> +		return -1;
> +	}
> +	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> +		rte_bbdev_log(ERR, "TB mode not supported");
> +		return -1;
> +
> +	}
> +
> +	/* K' range check */
> +	if (Kp % 8 > 0) {
> +		rte_bbdev_log(ERR, "K' not byte aligned %u", Kp);
> +		return -1;
> +	}
> +	if ((crc24 > 0) && (Kp < 292)) {
> +		rte_bbdev_log(ERR, "Invalid CRC24 for small block %u", Kp);
> +		return -1;
> +	}
> +	if (Kp < 24) {
> +		rte_bbdev_log(ERR, "K' too small %u", Kp);
> +		return -1;
> +	}
> +	if (n_filler >= (K - 2 * z_c)) {
> +		rte_bbdev_log(ERR, "K - F invalid %u %u", K, n_filler);
> +		return -1;
> +	}
> +	/* Ncb range check */
> +	if ((n_cb > N) || (n_cb < 32) || (n_cb <= (Kp - crc24))) {
> +		rte_bbdev_log(ERR, "Ncb (%u) is out of range K  %d N %d",
> n_cb, K, N);
> +		return -1;
> +	}
> +	/* Qm range check */
> +	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", q_m);
> +		return -1;
> +	}
> +	/* K0 range check */
> +	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
> +			&& (k0 < (K - 2 * z_c)))) {
> +		rte_bbdev_log(ERR, "K0 (%u) is out of range", k0);
> +		return -1;
> +	}
> +	/* E range check */
> +	if (e <= RTE_MAX(32, z_c)) {
> +		rte_bbdev_log(ERR, "E is too small %"PRIu32"", e);
> +		return -1;
> +	}
> +	if ((e > 0xFFFF)) {
> +		rte_bbdev_log(ERR, "E is too large for N3000 %"PRIu32" >
> 64k", e);
> +		return -1;
> +	}
> +	if (q_m > 0) {
> +		if (e % q_m > 0) {
> +			rte_bbdev_log(ERR, "E %"PRIu32" not multiple of qm
> %d", e, q_m);
>  			return -1;
>  		}
>  	}
> +	/* Code word in RM range check */
> +	if (k0 > (Kp - 2 * z_c))
> +		L = k0 + e;
> +	else
> +		L = k0 + e + n_filler;
> +	Lcb = RTE_MIN(L, n_cb);
> +	if (ldpc_enc->basegraph == 1) {
> +		if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 27 * z_c)
> +			cw = 27 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else if (Lcb <= 33 * z_c)
> +			cw = 33 * z_c;
> +		else if (Lcb <= 44 * z_c)
> +			cw = 44 * z_c;
> +		else if (Lcb <= 55 * z_c)
> +			cw = 55 * z_c;
> +		else
> +			cw = 66 * z_c;
> +	} else {
> +		if (Lcb <= 15 * z_c)
> +			cw = 15 * z_c;
> +		else if (Lcb <= 20 * z_c)
> +			cw = 20 * z_c;
> +		else if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else
> +			cw = 50 * z_c;
> +	}
> +	if (n_cb < Kp - 2 * z_c)
> +		cw_rm = n_cb;
> +	else if ((Kp - 2 * z_c <= n_cb) && (n_cb < K - 2 * z_c))
> +		cw_rm = Kp - 2 * z_c;
> +	else if ((K - 2 * z_c <= n_cb) && (n_cb < cw))
> +		cw_rm = n_cb - n_filler;
> +	else
> +		cw_rm = cw - n_filler;
> +	if (cw_rm <= 32) {
> +		rte_bbdev_log(ERR,
> +				"Invalid Ratematching");
> +		return -1;
> +	}
>  	return 0;
>  }
> -#endif
> -
> -static inline char *
> -mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len) -{
> -	if (unlikely(len > rte_pktmbuf_tailroom(m)))
> -		return NULL;
> -
> -	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
> -	m->data_len = (uint16_t)(m->data_len + len);
> -	m_head->pkt_len  = (m_head->pkt_len + len);
> -	return tail;
> -}
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
>  /* Validates LDPC decoder parameters */ -static int -validate_dec_op(struct
> rte_bbdev_dec_op *op __rte_unused)
> +static inline int
> +validate_ldpc_dec_op(struct rte_bbdev_dec_op *op)
>  {
>  	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &op->ldpc_dec;
> -	struct rte_bbdev_op_dec_ldpc_cb_params *cb = NULL;
> -	struct rte_bbdev_op_dec_ldpc_tb_params *tb = NULL;
> -
> -	if (op->mempool == NULL) {
> -		rte_bbdev_log(ERR, "Invalid mempool pointer");
> +	if (check_bit(ldpc_dec->op_flags,
> +
> 	RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK))
> +		return 0;
> +	if (ldpc_dec->input.data == NULL) {
> +		rte_bbdev_log(ERR, "Invalid input pointer");
>  		return -1;
>  	}
> -	if (ldpc_dec->rv_index > 3) {
> +	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)) {
>  		rte_bbdev_log(ERR,
> -				"rv_index (%u) is out of range 0 <= value <=
> 3",
> -				ldpc_dec->rv_index);
> +				"BG (%u) is out of range 1 <= value <= 2",
> +				ldpc_dec->basegraph);
>  		return -1;
>  	}
> -
>  	if (ldpc_dec->iter_max == 0) {
>  		rte_bbdev_log(ERR,
>  				"iter_max (%u) is equal to 0",
>  				ldpc_dec->iter_max);
>  		return -1;
>  	}
> -
> +	if (ldpc_dec->rv_index > 3) {
> +		rte_bbdev_log(ERR,
> +				"rv_index (%u) is out of range 0 <= value <=
> 3",
> +				ldpc_dec->rv_index);
> +		return -1;
> +	}
>  	if (ldpc_dec->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
>  		rte_bbdev_log(ERR,
>  				"code_block_mode (%u) is out of range 0 <=
> value <= 1",
>  				ldpc_dec->code_block_mode);
>  		return -1;
>  	}
> -
> -	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> -		tb = &ldpc_dec->tb_params;
> -		if (tb->c < 1) {
> -			rte_bbdev_log(ERR,
> -					"c (%u) is out of range 1 <= value <=
> %u",
> -					tb->c,
> RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
> +	if (check_bit(op->ldpc_dec.op_flags,
> +			RTE_BBDEV_LDPC_DECODE_BYPASS)) {
> +		rte_bbdev_log(ERR, "Avoid LDPC Decode bypass");
> +		return -1;
> +	}
> +	int z_c = ldpc_dec->z_c;
> +	/* Check Zc is valid value */
> +	if ((z_c > 384) || (z_c < 4)) {
> +		rte_bbdev_log(ERR,
> +				"Zc (%u) is out of range",
> +				z_c);
> +		return -1;
> +	}
> +	if (z_c > 256) {
> +		if ((z_c % 32) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -		if (tb->cab > tb->c) {
> -			rte_bbdev_log(ERR,
> -					"cab (%u) is greater than c (%u)",
> -					tb->cab, tb->c);
> +	} else if (z_c > 128) {
> +		if ((z_c % 16) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
> -	} else {
> -		cb = &ldpc_dec->cb_params;
> -		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
> -			rte_bbdev_log(ERR,
> -					"e (%u) is out of range %u <= value <=
> %u",
> -					cb->e,
> RTE_BBDEV_LDPC_MIN_CB_SIZE,
> -					RTE_BBDEV_LDPC_MAX_CB_SIZE);
> +	} else if (z_c > 64) {
> +		if ((z_c % 8) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
> +			return -1;
> +		}
> +	} else if (z_c > 32) {
> +		if ((z_c % 4) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
> +			return -1;
> +		}
> +	} else if (z_c > 16) {
> +		if ((z_c % 2) != 0) {
> +			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
>  			return -1;
>  		}
>  	}
> 
> +	int n_filler = ldpc_dec->n_filler;
> +	int K = (ldpc_dec->basegraph == 1 ? 22 : 10) * ldpc_dec->z_c;
> +	int Kp = K - n_filler;
> +	int q_m = ldpc_dec->q_m;
> +	int n_cb = ldpc_dec->n_cb;
> +	int N = (ldpc_dec->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
> +	int k0 = k0 = get_k0(n_cb, z_c, ldpc_dec->basegraph,
> +			ldpc_dec->rv_index);
> +	int crc24 = 0;
> +	int32_t L, Lcb, cw, cw_rm;
> +	int32_t e = ldpc_dec->cb_params.e;
> +	if (check_bit(op->ldpc_dec.op_flags,
> +			RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK))
> +		crc24 = 24;
> +
> +	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
> +		rte_bbdev_log(ERR,
> +				"TB mode not supported");
> +		return -1;
> +	}
> +	/* Enforce HARQ input length */
> +	ldpc_dec->harq_combined_input.length = RTE_MIN((uint32_t) n_cb,
> +			ldpc_dec->harq_combined_input.length);
> +	if ((ldpc_dec->harq_combined_input.length == 0) &&
> +			check_bit(ldpc_dec->op_flags,
> +			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
> +		rte_bbdev_log(ERR,
> +				"HARQ input length (%u) should not be null",
> +				ldpc_dec->harq_combined_input.length);
> +		return -1;
> +	}
> +	if ((ldpc_dec->harq_combined_input.length > 0) &&
> +			!check_bit(ldpc_dec->op_flags,
> +			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
> +		ldpc_dec->harq_combined_input.length = 0;
> +	}
> +
> +	/* K' range check */
> +	if (Kp % 8 > 0) {
> +		rte_bbdev_log(ERR,
> +				"K' not byte aligned %u",
> +				Kp);
> +		return -1;
> +	}
> +	if ((crc24 > 0) && (Kp < 292)) {
> +		rte_bbdev_log(ERR,
> +				"Invalid CRC24 for small block %u",
> +				Kp);
> +		return -1;
> +	}
> +	if (Kp < 24) {
> +		rte_bbdev_log(ERR,
> +				"K' too small %u",
> +				Kp);
> +		return -1;
> +	}
> +	if (n_filler >= (K - 2 * z_c)) {
> +		rte_bbdev_log(ERR,
> +				"K - F invalid %u %u",
> +				K, n_filler);
> +		return -1;
> +	}
> +	/* Ncb range check */
> +	if (n_cb != N) {
> +		rte_bbdev_log(ERR,
> +				"Ncb (%u) is out of range K  %d N %d",
> +				n_cb, K, N);
> +		return -1;
> +	}
> +	/* Qm range check */
> +	if (!check_bit(op->ldpc_dec.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",
> +				q_m);
> +		return -1;
> +	}
> +	/* K0 range check */
> +	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
> +			&& (k0 < (K - 2 * z_c)))) {
> +		rte_bbdev_log(ERR,
> +				"K0 (%u) is out of range",
> +				k0);
> +		return -1;
> +	}
> +	/* E range check */
> +	if (e <= RTE_MAX(32, z_c)) {
> +		rte_bbdev_log(ERR,
> +				"E is too small");
> +		return -1;
> +	}
> +	if ((e > 0xFFFF)) {
> +		rte_bbdev_log(ERR,
> +				"E is too large");
> +		return -1;
> +	}
> +	if (q_m > 0) {
> +		if (e % q_m > 0) {
> +			rte_bbdev_log(ERR,
> +					"E not multiple of qm %d", q_m);
> +			return -1;
> +		}
> +	}
> +	/* Code word in RM range check */
> +	if (k0 > (Kp - 2 * z_c))
> +		L = k0 + e;
> +	else
> +		L = k0 + e + n_filler;
> +	Lcb = RTE_MIN(n_cb, RTE_MAX(L,
> +			(int32_t) ldpc_dec->harq_combined_input.length));
> +	if (ldpc_dec->basegraph == 1) {
> +		if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 27 * z_c)
> +			cw = 27 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else if (Lcb <= 33 * z_c)
> +			cw = 33 * z_c;
> +		else if (Lcb <= 44 * z_c)
> +			cw = 44 * z_c;
> +		else if (Lcb <= 55 * z_c)
> +			cw = 55 * z_c;
> +		else
> +			cw = 66 * z_c;
> +	} else {
> +		if (Lcb <= 15 * z_c)
> +			cw = 15 * z_c;
> +		else if (Lcb <= 20 * z_c)
> +			cw = 20 * z_c;
> +		else if (Lcb <= 25 * z_c)
> +			cw = 25 * z_c;
> +		else if (Lcb <= 30 * z_c)
> +			cw = 30 * z_c;
> +		else
> +			cw = 50 * z_c;
> +	}
> +	cw_rm = cw - n_filler;
> +	if (cw_rm <= 32) {
> +		rte_bbdev_log(ERR,
> +				"Invalid Ratematching");
> +		return -1;
> +	}
>  	return 0;
>  }
> -#endif
> +
> +static inline char *
> +mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
> +{
> +	if (unlikely(len > rte_pktmbuf_tailroom(m)))
> +		return NULL;
> +
> +	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
> +	m->data_len = (uint16_t)(m->data_len + len);
> +	m_head->pkt_len  = (m_head->pkt_len + len);
> +	return tail;
> +}
> 
>  static inline void
>  fpga_mutex_acquisition(struct fpga_queue *q) @@ -1386,14 +1671,11 @@
> enqueue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct
> rte_bbdev_enc_op *op,
>  	uint16_t ring_offset;
>  	uint16_t K, k_;
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
> -	/* Validate op structure */
> -	/* FIXME */
> -	if (validate_enc_op(op) == -1) {
> -		rte_bbdev_log(ERR, "LDPC encoder validation failed");
> +
> +	if (validate_ldpc_enc_op(op) == -1) {
> +		rte_bbdev_log(ERR, "LDPC encoder validation rejected");
>  		return -EINVAL;
>  	}
> -#endif
> 
>  	/* Clear op status */
>  	op->status = 0;
> @@ -1481,13 +1763,10 @@ enqueue_ldpc_dec_one_op_cb(struct
> fpga_queue *q, struct rte_bbdev_dec_op *op,
>  	uint16_t out_offset = dec->hard_output.offset;
>  	uint32_t harq_offset = 0;
> 
> -#ifdef RTE_LIBRTE_BBDEV_DEBUG
> -		/* Validate op structure */
> -		if (validate_dec_op(op) == -1) {
> -			rte_bbdev_log(ERR, "LDPC decoder validation failed");
> -			return -EINVAL;
> -		}
> -#endif
> +	if (validate_ldpc_dec_op(op) == -1) {
> +		rte_bbdev_log(ERR, "LDPC decoder validation rejected");
> +		return -EINVAL;
> +	}
> 
>  	/* Clear op status */
>  	op->status = 0;
> @@ -1717,8 +1996,7 @@ fpga_enqueue_ldpc_dec(struct
> rte_bbdev_queue_data *q_data,
> 
> 
>  static inline int
> -dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q,
> -		struct rte_bbdev_enc_op **op,
> +dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct
> +rte_bbdev_enc_op **op,
>  		uint16_t desc_offset)
>  {
>  	union fpga_dma_desc *desc;
> --
> 2.25.1
  

Patch

diff --git a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
index 2d4b58067d..8fdb44c94a 100644
--- a/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
+++ b/drivers/baseband/fpga_5gnr_fec/rte_fpga_5gnr_fec.c
@@ -1032,23 +1032,11 @@  fpga_dma_desc_ld_fill(struct rte_bbdev_dec_op *op,
 	return 0;
 }
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
 /* Validates LDPC encoder parameters */
-static int
-validate_enc_op(struct rte_bbdev_enc_op *op __rte_unused)
+static inline int
+validate_ldpc_enc_op(struct rte_bbdev_enc_op *op)
 {
 	struct rte_bbdev_op_ldpc_enc *ldpc_enc = &op->ldpc_enc;
-	struct rte_bbdev_op_enc_ldpc_cb_params *cb = NULL;
-	struct rte_bbdev_op_enc_ldpc_tb_params *tb = NULL;
-
-
-	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 (op->mempool == NULL) {
 		rte_bbdev_log(ERR, "Invalid mempool pointer");
@@ -1062,140 +1050,437 @@  validate_enc_op(struct rte_bbdev_enc_op *op __rte_unused)
 		rte_bbdev_log(ERR, "Invalid output pointer");
 		return -1;
 	}
+	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)) {
 		rte_bbdev_log(ERR,
-				"basegraph (%u) is out of range 1 <= value <= 2",
+				"BG (%u) is out of range 1 <= value <= 2",
 				ldpc_enc->basegraph);
 		return -1;
 	}
+	if (ldpc_enc->rv_index > 3) {
+		rte_bbdev_log(ERR,
+				"rv_index (%u) is out of range 0 <= value <= 3",
+				ldpc_enc->rv_index);
+		return -1;
+	}
 	if (ldpc_enc->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
 		rte_bbdev_log(ERR,
-				"code_block_mode (%u) is out of range 0:Tb 1:CB",
+				"code_block_mode (%u) is out of range 0 <= value <= 1",
 				ldpc_enc->code_block_mode);
 		return -1;
 	}
 
-	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
-		tb = &ldpc_enc->tb_params;
-		if (tb->c == 0) {
-			rte_bbdev_log(ERR,
-					"c (%u) is out of range 1 <= value <= %u",
-					tb->c, RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
+	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;
+	}
+	int z_c = ldpc_enc->z_c;
+	/* Check Zc is valid value */
+	if ((z_c > 384) || (z_c < 4)) {
+		rte_bbdev_log(ERR, "Zc (%u) is out of range", z_c);
+		return -1;
+	}
+	if (z_c > 256) {
+		if ((z_c % 32) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if (tb->cab > tb->c) {
-			rte_bbdev_log(ERR,
-					"cab (%u) is greater than c (%u)",
-					tb->cab, tb->c);
+	} else if (z_c > 128) {
+		if ((z_c % 16) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if ((tb->ea < RTE_BBDEV_LDPC_MIN_CB_SIZE)
-				&& tb->r < tb->cab) {
-			rte_bbdev_log(ERR,
-					"ea (%u) is less than %u or it is not even",
-					tb->ea, RTE_BBDEV_LDPC_MIN_CB_SIZE);
+	} else if (z_c > 64) {
+		if ((z_c % 8) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if ((tb->eb < RTE_BBDEV_LDPC_MIN_CB_SIZE)
-				&& tb->c > tb->cab) {
-			rte_bbdev_log(ERR,
-					"eb (%u) is less than %u",
-					tb->eb, RTE_BBDEV_LDPC_MIN_CB_SIZE);
+	} else if (z_c > 32) {
+		if ((z_c % 4) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if (tb->r > (tb->c - 1)) {
-			rte_bbdev_log(ERR,
-					"r (%u) is greater than c - 1 (%u)",
-					tb->r, tb->c - 1);
+	} else if (z_c > 16) {
+		if ((z_c % 2) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-	} else {
-		cb = &ldpc_enc->cb_params;
-		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
-			rte_bbdev_log(ERR,
-					"e (%u) is less than %u or it is not even",
-					cb->e, RTE_BBDEV_LDPC_MIN_CB_SIZE);
+	}
+
+	int n_filler = ldpc_enc->n_filler;
+	int K = (ldpc_enc->basegraph == 1 ? 22 : 10) * ldpc_enc->z_c;
+	int Kp = K - n_filler;
+	int q_m = ldpc_enc->q_m;
+	int n_cb = ldpc_enc->n_cb;
+	int N = (ldpc_enc->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
+	int k0 = k0 = get_k0(n_cb, z_c, ldpc_enc->basegraph,
+			ldpc_enc->rv_index);
+	int crc24 = 0;
+	int32_t L, Lcb, cw, cw_rm;
+	int32_t e = ldpc_enc->cb_params.e;
+	if (check_bit(op->ldpc_enc.op_flags,
+			RTE_BBDEV_LDPC_CRC_24B_ATTACH))
+		crc24 = 24;
+
+	if (K < (int) (ldpc_enc->input.length * 8 + n_filler) + crc24) {
+		rte_bbdev_log(ERR, "K and F not matching input size %u %u %u",
+				K, n_filler, ldpc_enc->input.length);
+		return -1;
+	}
+	if (ldpc_enc->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
+		rte_bbdev_log(ERR, "TB mode not supported");
+		return -1;
+
+	}
+
+	/* K' range check */
+	if (Kp % 8 > 0) {
+		rte_bbdev_log(ERR, "K' not byte aligned %u", Kp);
+		return -1;
+	}
+	if ((crc24 > 0) && (Kp < 292)) {
+		rte_bbdev_log(ERR, "Invalid CRC24 for small block %u", Kp);
+		return -1;
+	}
+	if (Kp < 24) {
+		rte_bbdev_log(ERR, "K' too small %u", Kp);
+		return -1;
+	}
+	if (n_filler >= (K - 2 * z_c)) {
+		rte_bbdev_log(ERR, "K - F invalid %u %u", K, n_filler);
+		return -1;
+	}
+	/* Ncb range check */
+	if ((n_cb > N) || (n_cb < 32) || (n_cb <= (Kp - crc24))) {
+		rte_bbdev_log(ERR, "Ncb (%u) is out of range K  %d N %d", n_cb, K, N);
+		return -1;
+	}
+	/* Qm range check */
+	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", q_m);
+		return -1;
+	}
+	/* K0 range check */
+	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
+			&& (k0 < (K - 2 * z_c)))) {
+		rte_bbdev_log(ERR, "K0 (%u) is out of range", k0);
+		return -1;
+	}
+	/* E range check */
+	if (e <= RTE_MAX(32, z_c)) {
+		rte_bbdev_log(ERR, "E is too small %"PRIu32"", e);
+		return -1;
+	}
+	if ((e > 0xFFFF)) {
+		rte_bbdev_log(ERR, "E is too large for N3000 %"PRIu32" > 64k", e);
+		return -1;
+	}
+	if (q_m > 0) {
+		if (e % q_m > 0) {
+			rte_bbdev_log(ERR, "E %"PRIu32" not multiple of qm %d", e, q_m);
 			return -1;
 		}
 	}
+	/* Code word in RM range check */
+	if (k0 > (Kp - 2 * z_c))
+		L = k0 + e;
+	else
+		L = k0 + e + n_filler;
+	Lcb = RTE_MIN(L, n_cb);
+	if (ldpc_enc->basegraph == 1) {
+		if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 27 * z_c)
+			cw = 27 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else if (Lcb <= 33 * z_c)
+			cw = 33 * z_c;
+		else if (Lcb <= 44 * z_c)
+			cw = 44 * z_c;
+		else if (Lcb <= 55 * z_c)
+			cw = 55 * z_c;
+		else
+			cw = 66 * z_c;
+	} else {
+		if (Lcb <= 15 * z_c)
+			cw = 15 * z_c;
+		else if (Lcb <= 20 * z_c)
+			cw = 20 * z_c;
+		else if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else
+			cw = 50 * z_c;
+	}
+	if (n_cb < Kp - 2 * z_c)
+		cw_rm = n_cb;
+	else if ((Kp - 2 * z_c <= n_cb) && (n_cb < K - 2 * z_c))
+		cw_rm = Kp - 2 * z_c;
+	else if ((K - 2 * z_c <= n_cb) && (n_cb < cw))
+		cw_rm = n_cb - n_filler;
+	else
+		cw_rm = cw - n_filler;
+	if (cw_rm <= 32) {
+		rte_bbdev_log(ERR,
+				"Invalid Ratematching");
+		return -1;
+	}
 	return 0;
 }
-#endif
-
-static inline char *
-mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
-{
-	if (unlikely(len > rte_pktmbuf_tailroom(m)))
-		return NULL;
-
-	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
-	m->data_len = (uint16_t)(m->data_len + len);
-	m_head->pkt_len  = (m_head->pkt_len + len);
-	return tail;
-}
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
 /* Validates LDPC decoder parameters */
-static int
-validate_dec_op(struct rte_bbdev_dec_op *op __rte_unused)
+static inline int
+validate_ldpc_dec_op(struct rte_bbdev_dec_op *op)
 {
 	struct rte_bbdev_op_ldpc_dec *ldpc_dec = &op->ldpc_dec;
-	struct rte_bbdev_op_dec_ldpc_cb_params *cb = NULL;
-	struct rte_bbdev_op_dec_ldpc_tb_params *tb = NULL;
-
-	if (op->mempool == NULL) {
-		rte_bbdev_log(ERR, "Invalid mempool pointer");
+	if (check_bit(ldpc_dec->op_flags,
+			RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK))
+		return 0;
+	if (ldpc_dec->input.data == NULL) {
+		rte_bbdev_log(ERR, "Invalid input pointer");
 		return -1;
 	}
-	if (ldpc_dec->rv_index > 3) {
+	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)) {
 		rte_bbdev_log(ERR,
-				"rv_index (%u) is out of range 0 <= value <= 3",
-				ldpc_dec->rv_index);
+				"BG (%u) is out of range 1 <= value <= 2",
+				ldpc_dec->basegraph);
 		return -1;
 	}
-
 	if (ldpc_dec->iter_max == 0) {
 		rte_bbdev_log(ERR,
 				"iter_max (%u) is equal to 0",
 				ldpc_dec->iter_max);
 		return -1;
 	}
-
+	if (ldpc_dec->rv_index > 3) {
+		rte_bbdev_log(ERR,
+				"rv_index (%u) is out of range 0 <= value <= 3",
+				ldpc_dec->rv_index);
+		return -1;
+	}
 	if (ldpc_dec->code_block_mode > RTE_BBDEV_CODE_BLOCK) {
 		rte_bbdev_log(ERR,
 				"code_block_mode (%u) is out of range 0 <= value <= 1",
 				ldpc_dec->code_block_mode);
 		return -1;
 	}
-
-	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
-		tb = &ldpc_dec->tb_params;
-		if (tb->c < 1) {
-			rte_bbdev_log(ERR,
-					"c (%u) is out of range 1 <= value <= %u",
-					tb->c, RTE_BBDEV_LDPC_MAX_CODE_BLOCKS);
+	if (check_bit(op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_DECODE_BYPASS)) {
+		rte_bbdev_log(ERR, "Avoid LDPC Decode bypass");
+		return -1;
+	}
+	int z_c = ldpc_dec->z_c;
+	/* Check Zc is valid value */
+	if ((z_c > 384) || (z_c < 4)) {
+		rte_bbdev_log(ERR,
+				"Zc (%u) is out of range",
+				z_c);
+		return -1;
+	}
+	if (z_c > 256) {
+		if ((z_c % 32) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-		if (tb->cab > tb->c) {
-			rte_bbdev_log(ERR,
-					"cab (%u) is greater than c (%u)",
-					tb->cab, tb->c);
+	} else if (z_c > 128) {
+		if ((z_c % 16) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
-	} else {
-		cb = &ldpc_dec->cb_params;
-		if (cb->e < RTE_BBDEV_LDPC_MIN_CB_SIZE) {
-			rte_bbdev_log(ERR,
-					"e (%u) is out of range %u <= value <= %u",
-					cb->e, RTE_BBDEV_LDPC_MIN_CB_SIZE,
-					RTE_BBDEV_LDPC_MAX_CB_SIZE);
+	} else if (z_c > 64) {
+		if ((z_c % 8) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
+			return -1;
+		}
+	} else if (z_c > 32) {
+		if ((z_c % 4) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
+			return -1;
+		}
+	} else if (z_c > 16) {
+		if ((z_c % 2) != 0) {
+			rte_bbdev_log(ERR, "Invalid Zc %d", z_c);
 			return -1;
 		}
 	}
 
+	int n_filler = ldpc_dec->n_filler;
+	int K = (ldpc_dec->basegraph == 1 ? 22 : 10) * ldpc_dec->z_c;
+	int Kp = K - n_filler;
+	int q_m = ldpc_dec->q_m;
+	int n_cb = ldpc_dec->n_cb;
+	int N = (ldpc_dec->basegraph == 1 ? N_ZC_1 : N_ZC_2) * z_c;
+	int k0 = k0 = get_k0(n_cb, z_c, ldpc_dec->basegraph,
+			ldpc_dec->rv_index);
+	int crc24 = 0;
+	int32_t L, Lcb, cw, cw_rm;
+	int32_t e = ldpc_dec->cb_params.e;
+	if (check_bit(op->ldpc_dec.op_flags,
+			RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK))
+		crc24 = 24;
+
+	if (ldpc_dec->code_block_mode == RTE_BBDEV_TRANSPORT_BLOCK) {
+		rte_bbdev_log(ERR,
+				"TB mode not supported");
+		return -1;
+	}
+	/* Enforce HARQ input length */
+	ldpc_dec->harq_combined_input.length = RTE_MIN((uint32_t) n_cb,
+			ldpc_dec->harq_combined_input.length);
+	if ((ldpc_dec->harq_combined_input.length == 0) &&
+			check_bit(ldpc_dec->op_flags,
+			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
+		rte_bbdev_log(ERR,
+				"HARQ input length (%u) should not be null",
+				ldpc_dec->harq_combined_input.length);
+		return -1;
+	}
+	if ((ldpc_dec->harq_combined_input.length > 0) &&
+			!check_bit(ldpc_dec->op_flags,
+			RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE)) {
+		ldpc_dec->harq_combined_input.length = 0;
+	}
+
+	/* K' range check */
+	if (Kp % 8 > 0) {
+		rte_bbdev_log(ERR,
+				"K' not byte aligned %u",
+				Kp);
+		return -1;
+	}
+	if ((crc24 > 0) && (Kp < 292)) {
+		rte_bbdev_log(ERR,
+				"Invalid CRC24 for small block %u",
+				Kp);
+		return -1;
+	}
+	if (Kp < 24) {
+		rte_bbdev_log(ERR,
+				"K' too small %u",
+				Kp);
+		return -1;
+	}
+	if (n_filler >= (K - 2 * z_c)) {
+		rte_bbdev_log(ERR,
+				"K - F invalid %u %u",
+				K, n_filler);
+		return -1;
+	}
+	/* Ncb range check */
+	if (n_cb != N) {
+		rte_bbdev_log(ERR,
+				"Ncb (%u) is out of range K  %d N %d",
+				n_cb, K, N);
+		return -1;
+	}
+	/* Qm range check */
+	if (!check_bit(op->ldpc_dec.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",
+				q_m);
+		return -1;
+	}
+	/* K0 range check */
+	if (((k0 % z_c) > 0) || (k0 >= n_cb) || ((k0 >= (Kp - 2 * z_c))
+			&& (k0 < (K - 2 * z_c)))) {
+		rte_bbdev_log(ERR,
+				"K0 (%u) is out of range",
+				k0);
+		return -1;
+	}
+	/* E range check */
+	if (e <= RTE_MAX(32, z_c)) {
+		rte_bbdev_log(ERR,
+				"E is too small");
+		return -1;
+	}
+	if ((e > 0xFFFF)) {
+		rte_bbdev_log(ERR,
+				"E is too large");
+		return -1;
+	}
+	if (q_m > 0) {
+		if (e % q_m > 0) {
+			rte_bbdev_log(ERR,
+					"E not multiple of qm %d", q_m);
+			return -1;
+		}
+	}
+	/* Code word in RM range check */
+	if (k0 > (Kp - 2 * z_c))
+		L = k0 + e;
+	else
+		L = k0 + e + n_filler;
+	Lcb = RTE_MIN(n_cb, RTE_MAX(L,
+			(int32_t) ldpc_dec->harq_combined_input.length));
+	if (ldpc_dec->basegraph == 1) {
+		if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 27 * z_c)
+			cw = 27 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else if (Lcb <= 33 * z_c)
+			cw = 33 * z_c;
+		else if (Lcb <= 44 * z_c)
+			cw = 44 * z_c;
+		else if (Lcb <= 55 * z_c)
+			cw = 55 * z_c;
+		else
+			cw = 66 * z_c;
+	} else {
+		if (Lcb <= 15 * z_c)
+			cw = 15 * z_c;
+		else if (Lcb <= 20 * z_c)
+			cw = 20 * z_c;
+		else if (Lcb <= 25 * z_c)
+			cw = 25 * z_c;
+		else if (Lcb <= 30 * z_c)
+			cw = 30 * z_c;
+		else
+			cw = 50 * z_c;
+	}
+	cw_rm = cw - n_filler;
+	if (cw_rm <= 32) {
+		rte_bbdev_log(ERR,
+				"Invalid Ratematching");
+		return -1;
+	}
 	return 0;
 }
-#endif
+
+static inline char *
+mbuf_append(struct rte_mbuf *m_head, struct rte_mbuf *m, uint16_t len)
+{
+	if (unlikely(len > rte_pktmbuf_tailroom(m)))
+		return NULL;
+
+	char *tail = (char *)m->buf_addr + m->data_off + m->data_len;
+	m->data_len = (uint16_t)(m->data_len + len);
+	m_head->pkt_len  = (m_head->pkt_len + len);
+	return tail;
+}
 
 static inline void
 fpga_mutex_acquisition(struct fpga_queue *q)
@@ -1386,14 +1671,11 @@  enqueue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct rte_bbdev_enc_op *op,
 	uint16_t ring_offset;
 	uint16_t K, k_;
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
-	/* Validate op structure */
-	/* FIXME */
-	if (validate_enc_op(op) == -1) {
-		rte_bbdev_log(ERR, "LDPC encoder validation failed");
+
+	if (validate_ldpc_enc_op(op) == -1) {
+		rte_bbdev_log(ERR, "LDPC encoder validation rejected");
 		return -EINVAL;
 	}
-#endif
 
 	/* Clear op status */
 	op->status = 0;
@@ -1481,13 +1763,10 @@  enqueue_ldpc_dec_one_op_cb(struct fpga_queue *q, struct rte_bbdev_dec_op *op,
 	uint16_t out_offset = dec->hard_output.offset;
 	uint32_t harq_offset = 0;
 
-#ifdef RTE_LIBRTE_BBDEV_DEBUG
-		/* Validate op structure */
-		if (validate_dec_op(op) == -1) {
-			rte_bbdev_log(ERR, "LDPC decoder validation failed");
-			return -EINVAL;
-		}
-#endif
+	if (validate_ldpc_dec_op(op) == -1) {
+		rte_bbdev_log(ERR, "LDPC decoder validation rejected");
+		return -EINVAL;
+	}
 
 	/* Clear op status */
 	op->status = 0;
@@ -1717,8 +1996,7 @@  fpga_enqueue_ldpc_dec(struct rte_bbdev_queue_data *q_data,
 
 
 static inline int
-dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q,
-		struct rte_bbdev_enc_op **op,
+dequeue_ldpc_enc_one_op_cb(struct fpga_queue *q, struct rte_bbdev_enc_op **op,
 		uint16_t desc_offset)
 {
 	union fpga_dma_desc *desc;