From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) by dpdk.org (Postfix) with ESMTP id DC458292D for ; Sun, 22 Apr 2018 17:11:11 +0200 (CEST) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 72CA220FF9; Sun, 22 Apr 2018 11:11:11 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Sun, 22 Apr 2018 11:11:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fridaylinux.org; h=cc:date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=mVcA05pzj+wJhY58T g0OQAa9bFdDXngtGhNk+oysENo=; b=Jw1QxgrIvCyRdAaUyUWkrCWFIWIelSwYX j5zWy/inoElFDJSZVM1N3GMiLI0Zlmb1wcBa6EDXnB912XUKSDwR8BioqEfwjWDf QTEAYsU11wm265UiA24uRUFn7oeDXn3theYmqqDwOFDAcCvGmyn/7U4teBpRwyhr idRgHv0FfXT15mG21jY5/AL3byu0r+rlFm3ZWKESpgbkI2cyEE8fgMZ9EgaTIfo5 REuBsaq4L4dUk02xvdxMUmpTrKQ1X+z7nheuN8bUEqNk1PSE23uTQBsmd5W6UyVE VIqKO0kb1vlRqWrgiYtNoOrseRybPGv7eCzJ6Lx2CHA4QxBmmUa4w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=mVcA05pzj+wJhY58Tg0OQAa9bFdDXngtGhNk+oysENo=; b=ASUElyOq RYr5GW06j0/kkc+DtenxF4ReQ7etWjRa2FDoWhzdzz6IMNCAbBUixD5odriFrJpC Y5j2iYHhkwz0v6JlMu0/R89vOMZyn7B0zWA0PTBPZJdOWdVg9Ve5q89/jv0vxlIk MHBGlN4/5mysy/W0JSlAJkfU+Dbk+H8ZJhL2F28+JUntANSJH6+hoL29IPzRjSAT dacWAn/iKqunW6OEhZjZEhQIw2j2qyYSAXnXNUOJ/dZrc268fhVyoYyB1pQ36yPB SZVkir9FT7ATJGNhY6M7aw55JSjbJGad/3ujdY6Yas179burt0p8/R6AD2HrVOCj eCTjvO0fGqW9Vw== X-ME-Sender: Received: from yuanhanliu-NB0.tencent.com (unknown [223.74.148.66]) by mail.messagingengine.com (Postfix) with ESMTPA id E1A7C10253; Sun, 22 Apr 2018 11:11:08 -0400 (EDT) From: Yuanhan Liu To: Fan Zhang Cc: Andrey Chilikin , Eelco Chaudron , Wenzhuo Lu , dpdk stable Date: Sun, 22 Apr 2018 23:09:14 +0800 Message-Id: <20180422150949.17523-24-yliu@fridaylinux.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180422150949.17523-1-yliu@fridaylinux.org> References: <20180422150949.17523-1-yliu@fridaylinux.org> Subject: [dpdk-stable] patch 'net/i40e: fix link update no wait' has been queued to LTS release 17.11.2 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Apr 2018 15:11:12 -0000 Hi, FYI, your patch has been queued to LTS release 17.11.2 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 04/29/18. So please shout if anyone has objections. Thanks. --yliu --- >>From a991f1979bfd0e6e528185a686699566aeb7d403 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 8 Mar 2018 12:17:52 +0000 Subject: [PATCH] net/i40e: fix link update no wait [ upstream commit eef2daf2e199d2a22eba0bdf9ee990c2a9efc101 ] In i40e_dev_link_update() the driver obtains the link status info via admin queue command despite of "no_wait" flag. This requires relatively long time and may be a problem to some application such as ovs-dpdk. (https://bugzilla.redhat.com/show_bug.cgi?id=1551761). This patch aims to fix the problem by using a different approach of obtaining link status for i40e NIC without waiting. Instead of getting the link status via admin queue command, this patch reads the link status registers to accelerate the procedure. Fixes: 263333bbb7a9 ("i40e: fix link status timeout") Signed-off-by: Fan Zhang Signed-off-by: Andrey Chilikin Reviewed-by: Eelco Chaudron Tested-by: Eelco Chaudron Acked-by: Wenzhuo Lu --- drivers/net/i40e/i40e_ethdev.c | 128 ++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 33 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 290ef2491..ef6470814 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -2444,77 +2444,139 @@ i40e_dev_set_link_down(struct rte_eth_dev *dev) return i40e_phy_conf_link(hw, abilities, speed, false); } -int -i40e_dev_link_update(struct rte_eth_dev *dev, - int wait_to_complete) +static __rte_always_inline void +update_link_no_wait(struct i40e_hw *hw, struct rte_eth_link *link) +{ +/* Link status registers and values*/ +#define I40E_PRTMAC_LINKSTA 0x001E2420 +#define I40E_REG_LINK_UP 0x40000080 +#define I40E_PRTMAC_MACC 0x001E24E0 +#define I40E_REG_MACC_25GB 0x00020000 +#define I40E_REG_SPEED_MASK 0x38000000 +#define I40E_REG_SPEED_100MB 0x00000000 +#define I40E_REG_SPEED_1GB 0x08000000 +#define I40E_REG_SPEED_10GB 0x10000000 +#define I40E_REG_SPEED_20GB 0x20000000 +#define I40E_REG_SPEED_25_40GB 0x18000000 + uint32_t link_speed; + uint32_t reg_val; + + reg_val = I40E_READ_REG(hw, I40E_PRTMAC_LINKSTA); + link_speed = reg_val & I40E_REG_SPEED_MASK; + reg_val &= I40E_REG_LINK_UP; + link->link_status = (reg_val == I40E_REG_LINK_UP) ? 1 : 0; + + if (unlikely(link->link_status != 0)) + return; + + /* Parse the link status */ + switch (link_speed) { + case I40E_REG_SPEED_100MB: + link->link_speed = ETH_SPEED_NUM_100M; + break; + case I40E_REG_SPEED_1GB: + link->link_speed = ETH_SPEED_NUM_1G; + break; + case I40E_REG_SPEED_10GB: + link->link_speed = ETH_SPEED_NUM_10G; + break; + case I40E_REG_SPEED_20GB: + link->link_speed = ETH_SPEED_NUM_20G; + break; + case I40E_REG_SPEED_25_40GB: + reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC); + + if (reg_val & I40E_REG_MACC_25GB) + link->link_speed = ETH_SPEED_NUM_25G; + else + link->link_speed = ETH_SPEED_NUM_40G; + + break; + default: + PMD_DRV_LOG(ERR, "Unknown link speed info %u", link_speed); + break; + } +} + +static __rte_always_inline void +update_link_wait(struct i40e_hw *hw, struct rte_eth_link *link, + bool enable_lse) { -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ - struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ + uint32_t rep_cnt = MAX_REPEAT_TIME; struct i40e_link_status link_status; - struct rte_eth_link link, old; int status; - unsigned rep_cnt = MAX_REPEAT_TIME; - bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false; - memset(&link, 0, sizeof(link)); - memset(&old, 0, sizeof(old)); memset(&link_status, 0, sizeof(link_status)); - rte_i40e_dev_atomic_read_link_status(dev, &old); do { /* Get link status information from hardware */ status = i40e_aq_get_link_info(hw, enable_lse, &link_status, NULL); - if (status != I40E_SUCCESS) { - link.link_speed = ETH_SPEED_NUM_100M; - link.link_duplex = ETH_LINK_FULL_DUPLEX; + if (unlikely(status != I40E_SUCCESS)) { + link->link_speed = ETH_SPEED_NUM_100M; + link->link_duplex = ETH_LINK_FULL_DUPLEX; PMD_DRV_LOG(ERR, "Failed to get link info"); - goto out; + return; } - link.link_status = link_status.link_info & I40E_AQ_LINK_UP; - if (!wait_to_complete || link.link_status) - break; + link->link_status = link_status.link_info & I40E_AQ_LINK_UP; + if (unlikely(link->link_status != 0)) + return; rte_delay_ms(CHECK_INTERVAL); } while (--rep_cnt); - if (!link.link_status) - goto out; - - /* i40e uses full duplex only */ - link.link_duplex = ETH_LINK_FULL_DUPLEX; - /* Parse the link status */ switch (link_status.link_speed) { case I40E_LINK_SPEED_100MB: - link.link_speed = ETH_SPEED_NUM_100M; + link->link_speed = ETH_SPEED_NUM_100M; break; case I40E_LINK_SPEED_1GB: - link.link_speed = ETH_SPEED_NUM_1G; + link->link_speed = ETH_SPEED_NUM_1G; break; case I40E_LINK_SPEED_10GB: - link.link_speed = ETH_SPEED_NUM_10G; + link->link_speed = ETH_SPEED_NUM_10G; break; case I40E_LINK_SPEED_20GB: - link.link_speed = ETH_SPEED_NUM_20G; + link->link_speed = ETH_SPEED_NUM_20G; break; case I40E_LINK_SPEED_25GB: - link.link_speed = ETH_SPEED_NUM_25G; + link->link_speed = ETH_SPEED_NUM_25G; break; case I40E_LINK_SPEED_40GB: - link.link_speed = ETH_SPEED_NUM_40G; + link->link_speed = ETH_SPEED_NUM_40G; break; default: - link.link_speed = ETH_SPEED_NUM_100M; + link->link_speed = ETH_SPEED_NUM_100M; break; } +} + +int +i40e_dev_link_update(struct rte_eth_dev *dev, + int wait_to_complete) +{ + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_eth_link link, old; + bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false; + memset(&link, 0, sizeof(link)); + memset(&old, 0, sizeof(old)); + + rte_i40e_dev_atomic_read_link_status(dev, &old); + + /* i40e uses full duplex only */ + link.link_duplex = ETH_LINK_FULL_DUPLEX; link.link_autoneg = !(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED); -out: + if (!wait_to_complete) + update_link_no_wait(hw, &link); + else + update_link_wait(hw, &link, enable_lse); + rte_i40e_dev_atomic_write_link_status(dev, &link); if (link.link_status == old.link_status) return -1; -- 2.11.0