net/txgbe: fix queue statistics mapping
[dpdk.git] / drivers / net / virtio / virtio_ethdev.c
index 4570bec..d180162 100644 (file)
@@ -1843,6 +1843,31 @@ 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);
+}
+
 static uint64_t
 ethdev_to_virtio_rss_offloads(uint64_t ethdev_hash_types)
 {
@@ -2003,7 +2028,8 @@ virtio_dev_rss_hash_update(struct rte_eth_dev *dev,
 
        return 0;
 restore_key:
-       memcpy(hw->rss_key, old_rss_key, VIRTIO_NET_RSS_KEY_SIZE);
+       if (rss_conf->rss_key && rss_conf->rss_key_len)
+               memcpy(hw->rss_key, old_rss_key, VIRTIO_NET_RSS_KEY_SIZE);
 restore_types:
        hw->rss_hash_types = old_hash_types;
 
@@ -2225,19 +2251,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 == RTE_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 == RTE_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 = RTE_ETH_LINK_FULL_DUPLEX;
        PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d",
@@ -2641,7 +2658,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
        hw->has_rx_offload = rx_offload_enabled(hw);
 
        if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-               /* Enable vector (0) for Link State Intrerrupt */
+               /* Enable vector (0) for Link State Interrupt */
                if (VIRTIO_OPS(hw)->set_config_irq(hw, 0) ==
                                VIRTIO_MSI_NO_VECTOR) {
                        PMD_DRV_LOG(ERR, "failed to set config vector");
@@ -2759,7 +2776,7 @@ virtio_dev_start(struct rte_eth_dev *dev)
                }
        }
 
-       /* Enable uio/vfio intr/eventfd mapping: althrough we already did that
+       /* Enable uio/vfio intr/eventfd mapping: although we already did that
         * in device configure, but it could be unmapped  when device is
         * stopped.
         */
@@ -2964,11 +2981,15 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
                                     dev->data->port_id);
                } else {
                        link.link_status = RTE_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 = RTE_ETH_LINK_UP;
+               if (hw->get_speed_via_feat)
+                       virtio_get_speed_duplex(dev, &link);
        }
 
        return rte_eth_linkstatus_set(dev, &link);