Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) 2017 Netronome Systems, Inc.
0003  * Copyright (C) 2019 Mellanox Technologies. All rights reserved
0004  */
0005 
0006 #include <linux/device.h>
0007 #include <linux/idr.h>
0008 #include <linux/kernel.h>
0009 #include <linux/list.h>
0010 #include <linux/mutex.h>
0011 #include <linux/slab.h>
0012 #include <linux/sysfs.h>
0013 
0014 #include "netdevsim.h"
0015 
0016 static DEFINE_IDA(nsim_bus_dev_ids);
0017 static LIST_HEAD(nsim_bus_dev_list);
0018 static DEFINE_MUTEX(nsim_bus_dev_list_lock);
0019 static bool nsim_bus_enable;
0020 
0021 static struct nsim_bus_dev *to_nsim_bus_dev(struct device *dev)
0022 {
0023     return container_of(dev, struct nsim_bus_dev, dev);
0024 }
0025 
0026 static ssize_t
0027 nsim_bus_dev_numvfs_store(struct device *dev, struct device_attribute *attr,
0028               const char *buf, size_t count)
0029 {
0030     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0031     unsigned int num_vfs;
0032     int ret;
0033 
0034     ret = kstrtouint(buf, 0, &num_vfs);
0035     if (ret)
0036         return ret;
0037 
0038     device_lock(dev);
0039     ret = -ENOENT;
0040     if (dev_get_drvdata(dev))
0041         ret = nsim_drv_configure_vfs(nsim_bus_dev, num_vfs);
0042     device_unlock(dev);
0043 
0044     return ret ? ret : count;
0045 }
0046 
0047 static ssize_t
0048 nsim_bus_dev_numvfs_show(struct device *dev,
0049              struct device_attribute *attr, char *buf)
0050 {
0051     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0052 
0053     return sprintf(buf, "%u\n", nsim_bus_dev->num_vfs);
0054 }
0055 
0056 static struct device_attribute nsim_bus_dev_numvfs_attr =
0057     __ATTR(sriov_numvfs, 0664, nsim_bus_dev_numvfs_show,
0058            nsim_bus_dev_numvfs_store);
0059 
0060 static ssize_t
0061 new_port_store(struct device *dev, struct device_attribute *attr,
0062            const char *buf, size_t count)
0063 {
0064     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0065     unsigned int port_index;
0066     int ret;
0067 
0068     /* Prevent to use nsim_bus_dev before initialization. */
0069     if (!smp_load_acquire(&nsim_bus_dev->init))
0070         return -EBUSY;
0071     ret = kstrtouint(buf, 0, &port_index);
0072     if (ret)
0073         return ret;
0074 
0075     ret = nsim_drv_port_add(nsim_bus_dev, NSIM_DEV_PORT_TYPE_PF, port_index);
0076     return ret ? ret : count;
0077 }
0078 
0079 static struct device_attribute nsim_bus_dev_new_port_attr = __ATTR_WO(new_port);
0080 
0081 static ssize_t
0082 del_port_store(struct device *dev, struct device_attribute *attr,
0083            const char *buf, size_t count)
0084 {
0085     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0086     unsigned int port_index;
0087     int ret;
0088 
0089     /* Prevent to use nsim_bus_dev before initialization. */
0090     if (!smp_load_acquire(&nsim_bus_dev->init))
0091         return -EBUSY;
0092     ret = kstrtouint(buf, 0, &port_index);
0093     if (ret)
0094         return ret;
0095 
0096     ret = nsim_drv_port_del(nsim_bus_dev, NSIM_DEV_PORT_TYPE_PF, port_index);
0097     return ret ? ret : count;
0098 }
0099 
0100 static struct device_attribute nsim_bus_dev_del_port_attr = __ATTR_WO(del_port);
0101 
0102 static struct attribute *nsim_bus_dev_attrs[] = {
0103     &nsim_bus_dev_numvfs_attr.attr,
0104     &nsim_bus_dev_new_port_attr.attr,
0105     &nsim_bus_dev_del_port_attr.attr,
0106     NULL,
0107 };
0108 
0109 static const struct attribute_group nsim_bus_dev_attr_group = {
0110     .attrs = nsim_bus_dev_attrs,
0111 };
0112 
0113 static const struct attribute_group *nsim_bus_dev_attr_groups[] = {
0114     &nsim_bus_dev_attr_group,
0115     NULL,
0116 };
0117 
0118 static void nsim_bus_dev_release(struct device *dev)
0119 {
0120 }
0121 
0122 static struct device_type nsim_bus_dev_type = {
0123     .groups = nsim_bus_dev_attr_groups,
0124     .release = nsim_bus_dev_release,
0125 };
0126 
0127 static struct nsim_bus_dev *
0128 nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queues);
0129 
0130 static ssize_t
0131 new_device_store(struct bus_type *bus, const char *buf, size_t count)
0132 {
0133     unsigned int id, port_count, num_queues;
0134     struct nsim_bus_dev *nsim_bus_dev;
0135     int err;
0136 
0137     err = sscanf(buf, "%u %u %u", &id, &port_count, &num_queues);
0138     switch (err) {
0139     case 1:
0140         port_count = 1;
0141         fallthrough;
0142     case 2:
0143         num_queues = 1;
0144         fallthrough;
0145     case 3:
0146         if (id > INT_MAX) {
0147             pr_err("Value of \"id\" is too big.\n");
0148             return -EINVAL;
0149         }
0150         break;
0151     default:
0152         pr_err("Format for adding new device is \"id port_count num_queues\" (uint uint unit).\n");
0153         return -EINVAL;
0154     }
0155 
0156     mutex_lock(&nsim_bus_dev_list_lock);
0157     /* Prevent to use resource before initialization. */
0158     if (!smp_load_acquire(&nsim_bus_enable)) {
0159         err = -EBUSY;
0160         goto err;
0161     }
0162 
0163     nsim_bus_dev = nsim_bus_dev_new(id, port_count, num_queues);
0164     if (IS_ERR(nsim_bus_dev)) {
0165         err = PTR_ERR(nsim_bus_dev);
0166         goto err;
0167     }
0168 
0169     /* Allow using nsim_bus_dev */
0170     smp_store_release(&nsim_bus_dev->init, true);
0171 
0172     list_add_tail(&nsim_bus_dev->list, &nsim_bus_dev_list);
0173     mutex_unlock(&nsim_bus_dev_list_lock);
0174 
0175     return count;
0176 err:
0177     mutex_unlock(&nsim_bus_dev_list_lock);
0178     return err;
0179 }
0180 static BUS_ATTR_WO(new_device);
0181 
0182 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
0183 
0184 static ssize_t
0185 del_device_store(struct bus_type *bus, const char *buf, size_t count)
0186 {
0187     struct nsim_bus_dev *nsim_bus_dev, *tmp;
0188     unsigned int id;
0189     int err;
0190 
0191     err = sscanf(buf, "%u", &id);
0192     switch (err) {
0193     case 1:
0194         if (id > INT_MAX) {
0195             pr_err("Value of \"id\" is too big.\n");
0196             return -EINVAL;
0197         }
0198         break;
0199     default:
0200         pr_err("Format for deleting device is \"id\" (uint).\n");
0201         return -EINVAL;
0202     }
0203 
0204     err = -ENOENT;
0205     mutex_lock(&nsim_bus_dev_list_lock);
0206     /* Prevent to use resource before initialization. */
0207     if (!smp_load_acquire(&nsim_bus_enable)) {
0208         mutex_unlock(&nsim_bus_dev_list_lock);
0209         return -EBUSY;
0210     }
0211     list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
0212         if (nsim_bus_dev->dev.id != id)
0213             continue;
0214         list_del(&nsim_bus_dev->list);
0215         nsim_bus_dev_del(nsim_bus_dev);
0216         err = 0;
0217         break;
0218     }
0219     mutex_unlock(&nsim_bus_dev_list_lock);
0220     return !err ? count : err;
0221 }
0222 static BUS_ATTR_WO(del_device);
0223 
0224 static struct attribute *nsim_bus_attrs[] = {
0225     &bus_attr_new_device.attr,
0226     &bus_attr_del_device.attr,
0227     NULL
0228 };
0229 ATTRIBUTE_GROUPS(nsim_bus);
0230 
0231 static int nsim_bus_probe(struct device *dev)
0232 {
0233     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0234 
0235     return nsim_drv_probe(nsim_bus_dev);
0236 }
0237 
0238 static void nsim_bus_remove(struct device *dev)
0239 {
0240     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0241 
0242     nsim_drv_remove(nsim_bus_dev);
0243 }
0244 
0245 static int nsim_num_vf(struct device *dev)
0246 {
0247     struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
0248 
0249     return nsim_bus_dev->num_vfs;
0250 }
0251 
0252 static struct bus_type nsim_bus = {
0253     .name       = DRV_NAME,
0254     .dev_name   = DRV_NAME,
0255     .bus_groups = nsim_bus_groups,
0256     .probe      = nsim_bus_probe,
0257     .remove     = nsim_bus_remove,
0258     .num_vf     = nsim_num_vf,
0259 };
0260 
0261 #define NSIM_BUS_DEV_MAX_VFS 4
0262 
0263 static struct nsim_bus_dev *
0264 nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queues)
0265 {
0266     struct nsim_bus_dev *nsim_bus_dev;
0267     int err;
0268 
0269     nsim_bus_dev = kzalloc(sizeof(*nsim_bus_dev), GFP_KERNEL);
0270     if (!nsim_bus_dev)
0271         return ERR_PTR(-ENOMEM);
0272 
0273     err = ida_alloc_range(&nsim_bus_dev_ids, id, id, GFP_KERNEL);
0274     if (err < 0)
0275         goto err_nsim_bus_dev_free;
0276     nsim_bus_dev->dev.id = err;
0277     nsim_bus_dev->dev.bus = &nsim_bus;
0278     nsim_bus_dev->dev.type = &nsim_bus_dev_type;
0279     nsim_bus_dev->port_count = port_count;
0280     nsim_bus_dev->num_queues = num_queues;
0281     nsim_bus_dev->initial_net = current->nsproxy->net_ns;
0282     nsim_bus_dev->max_vfs = NSIM_BUS_DEV_MAX_VFS;
0283     /* Disallow using nsim_bus_dev */
0284     smp_store_release(&nsim_bus_dev->init, false);
0285 
0286     err = device_register(&nsim_bus_dev->dev);
0287     if (err)
0288         goto err_nsim_bus_dev_id_free;
0289 
0290     return nsim_bus_dev;
0291 
0292 err_nsim_bus_dev_id_free:
0293     ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
0294 err_nsim_bus_dev_free:
0295     kfree(nsim_bus_dev);
0296     return ERR_PTR(err);
0297 }
0298 
0299 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
0300 {
0301     /* Disallow using nsim_bus_dev */
0302     smp_store_release(&nsim_bus_dev->init, false);
0303     device_unregister(&nsim_bus_dev->dev);
0304     ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
0305     kfree(nsim_bus_dev);
0306 }
0307 
0308 static struct device_driver nsim_driver = {
0309     .name       = DRV_NAME,
0310     .bus        = &nsim_bus,
0311     .owner      = THIS_MODULE,
0312 };
0313 
0314 int nsim_bus_init(void)
0315 {
0316     int err;
0317 
0318     err = bus_register(&nsim_bus);
0319     if (err)
0320         return err;
0321     err = driver_register(&nsim_driver);
0322     if (err)
0323         goto err_bus_unregister;
0324     /* Allow using resources */
0325     smp_store_release(&nsim_bus_enable, true);
0326     return 0;
0327 
0328 err_bus_unregister:
0329     bus_unregister(&nsim_bus);
0330     return err;
0331 }
0332 
0333 void nsim_bus_exit(void)
0334 {
0335     struct nsim_bus_dev *nsim_bus_dev, *tmp;
0336 
0337     /* Disallow using resources */
0338     smp_store_release(&nsim_bus_enable, false);
0339 
0340     mutex_lock(&nsim_bus_dev_list_lock);
0341     list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
0342         list_del(&nsim_bus_dev->list);
0343         nsim_bus_dev_del(nsim_bus_dev);
0344     }
0345     mutex_unlock(&nsim_bus_dev_list_lock);
0346 
0347     driver_unregister(&nsim_driver);
0348     bus_unregister(&nsim_bus);
0349 }