]> git.droids-corp.org - dpdk.git/commitdiff
common/cnxk: support CPT CTX write through microcode op
authorSrujana Challa <schalla@marvell.com>
Tue, 2 Nov 2021 15:54:12 +0000 (21:24 +0530)
committerJerin Jacob <jerinj@marvell.com>
Wed, 3 Nov 2021 15:05:47 +0000 (16:05 +0100)
Adds APIs to write CPT CTX through microcode op(SET_CTX/WRITE_SA).

Signed-off-by: Srujana Challa <schalla@marvell.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
drivers/common/cnxk/hw/cpt.h
drivers/common/cnxk/roc_cpt.c
drivers/common/cnxk/roc_cpt.h
drivers/common/cnxk/roc_ie_ot.h
drivers/common/cnxk/roc_nix_inl.c
drivers/common/cnxk/roc_nix_inl.h
drivers/common/cnxk/roc_nix_inl_dev.c
drivers/common/cnxk/version.map

index 4d9df59d703aaed62210c71183556c8abe29a84f..919f8420f0d8ccb53276abdc244630c2afabe91c 100644 (file)
@@ -64,8 +64,6 @@ union cpt_lf_ctx_flush {
        struct {
                uint64_t cptr : 46;
                uint64_t inval : 1;
-               uint64_t res : 1;
-               uint64_t pf_func : 16;
        } s;
 };
 
index f0e52ae18f138485a3106e5ab692082e4bbb7eeb..49d8bf223085b9fb4e013233336624b8fce0ad10 100644 (file)
@@ -677,7 +677,7 @@ fail:
 }
 
 int
-roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, uint64_t cptr)
+roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, void *cptr, bool inval)
 {
        union cpt_lf_ctx_flush reg;
 
@@ -685,15 +685,32 @@ roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, uint64_t cptr)
                return -ENOTSUP;
 
        reg.u = 0;
-       reg.s.pf_func = lf->pf_func;
-       reg.s.inval = 1;
-       reg.s.cptr = cptr;
+       reg.s.inval = inval;
+       reg.s.cptr = (uintptr_t)cptr >> 7;
 
        plt_write64(reg.u, lf->rbase + CPT_LF_CTX_FLUSH);
 
        return 0;
 }
 
+int
+roc_cpt_lf_ctx_reload(struct roc_cpt_lf *lf, void *cptr)
+{
+       union cpt_lf_ctx_reload reg;
+
+       if (lf == NULL) {
+               plt_err("Could not trigger CTX reload");
+               return -ENOTSUP;
+       }
+
+       reg.u = 0;
+       reg.s.cptr = (uintptr_t)cptr >> 7;
+
+       plt_write64(reg.u, lf->rbase + CPT_LF_CTX_RELOAD);
+
+       return 0;
+}
+
 void
 cpt_lf_fini(struct roc_cpt_lf *lf)
 {
@@ -890,3 +907,61 @@ roc_cpt_lmtline_init(struct roc_cpt *roc_cpt, struct roc_cpt_lmtline *lmtline,
 
        return 0;
 }
+
+int
+roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
+                 uint16_t sa_len)
+{
+       uintptr_t lmt_base = lf->lmt_base;
+       uint64_t lmt_arg, io_addr;
+       struct cpt_inst_s *inst;
+       union cpt_res_s *res;
+       uint16_t lmt_id;
+       uint64_t *dptr;
+       int i;
+
+       ROC_LMT_CPT_BASE_ID_GET(lmt_base, lmt_id);
+       inst = (struct cpt_inst_s *)lmt_base;
+
+       memset(inst, 0, sizeof(struct cpt_inst_s));
+
+       res = plt_zmalloc(sizeof(*res), ROC_CPT_RES_ALIGN);
+       if (res == NULL) {
+               plt_err("Couldn't allocate memory for result address");
+               return -ENOMEM;
+       }
+       dptr = plt_zmalloc(sa_len, 0);
+       if (!dptr) {
+               plt_err("Couldn't allocate memory for SA dptr");
+               plt_free(res);
+               return -ENOMEM;
+       }
+       for (i = 0; i < (sa_len / 8); i++)
+               dptr[i] = plt_cpu_to_be_64(((uint64_t *)sa_dptr)[i]);
+
+       /* Fill CPT_INST_S for WRITE_SA microcode op */
+       res->cn10k.compcode = CPT_COMP_NOT_DONE;
+       inst->res_addr = (uint64_t)res;
+       inst->dptr = (uint64_t)dptr;
+       inst->w4.s.param2 = sa_len >> 3;
+       inst->w4.s.dlen = sa_len;
+       inst->w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_WRITE_SA;
+       inst->w4.s.opcode_minor = ROC_IE_OT_MINOR_OP_WRITE_SA;
+       inst->w7.s.cptr = (uint64_t)sa_cptr;
+       inst->w7.s.ctx_val = 1;
+       inst->w7.s.egrp = ROC_CPT_DFLT_ENG_GRP_SE_IE;
+
+       lmt_arg = ROC_CN10K_CPT_LMT_ARG | (uint64_t)lmt_id;
+       io_addr = lf->io_addr | ROC_CN10K_CPT_INST_DW_M1 << 4;
+
+       roc_lmt_submit_steorl(lmt_arg, io_addr);
+       plt_wmb();
+
+       /* Wait until CPT instruction completes */
+       while (res->cn10k.compcode == CPT_COMP_NOT_DONE)
+               plt_delay_ms(1);
+
+       plt_free(res);
+
+       return 0;
+}
index e84f1685c8663342943dc7dbce7dbee8bd70b244..12e6b81c4fde0fe7b29da7221ef87ecd0f9fdc10 100644 (file)
@@ -85,6 +85,8 @@
         (((ROC_CPT_CCM_ICV_LEN - 2) / 2) << 3) | (ROC_CPT_CCM_MSG_LEN - 1))
 #define ROC_CPT_CCM_SALT_LEN 3
 
