devlink.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860
  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. #define CREATE_TRACE_POINTS
  29. #include <trace/events/devlink.h>
  30. EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
  31. static LIST_HEAD(devlink_list);
  32. /* devlink_mutex
  33. *
  34. * An overall lock guarding every operation coming from userspace.
  35. * It also guards devlink devices list and it is taken when
  36. * driver registers/unregisters it.
  37. */
  38. static DEFINE_MUTEX(devlink_mutex);
  39. /* devlink_port_mutex
  40. *
  41. * Shared lock to guard lists of ports in all devlink devices.
  42. */
  43. static DEFINE_MUTEX(devlink_port_mutex);
  44. static struct net *devlink_net(const struct devlink *devlink)
  45. {
  46. return read_pnet(&devlink->_net);
  47. }
  48. static void devlink_net_set(struct devlink *devlink, struct net *net)
  49. {
  50. write_pnet(&devlink->_net, net);
  51. }
  52. static struct devlink *devlink_get_from_attrs(struct net *net,
  53. struct nlattr **attrs)
  54. {
  55. struct devlink *devlink;
  56. char *busname;
  57. char *devname;
  58. if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
  59. return ERR_PTR(-EINVAL);
  60. busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
  61. devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
  62. list_for_each_entry(devlink, &devlink_list, list) {
  63. if (strcmp(devlink->dev->bus->name, busname) == 0 &&
  64. strcmp(dev_name(devlink->dev), devname) == 0 &&
  65. net_eq(devlink_net(devlink), net))
  66. return devlink;
  67. }
  68. return ERR_PTR(-ENODEV);
  69. }
  70. static struct devlink *devlink_get_from_info(struct genl_info *info)
  71. {
  72. return devlink_get_from_attrs(genl_info_net(info), info->attrs);
  73. }
  74. static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
  75. int port_index)
  76. {
  77. struct devlink_port *devlink_port;
  78. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  79. if (devlink_port->index == port_index)
  80. return devlink_port;
  81. }
  82. return NULL;
  83. }
  84. static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
  85. {
  86. return devlink_port_get_by_index(devlink, port_index);
  87. }
  88. static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
  89. struct nlattr **attrs)
  90. {
  91. if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
  92. u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
  93. struct devlink_port *devlink_port;
  94. devlink_port = devlink_port_get_by_index(devlink, port_index);
  95. if (!devlink_port)
  96. return ERR_PTR(-ENODEV);
  97. return devlink_port;
  98. }
  99. return ERR_PTR(-EINVAL);
  100. }
  101. static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
  102. struct genl_info *info)
  103. {
  104. return devlink_port_get_from_attrs(devlink, info->attrs);
  105. }
  106. struct devlink_sb {
  107. struct list_head list;
  108. unsigned int index;
  109. u32 size;
  110. u16 ingress_pools_count;
  111. u16 egress_pools_count;
  112. u16 ingress_tc_count;
  113. u16 egress_tc_count;
  114. };
  115. static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
  116. {
  117. return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
  118. }
  119. static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
  120. unsigned int sb_index)
  121. {
  122. struct devlink_sb *devlink_sb;
  123. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  124. if (devlink_sb->index == sb_index)
  125. return devlink_sb;
  126. }
  127. return NULL;
  128. }
  129. static bool devlink_sb_index_exists(struct devlink *devlink,
  130. unsigned int sb_index)
  131. {
  132. return devlink_sb_get_by_index(devlink, sb_index);
  133. }
  134. static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
  135. struct nlattr **attrs)
  136. {
  137. if (attrs[DEVLINK_ATTR_SB_INDEX]) {
  138. u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
  139. struct devlink_sb *devlink_sb;
  140. devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
  141. if (!devlink_sb)
  142. return ERR_PTR(-ENODEV);
  143. return devlink_sb;
  144. }
  145. return ERR_PTR(-EINVAL);
  146. }
  147. static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
  148. struct genl_info *info)
  149. {
  150. return devlink_sb_get_from_attrs(devlink, info->attrs);
  151. }
  152. static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
  153. struct nlattr **attrs,
  154. u16 *p_pool_index)
  155. {
  156. u16 val;
  157. if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
  158. return -EINVAL;
  159. val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
  160. if (val >= devlink_sb_pool_count(devlink_sb))
  161. return -EINVAL;
  162. *p_pool_index = val;
  163. return 0;
  164. }
  165. static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
  166. struct genl_info *info,
  167. u16 *p_pool_index)
  168. {
  169. return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
  170. p_pool_index);
  171. }
  172. static int
  173. devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
  174. enum devlink_sb_pool_type *p_pool_type)
  175. {
  176. u8 val;
  177. if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
  178. return -EINVAL;
  179. val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
  180. if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
  181. val != DEVLINK_SB_POOL_TYPE_EGRESS)
  182. return -EINVAL;
  183. *p_pool_type = val;
  184. return 0;
  185. }
  186. static int
  187. devlink_sb_pool_type_get_from_info(struct genl_info *info,
  188. enum devlink_sb_pool_type *p_pool_type)
  189. {
  190. return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
  191. }
  192. static int
  193. devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
  194. enum devlink_sb_threshold_type *p_th_type)
  195. {
  196. u8 val;
  197. if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
  198. return -EINVAL;
  199. val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
  200. if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
  201. val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
  202. return -EINVAL;
  203. *p_th_type = val;
  204. return 0;
  205. }
  206. static int
  207. devlink_sb_th_type_get_from_info(struct genl_info *info,
  208. enum devlink_sb_threshold_type *p_th_type)
  209. {
  210. return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
  211. }
  212. static int
  213. devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
  214. struct nlattr **attrs,
  215. enum devlink_sb_pool_type pool_type,
  216. u16 *p_tc_index)
  217. {
  218. u16 val;
  219. if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
  220. return -EINVAL;
  221. val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
  222. if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
  223. val >= devlink_sb->ingress_tc_count)
  224. return -EINVAL;
  225. if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
  226. val >= devlink_sb->egress_tc_count)
  227. return -EINVAL;
  228. *p_tc_index = val;
  229. return 0;
  230. }
  231. static int
  232. devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
  233. struct genl_info *info,
  234. enum devlink_sb_pool_type pool_type,
  235. u16 *p_tc_index)
  236. {
  237. return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
  238. pool_type, p_tc_index);
  239. }
  240. #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
  241. #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
  242. #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
  243. #define DEVLINK_NL_FLAG_LOCK_PORTS BIT(3)
  244. /* port is not needed but we need to ensure they don't
  245. * change in the middle of command
  246. */
  247. static int devlink_nl_pre_doit(const struct genl_ops *ops,
  248. struct sk_buff *skb, struct genl_info *info)
  249. {
  250. struct devlink *devlink;
  251. mutex_lock(&devlink_mutex);
  252. devlink = devlink_get_from_info(info);
  253. if (IS_ERR(devlink)) {
  254. mutex_unlock(&devlink_mutex);
  255. return PTR_ERR(devlink);
  256. }
  257. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
  258. info->user_ptr[0] = devlink;
  259. } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
  260. struct devlink_port *devlink_port;
  261. mutex_lock(&devlink_port_mutex);
  262. devlink_port = devlink_port_get_from_info(devlink, info);
  263. if (IS_ERR(devlink_port)) {
  264. mutex_unlock(&devlink_port_mutex);
  265. mutex_unlock(&devlink_mutex);
  266. return PTR_ERR(devlink_port);
  267. }
  268. info->user_ptr[0] = devlink_port;
  269. }
  270. if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
  271. mutex_lock(&devlink_port_mutex);
  272. }
  273. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
  274. struct devlink_sb *devlink_sb;
  275. devlink_sb = devlink_sb_get_from_info(devlink, info);
  276. if (IS_ERR(devlink_sb)) {
  277. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
  278. mutex_unlock(&devlink_port_mutex);
  279. mutex_unlock(&devlink_mutex);
  280. return PTR_ERR(devlink_sb);
  281. }
  282. info->user_ptr[1] = devlink_sb;
  283. }
  284. return 0;
  285. }
  286. static void devlink_nl_post_doit(const struct genl_ops *ops,
  287. struct sk_buff *skb, struct genl_info *info)
  288. {
  289. if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
  290. ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
  291. mutex_unlock(&devlink_port_mutex);
  292. mutex_unlock(&devlink_mutex);
  293. }
  294. static struct genl_family devlink_nl_family = {
  295. .id = GENL_ID_GENERATE,
  296. .name = DEVLINK_GENL_NAME,
  297. .version = DEVLINK_GENL_VERSION,
  298. .maxattr = DEVLINK_ATTR_MAX,
  299. .netnsok = true,
  300. .pre_doit = devlink_nl_pre_doit,
  301. .post_doit = devlink_nl_post_doit,
  302. };
  303. enum devlink_multicast_groups {
  304. DEVLINK_MCGRP_CONFIG,
  305. };
  306. static const struct genl_multicast_group devlink_nl_mcgrps[] = {
  307. [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
  308. };
  309. static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
  310. {
  311. if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
  312. return -EMSGSIZE;
  313. if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
  314. return -EMSGSIZE;
  315. return 0;
  316. }
  317. static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
  318. enum devlink_command cmd, u32 portid,
  319. u32 seq, int flags)
  320. {
  321. void *hdr;
  322. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  323. if (!hdr)
  324. return -EMSGSIZE;
  325. if (devlink_nl_put_handle(msg, devlink))
  326. goto nla_put_failure;
  327. genlmsg_end(msg, hdr);
  328. return 0;
  329. nla_put_failure:
  330. genlmsg_cancel(msg, hdr);
  331. return -EMSGSIZE;
  332. }
  333. static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
  334. {
  335. struct sk_buff *msg;
  336. int err;
  337. WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
  338. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  339. if (!msg)
  340. return;
  341. err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
  342. if (err) {
  343. nlmsg_free(msg);
  344. return;
  345. }
  346. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  347. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  348. }
  349. static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
  350. struct devlink_port *devlink_port,
  351. enum devlink_command cmd, u32 portid,
  352. u32 seq, int flags)
  353. {
  354. void *hdr;
  355. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  356. if (!hdr)
  357. return -EMSGSIZE;
  358. if (devlink_nl_put_handle(msg, devlink))
  359. goto nla_put_failure;
  360. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  361. goto nla_put_failure;
  362. if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
  363. goto nla_put_failure;
  364. if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
  365. nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
  366. devlink_port->desired_type))
  367. goto nla_put_failure;
  368. if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
  369. struct net_device *netdev = devlink_port->type_dev;
  370. if (netdev &&
  371. (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
  372. netdev->ifindex) ||
  373. nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
  374. netdev->name)))
  375. goto nla_put_failure;
  376. }
  377. if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
  378. struct ib_device *ibdev = devlink_port->type_dev;
  379. if (ibdev &&
  380. nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
  381. ibdev->name))
  382. goto nla_put_failure;
  383. }
  384. if (devlink_port->split &&
  385. nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
  386. devlink_port->split_group))
  387. goto nla_put_failure;
  388. genlmsg_end(msg, hdr);
  389. return 0;
  390. nla_put_failure:
  391. genlmsg_cancel(msg, hdr);
  392. return -EMSGSIZE;
  393. }
  394. static void devlink_port_notify(struct devlink_port *devlink_port,
  395. enum devlink_command cmd)
  396. {
  397. struct devlink *devlink = devlink_port->devlink;
  398. struct sk_buff *msg;
  399. int err;
  400. if (!devlink_port->registered)
  401. return;
  402. WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
  403. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  404. if (!msg)
  405. return;
  406. err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
  407. if (err) {
  408. nlmsg_free(msg);
  409. return;
  410. }
  411. genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
  412. msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
  413. }
  414. static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
  415. {
  416. struct devlink *devlink = info->user_ptr[0];
  417. struct sk_buff *msg;
  418. int err;
  419. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  420. if (!msg)
  421. return -ENOMEM;
  422. err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
  423. info->snd_portid, info->snd_seq, 0);
  424. if (err) {
  425. nlmsg_free(msg);
  426. return err;
  427. }
  428. return genlmsg_reply(msg, info);
  429. }
  430. static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
  431. struct netlink_callback *cb)
  432. {
  433. struct devlink *devlink;
  434. int start = cb->args[0];
  435. int idx = 0;
  436. int err;
  437. mutex_lock(&devlink_mutex);
  438. list_for_each_entry(devlink, &devlink_list, list) {
  439. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  440. continue;
  441. if (idx < start) {
  442. idx++;
  443. continue;
  444. }
  445. err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
  446. NETLINK_CB(cb->skb).portid,
  447. cb->nlh->nlmsg_seq, NLM_F_MULTI);
  448. if (err)
  449. goto out;
  450. idx++;
  451. }
  452. out:
  453. mutex_unlock(&devlink_mutex);
  454. cb->args[0] = idx;
  455. return msg->len;
  456. }
  457. static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
  458. struct genl_info *info)
  459. {
  460. struct devlink_port *devlink_port = info->user_ptr[0];
  461. struct devlink *devlink = devlink_port->devlink;
  462. struct sk_buff *msg;
  463. int err;
  464. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  465. if (!msg)
  466. return -ENOMEM;
  467. err = devlink_nl_port_fill(msg, devlink, devlink_port,
  468. DEVLINK_CMD_PORT_NEW,
  469. info->snd_portid, info->snd_seq, 0);
  470. if (err) {
  471. nlmsg_free(msg);
  472. return err;
  473. }
  474. return genlmsg_reply(msg, info);
  475. }
  476. static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
  477. struct netlink_callback *cb)
  478. {
  479. struct devlink *devlink;
  480. struct devlink_port *devlink_port;
  481. int start = cb->args[0];
  482. int idx = 0;
  483. int err;
  484. mutex_lock(&devlink_mutex);
  485. mutex_lock(&devlink_port_mutex);
  486. list_for_each_entry(devlink, &devlink_list, list) {
  487. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  488. continue;
  489. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  490. if (idx < start) {
  491. idx++;
  492. continue;
  493. }
  494. err = devlink_nl_port_fill(msg, devlink, devlink_port,
  495. DEVLINK_CMD_NEW,
  496. NETLINK_CB(cb->skb).portid,
  497. cb->nlh->nlmsg_seq,
  498. NLM_F_MULTI);
  499. if (err)
  500. goto out;
  501. idx++;
  502. }
  503. }
  504. out:
  505. mutex_unlock(&devlink_port_mutex);
  506. mutex_unlock(&devlink_mutex);
  507. cb->args[0] = idx;
  508. return msg->len;
  509. }
  510. static int devlink_port_type_set(struct devlink *devlink,
  511. struct devlink_port *devlink_port,
  512. enum devlink_port_type port_type)
  513. {
  514. int err;
  515. if (devlink->ops && devlink->ops->port_type_set) {
  516. if (port_type == DEVLINK_PORT_TYPE_NOTSET)
  517. return -EINVAL;
  518. err = devlink->ops->port_type_set(devlink_port, port_type);
  519. if (err)
  520. return err;
  521. devlink_port->desired_type = port_type;
  522. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  523. return 0;
  524. }
  525. return -EOPNOTSUPP;
  526. }
  527. static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
  528. struct genl_info *info)
  529. {
  530. struct devlink_port *devlink_port = info->user_ptr[0];
  531. struct devlink *devlink = devlink_port->devlink;
  532. int err;
  533. if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
  534. enum devlink_port_type port_type;
  535. port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
  536. err = devlink_port_type_set(devlink, devlink_port, port_type);
  537. if (err)
  538. return err;
  539. }
  540. return 0;
  541. }
  542. static int devlink_port_split(struct devlink *devlink,
  543. u32 port_index, u32 count)
  544. {
  545. if (devlink->ops && devlink->ops->port_split)
  546. return devlink->ops->port_split(devlink, port_index, count);
  547. return -EOPNOTSUPP;
  548. }
  549. static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
  550. struct genl_info *info)
  551. {
  552. struct devlink *devlink = info->user_ptr[0];
  553. u32 port_index;
  554. u32 count;
  555. if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
  556. !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
  557. return -EINVAL;
  558. port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  559. count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
  560. return devlink_port_split(devlink, port_index, count);
  561. }
  562. static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
  563. {
  564. if (devlink->ops && devlink->ops->port_unsplit)
  565. return devlink->ops->port_unsplit(devlink, port_index);
  566. return -EOPNOTSUPP;
  567. }
  568. static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
  569. struct genl_info *info)
  570. {
  571. struct devlink *devlink = info->user_ptr[0];
  572. u32 port_index;
  573. if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
  574. return -EINVAL;
  575. port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
  576. return devlink_port_unsplit(devlink, port_index);
  577. }
  578. static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
  579. struct devlink_sb *devlink_sb,
  580. enum devlink_command cmd, u32 portid,
  581. u32 seq, int flags)
  582. {
  583. void *hdr;
  584. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  585. if (!hdr)
  586. return -EMSGSIZE;
  587. if (devlink_nl_put_handle(msg, devlink))
  588. goto nla_put_failure;
  589. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  590. goto nla_put_failure;
  591. if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
  592. goto nla_put_failure;
  593. if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
  594. devlink_sb->ingress_pools_count))
  595. goto nla_put_failure;
  596. if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
  597. devlink_sb->egress_pools_count))
  598. goto nla_put_failure;
  599. if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
  600. devlink_sb->ingress_tc_count))
  601. goto nla_put_failure;
  602. if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
  603. devlink_sb->egress_tc_count))
  604. goto nla_put_failure;
  605. genlmsg_end(msg, hdr);
  606. return 0;
  607. nla_put_failure:
  608. genlmsg_cancel(msg, hdr);
  609. return -EMSGSIZE;
  610. }
  611. static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
  612. struct genl_info *info)
  613. {
  614. struct devlink *devlink = info->user_ptr[0];
  615. struct devlink_sb *devlink_sb = info->user_ptr[1];
  616. struct sk_buff *msg;
  617. int err;
  618. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  619. if (!msg)
  620. return -ENOMEM;
  621. err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
  622. DEVLINK_CMD_SB_NEW,
  623. info->snd_portid, info->snd_seq, 0);
  624. if (err) {
  625. nlmsg_free(msg);
  626. return err;
  627. }
  628. return genlmsg_reply(msg, info);
  629. }
  630. static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
  631. struct netlink_callback *cb)
  632. {
  633. struct devlink *devlink;
  634. struct devlink_sb *devlink_sb;
  635. int start = cb->args[0];
  636. int idx = 0;
  637. int err;
  638. mutex_lock(&devlink_mutex);
  639. list_for_each_entry(devlink, &devlink_list, list) {
  640. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
  641. continue;
  642. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  643. if (idx < start) {
  644. idx++;
  645. continue;
  646. }
  647. err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
  648. DEVLINK_CMD_SB_NEW,
  649. NETLINK_CB(cb->skb).portid,
  650. cb->nlh->nlmsg_seq,
  651. NLM_F_MULTI);
  652. if (err)
  653. goto out;
  654. idx++;
  655. }
  656. }
  657. out:
  658. mutex_unlock(&devlink_mutex);
  659. cb->args[0] = idx;
  660. return msg->len;
  661. }
  662. static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
  663. struct devlink_sb *devlink_sb,
  664. u16 pool_index, enum devlink_command cmd,
  665. u32 portid, u32 seq, int flags)
  666. {
  667. struct devlink_sb_pool_info pool_info;
  668. void *hdr;
  669. int err;
  670. err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
  671. pool_index, &pool_info);
  672. if (err)
  673. return err;
  674. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  675. if (!hdr)
  676. return -EMSGSIZE;
  677. if (devlink_nl_put_handle(msg, devlink))
  678. goto nla_put_failure;
  679. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  680. goto nla_put_failure;
  681. if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
  682. goto nla_put_failure;
  683. if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
  684. goto nla_put_failure;
  685. if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
  686. goto nla_put_failure;
  687. if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
  688. pool_info.threshold_type))
  689. goto nla_put_failure;
  690. genlmsg_end(msg, hdr);
  691. return 0;
  692. nla_put_failure:
  693. genlmsg_cancel(msg, hdr);
  694. return -EMSGSIZE;
  695. }
  696. static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
  697. struct genl_info *info)
  698. {
  699. struct devlink *devlink = info->user_ptr[0];
  700. struct devlink_sb *devlink_sb = info->user_ptr[1];
  701. struct sk_buff *msg;
  702. u16 pool_index;
  703. int err;
  704. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  705. &pool_index);
  706. if (err)
  707. return err;
  708. if (!devlink->ops || !devlink->ops->sb_pool_get)
  709. return -EOPNOTSUPP;
  710. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  711. if (!msg)
  712. return -ENOMEM;
  713. err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
  714. DEVLINK_CMD_SB_POOL_NEW,
  715. info->snd_portid, info->snd_seq, 0);
  716. if (err) {
  717. nlmsg_free(msg);
  718. return err;
  719. }
  720. return genlmsg_reply(msg, info);
  721. }
  722. static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
  723. struct devlink *devlink,
  724. struct devlink_sb *devlink_sb,
  725. u32 portid, u32 seq)
  726. {
  727. u16 pool_count = devlink_sb_pool_count(devlink_sb);
  728. u16 pool_index;
  729. int err;
  730. for (pool_index = 0; pool_index < pool_count; pool_index++) {
  731. if (*p_idx < start) {
  732. (*p_idx)++;
  733. continue;
  734. }
  735. err = devlink_nl_sb_pool_fill(msg, devlink,
  736. devlink_sb,
  737. pool_index,
  738. DEVLINK_CMD_SB_POOL_NEW,
  739. portid, seq, NLM_F_MULTI);
  740. if (err)
  741. return err;
  742. (*p_idx)++;
  743. }
  744. return 0;
  745. }
  746. static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
  747. struct netlink_callback *cb)
  748. {
  749. struct devlink *devlink;
  750. struct devlink_sb *devlink_sb;
  751. int start = cb->args[0];
  752. int idx = 0;
  753. int err;
  754. mutex_lock(&devlink_mutex);
  755. list_for_each_entry(devlink, &devlink_list, list) {
  756. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
  757. !devlink->ops || !devlink->ops->sb_pool_get)
  758. continue;
  759. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  760. err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
  761. devlink_sb,
  762. NETLINK_CB(cb->skb).portid,
  763. cb->nlh->nlmsg_seq);
  764. if (err && err != -EOPNOTSUPP)
  765. goto out;
  766. }
  767. }
  768. out:
  769. mutex_unlock(&devlink_mutex);
  770. cb->args[0] = idx;
  771. return msg->len;
  772. }
  773. static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
  774. u16 pool_index, u32 size,
  775. enum devlink_sb_threshold_type threshold_type)
  776. {
  777. const struct devlink_ops *ops = devlink->ops;
  778. if (ops && ops->sb_pool_set)
  779. return ops->sb_pool_set(devlink, sb_index, pool_index,
  780. size, threshold_type);
  781. return -EOPNOTSUPP;
  782. }
  783. static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
  784. struct genl_info *info)
  785. {
  786. struct devlink *devlink = info->user_ptr[0];
  787. struct devlink_sb *devlink_sb = info->user_ptr[1];
  788. enum devlink_sb_threshold_type threshold_type;
  789. u16 pool_index;
  790. u32 size;
  791. int err;
  792. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  793. &pool_index);
  794. if (err)
  795. return err;
  796. err = devlink_sb_th_type_get_from_info(info, &threshold_type);
  797. if (err)
  798. return err;
  799. if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
  800. return -EINVAL;
  801. size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
  802. return devlink_sb_pool_set(devlink, devlink_sb->index,
  803. pool_index, size, threshold_type);
  804. }
  805. static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
  806. struct devlink *devlink,
  807. struct devlink_port *devlink_port,
  808. struct devlink_sb *devlink_sb,
  809. u16 pool_index,
  810. enum devlink_command cmd,
  811. u32 portid, u32 seq, int flags)
  812. {
  813. const struct devlink_ops *ops = devlink->ops;
  814. u32 threshold;
  815. void *hdr;
  816. int err;
  817. err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
  818. pool_index, &threshold);
  819. if (err)
  820. return err;
  821. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  822. if (!hdr)
  823. return -EMSGSIZE;
  824. if (devlink_nl_put_handle(msg, devlink))
  825. goto nla_put_failure;
  826. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  827. goto nla_put_failure;
  828. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  829. goto nla_put_failure;
  830. if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
  831. goto nla_put_failure;
  832. if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
  833. goto nla_put_failure;
  834. if (ops->sb_occ_port_pool_get) {
  835. u32 cur;
  836. u32 max;
  837. err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
  838. pool_index, &cur, &max);
  839. if (err && err != -EOPNOTSUPP)
  840. return err;
  841. if (!err) {
  842. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
  843. goto nla_put_failure;
  844. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
  845. goto nla_put_failure;
  846. }
  847. }
  848. genlmsg_end(msg, hdr);
  849. return 0;
  850. nla_put_failure:
  851. genlmsg_cancel(msg, hdr);
  852. return -EMSGSIZE;
  853. }
  854. static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
  855. struct genl_info *info)
  856. {
  857. struct devlink_port *devlink_port = info->user_ptr[0];
  858. struct devlink *devlink = devlink_port->devlink;
  859. struct devlink_sb *devlink_sb = info->user_ptr[1];
  860. struct sk_buff *msg;
  861. u16 pool_index;
  862. int err;
  863. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  864. &pool_index);
  865. if (err)
  866. return err;
  867. if (!devlink->ops || !devlink->ops->sb_port_pool_get)
  868. return -EOPNOTSUPP;
  869. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  870. if (!msg)
  871. return -ENOMEM;
  872. err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
  873. devlink_sb, pool_index,
  874. DEVLINK_CMD_SB_PORT_POOL_NEW,
  875. info->snd_portid, info->snd_seq, 0);
  876. if (err) {
  877. nlmsg_free(msg);
  878. return err;
  879. }
  880. return genlmsg_reply(msg, info);
  881. }
  882. static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
  883. struct devlink *devlink,
  884. struct devlink_sb *devlink_sb,
  885. u32 portid, u32 seq)
  886. {
  887. struct devlink_port *devlink_port;
  888. u16 pool_count = devlink_sb_pool_count(devlink_sb);
  889. u16 pool_index;
  890. int err;
  891. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  892. for (pool_index = 0; pool_index < pool_count; pool_index++) {
  893. if (*p_idx < start) {
  894. (*p_idx)++;
  895. continue;
  896. }
  897. err = devlink_nl_sb_port_pool_fill(msg, devlink,
  898. devlink_port,
  899. devlink_sb,
  900. pool_index,
  901. DEVLINK_CMD_SB_PORT_POOL_NEW,
  902. portid, seq,
  903. NLM_F_MULTI);
  904. if (err)
  905. return err;
  906. (*p_idx)++;
  907. }
  908. }
  909. return 0;
  910. }
  911. static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
  912. struct netlink_callback *cb)
  913. {
  914. struct devlink *devlink;
  915. struct devlink_sb *devlink_sb;
  916. int start = cb->args[0];
  917. int idx = 0;
  918. int err;
  919. mutex_lock(&devlink_mutex);
  920. mutex_lock(&devlink_port_mutex);
  921. list_for_each_entry(devlink, &devlink_list, list) {
  922. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
  923. !devlink->ops || !devlink->ops->sb_port_pool_get)
  924. continue;
  925. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  926. err = __sb_port_pool_get_dumpit(msg, start, &idx,
  927. devlink, devlink_sb,
  928. NETLINK_CB(cb->skb).portid,
  929. cb->nlh->nlmsg_seq);
  930. if (err && err != -EOPNOTSUPP)
  931. goto out;
  932. }
  933. }
  934. out:
  935. mutex_unlock(&devlink_port_mutex);
  936. mutex_unlock(&devlink_mutex);
  937. cb->args[0] = idx;
  938. return msg->len;
  939. }
  940. static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
  941. unsigned int sb_index, u16 pool_index,
  942. u32 threshold)
  943. {
  944. const struct devlink_ops *ops = devlink_port->devlink->ops;
  945. if (ops && ops->sb_port_pool_set)
  946. return ops->sb_port_pool_set(devlink_port, sb_index,
  947. pool_index, threshold);
  948. return -EOPNOTSUPP;
  949. }
  950. static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
  951. struct genl_info *info)
  952. {
  953. struct devlink_port *devlink_port = info->user_ptr[0];
  954. struct devlink_sb *devlink_sb = info->user_ptr[1];
  955. u16 pool_index;
  956. u32 threshold;
  957. int err;
  958. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  959. &pool_index);
  960. if (err)
  961. return err;
  962. if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
  963. return -EINVAL;
  964. threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
  965. return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
  966. pool_index, threshold);
  967. }
  968. static int
  969. devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
  970. struct devlink_port *devlink_port,
  971. struct devlink_sb *devlink_sb, u16 tc_index,
  972. enum devlink_sb_pool_type pool_type,
  973. enum devlink_command cmd,
  974. u32 portid, u32 seq, int flags)
  975. {
  976. const struct devlink_ops *ops = devlink->ops;
  977. u16 pool_index;
  978. u32 threshold;
  979. void *hdr;
  980. int err;
  981. err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
  982. tc_index, pool_type,
  983. &pool_index, &threshold);
  984. if (err)
  985. return err;
  986. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  987. if (!hdr)
  988. return -EMSGSIZE;
  989. if (devlink_nl_put_handle(msg, devlink))
  990. goto nla_put_failure;
  991. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
  992. goto nla_put_failure;
  993. if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
  994. goto nla_put_failure;
  995. if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
  996. goto nla_put_failure;
  997. if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
  998. goto nla_put_failure;
  999. if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
  1000. goto nla_put_failure;
  1001. if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
  1002. goto nla_put_failure;
  1003. if (ops->sb_occ_tc_port_bind_get) {
  1004. u32 cur;
  1005. u32 max;
  1006. err = ops->sb_occ_tc_port_bind_get(devlink_port,
  1007. devlink_sb->index,
  1008. tc_index, pool_type,
  1009. &cur, &max);
  1010. if (err && err != -EOPNOTSUPP)
  1011. return err;
  1012. if (!err) {
  1013. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
  1014. goto nla_put_failure;
  1015. if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
  1016. goto nla_put_failure;
  1017. }
  1018. }
  1019. genlmsg_end(msg, hdr);
  1020. return 0;
  1021. nla_put_failure:
  1022. genlmsg_cancel(msg, hdr);
  1023. return -EMSGSIZE;
  1024. }
  1025. static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
  1026. struct genl_info *info)
  1027. {
  1028. struct devlink_port *devlink_port = info->user_ptr[0];
  1029. struct devlink *devlink = devlink_port->devlink;
  1030. struct devlink_sb *devlink_sb = info->user_ptr[1];
  1031. struct sk_buff *msg;
  1032. enum devlink_sb_pool_type pool_type;
  1033. u16 tc_index;
  1034. int err;
  1035. err = devlink_sb_pool_type_get_from_info(info, &pool_type);
  1036. if (err)
  1037. return err;
  1038. err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
  1039. pool_type, &tc_index);
  1040. if (err)
  1041. return err;
  1042. if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
  1043. return -EOPNOTSUPP;
  1044. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1045. if (!msg)
  1046. return -ENOMEM;
  1047. err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
  1048. devlink_sb, tc_index, pool_type,
  1049. DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
  1050. info->snd_portid,
  1051. info->snd_seq, 0);
  1052. if (err) {
  1053. nlmsg_free(msg);
  1054. return err;
  1055. }
  1056. return genlmsg_reply(msg, info);
  1057. }
  1058. static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
  1059. int start, int *p_idx,
  1060. struct devlink *devlink,
  1061. struct devlink_sb *devlink_sb,
  1062. u32 portid, u32 seq)
  1063. {
  1064. struct devlink_port *devlink_port;
  1065. u16 tc_index;
  1066. int err;
  1067. list_for_each_entry(devlink_port, &devlink->port_list, list) {
  1068. for (tc_index = 0;
  1069. tc_index < devlink_sb->ingress_tc_count; tc_index++) {
  1070. if (*p_idx < start) {
  1071. (*p_idx)++;
  1072. continue;
  1073. }
  1074. err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
  1075. devlink_port,
  1076. devlink_sb,
  1077. tc_index,
  1078. DEVLINK_SB_POOL_TYPE_INGRESS,
  1079. DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
  1080. portid, seq,
  1081. NLM_F_MULTI);
  1082. if (err)
  1083. return err;
  1084. (*p_idx)++;
  1085. }
  1086. for (tc_index = 0;
  1087. tc_index < devlink_sb->egress_tc_count; tc_index++) {
  1088. if (*p_idx < start) {
  1089. (*p_idx)++;
  1090. continue;
  1091. }
  1092. err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
  1093. devlink_port,
  1094. devlink_sb,
  1095. tc_index,
  1096. DEVLINK_SB_POOL_TYPE_EGRESS,
  1097. DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
  1098. portid, seq,
  1099. NLM_F_MULTI);
  1100. if (err)
  1101. return err;
  1102. (*p_idx)++;
  1103. }
  1104. }
  1105. return 0;
  1106. }
  1107. static int
  1108. devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
  1109. struct netlink_callback *cb)
  1110. {
  1111. struct devlink *devlink;
  1112. struct devlink_sb *devlink_sb;
  1113. int start = cb->args[0];
  1114. int idx = 0;
  1115. int err;
  1116. mutex_lock(&devlink_mutex);
  1117. mutex_lock(&devlink_port_mutex);
  1118. list_for_each_entry(devlink, &devlink_list, list) {
  1119. if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
  1120. !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
  1121. continue;
  1122. list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
  1123. err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
  1124. devlink,
  1125. devlink_sb,
  1126. NETLINK_CB(cb->skb).portid,
  1127. cb->nlh->nlmsg_seq);
  1128. if (err && err != -EOPNOTSUPP)
  1129. goto out;
  1130. }
  1131. }
  1132. out:
  1133. mutex_unlock(&devlink_port_mutex);
  1134. mutex_unlock(&devlink_mutex);
  1135. cb->args[0] = idx;
  1136. return msg->len;
  1137. }
  1138. static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
  1139. unsigned int sb_index, u16 tc_index,
  1140. enum devlink_sb_pool_type pool_type,
  1141. u16 pool_index, u32 threshold)
  1142. {
  1143. const struct devlink_ops *ops = devlink_port->devlink->ops;
  1144. if (ops && ops->sb_tc_pool_bind_set)
  1145. return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
  1146. tc_index, pool_type,
  1147. pool_index, threshold);
  1148. return -EOPNOTSUPP;
  1149. }
  1150. static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
  1151. struct genl_info *info)
  1152. {
  1153. struct devlink_port *devlink_port = info->user_ptr[0];
  1154. struct devlink_sb *devlink_sb = info->user_ptr[1];
  1155. enum devlink_sb_pool_type pool_type;
  1156. u16 tc_index;
  1157. u16 pool_index;
  1158. u32 threshold;
  1159. int err;
  1160. err = devlink_sb_pool_type_get_from_info(info, &pool_type);
  1161. if (err)
  1162. return err;
  1163. err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
  1164. pool_type, &tc_index);
  1165. if (err)
  1166. return err;
  1167. err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
  1168. &pool_index);
  1169. if (err)
  1170. return err;
  1171. if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
  1172. return -EINVAL;
  1173. threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
  1174. return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
  1175. tc_index, pool_type,
  1176. pool_index, threshold);
  1177. }
  1178. static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
  1179. struct genl_info *info)
  1180. {
  1181. struct devlink *devlink = info->user_ptr[0];
  1182. struct devlink_sb *devlink_sb = info->user_ptr[1];
  1183. const struct devlink_ops *ops = devlink->ops;
  1184. if (ops && ops->sb_occ_snapshot)
  1185. return ops->sb_occ_snapshot(devlink, devlink_sb->index);
  1186. return -EOPNOTSUPP;
  1187. }
  1188. static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
  1189. struct genl_info *info)
  1190. {
  1191. struct devlink *devlink = info->user_ptr[0];
  1192. struct devlink_sb *devlink_sb = info->user_ptr[1];
  1193. const struct devlink_ops *ops = devlink->ops;
  1194. if (ops && ops->sb_occ_max_clear)
  1195. return ops->sb_occ_max_clear(devlink, devlink_sb->index);
  1196. return -EOPNOTSUPP;
  1197. }
  1198. static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
  1199. enum devlink_command cmd, u32 portid,
  1200. u32 seq, int flags, u16 mode)
  1201. {
  1202. void *hdr;
  1203. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  1204. if (!hdr)
  1205. return -EMSGSIZE;
  1206. if (devlink_nl_put_handle(msg, devlink))
  1207. goto nla_put_failure;
  1208. if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))
  1209. goto nla_put_failure;
  1210. genlmsg_end(msg, hdr);
  1211. return 0;
  1212. nla_put_failure:
  1213. genlmsg_cancel(msg, hdr);
  1214. return -EMSGSIZE;
  1215. }
  1216. static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
  1217. struct genl_info *info)
  1218. {
  1219. struct devlink *devlink = info->user_ptr[0];
  1220. const struct devlink_ops *ops = devlink->ops;
  1221. struct sk_buff *msg;
  1222. u16 mode;
  1223. int err;
  1224. if (!ops || !ops->eswitch_mode_get)
  1225. return -EOPNOTSUPP;
  1226. err = ops->eswitch_mode_get(devlink, &mode);
  1227. if (err)
  1228. return err;
  1229. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  1230. if (!msg)
  1231. return -ENOMEM;
  1232. err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
  1233. info->snd_portid, info->snd_seq, 0, mode);
  1234. if (err) {
  1235. nlmsg_free(msg);
  1236. return err;
  1237. }
  1238. return genlmsg_reply(msg, info);
  1239. }
  1240. static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb,
  1241. struct genl_info *info)
  1242. {
  1243. struct devlink *devlink = info->user_ptr[0];
  1244. const struct devlink_ops *ops = devlink->ops;
  1245. u16 mode;
  1246. if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])
  1247. return -EINVAL;
  1248. mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
  1249. if (ops && ops->eswitch_mode_set)
  1250. return ops->eswitch_mode_set(devlink, mode);
  1251. return -EOPNOTSUPP;
  1252. }
  1253. static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
  1254. [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
  1255. [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
  1256. [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
  1257. [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
  1258. [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
  1259. [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
  1260. [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
  1261. [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
  1262. [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
  1263. [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
  1264. [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
  1265. [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
  1266. [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
  1267. };
  1268. static const struct genl_ops devlink_nl_ops[] = {
  1269. {
  1270. .cmd = DEVLINK_CMD_GET,
  1271. .doit = devlink_nl_cmd_get_doit,
  1272. .dumpit = devlink_nl_cmd_get_dumpit,
  1273. .policy = devlink_nl_policy,
  1274. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
  1275. /* can be retrieved by unprivileged users */
  1276. },
  1277. {
  1278. .cmd = DEVLINK_CMD_PORT_GET,
  1279. .doit = devlink_nl_cmd_port_get_doit,
  1280. .dumpit = devlink_nl_cmd_port_get_dumpit,
  1281. .policy = devlink_nl_policy,
  1282. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  1283. /* can be retrieved by unprivileged users */
  1284. },
  1285. {
  1286. .cmd = DEVLINK_CMD_PORT_SET,
  1287. .doit = devlink_nl_cmd_port_set_doit,
  1288. .policy = devlink_nl_policy,
  1289. .flags = GENL_ADMIN_PERM,
  1290. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
  1291. },
  1292. {
  1293. .cmd = DEVLINK_CMD_PORT_SPLIT,
  1294. .doit = devlink_nl_cmd_port_split_doit,
  1295. .policy = devlink_nl_policy,
  1296. .flags = GENL_ADMIN_PERM,
  1297. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
  1298. },
  1299. {
  1300. .cmd = DEVLINK_CMD_PORT_UNSPLIT,
  1301. .doit = devlink_nl_cmd_port_unsplit_doit,
  1302. .policy = devlink_nl_policy,
  1303. .flags = GENL_ADMIN_PERM,
  1304. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
  1305. },
  1306. {
  1307. .cmd = DEVLINK_CMD_SB_GET,
  1308. .doit = devlink_nl_cmd_sb_get_doit,
  1309. .dumpit = devlink_nl_cmd_sb_get_dumpit,
  1310. .policy = devlink_nl_policy,
  1311. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
  1312. DEVLINK_NL_FLAG_NEED_SB,
  1313. /* can be retrieved by unprivileged users */
  1314. },
  1315. {
  1316. .cmd = DEVLINK_CMD_SB_POOL_GET,
  1317. .doit = devlink_nl_cmd_sb_pool_get_doit,
  1318. .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
  1319. .policy = devlink_nl_policy,
  1320. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
  1321. DEVLINK_NL_FLAG_NEED_SB,
  1322. /* can be retrieved by unprivileged users */
  1323. },
  1324. {
  1325. .cmd = DEVLINK_CMD_SB_POOL_SET,
  1326. .doit = devlink_nl_cmd_sb_pool_set_doit,
  1327. .policy = devlink_nl_policy,
  1328. .flags = GENL_ADMIN_PERM,
  1329. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
  1330. DEVLINK_NL_FLAG_NEED_SB,
  1331. },
  1332. {
  1333. .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
  1334. .doit = devlink_nl_cmd_sb_port_pool_get_doit,
  1335. .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
  1336. .policy = devlink_nl_policy,
  1337. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
  1338. DEVLINK_NL_FLAG_NEED_SB,
  1339. /* can be retrieved by unprivileged users */
  1340. },
  1341. {
  1342. .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
  1343. .doit = devlink_nl_cmd_sb_port_pool_set_doit,
  1344. .policy = devlink_nl_policy,
  1345. .flags = GENL_ADMIN_PERM,
  1346. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
  1347. DEVLINK_NL_FLAG_NEED_SB,
  1348. },
  1349. {
  1350. .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
  1351. .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
  1352. .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
  1353. .policy = devlink_nl_policy,
  1354. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
  1355. DEVLINK_NL_FLAG_NEED_SB,
  1356. /* can be retrieved by unprivileged users */
  1357. },
  1358. {
  1359. .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
  1360. .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
  1361. .policy = devlink_nl_policy,
  1362. .flags = GENL_ADMIN_PERM,
  1363. .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
  1364. DEVLINK_NL_FLAG_NEED_SB,
  1365. },
  1366. {
  1367. .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
  1368. .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
  1369. .policy = devlink_nl_policy,
  1370. .flags = GENL_ADMIN_PERM,
  1371. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
  1372. DEVLINK_NL_FLAG_NEED_SB |
  1373. DEVLINK_NL_FLAG_LOCK_PORTS,
  1374. },
  1375. {
  1376. .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
  1377. .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
  1378. .policy = devlink_nl_policy,
  1379. .flags = GENL_ADMIN_PERM,
  1380. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
  1381. DEVLINK_NL_FLAG_NEED_SB |
  1382. DEVLINK_NL_FLAG_LOCK_PORTS,
  1383. },
  1384. {
  1385. .cmd = DEVLINK_CMD_ESWITCH_MODE_GET,
  1386. .doit = devlink_nl_cmd_eswitch_mode_get_doit,
  1387. .policy = devlink_nl_policy,
  1388. .flags = GENL_ADMIN_PERM,
  1389. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
  1390. },
  1391. {
  1392. .cmd = DEVLINK_CMD_ESWITCH_MODE_SET,
  1393. .doit = devlink_nl_cmd_eswitch_mode_set_doit,
  1394. .policy = devlink_nl_policy,
  1395. .flags = GENL_ADMIN_PERM,
  1396. .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
  1397. },
  1398. };
  1399. /**
  1400. * devlink_alloc - Allocate new devlink instance resources
  1401. *
  1402. * @ops: ops
  1403. * @priv_size: size of user private data
  1404. *
  1405. * Allocate new devlink instance resources, including devlink index
  1406. * and name.
  1407. */
  1408. struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
  1409. {
  1410. struct devlink *devlink;
  1411. devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
  1412. if (!devlink)
  1413. return NULL;
  1414. devlink->ops = ops;
  1415. devlink_net_set(devlink, &init_net);
  1416. INIT_LIST_HEAD(&devlink->port_list);
  1417. INIT_LIST_HEAD(&devlink->sb_list);
  1418. return devlink;
  1419. }
  1420. EXPORT_SYMBOL_GPL(devlink_alloc);
  1421. /**
  1422. * devlink_register - Register devlink instance
  1423. *
  1424. * @devlink: devlink
  1425. */
  1426. int devlink_register(struct devlink *devlink, struct device *dev)
  1427. {
  1428. mutex_lock(&devlink_mutex);
  1429. devlink->dev = dev;
  1430. list_add_tail(&devlink->list, &devlink_list);
  1431. devlink_notify(devlink, DEVLINK_CMD_NEW);
  1432. mutex_unlock(&devlink_mutex);
  1433. return 0;
  1434. }
  1435. EXPORT_SYMBOL_GPL(devlink_register);
  1436. /**
  1437. * devlink_unregister - Unregister devlink instance
  1438. *
  1439. * @devlink: devlink
  1440. */
  1441. void devlink_unregister(struct devlink *devlink)
  1442. {
  1443. mutex_lock(&devlink_mutex);
  1444. devlink_notify(devlink, DEVLINK_CMD_DEL);
  1445. list_del(&devlink->list);
  1446. mutex_unlock(&devlink_mutex);
  1447. }
  1448. EXPORT_SYMBOL_GPL(devlink_unregister);
  1449. /**
  1450. * devlink_free - Free devlink instance resources
  1451. *
  1452. * @devlink: devlink
  1453. */
  1454. void devlink_free(struct devlink *devlink)
  1455. {
  1456. kfree(devlink);
  1457. }
  1458. EXPORT_SYMBOL_GPL(devlink_free);
  1459. /**
  1460. * devlink_port_register - Register devlink port
  1461. *
  1462. * @devlink: devlink
  1463. * @devlink_port: devlink port
  1464. * @port_index
  1465. *
  1466. * Register devlink port with provided port index. User can use
  1467. * any indexing, even hw-related one. devlink_port structure
  1468. * is convenient to be embedded inside user driver private structure.
  1469. * Note that the caller should take care of zeroing the devlink_port
  1470. * structure.
  1471. */
  1472. int devlink_port_register(struct devlink *devlink,
  1473. struct devlink_port *devlink_port,
  1474. unsigned int port_index)
  1475. {
  1476. mutex_lock(&devlink_port_mutex);
  1477. if (devlink_port_index_exists(devlink, port_index)) {
  1478. mutex_unlock(&devlink_port_mutex);
  1479. return -EEXIST;
  1480. }
  1481. devlink_port->devlink = devlink;
  1482. devlink_port->index = port_index;
  1483. devlink_port->registered = true;
  1484. list_add_tail(&devlink_port->list, &devlink->port_list);
  1485. mutex_unlock(&devlink_port_mutex);
  1486. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  1487. return 0;
  1488. }
  1489. EXPORT_SYMBOL_GPL(devlink_port_register);
  1490. /**
  1491. * devlink_port_unregister - Unregister devlink port
  1492. *
  1493. * @devlink_port: devlink port
  1494. */
  1495. void devlink_port_unregister(struct devlink_port *devlink_port)
  1496. {
  1497. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
  1498. mutex_lock(&devlink_port_mutex);
  1499. list_del(&devlink_port->list);
  1500. mutex_unlock(&devlink_port_mutex);
  1501. }
  1502. EXPORT_SYMBOL_GPL(devlink_port_unregister);
  1503. static void __devlink_port_type_set(struct devlink_port *devlink_port,
  1504. enum devlink_port_type type,
  1505. void *type_dev)
  1506. {
  1507. devlink_port->type = type;
  1508. devlink_port->type_dev = type_dev;
  1509. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  1510. }
  1511. /**
  1512. * devlink_port_type_eth_set - Set port type to Ethernet
  1513. *
  1514. * @devlink_port: devlink port
  1515. * @netdev: related netdevice
  1516. */
  1517. void devlink_port_type_eth_set(struct devlink_port *devlink_port,
  1518. struct net_device *netdev)
  1519. {
  1520. return __devlink_port_type_set(devlink_port,
  1521. DEVLINK_PORT_TYPE_ETH, netdev);
  1522. }
  1523. EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
  1524. /**
  1525. * devlink_port_type_ib_set - Set port type to InfiniBand
  1526. *
  1527. * @devlink_port: devlink port
  1528. * @ibdev: related IB device
  1529. */
  1530. void devlink_port_type_ib_set(struct devlink_port *devlink_port,
  1531. struct ib_device *ibdev)
  1532. {
  1533. return __devlink_port_type_set(devlink_port,
  1534. DEVLINK_PORT_TYPE_IB, ibdev);
  1535. }
  1536. EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
  1537. /**
  1538. * devlink_port_type_clear - Clear port type
  1539. *
  1540. * @devlink_port: devlink port
  1541. */
  1542. void devlink_port_type_clear(struct devlink_port *devlink_port)
  1543. {
  1544. return __devlink_port_type_set(devlink_port,
  1545. DEVLINK_PORT_TYPE_NOTSET, NULL);
  1546. }
  1547. EXPORT_SYMBOL_GPL(devlink_port_type_clear);
  1548. /**
  1549. * devlink_port_split_set - Set port is split
  1550. *
  1551. * @devlink_port: devlink port
  1552. * @split_group: split group - identifies group split port is part of
  1553. */
  1554. void devlink_port_split_set(struct devlink_port *devlink_port,
  1555. u32 split_group)
  1556. {
  1557. devlink_port->split = true;
  1558. devlink_port->split_group = split_group;
  1559. devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
  1560. }
  1561. EXPORT_SYMBOL_GPL(devlink_port_split_set);
  1562. int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
  1563. u32 size, u16 ingress_pools_count,
  1564. u16 egress_pools_count, u16 ingress_tc_count,
  1565. u16 egress_tc_count)
  1566. {
  1567. struct devlink_sb *devlink_sb;
  1568. int err = 0;
  1569. mutex_lock(&devlink_mutex);
  1570. if (devlink_sb_index_exists(devlink, sb_index)) {
  1571. err = -EEXIST;
  1572. goto unlock;
  1573. }
  1574. devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
  1575. if (!devlink_sb) {
  1576. err = -ENOMEM;
  1577. goto unlock;
  1578. }
  1579. devlink_sb->index = sb_index;
  1580. devlink_sb->size = size;
  1581. devlink_sb->ingress_pools_count = ingress_pools_count;
  1582. devlink_sb->egress_pools_count = egress_pools_count;
  1583. devlink_sb->ingress_tc_count = ingress_tc_count;
  1584. devlink_sb->egress_tc_count = egress_tc_count;
  1585. list_add_tail(&devlink_sb->list, &devlink->sb_list);
  1586. unlock:
  1587. mutex_unlock(&devlink_mutex);
  1588. return err;
  1589. }
  1590. EXPORT_SYMBOL_GPL(devlink_sb_register);
  1591. void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
  1592. {
  1593. struct devlink_sb *devlink_sb;
  1594. mutex_lock(&devlink_mutex);
  1595. devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
  1596. WARN_ON(!devlink_sb);
  1597. list_del(&devlink_sb->list);
  1598. mutex_unlock(&devlink_mutex);
  1599. kfree(devlink_sb);
  1600. }
  1601. EXPORT_SYMBOL_GPL(devlink_sb_unregister);
  1602. static int __init devlink_module_init(void)
  1603. {
  1604. return genl_register_family_with_ops_groups(&devlink_nl_family,
  1605. devlink_nl_ops,
  1606. devlink_nl_mcgrps);
  1607. }
  1608. static void __exit devlink_module_exit(void)
  1609. {
  1610. genl_unregister_family(&devlink_nl_family);
  1611. }
  1612. module_init(devlink_module_init);
  1613. module_exit(devlink_module_exit);
  1614. MODULE_LICENSE("GPL v2");
  1615. MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
  1616. MODULE_DESCRIPTION("Network physical device Netlink interface");
  1617. MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);