[Accel-config] [PATCH v1 4/9] accel-config/test: rewrite init task and add the init of dif operations

Tony Zhu <tony.zhu at intel.com> Fri, 11 Feb 2022 21:16:28 +0800
Newsgroups dev.linux.lists.accel-config
Message-ID <[email protected]>
DIF computation is performed on each block of source data, to avoid mistakes
the task init will be completed one by one.

Signed-off-by: Tony Zhu <tony.zhu(a)intel.com>
---
 test/dsa.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++++----
 test/dsa.h |  34 ++++++
 2 files changed, 313 insertions(+), 20 deletions(-)

diff --git a/test/dsa.c b/test/dsa.c
index f427664..0743895 100644
--- a/test/dsa.c
+++ b/test/dsa.c
@@ -22,6 +22,37 @@ unsigned int ms_timeout = 5000;
 int debug_logging;
 static int umwait_support;
 
+unsigned int dif_blk_arr[] = {512, 520, 4096, 4104};
+
+/*ANINDYA Logic to get blk_sz_flg*/
+int get_dif_blksz_flg(unsigned long xfer_size)
+{
+	int blk_idx_flg = 3;
+
+	while (blk_idx_flg) {
+		if (xfer_size % dif_blk_arr[blk_idx_flg] == 0)
+			break;
+		blk_idx_flg--;
+	}
+	return blk_idx_flg;
+}
+
+/* ASD Logic */
+unsigned long get_blks(unsigned long xfer_size)
+{
+	int blk_idx_flg = 3;
+	unsigned long num_blks;
+
+	while (blk_idx_flg) {
+		if (xfer_size % dif_blk_arr[blk_idx_flg] == 0)
+			break;
+		blk_idx_flg--;
+	}
+
+	num_blks = xfer_size / dif_blk_arr[blk_idx_flg];
+	return num_blks;
+}
+
 static inline void cpuid(unsigned int *eax, unsigned int *ebx,
 			 unsigned int *ecx, unsigned int *edx)
 {
@@ -284,7 +315,22 @@ struct task *__alloc_task(void)
 int init_task(struct task *tsk, int tflags, int opcode,
 	      unsigned long xfer_size)
 {
-	dbg("initilizing single task %#lx\n", tsk);
+	unsigned long buf_size;
+	unsigned long force_align = ADDR_ALIGNMENT;
+	uint8_t *src;
+	uint8_t *src2;
+	uint8_t *src3;
+	unsigned int dif_reftag;
+	unsigned int dif_apptag;
+	unsigned int dif_guardtag;
+	unsigned long delta_size;
+	unsigned long blks = 0;
+	unsigned long i;
+	uint64_t patternx = 0x1234;
+	uint64_t patterny = 0x1233;
+	unsigned long dif_size;
+
+	dbg("initilizing task %#lx\n", tsk);
 
 	tsk->pattern = 0x0123456789abcdef;
 	tsk->pattern2 = 0xfedcba9876543210;
@@ -292,47 +338,241 @@ int init_task(struct task *tsk, int tflags, int opcode,
 	tsk->test_flags = tflags;
 	tsk->xfer_size = xfer_size;
 
+	tsk->apptag = 0xFACE;
+	tsk->reftag = 0xABBA;
+
 	/* allocate memory: src1*/
 	switch (opcode) {
 	case DSA_OPCODE_MEMMOVE: /* intentionally empty */
-	case DSA_OPCODE_COMPARE: /* intentionally empty */
-	case DSA_OPCODE_COMPVAL: /* intentionally empty */
-	case DSA_OPCODE_DUALCAST:
-		tsk->src1 = malloc(xfer_size);
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
 		if (!tsk->src1)
 			return -ENOMEM;
 		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
-	}
 
-	/* allocate memory: src2*/
-	switch (opcode) {
+		tsk->dst1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->dst1)
+			return -ENOMEM;
+		memset_pattern(tsk->dst1, tsk->pattern2, xfer_size);
+		break;
+
+	case DSA_OPCODE_MEMFILL:
+		tsk->dst1 = aligned_alloc(1 << 12, xfer_size);
+		if (!tsk->dst1)
+			return -ENOMEM;
+		memset(tsk->dst1, 0, xfer_size);
+		break;
+
 	case DSA_OPCODE_COMPARE:
-		tsk->src2 = malloc(xfer_size);
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
+
+		tsk->src2 = aligned_alloc(force_align, xfer_size);
 		if (!tsk->src2)
 			return -ENOMEM;
 		memset_pattern(tsk->src2, tsk->pattern, xfer_size);
-	}
+		break;
+
+	case DSA_OPCODE_COMPVAL:
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
+		break;
+
+	case DSA_OPCODE_CFLUSH:
+		tsk->dst1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->dst1)
+			return -ENOMEM;
+		memset_pattern(tsk->dst1, tsk->pattern, xfer_size);
+		break;
 
-	/* allocate memory: dst1*/
-	switch (opcode) {
-	case DSA_OPCODE_MEMMOVE: /* intentionally empty */
-	case DSA_OPCODE_MEMFILL: /* intentionally empty */
 	case DSA_OPCODE_DUALCAST:
-		/* DUALCAST: dst1/dst2 lower 12 bits must be same */
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
+
 		tsk->dst1 = aligned_alloc(1 << 12, xfer_size);
 		if (!tsk->dst1)
 			return -ENOMEM;
 		memset_pattern(tsk->dst1, tsk->pattern2, xfer_size);
-	}
 
-	/* allocate memory: dst2*/
-	switch (opcode) {
-	case DSA_OPCODE_DUALCAST:
-		/* DUALCAST: dst1/dst2 lower 12 bits must be same */
 		tsk->dst2 = aligned_alloc(1 << 12, xfer_size);
 		if (!tsk->dst2)
 			return -ENOMEM;
 		memset_pattern(tsk->dst2, tsk->pattern2, xfer_size);
+		break;
+
+	case DSA_OPCODE_DIF_CHECK:	/*DIF_CHECK_OPCODE*/
+		tsk->blk_idx_flg = get_dif_blksz_flg(tsk->xfer_size);
+		blks = tsk->xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+		tsk->blks = blks;
+
+		buf_size = tsk->xfer_size / blks;
+		/* 8 bytes for inclusion of tags */
+		tsk->xfer_size += 8 * blks;
+		tsk->src1 = aligned_alloc(force_align, tsk->xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		src = (uint8_t *)tsk->src1;
+		dif_reftag = tsk->reftag;
+		dif_apptag = tsk->apptag;
+
+		for (i = 1; i <= blks; i++) {
+			dif_size = (buf_size + 8) * (i - 1);
+			memset_pattern((src + dif_size), tsk->pattern, buf_size);
+			dif_guardtag = dsa_calculate_crc_t10dif((src + dif_size), buf_size, 0);
+			src[buf_size + DIF_BLK_GRD_1 + dif_size] = (dif_guardtag >> 8) & 0xFF;
+			src[buf_size + DIF_BLK_GRD_2 + dif_size] = dif_guardtag & 0xFF;
+			src[buf_size + DIF_APP_TAG_1 + dif_size] = (dif_apptag >> 8) & 0xFF;
+			src[buf_size + DIF_APP_TAG_2 + dif_size] = (dif_apptag) & 0xFF;
+			src[buf_size + DIF_REF_TAG_1 + dif_size] = (dif_reftag >> 24) & 0xFF;
+			src[buf_size + DIF_REF_TAG_2 + dif_size] = (dif_reftag >> 16) & 0xFF;
+			src[buf_size + DIF_REF_TAG_3 + dif_size] = (dif_reftag >> 8) & 0xFF;
+			src[buf_size + DIF_REF_TAG_4 + dif_size] = dif_reftag & 0xFF;
+			dif_reftag++;
+		}
+		break;
+
+	case DSA_OPCODE_DIF_INS:
+		tsk->blk_idx_flg = get_dif_blksz_flg(tsk->xfer_size);
+		blks = tsk->xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+		tsk->blks = blks;
+
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
+		blks = get_blks(xfer_size);
+		xfer_size += 8 * blks;
+		tsk->dst1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->dst1)
+			return -ENOMEM;
+		break;
+
+	case DSA_OPCODE_DIF_STRP:
+		tsk->blk_idx_flg = get_dif_blksz_flg(tsk->xfer_size);
+		blks = tsk->xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+		tsk->blks = blks;
+		buf_size = tsk->xfer_size / blks;
+		/* 8 bytes for inclusion of tags */
+		tsk->xfer_size += 8 * blks;
+		tsk->src1 = aligned_alloc(force_align, tsk->xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+
+		src2 = (uint8_t *)tsk->src1;
+		dif_reftag = tsk->reftag;
+		dif_apptag = tsk->apptag;
+
+		for (i = 1; i <= blks; i++) {
+			dif_size = (buf_size + 8) * (i - 1);
+			memset_pattern((src2 + dif_size), tsk->pattern, buf_size);
+			dif_guardtag = dsa_calculate_crc_t10dif((src2 + dif_size), buf_size, 0);
+			src2[buf_size + DIF_BLK_GRD_1 + dif_size] = (dif_guardtag >> 8) & 0xFF;
+			src2[buf_size + DIF_BLK_GRD_2 + dif_size] = dif_guardtag & 0xFF;
+			src2[buf_size + DIF_APP_TAG_1 + dif_size] = (dif_apptag >> 8) & 0xFF;
+			src2[buf_size + DIF_APP_TAG_2 + dif_size] = (dif_apptag) & 0xFF;
+			src2[buf_size + DIF_REF_TAG_1 + dif_size] = (dif_reftag >> 24) & 0xFF;
+			src2[buf_size + DIF_REF_TAG_2 + dif_size] = (dif_reftag >> 16) & 0xFF;
+			src2[buf_size + DIF_REF_TAG_3 + dif_size] = (dif_reftag >> 8) & 0xFF;
+			src2[buf_size + DIF_REF_TAG_4 + dif_size] = dif_reftag & 0xFF;
+			dif_reftag++;
+		}
+
+		tsk->dst1 = aligned_alloc(force_align, tsk->xfer_size - 8 * blks);
+		if (!tsk->dst1)
+			return -ENOMEM;
+		break;
+
+	case DSA_OPCODE_DIF_UPDT:
+		tsk->blk_idx_flg = get_dif_blksz_flg(tsk->xfer_size);
+		blks = tsk->xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+		tsk->blks = blks;
+		buf_size = tsk->xfer_size / blks;
+		tsk->xfer_size += 8 * blks;
+		tsk->src1 = aligned_alloc(force_align, tsk->xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+
+		src3 = (uint8_t *)tsk->src1;
+		dif_reftag = tsk->reftag;
+		dif_apptag = tsk->apptag;
+
+		for (i = 1; i <= blks; i++) {
+			dif_size = (buf_size + 8) * (i - 1);
+			memset_pattern((src3 + dif_size), tsk->pattern, buf_size);
+			dif_guardtag = dsa_calculate_crc_t10dif((src3 + dif_size), buf_size, 0);
+			src3[buf_size + DIF_BLK_GRD_1 + dif_size] = (dif_guardtag >> 8) & 0xFF;
+			src3[buf_size + DIF_BLK_GRD_2 + dif_size] = dif_guardtag & 0xFF;
+			src3[buf_size + DIF_APP_TAG_1 + dif_size] = (dif_apptag >> 8) & 0xFF;
+			src3[buf_size + DIF_APP_TAG_2 + dif_size] = (dif_apptag) & 0xFF;
+			src3[buf_size + DIF_REF_TAG_1 + dif_size] = (dif_reftag >> 24) & 0xFF;
+			src3[buf_size + DIF_REF_TAG_2 + dif_size] = (dif_reftag >> 16) & 0xFF;
+			src3[buf_size + DIF_REF_TAG_3 + dif_size] = (dif_reftag >> 8) & 0xFF;
+			src3[buf_size + DIF_REF_TAG_4 + dif_size] = dif_reftag & 0xFF;
+		}
+		tsk->dst1 = aligned_alloc(force_align, tsk->xfer_size);
+		if (!tsk->dst1)
+			return -ENOMEM;
+		break;
+
+	case DSA_OPCODE_AP_DELTA:
+	case DSA_OPCODE_CR_DELTA:
+		tsk->src1 = aligned_alloc(force_align, tsk->xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, patternx, tsk->xfer_size);
+		tsk->src2 = aligned_alloc(force_align, tsk->xfer_size);
+		if (!tsk->src2)
+			return -ENOMEM;
+		memset_pattern(tsk->src2, patterny, tsk->xfer_size);
+		delta_size = 2 * xfer_size;
+		tsk->delta1 = aligned_alloc(force_align, delta_size);
+		if (!tsk->delta1)
+			return -ENOMEM;
+		if (opcode == DSA_OPCODE_AP_DELTA) {
+			tsk->dst1 = aligned_alloc(force_align, tsk->xfer_size);
+			if (!tsk->dst1)
+				return -ENOMEM;
+		}
+		break;
+
+	case DSA_OPCODE_CRCGEN:
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
+		srand(time(0));
+		tsk->crc_seed = 0x12345678;
+		if (tsk->test_flags & (unsigned int)(READ_CRC_SEED)) {
+			tsk->crc_seed_addr = aligned_alloc(ADDR_ALIGNMENT, sizeof(tsk->crc_seed));
+			*tsk->crc_seed_addr = tsk->crc_seed;
+			tsk->crc_seed = 0x0;
+		}
+		break;
+
+	case DSA_OPCODE_COPY_CRC:
+		tsk->src1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->src1)
+			return -ENOMEM;
+		memset_pattern(tsk->src1, tsk->pattern, xfer_size);
+
+		tsk->dst1 = aligned_alloc(force_align, xfer_size);
+		if (!tsk->dst1)
+			return -ENOMEM;
+
+		memset_pattern(tsk->dst1, tsk->pattern2, xfer_size);
+		srand(time(0));
+		tsk->crc_seed = 0x12345678;
+		if (tsk->test_flags & (unsigned int)(READ_CRC_SEED)) {
+			tsk->crc_seed_addr = aligned_alloc(ADDR_ALIGNMENT, sizeof(tsk->crc_seed));
+			*tsk->crc_seed_addr = tsk->crc_seed;
+			tsk->crc_seed = 0x0;
+		}
+		break;
 	}
 
 	dbg("Mem allocated: s1 %#lx s2 %#lx d1 %#lx d2 %#lx\n",
@@ -1237,6 +1477,25 @@ int task_result_verify_dualcast(struct task *tsk, int mismatch_expected)
 	return DSA_STATUS_OK;
 }
 
+/**
+ * This function calculates the CRC16 T10 checksum for the DIF descriptors.
+ * @param *buffer pointer to the data buffer.
+ * @param len size of the buffer.
+ *
+ **/
+uint16_t dsa_calculate_crc_t10dif(unsigned char *buffer, size_t len, int flags)
+{
+	uint16_t crc;
+	unsigned int i = 0;
+
+	crc = (flags & DIF_INVERT_CRC_SEED) ? 0xFFFF : 0;
+
+	for (i = 0; i < len; i++)
+		crc = (crc << 8) ^ t10_dif_crc_table[((crc >> 8) ^ buffer[i]) & 0xff];
+
+	return (flags & DIF_INVERT_CRC_RESULT) ? ~crc : crc;
+}
+
 int batch_result_verify(struct batch_task *btsk, int bof)
 {
 	uint8_t core_stat, sub_stat;
diff --git a/test/dsa.h b/test/dsa.h
index 6363bbd..72c2675 100644
--- a/test/dsa.h
+++ b/test/dsa.h
@@ -4,6 +4,7 @@
 #define __TEST_DSA_H__
 #include <accfg/libaccel_config.h>
 #include <accfg/idxd.h>
+#include "crc16_t10_lookup.h"
 #include "accfg_test.h"
 
 #define MAX_PATH_LENGTH 1024
@@ -41,6 +42,26 @@
 #define DSA_COMP_STAT_CODE_MASK                 0x3F
 #define DSA_COMP_STAT_RW_MASK                   0x80
 
+#define DIF_INVERT_CRC_SEED         ((unsigned long)(1 << 2))
+#define DIF_INVERT_CRC_RESULT       ((unsigned long)(1 << 3))
+
+/* DIF index */
+#define DIF_BLK_GRD_1  0
+#define DIF_BLK_GRD_2  1
+#define DIF_APP_TAG_1  2
+#define DIF_APP_TAG_2  3
+#define DIF_REF_TAG_1  4
+#define DIF_REF_TAG_2  5
+#define DIF_REF_TAG_3  6
+#define DIF_REF_TAG_4  7
+
+/* CRC Flags */
+#define READ_CRC_SEED		((unsigned long)(1 << 16))
+#define BYPASS_CRC_INV_REF	((unsigned long)(1 << 17))
+#define BYPASS_DATA_REF		((unsigned long)(1 << 18))
+
+#define ADDR_ALIGNMENT 32
+
 #define MIN_DELTA_RECORD_SIZE 80
 /* helper macro to get lower 6 bits (ret code) from completion status */
 #define stat_val(status) ((status) & DSA_COMP_STAT_CODE_MASK)
@@ -63,6 +84,14 @@ struct task {
 	uint64_t xfer_size;
 	uint32_t dflags;
 	int test_flags;
+	int reftag;
+	int apptag;
+	int guardtag;
+	unsigned long blks;
+	int blk_idx_flg;
+	int crc_seed;
+	int delta_rec_size;
+	uint64_t *crc_seed_addr;
 };
 
 struct task_node {
@@ -306,4 +335,9 @@ void free_batch_task(struct batch_task *btsk);
 void dsa_prep_desc_common(struct dsa_hw_desc *hw, char opcode,
 			  uint64_t dest, uint64_t src, size_t len, unsigned long dflags);
 void dsa_desc_submit(struct dsa_context *ctx, struct dsa_hw_desc *hw);
+
+uint16_t dsa_calculate_crc_t10dif(unsigned char *buffer, size_t len, int flags);
+
+int get_dif_blksz_flg(unsigned long xfer_size);
+unsigned long get_blks(unsigned long xfer_size);
 #endif
-- 
2.27.0