From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 774A9A04C3 for ; Fri, 22 Nov 2019 15:43:10 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6BB591BEA7; Fri, 22 Nov 2019 15:43:10 +0100 (CET) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by dpdk.org (Postfix) with ESMTP id C4C5C1BEB9 for ; Fri, 22 Nov 2019 15:43:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1574433789; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4ntm4udwlUFBbkEQbZ//XqJCtLQEHYfVKMT4onkf2Uo=; b=c2RkHxJHHQxyXRaKGME7NEHYrkXdXYJlqJYQ87+SgtKYdQ4HA1r6gEpLoEh0ChKXERx64L sLC+8w3XwSwzk2b/UJqIbRyEIDu6P158motnHMo3jxl1X3P7KQAlJwBREUY4VDIm93ganf UmIQ+QmQo8Df5lSaWv4m5Oy/sUasOiU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-134-tBx6wgQrPSeduGA0roNrQg-1; Fri, 22 Nov 2019 09:43:07 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BB20B184CAA3; Fri, 22 Nov 2019 14:43:06 +0000 (UTC) Received: from rh.redhat.com (unknown [10.36.118.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 833159F47; Fri, 22 Nov 2019 14:43:05 +0000 (UTC) From: Kevin Traynor To: Xiao Zhang Cc: Xiaolong Ye , Kevin Traynor , dpdk stable Date: Fri, 22 Nov 2019 14:41:30 +0000 Message-Id: <20191122144131.21231-44-ktraynor@redhat.com> In-Reply-To: <20191122144131.21231-1-ktraynor@redhat.com> References: <20191122144131.21231-1-ktraynor@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-MC-Unique: tBx6wgQrPSeduGA0roNrQg-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Subject: [dpdk-stable] patch 'net/e1000: fix i219 hang on reset/close' has been queued to LTS release 18.11.6 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Hi, FYI, your patch has been queued to LTS release 18.11.6 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 11/29/19. So please shout if anyone has objections. Also note that after the patch there's a diff of the upstream commit vs the patch applied to the branch. This will indicate if there was any rebasing needed to apply to the stable branch. If there were code changes for rebasi= ng (ie: not only metadata diffs), please double check that the rebase was correctly done. Queued patches are on a temporary branch at: https://github.com/kevintraynor/dpdk-stable-queue This queued commit can be viewed at: https://github.com/kevintraynor/dpdk-stable-queue/commit/0c97c2c11cb9408f35= cebbb6aaf94ed45671ccbc Thanks. Kevin. --- >From 0c97c2c11cb9408f35cebbb6aaf94ed45671ccbc Mon Sep 17 00:00:00 2001 From: Xiao Zhang Date: Mon, 22 Jul 2019 23:11:52 +0800 Subject: [PATCH] net/e1000: fix i219 hang on reset/close [ upstream commit 1fc9701238edcf0541289b9ae15565b6d9d7ab30] [ upstream commit 675f65dc660805eff1953e3dfb6242ec076a9444] Squashing these commits because an issue was identified with the first commit after it was applied on master but before backported to stable. The second commit fixes the issue introduced in the first commit. commit 1fc9701238edcf0541289b9ae15565b6d9d7ab30 Author: Xiao Zhang Date: Mon Jul 22 23:11:52 2019 +0800 net/e1000: fix i219 hang on reset/close Unit hang may occur if multiple descriptors are available in the rings during reset or close. This state can be detected by configure status by bit 8 in register. If the bit is set and there are pending descriptors in one of the rings, we must flush them before reset or close. Fixes: 805803445a02 ("e1000: support EM devices (also known as e1000/e1= 000e)") Signed-off-by: Xiao Zhang Reviewed-by: Xiaolong Ye commit 675f65dc660805eff1953e3dfb6242ec076a9444 Author: Xiao Zhang Date: Wed Sep 11 01:40:55 2019 +0800 net/e1000: fix MAC type checking The mac types of i219 are e1000_pch_spt and e1000_pch_cnp, correct the checking code of mac type when flushing i219 descriptor rings. Fixes: 1fc9701238ed ("net/e1000: fix i219 hang on reset/close") Reported-by: Kevin Traynor Signed-off-by: Xiao Zhang Acked-by: Kevin Traynor Reviewed-by: Xiaolong Ye Signed-off-by: Kevin Traynor --- drivers/net/e1000/e1000_ethdev.h | 4 ++ drivers/net/e1000/em_ethdev.c | 5 ++ drivers/net/e1000/em_rxtx.c | 111 +++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_eth= dev.h index 94edff08e..78fb61e41 100644 --- a/drivers/net/e1000/e1000_ethdev.h +++ b/drivers/net/e1000/e1000_ethdev.h @@ -36,4 +36,7 @@ #define IGB_MAX_RX_QUEUE_NUM_82576 16 =20 +#define E1000_I219_MAX_RX_QUEUE_NUM=09=092 +#define E1000_I219_MAX_TX_QUEUE_NUM=09=092 + #define E1000_SYN_FILTER_ENABLE 0x00000001 /* syn filter enable fie= ld */ #define E1000_SYN_FILTER_QUEUE 0x0000000E /* syn filter queue fiel= d */ @@ -516,4 +519,5 @@ int igb_config_rss_filter(struct rte_eth_dev *dev, =09=09=09struct igb_rte_flow_rss_conf *conf, =09=09=09bool add); +void em_flush_desc_rings(struct rte_eth_dev *dev); =20 #endif /* _E1000_ETHDEV_H_ */ diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c index 8230824e7..123c73053 100644 --- a/drivers/net/e1000/em_ethdev.c +++ b/drivers/net/e1000/em_ethdev.c @@ -738,4 +738,9 @@ eth_em_stop(struct rte_eth_dev *dev) =20 =09e1000_reset_hw(hw); + +=09/* Flush desc rings for i219 */ +=09if (hw->mac.type =3D=3D e1000_pch_spt || hw->mac.type =3D=3D e1000_pch_= cnp) +=09=09em_flush_desc_rings(dev); + =09if (hw->mac.type >=3D e1000_82544) =09=09E1000_WRITE_REG(hw, E1000_WUC, 0); diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c index 67c7ec701..951d1642c 100644 --- a/drivers/net/e1000/em_rxtx.c +++ b/drivers/net/e1000/em_rxtx.c @@ -19,4 +19,5 @@ #include #include +#include #include #include @@ -60,4 +61,9 @@ =09=09(PKT_TX_OFFLOAD_MASK ^ E1000_TX_OFFLOAD_MASK) =20 +/* PCI offset for querying configuration status register */ +#define PCI_CFG_STATUS_REG 0x06 +#define FLUSH_DESC_REQUIRED 0x100 + + /** * Structure associated with each descriptor of the RX ring of a RX queue. @@ -2017,2 +2023,107 @@ em_txq_info_get(struct rte_eth_dev *dev, uint16_t q= ueue_id, =09qinfo->conf.offloads =3D txq->offloads; } + +static void +e1000_flush_tx_ring(struct rte_eth_dev *dev) +{ +=09struct e1000_hw *hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private)= ; +=09volatile struct e1000_data_desc *tx_desc; +=09volatile uint32_t *tdt_reg_addr; +=09uint32_t tdt, tctl, txd_lower =3D E1000_TXD_CMD_IFCS; +=09uint16_t size =3D 512; +=09struct em_tx_queue *txq; +=09int i; + +=09if (dev->data->tx_queues =3D=3D NULL) +=09=09return; +=09tctl =3D E1000_READ_REG(hw, E1000_TCTL); +=09E1000_WRITE_REG(hw, E1000_TCTL, tctl | E1000_TCTL_EN); +=09for (i =3D 0; i < dev->data->nb_tx_queues && +=09=09i < E1000_I219_MAX_TX_QUEUE_NUM; i++) { +=09=09txq =3D dev->data->tx_queues[i]; +=09=09tdt =3D E1000_READ_REG(hw, E1000_TDT(i)); +=09=09if (tdt !=3D txq->tx_tail) +=09=09=09return; +=09=09tx_desc =3D &txq->tx_ring[txq->tx_tail]; +=09=09tx_desc->buffer_addr =3D rte_cpu_to_le_64(txq->tx_ring_phys_addr); +=09=09tx_desc->lower.data =3D rte_cpu_to_le_32(txd_lower | size); +=09=09tx_desc->upper.data =3D 0; + +=09=09rte_wmb(); +=09=09txq->tx_tail++; +=09=09if (txq->tx_tail =3D=3D txq->nb_tx_desc) +=09=09=09txq->tx_tail =3D 0; +=09=09rte_io_wmb(); +=09=09tdt_reg_addr =3D E1000_PCI_REG_ADDR(hw, E1000_TDT(i)); +=09=09E1000_PCI_REG_WRITE_RELAXED(tdt_reg_addr, txq->tx_tail); +=09=09usec_delay(250); +=09} +} + +static void +e1000_flush_rx_ring(struct rte_eth_dev *dev) +{ +=09uint32_t rctl, rxdctl; +=09struct e1000_hw *hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private)= ; +=09int i; + +=09rctl =3D E1000_READ_REG(hw, E1000_RCTL); +=09E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); +=09E1000_WRITE_FLUSH(hw); +=09usec_delay(150); + +=09for (i =3D 0; i < dev->data->nb_rx_queues && +=09=09i < E1000_I219_MAX_RX_QUEUE_NUM; i++) { +=09=09rxdctl =3D E1000_READ_REG(hw, E1000_RXDCTL(i)); +=09=09/* zero the lower 14 bits (prefetch and host thresholds) */ +=09=09rxdctl &=3D 0xffffc000; + +=09=09/* update thresholds: prefetch threshold to 31, +=09=09 * host threshold to 1 and make sure the granularity +=09=09 * is "descriptors" and not "cache lines" +=09=09 */ +=09=09rxdctl |=3D (0x1F | (1UL << 8) | E1000_RXDCTL_THRESH_UNIT_DESC); + +=09=09E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); +=09} +=09/* momentarily enable the RX ring for the changes to take effect */ +=09E1000_WRITE_REG(hw, E1000_RCTL, rctl | E1000_RCTL_EN); +=09E1000_WRITE_FLUSH(hw); +=09usec_delay(150); +=09E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); +} + +/** + * em_flush_desc_rings - remove all descriptors from the descriptor rings + * + * In i219, the descriptor rings must be emptied before resetting/closing = the + * HW. Failure to do this will cause the HW to enter a unit hang state whi= ch + * can only be released by PCI reset on the device + * + */ + +void +em_flush_desc_rings(struct rte_eth_dev *dev) +{ +=09uint32_t fextnvm11, tdlen; +=09struct e1000_hw *hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private)= ; +=09struct rte_pci_device *pci_dev =3D RTE_ETH_DEV_TO_PCI(dev); +=09uint16_t pci_cfg_status =3D 0; + +=09fextnvm11 =3D E1000_READ_REG(hw, E1000_FEXTNVM11); +=09E1000_WRITE_REG(hw, E1000_FEXTNVM11, +=09=09=09fextnvm11 | E1000_FEXTNVM11_DISABLE_MULR_FIX); +=09tdlen =3D E1000_READ_REG(hw, E1000_TDLEN(0)); +=09rte_pci_read_config(pci_dev, &pci_cfg_status, sizeof(pci_cfg_status), +=09=09=09=09PCI_CFG_STATUS_REG); + +=09/* do nothing if we're not in faulty state, or if the queue is empty */ +=09if ((pci_cfg_status & FLUSH_DESC_REQUIRED) && tdlen) { +=09=09/* flush desc ring */ +=09=09e1000_flush_tx_ring(dev); +=09=09rte_pci_read_config(pci_dev, &pci_cfg_status, +=09=09=09=09sizeof(pci_cfg_status), PCI_CFG_STATUS_REG); +=09=09if (pci_cfg_status & FLUSH_DESC_REQUIRED) +=09=09=09e1000_flush_rx_ring(dev); +=09} +} --=20 2.21.0 --- Diff of the applied patch vs upstream commit (please double-check if non-= empty: --- --- -=092019-11-22 14:36:57.543482433 +0000 +++ 0044-net-e1000-fix-i219-hang-on-reset-close.patch=092019-11-22 14:36:55= .231148560 +0000 @@ -0,0 +1,216 @@ +From 0c97c2c11cb9408f35cebbb6aaf94ed45671ccbc Mon Sep 17 00:00:00 2001 +From: Xiao Zhang +Date: Mon, 22 Jul 2019 23:11:52 +0800 +Subject: [PATCH] net/e1000: fix i219 hang on reset/close + +[ upstream commit 1fc9701238edcf0541289b9ae15565b6d9d7ab30] +[ upstream commit 675f65dc660805eff1953e3dfb6242ec076a9444] + +Squashing these commits because an issue was identified with +the first commit after it was applied on master but before +backported to stable. The second commit fixes the issue +introduced in the first commit. + +commit 1fc9701238edcf0541289b9ae15565b6d9d7ab30 +Author: Xiao Zhang +Date: Mon Jul 22 23:11:52 2019 +0800 + + net/e1000: fix i219 hang on reset/close + + Unit hang may occur if multiple descriptors are available in the rings + during reset or close. This state can be detected by configure status + by bit 8 in register. If the bit is set and there are pending + descriptors in one of the rings, we must flush them before reset or + close. + + Fixes: 805803445a02 ("e1000: support EM devices (also known as e1000/e= 1000e)") + + Signed-off-by: Xiao Zhang + Reviewed-by: Xiaolong Ye + +commit 675f65dc660805eff1953e3dfb6242ec076a9444 +Author: Xiao Zhang +Date: Wed Sep 11 01:40:55 2019 +0800 + + net/e1000: fix MAC type checking + + The mac types of i219 are e1000_pch_spt and e1000_pch_cnp, correct the + checking code of mac type when flushing i219 descriptor rings. + + Fixes: 1fc9701238ed ("net/e1000: fix i219 hang on reset/close") + + Reported-by: Kevin Traynor + Signed-off-by: Xiao Zhang + Acked-by: Kevin Traynor + Reviewed-by: Xiaolong Ye + +Signed-off-by: Kevin Traynor +--- + drivers/net/e1000/e1000_ethdev.h | 4 ++ + drivers/net/e1000/em_ethdev.c | 5 ++ + drivers/net/e1000/em_rxtx.c | 111 +++++++++++++++++++++++++++++++ + 3 files changed, 120 insertions(+) + +diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_et= hdev.h +index 94edff08e..78fb61e41 100644 +--- a/drivers/net/e1000/e1000_ethdev.h ++++ b/drivers/net/e1000/e1000_ethdev.h +@@ -36,4 +36,7 @@ + #define IGB_MAX_RX_QUEUE_NUM_82576 16 +=20 ++#define E1000_I219_MAX_RX_QUEUE_NUM=09=092 ++#define E1000_I219_MAX_TX_QUEUE_NUM=09=092 ++ + #define E1000_SYN_FILTER_ENABLE 0x00000001 /* syn filter enable fi= eld */ + #define E1000_SYN_FILTER_QUEUE 0x0000000E /* syn filter queue fie= ld */ +@@ -516,4 +519,5 @@ int igb_config_rss_filter(struct rte_eth_dev *dev, + =09=09=09struct igb_rte_flow_rss_conf *conf, + =09=09=09bool add); ++void em_flush_desc_rings(struct rte_eth_dev *dev); +=20 + #endif /* _E1000_ETHDEV_H_ */ +diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c +index 8230824e7..123c73053 100644 +--- a/drivers/net/e1000/em_ethdev.c ++++ b/drivers/net/e1000/em_ethdev.c +@@ -738,4 +738,9 @@ eth_em_stop(struct rte_eth_dev *dev) +=20 + =09e1000_reset_hw(hw); ++ ++=09/* Flush desc rings for i219 */ ++=09if (hw->mac.type =3D=3D e1000_pch_spt || hw->mac.type =3D=3D e1000_pch= _cnp) ++=09=09em_flush_desc_rings(dev); ++ + =09if (hw->mac.type >=3D e1000_82544) + =09=09E1000_WRITE_REG(hw, E1000_WUC, 0); +diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c +index 67c7ec701..951d1642c 100644 +--- a/drivers/net/e1000/em_rxtx.c ++++ b/drivers/net/e1000/em_rxtx.c +@@ -19,4 +19,5 @@ + #include + #include ++#include + #include + #include +@@ -60,4 +61,9 @@ + =09=09(PKT_TX_OFFLOAD_MASK ^ E1000_TX_OFFLOAD_MASK) +=20 ++/* PCI offset for querying configuration status register */ ++#define PCI_CFG_STATUS_REG 0x06 ++#define FLUSH_DESC_REQUIRED 0x100 ++ ++ + /** + * Structure associated with each descriptor of the RX ring of a RX queue= . +@@ -2017,2 +2023,107 @@ em_txq_info_get(struct rte_eth_dev *dev, uint16_t = queue_id, + =09qinfo->conf.offloads =3D txq->offloads; + } ++ ++static void ++e1000_flush_tx_ring(struct rte_eth_dev *dev) ++{ ++=09struct e1000_hw *hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private= ); ++=09volatile struct e1000_data_desc *tx_desc; ++=09volatile uint32_t *tdt_reg_addr; ++=09uint32_t tdt, tctl, txd_lower =3D E1000_TXD_CMD_IFCS; ++=09uint16_t size =3D 512; ++=09struct em_tx_queue *txq; ++=09int i; ++ ++=09if (dev->data->tx_queues =3D=3D NULL) ++=09=09return; ++=09tctl =3D E1000_READ_REG(hw, E1000_TCTL); ++=09E1000_WRITE_REG(hw, E1000_TCTL, tctl | E1000_TCTL_EN); ++=09for (i =3D 0; i < dev->data->nb_tx_queues && ++=09=09i < E1000_I219_MAX_TX_QUEUE_NUM; i++) { ++=09=09txq =3D dev->data->tx_queues[i]; ++=09=09tdt =3D E1000_READ_REG(hw, E1000_TDT(i)); ++=09=09if (tdt !=3D txq->tx_tail) ++=09=09=09return; ++=09=09tx_desc =3D &txq->tx_ring[txq->tx_tail]; ++=09=09tx_desc->buffer_addr =3D rte_cpu_to_le_64(txq->tx_ring_phys_addr); ++=09=09tx_desc->lower.data =3D rte_cpu_to_le_32(txd_lower | size); ++=09=09tx_desc->upper.data =3D 0; ++ ++=09=09rte_wmb(); ++=09=09txq->tx_tail++; ++=09=09if (txq->tx_tail =3D=3D txq->nb_tx_desc) ++=09=09=09txq->tx_tail =3D 0; ++=09=09rte_io_wmb(); ++=09=09tdt_reg_addr =3D E1000_PCI_REG_ADDR(hw, E1000_TDT(i)); ++=09=09E1000_PCI_REG_WRITE_RELAXED(tdt_reg_addr, txq->tx_tail); ++=09=09usec_delay(250); ++=09} ++} ++ ++static void ++e1000_flush_rx_ring(struct rte_eth_dev *dev) ++{ ++=09uint32_t rctl, rxdctl; ++=09struct e1000_hw *hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private= ); ++=09int i; ++ ++=09rctl =3D E1000_READ_REG(hw, E1000_RCTL); ++=09E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); ++=09E1000_WRITE_FLUSH(hw); ++=09usec_delay(150); ++ ++=09for (i =3D 0; i < dev->data->nb_rx_queues && ++=09=09i < E1000_I219_MAX_RX_QUEUE_NUM; i++) { ++=09=09rxdctl =3D E1000_READ_REG(hw, E1000_RXDCTL(i)); ++=09=09/* zero the lower 14 bits (prefetch and host thresholds) */ ++=09=09rxdctl &=3D 0xffffc000; ++ ++=09=09/* update thresholds: prefetch threshold to 31, ++=09=09 * host threshold to 1 and make sure the granularity ++=09=09 * is "descriptors" and not "cache lines" ++=09=09 */ ++=09=09rxdctl |=3D (0x1F | (1UL << 8) | E1000_RXDCTL_THRESH_UNIT_DESC); ++ ++=09=09E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); ++=09} ++=09/* momentarily enable the RX ring for the changes to take effect */ ++=09E1000_WRITE_REG(hw, E1000_RCTL, rctl | E1000_RCTL_EN); ++=09E1000_WRITE_FLUSH(hw); ++=09usec_delay(150); ++=09E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); ++} ++ ++/** ++ * em_flush_desc_rings - remove all descriptors from the descriptor rings ++ * ++ * In i219, the descriptor rings must be emptied before resetting/closing= the ++ * HW. Failure to do this will cause the HW to enter a unit hang state wh= ich ++ * can only be released by PCI reset on the device ++ * ++ */ ++ ++void ++em_flush_desc_rings(struct rte_eth_dev *dev) ++{ ++=09uint32_t fextnvm11, tdlen; ++=09struct e1000_hw *hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private= ); ++=09struct rte_pci_device *pci_dev =3D RTE_ETH_DEV_TO_PCI(dev); ++=09uint16_t pci_cfg_status =3D 0; ++ ++=09fextnvm11 =3D E1000_READ_REG(hw, E1000_FEXTNVM11); ++=09E1000_WRITE_REG(hw, E1000_FEXTNVM11, ++=09=09=09fextnvm11 | E1000_FEXTNVM11_DISABLE_MULR_FIX); ++=09tdlen =3D E1000_READ_REG(hw, E1000_TDLEN(0)); ++=09rte_pci_read_config(pci_dev, &pci_cfg_status, sizeof(pci_cfg_status), ++=09=09=09=09PCI_CFG_STATUS_REG); ++ ++=09/* do nothing if we're not in faulty state, or if the queue is empty *= / ++=09if ((pci_cfg_status & FLUSH_DESC_REQUIRED) && tdlen) { ++=09=09/* flush desc ring */ ++=09=09e1000_flush_tx_ring(dev); ++=09=09rte_pci_read_config(pci_dev, &pci_cfg_status, ++=09=09=09=09sizeof(pci_cfg_status), PCI_CFG_STATUS_REG); ++=09=09if (pci_cfg_status & FLUSH_DESC_REQUIRED) ++=09=09=09e1000_flush_rx_ring(dev); ++=09} ++} +--=20 +2.21.0 +