Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/947248/?format=api
{ "id": 947248, "url": "http://patchwork.ozlabs.org/api/patches/947248/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180720222934.3568.15842.stgit@ahduyck-green-test.jf.intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20180720222934.3568.15842.stgit@ahduyck-green-test.jf.intel.com>", "list_archive_url": null, "date": "2018-07-20T22:29:34", "name": "[jkirsher/next-queue,2/2] ixgbe: Refactor queue disable logic to take completion time into account", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "1d613a73abd79007ff83ed54066d6154a091bcfc", "submitter": { "id": 251, "url": "http://patchwork.ozlabs.org/api/people/251/?format=api", "name": "Duyck, Alexander H", "email": "alexander.h.duyck@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180720222934.3568.15842.stgit@ahduyck-green-test.jf.intel.com/mbox/", "series": [ { "id": 56816, "url": "http://patchwork.ozlabs.org/api/series/56816/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=56816", "date": "2018-07-20T22:29:29", "name": "[jkirsher/next-queue,1/2] ixgbe: Reorder Tx/Rx shutdown to reduce time needed to stop device", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/56816/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/947248/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/947248/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.133; helo=hemlock.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 41XQlV1GxVz9s55\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat, 21 Jul 2018 08:38:29 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 2EABC8AAD2;\n\tFri, 20 Jul 2018 22:38:28 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id feRKUE0sgYP6; Fri, 20 Jul 2018 22:38:25 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 232AC8AAC7;\n\tFri, 20 Jul 2018 22:38:25 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id E76E31C0945\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 20 Jul 2018 22:38:23 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id E4FEEE485F\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 20 Jul 2018 22:38:23 +0000 (UTC)", "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id Gr0cD3h99h35 for <intel-wired-lan@lists.osuosl.org>;\n\tFri, 20 Jul 2018 22:38:22 +0000 (UTC)", "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id DF052E4859\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 20 Jul 2018 22:38:22 +0000 (UTC)", "from orsmga008.jf.intel.com ([10.7.209.65])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t20 Jul 2018 15:38:21 -0700", "from ahduyck-green-test.jf.intel.com ([10.166.244.158])\n\tby orsmga008.jf.intel.com with ESMTP; 20 Jul 2018 15:38:22 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.51,381,1526367600\"; d=\"scan'208\";a=\"58557688\"", "From": "Alexander Duyck <alexander.h.duyck@intel.com>", "To": "lihong.yang@intel.com, todd.fujinaka@intel.com,\n\tintel-wired-lan@lists.osuosl.org", "Date": "Fri, 20 Jul 2018 18:29:34 -0400", "Message-ID": "<20180720222934.3568.15842.stgit@ahduyck-green-test.jf.intel.com>", "In-Reply-To": "<20180720222647.3568.34992.stgit@ahduyck-green-test.jf.intel.com>", "References": "<20180720222647.3568.34992.stgit@ahduyck-green-test.jf.intel.com>", "User-Agent": "StGit/0.17.1-dirty", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [jkirsher/next-queue PATCH 2/2] ixgbe: Refactor\n\tqueue disable logic to take completion time into account", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "This change is meant to allow us to take completion time into account when\ndisabling queues. Previously we were just working with hard coded values\nfor how long we should wait. This worked fine for the standard case where\ncompletion timeout was operating in the 50us to 50ms range, however on\nplatforms that have higher completion timeout times this was resulting in\nRx queues disable messages being displayed as we weren't waiting long\nenough for outstanding Rx DMA completions.\n\nSigned-off-by: Alexander Duyck <alexander.h.duyck@intel.com>\n---\n drivers/net/ethernet/intel/ixgbe/ixgbe.h | 3 \n drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 32 +--\n drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 280 +++++++++++++++++-----\n 3 files changed, 224 insertions(+), 91 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\nindex 144d5fe..4fc906c 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n@@ -855,7 +855,8 @@ enum ixgbe_boards {\n void ixgbe_free_tx_resources(struct ixgbe_ring *);\n void ixgbe_configure_rx_ring(struct ixgbe_adapter *, struct ixgbe_ring *);\n void ixgbe_configure_tx_ring(struct ixgbe_adapter *, struct ixgbe_ring *);\n-void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, struct ixgbe_ring *);\n+void ixgbe_disable_rx(struct ixgbe_adapter *adapter);\n+void ixgbe_disable_tx(struct ixgbe_adapter *adapter);\n void ixgbe_update_stats(struct ixgbe_adapter *adapter);\n int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);\n bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\nindex 1d68884..e5a8461 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\n@@ -1698,35 +1698,17 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)\n \n static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)\n {\n-\tstruct ixgbe_ring *tx_ring = &adapter->test_tx_ring;\n-\tstruct ixgbe_ring *rx_ring = &adapter->test_rx_ring;\n-\tstruct ixgbe_hw *hw = &adapter->hw;\n-\tu32 reg_ctl;\n-\n-\t/* shut down the DMA engines now so they can be reinitialized later */\n+\t/* Shut down the DMA engines now so they can be reinitialized later,\n+\t * since the test rings and normally used rings should overlap on\n+\t * queue 0 we can just use the standard disable Rx/Tx calls and they\n+\t * will take care of disabling the test rings for us.\n+\t */\n \n \t/* first Rx */\n-\thw->mac.ops.disable_rx(hw);\n-\tixgbe_disable_rx_queue(adapter, rx_ring);\n+\tixgbe_disable_rx(adapter);\n \n \t/* now Tx */\n-\treg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx));\n-\treg_ctl &= ~IXGBE_TXDCTL_ENABLE;\n-\tIXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl);\n-\n-\tswitch (hw->mac.type) {\n-\tcase ixgbe_mac_82599EB:\n-\tcase ixgbe_mac_X540:\n-\tcase ixgbe_mac_X550:\n-\tcase ixgbe_mac_X550EM_x:\n-\tcase ixgbe_mac_x550em_a:\n-\t\treg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);\n-\t\treg_ctl &= ~IXGBE_DMATXCTL_TE;\n-\t\tIXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);\n-\t\tbreak;\n-\tdefault:\n-\t\tbreak;\n-\t}\n+\tixgbe_disable_tx(adapter);\n \n \tixgbe_reset(adapter);\n \ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\nindex 7eef089..951655b 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n@@ -4022,38 +4022,6 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,\n \t}\n }\n \n-void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter,\n-\t\t\t struct ixgbe_ring *ring)\n-{\n-\tstruct ixgbe_hw *hw = &adapter->hw;\n-\tint wait_loop = IXGBE_MAX_RX_DESC_POLL;\n-\tu32 rxdctl;\n-\tu8 reg_idx = ring->reg_idx;\n-\n-\tif (ixgbe_removed(hw->hw_addr))\n-\t\treturn;\n-\trxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));\n-\trxdctl &= ~IXGBE_RXDCTL_ENABLE;\n-\n-\t/* write value back with RXDCTL.ENABLE bit cleared */\n-\tIXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);\n-\n-\tif (hw->mac.type == ixgbe_mac_82598EB &&\n-\t !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))\n-\t\treturn;\n-\n-\t/* the hardware may take up to 100us to really disable the rx queue */\n-\tdo {\n-\t\tudelay(10);\n-\t\trxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));\n-\t} while (--wait_loop && (rxdctl & IXGBE_RXDCTL_ENABLE));\n-\n-\tif (!wait_loop) {\n-\t\te_err(drv, \"RXDCTL.ENABLE on Rx queue %d not cleared within \"\n-\t\t \"the polling period\\n\", reg_idx);\n-\t}\n-}\n-\n void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,\n \t\t\t struct ixgbe_ring *ring)\n {\n@@ -4063,9 +4031,13 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,\n \tu32 rxdctl;\n \tu8 reg_idx = ring->reg_idx;\n \n-\t/* disable queue to avoid issues while updating state */\n+\t/* disable queue to avoid use of these values while updating state */\n \trxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));\n-\tixgbe_disable_rx_queue(adapter, ring);\n+\trxdctl &= ~IXGBE_RXDCTL_ENABLE;\n+\n+\t/* write value back with RXDCTL.ENABLE bit cleared */\n+\tIXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);\n+\tIXGBE_WRITE_FLUSH(hw);\n \n \tIXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32)));\n \tIXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32));\n@@ -5633,6 +5605,212 @@ void ixgbe_up(struct ixgbe_adapter *adapter)\n \tixgbe_up_complete(adapter);\n }\n \n+unsigned long ixgbe_get_completion_timeout(struct ixgbe_adapter *adapter)\n+{\n+\tu16 devctl2;\n+\n+\tpcie_capability_read_word(adapter->pdev, PCI_EXP_DEVCTL2, &devctl2);\n+\n+\tswitch (devctl2 & IXGBE_PCIDEVCTRL2_TIMEO_MASK) {\n+\tcase IXGBE_PCIDEVCTRL2_17_34s:\n+\tcase IXGBE_PCIDEVCTRL2_4_8s:\n+\t\t/* For now we cap the upper limit on delay to 2 seconds\n+\t\t * as we end up going up to 34 seconds of delay in worst\n+\t\t * case timeout value.\n+\t\t */\n+\tcase IXGBE_PCIDEVCTRL2_1_2s:\n+\t\treturn 2000000ul;\t/* 2.0 s */\n+\tcase IXGBE_PCIDEVCTRL2_260_520ms:\n+\t\treturn 520000ul;\t/* 520 ms */\n+\tcase IXGBE_PCIDEVCTRL2_65_130ms:\n+\t\treturn 130000ul;\t/* 130 ms */\n+\tcase IXGBE_PCIDEVCTRL2_16_32ms:\n+\t\treturn 32000ul;\t\t/* 32 ms */\n+\tcase IXGBE_PCIDEVCTRL2_1_2ms:\n+\t\treturn 2000ul;\t\t/* 2 ms */\n+\tcase IXGBE_PCIDEVCTRL2_50_100us:\n+\t\treturn 100ul;\t\t/* 100 us */\n+\tcase IXGBE_PCIDEVCTRL2_16_32ms_def:\n+\t\treturn 32000ul;\t\t/* 32 ms */\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* We shouldn't need to hit this path, but just in case default as\n+\t * though completion timeout is not supported and support 32ms.\n+\t */\n+\treturn 32000ul;\n+}\n+\n+void ixgbe_disable_rx(struct ixgbe_adapter *adapter)\n+{\n+\tunsigned long wait_delay, delay_interval;\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tint i, wait_loop;\n+\tu32 rxdctl;\n+\n+\t/* disable receives */\n+\thw->mac.ops.disable_rx(hw);\n+\n+\tif (ixgbe_removed(hw->hw_addr))\n+\t\treturn;\n+\n+\t/* disable all enabled Rx queues */\n+\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\tstruct ixgbe_ring *ring = adapter->rx_ring[i];\n+\t\tu8 reg_idx = ring->reg_idx;\n+\n+\t\trxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));\n+\t\trxdctl &= ~IXGBE_RXDCTL_ENABLE;\n+\t\trxdctl |= IXGBE_RXDCTL_SWFLSH;\n+\n+\t\t/* write value back with RXDCTL.ENABLE bit cleared */\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);\n+\t}\n+\n+\t/* RXDCTL.EN may not change on 82598 if link is down, so skip it */\n+\tif (hw->mac.type == ixgbe_mac_82598EB &&\n+\t !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))\n+\t\treturn;\n+\n+\t/* Determine our minimum delay interval. We will increase this value\n+\t * with each subsequent test. This way if the device returns quickly\n+\t * we should spend as little time as possible waiting, however as\n+\t * the time increases we will wait for larger periods of time.\n+\t *\n+\t * The trick here is that we increase the interval using the\n+\t * following pattern: 1x 3x 5x 7x 9x 11x 13x 15x 17x 19x. The result\n+\t * of that wait is that it totals up to 100x whatever interval we\n+\t * choose. Since our minimum wait is 100us we can just divide the\n+\t * total timeout by 100 to get our minimum delay interval.\n+\t */\n+\tdelay_interval = ixgbe_get_completion_timeout(adapter) / 100;\n+\n+\twait_loop = IXGBE_MAX_RX_DESC_POLL;\n+\twait_delay = delay_interval;\n+\n+\twhile (wait_loop--) {\n+\t\tusleep_range(wait_delay, wait_delay + 10);\n+\t\twait_delay += delay_interval * 2;\n+\t\trxdctl = 0;\n+\n+\t\t/* OR together the reading of all the active RXDCTL registers,\n+\t\t * and then test the result. We need the disable to complete\n+\t\t * before we start freeing the memory and invalidating the\n+\t\t * DMA mappings.\n+\t\t */\n+\t\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\t\tstruct ixgbe_ring *ring = adapter->rx_ring[i];\n+\t\t\tu8 reg_idx = ring->reg_idx;\n+\n+\t\t\trxdctl |= IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));\n+\t\t}\n+\n+\t\tif (!(rxdctl & IXGBE_RXDCTL_ENABLE))\n+\t\t\treturn;\n+\t}\n+\n+\te_err(drv,\n+\t \"RXDCTL.ENABLE for one or more queues not cleared within the polling period\\n\");\n+}\n+\n+void ixgbe_disable_tx(struct ixgbe_adapter *adapter)\n+{\n+\tunsigned long wait_delay, delay_interval;\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tint i, wait_loop;\n+\tu32 txdctl;\n+\n+\tif (ixgbe_removed(hw->hw_addr))\n+\t\treturn;\n+\n+\t/* disable all enabled Tx queues */\n+\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\tstruct ixgbe_ring *ring = adapter->tx_ring[i];\n+\t\tu8 reg_idx = ring->reg_idx;\n+\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);\n+\t}\n+\n+\t/* disable all enabled XDP Tx queues */\n+\tfor (i = 0; i < adapter->num_xdp_queues; i++) {\n+\t\tstruct ixgbe_ring *ring = adapter->xdp_ring[i];\n+\t\tu8 reg_idx = ring->reg_idx;\n+\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);\n+\t}\n+\n+\t/* If the link is now up there shouldn't be much in the way of\n+\t * pending transactions. Those that are left will be flushed out\n+\t * when the reset logic goes through the flush sequence to clean out\n+\t * the pending Tx transactions.\n+\t */\n+\tif (!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))\n+\t\tgoto dma_engine_disable;\n+\n+\t/* Determine our minimum delay interval. We will increase this value\n+\t * with each subsequent test. This way if the device returns quickly\n+\t * we should spend as little time as possible waiting, however as\n+\t * the time increases we will wait for larger periods of time.\n+\t *\n+\t * The trick here is that we increase the interval using the\n+\t * following pattern: 1x 3x 5x 7x 9x 11x 13x 15x 17x 19x. The result\n+\t * of that wait is that it totals up to 100x whatever interval we\n+\t * choose. Since our minimum wait is 100us we can just divide the\n+\t * total timeout by 100 to get our minimum delay interval.\n+\t */\n+\tdelay_interval = ixgbe_get_completion_timeout(adapter) / 100;\n+\n+\twait_loop = IXGBE_MAX_RX_DESC_POLL;\n+\twait_delay = delay_interval;\n+\n+\twhile (wait_loop--) {\n+\t\tusleep_range(wait_delay, wait_delay + 10);\n+\t\twait_delay += delay_interval * 2;\n+\t\ttxdctl = 0;\n+\n+\t\t/* OR together the reading of all the active TXDCTL registers,\n+\t\t * and then test the result. We need the disable to complete\n+\t\t * before we start freeing the memory and invalidating the\n+\t\t * DMA mappings.\n+\t\t */\n+\t\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\t\tstruct ixgbe_ring *ring = adapter->tx_ring[i];\n+\t\t\tu8 reg_idx = ring->reg_idx;\n+\n+\t\t\ttxdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));\n+\t\t}\n+\t\tfor (i = 0; i < adapter->num_xdp_queues; i++) {\n+\t\t\tstruct ixgbe_ring *ring = adapter->xdp_ring[i];\n+\t\t\tu8 reg_idx = ring->reg_idx;\n+\n+\t\t\ttxdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));\n+\t\t}\n+\n+\t\tif (!(txdctl & IXGBE_TXDCTL_ENABLE))\n+\t\t\tgoto dma_engine_disable;\n+\t}\n+\n+\te_err(drv,\n+\t \"TXDCTL.ENABLE for one or more queues not cleared within the polling period\\n\");\n+\n+dma_engine_disable:\n+\t/* Disable the Tx DMA engine on 82599 and later MAC */\n+\tswitch (hw->mac.type) {\n+\tcase ixgbe_mac_82599EB:\n+\tcase ixgbe_mac_X540:\n+\tcase ixgbe_mac_X550:\n+\tcase ixgbe_mac_X550EM_x:\n+\tcase ixgbe_mac_x550em_a:\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,\n+\t\t\t\t(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &\n+\t\t\t\t ~IXGBE_DMATXCTL_TE));\n+\t\t/* fall through */\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n void ixgbe_reset(struct ixgbe_adapter *adapter)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n@@ -5821,13 +5999,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)\n \tnetif_carrier_off(netdev);\n \tnetif_tx_disable(netdev);\n \n-\t/* disable receives */\n-\thw->mac.ops.disable_rx(hw);\n-\n-\t/* disable all enabled rx queues */\n-\tfor (i = 0; i < adapter->num_rx_queues; i++)\n-\t\t/* this call also flushes the previous write */\n-\t\tixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]);\n+\t/* Disable Rx */\n+\tixgbe_disable_rx(adapter);\n \n \t/* synchronize_sched() needed for pending XDP buffers to drain */\n \tif (adapter->xdp_ring[0])\n@@ -5859,30 +6032,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)\n \t}\n \n \t/* disable transmits in the hardware now that interrupts are off */\n-\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n-\t\tu8 reg_idx = adapter->tx_ring[i]->reg_idx;\n-\t\tIXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);\n-\t}\n-\tfor (i = 0; i < adapter->num_xdp_queues; i++) {\n-\t\tu8 reg_idx = adapter->xdp_ring[i]->reg_idx;\n-\n-\t\tIXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);\n-\t}\n-\n-\t/* Disable the Tx DMA engine on 82599 and later MAC */\n-\tswitch (hw->mac.type) {\n-\tcase ixgbe_mac_82599EB:\n-\tcase ixgbe_mac_X540:\n-\tcase ixgbe_mac_X550:\n-\tcase ixgbe_mac_X550EM_x:\n-\tcase ixgbe_mac_x550em_a:\n-\t\tIXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,\n-\t\t\t\t(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &\n-\t\t\t\t ~IXGBE_DMATXCTL_TE));\n-\t\tbreak;\n-\tdefault:\n-\t\tbreak;\n-\t}\n+\tixgbe_disable_tx(adapter);\n \n \tif (!pci_channel_offline(adapter->pdev))\n \t\tixgbe_reset(adapter);\n", "prefixes": [ "jkirsher/next-queue", "2/2" ] }