From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f196.google.com (mail-wr0-f196.google.com [209.85.128.196]) by dpdk.org (Postfix) with ESMTP id 8D53628F3 for ; Tue, 1 May 2018 12:46:57 +0200 (CEST) Received: by mail-wr0-f196.google.com with SMTP id o4-v6so10478954wrm.0 for ; Tue, 01 May 2018 03:46:57 -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=3/nvlbtQsP4pu+II+nhWtgJ4d0P8uqc3fiW3+87C+IU=; b=BJu0yYI0wCtxThK7Gcgc+g1ZF25+LE0xJobESNTCU3FZCrNZKdpBT1CrP5c0kvj1nS rEtNO5HKj/G6L+sQIgILOTJel/RRRDWbi6mYCUb/W2P4siOSYfa2xj57yxTwNnKWlueM +mVnqtdjpG9DosLLV1AyPv9xND5uQjrBhPiKS2yzy5xpLNfHf06gtxL9mbfG4krTt8Rl a1YhMmdzooJiulcjoA7DDsT8FnqxfU6n7ZUBmTvQYhBSSaQOPzvKKmSvDMnaKJrjWlhS zo3+qDk4SuCHHNF2q+yHfGOJ6xSxXSMRNgGSd/TfGFWEsYmA6lFN/CJ8AtCd8mcfyzJQ 4V2g== 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=3/nvlbtQsP4pu+II+nhWtgJ4d0P8uqc3fiW3+87C+IU=; b=Evohz6j+tzmd2Ui2u4PtSxEw+LNk4tych7uCnuDR0/6FZYTmKWLLNwsgNvvQoUtOr0 JrhC2R8vmwwQgn6orBhsWsHZ8YotYbV0hHe4Pj87c3o4XbIP34I63aaRCV/Y3BGktLFG C9a/4QUx9PiGXUnMLoo7xu5avVO859YUzX8MgHpdVc7v7mgFyYUopL25Pw6fbkqA/sUe vefymbK8L30q93TDhLEmX2h3ifL0M0Hj+cqsP6Yj2GgvWVcKZVv4labFhLL8TiaE12ky n3X4Mh5y5xhaKBc928Tn/65yis+xtOAaKV3K/+vlMTihE0l3qK0vU/z2Kdi8DK4KIBxy Cs2g== X-Gm-Message-State: ALQs6tDXo4CFPEGDK3NrCLYm9kd8c4+fUyWeBqn4Ue8XN5o4dZVOSW12 ogqiFxTjuQ+0MuJrhsxHe3s= X-Google-Smtp-Source: AB8JxZqmI3KMB/mqMdueqx5KGVpHkHhOvkI+pkErWxUu5MA5NaKZNxRKXPdr57w/NKmLjxRfVqk9vQ== X-Received: by 2002:adf:a194:: with SMTP id u20-v6mr8476855wru.262.1525171617199; Tue, 01 May 2018 03:46:57 -0700 (PDT) Received: from localhost (slip139-92-244-193.lon.uk.prserv.net. [139.92.244.193]) by smtp.gmail.com with ESMTPSA id u20-v6sm14559108wru.33.2018.05.01.03.46.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 01 May 2018 03:46:56 -0700 (PDT) From: luca.boccassi@gmail.com To: Fan Zhang Cc: Andrey Chilikin , Eelco Chaudron , Wenzhuo Lu , dpdk stable Date: Tue, 1 May 2018 11:44:38 +0100 Message-Id: <20180501104509.17238-15-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20180501104509.17238-1-luca.boccassi@gmail.com> References: <20180501104509.17238-1-luca.boccassi@gmail.com> Subject: [dpdk-stable] patch 'net/i40e: fix link update no wait' has been queued to LTS release 16.11.7 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: Tue, 01 May 2018 10:46:57 -0000 Hi, FYI, your patch has been queued to LTS release 16.11.7 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/03/18. So please shout if anyone has objections. Thanks. Luca Boccassi --- >>From 1ee4643d14144dae2bf12de30dbade1250b527a4 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 0b270b690..696bb6595 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -2117,77 +2117,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 inline void __attribute__((always_inline)) +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 inline void __attribute__((always_inline)) +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