vdpa_sim: add struct vdpasim_dev_attr for device attributes
[linux-2.6-microblaze.git] / drivers / vdpa / vdpa_sim / vdpa_sim.c
index 6a90fdb..ae295dc 100644 (file)
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/uuid.h>
-#include <linux/iommu.h>
 #include <linux/dma-map-ops.h>
-#include <linux/sysfs.h>
-#include <linux/file.h>
 #include <linux/etherdevice.h>
 #include <linux/vringh.h>
 #include <linux/vdpa.h>
@@ -38,6 +31,11 @@ static int batch_mapping = 1;
 module_param(batch_mapping, int, 0444);
 MODULE_PARM_DESC(batch_mapping, "Batched mapping 1 -Enable; 0 - Disable");
 
+static int max_iotlb_entries = 2048;
+module_param(max_iotlb_entries, int, 0444);
+MODULE_PARM_DESC(max_iotlb_entries,
+                "Maximum number of iotlb entries. 0 means unlimited. (default: 2048)");
+
 static char *macaddr;
 module_param(macaddr, charp, 0);
 MODULE_PARM_DESC(macaddr, "Ethernet MAC address");
@@ -67,11 +65,16 @@ static u64 vdpasim_features = (1ULL << VIRTIO_F_ANY_LAYOUT) |
                              (1ULL << VIRTIO_F_ACCESS_PLATFORM) |
                              (1ULL << VIRTIO_NET_F_MAC);
 
+struct vdpasim_dev_attr {
+       int nvqs;
+};
+
 /* State of each vdpasim device */
 struct vdpasim {
        struct vdpa_device vdpa;
-       struct vdpasim_virtqueue vqs[VDPASIM_VQ_NUM];
+       struct vdpasim_virtqueue *vqs;
        struct work_struct work;
+       struct vdpasim_dev_attr dev_attr;
        /* spinlock to synchronize virtqueue state */
        spinlock_t lock;
        struct virtio_net_config config;
@@ -144,7 +147,7 @@ static void vdpasim_reset(struct vdpasim *vdpasim)
 {
        int i;
 
-       for (i = 0; i < VDPASIM_VQ_NUM; i++)
+       for (i = 0; i < vdpasim->dev_attr.nvqs; i++)
                vdpasim_vq_reset(&vdpasim->vqs[i]);
 
        spin_lock(&vdpasim->iommu_lock);
@@ -342,25 +345,27 @@ static const struct dma_map_ops vdpasim_dma_ops = {
        .free = vdpasim_free_coherent,
 };
 
-static const struct vdpa_config_ops vdpasim_net_config_ops;
-static const struct vdpa_config_ops vdpasim_net_batch_config_ops;
+static const struct vdpa_config_ops vdpasim_config_ops;
+static const struct vdpa_config_ops vdpasim_batch_config_ops;
 
-static struct vdpasim *vdpasim_create(void)
+static struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr)
 {
        const struct vdpa_config_ops *ops;
        struct vdpasim *vdpasim;
        struct device *dev;
-       int ret = -ENOMEM;
+       int i, ret = -ENOMEM;
 
        if (batch_mapping)
-               ops = &vdpasim_net_batch_config_ops;
+               ops = &vdpasim_batch_config_ops;
        else
-               ops = &vdpasim_net_config_ops;
+               ops = &vdpasim_config_ops;
 
-       vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, VDPASIM_VQ_NUM);
+       vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops,
+                                   dev_attr->nvqs);
        if (!vdpasim)
                goto err_alloc;
 
+       vdpasim->dev_attr = *dev_attr;
        INIT_WORK(&vdpasim->work, vdpasim_work);
        spin_lock_init(&vdpasim->lock);
        spin_lock_init(&vdpasim->iommu_lock);
@@ -371,7 +376,12 @@ static struct vdpasim *vdpasim_create(void)
                goto err_iommu;
        set_dma_ops(dev, &vdpasim_dma_ops);
 
-       vdpasim->iommu = vhost_iotlb_alloc(2048, 0);
+       vdpasim->vqs = kcalloc(dev_attr->nvqs, sizeof(struct vdpasim_virtqueue),
+                              GFP_KERNEL);
+       if (!vdpasim->vqs)
+               goto err_iommu;
+
+       vdpasim->iommu = vhost_iotlb_alloc(max_iotlb_entries, 0);
        if (!vdpasim->iommu)
                goto err_iommu;
 
@@ -389,8 +399,8 @@ static struct vdpasim *vdpasim_create(void)
                eth_random_addr(vdpasim->config.mac);
        }
 
-       vringh_set_iotlb(&vdpasim->vqs[0].vring, vdpasim->iommu);
-       vringh_set_iotlb(&vdpasim->vqs[1].vring, vdpasim->iommu);
+       for (i = 0; i < dev_attr->nvqs; i++)
+               vringh_set_iotlb(&vdpasim->vqs[i].vring, vdpasim->iommu);
 
        vdpasim->vdpa.dma_dev = dev;
        ret = vdpa_register_device(&vdpasim->vdpa);
@@ -659,9 +669,10 @@ static void vdpasim_free(struct vdpa_device *vdpa)
        kfree(vdpasim->buffer);
        if (vdpasim->iommu)
                vhost_iotlb_free(vdpasim->iommu);
+       kfree(vdpasim->vqs);
 }
 
-static const struct vdpa_config_ops vdpasim_net_config_ops = {
+static const struct vdpa_config_ops vdpasim_config_ops = {
        .set_vq_address         = vdpasim_set_vq_address,
        .set_vq_num             = vdpasim_set_vq_num,
        .kick_vq                = vdpasim_kick_vq,
@@ -688,7 +699,7 @@ static const struct vdpa_config_ops vdpasim_net_config_ops = {
        .free                   = vdpasim_free,
 };
 
-static const struct vdpa_config_ops vdpasim_net_batch_config_ops = {
+static const struct vdpa_config_ops vdpasim_batch_config_ops = {
        .set_vq_address         = vdpasim_set_vq_address,
        .set_vq_num             = vdpasim_set_vq_num,
        .kick_vq                = vdpasim_kick_vq,
@@ -716,7 +727,11 @@ static const struct vdpa_config_ops vdpasim_net_batch_config_ops = {
 
 static int __init vdpasim_dev_init(void)
 {
-       vdpasim_dev = vdpasim_create();
+       struct vdpasim_dev_attr dev_attr = {};
+
+       dev_attr.nvqs = VDPASIM_VQ_NUM;
+
+       vdpasim_dev = vdpasim_create(&dev_attr);
 
        if (!IS_ERR(vdpasim_dev))
                return 0;