From patchwork Mon Apr 24 12:28:26 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: 126476 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 E1498429DB; Mon, 24 Apr 2023 15:55:18 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F1D7542B8C; Mon, 24 Apr 2023 15:55:14 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id D3601410ED for ; Mon, 24 Apr 2023 15:55:11 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 33O7WYUr028418 for ; Mon, 24 Apr 2023 06:55:10 -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=2M1W+aEYz14v42PvW79iESxTmW7hZ91nQOlAL2e7r30=; b=QoZ87+uiXLHJai/q16hSHiusdMYVkaCHFOLoAJVz5o61LMq0z2LUSCVQhbom34EmWQcN CIL6x3r1M05ajdL3689lGCJ+9EOY/j73z6HBWapF+SD3oYQplfa+FckwshfGlkR8VLu1 VwGT5h+V9ke6WWJykSBQOWtXxp4GSyhZo4RYSGg2LBDiG/jmsCN7jGuzGjQztOVpbBbl QX0mEusKputDi0/Zrw5SmMfB9wGBkHoLzMT8I2yhKJ2H/OUFTYITGehGNL0sVUSSwdII BccOoF1D68vq+eLFnYM3FXxLiTRemkgPPE64XK5YeBcCh1fgahw/gJykdM21OM707ULc Wg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3q5nfb1b6t-10 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Mon, 24 Apr 2023 06:55:10 -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.48; Mon, 24 Apr 2023 05:28:49 -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.48 via Frontend Transport; Mon, 24 Apr 2023 05:28:49 -0700 Received: from localhost.marvell.com (unknown [10.106.27.249]) by maili.marvell.com (Postfix) with ESMTP id 7F1FA3F70A0; Mon, 24 Apr 2023 05:28:49 -0700 (PDT) From: Sathesh Edara To: , , , "Radha Mohan Chintakuntla" , Veerasenareddy Burru CC: Subject: [PATCH v3 03/11] net/octeon_ep: support error propagation Date: Mon, 24 Apr 2023 05:28:26 -0700 Message-ID: <20230424122835.39493-4-sedara@marvell.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230424122835.39493-1-sedara@marvell.com> References: <20230405142537.1899973-2-sedara@marvell.com> <20230424122835.39493-1-sedara@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: QykaN8NwW4nTTiXjXDrgFwMm7vrxaYXx X-Proofpoint-GUID: QykaN8NwW4nTTiXjXDrgFwMm7vrxaYXx 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-24_09,2023-04-21_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 Adds detection of loop limits being hit, and propagate errors up the call chain when this happens. Signed-off-by: Sathesh Edara --- drivers/net/octeon_ep/cnxk_ep_vf.c | 51 +++++++++++-------- drivers/net/octeon_ep/otx2_ep_vf.c | 49 ++++++++++-------- drivers/net/octeon_ep/otx_ep_common.h | 6 +-- drivers/net/octeon_ep/otx_ep_ethdev.c | 27 +++++++--- drivers/net/octeon_ep/otx_ep_rxtx.c | 51 +++++++++---------- drivers/net/octeon_ep/otx_ep_vf.c | 71 +++++++++++++++++++-------- 6 files changed, 155 insertions(+), 100 deletions(-) diff --git a/drivers/net/octeon_ep/cnxk_ep_vf.c b/drivers/net/octeon_ep/cnxk_ep_vf.c index 3427fb213b..1a92887109 100644 --- a/drivers/net/octeon_ep/cnxk_ep_vf.c +++ b/drivers/net/octeon_ep/cnxk_ep_vf.c @@ -47,36 +47,43 @@ cnxk_ep_vf_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no) oct_ep_write64(reg_val, otx_ep->hw_addr + CNXK_EP_R_OUT_CONTROL(q_no)); } -static void +static int cnxk_ep_vf_setup_global_input_regs(struct otx_ep_device *otx_ep) { uint64_t q_no = 0ull; for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++) cnxk_ep_vf_setup_global_iq_reg(otx_ep, q_no); + return 0; } -static void +static int cnxk_ep_vf_setup_global_output_regs(struct otx_ep_device *otx_ep) { uint32_t q_no; for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++) cnxk_ep_vf_setup_global_oq_reg(otx_ep, q_no); + return 0; } -static void +static int cnxk_ep_vf_setup_device_regs(struct otx_ep_device *otx_ep) { - cnxk_ep_vf_setup_global_input_regs(otx_ep); - cnxk_ep_vf_setup_global_output_regs(otx_ep); + int ret; + + ret = cnxk_ep_vf_setup_global_input_regs(otx_ep); + if (ret) + return ret; + ret = cnxk_ep_vf_setup_global_output_regs(otx_ep); + return ret; } -static void +static int cnxk_ep_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) { struct otx_ep_instr_queue *iq = otx_ep->instr_queue[iq_no]; - uint64_t loop = OTX_EP_BUSY_LOOP_COUNT; + int loop = OTX_EP_BUSY_LOOP_COUNT; volatile uint64_t reg_val = 0ull; reg_val = oct_ep_read64(otx_ep->hw_addr + CNXK_EP_R_IN_CONTROL(iq_no)); @@ -91,9 +98,9 @@ cnxk_ep_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) } while ((!(reg_val & CNXK_EP_R_IN_CTL_IDLE)) && loop--); } - if (!loop) { + if (loop < 0) { otx_ep_err("IDLE bit is not set\n"); - return; + return -EIO; } /* Write the start of the input queue's ring and its size */ @@ -115,9 +122,9 @@ cnxk_ep_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) rte_delay_ms(1); } while (reg_val != 0 && loop--); - if (!loop) { + if (loop < 0) { otx_ep_err("INST CNT REGISTER is not zero\n"); - return; + return -EIO; } /* IN INTR_THRESHOLD is set to max(FFFFFFFF) which disable the IN INTR @@ -125,14 +132,15 @@ cnxk_ep_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) */ oct_ep_write64(OTX_EP_CLEAR_SDP_IN_INT_LVLS, otx_ep->hw_addr + CNXK_EP_R_IN_INT_LEVELS(iq_no)); + return 0; } -static void +static int cnxk_ep_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) { volatile uint64_t reg_val = 0ull; uint64_t oq_ctl = 0ull; - uint64_t loop = OTX_EP_BUSY_LOOP_COUNT; + int loop = OTX_EP_BUSY_LOOP_COUNT; struct otx_ep_droq *droq = otx_ep->droq[oq_no]; /* Wait on IDLE to set to 1, supposed to configure BADDR @@ -145,9 +153,9 @@ cnxk_ep_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("OUT CNT REGISTER value is zero\n"); - return; + return -EIO; } oct_ep_write64(droq->desc_ring_dma, otx_ep->hw_addr + CNXK_EP_R_OUT_SLIST_BADDR(oq_no)); @@ -181,9 +189,9 @@ cnxk_ep_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("Packets credit register value is not cleared\n"); - return; + return -EIO; } otx_ep_dbg("SDP_R[%d]_credit:%x", oq_no, rte_read32(droq->pkts_credit_reg)); @@ -201,18 +209,19 @@ cnxk_ep_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("Packets sent register value is not cleared\n"); - return; + return -EIO; } otx_ep_dbg("SDP_R[%d]_sent: %x", oq_no, rte_read32(droq->pkts_sent_reg)); + return 0; } static int cnxk_ep_vf_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) { - uint64_t loop = OTX_EP_BUSY_LOOP_COUNT; + int loop = OTX_EP_BUSY_LOOP_COUNT; uint64_t reg_val = 0ull; /* Resetting doorbells during IQ enabling also to handle abrupt @@ -225,7 +234,7 @@ cnxk_ep_vf_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("INSTR DBELL not coming back to 0\n"); return -EIO; } diff --git a/drivers/net/octeon_ep/otx2_ep_vf.c b/drivers/net/octeon_ep/otx2_ep_vf.c index 3c9a70157e..3ffc7275c7 100644 --- a/drivers/net/octeon_ep/otx2_ep_vf.c +++ b/drivers/net/octeon_ep/otx2_ep_vf.c @@ -49,32 +49,39 @@ 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 void +static int otx2_vf_setup_global_input_regs(struct otx_ep_device *otx_ep) { uint64_t q_no = 0ull; 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; } -static void +static int otx2_vf_setup_global_output_regs(struct otx_ep_device *otx_ep) { uint32_t q_no; 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; } -static void +static int otx2_vf_setup_device_regs(struct otx_ep_device *otx_ep) { - otx2_vf_setup_global_input_regs(otx_ep); - otx2_vf_setup_global_output_regs(otx_ep); + int ret; + + ret = otx2_vf_setup_global_input_regs(otx_ep); + if (ret) + return ret; + ret = otx2_vf_setup_global_output_regs(otx_ep); + return ret; } -static void +static int otx2_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) { struct otx_ep_instr_queue *iq = otx_ep->instr_queue[iq_no]; @@ -92,9 +99,9 @@ otx2_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) } while ((!(reg_val & SDP_VF_R_IN_CTL_IDLE)) && loop--); } - if (!loop) { + if (loop < 0) { otx_ep_err("IDLE bit is not set\n"); - return; + return -EIO; } /* Write the start of the input queue's ring and its size */ @@ -115,9 +122,9 @@ otx2_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) rte_write32(reg_val, iq->inst_cnt_reg); } while (reg_val != 0 && loop--); - if (!loop) { + if (loop < 0) { otx_ep_err("INST CNT REGISTER is not zero\n"); - return; + return -EIO; } /* IN INTR_THRESHOLD is set to max(FFFFFFFF) which disable the IN INTR @@ -125,14 +132,15 @@ otx2_vf_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) */ oct_ep_write64(OTX_EP_CLEAR_SDP_IN_INT_LVLS, otx_ep->hw_addr + SDP_VF_R_IN_INT_LEVELS(iq_no)); + return 0; } -static void +static int otx2_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) { volatile uint64_t reg_val = 0ull; uint64_t oq_ctl = 0ull; - uint64_t loop = OTX_EP_BUSY_LOOP_COUNT; + int loop = OTX_EP_BUSY_LOOP_COUNT; struct otx_ep_droq *droq = otx_ep->droq[oq_no]; /* Wait on IDLE to set to 1, supposed to configure BADDR @@ -145,9 +153,9 @@ otx2_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("OUT CNT REGISTER value is zero\n"); - return; + return -EIO; } oct_ep_write64(droq->desc_ring_dma, otx_ep->hw_addr + SDP_VF_R_OUT_SLIST_BADDR(oq_no)); @@ -181,9 +189,9 @@ otx2_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("Packets credit register value is not cleared\n"); - return; + return -EIO; } otx_ep_dbg("SDP_R[%d]_credit:%x", oq_no, rte_read32(droq->pkts_credit_reg)); @@ -200,17 +208,18 @@ otx2_vf_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("Packets sent register value is not cleared\n"); - return; + return -EIO; } otx_ep_dbg("SDP_R[%d]_sent: %x", oq_no, rte_read32(droq->pkts_sent_reg)); + return 0; } static int otx2_vf_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) { - uint64_t loop = SDP_VF_BUSY_LOOP_COUNT; + int loop = SDP_VF_BUSY_LOOP_COUNT; uint64_t reg_val = 0ull; /* Resetting doorbells during IQ enabling also to handle abrupt @@ -223,7 +232,7 @@ otx2_vf_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) rte_delay_ms(1); } - if (!loop) { + if (loop < 0) { otx_ep_err("INSTR DBELL not coming back to 0\n"); return -EIO; } diff --git a/drivers/net/octeon_ep/otx_ep_common.h b/drivers/net/octeon_ep/otx_ep_common.h index e4c92270d4..479bb1a1a0 100644 --- a/drivers/net/octeon_ep/otx_ep_common.h +++ b/drivers/net/octeon_ep/otx_ep_common.h @@ -394,11 +394,11 @@ struct otx_ep_sriov_info { /* Required functions for each VF device */ struct otx_ep_fn_list { - void (*setup_iq_regs)(struct otx_ep_device *otx_ep, uint32_t q_no); + int (*setup_iq_regs)(struct otx_ep_device *otx_ep, uint32_t q_no); - void (*setup_oq_regs)(struct otx_ep_device *otx_ep, uint32_t q_no); + int (*setup_oq_regs)(struct otx_ep_device *otx_ep, uint32_t q_no); - void (*setup_device_regs)(struct otx_ep_device *otx_ep); + int (*setup_device_regs)(struct otx_ep_device *otx_ep); int (*enable_io_queues)(struct otx_ep_device *otx_ep); void (*disable_io_queues)(struct otx_ep_device *otx_ep); diff --git a/drivers/net/octeon_ep/otx_ep_ethdev.c b/drivers/net/octeon_ep/otx_ep_ethdev.c index b23d52ff84..5677a2d6a6 100644 --- a/drivers/net/octeon_ep/otx_ep_ethdev.c +++ b/drivers/net/octeon_ep/otx_ep_ethdev.c @@ -151,13 +151,17 @@ otx_epdev_init(struct otx_ep_device *otx_epvf) else if (otx_epvf->chip_id == PCI_DEVID_CN9K_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CN98XX_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CNF95N_EP_NET_VF || - otx_epvf->chip_id == PCI_DEVID_CNF95O_EP_NET_VF) - otx_epvf->eth_dev->tx_pkt_burst = &otx2_ep_xmit_pkts; - else if (otx_epvf->chip_id == PCI_DEVID_CN10KA_EP_NET_VF || + otx_epvf->chip_id == PCI_DEVID_CNF95O_EP_NET_VF || + otx_epvf->chip_id == PCI_DEVID_CN10KA_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CN10KB_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CNF10KA_EP_NET_VF || - otx_epvf->chip_id == PCI_DEVID_CNF10KB_EP_NET_VF) + otx_epvf->chip_id == PCI_DEVID_CNF10KB_EP_NET_VF) { otx_epvf->eth_dev->tx_pkt_burst = &otx2_ep_xmit_pkts; + } else { + otx_ep_err("Invalid chip_id\n"); + ret = -EINVAL; + goto setup_fail; + } ethdev_queues = (uint32_t)(otx_epvf->sriov_info.rings_per_vf); otx_epvf->max_rx_queues = ethdev_queues; otx_epvf->max_tx_queues = ethdev_queues; @@ -489,6 +493,7 @@ otx_ep_eth_dev_init(struct rte_eth_dev *eth_dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; + rte_eth_copy_pci_info(eth_dev, pdev); otx_epvf->eth_dev = eth_dev; otx_epvf->port_id = eth_dev->data->port_id; eth_dev->dev_ops = &otx_ep_eth_dev_ops; @@ -503,7 +508,8 @@ otx_ep_eth_dev_init(struct rte_eth_dev *eth_dev) otx_epvf->hw_addr = pdev->mem_resource[0].addr; otx_epvf->pdev = pdev; - otx_epdev_init(otx_epvf); + if (otx_epdev_init(otx_epvf)) + return -ENOMEM; if (otx_epvf->chip_id == PCI_DEVID_CN9K_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CN98XX_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CNF95N_EP_NET_VF || @@ -511,11 +517,16 @@ otx_ep_eth_dev_init(struct rte_eth_dev *eth_dev) otx_epvf->chip_id == PCI_DEVID_CN10KA_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CN10KB_EP_NET_VF || otx_epvf->chip_id == PCI_DEVID_CNF10KA_EP_NET_VF || - otx_epvf->chip_id == PCI_DEVID_CNF10KB_EP_NET_VF) + otx_epvf->chip_id == PCI_DEVID_CNF10KB_EP_NET_VF) { otx_epvf->pkind = SDP_OTX2_PKIND_FS0; - else + otx_ep_info("using pkind %d\n", otx_epvf->pkind); + } else if (otx_epvf->chip_id == PCI_DEVID_OCTEONTX_EP_VF) { otx_epvf->pkind = SDP_PKIND; - otx_ep_info("using pkind %d\n", otx_epvf->pkind); + otx_ep_info("Using pkind %d.\n", otx_epvf->pkind); + } else { + otx_ep_err("Invalid chip id\n"); + return -EINVAL; + } return 0; } diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.c b/drivers/net/octeon_ep/otx_ep_rxtx.c index 6912ca2401..9712e6cce6 100644 --- a/drivers/net/octeon_ep/otx_ep_rxtx.c +++ b/drivers/net/octeon_ep/otx_ep_rxtx.c @@ -3,7 +3,7 @@ */ #include - +#include #include #include #include @@ -81,6 +81,7 @@ otx_ep_init_instr_queue(struct otx_ep_device *otx_ep, int iq_no, int num_descs, const struct otx_ep_config *conf; struct otx_ep_instr_queue *iq; uint32_t q_size; + int ret; conf = otx_ep->conf; iq = otx_ep->instr_queue[iq_no]; @@ -140,7 +141,9 @@ otx_ep_init_instr_queue(struct otx_ep_device *otx_ep, int iq_no, int num_descs, iq->iqcmd_64B = (conf->iq.instr_type == 64); /* Set up IQ registers */ - otx_ep->fn_list.setup_iq_regs(otx_ep, iq_no); + ret = otx_ep->fn_list.setup_iq_regs(otx_ep, iq_no); + if (ret) + return ret; return 0; @@ -271,6 +274,7 @@ otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no, uint32_t c_refill_threshold; struct otx_ep_droq *droq; uint32_t desc_ring_size; + int ret; otx_ep_info("OQ[%d] Init start\n", q_no); @@ -318,7 +322,9 @@ otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no, droq->refill_threshold = c_refill_threshold; /* Set up OQ registers */ - otx_ep->fn_list.setup_oq_regs(otx_ep, q_no); + ret = otx_ep->fn_list.setup_oq_regs(otx_ep, q_no); + if (ret) + return ret; otx_ep->io_qmask.oq |= (1ull << q_no); @@ -852,19 +858,15 @@ otx_ep_droq_read_packet(struct otx_ep_device *otx_ep, * droq->pkts_pending); */ droq->stats.pkts_delayed_data++; - while (retry && !info->length) + while (retry && !info->length) { retry--; + rte_delay_us_block(50); + } if (!retry && !info->length) { otx_ep_err("OCTEON DROQ[%d]: read_idx: %d; Retry failed !!\n", droq->q_no, droq->read_idx); /* May be zero length packet; drop it */ - rte_pktmbuf_free(droq_pkt); - droq->recv_buf_list[droq->read_idx] = NULL; - droq->read_idx = otx_ep_incr_index(droq->read_idx, 1, - droq->nb_desc); - droq->stats.dropped_zlp++; - droq->refill_count++; - goto oq_read_fail; + assert(0); } } if (next_fetch) { @@ -938,6 +940,7 @@ otx_ep_droq_read_packet(struct otx_ep_device *otx_ep, last_buf = droq_pkt; } else { otx_ep_err("no buf\n"); + assert(0); } pkt_len += cpy_len; @@ -953,16 +956,7 @@ otx_ep_droq_read_packet(struct otx_ep_device *otx_ep, droq_pkt->l3_len = hdr_lens.l3_len; droq_pkt->l4_len = hdr_lens.l4_len; - if (droq_pkt->nb_segs > 1 && - !(otx_ep->rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER)) { - rte_pktmbuf_free(droq_pkt); - goto oq_read_fail; - } - return droq_pkt; - -oq_read_fail: - return NULL; } static inline uint32_t @@ -992,6 +986,7 @@ otx_ep_recv_pkts(void *rx_queue, struct rte_mbuf *oq_pkt; uint32_t pkts = 0; + uint32_t valid_pkts = 0; uint32_t new_pkts = 0; int next_fetch; @@ -1019,14 +1014,15 @@ otx_ep_recv_pkts(void *rx_queue, "last_pkt_count %" PRIu64 "new_pkts %d.\n", droq->pkts_pending, droq->last_pkt_count, new_pkts); - droq->pkts_pending -= pkts; droq->stats.rx_err++; - goto finish; + continue; + } else { + rx_pkts[valid_pkts] = oq_pkt; + valid_pkts++; + /* Stats */ + droq->stats.pkts_received++; + droq->stats.bytes_received += oq_pkt->pkt_len; } - rx_pkts[pkts] = oq_pkt; - /* Stats */ - droq->stats.pkts_received++; - droq->stats.bytes_received += oq_pkt->pkt_len; } droq->pkts_pending -= pkts; @@ -1053,6 +1049,5 @@ otx_ep_recv_pkts(void *rx_queue, rte_write32(0, droq->pkts_credit_reg); } -finish: - return pkts; + return valid_pkts; } diff --git a/drivers/net/octeon_ep/otx_ep_vf.c b/drivers/net/octeon_ep/otx_ep_vf.c index 96366b2a7f..4f3538146b 100644 --- a/drivers/net/octeon_ep/otx_ep_vf.c +++ b/drivers/net/octeon_ep/otx_ep_vf.c @@ -12,10 +12,11 @@ #include "otx_ep_vf.h" -static void +static int otx_ep_setup_global_iq_reg(struct otx_ep_device *otx_ep, int q_no) { volatile uint64_t reg_val = 0ull; + int loop = OTX_EP_BUSY_LOOP_COUNT; /* Select ES, RO, NS, RDSIZE,DPTR Format#0 for IQs * IS_64B is by default enabled. @@ -33,8 +34,11 @@ otx_ep_setup_global_iq_reg(struct otx_ep_device *otx_ep, int q_no) do { reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_IN_CONTROL(q_no)); - } while (!(reg_val & OTX_EP_R_IN_CTL_IDLE)); + } while (!(reg_val & OTX_EP_R_IN_CTL_IDLE) && loop--); + if (loop < 0) + return -EIO; } + return 0; } static void @@ -60,13 +64,18 @@ otx_ep_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no) otx_ep_write64(reg_val, otx_ep->hw_addr, OTX_EP_R_OUT_CONTROL(q_no)); } -static void +static int otx_ep_setup_global_input_regs(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++) - otx_ep_setup_global_iq_reg(otx_ep, q_no); + for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++) { + ret = otx_ep_setup_global_iq_reg(otx_ep, q_no); + if (ret) + return ret; + } + return 0; } static void @@ -78,18 +87,24 @@ otx_ep_setup_global_output_regs(struct otx_ep_device *otx_ep) otx_ep_setup_global_oq_reg(otx_ep, q_no); } -static void +static int otx_ep_setup_device_regs(struct otx_ep_device *otx_ep) { - otx_ep_setup_global_input_regs(otx_ep); + int ret; + + ret = otx_ep_setup_global_input_regs(otx_ep); + if (ret) + return ret; otx_ep_setup_global_output_regs(otx_ep); + return 0; } -static void +static int otx_ep_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) { struct otx_ep_instr_queue *iq = otx_ep->instr_queue[iq_no]; volatile uint64_t reg_val = 0ull; + int loop = OTX_EP_BUSY_LOOP_COUNT; reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_IN_CONTROL(iq_no)); @@ -100,7 +115,9 @@ otx_ep_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) do { reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_IN_CONTROL(iq_no)); - } while (!(reg_val & OTX_EP_R_IN_CTL_IDLE)); + } while (!(reg_val & OTX_EP_R_IN_CTL_IDLE) && loop--); + if (loop < 0) + return -EIO; } /* Write the start of the input queue's ring and its size */ @@ -120,10 +137,13 @@ otx_ep_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) otx_ep_dbg("InstQ[%d]:dbell reg @ 0x%p inst_cnt_reg @ 0x%p\n", iq_no, iq->doorbell_reg, iq->inst_cnt_reg); + loop = OTX_EP_BUSY_LOOP_COUNT; do { reg_val = rte_read32(iq->inst_cnt_reg); rte_write32(reg_val, iq->inst_cnt_reg); - } while (reg_val != 0); + } while ((reg_val != 0) && loop--); + if (loop < 0) + return -EIO; /* IN INTR_THRESHOLD is set to max(FFFFFFFF) which disable the IN INTR * to raise @@ -133,13 +153,15 @@ otx_ep_setup_iq_regs(struct otx_ep_device *otx_ep, uint32_t iq_no) */ otx_ep_write64(OTX_EP_CLEAR_IN_INT_LVLS, otx_ep->hw_addr, OTX_EP_R_IN_INT_LEVELS(iq_no)); + return 0; } -static void +static int otx_ep_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) { volatile uint64_t reg_val = 0ull; uint64_t oq_ctl = 0ull; + int loop = OTX_EP_BUSY_LOOP_COUNT; struct otx_ep_droq *droq = otx_ep->droq[oq_no]; @@ -150,10 +172,12 @@ otx_ep_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_OUT_CONTROL(oq_no)); - while (!(reg_val & OTX_EP_R_OUT_CTL_IDLE)) { + while (!(reg_val & OTX_EP_R_OUT_CTL_IDLE) && loop--) { reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_OUT_CONTROL(oq_no)); } + if (loop < 0) + return -EIO; otx_ep_write64(droq->desc_ring_dma, otx_ep->hw_addr, OTX_EP_R_OUT_SLIST_BADDR(oq_no)); @@ -180,11 +204,14 @@ otx_ep_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) OTX_EP_R_OUT_INT_LEVELS(oq_no)); /* 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)) { + while ((rte_read32(droq->pkts_credit_reg) != 0ull) && loop--) { rte_write32(OTX_EP_CLEAR_SLIST_DBELL, droq->pkts_credit_reg); rte_delay_ms(1); } + if (loop < 0) + return -EIO; otx_ep_dbg("OTX_EP_R[%d]_credit:%x\n", oq_no, rte_read32(droq->pkts_credit_reg)); @@ -195,18 +222,22 @@ otx_ep_setup_oq_regs(struct otx_ep_device *otx_ep, uint32_t oq_no) otx_ep_dbg("OTX_EP_R[%d]_sent: %x\n", oq_no, rte_read32(droq->pkts_sent_reg)); - while (((rte_read32(droq->pkts_sent_reg)) != 0ull)) { + loop = OTX_EP_BUSY_LOOP_COUNT; + while (((rte_read32(droq->pkts_sent_reg)) != 0ull) && loop--) { reg_val = rte_read32(droq->pkts_sent_reg); rte_write32((uint32_t)reg_val, droq->pkts_sent_reg); rte_delay_ms(1); } + if (loop < 0) + return -EIO; + return 0; } static int otx_ep_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) { - uint64_t loop = OTX_EP_BUSY_LOOP_COUNT; - uint64_t reg_val = 0ull; + volatile uint64_t reg_val = 0ull; + int loop = OTX_EP_BUSY_LOOP_COUNT; /* Resetting doorbells during IQ enabling also to handle abrupt * guest reboot. IQ reset does not clear the doorbells. @@ -219,7 +250,7 @@ otx_ep_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) rte_delay_ms(1); } - if (loop == 0) { + if (loop < 0) { otx_ep_err("dbell reset failed\n"); return -EIO; } @@ -238,8 +269,8 @@ otx_ep_enable_iq(struct otx_ep_device *otx_ep, uint32_t q_no) static int otx_ep_enable_oq(struct otx_ep_device *otx_ep, uint32_t q_no) { - uint64_t reg_val = 0ull; - uint64_t loop = OTX_EP_BUSY_LOOP_COUNT; + volatile uint64_t reg_val = 0ull; + int loop = OTX_EP_BUSY_LOOP_COUNT; /* Resetting doorbells during IQ enabling also to handle abrupt * guest reboot. IQ reset does not clear the doorbells. @@ -250,7 +281,7 @@ otx_ep_enable_oq(struct otx_ep_device *otx_ep, uint32_t q_no) OTX_EP_R_OUT_SLIST_DBELL(q_no))) != 0ull) && loop--) { rte_delay_ms(1); } - if (loop == 0) { + if (loop < 0) { otx_ep_err("dbell reset failed\n"); return -EIO; }