get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 104863,
    "url": "http://patchwork.dpdk.org/api/patches/104863/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20211203225516.571368-6-stephend@silicom-usa.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20211203225516.571368-6-stephend@silicom-usa.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211203225516.571368-6-stephend@silicom-usa.com",
    "date": "2021-12-03T22:55:14",
    "name": "[5/7] net/ixgbe: Fix SFP detection and linking on hotplug",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "58ea1bf769d8fe92a7745656ea7b41ce1cca6931",
    "submitter": {
        "id": 2437,
        "url": "http://patchwork.dpdk.org/api/people/2437/?format=api",
        "name": "Stephen Douthit",
        "email": "stephend@silicom-usa.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patchwork.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20211203225516.571368-6-stephend@silicom-usa.com/mbox/",
    "series": [
        {
            "id": 20852,
            "url": "http://patchwork.dpdk.org/api/series/20852/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=20852",
            "date": "2021-12-03T22:55:09",
            "name": "ixgbe SFP handling fixes",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/20852/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/104863/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/104863/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 31062A0C41;\n\tFri,  3 Dec 2021 23:56:31 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 6D51142745;\n\tFri,  3 Dec 2021 23:56:06 +0100 (CET)",
            "from EUR05-VI1-obe.outbound.protection.outlook.com\n (mail-vi1eur05on2104.outbound.protection.outlook.com [40.107.21.104])\n by mails.dpdk.org (Postfix) with ESMTP id 1876640041;\n Fri,  3 Dec 2021 23:56:00 +0100 (CET)",
            "from AM0PR04MB4083.eurprd04.prod.outlook.com (2603:10a6:208:64::29)\n by AM0PR04MB6404.eurprd04.prod.outlook.com (2603:10a6:208:178::23)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4734.23; Fri, 3 Dec\n 2021 22:55:58 +0000",
            "from AM0PR04MB4083.eurprd04.prod.outlook.com\n ([fe80::f4db:d40d:a746:7bfc]) by AM0PR04MB4083.eurprd04.prod.outlook.com\n ([fe80::f4db:d40d:a746:7bfc%7]) with mapi id 15.20.4755.019; Fri, 3 Dec 2021\n 22:55:58 +0000",
            "from lappy.adi.eng (173.14.114.227) by\n BL1PR13CA0431.namprd13.prod.outlook.com (2603:10b6:208:2c3::16) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4755.10 via Frontend\n Transport; Fri, 3 Dec 2021 22:55:58 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=L+l5lHL5Fx9NYpUky/9cdLqXM5SGwW19RWlNiQRigSOIJwfdmjaKxietDTSB4NTzr55TlpZ5k9DjTkSPoWUUkxFHpT4Qdt1YqbNKwQIJL9TkaoypHPZMkd0C7bwqQZZcsowh9Zn/ZSAS0vqE5Zjah1NMVKwB/lgwXB0ZYXF9qAQ0yPnC5JNrUt4TcCPBcvO1ynvg3p2Is2Bebb3s7N8cQFUQTsYkVAxmwTF8/BftmjH6WkA0wekAmh5pjYQ0msoHN+lte+L5duu0OZvuQ0oR1WcOceFe8zTzndEuRPZJ90D1uB1BMbWl3Ryg7JMVvf4JAiUBpAHkXWJp61wFIkRhvA==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=vq/60XPKnfJkiH0fCeGH8KVqdWS5GHyNdO1UPIck2ng=;\n b=LYHCjNh4ugxgQPDi2alkwqvJ7PjkaA2bhnxN73643aCgOA+DAECyormjPLMfzhlHXas8KGFfrObditq/3F2sXie9w5dhhQE0Fclv68yg6P7Qs4ucJ8jsV+VDA++W2O+8sLh8NbljfNmkIGKNJdKFVLsDCEBGKyf/FJW3hG9MPKAzCkEYh761bXAlW+LaMEPdEIDNyEAjgTL86NFs/B0fP2KONaHAKXdj8tlyYt9ifeRlI93teoS5vTJeTtj9MlFfcjpaff8szdDnwtmMzPrP+czuMEO94gr+ofzmhwct22yHrbAP7icTHVSjs8TmqdIOpx09A2Be08uxTr7GBRsRzw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=silicom-usa.com; dmarc=pass action=none\n header.from=silicom-usa.com; dkim=pass header.d=silicom-usa.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=SILICOMLTD.onmicrosoft.com; s=selector2-SILICOMLTD-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=vq/60XPKnfJkiH0fCeGH8KVqdWS5GHyNdO1UPIck2ng=;\n b=jZu7CDwlMyKz1bGBbA0AkeU1a0cICYb4y0gs11cB0SGWPPAmvUg/wLxcJBIwsL1Y8IR6gcMnp352UEb6n6ESyRau4hTHoqzHR4d1SuxU30Tk+XPmckOjpjzBnuc174hIs8pP+FzitTkEkB9FaC2AOS2DkNXcSJZAXLe3hCyYLwM=",
        "Authentication-Results": "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=silicom-usa.com;",
        "From": "Stephen Douthit <stephend@silicom-usa.com>",
        "To": "dev@dpdk.org",
        "Cc": "wenw@silicom-usa.com, Stephen Douthit <stephend@silicom-usa.com>,\n stable@dpdk.org, Haiyue Wang <haiyue.wang@intel.com>",
        "Subject": "[PATCH 5/7] net/ixgbe: Fix SFP detection and linking on hotplug",
        "Date": "Fri,  3 Dec 2021 17:55:14 -0500",
        "Message-Id": "<20211203225516.571368-6-stephend@silicom-usa.com>",
        "X-Mailer": "git-send-email 2.31.1",
        "In-Reply-To": "<20211203225516.571368-1-stephend@silicom-usa.com>",
        "References": "<20211203225516.571368-1-stephend@silicom-usa.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "BL1PR13CA0431.namprd13.prod.outlook.com\n (2603:10b6:208:2c3::16) To AM0PR04MB4083.eurprd04.prod.outlook.com\n (2603:10a6:208:64::29)",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "79911d8e-fe6f-4608-8886-08d9b6b01248",
        "X-MS-TrafficTypeDiagnostic": "AM0PR04MB6404:",
        "X-Microsoft-Antispam-PRVS": "\n <AM0PR04MB6404ED6447064E94011278EA946A9@AM0PR04MB6404.eurprd04.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:10000;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n POwXU2UnMJEichqFHTGSp7gYkNx3fvK8YGJ9Hjm819j6NVY7wmBhfkDpYi1rM2+tpJZOlcDjnzjLoWCHBydpTXr6BzkuC5gREEWn5Jbg1ntrfmVTp+SyUWUZh2j5pzqRJm0EH9QecwQEi1FjEMre4B9Euxq5iJQ7PPQhmptSCb82yG5o2AA/qUQqkp77lrOUcKgKqIfgXUI21x3OYsr7JX5frwJ9YFbuygvOsnLGQx1YQ3zvbzGQgmUzQ3BW1GB0guMcfLctsrPRg+wdAIPYGqgwvD/J5KAYpMUJiCksnsW82crfPLJxdEN3h5QmGd83q1Gp4LaUeZvlCjoiPhEDbN6g6RpzUP7NpmHZzeKElQkzjo7NnNwCrEfGXFwZobPPqO5WAGy/Kr/pOQrv1hbukk1/grvfH8V59LH4umX0JuP678pA1+r2dfbm8oXKlb9RIhLw6Jfm7Y5CwMxLmfkJ3L8VQORZ5dijBt1AhQ7WblabbPvgc8w/AJ5jAsV/y5CWtzJRgp12I8Psi9jiYR+hyMuUzNv8q1Fw/2rwVw2iBL6QI9/OrhuT1DnhGrxyRH44DYi3lfNeERhxFme2LEp7DhSFUHwkQ39tarva2KnTRpBhId1qiCgBN4s428fU9FmCVss7qFwacJydhXfRwlheiD522SrW4jqjKZ14XJM53pRxcjfVeyqYup3iaChfh8BmE7mqDggqMaSM99ag4KRxXg==",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:AM0PR04MB4083.eurprd04.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(4636009)(366004)(8936002)(2906002)(30864003)(508600001)(6916009)(8676002)(6486002)(26005)(956004)(83380400001)(316002)(1076003)(36756003)(5660300002)(86362001)(186003)(4326008)(66946007)(2616005)(38100700002)(38350700002)(6506007)(66556008)(52116002)(66476007)(6666004)(6512007)(54906003);\n DIR:OUT; SFP:1102;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "\n tSQpp81a8SWBBxuwnZOYdIwr2soLlyGfCXuuSU1OeB1AZEz8E6MMHHBX/EhpqVil4alkQGQQkWbw431Az/OCpErK+QKsB4Nj2cs6kcR1oDF2DIOCnFWZdZxRIZyLHN3xJqhsNeqPrTpjd7KYyu6xH+eoHuzIsRtc9f1UCV4ZcngK2Tukm1oGQLflaLk50UzrjGm1L8voVcqUknl2FFu4G9BebGEHfgZy7LiruDzETsaABPvTIaauV33yi0+hyvCn0I4y2M5wWfi1Pr+xS7uK9lupLLE5YYdeKzdl8KEI02xacfyYmpXzpcJB99Rz46LdEhBGveeswBYPoDypxZ02Zq+LbVet7wMg4rL0Z5c/hH6jSTPvkm1Qrh12MbPkCl9/ANUf+NMHXmjz0uKa+lanNMUW/7gv9Pk6L2JQlXvAjePDK20aycwjgcauQfMtHrfxGRs/ncZ1pLtSMl0ZqxAtiVAdTgn1soXgEZcH+1dhW7KGEoQx/C1NLcAw/RaChzKZSb1xeJNiF6S4GIVnddyZuniLPQnaU92UT8DdU3yVkPgAtbrg8xZjUT1f/PDKDi6oVpaiSWJ9xGJ9aQmJnksW3SWBcAyEepuBW4FYh+ScnkUTGF064z9fQAr2bSYVjmtb0kZJ7+wa0YvPC8KdiY/bXT5SCq+ImllGsrvaZ1h5bstmMdX56ADibPu5jvm00LOX25XGKDQK622OG2+19FYH80v+Xjt3FQKJbg7t33kbIvLEX+vzyFIRnq3FI+vkfHyJwiYcwXm74rHlKnn32OMRBpbLUwGefAYvk5dAvScAWrM72rH5ZY6dwJCT4jU7H1f+ApQ76wKwm6f+fOhrMjGexsbsfyCEwkOmrzDGJWSjEnEbyscwHJnFIRFA+z4V1Vr4krbJw3ZgYILwGarxsRMALfAhMqQoz+UxYiTWZ9FQLByADbWmFr8SJq2pVNZwLyMOiXRoYxeavt7VNpGt4Sxw6GVGecrqUBEqCUj8OjGzjlokuasOiKNq0jYu95IB8+fGfSx0oQABwbJa4mp/iaui1MmYDz7WvYC/owKELYDawhwwAoYqgcrqrN2fnYVvu4dZKVy1Q52Ey7kSFSwVmDbG4lfXXpVuEyHAa038qTMYByjR6/VBmOB2bzKAAUcrxQaAYdNQK1fON7KCx6Y1hAqeMKAO5rw9srcV1udXL52vsazDXH01o1SGNuFgw+XJpIn22sxykJRqx5DjAxV0vsB2nyOxJuHOWlp/RArGFYnlvbplckbh7uG3rCUCouKtjWGqgkUut/A0BElPVvfg+SRPQ85qcbQsUszOlaOFpoqU2XKsSuQbRHQp13IYmSaQKKYmYauJKHFfJjhWfKeoa0JADKM6qs8RYsV1wBFNDRx+DVmyVz0zehDLG4NLqaZZ5CuCaUgmbfGkaRoP9/DKvYnfsqYBk8/JwAx/kId3KM4dDesCBj1Zn3/8GTzyHzikDN6uU+E84FzAfFKAJ5SgU2mhZrUP8n439XTmuVLpV6iMIlhviNO6v3ntkVBKmsWfTNOmr0CctQbYpgMe1RBaE2M8mU3z7szFnOujz3Ayrrxp06gsqZ3LKG70OuANkVaV4vHsNPBOk8iKUuOLy9Js/j8WS75fYjAuMlOLiDV4VH/eDyUyl07jVMqY1yiSfHQIn6yVdoZWPpkB+ThryAfJa1zQs0eJrTXhkBOQPqNIRWTFEKo=",
        "X-OriginatorOrg": "silicom-usa.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 79911d8e-fe6f-4608-8886-08d9b6b01248",
        "X-MS-Exchange-CrossTenant-AuthSource": "AM0PR04MB4083.eurprd04.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "03 Dec 2021 22:55:58.8357 (UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "c9e326d8-ce47-4930-8612-cc99d3c87ad1",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n zzPPzU2plWBnZQ7YFjXm1GL9MIy0XhceyQYKAGSOHjlkUajCo5SB9dj+8M92hi7t0d0Xh46iD89IIrPRrqemfTELsdujhXY2E+dYt/v5KkM=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM0PR04MB6404",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Currently the ixgbe driver does not ID any SFP except for the first one\nplugged in. This can lead to no-link, or incorrect speed conditions.\n\nFor example:\n\n* If link is initially established with a 1G SFP, and later a 1G/10G\nmultispeed part is later installed, then the MAC link setup functions are\nnever called to change from 1000BASE-X to 10GBASE-R mode, and the link\nstays running at the slower rate.\n\n* If link is initially established with a 1G SFP, and later a 10G only\nmodule is later installed, no link is established, since we are still\ntrasnsmitting in 1000BASE-X mode to a 10GBASE-R only partner.\n\nRefactor the SFP ID/setup, and link setup code, to more closely match the\nflow of the mainline kernel driver which does not have these issues.  In\nthat driver a service task runs periodically to handle these operations\nbased on bit flags that have been set (usually via interrupt or userspace\nrequest), and then get cleared once the requested subtask has been\ncompleted.\n\nFixes: af75078fece (\"first public release\")\nCc: stable@dpdk.org\n\nSigned-off-by: Stephen Douthit <stephend@silicom-usa.com>\n---\n drivers/net/ixgbe/base/ixgbe_type.h |   2 +\n drivers/net/ixgbe/ixgbe_ethdev.c    | 391 ++++++++++++++++++----------\n drivers/net/ixgbe/ixgbe_ethdev.h    |  18 +-\n 3 files changed, 266 insertions(+), 145 deletions(-)",
    "diff": "diff --git a/drivers/net/ixgbe/base/ixgbe_type.h b/drivers/net/ixgbe/base/ixgbe_type.h\nindex b7eec45635..c23257aa4c 100644\n--- a/drivers/net/ixgbe/base/ixgbe_type.h\n+++ b/drivers/net/ixgbe/base/ixgbe_type.h\n@@ -45,6 +45,8 @@\n \n #include \"ixgbe_osdep.h\"\n \n+#define BIT(a) (1UL << (a))\n+\n /* Override this by setting IOMEM in your ixgbe_osdep.h header */\n \n /* Vendor ID */\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex 34b7cb2d4e..974b3427d1 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -229,9 +229,6 @@ static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev);\n static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev);\n static void ixgbe_dev_interrupt_handler(void *param);\n static void ixgbe_dev_interrupt_delayed_handler(void *param);\n-static void *ixgbe_dev_setup_link_thread_handler(void *param);\n-static int ixgbe_dev_wait_setup_link_complete(struct rte_eth_dev *dev,\n-\t\t\t\t\t      uint32_t timeout_ms);\n \n static int ixgbe_add_rar(struct rte_eth_dev *dev,\n \t\t\tstruct rte_ether_addr *mac_addr,\n@@ -1032,6 +1029,205 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)\n \tixgbe_release_swfw_semaphore(hw, mask);\n }\n \n+static s32\n+ixgbe_sfp_id_and_setup(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_hw *hw =\n+\t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tenum ixgbe_sfp_cage_status sfp_cage_status;\n+\ts32 err;\n+\n+\t/* Can't ID or setup SFP if it's not plugged in */\n+\tsfp_cage_status = ixgbe_check_sfp_cage(hw);\n+\tif (sfp_cage_status == IXGBE_SFP_CAGE_EMPTY ||\n+\t    sfp_cage_status == IXGBE_SFP_CAGE_NOCAGE)\n+\t\treturn IXGBE_ERR_SFP_NOT_PRESENT;\n+\n+\t/* Something's in the cage, ID it */\n+\thw->phy.ops.identify_sfp(hw);\n+\n+\t/* Unknown module type, give up */\n+\tif (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {\n+\t\tPMD_DRV_LOG(ERR, \"unknown SFP type, giving up\");\n+\t\treturn IXGBE_ERR_SFP_NOT_SUPPORTED;\n+\t}\n+\n+\t/* This should be a redundant check, since we looked at the\n+\t * PRSNT# signal from the cage above, but just in case this is\n+\t * an SFP that's slow to respond to I2C pokes correctly, try it\n+\t * again later\n+\t */\n+\tif (hw->phy.sfp_type == ixgbe_sfp_type_not_present) {\n+\t\tPMD_DRV_LOG(ERR, \"IDed SFP as absent but cage PRSNT# active!?\");\n+\t\treturn IXGBE_ERR_SFP_NOT_PRESENT;\n+\t}\n+\n+\t/* SFP is present and identified, try to set it up */\n+\terr = hw->mac.ops.setup_sfp(hw);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"setup_sfp() failed %d\", err);\n+\n+\treturn err;\n+}\n+\n+/**\n+ * SFP polling task to identify and setup SFPs.\n+ *\n+ * If we see an SFP present, try to ID it and set it up.  If that works then let\n+ * ixgbe_dev_link_update() do the remainder of the non-SFP link setup.\n+ *\n+ * If that fails, schedule ourself to try again.\n+ *\n+ * @param handle\n+ *  Pointer to interrupt handle.\n+ * @param param\n+ *  The address of parameter (struct rte_eth_dev *) registered before.\n+ *\n+ * @return\n+ *  void\n+ */\n+static void\n+ixgbe_sfp_service(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_hw *hw =\n+\t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_interrupt *intr =\n+\t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n+\tenum ixgbe_sfp_cage_status sfp_cage_status;\n+\ts32 err;\n+\n+\t/* No setup requested?  Nothing to do */\n+\tif (!(intr->flags & IXGBE_FLAG_NEED_SFP_SETUP))\n+\t\treturn;\n+\n+\tsfp_cage_status = ixgbe_check_sfp_cage(hw);\n+\tif (sfp_cage_status == IXGBE_SFP_CAGE_EMPTY ||\n+\t    sfp_cage_status == IXGBE_SFP_CAGE_NOCAGE)\n+\t\treturn;\n+\n+\terr = ixgbe_sfp_id_and_setup(dev);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(DEBUG, \"failed to ID & setup SFP %d\", err);\n+\t\treturn;\n+\t}\n+\n+\t/* Setup is done, clear the flag, but make sure link config runs for new SFP */\n+\tintr->flags &= ~IXGBE_FLAG_NEED_SFP_SETUP;\n+\tintr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;\n+\n+\t/*\n+\t * Since this is a new SFP, clear the old advertised speed mask so we don't\n+\t * end up using an old slower rate\n+\t */\n+\thw->phy.autoneg_advertised = 0;\n+}\n+\n+static void\n+ixgbe_link_service(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_interrupt *intr =\n+\t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n+\tbool link_up, autoneg = false;\n+\tu32 speed;\n+\ts32 err;\n+\n+\t/* Skip if we still need to setup an SFP, or if no link config requested\n+\t */\n+\tif ((intr->flags & IXGBE_FLAG_NEED_SFP_SETUP) ||\n+\t    !(intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG))\n+\t\treturn;\n+\n+\tspeed = hw->phy.autoneg_advertised;\n+\tif (!speed)\n+\t\tixgbe_get_link_capabilities(hw, &speed, &autoneg);\n+\n+\terr = ixgbe_setup_link(hw, speed, true);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"ixgbe_setup_link failed %d\", err);\n+\t\treturn;\n+\t}\n+\n+\t/* Update internal link status, waiting for link */\n+\terr = ixgbe_check_link(hw, &speed, &link_up, 1);\n+\tif (!err && link_up)\n+\t\tintr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;\n+\n+\tif (!ixgbe_dev_link_update(dev, 0)) {\n+\t\tixgbe_dev_link_status_print(dev);\n+\t\trte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);\n+\t}\n+}\n+\n+/*\n+ * Is time b after time a?\n+ */\n+static bool\n+ts_time_after(const struct timespec *a, const struct timespec *b)\n+{\n+\tif (b->tv_sec > a->tv_sec ||\n+\t    (b->tv_sec == a->tv_sec && b->tv_nsec > a->tv_nsec))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n+/*\n+ * Service task thread to handle periodic tasks\n+ */\n+static void *\n+ixgbe_dev_service_thread_handler(void *param)\n+{\n+#define SERVICE_THREAD_US_SLEEP (100 * 1000)\n+\n+\tstruct rte_eth_dev *dev = (struct rte_eth_dev *)param;\n+\tstruct ixgbe_hw *hw =\n+\t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct timespec ts, end_ts;\n+\tuint32_t speed;\n+\ts32 err;\n+\tbool link_up;\n+\n+\twhile (1) {\n+\t\tixgbe_sfp_service(dev);\n+\t\tixgbe_link_service(dev);\n+\n+\t\t/* Run the service thread handler more frequently when link is\n+\t\t * down to reduce link up latency (every 200ms vs 1s)\n+\t\t *\n+\t\t * Use a number of smaller sleeps to decrease exit latency when\n+\t\t * ixgbe_dev_stop() wants this thread to join\n+\t\t */\n+\t\terr = ixgbe_check_link(hw, &speed, &link_up, 0);\n+\t\tclock_gettime(CLOCK_REALTIME, &end_ts);\n+\t\tif (err == IXGBE_SUCCESS && link_up) {\n+\t\t\tend_ts.tv_sec += 1;\n+\t\t} else {\n+\t\t\tend_ts.tv_nsec += 200000000;\n+\t\t\tif (end_ts.tv_nsec > 1000000000) {\n+\t\t\t\tend_ts.tv_nsec -= 1000000000;\n+\t\t\t\tend_ts.tv_sec++;\n+\t\t\t}\n+\t\t}\n+\n+\t\twhile (1) {\n+\t\t\t/* Don't assume that rte_delay_us_sleep() provides a\n+\t\t\t * cancellation point in all execution environments,\n+\t\t\t * explicitly check for thread cancellation\n+\t\t\t */\n+\t\t\tpthread_testcancel();\n+\t\t\trte_delay_us_sleep(SERVICE_THREAD_US_SLEEP);\n+\n+\t\t\tclock_gettime(CLOCK_REALTIME, &ts);\n+\t\t\tif (ts_time_after(&end_ts, &ts))\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Never return */\n+\treturn NULL;\n+}\n+\n /*\n  * This function is based on code in ixgbe_attach() in base/ixgbe.c.\n  * It returns 0 on success.\n@@ -1039,7 +1235,6 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)\n static int\n eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)\n {\n-\tstruct ixgbe_adapter *ad = eth_dev->data->dev_private;\n \tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n \tstruct rte_intr_handle *intr_handle = pci_dev->intr_handle;\n \tstruct ixgbe_hw *hw =\n@@ -1094,7 +1289,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)\n \t\treturn 0;\n \t}\n \n-\trte_atomic32_clear(&ad->link_thread_running);\n \trte_eth_copy_pci_info(eth_dev, pci_dev);\n \teth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;\n \n@@ -1537,7 +1731,6 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)\n {\n \tint diag;\n \tuint32_t tc, tcs;\n-\tstruct ixgbe_adapter *ad = eth_dev->data->dev_private;\n \tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);\n \tstruct rte_intr_handle *intr_handle = pci_dev->intr_handle;\n \tstruct ixgbe_hw *hw =\n@@ -1580,7 +1773,6 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)\n \t\treturn 0;\n \t}\n \n-\trte_atomic32_clear(&ad->link_thread_running);\n \tixgbevf_parse_devargs(eth_dev->data->dev_private,\n \t\t\t      pci_dev->device.devargs);\n \n@@ -2382,6 +2574,8 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)\n \tstruct ixgbe_interrupt *intr =\n \t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n \tstruct ixgbe_adapter *adapter = dev->data->dev_private;\n+\tstruct ixgbe_hw *hw =\n+\t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tint ret;\n \n \tPMD_INIT_FUNC_TRACE();\n@@ -2400,6 +2594,10 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)\n \t/* set flag to update link status after init */\n \tintr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;\n \n+\t/* set flag to setup SFP after init */\n+\tif (ixgbe_is_sfp(hw))\n+\t\tintr->flags |= IXGBE_FLAG_NEED_SFP_SETUP;\n+\n \t/*\n \t * Initialize to TRUE. If any of Rx queues doesn't meet the bulk\n \t * allocation or vector Rx preconditions we will reset it.\n@@ -2419,13 +2617,24 @@ ixgbe_dev_phy_intr_setup(struct rte_eth_dev *dev)\n \t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n \tuint32_t gpie;\n \n-\t/* only set up it on X550EM_X */\n+\t/* only set up it on X550EM_X (external PHY interrupt)\n+\t * or on x550em_a_* for SFP_PRSNT# de-assertion (SFP removal event)\n+\t */\n \tif (hw->mac.type == ixgbe_mac_X550EM_x) {\n \t\tgpie = IXGBE_READ_REG(hw, IXGBE_GPIE);\n \t\tgpie |= IXGBE_SDP0_GPIEN_X550EM_x;\n \t\tIXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);\n \t\tif (hw->phy.type == ixgbe_phy_x550em_ext_t)\n \t\t\tintr->mask |= IXGBE_EICR_GPI_SDP0_X550EM_x;\n+\t} else if (hw->mac.type == ixgbe_mac_X550EM_a) {\n+\t\tgpie = IXGBE_READ_REG(hw, IXGBE_GPIE);\n+\t\tgpie |= IXGBE_SDP0_GPIEN_X550EM_a;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);\n+\t\tintr->mask |= IXGBE_EICR_GPI_SDP0_X550EM_a;\n+\t} else {\n+\t\tPMD_DRV_LOG(DEBUG,\n+\t\t\t    \"No PHY/SFP interrupt for MAC %d, PHY %d\\n\",\n+\t\t\t    hw->mac.type, hw->phy.type);\n \t}\n }\n \n@@ -2548,8 +2757,11 @@ ixgbe_flow_ctrl_enable(struct rte_eth_dev *dev, struct ixgbe_hw *hw)\n static int\n ixgbe_dev_start(struct rte_eth_dev *dev)\n {\n+\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n \tstruct ixgbe_hw *hw =\n \t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_interrupt *intr =\n+\t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n \tstruct ixgbe_vf_info *vfinfo =\n \t\t*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);\n \tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n@@ -2570,9 +2782,6 @@ ixgbe_dev_start(struct rte_eth_dev *dev)\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\t/* Stop the link setup handler before resetting the HW. */\n-\tixgbe_dev_wait_setup_link_complete(dev, 0);\n-\n \t/* disable uio/vfio intr/eventfd mapping */\n \trte_intr_disable(intr_handle);\n \n@@ -2688,12 +2897,6 @@ ixgbe_dev_start(struct rte_eth_dev *dev)\n \t\t}\n \t}\n \n-\tif (ixgbe_is_sfp(hw) && hw->phy.multispeed_fiber) {\n-\t\terr = hw->mac.ops.setup_sfp(hw);\n-\t\tif (err)\n-\t\t\tgoto error;\n-\t}\n-\n \tif (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {\n \t\t/* Turn on the copper */\n \t\tixgbe_set_phy_power(hw, true);\n@@ -2805,6 +3008,20 @@ ixgbe_dev_start(struct rte_eth_dev *dev)\n \tixgbe_l2_tunnel_conf(dev);\n \tixgbe_filter_restore(dev);\n \n+\t/* Spawn service thread */\n+\tif (ixgbe_is_sfp(hw)) {\n+\t\tintr->flags |= IXGBE_FLAG_NEED_SFP_SETUP;\n+\t\terr = rte_ctrl_thread_create(&ad->service_thread_tid,\n+\t\t\t\t\t     \"ixgbe-service-thread\",\n+\t\t\t\t\t     NULL,\n+\t\t\t\t\t     ixgbe_dev_service_thread_handler,\n+\t\t\t\t\t     dev);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"service_thread err\");\n+\t\t\tgoto error;\n+\t\t}\n+\t}\n+\n \tif (tm_conf->root && !tm_conf->committed)\n \t\tPMD_DRV_LOG(WARNING,\n \t\t\t    \"please call hierarchy_commit() \"\n@@ -2815,12 +3032,6 @@ ixgbe_dev_start(struct rte_eth_dev *dev)\n \tif (err)\n \t\tgoto error;\n \n-\t/*\n-\t * Update link status right before return, because it may\n-\t * start link configuration process in a separate thread.\n-\t */\n-\tixgbe_dev_link_update(dev, 0);\n-\n \t/* setup the macsec setting register */\n \tif (macsec_setting->offload_en)\n \t\tixgbe_dev_macsec_register_enable(dev, macsec_setting);\n@@ -2850,13 +3061,21 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)\n \tint vf;\n \tstruct ixgbe_tm_conf *tm_conf =\n \t\tIXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private);\n+\tvoid *res;\n+\ts32 err;\n \n \tif (hw->adapter_stopped)\n \t\treturn 0;\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\tixgbe_dev_wait_setup_link_complete(dev, 0);\n+\t/* Cancel the service thread, and wait for it to join */\n+\terr = pthread_cancel(adapter->service_thread_tid);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"failed to cancel service thread %d\", err);\n+\terr = pthread_join(adapter->service_thread_tid, &res);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR, \"failed to join service thread %d\", err);\n \n \t/* disable interrupts */\n \tixgbe_disable_intr(hw);\n@@ -2935,7 +3154,6 @@ ixgbe_dev_set_link_up(struct rte_eth_dev *dev)\n \t} else {\n \t\t/* Turn on the laser */\n \t\tixgbe_enable_tx_laser(hw);\n-\t\tixgbe_dev_link_update(dev, 0);\n \t}\n \n \treturn 0;\n@@ -2966,7 +3184,6 @@ ixgbe_dev_set_link_down(struct rte_eth_dev *dev)\n \t} else {\n \t\t/* Turn off the laser */\n \t\tixgbe_disable_tx_laser(hw);\n-\t\tixgbe_dev_link_update(dev, 0);\n \t}\n \n \treturn 0;\n@@ -4118,57 +4335,6 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n \treturn ret_val;\n }\n \n-/*\n- * If @timeout_ms was 0, it means that it will not return until link complete.\n- * It returns 1 on complete, return 0 on timeout.\n- */\n-static int\n-ixgbe_dev_wait_setup_link_complete(struct rte_eth_dev *dev, uint32_t timeout_ms)\n-{\n-#define WARNING_TIMEOUT    9000 /* 9s  in total */\n-\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n-\tuint32_t timeout = timeout_ms ? timeout_ms : WARNING_TIMEOUT;\n-\n-\twhile (rte_atomic32_read(&ad->link_thread_running)) {\n-\t\tmsec_delay(1);\n-\t\ttimeout--;\n-\n-\t\tif (timeout_ms) {\n-\t\t\tif (!timeout)\n-\t\t\t\treturn 0;\n-\t\t} else if (!timeout) {\n-\t\t\t/* It will not return until link complete */\n-\t\t\ttimeout = WARNING_TIMEOUT;\n-\t\t\tPMD_DRV_LOG(ERR, \"IXGBE link thread not complete too long time!\");\n-\t\t}\n-\t}\n-\n-\treturn 1;\n-}\n-\n-static void *\n-ixgbe_dev_setup_link_thread_handler(void *param)\n-{\n-\tstruct rte_eth_dev *dev = (struct rte_eth_dev *)param;\n-\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n-\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tstruct ixgbe_interrupt *intr =\n-\t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n-\tu32 speed;\n-\tbool autoneg = false;\n-\n-\tpthread_detach(pthread_self());\n-\tspeed = hw->phy.autoneg_advertised;\n-\tif (!speed)\n-\t\tixgbe_get_link_capabilities(hw, &speed, &autoneg);\n-\n-\tixgbe_setup_link(hw, speed, true);\n-\n-\tintr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;\n-\trte_atomic32_clear(&ad->link_thread_running);\n-\treturn NULL;\n-}\n-\n /*\n  * In freebsd environment, nic_uio drivers do not support interrupts,\n  * rte_intr_callback_register() will fail to register interrupts.\n@@ -4208,11 +4374,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,\n \t\t\t    int wait_to_complete, int vf)\n {\n \tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n-\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n \tstruct rte_eth_link link;\n \tixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;\n-\tstruct ixgbe_interrupt *intr =\n-\t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n \tbool link_up;\n \tint diag;\n \tint wait = 1;\n@@ -4226,9 +4389,6 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,\n \n \thw->mac.get_link_status = true;\n \n-\tif (intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG)\n-\t\treturn rte_eth_linkstatus_set(dev, &link);\n-\n \t/* check if it needs to wait to complete, if lsc interrupt is enabled */\n \tif (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)\n \t\twait = 0;\n@@ -4243,38 +4403,12 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,\n \telse\n \t\tdiag = ixgbe_check_link(hw, &link_speed, &link_up, wait);\n \n-\tif (diag != 0) {\n+\tif (diag != 0 || !link_up) {\n \t\tlink.link_speed = RTE_ETH_SPEED_NUM_100M;\n \t\tlink.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;\n \t\treturn rte_eth_linkstatus_set(dev, &link);\n \t}\n \n-\tif (link_up == 0) {\n-\t\tif (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {\n-\t\t\tixgbe_dev_wait_setup_link_complete(dev, 0);\n-\t\t\tif (rte_atomic32_test_and_set(&ad->link_thread_running)) {\n-\t\t\t\t/* To avoid race condition between threads, set\n-\t\t\t\t * the IXGBE_FLAG_NEED_LINK_CONFIG flag only\n-\t\t\t\t * when there is no link thread running.\n-\t\t\t\t */\n-\t\t\t\tintr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;\n-\t\t\t\tif (rte_ctrl_thread_create(&ad->link_thread_tid,\n-\t\t\t\t\t\"ixgbe-link-handler\",\n-\t\t\t\t\tNULL,\n-\t\t\t\t\tixgbe_dev_setup_link_thread_handler,\n-\t\t\t\t\tdev) < 0) {\n-\t\t\t\t\tPMD_DRV_LOG(ERR,\n-\t\t\t\t\t\t\"Create link thread failed!\");\n-\t\t\t\t\trte_atomic32_clear(&ad->link_thread_running);\n-\t\t\t\t}\n-\t\t\t} else {\n-\t\t\t\tPMD_DRV_LOG(ERR,\n-\t\t\t\t\t\"Other link thread is running now!\");\n-\t\t\t}\n-\t\t}\n-\t\treturn rte_eth_linkstatus_set(dev, &link);\n-\t}\n-\n \tlink.link_status = RTE_ETH_LINK_UP;\n \tlink.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;\n \n@@ -4480,8 +4614,6 @@ ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev)\n \teicr = IXGBE_READ_REG(hw, IXGBE_EICR);\n \tPMD_DRV_LOG(DEBUG, \"eicr %x\", eicr);\n \n-\tintr->flags = 0;\n-\n \t/* set flag for async link update */\n \tif (eicr & IXGBE_EICR_LSC)\n \t\tintr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;\n@@ -4497,6 +4629,11 @@ ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev)\n \t    (eicr & IXGBE_EICR_GPI_SDP0_X550EM_x))\n \t\tintr->flags |= IXGBE_FLAG_PHY_INTERRUPT;\n \n+\t/* Check for loss of SFP */\n+\tif (hw->mac.type ==  ixgbe_mac_X550EM_a &&\n+\t    (eicr & IXGBE_EICR_GPI_SDP0_X550EM_a))\n+\t\tintr->flags |= IXGBE_FLAG_NEED_SFP_SETUP;\n+\n \treturn 0;\n }\n \n@@ -4548,11 +4685,13 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)\n static int\n ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)\n {\n+\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n+\tstruct rte_intr_handle *intr_handle = pci_dev->intr_handle;\n \tstruct ixgbe_interrupt *intr =\n \t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n-\tint64_t timeout;\n \tstruct ixgbe_hw *hw =\n \t\tIXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tint64_t timeout;\n \n \tPMD_DRV_LOG(DEBUG, \"intr action type %d\", intr->flags);\n \n@@ -4587,16 +4726,14 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)\n \t\tif (rte_eal_alarm_set(timeout * 1000,\n \t\t\t\t      ixgbe_dev_interrupt_delayed_handler, (void *)dev) < 0)\n \t\t\tPMD_DRV_LOG(ERR, \"Error setting alarm\");\n-\t\telse {\n-\t\t\t/* remember original mask */\n-\t\t\tintr->mask_original = intr->mask;\n+\t\telse\n \t\t\t/* only disable lsc interrupt */\n \t\t\tintr->mask &= ~IXGBE_EIMS_LSC;\n-\t\t}\n \t}\n \n \tPMD_DRV_LOG(DEBUG, \"enable intr immediately\");\n \tixgbe_enable_intr(dev);\n+\trte_intr_ack(intr_handle);\n \n \treturn 0;\n }\n@@ -4619,8 +4756,6 @@ static void\n ixgbe_dev_interrupt_delayed_handler(void *param)\n {\n \tstruct rte_eth_dev *dev = (struct rte_eth_dev *)param;\n-\tstruct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);\n-\tstruct rte_intr_handle *intr_handle = pci_dev->intr_handle;\n \tstruct ixgbe_interrupt *intr =\n \t\tIXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);\n \tstruct ixgbe_hw *hw =\n@@ -4650,13 +4785,10 @@ ixgbe_dev_interrupt_delayed_handler(void *param)\n \t\tintr->flags &= ~IXGBE_FLAG_MACSEC;\n \t}\n \n-\t/* restore original mask */\n-\tintr->mask = intr->mask_original;\n-\tintr->mask_original = 0;\n+\tif (dev->data->dev_conf.intr_conf.lsc != 0)\n+\t\tintr->mask |= IXGBE_EICR_LSC;\n \n-\tPMD_DRV_LOG(DEBUG, \"enable intr in delayed handler S[%08x]\", eicr);\n \tixgbe_enable_intr(dev);\n-\trte_intr_ack(intr_handle);\n }\n \n /**\n@@ -5298,9 +5430,6 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\t/* Stop the link setup handler before resetting the HW. */\n-\tixgbe_dev_wait_setup_link_complete(dev, 0);\n-\n \terr = hw->mac.ops.reset_hw(hw);\n \n \t/**\n@@ -5380,12 +5509,6 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)\n \t/* Re-enable interrupt for VF */\n \tixgbevf_intr_enable(dev);\n \n-\t/*\n-\t * Update link status right before return, because it may\n-\t * start link configuration process in a separate thread.\n-\t */\n-\tixgbevf_dev_link_update(dev, 0);\n-\n \thw->adapter_stopped = false;\n \n \treturn 0;\n@@ -5404,8 +5527,6 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)\n \n \tPMD_INIT_FUNC_TRACE();\n \n-\tixgbe_dev_wait_setup_link_complete(dev, 0);\n-\n \tixgbevf_intr_disable(dev);\n \n \tdev->data->dev_started = 0;\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h\nindex 83e8b5e56a..14658a2a82 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.h\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.h\n@@ -24,11 +24,12 @@\n #include <rte_tm_driver.h>\n \n /* need update link, bit flag */\n-#define IXGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)\n-#define IXGBE_FLAG_MAILBOX          (uint32_t)(1 << 1)\n-#define IXGBE_FLAG_PHY_INTERRUPT    (uint32_t)(1 << 2)\n-#define IXGBE_FLAG_MACSEC           (uint32_t)(1 << 3)\n-#define IXGBE_FLAG_NEED_LINK_CONFIG (uint32_t)(1 << 4)\n+#define IXGBE_FLAG_NEED_LINK_UPDATE BIT(0)\n+#define IXGBE_FLAG_MAILBOX          BIT(1)\n+#define IXGBE_FLAG_PHY_INTERRUPT    BIT(2)\n+#define IXGBE_FLAG_MACSEC           BIT(3)\n+#define IXGBE_FLAG_NEED_LINK_CONFIG BIT(4)\n+#define IXGBE_FLAG_NEED_SFP_SETUP   BIT(5)\n \n /*\n  * Defines that were not part of ixgbe_type.h as they are not used by the\n@@ -41,7 +42,7 @@\n #define IXGBE_RXDADV_ERR_CKSUM_MSK  3\n #define IXGBE_ADVTXD_MACLEN_SHIFT   9          /* Bit shift for l2_len */\n #define IXGBE_NB_STAT_MAPPING_REGS  32\n-#define IXGBE_EXTENDED_VLAN\t  (uint32_t)(1 << 26) /* EXTENDED VLAN ENABLE */\n+#define IXGBE_EXTENDED_VLAN\t    BIT(26)    /* EXTENDED VLAN ENABLE */\n #define IXGBE_VFTA_SIZE 128\n #define IXGBE_HKEY_MAX_INDEX 10\n #define IXGBE_MAX_RX_QUEUE_NUM\t128\n@@ -223,8 +224,6 @@ struct ixgbe_rte_flow_rss_conf {\n struct ixgbe_interrupt {\n \tuint32_t flags;\n \tuint32_t mask;\n-\t/*to save original mask during delayed handler */\n-\tuint32_t mask_original;\n };\n \n struct ixgbe_stat_mapping_registers {\n@@ -506,8 +505,7 @@ struct ixgbe_adapter {\n \t */\n \tuint8_t pflink_fullchk;\n \tuint8_t mac_ctrl_frame_fwd;\n-\trte_atomic32_t link_thread_running;\n-\tpthread_t link_thread_tid;\n+\tpthread_t service_thread_tid;\n };\n \n struct ixgbe_vf_representor {\n",
    "prefixes": [
        "5/7"
    ]
}