Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | /* SPDX-License-Identifier: GPL-2.0-only */ /* * 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)) */ #ifndef _HASH_ALG_H #define _HASH_ALG_H #include <linux/bitops.h> #define HASH_BLOCK_SIZE 64 #define HASH_DMA_FIFO 4 #define HASH_DMA_ALIGN_SIZE 4 #define HASH_DMA_PERFORMANCE_MIN_SIZE 1024 #define HASH_BYTES_PER_WORD 4 /* Maximum value of the length's high word */ #define HASH_HIGH_WORD_MAX_VAL 0xFFFFFFFFUL /* Power on Reset values HASH registers */ #define HASH_RESET_CR_VALUE 0x0 #define HASH_RESET_STR_VALUE 0x0 /* Number of context swap registers */ #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_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_SWITCHON_POS 31 #define HASH_CR_SWITCHON_MASK BIT(31) #define HASH_CR_EMPTYMSG_POS 20 #define HASH_CR_EMPTYMSG_MASK BIT(20) #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_LKEY_POS 16 #define HASH_CR_LKEY_MASK BIT(16) #define HASH_CR_ALGO_POS 7 #define HASH_CR_ALGO_MASK BIT(7) #define HASH_CR_MODE_POS 6 #define HASH_CR_MODE_MASK BIT(6) #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 BIT(3) #define HASH_CR_INIT_POS 2 #define HASH_CR_INIT_MASK BIT(2) #define HASH_CR_PRIVN_POS 1 #define HASH_CR_PRIVN_MASK BIT(1) #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 BIT(8) #define HASH_STR_DEFAULT 0x0 #define HASH_STR_NBLW_POS 0 #define HASH_STR_NBLW_MASK 0x0000001FUL #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_BITS(reg_name, mask) \ writel_relaxed((readl_relaxed(reg_name) | mask), reg_name) #define HASH_CLEAR_BITS(reg_name, mask) \ writel_relaxed((readl_relaxed(reg_name) & ~mask), reg_name) #define HASH_PUT_BITS(reg, val, shift, mask) \ writel_relaxed(((readl(reg) & ~(mask)) | \ (((u32)val << shift) & (mask))), reg) #define HASH_SET_DIN(val, len) writesl(&device_data->base->din, (val), (len)) #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) \ HASH_PUT_BITS( \ &device_data->base->cr, \ (u32) (data_format), HASH_CR_DATAFORM_POS, \ HASH_CR_DATAFORM_MASK) #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 \ HASH_PUT_BITS( \ &device_data->base->str, \ 0x01, HASH_STR_DCAL_POS, \ HASH_STR_DCAL_MASK) /* Hardware access method */ enum hash_mode { HASH_MODE_CPU, HASH_MODE_DMA }; /** * struct uint64 - Structure to handle 64 bits integers. * @high_word: Most significant bits. * @low_word: Least significant bits. * * Used to handle 64 bits integers. */ struct uint64 { u32 high_word; u32 low_word; }; /** * struct hash_register - Contains all registers in ux500 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). * * 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 * with the registers used. */ struct hash_register { u32 cr; u32 din; u32 str; u32 hx[8]; u32 padding0[(0x080 - 0x02C) / sizeof(u32)]; u32 itcr; u32 itip; u32 itop; u32 padding1[(0x0F8 - 0x08C) / sizeof(u32)]; u32 csfull; u32 csdatain; u32 csrx[HASH_CSR_COUNT]; u32 padding2[(0xFE0 - 0x1D0) / sizeof(u32)]; u32 periphid0; u32 periphid1; u32 periphid2; u32 periphid3; u32 cellid0; u32 cellid1; u32 cellid2; u32 cellid3; }; /** * 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 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 * results in software. * * WARNING: "index" is the member of the structure, to be sure that "buffer" * is aligned on a 4-bytes boundary. This is highly implementation dependent * 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; }; /** * enum hash_device_id - HASH device ID. * @HASH_DEVICE_ID_0: Hash hardware with ID 0 * @HASH_DEVICE_ID_1: Hash hardware with ID 1 */ enum hash_device_id { HASH_DEVICE_ID_0 = 0, HASH_DEVICE_ID_1 = 1 }; /** * 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. */ enum hash_data_format { 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. * @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_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 { HASH_OPER_MODE_HASH = 0x0, HASH_OPER_MODE_HMAC = 0x1 }; /** * 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; int algorithm; int oper_mode; }; /** * struct hash_dma - Structure used for dma. * @mask: DMA capabilities bitmap mask. * @complete: Used to maintain state for a "completion". * @chan_mem2hash: DMA channel. * @cfg_mem2hash: DMA channel configuration. * @sg_len: Scatterlist length. * @sg: Scatterlist. * @nents: Number of sg entries. */ struct hash_dma { dma_cap_mask_t mask; struct completion complete; struct dma_chan *chan_mem2hash; void *cfg_mem2hash; int sg_len; struct scatterlist *sg; int nents; }; /** * struct hash_ctx - The context used for hash calculations. * @key: The key used in the operation. * @keylen: The length of the key. * @state: The state of the current calculations. * @config: The current configuration. * @digestsize: The size of current digest. * @device: Pointer to the device structure. */ struct hash_ctx { u8 *key; u32 keylen; struct hash_config config; int digestsize; struct hash_device_data *device; }; /** * struct hash_ctx - The request context used for hash calculations. * @state: The state of the current calculations. * @dma_mode: Used in special cases (workaround), e.g. need to change to * cpu mode, if not supported/working in dma mode. * @updated: Indicates if hardware is initialized for new operations. */ struct hash_req_ctx { struct hash_state state; bool dma_mode; u8 updated; }; /** * struct hash_device_data - structure for a hash device. * @base: Pointer to virtual base address of the hash device. * @phybase: Pointer to physical memory location of the hash device. * @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. * @dma: Structure used for dma. */ struct hash_device_data { struct hash_register __iomem *base; phys_addr_t phybase; struct klist_node list_node; struct device *dev; spinlock_t ctx_lock; struct hash_ctx *current_ctx; bool power_state; spinlock_t power_state_lock; struct regulator *regulator; struct clk *clk; bool restore_dev_state; struct hash_state state; /* Used for saving and resuming state */ struct hash_dma dma; }; int hash_check_hw(struct hash_device_data *device_data); int hash_setconfiguration(struct hash_device_data *device_data, struct hash_config *config); void hash_begin(struct hash_device_data *device_data, struct hash_ctx *ctx); void hash_get_digest(struct hash_device_data *device_data, u8 *digest, int algorithm); int hash_hw_update(struct ahash_request *req); int hash_save_state(struct hash_device_data *device_data, struct hash_state *state); int hash_resume_state(struct hash_device_data *device_data, const struct hash_state *state); #endif |