get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/669017/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 669017,
    "url": "http://patchwork.ozlabs.org/api/patches/669017/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1473715124-31296-9-git-send-email-bimmy.pujari@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": "<1473715124-31296-9-git-send-email-bimmy.pujari@intel.com>",
    "list_archive_url": null,
    "date": "2016-09-12T21:18:44",
    "name": "[next,S46,8/8] i40evf: support queue-specific settings for interrupt moderation",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "800f55a7c7265c5db51036ca78d234caeaf77e22",
    "submitter": {
        "id": 68919,
        "url": "http://patchwork.ozlabs.org/api/people/68919/?format=api",
        "name": "Pujari, Bimmy",
        "email": "bimmy.pujari@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/1473715124-31296-9-git-send-email-bimmy.pujari@intel.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/669017/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/669017/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@lists.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"
        ],
        "Received": [
            "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\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 3sY10q5LlLz9sdg\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 13 Sep 2016 07:19:55 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 42B168911B;\n\tMon, 12 Sep 2016 21:19:54 +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 m-2lTMvHUaIq; Mon, 12 Sep 2016 21:19:52 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 7CA6889030;\n\tMon, 12 Sep 2016 21:19:37 +0000 (UTC)",
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\tby ash.osuosl.org (Postfix) with ESMTP id F2E061C2D64\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 12 Sep 2016 21:19:35 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id EB0B131510\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 12 Sep 2016 21:19:35 +0000 (UTC)",
            "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 3UUR8QpBvvX3 for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 12 Sep 2016 21:19:18 +0000 (UTC)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby silver.osuosl.org (Postfix) with ESMTPS id BFBE131617\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 12 Sep 2016 21:19:17 +0000 (UTC)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby orsmga105.jf.intel.com with ESMTP; 12 Sep 2016 14:19:16 -0700",
            "from bimmy.jf.intel.com (HELO bimmy.linux1.jf.intel.com)\n\t([134.134.2.177])\n\tby orsmga003.jf.intel.com with ESMTP; 12 Sep 2016 14:19:17 -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-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.30,324,1470726000\"; d=\"scan'208\";a=\"877982166\"",
        "From": "Bimmy Pujari <bimmy.pujari@intel.com>",
        "To": "intel-wired-lan@lists.osuosl.org",
        "Date": "Mon, 12 Sep 2016 14:18:44 -0700",
        "Message-Id": "<1473715124-31296-9-git-send-email-bimmy.pujari@intel.com>",
        "X-Mailer": "git-send-email 2.4.11",
        "In-Reply-To": "<1473715124-31296-1-git-send-email-bimmy.pujari@intel.com>",
        "References": "<1473715124-31296-1-git-send-email-bimmy.pujari@intel.com>",
        "Subject": "[Intel-wired-lan] [next PATCH S46 8/8] i40evf: support\n\tqueue-specific settings for interrupt moderation",
        "X-BeenThere": "intel-wired-lan@lists.osuosl.org",
        "X-Mailman-Version": "2.1.18-1",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.lists.osuosl.org>",
        "List-Unsubscribe": "<http://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@lists.osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@lists.osuosl.org?subject=help>",
        "List-Subscribe": "<http://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "intel-wired-lan-bounces@lists.osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@lists.osuosl.org>"
    },
    "content": "From: Jacob Keller <jacob.e.keller@intel.com>\n\nIn commit a75e8005d506f3 (\"i40e: queue-specific settings for interrupt\nmoderation\") the i40e driver gained support for setting interrupt\nmoderation values per queue. This patch adds support for this feature\nto the i40evf driver as well. In addition, a few changes are made to\nthe i40e implementation to add function header documentation comments,\nas well.\n\nThis behaves in a similar fashion to the implementation in i40e. Thus,\nrequesting the moderation value when no queue is provided will report\nqueue 0 value, while setting the value without a queue will set all\nqueues at once.\n\nSigned-off-by: Jacob Keller <jacob.e.keller@intel.com>\nChange-ID: I1f310a57c8e6c84a8524c178d44d1b7a6d3a848e\n---\n drivers/net/ethernet/intel/i40e/i40e_ethtool.c     |  72 ++++++-\n drivers/net/ethernet/intel/i40e/i40e_txrx.c        |  21 ++-\n drivers/net/ethernet/intel/i40evf/i40e_txrx.c      |  26 ++-\n drivers/net/ethernet/intel/i40evf/i40e_txrx.h      |   8 +\n drivers/net/ethernet/intel/i40evf/i40evf.h         |   7 -\n drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 206 ++++++++++++++++-----\n drivers/net/ethernet/intel/i40evf/i40evf_main.c    |  10 +-\n 7 files changed, 280 insertions(+), 70 deletions(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\nindex e842628..c1c0775 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c\n@@ -1970,11 +1970,22 @@ static int i40e_set_phys_id(struct net_device *netdev,\n  * 125us (8000 interrupts per second) == ITR(62)\n  */\n \n+/**\n+ * __i40e_get_coalesce - get per-queue coalesce settings\n+ * @netdev: the netdev to check\n+ * @ec: ethtool coalesce data structure\n+ * @queue: which queue to pick\n+ *\n+ * Gets the per-queue settings for coalescence. Specifically rx and tx usecs\n+ * are per queue. If queue is <0 then we default to queue 0 as the\n+ * representative value.\n+ **/\n static int __i40e_get_coalesce(struct net_device *netdev,\n \t\t\t       struct ethtool_coalesce *ec,\n \t\t\t       int queue)\n {\n \tstruct i40e_netdev_priv *np = netdev_priv(netdev);\n+\tstruct i40e_ring *rx_ring, *tx_ring;\n \tstruct i40e_vsi *vsi = np->vsi;\n \n \tec->tx_max_coalesced_frames_irq = vsi->work_limit;\n@@ -1989,14 +2000,18 @@ static int __i40e_get_coalesce(struct net_device *netdev,\n \t\treturn -EINVAL;\n \t}\n \n-\tif (ITR_IS_DYNAMIC(vsi->rx_rings[queue]->rx_itr_setting))\n+\trx_ring = vsi->rx_rings[queue];\n+\ttx_ring = vsi->tx_rings[queue];\n+\n+\tif (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting))\n \t\tec->use_adaptive_rx_coalesce = 1;\n \n-\tif (ITR_IS_DYNAMIC(vsi->tx_rings[queue]->tx_itr_setting))\n+\tif (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting))\n \t\tec->use_adaptive_tx_coalesce = 1;\n \n-\tec->rx_coalesce_usecs = vsi->rx_rings[queue]->rx_itr_setting & ~I40E_ITR_DYNAMIC;\n-\tec->tx_coalesce_usecs = vsi->tx_rings[queue]->tx_itr_setting & ~I40E_ITR_DYNAMIC;\n+\tec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC;\n+\tec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC;\n+\n \n \t/* we use the _usecs_high to store/set the interrupt rate limit\n \t * that the hardware supports, that almost but not quite\n@@ -2010,18 +2025,44 @@ static int __i40e_get_coalesce(struct net_device *netdev,\n \treturn 0;\n }\n \n+/**\n+ * i40e_get_coalesce - get a netdev's coalesce settings\n+ * @netdev: the netdev to check\n+ * @ec: ethtool coalesce data structure\n+ *\n+ * Gets the coalesce settings for a particular netdev. Note that if user has\n+ * modified per-queue settings, this only guarantees to represent queue 0. See\n+ * __i40e_get_coalesce for more details.\n+ **/\n static int i40e_get_coalesce(struct net_device *netdev,\n \t\t\t     struct ethtool_coalesce *ec)\n {\n \treturn __i40e_get_coalesce(netdev, ec, -1);\n }\n \n+/**\n+ * i40e_get_per_queue_coalesce - gets coalesce settings for particular queue\n+ * @netdev: netdev structure\n+ * @ec: ethtool's coalesce settings\n+ * @queue: the particular queue to read\n+ *\n+ * Will read a specific queue's coalesce settings\n+ **/\n static int i40e_get_per_queue_coalesce(struct net_device *netdev, u32 queue,\n \t\t\t\t       struct ethtool_coalesce *ec)\n {\n \treturn __i40e_get_coalesce(netdev, ec, queue);\n }\n \n+/**\n+ * i40e_set_itr_per_queue - set ITR values for specific queue\n+ * @vsi: the vsi to set values for\n+ * @ec: coalesce settings from ethtool\n+ * @queue: the queue to modify\n+ *\n+ * Change the ITR settings for a specific queue.\n+ **/\n+\n static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,\n \t\t\t\t   struct ethtool_coalesce *ec,\n \t\t\t\t   int queue)\n@@ -2060,6 +2101,14 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,\n \ti40e_flush(hw);\n }\n \n+/**\n+ * __i40e_set_coalesce - set coalesce settings for particular queue\n+ * @netdev: the netdev to change\n+ * @ec: ethtool coalesce settings\n+ * @queue: the queue to change\n+ *\n+ * Sets the coalesce settings for a particular queue.\n+ **/\n static int __i40e_set_coalesce(struct net_device *netdev,\n \t\t\t       struct ethtool_coalesce *ec,\n \t\t\t       int queue)\n@@ -2120,12 +2169,27 @@ static int __i40e_set_coalesce(struct net_device *netdev,\n \treturn 0;\n }\n \n+/**\n+ * i40e_set_coalesce - set coalesce settings for every queue on the netdev\n+ * @netdev: the netdev to change\n+ * @ec: ethtool coalesce settings\n+ *\n+ * This will set each queue to the same coalesce settings.\n+ **/\n static int i40e_set_coalesce(struct net_device *netdev,\n \t\t\t     struct ethtool_coalesce *ec)\n {\n \treturn __i40e_set_coalesce(netdev, ec, -1);\n }\n \n+/**\n+ * i40e_set_per_queue_coalesce - set specific queue's coalesce settings\n+ * @netdev: the netdev to change\n+ * @ec: ethtool's coalesce settings\n+ * @queue: the queue to change\n+ *\n+ * Sets the specified queue's coalesce settings.\n+ **/\n static int i40e_set_per_queue_coalesce(struct net_device *netdev, u32 queue,\n \t\t\t\t       struct ethtool_coalesce *ec)\n {\ndiff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\nindex e94e4e1..9b82240 100644\n--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c\n@@ -1877,6 +1877,15 @@ static u32 i40e_buildreg_itr(const int type, const u16 itr)\n \n /* a small macro to shorten up some long lines */\n #define INTREG I40E_PFINT_DYN_CTLN\n+static inline int get_rx_itr_enabled(struct i40e_vsi *vsi, int idx)\n+{\n+\treturn !!(vsi->rx_rings[idx]->rx_itr_setting);\n+}\n+\n+static inline int get_tx_itr_enabled(struct i40e_vsi *vsi, int idx)\n+{\n+\treturn !!(vsi->tx_rings[idx]->tx_itr_setting);\n+}\n \n /**\n  * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt\n@@ -1892,6 +1901,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \tu32 rxval, txval;\n \tint vector;\n \tint idx = q_vector->v_idx;\n+\tint rx_itr_setting, tx_itr_setting;\n \n \tvector = (q_vector->v_idx + vsi->base_vector);\n \n@@ -1900,18 +1910,21 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \t */\n \trxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);\n \n+\trx_itr_setting = get_rx_itr_enabled(vsi, idx);\n+\ttx_itr_setting = get_tx_itr_enabled(vsi, idx);\n+\n \tif (q_vector->itr_countdown > 0 ||\n-\t    (!ITR_IS_DYNAMIC(vsi->rx_rings[idx]->rx_itr_setting) &&\n-\t     !ITR_IS_DYNAMIC(vsi->tx_rings[idx]->tx_itr_setting))) {\n+\t    (!ITR_IS_DYNAMIC(rx_itr_setting) &&\n+\t     !ITR_IS_DYNAMIC(tx_itr_setting))) {\n \t\tgoto enable_int;\n \t}\n \n-\tif (ITR_IS_DYNAMIC(vsi->rx_rings[idx]->rx_itr_setting)) {\n+\tif (ITR_IS_DYNAMIC(tx_itr_setting)) {\n \t\trx = i40e_set_new_dynamic_itr(&q_vector->rx);\n \t\trxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);\n \t}\n \n-\tif (ITR_IS_DYNAMIC(vsi->tx_rings[idx]->tx_itr_setting)) {\n+\tif (ITR_IS_DYNAMIC(tx_itr_setting)) {\n \t\ttx = i40e_set_new_dynamic_itr(&q_vector->tx);\n \t\ttxval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);\n \t}\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\nindex d4c6a76..75f2a2c 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c\n@@ -1311,6 +1311,19 @@ static u32 i40e_buildreg_itr(const int type, const u16 itr)\n \n /* a small macro to shorten up some long lines */\n #define INTREG I40E_VFINT_DYN_CTLN1\n+static inline int get_rx_itr_enabled(struct i40e_vsi *vsi, int idx)\n+{\n+\tstruct i40evf_adapter *adapter = vsi->back;\n+\n+\treturn !!(adapter->rx_rings[idx].rx_itr_setting);\n+}\n+\n+static inline int get_tx_itr_enabled(struct i40e_vsi *vsi, int idx)\n+{\n+\tstruct i40evf_adapter *adapter = vsi->back;\n+\n+\treturn !!(adapter->tx_rings[idx].tx_itr_setting);\n+}\n \n /**\n  * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt\n@@ -1325,6 +1338,8 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \tbool rx = false, tx = false;\n \tu32 rxval, txval;\n \tint vector;\n+\tint idx = q_vector->v_idx;\n+\tint rx_itr_setting, tx_itr_setting;\n \n \tvector = (q_vector->v_idx + vsi->base_vector);\n \n@@ -1333,18 +1348,21 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,\n \t */\n \trxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);\n \n+\trx_itr_setting = get_rx_itr_enabled(vsi, idx);\n+\ttx_itr_setting = get_tx_itr_enabled(vsi, idx);\n+\n \tif (q_vector->itr_countdown > 0 ||\n-\t    (!ITR_IS_DYNAMIC(vsi->rx_itr_setting) &&\n-\t     !ITR_IS_DYNAMIC(vsi->tx_itr_setting))) {\n+\t    (!ITR_IS_DYNAMIC(rx_itr_setting) &&\n+\t     !ITR_IS_DYNAMIC(tx_itr_setting))) {\n \t\tgoto enable_int;\n \t}\n \n-\tif (ITR_IS_DYNAMIC(vsi->rx_itr_setting)) {\n+\tif (ITR_IS_DYNAMIC(rx_itr_setting)) {\n \t\trx = i40e_set_new_dynamic_itr(&q_vector->rx);\n \t\trxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);\n \t}\n \n-\tif (ITR_IS_DYNAMIC(vsi->tx_itr_setting)) {\n+\tif (ITR_IS_DYNAMIC(tx_itr_setting)) {\n \t\ttx = i40e_set_new_dynamic_itr(&q_vector->tx);\n \t\ttxval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);\n \t}\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\nindex 7f72ee7..1bc5b99 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h\n@@ -287,6 +287,14 @@ struct i40e_ring {\n \tu8 dcb_tc;\t\t\t/* Traffic class of ring */\n \tu8 __iomem *tail;\n \n+\t/* high bit set means dynamic, use accessor routines to read/write.\n+\t * hardware only supports 2us resolution for the ITR registers.\n+\t * these values always store the USER setting, and must be converted\n+\t * before programming to a register.\n+\t */\n+\tu16 rx_itr_setting;\n+\tu16 tx_itr_setting;\n+\n \tu16 count;\t\t\t/* Number of descriptors */\n \tu16 reg_idx;\t\t\t/* HW register index of the ring */\n \tu16 rx_buf_len;\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h\nindex dc00aaf..c5fd724 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf.h\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf.h\n@@ -59,13 +59,6 @@ struct i40e_vsi {\n \tunsigned long state;\n \tint base_vector;\n \tu16 work_limit;\n-\t/* high bit set means dynamic, use accessor routines to read/write.\n-\t * hardware only supports 2us resolution for the ITR registers.\n-\t * these values always store the USER setting, and must be converted\n-\t * before programming to a register.\n-\t */\n-\tu16 rx_itr_setting;\n-\tu16 tx_itr_setting;\n \tu16 qs_handle;\n };\n \ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\nindex e17a154..6d15a71 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c\n@@ -296,93 +296,207 @@ static int i40evf_set_ringparam(struct net_device *netdev,\n }\n \n /**\n- * i40evf_get_coalesce - Get interrupt coalescing settings\n- * @netdev: network interface device structure\n- * @ec: ethtool coalesce structure\n+ * __i40evf_get_coalesce - get per-queue coalesce settings\n+ * @netdev: the netdev to check\n+ * @ec: ethtool coalesce data structure\n+ * @queue: which queue to pick\n  *\n- * Returns current coalescing settings. This is referred to elsewhere in the\n- * driver as Interrupt Throttle Rate, as this is how the hardware describes\n- * this functionality.\n+ * Gets the per-queue settings for coalescence. Specifically rx and tx usecs\n+ * are per queue. If queue is <0 then we default to queue 0 as the\n+ * representative value.\n  **/\n-static int i40evf_get_coalesce(struct net_device *netdev,\n-\t\t\t       struct ethtool_coalesce *ec)\n+static int __i40evf_get_coalesce(struct net_device *netdev,\n+\t\t\t\t struct ethtool_coalesce *ec,\n+\t\t\t\t int queue)\n {\n \tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n \tstruct i40e_vsi *vsi = &adapter->vsi;\n+\tstruct i40e_ring *rx_ring, *tx_ring;\n \n \tec->tx_max_coalesced_frames = vsi->work_limit;\n \tec->rx_max_coalesced_frames = vsi->work_limit;\n \n-\tif (ITR_IS_DYNAMIC(vsi->rx_itr_setting))\n+\t/* rx and tx usecs per queue value. If user doesn't specify the\n+\t * queue, return queue 0's value to represent.\n+\t */\n+\tif (queue < 0)\n+\t\tqueue = 0;\n+\telse if (queue >= adapter->num_active_queues)\n+\t\treturn -EINVAL;\n+\n+\trx_ring = &adapter->rx_rings[queue];\n+\ttx_ring = &adapter->tx_rings[queue];\n+\n+\tif (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting))\n \t\tec->use_adaptive_rx_coalesce = 1;\n \n-\tif (ITR_IS_DYNAMIC(vsi->tx_itr_setting))\n+\tif (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting))\n \t\tec->use_adaptive_tx_coalesce = 1;\n \n-\tec->rx_coalesce_usecs = vsi->rx_itr_setting & ~I40E_ITR_DYNAMIC;\n-\tec->tx_coalesce_usecs = vsi->tx_itr_setting & ~I40E_ITR_DYNAMIC;\n+\tec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC;\n+\tec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC;\n \n \treturn 0;\n }\n \n /**\n- * i40evf_set_coalesce - Set interrupt coalescing settings\n+ * i40evf_get_coalesce - Get interrupt coalescing settings\n  * @netdev: network interface device structure\n  * @ec: ethtool coalesce structure\n  *\n- * Change current coalescing settings.\n+ * Returns current coalescing settings. This is referred to elsewhere in the\n+ * driver as Interrupt Throttle Rate, as this is how the hardware describes\n+ * this functionality. Note that if per-queue settings have been modified this\n+ * only represents the settings of queue 0.\n  **/\n-static int i40evf_set_coalesce(struct net_device *netdev,\n+static int i40evf_get_coalesce(struct net_device *netdev,\n \t\t\t       struct ethtool_coalesce *ec)\n {\n-\tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n-\tstruct i40e_hw *hw = &adapter->hw;\n+\treturn __i40evf_get_coalesce(netdev, ec, -1);\n+}\n+\n+/**\n+ * i40evf_get_per_queue_coalesce - get coalesce values for specific queue\n+ * @netdev: netdev to read\n+ * @ec: coalesce settings from ethtool\n+ * @queue: the queue to read\n+ *\n+ * Read specific queue's coalesce settings.\n+ **/\n+static int i40evf_get_per_queue_coalesce(struct net_device *netdev,\n+\t\t\t\t\t u32 queue,\n+\t\t\t\t\t struct ethtool_coalesce *ec)\n+{\n+\treturn __i40evf_get_coalesce(netdev, ec, queue);\n+}\n+\n+/**\n+ * i40evf_set_itr_per_queue - set ITR values for specific queue\n+ * @vsi: the vsi to set values for\n+ * @ec: coalesce settings from ethtool\n+ * @queue: the queue to modify\n+ *\n+ * Change the ITR settings for a specific queue.\n+ **/\n+static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter,\n+\t\t\t\t     struct ethtool_coalesce *ec,\n+\t\t\t\t     int queue)\n+{\n \tstruct i40e_vsi *vsi = &adapter->vsi;\n+\tstruct i40e_hw *hw = &adapter->hw;\n \tstruct i40e_q_vector *q_vector;\n+\tu16 vector;\n+\n+\tadapter->rx_rings[queue].rx_itr_setting = ec->rx_coalesce_usecs;\n+\tadapter->tx_rings[queue].tx_itr_setting = ec->tx_coalesce_usecs;\n+\n+\tif (ec->use_adaptive_rx_coalesce)\n+\t\tadapter->rx_rings[queue].rx_itr_setting |= I40E_ITR_DYNAMIC;\n+\telse\n+\t\tadapter->rx_rings[queue].rx_itr_setting &= ~I40E_ITR_DYNAMIC;\n+\n+\tif (ec->use_adaptive_tx_coalesce)\n+\t\tadapter->tx_rings[queue].tx_itr_setting |= I40E_ITR_DYNAMIC;\n+\telse\n+\t\tadapter->tx_rings[queue].tx_itr_setting &= ~I40E_ITR_DYNAMIC;\n+\n+\tq_vector = adapter->rx_rings[queue].q_vector;\n+\tq_vector->rx.itr = ITR_TO_REG(adapter->rx_rings[queue].rx_itr_setting);\n+\tvector = vsi->base_vector + q_vector->v_idx;\n+\twr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, vector - 1), q_vector->rx.itr);\n+\n+\tq_vector = adapter->tx_rings[queue].q_vector;\n+\tq_vector->tx.itr = ITR_TO_REG(adapter->tx_rings[queue].tx_itr_setting);\n+\tvector = vsi->base_vector + q_vector->v_idx;\n+\twr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, vector - 1), q_vector->tx.itr);\n+\n+\ti40e_flush(hw);\n+}\n+\n+/**\n+ * __i40evf_set_coalesce - set coalesce settings for particular queue\n+ * @netdev: the netdev to change\n+ * @ec: ethtool coalesce settings\n+ * @queue: the queue to change\n+ *\n+ * Sets the coalesce settings for a particular queue.\n+ **/\n+static int __i40evf_set_coalesce(struct net_device *netdev,\n+\t\t\t\t struct ethtool_coalesce *ec,\n+\t\t\t\t int queue)\n+{\n+\tstruct i40evf_adapter *adapter = netdev_priv(netdev);\n+\tstruct i40e_vsi *vsi = &adapter->vsi;\n \tint i;\n \n \tif (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)\n \t\tvsi->work_limit = ec->tx_max_coalesced_frames_irq;\n \n-\tif ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&\n-\t    (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1)))\n-\t\tvsi->rx_itr_setting = ec->rx_coalesce_usecs;\n-\n-\telse\n+\tif (ec->rx_coalesce_usecs == 0) {\n+\t\tif (ec->use_adaptive_rx_coalesce)\n+\t\t\tnetif_info(adapter, drv, netdev, \"rx-usecs=0, need to disable adaptive-rx for a complete disable\\n\");\n+\t} else if ((ec->rx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||\n+\t\t   (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1))) {\n+\t\tnetif_info(adapter, drv, netdev, \"Invalid value, rx-usecs range is 0-8160\\n\");\n \t\treturn -EINVAL;\n+\t}\n \n-\tif ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&\n-\t    (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1)))\n-\t\tvsi->tx_itr_setting = ec->tx_coalesce_usecs;\n-\telse if (ec->use_adaptive_tx_coalesce)\n-\t\tvsi->tx_itr_setting = (I40E_ITR_DYNAMIC |\n-\t\t\t\t       ITR_REG_TO_USEC(I40E_ITR_RX_DEF));\n \telse\n+\tif (ec->tx_coalesce_usecs == 0) {\n+\t\tif (ec->use_adaptive_tx_coalesce)\n+\t\t\tnetif_info(adapter, drv, netdev, \"tx-usecs=0, need to disable adaptive-tx for a complete disable\\n\");\n+\t} else if ((ec->tx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||\n+\t\t   (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1))) {\n+\t\tnetif_info(adapter, drv, netdev, \"Invalid value, tx-usecs range is 0-8160\\n\");\n \t\treturn -EINVAL;\n+\t}\n \n-\tif (ec->use_adaptive_rx_coalesce)\n-\t\tvsi->rx_itr_setting |= I40E_ITR_DYNAMIC;\n-\telse\n-\t\tvsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC;\n-\n-\tif (ec->use_adaptive_tx_coalesce)\n-\t\tvsi->tx_itr_setting |= I40E_ITR_DYNAMIC;\n-\telse\n-\t\tvsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;\n-\n-\tfor (i = 0; i < adapter->num_msix_vectors - NONQ_VECS; i++) {\n-\t\tq_vector = &adapter->q_vectors[i];\n-\t\tq_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);\n-\t\twr32(hw, I40E_VFINT_ITRN1(0, i), q_vector->rx.itr);\n-\t\tq_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);\n-\t\twr32(hw, I40E_VFINT_ITRN1(1, i), q_vector->tx.itr);\n-\t\ti40e_flush(hw);\n+\t/* rx and tx usecs has per queue value. If user doesn't specify the\n+\t * queue, apply to all queues.\n+\t */\n+\tif (queue < 0) {\n+\t\tfor (i = 0; i < adapter->num_active_queues; i++)\n+\t\t\ti40evf_set_itr_per_queue(adapter, ec, i);\n+\t} else if (queue < adapter->num_active_queues) {\n+\t\ti40evf_set_itr_per_queue(adapter, ec, queue);\n+\t} else {\n+\t\tnetif_info(adapter, drv, netdev, \"Invalid queue value, queue range is 0 - %d\\n\",\n+\t\t\t   adapter->num_active_queues - 1);\n+\t\treturn -EINVAL;\n \t}\n \n \treturn 0;\n }\n \n /**\n+ * i40evf_set_coalesce - Set interrupt coalescing settings\n+ * @netdev: network interface device structure\n+ * @ec: ethtool coalesce structure\n+ *\n+ * Change current coalescing settings for every queue.\n+ **/\n+static int i40evf_set_coalesce(struct net_device *netdev,\n+\t\t\t       struct ethtool_coalesce *ec)\n+{\n+\treturn __i40evf_set_coalesce(netdev, ec, -1);\n+}\n+\n+/**\n+ * i40evf_set_per_queue_coalesce - set specific queue's coalesce settings\n+ * @netdev: the netdev to change\n+ * @ec: ethtool's coalesce settings\n+ * @queue: the queue to modify\n+ *\n+ * Modifies a specific queue's coalesce settings.\n+ */\n+static int i40evf_set_per_queue_coalesce(struct net_device *netdev,\n+\t\t\t\t\t u32 queue,\n+\t\t\t\t\t struct ethtool_coalesce *ec)\n+{\n+\treturn __i40evf_set_coalesce(netdev, ec, queue);\n+}\n+\n+/**\n  * i40evf_get_rxnfc - command to get RX flow classification rules\n  * @netdev: network interface device structure\n  * @cmd: ethtool rxnfc command\n@@ -533,6 +647,8 @@ static const struct ethtool_ops i40evf_ethtool_ops = {\n \t.set_msglevel\t\t= i40evf_set_msglevel,\n \t.get_coalesce\t\t= i40evf_get_coalesce,\n \t.set_coalesce\t\t= i40evf_set_coalesce,\n+\t.get_per_queue_coalesce = i40evf_get_per_queue_coalesce,\n+\t.set_per_queue_coalesce = i40evf_set_per_queue_coalesce,\n \t.get_rxnfc\t\t= i40evf_get_rxnfc,\n \t.get_rxfh_indir_size\t= i40evf_get_rxfh_indir_size,\n \t.get_rxfh\t\t= i40evf_get_rxfh,\ndiff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\nindex 302c974..1437281 100644\n--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c\n@@ -370,7 +370,6 @@ i40evf_map_vector_to_rxq(struct i40evf_adapter *adapter, int v_idx, int r_idx)\n {\n \tstruct i40e_q_vector *q_vector = &adapter->q_vectors[v_idx];\n \tstruct i40e_ring *rx_ring = &adapter->rx_rings[r_idx];\n-\tstruct i40e_vsi *vsi = &adapter->vsi;\n \tstruct i40e_hw *hw = &adapter->hw;\n \n \trx_ring->q_vector = q_vector;\n@@ -379,7 +378,7 @@ i40evf_map_vector_to_rxq(struct i40evf_adapter *adapter, int v_idx, int r_idx)\n \tq_vector->rx.ring = rx_ring;\n \tq_vector->rx.count++;\n \tq_vector->rx.latency_range = I40E_LOW_LATENCY;\n-\tq_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);\n+\tq_vector->rx.itr = ITR_TO_REG(rx_ring->rx_itr_setting);\n \tq_vector->ring_mask |= BIT(r_idx);\n \tq_vector->itr_countdown = ITR_COUNTDOWN_START;\n \twr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, v_idx - 1), q_vector->rx.itr);\n@@ -396,7 +395,6 @@ i40evf_map_vector_to_txq(struct i40evf_adapter *adapter, int v_idx, int t_idx)\n {\n \tstruct i40e_q_vector *q_vector = &adapter->q_vectors[v_idx];\n \tstruct i40e_ring *tx_ring = &adapter->tx_rings[t_idx];\n-\tstruct i40e_vsi *vsi = &adapter->vsi;\n \tstruct i40e_hw *hw = &adapter->hw;\n \n \ttx_ring->q_vector = q_vector;\n@@ -405,7 +403,7 @@ i40evf_map_vector_to_txq(struct i40evf_adapter *adapter, int v_idx, int t_idx)\n \tq_vector->tx.ring = tx_ring;\n \tq_vector->tx.count++;\n \tq_vector->tx.latency_range = I40E_LOW_LATENCY;\n-\tq_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);\n+\tq_vector->tx.itr = ITR_TO_REG(tx_ring->tx_itr_setting);\n \tq_vector->itr_countdown = ITR_COUNTDOWN_START;\n \tq_vector->num_ringpairs++;\n \twr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, v_idx - 1), q_vector->tx.itr);\n@@ -1162,6 +1160,7 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter)\n \t\ttx_ring->netdev = adapter->netdev;\n \t\ttx_ring->dev = &adapter->pdev->dev;\n \t\ttx_ring->count = adapter->tx_desc_count;\n+\t\ttx_ring->tx_itr_setting = (I40E_ITR_DYNAMIC | I40E_ITR_TX_DEF);\n \t\tif (adapter->flags & I40E_FLAG_WB_ON_ITR_CAPABLE)\n \t\t\ttx_ring->flags |= I40E_TXR_FLAGS_WB_ON_ITR;\n \n@@ -1170,6 +1169,7 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter)\n \t\trx_ring->netdev = adapter->netdev;\n \t\trx_ring->dev = &adapter->pdev->dev;\n \t\trx_ring->count = adapter->rx_desc_count;\n+\t\trx_ring->rx_itr_setting = (I40E_ITR_DYNAMIC | I40E_ITR_RX_DEF);\n \t}\n \n \treturn 0;\n@@ -2277,8 +2277,6 @@ int i40evf_process_config(struct i40evf_adapter *adapter)\n \tadapter->vsi.back = adapter;\n \tadapter->vsi.base_vector = 1;\n \tadapter->vsi.work_limit = I40E_DEFAULT_IRQ_WORK;\n-\tadapter->vsi.rx_itr_setting = (I40E_ITR_DYNAMIC | I40E_ITR_RX_DEF);\n-\tadapter->vsi.tx_itr_setting = (I40E_ITR_DYNAMIC | I40E_ITR_TX_DEF);\n \tvsi->netdev = adapter->netdev;\n \tvsi->qs_handle = adapter->vsi_res->qset_handle;\n \tif (vfres->vf_offload_flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF) {\n",
    "prefixes": [
        "next",
        "S46",
        "8/8"
    ]
}