From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f195.google.com (mail-wr0-f195.google.com [209.85.128.195]) by dpdk.org (Postfix) with ESMTP id 5EEF21DB9 for ; Mon, 30 Apr 2018 16:07:53 +0200 (CEST) Received: by mail-wr0-f195.google.com with SMTP id 94-v6so6853720wrf.5 for ; Mon, 30 Apr 2018 07:07:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=U1PTNv4oTVgTdZSzE3WzBivgpW1OP6b/9WY5bK9COqc=; b=TbPatS6jC2YsoWfLygpVUoOiggERp1UKW3nWm1QvejBf8SKk6/j7LEZCEEjnyHFQT7 sFcN5joqkzCQ7UQGB0ctqjCgHUIR0uxWPwLWUHWyY++OHjSp5aoOhauc6SJ0XZLg+9ap xK9RHPBnIyW4DDDL7xpJqjz/FXX81xBMFExfrhHIQpjWSnIHjgCtVmtgjxIgvbUjW6oL If6vBO7TRfiVBEU6aKM3M7PkNrpO3RyfLDvq4IQ7fgM4Gemj+pO8lrumSMIPcfTU7V/0 VjYhXlPM3Bv/ERAYf3L5TgYBZoYsfXgO9QsPcKnM2yVxgvAvLnGkyvlSU+juXaOldm6Y 8rmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=U1PTNv4oTVgTdZSzE3WzBivgpW1OP6b/9WY5bK9COqc=; b=uYxAR/pQcrvH3HVZ7A8ZGGpJz27RiBgdtvL7qdvIkl204IA5WBrtoQh/JS1Vi+FvF7 Vh04/7+UIh0aPE0DeFFnL1GRzu66G2U0T+wnvQseemavWadMDVVZmS0AehDfTKeIef1P CY3EG11aekH3xsDXYdkWNr8nW6WZmwXPzGRuC58YBF9HxL3QB4lMLh7A4jG6wI+8QXrQ gjh0O1YVUzAe+NnuAH1Gg6eqZm9c4bTF1628mmbskbrfPuLDHRdneDK7sG/Mp9jMOYX2 yzBC+NN+5Psqg8VWNU7KdXDY+vy1gkqGW8wpnqMUCRC68Nu3ESsmbT6YJ2c2nfyZq4yV JDxA== X-Gm-Message-State: ALQs6tCgYouW+SHwFQHYve507U8G/iiZ97lrQ07OdKUu5UXQ88aBP+uo BYr0iWtuKFGjQ7mgiKhSiS0= X-Google-Smtp-Source: AB8JxZrpW1OdYmMnN08Qovd4yUQB5rPzBIlbTHQL4QtDnZRS4+dWCHU2L+X01RojVegKU24mH426Xw== X-Received: by 2002:adf:90cd:: with SMTP id i71-v6mr4260895wri.136.1525097273090; Mon, 30 Apr 2018 07:07:53 -0700 (PDT) Received: from localhost ([2a00:23c5:be9a:5200:ce4c:82c0:d567:ecbb]) by smtp.gmail.com with ESMTPSA id h124sm17504375wma.35.2018.04.30.07.07.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 30 Apr 2018 07:07:52 -0700 (PDT) From: luca.boccassi@gmail.com To: Fan Zhang Cc: Andrey Chilikin , Eelco Chaudron , Wenzhuo Lu , dpdk stable Date: Mon, 30 Apr 2018 15:03:34 +0100 Message-Id: <20180430140606.4615-56-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20180430140606.4615-1-luca.boccassi@gmail.com> References: <20180430140606.4615-1-luca.boccassi@gmail.com> Subject: [dpdk-stable] patch 'net/i40e: fix link update no wait' has been queued to stable release 18.02.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: Mon, 30 Apr 2018 14:07:53 -0000 Hi, FYI, your patch has been queued to stable release 18.02.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 05/02/18. So please shout if anyone has objections. Thanks. Luca Boccassi --- >>From b4e1a9b51c5dc2b209ec634dd56b43e7f123dac7 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 508b4171c..968249ed1 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -2437,77 +2437,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) { -#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); +/* 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 */ + 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.14.2