This patch introduce new callbacks for getting
and setting Vhost-user protocol features.

Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  2 +
 drivers/net/virtio/virtio_user/vhost_user.c   | 64 +++++++++++++++++--
 .../net/virtio/virtio_user/virtio_user_dev.c  | 17 ++---
 drivers/net/virtio/virtio_user_ethdev.c       | 14 ++--
 4 files changed, 69 insertions(+), 28 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h 
b/drivers/net/virtio/virtio_user/vhost.h
index 16978e27ed..d8c59ab308 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -104,6 +104,8 @@ struct virtio_user_backend_ops {
        int (*set_owner)(struct virtio_user_dev *dev);
        int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
        int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
+       int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t 
*features);
+       int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t 
features);
        int (*send_request)(struct virtio_user_dev *dev,
                            enum vhost_user_request req,
                            void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c 
b/drivers/net/virtio/virtio_user/vhost_user.c
index d204fa1eb0..5e89b1d72d 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -199,6 +199,62 @@ vhost_user_set_features(struct virtio_user_dev *dev, 
uint64_t features)
        return 0;
 }
 
+static int
+vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t 
*features)
+{
+       int ret;
+       struct vhost_user_msg msg = {
+               .request = VHOST_USER_GET_PROTOCOL_FEATURES,
+               .flags = VHOST_USER_VERSION,
+       };
+
+       ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+       if (ret < 0)
+               goto err;
+
+       ret = vhost_user_read(dev->vhostfd, &msg);
+       if (ret < 0)
+               goto err;
+
+       if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
+               PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
+               goto err;
+       }
+
+       if (msg.size != sizeof(*features)) {
+               PMD_DRV_LOG(ERR, "Unexpected payload size (%d)", msg.size);
+               goto err;
+       }
+
+       *features = msg.payload.u64;
+
+       return 0;
+err:
+       PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
+
+       return -1;
+}
+
+static int
+vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t 
features)
+{
+       int ret;
+       struct vhost_user_msg msg = {
+               .request = VHOST_USER_SET_PROTOCOL_FEATURES,
+               .flags = VHOST_USER_VERSION,
+               .size = sizeof(features),
+               .payload.u64 = features,
+       };
+
+       ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR, "Failed to set protocol features");
+               return -1;
+       }
+
+       return 0;
+}
+
 struct walk_arg {
        struct vhost_memory *vm;
        int *fds;
@@ -313,8 +369,6 @@ const char * const vhost_msg_strings[] = {
        [VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
        [VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE",
        [VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
-       [VHOST_USER_GET_PROTOCOL_FEATURES] = "VHOST_USER_GET_PROTOCOL_FEATURES",
-       [VHOST_USER_SET_PROTOCOL_FEATURES] = "VHOST_USER_SET_PROTOCOL_FEATURES",
        [VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
        [VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
@@ -352,8 +406,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
                    (!(dev->protocol_features &
                                (1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
                        return -ENOTSUP;
-               /* Fallthrough */
-       case VHOST_USER_GET_PROTOCOL_FEATURES:
                need_reply = 1;
                break;
 
@@ -366,7 +418,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
                if (has_reply_ack)
                        msg.flags |= VHOST_USER_NEED_REPLY_MASK;
                /* Fallthrough */
-       case VHOST_USER_SET_PROTOCOL_FEATURES:
        case VHOST_USER_SET_LOG_BASE:
                msg.payload.u64 = *((__u64 *)arg);
                msg.size = sizeof(m.payload.u64);
@@ -446,7 +497,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 
                switch (req) {
                case VHOST_USER_GET_STATUS:
-               case VHOST_USER_GET_PROTOCOL_FEATURES:
                        if (msg.size != sizeof(m.payload.u64)) {
                                PMD_DRV_LOG(ERR, "Received bad msg size");
                                return -1;
@@ -584,6 +634,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
        .set_owner = vhost_user_set_owner,
        .get_features = vhost_user_get_features,
        .set_features = vhost_user_set_features,
+       .get_protocol_features = vhost_user_get_protocol_features,
+       .set_protocol_features = vhost_user_set_protocol_features,
        .send_request = vhost_user_sock,
        .enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c 
b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 0a85d058a8..6bb61b3e89 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -495,24 +495,17 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char 
*path, int queues,
                }
 
 
-               if (dev->device_features &
-                               (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
-                       if (dev->ops->send_request(dev,
-                                       VHOST_USER_GET_PROTOCOL_FEATURES,
-                                       &protocol_features))
+               if (dev->device_features & (1ULL << 
VHOST_USER_F_PROTOCOL_FEATURES)) {
+                       if (dev->ops->get_protocol_features(dev, 
&protocol_features))
                                return -1;
 
                        dev->protocol_features &= protocol_features;
 
-                       if (dev->ops->send_request(dev,
-                                       VHOST_USER_SET_PROTOCOL_FEATURES,
-                                       &dev->protocol_features))
+                       if (dev->ops->set_protocol_features(dev, 
dev->protocol_features))
                                return -1;
 
-                       if (!(dev->protocol_features &
-                                       (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
-                               dev->unsupported_features |=
-                                       (1ull << VIRTIO_NET_F_MQ);
+                       if (!(dev->protocol_features & (1ULL << 
VHOST_USER_PROTOCOL_F_MQ)))
+                               dev->unsupported_features |= (1ull << 
VIRTIO_NET_F_MQ);
                }
        } else {
                /* We just pretend vhost-user can support all these features.
diff --git a/drivers/net/virtio/virtio_user_ethdev.c 
b/drivers/net/virtio/virtio_user_ethdev.c
index 4d2635c8aa..c63d010e16 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -93,23 +93,17 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 
        if (dev->device_features &
                        (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
-               if (dev->ops->send_request(dev,
-                                       VHOST_USER_GET_PROTOCOL_FEATURES,
-                                       &protocol_features))
+               if (dev->ops->get_protocol_features(dev, &protocol_features))
                        return -1;
 
                /* Offer VHOST_USER_PROTOCOL_F_STATUS */
-               dev->protocol_features |=
-                       (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
+               dev->protocol_features |= (1ULL << 
VHOST_USER_PROTOCOL_F_STATUS);
                dev->protocol_features &= protocol_features;
 
-               if (dev->ops->send_request(dev,
-                                       VHOST_USER_SET_PROTOCOL_FEATURES,
-                                       &dev->protocol_features))
+               if (dev->ops->set_protocol_features(dev, 
dev->protocol_features))
                        return -1;
 
-               if (!(dev->protocol_features &
-                               (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+               if (!(dev->protocol_features & (1ULL << 
VHOST_USER_PROTOCOL_F_MQ)))
                        dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
        }
 
-- 
2.29.2

Reply via email to