devlink.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. /*
  2. * net/core/devlink.c - Network physical/parent device Netlink interface
  3. *
  4. * Heavily inspired by net/wireless/
  5. * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
  6. * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/types.h>
  16. #include <linux/slab.h>
  17. #include <linux/gfp.h>
  18. #include <linux/device.h>
  19. #include <linux/list.h>
  20. #include <linux/netdevice.h>
  21. #include <rdma/ib_verbs.h>
  22. #include <net/netlink.h>
  23. #include <net/genetlink.h>
  24. #include <net/rtnetlink.h>
  25. #include <net/net_namespace.h>
  26. #include <net/sock.h>
  27. #include <net/devlink.h>
  28. static LIST_HEAD(devlink_list);
  29. /* devlink_mutex
  30. *
  31. * An overall lock guarding every operation coming from userspace.
  32. * It also guards devlink devices list and it is taken when
  33. * driver registers/unregisters it.
  34. */
  35. static DEFINE_MUTEX(devlink_mutex);
  36. /* devlink_port_mutex
  37. *
  38. * Shared lock to guard lists of ports in all devlink devices.
  39. */
  40. static DEFINE_MUTEX(devlink_port_mutex);
  41. static struct net *devlink_net(const struct devlink *devlink)
  42. {
  43. return read_pnet(&devlink->_net);
  44. }
  45. static void devlink_net_set(struct devlink *devlink, struct net *net)
  46. {
  47. write_pnet(&devlink->_net, net);
  48. }
  49. static struct devlink *devlink_get_from_attrs(struct net *net,
  50. struct nlattr **attrs)
  51. {
  52. struct devlink *devlink;
  53. char *busname;
  54. char *devname;
  55. if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
  56. return ERR_PTR(-EINVAL);
  57. busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
  58. devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
  59. list_for_each_entry(devlink, &devlink_list, list) {
  60. if (strcmp(devlink->dev->bus->name, busname) == 0 &&
  61. strcmp(dev_name(devlink->dev), devname) == 0 &&
  62. net_eq(devlink_net(devlink), net))
  63. return devlink;
  64. }
  65. return ERR_PTR(-ENODEV);
  66. }
  67. static struct devlink *devlink_get_from_info(struct genl_info *info)
  68. {
  69. return devlink_get_from_attrs(genl_info_net(info), info->attrs);
  70. }
  71. static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
  72. int port_index)
  73. {
  74. struct devlink_port *devlink_port;
  75. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  76. if (devlink_port->index == port_index)
  77. return devlink_port;
  78. }
  79. return NULL;
  80. }
  81. static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
  82. {
  83. return devlink_port_get_by_index(devlink, port_index);
  84. }
  85. static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
  86. struct nlattr **attrs)
  87. {
  88. if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
  89. u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
  90. struct devlink_port *devlink_port;
  91. devlink_port = devlink_port_get_by_index(devlink, port_index);
  92. if (!devlink_port)
  93. return ERR_PTR(-ENODEV);
  94. return devlink_port;
  95. }
  96. return ERR_PTR(-EINVAL);
  97. }
  98. static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
  99. struct genl_info *info)
  100. {
  101. return devlink_port_get_from_attrs(devlink, info->attrs);
  102. }
  103. #define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
  104. static int devlink_nl_pre_doit(const struct genl_ops *ops,
  105. struct sk_buff *skb, struct genl_info *info)
  106. {
  107. struct devlink *devlink;
  108. mutex_lock(&devlink_mutex);
  109. devlink = devlink_get_from_info(info);
  110. if (IS_ERR(devlink)) {
  111. mutex_unlock(&devlink_mutex);
  112. return PTR_ERR(devlink);
  113. }
  114. info->user_ptr[0] = devlink;
  115. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
  116. struct devlink_port *devlink_port;
  117. mutex_lock(&devlink_port_mutex);
  118. devlink_port = devlink_port_get_from_info(devlink, info);
  119. if (IS_ERR(devlink_port)) {
  120. mutex_unlock(&devlink_port_mutex);
  121. mutex_unlock(&devlink_mutex);
  122. return PTR_ERR(devlink_port);
  123. }
  124. info->user_ptr[1] = devlink_port;
  125. }
  126. return 0;
  127. }
  128. static void devlink_nl_post_doit(const struct genl_ops *ops,
  129. struct sk_buff *skb, struct genl_info *info)
  130. {
  131. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
  132. mutex_unlock(&devlink_port_mutex);
  133. mutex_unlock(&devlink_mutex);
  134. }
  135. static struct genl_family devlink_nl_family = {
  136. .id = GENL_ID_GENERATE,
  137. .name = DEVLINK_GENL_NAME,
  138. .version = DEVLINK_GENL_VERSION,
  139. .maxattr = DEVLINK_ATTR_MAX,
  140. .netnsok = true,
  141. .pre_doit = devlink_nl_pre_doit,
  142. .post_doit = devlink_nl_post_doit,
  143. };
  144. enum devlink_multicast_groups {
  145. DEVLINK_MCGRP_CONFIG,
  146. };
  147. static const struct genl_multicast_group devlink_nl_mcgrps[] = {
  148. [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
  149. };
  150. static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
  151. {
  152. if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
  153. return -EMSGSIZE;
  154. if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
  155. return -EMSGSIZE;
  156. return 0;
  157. }
  158. static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
  159. enum devlink_command cmd, u32 portid,
  160. u32 seq, int flags)
  161. {
  162. void *hdr;
  163. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  164. if (!hdr)
  165. return -EMSGSIZE;
  166. if (devlink_nl_put_handle(msg, devlink))
  167. goto nla_put_failure;
  168. genlmsg_end(msg, hdr);
  169. return 0;
  170. nla_put_failure:
  171. genlmsg_cancel(msg, hdr);
  172. return -EMSGSIZE;
  173. }
  174. static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
  175. {
  176. struct sk_buff *msg;
  177. int err;
  178. WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
  179. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  180. if (!msg)
  181. return;
  182. err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
  183. if (err) {
  184. nlmsg_free(msg);
  185. return;
  186. }
  187. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  188. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  189. }
  190. static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
  191. struct devlink_port *devlink_port,
  192. enum devlink_command cmd, u32 portid,
  193. u32 seq, int flags)
  194. {
  195. void *hdr;
  196. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  197. if (!hdr)
  198. return -EMSGSIZE;
  199. if (devlink_nl_put_handle(msg, devlink))
  200. goto nla_put_failure;
  201. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  202. goto nla_put_failure;
  203. if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
  204. goto nla_put_failure;
  205. if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
  206. nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
  207. devlink_port->desired_type))
  208. goto nla_put_failure;
  209. if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
  210. struct net_device *netdev = devlink_port->type_dev;
  211. if (netdev &&
  212. (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
  213. netdev->ifindex) ||
  214. nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
  215. netdev->name)))
  216. goto nla_put_failure;
  217. }
  218. if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
  219. struct ib_device *ibdev = devlink_port->type_dev;
  220. if (ibdev &&
  221. nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
  222. ibdev->name))
  223. goto nla_put_failure;
  224. }
  225. if (devlink_port->split &&
  226. nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
  227. devlink_port->split_group))
  228. goto nla_put_failure;
  229. genlmsg_end(msg, hdr);
  230. return 0;
  231. nla_put_failure:
  232. genlmsg_cancel(msg, hdr);
  233. return -EMSGSIZE;
  234. }
  235. static void devlink_port_notify(struct devlink_port *devlink_port,
  236. enum devlink_command cmd)
  237. {
  238. struct devlink *devlink = devlink_port->devlink;
  239. struct sk_buff *msg;
  240. int err;
  241. if (!devlink_port->registered)
  242. return;
  243. WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
  244. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  245. if (!msg)
  246. return;
  247. err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
  248. if (err) {
  249. nlmsg_free(msg);
  250. return;
  251. }
  252. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  253. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  254. }
  255. static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
  256. {
  257. struct devlink *devlink = info->user_ptr[0];
  258. struct sk_buff *msg;
  259. int err;
  260. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  261. if (!msg)
  262. return -ENOMEM;
  263. err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
  264. info->snd_portid, info->snd_seq, 0);
  265. if (err) {
  266. nlmsg_free(msg);
  267. return err;
  268. }
  269. return genlmsg_reply(msg, info);
  270. }
  271. static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
  272. struct netlink_callback *cb)
  273. {
  274. struct devlink *devlink;
  275. int start = cb->args[0];
  276. int idx = 0;
  277. int err;
  278. mutex_lock(&devlink_mutex);
  279. list_for_each_entry(devlink, &devlink_list, list) {
  280. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  281. continue;
  282. if (idx < start) {
  283. idx++;
  284. continue;
  285. }
  286. err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
  287. NETLINK_CB(cb->skb).portid,
  288. cb->nlh->nlmsg_seq, NLM_F_MULTI);
  289. if (err)
  290. goto out;
  291. idx++;
  292. }
  293. out:
  294. mutex_unlock(&devlink_mutex);
  295. cb->args[0] = idx;
  296. return msg->len;
  297. }
  298. static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
  299. struct genl_info *info)
  300. {
  301. struct devlink *devlink = info->user_ptr[0];
  302. struct devlink_port *devlink_port = info->user_ptr[1];
  303. struct sk_buff *msg;
  304. int err;
  305. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  306. if (!msg)
  307. return -ENOMEM;
  308. err = devlink_nl_port_fill(msg, devlink, devlink_port,
  309. DEVLINK_CMD_PORT_NEW,
  310. info->snd_portid, info->snd_seq, 0);
  311. if (err) {
  312. nlmsg_free(msg);
  313. return err;
  314. }
  315. return genlmsg_reply(msg, info);
  316. }
  317. static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
  318. struct netlink_callback *cb)
  319. {
  320. struct devlink *devlink;
  321. struct devlink_port *devlink_port;
  322. int start = cb->args[0];
  323. int idx = 0;
  324. int err;
  325. mutex_lock(&devlink_mutex);
  326. mutex_lock(&devlink_port_mutex);
  327. list_for_each_entry(devlink, &devlink_list, list) {
  328. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  329. continue;
  330. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  331. if (idx < start) {
  332. idx++;
  333. continue;
  334. }
  335. err = devlink_nl_port_fill(msg, devlink, devlink_port,
  336. DEVLINK_CMD_NEW,
  337. NETLINK_CB(cb->skb).portid,
  338. cb->nlh->nlmsg_seq,
  339. NLM_F_MULTI);
  340. if (err)
  341. goto out;
  342. idx++;
  343. }
  344. }
  345. out:
  346. mutex_unlock(&devlink_port_mutex);
  347. mutex_unlock(&devlink_mutex);
  348. cb->args[0] = idx;
  349. return msg->len;
  350. }
  351. static int devlink_port_type_set(struct devlink *devlink,
  352. struct devlink_port *devlink_port,
  353. enum devlink_port_type port_type)
  354. {
  355. int err;
  356. if (devlink->ops && devlink->ops->port_type_set) {
  357. if (port_type == DEVLINK_PORT_TYPE_NOTSET)
  358. return -EINVAL;
  359. err = devlink->ops->port_type_set(devlink_port, port_type);
  360. if (err)
  361. return err;
  362. devlink_port->desired_type = port_type;
  363. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  364. return 0;
  365. }
  366. return -EOPNOTSUPP;
  367. }
  368. static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
  369. struct genl_info *info)
  370. {
  371. struct devlink *devlink = info->user_ptr[0];
  372. struct devlink_port *devlink_port = info->user_ptr[1];
  373. int err;
  374. if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
  375. enum devlink_port_type port_type;
  376. port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
  377. err = devlink_port_type_set(devlink, devlink_port, port_type);
  378. if (err)
  379. return err;
  380. }
  381. return 0;
  382. }
  383. static int devlink_port_split(struct devlink *devlink,
  384. u32 port_index, u32 count)
  385. {
  386. if (devlink->ops && devlink->ops->port_split)
  387. return devlink->ops->port_split(devlink, port_index, count);
  388. return -EOPNOTSUPP;
  389. }
  390. static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
  391. struct genl_info *info)
  392. {
  393. struct devlink *devlink = info->user_ptr[0];
  394. u32 port_index;
  395. u32 count;
  396. if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
  397. !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
  398. return -EINVAL;
  399. port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  400. count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
  401. return devlink_port_split(devlink, port_index, count);
  402. }
  403. static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
  404. {
  405. if (devlink->ops && devlink->ops->port_unsplit)
  406. return devlink->ops->port_unsplit(devlink, port_index);
  407. return -EOPNOTSUPP;
  408. }
  409. static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
  410. struct genl_info *info)
  411. {
  412. struct devlink *devlink = info->user_ptr[0];
  413. u32 port_index;
  414. if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
  415. return -EINVAL;
  416. port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  417. return devlink_port_unsplit(devlink, port_index);
  418. }
  419. static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
  420. [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
  421. [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
  422. [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
  423. [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
  424. [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
  425. };
  426. static const struct genl_ops devlink_nl_ops[] = {
  427. {
  428. .cmd = DEVLINK_CMD_GET,
  429. .doit = devlink_nl_cmd_get_doit,
  430. .dumpit = devlink_nl_cmd_get_dumpit,
  431. .policy = devlink_nl_policy,
  432. /* can be retrieved by unprivileged users */
  433. },
  434. {
  435. .cmd = DEVLINK_CMD_PORT_GET,
  436. .doit = devlink_nl_cmd_port_get_doit,
  437. .dumpit = devlink_nl_cmd_port_get_dumpit,
  438. .policy = devlink_nl_policy,
  439. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  440. /* can be retrieved by unprivileged users */
  441. },
  442. {
  443. .cmd = DEVLINK_CMD_PORT_SET,
  444. .doit = devlink_nl_cmd_port_set_doit,
  445. .policy = devlink_nl_policy,
  446. .flags = GENL_ADMIN_PERM,
  447. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  448. },
  449. {
  450. .cmd = DEVLINK_CMD_PORT_SPLIT,
  451. .doit = devlink_nl_cmd_port_split_doit,
  452. .policy = devlink_nl_policy,
  453. .flags = GENL_ADMIN_PERM,
  454. },
  455. {
  456. .cmd = DEVLINK_CMD_PORT_UNSPLIT,
  457. .doit = devlink_nl_cmd_port_unsplit_doit,
  458. .policy = devlink_nl_policy,
  459. .flags = GENL_ADMIN_PERM,
  460. },
  461. };
  462. /**
  463. * devlink_alloc - Allocate new devlink instance resources
  464. *
  465. * @ops: ops
  466. * @priv_size: size of user private data
  467. *
  468. * Allocate new devlink instance resources, including devlink index
  469. * and name.
  470. */
  471. struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
  472. {
  473. struct devlink *devlink;
  474. devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
  475. if (!devlink)
  476. return NULL;
  477. devlink->ops = ops;
  478. devlink_net_set(devlink, &init_net);
  479. INIT_LIST_HEAD(&devlink->port_list);
  480. return devlink;
  481. }
  482. EXPORT_SYMBOL_GPL(devlink_alloc);
  483. /**
  484. * devlink_register - Register devlink instance
  485. *
  486. * @devlink: devlink
  487. */
  488. int devlink_register(struct devlink *devlink, struct device *dev)
  489. {
  490. mutex_lock(&devlink_mutex);
  491. devlink->dev = dev;
  492. list_add_tail(&devlink->list, &devlink_list);
  493. devlink_notify(devlink, DEVLINK_CMD_NEW);
  494. mutex_unlock(&devlink_mutex);
  495. return 0;
  496. }
  497. EXPORT_SYMBOL_GPL(devlink_register);
  498. /**
  499. * devlink_unregister - Unregister devlink instance
  500. *
  501. * @devlink: devlink
  502. */
  503. void devlink_unregister(struct devlink *devlink)
  504. {
  505. mutex_lock(&devlink_mutex);
  506. devlink_notify(devlink, DEVLINK_CMD_DEL);
  507. list_del(&devlink->list);
  508. mutex_unlock(&devlink_mutex);
  509. }
  510. EXPORT_SYMBOL_GPL(devlink_unregister);
  511. /**
  512. * devlink_free - Free devlink instance resources
  513. *
  514. * @devlink: devlink
  515. */
  516. void devlink_free(struct devlink *devlink)
  517. {
  518. kfree(devlink);
  519. }
  520. EXPORT_SYMBOL_GPL(devlink_free);
  521. /**
  522. * devlink_port_register - Register devlink port
  523. *
  524. * @devlink: devlink
  525. * @devlink_port: devlink port
  526. * @port_index
  527. *
  528. * Register devlink port with provided port index. User can use
  529. * any indexing, even hw-related one. devlink_port structure
  530. * is convenient to be embedded inside user driver private structure.
  531. * Note that the caller should take care of zeroing the devlink_port
  532. * structure.
  533. */
  534. int devlink_port_register(struct devlink *devlink,
  535. struct devlink_port *devlink_port,
  536. unsigned int port_index)
  537. {
  538. mutex_lock(&devlink_port_mutex);
  539. if (devlink_port_index_exists(devlink, port_index)) {
  540. mutex_unlock(&devlink_port_mutex);
  541. return -EEXIST;
  542. }
  543. devlink_port->devlink = devlink;
  544. devlink_port->index = port_index;
  545. devlink_port->type = DEVLINK_PORT_TYPE_NOTSET;
  546. devlink_port->registered = true;
  547. list_add_tail(&devlink_port->list, &devlink->port_list);
  548. mutex_unlock(&devlink_port_mutex);
  549. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  550. return 0;
  551. }
  552. EXPORT_SYMBOL_GPL(devlink_port_register);
  553. /**
  554. * devlink_port_unregister - Unregister devlink port
  555. *
  556. * @devlink_port: devlink port
  557. */
  558. void devlink_port_unregister(struct devlink_port *devlink_port)
  559. {
  560. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
  561. mutex_lock(&devlink_port_mutex);
  562. list_del(&devlink_port->list);
  563. mutex_unlock(&devlink_port_mutex);
  564. }
  565. EXPORT_SYMBOL_GPL(devlink_port_unregister);
  566. static void __devlink_port_type_set(struct devlink_port *devlink_port,
  567. enum devlink_port_type type,
  568. void *type_dev)
  569. {
  570. devlink_port->type = type;
  571. devlink_port->type_dev = type_dev;
  572. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  573. }
  574. /**
  575. * devlink_port_type_eth_set - Set port type to Ethernet
  576. *
  577. * @devlink_port: devlink port
  578. * @netdev: related netdevice
  579. */
  580. void devlink_port_type_eth_set(struct devlink_port *devlink_port,
  581. struct net_device *netdev)
  582. {
  583. return __devlink_port_type_set(devlink_port,
  584. DEVLINK_PORT_TYPE_ETH, netdev);
  585. }
  586. EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
  587. /**
  588. * devlink_port_type_ib_set - Set port type to InfiniBand
  589. *
  590. * @devlink_port: devlink port
  591. * @ibdev: related IB device
  592. */
  593. void devlink_port_type_ib_set(struct devlink_port *devlink_port,
  594. struct ib_device *ibdev)
  595. {
  596. return __devlink_port_type_set(devlink_port,
  597. DEVLINK_PORT_TYPE_IB, ibdev);
  598. }
  599. EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
  600. /**
  601. * devlink_port_type_clear - Clear port type
  602. *
  603. * @devlink_port: devlink port
  604. */
  605. void devlink_port_type_clear(struct devlink_port *devlink_port)
  606. {
  607. return __devlink_port_type_set(devlink_port,
  608. DEVLINK_PORT_TYPE_NOTSET, NULL);
  609. }
  610. EXPORT_SYMBOL_GPL(devlink_port_type_clear);
  611. /**
  612. * devlink_port_split_set - Set port is split
  613. *
  614. * @devlink_port: devlink port
  615. * @split_group: split group - identifies group split port is part of
  616. */
  617. void devlink_port_split_set(struct devlink_port *devlink_port,
  618. u32 split_group)
  619. {
  620. devlink_port->split = true;
  621. devlink_port->split_group = split_group;
  622. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  623. }
  624. EXPORT_SYMBOL_GPL(devlink_port_split_set);
  625. static int __init devlink_module_init(void)
  626. {
  627. return genl_register_family_with_ops_groups(&devlink_nl_family,
  628. devlink_nl_ops,
  629. devlink_nl_mcgrps);
  630. }
  631. static void __exit devlink_module_exit(void)
  632. {
  633. genl_unregister_family(&devlink_nl_family);
  634. }
  635. module_init(devlink_module_init);
  636. module_exit(devlink_module_exit);
  637. MODULE_LICENSE("GPL v2");
  638. MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
  639. MODULE_DESCRIPTION("Network physical device Netlink interface");
  640. MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);