bus.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. #include <linux/device.h>
  6. #include <linux/idr.h>
  7. #include <linux/kernel.h>
  8. #include <linux/list.h>
  9. #include <linux/mutex.h>
  10. #include <linux/rtnetlink.h>
  11. #include <linux/slab.h>
  12. #include <linux/sysfs.h>
  13. #include "netdevsim.h"
  14. static DEFINE_IDA(nsim_bus_dev_ids);
  15. static LIST_HEAD(nsim_bus_dev_list);
  16. static DEFINE_MUTEX(nsim_bus_dev_list_lock);
  17. static struct nsim_bus_dev *to_nsim_bus_dev(struct device *dev)
  18. {
  19. return container_of(dev, struct nsim_bus_dev, dev);
  20. }
  21. static int nsim_bus_dev_vfs_enable(struct nsim_bus_dev *nsim_bus_dev,
  22. unsigned int num_vfs)
  23. {
  24. nsim_bus_dev->vfconfigs = kcalloc(num_vfs,
  25. sizeof(struct nsim_vf_config),
  26. GFP_KERNEL);
  27. if (!nsim_bus_dev->vfconfigs)
  28. return -ENOMEM;
  29. nsim_bus_dev->num_vfs = num_vfs;
  30. return 0;
  31. }
  32. static void nsim_bus_dev_vfs_disable(struct nsim_bus_dev *nsim_bus_dev)
  33. {
  34. kfree(nsim_bus_dev->vfconfigs);
  35. nsim_bus_dev->vfconfigs = NULL;
  36. nsim_bus_dev->num_vfs = 0;
  37. }
  38. static ssize_t
  39. nsim_bus_dev_numvfs_store(struct device *dev, struct device_attribute *attr,
  40. const char *buf, size_t count)
  41. {
  42. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  43. unsigned int num_vfs;
  44. int ret;
  45. ret = kstrtouint(buf, 0, &num_vfs);
  46. if (ret)
  47. return ret;
  48. rtnl_lock();
  49. if (nsim_bus_dev->num_vfs == num_vfs)
  50. goto exit_good;
  51. if (nsim_bus_dev->num_vfs && num_vfs) {
  52. ret = -EBUSY;
  53. goto exit_unlock;
  54. }
  55. if (num_vfs) {
  56. ret = nsim_bus_dev_vfs_enable(nsim_bus_dev, num_vfs);
  57. if (ret)
  58. goto exit_unlock;
  59. } else {
  60. nsim_bus_dev_vfs_disable(nsim_bus_dev);
  61. }
  62. exit_good:
  63. ret = count;
  64. exit_unlock:
  65. rtnl_unlock();
  66. return ret;
  67. }
  68. static ssize_t
  69. nsim_bus_dev_numvfs_show(struct device *dev,
  70. struct device_attribute *attr, char *buf)
  71. {
  72. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  73. return sprintf(buf, "%u\n", nsim_bus_dev->num_vfs);
  74. }
  75. static struct device_attribute nsim_bus_dev_numvfs_attr =
  76. __ATTR(sriov_numvfs, 0664, nsim_bus_dev_numvfs_show,
  77. nsim_bus_dev_numvfs_store);
  78. static ssize_t
  79. new_port_store(struct device *dev, struct device_attribute *attr,
  80. const char *buf, size_t count)
  81. {
  82. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  83. unsigned int port_index;
  84. int ret;
  85. ret = kstrtouint(buf, 0, &port_index);
  86. if (ret)
  87. return ret;
  88. ret = nsim_dev_port_add(nsim_bus_dev, port_index);
  89. return ret ? ret : count;
  90. }
  91. static struct device_attribute nsim_bus_dev_new_port_attr = __ATTR_WO(new_port);
  92. static ssize_t
  93. del_port_store(struct device *dev, struct device_attribute *attr,
  94. const char *buf, size_t count)
  95. {
  96. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  97. unsigned int port_index;
  98. int ret;
  99. ret = kstrtouint(buf, 0, &port_index);
  100. if (ret)
  101. return ret;
  102. ret = nsim_dev_port_del(nsim_bus_dev, port_index);
  103. return ret ? ret : count;
  104. }
  105. static struct device_attribute nsim_bus_dev_del_port_attr = __ATTR_WO(del_port);
  106. static struct attribute *nsim_bus_dev_attrs[] = {
  107. &nsim_bus_dev_numvfs_attr.attr,
  108. &nsim_bus_dev_new_port_attr.attr,
  109. &nsim_bus_dev_del_port_attr.attr,
  110. NULL,
  111. };
  112. static const struct attribute_group nsim_bus_dev_attr_group = {
  113. .attrs = nsim_bus_dev_attrs,
  114. };
  115. static const struct attribute_group *nsim_bus_dev_attr_groups[] = {
  116. &nsim_bus_dev_attr_group,
  117. NULL,
  118. };
  119. static void nsim_bus_dev_release(struct device *dev)
  120. {
  121. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  122. nsim_bus_dev_vfs_disable(nsim_bus_dev);
  123. }
  124. static struct device_type nsim_bus_dev_type = {
  125. .groups = nsim_bus_dev_attr_groups,
  126. .release = nsim_bus_dev_release,
  127. };
  128. static struct nsim_bus_dev *
  129. nsim_bus_dev_new(unsigned int id, unsigned int port_count);
  130. static ssize_t
  131. new_device_store(struct bus_type *bus, const char *buf, size_t count)
  132. {
  133. struct nsim_bus_dev *nsim_bus_dev;
  134. unsigned int port_count;
  135. unsigned int id;
  136. int err;
  137. err = sscanf(buf, "%u %u", &id, &port_count);
  138. switch (err) {
  139. case 1:
  140. port_count = 1;
  141. /* fall through */
  142. case 2:
  143. if (id > INT_MAX) {
  144. pr_err("Value of \"id\" is too big.\n");
  145. return -EINVAL;
  146. }
  147. break;
  148. default:
  149. pr_err("Format for adding new device is \"id port_count\" (uint uint).\n");
  150. return -EINVAL;
  151. }
  152. nsim_bus_dev = nsim_bus_dev_new(id, port_count);
  153. if (IS_ERR(nsim_bus_dev))
  154. return PTR_ERR(nsim_bus_dev);
  155. mutex_lock(&nsim_bus_dev_list_lock);
  156. list_add_tail(&nsim_bus_dev->list, &nsim_bus_dev_list);
  157. mutex_unlock(&nsim_bus_dev_list_lock);
  158. return count;
  159. }
  160. static BUS_ATTR_WO(new_device);
  161. static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
  162. static ssize_t
  163. del_device_store(struct bus_type *bus, const char *buf, size_t count)
  164. {
  165. struct nsim_bus_dev *nsim_bus_dev, *tmp;
  166. unsigned int id;
  167. int err;
  168. err = sscanf(buf, "%u", &id);
  169. switch (err) {
  170. case 1:
  171. if (id > INT_MAX) {
  172. pr_err("Value of \"id\" is too big.\n");
  173. return -EINVAL;
  174. }
  175. break;
  176. default:
  177. pr_err("Format for deleting device is \"id\" (uint).\n");
  178. return -EINVAL;
  179. }
  180. err = -ENOENT;
  181. mutex_lock(&nsim_bus_dev_list_lock);
  182. list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
  183. if (nsim_bus_dev->dev.id != id)
  184. continue;
  185. list_del(&nsim_bus_dev->list);
  186. nsim_bus_dev_del(nsim_bus_dev);
  187. err = 0;
  188. break;
  189. }
  190. mutex_unlock(&nsim_bus_dev_list_lock);
  191. return !err ? count : err;
  192. }
  193. static BUS_ATTR_WO(del_device);
  194. static struct attribute *nsim_bus_attrs[] = {
  195. &bus_attr_new_device.attr,
  196. &bus_attr_del_device.attr,
  197. NULL
  198. };
  199. ATTRIBUTE_GROUPS(nsim_bus);
  200. static int nsim_bus_probe(struct device *dev)
  201. {
  202. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  203. return nsim_dev_probe(nsim_bus_dev);
  204. }
  205. static int nsim_bus_remove(struct device *dev)
  206. {
  207. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  208. nsim_dev_remove(nsim_bus_dev);
  209. return 0;
  210. }
  211. static int nsim_num_vf(struct device *dev)
  212. {
  213. struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  214. return nsim_bus_dev->num_vfs;
  215. }
  216. static struct bus_type nsim_bus = {
  217. .name = DRV_NAME,
  218. .dev_name = DRV_NAME,
  219. .bus_groups = nsim_bus_groups,
  220. .probe = nsim_bus_probe,
  221. .remove = nsim_bus_remove,
  222. .num_vf = nsim_num_vf,
  223. };
  224. static struct nsim_bus_dev *
  225. nsim_bus_dev_new(unsigned int id, unsigned int port_count)
  226. {
  227. struct nsim_bus_dev *nsim_bus_dev;
  228. int err;
  229. nsim_bus_dev = kzalloc(sizeof(*nsim_bus_dev), GFP_KERNEL);
  230. if (!nsim_bus_dev)
  231. return ERR_PTR(-ENOMEM);
  232. err = ida_alloc_range(&nsim_bus_dev_ids, id, id, GFP_KERNEL);
  233. if (err < 0)
  234. goto err_nsim_bus_dev_free;
  235. nsim_bus_dev->dev.id = err;
  236. nsim_bus_dev->dev.bus = &nsim_bus;
  237. nsim_bus_dev->dev.type = &nsim_bus_dev_type;
  238. nsim_bus_dev->port_count = port_count;
  239. err = device_register(&nsim_bus_dev->dev);
  240. if (err)
  241. goto err_nsim_bus_dev_id_free;
  242. return nsim_bus_dev;
  243. err_nsim_bus_dev_id_free:
  244. ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
  245. err_nsim_bus_dev_free:
  246. kfree(nsim_bus_dev);
  247. return ERR_PTR(err);
  248. }
  249. static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
  250. {
  251. device_unregister(&nsim_bus_dev->dev);
  252. ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
  253. kfree(nsim_bus_dev);
  254. }
  255. static struct device_driver nsim_driver = {
  256. .name = DRV_NAME,
  257. .bus = &nsim_bus,
  258. .owner = THIS_MODULE,
  259. };
  260. int nsim_bus_init(void)
  261. {
  262. int err;
  263. err = bus_register(&nsim_bus);
  264. if (err)
  265. return err;
  266. err = driver_register(&nsim_driver);
  267. if (err)
  268. goto err_bus_unregister;
  269. return 0;
  270. err_bus_unregister:
  271. bus_unregister(&nsim_bus);
  272. return err;
  273. }
  274. void nsim_bus_exit(void)
  275. {
  276. struct nsim_bus_dev *nsim_bus_dev, *tmp;
  277. mutex_lock(&nsim_bus_dev_list_lock);
  278. list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
  279. list_del(&nsim_bus_dev->list);
  280. nsim_bus_dev_del(nsim_bus_dev);
  281. }
  282. mutex_unlock(&nsim_bus_dev_list_lock);
  283. driver_unregister(&nsim_driver);
  284. bus_unregister(&nsim_bus);
  285. }