net/virtio-user: fix net status report
[dpdk.git] / drivers / net / virtio / virtio_user / virtio_user_dev.c
index b0070d5..c9e8ac5 100644 (file)
@@ -139,6 +139,7 @@ virtio_user_start_device(struct virtio_user_dev *dev)
        features &= ~(1ull << VIRTIO_NET_F_MAC);
        /* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know */
        features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
+       features &= ~(1ull << VIRTIO_NET_F_STATUS);
        ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
        if (ret < 0)
                goto error;
@@ -250,6 +251,30 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev)
        return 0;
 }
 
+static int
+virtio_user_fill_intr_handle(struct virtio_user_dev *dev)
+{
+       uint32_t i;
+       struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
+
+       if (!eth_dev->intr_handle) {
+               eth_dev->intr_handle = malloc(sizeof(*eth_dev->intr_handle));
+               if (!eth_dev->intr_handle) {
+                       PMD_DRV_LOG(ERR, "fail to allocate intr_handle");
+                       return -1;
+               }
+               memset(eth_dev->intr_handle, 0, sizeof(*eth_dev->intr_handle));
+       }
+
+       for (i = 0; i < dev->max_queue_pairs; ++i)
+               eth_dev->intr_handle->efds[i] = dev->callfds[i];
+       eth_dev->intr_handle->nb_efd = dev->max_queue_pairs;
+       eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1;
+       eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV;
+
+       return 0;
+}
+
 static int
 virtio_user_dev_setup(struct virtio_user_dev *dev)
 {
@@ -262,6 +287,9 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
        if (virtio_user_dev_init_notify(dev) < 0)
                return -1;
 
+       if (virtio_user_fill_intr_handle(dev) < 0)
+               return -1;
+
        if (is_vhost_user_by_type(dev->path)) {
                dev->ops = &ops_user;
        } else {
@@ -283,6 +311,25 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
        return dev->ops->setup(dev);
 }
 
+/* Use below macro to filter features from vhost backend */
+#define VIRTIO_USER_SUPPORTED_FEATURES                 \
+       (1ULL << VIRTIO_NET_F_MAC               |       \
+        1ULL << VIRTIO_NET_F_STATUS            |       \
+        1ULL << VIRTIO_NET_F_MQ                |       \
+        1ULL << VIRTIO_NET_F_CTRL_MAC_ADDR     |       \
+        1ULL << VIRTIO_NET_F_CTRL_VQ           |       \
+        1ULL << VIRTIO_NET_F_CTRL_RX           |       \
+        1ULL << VIRTIO_NET_F_CTRL_VLAN         |       \
+        1ULL << VIRTIO_NET_F_CSUM              |       \
+        1ULL << VIRTIO_NET_F_HOST_TSO4         |       \
+        1ULL << VIRTIO_NET_F_HOST_TSO6         |       \
+        1ULL << VIRTIO_NET_F_MRG_RXBUF         |       \
+        1ULL << VIRTIO_RING_F_INDIRECT_DESC    |       \
+        1ULL << VIRTIO_NET_F_GUEST_CSUM        |       \
+        1ULL << VIRTIO_NET_F_GUEST_TSO4        |       \
+        1ULL << VIRTIO_NET_F_GUEST_TSO6        |       \
+        1ULL << VIRTIO_F_VERSION_1)
+
 int
 virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
                     int cq, int queue_size, const char *mac, char **ifname)
@@ -331,6 +378,12 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
                dev->device_features &= ~(1ull << VIRTIO_NET_F_CTRL_MAC_ADDR);
        }
 
+       /* The backend will not report this feature, we add it explicitly */
+       if (is_vhost_user_by_type(dev->path))
+               dev->device_features |= (1ull << VIRTIO_NET_F_STATUS);
+
+       dev->device_features &= VIRTIO_USER_SUPPORTED_FEATURES;
+
        return 0;
 }