1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
7 #include "devl_internal.h"
9 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet
[] = {
11 .name
= "destination mac",
12 .id
= DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC
,
17 struct devlink_dpipe_header devlink_dpipe_header_ethernet
= {
19 .id
= DEVLINK_DPIPE_HEADER_ETHERNET
,
20 .fields
= devlink_dpipe_fields_ethernet
,
21 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ethernet
),
24 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet
);
26 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4
[] = {
28 .name
= "destination ip",
29 .id
= DEVLINK_DPIPE_FIELD_IPV4_DST_IP
,
34 struct devlink_dpipe_header devlink_dpipe_header_ipv4
= {
36 .id
= DEVLINK_DPIPE_HEADER_IPV4
,
37 .fields
= devlink_dpipe_fields_ipv4
,
38 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ipv4
),
41 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4
);
43 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6
[] = {
45 .name
= "destination ip",
46 .id
= DEVLINK_DPIPE_FIELD_IPV6_DST_IP
,
51 struct devlink_dpipe_header devlink_dpipe_header_ipv6
= {
53 .id
= DEVLINK_DPIPE_HEADER_IPV6
,
54 .fields
= devlink_dpipe_fields_ipv6
,
55 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ipv6
),
58 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6
);
60 int devlink_dpipe_match_put(struct sk_buff
*skb
,
61 struct devlink_dpipe_match
*match
)
63 struct devlink_dpipe_header
*header
= match
->header
;
64 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
65 struct nlattr
*match_attr
;
67 match_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
71 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
72 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
73 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
74 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
75 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
78 nla_nest_end(skb
, match_attr
);
82 nla_nest_cancel(skb
, match_attr
);
85 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
87 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
90 struct nlattr
*matches_attr
;
92 matches_attr
= nla_nest_start_noflag(skb
,
93 DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
97 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
100 nla_nest_end(skb
, matches_attr
);
104 nla_nest_cancel(skb
, matches_attr
);
108 int devlink_dpipe_action_put(struct sk_buff
*skb
,
109 struct devlink_dpipe_action
*action
)
111 struct devlink_dpipe_header
*header
= action
->header
;
112 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
113 struct nlattr
*action_attr
;
115 action_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
119 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
120 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
121 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
122 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
123 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
124 goto nla_put_failure
;
126 nla_nest_end(skb
, action_attr
);
130 nla_nest_cancel(skb
, action_attr
);
133 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
135 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
138 struct nlattr
*actions_attr
;
140 actions_attr
= nla_nest_start_noflag(skb
,
141 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
145 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
146 goto nla_put_failure
;
148 nla_nest_end(skb
, actions_attr
);
152 nla_nest_cancel(skb
, actions_attr
);
156 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
157 struct devlink_dpipe_table
*table
)
159 struct nlattr
*table_attr
;
162 table_size
= table
->table_ops
->size_get(table
->priv
);
163 table_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
167 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
168 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
170 goto nla_put_failure
;
171 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
172 table
->counters_enabled
))
173 goto nla_put_failure
;
175 if (table
->resource_valid
) {
176 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
177 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
178 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
179 table
->resource_units
, DEVLINK_ATTR_PAD
))
180 goto nla_put_failure
;
182 if (devlink_dpipe_matches_put(table
, skb
))
183 goto nla_put_failure
;
185 if (devlink_dpipe_actions_put(table
, skb
))
186 goto nla_put_failure
;
188 nla_nest_end(skb
, table_attr
);
192 nla_nest_cancel(skb
, table_attr
);
196 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
197 struct genl_info
*info
)
202 err
= genlmsg_reply(*pskb
, info
);
206 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
212 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
213 enum devlink_command cmd
, int flags
,
214 struct list_head
*dpipe_tables
,
215 const char *table_name
)
217 struct devlink
*devlink
= info
->user_ptr
[0];
218 struct devlink_dpipe_table
*table
;
219 struct nlattr
*tables_attr
;
220 struct sk_buff
*skb
= NULL
;
221 struct nlmsghdr
*nlh
;
227 table
= list_first_entry(dpipe_tables
,
228 struct devlink_dpipe_table
, list
);
230 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
234 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
235 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
241 if (devlink_nl_put_handle(skb
, devlink
))
242 goto nla_put_failure
;
243 tables_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
245 goto nla_put_failure
;
249 list_for_each_entry_from(table
, dpipe_tables
, list
) {
251 err
= devlink_dpipe_table_put(skb
, table
);
259 if (!strcmp(table
->name
, table_name
)) {
260 err
= devlink_dpipe_table_put(skb
, table
);
268 nla_nest_end(skb
, tables_attr
);
269 genlmsg_end(skb
, hdr
);
274 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
275 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
277 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
283 return genlmsg_reply(skb
, info
);
292 int devlink_nl_dpipe_table_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
294 struct devlink
*devlink
= info
->user_ptr
[0];
295 const char *table_name
= NULL
;
297 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
298 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
300 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
301 &devlink
->dpipe_table_list
,
305 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
306 struct devlink_dpipe_value
*value
)
308 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
309 value
->value_size
, value
->value
))
312 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
313 value
->value_size
, value
->mask
))
315 if (value
->mapping_valid
)
316 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
317 value
->mapping_value
))
322 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
323 struct devlink_dpipe_value
*value
)
327 if (devlink_dpipe_action_put(skb
, value
->action
))
329 if (devlink_dpipe_value_put(skb
, value
))
334 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
335 struct devlink_dpipe_value
*values
,
336 unsigned int values_count
)
338 struct nlattr
*action_attr
;
342 for (i
= 0; i
< values_count
; i
++) {
343 action_attr
= nla_nest_start_noflag(skb
,
344 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
347 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
349 goto err_action_value_put
;
350 nla_nest_end(skb
, action_attr
);
354 err_action_value_put
:
355 nla_nest_cancel(skb
, action_attr
);
359 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
360 struct devlink_dpipe_value
*value
)
364 if (devlink_dpipe_match_put(skb
, value
->match
))
366 if (devlink_dpipe_value_put(skb
, value
))
371 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
372 struct devlink_dpipe_value
*values
,
373 unsigned int values_count
)
375 struct nlattr
*match_attr
;
379 for (i
= 0; i
< values_count
; i
++) {
380 match_attr
= nla_nest_start_noflag(skb
,
381 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
384 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
386 goto err_match_value_put
;
387 nla_nest_end(skb
, match_attr
);
392 nla_nest_cancel(skb
, match_attr
);
396 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
397 struct devlink_dpipe_entry
*entry
)
399 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
402 entry_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
406 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
408 goto nla_put_failure
;
409 if (entry
->counter_valid
)
410 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
411 entry
->counter
, DEVLINK_ATTR_PAD
))
412 goto nla_put_failure
;
414 matches_attr
= nla_nest_start_noflag(skb
,
415 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
417 goto nla_put_failure
;
419 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
420 entry
->match_values_count
);
422 nla_nest_cancel(skb
, matches_attr
);
423 goto err_match_values_put
;
425 nla_nest_end(skb
, matches_attr
);
427 actions_attr
= nla_nest_start_noflag(skb
,
428 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
430 goto nla_put_failure
;
432 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
433 entry
->action_values_count
);
435 nla_nest_cancel(skb
, actions_attr
);
436 goto err_action_values_put
;
438 nla_nest_end(skb
, actions_attr
);
440 nla_nest_end(skb
, entry_attr
);
445 err_match_values_put
:
446 err_action_values_put
:
447 nla_nest_cancel(skb
, entry_attr
);
451 static struct devlink_dpipe_table
*
452 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
453 const char *table_name
, struct devlink
*devlink
)
455 struct devlink_dpipe_table
*table
;
457 list_for_each_entry_rcu(table
, dpipe_tables
, list
,
458 lockdep_is_held(&devlink
->lock
)) {
459 if (!strcmp(table
->name
, table_name
))
465 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
467 struct devlink
*devlink
;
470 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
475 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
476 dump_ctx
->info
->snd_portid
,
477 dump_ctx
->info
->snd_seq
,
478 &devlink_nl_family
, NLM_F_MULTI
,
481 goto nla_put_failure
;
483 devlink
= dump_ctx
->info
->user_ptr
[0];
484 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
485 goto nla_put_failure
;
486 dump_ctx
->nest
= nla_nest_start_noflag(dump_ctx
->skb
,
487 DEVLINK_ATTR_DPIPE_ENTRIES
);
489 goto nla_put_failure
;
493 nlmsg_free(dump_ctx
->skb
);
496 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
498 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
499 struct devlink_dpipe_entry
*entry
)
501 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
503 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
505 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
507 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
508 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
511 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
513 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
516 unsigned int value_count
, value_index
;
517 struct devlink_dpipe_value
*value
;
519 value
= entry
->action_values
;
520 value_count
= entry
->action_values_count
;
521 for (value_index
= 0; value_index
< value_count
; value_index
++) {
522 kfree(value
[value_index
].value
);
523 kfree(value
[value_index
].mask
);
526 value
= entry
->match_values
;
527 value_count
= entry
->match_values_count
;
528 for (value_index
= 0; value_index
< value_count
; value_index
++) {
529 kfree(value
[value_index
].value
);
530 kfree(value
[value_index
].mask
);
533 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear
);
535 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
536 enum devlink_command cmd
, int flags
,
537 struct devlink_dpipe_table
*table
)
539 struct devlink_dpipe_dump_ctx dump_ctx
;
540 struct nlmsghdr
*nlh
;
545 dump_ctx
.info
= info
;
547 err
= table
->table_ops
->entries_dump(table
->priv
,
548 table
->counters_enabled
,
554 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
555 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
557 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
562 return genlmsg_reply(dump_ctx
.skb
, info
);
565 int devlink_nl_dpipe_entries_get_doit(struct sk_buff
*skb
,
566 struct genl_info
*info
)
568 struct devlink
*devlink
= info
->user_ptr
[0];
569 struct devlink_dpipe_table
*table
;
570 const char *table_name
;
572 if (GENL_REQ_ATTR_CHECK(info
, DEVLINK_ATTR_DPIPE_TABLE_NAME
))
575 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
576 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
577 table_name
, devlink
);
581 if (!table
->table_ops
->entries_dump
)
584 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
588 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
589 const struct devlink_dpipe_header
*header
)
591 struct devlink_dpipe_field
*field
;
592 struct nlattr
*field_attr
;
595 for (i
= 0; i
< header
->fields_count
; i
++) {
596 field
= &header
->fields
[i
];
597 field_attr
= nla_nest_start_noflag(skb
,
598 DEVLINK_ATTR_DPIPE_FIELD
);
601 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
602 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
603 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
604 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
605 goto nla_put_failure
;
606 nla_nest_end(skb
, field_attr
);
611 nla_nest_cancel(skb
, field_attr
);
615 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
616 struct devlink_dpipe_header
*header
)
618 struct nlattr
*fields_attr
, *header_attr
;
621 header_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
625 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
626 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
627 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
628 goto nla_put_failure
;
630 fields_attr
= nla_nest_start_noflag(skb
,
631 DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
633 goto nla_put_failure
;
635 err
= devlink_dpipe_fields_put(skb
, header
);
637 nla_nest_cancel(skb
, fields_attr
);
638 goto nla_put_failure
;
640 nla_nest_end(skb
, fields_attr
);
641 nla_nest_end(skb
, header_attr
);
646 nla_nest_cancel(skb
, header_attr
);
650 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
651 enum devlink_command cmd
, int flags
,
652 struct devlink_dpipe_headers
*
655 struct devlink
*devlink
= info
->user_ptr
[0];
656 struct nlattr
*headers_attr
;
657 struct sk_buff
*skb
= NULL
;
658 struct nlmsghdr
*nlh
;
665 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
669 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
670 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
676 if (devlink_nl_put_handle(skb
, devlink
))
677 goto nla_put_failure
;
678 headers_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
680 goto nla_put_failure
;
683 for (; i
< dpipe_headers
->headers_count
; i
++) {
684 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
692 nla_nest_end(skb
, headers_attr
);
693 genlmsg_end(skb
, hdr
);
694 if (i
!= dpipe_headers
->headers_count
)
698 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
699 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
701 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
706 return genlmsg_reply(skb
, info
);
715 int devlink_nl_dpipe_headers_get_doit(struct sk_buff
*skb
,
716 struct genl_info
*info
)
718 struct devlink
*devlink
= info
->user_ptr
[0];
720 if (!devlink
->dpipe_headers
)
722 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
723 0, devlink
->dpipe_headers
);
726 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
727 const char *table_name
,
730 struct devlink_dpipe_table
*table
;
732 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
733 table_name
, devlink
);
737 if (table
->counter_control_extern
)
740 if (!(table
->counters_enabled
^ enable
))
743 table
->counters_enabled
= enable
;
744 if (table
->table_ops
->counters_set_update
)
745 table
->table_ops
->counters_set_update(table
->priv
, enable
);
749 int devlink_nl_dpipe_table_counters_set_doit(struct sk_buff
*skb
,
750 struct genl_info
*info
)
752 struct devlink
*devlink
= info
->user_ptr
[0];
753 const char *table_name
;
754 bool counters_enable
;
756 if (GENL_REQ_ATTR_CHECK(info
, DEVLINK_ATTR_DPIPE_TABLE_NAME
) ||
757 GENL_REQ_ATTR_CHECK(info
,
758 DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
))
761 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
762 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
764 return devlink_dpipe_table_counters_set(devlink
, table_name
,
769 * devl_dpipe_headers_register - register dpipe headers
772 * @dpipe_headers: dpipe header array
774 * Register the headers supported by hardware.
776 void devl_dpipe_headers_register(struct devlink
*devlink
,
777 struct devlink_dpipe_headers
*dpipe_headers
)
779 lockdep_assert_held(&devlink
->lock
);
781 devlink
->dpipe_headers
= dpipe_headers
;
783 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register
);
786 * devl_dpipe_headers_unregister - unregister dpipe headers
790 * Unregister the headers supported by hardware.
792 void devl_dpipe_headers_unregister(struct devlink
*devlink
)
794 lockdep_assert_held(&devlink
->lock
);
796 devlink
->dpipe_headers
= NULL
;
798 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister
);
801 * devlink_dpipe_table_counter_enabled - check if counter allocation
804 * @table_name: tables name
806 * Used by driver to check if counter allocation is required.
807 * After counter allocation is turned on the table entries
808 * are updated to include counter statistics.
810 * After that point on the driver must respect the counter
811 * state so that each entry added to the table is added
814 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
815 const char *table_name
)
817 struct devlink_dpipe_table
*table
;
821 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
822 table_name
, devlink
);
825 enabled
= table
->counters_enabled
;
829 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
832 * devl_dpipe_table_register - register dpipe table
835 * @table_name: table name
836 * @table_ops: table ops
838 * @counter_control_extern: external control for counters
840 int devl_dpipe_table_register(struct devlink
*devlink
,
841 const char *table_name
,
842 const struct devlink_dpipe_table_ops
*table_ops
,
843 void *priv
, bool counter_control_extern
)
845 struct devlink_dpipe_table
*table
;
847 lockdep_assert_held(&devlink
->lock
);
849 if (WARN_ON(!table_ops
->size_get
))
852 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
,
856 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
860 table
->name
= table_name
;
861 table
->table_ops
= table_ops
;
863 table
->counter_control_extern
= counter_control_extern
;
865 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
869 EXPORT_SYMBOL_GPL(devl_dpipe_table_register
);
872 * devl_dpipe_table_unregister - unregister dpipe table
875 * @table_name: table name
877 void devl_dpipe_table_unregister(struct devlink
*devlink
,
878 const char *table_name
)
880 struct devlink_dpipe_table
*table
;
882 lockdep_assert_held(&devlink
->lock
);
884 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
885 table_name
, devlink
);
888 list_del_rcu(&table
->list
);
889 kfree_rcu(table
, rcu
);
891 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister
);
894 * devl_dpipe_table_resource_set - set the resource id
897 * @table_name: table name
898 * @resource_id: resource id
899 * @resource_units: number of resource's units consumed per table's entry
901 int devl_dpipe_table_resource_set(struct devlink
*devlink
,
902 const char *table_name
, u64 resource_id
,
905 struct devlink_dpipe_table
*table
;
907 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
908 table_name
, devlink
);
912 table
->resource_id
= resource_id
;
913 table
->resource_units
= resource_units
;
914 table
->resource_valid
= true;
917 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set
);