// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <net/devlink.h>
#include "spectrum.h"
#include "spectrum_dpipe.h"
#include "spectrum_router.h"
enum mlxsw_sp_field_metadata_id {
MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_INDEX,
MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_SIZE,
MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_HASH_INDEX,
};
static struct devlink_dpipe_field mlxsw_sp_dpipe_fields_metadata[] = {
{
.name = "erif_port",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
.bitwidth = 32,
.mapping_type = DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX,
},
{
.name = "l3_forward",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
.bitwidth = 1,
},
{
.name = "l3_drop",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
.bitwidth = 1,
},
{
.name = "adj_index",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_INDEX,
.bitwidth = 32,
},
{
.name = "adj_size",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_SIZE,
.bitwidth = 32,
},
{
.name = "adj_hash_index",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_HASH_INDEX,
.bitwidth = 32,
},
};
enum mlxsw_sp_dpipe_header_id {
MLXSW_SP_DPIPE_HEADER_METADATA,
};
static struct devlink_dpipe_header mlxsw_sp_dpipe_header_metadata = {
.name = "mlxsw_meta",
.id = MLXSW_SP_DPIPE_HEADER_METADATA,
.fields = mlxsw_sp_dpipe_fields_metadata,
.fields_count = ARRAY_SIZE(mlxsw_sp_dpipe_fields_metadata),
};
static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {
&mlxsw_sp_dpipe_header_metadata,
&devlink_dpipe_header_ethernet,
&devlink_dpipe_header_ipv4,
&devlink_dpipe_header_ipv6,
};
static struct devlink_dpipe_headers mlxsw_sp_dpipe_headers = {
.headers = mlxsw_dpipe_headers,
.headers_count = ARRAY_SIZE(mlxsw_dpipe_headers),
};
static int mlxsw_sp_dpipe_table_erif_actions_dump(void *priv,
struct sk_buff *skb)
{
struct devlink_dpipe_action action = {0};
int err;
action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
action.header = &mlxsw_sp_dpipe_header_metadata;
action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD;
err = devlink_dpipe_action_put(skb, &action);
if (err)
return err;
action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
action.header = &mlxsw_sp_dpipe_header_metadata;
action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP;
return devlink_dpipe_action_put(skb, &action);
}
static int mlxsw_sp_dpipe_table_erif_matches_dump(void *priv,
struct sk_buff *skb)
{
struct devlink_dpipe_match match = {0};
match.type