X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fcnxk%2Froc_cpt.c;h=1bc7a29ef95f0715b59362e7d18a29d26bfda3d0;hb=ad5fdb2fc1750f428c7d1c1f344fb2e9c19684e8;hp=fd92de33abb51bd79a23fd0bd3038d0d2c1d1adf;hpb=507dda437fe4ef9811abd5d4a69158e816ec8749;p=dpdk.git diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c index fd92de33ab..1bc7a29ef9 100644 --- a/drivers/common/cnxk/roc_cpt.c +++ b/drivers/common/cnxk/roc_cpt.c @@ -51,6 +51,9 @@ cpt_lf_misc_irq(void *param) plt_err("Err_irq=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf); + /* Dump lf registers */ + cpt_lf_print(lf); + /* Clear interrupt */ plt_write64(intr, lf->rbase + CPT_LF_MISC_INT); } @@ -62,7 +65,7 @@ cpt_lf_register_misc_irq(struct roc_cpt_lf *lf) struct plt_intr_handle *handle; int rc, vec; - handle = &pci_dev->intr_handle; + handle = pci_dev->intr_handle; vec = lf->msixoff + CPT_LF_INT_VEC_MISC; /* Clear err interrupt */ @@ -82,7 +85,7 @@ cpt_lf_unregister_misc_irq(struct roc_cpt_lf *lf) struct plt_intr_handle *handle; int vec; - handle = &pci_dev->intr_handle; + handle = pci_dev->intr_handle; vec = lf->msixoff + CPT_LF_INT_VEC_MISC; /* Clear err interrupt */ @@ -126,7 +129,7 @@ cpt_lf_register_done_irq(struct roc_cpt_lf *lf) struct plt_intr_handle *handle; int rc, vec; - handle = &pci_dev->intr_handle; + handle = pci_dev->intr_handle; vec = lf->msixoff + CPT_LF_INT_VEC_DONE; @@ -149,7 +152,7 @@ cpt_lf_unregister_done_irq(struct roc_cpt_lf *lf) struct plt_intr_handle *handle; int vec; - handle = &pci_dev->intr_handle; + handle = pci_dev->intr_handle; vec = lf->msixoff + CPT_LF_INT_VEC_DONE; @@ -203,7 +206,7 @@ cpt_lf_dump(struct roc_cpt_lf *lf) plt_cpt_dbg("CPT LF REG:"); plt_cpt_dbg("LF_CTL[0x%016llx]: 0x%016" PRIx64, CPT_LF_CTL, plt_read64(lf->rbase + CPT_LF_CTL)); - plt_cpt_dbg("Q_SIZE[0x%016llx]: 0x%016" PRIx64, CPT_LF_INPROG, + plt_cpt_dbg("LF_INPROG[0x%016llx]: 0x%016" PRIx64, CPT_LF_INPROG, plt_read64(lf->rbase + CPT_LF_INPROG)); plt_cpt_dbg("Q_BASE[0x%016llx]: 0x%016" PRIx64, CPT_LF_Q_BASE, @@ -216,6 +219,67 @@ cpt_lf_dump(struct roc_cpt_lf *lf) plt_read64(lf->rbase + CPT_LF_Q_GRP_PTR)); } +int +cpt_lf_outb_cfg(struct dev *dev, uint16_t sso_pf_func, uint16_t nix_pf_func, + uint8_t lf_id, bool ena) +{ + struct cpt_inline_ipsec_cfg_msg *req; + struct mbox *mbox = dev->mbox; + + req = mbox_alloc_msg_cpt_inline_ipsec_cfg(mbox); + if (req == NULL) + return -ENOSPC; + + req->dir = CPT_INLINE_OUTBOUND; + req->slot = lf_id; + if (ena) { + req->enable = 1; + req->sso_pf_func = sso_pf_func; + req->nix_pf_func = nix_pf_func; + } else { + req->enable = 0; + } + + return mbox_process(mbox); +} + +int +roc_cpt_inline_ipsec_cfg(struct dev *cpt_dev, uint8_t lf_id, + struct roc_nix *roc_nix) +{ + bool ena = roc_nix ? true : false; + uint16_t nix_pf_func = 0; + uint16_t sso_pf_func = 0; + + if (ena) { + nix_pf_func = roc_nix_get_pf_func(roc_nix); + sso_pf_func = idev_sso_pffunc_get(); + } + + return cpt_lf_outb_cfg(cpt_dev, sso_pf_func, nix_pf_func, lf_id, ena); +} + +int +roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt, uint16_t param1, + uint16_t param2) +{ + struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt); + struct cpt_rx_inline_lf_cfg_msg *req; + struct mbox *mbox; + + mbox = cpt->dev.mbox; + + req = mbox_alloc_msg_cpt_rx_inline_lf_cfg(mbox); + if (req == NULL) + return -ENOSPC; + + req->sso_pf_func = idev_sso_pffunc_get(); + req->param1 = param1; + req->param2 = param2; + + return mbox_process(mbox); +} + int roc_cpt_rxc_time_cfg(struct roc_cpt *roc_cpt, struct roc_cpt_rxc_time_cfg *cfg) { @@ -306,7 +370,7 @@ cpt_available_lfs_get(struct dev *dev, uint16_t *nb_lf) if (rc) return -EIO; - *nb_lf = rsp->cpt; + *nb_lf = PLT_MAX((uint16_t)rsp->cpt, (uint16_t)rsp->cpt1); return 0; } @@ -320,11 +384,12 @@ cpt_lfs_alloc(struct dev *dev, uint8_t eng_grpmsk, uint8_t blkaddr, if (blkaddr != RVU_BLOCK_ADDR_CPT0 && blkaddr != RVU_BLOCK_ADDR_CPT1) return -EINVAL; - PLT_SET_USED(inl_dev_sso); - req = mbox_alloc_msg_cpt_lf_alloc(mbox); req->nix_pf_func = 0; - req->sso_pf_func = idev_sso_pffunc_get(); + if (inl_dev_sso && nix_inl_dev_pffunc_get()) + req->sso_pf_func = nix_inl_dev_pffunc_get(); + else + req->sso_pf_func = idev_sso_pffunc_get(); req->eng_grpmsk = eng_grpmsk; req->blkaddr = blkaddr; @@ -340,7 +405,7 @@ cpt_lfs_free(struct dev *dev) } static int -cpt_hardware_caps_get(struct dev *dev, union cpt_eng_caps *hw_caps) +cpt_hardware_caps_get(struct dev *dev, struct roc_cpt *roc_cpt) { struct cpt_caps_rsp_msg *rsp; int ret; @@ -351,7 +416,8 @@ cpt_hardware_caps_get(struct dev *dev, union cpt_eng_caps *hw_caps) if (ret) return -EIO; - mbox_memcpy(hw_caps, rsp->eng_caps, + roc_cpt->cpt_revision = rsp->cpt_revision; + mbox_memcpy(roc_cpt->hw_caps, rsp->eng_caps, sizeof(union cpt_eng_caps) * CPT_MAX_ENG_TYPES); return 0; @@ -372,8 +438,10 @@ cpt_lf_iq_mem_calc(uint32_t nb_desc) len += CPT_IQ_FC_LEN; /* For instruction queues */ - len += CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) * CPT_IQ_NB_DESC_MULTIPLIER * - sizeof(struct cpt_inst_s); + len += PLT_ALIGN(CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) * + CPT_IQ_NB_DESC_MULTIPLIER * + sizeof(struct cpt_inst_s), + ROC_ALIGN); return len; } @@ -383,8 +451,6 @@ cpt_iq_init(struct roc_cpt_lf *lf) { union cpt_lf_q_size lf_q_size = {.u = 0x0}; union cpt_lf_q_base lf_q_base = {.u = 0x0}; - union cpt_lf_inprog lf_inprog; - union cpt_lf_ctl lf_ctl; uintptr_t addr; lf->io_addr = lf->rbase + CPT_LF_NQX(0); @@ -404,41 +470,49 @@ cpt_iq_init(struct roc_cpt_lf *lf) lf_q_size.s.size_div40 = CPT_IQ_NB_DESC_SIZE_DIV40(lf->nb_desc); plt_write64(lf_q_size.u, lf->rbase + CPT_LF_Q_SIZE); - /* 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); - - /* 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 = 1; - lf_ctl.s.fc_hyst_bits = CPT_FC_NUM_HYST_BITS; - plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL); - lf->fc_addr = (uint64_t *)addr; + lf->fc_hyst_bits = plt_log2_u32(lf->nb_desc) / 2; + lf->fc_thresh = lf->nb_desc - (lf->nb_desc % (1 << lf->fc_hyst_bits)); } int roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf) { struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt); - uint8_t blkaddr = RVU_BLOCK_ADDR_CPT0; + uint8_t blkaddr[ROC_CPT_MAX_BLKS]; struct msix_offset_rsp *rsp; uint8_t eng_grpmsk; + int blknum = 0; int rc, i; + blkaddr[0] = RVU_BLOCK_ADDR_CPT0; + blkaddr[1] = RVU_BLOCK_ADDR_CPT1; + + if ((roc_cpt->cpt_revision == ROC_CPT_REVISION_ID_98XX) && + (cpt->dev.pf_func & 0x1)) + blknum = (blknum + 1) % ROC_CPT_MAX_BLKS; + /* Request LF resources */ - rc = cpt_lfs_attach(&cpt->dev, blkaddr, false, nb_lf); - if (rc) + rc = cpt_lfs_attach(&cpt->dev, blkaddr[blknum], true, nb_lf); + + /* Request LFs from another block if current block has less LFs */ + if (roc_cpt->cpt_revision == ROC_CPT_REVISION_ID_98XX && rc == ENOSPC) { + blknum = (blknum + 1) % ROC_CPT_MAX_BLKS; + rc = cpt_lfs_attach(&cpt->dev, blkaddr[blknum], true, nb_lf); + } + if (rc) { + plt_err("Could not attach LFs"); return rc; + } + + for (i = 0; i < nb_lf; i++) + cpt->lf_blkaddr[i] = blkaddr[blknum]; eng_grpmsk = (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_AE]) | (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_SE]) | (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_IE]); - rc = cpt_lfs_alloc(&cpt->dev, eng_grpmsk, blkaddr, false); + rc = cpt_lfs_alloc(&cpt->dev, eng_grpmsk, blkaddr[blknum], false); if (rc) goto lfs_detach; @@ -494,10 +568,14 @@ cpt_lf_init(struct roc_cpt_lf *lf) if (lf->nb_desc == 0 || lf->nb_desc > CPT_LF_MAX_NB_DESC) lf->nb_desc = CPT_LF_DEFAULT_NB_DESC; + /* Update nb_desc to next power of 2 to aid in pending queue checks */ + lf->nb_desc = plt_align32pow2(lf->nb_desc); + /* Allocate memory for instruction queue for CPT LF. */ iq_mem = plt_zmalloc(cpt_lf_iq_mem_calc(lf->nb_desc), ROC_ALIGN); if (iq_mem == NULL) return -ENOMEM; + plt_atomic_thread_fence(__ATOMIC_ACQ_REL); blkaddr = cpt_get_blkaddr(dev); lf->rbase = dev->bar2 + ((blkaddr << 20) | (lf->lf_id << 12)); @@ -512,7 +590,6 @@ cpt_lf_init(struct roc_cpt_lf *lf) if (rc) goto disable_iq; - cpt_lf_dump(lf); return 0; disable_iq: @@ -570,7 +647,7 @@ roc_cpt_dev_init(struct roc_cpt *roc_cpt) cpt->pci_dev = pci_dev; roc_cpt->lmt_base = dev->lmt_base; - rc = cpt_hardware_caps_get(dev, roc_cpt->hw_caps); + rc = cpt_hardware_caps_get(dev, roc_cpt); if (rc) { plt_err("Could not determine hardware capabilities"); goto fail; @@ -583,7 +660,7 @@ roc_cpt_dev_init(struct roc_cpt *roc_cpt) } /* Reserve 1 CPT LF for inline inbound */ - nb_lf_avail = PLT_MIN(nb_lf_avail, ROC_CPT_MAX_LFS - 1); + nb_lf_avail = PLT_MIN(nb_lf_avail, (uint16_t)(ROC_CPT_MAX_LFS - 1)); roc_cpt->nb_lf_avail = nb_lf_avail; @@ -600,23 +677,42 @@ 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; - if (lf == NULL) + if (lf == NULL) { + plt_err("Could not trigger CTX flush"); 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) { @@ -719,8 +815,10 @@ void roc_cpt_iq_disable(struct roc_cpt_lf *lf) { union cpt_lf_ctl lf_ctl = {.u = 0x0}; + union cpt_lf_q_grp_ptr grp_ptr; union cpt_lf_inprog lf_inprog; int timeout = 20; + int cnt; /* Disable instructions enqueuing */ plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL); @@ -744,4 +842,131 @@ roc_cpt_iq_disable(struct roc_cpt_lf *lf) */ lf_inprog.s.eena = 0x0; plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG); + + /* 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; }