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);
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);
261 devlink_dpipe_entry_clear(&entry);
265 static int mlxsw_sp_dpipe_table_erif_counters_update(void *priv, bool enable)
267 struct mlxsw_sp *mlxsw_sp = priv;
271 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
272 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
277 mlxsw_sp_rif_counter_alloc(mlxsw_sp, rif,
278 MLXSW_SP_RIF_COUNTER_EGRESS);
280 mlxsw_sp_rif_counter_free(mlxsw_sp, rif,
281 MLXSW_SP_RIF_COUNTER_EGRESS);
287 static u64 mlxsw_sp_dpipe_table_erif_size_get(void *priv)
289 struct mlxsw_sp *mlxsw_sp = priv;
291 return MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
294 static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
295 .matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
296 .actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
297 .entries_dump = mlxsw_sp_dpipe_table_erif_entries_dump,
298 .counters_set_update = mlxsw_sp_dpipe_table_erif_counters_update,
299 .size_get = mlxsw_sp_dpipe_table_erif_size_get,
302 static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
304 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
306 return devlink_dpipe_table_register(devlink,
307 MLXSW_SP_DPIPE_TABLE_NAME_ERIF,
312 static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
314 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
316 devlink_dpipe_table_unregister(devlink, MLXSW_SP_DPIPE_TABLE_NAME_ERIF);
319 static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
321 struct devlink_dpipe_match match = {0};
324 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
325 match.header = &mlxsw_sp_dpipe_header_metadata;
326 match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
328 err = devlink_dpipe_match_put(skb, &match);
334 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
335 match.header = &devlink_dpipe_header_ipv4;
336 match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
339 match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
340 match.header = &devlink_dpipe_header_ipv6;
341 match.field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP;
348 return devlink_dpipe_match_put(skb, &match);
352 mlxsw_sp_dpipe_table_host4_matches_dump(void *priv, struct sk_buff *skb)
354 return mlxsw_sp_dpipe_table_host_matches_dump(skb, AF_INET);
358 mlxsw_sp_dpipe_table_host_actions_dump(void *priv, struct sk_buff *skb)
360 struct devlink_dpipe_action action = {0};
362 action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
363 action.header = &devlink_dpipe_header_ethernet;
364 action.field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC;
366 return devlink_dpipe_action_put(skb, &action);
369 enum mlxsw_sp_dpipe_table_host_match {
370 MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF,
371 MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP,
372 MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT,
376 mlxsw_sp_dpipe_table_host_match_action_prepare(struct devlink_dpipe_match *matches,
377 struct devlink_dpipe_action *action,
380 struct devlink_dpipe_match *match;
382 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
383 match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
384 match->header = &mlxsw_sp_dpipe_header_metadata;
385 match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
387 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
388 match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
391 match->header = &devlink_dpipe_header_ipv4;
392 match->field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
395 match->header = &devlink_dpipe_header_ipv6;
396 match->field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP;
403 action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
404 action->header = &devlink_dpipe_header_ethernet;
405 action->field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC;
409 mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
410 struct devlink_dpipe_value *match_values,
411 struct devlink_dpipe_match *matches,
412 struct devlink_dpipe_value *action_value,
413 struct devlink_dpipe_action *action,
416 struct devlink_dpipe_value *match_value;
417 struct devlink_dpipe_match *match;
419 entry->match_values = match_values;
420 entry->match_values_count = MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT;
422 entry->action_values = action_value;
423 entry->action_values_count = 1;
425 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
426 match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
428 match_value->match = match;
429 match_value->value_size = sizeof(u32);
430 match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
431 if (!match_value->value)
434 match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
435 match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
437 match_value->match = match;
440 match_value->value_size = sizeof(u32);
443 match_value->value_size = sizeof(struct in6_addr);
450 match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
451 if (!match_value->value)
454 action_value->action = action;
455 action_value->value_size = sizeof(u64);
456 action_value->value = kmalloc(action_value->value_size, GFP_KERNEL);
457 if (!action_value->value)
464 __mlxsw_sp_dpipe_table_host_entry_fill(struct devlink_dpipe_entry *entry,
465 struct mlxsw_sp_rif *rif,
466 unsigned char *ha, void *dip)
468 struct devlink_dpipe_value *value;
472 /* Set Match RIF index */
473 value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
475 rif_value = value->value;
476 *rif_value = mlxsw_sp_rif_index(rif);
477 value->mapping_value = mlxsw_sp_rif_dev_ifindex(rif);
478 value->mapping_valid = true;
481 value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
482 memcpy(value->value, dip, value->value_size);
484 /* Set Action DMAC */
485 value = entry->action_values;
486 ha_value = value->value;
487 ether_addr_copy(ha_value, ha);
491 mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
492 struct mlxsw_sp_neigh_entry *neigh_entry,
493 struct mlxsw_sp_rif *rif)
498 ha = mlxsw_sp_neigh_entry_ha(neigh_entry);
499 dip = mlxsw_sp_neigh4_entry_dip(neigh_entry);
500 __mlxsw_sp_dpipe_table_host_entry_fill(entry, rif, ha, &dip);
504 mlxsw_sp_dpipe_table_host6_entry_fill(struct devlink_dpipe_entry *entry,
505 struct mlxsw_sp_neigh_entry *neigh_entry,
506 struct mlxsw_sp_rif *rif)
508 struct in6_addr *dip;
511 ha = mlxsw_sp_neigh_entry_ha(neigh_entry);
512 dip = mlxsw_sp_neigh6_entry_dip(neigh_entry);
514 __mlxsw_sp_dpipe_table_host_entry_fill(entry, rif, ha, dip);
518 mlxsw_sp_dpipe_table_host_entry_fill(struct mlxsw_sp *mlxsw_sp,
519 struct devlink_dpipe_entry *entry,
520 struct mlxsw_sp_neigh_entry *neigh_entry,
521 struct mlxsw_sp_rif *rif,
528 mlxsw_sp_dpipe_table_host4_entry_fill(entry, neigh_entry, rif);
531 mlxsw_sp_dpipe_table_host6_entry_fill(entry, neigh_entry, rif);
538 err = mlxsw_sp_neigh_counter_get(mlxsw_sp, neigh_entry,
541 entry->counter_valid = true;
545 mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
546 struct devlink_dpipe_entry *entry,
547 bool counters_enabled,
548 struct devlink_dpipe_dump_ctx *dump_ctx,
551 int rif_neigh_count = 0;
552 int rif_neigh_skip = 0;
560 rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
562 err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
564 goto err_ctx_prepare;
566 rif_neigh_skip = rif_neigh_count;
567 for (; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
568 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
569 struct mlxsw_sp_neigh_entry *neigh_entry;
575 mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
576 int neigh_type = mlxsw_sp_neigh_entry_type(neigh_entry);
578 if (neigh_type != type)
581 if (neigh_type == AF_INET6 &&
582 mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
585 if (rif_neigh_count < rif_neigh_skip)
588 mlxsw_sp_dpipe_table_host_entry_fill(mlxsw_sp, entry,
591 entry->index = neigh_count;
592 err = devlink_dpipe_entry_ctx_append(dump_ctx, entry);
594 if (err == -EMSGSIZE) {
596 goto err_entry_append;
600 goto err_entry_append;
610 devlink_dpipe_entry_ctx_close(dump_ctx);
624 mlxsw_sp_dpipe_table_host_entries_dump(struct mlxsw_sp *mlxsw_sp,
625 bool counters_enabled,
626 struct devlink_dpipe_dump_ctx *dump_ctx,
629 struct devlink_dpipe_value match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT];
630 struct devlink_dpipe_match matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT];
631 struct devlink_dpipe_value action_value;
632 struct devlink_dpipe_action action = {0};
633 struct devlink_dpipe_entry entry = {0};
636 memset(matches, 0, MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT *
638 memset(match_values, 0, MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT *
639 sizeof(match_values[0]));
640 memset(&action_value, 0, sizeof(action_value));
642 mlxsw_sp_dpipe_table_host_match_action_prepare(matches, &action, type);
643 err = mlxsw_sp_dpipe_table_host_entry_prepare(&entry, match_values,
644 matches, &action_value,
649 err = mlxsw_sp_dpipe_table_host_entries_get(mlxsw_sp, &entry,
650 counters_enabled, dump_ctx,
653 devlink_dpipe_entry_clear(&entry);
658 mlxsw_sp_dpipe_table_host4_entries_dump(void *priv, bool counters_enabled,
659 struct devlink_dpipe_dump_ctx *dump_ctx)
661 struct mlxsw_sp *mlxsw_sp = priv;
663 return mlxsw_sp_dpipe_table_host_entries_dump(mlxsw_sp,
669 mlxsw_sp_dpipe_table_host_counters_update(struct mlxsw_sp *mlxsw_sp,
670 bool enable, int type)
675 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
676 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
677 struct mlxsw_sp_neigh_entry *neigh_entry;
681 mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
682 int neigh_type = mlxsw_sp_neigh_entry_type(neigh_entry);
684 if (neigh_type != type)
687 if (neigh_type == AF_INET6 &&
688 mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
691 mlxsw_sp_neigh_entry_counter_update(mlxsw_sp,
699 static int mlxsw_sp_dpipe_table_host4_counters_update(void *priv, bool enable)
701 struct mlxsw_sp *mlxsw_sp = priv;
703 mlxsw_sp_dpipe_table_host_counters_update(mlxsw_sp, enable, AF_INET);
708 mlxsw_sp_dpipe_table_host_size_get(struct mlxsw_sp *mlxsw_sp, int type)
714 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
715 struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
716 struct mlxsw_sp_neigh_entry *neigh_entry;
720 mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
721 int neigh_type = mlxsw_sp_neigh_entry_type(neigh_entry);
723 if (neigh_type != type)
726 if (neigh_type == AF_INET6 &&
727 mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
738 static u64 mlxsw_sp_dpipe_table_host4_size_get(void *priv)
740 struct mlxsw_sp *mlxsw_sp = priv;
742 return mlxsw_sp_dpipe_table_host_size_get(mlxsw_sp, AF_INET);
745 static struct devlink_dpipe_table_ops mlxsw_sp_host4_ops = {
746 .matches_dump = mlxsw_sp_dpipe_table_host4_matches_dump,
747 .actions_dump = mlxsw_sp_dpipe_table_host_actions_dump,
748 .entries_dump = mlxsw_sp_dpipe_table_host4_entries_dump,
749 .counters_set_update = mlxsw_sp_dpipe_table_host4_counters_update,
750 .size_get = mlxsw_sp_dpipe_table_host4_size_get,
753 static int mlxsw_sp_dpipe_host4_table_init(struct mlxsw_sp *mlxsw_sp)
755 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
757 return devlink_dpipe_table_register(devlink,
758 MLXSW_SP_DPIPE_TABLE_NAME_HOST4,
763 static void mlxsw_sp_dpipe_host4_table_fini(struct mlxsw_sp *mlxsw_sp)
765 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
767 devlink_dpipe_table_unregister(devlink,
768 MLXSW_SP_DPIPE_TABLE_NAME_HOST4);
772 mlxsw_sp_dpipe_table_host6_matches_dump(void *priv, struct sk_buff *skb)
774 return mlxsw_sp_dpipe_table_host_matches_dump(skb, AF_INET6);
778 mlxsw_sp_dpipe_table_host6_entries_dump(void *priv, bool counters_enabled,
779 struct devlink_dpipe_dump_ctx *dump_ctx)
781 struct mlxsw_sp *mlxsw_sp = priv;
783 return mlxsw_sp_dpipe_table_host_entries_dump(mlxsw_sp,
788 static int mlxsw_sp_dpipe_table_host6_counters_update(void *priv, bool enable)
790 struct mlxsw_sp *mlxsw_sp = priv;
792 mlxsw_sp_dpipe_table_host_counters_update(mlxsw_sp, enable, AF_INET6);
796 static u64 mlxsw_sp_dpipe_table_host6_size_get(void *priv)
798 struct mlxsw_sp *mlxsw_sp = priv;
800 return mlxsw_sp_dpipe_table_host_size_get(mlxsw_sp, AF_INET6);
803 static struct devlink_dpipe_table_ops mlxsw_sp_host6_ops = {
804 .matches_dump = mlxsw_sp_dpipe_table_host6_matches_dump,
805 .actions_dump = mlxsw_sp_dpipe_table_host_actions_dump,
806 .entries_dump = mlxsw_sp_dpipe_table_host6_entries_dump,
807 .counters_set_update = mlxsw_sp_dpipe_table_host6_counters_update,
808 .size_get = mlxsw_sp_dpipe_table_host6_size_get,
811 static int mlxsw_sp_dpipe_host6_table_init(struct mlxsw_sp *mlxsw_sp)
813 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
815 return devlink_dpipe_table_register(devlink,
816 MLXSW_SP_DPIPE_TABLE_NAME_HOST6,
821 static void mlxsw_sp_dpipe_host6_table_fini(struct mlxsw_sp *mlxsw_sp)
823 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
825 devlink_dpipe_table_unregister(devlink,
826 MLXSW_SP_DPIPE_TABLE_NAME_HOST6);
829 int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
831 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
834 err = devlink_dpipe_headers_register(devlink,
835 &mlxsw_sp_dpipe_headers);
838 err = mlxsw_sp_dpipe_erif_table_init(mlxsw_sp);
840 goto err_erif_table_init;
842 err = mlxsw_sp_dpipe_host4_table_init(mlxsw_sp);
844 goto err_host4_table_init;
846 err = mlxsw_sp_dpipe_host6_table_init(mlxsw_sp);
848 goto err_host6_table_init;
851 err_host6_table_init:
852 mlxsw_sp_dpipe_host4_table_fini(mlxsw_sp);
853 err_host4_table_init:
854 mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
856 devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
860 void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
862 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
864 mlxsw_sp_dpipe_host6_table_fini(mlxsw_sp);
865 mlxsw_sp_dpipe_host4_table_fini(mlxsw_sp);
866 mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
867 devlink_dpipe_headers_unregister(devlink);