platform: msm_shared: Enable crypto HW version check
Crypto HW version prior to 5.1.0 has a hardware bug which
requires descriptor addresses to be burst aligned. Restrict
this behaviour to older crypto HW by checking the crypto HW version.
Change-Id: I14905ffbc559f6876b474c80cf37394e264fe385
CRs-Fixed: 595242
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index 3fecd61..c954a7f 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -414,19 +414,45 @@
crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
uint32_t wr_flags = BAM_DESC_NWD_FLAG | BAM_DESC_INT_FLAG | BAM_DESC_EOT_FLAG;
uint32_t ret_status;
+ uint32_t minor_ver = 0;
+ uint8_t *buffer = NULL;
- /* A H/W bug on Crypto 5.0.0 enforces a rule that the desc lengths must be burst aligned. */
- if ((uint32_t) data_ptr & (CRYPTO_BURST_LEN - 1))
+ /* Bits 23:16 - minor version */
+ minor_ver = (readl(CRYPTO_VERSION(dev->base)) & 0x00FF0000) >> 16;
+
+ /* A H/W bug on Crypto 5.0.0 enforces a rule that the desc lengths must be burst aligned.
+ * This bug is fixed in 5.1.0 onwards.*/
+
+ if(minor_ver == 0)
{
- dprintf(CRITICAL, "Crypto send data failed\n");
- dprintf(CRITICAL, "Data start not aligned at burst length.\n");
- ret_status = CRYPTO_ERR_FAIL;
- goto CRYPTO_SEND_DATA_ERR;
+ if ((uint32_t) data_ptr & (CRYPTO_BURST_LEN - 1))
+ {
+ dprintf(CRITICAL, "Data start not aligned at burst length.\n");
+
+ buffer = (uint8_t *)memalign(CRYPTO_BURST_LEN, sha256_ctx->bytes_to_write);
+ if(!buffer)
+ {
+ dprintf(CRITICAL, "ERROR: Failed to allocate burst aligned crypto buffer\n");
+ ret_status = CRYPTO_ERR_FAIL;
+ goto CRYPTO_SEND_DATA_ERR;
+ }
+
+ memset(buffer, 0, sha256_ctx->bytes_to_write);
+ memcpy(buffer, data_ptr, sha256_ctx->bytes_to_write);
+ }
}
- arch_clean_invalidate_cache_range((addr_t) data_ptr, sha256_ctx->bytes_to_write);
+ if(buffer)
+ {
+ arch_clean_invalidate_cache_range((addr_t) buffer, sha256_ctx->bytes_to_write);
- bam_status = ADD_WRITE_DESC(&dev->bam, data_ptr, sha256_ctx->bytes_to_write, wr_flags);
+ bam_status = ADD_WRITE_DESC(&dev->bam, buffer, sha256_ctx->bytes_to_write, wr_flags);
+ }
+ else
+ {
+ arch_clean_invalidate_cache_range((addr_t) data_ptr, sha256_ctx->bytes_to_write);
+ bam_status = ADD_WRITE_DESC(&dev->bam, data_ptr, sha256_ctx->bytes_to_write, wr_flags);
+ }
if (bam_status)
{
@@ -459,6 +485,9 @@
CRYPTO_SEND_DATA_ERR:
+ if(buffer)
+ free(buffer);
+
return ret_status;
}