FIELD_PREP(OP_LCSR_A_SRC, areg) |
                FIELD_PREP(OP_LCSR_B_SRC, breg) |
                FIELD_PREP(OP_LCSR_WRITE, wr) |
-               FIELD_PREP(OP_LCSR_ADDR, addr) |
+               FIELD_PREP(OP_LCSR_ADDR, addr / 4) |
                FIELD_PREP(OP_LCSR_SRC_LMEXTN, src_lmextn) |
                FIELD_PREP(OP_LCSR_DST_LMEXTN, dst_lmextn);
 
                return;
        }
 
-       __emit_lcsr(nfp_prog, reg.areg, reg.breg, true, addr / 4,
+       __emit_lcsr(nfp_prog, reg.areg, reg.breg, true, addr,
                    false, reg.src_lmextn);
 }
 
+/* CSR value is read in following immed[gpr, 0] */
+static void __emit_csr_rd(struct nfp_prog *nfp_prog, u16 addr)
+{
+       __emit_lcsr(nfp_prog, 0, 0, false, addr, false, false);
+}
+
 static void emit_nop(struct nfp_prog *nfp_prog)
 {
        __emit_immed(nfp_prog, UR_REG_IMM, UR_REG_IMM, 0, 0, 0, 0, 0, 0, 0);
        return 0;
 }
 
+static int
+nfp_get_prandom_u32(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       __emit_csr_rd(nfp_prog, NFP_CSR_PSEUDO_RND_NUM);
+       /* CSR value is read in following immed[gpr, 0] */
+       emit_immed(nfp_prog, reg_both(0), 0,
+                  IMMED_WIDTH_ALL, false, IMMED_SHIFT_0B);
+       emit_immed(nfp_prog, reg_both(1), 0,
+                  IMMED_WIDTH_ALL, false, IMMED_SHIFT_0B);
+       return 0;
+}
+
 /* --- Callbacks --- */
 static int mov_reg64(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
        case BPF_FUNC_map_update_elem:
        case BPF_FUNC_map_delete_elem:
                return map_call_stack_common(nfp_prog, meta);
+       case BPF_FUNC_get_prandom_u32:
+               return nfp_get_prandom_u32(nfp_prog, meta);
        default:
                WARN_ONCE(1, "verifier allowed unsupported function\n");
                return -EOPNOTSUPP;
 
        return 0;
 }
 
+static int
+nfp_bpf_parse_cap_random(struct nfp_app_bpf *bpf, void __iomem *value,
+                        u32 length)
+{
+       bpf->pseudo_random = true;
+       return 0;
+}
+
 static int nfp_bpf_parse_capabilities(struct nfp_app *app)
 {
        struct nfp_cpp *cpp = app->pf->cpp;
                        if (nfp_bpf_parse_cap_maps(app->priv, value, length))
                                goto err_release_free;
                        break;
+               case NFP_BPF_CAP_TYPE_RANDOM:
+                       if (nfp_bpf_parse_cap_random(app->priv, value, length))
+                               goto err_release_free;
+                       break;
                default:
                        nfp_dbg(cpp, "unknown BPF capability: %d\n", type);
                        break;