+#define ROC_CPT_RES_ALIGN 16
+
 enum {
        ROC_CPT_REVISION_ID_83XX = 0,
        ROC_CPT_REVISION_ID_96XX_B0 = 1,
@@ -161,7 +163,9 @@ int __roc_api roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf);
 void __roc_api roc_cpt_dev_clear(struct roc_cpt *roc_cpt);
 int __roc_api roc_cpt_lf_init(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf);
 void __roc_api roc_cpt_lf_fini(struct roc_cpt_lf *lf);
-int __roc_api roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, uint64_t cptr);
+int __roc_api roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, void *cptr,
+                                  bool inval);
+int __roc_api roc_cpt_lf_ctx_reload(struct roc_cpt_lf *lf, void *cptr);
 int __roc_api roc_cpt_inline_ipsec_cfg(struct dev *dev, uint8_t slot,
                                       struct roc_nix *nix);
 int __roc_api roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt,
@@ -174,5 +178,7 @@ int __roc_api roc_cpt_lmtline_init(struct roc_cpt *roc_cpt,
                                   struct roc_cpt_lmtline *lmtline, int lf_id);
 
 void __roc_api roc_cpt_parse_hdr_dump(const struct cpt_parse_hdr_s *cpth);
+int __roc_api roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr,
+                               void *sa_cptr, uint16_t sa_len);
 
 #endif /* _ROC_CPT_H_ */
index e8415cff3cbfce80577d6e2932e8dc3e6efe24a4..5b61902519fdbd7c3ed69fdca781ac46d984436d 100644 (file)
 #define ROC_IE_OT_MAJOR_OP_PROCESS_OUTBOUND_IPSEC 0x28UL
 #define ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC  0x29UL
 
+#define ROC_IE_OT_MAJOR_OP_WRITE_SA 0x01UL
+#define ROC_IE_OT_MINOR_OP_WRITE_SA 0x09UL
+
+#define ROC_IE_OT_CTX_ILEN 2
+
 enum roc_ie_ot_ucc_ipsec {
        ROC_IE_OT_UCC_SUCCESS = 0x00,
        ROC_IE_OT_UCC_ERR_SA_INVAL = 0xb0,
index 1d962e31a38dcc34dbdb1944fd79aa1ff1ccc027..3955d9b1cfca8717d1a0ff2d2f4443957db96887 100644 (file)
@@ -23,7 +23,8 @@ nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
        struct nix *nix = roc_nix_to_nix_priv(roc_nix);
        struct roc_nix_ipsec_cfg cfg;
        size_t inb_sa_sz;
-       int rc;
+       int rc, i;
+       void *sa;
 
        /* CN9K SA size is different */
        if (roc_model_is_cn9k())
@@ -39,6 +40,12 @@ nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
                plt_err("Failed to allocate memory for Inbound SA");
                return -ENOMEM;
        }
