X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_ethdev.c;h=7048f843ef3e9e1c3dade032cceae73fe27cde3d;hb=60e6f4707ef2291238471bde8378c43cc95810f5;hp=9abcfc9a9a196d8f6a44f8952610b26d1a6c39ef;hpb=45e4acd476644872d69a8d2f469712912c174957;p=dpdk.git diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 9abcfc9a9a..7048f843ef 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1063,14 +1063,13 @@ virtio_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) } static int -virtio_negotiate_features(struct virtio_hw *hw) +virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features) { uint64_t host_features; /* Prepare guest_features: feature that driver wants to support */ - hw->guest_features = VIRTIO_PMD_GUEST_FEATURES; PMD_INIT_LOG(DEBUG, "guest_features before negotiate = %" PRIx64, - hw->guest_features); + req_features); /* Read device(host) feature bits */ host_features = hw->vtpci_ops->get_features(hw); @@ -1081,6 +1080,7 @@ virtio_negotiate_features(struct virtio_hw *hw) * Negotiate features: Subset of device feature bits are written back * guest feature bits. */ + hw->guest_features = req_features; hw->guest_features = vtpci_negotiate_features(hw, host_features); PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64, hw->guest_features); @@ -1099,6 +1099,8 @@ virtio_negotiate_features(struct virtio_hw *hw) } } + hw->req_guest_features = req_features; + return 0; } @@ -1139,8 +1141,9 @@ rx_func_get(struct rte_eth_dev *eth_dev) eth_dev->rx_pkt_burst = &virtio_recv_pkts; } +/* reset device and renegotiate features if needed */ static int -virtio_init_device(struct rte_eth_dev *eth_dev) +virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features) { struct virtio_hw *hw = eth_dev->data->dev_private; struct virtio_net_config *config; @@ -1155,7 +1158,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev) /* Tell the host we've known how to drive the device. */ vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); - if (virtio_negotiate_features(hw) < 0) + if (virtio_negotiate_features(hw, req_features) < 0) return -1; /* If host does not support status then disable LSC */ @@ -1276,8 +1279,8 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev) eth_dev->data->dev_flags = dev_flags; - /* reset device and negotiate features */ - ret = virtio_init_device(eth_dev); + /* reset device and negotiate default features */ + ret = virtio_init_device(eth_dev, VIRTIO_PMD_GUEST_FEATURES); if (ret < 0) return ret; @@ -1359,6 +1362,7 @@ virtio_dev_configure(struct rte_eth_dev *dev) { const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; struct virtio_hw *hw = dev->data->dev_private; + uint64_t req_features; int ret; PMD_INIT_LOG(DEBUG, "configure"); @@ -1368,6 +1372,14 @@ virtio_dev_configure(struct rte_eth_dev *dev) return -EINVAL; } + req_features = VIRTIO_PMD_GUEST_FEATURES; + /* if request features changed, reinit the device */ + if (req_features != hw->req_guest_features) { + ret = virtio_init_device(dev, req_features); + if (ret < 0) + return ret; + } + /* Setup and start control queue */ if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) { ret = virtio_dev_cq_queue_setup(dev,