diff options
Diffstat (limited to 'drivers/crypto/caam/ctrl.c')
| -rw-r--r-- | drivers/crypto/caam/ctrl.c | 418 |
1 files changed, 331 insertions, 87 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index bc6d820812b6..63fb1af2c431 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c | |||
| @@ -16,82 +16,75 @@ | |||
| 16 | #include "error.h" | 16 | #include "error.h" |
| 17 | #include "ctrl.h" | 17 | #include "ctrl.h" |
| 18 | 18 | ||
| 19 | static int caam_remove(struct platform_device *pdev) | ||
| 20 | { | ||
| 21 | struct device *ctrldev; | ||
| 22 | struct caam_drv_private *ctrlpriv; | ||
| 23 | struct caam_drv_private_jr *jrpriv; | ||
| 24 | struct caam_full __iomem *topregs; | ||
| 25 | int ring, ret = 0; | ||
| 26 | |||
| 27 | ctrldev = &pdev->dev; | ||
| 28 | ctrlpriv = dev_get_drvdata(ctrldev); | ||
| 29 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | ||
| 30 | |||
| 31 | /* shut down JobRs */ | ||
| 32 | for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { | ||
| 33 | ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]); | ||
| 34 | jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); | ||
| 35 | irq_dispose_mapping(jrpriv->irq); | ||
| 36 | } | ||
| 37 | |||
| 38 | /* Shut down debug views */ | ||
| 39 | #ifdef CONFIG_DEBUG_FS | ||
| 40 | debugfs_remove_recursive(ctrlpriv->dfs_root); | ||
| 41 | #endif | ||
| 42 | |||
| 43 | /* Unmap controller region */ | ||
| 44 | iounmap(&topregs->ctrl); | ||
| 45 | |||
| 46 | kfree(ctrlpriv->jrdev); | ||
| 47 | kfree(ctrlpriv); | ||
| 48 | |||
| 49 | return ret; | ||
| 50 | } | ||
| 51 | |||
| 52 | /* | 19 | /* |
| 53 | * Descriptor to instantiate RNG State Handle 0 in normal mode and | 20 | * Descriptor to instantiate RNG State Handle 0 in normal mode and |
| 54 | * load the JDKEK, TDKEK and TDSK registers | 21 | * load the JDKEK, TDKEK and TDSK registers |
| 55 | */ | 22 | */ |
| 56 | static void build_instantiation_desc(u32 *desc) | 23 | static void build_instantiation_desc(u32 *desc, int handle, int do_sk) |
| 57 | { | 24 | { |
| 58 | u32 *jump_cmd; | 25 | u32 *jump_cmd, op_flags; |
| 59 | 26 | ||
| 60 | init_job_desc(desc, 0); | 27 | init_job_desc(desc, 0); |
| 61 | 28 | ||
| 29 | op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | ||
| 30 | (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT; | ||
| 31 | |||
| 62 | /* INIT RNG in non-test mode */ | 32 | /* INIT RNG in non-test mode */ |
| 63 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | 33 | append_operation(desc, op_flags); |
| 64 | OP_ALG_AS_INIT); | 34 | |
| 35 | if (!handle && do_sk) { | ||
| 36 | /* | ||
| 37 | * For SH0, Secure Keys must be generated as well | ||
| 38 | */ | ||
| 39 | |||
| 40 | /* wait for done */ | ||
| 41 | jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1); | ||
| 42 | set_jump_tgt_here(desc, jump_cmd); | ||
| 43 | |||
| 44 | /* | ||
| 45 | * load 1 to clear written reg: | ||
| 46 | * resets the done interrrupt and returns the RNG to idle. | ||
| 47 | */ | ||
| 48 | append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW); | ||
| 49 | |||
| 50 | /* Initialize State Handle */ | ||
| 51 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | ||
| 52 | OP_ALG_AAI_RNG4_SK); | ||
| 53 | } | ||
| 65 | 54 | ||
| 66 | /* wait for done */ | 55 | append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); |
| 67 | jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1); | 56 | } |
| 68 | set_jump_tgt_here(desc, jump_cmd); | ||
| 69 | 57 | ||
| 70 | /* | 58 | /* Descriptor for deinstantiation of State Handle 0 of the RNG block. */ |
| 71 | * load 1 to clear written reg: | 59 | static void build_deinstantiation_desc(u32 *desc, int handle) |
| 72 | * resets the done interrupt and returns the RNG to idle. | 60 | { |
| 73 | */ | 61 | init_job_desc(desc, 0); |
| 74 | append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW); | ||
| 75 | 62 | ||
| 76 | /* generate secure keys (non-test) */ | 63 | /* Uninstantiate State Handle 0 */ |
| 77 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | | 64 | append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | |
| 78 | OP_ALG_RNG4_SK); | 65 | (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL); |
| 66 | |||
| 67 | append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT); | ||
| 79 | } | 68 | } |
| 80 | 69 | ||
| 81 | static int instantiate_rng(struct device *ctrldev) | 70 | /* |
| 71 | * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of | ||
| 72 | * the software (no JR/QI used). | ||
| 73 | * @ctrldev - pointer to device | ||
| 74 | * @status - descriptor status, after being run | ||
| 75 | * | ||
| 76 | * Return: - 0 if no error occurred | ||
| 77 | * - -ENODEV if the DECO couldn't be acquired | ||
| 78 | * - -EAGAIN if an error occurred while executing the descriptor | ||
| 79 | */ | ||
| 80 | static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc, | ||
| 81 | u32 *status) | ||
| 82 | { | 82 | { |
| 83 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | 83 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); |
| 84 | struct caam_full __iomem *topregs; | 84 | struct caam_full __iomem *topregs; |
| 85 | unsigned int timeout = 100000; | 85 | unsigned int timeout = 100000; |
| 86 | u32 *desc; | 86 | u32 deco_dbg_reg, flags; |
| 87 | int i, ret = 0; | 87 | int i; |
| 88 | |||
| 89 | desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA); | ||
| 90 | if (!desc) { | ||
| 91 | dev_err(ctrldev, "can't allocate RNG init descriptor memory\n"); | ||
| 92 | return -ENOMEM; | ||
| 93 | } | ||
| 94 | build_instantiation_desc(desc); | ||
| 95 | 88 | ||
| 96 | /* Set the bit to request direct access to DECO0 */ | 89 | /* Set the bit to request direct access to DECO0 */ |
| 97 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | 90 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; |
| @@ -103,36 +96,219 @@ static int instantiate_rng(struct device *ctrldev) | |||
| 103 | 96 | ||
| 104 | if (!timeout) { | 97 | if (!timeout) { |
| 105 | dev_err(ctrldev, "failed to acquire DECO 0\n"); | 98 | dev_err(ctrldev, "failed to acquire DECO 0\n"); |
| 106 | ret = -EIO; | 99 | clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE); |
| 107 | goto out; | 100 | return -ENODEV; |
| 108 | } | 101 | } |
| 109 | 102 | ||
| 110 | for (i = 0; i < desc_len(desc); i++) | 103 | for (i = 0; i < desc_len(desc); i++) |
| 111 | topregs->deco.descbuf[i] = *(desc + i); | 104 | wr_reg32(&topregs->deco.descbuf[i], *(desc + i)); |
| 105 | |||
| 106 | flags = DECO_JQCR_WHL; | ||
| 107 | /* | ||
| 108 | * If the descriptor length is longer than 4 words, then the | ||
| 109 | * FOUR bit in JRCTRL register must be set. | ||
| 110 | */ | ||
| 111 | if (desc_len(desc) >= 4) | ||
| 112 | flags |= DECO_JQCR_FOUR; | ||
| 112 | 113 | ||
| 113 | wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR); | 114 | /* Instruct the DECO to execute it */ |
| 115 | wr_reg32(&topregs->deco.jr_ctl_hi, flags); | ||
| 114 | 116 | ||
| 115 | timeout = 10000000; | 117 | timeout = 10000000; |
| 116 | while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) && | 118 | do { |
| 117 | --timeout) | 119 | deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg); |
| 120 | /* | ||
| 121 | * If an error occured in the descriptor, then | ||
| 122 | * the DECO status field will be set to 0x0D | ||
| 123 | */ | ||
| 124 | if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) == | ||
| 125 | DESC_DBG_DECO_STAT_HOST_ERR) | ||
| 126 | break; | ||
| 118 | cpu_relax(); | 127 | cpu_relax(); |
| 128 | } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout); | ||
| 119 | 129 | ||
| 120 | if (!timeout) { | 130 | *status = rd_reg32(&topregs->deco.op_status_hi) & |
| 121 | dev_err(ctrldev, "failed to instantiate RNG\n"); | 131 | DECO_OP_STATUS_HI_ERR_MASK; |
| 122 | ret = -EIO; | ||
| 123 | } | ||
| 124 | 132 | ||
| 133 | /* Mark the DECO as free */ | ||
| 125 | clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE); | 134 | clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE); |
| 126 | out: | 135 | |
| 136 | if (!timeout) | ||
| 137 | return -EAGAIN; | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | /* | ||
| 143 | * instantiate_rng - builds and executes a descriptor on DECO0, | ||
| 144 | * which initializes the RNG block. | ||
| 145 | * @ctrldev - pointer to device | ||
| 146 | * @state_handle_mask - bitmask containing the instantiation status | ||
| 147 | * for the RNG4 state handles which exist in | ||
| 148 | * the RNG4 block: 1 if it's been instantiated | ||
| 149 | * by an external entry, 0 otherwise. | ||
| 150 | * @gen_sk - generate data to be loaded into the JDKEK, TDKEK and TDSK; | ||
| 151 | * Caution: this can be done only once; if the keys need to be | ||
| 152 | * regenerated, a POR is required | ||
| 153 | * | ||
| 154 | * Return: - 0 if no error occurred | ||
| 155 | * - -ENOMEM if there isn't enough memory to allocate the descriptor | ||
| 156 | * - -ENODEV if DECO0 couldn't be acquired | ||
| 157 | * - -EAGAIN if an error occurred when executing the descriptor | ||
| 158 | * f.i. there was a RNG hardware error due to not "good enough" | ||
| 159 | * entropy being aquired. | ||
| 160 | */ | ||
| 161 | static int instantiate_rng(struct device *ctrldev, int state_handle_mask, | ||
| 162 | int gen_sk) | ||
| 163 | { | ||
| 164 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | ||
| 165 | struct caam_full __iomem *topregs; | ||
| 166 | struct rng4tst __iomem *r4tst; | ||
| 167 | u32 *desc, status, rdsta_val; | ||
| 168 | int ret = 0, sh_idx; | ||
| 169 | |||
| 170 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | ||
| 171 | r4tst = &topregs->ctrl.r4tst[0]; | ||
| 172 | |||
| 173 | desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL); | ||
| 174 | if (!desc) | ||
| 175 | return -ENOMEM; | ||
| 176 | |||
| 177 | for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { | ||
| 178 | /* | ||
| 179 | * If the corresponding bit is set, this state handle | ||
| 180 | * was initialized by somebody else, so it's left alone. | ||
| 181 | */ | ||
| 182 | if ((1 << sh_idx) & state_handle_mask) | ||
| 183 | continue; | ||
| 184 | |||
| 185 | /* Create the descriptor for instantiating RNG State Handle */ | ||
| 186 | build_instantiation_desc(desc, sh_idx, gen_sk); | ||
| 187 | |||
| 188 | /* Try to run it through DECO0 */ | ||
| 189 | ret = run_descriptor_deco0(ctrldev, desc, &status); | ||
| 190 | |||
| 191 | /* | ||
| 192 | * If ret is not 0, or descriptor status is not 0, then | ||
| 193 | * something went wrong. No need to try the next state | ||
| 194 | * handle (if available), bail out here. | ||
| 195 | * Also, if for some reason, the State Handle didn't get | ||
| 196 | * instantiated although the descriptor has finished | ||
| 197 | * without any error (HW optimizations for later | ||
| 198 | * CAAM eras), then try again. | ||
| 199 | */ | ||
| 200 | rdsta_val = | ||
| 201 | rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IFMASK; | ||
| 202 | if (status || !(rdsta_val & (1 << sh_idx))) | ||
| 203 | ret = -EAGAIN; | ||
| 204 | if (ret) | ||
| 205 | break; | ||
| 206 | |||
| 207 | dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx); | ||
| 208 | /* Clear the contents before recreating the descriptor */ | ||
| 209 | memset(desc, 0x00, CAAM_CMD_SZ * 7); | ||
| 210 | } | ||
| 211 | |||
| 127 | kfree(desc); | 212 | kfree(desc); |
| 213 | |||
| 128 | return ret; | 214 | return ret; |
| 129 | } | 215 | } |
| 130 | 216 | ||
| 131 | /* | 217 | /* |
| 132 | * By default, the TRNG runs for 200 clocks per sample; | 218 | * deinstantiate_rng - builds and executes a descriptor on DECO0, |
| 133 | * 1600 clocks per sample generates better entropy. | 219 | * which deinitializes the RNG block. |
| 220 | * @ctrldev - pointer to device | ||
| 221 | * @state_handle_mask - bitmask containing the instantiation status | ||
| 222 | * for the RNG4 state handles which exist in | ||
| 223 | * the RNG4 block: 1 if it's been instantiated | ||
| 224 | * | ||
| 225 | * Return: - 0 if no error occurred | ||
| 226 | * - -ENOMEM if there isn't enough memory to allocate the descriptor | ||
| 227 | * - -ENODEV if DECO0 couldn't be acquired | ||
| 228 | * - -EAGAIN if an error occurred when executing the descriptor | ||
| 134 | */ | 229 | */ |
| 135 | static void kick_trng(struct platform_device *pdev) | 230 | static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) |
| 231 | { | ||
| 232 | u32 *desc, status; | ||
| 233 | int sh_idx, ret = 0; | ||
| 234 | |||
| 235 | desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL); | ||
| 236 | if (!desc) | ||
| 237 | return -ENOMEM; | ||
| 238 | |||
| 239 | for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { | ||
| 240 | /* | ||
| 241 | * If the corresponding bit is set, then it means the state | ||
| 242 | * handle was initialized by us, and thus it needs to be | ||
| 243 | * deintialized as well | ||
| 244 | */ | ||
| 245 | if ((1 << sh_idx) & state_handle_mask) { | ||
| 246 | /* | ||
| 247 | * Create the descriptor for deinstantating this state | ||
| 248 | * handle | ||
| 249 | */ | ||
| 250 | build_deinstantiation_desc(desc, sh_idx); | ||
| 251 | |||
| 252 | /* Try to run it through DECO0 */ | ||
| 253 | ret = run_descriptor_deco0(ctrldev, desc, &status); | ||
| 254 | |||
| 255 | if (ret || status) { | ||
| 256 | dev_err(ctrldev, | ||
| 257 | "Failed to deinstantiate RNG4 SH%d\n", | ||
| 258 | sh_idx); | ||
| 259 | break; | ||
| 260 | } | ||
| 261 | dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx); | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | kfree(desc); | ||
| 266 | |||
| 267 | return ret; | ||
| 268 | } | ||
| 269 | |||
| 270 | static int caam_remove(struct platform_device *pdev) | ||
| 271 | { | ||
| 272 | struct device *ctrldev; | ||
| 273 | struct caam_drv_private *ctrlpriv; | ||
| 274 | struct caam_full __iomem *topregs; | ||
| 275 | int ring, ret = 0; | ||
| 276 | |||
| 277 | ctrldev = &pdev->dev; | ||
| 278 | ctrlpriv = dev_get_drvdata(ctrldev); | ||
| 279 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | ||
| 280 | |||
| 281 | /* Remove platform devices for JobRs */ | ||
| 282 | for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { | ||
| 283 | if (ctrlpriv->jrpdev[ring]) | ||
| 284 | of_device_unregister(ctrlpriv->jrpdev[ring]); | ||
| 285 | } | ||
| 286 | |||
| 287 | /* De-initialize RNG state handles initialized by this driver. */ | ||
| 288 | if (ctrlpriv->rng4_sh_init) | ||
| 289 | deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); | ||
| 290 | |||
| 291 | /* Shut down debug views */ | ||
| 292 | #ifdef CONFIG_DEBUG_FS | ||
| 293 | debugfs_remove_recursive(ctrlpriv->dfs_root); | ||
| 294 | #endif | ||
| 295 | |||
| 296 | /* Unmap controller region */ | ||
| 297 | iounmap(&topregs->ctrl); | ||
| 298 | |||
| 299 | kfree(ctrlpriv->jrpdev); | ||
| 300 | kfree(ctrlpriv); | ||
| 301 | |||
| 302 | return ret; | ||
| 303 | } | ||
| 304 | |||
| 305 | /* | ||
| 306 | * kick_trng - sets the various parameters for enabling the initialization | ||
| 307 | * of the RNG4 block in CAAM | ||
| 308 | * @pdev - pointer to the platform device | ||
| 309 | * @ent_delay - Defines the length (in system clocks) of each entropy sample. | ||
| 310 | */ | ||
| 311 | static void kick_trng(struct platform_device *pdev, int ent_delay) | ||
| 136 | { | 312 | { |
| 137 | struct device *ctrldev = &pdev->dev; | 313 | struct device *ctrldev = &pdev->dev; |
| 138 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | 314 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); |
| @@ -145,14 +321,31 @@ static void kick_trng(struct platform_device *pdev) | |||
| 145 | 321 | ||
| 146 | /* put RNG4 into program mode */ | 322 | /* put RNG4 into program mode */ |
| 147 | setbits32(&r4tst->rtmctl, RTMCTL_PRGM); | 323 | setbits32(&r4tst->rtmctl, RTMCTL_PRGM); |
| 148 | /* 1600 clocks per sample */ | 324 | |
| 325 | /* | ||
| 326 | * Performance-wise, it does not make sense to | ||
| 327 | * set the delay to a value that is lower | ||
| 328 | * than the last one that worked (i.e. the state handles | ||
| 329 | * were instantiated properly. Thus, instead of wasting | ||
| 330 | * time trying to set the values controlling the sample | ||
| 331 | * frequency, the function simply returns. | ||
| 332 | */ | ||
| 333 | val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK) | ||
| 334 | >> RTSDCTL_ENT_DLY_SHIFT; | ||
| 335 | if (ent_delay <= val) { | ||
| 336 | /* put RNG4 into run mode */ | ||
| 337 | clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); | ||
| 338 | return; | ||
| 339 | } | ||
| 340 | |||
| 149 | val = rd_reg32(&r4tst->rtsdctl); | 341 | val = rd_reg32(&r4tst->rtsdctl); |
| 150 | val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT); | 342 | val = (val & ~RTSDCTL_ENT_DLY_MASK) | |
| 343 | (ent_delay << RTSDCTL_ENT_DLY_SHIFT); | ||
| 151 | wr_reg32(&r4tst->rtsdctl, val); | 344 | wr_reg32(&r4tst->rtsdctl, val); |
| 152 | /* min. freq. count */ | 345 | /* min. freq. count, equal to 1/4 of the entropy sample length */ |
| 153 | wr_reg32(&r4tst->rtfrqmin, 400); | 346 | wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2); |
| 154 | /* max. freq. count */ | 347 | /* max. freq. count, equal to 8 times the entropy sample length */ |
| 155 | wr_reg32(&r4tst->rtfrqmax, 6400); | 348 | wr_reg32(&r4tst->rtfrqmax, ent_delay << 3); |
| 156 | /* put RNG4 into run mode */ | 349 | /* put RNG4 into run mode */ |
| 157 | clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); | 350 | clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); |
| 158 | } | 351 | } |
| @@ -193,7 +386,7 @@ EXPORT_SYMBOL(caam_get_era); | |||
| 193 | /* Probe routine for CAAM top (controller) level */ | 386 | /* Probe routine for CAAM top (controller) level */ |
| 194 | static int caam_probe(struct platform_device *pdev) | 387 | static int caam_probe(struct platform_device *pdev) |
| 195 | { | 388 | { |
| 196 | int ret, ring, rspec; | 389 | int ret, ring, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; |
| 197 | u64 caam_id; | 390 | u64 caam_id; |
| 198 | struct device *dev; | 391 | struct device *dev; |
| 199 | struct device_node *nprop, *np; | 392 | struct device_node *nprop, *np; |
| @@ -258,8 +451,9 @@ static int caam_probe(struct platform_device *pdev) | |||
| 258 | rspec++; | 451 | rspec++; |
| 259 | } | 452 | } |
| 260 | 453 | ||
| 261 | ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL); | 454 | ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec, |
| 262 | if (ctrlpriv->jrdev == NULL) { | 455 | GFP_KERNEL); |
| 456 | if (ctrlpriv->jrpdev == NULL) { | ||
| 263 | iounmap(&topregs->ctrl); | 457 | iounmap(&topregs->ctrl); |
| 264 | return -ENOMEM; | 458 | return -ENOMEM; |
| 265 | } | 459 | } |
| @@ -267,13 +461,24 @@ static int caam_probe(struct platform_device *pdev) | |||
| 267 | ring = 0; | 461 | ring = 0; |
| 268 | ctrlpriv->total_jobrs = 0; | 462 | ctrlpriv->total_jobrs = 0; |
| 269 | for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") { | 463 | for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") { |
| 270 | caam_jr_probe(pdev, np, ring); | 464 | ctrlpriv->jrpdev[ring] = |
| 465 | of_platform_device_create(np, NULL, dev); | ||
| 466 | if (!ctrlpriv->jrpdev[ring]) { | ||
| 467 | pr_warn("JR%d Platform device creation error\n", ring); | ||
| 468 | continue; | ||
| 469 | } | ||
| 271 | ctrlpriv->total_jobrs++; | 470 | ctrlpriv->total_jobrs++; |
| 272 | ring++; | 471 | ring++; |
| 273 | } | 472 | } |
| 274 | if (!ring) { | 473 | if (!ring) { |
| 275 | for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") { | 474 | for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") { |
| 276 | caam_jr_probe(pdev, np, ring); | 475 | ctrlpriv->jrpdev[ring] = |
| 476 | of_platform_device_create(np, NULL, dev); | ||
| 477 | if (!ctrlpriv->jrpdev[ring]) { | ||
| 478 | pr_warn("JR%d Platform device creation error\n", | ||
| 479 | ring); | ||
| 480 | continue; | ||
| 481 | } | ||
| 277 | ctrlpriv->total_jobrs++; | 482 | ctrlpriv->total_jobrs++; |
| 278 | ring++; | 483 | ring++; |
| 279 | } | 484 | } |
| @@ -299,16 +504,55 @@ static int caam_probe(struct platform_device *pdev) | |||
| 299 | 504 | ||
| 300 | /* | 505 | /* |
| 301 | * If SEC has RNG version >= 4 and RNG state handle has not been | 506 | * If SEC has RNG version >= 4 and RNG state handle has not been |
| 302 | * already instantiated ,do RNG instantiation | 507 | * already instantiated, do RNG instantiation |
| 303 | */ | 508 | */ |
| 304 | if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 && | 509 | if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) { |
| 305 | !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) { | 510 | ctrlpriv->rng4_sh_init = |
| 306 | kick_trng(pdev); | 511 | rd_reg32(&topregs->ctrl.r4tst[0].rdsta); |
| 307 | ret = instantiate_rng(dev); | 512 | /* |
| 513 | * If the secure keys (TDKEK, JDKEK, TDSK), were already | ||
| 514 | * generated, signal this to the function that is instantiating | ||
| 515 | * the state handles. An error would occur if RNG4 attempts | ||
| 516 | * to regenerate these keys before the next POR. | ||
| 517 | */ | ||
| 518 | gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1; | ||
| 519 | ctrlpriv->rng4_sh_init &= RDSTA_IFMASK; | ||
| 520 | do { | ||
| 521 | int inst_handles = | ||
| 522 | rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & | ||
| 523 | RDSTA_IFMASK; | ||
| 524 | /* | ||
| 525 | * If either SH were instantiated by somebody else | ||
| 526 | * (e.g. u-boot) then it is assumed that the entropy | ||
| 527 | * parameters are properly set and thus the function | ||
| 528 | * setting these (kick_trng(...)) is skipped. | ||
| 529 | * Also, if a handle was instantiated, do not change | ||
| 530 | * the TRNG parameters. | ||
| 531 | */ | ||
| 532 | if (!(ctrlpriv->rng4_sh_init || inst_handles)) { | ||
| 533 | kick_trng(pdev, ent_delay); | ||
| 534 | ent_delay += 400; | ||
| 535 | } | ||
| 536 | /* | ||
| 537 | * if instantiate_rng(...) fails, the loop will rerun | ||
| 538 | * and the kick_trng(...) function will modfiy the | ||
| 539 | * upper and lower limits of the entropy sampling | ||
| 540 | * interval, leading to a sucessful initialization of | ||
| 541 | * the RNG. | ||
| 542 | */ | ||
| 543 | ret = instantiate_rng(dev, inst_handles, | ||
| 544 | gen_sk); | ||
| 545 | } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); | ||
| 308 | if (ret) { | 546 | if (ret) { |
| 547 | dev_err(dev, "failed to instantiate RNG"); | ||
| 309 | caam_remove(pdev); | 548 | caam_remove(pdev); |
| 310 | return ret; | 549 | return ret; |
| 311 | } | 550 | } |
| 551 | /* | ||
| 552 | * Set handles init'ed by this module as the complement of the | ||
| 553 | * already initialized ones | ||
| 554 | */ | ||
| 555 | ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK; | ||
| 312 | 556 | ||
| 313 | /* Enable RDB bit so that RNG works faster */ | 557 | /* Enable RDB bit so that RNG works faster */ |
| 314 | setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE); | 558 | setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE); |
