root/drivers/crypto/ux500/cryp/cryp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cryp_wait_until_done
  2. cryp_check
  3. cryp_activity
  4. cryp_flush_inoutfifo
  5. cryp_set_configuration
  6. cryp_configure_protection
  7. cryp_is_logic_busy
  8. cryp_configure_for_dma
  9. cryp_configure_key_values
  10. cryp_configure_init_vector
  11. cryp_save_device_context
  12. cryp_restore_device_context

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /**
   3  * Copyright (C) ST-Ericsson SA 2010
   4  * Author: Shujuan Chen <shujuan.chen@stericsson.com> for ST-Ericsson.
   5  * Author: Jonas Linde <jonas.linde@stericsson.com> for ST-Ericsson.
   6  * Author: Niklas Hernaeus <niklas.hernaeus@stericsson.com> for ST-Ericsson.
   7  * Author: Joakim Bech <joakim.xx.bech@stericsson.com> for ST-Ericsson.
   8  * Author: Berne Hebark <berne.herbark@stericsson.com> for ST-Ericsson.
   9  */
  10 
  11 #include <linux/errno.h>
  12 #include <linux/kernel.h>
  13 #include <linux/types.h>
  14 
  15 #include "cryp_p.h"
  16 #include "cryp.h"
  17 
  18 /**
  19  * cryp_wait_until_done - wait until the device logic is not busy
  20  */
  21 void cryp_wait_until_done(struct cryp_device_data *device_data)
  22 {
  23         while (cryp_is_logic_busy(device_data))
  24                 cpu_relax();
  25 }
  26 
  27 /**
  28  * cryp_check - This routine checks Peripheral and PCell Id
  29  * @device_data: Pointer to the device data struct for base address.
  30  */
  31 int cryp_check(struct cryp_device_data *device_data)
  32 {
  33         int peripheralid2 = 0;
  34 
  35         if (NULL == device_data)
  36                 return -EINVAL;
  37 
  38         peripheralid2 = readl_relaxed(&device_data->base->periphId2);
  39 
  40         if (peripheralid2 != CRYP_PERIPHERAL_ID2_DB8500)
  41                 return -EPERM;
  42 
  43         /* Check Peripheral and Pcell Id Register for CRYP */
  44         if ((CRYP_PERIPHERAL_ID0 ==
  45                 readl_relaxed(&device_data->base->periphId0))
  46             && (CRYP_PERIPHERAL_ID1 ==
  47                     readl_relaxed(&device_data->base->periphId1))
  48             && (CRYP_PERIPHERAL_ID3 ==
  49                     readl_relaxed(&device_data->base->periphId3))
  50             && (CRYP_PCELL_ID0 ==
  51                     readl_relaxed(&device_data->base->pcellId0))
  52             && (CRYP_PCELL_ID1 ==
  53                     readl_relaxed(&device_data->base->pcellId1))
  54             && (CRYP_PCELL_ID2 ==
  55                     readl_relaxed(&device_data->base->pcellId2))
  56             && (CRYP_PCELL_ID3 ==
  57                     readl_relaxed(&device_data->base->pcellId3))) {
  58                 return 0;
  59         }
  60 
  61         return -EPERM;
  62 }
  63 
  64 /**
  65  * cryp_activity - This routine enables/disable the cryptography function.
  66  * @device_data: Pointer to the device data struct for base address.
  67  * @cryp_crypen: Enable/Disable functionality
  68  */
  69 void cryp_activity(struct cryp_device_data *device_data,
  70                    enum cryp_crypen cryp_crypen)
  71 {
  72         CRYP_PUT_BITS(&device_data->base->cr,
  73                       cryp_crypen,
  74                       CRYP_CR_CRYPEN_POS,
  75                       CRYP_CR_CRYPEN_MASK);
  76 }
  77 
  78 /**
  79  * cryp_flush_inoutfifo - Resets both the input and the output FIFOs
  80  * @device_data: Pointer to the device data struct for base address.
  81  */
  82 void cryp_flush_inoutfifo(struct cryp_device_data *device_data)
  83 {
  84         /*
  85          * We always need to disable the hardware before trying to flush the
  86          * FIFO. This is something that isn't written in the design
  87          * specification, but we have been informed by the hardware designers
  88          * that this must be done.
  89          */
  90         cryp_activity(device_data, CRYP_CRYPEN_DISABLE);
  91         cryp_wait_until_done(device_data);
  92 
  93         CRYP_SET_BITS(&device_data->base->cr, CRYP_CR_FFLUSH_MASK);
  94         /*
  95          * CRYP_SR_INFIFO_READY_MASK is the expected value on the status
  96          * register when starting a new calculation, which means Input FIFO is
  97          * not full and input FIFO is empty.
  98          */
  99         while (readl_relaxed(&device_data->base->sr) !=
 100                CRYP_SR_INFIFO_READY_MASK)
 101                 cpu_relax();
 102 }
 103 
 104 /**
 105  * cryp_set_configuration - This routine set the cr CRYP IP
 106  * @device_data: Pointer to the device data struct for base address.
 107  * @cryp_config: Pointer to the configuration parameter
 108  * @control_register: The control register to be written later on.
 109  */
 110 int cryp_set_configuration(struct cryp_device_data *device_data,
 111                            struct cryp_config *cryp_config,
 112                            u32 *control_register)
 113 {
 114         u32 cr_for_kse;
 115 
 116         if (NULL == device_data || NULL == cryp_config)
 117                 return -EINVAL;
 118 
 119         *control_register |= (cryp_config->keysize << CRYP_CR_KEYSIZE_POS);
 120 
 121         /* Prepare key for decryption in AES_ECB and AES_CBC mode. */
 122         if ((CRYP_ALGORITHM_DECRYPT == cryp_config->algodir) &&
 123             ((CRYP_ALGO_AES_ECB == cryp_config->algomode) ||
 124              (CRYP_ALGO_AES_CBC == cryp_config->algomode))) {
 125                 cr_for_kse = *control_register;
 126                 /*
 127                  * This seems a bit odd, but it is indeed needed to set this to
 128                  * encrypt even though it is a decryption that we are doing. It
 129                  * also mentioned in the design spec that you need to do this.
 130                  * After the keyprepartion for decrypting is done you should set
 131                  * algodir back to decryption, which is done outside this if
 132                  * statement.
 133                  *
 134                  * According to design specification we should set mode ECB
 135                  * during key preparation even though we might be running CBC
 136                  * when enter this function.
 137                  *
 138                  * Writing to KSE_ENABLED will drop CRYPEN when key preparation
 139                  * is done. Therefore we need to set CRYPEN again outside this
 140                  * if statement when running decryption.
 141                  */
 142                 cr_for_kse |= ((CRYP_ALGORITHM_ENCRYPT << CRYP_CR_ALGODIR_POS) |
 143                                (CRYP_ALGO_AES_ECB << CRYP_CR_ALGOMODE_POS) |
 144                                (CRYP_CRYPEN_ENABLE << CRYP_CR_CRYPEN_POS) |
 145                                (KSE_ENABLED << CRYP_CR_KSE_POS));
 146 
 147                 writel_relaxed(cr_for_kse, &device_data->base->cr);
 148                 cryp_wait_until_done(device_data);
 149         }
 150 
 151         *control_register |=
 152                 ((cryp_config->algomode << CRYP_CR_ALGOMODE_POS) |
 153                  (cryp_config->algodir << CRYP_CR_ALGODIR_POS));
 154 
 155         return 0;
 156 }
 157 
 158 /**
 159  * cryp_configure_protection - set the protection bits in the CRYP logic.
 160  * @device_data: Pointer to the device data struct for base address.
 161  * @p_protect_config:   Pointer to the protection mode and
 162  *                      secure mode configuration
 163  */
 164 int cryp_configure_protection(struct cryp_device_data *device_data,
 165                               struct cryp_protection_config *p_protect_config)
 166 {
 167         if (NULL == p_protect_config)
 168                 return -EINVAL;
 169 
 170         CRYP_WRITE_BIT(&device_data->base->cr,
 171                        (u32) p_protect_config->secure_access,
 172                        CRYP_CR_SECURE_MASK);
 173         CRYP_PUT_BITS(&device_data->base->cr,
 174                       p_protect_config->privilege_access,
 175                       CRYP_CR_PRLG_POS,
 176                       CRYP_CR_PRLG_MASK);
 177 
 178         return 0;
 179 }
 180 
 181 /**
 182  * cryp_is_logic_busy - returns the busy status of the CRYP logic
 183  * @device_data: Pointer to the device data struct for base address.
 184  */
 185 int cryp_is_logic_busy(struct cryp_device_data *device_data)
 186 {
 187         return CRYP_TEST_BITS(&device_data->base->sr,
 188                               CRYP_SR_BUSY_MASK);
 189 }
 190 
 191 /**
 192  * cryp_configure_for_dma - configures the CRYP IP for DMA operation
 193  * @device_data: Pointer to the device data struct for base address.
 194  * @dma_req: Specifies the DMA request type value.
 195  */
 196 void cryp_configure_for_dma(struct cryp_device_data *device_data,
 197                             enum cryp_dma_req_type dma_req)
 198 {
 199         CRYP_SET_BITS(&device_data->base->dmacr,
 200                       (u32) dma_req);
 201 }
 202 
 203 /**
 204  * cryp_configure_key_values - configures the key values for CRYP operations
 205  * @device_data: Pointer to the device data struct for base address.
 206  * @key_reg_index: Key value index register
 207  * @key_value: The key value struct
 208  */
 209 int cryp_configure_key_values(struct cryp_device_data *device_data,
 210                               enum cryp_key_reg_index key_reg_index,
 211                               struct cryp_key_value key_value)
 212 {
 213         while (cryp_is_logic_busy(device_data))
 214                 cpu_relax();
 215 
 216         switch (key_reg_index) {
 217         case CRYP_KEY_REG_1:
 218                 writel_relaxed(key_value.key_value_left,
 219                                 &device_data->base->key_1_l);
 220                 writel_relaxed(key_value.key_value_right,
 221                                 &device_data->base->key_1_r);
 222                 break;
 223         case CRYP_KEY_REG_2:
 224                 writel_relaxed(key_value.key_value_left,
 225                                 &device_data->base->key_2_l);
 226                 writel_relaxed(key_value.key_value_right,
 227                                 &device_data->base->key_2_r);
 228                 break;
 229         case CRYP_KEY_REG_3:
 230                 writel_relaxed(key_value.key_value_left,
 231                                 &device_data->base->key_3_l);
 232                 writel_relaxed(key_value.key_value_right,
 233                                 &device_data->base->key_3_r);
 234                 break;
 235         case CRYP_KEY_REG_4:
 236                 writel_relaxed(key_value.key_value_left,
 237                                 &device_data->base->key_4_l);
 238                 writel_relaxed(key_value.key_value_right,
 239                                 &device_data->base->key_4_r);
 240                 break;
 241         default:
 242                 return -EINVAL;
 243         }
 244 
 245         return 0;
 246 }
 247 
 248 /**
 249  * cryp_configure_init_vector - configures the initialization vector register
 250  * @device_data: Pointer to the device data struct for base address.
 251  * @init_vector_index: Specifies the index of the init vector.
 252  * @init_vector_value: Specifies the value for the init vector.
 253  */
 254 int cryp_configure_init_vector(struct cryp_device_data *device_data,
 255                                enum cryp_init_vector_index
 256                                init_vector_index,
 257                                struct cryp_init_vector_value
 258                                init_vector_value)
 259 {
 260         while (cryp_is_logic_busy(device_data))
 261                 cpu_relax();
 262 
 263         switch (init_vector_index) {
 264         case CRYP_INIT_VECTOR_INDEX_0:
 265                 writel_relaxed(init_vector_value.init_value_left,
 266                        &device_data->base->init_vect_0_l);
 267                 writel_relaxed(init_vector_value.init_value_right,
 268                        &device_data->base->init_vect_0_r);
 269                 break;
 270         case CRYP_INIT_VECTOR_INDEX_1:
 271                 writel_relaxed(init_vector_value.init_value_left,
 272                        &device_data->base->init_vect_1_l);
 273                 writel_relaxed(init_vector_value.init_value_right,
 274                        &device_data->base->init_vect_1_r);
 275                 break;
 276         default:
 277                 return -EINVAL;
 278         }
 279 
 280         return 0;
 281 }
 282 
 283 /**
 284  * cryp_save_device_context -   Store hardware registers and
 285  *                              other device context parameter
 286  * @device_data: Pointer to the device data struct for base address.
 287  * @ctx: Crypto device context
 288  */
 289 void cryp_save_device_context(struct cryp_device_data *device_data,
 290                               struct cryp_device_context *ctx,
 291                               int cryp_mode)
 292 {
 293         enum cryp_algo_mode algomode;
 294         struct cryp_register __iomem *src_reg = device_data->base;
 295         struct cryp_config *config =
 296                 (struct cryp_config *)device_data->current_ctx;
 297 
 298         /*
 299          * Always start by disable the hardware and wait for it to finish the
 300          * ongoing calculations before trying to reprogram it.
 301          */
 302         cryp_activity(device_data, CRYP_CRYPEN_DISABLE);
 303         cryp_wait_until_done(device_data);
 304 
 305         if (cryp_mode == CRYP_MODE_DMA)
 306                 cryp_configure_for_dma(device_data, CRYP_DMA_DISABLE_BOTH);
 307 
 308         if (CRYP_TEST_BITS(&src_reg->sr, CRYP_SR_IFEM_MASK) == 0)
 309                 ctx->din = readl_relaxed(&src_reg->din);
 310 
 311         ctx->cr = readl_relaxed(&src_reg->cr) & CRYP_CR_CONTEXT_SAVE_MASK;
 312 
 313         switch (config->keysize) {
 314         case CRYP_KEY_SIZE_256:
 315                 ctx->key_4_l = readl_relaxed(&src_reg->key_4_l);
 316                 ctx->key_4_r = readl_relaxed(&src_reg->key_4_r);
 317                 /* Fall through */
 318 
 319         case CRYP_KEY_SIZE_192:
 320                 ctx->key_3_l = readl_relaxed(&src_reg->key_3_l);
 321                 ctx->key_3_r = readl_relaxed(&src_reg->key_3_r);
 322                 /* Fall through */
 323 
 324         case CRYP_KEY_SIZE_128:
 325                 ctx->key_2_l = readl_relaxed(&src_reg->key_2_l);
 326                 ctx->key_2_r = readl_relaxed(&src_reg->key_2_r);
 327                 /* Fall through */
 328 
 329         default:
 330                 ctx->key_1_l = readl_relaxed(&src_reg->key_1_l);
 331                 ctx->key_1_r = readl_relaxed(&src_reg->key_1_r);
 332         }
 333 
 334         /* Save IV for CBC mode for both AES and DES. */
 335         algomode = ((ctx->cr & CRYP_CR_ALGOMODE_MASK) >> CRYP_CR_ALGOMODE_POS);
 336         if (algomode == CRYP_ALGO_TDES_CBC ||
 337             algomode == CRYP_ALGO_DES_CBC ||
 338             algomode == CRYP_ALGO_AES_CBC) {
 339                 ctx->init_vect_0_l = readl_relaxed(&src_reg->init_vect_0_l);
 340                 ctx->init_vect_0_r = readl_relaxed(&src_reg->init_vect_0_r);
 341                 ctx->init_vect_1_l = readl_relaxed(&src_reg->init_vect_1_l);
 342                 ctx->init_vect_1_r = readl_relaxed(&src_reg->init_vect_1_r);
 343         }
 344 }
 345 
 346 /**
 347  * cryp_restore_device_context -        Restore hardware registers and
 348  *                                      other device context parameter
 349  * @device_data: Pointer to the device data struct for base address.
 350  * @ctx: Crypto device context
 351  */
 352 void cryp_restore_device_context(struct cryp_device_data *device_data,
 353                                  struct cryp_device_context *ctx)
 354 {
 355         struct cryp_register __iomem *reg = device_data->base;
 356         struct cryp_config *config =
 357                 (struct cryp_config *)device_data->current_ctx;
 358 
 359         /*
 360          * Fall through for all items in switch statement. DES is captured in
 361          * the default.
 362          */
 363         switch (config->keysize) {
 364         case CRYP_KEY_SIZE_256:
 365                 writel_relaxed(ctx->key_4_l, &reg->key_4_l);
 366                 writel_relaxed(ctx->key_4_r, &reg->key_4_r);
 367                 /* Fall through */
 368 
 369         case CRYP_KEY_SIZE_192:
 370                 writel_relaxed(ctx->key_3_l, &reg->key_3_l);
 371                 writel_relaxed(ctx->key_3_r, &reg->key_3_r);
 372                 /* Fall through */
 373 
 374         case CRYP_KEY_SIZE_128:
 375                 writel_relaxed(ctx->key_2_l, &reg->key_2_l);
 376                 writel_relaxed(ctx->key_2_r, &reg->key_2_r);
 377                 /* Fall through */
 378 
 379         default:
 380                 writel_relaxed(ctx->key_1_l, &reg->key_1_l);
 381                 writel_relaxed(ctx->key_1_r, &reg->key_1_r);
 382         }
 383 
 384         /* Restore IV for CBC mode for AES and DES. */
 385         if (config->algomode == CRYP_ALGO_TDES_CBC ||
 386             config->algomode == CRYP_ALGO_DES_CBC ||
 387             config->algomode == CRYP_ALGO_AES_CBC) {
 388                 writel_relaxed(ctx->init_vect_0_l, &reg->init_vect_0_l);
 389                 writel_relaxed(ctx->init_vect_0_r, &reg->init_vect_0_r);
 390                 writel_relaxed(ctx->init_vect_1_l, &reg->init_vect_1_l);
 391                 writel_relaxed(ctx->init_vect_1_r, &reg->init_vect_1_r);
 392         }
 393 }

/* [<][>][^][v][top][bottom][index][help] */