{"id":816805,"url":"http://patchwork.ozlabs.org/api/patches/816805/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/cef3863edd8d504d7406f781c97260c52f21e156.1505915085.git.igor.russkikh@aquantia.com/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<cef3863edd8d504d7406f781c97260c52f21e156.1505915085.git.igor.russkikh@aquantia.com>","list_archive_url":null,"date":"2017-09-21T10:53:40","name":"[net,2/4] net:ethernet:aquantia: Fix Tx queue hangups","commit_ref":null,"pull_url":null,"state":"changes-requested","archived":true,"hash":"07cf62974cfc01b1dd571cd3ad768d5a9be7933f","submitter":{"id":72409,"url":"http://patchwork.ozlabs.org/api/people/72409/?format=json","name":"Igor Russkikh","email":"igor.russkikh@aquantia.com"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/cef3863edd8d504d7406f781c97260c52f21e156.1505915085.git.igor.russkikh@aquantia.com/mbox/","series":[{"id":4355,"url":"http://patchwork.ozlabs.org/api/series/4355/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=4355","date":"2017-09-21T10:53:38","name":"net:ethernet:aquantia: Atlantic driver bugfixes and improvements","version":1,"mbox":"http://patchwork.ozlabs.org/series/4355/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/816805/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/816805/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=AQUANTIA1COM.onmicrosoft.com\n\theader.i=@AQUANTIA1COM.onmicrosoft.com header.b=\"ZTJU50Pi\"; \n\tdkim-atps=neutral","spf=none (sender IP is )\n\tsmtp.mailfrom=Igor.Russkikh@aquantia.com; "],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xyYQr0ZvZz9sNw\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 21 Sep 2017 20:54:44 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751730AbdIUKyj (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tThu, 21 Sep 2017 06:54:39 -0400","from mail-co1nam03on0077.outbound.protection.outlook.com\n\t([104.47.40.77]:13920\n\t\"EHLO NAM03-CO1-obe.outbound.protection.outlook.com\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1751709AbdIUKyf (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tThu, 21 Sep 2017 06:54:35 -0400","from ubuntubox.rdc.aquantia.com (95.79.108.179) by\n\tBY2PR0701MB1958.namprd07.prod.outlook.com (10.163.155.16) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id\n\t15.20.77.7; Thu, 21 Sep 2017 10:54:31 +0000"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=AQUANTIA1COM.onmicrosoft.com; s=selector1-aquantia-com;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=t0FdaZBxp17HsLeyyM2nrSUZQD8Vi8UF47LS/1UpeUo=;\n\tb=ZTJU50Pi/h4xtyUkhmp85XpfanYyyey3Q/eYo5u/QxLn1Vt93s6pla6MyHr8iCjgByhyH73xk8r4OY4m4oYfGSoX3MSa0S875lFk3x6SgdH6ZZJtbVust2lYqPe7Spr+cSe2gx1sv0Hpj/FqoKJpYLNpf3+O2nLBNauV+lrBx7U=","From":"Igor Russkikh <igor.russkikh@aquantia.com>","To":"\"David S . Miller\" <davem@davemloft.net>","Cc":"netdev@vger.kernel.org, David Arcari <darcari@redhat.com>,\n\tPavel Belous <Pavel.Belous@aquantia.com>,\n\tNadezhda Krupnina <Nadezhda.Krupnina@aquantia.com>,\n\tSimon Edelhaus <simon.edelhaus@aquantia.com>,\n\tIgor Russkikh <igor.russkikh@aquantia.com>","Subject":"[PATCH net 2/4] net:ethernet:aquantia: Fix Tx queue hangups","Date":"Thu, 21 Sep 2017 13:53:40 +0300","Message-Id":"<cef3863edd8d504d7406f781c97260c52f21e156.1505915085.git.igor.russkikh@aquantia.com>","X-Mailer":"git-send-email 2.7.4","In-Reply-To":"<cover.1505915085.git.igor.russkikh@aquantia.com>","References":"<cover.1505915085.git.igor.russkikh@aquantia.com>","MIME-Version":"1.0","Content-Type":"text/plain","X-Originating-IP":"[95.79.108.179]","X-ClientProxiedBy":"VI1PR0501CA0018.eurprd05.prod.outlook.com (10.172.9.156)\n\tTo\n\tBY2PR0701MB1958.namprd07.prod.outlook.com (10.163.155.16)","X-MS-Office365-Filtering-Correlation-Id":"01b1b90a-968c-4ece-b2d7-08d500df247a","X-Microsoft-Antispam":"UriScan:; BCL:0; PCL:0;\n\tRULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(2017052603199)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);\n\tSRVR:BY2PR0701MB1958; ","X-Microsoft-Exchange-Diagnostics":["1; BY2PR0701MB1958;\n\t3:CMLDHZb7XHHacU7OAlV5Fu0a3Llq+Pbu3REJ39JM9mvZd1BVOUjuNjMLziC4NEzMzKM3nI999wEy55IR4BDomstrF0R7lKplRgaqNVn0r3b/fftI4elvj/mcQzYMf7/MDGwyBjtFEnELgr4tcSKRudH9mPi94pwyVZaON6l5BskSge3tnk8PaiTP1xI3NXStTpL8Al00cKdvan47C+HIKDUsbZj0G7en6OzYD9+vVMIBAdI4DUb5oPyXHPPG17GS;\n\t25:uCmydp8Aqnh8+/JsZUtPg+Dj/udv/1b1Iudnp8GeBPJK6B7YmHQceyLtRItE0amhSwbu9uCdaHwf6H1Bit0s5iWFlAdL5F+/qbjQywqHybFHRm4KT8tMXx1N7jqDVdAHXJRRTiFXni+Y0P9jy51rcYOGFWiWsA6toP2xJq0pPWtcVKRp8qeWft/JW2len5pVXzYhOzsn0WErcW9pAGdRYhfsHCqXeTj2OA0h9J/CeRWs1LLPQW2NVhRYOKFq3dFohu0Ta93PmCWOz9RGoerRlRzboYhvivr9x/xzQspfqB2ZJZ+PrGWHMaRF8mxMoZZuyuDyFmdGeiyKNbow90wo+Q==;\n\t31:onIIz88jql7CTn+2dYLqKUIgcNC4cxJqvvZUxoSxiXX8eV0DbbJPPPYN0ssDyq29prq1t7YnYKuar0cogvS0W1pvt4F0IxrpGLC1Grao3mJzj3NaTz7HbkCyOwzgSYeF7GtkhaUl3eIVFxVGer3WgpjM86wu2OBAMaFO+qO+nDeAKMATWQOa3TpFgg8piCd9Fb8TtEBmgxOW8QNbwtzL6sqIHzazHB6TNZq8OY0v5Fc=","1; BY2PR0701MB1958;\n\t20:v7RqeLEvYQ7tBwVYrg08DRt+JPmPWq+85VCCmb0KuZzIj6k2av85MM7TwDQaAqxTsMBvmWgMJbbK6anaqm6KnK+VJZwlCmbOw3vh6/l/QdVirvlvJSqYF/ooVfLj4K1kY7wGEbF/yCFS9idZle6Ylp9QdToo1WUqfg6YYsqw4B3u9w4rtbu5qVhto854VyFOb+bypmbMT84AdSXBTqlHqDRipOVgDMgnGGzwpxIk3w256zoxolZltii+PekVx9WVs5c/8GVrCmJuc8UDnq5HkdP1BrFAN+euThiEKaKrvtbV+xgqk9nzZMGuzHWsPxLU0tCEfmZ4m3EN4gJ6n8A6JlH6ODmCJvf5WdAuEhB4BoeJOKXtvTh3zxYaDDkzYP+bPfBIi4ASvROsZ2k03dRCZYAwtgKGP43H2s+ejtvS1ua5V9aSeS4UcCv2EGhfIGPqtJ9NEqpT539NbIs2vMC9Sgc9U407ZXzTIwQxTsTlZqMAHvGEdpSsTDog66PGu+U2;\n\t4:wnqCPQ7UJlWvxrbCGhcEqg834XDXytSCspxU23i2Kg1EH4bHrJ90+Bo221fim/lxxbVnFebPoi6z5EpMlJTz2w8ayfsEviIoqKDXinPa5Dooid9UK8GTfYpQ+ZEuGTfhxyaW5sWbzPyuS6EB7jeIknp1qjvfnUe907vk0Mrv4b9xWPPd/o3qi87Yu0Yqbw0ou2vRhtlynAEUxKRa78CVFZM6sYakv7+FduFhJXmiljXC/exbj7n9dpFtVlBP9KbM","1; BY2PR0701MB1958;\n\t23:yQaXVxTkG2vTPhRopslLDbNi6M/UuqWrWh+h6QfzY6p3xTWd4pDXfrbx3PJsKFiy/AcoHL9Z+4ERzrWB3f6qcY61b6bk+IhAVTkMf2EBai9CSiujmLA8JdJ9LLUF7XLzNED+Btf0FaONO3UqQFoyYPZJ8muOLErgsgcbPIAExIw6TGUJn6H1PYCl9U3tFGRzHZc0nQIDBrXghKGeMVf9090Ogp0jJu9SzdkQVyNEizt8bJ5ylb7S3yeZSllvbTFW+0RyCKZA5UOV9ALlKMGKVOYq8+KbXYrxKAL2rSA16AWIC7eE4TfIo+AkQwBF1HloRM/jXz8VYjx+TEl8WWlooF4NVKDQfmXg78Zxnui22aWo1AmLLYIUzUU5kuxRssW3UhTpuvq6sTjTkXsdHeX1Ej7FiIXBTupC4n2fddP4seh6qYMrbiK9r2CFauyHsZ0FUFkz4v5qLTXm2BW+vv616JjyDLRe/XWDKgYQCxR16HZWgAaFKhQ+9L7PnXKbjWu7vmroznwAvO+8dkqRCHvi9RkJYp07lKarEOzR3BhEAZCmlW1Wr5znRkRPkdshYKDDqj5myqiBShVSzYvqwpkf7xEN3abh8gCIdAXUh4g9b4qoA8MHieBLQ7Nt5X51KA/3NuTPOMPd6YD5HKzF4X3wTWOoqZbDqbvj1E4ulnV7ANxL0p3pSP+tkh8cN+pfBFfmobgBPi5BcOhB1CFIsceNOG2oQcXTPnIZ5VV9ERL0t6eNjE6PtkUjWogSTct5gHyz35wVPePnUjkBEm+TqaXmAWOqotI4WQDWIDMxOfvT+JzOpW18J6+Ud/H/5Ocawb4FcXussi9eQy3FsBGMzBZBn62N6o4LdB39ISZeHCKi04XVf3806eu2p06oIt9bJfet/4FeyfTdo6bSrkpM6y5lg58wx2EqfrwtbMtPS7TX+A1/hj+vyx6qru2eu1XrGAumsADvR9qiELoKWULZoYh67DPr9thCsZLJjjnIjYWXUgykI4izc3vKYcu6OqJPz0l+RWAg1a+lttZriWqwndtleMcYs0lXbAli62066ftc+S1jqlj39IrIYVh/vngZve5vTaQheBY+T98zk1eFdB1GMAGBKZFvPYcQr1uXBfltpHDPjfb47tZdEiaeCQLQ94PL","1; BY2PR0701MB1958;\n\t6:sQxPt1XbgZg07Sc6xGmE0aSCsvEnOr/lw6LESs4h8DhZtchoESuDz2quKOvHzbOK06dcr3cYg16kgZ+jg4CN20mzA2u1zY8/QGy3LSfVTK5yISspNdUXe4rpciBYszLKgqnRV1N16muwm+VxFkR1mdfiEGImMdR6L7l3qflpU7eWw3Izz+9UE9Bd+E6WUfcirRktCcgUmwx5anp4LDU599i4kRWcOPJaVBl49CMxezRzygh3bK5mqzuo6xTaePMKAuJeAVWoXSfnObe/Q3HxpjzTFV1bxGVhBTeknCe6xz7IeHCkRhrI/vdwowDU/FrlCLRD8fZmOfWZU6451IpAgw==;\n\t5:tBnu55rC/uCcSh3OJMDYXbSgqMgi9BMSX/oANTee5Fh7PG7mu1CcFDMpKIr5ZcI3NB+HBDvNCx1Rk65rZwxyalxs1elokrKKqof4uDnJyNmBHpCz0QnvOX/rMKmIMIHdNuUtmtjwxkVRqLfudtN3vg==;\n\t24:xoyZzsio/lgWEeMkEl4iy1QjEOwjyI3OE2fe6uOWcNMfKtN3mi44pZ5LTaW8t6uTZEGb45LrgfXNGLFpVWRC30J3w919a9Lt2Way/rNf458=;\n\t7:l+w56J68T7CWcDgQ5dW9J3P4812jHcWf261M4zelqvFjBb+7xJWdtm8zXMsGymdRtRo19u3YAekz64iVAVUnjkBSD+1B8u0PA145f1VelKB+mu4OHw4MYgRXDqv/+hK7+WpxQYtfGJ8dJpwXCvHqE0bmlIVVc0j4s+d0479pLyDXUeNJqyz0RxWqjG3ZY2S2BBj1tuGinVk1WrG0E00SgcuVAmLY358642T8v9wsMQ0="],"X-MS-PublicTrafficType":"Email","X-MS-TrafficTypeDiagnostic":"BY2PR0701MB1958:","X-Exchange-Antispam-Report-Test":"UriScan:;","X-Microsoft-Antispam-PRVS":"<BY2PR0701MB19583B1884C2AB231B768B0598660@BY2PR0701MB1958.namprd07.prod.outlook.com>","X-Exchange-Antispam-Report-CFA-Test":"BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(100000703101)(100105400095)(10201501046)(3002001)(93006095)(93001095)(6041248)(20161123558100)(20161123555025)(20161123560025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:BY2PR0701MB1958; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:BY2PR0701MB1958; ","X-Forefront-PRVS":"04371797A5","X-Forefront-Antispam-Report":"SFV:NSPM;\n\tSFS:(10009020)(6009001)(39830400002)(376002)(346002)(199003)(189002)(6486002)(189998001)(86362001)(81156014)(4326008)(33646002)(68736007)(8676002)(72206003)(478600001)(81166006)(16586007)(316002)(101416001)(16526017)(54906003)(36756003)(2950100002)(6666003)(6916009)(97736004)(5660300001)(50466002)(118296001)(48376002)(50226002)(76176999)(106356001)(2906002)(53936002)(25786009)(50986999)(105586002)(107886003)(5003940100001)(66066001)(8936002)(47776003)(6116002)(3846002)(305945005)(7736002);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR0701MB1958;\n\tH:ubuntubox.rdc.aquantia.com; FPR:; SPF:None;\n\tPTR:InfoNoRecords; A:1; MX:1; LANG:en; ","Received-SPF":"None (protection.outlook.com: aquantia.com does not designate\n\tpermitted sender hosts)","SpamDiagnosticOutput":"1:99","SpamDiagnosticMetadata":"NSPM","X-OriginatorOrg":"aquantia.com","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"21 Sep 2017 10:54:31.0645\n\t(UTC)","X-MS-Exchange-CrossTenant-FromEntityHeader":"Hosted","X-MS-Exchange-CrossTenant-Id":"83e2e134-991c-4ede-8ced-34d47e38e6b1","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"BY2PR0701MB1958","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"Driver did a poor job in managing its Tx queues: Sometimes it could stop\ntx queues due to link down condition in aq_nic_xmit - but never waked up\nthem. That led to Tx path total suspend.\nThis patch fixes this and improves generic queue management:\n- introduces queue restart counter\n- uses generic netif_ interface to disable and enable tx path\n- refactors link up/down condition and introduces dmesg log event when\n  link changes.\n- introduces new constant for minimum descriptors count required for queue\n  wakeup\n\nSigned-off-by: Pavel Belous <Pavel.Belous@aquantia.com>\nSigned-off-by: Igor Russkikh <igor.russkikh@aquantia.com>\n---\n drivers/net/ethernet/aquantia/atlantic/aq_cfg.h  |  4 ++\n drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 91 +++++++++++-------------\n drivers/net/ethernet/aquantia/atlantic/aq_nic.h  |  2 -\n drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 26 +++++++\n drivers/net/ethernet/aquantia/atlantic/aq_ring.h |  4 ++\n drivers/net/ethernet/aquantia/atlantic/aq_vec.c  |  8 +--\n 6 files changed, 76 insertions(+), 59 deletions(-)","diff":"diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h\nindex 2149864..0fdaaa6 100644\n--- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h\n+++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h\n@@ -51,6 +51,10 @@\n \n #define AQ_CFG_SKB_FRAGS_MAX   32U\n \n+/* Number of descriptors available in one ring to resume this ring queue\n+ */\n+#define AQ_CFG_RESTART_DESC_THRES   (AQ_CFG_SKB_FRAGS_MAX * 2)\n+\n #define AQ_CFG_NAPI_WEIGHT     64U\n \n #define AQ_CFG_MULTICAST_ADDRESS_MAX     32U\ndiff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c\nindex f281392..24f573c 100644\n--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c\n+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c\n@@ -119,6 +119,35 @@ int aq_nic_cfg_start(struct aq_nic_s *self)\n \treturn 0;\n }\n \n+static int aq_nic_update_link_status(struct aq_nic_s *self)\n+{\n+\tint err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);\n+\n+\tif (err < 0)\n+\t\treturn -1;\n+\n+\tif (self->link_status.mbps != self->aq_hw->aq_link_status.mbps)\n+\t\tpr_info(\"%s: link change old %d new %d\\n\",\n+\t\t\tAQ_CFG_DRV_NAME, self->link_status.mbps,\n+\t\t\tself->aq_hw->aq_link_status.mbps);\n+\n+\tself->link_status = self->aq_hw->aq_link_status;\n+\tif (!netif_carrier_ok(self->ndev) && self->link_status.mbps) {\n+\t\taq_utils_obj_set(&self->header.flags,\n+\t\t\t\t AQ_NIC_FLAG_STARTED);\n+\t\taq_utils_obj_clear(&self->header.flags,\n+\t\t\t\t   AQ_NIC_LINK_DOWN);\n+\t\tnetif_carrier_on(self->ndev);\n+\t\tnetif_tx_wake_all_queues(self->ndev);\n+\t}\n+\tif (netif_carrier_ok(self->ndev) && !self->link_status.mbps) {\n+\t\tnetif_carrier_off(self->ndev);\n+\t\tnetif_tx_disable(self->ndev);\n+\t\taq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN);\n+\t}\n+\treturn 0;\n+}\n+\n static void aq_nic_service_timer_cb(unsigned long param)\n {\n \tstruct aq_nic_s *self = (struct aq_nic_s *)param;\n@@ -131,26 +160,13 @@ static void aq_nic_service_timer_cb(unsigned long param)\n \tif (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY))\n \t\tgoto err_exit;\n \n-\terr = self->aq_hw_ops.hw_get_link_status(self->aq_hw);\n-\tif (err < 0)\n+\terr = aq_nic_update_link_status(self);\n+\tif (err)\n \t\tgoto err_exit;\n \n-\tself->link_status = self->aq_hw->aq_link_status;\n-\n \tself->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,\n \t\t    self->aq_nic_cfg.is_interrupt_moderation);\n \n-\tif (self->link_status.mbps) {\n-\t\taq_utils_obj_set(&self->header.flags,\n-\t\t\t\t AQ_NIC_FLAG_STARTED);\n-\t\taq_utils_obj_clear(&self->header.flags,\n-\t\t\t\t   AQ_NIC_LINK_DOWN);\n-\t\tnetif_carrier_on(self->ndev);\n-\t} else {\n-\t\tnetif_carrier_off(self->ndev);\n-\t\taq_utils_obj_set(&self->header.flags, AQ_NIC_LINK_DOWN);\n-\t}\n-\n \tmemset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));\n \tmemset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));\n \tfor (i = AQ_DIMOF(self->aq_vec); i--;) {\n@@ -240,7 +256,6 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,\n int aq_nic_ndev_register(struct aq_nic_s *self)\n {\n \tint err = 0;\n-\tunsigned int i = 0U;\n \n \tif (!self->ndev) {\n \t\terr = -EINVAL;\n@@ -262,8 +277,7 @@ int aq_nic_ndev_register(struct aq_nic_s *self)\n \n \tnetif_carrier_off(self->ndev);\n \n-\tfor (i = AQ_CFG_VECS_MAX; i--;)\n-\t\taq_nic_ndev_queue_stop(self, i);\n+\tnetif_tx_disable(self->ndev);\n \n \terr = register_netdev(self->ndev);\n \tif (err < 0)\n@@ -319,12 +333,8 @@ struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev)\n \t\terr = -EINVAL;\n \t\tgoto err_exit;\n \t}\n-\tif (netif_running(ndev)) {\n-\t\tunsigned int i;\n-\n-\t\tfor (i = AQ_CFG_VECS_MAX; i--;)\n-\t\t\tnetif_stop_subqueue(ndev, i);\n-\t}\n+\tif (netif_running(ndev))\n+\t\tnetif_tx_disable(ndev);\n \n \tfor (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs;\n \t\tself->aq_vecs++) {\n@@ -384,16 +394,6 @@ int aq_nic_init(struct aq_nic_s *self)\n \treturn err;\n }\n \n-void aq_nic_ndev_queue_start(struct aq_nic_s *self, unsigned int idx)\n-{\n-\tnetif_start_subqueue(self->ndev, idx);\n-}\n-\n-void aq_nic_ndev_queue_stop(struct aq_nic_s *self, unsigned int idx)\n-{\n-\tnetif_stop_subqueue(self->ndev, idx);\n-}\n-\n int aq_nic_start(struct aq_nic_s *self)\n {\n \tstruct aq_vec_s *aq_vec = NULL;\n@@ -452,10 +452,6 @@ int aq_nic_start(struct aq_nic_s *self)\n \t\t\tgoto err_exit;\n \t}\n \n-\tfor (i = 0U, aq_vec = self->aq_vec[0];\n-\t\tself->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])\n-\t\taq_nic_ndev_queue_start(self, i);\n-\n \terr = netif_set_real_num_tx_queues(self->ndev, self->aq_vecs);\n \tif (err < 0)\n \t\tgoto err_exit;\n@@ -464,6 +460,8 @@ int aq_nic_start(struct aq_nic_s *self)\n \tif (err < 0)\n \t\tgoto err_exit;\n \n+\tnetif_tx_start_all_queues(self->ndev);\n+\n err_exit:\n \treturn err;\n }\n@@ -603,7 +601,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)\n \tunsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;\n \tunsigned int tc = 0U;\n \tint err = NETDEV_TX_OK;\n-\tbool is_nic_in_bad_state;\n \n \tfrags = skb_shinfo(skb)->nr_frags + 1;\n \n@@ -614,13 +611,10 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)\n \t\tgoto err_exit;\n \t}\n \n-\tis_nic_in_bad_state = aq_utils_obj_test(&self->header.flags,\n-\t\t\t\t\t\tAQ_NIC_FLAGS_IS_NOT_TX_READY) ||\n-\t\t\t\t\t\t(aq_ring_avail_dx(ring) <\n-\t\t\t\t\t\tAQ_CFG_SKB_FRAGS_MAX);\n+\taq_ring_update_queue_state(ring);\n \n-\tif (is_nic_in_bad_state) {\n-\t\taq_nic_ndev_queue_stop(self, ring->idx);\n+\t/* Above status update may stop the queue. Check this. */\n+\tif (__netif_subqueue_stopped(self->ndev, ring->idx)) {\n \t\terr = NETDEV_TX_BUSY;\n \t\tgoto err_exit;\n \t}\n@@ -632,9 +626,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)\n \t\t\t\t\t\t      ring,\n \t\t\t\t\t\t      frags);\n \t\tif (err >= 0) {\n-\t\t\tif (aq_ring_avail_dx(ring) < AQ_CFG_SKB_FRAGS_MAX + 1)\n-\t\t\t\taq_nic_ndev_queue_stop(self, ring->idx);\n-\n \t\t\t++ring->stats.tx.packets;\n \t\t\tring->stats.tx.bytes += skb->len;\n \t\t}\n@@ -906,9 +897,7 @@ int aq_nic_stop(struct aq_nic_s *self)\n \tstruct aq_vec_s *aq_vec = NULL;\n \tunsigned int i = 0U;\n \n-\tfor (i = 0U, aq_vec = self->aq_vec[0];\n-\t\tself->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])\n-\t\taq_nic_ndev_queue_stop(self, i);\n+\tnetif_tx_disable(self->ndev);\n \n \tdel_timer_sync(&self->service_timer);\n \ndiff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h\nindex 7fc2a5e..0ddd556 100644\n--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h\n+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h\n@@ -83,8 +83,6 @@ struct net_device *aq_nic_get_ndev(struct aq_nic_s *self);\n int aq_nic_init(struct aq_nic_s *self);\n int aq_nic_cfg_start(struct aq_nic_s *self);\n int aq_nic_ndev_register(struct aq_nic_s *self);\n-void aq_nic_ndev_queue_start(struct aq_nic_s *self, unsigned int idx);\n-void aq_nic_ndev_queue_stop(struct aq_nic_s *self, unsigned int idx);\n void aq_nic_ndev_free(struct aq_nic_s *self);\n int aq_nic_start(struct aq_nic_s *self);\n int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb);\ndiff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c\nindex 4eee199..02f79b0 100644\n--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c\n+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c\n@@ -104,6 +104,32 @@ int aq_ring_init(struct aq_ring_s *self)\n \treturn 0;\n }\n \n+void aq_ring_update_queue_state(struct aq_ring_s *ring)\n+{\n+\tif (aq_ring_avail_dx(ring) <= AQ_CFG_SKB_FRAGS_MAX)\n+\t\taq_ring_queue_stop(ring);\n+\telse if (aq_ring_avail_dx(ring) > AQ_CFG_RESTART_DESC_THRES)\n+\t\taq_ring_queue_wake(ring);\n+}\n+\n+void aq_ring_queue_wake(struct aq_ring_s *ring)\n+{\n+\tstruct net_device *ndev = aq_nic_get_ndev(ring->aq_nic);\n+\n+\tif (__netif_subqueue_stopped(ndev, ring->idx)) {\n+\t\tnetif_wake_subqueue(ndev, ring->idx);\n+\t\tring->stats.tx.queue_restarts++;\n+\t}\n+}\n+\n+void aq_ring_queue_stop(struct aq_ring_s *ring)\n+{\n+\tstruct net_device *ndev = aq_nic_get_ndev(ring->aq_nic);\n+\n+\tif (!__netif_subqueue_stopped(ndev, ring->idx))\n+\t\tnetif_stop_subqueue(ndev, ring->idx);\n+}\n+\n void aq_ring_tx_clean(struct aq_ring_s *self)\n {\n \tstruct device *dev = aq_nic_get_dev(self->aq_nic);\ndiff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h\nindex 782176c..24523b5 100644\n--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h\n+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h\n@@ -94,6 +94,7 @@ struct aq_ring_stats_tx_s {\n \tu64 errors;\n \tu64 packets;\n \tu64 bytes;\n+\tu64 queue_restarts;\n };\n \n union aq_ring_stats_s {\n@@ -147,6 +148,9 @@ struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self,\n int aq_ring_init(struct aq_ring_s *self);\n void aq_ring_rx_deinit(struct aq_ring_s *self);\n void aq_ring_free(struct aq_ring_s *self);\n+void aq_ring_update_queue_state(struct aq_ring_s *ring);\n+void aq_ring_queue_wake(struct aq_ring_s *ring);\n+void aq_ring_queue_stop(struct aq_ring_s *ring);\n void aq_ring_tx_clean(struct aq_ring_s *self);\n int aq_ring_rx_clean(struct aq_ring_s *self,\n \t\t     struct napi_struct *napi,\ndiff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c\nindex ebf5880..305ff8f 100644\n--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c\n+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c\n@@ -59,12 +59,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)\n \t\t\tif (ring[AQ_VEC_TX_ID].sw_head !=\n \t\t\t    ring[AQ_VEC_TX_ID].hw_head) {\n \t\t\t\taq_ring_tx_clean(&ring[AQ_VEC_TX_ID]);\n-\n-\t\t\t\tif (aq_ring_avail_dx(&ring[AQ_VEC_TX_ID]) >\n-\t\t\t\t    AQ_CFG_SKB_FRAGS_MAX) {\n-\t\t\t\t\taq_nic_ndev_queue_start(self->aq_nic,\n-\t\t\t\t\t\tring[AQ_VEC_TX_ID].idx);\n-\t\t\t\t}\n+\t\t\t\taq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]);\n \t\t\t\twas_tx_cleaned = true;\n \t\t\t}\n \n@@ -364,6 +359,7 @@ void aq_vec_add_stats(struct aq_vec_s *self,\n \t\tstats_tx->packets += tx->packets;\n \t\tstats_tx->bytes += tx->bytes;\n \t\tstats_tx->errors += tx->errors;\n+\t\tstats_tx->queue_restarts += tx->queue_restarts;\n \t}\n }\n \n","prefixes":["net","2/4"]}