X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_user_ethdev.c;h=add97746f2fd1165583f4f280e9724cca3c153e7;hb=6a504290a7838a40223f8da3ab8144ff8f78c731;hp=40345193e6d3a7d5360f2f37011fe8b606485334;hpb=47235f16505f8f4c0de689a94c66169a2b944e37;p=dpdk.git diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 40345193e6..add97746f2 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -13,26 +13,26 @@ #include #include -#include +#include #include #include #include #include "virtio_ethdev.h" #include "virtio_logs.h" -#include "virtio_pci.h" +#include "virtio.h" #include "virtqueue.h" #include "virtio_rxtx.h" #include "virtio_user/virtio_user_dev.h" #include "virtio_user/vhost.h" -#define virtio_user_get_dev(hw) \ - ((struct virtio_user_dev *)(hw)->virtio_user_dev) +#define virtio_user_get_dev(hwp) container_of(hwp, struct virtio_user_dev, hw) static void -virtio_user_reset_queues_packed(struct rte_eth_dev *dev) +virtio_user_reset_queues_packed(struct rte_eth_dev *eth_dev) { - struct virtio_hw *hw = dev->data->dev_private; + struct virtio_user_dev *dev = eth_dev->data->dev_private; + struct virtio_hw *hw = &dev->hw; struct virtnet_rx *rxvq; struct virtnet_tx *txvq; uint16_t i; @@ -48,14 +48,14 @@ virtio_user_reset_queues_packed(struct rte_eth_dev *dev) rte_delay_ms(1); /* Vring reset for each Tx queue and Rx queue. */ - for (i = 0; i < dev->data->nb_rx_queues; i++) { - rxvq = dev->data->rx_queues[i]; + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxvq = eth_dev->data->rx_queues[i]; virtqueue_rxvq_reset_packed(rxvq->vq); - virtio_dev_rx_queue_setup_finish(dev, i); + virtio_dev_rx_queue_setup_finish(eth_dev, i); } - for (i = 0; i < dev->data->nb_tx_queues; i++) { - txvq = dev->data->tx_queues[i]; + for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { + txvq = eth_dev->data->tx_queues[i]; virtqueue_txvq_reset_packed(txvq->vq); } @@ -69,7 +69,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) { int ret, connectfd, old_status; struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id]; - struct virtio_hw *hw = eth_dev->data->dev_private; + struct virtio_hw *hw = &dev->hw; uint64_t protocol_features; connectfd = accept(dev->listenfd, NULL, NULL); @@ -77,13 +77,13 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) return -1; dev->vhostfd = connectfd; - old_status = vtpci_get_status(hw); + old_status = dev->status; - vtpci_reset(hw); + virtio_reset(hw); - vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK); + virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK); - vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); + virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES, &dev->device_features) < 0) { @@ -122,17 +122,17 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) dev->features &= dev->device_features; /* For packed ring, resetting queues is required in reconnection. */ - if (vtpci_packed_queue(hw) && + if (virtio_with_packed_queue(hw) && (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) { PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped" " when packed ring reconnecting."); virtio_user_reset_queues_packed(eth_dev); } - vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK); + virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK); /* Start the device */ - vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK); + virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK); if (!dev->started) return -1; @@ -327,13 +327,19 @@ virtio_user_set_features(struct virtio_hw *hw, uint64_t features) dev->features = features & dev->device_features; } +static int +virtio_user_features_ok(struct virtio_hw *hw __rte_unused) +{ + return 0; +} + static uint8_t virtio_user_get_isr(struct virtio_hw *hw __rte_unused) { /* rxq interrupts and config interrupt are separated in virtio-user, * here we only report config change. */ - return VIRTIO_PCI_ISR_CONFIG; + return VIRTIO_ISR_CONFIG; } static uint16_t @@ -417,7 +423,7 @@ virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq) { struct virtio_user_dev *dev = virtio_user_get_dev(hw); - if (vtpci_packed_queue(hw)) + if (virtio_with_packed_queue(hw)) virtio_user_setup_queue_packed(vq, dev); else virtio_user_setup_queue_split(vq, dev); @@ -450,7 +456,7 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq) struct virtio_user_dev *dev = virtio_user_get_dev(hw); if (hw->cvq && (hw->cvq->vq == vq)) { - if (vtpci_packed_queue(vq->hw)) + if (virtio_with_packed_queue(vq->hw)) virtio_user_handle_cq_packed(dev, vq->vq_queue_index); else virtio_user_handle_cq(dev, vq->vq_queue_index); @@ -462,13 +468,24 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq) strerror(errno)); } -const struct virtio_pci_ops virtio_user_ops = { +static int +virtio_user_dev_close(struct virtio_hw *hw) +{ + struct virtio_user_dev *dev = virtio_user_get_dev(hw); + + virtio_user_dev_uninit(dev); + + return 0; +} + +const struct virtio_ops virtio_user_ops = { .read_dev_cfg = virtio_user_read_dev_config, .write_dev_cfg = virtio_user_write_dev_config, .get_status = virtio_user_get_status, .set_status = virtio_user_set_status, .get_features = virtio_user_get_features, .set_features = virtio_user_set_features, + .features_ok = virtio_user_features_ok, .get_isr = virtio_user_get_isr, .set_config_irq = virtio_user_set_config_irq, .set_queue_irq = virtio_user_set_queue_irq, @@ -476,6 +493,7 @@ const struct virtio_pci_ops virtio_user_ops = { .setup_queue = virtio_user_setup_queue, .del_queue = virtio_user_del_queue, .notify_queue = virtio_user_notify_queue, + .dev_close = virtio_user_dev_close, }; static const char *valid_args[] = { @@ -605,46 +623,32 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev) struct virtio_hw *hw; struct virtio_user_dev *dev; - eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*hw)); + eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*dev)); if (!eth_dev) { PMD_INIT_LOG(ERR, "cannot alloc rte_eth_dev"); return NULL; } data = eth_dev->data; - hw = eth_dev->data->dev_private; - - dev = rte_zmalloc(NULL, sizeof(*dev), 0); - if (!dev) { - PMD_INIT_LOG(ERR, "malloc virtio_user_dev failed"); - rte_eth_dev_release_port(eth_dev); - return NULL; - } + dev = eth_dev->data->dev_private; + hw = &dev->hw; hw->port_id = data->port_id; dev->port_id = data->port_id; - virtio_hw_internal[hw->port_id].vtpci_ops = &virtio_user_ops; - /* - * MSIX is required to enable LSC (see virtio_init_device). - * Here just pretend that we support msix. - */ - hw->use_msix = 1; - hw->modern = 0; + VIRTIO_OPS(hw) = &virtio_user_ops; + + hw->intr_lsc = 1; hw->use_vec_rx = 0; hw->use_vec_tx = 0; hw->use_inorder_rx = 0; hw->use_inorder_tx = 0; - hw->virtio_user_dev = dev; + return eth_dev; } static void virtio_user_eth_dev_free(struct rte_eth_dev *eth_dev) { - struct rte_eth_dev_data *data = eth_dev->data; - struct virtio_hw *hw = data->dev_private; - - rte_free(hw->virtio_user_dev); rte_eth_dev_release_port(eth_dev); } @@ -653,11 +657,12 @@ virtio_user_eth_dev_free(struct rte_eth_dev *eth_dev) * Returns 0 on success. */ static int -virtio_user_pmd_probe(struct rte_vdev_device *dev) +virtio_user_pmd_probe(struct rte_vdev_device *vdev) { struct rte_kvargs *kvlist = NULL; struct rte_eth_dev *eth_dev; struct virtio_hw *hw; + struct virtio_user_dev *dev; enum virtio_user_backend_type backend_type = VIRTIO_USER_BACKEND_UNKNOWN; uint64_t queues = VIRTIO_USER_DEF_Q_NUM; uint64_t cq = VIRTIO_USER_DEF_CQ_EN; @@ -672,14 +677,20 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) char *mac_addr = NULL; int ret = -1; + RTE_BUILD_BUG_ON(offsetof(struct virtio_user_dev, hw) != 0); + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { - const char *name = rte_vdev_device_name(dev); + const char *name = rte_vdev_device_name(vdev); eth_dev = rte_eth_dev_attach_secondary(name); if (!eth_dev) { PMD_INIT_LOG(ERR, "Failed to probe %s", name); return -1; } + dev = eth_dev->data->dev_private; + hw = &dev->hw; + VIRTIO_OPS(hw) = &virtio_user_ops; + if (eth_virtio_dev_init(eth_dev) < 0) { PMD_INIT_LOG(ERR, "eth_virtio_dev_init fails"); rte_eth_dev_release_port(eth_dev); @@ -687,12 +698,12 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) } eth_dev->dev_ops = &virtio_user_secondary_eth_dev_ops; - eth_dev->device = &dev->device; + eth_dev->device = &vdev->device; rte_eth_dev_probing_finish(eth_dev); return 0; } - kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_args); + kvlist = rte_kvargs_parse(rte_vdev_device_args(vdev), valid_args); if (!kvlist) { PMD_INIT_LOG(ERR, "error when parsing param"); goto end; @@ -832,14 +843,15 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) } } - eth_dev = virtio_user_eth_dev_alloc(dev); + eth_dev = virtio_user_eth_dev_alloc(vdev); if (!eth_dev) { PMD_INIT_LOG(ERR, "virtio_user fails to alloc device"); goto end; } - hw = eth_dev->data->dev_private; - if (virtio_user_dev_init(hw->virtio_user_dev, path, queues, cq, + dev = eth_dev->data->dev_private; + hw = &dev->hw; + if (virtio_user_dev_init(dev, path, queues, cq, queue_size, mac_addr, &ifname, server_mode, mrg_rxbuf, in_order, packed_vq, backend_type) < 0) { PMD_INIT_LOG(ERR, "virtio_user_dev_init fails"); @@ -856,7 +868,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) if (vectorized) { if (packed_vq) { -#if defined(CC_AVX512_SUPPORT) +#if defined(CC_AVX512_SUPPORT) || defined(RTE_ARCH_ARM) hw->use_vec_rx = 1; hw->use_vec_tx = 1; #else @@ -912,7 +924,6 @@ static int virtio_user_pmd_dma_map(struct rte_vdev_device *vdev, void *addr, const char *name; struct rte_eth_dev *eth_dev; struct virtio_user_dev *dev; - struct virtio_hw *hw; if (!vdev) return -EINVAL; @@ -923,8 +934,7 @@ static int virtio_user_pmd_dma_map(struct rte_vdev_device *vdev, void *addr, if (!eth_dev) return 0; - hw = (struct virtio_hw *)eth_dev->data->dev_private; - dev = hw->virtio_user_dev; + dev = eth_dev->data->dev_private; if (dev->ops->dma_map) return dev->ops->dma_map(dev, addr, iova, len); @@ -938,7 +948,6 @@ static int virtio_user_pmd_dma_unmap(struct rte_vdev_device *vdev, void *addr, const char *name; struct rte_eth_dev *eth_dev; struct virtio_user_dev *dev; - struct virtio_hw *hw; if (!vdev) return -EINVAL; @@ -949,8 +958,7 @@ static int virtio_user_pmd_dma_unmap(struct rte_vdev_device *vdev, void *addr, if (!eth_dev) return 0; - hw = (struct virtio_hw *)eth_dev->data->dev_private; - dev = hw->virtio_user_dev; + dev = eth_dev->data->dev_private; if (dev->ops->dma_unmap) return dev->ops->dma_unmap(dev, addr, iova, len); @@ -963,6 +971,7 @@ static struct rte_vdev_driver virtio_user_driver = { .remove = virtio_user_pmd_remove, .dma_map = virtio_user_pmd_dma_map, .dma_unmap = virtio_user_pmd_dma_unmap, + .drv_flags = RTE_VDEV_DRV_NEED_IOVA_AS_VA, }; RTE_PMD_REGISTER_VDEV(net_virtio_user, virtio_user_driver);