Commit 5d025489 authored by Slawomir Ptak's avatar Slawomir Ptak Committed by Tomasz Zawadzki
Browse files

lib/util/crc32c: Added an NVMe PI compliant crc32c



Change-Id: I5d5441b2f60ef53d9fcee0ff894c61f0e2b7997f
Signed-off-by: default avatarSlawomir Ptak <slawomir.ptak@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/18150


Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 363e03b0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -50,6 +50,16 @@ uint32_t spdk_crc32c_update(const void *buf, size_t len, uint32_t crc);
 */
uint32_t spdk_crc32c_iov_update(struct iovec *iov, int iovcnt, uint32_t crc32c);

/**
 * Calculate a CRC-32C checksum, for NVMe Protection Information
 *
 * \param buf Data buffer to checksum.
 * \param len Length of buf in bytes.
 * \param crc Previous CRC-32C value.
 * \return Updated CRC-32C value.
 */
uint32_t spdk_crc32c_nvme(const void *buf, size_t len, uint32_t crc);

#ifdef __cplusplus
}
#endif
+6 −0
Original line number Diff line number Diff line
@@ -125,3 +125,9 @@ spdk_crc32c_iov_update(struct iovec *iov, int iovcnt, uint32_t crc32c)

	return crc32c;
}

uint32_t
spdk_crc32c_nvme(const void *buf, size_t len, uint32_t crc)
{
	return ~(spdk_crc32c_update(buf, len, ~crc));
}
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
	spdk_crc32_ieee_update;
	spdk_crc32c_update;
	spdk_crc32c_iov_update;
	spdk_crc32c_nvme;

	# public functions in dif.h
	spdk_dif_ctx_init;
+51 −0
Original line number Diff line number Diff line
@@ -114,6 +114,56 @@ test_crc32c(void)
	CU_ASSERT(crc == 0x6087809A);
}

static void
test_crc32c_nvme(void)
{
	unsigned int buf_size = 4096;
	char buf[buf_size];
	uint32_t crc;
	unsigned int i, j;

	/* All the expected CRC values are compliant with
	* the NVM Command Set Specification 1.0c */

	/* Input buffer = 0s */
	memset(buf, 0, buf_size);
	crc = spdk_crc32c_nvme(buf, buf_size, 0);
	CU_ASSERT(crc == 0x98F94189);

	/* Input buffer = 1s */
	memset(buf, 0xFF, buf_size);
	crc = spdk_crc32c_nvme(buf, buf_size, 0);
	CU_ASSERT(crc == 0x25C1FE13);

	/* Input buffer = 0x00, 0x01, 0x02, ... */
	memset(buf, 0, buf_size);
	j = 0;
	for (i = 0; i < buf_size; i++) {
		buf[i] = (char)j;
		if (j == 0xFF) {
			j = 0;
		} else {
			j++;
		}
	}
	crc = spdk_crc32c_nvme(buf, buf_size, 0);
	CU_ASSERT(crc == 0x9C71FE32);

	/* Input buffer = 0xFF, 0xFE, 0xFD, ... */
	memset(buf, 0, buf_size);
	j = 0xFF;
	for (i = 0; i < buf_size ; i++) {
		buf[i] = (char)j;
		if (j == 0) {
			j = 0xFF;
		} else {
			j--;
		}
	}
	crc = spdk_crc32c_nvme(buf, buf_size, 0);
	CU_ASSERT(crc == 0x214941A8);
}

int
main(int argc, char **argv)
{
@@ -126,6 +176,7 @@ main(int argc, char **argv)
	suite = CU_add_suite("crc32c", NULL, NULL);

	CU_ADD_TEST(suite, test_crc32c);
	CU_ADD_TEST(suite, test_crc32c_nvme);

	CU_basic_set_mode(CU_BRM_VERBOSE);