From patchwork Wed Apr 5 14:25:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sathesh B Edara X-Patchwork-Id: 125805 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C1979428D4; Wed, 5 Apr 2023 16:26:13 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5846B42D20; Wed, 5 Apr 2023 16:25:52 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 9829C42D1A for ; Wed, 5 Apr 2023 16:25:50 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 335DWaJt017817 for ; Wed, 5 Apr 2023 07:25:50 -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=TpTMwiJP9UNePM1F0wLKTKPTUSz5UzsdAs3a4mwhEio=; b=JpTI3IUwEzebNY2N8gP6r3VMWrQB/YNhXi+mb7e7kb98Nw/+RMlqabTX/pb5wgoU0+KL BIN5eElljx82zw7KdNL05MgHxe2GRKhxb8az0rrnVqIvkfmrBpwmP0O8086mb2meEfaJ nWrtYb4AMnedtVPf/GjG117f1YPwKEZHww1GVJFbVsI6C7P0NfatXY+cHvs4wOEeUDl/ S511gsShClggCbWASehzV42AiwwCl2LsaYgyloxLHMh2OPboJsMtiq4G0AfiMp/6qjcV f/8cZfcAyTOX1nRQy3QvvxkCORL5IGWtWkIlSMCuOX05Qv2mjLQE5eGuzfibcqzO95iR tg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3prpnd5gs4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Wed, 05 Apr 2023 07:25:49 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Wed, 5 Apr 2023 07:25:47 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Wed, 5 Apr 2023 07:25:47 -0700 Received: from localhost.marvell.com (unknown [10.106.27.249]) by maili.marvell.com (Postfix) with ESMTP id 07CFE3F7050; Wed, 5 Apr 2023 07:25:47 -0700 (PDT) From: Sathesh Edara To: , , , "Radha Mohan Chintakuntla" , Veerasenareddy Burru CC: Subject: [PATCH v2 04/10] net/octeon_ep: support IQ/OQ reset Date: Wed, 5 Apr 2023 07:25:30 -0700 Message-ID: <20230405142537.1899973-5-sedara@marvell.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230405142537.1899973-1-sedara@marvell.com> References: <20230404141855.1025625-2-sedara@marvell.com> <20230405142537.1899973-1-sedara@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: LLf7rDcRj8wcLrUkIfA8CWB4sRcaXyit X-Proofpoint-GUID: LLf7rDcRj8wcLrUkIfA8CWB4sRcaXyit X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-04-05_09,2023-04-05_01,2023-02-09_01 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 This patch adds input and output queue reset functionality, also receive queue interrupt enable and disable functionality. Signed-off-by: Sathesh Edara --- drivers/net/octeon_ep/otx2_ep_vf.c | 193 +++++++++++++++++++++++++- drivers/net/octeon_ep/otx2_ep_vf.h | 61 ++++++-- drivers/net/octeon_ep/otx_ep_common.h | 5 +- 3 files changed, 244 insertions(+), 15 deletions(-) diff --git a/drivers/net/octeon_ep/otx2_ep_vf.c b/drivers/net/octeon_ep/otx2_ep_vf.c index 3ffc7275c7..3e4895862b 100644 --- a/drivers/net/octeon_ep/otx2_ep_vf.c +++ b/drivers/net/octeon_ep/otx2_ep_vf.c @@ -9,6 +9,117 @@ #include "otx_ep_common.h" #include "otx2_ep_vf.h" +static int otx2_vf_enable_rxq_intr(struct otx_ep_device *otx_epvf, + uint16_t q_no); + +static int +otx2_vf_reset_iq(struct otx_ep_device *otx_ep, int q_no) +{ + int loop = SDP_VF_BUSY_LOOP_COUNT; + volatile uint64_t d64 = 0ull; + + /* There is no RST for a ring. + * Clear all registers one by one after disabling the ring + */ + + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_ENABLE(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_INSTR_BADDR(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_INSTR_RSIZE(q_no)); + + d64 = 0xFFFFFFFF; /* ~0ull */ + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_INSTR_DBELL(q_no)); + d64 = otx2_read64(otx_ep->hw_addr + SDP_VF_R_IN_INSTR_DBELL(q_no)); + + while ((d64 != 0) && loop--) { + rte_delay_ms(1); + d64 = otx2_read64(otx_ep->hw_addr + + SDP_VF_R_IN_INSTR_DBELL(q_no)); + } + if (loop < 0) { + otx_ep_err("%s: doorbell init retry limit exceeded.\n", __func__); + return -EIO; + } + + loop = SDP_VF_BUSY_LOOP_COUNT; + do { + d64 = otx2_read64(otx_ep->hw_addr + SDP_VF_R_IN_CNTS(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_CNTS(q_no)); + rte_delay_ms(1); + } while ((d64 & ~SDP_VF_R_IN_CNTS_OUT_INT) != 0 && loop--); + if (loop < 0) { + otx_ep_err("%s: in_cnts init retry limit exceeded.\n", __func__); + return -EIO; + } + + d64 = 0ull; + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_INT_LEVELS(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_PKT_CNT(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_IN_BYTE_CNT(q_no)); + + return 0; +} + +static int +otx2_vf_reset_oq(struct otx_ep_device *otx_ep, int q_no) +{ + int loop = SDP_VF_BUSY_LOOP_COUNT; + volatile uint64_t d64 = 0ull; + + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_ENABLE(q_no)); + + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_SLIST_BADDR(q_no)); + + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_SLIST_RSIZE(q_no)); + + d64 = 0xFFFFFFFF; + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_SLIST_DBELL(q_no)); + d64 = otx2_read64(otx_ep->hw_addr + SDP_VF_R_OUT_SLIST_DBELL(q_no)); + while ((d64 != 0) && loop--) { + rte_delay_ms(1); + d64 = otx2_read64(otx_ep->hw_addr + + SDP_VF_R_OUT_SLIST_DBELL(q_no)); + } + if (loop < 0) { + otx_ep_err("%s: doorbell init retry limit exceeded.\n", __func__); + return -EIO; + } + + if (otx2_read64(otx_ep->hw_addr + SDP_VF_R_OUT_CNTS(q_no)) + & SDP_VF_R_OUT_CNTS_OUT_INT) { + /* + * The OUT_INT bit is set. This interrupt must be enabled in + * order to clear the interrupt. Interrupts are disabled + * at the end of this function. + */ + union out_int_lvl_t out_int_lvl; + + out_int_lvl.d64 = otx2_read64(otx_ep->hw_addr + + SDP_VF_R_OUT_INT_LEVELS(q_no)); + out_int_lvl.s.time_cnt_en = 1; + out_int_lvl.s.cnt = 0; + otx2_write64(out_int_lvl.d64, otx_ep->hw_addr + + SDP_VF_R_OUT_INT_LEVELS(q_no)); + } + + loop = SDP_VF_BUSY_LOOP_COUNT; + do { + d64 = otx2_read64(otx_ep->hw_addr + SDP_VF_R_OUT_CNTS(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_CNTS(q_no)); + rte_delay_ms(1); + } while ((d64 & ~SDP_VF_R_OUT_CNTS_IN_INT) != 0 && loop--); + if (loop < 0) { + otx_ep_err("%s: out_cnts init retry limit exceeded.\n", __func__); + return -EIO; + } + + d64 = 0ull; + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_INT_LEVELS(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_PKT_CNT(q_no)); + otx2_write64(d64, otx_ep->hw_addr + SDP_VF_R_OUT_BYTE_CNT(q_no)); + + return 0; +} + static void otx2_vf_setup_global_iq_reg(struct otx_ep_device *otx_ep, int q_no) { @@ -49,24 +160,63 @@ otx2_vf_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no) oct_ep_write64(reg_val, otx_ep->hw_addr + SDP_VF_R_OUT_CONTROL(q_no)); } +static int +otx2_vf_reset_input_queues(struct otx_ep_device *otx_ep) +{ + uint32_t q_no = 0; + int ret = 0; + + for (q_no = 0; q_no < otx_ep->sriov_info.rings_per_vf; q_no++) { + ret = otx2_vf_reset_iq(otx_ep, q_no); + if (ret) + return ret; + } + + return ret; +} + +static int +otx2_vf_reset_output_queues(struct otx_ep_device *otx_ep) +{ + uint64_t q_no = 0ull; + int ret = 0; + + for (q_no = 0; q_no < otx_ep->sriov_info.rings_per_vf; q_no++) { + ret = otx2_vf_reset_oq(otx_ep, q_no); + if (ret) + return ret; + } + + return ret; +} + static int otx2_vf_setup_global_input_regs(struct otx_ep_device *otx_ep) { uint64_t q_no = 0ull; + int ret = 0; + + ret = otx2_vf_reset_input_queues(otx_ep); + if (ret) + return ret; for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++) otx2_vf_setup_global_iq_reg(otx_ep, q_no); - return 0; + return ret; } static int otx2_vf_setup_global_output_regs(struct otx_ep_device *otx_ep) { uint32_t q_no; + int ret = 0; + ret = otx2_vf_reset_output_queues(otx_ep); + if (ret) + return ret; for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++) otx2_vf_setup_global_oq_reg(otx_ep, q_no); - return 0; + return ret; } static int @@ -181,8 +331,8 @@ otx2_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_write64(OTX_EP_CLEAR_SDP_OUT_PKT_CNT, (uint8_t *)otx_ep->hw_addr + SDP_VF_R_OUT_PKT_CNT(oq_no)); - loop = OTX_EP_BUSY_LOOP_COUNT; /* Clear the OQ doorbell */ + loop = OTX_EP_BUSY_LOOP_COUNT; rte_write32(OTX_EP_CLEAR_SLIST_DBELL, droq->pkts_credit_reg); while ((rte_read32(droq->pkts_credit_reg) != 0ull) && loop--) { rte_write32(OTX_EP_CLEAR_SLIST_DBELL, droq->pkts_credit_reg); @@ -344,6 +494,40 @@ otx2_ep_get_defconf(struct otx_ep_device *otx_ep_dev __rte_unused) return default_conf; } +static int otx2_vf_enable_rxq_intr(struct otx_ep_device *otx_epvf, + uint16_t q_no) +{ + union out_int_lvl_t out_int_lvl; + union out_cnts_t out_cnts; + + out_int_lvl.d64 = otx2_read64(otx_epvf->hw_addr + + SDP_VF_R_OUT_INT_LEVELS(q_no)); + out_int_lvl.s.time_cnt_en = 1; + out_int_lvl.s.cnt = 0; + otx2_write64(out_int_lvl.d64, otx_epvf->hw_addr + + SDP_VF_R_OUT_INT_LEVELS(q_no)); + out_cnts.d64 = 0; + out_cnts.s.resend = 1; + otx2_write64(out_cnts.d64, otx_epvf->hw_addr + SDP_VF_R_OUT_CNTS(q_no)); + return 0; +} + +static int otx2_vf_disable_rxq_intr(struct otx_ep_device *otx_epvf, + uint16_t q_no) +{ + union out_int_lvl_t out_int_lvl; + + /* Disable the interrupt for this queue */ + out_int_lvl.d64 = otx2_read64(otx_epvf->hw_addr + + SDP_VF_R_OUT_INT_LEVELS(q_no)); + out_int_lvl.s.time_cnt_en = 0; + out_int_lvl.s.cnt = 0; + otx2_write64(out_int_lvl.d64, otx_epvf->hw_addr + + SDP_VF_R_OUT_INT_LEVELS(q_no)); + + return 0; +} + int otx2_ep_vf_setup_device(struct otx_ep_device *otx_ep) { @@ -381,5 +565,8 @@ otx2_ep_vf_setup_device(struct otx_ep_device *otx_ep) otx_ep->fn_list.enable_oq = otx2_vf_enable_oq; otx_ep->fn_list.disable_oq = otx2_vf_disable_oq; + otx_ep->fn_list.enable_rxq_intr = otx2_vf_enable_rxq_intr; + otx_ep->fn_list.disable_rxq_intr = otx2_vf_disable_rxq_intr; + return 0; } diff --git a/drivers/net/octeon_ep/otx2_ep_vf.h b/drivers/net/octeon_ep/otx2_ep_vf.h index 8f00acd737..36c0b25dea 100644 --- a/drivers/net/octeon_ep/otx2_ep_vf.h +++ b/drivers/net/octeon_ep/otx2_ep_vf.h @@ -14,17 +14,20 @@ #define SDP_VF_BUSY_LOOP_COUNT (10000) /* SDP VF OQ Masks */ -#define SDP_VF_R_OUT_CTL_IDLE (1ull << 40) -#define SDP_VF_R_OUT_CTL_ES_I (1ull << 34) -#define SDP_VF_R_OUT_CTL_NSR_I (1ull << 33) -#define SDP_VF_R_OUT_CTL_ROR_I (1ull << 32) -#define SDP_VF_R_OUT_CTL_ES_D (1ull << 30) -#define SDP_VF_R_OUT_CTL_NSR_D (1ull << 29) -#define SDP_VF_R_OUT_CTL_ROR_D (1ull << 28) -#define SDP_VF_R_OUT_CTL_ES_P (1ull << 26) -#define SDP_VF_R_OUT_CTL_NSR_P (1ull << 25) -#define SDP_VF_R_OUT_CTL_ROR_P (1ull << 24) -#define SDP_VF_R_OUT_CTL_IMODE (1ull << 23) +#define SDP_VF_R_OUT_CTL_IDLE (0x1ull << 40) +#define SDP_VF_R_OUT_CTL_ES_I (0x1ull << 34) +#define SDP_VF_R_OUT_CTL_NSR_I (0x1ull << 33) +#define SDP_VF_R_OUT_CTL_ROR_I (0x1ull << 32) +#define SDP_VF_R_OUT_CTL_ES_D (0x1ull << 30) +#define SDP_VF_R_OUT_CTL_NSR_D (0x1ull << 29) +#define SDP_VF_R_OUT_CTL_ROR_D (0x1ull << 28) +#define SDP_VF_R_OUT_CTL_ES_P (0x1ull << 26) +#define SDP_VF_R_OUT_CTL_NSR_P (0x1ull << 25) +#define SDP_VF_R_OUT_CTL_ROR_P (0x1ull << 24) +#define SDP_VF_R_OUT_CTL_IMODE (0x1ull << 23) +#define SDP_VF_R_OUT_CNTS_OUT_INT (0x1ull << 62) +#define SDP_VF_R_OUT_CNTS_IN_INT (0x1ull << 61) +#define SDP_VF_R_IN_CNTS_OUT_INT (0x1ull << 62) /* SDP VF Register definitions */ #define SDP_VF_RING_OFFSET (0x1ull << 17) @@ -140,4 +143,40 @@ struct otx2_ep_instr_64B { uint64_t exhdr[4]; }; +union out_int_lvl_t { + uint64_t d64; + struct { + uint64_t cnt:32; + uint64_t timet:22; + uint64_t max_len:7; + uint64_t max_len_en:1; + uint64_t time_cnt_en:1; + uint64_t bmode:1; + } s; +}; + +union out_cnts_t { + uint64_t d64; + struct { + uint64_t cnt:32; + uint64_t timer:22; + uint64_t rsvd:5; + uint64_t resend:1; + uint64_t mbox_int:1; + uint64_t in_int:1; + uint64_t out_int:1; + uint64_t send_ism:1; + } s; +}; + +#define OTX2_EP_64B_INSTR_SIZE (sizeof(otx2_ep_instr_64B)) + +#define NIX_MAX_HW_FRS 9212 +#define NIX_MAX_VTAG_INS 2 +#define NIX_MAX_VTAG_ACT_SIZE (4 * NIX_MAX_VTAG_INS) +#define NIX_MAX_FRS \ + (NIX_MAX_HW_FRS + RTE_ETHER_CRC_LEN - NIX_MAX_VTAG_ACT_SIZE) + +#define CN93XX_INTR_R_OUT_INT (1ULL << 62) +#define CN93XX_INTR_R_IN_INT (1ULL << 61) #endif /*_OTX2_EP_VF_H_ */ diff --git a/drivers/net/octeon_ep/otx_ep_common.h b/drivers/net/octeon_ep/otx_ep_common.h index 479bb1a1a0..a3260d5243 100644 --- a/drivers/net/octeon_ep/otx_ep_common.h +++ b/drivers/net/octeon_ep/otx_ep_common.h @@ -408,6 +408,9 @@ struct otx_ep_fn_list { int (*enable_oq)(struct otx_ep_device *otx_ep, uint32_t q_no); void (*disable_oq)(struct otx_ep_device *otx_ep, uint32_t q_no); + + int (*enable_rxq_intr)(struct otx_ep_device *otx_epvf, uint16_t q_no); + int (*disable_rxq_intr)(struct otx_ep_device *otx_epvf, uint16_t q_no); }; /* OTX_EP EP VF device data structure */ @@ -498,7 +501,7 @@ struct otx_ep_buf_free_info { struct otx_ep_gather g; }; -#define OTX_EP_MAX_PKT_SZ 64000U +#define OTX_EP_MAX_PKT_SZ 65498U #define OTX_EP_MAX_MAC_ADDRS 1 #define OTX_EP_SG_ALIGN 8 #define OTX_EP_CLEAR_ISIZE_BSIZE 0x7FFFFFULL