xref: /spdk/test/accel/dif/dif.c (revision f74d16bead289b710674d39aadc9f2e1e599df3f)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2023 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 
8 #include "spdk/accel.h"
9 #include "spdk/env.h"
10 #include "spdk/log.h"
11 #include "spdk/thread.h"
12 #include "spdk/event.h"
13 #include "spdk/rpc.h"
14 #include "spdk/util.h"
15 #include "spdk/string.h"
16 #include "spdk_internal/cunit.h"
17 
18 #include "CUnit/Basic.h"
19 
20 pthread_mutex_t g_test_mutex;
21 pthread_cond_t g_test_cond;
22 
23 #define WORKER_COUNT 2
24 #define WORKER_IO 0
25 #define WORKER_UT 1
26 
27 static struct spdk_thread *g_thread[WORKER_COUNT];
28 static int g_num_failures = 0;
29 static bool g_shutdown = false;
30 static bool g_completion_success;
31 struct spdk_io_channel	*g_channel = NULL;
32 
33 struct dif_task {
34 	struct iovec		*dst_iovs;
35 	uint32_t		dst_iovcnt;
36 	struct iovec		*src_iovs;
37 	uint32_t		src_iovcnt;
38 	struct iovec		*aux_iovs;
39 	uint32_t		aux_iovcnt;
40 	struct iovec		md_iov;
41 	uint32_t		num_blocks; /* used for the DIF related operations */
42 	struct spdk_dif_ctx	dif_ctx;
43 	struct spdk_dif_error	dif_err;
44 };
45 
46 static void
47 execute_spdk_function(spdk_msg_fn fn, void *arg)
48 {
49 	pthread_mutex_lock(&g_test_mutex);
50 	spdk_thread_send_msg(g_thread[WORKER_IO], fn, arg);
51 	pthread_cond_wait(&g_test_cond, &g_test_mutex);
52 	pthread_mutex_unlock(&g_test_mutex);
53 }
54 
55 static void
56 wake_ut_thread(void)
57 {
58 	pthread_mutex_lock(&g_test_mutex);
59 	pthread_cond_signal(&g_test_cond);
60 	pthread_mutex_unlock(&g_test_mutex);
61 }
62 
63 static void
64 exit_io_thread(void *arg)
65 {
66 	assert(spdk_get_thread() == g_thread[WORKER_IO]);
67 	spdk_thread_exit(g_thread[WORKER_IO]);
68 	wake_ut_thread();
69 }
70 
71 #define DATA_PATTERN 0x5A
72 
73 static int g_xfer_size_bytes = 4096;
74 static int g_block_size_bytes = 512;
75 static int g_md_size_bytes = 8;
76 struct dif_task g_dif_task;
77 
78 struct accel_dif_request {
79 	struct spdk_accel_sequence *sequence;
80 	struct spdk_io_channel *channel;
81 	struct iovec *dst_iovs;
82 	size_t dst_iovcnt;
83 	struct iovec *src_iovs;
84 	size_t src_iovcnt;
85 	struct iovec *aux_iovs;
86 	size_t aux_iovcnt;
87 	struct iovec *md_iov;
88 	uint32_t num_blocks;
89 	const struct spdk_dif_ctx *ctx;
90 	struct spdk_dif_error *err;
91 	spdk_accel_completion_cb cb_fn;
92 	void *cb_arg;
93 };
94 
95 static void
96 accel_dif_oper_done(void *arg1, int status)
97 {
98 	if (status == 0) {
99 		g_completion_success = true;
100 	}
101 	wake_ut_thread();
102 }
103 
104 static bool
105 accel_dif_error_validate(const uint32_t dif_flags,
106 			 const struct spdk_dif_error *err)
107 {
108 	if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
109 		return err->err_type == SPDK_DIF_GUARD_ERROR;
110 	} else if (dif_flags & SPDK_DIF_FLAGS_APPTAG_CHECK) {
111 		return err->err_type == SPDK_DIF_APPTAG_ERROR;
112 	} else if (dif_flags & SPDK_DIF_FLAGS_REFTAG_CHECK) {
113 		return err->err_type == SPDK_DIF_REFTAG_ERROR;
114 	}
115 
116 	return false;
117 }
118 
119 static int
120 alloc_dif_verify_bufs(struct dif_task *task, uint32_t chained_count)
121 {
122 	int src_buff_len = g_xfer_size_bytes;
123 	uint32_t i = 0;
124 
125 	assert(chained_count > 0);
126 	task->src_iovcnt = chained_count;
127 	task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec));
128 	if (spdk_unlikely(task->src_iovs == NULL)) {
129 		return -ENOMEM;
130 	}
131 
132 	src_buff_len += (g_xfer_size_bytes / g_block_size_bytes) * g_md_size_bytes;
133 
134 	for (i = 0; i < task->src_iovcnt; i++) {
135 		task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL);
136 		if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) {
137 			return -ENOMEM;
138 		}
139 
140 		memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len);
141 		task->src_iovs[i].iov_len = src_buff_len;
142 	}
143 
144 	task->num_blocks = (g_xfer_size_bytes * chained_count) / g_block_size_bytes;
145 
146 	return 0;
147 }
148 
149 static int
150 alloc_dix_bufs(struct dif_task *task, uint32_t chained_count)
151 {
152 	int src_buff_len = g_xfer_size_bytes, md_buff_len;
153 	uint32_t i = 0;
154 
155 	assert(chained_count > 0);
156 	task->src_iovcnt = chained_count;
157 	task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec));
158 	if (spdk_unlikely(task->src_iovs == NULL)) {
159 		return -ENOMEM;
160 	}
161 
162 	md_buff_len = (g_xfer_size_bytes / g_block_size_bytes) * g_md_size_bytes * chained_count;
163 
164 	for (i = 0; i < task->src_iovcnt; i++) {
165 		task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL);
166 		if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) {
167 			return -ENOMEM;
168 		}
169 
170 		memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len);
171 		task->src_iovs[i].iov_len = src_buff_len;
172 	}
173 
174 	task->md_iov.iov_base = spdk_dma_zmalloc(md_buff_len, 0, NULL);
175 	if (spdk_unlikely(task->md_iov.iov_base == NULL)) {
176 		return -ENOMEM;
177 	}
178 
179 	task->md_iov.iov_len = md_buff_len;
180 	task->num_blocks = (g_xfer_size_bytes * chained_count) / g_block_size_bytes;
181 
182 	return 0;
183 }
184 
185 static void
186 free_dif_verify_bufs(struct dif_task *task)
187 {
188 	uint32_t i = 0;
189 
190 	if (task->src_iovs != NULL) {
191 		for (i = 0; i < task->src_iovcnt; i++) {
192 			if (task->src_iovs[i].iov_base != NULL) {
193 				spdk_dma_free(task->src_iovs[i].iov_base);
194 			}
195 		}
196 		free(task->src_iovs);
197 	}
198 }
199 
200 static void
201 free_dix_bufs(struct dif_task *task)
202 {
203 	uint32_t i = 0;
204 
205 	if (task->src_iovs != NULL) {
206 		for (i = 0; i < task->src_iovcnt; i++) {
207 			if (task->src_iovs[i].iov_base != NULL) {
208 				spdk_dma_free(task->src_iovs[i].iov_base);
209 			}
210 		}
211 		free(task->src_iovs);
212 	}
213 
214 	if (task->md_iov.iov_base != NULL) {
215 		spdk_dma_free(task->md_iov.iov_base);
216 	}
217 }
218 
219 static int
220 alloc_dif_verify_copy_bufs(struct dif_task *task, uint32_t chained_count)
221 {
222 	int dst_buff_len = g_xfer_size_bytes;
223 	uint32_t data_size_with_md;
224 	uint32_t i = 0;
225 
226 	assert(chained_count > 0);
227 	task->src_iovcnt = chained_count;
228 	task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec));
229 	if (spdk_unlikely(task->src_iovs == NULL)) {
230 		return -ENOMEM;
231 	}
232 
233 	task->num_blocks = g_xfer_size_bytes / g_block_size_bytes;
234 
235 	/* Add bytes for each block for metadata */
236 	data_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes);
237 
238 	for (i = 0; i < task->src_iovcnt; i++) {
239 		task->src_iovs[i].iov_base = spdk_dma_zmalloc(data_size_with_md, 0, NULL);
240 		if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) {
241 			return -ENOMEM;
242 		}
243 
244 		memset(task->src_iovs[i].iov_base, DATA_PATTERN, data_size_with_md);
245 		task->src_iovs[i].iov_len = data_size_with_md;
246 	}
247 
248 	task->dst_iovcnt = chained_count;
249 	task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec));
250 	if (spdk_unlikely(task->dst_iovs == NULL)) {
251 		return -ENOMEM;
252 	}
253 
254 	for (i = 0; i < task->dst_iovcnt; i++) {
255 		task->dst_iovs[i].iov_base = spdk_dma_zmalloc(dst_buff_len, 0, NULL);
256 		if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) {
257 			return -ENOMEM;
258 		}
259 
260 		memset(task->dst_iovs[i].iov_base, 0, dst_buff_len);
261 		task->dst_iovs[i].iov_len = dst_buff_len;
262 	}
263 
264 	return 0;
265 }
266 
267 static void
268 free_dif_verify_copy_bufs(struct dif_task *task)
269 {
270 	uint32_t i = 0;
271 
272 	if (task->dst_iovs != NULL) {
273 		for (i = 0; i < task->dst_iovcnt; i++) {
274 			if (task->dst_iovs[i].iov_base != NULL) {
275 				spdk_dma_free(task->dst_iovs[i].iov_base);
276 			}
277 		}
278 		free(task->dst_iovs);
279 	}
280 
281 	if (task->src_iovs != NULL) {
282 		for (i = 0; i < task->src_iovcnt; i++) {
283 			if (task->src_iovs[i].iov_base != NULL) {
284 				spdk_dma_free(task->src_iovs[i].iov_base);
285 			}
286 		}
287 		free(task->src_iovs);
288 	}
289 }
290 
291 static int
292 alloc_dif_generate_copy_bufs(struct dif_task *task, uint32_t chained_count)
293 {
294 	int src_buff_len = g_xfer_size_bytes;
295 	uint32_t transfer_size_with_md;
296 	uint32_t i = 0;
297 
298 	assert(chained_count > 0);
299 	task->dst_iovcnt = chained_count;
300 	task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec));
301 	if (spdk_unlikely(task->dst_iovs == NULL)) {
302 		return -ENOMEM;
303 	}
304 
305 	task->num_blocks = g_xfer_size_bytes / g_block_size_bytes;
306 
307 	/* Add bytes for each block for metadata */
308 	transfer_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes);
309 
310 	for (i = 0; i < task->dst_iovcnt; i++) {
311 		task->dst_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL);
312 		if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) {
313 			return -ENOMEM;
314 		}
315 
316 		memset(task->dst_iovs[i].iov_base, 0, transfer_size_with_md);
317 		task->dst_iovs[i].iov_len = transfer_size_with_md;
318 	}
319 
320 	task->src_iovcnt = chained_count;
321 	task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec));
322 	if (spdk_unlikely(task->src_iovs == NULL)) {
323 		return -ENOMEM;
324 	}
325 
326 	for (i = 0; i < task->src_iovcnt; i++) {
327 		task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL);
328 		if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) {
329 			return -ENOMEM;
330 		}
331 
332 		memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len);
333 		task->src_iovs[i].iov_len = src_buff_len;
334 	}
335 
336 	return 0;
337 }
338 
339 static void
340 free_dif_generate_copy_bufs(struct dif_task *task)
341 {
342 	uint32_t i = 0;
343 
344 	if (task->dst_iovs != NULL) {
345 		for (i = 0; i < task->dst_iovcnt; i++) {
346 			if (task->dst_iovs[i].iov_base != NULL) {
347 				spdk_dma_free(task->dst_iovs[i].iov_base);
348 			}
349 		}
350 		free(task->dst_iovs);
351 	}
352 
353 	if (task->src_iovs != NULL) {
354 		for (i = 0; i < task->src_iovcnt; i++) {
355 			if (task->src_iovs[i].iov_base != NULL) {
356 				spdk_dma_free(task->src_iovs[i].iov_base);
357 			}
358 		}
359 		free(task->src_iovs);
360 	}
361 }
362 
363 static int
364 alloc_dif_generate_copy_sequence_bufs(struct dif_task *task, uint32_t chained_count)
365 {
366 	int src_buff_len = g_xfer_size_bytes;
367 	uint32_t transfer_size_with_md;
368 	uint32_t i = 0;
369 
370 	assert(chained_count > 0);
371 	task->dst_iovcnt = chained_count;
372 	task->dst_iovs = calloc(task->dst_iovcnt, sizeof(struct iovec));
373 	if (spdk_unlikely(task->dst_iovs == NULL)) {
374 		return -ENOMEM;
375 	}
376 
377 	task->num_blocks = g_xfer_size_bytes / g_block_size_bytes;
378 
379 	/* Add bytes for each block for metadata */
380 	transfer_size_with_md = g_xfer_size_bytes + (task->num_blocks * g_md_size_bytes);
381 
382 	for (i = 0; i < task->dst_iovcnt; i++) {
383 		task->dst_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL);
384 		if (spdk_unlikely(task->dst_iovs[i].iov_base == NULL)) {
385 			return -ENOMEM;
386 		}
387 
388 		memset(task->dst_iovs[i].iov_base, 0, transfer_size_with_md);
389 		task->dst_iovs[i].iov_len = transfer_size_with_md;
390 	}
391 
392 	task->src_iovcnt = chained_count;
393 	task->src_iovs = calloc(task->src_iovcnt, sizeof(struct iovec));
394 	if (spdk_unlikely(task->src_iovs == NULL)) {
395 		return -ENOMEM;
396 	}
397 
398 	for (i = 0; i < task->src_iovcnt; i++) {
399 		task->src_iovs[i].iov_base = spdk_dma_zmalloc(src_buff_len, 0, NULL);
400 		if (spdk_unlikely(task->src_iovs[i].iov_base == NULL)) {
401 			return -ENOMEM;
402 		}
403 
404 		memset(task->src_iovs[i].iov_base, DATA_PATTERN, src_buff_len);
405 		task->src_iovs[i].iov_len = src_buff_len;
406 	}
407 
408 	/*
409 	 * For write, we do not want to insert DIF in place because host does not expect
410 	 * write buffer to be updated. We allocate auxiliary buffer to simulate such case.
411 	 */
412 	task->aux_iovcnt = chained_count;
413 	task->aux_iovs = calloc(task->aux_iovcnt, sizeof(struct iovec));
414 	if (spdk_unlikely(task->aux_iovs == NULL)) {
415 		return -ENOMEM;
416 	}
417 
418 	for (i = 0; i < task->aux_iovcnt; i++) {
419 		task->aux_iovs[i].iov_base = spdk_dma_zmalloc(transfer_size_with_md, 0, NULL);
420 		if (spdk_unlikely(task->aux_iovs[i].iov_base == NULL)) {
421 			return -ENOMEM;
422 		}
423 
424 		memset(task->aux_iovs[i].iov_base, 0, transfer_size_with_md);
425 		task->aux_iovs[i].iov_len = transfer_size_with_md;
426 	}
427 
428 	return 0;
429 }
430 
431 static void
432 free_dif_generate_copy_sequence_bufs(struct dif_task *task)
433 {
434 	uint32_t i = 0;
435 
436 	if (task->dst_iovs != NULL) {
437 		for (i = 0; i < task->dst_iovcnt; i++) {
438 			if (task->dst_iovs[i].iov_base != NULL) {
439 				spdk_dma_free(task->dst_iovs[i].iov_base);
440 			}
441 		}
442 		free(task->dst_iovs);
443 	}
444 
445 	if (task->src_iovs != NULL) {
446 		for (i = 0; i < task->src_iovcnt; i++) {
447 			if (task->src_iovs[i].iov_base != NULL) {
448 				spdk_dma_free(task->src_iovs[i].iov_base);
449 			}
450 		}
451 		free(task->src_iovs);
452 	}
453 
454 	if (task->aux_iovs != NULL) {
455 		for (i = 0; i < task->aux_iovcnt; i++) {
456 			if (task->aux_iovs[i].iov_base != NULL) {
457 				spdk_dma_free(task->aux_iovs[i].iov_base);
458 			}
459 		}
460 		free(task->aux_iovs);
461 	}
462 }
463 
464 static void
465 accel_dif_verify_test(void *arg)
466 {
467 	int rc;
468 	struct accel_dif_request *req = arg;
469 
470 	g_completion_success = false;
471 	rc = spdk_accel_submit_dif_verify(req->channel, req->src_iovs, req->src_iovcnt,
472 					  req->num_blocks, req->ctx, req->err,
473 					  req->cb_fn, req->cb_arg);
474 	if (rc) {
475 		wake_ut_thread();
476 	}
477 }
478 
479 static void
480 accel_dix_verify_test(void *arg)
481 {
482 	int rc;
483 	struct accel_dif_request *req = arg;
484 
485 	g_completion_success = false;
486 	rc = spdk_accel_submit_dix_verify(req->channel, req->src_iovs, req->src_iovcnt, req->md_iov,
487 					  req->num_blocks, req->ctx, req->err, req->cb_fn,
488 					  req->cb_arg);
489 	if (rc) {
490 		wake_ut_thread();
491 	}
492 }
493 
494 static void
495 accel_dix_generate_test(void *arg)
496 {
497 	int rc;
498 	struct accel_dif_request *req = arg;
499 
500 	g_completion_success = false;
501 	rc = spdk_accel_submit_dix_generate(req->channel, req->src_iovs, req->src_iovcnt,
502 					    req->md_iov, req->num_blocks, req->ctx, req->cb_fn, req->cb_arg);
503 	if (rc) {
504 		wake_ut_thread();
505 	}
506 }
507 
508 static void
509 accel_dif_verify_copy_test(void *arg)
510 {
511 	int rc;
512 	struct accel_dif_request *req = arg;
513 
514 	g_completion_success = false;
515 	rc = spdk_accel_submit_dif_verify_copy(req->channel, req->dst_iovs, req->dst_iovcnt,
516 					       req->src_iovs, req->src_iovcnt,
517 					       req->num_blocks, req->ctx, req->err,
518 					       req->cb_fn, req->cb_arg);
519 	if (rc) {
520 		wake_ut_thread();
521 	}
522 }
523 
524 static void
525 accel_dif_generate_copy_test(void *arg)
526 {
527 	int rc;
528 	struct accel_dif_request *req = arg;
529 
530 	g_completion_success = false;
531 	rc = spdk_accel_submit_dif_generate_copy(req->channel, req->dst_iovs, req->dst_iovcnt,
532 			req->src_iovs, req->src_iovcnt, req->num_blocks, req->ctx,
533 			req->cb_fn, req->cb_arg);
534 	if (rc) {
535 		wake_ut_thread();
536 	}
537 }
538 
539 static void
540 accel_dif_generate_copy_sequence_test(void *arg)
541 {
542 	int rc;
543 	struct accel_dif_request *req = arg;
544 
545 	g_completion_success = false;
546 	req->sequence = NULL;
547 
548 	rc = spdk_accel_append_dif_generate_copy(&req->sequence, req->channel,
549 			req->aux_iovs, req->aux_iovcnt, NULL, NULL,
550 			req->src_iovs, req->src_iovcnt, NULL, NULL,
551 			req->num_blocks, req->ctx, NULL, NULL);
552 	if (rc) {
553 		wake_ut_thread();
554 		return;
555 	}
556 
557 	rc = spdk_accel_append_copy(&req->sequence, req->channel,
558 				    req->dst_iovs, req->dst_iovcnt, NULL, NULL,
559 				    req->aux_iovs, req->aux_iovcnt, NULL, NULL,
560 				    NULL, NULL);
561 	if (rc) {
562 		spdk_accel_sequence_abort(req->sequence);
563 		wake_ut_thread();
564 		return;
565 	}
566 
567 	spdk_accel_sequence_finish(req->sequence, req->cb_fn, req->cb_arg);
568 }
569 
570 static void
571 accel_dif_verify_copy_sequence_test(void *arg)
572 {
573 	int rc;
574 	struct accel_dif_request *req = arg;
575 
576 	g_completion_success = false;
577 	req->sequence = NULL;
578 
579 	rc = spdk_accel_append_dif_verify_copy(&req->sequence, req->channel,
580 					       req->dst_iovs, req->dst_iovcnt, NULL, NULL,
581 					       req->dst_iovs, req->dst_iovcnt, NULL, NULL,
582 					       req->num_blocks, req->ctx, req->err,
583 					       NULL, NULL);
584 	if (rc) {
585 		wake_ut_thread();
586 		return;
587 	}
588 
589 	rc = spdk_accel_append_copy(&req->sequence, req->channel,
590 				    req->dst_iovs, req->dst_iovcnt, NULL, NULL,
591 				    req->src_iovs, req->src_iovcnt, NULL, NULL,
592 				    NULL, NULL);
593 	if (rc) {
594 		spdk_accel_sequence_abort(req->sequence);
595 		wake_ut_thread();
596 		return;
597 	}
598 
599 	spdk_accel_sequence_reverse(req->sequence);
600 	spdk_accel_sequence_finish(req->sequence, req->cb_fn, req->cb_arg);
601 }
602 
603 static void
604 accel_dif_verify_op_dif_generated_do_check(uint32_t dif_flags)
605 {
606 	struct spdk_dif_ctx_init_ext_opts dif_opts;
607 	struct accel_dif_request req;
608 	struct dif_task *task = &g_dif_task;
609 	int rc;
610 
611 	rc = alloc_dif_verify_bufs(task, 1);
612 	SPDK_CU_ASSERT_FATAL(rc == 0);
613 
614 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
615 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
616 
617 	rc = spdk_dif_ctx_init(&task->dif_ctx,
618 			       g_block_size_bytes + g_md_size_bytes,
619 			       g_md_size_bytes, true, true,
620 			       SPDK_DIF_TYPE1,
621 			       SPDK_DIF_FLAGS_GUARD_CHECK |
622 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
623 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
624 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
625 	SPDK_CU_ASSERT_FATAL(rc == 0);
626 
627 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
628 	SPDK_CU_ASSERT_FATAL(rc == 0);
629 
630 	rc = spdk_dif_ctx_init(&task->dif_ctx,
631 			       g_block_size_bytes + g_md_size_bytes,
632 			       g_md_size_bytes, true, true,
633 			       SPDK_DIF_TYPE1,
634 			       dif_flags,
635 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
636 	SPDK_CU_ASSERT_FATAL(rc == 0);
637 
638 	req.channel = g_channel;
639 	req.src_iovs = task->src_iovs;
640 	req.src_iovcnt = task->src_iovcnt;
641 	req.num_blocks = task->num_blocks;
642 	req.ctx = &task->dif_ctx;
643 	req.err = &task->dif_err;
644 	req.cb_fn = accel_dif_oper_done;
645 	req.cb_arg = task;
646 
647 	execute_spdk_function(accel_dif_verify_test, &req);
648 	CU_ASSERT_EQUAL(g_completion_success, true);
649 
650 	free_dif_verify_bufs(task);
651 }
652 
653 static void
654 accel_dix_generate_verify(struct accel_dif_request *req,
655 			  uint32_t dif_flags_generate, uint32_t dif_flags_verify)
656 {
657 	struct spdk_dif_ctx_init_ext_opts dif_opts;
658 	struct dif_task *task = &g_dif_task;
659 	int rc;
660 
661 	rc = alloc_dix_bufs(task, 1);
662 	SPDK_CU_ASSERT_FATAL(rc == 0);
663 
664 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
665 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
666 
667 	rc = spdk_dif_ctx_init(&task->dif_ctx,
668 			       g_block_size_bytes,
669 			       g_md_size_bytes, false, true,
670 			       SPDK_DIF_TYPE1,
671 			       dif_flags_generate,
672 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
673 	SPDK_CU_ASSERT_FATAL(rc == 0);
674 
675 	rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks,
676 			       &task->dif_ctx);
677 	SPDK_CU_ASSERT_FATAL(rc == 0);
678 
679 	rc = spdk_dif_ctx_init(&task->dif_ctx,
680 			       g_block_size_bytes,
681 			       g_md_size_bytes, false, true,
682 			       SPDK_DIF_TYPE1,
683 			       dif_flags_verify,
684 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
685 	SPDK_CU_ASSERT_FATAL(rc == 0);
686 
687 	req->channel = g_channel;
688 	req->src_iovs = task->src_iovs;
689 	req->src_iovcnt = task->src_iovcnt;
690 	req->md_iov = &task->md_iov;
691 	req->num_blocks = task->num_blocks;
692 	req->ctx = &task->dif_ctx;
693 	req->err = &task->dif_err;
694 	req->cb_fn = accel_dif_oper_done;
695 	req->cb_arg = task;
696 
697 	execute_spdk_function(accel_dix_verify_test, req);
698 
699 	free_dix_bufs(task);
700 }
701 
702 static void
703 accel_dif_verify_op_dif_generated_guard_check(void)
704 {
705 	accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
706 }
707 
708 static void
709 accel_dif_verify_op_dif_generated_apptag_check(void)
710 {
711 	accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
712 }
713 
714 static void
715 accel_dif_verify_op_dif_generated_reftag_check(void)
716 {
717 	accel_dif_verify_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
718 }
719 
720 static void
721 accel_dix_verify_op_dix_generated_guard_check(void)
722 {
723 	struct accel_dif_request req;
724 	const char *module_name = NULL;
725 	int rc;
726 
727 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
728 	SPDK_CU_ASSERT_FATAL(rc == 0);
729 
730 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
731 	if (!strcmp(module_name, "dsa")) {
732 		return;
733 	}
734 
735 	accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK |
736 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
737 				  SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_FLAGS_GUARD_CHECK);
738 
739 	CU_ASSERT_EQUAL(g_completion_success, true);
740 }
741 
742 static void
743 accel_dix_verify_op_dix_generated_apptag_check(void)
744 {
745 	struct accel_dif_request req;
746 	const char *module_name = NULL;
747 	int rc;
748 
749 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
750 	SPDK_CU_ASSERT_FATAL(rc == 0);
751 
752 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
753 	if (!strcmp(module_name, "dsa")) {
754 		return;
755 	}
756 
757 	accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK |
758 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
759 				  SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_FLAGS_APPTAG_CHECK);
760 
761 	CU_ASSERT_EQUAL(g_completion_success, true);
762 }
763 
764 static void
765 accel_dix_verify_op_dix_generated_reftag_check(void)
766 {
767 	struct accel_dif_request req;
768 	const char *module_name = NULL;
769 	int rc;
770 
771 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
772 	SPDK_CU_ASSERT_FATAL(rc == 0);
773 
774 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
775 	if (!strcmp(module_name, "dsa")) {
776 		return;
777 	}
778 
779 	accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK |
780 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
781 				  SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_FLAGS_REFTAG_CHECK);
782 
783 	CU_ASSERT_EQUAL(g_completion_success, true);
784 }
785 
786 static void
787 accel_dix_verify_op_dix_generated_all_flags_check(void)
788 {
789 	struct accel_dif_request req;
790 	accel_dix_generate_verify(&req, SPDK_DIF_FLAGS_GUARD_CHECK |
791 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
792 				  SPDK_DIF_FLAGS_REFTAG_CHECK,
793 				  SPDK_DIF_FLAGS_GUARD_CHECK |
794 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
795 				  SPDK_DIF_FLAGS_REFTAG_CHECK);
796 
797 	CU_ASSERT_EQUAL(g_completion_success, true);
798 }
799 
800 static void
801 accel_dix_verify_op_dix_not_generated_all_flags_check(void)
802 {
803 	struct accel_dif_request req;
804 	accel_dix_generate_verify(&req, 0,
805 				  SPDK_DIF_FLAGS_GUARD_CHECK |
806 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
807 				  SPDK_DIF_FLAGS_REFTAG_CHECK);
808 
809 	CU_ASSERT_EQUAL(g_completion_success, false);
810 }
811 
812 static void
813 accel_dif_verify_op_dif_not_generated_do_check(uint32_t dif_flags)
814 {
815 	struct spdk_dif_ctx_init_ext_opts dif_opts;
816 	struct accel_dif_request req;
817 	struct dif_task *task = &g_dif_task;
818 	int rc;
819 
820 	rc = alloc_dif_verify_bufs(task, 1);
821 	SPDK_CU_ASSERT_FATAL(rc == 0);
822 
823 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
824 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
825 
826 	rc = spdk_dif_ctx_init(&task->dif_ctx,
827 			       g_block_size_bytes + g_md_size_bytes,
828 			       g_md_size_bytes, true, true,
829 			       SPDK_DIF_TYPE1,
830 			       dif_flags,
831 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
832 	SPDK_CU_ASSERT_FATAL(rc == 0);
833 
834 	req.channel = g_channel;
835 	req.src_iovs = task->src_iovs;
836 	req.src_iovcnt = task->src_iovcnt;
837 	req.num_blocks = task->num_blocks;
838 	req.ctx = &task->dif_ctx;
839 	req.err = &task->dif_err;
840 	req.cb_fn = accel_dif_oper_done;
841 	req.cb_arg = task;
842 
843 	execute_spdk_function(accel_dif_verify_test, &req);
844 	CU_ASSERT_EQUAL(g_completion_success, false);
845 	CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags, req.err), true);
846 
847 	free_dif_verify_bufs(task);
848 }
849 
850 static void
851 accel_dif_verify_op_dif_not_generated_guard_check(void)
852 {
853 	accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
854 }
855 
856 static void
857 accel_dix_verify_op_dix_not_generated_guard_check(void)
858 {
859 	const char *module_name = NULL;
860 	uint32_t dif_flags_verify = SPDK_DIF_FLAGS_GUARD_CHECK;
861 	struct accel_dif_request req;
862 	int rc;
863 
864 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
865 	SPDK_CU_ASSERT_FATAL(rc == 0);
866 
867 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
868 	if (!strcmp(module_name, "dsa")) {
869 		return;
870 	}
871 
872 	accel_dix_generate_verify(&req, 0, dif_flags_verify);
873 
874 	CU_ASSERT_EQUAL(g_completion_success, false);
875 	CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags_verify, req.err), true);
876 }
877 
878 static void
879 accel_dif_verify_op_dif_not_generated_apptag_check(void)
880 {
881 	accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
882 }
883 
884 static void
885 accel_dix_verify_op_dix_not_generated_apptag_check(void)
886 {
887 	const char *module_name = NULL;
888 	uint32_t dif_flags_verify = SPDK_DIF_FLAGS_APPTAG_CHECK;
889 	struct accel_dif_request req;
890 	int rc;
891 
892 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
893 	SPDK_CU_ASSERT_FATAL(rc == 0);
894 
895 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
896 	if (!strcmp(module_name, "dsa")) {
897 		return;
898 	}
899 
900 	accel_dix_generate_verify(&req, 0, dif_flags_verify);
901 
902 	CU_ASSERT_EQUAL(g_completion_success, false);
903 	CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags_verify, req.err), true);
904 }
905 
906 static void
907 accel_dif_verify_op_dif_not_generated_reftag_check(void)
908 {
909 	accel_dif_verify_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
910 }
911 
912 static void
913 accel_dix_verify_op_dix_not_generated_reftag_check(void)
914 {
915 	const char *module_name = NULL;
916 	uint32_t dif_flags_verify = SPDK_DIF_FLAGS_REFTAG_CHECK;
917 	struct accel_dif_request req;
918 	int rc;
919 
920 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
921 	SPDK_CU_ASSERT_FATAL(rc == 0);
922 
923 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
924 	if (!strcmp(module_name, "dsa")) {
925 		return;
926 	}
927 
928 	accel_dix_generate_verify(&req, 0, dif_flags_verify);
929 
930 	CU_ASSERT_EQUAL(g_completion_success, false);
931 	CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags_verify, req.err), true);
932 }
933 
934 static void
935 accel_dix_verify_op_dix_guard_not_generated_all_flags_check(void)
936 {
937 	struct accel_dif_request req;
938 	accel_dix_generate_verify(&req,
939 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
940 				  SPDK_DIF_FLAGS_REFTAG_CHECK,
941 				  SPDK_DIF_FLAGS_GUARD_CHECK |
942 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
943 				  SPDK_DIF_FLAGS_REFTAG_CHECK);
944 
945 	CU_ASSERT_EQUAL(g_completion_success, false);
946 	CU_ASSERT_EQUAL(accel_dif_error_validate(SPDK_DIF_FLAGS_GUARD_CHECK, req.err), true);
947 }
948 
949 static void
950 accel_dix_verify_op_dix_apptag_not_generated_all_flags_check(void)
951 {
952 	struct accel_dif_request req;
953 	accel_dix_generate_verify(&req,
954 				  SPDK_DIF_FLAGS_GUARD_CHECK |
955 				  SPDK_DIF_FLAGS_REFTAG_CHECK,
956 				  SPDK_DIF_FLAGS_GUARD_CHECK |
957 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
958 				  SPDK_DIF_FLAGS_REFTAG_CHECK);
959 
960 	CU_ASSERT_EQUAL(g_completion_success, false);
961 	CU_ASSERT_EQUAL(accel_dif_error_validate(SPDK_DIF_FLAGS_APPTAG_CHECK, req.err), true);
962 }
963 
964 static void
965 accel_dix_verify_op_dix_reftag_not_generated_all_flags_check(void)
966 {
967 	struct accel_dif_request req;
968 	accel_dix_generate_verify(&req,
969 				  SPDK_DIF_FLAGS_GUARD_CHECK |
970 				  SPDK_DIF_FLAGS_APPTAG_CHECK,
971 				  SPDK_DIF_FLAGS_GUARD_CHECK |
972 				  SPDK_DIF_FLAGS_APPTAG_CHECK |
973 				  SPDK_DIF_FLAGS_REFTAG_CHECK);
974 
975 	CU_ASSERT_EQUAL(g_completion_success, false);
976 	CU_ASSERT_EQUAL(accel_dif_error_validate(SPDK_DIF_FLAGS_REFTAG_CHECK, req.err), true);
977 }
978 
979 static void
980 accel_dif_verify_op_apptag_correct_apptag_check(void)
981 {
982 	struct spdk_dif_ctx_init_ext_opts dif_opts;
983 	struct accel_dif_request req;
984 	struct dif_task *task = &g_dif_task;
985 	int rc;
986 
987 	rc = alloc_dif_verify_bufs(task, 1);
988 	SPDK_CU_ASSERT_FATAL(rc == 0);
989 
990 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
991 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
992 
993 	rc = spdk_dif_ctx_init(&task->dif_ctx,
994 			       g_block_size_bytes + g_md_size_bytes,
995 			       g_md_size_bytes, true, true,
996 			       SPDK_DIF_TYPE1,
997 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
998 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
999 	SPDK_CU_ASSERT_FATAL(rc == 0);
1000 
1001 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
1002 	SPDK_CU_ASSERT_FATAL(rc == 0);
1003 
1004 	req.channel = g_channel;
1005 	req.src_iovs = task->src_iovs;
1006 	req.src_iovcnt = task->src_iovcnt;
1007 	req.num_blocks = task->num_blocks;
1008 	req.ctx = &task->dif_ctx;
1009 	req.err = &task->dif_err;
1010 	req.cb_fn = accel_dif_oper_done;
1011 	req.cb_arg = task;
1012 
1013 	execute_spdk_function(accel_dif_verify_test, &req);
1014 	CU_ASSERT_EQUAL(g_completion_success, true);
1015 
1016 	free_dif_verify_bufs(task);
1017 }
1018 
1019 static void
1020 accel_dix_verify_op_apptag_correct_apptag_check(void)
1021 {
1022 	const char *module_name = NULL;
1023 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1024 	struct accel_dif_request req;
1025 	struct dif_task *task = &g_dif_task;
1026 	int rc;
1027 
1028 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
1029 	SPDK_CU_ASSERT_FATAL(rc == 0);
1030 
1031 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
1032 	if (!strcmp(module_name, "dsa")) {
1033 		return;
1034 	}
1035 
1036 	rc = alloc_dix_bufs(task, 1);
1037 	SPDK_CU_ASSERT_FATAL(rc == 0);
1038 
1039 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1040 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1041 
1042 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1043 			       g_block_size_bytes,
1044 			       g_md_size_bytes, false, true,
1045 			       SPDK_DIF_TYPE1,
1046 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
1047 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1048 	SPDK_CU_ASSERT_FATAL(rc == 0);
1049 
1050 	rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks,
1051 			       &task->dif_ctx);
1052 	SPDK_CU_ASSERT_FATAL(rc == 0);
1053 
1054 	req.channel = g_channel;
1055 	req.src_iovs = task->src_iovs;
1056 	req.src_iovcnt = task->src_iovcnt;
1057 	req.md_iov = &task->md_iov;
1058 	req.num_blocks = task->num_blocks;
1059 	req.ctx = &task->dif_ctx;
1060 	req.err = &task->dif_err;
1061 	req.cb_fn = accel_dif_oper_done;
1062 	req.cb_arg = task;
1063 
1064 	execute_spdk_function(accel_dix_verify_test, &req);
1065 
1066 	CU_ASSERT_EQUAL(g_completion_success, true);
1067 
1068 	free_dix_bufs(task);
1069 }
1070 
1071 static void
1072 accel_dif_verify_op_apptag_incorrect_apptag_check(void)
1073 {
1074 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1075 	struct accel_dif_request req;
1076 	struct dif_task *task = &g_dif_task;
1077 	int rc;
1078 
1079 	rc = alloc_dif_verify_bufs(task, 1);
1080 	SPDK_CU_ASSERT_FATAL(rc == 0);
1081 
1082 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1083 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1084 
1085 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1086 			       g_block_size_bytes + g_md_size_bytes,
1087 			       g_md_size_bytes, true, true,
1088 			       SPDK_DIF_TYPE1,
1089 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
1090 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1091 	SPDK_CU_ASSERT_FATAL(rc == 0);
1092 
1093 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
1094 	SPDK_CU_ASSERT_FATAL(rc == 0);
1095 
1096 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1097 			       g_block_size_bytes + g_md_size_bytes,
1098 			       g_md_size_bytes, true, true,
1099 			       SPDK_DIF_TYPE1,
1100 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
1101 			       30, 0xFFFF, 40, 0, 0, &dif_opts);
1102 	SPDK_CU_ASSERT_FATAL(rc == 0);
1103 
1104 	req.channel = g_channel;
1105 	req.src_iovs = task->src_iovs;
1106 	req.src_iovcnt = task->src_iovcnt;
1107 	req.num_blocks = task->num_blocks;
1108 	req.ctx = &task->dif_ctx;
1109 	req.err = &task->dif_err;
1110 	req.cb_fn = accel_dif_oper_done;
1111 	req.cb_arg = task;
1112 
1113 	execute_spdk_function(accel_dif_verify_test, &req);
1114 	CU_ASSERT_EQUAL(g_completion_success, false);
1115 
1116 	free_dif_verify_bufs(task);
1117 }
1118 
1119 static void
1120 accel_dix_verify_op_apptag_incorrect_apptag_check(void)
1121 {
1122 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1123 	struct accel_dif_request req;
1124 	struct dif_task *task = &g_dif_task;
1125 	int rc;
1126 
1127 	rc = alloc_dix_bufs(task, 1);
1128 	SPDK_CU_ASSERT_FATAL(rc == 0);
1129 
1130 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1131 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1132 
1133 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1134 			       g_block_size_bytes,
1135 			       g_md_size_bytes, false, true,
1136 			       SPDK_DIF_TYPE1,
1137 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
1138 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1139 	SPDK_CU_ASSERT_FATAL(rc == 0);
1140 
1141 	rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks,
1142 			       &task->dif_ctx);
1143 	SPDK_CU_ASSERT_FATAL(rc == 0);
1144 
1145 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1146 			       g_block_size_bytes,
1147 			       g_md_size_bytes, false, true,
1148 			       SPDK_DIF_TYPE1,
1149 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
1150 			       30, 0xFFFF, 40, 0, 0, &dif_opts);
1151 	SPDK_CU_ASSERT_FATAL(rc == 0);
1152 
1153 	req.channel = g_channel;
1154 	req.src_iovs = task->src_iovs;
1155 	req.src_iovcnt = task->src_iovcnt;
1156 	req.md_iov = &task->md_iov;
1157 	req.num_blocks = task->num_blocks;
1158 	req.ctx = &task->dif_ctx;
1159 	req.err = &task->dif_err;
1160 	req.cb_fn = accel_dif_oper_done;
1161 	req.cb_arg = task;
1162 
1163 	execute_spdk_function(accel_dix_verify_test, &req);
1164 	CU_ASSERT_EQUAL(g_completion_success, false);
1165 
1166 	free_dix_bufs(task);
1167 }
1168 
1169 static void
1170 accel_dif_verify_op_tag_incorrect_no_check_or_ignore(uint32_t dif_flags)
1171 {
1172 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1173 	struct accel_dif_request req;
1174 	struct dif_task *task = &g_dif_task;
1175 	int rc;
1176 
1177 	rc = alloc_dif_verify_bufs(task, 1);
1178 	SPDK_CU_ASSERT_FATAL(rc == 0);
1179 
1180 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1181 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1182 
1183 	/* For set 'Application Tag F Detect' (Source DIF Flags)
1184 	 * When all bits of the Application Tag field of the source Data Integrity Field
1185 	 * are equal to 1, the Application Tag check is not done and the Guard field and
1186 	 * Reference Tag field are ignored. */
1187 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1188 			       g_block_size_bytes + g_md_size_bytes,
1189 			       g_md_size_bytes, true, true,
1190 			       SPDK_DIF_TYPE1,
1191 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1192 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1193 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1194 			       10, 0xFFFF, 0xFFFF, 0, 0, &dif_opts);
1195 	SPDK_CU_ASSERT_FATAL(rc == 0);
1196 
1197 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
1198 	SPDK_CU_ASSERT_FATAL(rc == 0);
1199 
1200 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1201 			       g_block_size_bytes + g_md_size_bytes,
1202 			       g_md_size_bytes, true, true,
1203 			       SPDK_DIF_TYPE1,
1204 			       dif_flags,
1205 			       30, 0xFFFF, 40, 0, 0, &dif_opts);
1206 	SPDK_CU_ASSERT_FATAL(rc == 0);
1207 
1208 	req.channel = g_channel;
1209 	req.src_iovs = task->src_iovs;
1210 	req.src_iovcnt = task->src_iovcnt;
1211 	req.num_blocks = task->num_blocks;
1212 	req.ctx = &task->dif_ctx;
1213 	req.err = &task->dif_err;
1214 	req.cb_fn = accel_dif_oper_done;
1215 	req.cb_arg = task;
1216 
1217 	execute_spdk_function(accel_dif_verify_test, &req);
1218 	CU_ASSERT_EQUAL(g_completion_success, true);
1219 
1220 	free_dif_verify_bufs(task);
1221 }
1222 
1223 static void
1224 accel_dix_verify_op_tag_incorrect_no_check_or_ignore(uint32_t dif_flags)
1225 {
1226 	const char *module_name = NULL;
1227 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1228 	struct accel_dif_request req;
1229 	struct dif_task *task = &g_dif_task;
1230 	int rc;
1231 
1232 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
1233 	SPDK_CU_ASSERT_FATAL(rc == 0);
1234 
1235 	/* Intel DSA does not allow for selective DIF fields verify for DIX */
1236 	if (!strcmp(module_name, "dsa") && (dif_flags != (SPDK_DIF_FLAGS_GUARD_CHECK |
1237 					    SPDK_DIF_FLAGS_APPTAG_CHECK |
1238 					    SPDK_DIF_FLAGS_REFTAG_CHECK))) {
1239 		return;
1240 	}
1241 
1242 	rc = alloc_dix_bufs(task, 1);
1243 	SPDK_CU_ASSERT_FATAL(rc == 0);
1244 
1245 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1246 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1247 
1248 	/* For set 'Application Tag F Detect' (Source DIF Flags)
1249 	 * When all bits of the Application Tag field of the source Data Integrity Field
1250 	 * are equal to 1, the Application Tag check is not done and the Guard field and
1251 	 * Reference Tag field are ignored. */
1252 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1253 			       g_block_size_bytes,
1254 			       g_md_size_bytes, false, true,
1255 			       SPDK_DIF_TYPE1,
1256 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1257 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1258 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1259 			       10, 0xFFFF, 0xFFFF, 0, 0, &dif_opts);
1260 	SPDK_CU_ASSERT_FATAL(rc == 0);
1261 
1262 	rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks,
1263 			       &task->dif_ctx);
1264 	SPDK_CU_ASSERT_FATAL(rc == 0);
1265 
1266 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1267 			       g_block_size_bytes,
1268 			       g_md_size_bytes, false, true,
1269 			       SPDK_DIF_TYPE1,
1270 			       dif_flags,
1271 			       30, 0xFFFF, 40, 0, 0, &dif_opts);
1272 	SPDK_CU_ASSERT_FATAL(rc == 0);
1273 
1274 	req.channel = g_channel;
1275 	req.src_iovs = task->src_iovs;
1276 	req.src_iovcnt = task->src_iovcnt;
1277 	req.md_iov = &task->md_iov;
1278 	req.num_blocks = task->num_blocks;
1279 	req.ctx = &task->dif_ctx;
1280 	req.err = &task->dif_err;
1281 	req.cb_fn = accel_dif_oper_done;
1282 	req.cb_arg = task;
1283 
1284 	execute_spdk_function(accel_dix_verify_test, &req);
1285 
1286 	CU_ASSERT_EQUAL(g_completion_success, true);
1287 
1288 	free_dix_bufs(task);
1289 }
1290 
1291 static void
1292 accel_dif_verify_op_apptag_incorrect_no_apptag_check(void)
1293 {
1294 	accel_dif_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_APPTAG_CHECK);
1295 }
1296 
1297 static void
1298 accel_dix_verify_op_apptag_incorrect_no_apptag_check(void)
1299 {
1300 	accel_dix_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_APPTAG_CHECK);
1301 }
1302 
1303 static void
1304 accel_dif_verify_op_reftag_incorrect_reftag_ignore(void)
1305 {
1306 	accel_dif_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_REFTAG_CHECK);
1307 }
1308 
1309 static void
1310 accel_dix_verify_op_reftag_incorrect_reftag_ignore(void)
1311 {
1312 	accel_dix_verify_op_tag_incorrect_no_check_or_ignore(SPDK_DIF_FLAGS_REFTAG_CHECK);
1313 }
1314 
1315 static void
1316 accel_dif_verify_op_reftag_init_correct_reftag_check(void)
1317 {
1318 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1319 	struct accel_dif_request req;
1320 	struct dif_task *task = &g_dif_task;
1321 	int rc;
1322 
1323 	rc = alloc_dif_verify_bufs(task, 2);
1324 	SPDK_CU_ASSERT_FATAL(rc == 0);
1325 
1326 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1327 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1328 
1329 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1330 			       g_block_size_bytes + g_md_size_bytes,
1331 			       g_md_size_bytes, true, true,
1332 			       SPDK_DIF_TYPE1,
1333 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1334 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1335 	SPDK_CU_ASSERT_FATAL(rc == 0);
1336 
1337 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
1338 	SPDK_CU_ASSERT_FATAL(rc == 0);
1339 
1340 	req.channel = g_channel;
1341 	req.src_iovs = task->src_iovs;
1342 	req.src_iovcnt = task->src_iovcnt;
1343 	req.num_blocks = task->num_blocks;
1344 	req.ctx = &task->dif_ctx;
1345 	req.err = &task->dif_err;
1346 	req.cb_fn = accel_dif_oper_done;
1347 	req.cb_arg = task;
1348 
1349 	execute_spdk_function(accel_dif_verify_test, &req);
1350 	CU_ASSERT_EQUAL(g_completion_success, true);
1351 
1352 	free_dif_verify_bufs(task);
1353 }
1354 
1355 static void
1356 accel_dix_verify_op_reftag_init_correct_reftag_check(void)
1357 {
1358 	const char *module_name = NULL;
1359 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1360 	struct accel_dif_request req;
1361 	struct dif_task *task = &g_dif_task;
1362 	int rc;
1363 
1364 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIX_VERIFY, &module_name);
1365 	SPDK_CU_ASSERT_FATAL(rc == 0);
1366 
1367 	/* Intel DSA does not allow for selective DIF fields verification for DIX */
1368 	if (!strcmp(module_name, "dsa")) {
1369 		return;
1370 	}
1371 
1372 	rc = alloc_dix_bufs(task, 2);
1373 	SPDK_CU_ASSERT_FATAL(rc == 0);
1374 
1375 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1376 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1377 
1378 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1379 			       g_block_size_bytes,
1380 			       g_md_size_bytes, false, true,
1381 			       SPDK_DIF_TYPE1,
1382 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1383 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1384 	SPDK_CU_ASSERT_FATAL(rc == 0);
1385 
1386 	rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks,
1387 			       &task->dif_ctx);
1388 	SPDK_CU_ASSERT_FATAL(rc == 0);
1389 
1390 	req.channel = g_channel;
1391 	req.src_iovs = task->src_iovs;
1392 	req.src_iovcnt = task->src_iovcnt;
1393 	req.md_iov = &task->md_iov;
1394 	req.num_blocks = task->num_blocks;
1395 	req.ctx = &task->dif_ctx;
1396 	req.err = &task->dif_err;
1397 	req.cb_fn = accel_dif_oper_done;
1398 	req.cb_arg = task;
1399 
1400 	execute_spdk_function(accel_dix_verify_test, &req);
1401 
1402 	CU_ASSERT_EQUAL(g_completion_success, true);
1403 
1404 	free_dix_bufs(task);
1405 }
1406 
1407 static void
1408 accel_dif_verify_op_reftag_init_incorrect_reftag_check(void)
1409 {
1410 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1411 	struct accel_dif_request req;
1412 	struct dif_task *task = &g_dif_task;
1413 	int rc;
1414 
1415 	rc = alloc_dif_verify_bufs(task, 2);
1416 	SPDK_CU_ASSERT_FATAL(rc == 0);
1417 
1418 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1419 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1420 
1421 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1422 			       g_block_size_bytes + g_md_size_bytes,
1423 			       g_md_size_bytes, true, true,
1424 			       SPDK_DIF_TYPE1,
1425 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1426 			       16, 0xFFFF, 20, 0, 0, &dif_opts);
1427 	SPDK_CU_ASSERT_FATAL(rc == 0);
1428 
1429 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
1430 	SPDK_CU_ASSERT_FATAL(rc == 0);
1431 
1432 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1433 			       g_block_size_bytes + g_md_size_bytes,
1434 			       g_md_size_bytes, true, true,
1435 			       SPDK_DIF_TYPE1,
1436 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1437 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1438 	SPDK_CU_ASSERT_FATAL(rc == 0);
1439 
1440 	req.channel = g_channel;
1441 	req.src_iovs = task->src_iovs;
1442 	req.src_iovcnt = task->src_iovcnt;
1443 	req.num_blocks = task->num_blocks;
1444 	req.ctx = &task->dif_ctx;
1445 	req.err = &task->dif_err;
1446 	req.cb_fn = accel_dif_oper_done;
1447 	req.cb_arg = task;
1448 
1449 	execute_spdk_function(accel_dif_verify_test, &req);
1450 	CU_ASSERT_EQUAL(g_completion_success, false);
1451 
1452 	free_dif_verify_bufs(task);
1453 }
1454 
1455 static void
1456 accel_dix_verify_op_reftag_init_incorrect_reftag_check(void)
1457 {
1458 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1459 	struct accel_dif_request req;
1460 	struct dif_task *task = &g_dif_task;
1461 	int rc;
1462 
1463 	rc = alloc_dix_bufs(task, 2);
1464 	SPDK_CU_ASSERT_FATAL(rc == 0);
1465 
1466 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1467 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1468 
1469 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1470 			       g_block_size_bytes,
1471 			       g_md_size_bytes, false, true,
1472 			       SPDK_DIF_TYPE1,
1473 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1474 			       16, 0xFFFF, 20, 0, 0, &dif_opts);
1475 	SPDK_CU_ASSERT_FATAL(rc == 0);
1476 
1477 	rc = spdk_dix_generate(task->src_iovs, task->src_iovcnt, &task->md_iov, task->num_blocks,
1478 			       &task->dif_ctx);
1479 	SPDK_CU_ASSERT_FATAL(rc == 0);
1480 
1481 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1482 			       g_block_size_bytes,
1483 			       g_md_size_bytes, false, true,
1484 			       SPDK_DIF_TYPE1,
1485 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1486 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1487 	SPDK_CU_ASSERT_FATAL(rc == 0);
1488 
1489 	req.channel = g_channel;
1490 	req.src_iovs = task->src_iovs;
1491 	req.src_iovcnt = task->src_iovcnt;
1492 	req.md_iov = &task->md_iov;
1493 	req.num_blocks = task->num_blocks;
1494 	req.ctx = &task->dif_ctx;
1495 	req.err = &task->dif_err;
1496 	req.cb_fn = accel_dif_oper_done;
1497 	req.cb_arg = task;
1498 
1499 	execute_spdk_function(accel_dix_verify_test, &req);
1500 	CU_ASSERT_EQUAL(g_completion_success, false);
1501 
1502 	free_dix_bufs(task);
1503 }
1504 
1505 static void
1506 accel_dif_verify_copy_op_dif_generated_do_check(uint32_t dif_flags)
1507 {
1508 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1509 	struct accel_dif_request req;
1510 	struct dif_task *task = &g_dif_task;
1511 	int rc;
1512 
1513 	rc = alloc_dif_verify_copy_bufs(task, 1);
1514 	SPDK_CU_ASSERT_FATAL(rc == 0);
1515 
1516 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1517 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1518 
1519 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1520 			       g_block_size_bytes + g_md_size_bytes,
1521 			       g_md_size_bytes, true, true,
1522 			       SPDK_DIF_TYPE1,
1523 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1524 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1525 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1526 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1527 	SPDK_CU_ASSERT_FATAL(rc == 0);
1528 
1529 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
1530 	SPDK_CU_ASSERT_FATAL(rc == 0);
1531 
1532 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1533 			       g_block_size_bytes + g_md_size_bytes,
1534 			       g_md_size_bytes, true, true,
1535 			       SPDK_DIF_TYPE1,
1536 			       dif_flags,
1537 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1538 	SPDK_CU_ASSERT_FATAL(rc == 0);
1539 
1540 	req.channel = g_channel;
1541 	req.dst_iovs = task->dst_iovs;
1542 	req.dst_iovcnt = task->dst_iovcnt;
1543 	req.src_iovs = task->src_iovs;
1544 	req.src_iovcnt = task->src_iovcnt;
1545 	req.num_blocks = task->num_blocks;
1546 	req.ctx = &task->dif_ctx;
1547 	req.err = &task->dif_err;
1548 	req.cb_fn = accel_dif_oper_done;
1549 	req.cb_arg = task;
1550 
1551 	execute_spdk_function(accel_dif_verify_copy_test, &req);
1552 	CU_ASSERT_EQUAL(g_completion_success, true);
1553 
1554 	free_dif_verify_copy_bufs(task);
1555 }
1556 
1557 static void
1558 accel_dif_verify_copy_op_dif_generated_guard_check(void)
1559 {
1560 	accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
1561 }
1562 
1563 static void
1564 accel_dif_verify_copy_op_dif_generated_apptag_check(void)
1565 {
1566 	accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
1567 }
1568 
1569 static void
1570 accel_dif_verify_copy_op_dif_generated_reftag_check(void)
1571 {
1572 	accel_dif_verify_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
1573 }
1574 
1575 static void
1576 accel_dif_verify_copy_op_dif_not_generated_do_check(uint32_t dif_flags)
1577 {
1578 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1579 	struct accel_dif_request req;
1580 	struct dif_task *task = &g_dif_task;
1581 	int rc;
1582 
1583 	rc = alloc_dif_verify_copy_bufs(task, 1);
1584 	SPDK_CU_ASSERT_FATAL(rc == 0);
1585 
1586 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1587 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1588 
1589 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1590 			       g_block_size_bytes + g_md_size_bytes,
1591 			       g_md_size_bytes, true, true,
1592 			       SPDK_DIF_TYPE1,
1593 			       dif_flags,
1594 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1595 	SPDK_CU_ASSERT_FATAL(rc == 0);
1596 
1597 	req.channel = g_channel;
1598 	req.dst_iovs = task->dst_iovs;
1599 	req.dst_iovcnt = task->dst_iovcnt;
1600 	req.src_iovs = task->src_iovs;
1601 	req.src_iovcnt = task->src_iovcnt;
1602 	req.num_blocks = task->num_blocks;
1603 	req.ctx = &task->dif_ctx;
1604 	req.err = &task->dif_err;
1605 	req.cb_fn = accel_dif_oper_done;
1606 	req.cb_arg = task;
1607 
1608 	execute_spdk_function(accel_dif_verify_copy_test, &req);
1609 	CU_ASSERT_EQUAL(g_completion_success, false);
1610 	CU_ASSERT_EQUAL(accel_dif_error_validate(dif_flags, req.err), true);
1611 
1612 	free_dif_verify_copy_bufs(task);
1613 }
1614 
1615 static void
1616 accel_dif_verify_copy_op_dif_not_generated_guard_check(void)
1617 {
1618 	accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
1619 }
1620 
1621 static void
1622 accel_dif_verify_copy_op_dif_not_generated_apptag_check(void)
1623 {
1624 	accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
1625 }
1626 
1627 static void
1628 accel_dif_verify_copy_op_dif_not_generated_reftag_check(void)
1629 {
1630 	accel_dif_verify_copy_op_dif_not_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
1631 }
1632 
1633 static void
1634 accel_dif_generate_copy_op_dif_generated_do_check(uint32_t dif_flags)
1635 {
1636 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1637 	struct accel_dif_request req;
1638 	struct dif_task *task = &g_dif_task;
1639 	struct spdk_dif_error err_blk;
1640 	int rc;
1641 
1642 	rc = alloc_dif_generate_copy_bufs(task, 1);
1643 	SPDK_CU_ASSERT_FATAL(rc == 0);
1644 
1645 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1646 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1647 
1648 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1649 			       g_block_size_bytes + g_md_size_bytes,
1650 			       g_md_size_bytes, true, true,
1651 			       SPDK_DIF_TYPE1,
1652 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1653 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1654 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1655 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1656 	SPDK_CU_ASSERT_FATAL(rc == 0);
1657 
1658 	req.channel = g_channel;
1659 	req.dst_iovs = task->dst_iovs;
1660 	req.dst_iovcnt = task->dst_iovcnt;
1661 	req.src_iovs = task->src_iovs;
1662 	req.src_iovcnt = task->src_iovcnt;
1663 	req.num_blocks = task->num_blocks;
1664 	req.ctx = &task->dif_ctx;
1665 	req.err = &task->dif_err;
1666 	req.cb_fn = accel_dif_oper_done;
1667 	req.cb_arg = task;
1668 
1669 	execute_spdk_function(accel_dif_generate_copy_test, &req);
1670 	CU_ASSERT_EQUAL(g_completion_success, true);
1671 
1672 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1673 			       g_block_size_bytes + g_md_size_bytes,
1674 			       g_md_size_bytes, true, true,
1675 			       SPDK_DIF_TYPE1,
1676 			       dif_flags,
1677 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1678 	SPDK_CU_ASSERT_FATAL(rc == 0);
1679 
1680 	rc = spdk_dif_verify(req.dst_iovs, req.dst_iovcnt, req.num_blocks,
1681 			     &task->dif_ctx, &err_blk);
1682 	SPDK_CU_ASSERT_FATAL(rc == 0);
1683 
1684 	free_dif_generate_copy_bufs(task);
1685 }
1686 
1687 static void
1688 accel_dix_generate_op_dix_generated_do_check(uint32_t dif_flags)
1689 {
1690 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1691 	struct accel_dif_request req;
1692 	struct dif_task *task = &g_dif_task;
1693 	struct spdk_dif_error err_blk;
1694 	int rc;
1695 
1696 	rc = alloc_dix_bufs(task, 3);
1697 	SPDK_CU_ASSERT_FATAL(rc == 0);
1698 
1699 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1700 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1701 
1702 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1703 			       g_block_size_bytes,
1704 			       g_md_size_bytes, false, true,
1705 			       SPDK_DIF_TYPE1,
1706 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1707 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1708 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1709 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1710 	SPDK_CU_ASSERT_FATAL(rc == 0);
1711 
1712 	req.channel = g_channel;
1713 	req.src_iovs = task->src_iovs;
1714 	req.src_iovcnt = task->src_iovcnt;
1715 	req.md_iov = &task->md_iov;
1716 	req.num_blocks = task->num_blocks;
1717 	req.ctx = &task->dif_ctx;
1718 	req.err = &task->dif_err;
1719 	req.cb_fn = accel_dif_oper_done;
1720 	req.cb_arg = task;
1721 
1722 	execute_spdk_function(accel_dix_generate_test, &req);
1723 	CU_ASSERT_EQUAL(g_completion_success, true);
1724 
1725 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1726 			       g_block_size_bytes,
1727 			       g_md_size_bytes, false, true,
1728 			       SPDK_DIF_TYPE1,
1729 			       dif_flags,
1730 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
1731 	SPDK_CU_ASSERT_FATAL(rc == 0);
1732 
1733 	rc = spdk_dix_verify(req.src_iovs, req.src_iovcnt, req.md_iov, req.num_blocks,
1734 			     &task->dif_ctx, &err_blk);
1735 	CU_ASSERT_EQUAL(rc, 0);
1736 
1737 	free_dix_bufs(task);
1738 }
1739 
1740 static void
1741 accel_dif_generate_copy_op_dif_generated_guard_check(void)
1742 {
1743 	accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
1744 }
1745 
1746 static void
1747 accel_dix_generate_op_dix_generated_guard_check(void)
1748 {
1749 	accel_dix_generate_op_dix_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
1750 }
1751 
1752 static void
1753 accel_dif_generate_copy_op_dif_generated_apptag_check(void)
1754 {
1755 	accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
1756 }
1757 
1758 static void
1759 accel_dix_generate_op_dix_generated_apptag_check(void)
1760 {
1761 	accel_dix_generate_op_dix_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
1762 }
1763 
1764 static void
1765 accel_dif_generate_copy_op_dif_generated_reftag_check(void)
1766 {
1767 	accel_dif_generate_copy_op_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
1768 }
1769 
1770 static void
1771 accel_dix_generate_op_dix_generated_reftag_check(void)
1772 {
1773 	accel_dix_generate_op_dix_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
1774 }
1775 
1776 static void
1777 accel_dif_generate_copy_op_dif_generated_no_guard_check_flag_set(void)
1778 {
1779 	const char *module_name = NULL;
1780 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1781 	struct accel_dif_request req;
1782 	struct dif_task *task = &g_dif_task;
1783 	int rc;
1784 
1785 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name);
1786 	SPDK_CU_ASSERT_FATAL(rc == 0);
1787 
1788 	rc = alloc_dif_generate_copy_bufs(task, 1);
1789 	SPDK_CU_ASSERT_FATAL(rc == 0);
1790 
1791 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1792 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1793 
1794 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1795 			       g_block_size_bytes + g_md_size_bytes,
1796 			       g_md_size_bytes, true, true,
1797 			       SPDK_DIF_TYPE1,
1798 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1799 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1800 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1801 	SPDK_CU_ASSERT_FATAL(rc == 0);
1802 
1803 	req.channel = g_channel;
1804 	req.dst_iovs = task->dst_iovs;
1805 	req.dst_iovcnt = task->dst_iovcnt;
1806 	req.src_iovs = task->src_iovs;
1807 	req.src_iovcnt = task->src_iovcnt;
1808 	req.num_blocks = task->num_blocks;
1809 	req.ctx = &task->dif_ctx;
1810 	req.err = &task->dif_err;
1811 	req.cb_fn = accel_dif_oper_done;
1812 	req.cb_arg = task;
1813 
1814 	execute_spdk_function(accel_dif_generate_copy_test, &req);
1815 
1816 	/* Intel DSA does not allow for selective DIF fields generation */
1817 	if (!strcmp(module_name, "dsa")) {
1818 		CU_ASSERT_EQUAL(g_completion_success, false);
1819 	} else if (!strcmp(module_name, "software")) {
1820 		CU_ASSERT_EQUAL(g_completion_success, true);
1821 	} else {
1822 		SPDK_CU_ASSERT_FATAL(false);
1823 	}
1824 
1825 	free_dif_generate_copy_bufs(task);
1826 }
1827 
1828 static void
1829 accel_dif_generate_copy_op_dif_generated_no_apptag_check_flag_set(void)
1830 {
1831 	const char *module_name = NULL;
1832 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1833 	struct accel_dif_request req;
1834 	struct dif_task *task = &g_dif_task;
1835 	int rc;
1836 
1837 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name);
1838 	SPDK_CU_ASSERT_FATAL(rc == 0);
1839 
1840 	rc = alloc_dif_generate_copy_bufs(task, 1);
1841 	SPDK_CU_ASSERT_FATAL(rc == 0);
1842 
1843 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1844 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1845 
1846 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1847 			       g_block_size_bytes + g_md_size_bytes,
1848 			       g_md_size_bytes, true, true,
1849 			       SPDK_DIF_TYPE1,
1850 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1851 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1852 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1853 	SPDK_CU_ASSERT_FATAL(rc == 0);
1854 
1855 	req.channel = g_channel;
1856 	req.dst_iovs = task->dst_iovs;
1857 	req.dst_iovcnt = task->dst_iovcnt;
1858 	req.src_iovs = task->src_iovs;
1859 	req.src_iovcnt = task->src_iovcnt;
1860 	req.num_blocks = task->num_blocks;
1861 	req.ctx = &task->dif_ctx;
1862 	req.err = &task->dif_err;
1863 	req.cb_fn = accel_dif_oper_done;
1864 	req.cb_arg = task;
1865 
1866 	execute_spdk_function(accel_dif_generate_copy_test, &req);
1867 
1868 	/* Intel DSA does not allow for selective DIF fields generation */
1869 	if (!strcmp(module_name, "dsa")) {
1870 		CU_ASSERT_EQUAL(g_completion_success, false);
1871 	} else if (!strcmp(module_name, "software")) {
1872 		CU_ASSERT_EQUAL(g_completion_success, true);
1873 	} else {
1874 		SPDK_CU_ASSERT_FATAL(false);
1875 	}
1876 
1877 	free_dif_generate_copy_bufs(task);
1878 }
1879 
1880 static void
1881 accel_dif_generate_copy_op_dif_generated_no_reftag_check_flag_set(void)
1882 {
1883 	const char *module_name = NULL;
1884 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1885 	struct accel_dif_request req;
1886 	struct dif_task *task = &g_dif_task;
1887 	int rc;
1888 
1889 	rc = spdk_accel_get_opc_module_name(SPDK_ACCEL_OPC_DIF_GENERATE_COPY, &module_name);
1890 	SPDK_CU_ASSERT_FATAL(rc == 0);
1891 
1892 	rc = alloc_dif_generate_copy_bufs(task, 1);
1893 	SPDK_CU_ASSERT_FATAL(rc == 0);
1894 
1895 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1896 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1897 
1898 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1899 			       g_block_size_bytes + g_md_size_bytes,
1900 			       g_md_size_bytes, true, true,
1901 			       SPDK_DIF_TYPE1,
1902 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1903 			       SPDK_DIF_FLAGS_APPTAG_CHECK,
1904 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1905 	SPDK_CU_ASSERT_FATAL(rc == 0);
1906 
1907 	req.channel = g_channel;
1908 	req.dst_iovs = task->dst_iovs;
1909 	req.dst_iovcnt = task->dst_iovcnt;
1910 	req.src_iovs = task->src_iovs;
1911 	req.src_iovcnt = task->src_iovcnt;
1912 	req.num_blocks = task->num_blocks;
1913 	req.ctx = &task->dif_ctx;
1914 	req.err = &task->dif_err;
1915 	req.cb_fn = accel_dif_oper_done;
1916 	req.cb_arg = task;
1917 
1918 	execute_spdk_function(accel_dif_generate_copy_test, &req);
1919 
1920 	/* Intel DSA does not allow for selective DIF fields generation */
1921 	if (!strcmp(module_name, "dsa")) {
1922 		CU_ASSERT_EQUAL(g_completion_success, false);
1923 	} else if (!strcmp(module_name, "software")) {
1924 		CU_ASSERT_EQUAL(g_completion_success, true);
1925 	} else {
1926 		SPDK_CU_ASSERT_FATAL(false);
1927 	}
1928 
1929 	free_dif_generate_copy_bufs(task);
1930 }
1931 
1932 static void
1933 accel_dif_generate_copy_op_iovecs_len_validate(void)
1934 {
1935 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1936 	struct accel_dif_request req;
1937 	struct dif_task *task = &g_dif_task;
1938 	int rc;
1939 
1940 	rc = alloc_dif_generate_copy_bufs(task, 1);
1941 	SPDK_CU_ASSERT_FATAL(rc == 0);
1942 
1943 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1944 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1945 
1946 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1947 			       g_block_size_bytes + g_md_size_bytes,
1948 			       g_md_size_bytes, true, true,
1949 			       SPDK_DIF_TYPE1,
1950 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1951 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1952 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1953 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1954 	SPDK_CU_ASSERT_FATAL(rc == 0);
1955 
1956 	req.channel = g_channel;
1957 	req.dst_iovs = task->dst_iovs;
1958 	/* Make iov_len param incorrect */
1959 	req.dst_iovs->iov_len -= 16;
1960 	req.dst_iovcnt = task->dst_iovcnt;
1961 	req.src_iovs = task->src_iovs;
1962 	req.src_iovcnt = task->src_iovcnt;
1963 	req.num_blocks = task->num_blocks;
1964 	req.ctx = &task->dif_ctx;
1965 	req.err = &task->dif_err;
1966 	req.cb_fn = accel_dif_oper_done;
1967 	req.cb_arg = task;
1968 
1969 	execute_spdk_function(accel_dif_generate_copy_test, &req);
1970 	CU_ASSERT_EQUAL(g_completion_success, false);
1971 
1972 	free_dif_generate_copy_bufs(task);
1973 }
1974 
1975 static void
1976 accel_dif_generate_copy_op_buf_align_validate(void)
1977 {
1978 	struct spdk_dif_ctx_init_ext_opts dif_opts;
1979 	struct accel_dif_request req;
1980 	struct dif_task *task = &g_dif_task;
1981 	int rc;
1982 
1983 	rc = alloc_dif_generate_copy_bufs(task, 1);
1984 	SPDK_CU_ASSERT_FATAL(rc == 0);
1985 
1986 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1987 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
1988 
1989 	rc = spdk_dif_ctx_init(&task->dif_ctx,
1990 			       g_block_size_bytes + g_md_size_bytes,
1991 			       g_md_size_bytes, true, true,
1992 			       SPDK_DIF_TYPE1,
1993 			       SPDK_DIF_FLAGS_GUARD_CHECK |
1994 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
1995 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
1996 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
1997 	SPDK_CU_ASSERT_FATAL(rc == 0);
1998 
1999 	req.channel = g_channel;
2000 	req.dst_iovs = task->dst_iovs;
2001 	req.dst_iovcnt = task->dst_iovcnt;
2002 	req.src_iovs = task->src_iovs;
2003 	req.src_iovcnt = task->src_iovcnt;
2004 	req.num_blocks = task->num_blocks;
2005 	req.ctx = &task->dif_ctx;
2006 	req.err = &task->dif_err;
2007 	req.cb_fn = accel_dif_oper_done;
2008 	req.cb_arg = task;
2009 
2010 	execute_spdk_function(accel_dif_generate_copy_test, &req);
2011 	CU_ASSERT_EQUAL(g_completion_success, true);
2012 
2013 	free_dif_generate_copy_bufs(task);
2014 }
2015 
2016 static void
2017 accel_dif_generate_copy_sequence_dif_generated_do_check(uint32_t dif_flags)
2018 {
2019 	struct spdk_dif_ctx_init_ext_opts dif_opts;
2020 	struct accel_dif_request req;
2021 	struct dif_task *task = &g_dif_task;
2022 	struct spdk_dif_error err_blk;
2023 	int rc;
2024 
2025 	rc = alloc_dif_generate_copy_sequence_bufs(task, 1);
2026 	SPDK_CU_ASSERT_FATAL(rc == 0);
2027 
2028 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2029 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
2030 
2031 	rc = spdk_dif_ctx_init(&task->dif_ctx,
2032 			       g_block_size_bytes + g_md_size_bytes,
2033 			       g_md_size_bytes, true, true,
2034 			       SPDK_DIF_TYPE1,
2035 			       SPDK_DIF_FLAGS_GUARD_CHECK |
2036 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
2037 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
2038 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
2039 	SPDK_CU_ASSERT_FATAL(rc == 0);
2040 
2041 	req.channel = g_channel;
2042 	req.dst_iovs = task->dst_iovs;
2043 	req.dst_iovcnt = task->dst_iovcnt;
2044 	req.src_iovs = task->src_iovs;
2045 	req.src_iovcnt = task->src_iovcnt;
2046 	req.aux_iovs = task->aux_iovs;
2047 	req.aux_iovcnt = task->aux_iovcnt;
2048 	req.num_blocks = task->num_blocks;
2049 	req.ctx = &task->dif_ctx;
2050 	req.err = &task->dif_err;
2051 	req.cb_fn = accel_dif_oper_done;
2052 	req.cb_arg = task;
2053 
2054 	execute_spdk_function(accel_dif_generate_copy_sequence_test, &req);
2055 	CU_ASSERT_EQUAL(g_completion_success, true);
2056 
2057 	rc = spdk_dif_ctx_init(&task->dif_ctx,
2058 			       g_block_size_bytes + g_md_size_bytes,
2059 			       g_md_size_bytes, true, true,
2060 			       SPDK_DIF_TYPE1,
2061 			       dif_flags,
2062 			       16, 0xFFFF, 10, 0, 0, &dif_opts);
2063 	SPDK_CU_ASSERT_FATAL(rc == 0);
2064 
2065 	rc = spdk_dif_verify(req.dst_iovs, req.dst_iovcnt, req.num_blocks,
2066 			     &task->dif_ctx, &err_blk);
2067 	SPDK_CU_ASSERT_FATAL(rc == 0);
2068 
2069 	free_dif_generate_copy_sequence_bufs(task);
2070 }
2071 
2072 static void
2073 accel_dif_generate_copy_sequence_dif_generated_guard_check(void)
2074 {
2075 	accel_dif_generate_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
2076 }
2077 
2078 static void
2079 accel_dif_generate_copy_sequence_dif_generated_apptag_check(void)
2080 {
2081 	accel_dif_generate_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
2082 }
2083 
2084 static void
2085 accel_dif_generate_copy_sequence_dif_generated_reftag_check(void)
2086 {
2087 	accel_dif_generate_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
2088 }
2089 
2090 static void
2091 accel_dif_verify_copy_sequence_dif_generated_do_check(uint32_t dif_flags)
2092 {
2093 	struct spdk_dif_ctx_init_ext_opts dif_opts;
2094 	struct accel_dif_request req;
2095 	struct dif_task *task = &g_dif_task;
2096 	int rc;
2097 
2098 	rc = alloc_dif_verify_copy_bufs(task, 1);
2099 	SPDK_CU_ASSERT_FATAL(rc == 0);
2100 
2101 	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2102 	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
2103 
2104 	rc = spdk_dif_ctx_init(&task->dif_ctx,
2105 			       g_block_size_bytes + g_md_size_bytes,
2106 			       g_md_size_bytes, true, true,
2107 			       SPDK_DIF_TYPE1,
2108 			       SPDK_DIF_FLAGS_GUARD_CHECK |
2109 			       SPDK_DIF_FLAGS_APPTAG_CHECK |
2110 			       SPDK_DIF_FLAGS_REFTAG_CHECK,
2111 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
2112 	SPDK_CU_ASSERT_FATAL(rc == 0);
2113 
2114 	rc = spdk_dif_generate(task->src_iovs, task->src_iovcnt, task->num_blocks, &task->dif_ctx);
2115 	SPDK_CU_ASSERT_FATAL(rc == 0);
2116 
2117 	rc = spdk_dif_ctx_init(&task->dif_ctx,
2118 			       g_block_size_bytes + g_md_size_bytes,
2119 			       g_md_size_bytes, true, true,
2120 			       SPDK_DIF_TYPE1,
2121 			       dif_flags,
2122 			       10, 0xFFFF, 20, 0, 0, &dif_opts);
2123 	SPDK_CU_ASSERT_FATAL(rc == 0);
2124 
2125 	req.channel = g_channel;
2126 	req.dst_iovs = task->dst_iovs;
2127 	req.dst_iovcnt = task->dst_iovcnt;
2128 	req.src_iovs = task->src_iovs;
2129 	req.src_iovcnt = task->src_iovcnt;
2130 	req.num_blocks = task->num_blocks;
2131 	req.ctx = &task->dif_ctx;
2132 	req.err = &task->dif_err;
2133 	req.cb_fn = accel_dif_oper_done;
2134 	req.cb_arg = task;
2135 
2136 	execute_spdk_function(accel_dif_verify_copy_sequence_test, &req);
2137 	CU_ASSERT_EQUAL(g_completion_success, true);
2138 
2139 	free_dif_verify_copy_bufs(task);
2140 }
2141 
2142 static void
2143 accel_dif_verify_copy_sequence_dif_generated_guard_check(void)
2144 {
2145 	accel_dif_verify_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_GUARD_CHECK);
2146 }
2147 
2148 static void
2149 accel_dif_verify_copy_sequence_dif_generated_apptag_check(void)
2150 {
2151 	accel_dif_verify_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_APPTAG_CHECK);
2152 }
2153 
2154 static void
2155 accel_dif_verify_copy_sequence_dif_generated_reftag_check(void)
2156 {
2157 	accel_dif_verify_copy_sequence_dif_generated_do_check(SPDK_DIF_FLAGS_REFTAG_CHECK);
2158 }
2159 
2160 static void
2161 _stop_init_thread(void *arg)
2162 {
2163 	unsigned num_failures = g_num_failures;
2164 
2165 	g_num_failures = 0;
2166 
2167 	assert(spdk_get_thread() == g_thread[WORKER_UT]);
2168 	assert(spdk_thread_is_app_thread(NULL));
2169 	execute_spdk_function(exit_io_thread, NULL);
2170 	spdk_app_stop(num_failures);
2171 }
2172 
2173 static void
2174 stop_init_thread(unsigned num_failures, struct spdk_jsonrpc_request *request)
2175 {
2176 	g_num_failures = num_failures;
2177 
2178 	spdk_thread_send_msg(g_thread[WORKER_UT], _stop_init_thread, request);
2179 }
2180 
2181 static int
2182 setup_accel_tests(void)
2183 {
2184 	unsigned rc = 0;
2185 	CU_pSuite suite = NULL;
2186 
2187 	suite = CU_add_suite("accel_dif", NULL, NULL);
2188 	if (suite == NULL) {
2189 		CU_cleanup_registry();
2190 		rc = CU_get_error();
2191 		return -rc;
2192 	}
2193 
2194 	if (CU_add_test(suite, "verify: DIF generated, GUARD check",
2195 			accel_dif_verify_op_dif_generated_guard_check) == NULL ||
2196 	    CU_add_test(suite, "verify: DIX generated, GUARD check",
2197 			accel_dix_verify_op_dix_generated_guard_check) == NULL ||
2198 	    CU_add_test(suite, "verify: DIF generated, APPTAG check",
2199 			accel_dif_verify_op_dif_generated_apptag_check) == NULL ||
2200 	    CU_add_test(suite, "verify: DIX generated, APPTAG check",
2201 			accel_dix_verify_op_dix_generated_apptag_check) == NULL ||
2202 	    CU_add_test(suite, "verify: DIF generated, REFTAG check",
2203 			accel_dif_verify_op_dif_generated_reftag_check) == NULL ||
2204 	    CU_add_test(suite, "verify: DIX generated, REFTAG check",
2205 			accel_dix_verify_op_dix_generated_reftag_check) == NULL ||
2206 	    CU_add_test(suite, "verify: DIX generated, all flags check",
2207 			accel_dix_verify_op_dix_generated_all_flags_check) == NULL ||
2208 
2209 	    CU_add_test(suite, "verify: DIF not generated, GUARD check",
2210 			accel_dif_verify_op_dif_not_generated_guard_check) == NULL ||
2211 	    CU_add_test(suite, "verify: DIX not generated, GUARD check",
2212 			accel_dix_verify_op_dix_not_generated_guard_check) == NULL ||
2213 	    CU_add_test(suite, "verify: DIF not generated, APPTAG check",
2214 			accel_dif_verify_op_dif_not_generated_apptag_check) == NULL ||
2215 	    CU_add_test(suite, "verify: DIX not generated, APPTAG check",
2216 			accel_dix_verify_op_dix_not_generated_apptag_check) == NULL ||
2217 	    CU_add_test(suite, "verify: DIF not generated, REFTAG check",
2218 			accel_dif_verify_op_dif_not_generated_reftag_check) == NULL ||
2219 	    CU_add_test(suite, "verify: DIX not generated, REFTAG check",
2220 			accel_dix_verify_op_dix_not_generated_reftag_check) == NULL ||
2221 	    CU_add_test(suite, "verify: DIX not generated, all flags check",
2222 			accel_dix_verify_op_dix_not_generated_all_flags_check) == NULL ||
2223 	    CU_add_test(suite, "verify: DIX guard not generated, all flags check",
2224 			accel_dix_verify_op_dix_guard_not_generated_all_flags_check) == NULL ||
2225 	    CU_add_test(suite, "verify: DIX apptag not generated, all flags check",
2226 			accel_dix_verify_op_dix_apptag_not_generated_all_flags_check) == NULL ||
2227 	    CU_add_test(suite, "verify: DIX reftag not generated, all flags check",
2228 			accel_dix_verify_op_dix_reftag_not_generated_all_flags_check) == NULL ||
2229 
2230 	    CU_add_test(suite, "verify: DIF APPTAG correct, APPTAG check",
2231 			accel_dif_verify_op_apptag_correct_apptag_check) == NULL ||
2232 	    CU_add_test(suite, "verify: DIX APPTAG correct, APPTAG check",
2233 			accel_dix_verify_op_apptag_correct_apptag_check) == NULL ||
2234 	    CU_add_test(suite, "verify: DIF APPTAG incorrect, APPTAG check",
2235 			accel_dif_verify_op_apptag_incorrect_apptag_check) == NULL ||
2236 	    CU_add_test(suite, "verify: DIX APPTAG incorrect, APPTAG check",
2237 			accel_dix_verify_op_apptag_incorrect_apptag_check) == NULL ||
2238 	    CU_add_test(suite, "verify: DIF APPTAG incorrect, no APPTAG check",
2239 			accel_dif_verify_op_apptag_incorrect_no_apptag_check) == NULL ||
2240 	    CU_add_test(suite, "verify: DIX APPTAG incorrect, no APPTAG check",
2241 			accel_dix_verify_op_apptag_incorrect_no_apptag_check) == NULL ||
2242 	    CU_add_test(suite, "verify: DIF REFTAG incorrect, REFTAG ignore",
2243 			accel_dif_verify_op_reftag_incorrect_reftag_ignore) == NULL ||
2244 	    CU_add_test(suite, "verify: DIX REFTAG incorrect, REFTAG ignore",
2245 			accel_dix_verify_op_reftag_incorrect_reftag_ignore) == NULL ||
2246 
2247 	    CU_add_test(suite, "verify: DIF REFTAG_INIT correct, REFTAG check",
2248 			accel_dif_verify_op_reftag_init_correct_reftag_check) == NULL ||
2249 	    CU_add_test(suite, "verify: DIX REFTAG_INIT correct, REFTAG check",
2250 			accel_dix_verify_op_reftag_init_correct_reftag_check) == NULL ||
2251 	    CU_add_test(suite, "verify: DIF REFTAG_INIT incorrect, REFTAG check",
2252 			accel_dif_verify_op_reftag_init_incorrect_reftag_check) == NULL ||
2253 	    CU_add_test(suite, "verify: DIX REFTAG_INIT incorrect, REFTAG check",
2254 			accel_dix_verify_op_reftag_init_incorrect_reftag_check) == NULL ||
2255 
2256 	    CU_add_test(suite, "verify copy: DIF generated, GUARD check",
2257 			accel_dif_verify_copy_op_dif_generated_guard_check) == NULL ||
2258 	    CU_add_test(suite, "verify copy: DIF generated, APPTAG check",
2259 			accel_dif_verify_copy_op_dif_generated_apptag_check) == NULL ||
2260 	    CU_add_test(suite, "verify copy: DIF generated, REFTAG check",
2261 			accel_dif_verify_copy_op_dif_generated_reftag_check) == NULL ||
2262 
2263 	    CU_add_test(suite, "verify copy: DIF not generated, GUARD check",
2264 			accel_dif_verify_copy_op_dif_not_generated_guard_check) == NULL ||
2265 	    CU_add_test(suite, "verify copy: DIF not generated, APPTAG check",
2266 			accel_dif_verify_copy_op_dif_not_generated_apptag_check) == NULL ||
2267 	    CU_add_test(suite, "verify copy: DIF not generated, REFTAG check",
2268 			accel_dif_verify_copy_op_dif_not_generated_reftag_check) == NULL ||
2269 
2270 	    CU_add_test(suite, "generate copy: DIF generated, GUARD check",
2271 			accel_dif_generate_copy_op_dif_generated_guard_check) == NULL ||
2272 	    CU_add_test(suite, "generate copy: DIF generated, APTTAG check",
2273 			accel_dif_generate_copy_op_dif_generated_apptag_check) == NULL ||
2274 	    CU_add_test(suite, "generate copy: DIF generated, REFTAG check",
2275 			accel_dif_generate_copy_op_dif_generated_reftag_check) == NULL ||
2276 
2277 	    CU_add_test(suite, "generate: DIX generated, GUARD check",
2278 			accel_dix_generate_op_dix_generated_guard_check) == NULL ||
2279 	    CU_add_test(suite, "generate: DIX generated, APTTAG check",
2280 			accel_dix_generate_op_dix_generated_apptag_check) == NULL ||
2281 	    CU_add_test(suite, "generate: DIX generated, REFTAG check",
2282 			accel_dix_generate_op_dix_generated_reftag_check) == NULL ||
2283 
2284 	    CU_add_test(suite, "generate copy: DIF generated, no GUARD check flag set",
2285 			accel_dif_generate_copy_op_dif_generated_no_guard_check_flag_set) == NULL ||
2286 	    CU_add_test(suite, "generate copy: DIF generated, no APPTAG check flag set",
2287 			accel_dif_generate_copy_op_dif_generated_no_apptag_check_flag_set) == NULL ||
2288 	    CU_add_test(suite, "generate copy: DIF generated, no REFTAG check flag set",
2289 			accel_dif_generate_copy_op_dif_generated_no_reftag_check_flag_set) == NULL ||
2290 
2291 	    CU_add_test(suite, "generate copy: DIF iovecs-len validate",
2292 			accel_dif_generate_copy_op_iovecs_len_validate) == NULL ||
2293 	    CU_add_test(suite, "generate copy: DIF buffer alignment validate",
2294 			accel_dif_generate_copy_op_buf_align_validate) == NULL ||
2295 
2296 	    CU_add_test(suite, "generate copy sequence: DIF generated, GUARD check",
2297 			accel_dif_generate_copy_sequence_dif_generated_guard_check) == NULL ||
2298 	    CU_add_test(suite, "generate copy sequence: DIF generated, APTTAG check",
2299 			accel_dif_generate_copy_sequence_dif_generated_apptag_check) == NULL ||
2300 	    CU_add_test(suite, "generate copy sequence: DIF generated, REFTAG check",
2301 			accel_dif_generate_copy_sequence_dif_generated_reftag_check) == NULL ||
2302 	    CU_add_test(suite, "verify copy sequence: DIF generated, GUARD check",
2303 			accel_dif_verify_copy_sequence_dif_generated_guard_check) == NULL ||
2304 	    CU_add_test(suite, "verify copy sequence: DIF generated, APPTAG check",
2305 			accel_dif_verify_copy_sequence_dif_generated_apptag_check) == NULL ||
2306 	    CU_add_test(suite, "verify copy sequence: DIF generated, REFTAG check",
2307 			accel_dif_verify_copy_sequence_dif_generated_reftag_check) == NULL) {
2308 		CU_cleanup_registry();
2309 		rc = CU_get_error();
2310 		return -rc;
2311 	}
2312 	return 0;
2313 }
2314 
2315 static void
2316 get_io_channel(void *arg)
2317 {
2318 	g_channel = spdk_accel_get_io_channel();
2319 	assert(g_channel);
2320 	wake_ut_thread();
2321 }
2322 
2323 static void
2324 put_io_channel(void *arg)
2325 {
2326 	assert(g_channel);
2327 	spdk_put_io_channel(g_channel);
2328 	wake_ut_thread();
2329 }
2330 
2331 static void
2332 run_accel_test_thread(void *arg)
2333 {
2334 	struct spdk_jsonrpc_request *request = arg;
2335 	int rc = 0;
2336 
2337 	execute_spdk_function(get_io_channel, NULL);
2338 	if (g_channel == NULL) {
2339 		fprintf(stderr, "Unable to get an accel channel\n");
2340 		goto ret;
2341 	}
2342 
2343 	if (CU_initialize_registry() != CUE_SUCCESS) {
2344 		/* CUnit error, probably won't recover */
2345 		rc = CU_get_error();
2346 		rc = -rc;
2347 		goto ret;
2348 	}
2349 
2350 	rc = setup_accel_tests();
2351 	if (rc < 0) {
2352 		/* CUnit error, probably won't recover */
2353 		rc = -rc;
2354 		goto ret;
2355 	}
2356 	CU_basic_set_mode(CU_BRM_VERBOSE);
2357 	CU_basic_run_tests();
2358 	rc = CU_get_number_of_failures();
2359 	CU_cleanup_registry();
2360 
2361 ret:
2362 	if (g_channel != NULL) {
2363 		execute_spdk_function(put_io_channel, NULL);
2364 	}
2365 	stop_init_thread(rc, request);
2366 }
2367 
2368 static void
2369 accel_dif_test_main(void *arg1)
2370 {
2371 	struct spdk_cpuset tmpmask = {};
2372 	uint32_t i;
2373 
2374 	pthread_mutex_init(&g_test_mutex, NULL);
2375 	pthread_cond_init(&g_test_cond, NULL);
2376 
2377 	/* This test runs specifically on at least two cores.
2378 	 * g_thread[WORKER_UT] is the app_thread on main core from event framework.
2379 	 * Next one is only for the tests and should always be on separate CPU cores. */
2380 	if (spdk_env_get_core_count() < 3) {
2381 		spdk_app_stop(-1);
2382 		return;
2383 	}
2384 
2385 	SPDK_ENV_FOREACH_CORE(i) {
2386 		if (i == spdk_env_get_current_core()) {
2387 			g_thread[WORKER_UT] = spdk_get_thread();
2388 			continue;
2389 		}
2390 		spdk_cpuset_zero(&tmpmask);
2391 		spdk_cpuset_set_cpu(&tmpmask, i, true);
2392 		if (g_thread[WORKER_IO] == NULL) {
2393 			g_thread[WORKER_IO] = spdk_thread_create("io_thread", &tmpmask);
2394 		}
2395 
2396 	}
2397 
2398 	spdk_thread_send_msg(g_thread[WORKER_UT], run_accel_test_thread, NULL);
2399 }
2400 
2401 static void
2402 accel_dif_usage(void)
2403 {
2404 }
2405 
2406 static int
2407 accel_dif_parse_arg(int ch, char *arg)
2408 {
2409 	return 0;
2410 }
2411 
2412 static void
2413 spdk_dif_shutdown_cb(void)
2414 {
2415 	g_shutdown = true;
2416 	spdk_thread_send_msg(g_thread[WORKER_UT], _stop_init_thread, NULL);
2417 }
2418 
2419 int
2420 main(int argc, char **argv)
2421 {
2422 	struct spdk_app_opts opts = {};
2423 	char reactor_mask[8];
2424 	int rc;
2425 
2426 	spdk_app_opts_init(&opts, sizeof(opts));
2427 	opts.name = "DIF";
2428 	snprintf(reactor_mask, sizeof(reactor_mask), "0x%x", (1 << (SPDK_COUNTOF(g_thread) + 1)) - 1);
2429 	opts.reactor_mask = reactor_mask;
2430 	opts.shutdown_cb = spdk_dif_shutdown_cb;
2431 	opts.rpc_addr = NULL;
2432 
2433 	if ((rc = spdk_app_parse_args(argc, argv, &opts, "", NULL,
2434 				      accel_dif_parse_arg, accel_dif_usage)) !=
2435 	    SPDK_APP_PARSE_ARGS_SUCCESS) {
2436 		return rc;
2437 	}
2438 
2439 	rc = spdk_app_start(&opts, accel_dif_test_main, NULL);
2440 	spdk_app_fini();
2441 
2442 	return rc;
2443 }
2444