Add the ability to reset the virtio device in the configure callback
if the features flag changed since previous reset. This will be possible
with the introduction of offload support in next commits.
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
-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 */
{
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,
PMD_INIT_LOG(DEBUG, "guest_features before negotiate = %" PRIx64,
/* Read device(host) feature bits */
host_features = hw->vtpci_ops->get_features(hw);
/* Read device(host) feature bits */
host_features = hw->vtpci_ops->get_features(hw);
* Negotiate features: Subset of device feature bits are written back
* guest feature bits.
*/
* 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);
hw->guest_features = vtpci_negotiate_features(hw, host_features);
PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
hw->guest_features);
+ hw->req_guest_features = req_features;
+
eth_dev->rx_pkt_burst = &virtio_recv_pkts;
}
eth_dev->rx_pkt_burst = &virtio_recv_pkts;
}
+/* reset device and renegotiate features if needed */
-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;
{
struct virtio_hw *hw = eth_dev->data->dev_private;
struct virtio_net_config *config;
/* Tell the host we've known how to drive the device. */
vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
/* 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 */
return -1;
/* If host does not support status then disable LSC */
eth_dev->data->dev_flags = dev_flags;
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);
{
const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
struct virtio_hw *hw = dev->data->dev_private;
{
const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
struct virtio_hw *hw = dev->data->dev_private;
int ret;
PMD_INIT_LOG(DEBUG, "configure");
int ret;
PMD_INIT_LOG(DEBUG, "configure");
+ 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,
/* Setup and start control queue */
if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
ret = virtio_dev_cq_queue_setup(dev,
struct virtio_hw {
struct virtnet_ctl *cvq;
struct rte_pci_ioport io;
struct virtio_hw {
struct virtnet_ctl *cvq;
struct rte_pci_ioport io;
+ uint64_t req_guest_features;
uint64_t guest_features;
uint32_t max_queue_pairs;
uint16_t vtnet_hdr_size;
uint64_t guest_features;
uint32_t max_queue_pairs;
uint16_t vtnet_hdr_size;