From patchwork Fri Oct 22 13:17:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 102668 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 81A23A0C43; Fri, 22 Oct 2021 15:18:10 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F0A9A4114A; Fri, 22 Oct 2021 15:18:09 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 9325441149; Fri, 22 Oct 2021 15:18:09 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 2A1347F6FA; Fri, 22 Oct 2021 16:18:09 +0300 (MSK) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on shelob.oktetlabs.ru X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=ALL_TRUSTED, DKIM_ADSP_DISCARD, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from aros.oktetlabs.ru (aros.oktetlabs.ru [192.168.38.17]) by shelob.oktetlabs.ru (Postfix) with ESMTP id A36E47F5B3; Fri, 22 Oct 2021 16:18:04 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru A36E47F5B3 Authentication-Results: shelob.oktetlabs.ru/A36E47F5B3; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: Maxime Coquelin , Chenbo Xia , Ivan Dyukov Cc: dev@dpdk.org, Ivan Ilchenko , stable@dpdk.org Date: Fri, 22 Oct 2021 16:17:54 +0300 Message-Id: <20211022131755.932304-1-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] net/virtio: fix link update in speed feature case X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Ivan Ilchenko Link update callback reports speed/duplex based on data filled on device initialization. This is wrong in case of VIRTIO_NET_F_SPEED_DUPLEX is negotiated since link could be down at this time. Fix this function to actually update the HW data in this case with respect to the fact that specifying speed via devarg is a highest priority. Fixes: 1357b4b36246 ("net/virtio: support Virtio link speed feature") Cc: stable@dpdk.org Signed-off-by: Ivan Ilchenko Signed-off-by: Andrew Rybchenko Reviewed-by: Maxime Coquelin --- drivers/net/virtio/virtio.h | 5 ++++ drivers/net/virtio/virtio_ethdev.c | 47 +++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h index e78b2e429e..4fd1427375 100644 --- a/drivers/net/virtio/virtio.h +++ b/drivers/net/virtio/virtio.h @@ -178,6 +178,11 @@ struct virtio_hw { uint16_t port_id; uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; uint32_t speed; /* link speed in MB */ + /* + * Speed is specified via 'speed' devarg or + * negotiated via VIRTIO_NET_F_SPEED_DUPLEX + */ + bool get_speed_via_feat; uint8_t duplex; uint8_t intr_lsc; uint16_t max_mtu; diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 4001368bc4..3d80f664b3 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1777,6 +1777,32 @@ virtio_configure_intr(struct rte_eth_dev *dev) return 0; } + +static void +virtio_get_speed_duplex(struct rte_eth_dev *eth_dev, + struct rte_eth_link *link) +{ + struct virtio_hw *hw = eth_dev->data->dev_private; + struct virtio_net_config *config; + struct virtio_net_config local_config; + + config = &local_config; + virtio_read_dev_config(hw, + offsetof(struct virtio_net_config, speed), + &config->speed, sizeof(config->speed)); + virtio_read_dev_config(hw, + offsetof(struct virtio_net_config, duplex), + &config->duplex, sizeof(config->duplex)); + hw->speed = config->speed; + hw->duplex = config->duplex; + if (link != NULL) { + link->link_duplex = hw->duplex; + link->link_speed = hw->speed; + } + PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d", + hw->speed, hw->duplex); +} + #define DUPLEX_UNKNOWN 0xff /* reset device and renegotiate features if needed */ static int @@ -1830,19 +1856,10 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features) hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2], hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]); - if (hw->speed == ETH_SPEED_NUM_UNKNOWN) { - if (virtio_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) { - config = &local_config; - virtio_read_dev_config(hw, - offsetof(struct virtio_net_config, speed), - &config->speed, sizeof(config->speed)); - virtio_read_dev_config(hw, - offsetof(struct virtio_net_config, duplex), - &config->duplex, sizeof(config->duplex)); - hw->speed = config->speed; - hw->duplex = config->duplex; - } - } + hw->get_speed_via_feat = hw->speed == ETH_SPEED_NUM_UNKNOWN && + virtio_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX); + if (hw->get_speed_via_feat) + virtio_get_speed_duplex(eth_dev, NULL); if (hw->duplex == DUPLEX_UNKNOWN) hw->duplex = ETH_LINK_FULL_DUPLEX; PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d", @@ -2554,11 +2571,15 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet dev->data->port_id); } else { link.link_status = ETH_LINK_UP; + if (hw->get_speed_via_feat) + virtio_get_speed_duplex(dev, &link); PMD_INIT_LOG(DEBUG, "Port %d is up", dev->data->port_id); } } else { link.link_status = ETH_LINK_UP; + if (hw->get_speed_via_feat) + virtio_get_speed_duplex(dev, &link); } return rte_eth_linkstatus_set(dev, &link);