Commit 74e6b2a8 authored by Jianbo Liu's avatar Jianbo Liu Committed by Saeed Mahameed

net/mlx5e: Prepare for flow meter offload if hardware supports it

If flow meter aso object is supported, set the allocated range, and
initialize aso wqe.

The allocated range is indicated by log_meter_aso_granularity in HW
capabilities, and currently is 6.
Signed-off-by: default avatarJianbo Liu <jianbol@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Reviewed-by: default avatarMaor Dickman <maord@nvidia.com>
Reviewed-by: default avatarAriel Levkovich <lariel@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent c491ded0
......@@ -45,7 +45,7 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \
esw/indir_table.o en/tc_tun_encap.o \
en/tc_tun_vxlan.o en/tc_tun_gre.o en/tc_tun_geneve.o \
en/tc_tun_mplsoudp.o diag/en_tc_tracepoint.o \
en/tc/post_act.o en/tc/int_port.o
en/tc/post_act.o en/tc/int_port.o en/tc/meter.o
mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/act/trap.o \
en/tc/act/accept.o en/tc/act/mark.o en/tc/act/goto.o \
......
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include "lib/aso.h"
#include "en/tc/post_act.h"
#include "meter.h"
struct mlx5e_flow_meters {
enum mlx5_flow_namespace_type ns_type;
struct mlx5_aso *aso;
struct mutex aso_lock; /* Protects aso operations */
int log_granularity;
u32 pdn;
struct mlx5_core_dev *mdev;
struct mlx5e_post_act *post_act;
};
struct mlx5e_flow_meters *
mlx5e_flow_meters_init(struct mlx5e_priv *priv,
enum mlx5_flow_namespace_type ns_type,
struct mlx5e_post_act *post_act)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_flow_meters *flow_meters;
int err;
if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
MLX5_HCA_CAP_GENERAL_OBJECT_TYPES_FLOW_METER_ASO))
return ERR_PTR(-EOPNOTSUPP);
if (IS_ERR_OR_NULL(post_act)) {
netdev_dbg(priv->netdev,
"flow meter offload is not supported, post action is missing\n");
return ERR_PTR(-EOPNOTSUPP);
}
flow_meters = kzalloc(sizeof(*flow_meters), GFP_KERNEL);
if (!flow_meters)
return ERR_PTR(-ENOMEM);
err = mlx5_core_alloc_pd(mdev, &flow_meters->pdn);
if (err) {
mlx5_core_err(mdev, "Failed to alloc pd for flow meter aso, err=%d\n", err);
goto err_out;
}
flow_meters->aso = mlx5_aso_create(mdev, flow_meters->pdn);
if (IS_ERR(flow_meters->aso)) {
mlx5_core_warn(mdev, "Failed to create aso wqe for flow meter\n");
err = PTR_ERR(flow_meters->aso);
goto err_sq;
}
flow_meters->ns_type = ns_type;
flow_meters->mdev = mdev;
flow_meters->post_act = post_act;
mutex_init(&flow_meters->aso_lock);
flow_meters->log_granularity = min_t(int, 6,
MLX5_CAP_QOS(mdev, log_meter_aso_max_alloc));
return flow_meters;
err_sq:
mlx5_core_dealloc_pd(mdev, flow_meters->pdn);
err_out:
kfree(flow_meters);
return ERR_PTR(err);
}
void
mlx5e_flow_meters_cleanup(struct mlx5e_flow_meters *flow_meters)
{
if (IS_ERR_OR_NULL(flow_meters))
return;
mlx5_aso_destroy(flow_meters->aso);
mlx5_core_dealloc_pd(flow_meters->mdev, flow_meters->pdn);
kfree(flow_meters);
}
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#ifndef __MLX5_EN_FLOW_METER_H__
#define __MLX5_EN_FLOW_METER_H__
struct mlx5e_flow_meters;
struct mlx5e_flow_meters *
mlx5e_flow_meters_init(struct mlx5e_priv *priv,
enum mlx5_flow_namespace_type ns_type,
struct mlx5e_post_act *post_action);
void
mlx5e_flow_meters_cleanup(struct mlx5e_flow_meters *flow_meters);
#endif /* __MLX5_EN_FLOW_METER_H__ */
......@@ -203,6 +203,8 @@ struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow);
struct mlx5e_tc_int_port_priv *
mlx5e_get_int_port_priv(struct mlx5e_priv *priv);
struct mlx5e_flow_meters *mlx5e_get_flow_meters(struct mlx5_core_dev *dev);
void *mlx5e_get_match_headers_value(u32 flags, struct mlx5_flow_spec *spec);
void *mlx5e_get_match_headers_criteria(u32 flags, struct mlx5_flow_spec *spec);
......
......@@ -62,6 +62,7 @@ struct mlx5_tc_int_port_priv;
struct mlx5e_rep_bond;
struct mlx5e_tc_tun_encap;
struct mlx5e_post_act;
struct mlx5e_flow_meters;
struct mlx5_rep_uplink_priv {
/* indirect block callbacks are invoked on bind/unbind events
......@@ -97,6 +98,8 @@ struct mlx5_rep_uplink_priv {
/* OVS internal port support */
struct mlx5e_tc_int_port_priv *int_port_priv;
struct mlx5e_flow_meters *flow_meters;
};
struct mlx5e_rep_priv {
......
......@@ -240,6 +240,30 @@ mlx5e_get_int_port_priv(struct mlx5e_priv *priv)
return NULL;
}
struct mlx5e_flow_meters *
mlx5e_get_flow_meters(struct mlx5_core_dev *dev)
{
struct mlx5_eswitch *esw = dev->priv.eswitch;
struct mlx5_rep_uplink_priv *uplink_priv;
struct mlx5e_rep_priv *uplink_rpriv;
struct mlx5e_priv *priv;
if (is_mdev_switchdev_mode(dev)) {
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
uplink_priv = &uplink_rpriv->uplink_priv;
priv = netdev_priv(uplink_rpriv->netdev);
if (!uplink_priv->flow_meters)
uplink_priv->flow_meters =
mlx5e_flow_meters_init(priv,
MLX5_FLOW_NAMESPACE_FDB,
uplink_priv->post_act);
if (!IS_ERR(uplink_priv->flow_meters))
return uplink_priv->flow_meters;
}
return NULL;
}
static struct mlx5_tc_ct_priv *
get_ct_priv(struct mlx5e_priv *priv)
{
......@@ -4956,6 +4980,7 @@ void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv)
mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
mlx5e_tc_int_port_cleanup(uplink_priv->int_port_priv);
mlx5_tc_ct_clean(uplink_priv->ct_priv);
mlx5e_flow_meters_cleanup(uplink_priv->flow_meters);
mlx5e_tc_post_act_destroy(uplink_priv->post_act);
}
......
......@@ -39,6 +39,7 @@
#include "en/tc_ct.h"
#include "en/tc_tun.h"
#include "en/tc/int_port.h"
#include "en/tc/meter.h"
#include "en_rep.h"
#define MLX5E_TC_FLOW_ID_MASK 0x0000ffff
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment