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)
{
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",
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);