}
if (vq == NULL) {
PMD_INIT_LOG(ERR, "%s: Can not allocate virtqueue", __func__);
- return (-ENOMEM);
+ return -ENOMEM;
}
if (queue_type == VTNET_RQ && vq->sw_ring == NULL) {
PMD_INIT_LOG(ERR, "%s: Can not allocate RX soft ring",
return virtio_send_command(hw->cvq, &ctrl, &len, 1);
}
-static void
+static int
virtio_negotiate_features(struct virtio_hw *hw)
{
- uint32_t host_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 = %x",
+ PMD_INIT_LOG(DEBUG, "guest_features before negotiate = %" PRIx64,
hw->guest_features);
/* Read device(host) feature bits */
host_features = hw->vtpci_ops->get_features(hw);
- PMD_INIT_LOG(DEBUG, "host_features before negotiate = %x",
+ PMD_INIT_LOG(DEBUG, "host_features before negotiate = %" PRIx64,
host_features);
/*
* guest feature bits.
*/
hw->guest_features = vtpci_negotiate_features(hw, host_features);
- PMD_INIT_LOG(DEBUG, "features after negotiate = %x",
+ PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
hw->guest_features);
+
+ if (hw->modern) {
+ if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+ PMD_INIT_LOG(ERR,
+ "VIRTIO_F_VERSION_1 features is not enabled.");
+ return -1;
+ }
+ vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+ if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
+ PMD_INIT_LOG(ERR,
+ "failed to set FEATURES_OK status!");
+ return -1;
+ }
+ }
+
+ return 0;
}
/*
struct virtio_net_config *config;
struct virtio_net_config local_config;
struct rte_pci_device *pci_dev;
+ int ret;
RTE_BUILD_BUG_ON(RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr));
pci_dev = eth_dev->pci_dev;
- if (vtpci_init(pci_dev, hw) < 0)
- return -1;
+ ret = vtpci_init(pci_dev, hw);
+ if (ret)
+ return ret;
/* Reset the device although not necessary at startup */
vtpci_reset(hw);
/* Tell the host we've known how to drive the device. */
vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
- virtio_negotiate_features(hw);
+ if (virtio_negotiate_features(hw) < 0)
+ return -1;
/* If host does not support status then disable LSC */
if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS))
rx_func_get(eth_dev);
/* Setting up rx_header size for the device */
- if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
+ if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
+ vtpci_with_feature(hw, VIRTIO_F_VERSION_1))
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
else
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
rte_intr_callback_unregister(&pci_dev->intr_handle,
virtio_interrupt_handler,
eth_dev);
+ rte_eal_pci_unmap_device(pci_dev);
PMD_INIT_LOG(DEBUG, "dev_uninit completed");
if (rxmode->hw_ip_checksum) {
PMD_DRV_LOG(ERR, "HW IP checksum not supported");
- return (-EINVAL);
+ return -EINVAL;
}
hw->vlan_strip = rxmode->hw_vlan_strip;