summaryrefslogtreecommitdiff
path: root/drivers/crypto/ux500/hash/hash_alg.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/ux500/hash/hash_alg.h')
-rw-r--r--drivers/crypto/ux500/hash/hash_alg.h404
1 files changed, 195 insertions, 209 deletions
diff --git a/drivers/crypto/ux500/hash/hash_alg.h b/drivers/crypto/ux500/hash/hash_alg.h
index 1c3dd5705fb..3bf1354ea03 100644
--- a/drivers/crypto/ux500/hash/hash_alg.h
+++ b/drivers/crypto/ux500/hash/hash_alg.h
@@ -2,140 +2,137 @@
* Copyright (C) ST-Ericsson SA 2010
* Author: Shujuan Chen (shujuan.chen@stericsson.com)
* Author: Joakim Bech (joakim.xx.bech@stericsson.com)
+ * Author: Berne Hebark (berne.hebark@stericsson.com))
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef _HASH_ALG_H
#define _HASH_ALG_H
-#include <mach/hcl_defs.h>
+#include <linux/bitops.h>
/* Number of bytes the message digest */
-#define HASH_MSG_DIGEST_SIZE 32
-#define HASH_BLOCK_SIZE 64
+#define HASH_MSG_DIGEST_SIZE 32
+#define HASH_BLOCK_SIZE 64
#define HASH_SHA1_DIGEST_SIZE 20
-#define HASH_SHA2_DIGEST_SIZE 32
-
-/* Version defines */
-#define HASH_HCL_VERSION_ID 1
-#define HASH_HCL_MAJOR_ID 2
-#define HASH_HCL_MINOR_ID 1
-
-#define MAX_HASH_DEVICE 2
+#define HASH_SHA2_DIGEST_SIZE 32
/* Maximum value of the length's high word */
-#define HASH_HIGH_WORD_MAX_VAL 0xFFFFFFFFUL
+#define HASH_HIGH_WORD_MAX_VAL 0xFFFFFFFFUL
/* Power on Reset values HASH registers */
-#define HASH_RESET_CONTROL_REG_VALUE 0x0
-#define HASH_RESET_START_REG_VALUE 0x0
+#define HASH_RESET_CR_VALUE 0x0
+#define HASH_RESET_STR_VALUE 0x0
/* Number of context swap registers */
-#define HASH_CSR_COUNT 52
+#define HASH_CSR_COUNT 52
-#define HASH_RESET_CSRX_REG_VALUE 0x0
-#define HASH_RESET_CSFULL_REG_VALUE 0x0
-#define HASH_RESET_CSDATAIN_REG_VALUE 0x0
+#define HASH_RESET_CSRX_REG_VALUE 0x0
+#define HASH_RESET_CSFULL_REG_VALUE 0x0
+#define HASH_RESET_CSDATAIN_REG_VALUE 0x0
-#define HASH_RESET_INDEX_VAL 0x0
-#define HASH_RESET_BIT_INDEX_VAL 0x0
-#define HASH_RESET_BUFFER_VAL 0x0
-#define HASH_RESET_LEN_HIGH_VAL 0x0
-#define HASH_RESET_LEN_LOW_VAL 0x0
+#define HASH_RESET_INDEX_VAL 0x0
+#define HASH_RESET_BIT_INDEX_VAL 0x0
+#define HASH_RESET_BUFFER_VAL 0x0
+#define HASH_RESET_LEN_HIGH_VAL 0x0
+#define HASH_RESET_LEN_LOW_VAL 0x0
/* Control register bitfields */
-#define HASH_CR_RESUME_MASK 0x11FCF
+#define HASH_CR_RESUME_MASK 0x11FCF
-#define HASH_CR_SWITCHON_POS 31
-#define HASH_CR_SWITCHON_MASK MASK_BIT31
+#define HASH_CR_SWITCHON_POS 31
+#define HASH_CR_SWITCHON_MASK BIT(31)
-#define HASH_CR_EMPTYMSG_POS 20
-#define HASH_CR_EMPTYMSG_MASK MASK_BIT20
+#define HASH_CR_EMPTYMSG_POS 20
+#define HASH_CR_EMPTYMSG_MASK BIT(20)
-#define HASH_CR_DINF_POS 12
-#define HASH_CR_DINF_MASK MASK_BIT12
+#define HASH_CR_DINF_POS 12
+#define HASH_CR_DINF_MASK BIT(12)
-#define HASH_CR_NBW_POS 8
-#define HASH_CR_NBW_MASK 0x00000F00UL
+#define HASH_CR_NBW_POS 8
+#define HASH_CR_NBW_MASK 0x00000F00UL
-#define HASH_CR_LKEY_POS 16
-#define HASH_CR_LKEY_MASK MASK_BIT16
+#define HASH_CR_LKEY_POS 16
+#define HASH_CR_LKEY_MASK BIT(16)
-#define HASH_CR_ALGO_POS 7
-#define HASH_CR_ALGO_MASK MASK_BIT7
+#define HASH_CR_ALGO_POS 7
+#define HASH_CR_ALGO_MASK BIT(7)
-#define HASH_CR_MODE_POS 6
-#define HASH_CR_MODE_MASK MASK_BIT6
+#define HASH_CR_MODE_POS 6
+#define HASH_CR_MODE_MASK BIT(6)
-#define HASH_CR_DATAFORM_POS 4
-#define HASH_CR_DATAFORM_MASK (MASK_BIT4 | MASK_BIT5)
+#define HASH_CR_DATAFORM_POS 4
+#define HASH_CR_DATAFORM_MASK (BIT(4) | BIT(5))
-#define HASH_CR_DMAE_POS 3
-#define HASH_CR_DMAE_MASK MASK_BIT3
+#define HASH_CR_DMAE_POS 3
+#define HASH_CR_DMAE_MASK BIT(3)
-#define HASH_CR_INIT_POS 2
-#define HASH_CR_INIT_MASK MASK_BIT2
+#define HASH_CR_INIT_POS 2
+#define HASH_CR_INIT_MASK BIT(2)
-#define HASH_CR_PRIVN_POS 1
-#define HASH_CR_PRIVN_MASK MASK_BIT1
+#define HASH_CR_PRIVN_POS 1
+#define HASH_CR_PRIVN_MASK BIT(1)
-#define HASH_CR_SECN_POS 0
-#define HASH_CR_SECN_MASK MASK_BIT0
+#define HASH_CR_SECN_POS 0
+#define HASH_CR_SECN_MASK BIT(0)
/* Start register bitfields */
-#define HASH_STR_DCAL_POS 8
-#define HASH_STR_DCAL_MASK MASK_BIT8
+#define HASH_STR_DCAL_POS 8
+#define HASH_STR_DCAL_MASK BIT(8)
+#define HASH_STR_DEFAULT 0x0
-#define HASH_STR_NBLW_POS 0
-#define HASH_STR_NBLW_MASK 0x0000001FUL
+#define HASH_STR_NBLW_POS 0
+#define HASH_STR_NBLW_MASK 0x0000001FUL
-#define HASH_NBLW_MAX_VAL 0x1F
+#define HASH_NBLW_MAX_VAL 0x1F
/* PrimeCell IDs */
-#define HASH_P_ID0 0xE0
-#define HASH_P_ID1 0x05
-#define HASH_P_ID2 0x38
-#define HASH_P_ID3 0x00
-#define HASH_CELL_ID0 0x0D
-#define HASH_CELL_ID1 0xF0
-#define HASH_CELL_ID2 0x05
-#define HASH_CELL_ID3 0xB1
-
-#define HASH_SET_DIN(val) HCL_WRITE_REG( \
- sys_ctx_g.registry[HASH_DEVICE_ID_1]->din, (val))
-
-#define HASH_INITIALIZE \
- HCL_WRITE_BITS( \
- sys_ctx_g.registry[HASH_DEVICE_ID_1]->cr, \
- 0x01 << HASH_CR_INIT_POS, \
+#define HASH_P_ID0 0xE0
+#define HASH_P_ID1 0x05
+#define HASH_P_ID2 0x38
+#define HASH_P_ID3 0x00
+#define HASH_CELL_ID0 0x0D
+#define HASH_CELL_ID1 0xF0
+#define HASH_CELL_ID2 0x05
+#define HASH_CELL_ID3 0xB1
+
+#define HASH_SET_BITS(reg_name, mask) \
+ writel((readl(reg_name) | mask), reg_name)
+
+#define HASH_CLEAR_BITS(reg_name, mask) \
+ writel((readl(reg_name) & ~mask), reg_name)
+
+#define HASH_PUT_BITS(reg, val, shift, mask) \
+ writel(((readl(reg) & ~(mask)) | \
+ (((u32)val << shift) & (mask))), reg)
+
+#define HASH_SET_DIN(val) writel((val), &device_data->base->din)
+
+#define HASH_INITIALIZE \
+ HASH_PUT_BITS( \
+ &device_data->base->cr, \
+ 0x01, HASH_CR_INIT_POS, \
HASH_CR_INIT_MASK)
-#define HASH_SET_DATA_FORMAT(data_format) \
- HCL_WRITE_BITS( \
- sys_ctx_g.registry[HASH_DEVICE_ID_1]->cr, \
- (u32) (data_format) << HASH_CR_DATAFORM_POS, \
+#define HASH_SET_DATA_FORMAT(data_format) \
+ HASH_PUT_BITS( \
+ &device_data->base->cr, \
+ (u32) (data_format), HASH_CR_DATAFORM_POS, \
HASH_CR_DATAFORM_MASK)
-
-#define HASH_GET_HX(pos) \
- HCL_READ_REG(sys_ctx_g.registry[HASH_DEVICE_ID_1]->hx[pos])
-
-#define HASH_SET_NBLW(val) \
- HCL_WRITE_BITS( \
- sys_ctx_g.registry[HASH_DEVICE_ID_1]->str, \
- (u32) (val) << HASH_STR_NBLW_POS, \
+#define HASH_SET_NBLW(val) \
+ HASH_PUT_BITS( \
+ &device_data->base->str, \
+ (u32) (val), HASH_STR_NBLW_POS, \
HASH_STR_NBLW_MASK)
-
-#define HASH_SET_DCAL \
- HCL_WRITE_BITS( \
- sys_ctx_g.registry[HASH_DEVICE_ID_1]->str, \
- 0x01 << HASH_STR_DCAL_POS, \
+#define HASH_SET_DCAL \
+ HASH_PUT_BITS( \
+ &device_data->base->str, \
+ 0x01, HASH_STR_DCAL_POS, \
HASH_STR_DCAL_MASK)
-#define HASH_BLOCK_BYTE_SIZE 64
-
/**
* struct uint64 - Structure to handle 64 bits integers.
- * @high_word: Most significant bits
- * @low_word: Least significant bits
+ * @high_word: Most significant bits.
+ * @low_word: Least significant bits.
*
* Used to handle 64 bits integers.
*/
@@ -146,27 +143,27 @@ struct uint64 {
/**
* struct hash_register - Contains all registers in u8500 hash hardware.
- * @cr: HASH control register (0x000)
- * @din: HASH data input register (0x004)
- * @str: HASH start register (0x008)
- * @hx: HASH digest register 0..7 (0x00c-0x01C)
- * @padding0: Reserved (0x02C)
- * @itcr: Integration test control register (0x080)
- * @itip: Integration test input register (0x084)
- * @itop: Integration test output register (0x088)
- * @padding1: Reserved (0x08C)
- * @csfull: HASH context full register (0x0F8)
- * @csdatain: HASH context swap data input register (0x0FC)
- * @csrx: HASH context swap register 0..51 (0x100-0x1CC)
- * @padding2: Reserved (0x1D0)
- * @periphid0: HASH peripheral identification register 0 (0xFE0)
- * @periphid1: HASH peripheral identification register 1 (0xFE4)
- * @periphid2: HASH peripheral identification register 2 (0xFE8)
- * @periphid3: HASH peripheral identification register 3 (0xFEC)
- * @cellid0: HASH PCell identification register 0 (0xFF0)
- * @cellid1: HASH PCell identification register 1 (0xFF4)
- * @cellid2: HASH PCell identification register 2 (0xFF8)
- * @cellid3: HASH PCell identification register 3 (0xFFC)
+ * @cr: HASH control register (0x000).
+ * @din: HASH data input register (0x004).
+ * @str: HASH start register (0x008).
+ * @hx: HASH digest register 0..7 (0x00c-0x01C).
+ * @padding0: Reserved (0x02C).
+ * @itcr: Integration test control register (0x080).
+ * @itip: Integration test input register (0x084).
+ * @itop: Integration test output register (0x088).
+ * @padding1: Reserved (0x08C).
+ * @csfull: HASH context full register (0x0F8).
+ * @csdatain: HASH context swap data input register (0x0FC).
+ * @csrx: HASH context swap register 0..51 (0x100-0x1CC).
+ * @padding2: Reserved (0x1D0).
+ * @periphid0: HASH peripheral identification register 0 (0xFE0).
+ * @periphid1: HASH peripheral identification register 1 (0xFE4).
+ * @periphid2: HASH peripheral identification register 2 (0xFE8).
+ * @periphid3: HASH peripheral identification register 3 (0xFEC).
+ * @cellid0: HASH PCell identification register 0 (0xFF0).
+ * @cellid1: HASH PCell identification register 1 (0xFF4).
+ * @cellid2: HASH PCell identification register 2 (0xFF8).
+ * @cellid3: HASH PCell identification register 3 (0xFFC).
*
* The device communicates to the HASH via 32-bit-wide control registers
* accessible via the 32-bit width AMBA rev. 2.0 AHB Bus. Below is a structure
@@ -205,16 +202,16 @@ struct hash_register {
/**
* struct hash_state - Hash context state.
- * @temp_cr: Temporary HASH Control Register
- * @str_reg: HASH Start Register
- * @din_reg: HASH Data Input Register
- * @csr[52]: HASH Context Swap Registers 0-39
- * @csfull: HASH Context Swap Registers 40 ie Status flags
- * @csdatain: HASH Context Swap Registers 41 ie Input data
- * @buffer: Working buffer for messages going to the hardware
- * @length: Length of the part of the message hashed so far (floor(N/64) * 64)
- * @index: Valid number of bytes in buffer (N % 64)
- * @bit_index: Valid number of bits in buffer (N % 8)
+ * @temp_cr: Temporary HASH Control Register.
+ * @str_reg: HASH Start Register.
+ * @din_reg: HASH Data Input Register.
+ * @csr[52]: HASH Context Swap Registers 0-39.
+ * @csfull: HASH Context Swap Registers 40 ie Status flags.
+ * @csdatain: HASH Context Swap Registers 41 ie Input data.
+ * @buffer: Working buffer for messages going to the hardware.
+ * @length: Length of the part of message hashed so far (floor(N/64) * 64).
+ * @index: Valid number of bytes in buffer (N % 64).
+ * @bit_index: Valid number of bits in buffer (N % 8).
*
* This structure is used between context switches, i.e. when ongoing jobs are
* interupted with new jobs. When this happens we need to store intermediate
@@ -225,36 +222,16 @@ struct hash_register {
* and MUST be checked whenever this code is ported on new platforms.
*/
struct hash_state {
- u32 temp_cr;
- u32 str_reg;
- u32 din_reg;
- u32 csr[52];
- u32 csfull;
- u32 csdatain;
- u32 buffer[HASH_BLOCK_SIZE / sizeof(u32)];
- struct uint64 length;
- u8 index;
- u8 bit_index;
-};
-
-/**
- * struct hash_system_context - Structure for the global system context.
- * @registry: Pointer to the registry of the hash hardware
- * @state: State of the hash device
- */
-struct hash_system_context {
- /*
- * Pointer to HASH registers structure. We know that this gives a
- * checkpatch warning and in the current design it needs to be a
- * volatile. We will change it when we will rewrite the driver similar
- * to how we have done in cryp-part. We have also read
- * Documentation/volatile-considered-harmful.txt as checkpatch tell
- * us to do.
- */
- volatile struct hash_register *registry[MAX_HASH_DEVICE];
-
- /* State of HASH device */
- struct hash_state state[MAX_HASH_DEVICE];
+ u32 temp_cr;
+ u32 str_reg;
+ u32 din_reg;
+ u32 csr[52];
+ u32 csfull;
+ u32 csdatain;
+ u32 buffer[HASH_BLOCK_SIZE / sizeof(u32)];
+ struct uint64 length;
+ u8 index;
+ u8 bit_index;
};
/**
@@ -269,42 +246,32 @@ enum hash_device_id {
/**
* enum hash_data_format - HASH data format.
- * @HASH_DATA_32_BITS: 32 bits data format
- * @HASH_DATA_16_BITS: 16 bits data format
- * @HASH_DATA_8_BITS: 8 bits data format
- * @HASH_DATA_1_BITS: 1 bit data format
+ * @HASH_DATA_32_BITS: 32 bits data format
+ * @HASH_DATA_16_BITS: 16 bits data format
+ * @HASH_DATA_8_BITS: 8 bits data format.
+ * @HASH_DATA_1_BITS: 1 bit data format.
*/
enum hash_data_format {
- HASH_DATA_32_BITS = 0x0,
- HASH_DATA_16_BITS = 0x1,
- HASH_DATA_8_BITS = 0x2,
- HASH_DATA_1_BIT = 0x3
-};
-
-/**
- * struct hash_protection_config - Device protection configuration.
- * @privilege_access: FIXME, add comment.
- * @secure_access: FIXME, add comment.
- */
-struct hash_protection_config {
- int privilege_access;
- int secure_access;
+ HASH_DATA_32_BITS = 0x0,
+ HASH_DATA_16_BITS = 0x1,
+ HASH_DATA_8_BITS = 0x2,
+ HASH_DATA_1_BIT = 0x3
};
/**
- * enum hash_algo - Enumeration for selecting between SHA1 or SHA2 algorithm
+ * enum hash_algo - Enumeration for selecting between SHA1 or SHA2 algorithm.
* @HASH_ALGO_SHA1: Indicates that SHA1 is used.
* @HASH_ALGO_SHA2: Indicates that SHA2 (SHA256) is used.
*/
enum hash_algo {
- HASH_ALGO_SHA1 = 0x0,
- HASH_ALGO_SHA2 = 0x1
+ HASH_ALGO_SHA1 = 0x0,
+ HASH_ALGO_SHA256 = 0x1
};
/**
- * enum hash_op - Enumeration for selecting between HASH or HMAC mode
- * @HASH_OPER_MODE_HASH: Indicates usage of normal HASH mode
- * @HASH_OPER_MODE_HMAC: Indicates usage of HMAC
+ * enum hash_op - Enumeration for selecting between HASH or HMAC mode.
+ * @HASH_OPER_MODE_HASH: Indicates usage of normal HASH mode.
+ * @HASH_OPER_MODE_HMAC: Indicates usage of HMAC.
*/
enum hash_op {
HASH_OPER_MODE_HASH = 0x0,
@@ -312,10 +279,10 @@ enum hash_op {
};
/**
- * struct hash_config - Configuration data for the hardware
- * @data_format: Format of data entered into the hash data in register
- * @algorithm: Algorithm selection bit
- * @oper_mode: Operating mode selection bit
+ * struct hash_config - Configuration data for the hardware.
+ * @data_format: Format of data entered into the hash data in register.
+ * @algorithm: Algorithm selection bit.
+ * @oper_mode: Operating mode selection bit.
*/
struct hash_config {
int data_format;
@@ -324,48 +291,67 @@ struct hash_config {
};
/**
- * enum hash_rv - Return values / error codes for hash.
+ * struct hash_ctx - The context used for hash calculations.
+ * @key: The key used in the operation.
+ * @keylen: The length of the key.
+ * @updated: Indicates if hardware is initialized for new operations.
+ * @state: The state of the current calculations.
+ * @config: The current configuration.
+ * @digestsize The size of current digest.
+ * @device Pointer to the device structure.
*/
-enum hash_rv {
- HASH_OK = 0,
- HASH_MSG_LENGTH_OVERFLOW,
- HASH_INVALID_PARAMETER,
- HASH_UNSUPPORTED_HW
+struct hash_ctx {
+ u8 key[HASH_BLOCK_SIZE];
+ u32 keylen;
+ u8 updated;
+ struct hash_state state;
+ struct hash_config config;
+ int digestsize;
+ struct hash_device_data *device;
};
/**
- * struct hash_ctx - The context used for hash calculations.
- * @key: The key used in the operation
- * @keylen: The length of the key
- * @updated: Indicates if hardware is initialized for new operations
- * @state: The state of the current calculations
- * @config: The current configuration
+ * struct hash_device_data - structure for a hash device.
+ * @base: Pointer to the hardware base address.
+ * @list_node: For inclusion in klist.
+ * @dev: Pointer to the device dev structure.
+ * @ctx_lock: Spinlock for current_ctx.
+ * @current_ctx: Pointer to the currently allocated context.
+ * @power_state: TRUE = power state on, FALSE = power state off.
+ * @power_state_lock: Spinlock for power_state.
+ * @regulator: Pointer to the device's power control.
+ * @clk: Pointer to the device's clock control.
+ * @restore_dev_state: TRUE = saved state, FALSE = no saved state.
*/
-struct hash_ctx {
- u8 key[HASH_BLOCK_BYTE_SIZE];
- u32 keylen;
- u8 updated;
- struct hash_state state;
- struct hash_config config;
+struct hash_device_data {
+ struct hash_register __iomem *base;
+ struct klist_node list_node;
+ struct device *dev;
+ struct spinlock ctx_lock;
+ struct hash_ctx *current_ctx;
+ bool power_state;
+ struct spinlock power_state_lock;
+ struct ux500_regulator *regulator;
+ struct clk *clk;
+ bool restore_dev_state;
};
-int hash_init_base_address(int hash_device_id, t_logical_address base_address);
-
-int hash_setconfiguration(int hash_device_id, struct hash_config *p_config);
+int hash_check_hw(struct hash_device_data *device_data);
-void hash_begin(struct hash_ctx *ctx);
+int hash_setconfiguration(struct hash_device_data *device_data,
+ struct hash_config *config);
-void hash_get_digest(int hid, u8 *digest, int algorithm);
+void hash_begin(struct hash_device_data *device_data, struct hash_ctx *ctx);
-int hash_hw_update(struct shash_desc *desc,
- int hash_device_id,
- const u8 *p_data_buffer,
- u32 msg_length);
+void hash_get_digest(struct hash_device_data *device_data,
+ u8 *digest, int algorithm);
-int hash_end(struct hash_ctx *ctx, u8 digest[HASH_MSG_DIGEST_SIZE]);
+int hash_hw_update(struct ahash_request *req);
-int hash_save_state(int hash_device_id, struct hash_state *state);
+int hash_save_state(struct hash_device_data *device_data,
+ struct hash_state *state);
-int hash_resume_state(int hash_device_id, const struct hash_state *state);
+int hash_resume_state(struct hash_device_data *device_data,
+ const struct hash_state *state);
#endif