From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 58A7CA0C40; Fri, 25 Jun 2021 07:37:49 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 723AB40E5A; Fri, 25 Jun 2021 07:37:43 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 40B1240E25 for ; Fri, 25 Jun 2021 07:37:42 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 15P5ZC10014300; Thu, 24 Jun 2021 22:37:41 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=wnrXJUxwJy1x7XYexSLjCK66nUiF4CU2OK6btbKgg8I=; b=cKsVnMH13ONYbHB6lho/yof67gdYQFtpXVMvEARMnzXtA6KlTzcc9Uq2IsWV8csK4t5I d401Ap4YEcokOGBEHkqYpwposE9GyxSos1CDqEr0phpTNvnG3KlvUhUExkgMFlwsewc0 AZxThLA90wESV0haNtGKZJ2eb4iaUG2tm1RvA4Z5trlVmK0grmiCTKDt/rBH2bfLZH25 JS1QECPTR0Z6FG7eXX+S8KSYqFGaJrM8o3xS8M32KuQDGwjvpGegAvLEHZz9vAj9WrjA HvGyDNeaRTv3G0u7hgpzud6RiLf2Oxn3urxsFrkRlOpMtRK3/DyorCrOJ02InK+C1rUh Tg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com with ESMTP id 39d241sg4u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Thu, 24 Jun 2021 22:37:41 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Thu, 24 Jun 2021 22:37:39 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Thu, 24 Jun 2021 22:37:39 -0700 Received: from HY-LT1002.marvell.com (HY-LT1002.marvell.com [10.28.176.218]) by maili.marvell.com (Postfix) with ESMTP id 6B9CE3F7041; Thu, 24 Jun 2021 22:37:35 -0700 (PDT) From: Anoob Joseph To: Akhil Goyal , Thomas Monjalon CC: Archana Muniganti , Jerin Jacob , Ankur Dwivedi , Tejasree Kondoj , , Anoob Joseph , Vidya Sagar Velumuri Date: Fri, 25 Jun 2021 11:06:38 +0530 Message-ID: <1624599410-29689-7-git-send-email-anoobj@marvell.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624599410-29689-1-git-send-email-anoobj@marvell.com> References: <1624599410-29689-1-git-send-email-anoobj@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-GUID: RDmFvPSXU5H5DR5zvlcQl7u3AZQDbqM3 X-Proofpoint-ORIG-GUID: RDmFvPSXU5H5DR5zvlcQl7u3AZQDbqM3 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.790 definitions=2021-06-25_01:2021-06-24, 2021-06-25 signatures=0 Subject: [dpdk-dev] [PATCH v2 06/17] common/cnxk: add CPT LF config X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Archana Muniganti Add routines to init & fini CPT LFs. CPT LFs are queues to the hardware enabling instruction submissions. Signed-off-by: Anoob Joseph Signed-off-by: Archana Muniganti Signed-off-by: Vidya Sagar Velumuri --- drivers/common/cnxk/roc_cpt.c | 357 +++++++++++++++++++++++++++++++++++++ drivers/common/cnxk/roc_cpt.h | 20 +++ drivers/common/cnxk/roc_cpt_priv.h | 2 + drivers/common/cnxk/version.map | 3 + 4 files changed, 382 insertions(+) diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c index e723ee7..02062c1 100644 --- a/drivers/common/cnxk/roc_cpt.c +++ b/drivers/common/cnxk/roc_cpt.c @@ -5,6 +5,189 @@ #include "roc_api.h" #include "roc_priv.h" +#define CPT_IQ_FC_LEN 128 +#define CPT_IQ_GRP_LEN 16 + +#define CPT_IQ_NB_DESC_MULTIPLIER 40 + +/* The effective queue size to software is (CPT_LF_Q_SIZE[SIZE_DIV40] - 1 - 8). + * + * CPT requires 320 free entries (+8). And 40 entries are required for + * allowing CPT to discard packet when the queues are full (+1). + */ +#define CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) \ + (PLT_DIV_CEIL(nb_desc, CPT_IQ_NB_DESC_MULTIPLIER) + 1 + 8) + +#define CPT_IQ_GRP_SIZE(nb_desc) \ + (CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) * CPT_IQ_GRP_LEN) + +#define CPT_LF_MAX_NB_DESC 128000 +#define CPT_LF_DEFAULT_NB_DESC 1024 + +static void +cpt_lf_misc_intr_enb_dis(struct roc_cpt_lf *lf, bool enb) +{ + /* Enable all cpt lf error irqs except RQ_DISABLED and CQ_DISABLED */ + if (enb) + plt_write64((BIT_ULL(6) | BIT_ULL(5) | BIT_ULL(3) | BIT_ULL(2) | + BIT_ULL(1)), + lf->rbase + CPT_LF_MISC_INT_ENA_W1S); + else + plt_write64((BIT_ULL(6) | BIT_ULL(5) | BIT_ULL(3) | BIT_ULL(2) | + BIT_ULL(1)), + lf->rbase + CPT_LF_MISC_INT_ENA_W1C); +} + +static void +cpt_lf_misc_irq(void *param) +{ + struct roc_cpt_lf *lf = (struct roc_cpt_lf *)param; + struct dev *dev = lf->dev; + uint64_t intr; + + intr = plt_read64(lf->rbase + CPT_LF_MISC_INT); + if (intr == 0) + return; + + plt_err("Err_irq=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf); + + /* Clear interrupt */ + plt_write64(intr, lf->rbase + CPT_LF_MISC_INT); +} + +static int +cpt_lf_register_misc_irq(struct roc_cpt_lf *lf) +{ + struct plt_pci_device *pci_dev = lf->pci_dev; + struct plt_intr_handle *handle; + int rc, vec; + + handle = &pci_dev->intr_handle; + + vec = lf->msixoff + CPT_LF_INT_VEC_MISC; + /* Clear err interrupt */ + cpt_lf_misc_intr_enb_dis(lf, false); + /* Set used interrupt vectors */ + rc = dev_irq_register(handle, cpt_lf_misc_irq, lf, vec); + /* Enable all dev interrupt except for RQ_DISABLED */ + cpt_lf_misc_intr_enb_dis(lf, true); + + return rc; +} + +static void +cpt_lf_unregister_misc_irq(struct roc_cpt_lf *lf) +{ + struct plt_pci_device *pci_dev = lf->pci_dev; + struct plt_intr_handle *handle; + int vec; + + handle = &pci_dev->intr_handle; + + vec = lf->msixoff + CPT_LF_INT_VEC_MISC; + /* Clear err interrupt */ + cpt_lf_misc_intr_enb_dis(lf, false); + dev_irq_unregister(handle, cpt_lf_misc_irq, lf, vec); +} + +static void +cpt_lf_done_intr_enb_dis(struct roc_cpt_lf *lf, bool enb) +{ + if (enb) + plt_write64(0x1, lf->rbase + CPT_LF_DONE_INT_ENA_W1S); + else + plt_write64(0x1, lf->rbase + CPT_LF_DONE_INT_ENA_W1C); +} + +static void +cpt_lf_done_irq(void *param) +{ + struct roc_cpt_lf *lf = param; + uint64_t done_wait; + uint64_t intr; + + /* Read the number of completed requests */ + intr = plt_read64(lf->rbase + CPT_LF_DONE); + if (intr == 0) + return; + + done_wait = plt_read64(lf->rbase + CPT_LF_DONE_WAIT); + + /* Acknowledge the number of completed requests */ + plt_write64(intr, lf->rbase + CPT_LF_DONE_ACK); + + plt_write64(done_wait, lf->rbase + CPT_LF_DONE_WAIT); +} + +static int +cpt_lf_register_done_irq(struct roc_cpt_lf *lf) +{ + struct plt_pci_device *pci_dev = lf->pci_dev; + struct plt_intr_handle *handle; + int rc, vec; + + handle = &pci_dev->intr_handle; + + vec = lf->msixoff + CPT_LF_INT_VEC_DONE; + + /* Clear done interrupt */ + cpt_lf_done_intr_enb_dis(lf, false); + + /* Set used interrupt vectors */ + rc = dev_irq_register(handle, cpt_lf_done_irq, lf, vec); + + /* Enable done interrupt */ + cpt_lf_done_intr_enb_dis(lf, true); + + return rc; +} + +static void +cpt_lf_unregister_done_irq(struct roc_cpt_lf *lf) +{ + struct plt_pci_device *pci_dev = lf->pci_dev; + struct plt_intr_handle *handle; + int vec; + + handle = &pci_dev->intr_handle; + + vec = lf->msixoff + CPT_LF_INT_VEC_DONE; + + /* Clear done interrupt */ + cpt_lf_done_intr_enb_dis(lf, false); + dev_irq_unregister(handle, cpt_lf_done_irq, lf, vec); +} + +static int +cpt_lf_register_irqs(struct roc_cpt_lf *lf) +{ + int rc; + + if (lf->msixoff == MSIX_VECTOR_INVALID) { + plt_err("Invalid CPTLF MSIX vector offset vector: 0x%x", + lf->msixoff); + return -EINVAL; + } + + /* Register lf err interrupt */ + rc = cpt_lf_register_misc_irq(lf); + if (rc) + plt_err("Error registering IRQs"); + + rc = cpt_lf_register_done_irq(lf); + if (rc) + plt_err("Error registering IRQs"); + + return rc; +} + +static void +cpt_lf_unregister_irqs(struct roc_cpt_lf *lf) +{ + cpt_lf_unregister_misc_irq(lf); + cpt_lf_unregister_done_irq(lf); +} + int roc_cpt_rxc_time_cfg(struct roc_cpt *roc_cpt, struct roc_cpt_rxc_time_cfg *cfg) { @@ -146,6 +329,69 @@ cpt_hardware_caps_get(struct dev *dev, union cpt_eng_caps *hw_caps) return 0; } +static uint32_t +cpt_lf_iq_mem_calc(uint32_t nb_desc) +{ + uint32_t len; + + /* Space for instruction group memory */ + len = CPT_IQ_GRP_SIZE(nb_desc); + + /* Align to 128B */ + len = PLT_ALIGN(len, ROC_ALIGN); + + /* Space for FC */ + 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); + + return len; +} + +static inline void +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); + + /* Disable command queue */ + roc_cpt_iq_disable(lf); + + /* Set command queue base address */ + addr = (uintptr_t)lf->iq_vaddr + + PLT_ALIGN(CPT_IQ_GRP_SIZE(lf->nb_desc), ROC_ALIGN); + + lf_q_base.u = addr; + + plt_write64(lf_q_base.u, lf->rbase + CPT_LF_Q_BASE); + + /* Set command queue size */ + 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; +} + int roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf) { @@ -210,6 +456,63 @@ cpt_get_blkaddr(struct dev *dev) } int +cpt_lf_init(struct roc_cpt_lf *lf) +{ + struct dev *dev = lf->dev; + uint64_t blkaddr; + void *iq_mem; + int rc; + + if (lf->nb_desc == 0 || lf->nb_desc > CPT_LF_MAX_NB_DESC) + lf->nb_desc = CPT_LF_DEFAULT_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; + + blkaddr = cpt_get_blkaddr(dev); + lf->rbase = dev->bar2 + ((blkaddr << 20) | (lf->lf_id << 12)); + lf->iq_vaddr = iq_mem; + lf->lmt_base = dev->lmt_base; + lf->pf_func = dev->pf_func; + + /* Initialize instruction queue */ + cpt_iq_init(lf); + + rc = cpt_lf_register_irqs(lf); + if (rc) + goto disable_iq; + + return 0; + +disable_iq: + roc_cpt_iq_disable(lf); + plt_free(iq_mem); + return rc; +} + +int +roc_cpt_lf_init(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf) +{ + struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt); + int rc; + + lf->dev = &cpt->dev; + lf->roc_cpt = roc_cpt; + lf->msixoff = cpt->lf_msix_off[lf->lf_id]; + lf->pci_dev = cpt->pci_dev; + + rc = cpt_lf_init(lf); + if (rc) + return rc; + + /* LF init successful */ + roc_cpt->lf[lf->lf_id] = lf; + return rc; +} + +int roc_cpt_dev_init(struct roc_cpt *roc_cpt) { struct plt_pci_device *pci_dev; @@ -267,6 +570,29 @@ roc_cpt_dev_init(struct roc_cpt *roc_cpt) return rc; } +void +cpt_lf_fini(struct roc_cpt_lf *lf) +{ + /* Unregister IRQ's */ + cpt_lf_unregister_irqs(lf); + + /* Disable IQ */ + roc_cpt_iq_disable(lf); + + /* Free memory */ + plt_free(lf->iq_vaddr); + lf->iq_vaddr = NULL; +} + +void +roc_cpt_lf_fini(struct roc_cpt_lf *lf) +{ + if (lf == NULL) + return; + lf->roc_cpt->lf[lf->lf_id] = NULL; + cpt_lf_fini(lf); +} + int roc_cpt_dev_fini(struct roc_cpt *roc_cpt) { @@ -341,3 +667,34 @@ roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt, enum cpt_eng_type eng_type) return rsp->eng_grp_num; } + +void +roc_cpt_iq_disable(struct roc_cpt_lf *lf) +{ + union cpt_lf_ctl lf_ctl = {.u = 0x0}; + union cpt_lf_inprog lf_inprog; + int timeout = 20; + + /* Disable instructions enqueuing */ + plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL); + + /* Wait for instruction queue to become empty */ + do { + lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG); + if (!lf_inprog.s.inflight) + break; + + plt_delay_ms(20); + if (timeout-- < 0) { + plt_err("CPT LF %d is still busy", lf->lf_id); + break; + } + + } while (1); + + /* Disable executions in the LF's queue. + * The queue should be empty at this point + */ + lf_inprog.s.eena = 0x0; + plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG); +} diff --git a/drivers/common/cnxk/roc_cpt.h b/drivers/common/cnxk/roc_cpt.h index bae472f..e258ca5 100644 --- a/drivers/common/cnxk/roc_cpt.h +++ b/drivers/common/cnxk/roc_cpt.h @@ -14,6 +14,23 @@ #define ROC_CPT_MAX_LFS 64 +struct roc_cpt_lf { + /* Input parameters */ + uint16_t lf_id; + uint32_t nb_desc; + /* End of Input parameters */ + struct plt_pci_device *pci_dev; + struct dev *dev; + struct roc_cpt *roc_cpt; + uintptr_t rbase; + uintptr_t lmt_base; + uint16_t msixoff; + uint16_t pf_func; + uint64_t *fc_addr; + uint64_t io_addr; + uint8_t *iq_vaddr; +} __plt_cache_aligned; + struct roc_cpt { struct plt_pci_device *pci_dev; struct roc_cpt_lf *lf[ROC_CPT_MAX_LFS]; @@ -44,4 +61,7 @@ int __roc_api roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt, enum cpt_eng_type eng_type); 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); +void __roc_api roc_cpt_iq_disable(struct roc_cpt_lf *lf); #endif /* _ROC_CPT_H_ */ diff --git a/drivers/common/cnxk/roc_cpt_priv.h b/drivers/common/cnxk/roc_cpt_priv.h index 0ef6774..6cfa4df 100644 --- a/drivers/common/cnxk/roc_cpt_priv.h +++ b/drivers/common/cnxk/roc_cpt_priv.h @@ -30,6 +30,8 @@ int cpt_lfs_detach(struct dev *dev); int cpt_lfs_alloc(struct dev *dev, uint8_t eng_grpmsk, uint8_t blk, bool inl_dev_sso); int cpt_lfs_free(struct dev *dev); +int cpt_lf_init(struct roc_cpt_lf *lf); +void cpt_lf_fini(struct roc_cpt_lf *lf); int cpt_get_msix_offset(struct dev *dev, struct msix_offset_rsp **msix_rsp); uint64_t cpt_get_blkaddr(struct dev *dev); diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index 13fd026..128997e 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -16,6 +16,9 @@ INTERNAL { roc_cpt_dev_fini; roc_cpt_dev_init; roc_cpt_eng_grp_add; + roc_cpt_iq_disable; + roc_cpt_lf_init; + roc_cpt_lf_fini; roc_cpt_rxc_time_cfg; roc_error_msg_get; roc_idev_cpt_get; -- 2.7.4