[Accel-config] [PATCH v4 6/7] accel-config/test: add 4 dif operations support
Tony Zhu <tony.zhu at intel.com> Mon, 21 Feb 2022 09:34:22 +0800
| Newsgroups | dev.linux.lists.accel-config |
|---|---|
| Message-ID | <[email protected]> |
Add Data Integrity Field (DIF) check, insert, strip, and update
operation support while transferring data.
Signed-off-by: Tony Zhu <tony.zhu(a)intel.com>
---
test/dsa.c | 713 ++++++++++++++++++++++++++++++++++++++++++++++++
test/dsa.h | 44 +++
test/dsa_test.c | 104 +++++++
test/prep.c | 189 +++++++++++++
4 files changed, 1050 insertions(+)
diff --git a/test/dsa.c b/test/dsa.c
index 9a10267..fa3b8d6 100644
--- a/test/dsa.c
+++ b/test/dsa.c
@@ -23,6 +23,35 @@ unsigned int ms_timeout = 5000;
int debug_logging;
static int umwait_support;
+unsigned int dif_blk_arr[] = {512, 520, 4096, 4104};
+
+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;
+}
+
+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)
{
@@ -477,6 +506,196 @@ int init_copy_crc(struct task *tsk, int tflags, int opcode, unsigned long xfer_s
return DSA_STATUS_OK;
}
+int init_dif_check(struct task *tsk, int tflags, int opcode, unsigned long xfer_size)
+{
+ unsigned long buf_size;
+ unsigned long force_align = ADDR_ALIGNMENT;
+ unsigned char *src;
+ unsigned int dif_reftag;
+ unsigned int dif_apptag;
+ unsigned int dif_guardtag;
+ unsigned long blks = 0;
+ unsigned long i;
+ unsigned long dif_size;
+
+ tsk->pattern = 0x0123456789abcdef;
+ tsk->opcode = opcode;
+ tsk->test_flags = tflags;
+ tsk->xfer_size = xfer_size;
+
+ tsk->apptag = 0xFACE;
+ tsk->reftag = 0xABBA;
+
+ 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 = (unsigned char *)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++;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+int init_dif_ins(struct task *tsk, int tflags, int opcode, unsigned long xfer_size)
+{
+ unsigned long force_align = ADDR_ALIGNMENT;
+ unsigned long blks = 0;
+
+ tsk->pattern = 0x0123456789abcdef;
+ tsk->opcode = opcode;
+ tsk->test_flags = tflags;
+ tsk->xfer_size = xfer_size;
+
+ tsk->apptag = 0xFACE;
+ tsk->reftag = 0xABBA;
+ 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;
+
+ return DSA_STATUS_OK;
+}
+
+int init_dif_strp(struct task *tsk, int tflags, int opcode, unsigned long xfer_size)
+{
+ unsigned long buf_size;
+ unsigned long force_align = ADDR_ALIGNMENT;
+ unsigned char *src;
+ unsigned int dif_reftag;
+ unsigned int dif_apptag;
+ unsigned int dif_guardtag;
+ unsigned long blks = 0;
+ unsigned long i;
+ unsigned long dif_size;
+
+ tsk->pattern = 0x0123456789abcdef;
+ tsk->opcode = opcode;
+ tsk->test_flags = tflags;
+ tsk->xfer_size = xfer_size;
+
+ tsk->apptag = 0xFACE;
+ tsk->reftag = 0xABBA;
+
+ 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 = (unsigned char *)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++;
+ }
+
+ tsk->dst1 = aligned_alloc(force_align, tsk->xfer_size - 8 * blks);
+ if (!tsk->dst1)
+ return -ENOMEM;
+
+ return DSA_STATUS_OK;
+}
+
+int init_dif_updt(struct task *tsk, int tflags, int opcode, unsigned long xfer_size)
+{
+ unsigned long buf_size;
+ unsigned long force_align = ADDR_ALIGNMENT;
+ unsigned char *src;
+ unsigned int dif_reftag;
+ unsigned int dif_apptag;
+ unsigned int dif_guardtag;
+ unsigned long blks = 0;
+ unsigned long i;
+ unsigned long dif_size;
+
+ tsk->pattern = 0x0123456789abcdef;
+ tsk->opcode = opcode;
+ tsk->test_flags = tflags;
+ tsk->xfer_size = xfer_size;
+
+ tsk->apptag = 0xFACE;
+ tsk->reftag = 0xABBA;
+
+ 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;
+
+ src = (unsigned char *)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;
+ }
+ tsk->dst1 = aligned_alloc(force_align, tsk->xfer_size);
+ if (!tsk->dst1)
+ return -ENOMEM;
+
+ return DSA_STATUS_OK;
+}
+
/* this function is re-used by batch task */
int init_task(struct task *tsk, int tflags, int opcode,
unsigned long xfer_size)
@@ -520,6 +739,22 @@ int init_task(struct task *tsk, int tflags, int opcode,
case DSA_OPCODE_COPY_CRC:
rc = init_copy_crc(tsk, tflags, opcode, xfer_size);
break;
+
+ case DSA_OPCODE_DIF_CHECK:
+ rc = init_dif_check(tsk, tflags, opcode, xfer_size);
+ break;
+
+ case DSA_OPCODE_DIF_INS:
+ rc = init_dif_ins(tsk, tflags, opcode, xfer_size);
+ break;
+
+ case DSA_OPCODE_DIF_STRP:
+ rc = init_dif_strp(tsk, tflags, opcode, xfer_size);
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ rc = init_dif_updt(tsk, tflags, opcode, xfer_size);
+ break;
}
if (rc != DSA_STATUS_OK) {
@@ -1441,6 +1676,158 @@ int dsa_crc_copy_multi_task_nodes(struct dsa_context *ctx)
return ret;
}
+int dsa_wait_dif(struct dsa_context *ctx, struct task *tsk)
+{
+ struct dsa_hw_desc *desc = tsk->desc;
+ struct dsa_completion_record *comp = tsk->comp;
+ int rc;
+
+again:
+ rc = dsa_wait_on_desc_timeout(comp, ms_timeout);
+ if (rc < 0) {
+ err("DIF desc timeout\n");
+ return DSA_STATUS_TIMEOUT;
+ }
+
+ /* re-submit if PAGE_FAULT reported by HW && BOF is off */
+ if (stat_val(comp->status) == DSA_COMP_PAGE_FAULT_NOBOF &&
+ !(desc->flags & IDXD_OP_FLAG_BOF)) {
+ task_result_verify(tsk, 0);
+ dsa_reprep_dif(ctx, tsk);
+ goto again;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+int dsa_dif_check_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_check(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+
+ info("Submitted all dif check jobs\n");
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+ return ret;
+}
+
+int dsa_dif_ins_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_insert(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+ tsk_node = ctx->multi_task_node;
+ info("Submitted all dif insert jobs\n");
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+ return ret;
+}
+
+int dsa_dif_strp_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_strip(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+
+ info("Submitted all dif strp jobs\n");
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+
+ return ret;
+}
+
+int dsa_dif_updt_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_update(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+ tsk_node = ctx->multi_task_node;
+
+ info("Submitted all dif update jobs\n");
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+ return ret;
+}
+
/* mismatch_expected: expect mismatched buffer with success status 0x1 */
int task_result_verify(struct task *tsk, int mismatch_expected)
{
@@ -1476,6 +1863,19 @@ int task_result_verify(struct task *tsk, int mismatch_expected)
case DSA_OPCODE_COPY_CRC:
rc = task_result_verify_crc_copy(tsk, mismatch_expected);
return rc;
+ case DSA_OPCODE_DIF_INS:
+ rc = task_result_verify_dif(tsk, tsk->xfer_size, mismatch_expected);
+ rc = task_result_verify_dif_tags(tsk, tsk->xfer_size);
+ return rc;
+ case DSA_OPCODE_DIF_STRP:
+ rc = task_result_verify_dif(tsk, tsk->xfer_size - 8 * tsk->blks,
+ mismatch_expected);
+ return rc;
+ case DSA_OPCODE_DIF_UPDT:
+ rc = task_result_verify_dif(tsk, tsk->xfer_size - 8 * tsk->blks,
+ mismatch_expected);
+ rc = task_result_verify_dif_tags(tsk, tsk->xfer_size - 8 * tsk->blks);
+ return rc;
}
info("test with op %d passed\n", tsk->opcode);
@@ -1745,6 +2145,319 @@ int task_result_verify_crc_copy(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)
+{
+ unsigned short 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;
+}
+
+static int task_result_verify_dif_page_fault(struct task *tsk, unsigned long xfer_size,
+ int mismatch_expected)
+{
+ struct dsa_hw_desc *hw = tsk->desc;
+ int rc = 0;
+ unsigned char *src1 = (unsigned char *)hw->src_addr;
+ unsigned char *dst1 = (unsigned char *)hw->dst_addr;
+ unsigned long i, blks;
+
+ if (tsk->comp->status == 0x16 || xfer_size == 0)
+ return DSA_STATUS_OK;
+
+ info("Partial DIF Src and Dest Check Ongoing\n");
+
+ if (tsk->opcode == DSA_OPCODE_DIF_INS) {
+ blks = xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[dif_blk_arr[tsk->blk_idx_flg] * i],
+ &dst1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ dif_blk_arr[tsk->blk_idx_flg]);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_STRP) {
+ blks = xfer_size / (dif_blk_arr[tsk->blk_idx_flg] + 8);
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ &dst1[dif_blk_arr[tsk->blk_idx_flg] * i],
+ dif_blk_arr[tsk->blk_idx_flg]);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_UPDT) {
+ blks = xfer_size / (dif_blk_arr[tsk->blk_idx_flg] + 8);
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ &dst1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ dif_blk_arr[tsk->blk_idx_flg]);
+ }
+
+ if (rc) {
+ err("dif mismatch dst1, memcmp rc %d\n", rc);
+ return -ENXIO;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+int task_result_verify_dif(struct task *tsk, unsigned long xfer_size, int mismatch_expected)
+{
+ int rc;
+ unsigned long i;
+ unsigned long blks = tsk->blks;
+ unsigned long buf_size = dif_blk_arr[tsk->blk_idx_flg];
+ unsigned char *src1 = (unsigned char *)tsk->src1;
+ unsigned char *dst1 = (unsigned char *)tsk->dst1;
+
+ if (tsk->comp->status == DSA_COMP_PAGE_FAULT_NOBOF ||
+ tsk->comp->status == DSA_COMP_PAGE_FAULT_IR ||
+ tsk->comp->status == 0x83) {
+ rc = task_result_verify_dif_page_fault(tsk, tsk->comp->bytes_completed, 0);
+ info("Partial DIF Src and Dest Checking Done\n");
+ if (!rc)
+ return DSA_STATUS_OK;
+ }
+
+ if (tsk->comp->status == 0x16)
+ return DSA_STATUS_OK;
+
+ info("Checking Src & Dst buffers\n");
+ if (tsk->opcode == DSA_OPCODE_DIF_INS) {
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[buf_size * i], &dst1[(buf_size + 8) * i], buf_size);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_STRP) {
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(buf_size + 8) * i], &dst1[buf_size * i], buf_size);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_UPDT) {
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(buf_size + 8) * i], &dst1[(buf_size + 8) * i], buf_size);
+ }
+
+ if (rc) {
+ err("dif mismatch dst1, memcmp rc %d\n", rc);
+ return -ENXIO;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+static int task_result_verify_dif_tags_page_fault(struct task *tsk, unsigned long xfer_size)
+{
+ struct dsa_hw_desc *hw = tsk->desc;
+ unsigned long blks;
+ unsigned long buf_size;
+ unsigned char *dst1 = (uint8_t *)hw->dst_addr;
+ unsigned char *src1 = (uint8_t *)hw->src_addr;
+ unsigned long g_count = 0;
+ unsigned long a_count = 0;
+ unsigned long r_count = 0;
+ unsigned short dif_apptag = 0;
+ unsigned long dif_reftag = 0;
+ unsigned int dif_guardtag = 0;
+ unsigned char tmp_buf;
+ unsigned char dst_tag;
+ unsigned long i;
+
+ info("Checking Partial DIF Tags\n");
+
+ if (tsk->comp->status == 0x16 || xfer_size == 0)
+ return DSA_STATUS_OK;
+
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ blks = xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+ else
+ blks = xfer_size / (dif_blk_arr[tsk->blk_idx_flg] + 8);
+
+ switch (tsk->opcode) {
+ case DSA_OPCODE_DIF_INS:
+ dif_reftag = hw->ins_ref_tag_seed;
+ dif_apptag = hw->ins_app_tag_seed;
+ break;
+
+ case DSA_OPCODE_DIF_CHECK:
+ case DSA_OPCODE_DIF_STRP:
+ dif_reftag = hw->chk_ref_tag_seed;
+ dif_apptag = hw->chk_app_tag_seed;
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ dif_reftag = hw->dest_ref_tag_seed;
+ dif_apptag = hw->dest_app_tag_seed;
+ break;
+ }
+
+ buf_size = dif_blk_arr[tsk->blk_idx_flg];
+ for (i = 0; i < blks; i++) {
+ if (tsk->opcode == DSA_OPCODE_DIF_INS)
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + buf_size * i),
+ buf_size, 0);
+ else
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + (buf_size + 8) * i),
+ buf_size, 0);
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_guardtag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_2 + (buf_size + 8) * i];
+ tmp_buf = dif_guardtag & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 24) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 16) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_3 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_4 + (buf_size + 8) * i];
+ tmp_buf = dif_reftag & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ dif_reftag++;
+ }
+
+ if (g_count || a_count || r_count)
+ err("Tag Errors Found g: %ld a: %ld r: %ld\n", g_count, a_count, r_count);
+ else
+ info("All Tags Validated\n", g_count, a_count, r_count);
+
+ return DSA_STATUS_OK;
+}
+
+int task_result_verify_dif_tags(struct task *tsk, unsigned long xfer_size)
+{
+ int rc;
+ unsigned long blks;
+ unsigned long buf_size;
+ unsigned char *dst1 = (unsigned char *)tsk->dst1;
+ unsigned char *src1 = (unsigned char *)tsk->src1;
+ unsigned long g_count = 0;
+ unsigned long a_count = 0;
+ unsigned long r_count = 0;
+ unsigned int dif_reftag = tsk->reftag;
+ unsigned int dif_apptag = tsk->apptag;
+ unsigned int dif_guardtag = 0;
+ unsigned char tmp_buf;
+ unsigned char dst_tag;
+ unsigned long i;
+
+ info("compsts: %x\n", tsk->comp->status);
+ if (tsk->comp->status == 0x83 ||
+ tsk->comp->status == DSA_COMP_PAGE_FAULT_NOBOF ||
+ tsk->comp->status == DSA_COMP_PAGE_FAULT_IR) {
+ rc = task_result_verify_dif_tags_page_fault(tsk, tsk->comp->bytes_completed);
+ info("Partial DIF Tags Checking Done\n");
+ if (!rc)
+ return DSA_STATUS_OK;
+ }
+
+ info("Checking All Tags\n");
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ blks = xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+ else
+ blks = tsk->blks;
+
+ buf_size = dif_blk_arr[tsk->blk_idx_flg];
+ tsk->reftag = 0xABBA;
+ tsk->apptag = 0xFACE;
+
+ for (i = 0; i < blks; i++) {
+ if (tsk->opcode == DSA_OPCODE_DIF_INS)
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + (buf_size) * i),
+ buf_size, 0);
+ else
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + (buf_size + 8) * i),
+ buf_size, 0);
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_guardtag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_2 + (buf_size + 8) * i];
+ tmp_buf = dif_guardtag & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 24) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 16) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_3 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_4 + (buf_size + 8) * i];
+ tmp_buf = dif_reftag & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ dif_reftag++;
+ }
+
+ if (g_count || a_count || r_count)
+ err("Tag Errors Found g: %ld a: %ld r: %ld\n", g_count, a_count, r_count);
+ else
+ info("All Tags Validated\n", g_count, a_count, r_count);
+
+ return DSA_STATUS_OK;
+}
+
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 4bb08ed..9157741 100644
--- a/test/dsa.h
+++ b/test/dsa.h
@@ -5,6 +5,7 @@
#include <accfg/libaccel_config.h>
#include <accfg/idxd.h>
#include "accfg_test.h"
+#include "crc16_t10_lookup.h"
#define MAX_PATH_LENGTH 1024
@@ -46,6 +47,19 @@
#define BYPASS_CRC_INV_REF ((unsigned long)(1 << 17))
#define BYPASS_DATA_REF ((unsigned long)(1 << 18))
+/* 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
+
+#define DIF_INVERT_CRC_SEED ((unsigned long)(1 << 2))
+#define DIF_INVERT_CRC_RESULT ((unsigned long)(1 << 3))
+
#define ADDR_ALIGNMENT 32
#define MIN_DELTA_RECORD_SIZE 80
@@ -72,6 +86,11 @@ struct task {
int test_flags;
int crc_seed;
unsigned long long *crc_seed_addr;
+ int reftag;
+ int apptag;
+ int guardtag;
+ unsigned long blks;
+ int blk_idx_flg;
};
struct task_node {
@@ -247,6 +266,10 @@ int init_dualcast(struct task *tsk, int tflags, int opcode, unsigned long xfer_s
int init_cr_delta(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
int init_crcgen(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
int init_copy_crc(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
+int init_dif_check(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
+int init_dif_ins(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
+int init_dif_strp(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
+int init_dif_updt(struct task *tsk, int tflags, int opcode, unsigned long xfer_size);
int init_task(struct task *tsk, int tflags, int opcode,
unsigned long xfer_size);
@@ -283,6 +306,12 @@ int dsa_wait_crcgen(struct dsa_context *ctx, struct task *tsk);
int dsa_crc_copy_multi_task_nodes(struct dsa_context *ctx);
int dsa_wait_crc_copy(struct dsa_context *ctx, struct task *tsk);
+int dsa_dif_check_multi_task_nodes(struct dsa_context *ctx);
+int dsa_dif_ins_multi_task_nodes(struct dsa_context *ctx);
+int dsa_dif_strp_multi_task_nodes(struct dsa_context *ctx);
+int dsa_dif_updt_multi_task_nodes(struct dsa_context *ctx);
+int dsa_wait_dif(struct dsa_context *ctx, struct task *tsk);
+
void dsa_prep_noop(struct task *tsk);
void dsa_prep_drain(struct task *tsk);
void dsa_prep_memcpy(struct task *tsk);
@@ -303,6 +332,11 @@ void dsa_prep_crcgen(struct task *tsk);
void dsa_reprep_crcgen(struct dsa_context *ctx, struct task *tsk);
void dsa_prep_crc_copy(struct task *tsk);
void dsa_reprep_crc_copy(struct dsa_context *ctx, struct task *tsk);
+void dsa_prep_dif_check(struct task *tsk);
+void dsa_prep_dif_insert(struct task *tsk);
+void dsa_prep_dif_strip(struct task *tsk);
+void dsa_prep_dif_update(struct task *tsk);
+void dsa_reprep_dif(struct dsa_context *ctx, struct task *tsk);
int task_result_verify(struct task *tsk, int mismatch_expected);
int task_result_verify_task_nodes(struct dsa_context *ctx, int mismatch_expected);
@@ -314,6 +348,8 @@ int task_result_verify_dualcast(struct task *tsk, int mismatch_expected);
int task_result_verify_ap_delta(struct task *tsk, int mismatch_expected);
int task_result_verify_crcgen(struct task *tsk, int mismatch_expected);
int task_result_verify_crc_copy(struct task *tsk, int mismatch_expected);
+int task_result_verify_dif(struct task *tsk, unsigned long xfer_size, int mismatch_expected);
+int task_result_verify_dif_tags(struct task *tsk, unsigned long xfer_size);
int batch_result_verify(struct batch_task *btsk, int bof);
int alloc_batch_task(struct dsa_context *ctx, unsigned int task_num, int num_itr);
@@ -331,6 +367,10 @@ void dsa_prep_batch_cr_delta(struct batch_task *btsk);
void dsa_prep_batch_ap_delta(struct batch_task *btsk);
void dsa_prep_batch_crcgen(struct batch_task *btsk);
void dsa_prep_batch_crc_copy(struct batch_task *btsk);
+void dsa_prep_batch_dif_check(struct batch_task *btsk);
+void dsa_prep_batch_dif_insert(struct batch_task *btsk);
+void dsa_prep_batch_dif_strip(struct batch_task *btsk);
+void dsa_prep_batch_dif_update(struct batch_task *btsk);
int dsa_wait_batch(struct batch_task *btsk);
void dsa_free(struct dsa_context *ctx);
@@ -342,4 +382,8 @@ 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
diff --git a/test/dsa_test.c b/test/dsa_test.c
index 5a89687..a702f75 100644
--- a/test/dsa_test.c
+++ b/test/dsa_test.c
@@ -111,6 +111,22 @@ static int test_batch(struct dsa_context *ctx, size_t buf_size,
dsa_prep_batch_crc_copy(btsk_node->btsk);
break;
+ case DSA_OPCODE_DIF_CHECK:
+ dsa_prep_batch_dif_check(btsk_node->btsk);
+ break;
+
+ case DSA_OPCODE_DIF_INS:
+ dsa_prep_batch_dif_insert(btsk_node->btsk);
+ break;
+
+ case DSA_OPCODE_DIF_STRP:
+ dsa_prep_batch_dif_strip(btsk_node->btsk);
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ dsa_prep_batch_dif_update(btsk_node->btsk);
+ break;
+
default:
err("Unsupported op %#x\n", bopcode);
return -EINVAL;
@@ -191,6 +207,85 @@ static int test_batch(struct dsa_context *ctx, size_t buf_size,
return rc;
}
+static int test_dif(struct dsa_context *ctx, size_t buf_size,
+ int tflags, uint32_t opcode, int num_desc)
+{
+ struct task_node *tsk_node;
+ int rc = DSA_STATUS_OK;
+ int itr = num_desc, i = 0, range = 0;
+
+ info("testmemory: opcode %d len %#lx tflags %#x num_desc %ld\n",
+ opcode, buf_size, tflags, num_desc);
+
+ ctx->is_batch = 0;
+
+ if (ctx->dedicated == ACCFG_WQ_SHARED)
+ range = ctx->threshold;
+ else
+ range = ctx->wq_size - 1;
+
+ while (itr > 0 && rc == DSA_STATUS_OK) {
+ i = (itr < range) ? itr : range;
+ /* Allocate memory to all the task nodes, desc, completion record*/
+ rc = alloc_multiple_tasks(ctx, i);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+
+ /* allocate memory to src and dest buffers and fill in the desc for all the nodes*/
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ tsk_node->tsk->xfer_size = buf_size;
+ tsk_node->tsk->blk_idx_flg = get_dif_blksz_flg(tsk_node->tsk->xfer_size);
+
+ rc = init_task(tsk_node->tsk, tflags, opcode, buf_size);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+
+ tsk_node = tsk_node->next;
+ }
+
+ switch (opcode) {
+ case DSA_OPCODE_DIF_CHECK:
+ rc = dsa_dif_check_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ case DSA_OPCODE_DIF_INS:
+ rc = dsa_dif_ins_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ case DSA_OPCODE_DIF_STRP:
+ rc = dsa_dif_strp_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ rc = dsa_dif_updt_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ default:
+ err("Unsupported op %#x\n", opcode);
+ return -EINVAL;
+ }
+
+ /* Verification of all the nodes*/
+ rc = task_result_verify_task_nodes(ctx, 0);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+
+ dsa_free_task(ctx);
+ itr = itr - range;
+ }
+
+ return rc;
+}
+
static int test_noop(struct dsa_context *ctx, int tflags, int num_desc)
{
struct task_node *tsk_node;
@@ -650,6 +745,15 @@ int main(int argc, char *argv[])
goto error;
break;
+ case DSA_OPCODE_DIF_CHECK:
+ case DSA_OPCODE_DIF_INS:
+ case DSA_OPCODE_DIF_STRP:
+ case DSA_OPCODE_DIF_UPDT:
+ rc = test_dif(dsa, buf_size, tflags, opcode, num_desc);
+ if (rc != DSA_STATUS_OK)
+ goto error;
+ break;
+
default:
rc = -EINVAL;
break;
diff --git a/test/prep.c b/test/prep.c
index daa8db4..5f85b7c 100644
--- a/test/prep.c
+++ b/test/prep.c
@@ -8,6 +8,8 @@
#include <accfg/idxd.h>
#include "dsa.h"
+unsigned int dif_arr[] = {512, 520, 4096, 4104};
+
void dsa_prep_desc_common(struct dsa_hw_desc *hw, char opcode,
uint64_t dest, uint64_t src, size_t len, unsigned long dflags)
{
@@ -531,6 +533,193 @@ void dsa_prep_batch_crc_copy(struct batch_task *btsk)
}
}
+void dsa_prep_dif_check(struct task *tsk)
+{
+ info("preparing descriptor for dif check\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->chk_app_tag_seed = tsk->apptag;
+ tsk->desc->chk_ref_tag_seed = tsk->reftag;
+ tsk->desc->dif_chk_flags = tsk->blk_idx_flg;
+}
+
+void dsa_prep_dif_insert(struct task *tsk)
+{
+ info("preparing descriptor for dif insert\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->ins_app_tag_seed = tsk->apptag;
+ tsk->desc->ins_ref_tag_seed = tsk->reftag;
+ tsk->desc->dif_ins_flags = tsk->blk_idx_flg;
+}
+
+void dsa_prep_dif_strip(struct task *tsk)
+{
+ info("preparing descriptor for dif strip\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->chk_app_tag_seed = tsk->apptag;
+ tsk->desc->chk_ref_tag_seed = tsk->reftag;
+ tsk->desc->dif_chk_flags = tsk->blk_idx_flg;
+}
+
+void dsa_prep_dif_update(struct task *tsk)
+{
+ info("preparing descriptor for dif update\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->src_app_tag_seed = tsk->apptag;
+ tsk->desc->src_ref_tag_seed = tsk->reftag;
+ tsk->desc->dest_ref_tag_seed = tsk->reftag;
+ tsk->desc->dest_app_tag_seed = tsk->apptag;
+ tsk->desc->src_upd_flags = 0x80;
+ tsk->desc->upd_dest_flags = 0x80;
+ tsk->desc->dif_upd_flags = tsk->blk_idx_flg;
+}
+
+void dsa_reprep_dif(struct dsa_context *ctx, struct task *tsk)
+{
+ struct dsa_completion_record *compl = tsk->comp;
+ struct dsa_hw_desc *hw = tsk->desc;
+ unsigned long blks_completed = 0;
+
+ info("PF addr %#lx dir %d bc %#x\n",
+ compl->fault_addr, compl->result,
+ compl->bytes_completed);
+
+ hw->src_addr += compl->bytes_completed;
+ hw->ins_ref_tag_seed = compl->dif_ins_ref_tag;
+ if (tsk->opcode == DSA_OPCODE_DIF_INS) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg]);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->dst_addr += compl->bytes_completed + 8 * blks_completed;
+ hw->ins_app_tag_seed = compl->dif_ins_app_tag;
+ hw->ins_ref_tag_seed = compl->dif_ins_ref_tag;
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_STRP) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg] + 8);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->dst_addr += dif_arr[tsk->blk_idx_flg] * blks_completed;
+ hw->chk_app_tag_seed = compl->dif_chk_app_tag;
+ hw->chk_ref_tag_seed = compl->dif_chk_ref_tag;
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_UPDT) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg] + 8);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->dst_addr += (dif_arr[tsk->blk_idx_flg] + 8) * blks_completed;
+ hw->src_app_tag_seed = compl->dif_upd_src_app_tag;
+ hw->dest_app_tag_seed = compl->dif_upd_dest_app_tag;
+ hw->src_ref_tag_seed = compl->dif_upd_dest_ref_tag;
+ hw->dest_ref_tag_seed = compl->dif_upd_dest_ref_tag;
+ }
+ if (tsk->opcode == DSA_OPCODE_DIF_CHECK) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg] + 8);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->chk_app_tag_seed = compl->dif_chk_app_tag;
+ hw->chk_ref_tag_seed = compl->dif_chk_ref_tag;
+ }
+
+ resolve_page_fault(compl->fault_addr, compl->status);
+
+ compl->status = 0;
+
+ dsa_desc_submit(ctx, hw);
+}
+
+void dsa_prep_batch_dif_check(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, sub_task->dflags);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->chk_app_tag_seed = sub_task->apptag;
+ sub_task->desc->chk_ref_tag_seed = sub_task->reftag;
+ }
+}
+
+void dsa_prep_batch_dif_insert(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, sub_task->dflags);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->ins_app_tag_seed = sub_task->apptag;
+ sub_task->desc->ins_ref_tag_seed = sub_task->reftag;
+ }
+}
+
+void dsa_prep_batch_dif_strip(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, sub_task->dflags);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->chk_app_tag_seed = sub_task->apptag;
+ sub_task->desc->chk_ref_tag_seed = sub_task->reftag;
+ }
+}
+
+void dsa_prep_batch_dif_update(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, sub_task->dflags);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->src_app_tag_seed = sub_task->apptag;
+ sub_task->desc->src_ref_tag_seed = sub_task->reftag;
+ sub_task->desc->dest_ref_tag_seed = sub_task->reftag;
+ sub_task->desc->dest_app_tag_seed = sub_task->apptag;
+ sub_task->desc->src_upd_flags = 0x80;
+ sub_task->desc->upd_dest_flags = 0x80;
+ }
+}
+
void dsa_prep_batch(struct batch_task *btsk, unsigned long desc_flags)
{
struct task *ctsk = btsk->core_task;
--
2.27.0