+       if (roc_model_is_cn10k()) {
+               for (i = 0; i < ipsec_in_max_spi; i++) {
+                       sa = ((uint8_t *)nix->inb_sa_base) + (i * inb_sa_sz);
+                       roc_nix_inl_inb_sa_init(sa);
+               }
+       }
 
        memset(&cfg, 0, sizeof(cfg));
        cfg.sa_size = inb_sa_sz;
@@ -271,6 +278,7 @@ roc_nix_inl_outb_init(struct roc_nix *roc_nix)
        void *sa_base;
        size_t sa_sz;
        int i, j, rc;
+       void *sa;
 
        if (idev == NULL)
                return -ENOTSUP;
@@ -368,6 +376,12 @@ roc_nix_inl_outb_init(struct roc_nix *roc_nix)
                plt_err("Outbound SA base alloc failed");
                goto lf_fini;
        }
+       if (roc_model_is_cn10k()) {
+               for (i = 0; i < roc_nix->ipsec_out_max_sa; i++) {
+                       sa = ((uint8_t *)sa_base) + (i * sa_sz);
+                       roc_nix_inl_outb_sa_init(sa);
+               }
+       }
        nix->outb_sa_base = sa_base;
        nix->outb_sa_sz = sa_sz;
 
@@ -717,6 +731,8 @@ roc_nix_inl_sa_sync(struct roc_nix *roc_nix, void *sa, bool inb,
 {
        struct nix *nix = roc_nix_to_nix_priv(roc_nix);
        struct roc_cpt_lf *outb_lf = nix->cpt_lf_base;
+       struct idev_cfg *idev = idev_get_cfg();
+       struct nix_inl_dev *inl_dev = NULL;
        union cpt_lf_ctx_reload reload;
        union cpt_lf_ctx_flush flush;
        uintptr_t rbase;
@@ -727,13 +743,15 @@ roc_nix_inl_sa_sync(struct roc_nix *roc_nix, void *sa, bool inb,
                return 0;
        }
 
-       if (!inb && !outb_lf)
-               return -EINVAL;
+       if (inb && nix->inb_inl_dev) {
+               outb_lf = NULL;
+               if (idev)
+                       inl_dev = idev->nix_inl_dev;
+               if (inl_dev)
+                       outb_lf = &inl_dev->cpt_lf;
+       }
 
-       /* Performing op via outbound lf is enough
-        * when inline dev is not in use.
-        */
-       if (outb_lf && !nix->inb_inl_dev) {
+       if (outb_lf) {
                rbase = outb_lf->rbase;
 
                flush.u = 0;
@@ -755,10 +773,80 @@ roc_nix_inl_sa_sync(struct roc_nix *roc_nix, void *sa, bool inb,
                }
                return 0;
        }
+       plt_err("Could not get CPT LF for SA sync");
+       return -ENOTSUP;
+}
 
+int
+roc_nix_inl_ctx_write(struct roc_nix *roc_nix, void *sa_dptr, void *sa_cptr,
+                     bool inb, uint16_t sa_len)
+{
+       struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+       struct roc_cpt_lf *outb_lf = nix->cpt_lf_base;
+       struct idev_cfg *idev = idev_get_cfg();
+       struct nix_inl_dev *inl_dev = NULL;
+       union cpt_lf_ctx_flush flush;
+       uintptr_t rbase;
+       int rc;
+
+       /* Nothing much to do on cn9k */
+       if (roc_model_is_cn9k()) {
+               plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
+               return 0;
+       }
+
+       if (inb && nix->inb_inl_dev) {
+               outb_lf = NULL;
+               if (idev)
+                       inl_dev = idev->nix_inl_dev;
+               if (inl_dev && inl_dev->attach_cptlf)
+                       outb_lf = &inl_dev->cpt_lf;
+       }
+
+       if (outb_lf) {
+               rbase = outb_lf->rbase;
+               flush.u = 0;
+
+               rc = roc_cpt_ctx_write(outb_lf, sa_dptr, sa_cptr, sa_len);
+               if (rc)
+                       return rc;
+               /* Trigger CTX flush to write dirty data back to DRAM */
+               flush.s.cptr = ((uintptr_t)sa_cptr) >> 7;
+               plt_write64(flush.u, rbase + CPT_LF_CTX_FLUSH);
+
+               return 0;
+       }
+       plt_nix_dbg("Could not get CPT LF for CTX write");
        return -ENOTSUP;
 }
 
+void
+roc_nix_inl_inb_sa_init(struct roc_ot_ipsec_inb_sa *sa)
+{
+       size_t offset;
+
+       memset(sa, 0, sizeof(struct roc_ot_ipsec_inb_sa));
+
+       offset = offsetof(struct roc_ot_ipsec_inb_sa, ctx);
+       sa->w0.s.hw_ctx_off = offset / ROC_CTX_UNIT_8B;
+       sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
+       sa->w0.s.ctx_size = ROC_IE_OT_CTX_ILEN;
+       sa->w0.s.aop_valid = 1;
+}
+
+void
+roc_nix_inl_outb_sa_init(struct roc_ot_ipsec_outb_sa *sa)
+{
+       size_t offset;
+
+       memset(sa, 0, sizeof(struct roc_ot_ipsec_outb_sa));
+
+       offset = offsetof(struct roc_ot_ipsec_outb_sa, ctx);
+       sa->w0.s.ctx_push_size = (offset / ROC_CTX_UNIT_8B);
+       sa->w0.s.ctx_size = ROC_IE_OT_CTX_ILEN;
+       sa->w0.s.aop_valid = 1;
+}
+
 void
 roc_nix_inl_dev_lock(void)
 {
index ae5e02209eaf43617b0bf73e6d65789523fab3ac..abbeac684a77bcd5b1ae6aab52ec813303d0853a 100644 (file)
@@ -166,5 +166,9 @@ enum roc_nix_inl_sa_sync_op {
 
 int __roc_api roc_nix_inl_sa_sync(struct roc_nix *roc_nix, void *sa, bool inb,
                                  enum roc_nix_inl_sa_sync_op op);
+int __roc_api roc_nix_inl_ctx_write(struct roc_nix *roc_nix, void *sa_dptr,
+                                   void *sa_cptr, bool inb, uint16_t sa_len);
+void __roc_api roc_nix_inl_inb_sa_init(struct roc_ot_ipsec_inb_sa *sa);
+void __roc_api roc_nix_inl_outb_sa_init(struct roc_ot_ipsec_outb_sa *sa);
 
 #endif /* _ROC_NIX_INL_H_ */
index 495dd19bf2000d3b879e8c8e3f5fdbd6dda5cd41..33a59f60bd62c3e8c55db1d9b44b6b0d13f6d741 100644 (file)
@@ -334,7 +334,8 @@ nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
        struct nix_lf_alloc_rsp *rsp;
        struct nix_lf_alloc_req *req;
        size_t inb_sa_sz;
-       int rc = -ENOSPC;
+       int i, rc = -ENOSPC;
+       void *sa;
 
        /* Alloc NIX LF needed for single RQ */
        req = mbox_alloc_msg_nix_lf_alloc(mbox);
@@ -391,6 +392,13 @@ nix_inl_nix_setup(struct nix_inl_dev *inl_dev)
                goto unregister_irqs;
        }
 
+       if (roc_model_is_cn10k()) {
+               for (i = 0; i < ipsec_in_max_spi; i++) {
+                       sa = ((uint8_t *)inl_dev->inb_sa_base) +
+                            (i * inb_sa_sz);
+                       roc_nix_inl_inb_sa_init(sa);
+               }
+       }
        /* Setup device specific inb SA table */
        rc = nix_inl_nix_ipsec_cfg(inl_dev, true);
        if (rc) {
index bf47b33b3e13ff3c1a0d37a06c12a52d6e72c42e..c2333a539047212a477e9d73ae0e02946b180d2f 100644 (file)
@@ -62,12 +62,14 @@ INTERNAL {
        roc_cpt_iq_disable;
        roc_cpt_iq_enable;
        roc_cpt_lf_ctx_flush;
+       roc_cpt_lf_ctx_reload;
        roc_cpt_lf_init;
        roc_cpt_lf_fini;
        roc_cpt_lfs_print;
        roc_cpt_lmtline_init;
        roc_cpt_parse_hdr_dump;
        roc_cpt_rxc_time_cfg;
+       roc_cpt_ctx_write;
        roc_error_msg_get;
        roc_hash_sha1_gen;
        roc_hash_sha256_gen;
@@ -144,6 +146,9 @@ INTERNAL {
        roc_nix_inl_outb_sso_pffunc_get;
        roc_nix_inl_outb_is_enabled;
        roc_nix_inl_sa_sync;
+       roc_nix_inl_ctx_write;
+       roc_nix_inl_inb_sa_init;
+       roc_nix_inl_outb_sa_init;
        roc_nix_is_lbk;
        roc_nix_is_pf;
        roc_nix_is_sdp;