+
+ /* Wait for instruction queue to become empty */
+ cnt = 0;
+ do {
+ lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
+ if (lf_inprog.s.grb_partial)
+ cnt = 0;
+ else
+ cnt++;
+ grp_ptr.u = plt_read64(lf->rbase + CPT_LF_Q_GRP_PTR);
+ } while ((cnt < 10) && (grp_ptr.s.nq_ptr != grp_ptr.s.dq_ptr));
+
+ cnt = 0;
+ do {
+ lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
+ if ((lf_inprog.s.inflight == 0) && (lf_inprog.s.gwb_cnt < 40) &&
+ ((lf_inprog.s.grb_cnt == 0) || (lf_inprog.s.grb_cnt == 40)))
+ cnt++;
+ else
+ cnt = 0;
+ } while (cnt < 10);
+}
+
+void
+roc_cpt_iq_enable(struct roc_cpt_lf *lf)
+{
+ union cpt_lf_inprog lf_inprog;
+ union cpt_lf_ctl lf_ctl;
+
+ /* Disable command queue */
+ roc_cpt_iq_disable(lf);
+
+ /* Enable instruction queue enqueuing */
+ lf_ctl.u = plt_read64(lf->rbase + CPT_LF_CTL);
+ lf_ctl.s.ena = 1;
+ lf_ctl.s.fc_ena = 1;
+ lf_ctl.s.fc_up_crossing = 0;
+ lf_ctl.s.fc_hyst_bits = lf->fc_hyst_bits;
+ plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL);
+
+ /* Enable command queue execution */
+ lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
+ lf_inprog.s.eena = 1;
+ plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
+
+ cpt_lf_dump(lf);
+}
+
+int
+roc_cpt_lmtline_init(struct roc_cpt *roc_cpt, struct roc_cpt_lmtline *lmtline,
+ int lf_id)
+{
+ struct roc_cpt_lf *lf;
+
+ lf = roc_cpt->lf[lf_id];
+ if (lf == NULL)
+ return -ENOTSUP;
+
+ lmtline->io_addr = lf->io_addr;
+ if (roc_model_is_cn10k())
+ lmtline->io_addr |= ROC_CN10K_CPT_INST_DW_M1 << 4;
+
+ lmtline->fc_addr = lf->fc_addr;
+ lmtline->lmt_base = lf->lmt_base;
+
+ 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, 8);
+ if (dptr == NULL) {
+ 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);
+ plt_free(dptr);
+
+ return 0;