Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * net/core/devlink.c - Network physical/parent device Netlink interface
4 *
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
8 */
9
10#include <linux/etherdevice.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/slab.h>
15#include <linux/gfp.h>
16#include <linux/device.h>
17#include <linux/list.h>
18#include <linux/netdevice.h>
19#include <linux/spinlock.h>
20#include <linux/refcount.h>
21#include <linux/workqueue.h>
22#include <linux/u64_stats_sync.h>
23#include <linux/timekeeping.h>
24#include <rdma/ib_verbs.h>
25#include <net/netlink.h>
26#include <net/genetlink.h>
27#include <net/rtnetlink.h>
28#include <net/net_namespace.h>
29#include <net/sock.h>
30#include <net/devlink.h>
31#define CREATE_TRACE_POINTS
32#include <trace/events/devlink.h>
33
34#include "devl_internal.h"
35
36struct devlink_linecard {
37 struct list_head list;
38 struct devlink *devlink;
39 unsigned int index;
40 const struct devlink_linecard_ops *ops;
41 void *priv;
42 enum devlink_linecard_state state;
43 struct mutex state_lock; /* Protects state */
44 const char *type;
45 struct devlink_linecard_type *types;
46 unsigned int types_count;
47 struct devlink *nested_devlink;
48};
49
50/**
51 * struct devlink_resource - devlink resource
52 * @name: name of the resource
53 * @id: id, per devlink instance
54 * @size: size of the resource
55 * @size_new: updated size of the resource, reload is needed
56 * @size_valid: valid in case the total size of the resource is valid
57 * including its children
58 * @parent: parent resource
59 * @size_params: size parameters
60 * @list: parent list
61 * @resource_list: list of child resources
62 * @occ_get: occupancy getter callback
63 * @occ_get_priv: occupancy getter callback priv
64 */
65struct devlink_resource {
66 const char *name;
67 u64 id;
68 u64 size;
69 u64 size_new;
70 bool size_valid;
71 struct devlink_resource *parent;
72 struct devlink_resource_size_params size_params;
73 struct list_head list;
74 struct list_head resource_list;
75 devlink_resource_occ_get_t *occ_get;
76 void *occ_get_priv;
77};
78
79static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
80 {
81 .name = "destination mac",
82 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
83 .bitwidth = 48,
84 },
85};
86
87struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
88 .name = "ethernet",
89 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
90 .fields = devlink_dpipe_fields_ethernet,
91 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
92 .global = true,
93};
94EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
95
96static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
97 {
98 .name = "destination ip",
99 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
100 .bitwidth = 32,
101 },
102};
103
104struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
105 .name = "ipv4",
106 .id = DEVLINK_DPIPE_HEADER_IPV4,
107 .fields = devlink_dpipe_fields_ipv4,
108 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
109 .global = true,
110};
111EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
112
113static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
114 {
115 .name = "destination ip",
116 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
117 .bitwidth = 128,
118 },
119};
120
121struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
122 .name = "ipv6",
123 .id = DEVLINK_DPIPE_HEADER_IPV6,
124 .fields = devlink_dpipe_fields_ipv6,
125 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
126 .global = true,
127};
128EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
129
130EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
131EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
132EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
133
134#define DEVLINK_PORT_FN_CAPS_VALID_MASK \
135 (_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1)
136
137static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
138 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
139 [DEVLINK_PORT_FN_ATTR_STATE] =
140 NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
141 DEVLINK_PORT_FN_STATE_ACTIVE),
142 [DEVLINK_PORT_FN_ATTR_CAPS] =
143 NLA_POLICY_BITFIELD32(DEVLINK_PORT_FN_CAPS_VALID_MASK),
144};
145
146#define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \
147 WARN_ON_ONCE(!(devlink_port)->registered)
148#define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \
149 WARN_ON_ONCE((devlink_port)->registered)
150#define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \
151 WARN_ON_ONCE(!(devlink_port)->initialized)
152
153static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
154 unsigned int port_index)
155{
156 return xa_load(&devlink->ports, port_index);
157}
158
159struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
160 struct nlattr **attrs)
161{
162 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
163 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
164 struct devlink_port *devlink_port;
165
166 devlink_port = devlink_port_get_by_index(devlink, port_index);
167 if (!devlink_port)
168 return ERR_PTR(-ENODEV);
169 return devlink_port;
170 }
171 return ERR_PTR(-EINVAL);
172}
173
174struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
175 struct genl_info *info)
176{
177 return devlink_port_get_from_attrs(devlink, info->attrs);
178}
179
180static inline bool
181devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
182{
183 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
184}
185
186static inline bool
187devlink_rate_is_node(struct devlink_rate *devlink_rate)
188{
189 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
190}
191
192static struct devlink_rate *
193devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
194{
195 struct devlink_rate *devlink_rate;
196 struct devlink_port *devlink_port;
197
198 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
199 if (IS_ERR(devlink_port))
200 return ERR_CAST(devlink_port);
201 devlink_rate = devlink_port->devlink_rate;
202 return devlink_rate ?: ERR_PTR(-ENODEV);
203}
204
205static struct devlink_rate *
206devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
207{
208 static struct devlink_rate *devlink_rate;
209
210 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
211 if (devlink_rate_is_node(devlink_rate) &&
212 !strcmp(node_name, devlink_rate->name))
213 return devlink_rate;
214 }
215 return ERR_PTR(-ENODEV);
216}
217
218static struct devlink_rate *
219devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
220{
221 const char *rate_node_name;
222 size_t len;
223
224 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
225 return ERR_PTR(-EINVAL);
226 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
227 len = strlen(rate_node_name);
228 /* Name cannot be empty or decimal number */
229 if (!len || strspn(rate_node_name, "0123456789") == len)
230 return ERR_PTR(-EINVAL);
231
232 return devlink_rate_node_get_by_name(devlink, rate_node_name);
233}
234
235struct devlink_rate *
236devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
237{
238 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
239}
240
241struct devlink_rate *
242devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
243{
244 struct nlattr **attrs = info->attrs;
245
246 if (attrs[DEVLINK_ATTR_PORT_INDEX])
247 return devlink_rate_leaf_get_from_info(devlink, info);
248 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
249 return devlink_rate_node_get_from_info(devlink, info);
250 else
251 return ERR_PTR(-EINVAL);
252}
253
254static struct devlink_linecard *
255devlink_linecard_get_by_index(struct devlink *devlink,
256 unsigned int linecard_index)
257{
258 struct devlink_linecard *devlink_linecard;
259
260 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
261 if (devlink_linecard->index == linecard_index)
262 return devlink_linecard;
263 }
264 return NULL;
265}
266
267static bool devlink_linecard_index_exists(struct devlink *devlink,
268 unsigned int linecard_index)
269{
270 return devlink_linecard_get_by_index(devlink, linecard_index);
271}
272
273static struct devlink_linecard *
274devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
275{
276 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
277 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
278 struct devlink_linecard *linecard;
279
280 linecard = devlink_linecard_get_by_index(devlink, linecard_index);
281 if (!linecard)
282 return ERR_PTR(-ENODEV);
283 return linecard;
284 }
285 return ERR_PTR(-EINVAL);
286}
287
288struct devlink_linecard *
289devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
290{
291 return devlink_linecard_get_from_attrs(devlink, info->attrs);
292}
293
294struct devlink_sb {
295 struct list_head list;
296 unsigned int index;
297 u32 size;
298 u16 ingress_pools_count;
299 u16 egress_pools_count;
300 u16 ingress_tc_count;
301 u16 egress_tc_count;
302};
303
304static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
305{
306 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
307}
308
309static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
310 unsigned int sb_index)
311{
312 struct devlink_sb *devlink_sb;
313
314 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
315 if (devlink_sb->index == sb_index)
316 return devlink_sb;
317 }
318 return NULL;
319}
320
321static bool devlink_sb_index_exists(struct devlink *devlink,
322 unsigned int sb_index)
323{
324 return devlink_sb_get_by_index(devlink, sb_index);
325}
326
327static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
328 struct nlattr **attrs)
329{
330 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
331 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
332 struct devlink_sb *devlink_sb;
333
334 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
335 if (!devlink_sb)
336 return ERR_PTR(-ENODEV);
337 return devlink_sb;
338 }
339 return ERR_PTR(-EINVAL);
340}
341
342static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
343 struct genl_info *info)
344{
345 return devlink_sb_get_from_attrs(devlink, info->attrs);
346}
347
348static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
349 struct nlattr **attrs,
350 u16 *p_pool_index)
351{
352 u16 val;
353
354 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
355 return -EINVAL;
356
357 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
358 if (val >= devlink_sb_pool_count(devlink_sb))
359 return -EINVAL;
360 *p_pool_index = val;
361 return 0;
362}
363
364static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
365 struct genl_info *info,
366 u16 *p_pool_index)
367{
368 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
369 p_pool_index);
370}
371
372static int
373devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
374 enum devlink_sb_pool_type *p_pool_type)
375{
376 u8 val;
377
378 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
379 return -EINVAL;
380
381 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
382 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
383 val != DEVLINK_SB_POOL_TYPE_EGRESS)
384 return -EINVAL;
385 *p_pool_type = val;
386 return 0;
387}
388
389static int
390devlink_sb_pool_type_get_from_info(struct genl_info *info,
391 enum devlink_sb_pool_type *p_pool_type)
392{
393 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
394}
395
396static int
397devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
398 enum devlink_sb_threshold_type *p_th_type)
399{
400 u8 val;
401
402 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
403 return -EINVAL;
404
405 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
406 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
407 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
408 return -EINVAL;
409 *p_th_type = val;
410 return 0;
411}
412
413static int
414devlink_sb_th_type_get_from_info(struct genl_info *info,
415 enum devlink_sb_threshold_type *p_th_type)
416{
417 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
418}
419
420static int
421devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
422 struct nlattr **attrs,
423 enum devlink_sb_pool_type pool_type,
424 u16 *p_tc_index)
425{
426 u16 val;
427
428 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
429 return -EINVAL;
430
431 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
432 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
433 val >= devlink_sb->ingress_tc_count)
434 return -EINVAL;
435 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
436 val >= devlink_sb->egress_tc_count)
437 return -EINVAL;
438 *p_tc_index = val;
439 return 0;
440}
441
442static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
443 u32 cap, bool is_enable)
444{
445 caps->selector |= cap;
446 if (is_enable)
447 caps->value |= cap;
448}
449
450static int devlink_port_fn_roce_fill(struct devlink_port *devlink_port,
451 struct nla_bitfield32 *caps,
452 struct netlink_ext_ack *extack)
453{
454 bool is_enable;
455 int err;
456
457 if (!devlink_port->ops->port_fn_roce_get)
458 return 0;
459
460 err = devlink_port->ops->port_fn_roce_get(devlink_port, &is_enable,
461 extack);
462 if (err) {
463 if (err == -EOPNOTSUPP)
464 return 0;
465 return err;
466 }
467
468 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable);
469 return 0;
470}
471
472static int devlink_port_fn_migratable_fill(struct devlink_port *devlink_port,
473 struct nla_bitfield32 *caps,
474 struct netlink_ext_ack *extack)
475{
476 bool is_enable;
477 int err;
478
479 if (!devlink_port->ops->port_fn_migratable_get ||
480 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
481 return 0;
482
483 err = devlink_port->ops->port_fn_migratable_get(devlink_port,
484 &is_enable, extack);
485 if (err) {
486 if (err == -EOPNOTSUPP)
487 return 0;
488 return err;
489 }
490
491 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable);
492 return 0;
493}
494
495static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port,
496 struct sk_buff *msg,
497 struct netlink_ext_ack *extack,
498 bool *msg_updated)
499{
500 struct nla_bitfield32 caps = {};
501 int err;
502
503 err = devlink_port_fn_roce_fill(devlink_port, &caps, extack);
504 if (err)
505 return err;
506
507 err = devlink_port_fn_migratable_fill(devlink_port, &caps, extack);
508 if (err)
509 return err;
510
511 if (!caps.selector)
512 return 0;
513 err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
514 caps.selector);
515 if (err)
516 return err;
517
518 *msg_updated = true;
519 return 0;
520}
521
522static int
523devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
524 struct genl_info *info,
525 enum devlink_sb_pool_type pool_type,
526 u16 *p_tc_index)
527{
528 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
529 pool_type, p_tc_index);
530}
531
532struct devlink_region {
533 struct devlink *devlink;
534 struct devlink_port *port;
535 struct list_head list;
536 union {
537 const struct devlink_region_ops *ops;
538 const struct devlink_port_region_ops *port_ops;
539 };
540 struct mutex snapshot_lock; /* protects snapshot_list,
541 * max_snapshots and cur_snapshots
542 * consistency.
543 */
544 struct list_head snapshot_list;
545 u32 max_snapshots;
546 u32 cur_snapshots;
547 u64 size;
548};
549
550struct devlink_snapshot {
551 struct list_head list;
552 struct devlink_region *region;
553 u8 *data;
554 u32 id;
555};
556
557static struct devlink_region *
558devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
559{
560 struct devlink_region *region;
561
562 list_for_each_entry(region, &devlink->region_list, list)
563 if (!strcmp(region->ops->name, region_name))
564 return region;
565
566 return NULL;
567}
568
569static struct devlink_region *
570devlink_port_region_get_by_name(struct devlink_port *port,
571 const char *region_name)
572{
573 struct devlink_region *region;
574
575 list_for_each_entry(region, &port->region_list, list)
576 if (!strcmp(region->ops->name, region_name))
577 return region;
578
579 return NULL;
580}
581
582static struct devlink_snapshot *
583devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
584{
585 struct devlink_snapshot *snapshot;
586
587 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
588 if (snapshot->id == id)
589 return snapshot;
590
591 return NULL;
592}
593
594static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
595{
596 struct nlattr *nested_attr;
597
598 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
599 if (!nested_attr)
600 return -EMSGSIZE;
601 if (devlink_nl_put_handle(msg, devlink))
602 goto nla_put_failure;
603
604 nla_nest_end(msg, nested_attr);
605 return 0;
606
607nla_put_failure:
608 nla_nest_cancel(msg, nested_attr);
609 return -EMSGSIZE;
610}
611
612int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port)
613{
614 if (devlink_nl_put_handle(msg, devlink_port->devlink))
615 return -EMSGSIZE;
616 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
617 return -EMSGSIZE;
618 return 0;
619}
620
621size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
622{
623 struct devlink *devlink = devlink_port->devlink;
624
625 return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */
626 + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */
627 + nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */
628}
629
630static int devlink_nl_port_attrs_put(struct sk_buff *msg,
631 struct devlink_port *devlink_port)
632{
633 struct devlink_port_attrs *attrs = &devlink_port->attrs;
634
635 if (!devlink_port->attrs_set)
636 return 0;
637 if (attrs->lanes) {
638 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
639 return -EMSGSIZE;
640 }
641 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
642 return -EMSGSIZE;
643 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
644 return -EMSGSIZE;
645 switch (devlink_port->attrs.flavour) {
646 case DEVLINK_PORT_FLAVOUR_PCI_PF:
647 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
648 attrs->pci_pf.controller) ||
649 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
650 return -EMSGSIZE;
651 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
652 return -EMSGSIZE;
653 break;
654 case DEVLINK_PORT_FLAVOUR_PCI_VF:
655 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
656 attrs->pci_vf.controller) ||
657 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
658 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
659 return -EMSGSIZE;
660 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
661 return -EMSGSIZE;
662 break;
663 case DEVLINK_PORT_FLAVOUR_PCI_SF:
664 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
665 attrs->pci_sf.controller) ||
666 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
667 attrs->pci_sf.pf) ||
668 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
669 attrs->pci_sf.sf))
670 return -EMSGSIZE;
671 break;
672 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
673 case DEVLINK_PORT_FLAVOUR_CPU:
674 case DEVLINK_PORT_FLAVOUR_DSA:
675 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
676 attrs->phys.port_number))
677 return -EMSGSIZE;
678 if (!attrs->split)
679 return 0;
680 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
681 attrs->phys.port_number))
682 return -EMSGSIZE;
683 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
684 attrs->phys.split_subport_number))
685 return -EMSGSIZE;
686 break;
687 default:
688 break;
689 }
690 return 0;
691}
692
693static int devlink_port_fn_hw_addr_fill(struct devlink_port *port,
694 struct sk_buff *msg,
695 struct netlink_ext_ack *extack,
696 bool *msg_updated)
697{
698 u8 hw_addr[MAX_ADDR_LEN];
699 int hw_addr_len;
700 int err;
701
702 if (!port->ops->port_fn_hw_addr_get)
703 return 0;
704
705 err = port->ops->port_fn_hw_addr_get(port, hw_addr, &hw_addr_len,
706 extack);
707 if (err) {
708 if (err == -EOPNOTSUPP)
709 return 0;
710 return err;
711 }
712 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
713 if (err)
714 return err;
715 *msg_updated = true;
716 return 0;
717}
718
719static int devlink_nl_rate_fill(struct sk_buff *msg,
720 struct devlink_rate *devlink_rate,
721 enum devlink_command cmd, u32 portid, u32 seq,
722 int flags, struct netlink_ext_ack *extack)
723{
724 struct devlink *devlink = devlink_rate->devlink;
725 void *hdr;
726
727 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
728 if (!hdr)
729 return -EMSGSIZE;
730
731 if (devlink_nl_put_handle(msg, devlink))
732 goto nla_put_failure;
733
734 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
735 goto nla_put_failure;
736
737 if (devlink_rate_is_leaf(devlink_rate)) {
738 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
739 devlink_rate->devlink_port->index))
740 goto nla_put_failure;
741 } else if (devlink_rate_is_node(devlink_rate)) {
742 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
743 devlink_rate->name))
744 goto nla_put_failure;
745 }
746
747 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
748 devlink_rate->tx_share, DEVLINK_ATTR_PAD))
749 goto nla_put_failure;
750
751 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
752 devlink_rate->tx_max, DEVLINK_ATTR_PAD))
753 goto nla_put_failure;
754
755 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
756 devlink_rate->tx_priority))
757 goto nla_put_failure;
758
759 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
760 devlink_rate->tx_weight))
761 goto nla_put_failure;
762
763 if (devlink_rate->parent)
764 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
765 devlink_rate->parent->name))
766 goto nla_put_failure;
767
768 genlmsg_end(msg, hdr);
769 return 0;
770
771nla_put_failure:
772 genlmsg_cancel(msg, hdr);
773 return -EMSGSIZE;
774}
775
776static bool
777devlink_port_fn_state_valid(enum devlink_port_fn_state state)
778{
779 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
780 state == DEVLINK_PORT_FN_STATE_ACTIVE;
781}
782
783static bool
784devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
785{
786 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
787 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
788}
789
790static int devlink_port_fn_state_fill(struct devlink_port *port,
791 struct sk_buff *msg,
792 struct netlink_ext_ack *extack,
793 bool *msg_updated)
794{
795 enum devlink_port_fn_opstate opstate;
796 enum devlink_port_fn_state state;
797 int err;
798
799 if (!port->ops->port_fn_state_get)
800 return 0;
801
802 err = port->ops->port_fn_state_get(port, &state, &opstate, extack);
803 if (err) {
804 if (err == -EOPNOTSUPP)
805 return 0;
806 return err;
807 }
808 if (!devlink_port_fn_state_valid(state)) {
809 WARN_ON_ONCE(1);
810 NL_SET_ERR_MSG(extack, "Invalid state read from driver");
811 return -EINVAL;
812 }
813 if (!devlink_port_fn_opstate_valid(opstate)) {
814 WARN_ON_ONCE(1);
815 NL_SET_ERR_MSG(extack, "Invalid operational state read from driver");
816 return -EINVAL;
817 }
818 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
819 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
820 return -EMSGSIZE;
821 *msg_updated = true;
822 return 0;
823}
824
825static int
826devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
827 struct netlink_ext_ack *extack)
828{
829 return devlink_port->ops->port_fn_migratable_set(devlink_port, enable,
830 extack);
831}
832
833static int
834devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
835 struct netlink_ext_ack *extack)
836{
837 return devlink_port->ops->port_fn_roce_set(devlink_port, enable,
838 extack);
839}
840
841static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
842 const struct nlattr *attr,
843 struct netlink_ext_ack *extack)
844{
845 struct nla_bitfield32 caps;
846 u32 caps_value;
847 int err;
848
849 caps = nla_get_bitfield32(attr);
850 caps_value = caps.value & caps.selector;
851 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE) {
852 err = devlink_port_fn_roce_set(devlink_port,
853 caps_value & DEVLINK_PORT_FN_CAP_ROCE,
854 extack);
855 if (err)
856 return err;
857 }
858 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
859 err = devlink_port_fn_mig_set(devlink_port, caps_value &
860 DEVLINK_PORT_FN_CAP_MIGRATABLE,
861 extack);
862 if (err)
863 return err;
864 }
865 return 0;
866}
867
868static int
869devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
870 struct netlink_ext_ack *extack)
871{
872 struct nlattr *function_attr;
873 bool msg_updated = false;
874 int err;
875
876 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
877 if (!function_attr)
878 return -EMSGSIZE;
879
880 err = devlink_port_fn_hw_addr_fill(port, msg, extack, &msg_updated);
881 if (err)
882 goto out;
883 err = devlink_port_fn_caps_fill(port, msg, extack, &msg_updated);
884 if (err)
885 goto out;
886 err = devlink_port_fn_state_fill(port, msg, extack, &msg_updated);
887out:
888 if (err || !msg_updated)
889 nla_nest_cancel(msg, function_attr);
890 else
891 nla_nest_end(msg, function_attr);
892 return err;
893}
894
895static int devlink_nl_port_fill(struct sk_buff *msg,
896 struct devlink_port *devlink_port,
897 enum devlink_command cmd, u32 portid, u32 seq,
898 int flags, struct netlink_ext_ack *extack)
899{
900 struct devlink *devlink = devlink_port->devlink;
901 void *hdr;
902
903 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
904 if (!hdr)
905 return -EMSGSIZE;
906
907 if (devlink_nl_put_handle(msg, devlink))
908 goto nla_put_failure;
909 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
910 goto nla_put_failure;
911
912 spin_lock_bh(&devlink_port->type_lock);
913 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
914 goto nla_put_failure_type_locked;
915 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
916 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
917 devlink_port->desired_type))
918 goto nla_put_failure_type_locked;
919 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
920 if (devlink_port->type_eth.netdev &&
921 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
922 devlink_port->type_eth.ifindex) ||
923 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
924 devlink_port->type_eth.ifname)))
925 goto nla_put_failure_type_locked;
926 }
927 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
928 struct ib_device *ibdev = devlink_port->type_ib.ibdev;
929
930 if (ibdev &&
931 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
932 ibdev->name))
933 goto nla_put_failure_type_locked;
934 }
935 spin_unlock_bh(&devlink_port->type_lock);
936 if (devlink_nl_port_attrs_put(msg, devlink_port))
937 goto nla_put_failure;
938 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
939 goto nla_put_failure;
940 if (devlink_port->linecard &&
941 nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
942 devlink_port->linecard->index))
943 goto nla_put_failure;
944
945 genlmsg_end(msg, hdr);
946 return 0;
947
948nla_put_failure_type_locked:
949 spin_unlock_bh(&devlink_port->type_lock);
950nla_put_failure:
951 genlmsg_cancel(msg, hdr);
952 return -EMSGSIZE;
953}
954
955static void devlink_port_notify(struct devlink_port *devlink_port,
956 enum devlink_command cmd)
957{
958 struct devlink *devlink = devlink_port->devlink;
959 struct sk_buff *msg;
960 int err;
961
962 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
963
964 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
965 return;
966
967 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
968 if (!msg)
969 return;
970
971 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
972 if (err) {
973 nlmsg_free(msg);
974 return;
975 }
976
977 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
978 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
979}
980
981static void devlink_rate_notify(struct devlink_rate *devlink_rate,
982 enum devlink_command cmd)
983{
984 struct devlink *devlink = devlink_rate->devlink;
985 struct sk_buff *msg;
986 int err;
987
988 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
989
990 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
991 return;
992
993 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
994 if (!msg)
995 return;
996
997 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
998 if (err) {
999 nlmsg_free(msg);
1000 return;
1001 }
1002
1003 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1004 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1005}
1006
1007static int
1008devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1009 struct netlink_callback *cb)
1010{
1011 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1012 struct devlink_rate *devlink_rate;
1013 int idx = 0;
1014 int err = 0;
1015
1016 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1017 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1018 u32 id = NETLINK_CB(cb->skb).portid;
1019
1020 if (idx < state->idx) {
1021 idx++;
1022 continue;
1023 }
1024 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1025 cb->nlh->nlmsg_seq,
1026 NLM_F_MULTI, NULL);
1027 if (err) {
1028 state->idx = idx;
1029 break;
1030 }
1031 idx++;
1032 }
1033
1034 return err;
1035}
1036
1037const struct devlink_cmd devl_cmd_rate_get = {
1038 .dump_one = devlink_nl_cmd_rate_get_dump_one,
1039};
1040
1041static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1042 struct genl_info *info)
1043{
1044 struct devlink_rate *devlink_rate = info->user_ptr[1];
1045 struct sk_buff *msg;
1046 int err;
1047
1048 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1049 if (!msg)
1050 return -ENOMEM;
1051
1052 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1053 info->snd_portid, info->snd_seq, 0,
1054 info->extack);
1055 if (err) {
1056 nlmsg_free(msg);
1057 return err;
1058 }
1059
1060 return genlmsg_reply(msg, info);
1061}
1062
1063static bool
1064devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1065 struct devlink_rate *parent)
1066{
1067 while (parent) {
1068 if (parent == devlink_rate)
1069 return true;
1070 parent = parent->parent;
1071 }
1072 return false;
1073}
1074
1075static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1076 struct genl_info *info)
1077{
1078 struct devlink_port *devlink_port = info->user_ptr[1];
1079 struct sk_buff *msg;
1080 int err;
1081
1082 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1083 if (!msg)
1084 return -ENOMEM;
1085
1086 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1087 info->snd_portid, info->snd_seq, 0,
1088 info->extack);
1089 if (err) {
1090 nlmsg_free(msg);
1091 return err;
1092 }
1093
1094 return genlmsg_reply(msg, info);
1095}
1096
1097static int
1098devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1099 struct netlink_callback *cb)
1100{
1101 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1102 struct devlink_port *devlink_port;
1103 unsigned long port_index;
1104 int err = 0;
1105
1106 xa_for_each_start(&devlink->ports, port_index, devlink_port, state->idx) {
1107 err = devlink_nl_port_fill(msg, devlink_port,
1108 DEVLINK_CMD_NEW,
1109 NETLINK_CB(cb->skb).portid,
1110 cb->nlh->nlmsg_seq,
1111 NLM_F_MULTI, cb->extack);
1112 if (err) {
1113 state->idx = port_index;
1114 break;
1115 }
1116 }
1117
1118 return err;
1119}
1120
1121const struct devlink_cmd devl_cmd_port_get = {
1122 .dump_one = devlink_nl_cmd_port_get_dump_one,
1123};
1124
1125static int devlink_port_type_set(struct devlink_port *devlink_port,
1126 enum devlink_port_type port_type)
1127
1128{
1129 int err;
1130
1131 if (!devlink_port->ops->port_type_set)
1132 return -EOPNOTSUPP;
1133
1134 if (port_type == devlink_port->type)
1135 return 0;
1136
1137 err = devlink_port->ops->port_type_set(devlink_port, port_type);
1138 if (err)
1139 return err;
1140
1141 devlink_port->desired_type = port_type;
1142 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1143 return 0;
1144}
1145
1146static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1147 const struct nlattr *attr,
1148 struct netlink_ext_ack *extack)
1149{
1150 const u8 *hw_addr;
1151 int hw_addr_len;
1152
1153 hw_addr = nla_data(attr);
1154 hw_addr_len = nla_len(attr);
1155 if (hw_addr_len > MAX_ADDR_LEN) {
1156 NL_SET_ERR_MSG(extack, "Port function hardware address too long");
1157 return -EINVAL;
1158 }
1159 if (port->type == DEVLINK_PORT_TYPE_ETH) {
1160 if (hw_addr_len != ETH_ALEN) {
1161 NL_SET_ERR_MSG(extack, "Address must be 6 bytes for Ethernet device");
1162 return -EINVAL;
1163 }
1164 if (!is_unicast_ether_addr(hw_addr)) {
1165 NL_SET_ERR_MSG(extack, "Non-unicast hardware address unsupported");
1166 return -EINVAL;
1167 }
1168 }
1169
1170 return port->ops->port_fn_hw_addr_set(port, hw_addr, hw_addr_len,
1171 extack);
1172}
1173
1174static int devlink_port_fn_state_set(struct devlink_port *port,
1175 const struct nlattr *attr,
1176 struct netlink_ext_ack *extack)
1177{
1178 enum devlink_port_fn_state state;
1179
1180 state = nla_get_u8(attr);
1181 return port->ops->port_fn_state_set(port, state, extack);
1182}
1183
1184static int devlink_port_function_validate(struct devlink_port *devlink_port,
1185 struct nlattr **tb,
1186 struct netlink_ext_ack *extack)
1187{
1188 const struct devlink_port_ops *ops = devlink_port->ops;
1189 struct nlattr *attr;
1190
1191 if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
1192 !ops->port_fn_hw_addr_set) {
1193 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1194 "Port doesn't support function attributes");
1195 return -EOPNOTSUPP;
1196 }
1197 if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
1198 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1199 "Function does not support state setting");
1200 return -EOPNOTSUPP;
1201 }
1202 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1203 if (attr) {
1204 struct nla_bitfield32 caps;
1205
1206 caps = nla_get_bitfield32(attr);
1207 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE &&
1208 !ops->port_fn_roce_set) {
1209 NL_SET_ERR_MSG_ATTR(extack, attr,
1210 "Port doesn't support RoCE function attribute");
1211 return -EOPNOTSUPP;
1212 }
1213 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
1214 if (!ops->port_fn_migratable_set) {
1215 NL_SET_ERR_MSG_ATTR(extack, attr,
1216 "Port doesn't support migratable function attribute");
1217 return -EOPNOTSUPP;
1218 }
1219 if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) {
1220 NL_SET_ERR_MSG_ATTR(extack, attr,
1221 "migratable function attribute supported for VFs only");
1222 return -EOPNOTSUPP;
1223 }
1224 }
1225 }
1226 return 0;
1227}
1228
1229static int devlink_port_function_set(struct devlink_port *port,
1230 const struct nlattr *attr,
1231 struct netlink_ext_ack *extack)
1232{
1233 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1234 int err;
1235
1236 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1237 devlink_function_nl_policy, extack);
1238 if (err < 0) {
1239 NL_SET_ERR_MSG(extack, "Fail to parse port function attributes");
1240 return err;
1241 }
1242
1243 err = devlink_port_function_validate(port, tb, extack);
1244 if (err)
1245 return err;
1246
1247 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1248 if (attr) {
1249 err = devlink_port_function_hw_addr_set(port, attr, extack);
1250 if (err)
1251 return err;
1252 }
1253
1254 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1255 if (attr) {
1256 err = devlink_port_fn_caps_set(port, attr, extack);
1257 if (err)
1258 return err;
1259 }
1260
1261 /* Keep this as the last function attribute set, so that when
1262 * multiple port function attributes are set along with state,
1263 * Those can be applied first before activating the state.
1264 */
1265 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1266 if (attr)
1267 err = devlink_port_fn_state_set(port, attr, extack);
1268
1269 if (!err)
1270 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1271 return err;
1272}
1273
1274static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1275 struct genl_info *info)
1276{
1277 struct devlink_port *devlink_port = info->user_ptr[1];
1278 int err;
1279
1280 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1281 enum devlink_port_type port_type;
1282
1283 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1284 err = devlink_port_type_set(devlink_port, port_type);
1285 if (err)
1286 return err;
1287 }
1288
1289 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1290 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1291 struct netlink_ext_ack *extack = info->extack;
1292
1293 err = devlink_port_function_set(devlink_port, attr, extack);
1294 if (err)
1295 return err;
1296 }
1297
1298 return 0;
1299}
1300
1301static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1302 struct genl_info *info)
1303{
1304 struct devlink_port *devlink_port = info->user_ptr[1];
1305 struct devlink *devlink = info->user_ptr[0];
1306 u32 count;
1307
1308 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
1309 return -EINVAL;
1310 if (!devlink_port->ops->port_split)
1311 return -EOPNOTSUPP;
1312
1313 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1314
1315 if (!devlink_port->attrs.splittable) {
1316 /* Split ports cannot be split. */
1317 if (devlink_port->attrs.split)
1318 NL_SET_ERR_MSG(info->extack, "Port cannot be split further");
1319 else
1320 NL_SET_ERR_MSG(info->extack, "Port cannot be split");
1321 return -EINVAL;
1322 }
1323
1324 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
1325 NL_SET_ERR_MSG(info->extack, "Invalid split count");
1326 return -EINVAL;
1327 }
1328
1329 return devlink_port->ops->port_split(devlink, devlink_port, count,
1330 info->extack);
1331}
1332
1333static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1334 struct genl_info *info)
1335{
1336 struct devlink_port *devlink_port = info->user_ptr[1];
1337 struct devlink *devlink = info->user_ptr[0];
1338
1339 if (!devlink_port->ops->port_unsplit)
1340 return -EOPNOTSUPP;
1341 return devlink_port->ops->port_unsplit(devlink, devlink_port, info->extack);
1342}
1343
1344static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1345 struct genl_info *info)
1346{
1347 struct netlink_ext_ack *extack = info->extack;
1348 struct devlink_port_new_attrs new_attrs = {};
1349 struct devlink *devlink = info->user_ptr[0];
1350 struct devlink_port *devlink_port;
1351 struct sk_buff *msg;
1352 int err;
1353
1354 if (!devlink->ops->port_new)
1355 return -EOPNOTSUPP;
1356
1357 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1358 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1359 NL_SET_ERR_MSG(extack, "Port flavour or PCI PF are not specified");
1360 return -EINVAL;
1361 }
1362 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1363 new_attrs.pfnum =
1364 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1365
1366 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1367 /* Port index of the new port being created by driver. */
1368 new_attrs.port_index =
1369 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1370 new_attrs.port_index_valid = true;
1371 }
1372 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1373 new_attrs.controller =
1374 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1375 new_attrs.controller_valid = true;
1376 }
1377 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1378 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1379 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1380 new_attrs.sfnum_valid = true;
1381 }
1382
1383 err = devlink->ops->port_new(devlink, &new_attrs,
1384 extack, &devlink_port);
1385 if (err)
1386 return err;
1387
1388 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1389 if (!msg) {
1390 err = -ENOMEM;
1391 goto err_out_port_del;
1392 }
1393 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1394 info->snd_portid, info->snd_seq, 0, NULL);
1395 if (WARN_ON_ONCE(err))
1396 goto err_out_msg_free;
1397 err = genlmsg_reply(msg, info);
1398 if (err)
1399 goto err_out_port_del;
1400 return 0;
1401
1402err_out_msg_free:
1403 nlmsg_free(msg);
1404err_out_port_del:
1405 devlink_port->ops->port_del(devlink, devlink_port, NULL);
1406 return err;
1407}
1408
1409static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1410 struct genl_info *info)
1411{
1412 struct devlink_port *devlink_port = info->user_ptr[1];
1413 struct netlink_ext_ack *extack = info->extack;
1414 struct devlink *devlink = info->user_ptr[0];
1415
1416 if (!devlink_port->ops->port_del)
1417 return -EOPNOTSUPP;
1418
1419 return devlink_port->ops->port_del(devlink, devlink_port, extack);
1420}
1421
1422static int
1423devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1424 struct genl_info *info,
1425 struct nlattr *nla_parent)
1426{
1427 struct devlink *devlink = devlink_rate->devlink;
1428 const char *parent_name = nla_data(nla_parent);
1429 const struct devlink_ops *ops = devlink->ops;
1430 size_t len = strlen(parent_name);
1431 struct devlink_rate *parent;
1432 int err = -EOPNOTSUPP;
1433
1434 parent = devlink_rate->parent;
1435
1436 if (parent && !len) {
1437 if (devlink_rate_is_leaf(devlink_rate))
1438 err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1439 devlink_rate->priv, NULL,
1440 info->extack);
1441 else if (devlink_rate_is_node(devlink_rate))
1442 err = ops->rate_node_parent_set(devlink_rate, NULL,
1443 devlink_rate->priv, NULL,
1444 info->extack);
1445 if (err)
1446 return err;
1447
1448 refcount_dec(&parent->refcnt);
1449 devlink_rate->parent = NULL;
1450 } else if (len) {
1451 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1452 if (IS_ERR(parent))
1453 return -ENODEV;
1454
1455 if (parent == devlink_rate) {
1456 NL_SET_ERR_MSG(info->extack, "Parent to self is not allowed");
1457 return -EINVAL;
1458 }
1459
1460 if (devlink_rate_is_node(devlink_rate) &&
1461 devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1462 NL_SET_ERR_MSG(info->extack, "Node is already a parent of parent node.");
1463 return -EEXIST;
1464 }
1465
1466 if (devlink_rate_is_leaf(devlink_rate))
1467 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1468 devlink_rate->priv, parent->priv,
1469 info->extack);
1470 else if (devlink_rate_is_node(devlink_rate))
1471 err = ops->rate_node_parent_set(devlink_rate, parent,
1472 devlink_rate->priv, parent->priv,
1473 info->extack);
1474 if (err)
1475 return err;
1476
1477 if (devlink_rate->parent)
1478 /* we're reassigning to other parent in this case */
1479 refcount_dec(&devlink_rate->parent->refcnt);
1480
1481 refcount_inc(&parent->refcnt);
1482 devlink_rate->parent = parent;
1483 }
1484
1485 return 0;
1486}
1487
1488static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1489 const struct devlink_ops *ops,
1490 struct genl_info *info)
1491{
1492 struct nlattr *nla_parent, **attrs = info->attrs;
1493 int err = -EOPNOTSUPP;
1494 u32 priority;
1495 u32 weight;
1496 u64 rate;
1497
1498 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1499 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1500 if (devlink_rate_is_leaf(devlink_rate))
1501 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1502 rate, info->extack);
1503 else if (devlink_rate_is_node(devlink_rate))
1504 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1505 rate, info->extack);
1506 if (err)
1507 return err;
1508 devlink_rate->tx_share = rate;
1509 }
1510
1511 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1512 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1513 if (devlink_rate_is_leaf(devlink_rate))
1514 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1515 rate, info->extack);
1516 else if (devlink_rate_is_node(devlink_rate))
1517 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1518 rate, info->extack);
1519 if (err)
1520 return err;
1521 devlink_rate->tx_max = rate;
1522 }
1523
1524 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
1525 priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
1526 if (devlink_rate_is_leaf(devlink_rate))
1527 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
1528 priority, info->extack);
1529 else if (devlink_rate_is_node(devlink_rate))
1530 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
1531 priority, info->extack);
1532
1533 if (err)
1534 return err;
1535 devlink_rate->tx_priority = priority;
1536 }
1537
1538 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
1539 weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
1540 if (devlink_rate_is_leaf(devlink_rate))
1541 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
1542 weight, info->extack);
1543 else if (devlink_rate_is_node(devlink_rate))
1544 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
1545 weight, info->extack);
1546
1547 if (err)
1548 return err;
1549 devlink_rate->tx_weight = weight;
1550 }
1551
1552 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1553 if (nla_parent) {
1554 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1555 nla_parent);
1556 if (err)
1557 return err;
1558 }
1559
1560 return 0;
1561}
1562
1563static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1564 struct genl_info *info,
1565 enum devlink_rate_type type)
1566{
1567 struct nlattr **attrs = info->attrs;
1568
1569 if (type == DEVLINK_RATE_TYPE_LEAF) {
1570 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1571 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the leafs");
1572 return false;
1573 }
1574 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1575 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the leafs");
1576 return false;
1577 }
1578 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1579 !ops->rate_leaf_parent_set) {
1580 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the leafs");
1581 return false;
1582 }
1583 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
1584 NL_SET_ERR_MSG_ATTR(info->extack,
1585 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1586 "TX priority set isn't supported for the leafs");
1587 return false;
1588 }
1589 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
1590 NL_SET_ERR_MSG_ATTR(info->extack,
1591 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1592 "TX weight set isn't supported for the leafs");
1593 return false;
1594 }
1595 } else if (type == DEVLINK_RATE_TYPE_NODE) {
1596 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1597 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the nodes");
1598 return false;
1599 }
1600 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1601 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the nodes");
1602 return false;
1603 }
1604 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1605 !ops->rate_node_parent_set) {
1606 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the nodes");
1607 return false;
1608 }
1609 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) {
1610 NL_SET_ERR_MSG_ATTR(info->extack,
1611 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1612 "TX priority set isn't supported for the nodes");
1613 return false;
1614 }
1615 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) {
1616 NL_SET_ERR_MSG_ATTR(info->extack,
1617 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1618 "TX weight set isn't supported for the nodes");
1619 return false;
1620 }
1621 } else {
1622 WARN(1, "Unknown type of rate object");
1623 return false;
1624 }
1625
1626 return true;
1627}
1628
1629static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
1630 struct genl_info *info)
1631{
1632 struct devlink_rate *devlink_rate = info->user_ptr[1];
1633 struct devlink *devlink = devlink_rate->devlink;
1634 const struct devlink_ops *ops = devlink->ops;
1635 int err;
1636
1637 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
1638 return -EOPNOTSUPP;
1639
1640 err = devlink_nl_rate_set(devlink_rate, ops, info);
1641
1642 if (!err)
1643 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
1644 return err;
1645}
1646
1647static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
1648 struct genl_info *info)
1649{
1650 struct devlink *devlink = info->user_ptr[0];
1651 struct devlink_rate *rate_node;
1652 const struct devlink_ops *ops;
1653 int err;
1654
1655 ops = devlink->ops;
1656 if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
1657 NL_SET_ERR_MSG(info->extack, "Rate nodes aren't supported");
1658 return -EOPNOTSUPP;
1659 }
1660
1661 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
1662 return -EOPNOTSUPP;
1663
1664 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
1665 if (!IS_ERR(rate_node))
1666 return -EEXIST;
1667 else if (rate_node == ERR_PTR(-EINVAL))
1668 return -EINVAL;
1669
1670 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
1671 if (!rate_node)
1672 return -ENOMEM;
1673
1674 rate_node->devlink = devlink;
1675 rate_node->type = DEVLINK_RATE_TYPE_NODE;
1676 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
1677 if (!rate_node->name) {
1678 err = -ENOMEM;
1679 goto err_strdup;
1680 }
1681
1682 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
1683 if (err)
1684 goto err_node_new;
1685
1686 err = devlink_nl_rate_set(rate_node, ops, info);
1687 if (err)
1688 goto err_rate_set;
1689
1690 refcount_set(&rate_node->refcnt, 1);
1691 list_add(&rate_node->list, &devlink->rate_list);
1692 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
1693 return 0;
1694
1695err_rate_set:
1696 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1697err_node_new:
1698 kfree(rate_node->name);
1699err_strdup:
1700 kfree(rate_node);
1701 return err;
1702}
1703
1704static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
1705 struct genl_info *info)
1706{
1707 struct devlink_rate *rate_node = info->user_ptr[1];
1708 struct devlink *devlink = rate_node->devlink;
1709 const struct devlink_ops *ops = devlink->ops;
1710 int err;
1711
1712 if (refcount_read(&rate_node->refcnt) > 1) {
1713 NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node.");
1714 return -EBUSY;
1715 }
1716
1717 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
1718 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1719 if (rate_node->parent)
1720 refcount_dec(&rate_node->parent->refcnt);
1721 list_del(&rate_node->list);
1722 kfree(rate_node->name);
1723 kfree(rate_node);
1724 return err;
1725}
1726
1727struct devlink_linecard_type {
1728 const char *type;
1729 const void *priv;
1730};
1731
1732static int devlink_nl_linecard_fill(struct sk_buff *msg,
1733 struct devlink *devlink,
1734 struct devlink_linecard *linecard,
1735 enum devlink_command cmd, u32 portid,
1736 u32 seq, int flags,
1737 struct netlink_ext_ack *extack)
1738{
1739 struct devlink_linecard_type *linecard_type;
1740 struct nlattr *attr;
1741 void *hdr;
1742 int i;
1743
1744 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1745 if (!hdr)
1746 return -EMSGSIZE;
1747
1748 if (devlink_nl_put_handle(msg, devlink))
1749 goto nla_put_failure;
1750 if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
1751 goto nla_put_failure;
1752 if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
1753 goto nla_put_failure;
1754 if (linecard->type &&
1755 nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
1756 goto nla_put_failure;
1757
1758 if (linecard->types_count) {
1759 attr = nla_nest_start(msg,
1760 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
1761 if (!attr)
1762 goto nla_put_failure;
1763 for (i = 0; i < linecard->types_count; i++) {
1764 linecard_type = &linecard->types[i];
1765 if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
1766 linecard_type->type)) {
1767 nla_nest_cancel(msg, attr);
1768 goto nla_put_failure;
1769 }
1770 }
1771 nla_nest_end(msg, attr);
1772 }
1773
1774 if (linecard->nested_devlink &&
1775 devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
1776 goto nla_put_failure;
1777
1778 genlmsg_end(msg, hdr);
1779 return 0;
1780
1781nla_put_failure:
1782 genlmsg_cancel(msg, hdr);
1783 return -EMSGSIZE;
1784}
1785
1786static void devlink_linecard_notify(struct devlink_linecard *linecard,
1787 enum devlink_command cmd)
1788{
1789 struct devlink *devlink = linecard->devlink;
1790 struct sk_buff *msg;
1791 int err;
1792
1793 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
1794 cmd != DEVLINK_CMD_LINECARD_DEL);
1795
1796 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1797 return;
1798
1799 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1800 if (!msg)
1801 return;
1802
1803 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
1804 NULL);
1805 if (err) {
1806 nlmsg_free(msg);
1807 return;
1808 }
1809
1810 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
1811 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1812}
1813
1814static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
1815 struct genl_info *info)
1816{
1817 struct devlink_linecard *linecard = info->user_ptr[1];
1818 struct devlink *devlink = linecard->devlink;
1819 struct sk_buff *msg;
1820 int err;
1821
1822 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1823 if (!msg)
1824 return -ENOMEM;
1825
1826 mutex_lock(&linecard->state_lock);
1827 err = devlink_nl_linecard_fill(msg, devlink, linecard,
1828 DEVLINK_CMD_LINECARD_NEW,
1829 info->snd_portid, info->snd_seq, 0,
1830 info->extack);
1831 mutex_unlock(&linecard->state_lock);
1832 if (err) {
1833 nlmsg_free(msg);
1834 return err;
1835 }
1836
1837 return genlmsg_reply(msg, info);
1838}
1839
1840static int devlink_nl_cmd_linecard_get_dump_one(struct sk_buff *msg,
1841 struct devlink *devlink,
1842 struct netlink_callback *cb)
1843{
1844 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1845 struct devlink_linecard *linecard;
1846 int idx = 0;
1847 int err = 0;
1848
1849 list_for_each_entry(linecard, &devlink->linecard_list, list) {
1850 if (idx < state->idx) {
1851 idx++;
1852 continue;
1853 }
1854 mutex_lock(&linecard->state_lock);
1855 err = devlink_nl_linecard_fill(msg, devlink, linecard,
1856 DEVLINK_CMD_LINECARD_NEW,
1857 NETLINK_CB(cb->skb).portid,
1858 cb->nlh->nlmsg_seq,
1859 NLM_F_MULTI,
1860 cb->extack);
1861 mutex_unlock(&linecard->state_lock);
1862 if (err) {
1863 state->idx = idx;
1864 break;
1865 }
1866 idx++;
1867 }
1868
1869 return err;
1870}
1871
1872const struct devlink_cmd devl_cmd_linecard_get = {
1873 .dump_one = devlink_nl_cmd_linecard_get_dump_one,
1874};
1875
1876static struct devlink_linecard_type *
1877devlink_linecard_type_lookup(struct devlink_linecard *linecard,
1878 const char *type)
1879{
1880 struct devlink_linecard_type *linecard_type;
1881 int i;
1882
1883 for (i = 0; i < linecard->types_count; i++) {
1884 linecard_type = &linecard->types[i];
1885 if (!strcmp(type, linecard_type->type))
1886 return linecard_type;
1887 }
1888 return NULL;
1889}
1890
1891static int devlink_linecard_type_set(struct devlink_linecard *linecard,
1892 const char *type,
1893 struct netlink_ext_ack *extack)
1894{
1895 const struct devlink_linecard_ops *ops = linecard->ops;
1896 struct devlink_linecard_type *linecard_type;
1897 int err;
1898
1899 mutex_lock(&linecard->state_lock);
1900 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
1901 NL_SET_ERR_MSG(extack, "Line card is currently being provisioned");
1902 err = -EBUSY;
1903 goto out;
1904 }
1905 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
1906 NL_SET_ERR_MSG(extack, "Line card is currently being unprovisioned");
1907 err = -EBUSY;
1908 goto out;
1909 }
1910
1911 linecard_type = devlink_linecard_type_lookup(linecard, type);
1912 if (!linecard_type) {
1913 NL_SET_ERR_MSG(extack, "Unsupported line card type provided");
1914 err = -EINVAL;
1915 goto out;
1916 }
1917
1918 if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
1919 linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
1920 NL_SET_ERR_MSG(extack, "Line card already provisioned");
1921 err = -EBUSY;
1922 /* Check if the line card is provisioned in the same
1923 * way the user asks. In case it is, make the operation
1924 * to return success.
1925 */
1926 if (ops->same_provision &&
1927 ops->same_provision(linecard, linecard->priv,
1928 linecard_type->type,
1929 linecard_type->priv))
1930 err = 0;
1931 goto out;
1932 }
1933
1934 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
1935 linecard->type = linecard_type->type;
1936 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1937 mutex_unlock(&linecard->state_lock);
1938 err = ops->provision(linecard, linecard->priv, linecard_type->type,
1939 linecard_type->priv, extack);
1940 if (err) {
1941 /* Provisioning failed. Assume the linecard is unprovisioned
1942 * for future operations.
1943 */
1944 mutex_lock(&linecard->state_lock);
1945 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
1946 linecard->type = NULL;
1947 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1948 mutex_unlock(&linecard->state_lock);
1949 }
1950 return err;
1951
1952out:
1953 mutex_unlock(&linecard->state_lock);
1954 return err;
1955}
1956
1957static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
1958 struct netlink_ext_ack *extack)
1959{
1960 int err;
1961
1962 mutex_lock(&linecard->state_lock);
1963 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
1964 NL_SET_ERR_MSG(extack, "Line card is currently being provisioned");
1965 err = -EBUSY;
1966 goto out;
1967 }
1968 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
1969 NL_SET_ERR_MSG(extack, "Line card is currently being unprovisioned");
1970 err = -EBUSY;
1971 goto out;
1972 }
1973 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
1974 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
1975 linecard->type = NULL;
1976 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1977 err = 0;
1978 goto out;
1979 }
1980
1981 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
1982 NL_SET_ERR_MSG(extack, "Line card is not provisioned");
1983 err = 0;
1984 goto out;
1985 }
1986 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
1987 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1988 mutex_unlock(&linecard->state_lock);
1989 err = linecard->ops->unprovision(linecard, linecard->priv,
1990 extack);
1991 if (err) {
1992 /* Unprovisioning failed. Assume the linecard is unprovisioned
1993 * for future operations.
1994 */
1995 mutex_lock(&linecard->state_lock);
1996 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
1997 linecard->type = NULL;
1998 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1999 mutex_unlock(&linecard->state_lock);
2000 }
2001 return err;
2002
2003out:
2004 mutex_unlock(&linecard->state_lock);
2005 return err;
2006}
2007
2008static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2009 struct genl_info *info)
2010{
2011 struct devlink_linecard *linecard = info->user_ptr[1];
2012 struct netlink_ext_ack *extack = info->extack;
2013 int err;
2014
2015 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2016 const char *type;
2017
2018 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2019 if (strcmp(type, "")) {
2020 err = devlink_linecard_type_set(linecard, type, extack);
2021 if (err)
2022 return err;
2023 } else {
2024 err = devlink_linecard_type_unset(linecard, extack);
2025 if (err)
2026 return err;
2027 }
2028 }
2029
2030 return 0;
2031}
2032
2033static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
2034 struct devlink_sb *devlink_sb,
2035 enum devlink_command cmd, u32 portid,
2036 u32 seq, int flags)
2037{
2038 void *hdr;
2039
2040 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2041 if (!hdr)
2042 return -EMSGSIZE;
2043
2044 if (devlink_nl_put_handle(msg, devlink))
2045 goto nla_put_failure;
2046 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2047 goto nla_put_failure;
2048 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
2049 goto nla_put_failure;
2050 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
2051 devlink_sb->ingress_pools_count))
2052 goto nla_put_failure;
2053 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
2054 devlink_sb->egress_pools_count))
2055 goto nla_put_failure;
2056 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
2057 devlink_sb->ingress_tc_count))
2058 goto nla_put_failure;
2059 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
2060 devlink_sb->egress_tc_count))
2061 goto nla_put_failure;
2062
2063 genlmsg_end(msg, hdr);
2064 return 0;
2065
2066nla_put_failure:
2067 genlmsg_cancel(msg, hdr);
2068 return -EMSGSIZE;
2069}
2070
2071static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2072 struct genl_info *info)
2073{
2074 struct devlink *devlink = info->user_ptr[0];
2075 struct devlink_sb *devlink_sb;
2076 struct sk_buff *msg;
2077 int err;
2078
2079 devlink_sb = devlink_sb_get_from_info(devlink, info);
2080 if (IS_ERR(devlink_sb))
2081 return PTR_ERR(devlink_sb);
2082
2083 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2084 if (!msg)
2085 return -ENOMEM;
2086
2087 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2088 DEVLINK_CMD_SB_NEW,
2089 info->snd_portid, info->snd_seq, 0);
2090 if (err) {
2091 nlmsg_free(msg);
2092 return err;
2093 }
2094
2095 return genlmsg_reply(msg, info);
2096}
2097
2098static int
2099devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
2100 struct netlink_callback *cb)
2101{
2102 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2103 struct devlink_sb *devlink_sb;
2104 int idx = 0;
2105 int err = 0;
2106
2107 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2108 if (idx < state->idx) {
2109 idx++;
2110 continue;
2111 }
2112 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2113 DEVLINK_CMD_SB_NEW,
2114 NETLINK_CB(cb->skb).portid,
2115 cb->nlh->nlmsg_seq,
2116 NLM_F_MULTI);
2117 if (err) {
2118 state->idx = idx;
2119 break;
2120 }
2121 idx++;
2122 }
2123
2124 return err;
2125}
2126
2127const struct devlink_cmd devl_cmd_sb_get = {
2128 .dump_one = devlink_nl_cmd_sb_get_dump_one,
2129};
2130
2131static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
2132 struct devlink_sb *devlink_sb,
2133 u16 pool_index, enum devlink_command cmd,
2134 u32 portid, u32 seq, int flags)
2135{
2136 struct devlink_sb_pool_info pool_info;
2137 void *hdr;
2138 int err;
2139
2140 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2141 pool_index, &pool_info);
2142 if (err)
2143 return err;
2144
2145 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2146 if (!hdr)
2147 return -EMSGSIZE;
2148
2149 if (devlink_nl_put_handle(msg, devlink))
2150 goto nla_put_failure;
2151 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2152 goto nla_put_failure;
2153 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2154 goto nla_put_failure;
2155 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
2156 goto nla_put_failure;
2157 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
2158 goto nla_put_failure;
2159 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
2160 pool_info.threshold_type))
2161 goto nla_put_failure;
2162 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
2163 pool_info.cell_size))
2164 goto nla_put_failure;
2165
2166 genlmsg_end(msg, hdr);
2167 return 0;
2168
2169nla_put_failure:
2170 genlmsg_cancel(msg, hdr);
2171 return -EMSGSIZE;
2172}
2173
2174static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2175 struct genl_info *info)
2176{
2177 struct devlink *devlink = info->user_ptr[0];
2178 struct devlink_sb *devlink_sb;
2179 struct sk_buff *msg;
2180 u16 pool_index;
2181 int err;
2182
2183 devlink_sb = devlink_sb_get_from_info(devlink, info);
2184 if (IS_ERR(devlink_sb))
2185 return PTR_ERR(devlink_sb);
2186
2187 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2188 &pool_index);
2189 if (err)
2190 return err;
2191
2192 if (!devlink->ops->sb_pool_get)
2193 return -EOPNOTSUPP;
2194
2195 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2196 if (!msg)
2197 return -ENOMEM;
2198
2199 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
2200 DEVLINK_CMD_SB_POOL_NEW,
2201 info->snd_portid, info->snd_seq, 0);
2202 if (err) {
2203 nlmsg_free(msg);
2204 return err;
2205 }
2206
2207 return genlmsg_reply(msg, info);
2208}
2209
2210static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2211 struct devlink *devlink,
2212 struct devlink_sb *devlink_sb,
2213 u32 portid, u32 seq)
2214{
2215 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2216 u16 pool_index;
2217 int err;
2218
2219 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2220 if (*p_idx < start) {
2221 (*p_idx)++;
2222 continue;
2223 }
2224 err = devlink_nl_sb_pool_fill(msg, devlink,
2225 devlink_sb,
2226 pool_index,
2227 DEVLINK_CMD_SB_POOL_NEW,
2228 portid, seq, NLM_F_MULTI);
2229 if (err)
2230 return err;
2231 (*p_idx)++;
2232 }
2233 return 0;
2234}
2235
2236static int
2237devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg,
2238 struct devlink *devlink,
2239 struct netlink_callback *cb)
2240{
2241 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2242 struct devlink_sb *devlink_sb;
2243 int err = 0;
2244 int idx = 0;
2245
2246 if (!devlink->ops->sb_pool_get)
2247 return 0;
2248
2249 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2250 err = __sb_pool_get_dumpit(msg, state->idx, &idx,
2251 devlink, devlink_sb,
2252 NETLINK_CB(cb->skb).portid,
2253 cb->nlh->nlmsg_seq);
2254 if (err == -EOPNOTSUPP) {
2255 err = 0;
2256 } else if (err) {
2257 state->idx = idx;
2258 break;
2259 }
2260 }
2261
2262 return err;
2263}
2264
2265const struct devlink_cmd devl_cmd_sb_pool_get = {
2266 .dump_one = devlink_nl_cmd_sb_pool_get_dump_one,
2267};
2268
2269static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
2270 u16 pool_index, u32 size,
2271 enum devlink_sb_threshold_type threshold_type,
2272 struct netlink_ext_ack *extack)
2273
2274{
2275 const struct devlink_ops *ops = devlink->ops;
2276
2277 if (ops->sb_pool_set)
2278 return ops->sb_pool_set(devlink, sb_index, pool_index,
2279 size, threshold_type, extack);
2280 return -EOPNOTSUPP;
2281}
2282
2283static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2284 struct genl_info *info)
2285{
2286 struct devlink *devlink = info->user_ptr[0];
2287 enum devlink_sb_threshold_type threshold_type;
2288 struct devlink_sb *devlink_sb;
2289 u16 pool_index;
2290 u32 size;
2291 int err;
2292
2293 devlink_sb = devlink_sb_get_from_info(devlink, info);
2294 if (IS_ERR(devlink_sb))
2295 return PTR_ERR(devlink_sb);
2296
2297 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2298 &pool_index);
2299 if (err)
2300 return err;
2301
2302 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2303 if (err)
2304 return err;
2305
2306 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
2307 return -EINVAL;
2308
2309 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
2310 return devlink_sb_pool_set(devlink, devlink_sb->index,
2311 pool_index, size, threshold_type,
2312 info->extack);
2313}
2314
2315static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
2316 struct devlink *devlink,
2317 struct devlink_port *devlink_port,
2318 struct devlink_sb *devlink_sb,
2319 u16 pool_index,
2320 enum devlink_command cmd,
2321 u32 portid, u32 seq, int flags)
2322{
2323 const struct devlink_ops *ops = devlink->ops;
2324 u32 threshold;
2325 void *hdr;
2326 int err;
2327
2328 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2329 pool_index, &threshold);
2330 if (err)
2331 return err;
2332
2333 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2334 if (!hdr)
2335 return -EMSGSIZE;
2336
2337 if (devlink_nl_put_handle(msg, devlink))
2338 goto nla_put_failure;
2339 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2340 goto nla_put_failure;
2341 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2342 goto nla_put_failure;
2343 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2344 goto nla_put_failure;
2345 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2346 goto nla_put_failure;
2347
2348 if (ops->sb_occ_port_pool_get) {
2349 u32 cur;
2350 u32 max;
2351
2352 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
2353 pool_index, &cur, &max);
2354 if (err && err != -EOPNOTSUPP)
2355 goto sb_occ_get_failure;
2356 if (!err) {
2357 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2358 goto nla_put_failure;
2359 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2360 goto nla_put_failure;
2361 }
2362 }
2363
2364 genlmsg_end(msg, hdr);
2365 return 0;
2366
2367nla_put_failure:
2368 err = -EMSGSIZE;
2369sb_occ_get_failure:
2370 genlmsg_cancel(msg, hdr);
2371 return err;
2372}
2373
2374static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2375 struct genl_info *info)
2376{
2377 struct devlink_port *devlink_port = info->user_ptr[1];
2378 struct devlink *devlink = devlink_port->devlink;
2379 struct devlink_sb *devlink_sb;
2380 struct sk_buff *msg;
2381 u16 pool_index;
2382 int err;
2383
2384 devlink_sb = devlink_sb_get_from_info(devlink, info);
2385 if (IS_ERR(devlink_sb))
2386 return PTR_ERR(devlink_sb);
2387
2388 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2389 &pool_index);
2390 if (err)
2391 return err;
2392
2393 if (!devlink->ops->sb_port_pool_get)
2394 return -EOPNOTSUPP;
2395
2396 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2397 if (!msg)
2398 return -ENOMEM;
2399
2400 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
2401 devlink_sb, pool_index,
2402 DEVLINK_CMD_SB_PORT_POOL_NEW,
2403 info->snd_portid, info->snd_seq, 0);
2404 if (err) {
2405 nlmsg_free(msg);
2406 return err;
2407 }
2408
2409 return genlmsg_reply(msg, info);
2410}
2411
2412static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2413 struct devlink *devlink,
2414 struct devlink_sb *devlink_sb,
2415 u32 portid, u32 seq)
2416{
2417 struct devlink_port *devlink_port;
2418 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2419 unsigned long port_index;
2420 u16 pool_index;
2421 int err;
2422
2423 xa_for_each(&devlink->ports, port_index, devlink_port) {
2424 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2425 if (*p_idx < start) {
2426 (*p_idx)++;
2427 continue;
2428 }
2429 err = devlink_nl_sb_port_pool_fill(msg, devlink,
2430 devlink_port,
2431 devlink_sb,
2432 pool_index,
2433 DEVLINK_CMD_SB_PORT_POOL_NEW,
2434 portid, seq,
2435 NLM_F_MULTI);
2436 if (err)
2437 return err;
2438 (*p_idx)++;
2439 }
2440 }
2441 return 0;
2442}
2443
2444static int
2445devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg,
2446 struct devlink *devlink,
2447 struct netlink_callback *cb)
2448{
2449 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2450 struct devlink_sb *devlink_sb;
2451 int idx = 0;
2452 int err = 0;
2453
2454 if (!devlink->ops->sb_port_pool_get)
2455 return 0;
2456
2457 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2458 err = __sb_port_pool_get_dumpit(msg, state->idx, &idx,
2459 devlink, devlink_sb,
2460 NETLINK_CB(cb->skb).portid,
2461 cb->nlh->nlmsg_seq);
2462 if (err == -EOPNOTSUPP) {
2463 err = 0;
2464 } else if (err) {
2465 state->idx = idx;
2466 break;
2467 }
2468 }
2469
2470 return err;
2471}
2472
2473const struct devlink_cmd devl_cmd_sb_port_pool_get = {
2474 .dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one,
2475};
2476
2477static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2478 unsigned int sb_index, u16 pool_index,
2479 u32 threshold,
2480 struct netlink_ext_ack *extack)
2481
2482{
2483 const struct devlink_ops *ops = devlink_port->devlink->ops;
2484
2485 if (ops->sb_port_pool_set)
2486 return ops->sb_port_pool_set(devlink_port, sb_index,
2487 pool_index, threshold, extack);
2488 return -EOPNOTSUPP;
2489}
2490
2491static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2492 struct genl_info *info)
2493{
2494 struct devlink_port *devlink_port = info->user_ptr[1];
2495 struct devlink *devlink = info->user_ptr[0];
2496 struct devlink_sb *devlink_sb;
2497 u16 pool_index;
2498 u32 threshold;
2499 int err;
2500
2501 devlink_sb = devlink_sb_get_from_info(devlink, info);
2502 if (IS_ERR(devlink_sb))
2503 return PTR_ERR(devlink_sb);
2504
2505 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2506 &pool_index);
2507 if (err)
2508 return err;
2509
2510 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2511 return -EINVAL;
2512
2513 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2514 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
2515 pool_index, threshold, info->extack);
2516}
2517
2518static int
2519devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
2520 struct devlink_port *devlink_port,
2521 struct devlink_sb *devlink_sb, u16 tc_index,
2522 enum devlink_sb_pool_type pool_type,
2523 enum devlink_command cmd,
2524 u32 portid, u32 seq, int flags)
2525{
2526 const struct devlink_ops *ops = devlink->ops;
2527 u16 pool_index;
2528 u32 threshold;
2529 void *hdr;
2530 int err;
2531
2532 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2533 tc_index, pool_type,
2534 &pool_index, &threshold);
2535 if (err)
2536 return err;
2537
2538 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2539 if (!hdr)
2540 return -EMSGSIZE;
2541
2542 if (devlink_nl_put_handle(msg, devlink))
2543 goto nla_put_failure;
2544 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2545 goto nla_put_failure;
2546 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2547 goto nla_put_failure;
2548 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
2549 goto nla_put_failure;
2550 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
2551 goto nla_put_failure;
2552 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2553 goto nla_put_failure;
2554 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2555 goto nla_put_failure;
2556
2557 if (ops->sb_occ_tc_port_bind_get) {
2558 u32 cur;
2559 u32 max;
2560
2561 err = ops->sb_occ_tc_port_bind_get(devlink_port,
2562 devlink_sb->index,
2563 tc_index, pool_type,
2564 &cur, &max);
2565 if (err && err != -EOPNOTSUPP)
2566 return err;
2567 if (!err) {
2568 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2569 goto nla_put_failure;
2570 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2571 goto nla_put_failure;
2572 }
2573 }
2574
2575 genlmsg_end(msg, hdr);
2576 return 0;
2577
2578nla_put_failure:
2579 genlmsg_cancel(msg, hdr);
2580 return -EMSGSIZE;
2581}
2582
2583static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
2584 struct genl_info *info)
2585{
2586 struct devlink_port *devlink_port = info->user_ptr[1];
2587 struct devlink *devlink = devlink_port->devlink;
2588 struct devlink_sb *devlink_sb;
2589 struct sk_buff *msg;
2590 enum devlink_sb_pool_type pool_type;
2591 u16 tc_index;
2592 int err;
2593
2594 devlink_sb = devlink_sb_get_from_info(devlink, info);
2595 if (IS_ERR(devlink_sb))
2596 return PTR_ERR(devlink_sb);
2597
2598 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2599 if (err)
2600 return err;
2601
2602 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2603 pool_type, &tc_index);
2604 if (err)
2605 return err;
2606
2607 if (!devlink->ops->sb_tc_pool_bind_get)
2608 return -EOPNOTSUPP;
2609
2610 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2611 if (!msg)
2612 return -ENOMEM;
2613
2614 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
2615 devlink_sb, tc_index, pool_type,
2616 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2617 info->snd_portid,
2618 info->snd_seq, 0);
2619 if (err) {
2620 nlmsg_free(msg);
2621 return err;
2622 }
2623
2624 return genlmsg_reply(msg, info);
2625}
2626
2627static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
2628 int start, int *p_idx,
2629 struct devlink *devlink,
2630 struct devlink_sb *devlink_sb,
2631 u32 portid, u32 seq)
2632{
2633 struct devlink_port *devlink_port;
2634 unsigned long port_index;
2635 u16 tc_index;
2636 int err;
2637
2638 xa_for_each(&devlink->ports, port_index, devlink_port) {
2639 for (tc_index = 0;
2640 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
2641 if (*p_idx < start) {
2642 (*p_idx)++;
2643 continue;
2644 }
2645 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2646 devlink_port,
2647 devlink_sb,
2648 tc_index,
2649 DEVLINK_SB_POOL_TYPE_INGRESS,
2650 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2651 portid, seq,
2652 NLM_F_MULTI);
2653 if (err)
2654 return err;
2655 (*p_idx)++;
2656 }
2657 for (tc_index = 0;
2658 tc_index < devlink_sb->egress_tc_count; tc_index++) {
2659 if (*p_idx < start) {
2660 (*p_idx)++;
2661 continue;
2662 }
2663 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2664 devlink_port,
2665 devlink_sb,
2666 tc_index,
2667 DEVLINK_SB_POOL_TYPE_EGRESS,
2668 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2669 portid, seq,
2670 NLM_F_MULTI);
2671 if (err)
2672 return err;
2673 (*p_idx)++;
2674 }
2675 }
2676 return 0;
2677}
2678
2679static int
2680devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg,
2681 struct devlink *devlink,
2682 struct netlink_callback *cb)
2683{
2684 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2685 struct devlink_sb *devlink_sb;
2686 int idx = 0;
2687 int err = 0;
2688
2689 if (!devlink->ops->sb_tc_pool_bind_get)
2690 return 0;
2691
2692 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2693 err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx,
2694 devlink, devlink_sb,
2695 NETLINK_CB(cb->skb).portid,
2696 cb->nlh->nlmsg_seq);
2697 if (err == -EOPNOTSUPP) {
2698 err = 0;
2699 } else if (err) {
2700 state->idx = idx;
2701 break;
2702 }
2703 }
2704
2705 return err;
2706}
2707
2708const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get = {
2709 .dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one,
2710};
2711
2712static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
2713 unsigned int sb_index, u16 tc_index,
2714 enum devlink_sb_pool_type pool_type,
2715 u16 pool_index, u32 threshold,
2716 struct netlink_ext_ack *extack)
2717
2718{
2719 const struct devlink_ops *ops = devlink_port->devlink->ops;
2720
2721 if (ops->sb_tc_pool_bind_set)
2722 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
2723 tc_index, pool_type,
2724 pool_index, threshold, extack);
2725 return -EOPNOTSUPP;
2726}
2727
2728static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
2729 struct genl_info *info)
2730{
2731 struct devlink_port *devlink_port = info->user_ptr[1];
2732 struct devlink *devlink = info->user_ptr[0];
2733 enum devlink_sb_pool_type pool_type;
2734 struct devlink_sb *devlink_sb;
2735 u16 tc_index;
2736 u16 pool_index;
2737 u32 threshold;
2738 int err;
2739
2740 devlink_sb = devlink_sb_get_from_info(devlink, info);
2741 if (IS_ERR(devlink_sb))
2742 return PTR_ERR(devlink_sb);
2743
2744 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2745 if (err)
2746 return err;
2747
2748 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2749 pool_type, &tc_index);
2750 if (err)
2751 return err;
2752
2753 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2754 &pool_index);
2755 if (err)
2756 return err;
2757
2758 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2759 return -EINVAL;
2760
2761 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2762 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
2763 tc_index, pool_type,
2764 pool_index, threshold, info->extack);
2765}
2766
2767static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
2768 struct genl_info *info)
2769{
2770 struct devlink *devlink = info->user_ptr[0];
2771 const struct devlink_ops *ops = devlink->ops;
2772 struct devlink_sb *devlink_sb;
2773
2774 devlink_sb = devlink_sb_get_from_info(devlink, info);
2775 if (IS_ERR(devlink_sb))
2776 return PTR_ERR(devlink_sb);
2777
2778 if (ops->sb_occ_snapshot)
2779 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
2780 return -EOPNOTSUPP;
2781}
2782
2783static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
2784 struct genl_info *info)
2785{
2786 struct devlink *devlink = info->user_ptr[0];
2787 const struct devlink_ops *ops = devlink->ops;
2788 struct devlink_sb *devlink_sb;
2789
2790 devlink_sb = devlink_sb_get_from_info(devlink, info);
2791 if (IS_ERR(devlink_sb))
2792 return PTR_ERR(devlink_sb);
2793
2794 if (ops->sb_occ_max_clear)
2795 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
2796 return -EOPNOTSUPP;
2797}
2798
2799int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
2800 struct netlink_ext_ack *extack)
2801{
2802 struct devlink_rate *devlink_rate;
2803
2804 list_for_each_entry(devlink_rate, &devlink->rate_list, list)
2805 if (devlink_rate_is_node(devlink_rate)) {
2806 NL_SET_ERR_MSG(extack, "Rate node(s) exists.");
2807 return -EBUSY;
2808 }
2809 return 0;
2810}
2811
2812int devlink_dpipe_match_put(struct sk_buff *skb,
2813 struct devlink_dpipe_match *match)
2814{
2815 struct devlink_dpipe_header *header = match->header;
2816 struct devlink_dpipe_field *field = &header->fields[match->field_id];
2817 struct nlattr *match_attr;
2818
2819 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
2820 if (!match_attr)
2821 return -EMSGSIZE;
2822
2823 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
2824 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
2825 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2826 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2827 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2828 goto nla_put_failure;
2829
2830 nla_nest_end(skb, match_attr);
2831 return 0;
2832
2833nla_put_failure:
2834 nla_nest_cancel(skb, match_attr);
2835 return -EMSGSIZE;
2836}
2837EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
2838
2839static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
2840 struct sk_buff *skb)
2841{
2842 struct nlattr *matches_attr;
2843
2844 matches_attr = nla_nest_start_noflag(skb,
2845 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
2846 if (!matches_attr)
2847 return -EMSGSIZE;
2848
2849 if (table->table_ops->matches_dump(table->priv, skb))
2850 goto nla_put_failure;
2851
2852 nla_nest_end(skb, matches_attr);
2853 return 0;
2854
2855nla_put_failure:
2856 nla_nest_cancel(skb, matches_attr);
2857 return -EMSGSIZE;
2858}
2859
2860int devlink_dpipe_action_put(struct sk_buff *skb,
2861 struct devlink_dpipe_action *action)
2862{
2863 struct devlink_dpipe_header *header = action->header;
2864 struct devlink_dpipe_field *field = &header->fields[action->field_id];
2865 struct nlattr *action_attr;
2866
2867 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
2868 if (!action_attr)
2869 return -EMSGSIZE;
2870
2871 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
2872 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
2873 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2874 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2875 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2876 goto nla_put_failure;
2877
2878 nla_nest_end(skb, action_attr);
2879 return 0;
2880
2881nla_put_failure:
2882 nla_nest_cancel(skb, action_attr);
2883 return -EMSGSIZE;
2884}
2885EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
2886
2887static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
2888 struct sk_buff *skb)
2889{
2890 struct nlattr *actions_attr;
2891
2892 actions_attr = nla_nest_start_noflag(skb,
2893 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
2894 if (!actions_attr)
2895 return -EMSGSIZE;
2896
2897 if (table->table_ops->actions_dump(table->priv, skb))
2898 goto nla_put_failure;
2899
2900 nla_nest_end(skb, actions_attr);
2901 return 0;
2902
2903nla_put_failure:
2904 nla_nest_cancel(skb, actions_attr);
2905 return -EMSGSIZE;
2906}
2907
2908static int devlink_dpipe_table_put(struct sk_buff *skb,
2909 struct devlink_dpipe_table *table)
2910{
2911 struct nlattr *table_attr;
2912 u64 table_size;
2913
2914 table_size = table->table_ops->size_get(table->priv);
2915 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
2916 if (!table_attr)
2917 return -EMSGSIZE;
2918
2919 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
2920 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
2921 DEVLINK_ATTR_PAD))
2922 goto nla_put_failure;
2923 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
2924 table->counters_enabled))
2925 goto nla_put_failure;
2926
2927 if (table->resource_valid) {
2928 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
2929 table->resource_id, DEVLINK_ATTR_PAD) ||
2930 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
2931 table->resource_units, DEVLINK_ATTR_PAD))
2932 goto nla_put_failure;
2933 }
2934 if (devlink_dpipe_matches_put(table, skb))
2935 goto nla_put_failure;
2936
2937 if (devlink_dpipe_actions_put(table, skb))
2938 goto nla_put_failure;
2939
2940 nla_nest_end(skb, table_attr);
2941 return 0;
2942
2943nla_put_failure:
2944 nla_nest_cancel(skb, table_attr);
2945 return -EMSGSIZE;
2946}
2947
2948static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
2949 struct genl_info *info)
2950{
2951 int err;
2952
2953 if (*pskb) {
2954 err = genlmsg_reply(*pskb, info);
2955 if (err)
2956 return err;
2957 }
2958 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
2959 if (!*pskb)
2960 return -ENOMEM;
2961 return 0;
2962}
2963
2964static int devlink_dpipe_tables_fill(struct genl_info *info,
2965 enum devlink_command cmd, int flags,
2966 struct list_head *dpipe_tables,
2967 const char *table_name)
2968{
2969 struct devlink *devlink = info->user_ptr[0];
2970 struct devlink_dpipe_table *table;
2971 struct nlattr *tables_attr;
2972 struct sk_buff *skb = NULL;
2973 struct nlmsghdr *nlh;
2974 bool incomplete;
2975 void *hdr;
2976 int i;
2977 int err;
2978
2979 table = list_first_entry(dpipe_tables,
2980 struct devlink_dpipe_table, list);
2981start_again:
2982 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2983 if (err)
2984 return err;
2985
2986 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2987 &devlink_nl_family, NLM_F_MULTI, cmd);
2988 if (!hdr) {
2989 nlmsg_free(skb);
2990 return -EMSGSIZE;
2991 }
2992
2993 if (devlink_nl_put_handle(skb, devlink))
2994 goto nla_put_failure;
2995 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
2996 if (!tables_attr)
2997 goto nla_put_failure;
2998
2999 i = 0;
3000 incomplete = false;
3001 list_for_each_entry_from(table, dpipe_tables, list) {
3002 if (!table_name) {
3003 err = devlink_dpipe_table_put(skb, table);
3004 if (err) {
3005 if (!i)
3006 goto err_table_put;
3007 incomplete = true;
3008 break;
3009 }
3010 } else {
3011 if (!strcmp(table->name, table_name)) {
3012 err = devlink_dpipe_table_put(skb, table);
3013 if (err)
3014 break;
3015 }
3016 }
3017 i++;
3018 }
3019
3020 nla_nest_end(skb, tables_attr);
3021 genlmsg_end(skb, hdr);
3022 if (incomplete)
3023 goto start_again;
3024
3025send_done:
3026 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3027 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3028 if (!nlh) {
3029 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3030 if (err)
3031 return err;
3032 goto send_done;
3033 }
3034
3035 return genlmsg_reply(skb, info);
3036
3037nla_put_failure:
3038 err = -EMSGSIZE;
3039err_table_put:
3040 nlmsg_free(skb);
3041 return err;
3042}
3043
3044static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3045 struct genl_info *info)
3046{
3047 struct devlink *devlink = info->user_ptr[0];
3048 const char *table_name = NULL;
3049
3050 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3051 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3052
3053 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3054 &devlink->dpipe_table_list,
3055 table_name);
3056}
3057
3058static int devlink_dpipe_value_put(struct sk_buff *skb,
3059 struct devlink_dpipe_value *value)
3060{
3061 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3062 value->value_size, value->value))
3063 return -EMSGSIZE;
3064 if (value->mask)
3065 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3066 value->value_size, value->mask))
3067 return -EMSGSIZE;
3068 if (value->mapping_valid)
3069 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3070 value->mapping_value))
3071 return -EMSGSIZE;
3072 return 0;
3073}
3074
3075static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3076 struct devlink_dpipe_value *value)
3077{
3078 if (!value->action)
3079 return -EINVAL;
3080 if (devlink_dpipe_action_put(skb, value->action))
3081 return -EMSGSIZE;
3082 if (devlink_dpipe_value_put(skb, value))
3083 return -EMSGSIZE;
3084 return 0;
3085}
3086
3087static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3088 struct devlink_dpipe_value *values,
3089 unsigned int values_count)
3090{
3091 struct nlattr *action_attr;
3092 int i;
3093 int err;
3094
3095 for (i = 0; i < values_count; i++) {
3096 action_attr = nla_nest_start_noflag(skb,
3097 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3098 if (!action_attr)
3099 return -EMSGSIZE;
3100 err = devlink_dpipe_action_value_put(skb, &values[i]);
3101 if (err)
3102 goto err_action_value_put;
3103 nla_nest_end(skb, action_attr);
3104 }
3105 return 0;
3106
3107err_action_value_put:
3108 nla_nest_cancel(skb, action_attr);
3109 return err;
3110}
3111
3112static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3113 struct devlink_dpipe_value *value)
3114{
3115 if (!value->match)
3116 return -EINVAL;
3117 if (devlink_dpipe_match_put(skb, value->match))
3118 return -EMSGSIZE;
3119 if (devlink_dpipe_value_put(skb, value))
3120 return -EMSGSIZE;
3121 return 0;
3122}
3123
3124static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3125 struct devlink_dpipe_value *values,
3126 unsigned int values_count)
3127{
3128 struct nlattr *match_attr;
3129 int i;
3130 int err;
3131
3132 for (i = 0; i < values_count; i++) {
3133 match_attr = nla_nest_start_noflag(skb,
3134 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3135 if (!match_attr)
3136 return -EMSGSIZE;
3137 err = devlink_dpipe_match_value_put(skb, &values[i]);
3138 if (err)
3139 goto err_match_value_put;
3140 nla_nest_end(skb, match_attr);
3141 }
3142 return 0;
3143
3144err_match_value_put:
3145 nla_nest_cancel(skb, match_attr);
3146 return err;
3147}
3148
3149static int devlink_dpipe_entry_put(struct sk_buff *skb,
3150 struct devlink_dpipe_entry *entry)
3151{
3152 struct nlattr *entry_attr, *matches_attr, *actions_attr;
3153 int err;
3154
3155 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3156 if (!entry_attr)
3157 return -EMSGSIZE;
3158
3159 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3160 DEVLINK_ATTR_PAD))
3161 goto nla_put_failure;
3162 if (entry->counter_valid)
3163 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
3164 entry->counter, DEVLINK_ATTR_PAD))
3165 goto nla_put_failure;
3166
3167 matches_attr = nla_nest_start_noflag(skb,
3168 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3169 if (!matches_attr)
3170 goto nla_put_failure;
3171
3172 err = devlink_dpipe_match_values_put(skb, entry->match_values,
3173 entry->match_values_count);
3174 if (err) {
3175 nla_nest_cancel(skb, matches_attr);
3176 goto err_match_values_put;
3177 }
3178 nla_nest_end(skb, matches_attr);
3179
3180 actions_attr = nla_nest_start_noflag(skb,
3181 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3182 if (!actions_attr)
3183 goto nla_put_failure;
3184
3185 err = devlink_dpipe_action_values_put(skb, entry->action_values,
3186 entry->action_values_count);
3187 if (err) {
3188 nla_nest_cancel(skb, actions_attr);
3189 goto err_action_values_put;
3190 }
3191 nla_nest_end(skb, actions_attr);
3192
3193 nla_nest_end(skb, entry_attr);
3194 return 0;
3195
3196nla_put_failure:
3197 err = -EMSGSIZE;
3198err_match_values_put:
3199err_action_values_put:
3200 nla_nest_cancel(skb, entry_attr);
3201 return err;
3202}
3203
3204static struct devlink_dpipe_table *
3205devlink_dpipe_table_find(struct list_head *dpipe_tables,
3206 const char *table_name, struct devlink *devlink)
3207{
3208 struct devlink_dpipe_table *table;
3209 list_for_each_entry_rcu(table, dpipe_tables, list,
3210 lockdep_is_held(&devlink->lock)) {
3211 if (!strcmp(table->name, table_name))
3212 return table;
3213 }
3214 return NULL;
3215}
3216
3217int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3218{
3219 struct devlink *devlink;
3220 int err;
3221
3222 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3223 dump_ctx->info);
3224 if (err)
3225 return err;
3226
3227 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
3228 dump_ctx->info->snd_portid,
3229 dump_ctx->info->snd_seq,
3230 &devlink_nl_family, NLM_F_MULTI,
3231 dump_ctx->cmd);
3232 if (!dump_ctx->hdr)
3233 goto nla_put_failure;
3234
3235 devlink = dump_ctx->info->user_ptr[0];
3236 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
3237 goto nla_put_failure;
3238 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
3239 DEVLINK_ATTR_DPIPE_ENTRIES);
3240 if (!dump_ctx->nest)
3241 goto nla_put_failure;
3242 return 0;
3243
3244nla_put_failure:
3245 nlmsg_free(dump_ctx->skb);
3246 return -EMSGSIZE;
3247}
3248EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3249
3250int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3251 struct devlink_dpipe_entry *entry)
3252{
3253 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3254}
3255EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3256
3257int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3258{
3259 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3260 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3261 return 0;
3262}
3263EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3264
3265void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3266
3267{
3268 unsigned int value_count, value_index;
3269 struct devlink_dpipe_value *value;
3270
3271 value = entry->action_values;
3272 value_count = entry->action_values_count;
3273 for (value_index = 0; value_index < value_count; value_index++) {
3274 kfree(value[value_index].value);
3275 kfree(value[value_index].mask);
3276 }
3277
3278 value = entry->match_values;
3279 value_count = entry->match_values_count;
3280 for (value_index = 0; value_index < value_count; value_index++) {
3281 kfree(value[value_index].value);
3282 kfree(value[value_index].mask);
3283 }
3284}
3285EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3286
3287static int devlink_dpipe_entries_fill(struct genl_info *info,
3288 enum devlink_command cmd, int flags,
3289 struct devlink_dpipe_table *table)
3290{
3291 struct devlink_dpipe_dump_ctx dump_ctx;
3292 struct nlmsghdr *nlh;
3293 int err;
3294
3295 dump_ctx.skb = NULL;
3296 dump_ctx.cmd = cmd;
3297 dump_ctx.info = info;
3298
3299 err = table->table_ops->entries_dump(table->priv,
3300 table->counters_enabled,
3301 &dump_ctx);
3302 if (err)
3303 return err;
3304
3305send_done:
3306 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3307 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3308 if (!nlh) {
3309 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3310 if (err)
3311 return err;
3312 goto send_done;
3313 }
3314 return genlmsg_reply(dump_ctx.skb, info);
3315}
3316
3317static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3318 struct genl_info *info)
3319{
3320 struct devlink *devlink = info->user_ptr[0];
3321 struct devlink_dpipe_table *table;
3322 const char *table_name;
3323
3324 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
3325 return -EINVAL;
3326
3327 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3328 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3329 table_name, devlink);
3330 if (!table)
3331 return -EINVAL;
3332
3333 if (!table->table_ops->entries_dump)
3334 return -EINVAL;
3335
3336 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3337 0, table);
3338}
3339
3340static int devlink_dpipe_fields_put(struct sk_buff *skb,
3341 const struct devlink_dpipe_header *header)
3342{
3343 struct devlink_dpipe_field *field;
3344 struct nlattr *field_attr;
3345 int i;
3346
3347 for (i = 0; i < header->fields_count; i++) {
3348 field = &header->fields[i];
3349 field_attr = nla_nest_start_noflag(skb,
3350 DEVLINK_ATTR_DPIPE_FIELD);
3351 if (!field_attr)
3352 return -EMSGSIZE;
3353 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
3354 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3355 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
3356 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
3357 goto nla_put_failure;
3358 nla_nest_end(skb, field_attr);
3359 }
3360 return 0;
3361
3362nla_put_failure:
3363 nla_nest_cancel(skb, field_attr);
3364 return -EMSGSIZE;
3365}
3366
3367static int devlink_dpipe_header_put(struct sk_buff *skb,
3368 struct devlink_dpipe_header *header)
3369{
3370 struct nlattr *fields_attr, *header_attr;
3371 int err;
3372
3373 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3374 if (!header_attr)
3375 return -EMSGSIZE;
3376
3377 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
3378 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3379 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3380 goto nla_put_failure;
3381
3382 fields_attr = nla_nest_start_noflag(skb,
3383 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3384 if (!fields_attr)
3385 goto nla_put_failure;
3386
3387 err = devlink_dpipe_fields_put(skb, header);
3388 if (err) {
3389 nla_nest_cancel(skb, fields_attr);
3390 goto nla_put_failure;
3391 }
3392 nla_nest_end(skb, fields_attr);
3393 nla_nest_end(skb, header_attr);
3394 return 0;
3395
3396nla_put_failure:
3397 err = -EMSGSIZE;
3398 nla_nest_cancel(skb, header_attr);
3399 return err;
3400}
3401
3402static int devlink_dpipe_headers_fill(struct genl_info *info,
3403 enum devlink_command cmd, int flags,
3404 struct devlink_dpipe_headers *
3405 dpipe_headers)
3406{
3407 struct devlink *devlink = info->user_ptr[0];
3408 struct nlattr *headers_attr;
3409 struct sk_buff *skb = NULL;
3410 struct nlmsghdr *nlh;
3411 void *hdr;
3412 int i, j;
3413 int err;
3414
3415 i = 0;
3416start_again:
3417 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3418 if (err)
3419 return err;
3420
3421 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3422 &devlink_nl_family, NLM_F_MULTI, cmd);
3423 if (!hdr) {
3424 nlmsg_free(skb);
3425 return -EMSGSIZE;
3426 }
3427
3428 if (devlink_nl_put_handle(skb, devlink))
3429 goto nla_put_failure;
3430 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
3431 if (!headers_attr)
3432 goto nla_put_failure;
3433
3434 j = 0;
3435 for (; i < dpipe_headers->headers_count; i++) {
3436 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3437 if (err) {
3438 if (!j)
3439 goto err_table_put;
3440 break;
3441 }
3442 j++;
3443 }
3444 nla_nest_end(skb, headers_attr);
3445 genlmsg_end(skb, hdr);
3446 if (i != dpipe_headers->headers_count)
3447 goto start_again;
3448
3449send_done:
3450 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3451 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3452 if (!nlh) {
3453 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3454 if (err)
3455 return err;
3456 goto send_done;
3457 }
3458 return genlmsg_reply(skb, info);
3459
3460nla_put_failure:
3461 err = -EMSGSIZE;
3462err_table_put:
3463 nlmsg_free(skb);
3464 return err;
3465}
3466
3467static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
3468 struct genl_info *info)
3469{
3470 struct devlink *devlink = info->user_ptr[0];
3471
3472 if (!devlink->dpipe_headers)
3473 return -EOPNOTSUPP;
3474 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
3475 0, devlink->dpipe_headers);
3476}
3477
3478static int devlink_dpipe_table_counters_set(struct devlink *devlink,
3479 const char *table_name,
3480 bool enable)
3481{
3482 struct devlink_dpipe_table *table;
3483
3484 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3485 table_name, devlink);
3486 if (!table)
3487 return -EINVAL;
3488
3489 if (table->counter_control_extern)
3490 return -EOPNOTSUPP;
3491
3492 if (!(table->counters_enabled ^ enable))
3493 return 0;
3494
3495 table->counters_enabled = enable;
3496 if (table->table_ops->counters_set_update)
3497 table->table_ops->counters_set_update(table->priv, enable);
3498 return 0;
3499}
3500
3501static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
3502 struct genl_info *info)
3503{
3504 struct devlink *devlink = info->user_ptr[0];
3505 const char *table_name;
3506 bool counters_enable;
3507
3508 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
3509 GENL_REQ_ATTR_CHECK(info,
3510 DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
3511 return -EINVAL;
3512
3513 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3514 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
3515
3516 return devlink_dpipe_table_counters_set(devlink, table_name,
3517 counters_enable);
3518}
3519
3520static struct devlink_resource *
3521devlink_resource_find(struct devlink *devlink,
3522 struct devlink_resource *resource, u64 resource_id)
3523{
3524 struct list_head *resource_list;
3525
3526 if (resource)
3527 resource_list = &resource->resource_list;
3528 else
3529 resource_list = &devlink->resource_list;
3530
3531 list_for_each_entry(resource, resource_list, list) {
3532 struct devlink_resource *child_resource;
3533
3534 if (resource->id == resource_id)
3535 return resource;
3536
3537 child_resource = devlink_resource_find(devlink, resource,
3538 resource_id);
3539 if (child_resource)
3540 return child_resource;
3541 }
3542 return NULL;
3543}
3544
3545static void
3546devlink_resource_validate_children(struct devlink_resource *resource)
3547{
3548 struct devlink_resource *child_resource;
3549 bool size_valid = true;
3550 u64 parts_size = 0;
3551
3552 if (list_empty(&resource->resource_list))
3553 goto out;
3554
3555 list_for_each_entry(child_resource, &resource->resource_list, list)
3556 parts_size += child_resource->size_new;
3557
3558 if (parts_size > resource->size_new)
3559 size_valid = false;
3560out:
3561 resource->size_valid = size_valid;
3562}
3563
3564static int
3565devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
3566 struct netlink_ext_ack *extack)
3567{
3568 u64 reminder;
3569 int err = 0;
3570
3571 if (size > resource->size_params.size_max) {
3572 NL_SET_ERR_MSG(extack, "Size larger than maximum");
3573 err = -EINVAL;
3574 }
3575
3576 if (size < resource->size_params.size_min) {
3577 NL_SET_ERR_MSG(extack, "Size smaller than minimum");
3578 err = -EINVAL;
3579 }
3580
3581 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
3582 if (reminder) {
3583 NL_SET_ERR_MSG(extack, "Wrong granularity");
3584 err = -EINVAL;
3585 }
3586
3587 return err;
3588}
3589
3590static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
3591 struct genl_info *info)
3592{
3593 struct devlink *devlink = info->user_ptr[0];
3594 struct devlink_resource *resource;
3595 u64 resource_id;
3596 u64 size;
3597 int err;
3598
3599 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
3600 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
3601 return -EINVAL;
3602 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
3603
3604 resource = devlink_resource_find(devlink, NULL, resource_id);
3605 if (!resource)
3606 return -EINVAL;
3607
3608 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
3609 err = devlink_resource_validate_size(resource, size, info->extack);
3610 if (err)
3611 return err;
3612
3613 resource->size_new = size;
3614 devlink_resource_validate_children(resource);
3615 if (resource->parent)
3616 devlink_resource_validate_children(resource->parent);
3617 return 0;
3618}
3619
3620static int
3621devlink_resource_size_params_put(struct devlink_resource *resource,
3622 struct sk_buff *skb)
3623{
3624 struct devlink_resource_size_params *size_params;
3625
3626 size_params = &resource->size_params;
3627 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
3628 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
3629 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
3630 size_params->size_max, DEVLINK_ATTR_PAD) ||
3631 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
3632 size_params->size_min, DEVLINK_ATTR_PAD) ||
3633 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
3634 return -EMSGSIZE;
3635 return 0;
3636}
3637
3638static int devlink_resource_occ_put(struct devlink_resource *resource,
3639 struct sk_buff *skb)
3640{
3641 if (!resource->occ_get)
3642 return 0;
3643 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
3644 resource->occ_get(resource->occ_get_priv),
3645 DEVLINK_ATTR_PAD);
3646}
3647
3648static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
3649 struct devlink_resource *resource)
3650{
3651 struct devlink_resource *child_resource;
3652 struct nlattr *child_resource_attr;
3653 struct nlattr *resource_attr;
3654
3655 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
3656 if (!resource_attr)
3657 return -EMSGSIZE;
3658
3659 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
3660 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
3661 DEVLINK_ATTR_PAD) ||
3662 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
3663 DEVLINK_ATTR_PAD))
3664 goto nla_put_failure;
3665 if (resource->size != resource->size_new &&
3666 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
3667 resource->size_new, DEVLINK_ATTR_PAD))
3668 goto nla_put_failure;
3669 if (devlink_resource_occ_put(resource, skb))
3670 goto nla_put_failure;
3671 if (devlink_resource_size_params_put(resource, skb))
3672 goto nla_put_failure;
3673 if (list_empty(&resource->resource_list))
3674 goto out;
3675
3676 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
3677 resource->size_valid))
3678 goto nla_put_failure;
3679
3680 child_resource_attr = nla_nest_start_noflag(skb,
3681 DEVLINK_ATTR_RESOURCE_LIST);
3682 if (!child_resource_attr)
3683 goto nla_put_failure;
3684
3685 list_for_each_entry(child_resource, &resource->resource_list, list) {
3686 if (devlink_resource_put(devlink, skb, child_resource))
3687 goto resource_put_failure;
3688 }
3689
3690 nla_nest_end(skb, child_resource_attr);
3691out:
3692 nla_nest_end(skb, resource_attr);
3693 return 0;
3694
3695resource_put_failure:
3696 nla_nest_cancel(skb, child_resource_attr);
3697nla_put_failure:
3698 nla_nest_cancel(skb, resource_attr);
3699 return -EMSGSIZE;
3700}
3701
3702static int devlink_resource_fill(struct genl_info *info,
3703 enum devlink_command cmd, int flags)
3704{
3705 struct devlink *devlink = info->user_ptr[0];
3706 struct devlink_resource *resource;
3707 struct nlattr *resources_attr;
3708 struct sk_buff *skb = NULL;
3709 struct nlmsghdr *nlh;
3710 bool incomplete;
3711 void *hdr;
3712 int i;
3713 int err;
3714
3715 resource = list_first_entry(&devlink->resource_list,
3716 struct devlink_resource, list);
3717start_again:
3718 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3719 if (err)
3720 return err;
3721
3722 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3723 &devlink_nl_family, NLM_F_MULTI, cmd);
3724 if (!hdr) {
3725 nlmsg_free(skb);
3726 return -EMSGSIZE;
3727 }
3728
3729 if (devlink_nl_put_handle(skb, devlink))
3730 goto nla_put_failure;
3731
3732 resources_attr = nla_nest_start_noflag(skb,
3733 DEVLINK_ATTR_RESOURCE_LIST);
3734 if (!resources_attr)
3735 goto nla_put_failure;
3736
3737 incomplete = false;
3738 i = 0;
3739 list_for_each_entry_from(resource, &devlink->resource_list, list) {
3740 err = devlink_resource_put(devlink, skb, resource);
3741 if (err) {
3742 if (!i)
3743 goto err_resource_put;
3744 incomplete = true;
3745 break;
3746 }
3747 i++;
3748 }
3749 nla_nest_end(skb, resources_attr);
3750 genlmsg_end(skb, hdr);
3751 if (incomplete)
3752 goto start_again;
3753send_done:
3754 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3755 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3756 if (!nlh) {
3757 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3758 if (err)
3759 return err;
3760 goto send_done;
3761 }
3762 return genlmsg_reply(skb, info);
3763
3764nla_put_failure:
3765 err = -EMSGSIZE;
3766err_resource_put:
3767 nlmsg_free(skb);
3768 return err;
3769}
3770
3771static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
3772 struct genl_info *info)
3773{
3774 struct devlink *devlink = info->user_ptr[0];
3775
3776 if (list_empty(&devlink->resource_list))
3777 return -EOPNOTSUPP;
3778
3779 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
3780}
3781
3782int devlink_resources_validate(struct devlink *devlink,
3783 struct devlink_resource *resource,
3784 struct genl_info *info)
3785{
3786 struct list_head *resource_list;
3787 int err = 0;
3788
3789 if (resource)
3790 resource_list = &resource->resource_list;
3791 else
3792 resource_list = &devlink->resource_list;
3793
3794 list_for_each_entry(resource, resource_list, list) {
3795 if (!resource->size_valid)
3796 return -EINVAL;
3797 err = devlink_resources_validate(devlink, resource, info);
3798 if (err)
3799 return err;
3800 }
3801 return err;
3802}
3803
3804static const struct devlink_param devlink_param_generic[] = {
3805 {
3806 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
3807 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
3808 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
3809 },
3810 {
3811 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
3812 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
3813 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
3814 },
3815 {
3816 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
3817 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
3818 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
3819 },
3820 {
3821 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
3822 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
3823 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
3824 },
3825 {
3826 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
3827 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
3828 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
3829 },
3830 {
3831 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
3832 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
3833 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
3834 },
3835 {
3836 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
3837 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
3838 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
3839 },
3840 {
3841 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
3842 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
3843 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
3844 },
3845 {
3846 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
3847 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
3848 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
3849 },
3850 {
3851 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
3852 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
3853 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
3854 },
3855 {
3856 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
3857 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
3858 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
3859 },
3860 {
3861 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
3862 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
3863 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
3864 },
3865 {
3866 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
3867 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
3868 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
3869 },
3870 {
3871 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
3872 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
3873 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
3874 },
3875 {
3876 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
3877 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
3878 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
3879 },
3880 {
3881 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
3882 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
3883 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
3884 },
3885 {
3886 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
3887 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
3888 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
3889 },
3890};
3891
3892static int devlink_param_generic_verify(const struct devlink_param *param)
3893{
3894 /* verify it match generic parameter by id and name */
3895 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
3896 return -EINVAL;
3897 if (strcmp(param->name, devlink_param_generic[param->id].name))
3898 return -ENOENT;
3899
3900 WARN_ON(param->type != devlink_param_generic[param->id].type);
3901
3902 return 0;
3903}
3904
3905static int devlink_param_driver_verify(const struct devlink_param *param)
3906{
3907 int i;
3908
3909 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
3910 return -EINVAL;
3911 /* verify no such name in generic params */
3912 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
3913 if (!strcmp(param->name, devlink_param_generic[i].name))
3914 return -EEXIST;
3915
3916 return 0;
3917}
3918
3919static struct devlink_param_item *
3920devlink_param_find_by_name(struct xarray *params, const char *param_name)
3921{
3922 struct devlink_param_item *param_item;
3923 unsigned long param_id;
3924
3925 xa_for_each(params, param_id, param_item) {
3926 if (!strcmp(param_item->param->name, param_name))
3927 return param_item;
3928 }
3929 return NULL;
3930}
3931
3932static struct devlink_param_item *
3933devlink_param_find_by_id(struct xarray *params, u32 param_id)
3934{
3935 return xa_load(params, param_id);
3936}
3937
3938static bool
3939devlink_param_cmode_is_supported(const struct devlink_param *param,
3940 enum devlink_param_cmode cmode)
3941{
3942 return test_bit(cmode, ¶m->supported_cmodes);
3943}
3944
3945static int devlink_param_get(struct devlink *devlink,
3946 const struct devlink_param *param,
3947 struct devlink_param_gset_ctx *ctx)
3948{
3949 if (!param->get || devlink->reload_failed)
3950 return -EOPNOTSUPP;
3951 return param->get(devlink, param->id, ctx);
3952}
3953
3954static int devlink_param_set(struct devlink *devlink,
3955 const struct devlink_param *param,
3956 struct devlink_param_gset_ctx *ctx)
3957{
3958 if (!param->set || devlink->reload_failed)
3959 return -EOPNOTSUPP;
3960 return param->set(devlink, param->id, ctx);
3961}
3962
3963static int
3964devlink_param_type_to_nla_type(enum devlink_param_type param_type)
3965{
3966 switch (param_type) {
3967 case DEVLINK_PARAM_TYPE_U8:
3968 return NLA_U8;
3969 case DEVLINK_PARAM_TYPE_U16:
3970 return NLA_U16;
3971 case DEVLINK_PARAM_TYPE_U32:
3972 return NLA_U32;
3973 case DEVLINK_PARAM_TYPE_STRING:
3974 return NLA_STRING;
3975 case DEVLINK_PARAM_TYPE_BOOL:
3976 return NLA_FLAG;
3977 default:
3978 return -EINVAL;
3979 }
3980}
3981
3982static int
3983devlink_nl_param_value_fill_one(struct sk_buff *msg,
3984 enum devlink_param_type type,
3985 enum devlink_param_cmode cmode,
3986 union devlink_param_value val)
3987{
3988 struct nlattr *param_value_attr;
3989
3990 param_value_attr = nla_nest_start_noflag(msg,
3991 DEVLINK_ATTR_PARAM_VALUE);
3992 if (!param_value_attr)
3993 goto nla_put_failure;
3994
3995 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
3996 goto value_nest_cancel;
3997
3998 switch (type) {
3999 case DEVLINK_PARAM_TYPE_U8:
4000 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
4001 goto value_nest_cancel;
4002 break;
4003 case DEVLINK_PARAM_TYPE_U16:
4004 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
4005 goto value_nest_cancel;
4006 break;
4007 case DEVLINK_PARAM_TYPE_U32:
4008 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
4009 goto value_nest_cancel;
4010 break;
4011 case DEVLINK_PARAM_TYPE_STRING:
4012 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
4013 val.vstr))
4014 goto value_nest_cancel;
4015 break;
4016 case DEVLINK_PARAM_TYPE_BOOL:
4017 if (val.vbool &&
4018 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
4019 goto value_nest_cancel;
4020 break;
4021 }
4022
4023 nla_nest_end(msg, param_value_attr);
4024 return 0;
4025
4026value_nest_cancel:
4027 nla_nest_cancel(msg, param_value_attr);
4028nla_put_failure:
4029 return -EMSGSIZE;
4030}
4031
4032static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
4033 unsigned int port_index,
4034 struct devlink_param_item *param_item,
4035 enum devlink_command cmd,
4036 u32 portid, u32 seq, int flags)
4037{
4038 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
4039 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
4040 const struct devlink_param *param = param_item->param;
4041 struct devlink_param_gset_ctx ctx;
4042 struct nlattr *param_values_list;
4043 struct nlattr *param_attr;
4044 int nla_type;
4045 void *hdr;
4046 int err;
4047 int i;
4048
4049 /* Get value from driver part to driverinit configuration mode */
4050 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
4051 if (!devlink_param_cmode_is_supported(param, i))
4052 continue;
4053 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
4054 if (param_item->driverinit_value_new_valid)
4055 param_value[i] = param_item->driverinit_value_new;
4056 else if (param_item->driverinit_value_valid)
4057 param_value[i] = param_item->driverinit_value;
4058 else
4059 return -EOPNOTSUPP;
4060 } else {
4061 ctx.cmode = i;
4062 err = devlink_param_get(devlink, param, &ctx);
4063 if (err)
4064 return err;
4065 param_value[i] = ctx.val;
4066 }
4067 param_value_set[i] = true;
4068 }
4069
4070 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4071 if (!hdr)
4072 return -EMSGSIZE;
4073
4074 if (devlink_nl_put_handle(msg, devlink))
4075 goto genlmsg_cancel;
4076
4077 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
4078 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
4079 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
4080 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
4081 goto genlmsg_cancel;
4082
4083 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
4084 if (!param_attr)
4085 goto genlmsg_cancel;
4086 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
4087 goto param_nest_cancel;
4088 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
4089 goto param_nest_cancel;
4090
4091 nla_type = devlink_param_type_to_nla_type(param->type);
4092 if (nla_type < 0)
4093 goto param_nest_cancel;
4094 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
4095 goto param_nest_cancel;
4096
4097 param_values_list = nla_nest_start_noflag(msg,
4098 DEVLINK_ATTR_PARAM_VALUES_LIST);
4099 if (!param_values_list)
4100 goto param_nest_cancel;
4101
4102 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
4103 if (!param_value_set[i])
4104 continue;
4105 err = devlink_nl_param_value_fill_one(msg, param->type,
4106 i, param_value[i]);
4107 if (err)
4108 goto values_list_nest_cancel;
4109 }
4110
4111 nla_nest_end(msg, param_values_list);
4112 nla_nest_end(msg, param_attr);
4113 genlmsg_end(msg, hdr);
4114 return 0;
4115
4116values_list_nest_cancel:
4117 nla_nest_end(msg, param_values_list);
4118param_nest_cancel:
4119 nla_nest_cancel(msg, param_attr);
4120genlmsg_cancel:
4121 genlmsg_cancel(msg, hdr);
4122 return -EMSGSIZE;
4123}
4124
4125static void devlink_param_notify(struct devlink *devlink,
4126 unsigned int port_index,
4127 struct devlink_param_item *param_item,
4128 enum devlink_command cmd)
4129{
4130 struct sk_buff *msg;
4131 int err;
4132
4133 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
4134 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
4135 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
4136
4137 /* devlink_notify_register() / devlink_notify_unregister()
4138 * will replay the notifications if the params are added/removed
4139 * outside of the lifetime of the instance.
4140 */
4141 if (!devl_is_registered(devlink))
4142 return;
4143
4144 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4145 if (!msg)
4146 return;
4147 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
4148 0, 0, 0);
4149 if (err) {
4150 nlmsg_free(msg);
4151 return;
4152 }
4153
4154 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4155 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4156}
4157
4158static int
4159devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
4160 struct netlink_callback *cb)
4161{
4162 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
4163 struct devlink_param_item *param_item;
4164 unsigned long param_id;
4165 int err = 0;
4166
4167 xa_for_each_start(&devlink->params, param_id, param_item, state->idx) {
4168 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
4169 DEVLINK_CMD_PARAM_GET,
4170 NETLINK_CB(cb->skb).portid,
4171 cb->nlh->nlmsg_seq,
4172 NLM_F_MULTI);
4173 if (err == -EOPNOTSUPP) {
4174 err = 0;
4175 } else if (err) {
4176 state->idx = param_id;
4177 break;
4178 }
4179 }
4180
4181 return err;
4182}
4183
4184const struct devlink_cmd devl_cmd_param_get = {
4185 .dump_one = devlink_nl_cmd_param_get_dump_one,
4186};
4187
4188static int
4189devlink_param_type_get_from_info(struct genl_info *info,
4190 enum devlink_param_type *param_type)
4191{
4192 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
4193 return -EINVAL;
4194
4195 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
4196 case NLA_U8:
4197 *param_type = DEVLINK_PARAM_TYPE_U8;
4198 break;
4199 case NLA_U16:
4200 *param_type = DEVLINK_PARAM_TYPE_U16;
4201 break;
4202 case NLA_U32:
4203 *param_type = DEVLINK_PARAM_TYPE_U32;
4204 break;
4205 case NLA_STRING:
4206 *param_type = DEVLINK_PARAM_TYPE_STRING;
4207 break;
4208 case NLA_FLAG:
4209 *param_type = DEVLINK_PARAM_TYPE_BOOL;
4210 break;
4211 default:
4212 return -EINVAL;
4213 }
4214
4215 return 0;
4216}
4217
4218static int
4219devlink_param_value_get_from_info(const struct devlink_param *param,
4220 struct genl_info *info,
4221 union devlink_param_value *value)
4222{
4223 struct nlattr *param_data;
4224 int len;
4225
4226 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
4227
4228 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
4229 return -EINVAL;
4230
4231 switch (param->type) {
4232 case DEVLINK_PARAM_TYPE_U8:
4233 if (nla_len(param_data) != sizeof(u8))
4234 return -EINVAL;
4235 value->vu8 = nla_get_u8(param_data);
4236 break;
4237 case DEVLINK_PARAM_TYPE_U16:
4238 if (nla_len(param_data) != sizeof(u16))
4239 return -EINVAL;
4240 value->vu16 = nla_get_u16(param_data);
4241 break;
4242 case DEVLINK_PARAM_TYPE_U32:
4243 if (nla_len(param_data) != sizeof(u32))
4244 return -EINVAL;
4245 value->vu32 = nla_get_u32(param_data);
4246 break;
4247 case DEVLINK_PARAM_TYPE_STRING:
4248 len = strnlen(nla_data(param_data), nla_len(param_data));
4249 if (len == nla_len(param_data) ||
4250 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
4251 return -EINVAL;
4252 strcpy(value->vstr, nla_data(param_data));
4253 break;
4254 case DEVLINK_PARAM_TYPE_BOOL:
4255 if (param_data && nla_len(param_data))
4256 return -EINVAL;
4257 value->vbool = nla_get_flag(param_data);
4258 break;
4259 }
4260 return 0;
4261}
4262
4263static struct devlink_param_item *
4264devlink_param_get_from_info(struct xarray *params, struct genl_info *info)
4265{
4266 char *param_name;
4267
4268 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
4269 return NULL;
4270
4271 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
4272 return devlink_param_find_by_name(params, param_name);
4273}
4274
4275static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
4276 struct genl_info *info)
4277{
4278 struct devlink *devlink = info->user_ptr[0];
4279 struct devlink_param_item *param_item;
4280 struct sk_buff *msg;
4281 int err;
4282
4283 param_item = devlink_param_get_from_info(&devlink->params, info);
4284 if (!param_item)
4285 return -EINVAL;
4286
4287 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4288 if (!msg)
4289 return -ENOMEM;
4290
4291 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
4292 DEVLINK_CMD_PARAM_GET,
4293 info->snd_portid, info->snd_seq, 0);
4294 if (err) {
4295 nlmsg_free(msg);
4296 return err;
4297 }
4298
4299 return genlmsg_reply(msg, info);
4300}
4301
4302static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
4303 unsigned int port_index,
4304 struct xarray *params,
4305 struct genl_info *info,
4306 enum devlink_command cmd)
4307{
4308 enum devlink_param_type param_type;
4309 struct devlink_param_gset_ctx ctx;
4310 enum devlink_param_cmode cmode;
4311 struct devlink_param_item *param_item;
4312 const struct devlink_param *param;
4313 union devlink_param_value value;
4314 int err = 0;
4315
4316 param_item = devlink_param_get_from_info(params, info);
4317 if (!param_item)
4318 return -EINVAL;
4319 param = param_item->param;
4320 err = devlink_param_type_get_from_info(info, ¶m_type);
4321 if (err)
4322 return err;
4323 if (param_type != param->type)
4324 return -EINVAL;
4325 err = devlink_param_value_get_from_info(param, info, &value);
4326 if (err)
4327 return err;
4328 if (param->validate) {
4329 err = param->validate(devlink, param->id, value, info->extack);
4330 if (err)
4331 return err;
4332 }
4333
4334 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
4335 return -EINVAL;
4336 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
4337 if (!devlink_param_cmode_is_supported(param, cmode))
4338 return -EOPNOTSUPP;
4339
4340 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
4341 param_item->driverinit_value_new = value;
4342 param_item->driverinit_value_new_valid = true;
4343 } else {
4344 if (!param->set)
4345 return -EOPNOTSUPP;
4346 ctx.val = value;
4347 ctx.cmode = cmode;
4348 err = devlink_param_set(devlink, param, &ctx);
4349 if (err)
4350 return err;
4351 }
4352
4353 devlink_param_notify(devlink, port_index, param_item, cmd);
4354 return 0;
4355}
4356
4357static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
4358 struct genl_info *info)
4359{
4360 struct devlink *devlink = info->user_ptr[0];
4361
4362 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->params,
4363 info, DEVLINK_CMD_PARAM_NEW);
4364}
4365
4366static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
4367 struct netlink_callback *cb)
4368{
4369 NL_SET_ERR_MSG(cb->extack, "Port params are not supported");
4370 return msg->len;
4371}
4372
4373static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
4374 struct genl_info *info)
4375{
4376 NL_SET_ERR_MSG(info->extack, "Port params are not supported");
4377 return -EINVAL;
4378}
4379
4380static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
4381 struct genl_info *info)
4382{
4383 NL_SET_ERR_MSG(info->extack, "Port params are not supported");
4384 return -EINVAL;
4385}
4386
4387static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
4388 struct devlink *devlink,
4389 struct devlink_snapshot *snapshot)
4390{
4391 struct nlattr *snap_attr;
4392 int err;
4393
4394 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
4395 if (!snap_attr)
4396 return -EINVAL;
4397
4398 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
4399 if (err)
4400 goto nla_put_failure;
4401
4402 nla_nest_end(msg, snap_attr);
4403 return 0;
4404
4405nla_put_failure:
4406 nla_nest_cancel(msg, snap_attr);
4407 return err;
4408}
4409
4410static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
4411 struct devlink *devlink,
4412 struct devlink_region *region)
4413{
4414 struct devlink_snapshot *snapshot;
4415 struct nlattr *snapshots_attr;
4416 int err;
4417
4418 snapshots_attr = nla_nest_start_noflag(msg,
4419 DEVLINK_ATTR_REGION_SNAPSHOTS);
4420 if (!snapshots_attr)
4421 return -EINVAL;
4422
4423 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
4424 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
4425 if (err)
4426 goto nla_put_failure;
4427 }
4428
4429 nla_nest_end(msg, snapshots_attr);
4430 return 0;
4431
4432nla_put_failure:
4433 nla_nest_cancel(msg, snapshots_attr);
4434 return err;
4435}
4436
4437static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
4438 enum devlink_command cmd, u32 portid,
4439 u32 seq, int flags,
4440 struct devlink_region *region)
4441{
4442 void *hdr;
4443 int err;
4444
4445 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4446 if (!hdr)
4447 return -EMSGSIZE;
4448
4449 err = devlink_nl_put_handle(msg, devlink);
4450 if (err)
4451 goto nla_put_failure;
4452
4453 if (region->port) {
4454 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
4455 region->port->index);
4456 if (err)
4457 goto nla_put_failure;
4458 }
4459
4460 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
4461 if (err)
4462 goto nla_put_failure;
4463
4464 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
4465 region->size,
4466 DEVLINK_ATTR_PAD);
4467 if (err)
4468 goto nla_put_failure;
4469
4470 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
4471 region->max_snapshots);
4472 if (err)
4473 goto nla_put_failure;
4474
4475 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
4476 if (err)
4477 goto nla_put_failure;
4478
4479 genlmsg_end(msg, hdr);
4480 return 0;
4481
4482nla_put_failure:
4483 genlmsg_cancel(msg, hdr);
4484 return err;
4485}
4486
4487static struct sk_buff *
4488devlink_nl_region_notify_build(struct devlink_region *region,
4489 struct devlink_snapshot *snapshot,
4490 enum devlink_command cmd, u32 portid, u32 seq)
4491{
4492 struct devlink *devlink = region->devlink;
4493 struct sk_buff *msg;
4494 void *hdr;
4495 int err;
4496
4497
4498 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4499 if (!msg)
4500 return ERR_PTR(-ENOMEM);
4501
4502 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
4503 if (!hdr) {
4504 err = -EMSGSIZE;
4505 goto out_free_msg;
4506 }
4507
4508 err = devlink_nl_put_handle(msg, devlink);
4509 if (err)
4510 goto out_cancel_msg;
4511
4512 if (region->port) {
4513 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
4514 region->port->index);
4515 if (err)
4516 goto out_cancel_msg;
4517 }
4518
4519 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
4520 region->ops->name);
4521 if (err)
4522 goto out_cancel_msg;
4523
4524 if (snapshot) {
4525 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
4526 snapshot->id);
4527 if (err)
4528 goto out_cancel_msg;
4529 } else {
4530 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
4531 region->size, DEVLINK_ATTR_PAD);
4532 if (err)
4533 goto out_cancel_msg;
4534 }
4535 genlmsg_end(msg, hdr);
4536
4537 return msg;
4538
4539out_cancel_msg:
4540 genlmsg_cancel(msg, hdr);
4541out_free_msg:
4542 nlmsg_free(msg);
4543 return ERR_PTR(err);
4544}
4545
4546static void devlink_nl_region_notify(struct devlink_region *region,
4547 struct devlink_snapshot *snapshot,
4548 enum devlink_command cmd)
4549{
4550 struct devlink *devlink = region->devlink;
4551 struct sk_buff *msg;
4552
4553 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
4554 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4555 return;
4556
4557 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
4558 if (IS_ERR(msg))
4559 return;
4560
4561 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
4562 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4563}
4564
4565/**
4566 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
4567 * @devlink: devlink instance
4568 * @id: the snapshot id
4569 *
4570 * Track when a new snapshot begins using an id. Load the count for the
4571 * given id from the snapshot xarray, increment it, and store it back.
4572 *
4573 * Called when a new snapshot is created with the given id.
4574 *
4575 * The id *must* have been previously allocated by
4576 * devlink_region_snapshot_id_get().
4577 *
4578 * Returns 0 on success, or an error on failure.
4579 */
4580static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
4581{
4582 unsigned long count;
4583 void *p;
4584 int err;
4585
4586 xa_lock(&devlink->snapshot_ids);
4587 p = xa_load(&devlink->snapshot_ids, id);
4588 if (WARN_ON(!p)) {
4589 err = -EINVAL;
4590 goto unlock;
4591 }
4592
4593 if (WARN_ON(!xa_is_value(p))) {
4594 err = -EINVAL;
4595 goto unlock;
4596 }
4597
4598 count = xa_to_value(p);
4599 count++;
4600
4601 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4602 GFP_ATOMIC));
4603unlock:
4604 xa_unlock(&devlink->snapshot_ids);
4605 return err;
4606}
4607
4608/**
4609 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
4610 * @devlink: devlink instance
4611 * @id: the snapshot id
4612 *
4613 * Track when a snapshot is deleted and stops using an id. Load the count
4614 * for the given id from the snapshot xarray, decrement it, and store it
4615 * back.
4616 *
4617 * If the count reaches zero, erase this id from the xarray, freeing it
4618 * up for future re-use by devlink_region_snapshot_id_get().
4619 *
4620 * Called when a snapshot using the given id is deleted, and when the
4621 * initial allocator of the id is finished using it.
4622 */
4623static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
4624{
4625 unsigned long count;
4626 void *p;
4627
4628 xa_lock(&devlink->snapshot_ids);
4629 p = xa_load(&devlink->snapshot_ids, id);
4630 if (WARN_ON(!p))
4631 goto unlock;
4632
4633 if (WARN_ON(!xa_is_value(p)))
4634 goto unlock;
4635
4636 count = xa_to_value(p);
4637
4638 if (count > 1) {
4639 count--;
4640 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4641 GFP_ATOMIC);
4642 } else {
4643 /* If this was the last user, we can erase this id */
4644 __xa_erase(&devlink->snapshot_ids, id);
4645 }
4646unlock:
4647 xa_unlock(&devlink->snapshot_ids);
4648}
4649
4650/**
4651 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
4652 * @devlink: devlink instance
4653 * @id: the snapshot id
4654 *
4655 * Mark the given snapshot id as used by inserting a zero value into the
4656 * snapshot xarray.
4657 *
4658 * This must be called while holding the devlink instance lock. Unlike
4659 * devlink_snapshot_id_get, the initial reference count is zero, not one.
4660 * It is expected that the id will immediately be used before
4661 * releasing the devlink instance lock.
4662 *
4663 * Returns zero on success, or an error code if the snapshot id could not
4664 * be inserted.
4665 */
4666static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
4667{
4668 int err;
4669
4670 xa_lock(&devlink->snapshot_ids);
4671 if (xa_load(&devlink->snapshot_ids, id)) {
4672 xa_unlock(&devlink->snapshot_ids);
4673 return -EEXIST;
4674 }
4675 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
4676 GFP_ATOMIC));
4677 xa_unlock(&devlink->snapshot_ids);
4678 return err;
4679}
4680
4681/**
4682 * __devlink_region_snapshot_id_get - get snapshot ID
4683 * @devlink: devlink instance
4684 * @id: storage to return snapshot id
4685 *
4686 * Allocates a new snapshot id. Returns zero on success, or a negative
4687 * error on failure. Must be called while holding the devlink instance
4688 * lock.
4689 *
4690 * Snapshot IDs are tracked using an xarray which stores the number of
4691 * users of the snapshot id.
4692 *
4693 * Note that the caller of this function counts as a 'user', in order to
4694 * avoid race conditions. The caller must release its hold on the
4695 * snapshot by using devlink_region_snapshot_id_put.
4696 */
4697static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
4698{
4699 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
4700 xa_limit_32b, GFP_KERNEL);
4701}
4702
4703/**
4704 * __devlink_region_snapshot_create - create a new snapshot
4705 * This will add a new snapshot of a region. The snapshot
4706 * will be stored on the region struct and can be accessed
4707 * from devlink. This is useful for future analyses of snapshots.
4708 * Multiple snapshots can be created on a region.
4709 * The @snapshot_id should be obtained using the getter function.
4710 *
4711 * Must be called only while holding the region snapshot lock.
4712 *
4713 * @region: devlink region of the snapshot
4714 * @data: snapshot data
4715 * @snapshot_id: snapshot id to be created
4716 */
4717static int
4718__devlink_region_snapshot_create(struct devlink_region *region,
4719 u8 *data, u32 snapshot_id)
4720{
4721 struct devlink *devlink = region->devlink;
4722 struct devlink_snapshot *snapshot;
4723 int err;
4724
4725 lockdep_assert_held(®ion->snapshot_lock);
4726
4727 /* check if region can hold one more snapshot */
4728 if (region->cur_snapshots == region->max_snapshots)
4729 return -ENOSPC;
4730
4731 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
4732 return -EEXIST;
4733
4734 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
4735 if (!snapshot)
4736 return -ENOMEM;
4737
4738 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
4739 if (err)
4740 goto err_snapshot_id_increment;
4741
4742 snapshot->id = snapshot_id;
4743 snapshot->region = region;
4744 snapshot->data = data;
4745
4746 list_add_tail(&snapshot->list, ®ion->snapshot_list);
4747
4748 region->cur_snapshots++;
4749
4750 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
4751 return 0;
4752
4753err_snapshot_id_increment:
4754 kfree(snapshot);
4755 return err;
4756}
4757
4758static void devlink_region_snapshot_del(struct devlink_region *region,
4759 struct devlink_snapshot *snapshot)
4760{
4761 struct devlink *devlink = region->devlink;
4762
4763 lockdep_assert_held(®ion->snapshot_lock);
4764
4765 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
4766 region->cur_snapshots--;
4767 list_del(&snapshot->list);
4768 region->ops->destructor(snapshot->data);
4769 __devlink_snapshot_id_decrement(devlink, snapshot->id);
4770 kfree(snapshot);
4771}
4772
4773static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
4774 struct genl_info *info)
4775{
4776 struct devlink *devlink = info->user_ptr[0];
4777 struct devlink_port *port = NULL;
4778 struct devlink_region *region;
4779 const char *region_name;
4780 struct sk_buff *msg;
4781 unsigned int index;
4782 int err;
4783
4784 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
4785 return -EINVAL;
4786
4787 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4788 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4789
4790 port = devlink_port_get_by_index(devlink, index);
4791 if (!port)
4792 return -ENODEV;
4793 }
4794
4795 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4796 if (port)
4797 region = devlink_port_region_get_by_name(port, region_name);
4798 else
4799 region = devlink_region_get_by_name(devlink, region_name);
4800
4801 if (!region)
4802 return -EINVAL;
4803
4804 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4805 if (!msg)
4806 return -ENOMEM;
4807
4808 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
4809 info->snd_portid, info->snd_seq, 0,
4810 region);
4811 if (err) {
4812 nlmsg_free(msg);
4813 return err;
4814 }
4815
4816 return genlmsg_reply(msg, info);
4817}
4818
4819static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
4820 struct netlink_callback *cb,
4821 struct devlink_port *port,
4822 int *idx,
4823 int start)
4824{
4825 struct devlink_region *region;
4826 int err = 0;
4827
4828 list_for_each_entry(region, &port->region_list, list) {
4829 if (*idx < start) {
4830 (*idx)++;
4831 continue;
4832 }
4833 err = devlink_nl_region_fill(msg, port->devlink,
4834 DEVLINK_CMD_REGION_GET,
4835 NETLINK_CB(cb->skb).portid,
4836 cb->nlh->nlmsg_seq,
4837 NLM_F_MULTI, region);
4838 if (err)
4839 goto out;
4840 (*idx)++;
4841 }
4842
4843out:
4844 return err;
4845}
4846
4847static int
4848devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
4849 struct netlink_callback *cb)
4850{
4851 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
4852 struct devlink_region *region;
4853 struct devlink_port *port;
4854 unsigned long port_index;
4855 int idx = 0;
4856 int err;
4857
4858 list_for_each_entry(region, &devlink->region_list, list) {
4859 if (idx < state->idx) {
4860 idx++;
4861 continue;
4862 }
4863 err = devlink_nl_region_fill(msg, devlink,
4864 DEVLINK_CMD_REGION_GET,
4865 NETLINK_CB(cb->skb).portid,
4866 cb->nlh->nlmsg_seq,
4867 NLM_F_MULTI, region);
4868 if (err) {
4869 state->idx = idx;
4870 return err;
4871 }
4872 idx++;
4873 }
4874
4875 xa_for_each(&devlink->ports, port_index, port) {
4876 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
4877 state->idx);
4878 if (err) {
4879 state->idx = idx;
4880 return err;
4881 }
4882 }
4883
4884 return 0;
4885}
4886
4887const struct devlink_cmd devl_cmd_region_get = {
4888 .dump_one = devlink_nl_cmd_region_get_dump_one,
4889};
4890
4891static int devlink_nl_cmd_region_del(struct sk_buff *skb,
4892 struct genl_info *info)
4893{
4894 struct devlink *devlink = info->user_ptr[0];
4895 struct devlink_snapshot *snapshot;
4896 struct devlink_port *port = NULL;
4897 struct devlink_region *region;
4898 const char *region_name;
4899 unsigned int index;
4900 u32 snapshot_id;
4901
4902 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
4903 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
4904 return -EINVAL;
4905
4906 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4907 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4908
4909 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4910 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4911
4912 port = devlink_port_get_by_index(devlink, index);
4913 if (!port)
4914 return -ENODEV;
4915 }
4916
4917 if (port)
4918 region = devlink_port_region_get_by_name(port, region_name);
4919 else
4920 region = devlink_region_get_by_name(devlink, region_name);
4921
4922 if (!region)
4923 return -EINVAL;
4924
4925 mutex_lock(®ion->snapshot_lock);
4926 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4927 if (!snapshot) {
4928 mutex_unlock(®ion->snapshot_lock);
4929 return -EINVAL;
4930 }
4931
4932 devlink_region_snapshot_del(region, snapshot);
4933 mutex_unlock(®ion->snapshot_lock);
4934 return 0;
4935}
4936
4937static int
4938devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4939{
4940 struct devlink *devlink = info->user_ptr[0];
4941 struct devlink_snapshot *snapshot;
4942 struct devlink_port *port = NULL;
4943 struct nlattr *snapshot_id_attr;
4944 struct devlink_region *region;
4945 const char *region_name;
4946 unsigned int index;
4947 u32 snapshot_id;
4948 u8 *data;
4949 int err;
4950
4951 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
4952 NL_SET_ERR_MSG(info->extack, "No region name provided");
4953 return -EINVAL;
4954 }
4955
4956 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4957
4958 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4959 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4960
4961 port = devlink_port_get_by_index(devlink, index);
4962 if (!port)
4963 return -ENODEV;
4964 }
4965
4966 if (port)
4967 region = devlink_port_region_get_by_name(port, region_name);
4968 else
4969 region = devlink_region_get_by_name(devlink, region_name);
4970
4971 if (!region) {
4972 NL_SET_ERR_MSG(info->extack, "The requested region does not exist");
4973 return -EINVAL;
4974 }
4975
4976 if (!region->ops->snapshot) {
4977 NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot");
4978 return -EOPNOTSUPP;
4979 }
4980
4981 mutex_lock(®ion->snapshot_lock);
4982
4983 if (region->cur_snapshots == region->max_snapshots) {
4984 NL_SET_ERR_MSG(info->extack, "The region has reached the maximum number of stored snapshots");
4985 err = -ENOSPC;
4986 goto unlock;
4987 }
4988
4989 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
4990 if (snapshot_id_attr) {
4991 snapshot_id = nla_get_u32(snapshot_id_attr);
4992
4993 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4994 NL_SET_ERR_MSG(info->extack, "The requested snapshot id is already in use");
4995 err = -EEXIST;
4996 goto unlock;
4997 }
4998
4999 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
5000 if (err)
5001 goto unlock;
5002 } else {
5003 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
5004 if (err) {
5005 NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id");
5006 goto unlock;
5007 }
5008 }
5009
5010 if (port)
5011 err = region->port_ops->snapshot(port, region->port_ops,
5012 info->extack, &data);
5013 else
5014 err = region->ops->snapshot(devlink, region->ops,
5015 info->extack, &data);
5016 if (err)
5017 goto err_snapshot_capture;
5018
5019 err = __devlink_region_snapshot_create(region, data, snapshot_id);
5020 if (err)
5021 goto err_snapshot_create;
5022
5023 if (!snapshot_id_attr) {
5024 struct sk_buff *msg;
5025
5026 snapshot = devlink_region_snapshot_get_by_id(region,
5027 snapshot_id);
5028 if (WARN_ON(!snapshot)) {
5029 err = -EINVAL;
5030 goto unlock;
5031 }
5032
5033 msg = devlink_nl_region_notify_build(region, snapshot,
5034 DEVLINK_CMD_REGION_NEW,
5035 info->snd_portid,
5036 info->snd_seq);
5037 err = PTR_ERR_OR_ZERO(msg);
5038 if (err)
5039 goto err_notify;
5040
5041 err = genlmsg_reply(msg, info);
5042 if (err)
5043 goto err_notify;
5044 }
5045
5046 mutex_unlock(®ion->snapshot_lock);
5047 return 0;
5048
5049err_snapshot_create:
5050 region->ops->destructor(data);
5051err_snapshot_capture:
5052 __devlink_snapshot_id_decrement(devlink, snapshot_id);
5053 mutex_unlock(®ion->snapshot_lock);
5054 return err;
5055
5056err_notify:
5057 devlink_region_snapshot_del(region, snapshot);
5058unlock:
5059 mutex_unlock(®ion->snapshot_lock);
5060 return err;
5061}
5062
5063static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
5064 u8 *chunk, u32 chunk_size,
5065 u64 addr)
5066{
5067 struct nlattr *chunk_attr;
5068 int err;
5069
5070 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
5071 if (!chunk_attr)
5072 return -EINVAL;
5073
5074 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
5075 if (err)
5076 goto nla_put_failure;
5077
5078 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
5079 DEVLINK_ATTR_PAD);
5080 if (err)
5081 goto nla_put_failure;
5082
5083 nla_nest_end(msg, chunk_attr);
5084 return 0;
5085
5086nla_put_failure:
5087 nla_nest_cancel(msg, chunk_attr);
5088 return err;
5089}
5090
5091#define DEVLINK_REGION_READ_CHUNK_SIZE 256
5092
5093typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
5094 u64 curr_offset,
5095 struct netlink_ext_ack *extack);
5096
5097static int
5098devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
5099 void *cb_priv, u64 start_offset, u64 end_offset,
5100 u64 *new_offset, struct netlink_ext_ack *extack)
5101{
5102 u64 curr_offset = start_offset;
5103 int err = 0;
5104 u8 *data;
5105
5106 /* Allocate and re-use a single buffer */
5107 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
5108 if (!data)
5109 return -ENOMEM;
5110
5111 *new_offset = start_offset;
5112
5113 while (curr_offset < end_offset) {
5114 u32 data_size;
5115
5116 data_size = min_t(u32, end_offset - curr_offset,
5117 DEVLINK_REGION_READ_CHUNK_SIZE);
5118
5119 err = cb(cb_priv, data, data_size, curr_offset, extack);
5120 if (err)
5121 break;
5122
5123 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
5124 if (err)
5125 break;
5126
5127 curr_offset += data_size;
5128 }
5129 *new_offset = curr_offset;
5130
5131 kfree(data);
5132
5133 return err;
5134}
5135
5136static int
5137devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
5138 u64 curr_offset,
5139 struct netlink_ext_ack __always_unused *extack)
5140{
5141 struct devlink_snapshot *snapshot = cb_priv;
5142
5143 memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
5144
5145 return 0;
5146}
5147
5148static int
5149devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
5150 u64 curr_offset, struct netlink_ext_ack *extack)
5151{
5152 struct devlink_region *region = cb_priv;
5153
5154 return region->port_ops->read(region->port, region->port_ops, extack,
5155 curr_offset, chunk_size, chunk);
5156}
5157
5158static int
5159devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
5160 u64 curr_offset, struct netlink_ext_ack *extack)
5161{
5162 struct devlink_region *region = cb_priv;
5163
5164 return region->ops->read(region->devlink, region->ops, extack,
5165 curr_offset, chunk_size, chunk);
5166}
5167
5168static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
5169 struct netlink_callback *cb)
5170{
5171 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
5172 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5173 struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
5174 u64 ret_offset, start_offset, end_offset = U64_MAX;
5175 struct nlattr **attrs = info->attrs;
5176 struct devlink_port *port = NULL;
5177 devlink_chunk_fill_t *region_cb;
5178 struct devlink_region *region;
5179 const char *region_name;
5180 struct devlink *devlink;
5181 unsigned int index;
5182 void *region_cb_priv;
5183 void *hdr;
5184 int err;
5185
5186 start_offset = state->start_offset;
5187
5188 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
5189 if (IS_ERR(devlink))
5190 return PTR_ERR(devlink);
5191
5192 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
5193 NL_SET_ERR_MSG(cb->extack, "No region name provided");
5194 err = -EINVAL;
5195 goto out_unlock;
5196 }
5197
5198 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5199 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5200
5201 port = devlink_port_get_by_index(devlink, index);
5202 if (!port) {
5203 err = -ENODEV;
5204 goto out_unlock;
5205 }
5206 }
5207
5208 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
5209 region_name = nla_data(region_attr);
5210
5211 if (port)
5212 region = devlink_port_region_get_by_name(port, region_name);
5213 else
5214 region = devlink_region_get_by_name(devlink, region_name);
5215
5216 if (!region) {
5217 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
5218 err = -EINVAL;
5219 goto out_unlock;
5220 }
5221
5222 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
5223 if (!snapshot_attr) {
5224 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
5225 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
5226 err = -EINVAL;
5227 goto out_unlock;
5228 }
5229
5230 if (!region->ops->read) {
5231 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
5232 err = -EOPNOTSUPP;
5233 goto out_unlock;
5234 }
5235
5236 if (port)
5237 region_cb = &devlink_region_port_direct_fill;
5238 else
5239 region_cb = &devlink_region_direct_fill;
5240 region_cb_priv = region;
5241 } else {
5242 struct devlink_snapshot *snapshot;
5243 u32 snapshot_id;
5244
5245 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
5246 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
5247 err = -EINVAL;
5248 goto out_unlock;
5249 }
5250
5251 snapshot_id = nla_get_u32(snapshot_attr);
5252 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
5253 if (!snapshot) {
5254 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
5255 err = -EINVAL;
5256 goto out_unlock;
5257 }
5258 region_cb = &devlink_region_snapshot_fill;
5259 region_cb_priv = snapshot;
5260 }
5261
5262 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
5263 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
5264 if (!start_offset)
5265 start_offset =
5266 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
5267
5268 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
5269 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
5270 }
5271
5272 if (end_offset > region->size)
5273 end_offset = region->size;
5274
5275 /* return 0 if there is no further data to read */
5276 if (start_offset == end_offset) {
5277 err = 0;
5278 goto out_unlock;
5279 }
5280
5281 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
5282 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
5283 DEVLINK_CMD_REGION_READ);
5284 if (!hdr) {
5285 err = -EMSGSIZE;
5286 goto out_unlock;
5287 }
5288
5289 err = devlink_nl_put_handle(skb, devlink);
5290 if (err)
5291 goto nla_put_failure;
5292
5293 if (region->port) {
5294 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
5295 region->port->index);
5296 if (err)
5297 goto nla_put_failure;
5298 }
5299
5300 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
5301 if (err)
5302 goto nla_put_failure;
5303
5304 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
5305 if (!chunks_attr) {
5306 err = -EMSGSIZE;
5307 goto nla_put_failure;
5308 }
5309
5310 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
5311 start_offset, end_offset, &ret_offset,
5312 cb->extack);
5313
5314 if (err && err != -EMSGSIZE)
5315 goto nla_put_failure;
5316
5317 /* Check if there was any progress done to prevent infinite loop */
5318 if (ret_offset == start_offset) {
5319 err = -EINVAL;
5320 goto nla_put_failure;
5321 }
5322
5323 state->start_offset = ret_offset;
5324
5325 nla_nest_end(skb, chunks_attr);
5326 genlmsg_end(skb, hdr);
5327 devl_unlock(devlink);
5328 devlink_put(devlink);
5329 return skb->len;
5330
5331nla_put_failure:
5332 genlmsg_cancel(skb, hdr);
5333out_unlock:
5334 devl_unlock(devlink);
5335 devlink_put(devlink);
5336 return err;
5337}
5338
5339struct devlink_stats {
5340 u64_stats_t rx_bytes;
5341 u64_stats_t rx_packets;
5342 struct u64_stats_sync syncp;
5343};
5344
5345/**
5346 * struct devlink_trap_policer_item - Packet trap policer attributes.
5347 * @policer: Immutable packet trap policer attributes.
5348 * @rate: Rate in packets / sec.
5349 * @burst: Burst size in packets.
5350 * @list: trap_policer_list member.
5351 *
5352 * Describes packet trap policer attributes. Created by devlink during trap
5353 * policer registration.
5354 */
5355struct devlink_trap_policer_item {
5356 const struct devlink_trap_policer *policer;
5357 u64 rate;
5358 u64 burst;
5359 struct list_head list;
5360};
5361
5362/**
5363 * struct devlink_trap_group_item - Packet trap group attributes.
5364 * @group: Immutable packet trap group attributes.
5365 * @policer_item: Associated policer item. Can be NULL.
5366 * @list: trap_group_list member.
5367 * @stats: Trap group statistics.
5368 *
5369 * Describes packet trap group attributes. Created by devlink during trap
5370 * group registration.
5371 */
5372struct devlink_trap_group_item {
5373 const struct devlink_trap_group *group;
5374 struct devlink_trap_policer_item *policer_item;
5375 struct list_head list;
5376 struct devlink_stats __percpu *stats;
5377};
5378
5379/**
5380 * struct devlink_trap_item - Packet trap attributes.
5381 * @trap: Immutable packet trap attributes.
5382 * @group_item: Associated group item.
5383 * @list: trap_list member.
5384 * @action: Trap action.
5385 * @stats: Trap statistics.
5386 * @priv: Driver private information.
5387 *
5388 * Describes both mutable and immutable packet trap attributes. Created by
5389 * devlink during trap registration and used for all trap related operations.
5390 */
5391struct devlink_trap_item {
5392 const struct devlink_trap *trap;
5393 struct devlink_trap_group_item *group_item;
5394 struct list_head list;
5395 enum devlink_trap_action action;
5396 struct devlink_stats __percpu *stats;
5397 void *priv;
5398};
5399
5400static struct devlink_trap_policer_item *
5401devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
5402{
5403 struct devlink_trap_policer_item *policer_item;
5404
5405 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
5406 if (policer_item->policer->id == id)
5407 return policer_item;
5408 }
5409
5410 return NULL;
5411}
5412
5413static struct devlink_trap_item *
5414devlink_trap_item_lookup(struct devlink *devlink, const char *name)
5415{
5416 struct devlink_trap_item *trap_item;
5417
5418 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5419 if (!strcmp(trap_item->trap->name, name))
5420 return trap_item;
5421 }
5422
5423 return NULL;
5424}
5425
5426static struct devlink_trap_item *
5427devlink_trap_item_get_from_info(struct devlink *devlink,
5428 struct genl_info *info)
5429{
5430 struct nlattr *attr;
5431
5432 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
5433 return NULL;
5434 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
5435
5436 return devlink_trap_item_lookup(devlink, nla_data(attr));
5437}
5438
5439static int
5440devlink_trap_action_get_from_info(struct genl_info *info,
5441 enum devlink_trap_action *p_trap_action)
5442{
5443 u8 val;
5444
5445 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
5446 switch (val) {
5447 case DEVLINK_TRAP_ACTION_DROP:
5448 case DEVLINK_TRAP_ACTION_TRAP:
5449 case DEVLINK_TRAP_ACTION_MIRROR:
5450 *p_trap_action = val;
5451 break;
5452 default:
5453 return -EINVAL;
5454 }
5455
5456 return 0;
5457}
5458
5459static int devlink_trap_metadata_put(struct sk_buff *msg,
5460 const struct devlink_trap *trap)
5461{
5462 struct nlattr *attr;
5463
5464 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
5465 if (!attr)
5466 return -EMSGSIZE;
5467
5468 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
5469 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
5470 goto nla_put_failure;
5471 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
5472 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
5473 goto nla_put_failure;
5474
5475 nla_nest_end(msg, attr);
5476
5477 return 0;
5478
5479nla_put_failure:
5480 nla_nest_cancel(msg, attr);
5481 return -EMSGSIZE;
5482}
5483
5484static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
5485 struct devlink_stats *stats)
5486{
5487 int i;
5488
5489 memset(stats, 0, sizeof(*stats));
5490 for_each_possible_cpu(i) {
5491 struct devlink_stats *cpu_stats;
5492 u64 rx_packets, rx_bytes;
5493 unsigned int start;
5494
5495 cpu_stats = per_cpu_ptr(trap_stats, i);
5496 do {
5497 start = u64_stats_fetch_begin(&cpu_stats->syncp);
5498 rx_packets = u64_stats_read(&cpu_stats->rx_packets);
5499 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
5500 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
5501
5502 u64_stats_add(&stats->rx_packets, rx_packets);
5503 u64_stats_add(&stats->rx_bytes, rx_bytes);
5504 }
5505}
5506
5507static int
5508devlink_trap_group_stats_put(struct sk_buff *msg,
5509 struct devlink_stats __percpu *trap_stats)
5510{
5511 struct devlink_stats stats;
5512 struct nlattr *attr;
5513
5514 devlink_trap_stats_read(trap_stats, &stats);
5515
5516 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
5517 if (!attr)
5518 return -EMSGSIZE;
5519
5520 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
5521 u64_stats_read(&stats.rx_packets),
5522 DEVLINK_ATTR_PAD))
5523 goto nla_put_failure;
5524
5525 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
5526 u64_stats_read(&stats.rx_bytes),
5527 DEVLINK_ATTR_PAD))
5528 goto nla_put_failure;
5529
5530 nla_nest_end(msg, attr);
5531
5532 return 0;
5533
5534nla_put_failure:
5535 nla_nest_cancel(msg, attr);
5536 return -EMSGSIZE;
5537}
5538
5539static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
5540 const struct devlink_trap_item *trap_item)
5541{
5542 struct devlink_stats stats;
5543 struct nlattr *attr;
5544 u64 drops = 0;
5545 int err;
5546
5547 if (devlink->ops->trap_drop_counter_get) {
5548 err = devlink->ops->trap_drop_counter_get(devlink,
5549 trap_item->trap,
5550 &drops);
5551 if (err)
5552 return err;
5553 }
5554
5555 devlink_trap_stats_read(trap_item->stats, &stats);
5556
5557 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
5558 if (!attr)
5559 return -EMSGSIZE;
5560
5561 if (devlink->ops->trap_drop_counter_get &&
5562 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
5563 DEVLINK_ATTR_PAD))
5564 goto nla_put_failure;
5565
5566 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
5567 u64_stats_read(&stats.rx_packets),
5568 DEVLINK_ATTR_PAD))
5569 goto nla_put_failure;
5570
5571 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
5572 u64_stats_read(&stats.rx_bytes),
5573 DEVLINK_ATTR_PAD))
5574 goto nla_put_failure;
5575
5576 nla_nest_end(msg, attr);
5577
5578 return 0;
5579
5580nla_put_failure:
5581 nla_nest_cancel(msg, attr);
5582 return -EMSGSIZE;
5583}
5584
5585static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
5586 const struct devlink_trap_item *trap_item,
5587 enum devlink_command cmd, u32 portid, u32 seq,
5588 int flags)
5589{
5590 struct devlink_trap_group_item *group_item = trap_item->group_item;
5591 void *hdr;
5592 int err;
5593
5594 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5595 if (!hdr)
5596 return -EMSGSIZE;
5597
5598 if (devlink_nl_put_handle(msg, devlink))
5599 goto nla_put_failure;
5600
5601 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
5602 group_item->group->name))
5603 goto nla_put_failure;
5604
5605 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
5606 goto nla_put_failure;
5607
5608 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
5609 goto nla_put_failure;
5610
5611 if (trap_item->trap->generic &&
5612 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
5613 goto nla_put_failure;
5614
5615 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
5616 goto nla_put_failure;
5617
5618 err = devlink_trap_metadata_put(msg, trap_item->trap);
5619 if (err)
5620 goto nla_put_failure;
5621
5622 err = devlink_trap_stats_put(msg, devlink, trap_item);
5623 if (err)
5624 goto nla_put_failure;
5625
5626 genlmsg_end(msg, hdr);
5627
5628 return 0;
5629
5630nla_put_failure:
5631 genlmsg_cancel(msg, hdr);
5632 return -EMSGSIZE;
5633}
5634
5635static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
5636 struct genl_info *info)
5637{
5638 struct netlink_ext_ack *extack = info->extack;
5639 struct devlink *devlink = info->user_ptr[0];
5640 struct devlink_trap_item *trap_item;
5641 struct sk_buff *msg;
5642 int err;
5643
5644 if (list_empty(&devlink->trap_list))
5645 return -EOPNOTSUPP;
5646
5647 trap_item = devlink_trap_item_get_from_info(devlink, info);
5648 if (!trap_item) {
5649 NL_SET_ERR_MSG(extack, "Device did not register this trap");
5650 return -ENOENT;
5651 }
5652
5653 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5654 if (!msg)
5655 return -ENOMEM;
5656
5657 err = devlink_nl_trap_fill(msg, devlink, trap_item,
5658 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
5659 info->snd_seq, 0);
5660 if (err)
5661 goto err_trap_fill;
5662
5663 return genlmsg_reply(msg, info);
5664
5665err_trap_fill:
5666 nlmsg_free(msg);
5667 return err;
5668}
5669
5670static int
5671devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
5672 struct netlink_callback *cb)
5673{
5674 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5675 struct devlink_trap_item *trap_item;
5676 int idx = 0;
5677 int err = 0;
5678
5679 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5680 if (idx < state->idx) {
5681 idx++;
5682 continue;
5683 }
5684 err = devlink_nl_trap_fill(msg, devlink, trap_item,
5685 DEVLINK_CMD_TRAP_NEW,
5686 NETLINK_CB(cb->skb).portid,
5687 cb->nlh->nlmsg_seq,
5688 NLM_F_MULTI);
5689 if (err) {
5690 state->idx = idx;
5691 break;
5692 }
5693 idx++;
5694 }
5695
5696 return err;
5697}
5698
5699const struct devlink_cmd devl_cmd_trap_get = {
5700 .dump_one = devlink_nl_cmd_trap_get_dump_one,
5701};
5702
5703static int __devlink_trap_action_set(struct devlink *devlink,
5704 struct devlink_trap_item *trap_item,
5705 enum devlink_trap_action trap_action,
5706 struct netlink_ext_ack *extack)
5707{
5708 int err;
5709
5710 if (trap_item->action != trap_action &&
5711 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
5712 NL_SET_ERR_MSG(extack, "Cannot change action of non-drop traps. Skipping");
5713 return 0;
5714 }
5715
5716 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
5717 trap_action, extack);
5718 if (err)
5719 return err;
5720
5721 trap_item->action = trap_action;
5722
5723 return 0;
5724}
5725
5726static int devlink_trap_action_set(struct devlink *devlink,
5727 struct devlink_trap_item *trap_item,
5728 struct genl_info *info)
5729{
5730 enum devlink_trap_action trap_action;
5731 int err;
5732
5733 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
5734 return 0;
5735
5736 err = devlink_trap_action_get_from_info(info, &trap_action);
5737 if (err) {
5738 NL_SET_ERR_MSG(info->extack, "Invalid trap action");
5739 return -EINVAL;
5740 }
5741
5742 return __devlink_trap_action_set(devlink, trap_item, trap_action,
5743 info->extack);
5744}
5745
5746static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
5747 struct genl_info *info)
5748{
5749 struct netlink_ext_ack *extack = info->extack;
5750 struct devlink *devlink = info->user_ptr[0];
5751 struct devlink_trap_item *trap_item;
5752
5753 if (list_empty(&devlink->trap_list))
5754 return -EOPNOTSUPP;
5755
5756 trap_item = devlink_trap_item_get_from_info(devlink, info);
5757 if (!trap_item) {
5758 NL_SET_ERR_MSG(extack, "Device did not register this trap");
5759 return -ENOENT;
5760 }
5761
5762 return devlink_trap_action_set(devlink, trap_item, info);
5763}
5764
5765static struct devlink_trap_group_item *
5766devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
5767{
5768 struct devlink_trap_group_item *group_item;
5769
5770 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
5771 if (!strcmp(group_item->group->name, name))
5772 return group_item;
5773 }
5774
5775 return NULL;
5776}
5777
5778static struct devlink_trap_group_item *
5779devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
5780{
5781 struct devlink_trap_group_item *group_item;
5782
5783 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
5784 if (group_item->group->id == id)
5785 return group_item;
5786 }
5787
5788 return NULL;
5789}
5790
5791static struct devlink_trap_group_item *
5792devlink_trap_group_item_get_from_info(struct devlink *devlink,
5793 struct genl_info *info)
5794{
5795 char *name;
5796
5797 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
5798 return NULL;
5799 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
5800
5801 return devlink_trap_group_item_lookup(devlink, name);
5802}
5803
5804static int
5805devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
5806 const struct devlink_trap_group_item *group_item,
5807 enum devlink_command cmd, u32 portid, u32 seq,
5808 int flags)
5809{
5810 void *hdr;
5811 int err;
5812
5813 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5814 if (!hdr)
5815 return -EMSGSIZE;
5816
5817 if (devlink_nl_put_handle(msg, devlink))
5818 goto nla_put_failure;
5819
5820 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
5821 group_item->group->name))
5822 goto nla_put_failure;
5823
5824 if (group_item->group->generic &&
5825 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
5826 goto nla_put_failure;
5827
5828 if (group_item->policer_item &&
5829 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
5830 group_item->policer_item->policer->id))
5831 goto nla_put_failure;
5832
5833 err = devlink_trap_group_stats_put(msg, group_item->stats);
5834 if (err)
5835 goto nla_put_failure;
5836
5837 genlmsg_end(msg, hdr);
5838
5839 return 0;
5840
5841nla_put_failure:
5842 genlmsg_cancel(msg, hdr);
5843 return -EMSGSIZE;
5844}
5845
5846static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
5847 struct genl_info *info)
5848{
5849 struct netlink_ext_ack *extack = info->extack;
5850 struct devlink *devlink = info->user_ptr[0];
5851 struct devlink_trap_group_item *group_item;
5852 struct sk_buff *msg;
5853 int err;
5854
5855 if (list_empty(&devlink->trap_group_list))
5856 return -EOPNOTSUPP;
5857
5858 group_item = devlink_trap_group_item_get_from_info(devlink, info);
5859 if (!group_item) {
5860 NL_SET_ERR_MSG(extack, "Device did not register this trap group");
5861 return -ENOENT;
5862 }
5863
5864 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5865 if (!msg)
5866 return -ENOMEM;
5867
5868 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
5869 DEVLINK_CMD_TRAP_GROUP_NEW,
5870 info->snd_portid, info->snd_seq, 0);
5871 if (err)
5872 goto err_trap_group_fill;
5873
5874 return genlmsg_reply(msg, info);
5875
5876err_trap_group_fill:
5877 nlmsg_free(msg);
5878 return err;
5879}
5880
5881static int
5882devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg,
5883 struct devlink *devlink,
5884 struct netlink_callback *cb)
5885{
5886 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5887 struct devlink_trap_group_item *group_item;
5888 int idx = 0;
5889 int err = 0;
5890
5891
5892 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
5893 if (idx < state->idx) {
5894 idx++;
5895 continue;
5896 }
5897 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
5898 DEVLINK_CMD_TRAP_GROUP_NEW,
5899 NETLINK_CB(cb->skb).portid,
5900 cb->nlh->nlmsg_seq,
5901 NLM_F_MULTI);
5902 if (err) {
5903 state->idx = idx;
5904 break;
5905 }
5906 idx++;
5907 }
5908
5909 return err;
5910}
5911
5912const struct devlink_cmd devl_cmd_trap_group_get = {
5913 .dump_one = devlink_nl_cmd_trap_group_get_dump_one,
5914};
5915
5916static int
5917__devlink_trap_group_action_set(struct devlink *devlink,
5918 struct devlink_trap_group_item *group_item,
5919 enum devlink_trap_action trap_action,
5920 struct netlink_ext_ack *extack)
5921{
5922 const char *group_name = group_item->group->name;
5923 struct devlink_trap_item *trap_item;
5924 int err;
5925
5926 if (devlink->ops->trap_group_action_set) {
5927 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
5928 trap_action, extack);
5929 if (err)
5930 return err;
5931
5932 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5933 if (strcmp(trap_item->group_item->group->name, group_name))
5934 continue;
5935 if (trap_item->action != trap_action &&
5936 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
5937 continue;
5938 trap_item->action = trap_action;
5939 }
5940
5941 return 0;
5942 }
5943
5944 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5945 if (strcmp(trap_item->group_item->group->name, group_name))
5946 continue;
5947 err = __devlink_trap_action_set(devlink, trap_item,
5948 trap_action, extack);
5949 if (err)
5950 return err;
5951 }
5952
5953 return 0;
5954}
5955
5956static int
5957devlink_trap_group_action_set(struct devlink *devlink,
5958 struct devlink_trap_group_item *group_item,
5959 struct genl_info *info, bool *p_modified)
5960{
5961 enum devlink_trap_action trap_action;
5962 int err;
5963
5964 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
5965 return 0;
5966
5967 err = devlink_trap_action_get_from_info(info, &trap_action);
5968 if (err) {
5969 NL_SET_ERR_MSG(info->extack, "Invalid trap action");
5970 return -EINVAL;
5971 }
5972
5973 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
5974 info->extack);
5975 if (err)
5976 return err;
5977
5978 *p_modified = true;
5979
5980 return 0;
5981}
5982
5983static int devlink_trap_group_set(struct devlink *devlink,
5984 struct devlink_trap_group_item *group_item,
5985 struct genl_info *info)
5986{
5987 struct devlink_trap_policer_item *policer_item;
5988 struct netlink_ext_ack *extack = info->extack;
5989 const struct devlink_trap_policer *policer;
5990 struct nlattr **attrs = info->attrs;
5991 u32 policer_id;
5992 int err;
5993
5994 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
5995 return 0;
5996
5997 if (!devlink->ops->trap_group_set)
5998 return -EOPNOTSUPP;
5999
6000 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
6001 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
6002 if (policer_id && !policer_item) {
6003 NL_SET_ERR_MSG(extack, "Device did not register this trap policer");
6004 return -ENOENT;
6005 }
6006 policer = policer_item ? policer_item->policer : NULL;
6007
6008 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
6009 extack);
6010 if (err)
6011 return err;
6012
6013 group_item->policer_item = policer_item;
6014
6015 return 0;
6016}
6017
6018static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
6019 struct genl_info *info)
6020{
6021 struct netlink_ext_ack *extack = info->extack;
6022 struct devlink *devlink = info->user_ptr[0];
6023 struct devlink_trap_group_item *group_item;
6024 bool modified = false;
6025 int err;
6026
6027 if (list_empty(&devlink->trap_group_list))
6028 return -EOPNOTSUPP;
6029
6030 group_item = devlink_trap_group_item_get_from_info(devlink, info);
6031 if (!group_item) {
6032 NL_SET_ERR_MSG(extack, "Device did not register this trap group");
6033 return -ENOENT;
6034 }
6035
6036 err = devlink_trap_group_action_set(devlink, group_item, info,
6037 &modified);
6038 if (err)
6039 return err;
6040
6041 err = devlink_trap_group_set(devlink, group_item, info);
6042 if (err)
6043 goto err_trap_group_set;
6044
6045 return 0;
6046
6047err_trap_group_set:
6048 if (modified)
6049 NL_SET_ERR_MSG(extack, "Trap group set failed, but some changes were committed already");
6050 return err;
6051}
6052
6053static struct devlink_trap_policer_item *
6054devlink_trap_policer_item_get_from_info(struct devlink *devlink,
6055 struct genl_info *info)
6056{
6057 u32 id;
6058
6059 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
6060 return NULL;
6061 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
6062
6063 return devlink_trap_policer_item_lookup(devlink, id);
6064}
6065
6066static int
6067devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
6068 const struct devlink_trap_policer *policer)
6069{
6070 struct nlattr *attr;
6071 u64 drops;
6072 int err;
6073
6074 if (!devlink->ops->trap_policer_counter_get)
6075 return 0;
6076
6077 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
6078 if (err)
6079 return err;
6080
6081 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6082 if (!attr)
6083 return -EMSGSIZE;
6084
6085 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
6086 DEVLINK_ATTR_PAD))
6087 goto nla_put_failure;
6088
6089 nla_nest_end(msg, attr);
6090
6091 return 0;
6092
6093nla_put_failure:
6094 nla_nest_cancel(msg, attr);
6095 return -EMSGSIZE;
6096}
6097
6098static int
6099devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
6100 const struct devlink_trap_policer_item *policer_item,
6101 enum devlink_command cmd, u32 portid, u32 seq,
6102 int flags)
6103{
6104 void *hdr;
6105 int err;
6106
6107 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6108 if (!hdr)
6109 return -EMSGSIZE;
6110
6111 if (devlink_nl_put_handle(msg, devlink))
6112 goto nla_put_failure;
6113
6114 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
6115 policer_item->policer->id))
6116 goto nla_put_failure;
6117
6118 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
6119 policer_item->rate, DEVLINK_ATTR_PAD))
6120 goto nla_put_failure;
6121
6122 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
6123 policer_item->burst, DEVLINK_ATTR_PAD))
6124 goto nla_put_failure;
6125
6126 err = devlink_trap_policer_stats_put(msg, devlink,
6127 policer_item->policer);
6128 if (err)
6129 goto nla_put_failure;
6130
6131 genlmsg_end(msg, hdr);
6132
6133 return 0;
6134
6135nla_put_failure:
6136 genlmsg_cancel(msg, hdr);
6137 return -EMSGSIZE;
6138}
6139
6140static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
6141 struct genl_info *info)
6142{
6143 struct devlink_trap_policer_item *policer_item;
6144 struct netlink_ext_ack *extack = info->extack;
6145 struct devlink *devlink = info->user_ptr[0];
6146 struct sk_buff *msg;
6147 int err;
6148
6149 if (list_empty(&devlink->trap_policer_list))
6150 return -EOPNOTSUPP;
6151
6152 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
6153 if (!policer_item) {
6154 NL_SET_ERR_MSG(extack, "Device did not register this trap policer");
6155 return -ENOENT;
6156 }
6157
6158 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6159 if (!msg)
6160 return -ENOMEM;
6161
6162 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
6163 DEVLINK_CMD_TRAP_POLICER_NEW,
6164 info->snd_portid, info->snd_seq, 0);
6165 if (err)
6166 goto err_trap_policer_fill;
6167
6168 return genlmsg_reply(msg, info);
6169
6170err_trap_policer_fill:
6171 nlmsg_free(msg);
6172 return err;
6173}
6174
6175static int
6176devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg,
6177 struct devlink *devlink,
6178 struct netlink_callback *cb)
6179{
6180 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6181 struct devlink_trap_policer_item *policer_item;
6182 int idx = 0;
6183 int err = 0;
6184
6185 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
6186 if (idx < state->idx) {
6187 idx++;
6188 continue;
6189 }
6190 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
6191 DEVLINK_CMD_TRAP_POLICER_NEW,
6192 NETLINK_CB(cb->skb).portid,
6193 cb->nlh->nlmsg_seq,
6194 NLM_F_MULTI);
6195 if (err) {
6196 state->idx = idx;
6197 break;
6198 }
6199 idx++;
6200 }
6201
6202 return err;
6203}
6204
6205const struct devlink_cmd devl_cmd_trap_policer_get = {
6206 .dump_one = devlink_nl_cmd_trap_policer_get_dump_one,
6207};
6208
6209static int
6210devlink_trap_policer_set(struct devlink *devlink,
6211 struct devlink_trap_policer_item *policer_item,
6212 struct genl_info *info)
6213{
6214 struct netlink_ext_ack *extack = info->extack;
6215 struct nlattr **attrs = info->attrs;
6216 u64 rate, burst;
6217 int err;
6218
6219 rate = policer_item->rate;
6220 burst = policer_item->burst;
6221
6222 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
6223 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
6224
6225 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
6226 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
6227
6228 if (rate < policer_item->policer->min_rate) {
6229 NL_SET_ERR_MSG(extack, "Policer rate lower than limit");
6230 return -EINVAL;
6231 }
6232
6233 if (rate > policer_item->policer->max_rate) {
6234 NL_SET_ERR_MSG(extack, "Policer rate higher than limit");
6235 return -EINVAL;
6236 }
6237
6238 if (burst < policer_item->policer->min_burst) {
6239 NL_SET_ERR_MSG(extack, "Policer burst size lower than limit");
6240 return -EINVAL;
6241 }
6242
6243 if (burst > policer_item->policer->max_burst) {
6244 NL_SET_ERR_MSG(extack, "Policer burst size higher than limit");
6245 return -EINVAL;
6246 }
6247
6248 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
6249 rate, burst, info->extack);
6250 if (err)
6251 return err;
6252
6253 policer_item->rate = rate;
6254 policer_item->burst = burst;
6255
6256 return 0;
6257}
6258
6259static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
6260 struct genl_info *info)
6261{
6262 struct devlink_trap_policer_item *policer_item;
6263 struct netlink_ext_ack *extack = info->extack;
6264 struct devlink *devlink = info->user_ptr[0];
6265
6266 if (list_empty(&devlink->trap_policer_list))
6267 return -EOPNOTSUPP;
6268
6269 if (!devlink->ops->trap_policer_set)
6270 return -EOPNOTSUPP;
6271
6272 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
6273 if (!policer_item) {
6274 NL_SET_ERR_MSG(extack, "Device did not register this trap policer");
6275 return -ENOENT;
6276 }
6277
6278 return devlink_trap_policer_set(devlink, policer_item, info);
6279}
6280
6281const struct genl_small_ops devlink_nl_ops[56] = {
6282 {
6283 .cmd = DEVLINK_CMD_GET,
6284 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6285 .doit = devlink_nl_cmd_get_doit,
6286 .dumpit = devlink_nl_instance_iter_dumpit,
6287 /* can be retrieved by unprivileged users */
6288 },
6289 {
6290 .cmd = DEVLINK_CMD_PORT_GET,
6291 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6292 .doit = devlink_nl_cmd_port_get_doit,
6293 .dumpit = devlink_nl_instance_iter_dumpit,
6294 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6295 /* can be retrieved by unprivileged users */
6296 },
6297 {
6298 .cmd = DEVLINK_CMD_PORT_SET,
6299 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6300 .doit = devlink_nl_cmd_port_set_doit,
6301 .flags = GENL_ADMIN_PERM,
6302 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6303 },
6304 {
6305 .cmd = DEVLINK_CMD_RATE_GET,
6306 .doit = devlink_nl_cmd_rate_get_doit,
6307 .dumpit = devlink_nl_instance_iter_dumpit,
6308 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
6309 /* can be retrieved by unprivileged users */
6310 },
6311 {
6312 .cmd = DEVLINK_CMD_RATE_SET,
6313 .doit = devlink_nl_cmd_rate_set_doit,
6314 .flags = GENL_ADMIN_PERM,
6315 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
6316 },
6317 {
6318 .cmd = DEVLINK_CMD_RATE_NEW,
6319 .doit = devlink_nl_cmd_rate_new_doit,
6320 .flags = GENL_ADMIN_PERM,
6321 },
6322 {
6323 .cmd = DEVLINK_CMD_RATE_DEL,
6324 .doit = devlink_nl_cmd_rate_del_doit,
6325 .flags = GENL_ADMIN_PERM,
6326 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
6327 },
6328 {
6329 .cmd = DEVLINK_CMD_PORT_SPLIT,
6330 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6331 .doit = devlink_nl_cmd_port_split_doit,
6332 .flags = GENL_ADMIN_PERM,
6333 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6334 },
6335 {
6336 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
6337 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6338 .doit = devlink_nl_cmd_port_unsplit_doit,
6339 .flags = GENL_ADMIN_PERM,
6340 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6341 },
6342 {
6343 .cmd = DEVLINK_CMD_PORT_NEW,
6344 .doit = devlink_nl_cmd_port_new_doit,
6345 .flags = GENL_ADMIN_PERM,
6346 },
6347 {
6348 .cmd = DEVLINK_CMD_PORT_DEL,
6349 .doit = devlink_nl_cmd_port_del_doit,
6350 .flags = GENL_ADMIN_PERM,
6351 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6352 },
6353 {
6354 .cmd = DEVLINK_CMD_LINECARD_GET,
6355 .doit = devlink_nl_cmd_linecard_get_doit,
6356 .dumpit = devlink_nl_instance_iter_dumpit,
6357 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
6358 /* can be retrieved by unprivileged users */
6359 },
6360 {
6361 .cmd = DEVLINK_CMD_LINECARD_SET,
6362 .doit = devlink_nl_cmd_linecard_set_doit,
6363 .flags = GENL_ADMIN_PERM,
6364 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
6365 },
6366 {
6367 .cmd = DEVLINK_CMD_SB_GET,
6368 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6369 .doit = devlink_nl_cmd_sb_get_doit,
6370 .dumpit = devlink_nl_instance_iter_dumpit,
6371 /* can be retrieved by unprivileged users */
6372 },
6373 {
6374 .cmd = DEVLINK_CMD_SB_POOL_GET,
6375 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6376 .doit = devlink_nl_cmd_sb_pool_get_doit,
6377 .dumpit = devlink_nl_instance_iter_dumpit,
6378 /* can be retrieved by unprivileged users */
6379 },
6380 {
6381 .cmd = DEVLINK_CMD_SB_POOL_SET,
6382 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6383 .doit = devlink_nl_cmd_sb_pool_set_doit,
6384 .flags = GENL_ADMIN_PERM,
6385 },
6386 {
6387 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
6388 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6389 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
6390 .dumpit = devlink_nl_instance_iter_dumpit,
6391 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6392 /* can be retrieved by unprivileged users */
6393 },
6394 {
6395 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
6396 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6397 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
6398 .flags = GENL_ADMIN_PERM,
6399 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6400 },
6401 {
6402 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
6403 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6404 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
6405 .dumpit = devlink_nl_instance_iter_dumpit,
6406 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6407 /* can be retrieved by unprivileged users */
6408 },
6409 {
6410 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
6411 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6412 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
6413 .flags = GENL_ADMIN_PERM,
6414 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6415 },
6416 {
6417 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
6418 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6419 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
6420 .flags = GENL_ADMIN_PERM,
6421 },
6422 {
6423 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
6424 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6425 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
6426 .flags = GENL_ADMIN_PERM,
6427 },
6428 {
6429 .cmd = DEVLINK_CMD_ESWITCH_GET,
6430 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6431 .doit = devlink_nl_cmd_eswitch_get_doit,
6432 .flags = GENL_ADMIN_PERM,
6433 },
6434 {
6435 .cmd = DEVLINK_CMD_ESWITCH_SET,
6436 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6437 .doit = devlink_nl_cmd_eswitch_set_doit,
6438 .flags = GENL_ADMIN_PERM,
6439 },
6440 {
6441 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
6442 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6443 .doit = devlink_nl_cmd_dpipe_table_get,
6444 /* can be retrieved by unprivileged users */
6445 },
6446 {
6447 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
6448 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6449 .doit = devlink_nl_cmd_dpipe_entries_get,
6450 /* can be retrieved by unprivileged users */
6451 },
6452 {
6453 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
6454 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6455 .doit = devlink_nl_cmd_dpipe_headers_get,
6456 /* can be retrieved by unprivileged users */
6457 },
6458 {
6459 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
6460 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6461 .doit = devlink_nl_cmd_dpipe_table_counters_set,
6462 .flags = GENL_ADMIN_PERM,
6463 },
6464 {
6465 .cmd = DEVLINK_CMD_RESOURCE_SET,
6466 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6467 .doit = devlink_nl_cmd_resource_set,
6468 .flags = GENL_ADMIN_PERM,
6469 },
6470 {
6471 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
6472 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6473 .doit = devlink_nl_cmd_resource_dump,
6474 /* can be retrieved by unprivileged users */
6475 },
6476 {
6477 .cmd = DEVLINK_CMD_RELOAD,
6478 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6479 .doit = devlink_nl_cmd_reload,
6480 .flags = GENL_ADMIN_PERM,
6481 },
6482 {
6483 .cmd = DEVLINK_CMD_PARAM_GET,
6484 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6485 .doit = devlink_nl_cmd_param_get_doit,
6486 .dumpit = devlink_nl_instance_iter_dumpit,
6487 /* can be retrieved by unprivileged users */
6488 },
6489 {
6490 .cmd = DEVLINK_CMD_PARAM_SET,
6491 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6492 .doit = devlink_nl_cmd_param_set_doit,
6493 .flags = GENL_ADMIN_PERM,
6494 },
6495 {
6496 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
6497 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6498 .doit = devlink_nl_cmd_port_param_get_doit,
6499 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
6500 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6501 /* can be retrieved by unprivileged users */
6502 },
6503 {
6504 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
6505 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6506 .doit = devlink_nl_cmd_port_param_set_doit,
6507 .flags = GENL_ADMIN_PERM,
6508 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6509 },
6510 {
6511 .cmd = DEVLINK_CMD_REGION_GET,
6512 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6513 .doit = devlink_nl_cmd_region_get_doit,
6514 .dumpit = devlink_nl_instance_iter_dumpit,
6515 .flags = GENL_ADMIN_PERM,
6516 },
6517 {
6518 .cmd = DEVLINK_CMD_REGION_NEW,
6519 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6520 .doit = devlink_nl_cmd_region_new,
6521 .flags = GENL_ADMIN_PERM,
6522 },
6523 {
6524 .cmd = DEVLINK_CMD_REGION_DEL,
6525 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6526 .doit = devlink_nl_cmd_region_del,
6527 .flags = GENL_ADMIN_PERM,
6528 },
6529 {
6530 .cmd = DEVLINK_CMD_REGION_READ,
6531 .validate = GENL_DONT_VALIDATE_STRICT |
6532 GENL_DONT_VALIDATE_DUMP_STRICT,
6533 .dumpit = devlink_nl_cmd_region_read_dumpit,
6534 .flags = GENL_ADMIN_PERM,
6535 },
6536 {
6537 .cmd = DEVLINK_CMD_INFO_GET,
6538 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6539 .doit = devlink_nl_cmd_info_get_doit,
6540 .dumpit = devlink_nl_instance_iter_dumpit,
6541 /* can be retrieved by unprivileged users */
6542 },
6543 {
6544 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
6545 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6546 .doit = devlink_nl_cmd_health_reporter_get_doit,
6547 .dumpit = devlink_nl_instance_iter_dumpit,
6548 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
6549 /* can be retrieved by unprivileged users */
6550 },
6551 {
6552 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
6553 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6554 .doit = devlink_nl_cmd_health_reporter_set_doit,
6555 .flags = GENL_ADMIN_PERM,
6556 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
6557 },
6558 {
6559 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
6560 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6561 .doit = devlink_nl_cmd_health_reporter_recover_doit,
6562 .flags = GENL_ADMIN_PERM,
6563 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
6564 },
6565 {
6566 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
6567 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6568 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
6569 .flags = GENL_ADMIN_PERM,
6570 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
6571 },
6572 {
6573 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
6574 .validate = GENL_DONT_VALIDATE_STRICT |
6575 GENL_DONT_VALIDATE_DUMP_STRICT,
6576 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
6577 .flags = GENL_ADMIN_PERM,
6578 },
6579 {
6580 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
6581 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6582 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
6583 .flags = GENL_ADMIN_PERM,
6584 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
6585 },
6586 {
6587 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
6588 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6589 .doit = devlink_nl_cmd_health_reporter_test_doit,
6590 .flags = GENL_ADMIN_PERM,
6591 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
6592 },
6593 {
6594 .cmd = DEVLINK_CMD_FLASH_UPDATE,
6595 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6596 .doit = devlink_nl_cmd_flash_update,
6597 .flags = GENL_ADMIN_PERM,
6598 },
6599 {
6600 .cmd = DEVLINK_CMD_TRAP_GET,
6601 .doit = devlink_nl_cmd_trap_get_doit,
6602 .dumpit = devlink_nl_instance_iter_dumpit,
6603 /* can be retrieved by unprivileged users */
6604 },
6605 {
6606 .cmd = DEVLINK_CMD_TRAP_SET,
6607 .doit = devlink_nl_cmd_trap_set_doit,
6608 .flags = GENL_ADMIN_PERM,
6609 },
6610 {
6611 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
6612 .doit = devlink_nl_cmd_trap_group_get_doit,
6613 .dumpit = devlink_nl_instance_iter_dumpit,
6614 /* can be retrieved by unprivileged users */
6615 },
6616 {
6617 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
6618 .doit = devlink_nl_cmd_trap_group_set_doit,
6619 .flags = GENL_ADMIN_PERM,
6620 },
6621 {
6622 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
6623 .doit = devlink_nl_cmd_trap_policer_get_doit,
6624 .dumpit = devlink_nl_instance_iter_dumpit,
6625 /* can be retrieved by unprivileged users */
6626 },
6627 {
6628 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
6629 .doit = devlink_nl_cmd_trap_policer_set_doit,
6630 .flags = GENL_ADMIN_PERM,
6631 },
6632 {
6633 .cmd = DEVLINK_CMD_SELFTESTS_GET,
6634 .doit = devlink_nl_cmd_selftests_get_doit,
6635 .dumpit = devlink_nl_instance_iter_dumpit,
6636 /* can be retrieved by unprivileged users */
6637 },
6638 {
6639 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
6640 .doit = devlink_nl_cmd_selftests_run,
6641 .flags = GENL_ADMIN_PERM,
6642 },
6643 /* -- No new ops here! Use split ops going forward! -- */
6644};
6645
6646static void
6647devlink_trap_policer_notify(struct devlink *devlink,
6648 const struct devlink_trap_policer_item *policer_item,
6649 enum devlink_command cmd);
6650static void
6651devlink_trap_group_notify(struct devlink *devlink,
6652 const struct devlink_trap_group_item *group_item,
6653 enum devlink_command cmd);
6654static void devlink_trap_notify(struct devlink *devlink,
6655 const struct devlink_trap_item *trap_item,
6656 enum devlink_command cmd);
6657
6658void devlink_notify_register(struct devlink *devlink)
6659{
6660 struct devlink_trap_policer_item *policer_item;
6661 struct devlink_trap_group_item *group_item;
6662 struct devlink_param_item *param_item;
6663 struct devlink_trap_item *trap_item;
6664 struct devlink_port *devlink_port;
6665 struct devlink_linecard *linecard;
6666 struct devlink_rate *rate_node;
6667 struct devlink_region *region;
6668 unsigned long port_index;
6669 unsigned long param_id;
6670
6671 devlink_notify(devlink, DEVLINK_CMD_NEW);
6672 list_for_each_entry(linecard, &devlink->linecard_list, list)
6673 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
6674
6675 xa_for_each(&devlink->ports, port_index, devlink_port)
6676 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6677
6678 list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
6679 devlink_trap_policer_notify(devlink, policer_item,
6680 DEVLINK_CMD_TRAP_POLICER_NEW);
6681
6682 list_for_each_entry(group_item, &devlink->trap_group_list, list)
6683 devlink_trap_group_notify(devlink, group_item,
6684 DEVLINK_CMD_TRAP_GROUP_NEW);
6685
6686 list_for_each_entry(trap_item, &devlink->trap_list, list)
6687 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
6688
6689 list_for_each_entry(rate_node, &devlink->rate_list, list)
6690 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
6691
6692 list_for_each_entry(region, &devlink->region_list, list)
6693 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
6694
6695 xa_for_each(&devlink->params, param_id, param_item)
6696 devlink_param_notify(devlink, 0, param_item,
6697 DEVLINK_CMD_PARAM_NEW);
6698}
6699
6700void devlink_notify_unregister(struct devlink *devlink)
6701{
6702 struct devlink_trap_policer_item *policer_item;
6703 struct devlink_trap_group_item *group_item;
6704 struct devlink_param_item *param_item;
6705 struct devlink_trap_item *trap_item;
6706 struct devlink_port *devlink_port;
6707 struct devlink_rate *rate_node;
6708 struct devlink_region *region;
6709 unsigned long port_index;
6710 unsigned long param_id;
6711
6712 xa_for_each(&devlink->params, param_id, param_item)
6713 devlink_param_notify(devlink, 0, param_item,
6714 DEVLINK_CMD_PARAM_DEL);
6715
6716 list_for_each_entry_reverse(region, &devlink->region_list, list)
6717 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
6718
6719 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
6720 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
6721
6722 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
6723 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
6724
6725 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
6726 devlink_trap_group_notify(devlink, group_item,
6727 DEVLINK_CMD_TRAP_GROUP_DEL);
6728 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
6729 list)
6730 devlink_trap_policer_notify(devlink, policer_item,
6731 DEVLINK_CMD_TRAP_POLICER_DEL);
6732
6733 xa_for_each(&devlink->ports, port_index, devlink_port)
6734 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
6735 devlink_notify(devlink, DEVLINK_CMD_DEL);
6736}
6737
6738static void devlink_port_type_warn(struct work_struct *work)
6739{
6740 struct devlink_port *port = container_of(to_delayed_work(work),
6741 struct devlink_port,
6742 type_warn_dw);
6743 dev_warn(port->devlink->dev, "Type was not set for devlink port.");
6744}
6745
6746static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
6747{
6748 /* Ignore CPU and DSA flavours. */
6749 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
6750 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
6751 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
6752}
6753
6754#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
6755
6756static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
6757{
6758 if (!devlink_port_type_should_warn(devlink_port))
6759 return;
6760 /* Schedule a work to WARN in case driver does not set port
6761 * type within timeout.
6762 */
6763 schedule_delayed_work(&devlink_port->type_warn_dw,
6764 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
6765}
6766
6767static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
6768{
6769 if (!devlink_port_type_should_warn(devlink_port))
6770 return;
6771 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
6772}
6773
6774/**
6775 * devlink_port_init() - Init devlink port
6776 *
6777 * @devlink: devlink
6778 * @devlink_port: devlink port
6779 *
6780 * Initialize essential stuff that is needed for functions
6781 * that may be called before devlink port registration.
6782 * Call to this function is optional and not needed
6783 * in case the driver does not use such functions.
6784 */
6785void devlink_port_init(struct devlink *devlink,
6786 struct devlink_port *devlink_port)
6787{
6788 if (devlink_port->initialized)
6789 return;
6790 devlink_port->devlink = devlink;
6791 INIT_LIST_HEAD(&devlink_port->region_list);
6792 devlink_port->initialized = true;
6793}
6794EXPORT_SYMBOL_GPL(devlink_port_init);
6795
6796/**
6797 * devlink_port_fini() - Deinitialize devlink port
6798 *
6799 * @devlink_port: devlink port
6800 *
6801 * Deinitialize essential stuff that is in use for functions
6802 * that may be called after devlink port unregistration.
6803 * Call to this function is optional and not needed
6804 * in case the driver does not use such functions.
6805 */
6806void devlink_port_fini(struct devlink_port *devlink_port)
6807{
6808 WARN_ON(!list_empty(&devlink_port->region_list));
6809}
6810EXPORT_SYMBOL_GPL(devlink_port_fini);
6811
6812static const struct devlink_port_ops devlink_port_dummy_ops = {};
6813
6814/**
6815 * devl_port_register_with_ops() - Register devlink port
6816 *
6817 * @devlink: devlink
6818 * @devlink_port: devlink port
6819 * @port_index: driver-specific numerical identifier of the port
6820 * @ops: port ops
6821 *
6822 * Register devlink port with provided port index. User can use
6823 * any indexing, even hw-related one. devlink_port structure
6824 * is convenient to be embedded inside user driver private structure.
6825 * Note that the caller should take care of zeroing the devlink_port
6826 * structure.
6827 */
6828int devl_port_register_with_ops(struct devlink *devlink,
6829 struct devlink_port *devlink_port,
6830 unsigned int port_index,
6831 const struct devlink_port_ops *ops)
6832{
6833 int err;
6834
6835 devl_assert_locked(devlink);
6836
6837 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
6838
6839 devlink_port_init(devlink, devlink_port);
6840 devlink_port->registered = true;
6841 devlink_port->index = port_index;
6842 devlink_port->ops = ops ? ops : &devlink_port_dummy_ops;
6843 spin_lock_init(&devlink_port->type_lock);
6844 INIT_LIST_HEAD(&devlink_port->reporter_list);
6845 err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
6846 if (err)
6847 return err;
6848
6849 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
6850 devlink_port_type_warn_schedule(devlink_port);
6851 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6852 return 0;
6853}
6854EXPORT_SYMBOL_GPL(devl_port_register_with_ops);
6855
6856/**
6857 * devlink_port_register_with_ops - Register devlink port
6858 *
6859 * @devlink: devlink
6860 * @devlink_port: devlink port
6861 * @port_index: driver-specific numerical identifier of the port
6862 * @ops: port ops
6863 *
6864 * Register devlink port with provided port index. User can use
6865 * any indexing, even hw-related one. devlink_port structure
6866 * is convenient to be embedded inside user driver private structure.
6867 * Note that the caller should take care of zeroing the devlink_port
6868 * structure.
6869 *
6870 * Context: Takes and release devlink->lock <mutex>.
6871 */
6872int devlink_port_register_with_ops(struct devlink *devlink,
6873 struct devlink_port *devlink_port,
6874 unsigned int port_index,
6875 const struct devlink_port_ops *ops)
6876{
6877 int err;
6878
6879 devl_lock(devlink);
6880 err = devl_port_register_with_ops(devlink, devlink_port,
6881 port_index, ops);
6882 devl_unlock(devlink);
6883 return err;
6884}
6885EXPORT_SYMBOL_GPL(devlink_port_register_with_ops);
6886
6887/**
6888 * devl_port_unregister() - Unregister devlink port
6889 *
6890 * @devlink_port: devlink port
6891 */
6892void devl_port_unregister(struct devlink_port *devlink_port)
6893{
6894 lockdep_assert_held(&devlink_port->devlink->lock);
6895 WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
6896
6897 devlink_port_type_warn_cancel(devlink_port);
6898 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
6899 xa_erase(&devlink_port->devlink->ports, devlink_port->index);
6900 WARN_ON(!list_empty(&devlink_port->reporter_list));
6901 devlink_port->registered = false;
6902}
6903EXPORT_SYMBOL_GPL(devl_port_unregister);
6904
6905/**
6906 * devlink_port_unregister - Unregister devlink port
6907 *
6908 * @devlink_port: devlink port
6909 *
6910 * Context: Takes and release devlink->lock <mutex>.
6911 */
6912void devlink_port_unregister(struct devlink_port *devlink_port)
6913{
6914 struct devlink *devlink = devlink_port->devlink;
6915
6916 devl_lock(devlink);
6917 devl_port_unregister(devlink_port);
6918 devl_unlock(devlink);
6919}
6920EXPORT_SYMBOL_GPL(devlink_port_unregister);
6921
6922static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
6923 struct net_device *netdev)
6924{
6925 const struct net_device_ops *ops = netdev->netdev_ops;
6926
6927 /* If driver registers devlink port, it should set devlink port
6928 * attributes accordingly so the compat functions are called
6929 * and the original ops are not used.
6930 */
6931 if (ops->ndo_get_phys_port_name) {
6932 /* Some drivers use the same set of ndos for netdevs
6933 * that have devlink_port registered and also for
6934 * those who don't. Make sure that ndo_get_phys_port_name
6935 * returns -EOPNOTSUPP here in case it is defined.
6936 * Warn if not.
6937 */
6938 char name[IFNAMSIZ];
6939 int err;
6940
6941 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
6942 WARN_ON(err != -EOPNOTSUPP);
6943 }
6944 if (ops->ndo_get_port_parent_id) {
6945 /* Some drivers use the same set of ndos for netdevs
6946 * that have devlink_port registered and also for
6947 * those who don't. Make sure that ndo_get_port_parent_id
6948 * returns -EOPNOTSUPP here in case it is defined.
6949 * Warn if not.
6950 */
6951 struct netdev_phys_item_id ppid;
6952 int err;
6953
6954 err = ops->ndo_get_port_parent_id(netdev, &ppid);
6955 WARN_ON(err != -EOPNOTSUPP);
6956 }
6957}
6958
6959static void __devlink_port_type_set(struct devlink_port *devlink_port,
6960 enum devlink_port_type type,
6961 void *type_dev)
6962{
6963 struct net_device *netdev = type_dev;
6964
6965 ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
6966
6967 if (type == DEVLINK_PORT_TYPE_NOTSET) {
6968 devlink_port_type_warn_schedule(devlink_port);
6969 } else {
6970 devlink_port_type_warn_cancel(devlink_port);
6971 if (type == DEVLINK_PORT_TYPE_ETH && netdev)
6972 devlink_port_type_netdev_checks(devlink_port, netdev);
6973 }
6974
6975 spin_lock_bh(&devlink_port->type_lock);
6976 devlink_port->type = type;
6977 switch (type) {
6978 case DEVLINK_PORT_TYPE_ETH:
6979 devlink_port->type_eth.netdev = netdev;
6980 if (netdev) {
6981 ASSERT_RTNL();
6982 devlink_port->type_eth.ifindex = netdev->ifindex;
6983 BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
6984 sizeof(netdev->name));
6985 strcpy(devlink_port->type_eth.ifname, netdev->name);
6986 }
6987 break;
6988 case DEVLINK_PORT_TYPE_IB:
6989 devlink_port->type_ib.ibdev = type_dev;
6990 break;
6991 default:
6992 break;
6993 }
6994 spin_unlock_bh(&devlink_port->type_lock);
6995 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6996}
6997
6998/**
6999 * devlink_port_type_eth_set - Set port type to Ethernet
7000 *
7001 * @devlink_port: devlink port
7002 *
7003 * If driver is calling this, most likely it is doing something wrong.
7004 */
7005void devlink_port_type_eth_set(struct devlink_port *devlink_port)
7006{
7007 dev_warn(devlink_port->devlink->dev,
7008 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
7009 devlink_port->index);
7010 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
7011}
7012EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
7013
7014/**
7015 * devlink_port_type_ib_set - Set port type to InfiniBand
7016 *
7017 * @devlink_port: devlink port
7018 * @ibdev: related IB device
7019 */
7020void devlink_port_type_ib_set(struct devlink_port *devlink_port,
7021 struct ib_device *ibdev)
7022{
7023 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
7024}
7025EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
7026
7027/**
7028 * devlink_port_type_clear - Clear port type
7029 *
7030 * @devlink_port: devlink port
7031 *
7032 * If driver is calling this for clearing Ethernet type, most likely
7033 * it is doing something wrong.
7034 */
7035void devlink_port_type_clear(struct devlink_port *devlink_port)
7036{
7037 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
7038 dev_warn(devlink_port->devlink->dev,
7039 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
7040 devlink_port->index);
7041 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
7042}
7043EXPORT_SYMBOL_GPL(devlink_port_type_clear);
7044
7045int devlink_port_netdevice_event(struct notifier_block *nb,
7046 unsigned long event, void *ptr)
7047{
7048 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
7049 struct devlink_port *devlink_port = netdev->devlink_port;
7050 struct devlink *devlink;
7051
7052 if (!devlink_port)
7053 return NOTIFY_OK;
7054 devlink = devlink_port->devlink;
7055
7056 switch (event) {
7057 case NETDEV_POST_INIT:
7058 /* Set the type but not netdev pointer. It is going to be set
7059 * later on by NETDEV_REGISTER event. Happens once during
7060 * netdevice register
7061 */
7062 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
7063 NULL);
7064 break;
7065 case NETDEV_REGISTER:
7066 case NETDEV_CHANGENAME:
7067 if (devlink_net(devlink) != dev_net(netdev))
7068 return NOTIFY_OK;
7069 /* Set the netdev on top of previously set type. Note this
7070 * event happens also during net namespace change so here
7071 * we take into account netdev pointer appearing in this
7072 * namespace.
7073 */
7074 __devlink_port_type_set(devlink_port, devlink_port->type,
7075 netdev);
7076 break;
7077 case NETDEV_UNREGISTER:
7078 if (devlink_net(devlink) != dev_net(netdev))
7079 return NOTIFY_OK;
7080 /* Clear netdev pointer, but not the type. This event happens
7081 * also during net namespace change so we need to clear
7082 * pointer to netdev that is going to another net namespace.
7083 */
7084 __devlink_port_type_set(devlink_port, devlink_port->type,
7085 NULL);
7086 break;
7087 case NETDEV_PRE_UNINIT:
7088 /* Clear the type and the netdev pointer. Happens one during
7089 * netdevice unregister.
7090 */
7091 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
7092 NULL);
7093 break;
7094 }
7095
7096 return NOTIFY_OK;
7097}
7098
7099static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
7100 enum devlink_port_flavour flavour)
7101{
7102 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7103
7104 devlink_port->attrs_set = true;
7105 attrs->flavour = flavour;
7106 if (attrs->switch_id.id_len) {
7107 devlink_port->switch_port = true;
7108 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
7109 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
7110 } else {
7111 devlink_port->switch_port = false;
7112 }
7113 return 0;
7114}
7115
7116/**
7117 * devlink_port_attrs_set - Set port attributes
7118 *
7119 * @devlink_port: devlink port
7120 * @attrs: devlink port attrs
7121 */
7122void devlink_port_attrs_set(struct devlink_port *devlink_port,
7123 struct devlink_port_attrs *attrs)
7124{
7125 int ret;
7126
7127 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
7128
7129 devlink_port->attrs = *attrs;
7130 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
7131 if (ret)
7132 return;
7133 WARN_ON(attrs->splittable && attrs->split);
7134}
7135EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
7136
7137/**
7138 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
7139 *
7140 * @devlink_port: devlink port
7141 * @controller: associated controller number for the devlink port instance
7142 * @pf: associated PF for the devlink port instance
7143 * @external: indicates if the port is for an external controller
7144 */
7145void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
7146 u16 pf, bool external)
7147{
7148 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7149 int ret;
7150
7151 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
7152
7153 ret = __devlink_port_attrs_set(devlink_port,
7154 DEVLINK_PORT_FLAVOUR_PCI_PF);
7155 if (ret)
7156 return;
7157 attrs->pci_pf.controller = controller;
7158 attrs->pci_pf.pf = pf;
7159 attrs->pci_pf.external = external;
7160}
7161EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
7162
7163/**
7164 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
7165 *
7166 * @devlink_port: devlink port
7167 * @controller: associated controller number for the devlink port instance
7168 * @pf: associated PF for the devlink port instance
7169 * @vf: associated VF of a PF for the devlink port instance
7170 * @external: indicates if the port is for an external controller
7171 */
7172void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
7173 u16 pf, u16 vf, bool external)
7174{
7175 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7176 int ret;
7177
7178 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
7179
7180 ret = __devlink_port_attrs_set(devlink_port,
7181 DEVLINK_PORT_FLAVOUR_PCI_VF);
7182 if (ret)
7183 return;
7184 attrs->pci_vf.controller = controller;
7185 attrs->pci_vf.pf = pf;
7186 attrs->pci_vf.vf = vf;
7187 attrs->pci_vf.external = external;
7188}
7189EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
7190
7191/**
7192 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
7193 *
7194 * @devlink_port: devlink port
7195 * @controller: associated controller number for the devlink port instance
7196 * @pf: associated PF for the devlink port instance
7197 * @sf: associated SF of a PF for the devlink port instance
7198 * @external: indicates if the port is for an external controller
7199 */
7200void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
7201 u16 pf, u32 sf, bool external)
7202{
7203 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7204 int ret;
7205
7206 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
7207
7208 ret = __devlink_port_attrs_set(devlink_port,
7209 DEVLINK_PORT_FLAVOUR_PCI_SF);
7210 if (ret)
7211 return;
7212 attrs->pci_sf.controller = controller;
7213 attrs->pci_sf.pf = pf;
7214 attrs->pci_sf.sf = sf;
7215 attrs->pci_sf.external = external;
7216}
7217EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
7218
7219/**
7220 * devl_rate_node_create - create devlink rate node
7221 * @devlink: devlink instance
7222 * @priv: driver private data
7223 * @node_name: name of the resulting node
7224 * @parent: parent devlink_rate struct
7225 *
7226 * Create devlink rate object of type node
7227 */
7228struct devlink_rate *
7229devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
7230 struct devlink_rate *parent)
7231{
7232 struct devlink_rate *rate_node;
7233
7234 rate_node = devlink_rate_node_get_by_name(devlink, node_name);
7235 if (!IS_ERR(rate_node))
7236 return ERR_PTR(-EEXIST);
7237
7238 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
7239 if (!rate_node)
7240 return ERR_PTR(-ENOMEM);
7241
7242 if (parent) {
7243 rate_node->parent = parent;
7244 refcount_inc(&rate_node->parent->refcnt);
7245 }
7246
7247 rate_node->type = DEVLINK_RATE_TYPE_NODE;
7248 rate_node->devlink = devlink;
7249 rate_node->priv = priv;
7250
7251 rate_node->name = kstrdup(node_name, GFP_KERNEL);
7252 if (!rate_node->name) {
7253 kfree(rate_node);
7254 return ERR_PTR(-ENOMEM);
7255 }
7256
7257 refcount_set(&rate_node->refcnt, 1);
7258 list_add(&rate_node->list, &devlink->rate_list);
7259 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
7260 return rate_node;
7261}
7262EXPORT_SYMBOL_GPL(devl_rate_node_create);
7263
7264/**
7265 * devl_rate_leaf_create - create devlink rate leaf
7266 * @devlink_port: devlink port object to create rate object on
7267 * @priv: driver private data
7268 * @parent: parent devlink_rate struct
7269 *
7270 * Create devlink rate object of type leaf on provided @devlink_port.
7271 */
7272int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
7273 struct devlink_rate *parent)
7274{
7275 struct devlink *devlink = devlink_port->devlink;
7276 struct devlink_rate *devlink_rate;
7277
7278 devl_assert_locked(devlink_port->devlink);
7279
7280 if (WARN_ON(devlink_port->devlink_rate))
7281 return -EBUSY;
7282
7283 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
7284 if (!devlink_rate)
7285 return -ENOMEM;
7286
7287 if (parent) {
7288 devlink_rate->parent = parent;
7289 refcount_inc(&devlink_rate->parent->refcnt);
7290 }
7291
7292 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
7293 devlink_rate->devlink = devlink;
7294 devlink_rate->devlink_port = devlink_port;
7295 devlink_rate->priv = priv;
7296 list_add_tail(&devlink_rate->list, &devlink->rate_list);
7297 devlink_port->devlink_rate = devlink_rate;
7298 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
7299
7300 return 0;
7301}
7302EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
7303
7304/**
7305 * devl_rate_leaf_destroy - destroy devlink rate leaf
7306 *
7307 * @devlink_port: devlink port linked to the rate object
7308 *
7309 * Destroy the devlink rate object of type leaf on provided @devlink_port.
7310 */
7311void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
7312{
7313 struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
7314
7315 devl_assert_locked(devlink_port->devlink);
7316 if (!devlink_rate)
7317 return;
7318
7319 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
7320 if (devlink_rate->parent)
7321 refcount_dec(&devlink_rate->parent->refcnt);
7322 list_del(&devlink_rate->list);
7323 devlink_port->devlink_rate = NULL;
7324 kfree(devlink_rate);
7325}
7326EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
7327
7328/**
7329 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
7330 * @devlink: devlink instance
7331 *
7332 * Unset parent for all rate objects and destroy all rate nodes
7333 * on specified device.
7334 */
7335void devl_rate_nodes_destroy(struct devlink *devlink)
7336{
7337 static struct devlink_rate *devlink_rate, *tmp;
7338 const struct devlink_ops *ops = devlink->ops;
7339
7340 devl_assert_locked(devlink);
7341
7342 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
7343 if (!devlink_rate->parent)
7344 continue;
7345
7346 refcount_dec(&devlink_rate->parent->refcnt);
7347 if (devlink_rate_is_leaf(devlink_rate))
7348 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
7349 NULL, NULL);
7350 else if (devlink_rate_is_node(devlink_rate))
7351 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
7352 NULL, NULL);
7353 }
7354 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
7355 if (devlink_rate_is_node(devlink_rate)) {
7356 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
7357 list_del(&devlink_rate->list);
7358 kfree(devlink_rate->name);
7359 kfree(devlink_rate);
7360 }
7361 }
7362}
7363EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
7364
7365/**
7366 * devlink_port_linecard_set - Link port with a linecard
7367 *
7368 * @devlink_port: devlink port
7369 * @linecard: devlink linecard
7370 */
7371void devlink_port_linecard_set(struct devlink_port *devlink_port,
7372 struct devlink_linecard *linecard)
7373{
7374 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
7375
7376 devlink_port->linecard = linecard;
7377}
7378EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
7379
7380static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
7381 char *name, size_t len)
7382{
7383 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7384 int n = 0;
7385
7386 if (!devlink_port->attrs_set)
7387 return -EOPNOTSUPP;
7388
7389 switch (attrs->flavour) {
7390 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
7391 if (devlink_port->linecard)
7392 n = snprintf(name, len, "l%u",
7393 devlink_port->linecard->index);
7394 if (n < len)
7395 n += snprintf(name + n, len - n, "p%u",
7396 attrs->phys.port_number);
7397 if (n < len && attrs->split)
7398 n += snprintf(name + n, len - n, "s%u",
7399 attrs->phys.split_subport_number);
7400 break;
7401 case DEVLINK_PORT_FLAVOUR_CPU:
7402 case DEVLINK_PORT_FLAVOUR_DSA:
7403 case DEVLINK_PORT_FLAVOUR_UNUSED:
7404 /* As CPU and DSA ports do not have a netdevice associated
7405 * case should not ever happen.
7406 */
7407 WARN_ON(1);
7408 return -EINVAL;
7409 case DEVLINK_PORT_FLAVOUR_PCI_PF:
7410 if (attrs->pci_pf.external) {
7411 n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
7412 if (n >= len)
7413 return -EINVAL;
7414 len -= n;
7415 name += n;
7416 }
7417 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
7418 break;
7419 case DEVLINK_PORT_FLAVOUR_PCI_VF:
7420 if (attrs->pci_vf.external) {
7421 n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
7422 if (n >= len)
7423 return -EINVAL;
7424 len -= n;
7425 name += n;
7426 }
7427 n = snprintf(name, len, "pf%uvf%u",
7428 attrs->pci_vf.pf, attrs->pci_vf.vf);
7429 break;
7430 case DEVLINK_PORT_FLAVOUR_PCI_SF:
7431 if (attrs->pci_sf.external) {
7432 n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
7433 if (n >= len)
7434 return -EINVAL;
7435 len -= n;
7436 name += n;
7437 }
7438 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
7439 attrs->pci_sf.sf);
7440 break;
7441 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
7442 return -EOPNOTSUPP;
7443 }
7444
7445 if (n >= len)
7446 return -EINVAL;
7447
7448 return 0;
7449}
7450
7451static int devlink_linecard_types_init(struct devlink_linecard *linecard)
7452{
7453 struct devlink_linecard_type *linecard_type;
7454 unsigned int count;
7455 int i;
7456
7457 count = linecard->ops->types_count(linecard, linecard->priv);
7458 linecard->types = kmalloc_array(count, sizeof(*linecard_type),
7459 GFP_KERNEL);
7460 if (!linecard->types)
7461 return -ENOMEM;
7462 linecard->types_count = count;
7463
7464 for (i = 0; i < count; i++) {
7465 linecard_type = &linecard->types[i];
7466 linecard->ops->types_get(linecard, linecard->priv, i,
7467 &linecard_type->type,
7468 &linecard_type->priv);
7469 }
7470 return 0;
7471}
7472
7473static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
7474{
7475 kfree(linecard->types);
7476}
7477
7478/**
7479 * devl_linecard_create - Create devlink linecard
7480 *
7481 * @devlink: devlink
7482 * @linecard_index: driver-specific numerical identifier of the linecard
7483 * @ops: linecards ops
7484 * @priv: user priv pointer
7485 *
7486 * Create devlink linecard instance with provided linecard index.
7487 * Caller can use any indexing, even hw-related one.
7488 *
7489 * Return: Line card structure or an ERR_PTR() encoded error code.
7490 */
7491struct devlink_linecard *
7492devl_linecard_create(struct devlink *devlink, unsigned int linecard_index,
7493 const struct devlink_linecard_ops *ops, void *priv)
7494{
7495 struct devlink_linecard *linecard;
7496 int err;
7497
7498 if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
7499 !ops->types_count || !ops->types_get))
7500 return ERR_PTR(-EINVAL);
7501
7502 if (devlink_linecard_index_exists(devlink, linecard_index))
7503 return ERR_PTR(-EEXIST);
7504
7505 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
7506 if (!linecard)
7507 return ERR_PTR(-ENOMEM);
7508
7509 linecard->devlink = devlink;
7510 linecard->index = linecard_index;
7511 linecard->ops = ops;
7512 linecard->priv = priv;
7513 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
7514 mutex_init(&linecard->state_lock);
7515
7516 err = devlink_linecard_types_init(linecard);
7517 if (err) {
7518 mutex_destroy(&linecard->state_lock);
7519 kfree(linecard);
7520 return ERR_PTR(err);
7521 }
7522
7523 list_add_tail(&linecard->list, &devlink->linecard_list);
7524 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7525 return linecard;
7526}
7527EXPORT_SYMBOL_GPL(devl_linecard_create);
7528
7529/**
7530 * devl_linecard_destroy - Destroy devlink linecard
7531 *
7532 * @linecard: devlink linecard
7533 */
7534void devl_linecard_destroy(struct devlink_linecard *linecard)
7535{
7536 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
7537 list_del(&linecard->list);
7538 devlink_linecard_types_fini(linecard);
7539 mutex_destroy(&linecard->state_lock);
7540 kfree(linecard);
7541}
7542EXPORT_SYMBOL_GPL(devl_linecard_destroy);
7543
7544/**
7545 * devlink_linecard_provision_set - Set provisioning on linecard
7546 *
7547 * @linecard: devlink linecard
7548 * @type: linecard type
7549 *
7550 * This is either called directly from the provision() op call or
7551 * as a result of the provision() op call asynchronously.
7552 */
7553void devlink_linecard_provision_set(struct devlink_linecard *linecard,
7554 const char *type)
7555{
7556 mutex_lock(&linecard->state_lock);
7557 WARN_ON(linecard->type && strcmp(linecard->type, type));
7558 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
7559 linecard->type = type;
7560 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7561 mutex_unlock(&linecard->state_lock);
7562}
7563EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
7564
7565/**
7566 * devlink_linecard_provision_clear - Clear provisioning on linecard
7567 *
7568 * @linecard: devlink linecard
7569 *
7570 * This is either called directly from the unprovision() op call or
7571 * as a result of the unprovision() op call asynchronously.
7572 */
7573void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
7574{
7575 mutex_lock(&linecard->state_lock);
7576 WARN_ON(linecard->nested_devlink);
7577 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
7578 linecard->type = NULL;
7579 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7580 mutex_unlock(&linecard->state_lock);
7581}
7582EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
7583
7584/**
7585 * devlink_linecard_provision_fail - Fail provisioning on linecard
7586 *
7587 * @linecard: devlink linecard
7588 *
7589 * This is either called directly from the provision() op call or
7590 * as a result of the provision() op call asynchronously.
7591 */
7592void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
7593{
7594 mutex_lock(&linecard->state_lock);
7595 WARN_ON(linecard->nested_devlink);
7596 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
7597 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7598 mutex_unlock(&linecard->state_lock);
7599}
7600EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
7601
7602/**
7603 * devlink_linecard_activate - Set linecard active
7604 *
7605 * @linecard: devlink linecard
7606 */
7607void devlink_linecard_activate(struct devlink_linecard *linecard)
7608{
7609 mutex_lock(&linecard->state_lock);
7610 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
7611 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
7612 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7613 mutex_unlock(&linecard->state_lock);
7614}
7615EXPORT_SYMBOL_GPL(devlink_linecard_activate);
7616
7617/**
7618 * devlink_linecard_deactivate - Set linecard inactive
7619 *
7620 * @linecard: devlink linecard
7621 */
7622void devlink_linecard_deactivate(struct devlink_linecard *linecard)
7623{
7624 mutex_lock(&linecard->state_lock);
7625 switch (linecard->state) {
7626 case DEVLINK_LINECARD_STATE_ACTIVE:
7627 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
7628 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7629 break;
7630 case DEVLINK_LINECARD_STATE_UNPROVISIONING:
7631 /* Line card is being deactivated as part
7632 * of unprovisioning flow.
7633 */
7634 break;
7635 default:
7636 WARN_ON(1);
7637 break;
7638 }
7639 mutex_unlock(&linecard->state_lock);
7640}
7641EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
7642
7643/**
7644 * devlink_linecard_nested_dl_set - Attach/detach nested devlink
7645 * instance to linecard.
7646 *
7647 * @linecard: devlink linecard
7648 * @nested_devlink: devlink instance to attach or NULL to detach
7649 */
7650void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
7651 struct devlink *nested_devlink)
7652{
7653 mutex_lock(&linecard->state_lock);
7654 linecard->nested_devlink = nested_devlink;
7655 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
7656 mutex_unlock(&linecard->state_lock);
7657}
7658EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
7659
7660int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
7661 u32 size, u16 ingress_pools_count,
7662 u16 egress_pools_count, u16 ingress_tc_count,
7663 u16 egress_tc_count)
7664{
7665 struct devlink_sb *devlink_sb;
7666
7667 lockdep_assert_held(&devlink->lock);
7668
7669 if (devlink_sb_index_exists(devlink, sb_index))
7670 return -EEXIST;
7671
7672 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
7673 if (!devlink_sb)
7674 return -ENOMEM;
7675 devlink_sb->index = sb_index;
7676 devlink_sb->size = size;
7677 devlink_sb->ingress_pools_count = ingress_pools_count;
7678 devlink_sb->egress_pools_count = egress_pools_count;
7679 devlink_sb->ingress_tc_count = ingress_tc_count;
7680 devlink_sb->egress_tc_count = egress_tc_count;
7681 list_add_tail(&devlink_sb->list, &devlink->sb_list);
7682 return 0;
7683}
7684EXPORT_SYMBOL_GPL(devl_sb_register);
7685
7686int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
7687 u32 size, u16 ingress_pools_count,
7688 u16 egress_pools_count, u16 ingress_tc_count,
7689 u16 egress_tc_count)
7690{
7691 int err;
7692
7693 devl_lock(devlink);
7694 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
7695 egress_pools_count, ingress_tc_count,
7696 egress_tc_count);
7697 devl_unlock(devlink);
7698 return err;
7699}
7700EXPORT_SYMBOL_GPL(devlink_sb_register);
7701
7702void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
7703{
7704 struct devlink_sb *devlink_sb;
7705
7706 lockdep_assert_held(&devlink->lock);
7707
7708 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
7709 WARN_ON(!devlink_sb);
7710 list_del(&devlink_sb->list);
7711 kfree(devlink_sb);
7712}
7713EXPORT_SYMBOL_GPL(devl_sb_unregister);
7714
7715void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
7716{
7717 devl_lock(devlink);
7718 devl_sb_unregister(devlink, sb_index);
7719 devl_unlock(devlink);
7720}
7721EXPORT_SYMBOL_GPL(devlink_sb_unregister);
7722
7723/**
7724 * devl_dpipe_headers_register - register dpipe headers
7725 *
7726 * @devlink: devlink
7727 * @dpipe_headers: dpipe header array
7728 *
7729 * Register the headers supported by hardware.
7730 */
7731void devl_dpipe_headers_register(struct devlink *devlink,
7732 struct devlink_dpipe_headers *dpipe_headers)
7733{
7734 lockdep_assert_held(&devlink->lock);
7735
7736 devlink->dpipe_headers = dpipe_headers;
7737}
7738EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
7739
7740/**
7741 * devl_dpipe_headers_unregister - unregister dpipe headers
7742 *
7743 * @devlink: devlink
7744 *
7745 * Unregister the headers supported by hardware.
7746 */
7747void devl_dpipe_headers_unregister(struct devlink *devlink)
7748{
7749 lockdep_assert_held(&devlink->lock);
7750
7751 devlink->dpipe_headers = NULL;
7752}
7753EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
7754
7755/**
7756 * devlink_dpipe_table_counter_enabled - check if counter allocation
7757 * required
7758 * @devlink: devlink
7759 * @table_name: tables name
7760 *
7761 * Used by driver to check if counter allocation is required.
7762 * After counter allocation is turned on the table entries
7763 * are updated to include counter statistics.
7764 *
7765 * After that point on the driver must respect the counter
7766 * state so that each entry added to the table is added
7767 * with a counter.
7768 */
7769bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
7770 const char *table_name)
7771{
7772 struct devlink_dpipe_table *table;
7773 bool enabled;
7774
7775 rcu_read_lock();
7776 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
7777 table_name, devlink);
7778 enabled = false;
7779 if (table)
7780 enabled = table->counters_enabled;
7781 rcu_read_unlock();
7782 return enabled;
7783}
7784EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
7785
7786/**
7787 * devl_dpipe_table_register - register dpipe table
7788 *
7789 * @devlink: devlink
7790 * @table_name: table name
7791 * @table_ops: table ops
7792 * @priv: priv
7793 * @counter_control_extern: external control for counters
7794 */
7795int devl_dpipe_table_register(struct devlink *devlink,
7796 const char *table_name,
7797 struct devlink_dpipe_table_ops *table_ops,
7798 void *priv, bool counter_control_extern)
7799{
7800 struct devlink_dpipe_table *table;
7801
7802 lockdep_assert_held(&devlink->lock);
7803
7804 if (WARN_ON(!table_ops->size_get))
7805 return -EINVAL;
7806
7807 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
7808 devlink))
7809 return -EEXIST;
7810
7811 table = kzalloc(sizeof(*table), GFP_KERNEL);
7812 if (!table)
7813 return -ENOMEM;
7814
7815 table->name = table_name;
7816 table->table_ops = table_ops;
7817 table->priv = priv;
7818 table->counter_control_extern = counter_control_extern;
7819
7820 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
7821
7822 return 0;
7823}
7824EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
7825
7826/**
7827 * devl_dpipe_table_unregister - unregister dpipe table
7828 *
7829 * @devlink: devlink
7830 * @table_name: table name
7831 */
7832void devl_dpipe_table_unregister(struct devlink *devlink,
7833 const char *table_name)
7834{
7835 struct devlink_dpipe_table *table;
7836
7837 lockdep_assert_held(&devlink->lock);
7838
7839 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
7840 table_name, devlink);
7841 if (!table)
7842 return;
7843 list_del_rcu(&table->list);
7844 kfree_rcu(table, rcu);
7845}
7846EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
7847
7848/**
7849 * devl_resource_register - devlink resource register
7850 *
7851 * @devlink: devlink
7852 * @resource_name: resource's name
7853 * @resource_size: resource's size
7854 * @resource_id: resource's id
7855 * @parent_resource_id: resource's parent id
7856 * @size_params: size parameters
7857 *
7858 * Generic resources should reuse the same names across drivers.
7859 * Please see the generic resources list at:
7860 * Documentation/networking/devlink/devlink-resource.rst
7861 */
7862int devl_resource_register(struct devlink *devlink,
7863 const char *resource_name,
7864 u64 resource_size,
7865 u64 resource_id,
7866 u64 parent_resource_id,
7867 const struct devlink_resource_size_params *size_params)
7868{
7869 struct devlink_resource *resource;
7870 struct list_head *resource_list;
7871 bool top_hierarchy;
7872
7873 lockdep_assert_held(&devlink->lock);
7874
7875 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
7876
7877 resource = devlink_resource_find(devlink, NULL, resource_id);
7878 if (resource)
7879 return -EINVAL;
7880
7881 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
7882 if (!resource)
7883 return -ENOMEM;
7884
7885 if (top_hierarchy) {
7886 resource_list = &devlink->resource_list;
7887 } else {
7888 struct devlink_resource *parent_resource;
7889
7890 parent_resource = devlink_resource_find(devlink, NULL,
7891 parent_resource_id);
7892 if (parent_resource) {
7893 resource_list = &parent_resource->resource_list;
7894 resource->parent = parent_resource;
7895 } else {
7896 kfree(resource);
7897 return -EINVAL;
7898 }
7899 }
7900
7901 resource->name = resource_name;
7902 resource->size = resource_size;
7903 resource->size_new = resource_size;
7904 resource->id = resource_id;
7905 resource->size_valid = true;
7906 memcpy(&resource->size_params, size_params,
7907 sizeof(resource->size_params));
7908 INIT_LIST_HEAD(&resource->resource_list);
7909 list_add_tail(&resource->list, resource_list);
7910
7911 return 0;
7912}
7913EXPORT_SYMBOL_GPL(devl_resource_register);
7914
7915/**
7916 * devlink_resource_register - devlink resource register
7917 *
7918 * @devlink: devlink
7919 * @resource_name: resource's name
7920 * @resource_size: resource's size
7921 * @resource_id: resource's id
7922 * @parent_resource_id: resource's parent id
7923 * @size_params: size parameters
7924 *
7925 * Generic resources should reuse the same names across drivers.
7926 * Please see the generic resources list at:
7927 * Documentation/networking/devlink/devlink-resource.rst
7928 *
7929 * Context: Takes and release devlink->lock <mutex>.
7930 */
7931int devlink_resource_register(struct devlink *devlink,
7932 const char *resource_name,
7933 u64 resource_size,
7934 u64 resource_id,
7935 u64 parent_resource_id,
7936 const struct devlink_resource_size_params *size_params)
7937{
7938 int err;
7939
7940 devl_lock(devlink);
7941 err = devl_resource_register(devlink, resource_name, resource_size,
7942 resource_id, parent_resource_id, size_params);
7943 devl_unlock(devlink);
7944 return err;
7945}
7946EXPORT_SYMBOL_GPL(devlink_resource_register);
7947
7948static void devlink_resource_unregister(struct devlink *devlink,
7949 struct devlink_resource *resource)
7950{
7951 struct devlink_resource *tmp, *child_resource;
7952
7953 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
7954 list) {
7955 devlink_resource_unregister(devlink, child_resource);
7956 list_del(&child_resource->list);
7957 kfree(child_resource);
7958 }
7959}
7960
7961/**
7962 * devl_resources_unregister - free all resources
7963 *
7964 * @devlink: devlink
7965 */
7966void devl_resources_unregister(struct devlink *devlink)
7967{
7968 struct devlink_resource *tmp, *child_resource;
7969
7970 lockdep_assert_held(&devlink->lock);
7971
7972 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
7973 list) {
7974 devlink_resource_unregister(devlink, child_resource);
7975 list_del(&child_resource->list);
7976 kfree(child_resource);
7977 }
7978}
7979EXPORT_SYMBOL_GPL(devl_resources_unregister);
7980
7981/**
7982 * devlink_resources_unregister - free all resources
7983 *
7984 * @devlink: devlink
7985 *
7986 * Context: Takes and release devlink->lock <mutex>.
7987 */
7988void devlink_resources_unregister(struct devlink *devlink)
7989{
7990 devl_lock(devlink);
7991 devl_resources_unregister(devlink);
7992 devl_unlock(devlink);
7993}
7994EXPORT_SYMBOL_GPL(devlink_resources_unregister);
7995
7996/**
7997 * devl_resource_size_get - get and update size
7998 *
7999 * @devlink: devlink
8000 * @resource_id: the requested resource id
8001 * @p_resource_size: ptr to update
8002 */
8003int devl_resource_size_get(struct devlink *devlink,
8004 u64 resource_id,
8005 u64 *p_resource_size)
8006{
8007 struct devlink_resource *resource;
8008
8009 lockdep_assert_held(&devlink->lock);
8010
8011 resource = devlink_resource_find(devlink, NULL, resource_id);
8012 if (!resource)
8013 return -EINVAL;
8014 *p_resource_size = resource->size_new;
8015 resource->size = resource->size_new;
8016 return 0;
8017}
8018EXPORT_SYMBOL_GPL(devl_resource_size_get);
8019
8020/**
8021 * devl_dpipe_table_resource_set - set the resource id
8022 *
8023 * @devlink: devlink
8024 * @table_name: table name
8025 * @resource_id: resource id
8026 * @resource_units: number of resource's units consumed per table's entry
8027 */
8028int devl_dpipe_table_resource_set(struct devlink *devlink,
8029 const char *table_name, u64 resource_id,
8030 u64 resource_units)
8031{
8032 struct devlink_dpipe_table *table;
8033
8034 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
8035 table_name, devlink);
8036 if (!table)
8037 return -EINVAL;
8038
8039 table->resource_id = resource_id;
8040 table->resource_units = resource_units;
8041 table->resource_valid = true;
8042 return 0;
8043}
8044EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
8045
8046/**
8047 * devl_resource_occ_get_register - register occupancy getter
8048 *
8049 * @devlink: devlink
8050 * @resource_id: resource id
8051 * @occ_get: occupancy getter callback
8052 * @occ_get_priv: occupancy getter callback priv
8053 */
8054void devl_resource_occ_get_register(struct devlink *devlink,
8055 u64 resource_id,
8056 devlink_resource_occ_get_t *occ_get,
8057 void *occ_get_priv)
8058{
8059 struct devlink_resource *resource;
8060
8061 lockdep_assert_held(&devlink->lock);
8062
8063 resource = devlink_resource_find(devlink, NULL, resource_id);
8064 if (WARN_ON(!resource))
8065 return;
8066 WARN_ON(resource->occ_get);
8067
8068 resource->occ_get = occ_get;
8069 resource->occ_get_priv = occ_get_priv;
8070}
8071EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
8072
8073/**
8074 * devlink_resource_occ_get_register - register occupancy getter
8075 *
8076 * @devlink: devlink
8077 * @resource_id: resource id
8078 * @occ_get: occupancy getter callback
8079 * @occ_get_priv: occupancy getter callback priv
8080 *
8081 * Context: Takes and release devlink->lock <mutex>.
8082 */
8083void devlink_resource_occ_get_register(struct devlink *devlink,
8084 u64 resource_id,
8085 devlink_resource_occ_get_t *occ_get,
8086 void *occ_get_priv)
8087{
8088 devl_lock(devlink);
8089 devl_resource_occ_get_register(devlink, resource_id,
8090 occ_get, occ_get_priv);
8091 devl_unlock(devlink);
8092}
8093EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
8094
8095/**
8096 * devl_resource_occ_get_unregister - unregister occupancy getter
8097 *
8098 * @devlink: devlink
8099 * @resource_id: resource id
8100 */
8101void devl_resource_occ_get_unregister(struct devlink *devlink,
8102 u64 resource_id)
8103{
8104 struct devlink_resource *resource;
8105
8106 lockdep_assert_held(&devlink->lock);
8107
8108 resource = devlink_resource_find(devlink, NULL, resource_id);
8109 if (WARN_ON(!resource))
8110 return;
8111 WARN_ON(!resource->occ_get);
8112
8113 resource->occ_get = NULL;
8114 resource->occ_get_priv = NULL;
8115}
8116EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
8117
8118/**
8119 * devlink_resource_occ_get_unregister - unregister occupancy getter
8120 *
8121 * @devlink: devlink
8122 * @resource_id: resource id
8123 *
8124 * Context: Takes and release devlink->lock <mutex>.
8125 */
8126void devlink_resource_occ_get_unregister(struct devlink *devlink,
8127 u64 resource_id)
8128{
8129 devl_lock(devlink);
8130 devl_resource_occ_get_unregister(devlink, resource_id);
8131 devl_unlock(devlink);
8132}
8133EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
8134
8135static int devlink_param_verify(const struct devlink_param *param)
8136{
8137 if (!param || !param->name || !param->supported_cmodes)
8138 return -EINVAL;
8139 if (param->generic)
8140 return devlink_param_generic_verify(param);
8141 else
8142 return devlink_param_driver_verify(param);
8143}
8144
8145static int devlink_param_register(struct devlink *devlink,
8146 const struct devlink_param *param)
8147{
8148 struct devlink_param_item *param_item;
8149 int err;
8150
8151 WARN_ON(devlink_param_verify(param));
8152 WARN_ON(devlink_param_find_by_name(&devlink->params, param->name));
8153
8154 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
8155 WARN_ON(param->get || param->set);
8156 else
8157 WARN_ON(!param->get || !param->set);
8158
8159 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
8160 if (!param_item)
8161 return -ENOMEM;
8162
8163 param_item->param = param;
8164
8165 err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL);
8166 if (err)
8167 goto err_xa_insert;
8168
8169 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
8170 return 0;
8171
8172err_xa_insert:
8173 kfree(param_item);
8174 return err;
8175}
8176
8177static void devlink_param_unregister(struct devlink *devlink,
8178 const struct devlink_param *param)
8179{
8180 struct devlink_param_item *param_item;
8181
8182 param_item = devlink_param_find_by_id(&devlink->params, param->id);
8183 if (WARN_ON(!param_item))
8184 return;
8185 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
8186 xa_erase(&devlink->params, param->id);
8187 kfree(param_item);
8188}
8189
8190/**
8191 * devl_params_register - register configuration parameters
8192 *
8193 * @devlink: devlink
8194 * @params: configuration parameters array
8195 * @params_count: number of parameters provided
8196 *
8197 * Register the configuration parameters supported by the driver.
8198 */
8199int devl_params_register(struct devlink *devlink,
8200 const struct devlink_param *params,
8201 size_t params_count)
8202{
8203 const struct devlink_param *param = params;
8204 int i, err;
8205
8206 lockdep_assert_held(&devlink->lock);
8207
8208 for (i = 0; i < params_count; i++, param++) {
8209 err = devlink_param_register(devlink, param);
8210 if (err)
8211 goto rollback;
8212 }
8213 return 0;
8214
8215rollback:
8216 if (!i)
8217 return err;
8218
8219 for (param--; i > 0; i--, param--)
8220 devlink_param_unregister(devlink, param);
8221 return err;
8222}
8223EXPORT_SYMBOL_GPL(devl_params_register);
8224
8225int devlink_params_register(struct devlink *devlink,
8226 const struct devlink_param *params,
8227 size_t params_count)
8228{
8229 int err;
8230
8231 devl_lock(devlink);
8232 err = devl_params_register(devlink, params, params_count);
8233 devl_unlock(devlink);
8234 return err;
8235}
8236EXPORT_SYMBOL_GPL(devlink_params_register);
8237
8238/**
8239 * devl_params_unregister - unregister configuration parameters
8240 * @devlink: devlink
8241 * @params: configuration parameters to unregister
8242 * @params_count: number of parameters provided
8243 */
8244void devl_params_unregister(struct devlink *devlink,
8245 const struct devlink_param *params,
8246 size_t params_count)
8247{
8248 const struct devlink_param *param = params;
8249 int i;
8250
8251 lockdep_assert_held(&devlink->lock);
8252
8253 for (i = 0; i < params_count; i++, param++)
8254 devlink_param_unregister(devlink, param);
8255}
8256EXPORT_SYMBOL_GPL(devl_params_unregister);
8257
8258void devlink_params_unregister(struct devlink *devlink,
8259 const struct devlink_param *params,
8260 size_t params_count)
8261{
8262 devl_lock(devlink);
8263 devl_params_unregister(devlink, params, params_count);
8264 devl_unlock(devlink);
8265}
8266EXPORT_SYMBOL_GPL(devlink_params_unregister);
8267
8268/**
8269 * devl_param_driverinit_value_get - get configuration parameter
8270 * value for driver initializing
8271 *
8272 * @devlink: devlink
8273 * @param_id: parameter ID
8274 * @val: pointer to store the value of parameter in driverinit
8275 * configuration mode
8276 *
8277 * This function should be used by the driver to get driverinit
8278 * configuration for initialization after reload command.
8279 *
8280 * Note that lockless call of this function relies on the
8281 * driver to maintain following basic sane behavior:
8282 * 1) Driver ensures a call to this function cannot race with
8283 * registering/unregistering the parameter with the same parameter ID.
8284 * 2) Driver ensures a call to this function cannot race with
8285 * devl_param_driverinit_value_set() call with the same parameter ID.
8286 * 3) Driver ensures a call to this function cannot race with
8287 * reload operation.
8288 * If the driver is not able to comply, it has to take the devlink->lock
8289 * while calling this.
8290 */
8291int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
8292 union devlink_param_value *val)
8293{
8294 struct devlink_param_item *param_item;
8295
8296 if (WARN_ON(!devlink_reload_supported(devlink->ops)))
8297 return -EOPNOTSUPP;
8298
8299 param_item = devlink_param_find_by_id(&devlink->params, param_id);
8300 if (!param_item)
8301 return -EINVAL;
8302
8303 if (!param_item->driverinit_value_valid)
8304 return -EOPNOTSUPP;
8305
8306 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
8307 DEVLINK_PARAM_CMODE_DRIVERINIT)))
8308 return -EOPNOTSUPP;
8309
8310 *val = param_item->driverinit_value;
8311
8312 return 0;
8313}
8314EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get);
8315
8316/**
8317 * devl_param_driverinit_value_set - set value of configuration
8318 * parameter for driverinit
8319 * configuration mode
8320 *
8321 * @devlink: devlink
8322 * @param_id: parameter ID
8323 * @init_val: value of parameter to set for driverinit configuration mode
8324 *
8325 * This function should be used by the driver to set driverinit
8326 * configuration mode default value.
8327 */
8328void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
8329 union devlink_param_value init_val)
8330{
8331 struct devlink_param_item *param_item;
8332
8333 devl_assert_locked(devlink);
8334
8335 param_item = devlink_param_find_by_id(&devlink->params, param_id);
8336 if (WARN_ON(!param_item))
8337 return;
8338
8339 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
8340 DEVLINK_PARAM_CMODE_DRIVERINIT)))
8341 return;
8342
8343 param_item->driverinit_value = init_val;
8344 param_item->driverinit_value_valid = true;
8345
8346 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
8347}
8348EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set);
8349
8350void devlink_params_driverinit_load_new(struct devlink *devlink)
8351{
8352 struct devlink_param_item *param_item;
8353 unsigned long param_id;
8354
8355 xa_for_each(&devlink->params, param_id, param_item) {
8356 if (!devlink_param_cmode_is_supported(param_item->param,
8357 DEVLINK_PARAM_CMODE_DRIVERINIT) ||
8358 !param_item->driverinit_value_new_valid)
8359 continue;
8360 param_item->driverinit_value = param_item->driverinit_value_new;
8361 param_item->driverinit_value_valid = true;
8362 param_item->driverinit_value_new_valid = false;
8363 }
8364}
8365
8366/**
8367 * devl_param_value_changed - notify devlink on a parameter's value
8368 * change. Should be called by the driver
8369 * right after the change.
8370 *
8371 * @devlink: devlink
8372 * @param_id: parameter ID
8373 *
8374 * This function should be used by the driver to notify devlink on value
8375 * change, excluding driverinit configuration mode.
8376 * For driverinit configuration mode driver should use the function
8377 */
8378void devl_param_value_changed(struct devlink *devlink, u32 param_id)
8379{
8380 struct devlink_param_item *param_item;
8381
8382 param_item = devlink_param_find_by_id(&devlink->params, param_id);
8383 WARN_ON(!param_item);
8384
8385 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
8386}
8387EXPORT_SYMBOL_GPL(devl_param_value_changed);
8388
8389/**
8390 * devl_region_create - create a new address region
8391 *
8392 * @devlink: devlink
8393 * @ops: region operations and name
8394 * @region_max_snapshots: Maximum supported number of snapshots for region
8395 * @region_size: size of region
8396 */
8397struct devlink_region *devl_region_create(struct devlink *devlink,
8398 const struct devlink_region_ops *ops,
8399 u32 region_max_snapshots,
8400 u64 region_size)
8401{
8402 struct devlink_region *region;
8403
8404 devl_assert_locked(devlink);
8405
8406 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
8407 return ERR_PTR(-EINVAL);
8408
8409 if (devlink_region_get_by_name(devlink, ops->name))
8410 return ERR_PTR(-EEXIST);
8411
8412 region = kzalloc(sizeof(*region), GFP_KERNEL);
8413 if (!region)
8414 return ERR_PTR(-ENOMEM);
8415
8416 region->devlink = devlink;
8417 region->max_snapshots = region_max_snapshots;
8418 region->ops = ops;
8419 region->size = region_size;
8420 INIT_LIST_HEAD(®ion->snapshot_list);
8421 mutex_init(®ion->snapshot_lock);
8422 list_add_tail(®ion->list, &devlink->region_list);
8423 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
8424
8425 return region;
8426}
8427EXPORT_SYMBOL_GPL(devl_region_create);
8428
8429/**
8430 * devlink_region_create - create a new address region
8431 *
8432 * @devlink: devlink
8433 * @ops: region operations and name
8434 * @region_max_snapshots: Maximum supported number of snapshots for region
8435 * @region_size: size of region
8436 *
8437 * Context: Takes and release devlink->lock <mutex>.
8438 */
8439struct devlink_region *
8440devlink_region_create(struct devlink *devlink,
8441 const struct devlink_region_ops *ops,
8442 u32 region_max_snapshots, u64 region_size)
8443{
8444 struct devlink_region *region;
8445
8446 devl_lock(devlink);
8447 region = devl_region_create(devlink, ops, region_max_snapshots,
8448 region_size);
8449 devl_unlock(devlink);
8450 return region;
8451}
8452EXPORT_SYMBOL_GPL(devlink_region_create);
8453
8454/**
8455 * devlink_port_region_create - create a new address region for a port
8456 *
8457 * @port: devlink port
8458 * @ops: region operations and name
8459 * @region_max_snapshots: Maximum supported number of snapshots for region
8460 * @region_size: size of region
8461 *
8462 * Context: Takes and release devlink->lock <mutex>.
8463 */
8464struct devlink_region *
8465devlink_port_region_create(struct devlink_port *port,
8466 const struct devlink_port_region_ops *ops,
8467 u32 region_max_snapshots, u64 region_size)
8468{
8469 struct devlink *devlink = port->devlink;
8470 struct devlink_region *region;
8471 int err = 0;
8472
8473 ASSERT_DEVLINK_PORT_INITIALIZED(port);
8474
8475 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
8476 return ERR_PTR(-EINVAL);
8477
8478 devl_lock(devlink);
8479
8480 if (devlink_port_region_get_by_name(port, ops->name)) {
8481 err = -EEXIST;
8482 goto unlock;
8483 }
8484
8485 region = kzalloc(sizeof(*region), GFP_KERNEL);
8486 if (!region) {
8487 err = -ENOMEM;
8488 goto unlock;
8489 }
8490
8491 region->devlink = devlink;
8492 region->port = port;
8493 region->max_snapshots = region_max_snapshots;
8494 region->port_ops = ops;
8495 region->size = region_size;
8496 INIT_LIST_HEAD(®ion->snapshot_list);
8497 mutex_init(®ion->snapshot_lock);
8498 list_add_tail(®ion->list, &port->region_list);
8499 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
8500
8501 devl_unlock(devlink);
8502 return region;
8503
8504unlock:
8505 devl_unlock(devlink);
8506 return ERR_PTR(err);
8507}
8508EXPORT_SYMBOL_GPL(devlink_port_region_create);
8509
8510/**
8511 * devl_region_destroy - destroy address region
8512 *
8513 * @region: devlink region to destroy
8514 */
8515void devl_region_destroy(struct devlink_region *region)
8516{
8517 struct devlink *devlink = region->devlink;
8518 struct devlink_snapshot *snapshot, *ts;
8519
8520 devl_assert_locked(devlink);
8521
8522 /* Free all snapshots of region */
8523 mutex_lock(®ion->snapshot_lock);
8524 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
8525 devlink_region_snapshot_del(region, snapshot);
8526 mutex_unlock(®ion->snapshot_lock);
8527
8528 list_del(®ion->list);
8529 mutex_destroy(®ion->snapshot_lock);
8530
8531 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
8532 kfree(region);
8533}
8534EXPORT_SYMBOL_GPL(devl_region_destroy);
8535
8536/**
8537 * devlink_region_destroy - destroy address region
8538 *
8539 * @region: devlink region to destroy
8540 *
8541 * Context: Takes and release devlink->lock <mutex>.
8542 */
8543void devlink_region_destroy(struct devlink_region *region)
8544{
8545 struct devlink *devlink = region->devlink;
8546
8547 devl_lock(devlink);
8548 devl_region_destroy(region);
8549 devl_unlock(devlink);
8550}
8551EXPORT_SYMBOL_GPL(devlink_region_destroy);
8552
8553/**
8554 * devlink_region_snapshot_id_get - get snapshot ID
8555 *
8556 * This callback should be called when adding a new snapshot,
8557 * Driver should use the same id for multiple snapshots taken
8558 * on multiple regions at the same time/by the same trigger.
8559 *
8560 * The caller of this function must use devlink_region_snapshot_id_put
8561 * when finished creating regions using this id.
8562 *
8563 * Returns zero on success, or a negative error code on failure.
8564 *
8565 * @devlink: devlink
8566 * @id: storage to return id
8567 */
8568int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
8569{
8570 return __devlink_region_snapshot_id_get(devlink, id);
8571}
8572EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
8573
8574/**
8575 * devlink_region_snapshot_id_put - put snapshot ID reference
8576 *
8577 * This should be called by a driver after finishing creating snapshots
8578 * with an id. Doing so ensures that the ID can later be released in the
8579 * event that all snapshots using it have been destroyed.
8580 *
8581 * @devlink: devlink
8582 * @id: id to release reference on
8583 */
8584void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
8585{
8586 __devlink_snapshot_id_decrement(devlink, id);
8587}
8588EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
8589
8590/**
8591 * devlink_region_snapshot_create - create a new snapshot
8592 * This will add a new snapshot of a region. The snapshot
8593 * will be stored on the region struct and can be accessed
8594 * from devlink. This is useful for future analyses of snapshots.
8595 * Multiple snapshots can be created on a region.
8596 * The @snapshot_id should be obtained using the getter function.
8597 *
8598 * @region: devlink region of the snapshot
8599 * @data: snapshot data
8600 * @snapshot_id: snapshot id to be created
8601 */
8602int devlink_region_snapshot_create(struct devlink_region *region,
8603 u8 *data, u32 snapshot_id)
8604{
8605 int err;
8606
8607 mutex_lock(®ion->snapshot_lock);
8608 err = __devlink_region_snapshot_create(region, data, snapshot_id);
8609 mutex_unlock(®ion->snapshot_lock);
8610 return err;
8611}
8612EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
8613
8614#define DEVLINK_TRAP(_id, _type) \
8615 { \
8616 .type = DEVLINK_TRAP_TYPE_##_type, \
8617 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
8618 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
8619 }
8620
8621static const struct devlink_trap devlink_trap_generic[] = {
8622 DEVLINK_TRAP(SMAC_MC, DROP),
8623 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
8624 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
8625 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
8626 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
8627 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
8628 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
8629 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
8630 DEVLINK_TRAP(TAIL_DROP, DROP),
8631 DEVLINK_TRAP(NON_IP_PACKET, DROP),
8632 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
8633 DEVLINK_TRAP(DIP_LB, DROP),
8634 DEVLINK_TRAP(SIP_MC, DROP),
8635 DEVLINK_TRAP(SIP_LB, DROP),
8636 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
8637 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
8638 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
8639 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
8640 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
8641 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
8642 DEVLINK_TRAP(RPF, EXCEPTION),
8643 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
8644 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
8645 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
8646 DEVLINK_TRAP(NON_ROUTABLE, DROP),
8647 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
8648 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
8649 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
8650 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
8651 DEVLINK_TRAP(STP, CONTROL),
8652 DEVLINK_TRAP(LACP, CONTROL),
8653 DEVLINK_TRAP(LLDP, CONTROL),
8654 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
8655 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
8656 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
8657 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
8658 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
8659 DEVLINK_TRAP(MLD_QUERY, CONTROL),
8660 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
8661 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
8662 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
8663 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
8664 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
8665 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
8666 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
8667 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
8668 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
8669 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
8670 DEVLINK_TRAP(IPV4_BFD, CONTROL),
8671 DEVLINK_TRAP(IPV6_BFD, CONTROL),
8672 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
8673 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
8674 DEVLINK_TRAP(IPV4_BGP, CONTROL),
8675 DEVLINK_TRAP(IPV6_BGP, CONTROL),
8676 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
8677 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
8678 DEVLINK_TRAP(IPV4_PIM, CONTROL),
8679 DEVLINK_TRAP(IPV6_PIM, CONTROL),
8680 DEVLINK_TRAP(UC_LB, CONTROL),
8681 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
8682 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
8683 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
8684 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
8685 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
8686 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
8687 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
8688 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
8689 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
8690 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
8691 DEVLINK_TRAP(PTP_EVENT, CONTROL),
8692 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
8693 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
8694 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
8695 DEVLINK_TRAP(EARLY_DROP, DROP),
8696 DEVLINK_TRAP(VXLAN_PARSING, DROP),
8697 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
8698 DEVLINK_TRAP(VLAN_PARSING, DROP),
8699 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
8700 DEVLINK_TRAP(MPLS_PARSING, DROP),
8701 DEVLINK_TRAP(ARP_PARSING, DROP),
8702 DEVLINK_TRAP(IP_1_PARSING, DROP),
8703 DEVLINK_TRAP(IP_N_PARSING, DROP),
8704 DEVLINK_TRAP(GRE_PARSING, DROP),
8705 DEVLINK_TRAP(UDP_PARSING, DROP),
8706 DEVLINK_TRAP(TCP_PARSING, DROP),
8707 DEVLINK_TRAP(IPSEC_PARSING, DROP),
8708 DEVLINK_TRAP(SCTP_PARSING, DROP),
8709 DEVLINK_TRAP(DCCP_PARSING, DROP),
8710 DEVLINK_TRAP(GTP_PARSING, DROP),
8711 DEVLINK_TRAP(ESP_PARSING, DROP),
8712 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
8713 DEVLINK_TRAP(DMAC_FILTER, DROP),
8714 DEVLINK_TRAP(EAPOL, CONTROL),
8715 DEVLINK_TRAP(LOCKED_PORT, DROP),
8716};
8717
8718#define DEVLINK_TRAP_GROUP(_id) \
8719 { \
8720 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
8721 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
8722 }
8723
8724static const struct devlink_trap_group devlink_trap_group_generic[] = {
8725 DEVLINK_TRAP_GROUP(L2_DROPS),
8726 DEVLINK_TRAP_GROUP(L3_DROPS),
8727 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
8728 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
8729 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
8730 DEVLINK_TRAP_GROUP(ACL_DROPS),
8731 DEVLINK_TRAP_GROUP(STP),
8732 DEVLINK_TRAP_GROUP(LACP),
8733 DEVLINK_TRAP_GROUP(LLDP),
8734 DEVLINK_TRAP_GROUP(MC_SNOOPING),
8735 DEVLINK_TRAP_GROUP(DHCP),
8736 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
8737 DEVLINK_TRAP_GROUP(BFD),
8738 DEVLINK_TRAP_GROUP(OSPF),
8739 DEVLINK_TRAP_GROUP(BGP),
8740 DEVLINK_TRAP_GROUP(VRRP),
8741 DEVLINK_TRAP_GROUP(PIM),
8742 DEVLINK_TRAP_GROUP(UC_LB),
8743 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
8744 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
8745 DEVLINK_TRAP_GROUP(IPV6),
8746 DEVLINK_TRAP_GROUP(PTP_EVENT),
8747 DEVLINK_TRAP_GROUP(PTP_GENERAL),
8748 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
8749 DEVLINK_TRAP_GROUP(ACL_TRAP),
8750 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
8751 DEVLINK_TRAP_GROUP(EAPOL),
8752};
8753
8754static int devlink_trap_generic_verify(const struct devlink_trap *trap)
8755{
8756 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
8757 return -EINVAL;
8758
8759 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
8760 return -EINVAL;
8761
8762 if (trap->type != devlink_trap_generic[trap->id].type)
8763 return -EINVAL;
8764
8765 return 0;
8766}
8767
8768static int devlink_trap_driver_verify(const struct devlink_trap *trap)
8769{
8770 int i;
8771
8772 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
8773 return -EINVAL;
8774
8775 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
8776 if (!strcmp(trap->name, devlink_trap_generic[i].name))
8777 return -EEXIST;
8778 }
8779
8780 return 0;
8781}
8782
8783static int devlink_trap_verify(const struct devlink_trap *trap)
8784{
8785 if (!trap || !trap->name)
8786 return -EINVAL;
8787
8788 if (trap->generic)
8789 return devlink_trap_generic_verify(trap);
8790 else
8791 return devlink_trap_driver_verify(trap);
8792}
8793
8794static int
8795devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
8796{
8797 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
8798 return -EINVAL;
8799
8800 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
8801 return -EINVAL;
8802
8803 return 0;
8804}
8805
8806static int
8807devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
8808{
8809 int i;
8810
8811 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
8812 return -EINVAL;
8813
8814 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
8815 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
8816 return -EEXIST;
8817 }
8818
8819 return 0;
8820}
8821
8822static int devlink_trap_group_verify(const struct devlink_trap_group *group)
8823{
8824 if (group->generic)
8825 return devlink_trap_group_generic_verify(group);
8826 else
8827 return devlink_trap_group_driver_verify(group);
8828}
8829
8830static void
8831devlink_trap_group_notify(struct devlink *devlink,
8832 const struct devlink_trap_group_item *group_item,
8833 enum devlink_command cmd)
8834{
8835 struct sk_buff *msg;
8836 int err;
8837
8838 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
8839 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
8840 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
8841 return;
8842
8843 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8844 if (!msg)
8845 return;
8846
8847 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
8848 0);
8849 if (err) {
8850 nlmsg_free(msg);
8851 return;
8852 }
8853
8854 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
8855 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
8856}
8857
8858static int
8859devlink_trap_item_group_link(struct devlink *devlink,
8860 struct devlink_trap_item *trap_item)
8861{
8862 u16 group_id = trap_item->trap->init_group_id;
8863 struct devlink_trap_group_item *group_item;
8864
8865 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
8866 if (WARN_ON_ONCE(!group_item))
8867 return -EINVAL;
8868
8869 trap_item->group_item = group_item;
8870
8871 return 0;
8872}
8873
8874static void devlink_trap_notify(struct devlink *devlink,
8875 const struct devlink_trap_item *trap_item,
8876 enum devlink_command cmd)
8877{
8878 struct sk_buff *msg;
8879 int err;
8880
8881 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
8882 cmd != DEVLINK_CMD_TRAP_DEL);
8883 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
8884 return;
8885
8886 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8887 if (!msg)
8888 return;
8889
8890 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
8891 if (err) {
8892 nlmsg_free(msg);
8893 return;
8894 }
8895
8896 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
8897 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
8898}
8899
8900static int
8901devlink_trap_register(struct devlink *devlink,
8902 const struct devlink_trap *trap, void *priv)
8903{
8904 struct devlink_trap_item *trap_item;
8905 int err;
8906
8907 if (devlink_trap_item_lookup(devlink, trap->name))
8908 return -EEXIST;
8909
8910 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
8911 if (!trap_item)
8912 return -ENOMEM;
8913
8914 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
8915 if (!trap_item->stats) {
8916 err = -ENOMEM;
8917 goto err_stats_alloc;
8918 }
8919
8920 trap_item->trap = trap;
8921 trap_item->action = trap->init_action;
8922 trap_item->priv = priv;
8923
8924 err = devlink_trap_item_group_link(devlink, trap_item);
8925 if (err)
8926 goto err_group_link;
8927
8928 err = devlink->ops->trap_init(devlink, trap, trap_item);
8929 if (err)
8930 goto err_trap_init;
8931
8932 list_add_tail(&trap_item->list, &devlink->trap_list);
8933 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
8934
8935 return 0;
8936
8937err_trap_init:
8938err_group_link:
8939 free_percpu(trap_item->stats);
8940err_stats_alloc:
8941 kfree(trap_item);
8942 return err;
8943}
8944
8945static void devlink_trap_unregister(struct devlink *devlink,
8946 const struct devlink_trap *trap)
8947{
8948 struct devlink_trap_item *trap_item;
8949
8950 trap_item = devlink_trap_item_lookup(devlink, trap->name);
8951 if (WARN_ON_ONCE(!trap_item))
8952 return;
8953
8954 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
8955 list_del(&trap_item->list);
8956 if (devlink->ops->trap_fini)
8957 devlink->ops->trap_fini(devlink, trap, trap_item);
8958 free_percpu(trap_item->stats);
8959 kfree(trap_item);
8960}
8961
8962static void devlink_trap_disable(struct devlink *devlink,
8963 const struct devlink_trap *trap)
8964{
8965 struct devlink_trap_item *trap_item;
8966
8967 trap_item = devlink_trap_item_lookup(devlink, trap->name);
8968 if (WARN_ON_ONCE(!trap_item))
8969 return;
8970
8971 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
8972 NULL);
8973 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
8974}
8975
8976/**
8977 * devl_traps_register - Register packet traps with devlink.
8978 * @devlink: devlink.
8979 * @traps: Packet traps.
8980 * @traps_count: Count of provided packet traps.
8981 * @priv: Driver private information.
8982 *
8983 * Return: Non-zero value on failure.
8984 */
8985int devl_traps_register(struct devlink *devlink,
8986 const struct devlink_trap *traps,
8987 size_t traps_count, void *priv)
8988{
8989 int i, err;
8990
8991 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
8992 return -EINVAL;
8993
8994 devl_assert_locked(devlink);
8995 for (i = 0; i < traps_count; i++) {
8996 const struct devlink_trap *trap = &traps[i];
8997
8998 err = devlink_trap_verify(trap);
8999 if (err)
9000 goto err_trap_verify;
9001
9002 err = devlink_trap_register(devlink, trap, priv);
9003 if (err)
9004 goto err_trap_register;
9005 }
9006
9007 return 0;
9008
9009err_trap_register:
9010err_trap_verify:
9011 for (i--; i >= 0; i--)
9012 devlink_trap_unregister(devlink, &traps[i]);
9013 return err;
9014}
9015EXPORT_SYMBOL_GPL(devl_traps_register);
9016
9017/**
9018 * devlink_traps_register - Register packet traps with devlink.
9019 * @devlink: devlink.
9020 * @traps: Packet traps.
9021 * @traps_count: Count of provided packet traps.
9022 * @priv: Driver private information.
9023 *
9024 * Context: Takes and release devlink->lock <mutex>.
9025 *
9026 * Return: Non-zero value on failure.
9027 */
9028int devlink_traps_register(struct devlink *devlink,
9029 const struct devlink_trap *traps,
9030 size_t traps_count, void *priv)
9031{
9032 int err;
9033
9034 devl_lock(devlink);
9035 err = devl_traps_register(devlink, traps, traps_count, priv);
9036 devl_unlock(devlink);
9037 return err;
9038}
9039EXPORT_SYMBOL_GPL(devlink_traps_register);
9040
9041/**
9042 * devl_traps_unregister - Unregister packet traps from devlink.
9043 * @devlink: devlink.
9044 * @traps: Packet traps.
9045 * @traps_count: Count of provided packet traps.
9046 */
9047void devl_traps_unregister(struct devlink *devlink,
9048 const struct devlink_trap *traps,
9049 size_t traps_count)
9050{
9051 int i;
9052
9053 devl_assert_locked(devlink);
9054 /* Make sure we do not have any packets in-flight while unregistering
9055 * traps by disabling all of them and waiting for a grace period.
9056 */
9057 for (i = traps_count - 1; i >= 0; i--)
9058 devlink_trap_disable(devlink, &traps[i]);
9059 synchronize_rcu();
9060 for (i = traps_count - 1; i >= 0; i--)
9061 devlink_trap_unregister(devlink, &traps[i]);
9062}
9063EXPORT_SYMBOL_GPL(devl_traps_unregister);
9064
9065/**
9066 * devlink_traps_unregister - Unregister packet traps from devlink.
9067 * @devlink: devlink.
9068 * @traps: Packet traps.
9069 * @traps_count: Count of provided packet traps.
9070 *
9071 * Context: Takes and release devlink->lock <mutex>.
9072 */
9073void devlink_traps_unregister(struct devlink *devlink,
9074 const struct devlink_trap *traps,
9075 size_t traps_count)
9076{
9077 devl_lock(devlink);
9078 devl_traps_unregister(devlink, traps, traps_count);
9079 devl_unlock(devlink);
9080}
9081EXPORT_SYMBOL_GPL(devlink_traps_unregister);
9082
9083static void
9084devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
9085 size_t skb_len)
9086{
9087 struct devlink_stats *stats;
9088
9089 stats = this_cpu_ptr(trap_stats);
9090 u64_stats_update_begin(&stats->syncp);
9091 u64_stats_add(&stats->rx_bytes, skb_len);
9092 u64_stats_inc(&stats->rx_packets);
9093 u64_stats_update_end(&stats->syncp);
9094}
9095
9096static void
9097devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
9098 const struct devlink_trap_item *trap_item,
9099 struct devlink_port *in_devlink_port,
9100 const struct flow_action_cookie *fa_cookie)
9101{
9102 metadata->trap_name = trap_item->trap->name;
9103 metadata->trap_group_name = trap_item->group_item->group->name;
9104 metadata->fa_cookie = fa_cookie;
9105 metadata->trap_type = trap_item->trap->type;
9106
9107 spin_lock(&in_devlink_port->type_lock);
9108 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9109 metadata->input_dev = in_devlink_port->type_eth.netdev;
9110 spin_unlock(&in_devlink_port->type_lock);
9111}
9112
9113/**
9114 * devlink_trap_report - Report trapped packet to drop monitor.
9115 * @devlink: devlink.
9116 * @skb: Trapped packet.
9117 * @trap_ctx: Trap context.
9118 * @in_devlink_port: Input devlink port.
9119 * @fa_cookie: Flow action cookie. Could be NULL.
9120 */
9121void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
9122 void *trap_ctx, struct devlink_port *in_devlink_port,
9123 const struct flow_action_cookie *fa_cookie)
9124
9125{
9126 struct devlink_trap_item *trap_item = trap_ctx;
9127
9128 devlink_trap_stats_update(trap_item->stats, skb->len);
9129 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
9130
9131 if (trace_devlink_trap_report_enabled()) {
9132 struct devlink_trap_metadata metadata = {};
9133
9134 devlink_trap_report_metadata_set(&metadata, trap_item,
9135 in_devlink_port, fa_cookie);
9136 trace_devlink_trap_report(devlink, skb, &metadata);
9137 }
9138}
9139EXPORT_SYMBOL_GPL(devlink_trap_report);
9140
9141/**
9142 * devlink_trap_ctx_priv - Trap context to driver private information.
9143 * @trap_ctx: Trap context.
9144 *
9145 * Return: Driver private information passed during registration.
9146 */
9147void *devlink_trap_ctx_priv(void *trap_ctx)
9148{
9149 struct devlink_trap_item *trap_item = trap_ctx;
9150
9151 return trap_item->priv;
9152}
9153EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
9154
9155static int
9156devlink_trap_group_item_policer_link(struct devlink *devlink,
9157 struct devlink_trap_group_item *group_item)
9158{
9159 u32 policer_id = group_item->group->init_policer_id;
9160 struct devlink_trap_policer_item *policer_item;
9161
9162 if (policer_id == 0)
9163 return 0;
9164
9165 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
9166 if (WARN_ON_ONCE(!policer_item))
9167 return -EINVAL;
9168
9169 group_item->policer_item = policer_item;
9170
9171 return 0;
9172}
9173
9174static int
9175devlink_trap_group_register(struct devlink *devlink,
9176 const struct devlink_trap_group *group)
9177{
9178 struct devlink_trap_group_item *group_item;
9179 int err;
9180
9181 if (devlink_trap_group_item_lookup(devlink, group->name))
9182 return -EEXIST;
9183
9184 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
9185 if (!group_item)
9186 return -ENOMEM;
9187
9188 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
9189 if (!group_item->stats) {
9190 err = -ENOMEM;
9191 goto err_stats_alloc;
9192 }
9193
9194 group_item->group = group;
9195
9196 err = devlink_trap_group_item_policer_link(devlink, group_item);
9197 if (err)
9198 goto err_policer_link;
9199
9200 if (devlink->ops->trap_group_init) {
9201 err = devlink->ops->trap_group_init(devlink, group);
9202 if (err)
9203 goto err_group_init;
9204 }
9205
9206 list_add_tail(&group_item->list, &devlink->trap_group_list);
9207 devlink_trap_group_notify(devlink, group_item,
9208 DEVLINK_CMD_TRAP_GROUP_NEW);
9209
9210 return 0;
9211
9212err_group_init:
9213err_policer_link:
9214 free_percpu(group_item->stats);
9215err_stats_alloc:
9216 kfree(group_item);
9217 return err;
9218}
9219
9220static void
9221devlink_trap_group_unregister(struct devlink *devlink,
9222 const struct devlink_trap_group *group)
9223{
9224 struct devlink_trap_group_item *group_item;
9225
9226 group_item = devlink_trap_group_item_lookup(devlink, group->name);
9227 if (WARN_ON_ONCE(!group_item))
9228 return;
9229
9230 devlink_trap_group_notify(devlink, group_item,
9231 DEVLINK_CMD_TRAP_GROUP_DEL);
9232 list_del(&group_item->list);
9233 free_percpu(group_item->stats);
9234 kfree(group_item);
9235}
9236
9237/**
9238 * devl_trap_groups_register - Register packet trap groups with devlink.
9239 * @devlink: devlink.
9240 * @groups: Packet trap groups.
9241 * @groups_count: Count of provided packet trap groups.
9242 *
9243 * Return: Non-zero value on failure.
9244 */
9245int devl_trap_groups_register(struct devlink *devlink,
9246 const struct devlink_trap_group *groups,
9247 size_t groups_count)
9248{
9249 int i, err;
9250
9251 devl_assert_locked(devlink);
9252 for (i = 0; i < groups_count; i++) {
9253 const struct devlink_trap_group *group = &groups[i];
9254
9255 err = devlink_trap_group_verify(group);
9256 if (err)
9257 goto err_trap_group_verify;
9258
9259 err = devlink_trap_group_register(devlink, group);
9260 if (err)
9261 goto err_trap_group_register;
9262 }
9263
9264 return 0;
9265
9266err_trap_group_register:
9267err_trap_group_verify:
9268 for (i--; i >= 0; i--)
9269 devlink_trap_group_unregister(devlink, &groups[i]);
9270 return err;
9271}
9272EXPORT_SYMBOL_GPL(devl_trap_groups_register);
9273
9274/**
9275 * devlink_trap_groups_register - Register packet trap groups with devlink.
9276 * @devlink: devlink.
9277 * @groups: Packet trap groups.
9278 * @groups_count: Count of provided packet trap groups.
9279 *
9280 * Context: Takes and release devlink->lock <mutex>.
9281 *
9282 * Return: Non-zero value on failure.
9283 */
9284int devlink_trap_groups_register(struct devlink *devlink,
9285 const struct devlink_trap_group *groups,
9286 size_t groups_count)
9287{
9288 int err;
9289
9290 devl_lock(devlink);
9291 err = devl_trap_groups_register(devlink, groups, groups_count);
9292 devl_unlock(devlink);
9293 return err;
9294}
9295EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
9296
9297/**
9298 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
9299 * @devlink: devlink.
9300 * @groups: Packet trap groups.
9301 * @groups_count: Count of provided packet trap groups.
9302 */
9303void devl_trap_groups_unregister(struct devlink *devlink,
9304 const struct devlink_trap_group *groups,
9305 size_t groups_count)
9306{
9307 int i;
9308
9309 devl_assert_locked(devlink);
9310 for (i = groups_count - 1; i >= 0; i--)
9311 devlink_trap_group_unregister(devlink, &groups[i]);
9312}
9313EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
9314
9315/**
9316 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9317 * @devlink: devlink.
9318 * @groups: Packet trap groups.
9319 * @groups_count: Count of provided packet trap groups.
9320 *
9321 * Context: Takes and release devlink->lock <mutex>.
9322 */
9323void devlink_trap_groups_unregister(struct devlink *devlink,
9324 const struct devlink_trap_group *groups,
9325 size_t groups_count)
9326{
9327 devl_lock(devlink);
9328 devl_trap_groups_unregister(devlink, groups, groups_count);
9329 devl_unlock(devlink);
9330}
9331EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
9332
9333static void
9334devlink_trap_policer_notify(struct devlink *devlink,
9335 const struct devlink_trap_policer_item *policer_item,
9336 enum devlink_command cmd)
9337{
9338 struct sk_buff *msg;
9339 int err;
9340
9341 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
9342 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
9343 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
9344 return;
9345
9346 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9347 if (!msg)
9348 return;
9349
9350 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
9351 0, 0);
9352 if (err) {
9353 nlmsg_free(msg);
9354 return;
9355 }
9356
9357 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
9358 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
9359}
9360
9361static int
9362devlink_trap_policer_register(struct devlink *devlink,
9363 const struct devlink_trap_policer *policer)
9364{
9365 struct devlink_trap_policer_item *policer_item;
9366 int err;
9367
9368 if (devlink_trap_policer_item_lookup(devlink, policer->id))
9369 return -EEXIST;
9370
9371 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
9372 if (!policer_item)
9373 return -ENOMEM;
9374
9375 policer_item->policer = policer;
9376 policer_item->rate = policer->init_rate;
9377 policer_item->burst = policer->init_burst;
9378
9379 if (devlink->ops->trap_policer_init) {
9380 err = devlink->ops->trap_policer_init(devlink, policer);
9381 if (err)
9382 goto err_policer_init;
9383 }
9384
9385 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
9386 devlink_trap_policer_notify(devlink, policer_item,
9387 DEVLINK_CMD_TRAP_POLICER_NEW);
9388
9389 return 0;
9390
9391err_policer_init:
9392 kfree(policer_item);
9393 return err;
9394}
9395
9396static void
9397devlink_trap_policer_unregister(struct devlink *devlink,
9398 const struct devlink_trap_policer *policer)
9399{
9400 struct devlink_trap_policer_item *policer_item;
9401
9402 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
9403 if (WARN_ON_ONCE(!policer_item))
9404 return;
9405
9406 devlink_trap_policer_notify(devlink, policer_item,
9407 DEVLINK_CMD_TRAP_POLICER_DEL);
9408 list_del(&policer_item->list);
9409 if (devlink->ops->trap_policer_fini)
9410 devlink->ops->trap_policer_fini(devlink, policer);
9411 kfree(policer_item);
9412}
9413
9414/**
9415 * devl_trap_policers_register - Register packet trap policers with devlink.
9416 * @devlink: devlink.
9417 * @policers: Packet trap policers.
9418 * @policers_count: Count of provided packet trap policers.
9419 *
9420 * Return: Non-zero value on failure.
9421 */
9422int
9423devl_trap_policers_register(struct devlink *devlink,
9424 const struct devlink_trap_policer *policers,
9425 size_t policers_count)
9426{
9427 int i, err;
9428
9429 devl_assert_locked(devlink);
9430 for (i = 0; i < policers_count; i++) {
9431 const struct devlink_trap_policer *policer = &policers[i];
9432
9433 if (WARN_ON(policer->id == 0 ||
9434 policer->max_rate < policer->min_rate ||
9435 policer->max_burst < policer->min_burst)) {
9436 err = -EINVAL;
9437 goto err_trap_policer_verify;
9438 }
9439
9440 err = devlink_trap_policer_register(devlink, policer);
9441 if (err)
9442 goto err_trap_policer_register;
9443 }
9444 return 0;
9445
9446err_trap_policer_register:
9447err_trap_policer_verify:
9448 for (i--; i >= 0; i--)
9449 devlink_trap_policer_unregister(devlink, &policers[i]);
9450 return err;
9451}
9452EXPORT_SYMBOL_GPL(devl_trap_policers_register);
9453
9454/**
9455 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
9456 * @devlink: devlink.
9457 * @policers: Packet trap policers.
9458 * @policers_count: Count of provided packet trap policers.
9459 */
9460void
9461devl_trap_policers_unregister(struct devlink *devlink,
9462 const struct devlink_trap_policer *policers,
9463 size_t policers_count)
9464{
9465 int i;
9466
9467 devl_assert_locked(devlink);
9468 for (i = policers_count - 1; i >= 0; i--)
9469 devlink_trap_policer_unregister(devlink, &policers[i]);
9470}
9471EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
9472
9473int devlink_compat_phys_port_name_get(struct net_device *dev,
9474 char *name, size_t len)
9475{
9476 struct devlink_port *devlink_port;
9477
9478 /* RTNL mutex is held here which ensures that devlink_port
9479 * instance cannot disappear in the middle. No need to take
9480 * any devlink lock as only permanent values are accessed.
9481 */
9482 ASSERT_RTNL();
9483
9484 devlink_port = dev->devlink_port;
9485 if (!devlink_port)
9486 return -EOPNOTSUPP;
9487
9488 return __devlink_port_phys_port_name_get(devlink_port, name, len);
9489}
9490
9491int devlink_compat_switch_id_get(struct net_device *dev,
9492 struct netdev_phys_item_id *ppid)
9493{
9494 struct devlink_port *devlink_port;
9495
9496 /* Caller must hold RTNL mutex or reference to dev, which ensures that
9497 * devlink_port instance cannot disappear in the middle. No need to take
9498 * any devlink lock as only permanent values are accessed.
9499 */
9500 devlink_port = dev->devlink_port;
9501 if (!devlink_port || !devlink_port->switch_port)
9502 return -EOPNOTSUPP;
9503
9504 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
9505
9506 return 0;
9507}