1010#include <linux/of_address.h>
1111#include <linux/of_irq.h>
1212#include <linux/sys_soc.h>
13+ #include <linux/fsl/mc.h>
1314
1415#include "compat.h"
1516#include "regs.h"
@@ -36,7 +37,8 @@ static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
3637 init_job_desc (desc , 0 );
3738
3839 op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
39- (handle << OP_ALG_AAI_SHIFT ) | OP_ALG_AS_INIT ;
40+ (handle << OP_ALG_AAI_SHIFT ) | OP_ALG_AS_INIT |
41+ OP_ALG_PR_ON ;
4042
4143 /* INIT RNG in non-test mode */
4244 append_operation (desc , op_flags );
@@ -278,12 +280,25 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
278280 return - ENOMEM ;
279281
280282 for (sh_idx = 0 ; sh_idx < RNG4_MAX_HANDLES ; sh_idx ++ ) {
283+ const u32 rdsta_if = RDSTA_IF0 << sh_idx ;
284+ const u32 rdsta_pr = RDSTA_PR0 << sh_idx ;
285+ const u32 rdsta_mask = rdsta_if | rdsta_pr ;
281286 /*
282287 * If the corresponding bit is set, this state handle
283288 * was initialized by somebody else, so it's left alone.
284289 */
285- if ((1 << sh_idx ) & state_handle_mask )
286- continue ;
290+ if (rdsta_if & state_handle_mask ) {
291+ if (rdsta_pr & state_handle_mask )
292+ continue ;
293+
294+ dev_info (ctrldev ,
295+ "RNG4 SH%d was previously instantiated without prediction resistance. Tearing it down\n" ,
296+ sh_idx );
297+
298+ ret = deinstantiate_rng (ctrldev , rdsta_if );
299+ if (ret )
300+ break ;
301+ }
287302
288303 /* Create the descriptor for instantiating RNG State Handle */
289304 build_instantiation_desc (desc , sh_idx , gen_sk );
@@ -303,9 +318,9 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
303318 if (ret )
304319 break ;
305320
306- rdsta_val = rd_reg32 (& ctrl -> r4tst [0 ].rdsta ) & RDSTA_IFMASK ;
321+ rdsta_val = rd_reg32 (& ctrl -> r4tst [0 ].rdsta ) & RDSTA_MASK ;
307322 if ((status && status != JRSTA_SSRC_JUMP_HALT_CC ) ||
308- ! (rdsta_val & ( 1 << sh_idx )) ) {
323+ (rdsta_val & rdsta_mask ) != rdsta_mask ) {
309324 ret = - EAGAIN ;
310325 break ;
311326 }
@@ -564,6 +579,26 @@ static void caam_remove_debugfs(void *root)
564579}
565580#endif
566581
582+ #ifdef CONFIG_FSL_MC_BUS
583+ static bool check_version (struct fsl_mc_version * mc_version , u32 major ,
584+ u32 minor , u32 revision )
585+ {
586+ if (mc_version -> major > major )
587+ return true;
588+
589+ if (mc_version -> major == major ) {
590+ if (mc_version -> minor > minor )
591+ return true;
592+
593+ if (mc_version -> minor == minor &&
594+ mc_version -> revision > revision )
595+ return true;
596+ }
597+
598+ return false;
599+ }
600+ #endif
601+
567602/* Probe routine for CAAM top (controller) level */
568603static int caam_probe (struct platform_device * pdev )
569604{
@@ -582,6 +617,7 @@ static int caam_probe(struct platform_device *pdev)
582617 u8 rng_vid ;
583618 int pg_size ;
584619 int BLOCK_OFFSET = 0 ;
620+ bool pr_support = false;
585621
586622 ctrlpriv = devm_kzalloc (& pdev -> dev , sizeof (* ctrlpriv ), GFP_KERNEL );
587623 if (!ctrlpriv )
@@ -667,17 +703,28 @@ static int caam_probe(struct platform_device *pdev)
667703
668704 /* Get the IRQ of the controller (for security violations only) */
669705 ctrlpriv -> secvio_irq = irq_of_parse_and_map (nprop , 0 );
706+ np = of_find_compatible_node (NULL , NULL , "fsl,qoriq-mc" );
707+ ctrlpriv -> mc_en = !!np ;
708+ of_node_put (np );
709+
710+ #ifdef CONFIG_FSL_MC_BUS
711+ if (ctrlpriv -> mc_en ) {
712+ struct fsl_mc_version * mc_version ;
713+
714+ mc_version = fsl_mc_get_version ();
715+ if (mc_version )
716+ pr_support = check_version (mc_version , 10 , 20 , 0 );
717+ else
718+ return - EPROBE_DEFER ;
719+ }
720+ #endif
670721
671722 /*
672723 * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
673724 * long pointers in master configuration register.
674725 * In case of SoCs with Management Complex, MC f/w performs
675726 * the configuration.
676727 */
677- np = of_find_compatible_node (NULL , NULL , "fsl,qoriq-mc" );
678- ctrlpriv -> mc_en = !!np ;
679- of_node_put (np );
680-
681728 if (!ctrlpriv -> mc_en )
682729 clrsetbits_32 (& ctrl -> mcr , MCFGR_AWCACHE_MASK ,
683730 MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
@@ -784,7 +831,7 @@ static int caam_probe(struct platform_device *pdev)
784831 * already instantiated, do RNG instantiation
785832 * In case of SoCs with Management Complex, RNG is managed by MC f/w.
786833 */
787- if (!ctrlpriv -> mc_en && rng_vid >= 4 ) {
834+ if (!( ctrlpriv -> mc_en && pr_support ) && rng_vid >= 4 ) {
788835 ctrlpriv -> rng4_sh_init =
789836 rd_reg32 (& ctrl -> r4tst [0 ].rdsta );
790837 /*
@@ -794,11 +841,11 @@ static int caam_probe(struct platform_device *pdev)
794841 * to regenerate these keys before the next POR.
795842 */
796843 gen_sk = ctrlpriv -> rng4_sh_init & RDSTA_SKVN ? 0 : 1 ;
797- ctrlpriv -> rng4_sh_init &= RDSTA_IFMASK ;
844+ ctrlpriv -> rng4_sh_init &= RDSTA_MASK ;
798845 do {
799846 int inst_handles =
800847 rd_reg32 (& ctrl -> r4tst [0 ].rdsta ) &
801- RDSTA_IFMASK ;
848+ RDSTA_MASK ;
802849 /*
803850 * If either SH were instantiated by somebody else
804851 * (e.g. u-boot) then it is assumed that the entropy
@@ -838,7 +885,7 @@ static int caam_probe(struct platform_device *pdev)
838885 * Set handles init'ed by this module as the complement of the
839886 * already initialized ones
840887 */
841- ctrlpriv -> rng4_sh_init = ~ctrlpriv -> rng4_sh_init & RDSTA_IFMASK ;
888+ ctrlpriv -> rng4_sh_init = ~ctrlpriv -> rng4_sh_init & RDSTA_MASK ;
842889
843890 /* Enable RDB bit so that RNG works faster */
844891 clrsetbits_32 (& ctrl -> scfgr , 0 , SCFGR_RDBENABLE );
0 commit comments