1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2017 Netronome Systems, Inc. 3 * Copyright (C) 2019 Mellanox Technologies. All rights reserved 4 */ 5 6 #include <linux/device.h> 7 #include <linux/idr.h> 8 #include <linux/kernel.h> 9 #include <linux/list.h> 10 #include <linux/mutex.h> 11 #include <linux/rtnetlink.h> 12 #include <linux/slab.h> 13 #include <linux/sysfs.h> 14 15 #include "netdevsim.h" 16 17 static DEFINE_IDA(nsim_bus_dev_ids); 18 static LIST_HEAD(nsim_bus_dev_list); 19 static DEFINE_MUTEX(nsim_bus_dev_list_lock); 20 static bool nsim_bus_enable; 21 22 static struct nsim_bus_dev *to_nsim_bus_dev(struct device *dev) 23 { 24 return container_of(dev, struct nsim_bus_dev, dev); 25 } 26 27 static int nsim_bus_dev_vfs_enable(struct nsim_bus_dev *nsim_bus_dev, 28 unsigned int num_vfs) 29 { 30 nsim_bus_dev->vfconfigs = kcalloc(num_vfs, 31 sizeof(struct nsim_vf_config), 32 GFP_KERNEL); 33 if (!nsim_bus_dev->vfconfigs) 34 return -ENOMEM; 35 nsim_bus_dev->num_vfs = num_vfs; 36 37 return 0; 38 } 39 40 static void nsim_bus_dev_vfs_disable(struct nsim_bus_dev *nsim_bus_dev) 41 { 42 kfree(nsim_bus_dev->vfconfigs); 43 nsim_bus_dev->vfconfigs = NULL; 44 nsim_bus_dev->num_vfs = 0; 45 } 46 47 static ssize_t 48 nsim_bus_dev_numvfs_store(struct device *dev, struct device_attribute *attr, 49 const char *buf, size_t count) 50 { 51 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 52 unsigned int num_vfs; 53 int ret; 54 55 ret = kstrtouint(buf, 0, &num_vfs); 56 if (ret) 57 return ret; 58 59 rtnl_lock(); 60 if (nsim_bus_dev->num_vfs == num_vfs) 61 goto exit_good; 62 if (nsim_bus_dev->num_vfs && num_vfs) { 63 ret = -EBUSY; 64 goto exit_unlock; 65 } 66 67 if (num_vfs) { 68 ret = nsim_bus_dev_vfs_enable(nsim_bus_dev, num_vfs); 69 if (ret) 70 goto exit_unlock; 71 } else { 72 nsim_bus_dev_vfs_disable(nsim_bus_dev); 73 } 74 exit_good: 75 ret = count; 76 exit_unlock: 77 rtnl_unlock(); 78 79 return ret; 80 } 81 82 static ssize_t 83 nsim_bus_dev_numvfs_show(struct device *dev, 84 struct device_attribute *attr, char *buf) 85 { 86 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 87 88 return sprintf(buf, "%u\n", nsim_bus_dev->num_vfs); 89 } 90 91 static struct device_attribute nsim_bus_dev_numvfs_attr = 92 __ATTR(sriov_numvfs, 0664, nsim_bus_dev_numvfs_show, 93 nsim_bus_dev_numvfs_store); 94 95 static ssize_t 96 new_port_store(struct device *dev, struct device_attribute *attr, 97 const char *buf, size_t count) 98 { 99 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 100 unsigned int port_index; 101 int ret; 102 103 /* Prevent to use nsim_bus_dev before initialization. */ 104 if (!smp_load_acquire(&nsim_bus_dev->init)) 105 return -EBUSY; 106 ret = kstrtouint(buf, 0, &port_index); 107 if (ret) 108 return ret; 109 ret = nsim_dev_port_add(nsim_bus_dev, port_index); 110 return ret ? ret : count; 111 } 112 113 static struct device_attribute nsim_bus_dev_new_port_attr = __ATTR_WO(new_port); 114 115 static ssize_t 116 del_port_store(struct device *dev, struct device_attribute *attr, 117 const char *buf, size_t count) 118 { 119 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 120 unsigned int port_index; 121 int ret; 122 123 /* Prevent to use nsim_bus_dev before initialization. */ 124 if (!smp_load_acquire(&nsim_bus_dev->init)) 125 return -EBUSY; 126 ret = kstrtouint(buf, 0, &port_index); 127 if (ret) 128 return ret; 129 ret = nsim_dev_port_del(nsim_bus_dev, port_index); 130 return ret ? ret : count; 131 } 132 133 static struct device_attribute nsim_bus_dev_del_port_attr = __ATTR_WO(del_port); 134 135 static struct attribute *nsim_bus_dev_attrs[] = { 136 &nsim_bus_dev_numvfs_attr.attr, 137 &nsim_bus_dev_new_port_attr.attr, 138 &nsim_bus_dev_del_port_attr.attr, 139 NULL, 140 }; 141 142 static const struct attribute_group nsim_bus_dev_attr_group = { 143 .attrs = nsim_bus_dev_attrs, 144 }; 145 146 static const struct attribute_group *nsim_bus_dev_attr_groups[] = { 147 &nsim_bus_dev_attr_group, 148 NULL, 149 }; 150 151 static void nsim_bus_dev_release(struct device *dev) 152 { 153 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 154 155 nsim_bus_dev_vfs_disable(nsim_bus_dev); 156 } 157 158 static struct device_type nsim_bus_dev_type = { 159 .groups = nsim_bus_dev_attr_groups, 160 .release = nsim_bus_dev_release, 161 }; 162 163 static struct nsim_bus_dev * 164 nsim_bus_dev_new(unsigned int id, unsigned int port_count); 165 166 static ssize_t 167 new_device_store(struct bus_type *bus, const char *buf, size_t count) 168 { 169 struct nsim_bus_dev *nsim_bus_dev; 170 unsigned int port_count; 171 unsigned int id; 172 int err; 173 174 err = sscanf(buf, "%u %u", &id, &port_count); 175 switch (err) { 176 case 1: 177 port_count = 1; 178 /* fall through */ 179 case 2: 180 if (id > INT_MAX) { 181 pr_err("Value of \"id\" is too big.\n"); 182 return -EINVAL; 183 } 184 break; 185 default: 186 pr_err("Format for adding new device is \"id port_count\" (uint uint).\n"); 187 return -EINVAL; 188 } 189 190 mutex_lock(&nsim_bus_dev_list_lock); 191 /* Prevent to use resource before initialization. */ 192 if (!smp_load_acquire(&nsim_bus_enable)) { 193 err = -EBUSY; 194 goto err; 195 } 196 197 nsim_bus_dev = nsim_bus_dev_new(id, port_count); 198 if (IS_ERR(nsim_bus_dev)) { 199 err = PTR_ERR(nsim_bus_dev); 200 goto err; 201 } 202 203 /* Allow using nsim_bus_dev */ 204 smp_store_release(&nsim_bus_dev->init, true); 205 206 list_add_tail(&nsim_bus_dev->list, &nsim_bus_dev_list); 207 mutex_unlock(&nsim_bus_dev_list_lock); 208 209 return count; 210 err: 211 mutex_unlock(&nsim_bus_dev_list_lock); 212 return err; 213 } 214 static BUS_ATTR_WO(new_device); 215 216 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev); 217 218 static ssize_t 219 del_device_store(struct bus_type *bus, const char *buf, size_t count) 220 { 221 struct nsim_bus_dev *nsim_bus_dev, *tmp; 222 unsigned int id; 223 int err; 224 225 err = sscanf(buf, "%u", &id); 226 switch (err) { 227 case 1: 228 if (id > INT_MAX) { 229 pr_err("Value of \"id\" is too big.\n"); 230 return -EINVAL; 231 } 232 break; 233 default: 234 pr_err("Format for deleting device is \"id\" (uint).\n"); 235 return -EINVAL; 236 } 237 238 err = -ENOENT; 239 mutex_lock(&nsim_bus_dev_list_lock); 240 /* Prevent to use resource before initialization. */ 241 if (!smp_load_acquire(&nsim_bus_enable)) { 242 mutex_unlock(&nsim_bus_dev_list_lock); 243 return -EBUSY; 244 } 245 list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) { 246 if (nsim_bus_dev->dev.id != id) 247 continue; 248 list_del(&nsim_bus_dev->list); 249 nsim_bus_dev_del(nsim_bus_dev); 250 err = 0; 251 break; 252 } 253 mutex_unlock(&nsim_bus_dev_list_lock); 254 return !err ? count : err; 255 } 256 static BUS_ATTR_WO(del_device); 257 258 static struct attribute *nsim_bus_attrs[] = { 259 &bus_attr_new_device.attr, 260 &bus_attr_del_device.attr, 261 NULL 262 }; 263 ATTRIBUTE_GROUPS(nsim_bus); 264 265 static int nsim_bus_probe(struct device *dev) 266 { 267 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 268 269 return nsim_dev_probe(nsim_bus_dev); 270 } 271 272 static int nsim_bus_remove(struct device *dev) 273 { 274 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 275 276 nsim_dev_remove(nsim_bus_dev); 277 return 0; 278 } 279 280 static int nsim_num_vf(struct device *dev) 281 { 282 struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev); 283 284 return nsim_bus_dev->num_vfs; 285 } 286 287 static struct bus_type nsim_bus = { 288 .name = DRV_NAME, 289 .dev_name = DRV_NAME, 290 .bus_groups = nsim_bus_groups, 291 .probe = nsim_bus_probe, 292 .remove = nsim_bus_remove, 293 .num_vf = nsim_num_vf, 294 }; 295 296 static struct nsim_bus_dev * 297 nsim_bus_dev_new(unsigned int id, unsigned int port_count) 298 { 299 struct nsim_bus_dev *nsim_bus_dev; 300 int err; 301 302 nsim_bus_dev = kzalloc(sizeof(*nsim_bus_dev), GFP_KERNEL); 303 if (!nsim_bus_dev) 304 return ERR_PTR(-ENOMEM); 305 306 err = ida_alloc_range(&nsim_bus_dev_ids, id, id, GFP_KERNEL); 307 if (err < 0) 308 goto err_nsim_bus_dev_free; 309 nsim_bus_dev->dev.id = err; 310 nsim_bus_dev->dev.bus = &nsim_bus; 311 nsim_bus_dev->dev.type = &nsim_bus_dev_type; 312 nsim_bus_dev->port_count = port_count; 313 nsim_bus_dev->initial_net = current->nsproxy->net_ns; 314 /* Disallow using nsim_bus_dev */ 315 smp_store_release(&nsim_bus_dev->init, false); 316 317 err = device_register(&nsim_bus_dev->dev); 318 if (err) 319 goto err_nsim_bus_dev_id_free; 320 return nsim_bus_dev; 321 322 err_nsim_bus_dev_id_free: 323 ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id); 324 err_nsim_bus_dev_free: 325 kfree(nsim_bus_dev); 326 return ERR_PTR(err); 327 } 328 329 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev) 330 { 331 /* Disallow using nsim_bus_dev */ 332 smp_store_release(&nsim_bus_dev->init, false); 333 device_unregister(&nsim_bus_dev->dev); 334 ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id); 335 kfree(nsim_bus_dev); 336 } 337 338 static struct device_driver nsim_driver = { 339 .name = DRV_NAME, 340 .bus = &nsim_bus, 341 .owner = THIS_MODULE, 342 }; 343 344 int nsim_bus_init(void) 345 { 346 int err; 347 348 err = bus_register(&nsim_bus); 349 if (err) 350 return err; 351 err = driver_register(&nsim_driver); 352 if (err) 353 goto err_bus_unregister; 354 /* Allow using resources */ 355 smp_store_release(&nsim_bus_enable, true); 356 return 0; 357 358 err_bus_unregister: 359 bus_unregister(&nsim_bus); 360 return err; 361 } 362 363 void nsim_bus_exit(void) 364 { 365 struct nsim_bus_dev *nsim_bus_dev, *tmp; 366 367 /* Disallow using resources */ 368 smp_store_release(&nsim_bus_enable, false); 369 370 mutex_lock(&nsim_bus_dev_list_lock); 371 list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) { 372 list_del(&nsim_bus_dev->list); 373 nsim_bus_dev_del(nsim_bus_dev); 374 } 375 mutex_unlock(&nsim_bus_dev_list_lock); 376 377 driver_unregister(&nsim_driver); 378 bus_unregister(&nsim_bus); 379 } 380