2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2017 Arkadi Sharshevsky <arakdis@mellanox.com>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the names of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
35 #include <linux/kernel.h>
36 #include <net/devlink.h>
39 #include "spectrum_dpipe.h"
40 #include "spectrum_router.h"
42 enum mlxsw_sp_field_metadata_id {
43 MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
44 MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
45 MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
48 static struct devlink_dpipe_field mlxsw_sp_dpipe_fields_metadata[] = {
49 { .name = "erif_port",
50 .id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
52 .mapping_type = DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX,
54 { .name = "l3_forward",
55 .id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
59 .id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
64 enum mlxsw_sp_dpipe_header_id {
65 MLXSW_SP_DPIPE_HEADER_METADATA,
68 static struct devlink_dpipe_header mlxsw_sp_dpipe_header_metadata = {
70 .id = MLXSW_SP_DPIPE_HEADER_METADATA,
71 .fields = mlxsw_sp_dpipe_fields_metadata,
72 .fields_count = ARRAY_SIZE(mlxsw_sp_dpipe_fields_metadata),
75 static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {
76 &mlxsw_sp_dpipe_header_metadata,
77 &devlink_dpipe_header_ethernet,
78 &devlink_dpipe_header_ipv4,
79 &devlink_dpipe_header_ipv6,
82 static struct devlink_dpipe_headers mlxsw_sp_dpipe_headers = {
83 .headers = mlxsw_dpipe_headers,
84 .headers_count = ARRAY_SIZE(mlxsw_dpipe_headers),
87 static int mlxsw_sp_dpipe_table_erif_actions_dump(void *priv,
90 struct devlink_dpipe_action action = {0};
93 action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
94 action.header = &mlxsw_sp_dpipe_header_metadata;
95 action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD;
97 err = devlink_dpipe_action_put(skb, &action);
101 action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
102 action.header = &mlxsw_sp_dpipe_header_metadata;
103 action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP;
105 return devlink_dpipe_action_put(skb, &action);
108 static int mlxsw_sp_dpipe_table_erif_matches_dump(void *priv,
111 struct devlink_dpipe_match match = {0};
113 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
114 match.header = &mlxsw_sp_dpipe_header_metadata;
115 match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
117 return devlink_dpipe_match_put(skb, &match);
121 mlxsw_sp_erif_match_action_prepare(struct devlink_dpipe_match *match,
122 struct devlink_dpipe_action *action)
124 action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
125 action->header = &mlxsw_sp_dpipe_header_metadata;
126 action->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD;
128 match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
129 match->header = &mlxsw_sp_dpipe_header_metadata;
130 match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
133 static int mlxsw_sp_erif_entry_prepare(struct devlink_dpipe_entry *entry,
134 struct devlink_dpipe_value *match_value,
135 struct devlink_dpipe_match *match,
136 struct devlink_dpipe_value *action_value,
137 struct devlink_dpipe_action *action)
139 entry->match_values = match_value;
140 entry->match_values_count = 1;
142 entry->action_values = action_value;
143 entry->action_values_count = 1;
145 match_value->match = match;
146 match_value->value_size = sizeof(u32);
147 match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
148 if (!match_value->value)
151 action_value->action = action;
152 action_value->value_size = sizeof(u32);
153 action_value->value = kmalloc(action_value->value_size, GFP_KERNEL);
154 if (!action_value->value)
155 goto err_action_alloc;
159 kfree(match_value->value);
163 static int mlxsw_sp_erif_entry_get(struct mlxsw_sp *mlxsw_sp,
164 struct devlink_dpipe_entry *entry,
165 struct mlxsw_sp_rif *rif,
166 bool counters_enabled)
173 /* Set Match RIF index */
174 rif_value = entry->match_values->value;
175 *rif_value = mlxsw_sp_rif_index(rif);
176 entry->match_values->mapping_value = mlxsw_sp_rif_dev_ifindex(rif);
177 entry->match_values->mapping_valid = true;
179 /* Set Action Forwarding */
180 action_value = entry->action_values->value;
183 entry->counter_valid = false;
185 entry->index = mlxsw_sp_rif_index(rif);
187 if (!counters_enabled)
190 err = mlxsw_sp_rif_counter_value_get(mlxsw_sp, rif,
191 MLXSW_SP_RIF_COUNTER_EGRESS,
194 entry->counter = cnt;
195 entry->counter_valid = true;
201 mlxsw_sp_dpipe_table_erif_entries_dump(void *priv, bool counters_enabled,
202 struct devlink_dpipe_dump_ctx *dump_ctx)
204 struct devlink_dpipe_value match_value, action_value;
205 struct devlink_dpipe_action action = {0};
206 struct devlink_dpipe_match match = {0};
207 struct devlink_dpipe_entry entry = {0};
208 struct mlxsw_sp *mlxsw_sp = priv;
209 unsigned int rif_count;
213 memset(&match_value, 0, sizeof(match_value));
214 memset(&action_value, 0, sizeof(action_value));
216 mlxsw_sp_erif_match_action_prepare(&match, &action);
217 err = mlxsw_sp_erif_entry_prepare(&entry, &match_value, &match,
218 &action_value, &action);
222 rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
226 err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
228 goto err_ctx_prepare;
230 for (; i < rif_count; i++) {
231 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
235 err = mlxsw_sp_erif_entry_get(mlxsw_sp, &entry, rif,
239 err = devlink_dpipe_entry_ctx_append(dump_ctx, &entry);
241 if (err == -EMSGSIZE) {
243 goto err_entry_append;
246 goto err_entry_append;
251 devlink_dpipe_entry_ctx_close(dump_ctx);
256 devlink_dpipe_entry_clear(&entry);
262 devlink_dpipe_entry_clear(&entry);
266 static int mlxsw_sp_dpipe_table_erif_counters_update(void *priv, bool enable)
268 struct mlxsw_sp *mlxsw_sp = priv;
272 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
273 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
278 mlxsw_sp_rif_counter_alloc(mlxsw_sp, rif,
279 MLXSW_SP_RIF_COUNTER_EGRESS);
281 mlxsw_sp_rif_counter_free(mlxsw_sp, rif,
282 MLXSW_SP_RIF_COUNTER_EGRESS);
288 static u64 mlxsw_sp_dpipe_table_erif_size_get(void *priv)
290 struct mlxsw_sp *mlxsw_sp = priv;
292 return MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
295 static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
296 .matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
297 .actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
298 .entries_dump = mlxsw_sp_dpipe_table_erif_entries_dump,
299 .counters_set_update = mlxsw_sp_dpipe_table_erif_counters_update,
300 .size_get = mlxsw_sp_dpipe_table_erif_size_get,
303 static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
305 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
307 return devlink_dpipe_table_register(devlink,
308 MLXSW_SP_DPIPE_TABLE_NAME_ERIF,
313 static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
315 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
317 devlink_dpipe_table_unregister(devlink, MLXSW_SP_DPIPE_TABLE_NAME_ERIF);
320 static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
322 struct devlink_dpipe_match match = {0};
325 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
326 match.header = &mlxsw_sp_dpipe_header_metadata;
327 match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
329 err = devlink_dpipe_match_put(skb, &match);
335 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
336 match.header = &devlink_dpipe_header_ipv4;
337 match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
340 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
341 match.header = &devlink_dpipe_header_ipv6;
342 match.field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP;
349 return devlink_dpipe_match_put(skb, &match);
353 mlxsw_sp_dpipe_table_host4_matches_dump(void *priv, struct sk_buff *skb)
355 return mlxsw_sp_dpipe_table_host_matches_dump(skb, AF_INET);
359 mlxsw_sp_dpipe_table_host_actions_dump(void *priv, struct sk_buff *skb)
361 struct devlink_dpipe_action action = {0};
363 action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
364 action.header = &devlink_dpipe_header_ethernet;
365 action.field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC;
367 return devlink_dpipe_action_put(skb, &action);
370 enum mlxsw_sp_dpipe_table_host_match {
371 MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF,
372 MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP,
373 MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT,
377 mlxsw_sp_dpipe_table_host_match_action_prepare(struct devlink_dpipe_match *matches,
378 struct devlink_dpipe_action *action,
381 struct devlink_dpipe_match *match;
383 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
384 match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
385 match->header = &mlxsw_sp_dpipe_header_metadata;
386 match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
388 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
389 match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
392 match->header = &devlink_dpipe_header_ipv4;
393 match->field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
396 match->header = &devlink_dpipe_header_ipv6;
397 match->field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP;
404 action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
405 action->header = &devlink_dpipe_header_ethernet;
406 action->field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC;
410 mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
411 struct devlink_dpipe_value *match_values,
412 struct devlink_dpipe_match *matches,
413 struct devlink_dpipe_value *action_value,
414 struct devlink_dpipe_action *action,
417 struct devlink_dpipe_value *match_value;
418 struct devlink_dpipe_match *match;
420 entry->match_values = match_values;
421 entry->match_values_count = MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT;
423 entry->action_values = action_value;
424 entry->action_values_count = 1;
426 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
427 match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
429 match_value->match = match;
430 match_value->value_size = sizeof(u32);
431 match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
432 if (!match_value->value)
435 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
436 match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
438 match_value->match = match;
441 match_value->value_size = sizeof(u32);
444 match_value->value_size = sizeof(struct in6_addr);
451 match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
452 if (!match_value->value)
455 action_value->action = action;
456 action_value->value_size = sizeof(u64);
457 action_value->value = kmalloc(action_value->value_size, GFP_KERNEL);
458 if (!action_value->value)
465 __mlxsw_sp_dpipe_table_host_entry_fill(struct devlink_dpipe_entry *entry,
466 struct mlxsw_sp_rif *rif,
467 unsigned char *ha, void *dip)
469 struct devlink_dpipe_value *value;
473 /* Set Match RIF index */
474 value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
476 rif_value = value->value;
477 *rif_value = mlxsw_sp_rif_index(rif);
478 value->mapping_value = mlxsw_sp_rif_dev_ifindex(rif);
479 value->mapping_valid = true;
482 value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
483 memcpy(value->value, dip, value->value_size);
485 /* Set Action DMAC */
486 value = entry->action_values;
487 ha_value = value->value;
488 ether_addr_copy(ha_value, ha);
492 mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
493 struct mlxsw_sp_neigh_entry *neigh_entry,
494 struct mlxsw_sp_rif *rif)
499 ha = mlxsw_sp_neigh_entry_ha(neigh_entry);
500 dip = mlxsw_sp_neigh4_entry_dip(neigh_entry);
501 __mlxsw_sp_dpipe_table_host_entry_fill(entry, rif, ha, &dip);
505 mlxsw_sp_dpipe_table_host6_entry_fill(struct devlink_dpipe_entry *entry,
506 struct mlxsw_sp_neigh_entry *neigh_entry,
507 struct mlxsw_sp_rif *rif)
509 struct in6_addr *dip;
512 ha = mlxsw_sp_neigh_entry_ha(neigh_entry);
513 dip = mlxsw_sp_neigh6_entry_dip(neigh_entry);
515 __mlxsw_sp_dpipe_table_host_entry_fill(entry, rif, ha, dip);
519 mlxsw_sp_dpipe_table_host_entry_fill(struct mlxsw_sp *mlxsw_sp,
520 struct devlink_dpipe_entry *entry,
521 struct mlxsw_sp_neigh_entry *neigh_entry,
522 struct mlxsw_sp_rif *rif,
529 mlxsw_sp_dpipe_table_host4_entry_fill(entry, neigh_entry, rif);
532 mlxsw_sp_dpipe_table_host6_entry_fill(entry, neigh_entry, rif);
539 err = mlxsw_sp_neigh_counter_get(mlxsw_sp, neigh_entry,
542 entry->counter_valid = true;
546 mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
547 struct devlink_dpipe_entry *entry,
548 bool counters_enabled,
549 struct devlink_dpipe_dump_ctx *dump_ctx,
552 int rif_neigh_count = 0;
553 int rif_neigh_skip = 0;
561 rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
563 err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
565 goto err_ctx_prepare;
567 rif_neigh_skip = rif_neigh_count;
568 for (; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
569 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
570 struct mlxsw_sp_neigh_entry *neigh_entry;
576 mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
577 int neigh_type = mlxsw_sp_neigh_entry_type(neigh_entry);
579 if (neigh_type != type)
582 if (neigh_type == AF_INET6 &&
583 mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
586 if (rif_neigh_count < rif_neigh_skip)
589 mlxsw_sp_dpipe_table_host_entry_fill(mlxsw_sp, entry,
592 entry->index = neigh_count;
593 err = devlink_dpipe_entry_ctx_append(dump_ctx, entry);
595 if (err == -EMSGSIZE) {
597 goto err_entry_append;
601 goto err_entry_append;
611 devlink_dpipe_entry_ctx_close(dump_ctx);
625 mlxsw_sp_dpipe_table_host_entries_dump(struct mlxsw_sp *mlxsw_sp,
626 bool counters_enabled,
627 struct devlink_dpipe_dump_ctx *dump_ctx,
630 struct devlink_dpipe_value match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT];
631 struct devlink_dpipe_match matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT];
632 struct devlink_dpipe_value action_value;
633 struct devlink_dpipe_action action = {0};
634 struct devlink_dpipe_entry entry = {0};
637 memset(matches, 0, MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT *
639 memset(match_values, 0, MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT *
640 sizeof(match_values[0]));
641 memset(&action_value, 0, sizeof(action_value));
643 mlxsw_sp_dpipe_table_host_match_action_prepare(matches, &action, type);
644 err = mlxsw_sp_dpipe_table_host_entry_prepare(&entry, match_values,
645 matches, &action_value,
650 err = mlxsw_sp_dpipe_table_host_entries_get(mlxsw_sp, &entry,
651 counters_enabled, dump_ctx,
654 devlink_dpipe_entry_clear(&entry);
659 mlxsw_sp_dpipe_table_host4_entries_dump(void *priv, bool counters_enabled,
660 struct devlink_dpipe_dump_ctx *dump_ctx)
662 struct mlxsw_sp *mlxsw_sp = priv;
664 return mlxsw_sp_dpipe_table_host_entries_dump(mlxsw_sp,
670 mlxsw_sp_dpipe_table_host_counters_update(struct mlxsw_sp *mlxsw_sp,
671 bool enable, int type)
676 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
677 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
678 struct mlxsw_sp_neigh_entry *neigh_entry;
682 mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
683 int neigh_type = mlxsw_sp_neigh_entry_type(neigh_entry);
685 if (neigh_type != type)
688 if (neigh_type == AF_INET6 &&
689 mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
692 mlxsw_sp_neigh_entry_counter_update(mlxsw_sp,
700 static int mlxsw_sp_dpipe_table_host4_counters_update(void *priv, bool enable)
702 struct mlxsw_sp *mlxsw_sp = priv;
704 mlxsw_sp_dpipe_table_host_counters_update(mlxsw_sp, enable, AF_INET);
709 mlxsw_sp_dpipe_table_host_size_get(struct mlxsw_sp *mlxsw_sp, int type)
715 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
716 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
717 struct mlxsw_sp_neigh_entry *neigh_entry;
721 mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
722 int neigh_type = mlxsw_sp_neigh_entry_type(neigh_entry);
724 if (neigh_type != type)
727 if (neigh_type == AF_INET6 &&
728 mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
739 static u64 mlxsw_sp_dpipe_table_host4_size_get(void *priv)
741 struct mlxsw_sp *mlxsw_sp = priv;
743 return mlxsw_sp_dpipe_table_host_size_get(mlxsw_sp, AF_INET);
746 static struct devlink_dpipe_table_ops mlxsw_sp_host4_ops = {
747 .matches_dump = mlxsw_sp_dpipe_table_host4_matches_dump,
748 .actions_dump = mlxsw_sp_dpipe_table_host_actions_dump,
749 .entries_dump = mlxsw_sp_dpipe_table_host4_entries_dump,
750 .counters_set_update = mlxsw_sp_dpipe_table_host4_counters_update,
751 .size_get = mlxsw_sp_dpipe_table_host4_size_get,
754 static int mlxsw_sp_dpipe_host4_table_init(struct mlxsw_sp *mlxsw_sp)
756 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
758 return devlink_dpipe_table_register(devlink,
759 MLXSW_SP_DPIPE_TABLE_NAME_HOST4,
764 static void mlxsw_sp_dpipe_host4_table_fini(struct mlxsw_sp *mlxsw_sp)
766 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
768 devlink_dpipe_table_unregister(devlink,
769 MLXSW_SP_DPIPE_TABLE_NAME_HOST4);
773 mlxsw_sp_dpipe_table_host6_matches_dump(void *priv, struct sk_buff *skb)
775 return mlxsw_sp_dpipe_table_host_matches_dump(skb, AF_INET6);
779 mlxsw_sp_dpipe_table_host6_entries_dump(void *priv, bool counters_enabled,
780 struct devlink_dpipe_dump_ctx *dump_ctx)
782 struct mlxsw_sp *mlxsw_sp = priv;
784 return mlxsw_sp_dpipe_table_host_entries_dump(mlxsw_sp,
789 static int mlxsw_sp_dpipe_table_host6_counters_update(void *priv, bool enable)
791 struct mlxsw_sp *mlxsw_sp = priv;
793 mlxsw_sp_dpipe_table_host_counters_update(mlxsw_sp, enable, AF_INET6);
797 static u64 mlxsw_sp_dpipe_table_host6_size_get(void *priv)
799 struct mlxsw_sp *mlxsw_sp = priv;
801 return mlxsw_sp_dpipe_table_host_size_get(mlxsw_sp, AF_INET6);
804 static struct devlink_dpipe_table_ops mlxsw_sp_host6_ops = {
805 .matches_dump = mlxsw_sp_dpipe_table_host6_matches_dump,
806 .actions_dump = mlxsw_sp_dpipe_table_host_actions_dump,
807 .entries_dump = mlxsw_sp_dpipe_table_host6_entries_dump,
808 .counters_set_update = mlxsw_sp_dpipe_table_host6_counters_update,
809 .size_get = mlxsw_sp_dpipe_table_host6_size_get,
812 static int mlxsw_sp_dpipe_host6_table_init(struct mlxsw_sp *mlxsw_sp)
814 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
816 return devlink_dpipe_table_register(devlink,
817 MLXSW_SP_DPIPE_TABLE_NAME_HOST6,
822 static void mlxsw_sp_dpipe_host6_table_fini(struct mlxsw_sp *mlxsw_sp)
824 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
826 devlink_dpipe_table_unregister(devlink,
827 MLXSW_SP_DPIPE_TABLE_NAME_HOST6);
830 int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
832 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
835 err = devlink_dpipe_headers_register(devlink,
836 &mlxsw_sp_dpipe_headers);
839 err = mlxsw_sp_dpipe_erif_table_init(mlxsw_sp);
841 goto err_erif_table_init;
843 err = mlxsw_sp_dpipe_host4_table_init(mlxsw_sp);
845 goto err_host4_table_init;
847 err = mlxsw_sp_dpipe_host6_table_init(mlxsw_sp);
849 goto err_host6_table_init;
852 err_host6_table_init:
853 mlxsw_sp_dpipe_host4_table_fini(mlxsw_sp);
854 err_host4_table_init:
855 mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
857 devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
861 void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
863 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
865 mlxsw_sp_dpipe_host6_table_fini(mlxsw_sp);
866 mlxsw_sp_dpipe_host4_table_fini(mlxsw_sp);
867 mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
868 devlink_dpipe_headers_unregister(devlink);