Commit a6696735 authored by Maxim Mikityanskiy's avatar Maxim Mikityanskiy Committed by Saeed Mahameed

net/mlx5e: Convert TIR to a dedicated object

Code related to TIR is now encapsulated into a dedicated object and put
into new files en/tir.{c,h}. All usages are converted.

The Builder pattern is used to initialize a TIR. It allows to create a
multitude of different configurations, turning on and off some specific
features in different combinations, without having long parameter lists,
initializers per usage and repeating code in initializers.
Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@nvidia.com>
Reviewed-by: default avatarMaor Dickman <maord@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 6fe5ff2c
...@@ -27,7 +27,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \ ...@@ -27,7 +27,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
en_selftest.o en/port.o en/monitor_stats.o en/health.o \ en_selftest.o en/port.o en/monitor_stats.o en/health.o \
en/reporter_tx.o en/reporter_rx.o en/params.o en/xsk/pool.o \ en/reporter_tx.o en/reporter_rx.o en/params.o en/xsk/pool.o \
en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o en/devlink.o en/ptp.o \ en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o en/devlink.o en/ptp.o \
en/qos.o en/trap.o en/fs_tt_redirect.o en/rqt.o en/qos.o en/trap.o en/fs_tt_redirect.o en/rqt.o en/tir.o
# #
# Netdev extra # Netdev extra
......
...@@ -127,7 +127,6 @@ struct page_pool; ...@@ -127,7 +127,6 @@ struct page_pool;
#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW 0x2 #define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW 0x2
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
#define MLX5E_DEFAULT_LRO_TIMEOUT 32 #define MLX5E_DEFAULT_LRO_TIMEOUT 32
#define MLX5E_LRO_TIMEOUT_ARR_SIZE 4 #define MLX5E_LRO_TIMEOUT_ARR_SIZE 4
...@@ -922,10 +921,7 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto, ...@@ -922,10 +921,7 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
u16 vid); u16 vid);
void mlx5e_timestamp_init(struct mlx5e_priv *priv); void mlx5e_timestamp_init(struct mlx5e_priv *priv);
void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_rss_params *rss_params, int mlx5e_modify_tirs_hash(struct mlx5e_priv *priv);
const struct mlx5e_tirc_config *ttconfig,
void *tirc, bool inner);
void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in);
struct mlx5e_tirc_config mlx5e_tirc_get_default_config(enum mlx5e_traffic_types tt); struct mlx5e_tirc_config mlx5e_tirc_get_default_config(enum mlx5e_traffic_types tt);
struct mlx5e_xsk_param; struct mlx5e_xsk_param;
...@@ -1026,10 +1022,6 @@ static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev) ...@@ -1026,10 +1022,6 @@ static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
extern const struct ethtool_ops mlx5e_ethtool_ops; extern const struct ethtool_ops mlx5e_ethtool_ops;
int mlx5e_create_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir,
u32 *in);
void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
struct mlx5e_tir *tir);
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev); int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev);
void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev); void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb, int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb,
......
...@@ -6,26 +6,17 @@ ...@@ -6,26 +6,17 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include "rqt.h" #include "rqt.h"
#include "tir.h"
#include "fs.h" #include "fs.h"
#define MLX5E_MAX_NUM_CHANNELS (MLX5E_INDIR_RQT_SIZE / 2) #define MLX5E_MAX_NUM_CHANNELS (MLX5E_INDIR_RQT_SIZE / 2)
struct mlx5e_rss_params_hash {
u8 hfunc;
u8 toeplitz_hash_key[40];
};
struct mlx5e_rss_params { struct mlx5e_rss_params {
struct mlx5e_rss_params_hash hash; struct mlx5e_rss_params_hash hash;
struct mlx5e_rss_params_indir indir; struct mlx5e_rss_params_indir indir;
u32 rx_hash_fields[MLX5E_NUM_INDIR_TIRS]; u32 rx_hash_fields[MLX5E_NUM_INDIR_TIRS];
}; };
struct mlx5e_tir {
u32 tirn;
struct list_head list;
};
struct mlx5e_rx_res { struct mlx5e_rx_res {
struct mlx5e_rss_params rss_params; struct mlx5e_rss_params rss_params;
......
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2021, Mellanox Technologies inc. All rights reserved. */
#include "tir.h"
#include "params.h"
#include <linux/mlx5/transobj.h>
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
/* max() doesn't work inside square brackets. */
#define MLX5E_TIR_CMD_IN_SZ_DW ( \
MLX5_ST_SZ_DW(create_tir_in) > MLX5_ST_SZ_DW(modify_tir_in) ? \
MLX5_ST_SZ_DW(create_tir_in) : MLX5_ST_SZ_DW(modify_tir_in) \
)
struct mlx5e_tir_builder {
u32 in[MLX5E_TIR_CMD_IN_SZ_DW];
bool modify;
};
struct mlx5e_tir_builder *mlx5e_tir_builder_alloc(bool modify)
{
struct mlx5e_tir_builder *builder;
builder = kvzalloc(sizeof(*builder), GFP_KERNEL);
builder->modify = modify;
return builder;
}
void mlx5e_tir_builder_free(struct mlx5e_tir_builder *builder)
{
kvfree(builder);
}
void mlx5e_tir_builder_clear(struct mlx5e_tir_builder *builder)
{
memset(builder->in, 0, sizeof(builder->in));
}
static void *mlx5e_tir_builder_get_tirc(struct mlx5e_tir_builder *builder)
{
if (builder->modify)
return MLX5_ADDR_OF(modify_tir_in, builder->in, ctx);
return MLX5_ADDR_OF(create_tir_in, builder->in, ctx);
}
void mlx5e_tir_builder_build_inline(struct mlx5e_tir_builder *builder, u32 tdn, u32 rqn)
{
void *tirc = mlx5e_tir_builder_get_tirc(builder);
WARN_ON(builder->modify);
MLX5_SET(tirc, tirc, transport_domain, tdn);
MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_DIRECT);
MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_NONE);
MLX5_SET(tirc, tirc, inline_rqn, rqn);
}
void mlx5e_tir_builder_build_rqt(struct mlx5e_tir_builder *builder, u32 tdn,
u32 rqtn, bool inner_ft_support)
{
void *tirc = mlx5e_tir_builder_get_tirc(builder);
WARN_ON(builder->modify);
MLX5_SET(tirc, tirc, transport_domain, tdn);
MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
MLX5_SET(tirc, tirc, indirect_table, rqtn);
MLX5_SET(tirc, tirc, tunneled_offload_en, inner_ft_support);
}
void mlx5e_tir_builder_build_lro(struct mlx5e_tir_builder *builder,
const struct mlx5e_lro_param *lro_param)
{
void *tirc = mlx5e_tir_builder_get_tirc(builder);
const unsigned int rough_max_l2_l3_hdr_sz = 256;
if (builder->modify)
MLX5_SET(modify_tir_in, builder->in, bitmask.lro, 1);
if (!lro_param->enabled)
return;
MLX5_SET(tirc, tirc, lro_enable_mask,
MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
MLX5_SET(tirc, tirc, lro_max_ip_payload_size,
(MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ - rough_max_l2_l3_hdr_sz) >> 8);
MLX5_SET(tirc, tirc, lro_timeout_period_usecs, lro_param->timeout);
}
static int mlx5e_hfunc_to_hw(u8 hfunc)
{
switch (hfunc) {
case ETH_RSS_HASH_TOP:
return MLX5_RX_HASH_FN_TOEPLITZ;
case ETH_RSS_HASH_XOR:
return MLX5_RX_HASH_FN_INVERTED_XOR8;
default:
return MLX5_RX_HASH_FN_NONE;
}
}
void mlx5e_tir_builder_build_rss(struct mlx5e_tir_builder *builder,
const struct mlx5e_rss_params_hash *rss_hash,
const struct mlx5e_rss_params_traffic_type *rss_tt,
bool inner)
{
void *tirc = mlx5e_tir_builder_get_tirc(builder);
void *hfso;
if (builder->modify)
MLX5_SET(modify_tir_in, builder->in, bitmask.hash, 1);
MLX5_SET(tirc, tirc, rx_hash_fn, mlx5e_hfunc_to_hw(rss_hash->hfunc));
if (rss_hash->hfunc == ETH_RSS_HASH_TOP) {
const size_t len = MLX5_FLD_SZ_BYTES(tirc, rx_hash_toeplitz_key);
void *rss_key = MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
memcpy(rss_key, rss_hash->toeplitz_hash_key, len);
}
if (inner)
hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_inner);
else
hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
MLX5_SET(rx_hash_field_select, hfso, l3_prot_type, rss_tt->l3_prot_type);
MLX5_SET(rx_hash_field_select, hfso, l4_prot_type, rss_tt->l4_prot_type);
MLX5_SET(rx_hash_field_select, hfso, selected_fields, rss_tt->rx_hash_fields);
}
void mlx5e_tir_builder_build_direct(struct mlx5e_tir_builder *builder)
{
void *tirc = mlx5e_tir_builder_get_tirc(builder);
WARN_ON(builder->modify);
MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_INVERTED_XOR8);
}
int mlx5e_tir_init(struct mlx5e_tir *tir, struct mlx5e_tir_builder *builder,
struct mlx5_core_dev *mdev, bool reg)
{
int err;
tir->mdev = mdev;
err = mlx5_core_create_tir(tir->mdev, builder->in, &tir->tirn);
if (err)
return err;
if (reg) {
struct mlx5e_hw_objs *res = &tir->mdev->mlx5e_res.hw_objs;
mutex_lock(&res->td.list_lock);
list_add(&tir->list, &res->td.tirs_list);
mutex_unlock(&res->td.list_lock);
} else {
INIT_LIST_HEAD(&tir->list);
}
return 0;
}
void mlx5e_tir_destroy(struct mlx5e_tir *tir)
{
struct mlx5e_hw_objs *res = &tir->mdev->mlx5e_res.hw_objs;
/* Skip mutex if list_del is no-op (the TIR wasn't registered in the
* list). list_empty will never return true for an item of tirs_list,
* and READ_ONCE/WRITE_ONCE in list_empty/list_del guarantee consistency
* of the list->next value.
*/
if (!list_empty(&tir->list)) {
mutex_lock(&res->td.list_lock);
list_del(&tir->list);
mutex_unlock(&res->td.list_lock);
}
mlx5_core_destroy_tir(tir->mdev, tir->tirn);
}
int mlx5e_tir_modify(struct mlx5e_tir *tir, struct mlx5e_tir_builder *builder)
{
return mlx5_core_modify_tir(tir->mdev, tir->tirn, builder->in);
}
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, Mellanox Technologies inc. All rights reserved. */
#ifndef __MLX5_EN_TIR_H__
#define __MLX5_EN_TIR_H__
#include <linux/kernel.h>
struct mlx5e_rss_params_hash {
u8 hfunc;
u8 toeplitz_hash_key[40];
};
struct mlx5e_rss_params_traffic_type {
u8 l3_prot_type;
u8 l4_prot_type;
u32 rx_hash_fields;
};
struct mlx5e_tir_builder;
struct mlx5e_lro_param;
struct mlx5e_tir_builder *mlx5e_tir_builder_alloc(bool modify);
void mlx5e_tir_builder_free(struct mlx5e_tir_builder *builder);
void mlx5e_tir_builder_clear(struct mlx5e_tir_builder *builder);
void mlx5e_tir_builder_build_inline(struct mlx5e_tir_builder *builder, u32 tdn, u32 rqn);
void mlx5e_tir_builder_build_rqt(struct mlx5e_tir_builder *builder, u32 tdn,
u32 rqtn, bool inner_ft_support);
void mlx5e_tir_builder_build_lro(struct mlx5e_tir_builder *builder,
const struct mlx5e_lro_param *lro_param);
void mlx5e_tir_builder_build_rss(struct mlx5e_tir_builder *builder,
const struct mlx5e_rss_params_hash *rss_hash,
const struct mlx5e_rss_params_traffic_type *rss_tt,
bool inner);
void mlx5e_tir_builder_build_direct(struct mlx5e_tir_builder *builder);
struct mlx5_core_dev;
struct mlx5e_tir {
struct mlx5_core_dev *mdev;
u32 tirn;
struct list_head list;
};
int mlx5e_tir_init(struct mlx5e_tir *tir, struct mlx5e_tir_builder *builder,
struct mlx5_core_dev *mdev, bool reg);
void mlx5e_tir_destroy(struct mlx5e_tir *tir);
static inline u32 mlx5e_tir_get_tirn(struct mlx5e_tir *tir)
{
return tir->tirn;
}
int mlx5e_tir_modify(struct mlx5e_tir *tir, struct mlx5e_tir_builder *builder);
#endif /* __MLX5_EN_TIR_H__ */
...@@ -92,30 +92,19 @@ static void mlx5e_close_trap_rq(struct mlx5e_rq *rq) ...@@ -92,30 +92,19 @@ static void mlx5e_close_trap_rq(struct mlx5e_rq *rq)
static int mlx5e_create_trap_direct_rq_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir, static int mlx5e_create_trap_direct_rq_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir,
u32 rqn) u32 rqn)
{ {
void *tirc; struct mlx5e_tir_builder *builder;
int inlen;
u32 *in;
int err; int err;
inlen = MLX5_ST_SZ_BYTES(create_tir_in); builder = mlx5e_tir_builder_alloc(false);
in = kvzalloc(inlen, GFP_KERNEL); if (!builder)
if (!in)
return -ENOMEM; return -ENOMEM;
tirc = MLX5_ADDR_OF(create_tir_in, in, ctx); mlx5e_tir_builder_build_inline(builder, mdev->mlx5e_res.hw_objs.td.tdn, rqn);
MLX5_SET(tirc, tirc, transport_domain, mdev->mlx5e_res.hw_objs.td.tdn); err = mlx5e_tir_init(tir, builder, mdev, true);
MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_NONE);
MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_DIRECT);
MLX5_SET(tirc, tirc, inline_rqn, rqn);
err = mlx5e_create_tir(mdev, tir, in);
kvfree(in);
return err; mlx5e_tir_builder_free(builder);
}
static void mlx5e_destroy_trap_direct_rq_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir) return err;
{
mlx5e_destroy_tir(mdev, tir);
} }
static void mlx5e_build_trap_params(struct mlx5_core_dev *mdev, static void mlx5e_build_trap_params(struct mlx5_core_dev *mdev,
...@@ -173,7 +162,7 @@ static struct mlx5e_trap *mlx5e_open_trap(struct mlx5e_priv *priv) ...@@ -173,7 +162,7 @@ static struct mlx5e_trap *mlx5e_open_trap(struct mlx5e_priv *priv)
void mlx5e_close_trap(struct mlx5e_trap *trap) void mlx5e_close_trap(struct mlx5e_trap *trap)
{ {
mlx5e_destroy_trap_direct_rq_tir(trap->mdev, &trap->tir); mlx5e_tir_destroy(&trap->tir);
mlx5e_close_trap_rq(&trap->rq); mlx5e_close_trap_rq(&trap->rq);
netif_napi_del(&trap->napi); netif_napi_del(&trap->napi);
kvfree(trap); kvfree(trap);
......
...@@ -36,34 +36,6 @@ ...@@ -36,34 +36,6 @@
* Global resources are common to all the netdevices crated on the same nic. * Global resources are common to all the netdevices crated on the same nic.
*/ */
int mlx5e_create_tir(struct mlx5_core_dev *mdev, struct mlx5e_tir *tir, u32 *in)
{
struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs;
int err;
err = mlx5_core_create_tir(mdev, in, &tir->tirn);
if (err)
return err;
mutex_lock(&res->td.list_lock);
list_add(&tir->list, &res->td.tirs_list);
mutex_unlock(&res->td.list_lock);
return 0;
}
void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
struct mlx5e_tir *tir)
{
struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs;
mutex_lock(&res->td.list_lock);
list_del(&tir->list);
mutex_unlock(&res->td.list_lock);
mlx5_core_destroy_tir(mdev, tir->tirn);
}
void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc) void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc)
{ {
bool ro_pci_enable = pcie_relaxed_ordering_enabled(mdev->pdev); bool ro_pci_enable = pcie_relaxed_ordering_enabled(mdev->pdev);
......
...@@ -1218,21 +1218,15 @@ int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir, ...@@ -1218,21 +1218,15 @@ int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc) const u8 *key, const u8 hfunc)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
int inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
struct mlx5e_rss_params *rss; struct mlx5e_rss_params *rss;
bool refresh_tirs = false; bool refresh_tirs = false;
bool refresh_rqt = false; bool refresh_rqt = false;
void *in;
if ((hfunc != ETH_RSS_HASH_NO_CHANGE) && if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
(hfunc != ETH_RSS_HASH_XOR) && (hfunc != ETH_RSS_HASH_XOR) &&
(hfunc != ETH_RSS_HASH_TOP)) (hfunc != ETH_RSS_HASH_TOP))
return -EINVAL; return -EINVAL;
in = kvzalloc(inlen, GFP_KERNEL);
if (!in)
return -ENOMEM;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
rss = &priv->rx_res->rss_params; rss = &priv->rx_res->rss_params;
...@@ -1271,12 +1265,10 @@ int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir, ...@@ -1271,12 +1265,10 @@ int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
} }
if (refresh_tirs) if (refresh_tirs)
mlx5e_modify_tirs_hash(priv, in); mlx5e_modify_tirs_hash(priv);
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
kvfree(in);
return 0; return 0;
} }
......
...@@ -817,10 +817,8 @@ static enum mlx5e_traffic_types flow_type_to_traffic_type(u32 flow_type) ...@@ -817,10 +817,8 @@ static enum mlx5e_traffic_types flow_type_to_traffic_type(u32 flow_type)
static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv, static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
struct ethtool_rxnfc *nfc) struct ethtool_rxnfc *nfc)
{ {
int inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
enum mlx5e_traffic_types tt; enum mlx5e_traffic_types tt;
u8 rx_hash_field = 0; u8 rx_hash_field = 0;
void *in;
tt = flow_type_to_traffic_type(nfc->flow_type); tt = flow_type_to_traffic_type(nfc->flow_type);
if (tt == MLX5E_NUM_INDIR_TIRS) if (tt == MLX5E_NUM_INDIR_TIRS)
...@@ -849,21 +847,16 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv, ...@@ -849,21 +847,16 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
if (nfc->data & RXH_L4_B_2_3) if (nfc->data & RXH_L4_B_2_3)
rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT; rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT;
in = kvzalloc(inlen, GFP_KERNEL);
if (!in)
return -ENOMEM;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
if (rx_hash_field == priv->rx_res->rss_params.rx_hash_fields[tt]) if (rx_hash_field == priv->rx_res->rss_params.rx_hash_fields[tt])
goto out; goto out;
priv->rx_res->rss_params.rx_hash_fields[tt] = rx_hash_field; priv->rx_res->rss_params.rx_hash_fields[tt] = rx_hash_field;
mlx5e_modify_tirs_hash(priv, in); mlx5e_modify_tirs_hash(priv);
out: out:
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
kvfree(in);
return 0; return 0;
} }
......
...@@ -340,11 +340,11 @@ struct mlx5e_hairpin { ...@@ -340,11 +340,11 @@ struct mlx5e_hairpin {
struct mlx5_core_dev *func_mdev; struct mlx5_core_dev *func_mdev;
struct mlx5e_priv *func_priv; struct mlx5e_priv *func_priv;
u32 tdn; u32 tdn;
u32 tirn; struct mlx5e_tir direct_tir;
int num_channels; int num_channels;
struct mlx5e_rqt indir_rqt; struct mlx5e_rqt indir_rqt;
u32 indir_tirn[MLX5E_NUM_INDIR_TIRS]; struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS];
struct mlx5e_ttc_table ttc; struct mlx5e_ttc_table ttc;
}; };
...@@ -462,35 +462,35 @@ struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) ...@@ -462,35 +462,35 @@ struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex)
static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp) static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp)
{ {
u32 in[MLX5_ST_SZ_DW(create_tir_in)] = {}; struct mlx5e_tir_builder *builder;
void *tirc;
int err; int err;
builder = mlx5e_tir_builder_alloc(false);
if (!builder)
return -ENOMEM;
err = mlx5_core_alloc_transport_domain(hp->func_mdev, &hp->tdn); err = mlx5_core_alloc_transport_domain(hp->func_mdev, &hp->tdn);
if (err) if (err)
goto alloc_tdn_err; goto out;
tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_DIRECT);
MLX5_SET(tirc, tirc, inline_rqn, hp->pair->rqn[0]);
MLX5_SET(tirc, tirc, transport_domain, hp->tdn);
err = mlx5_core_create_tir(hp->func_mdev, in, &hp->tirn); mlx5e_tir_builder_build_inline(builder, hp->tdn, hp->pair->rqn[0]);
err = mlx5e_tir_init(&hp->direct_tir, builder, hp->func_mdev, false);
if (err) if (err)
goto create_tir_err; goto create_tir_err;
return 0; out:
mlx5e_tir_builder_free(builder);
return err;
create_tir_err: create_tir_err:
mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn); mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn);
alloc_tdn_err:
return err; goto out;
} }
static void mlx5e_hairpin_destroy_transport(struct mlx5e_hairpin *hp) static void mlx5e_hairpin_destroy_transport(struct mlx5e_hairpin *hp)
{ {
mlx5_core_destroy_tir(hp->func_mdev, hp->tirn); mlx5e_tir_destroy(&hp->direct_tir);
mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn); mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn);
} }
...@@ -515,36 +515,52 @@ static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp) ...@@ -515,36 +515,52 @@ static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp)
static int mlx5e_hairpin_create_indirect_tirs(struct mlx5e_hairpin *hp) static int mlx5e_hairpin_create_indirect_tirs(struct mlx5e_hairpin *hp)
{ {
struct mlx5e_rss_params_traffic_type rss_tt;
struct mlx5e_priv *priv = hp->func_priv; struct mlx5e_priv *priv = hp->func_priv;
u32 in[MLX5_ST_SZ_DW(create_tir_in)]; struct mlx5e_rss_params_hash *rss_hash;
int tt, i, err; enum mlx5e_traffic_types tt, max_tt;
void *tirc; struct mlx5e_tir_builder *builder;
int err = 0;
builder = mlx5e_tir_builder_alloc(false);
if (!builder)
return -ENOMEM;
rss_hash = &priv->rx_res->rss_params.hash;
for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
struct mlx5e_tirc_config ttconfig = mlx5e_tirc_get_default_config(tt); struct mlx5e_tirc_config ttconfig = mlx5e_tirc_get_default_config(tt);
memset(in, 0, MLX5_ST_SZ_BYTES(create_tir_in)); rss_tt = (struct mlx5e_rss_params_traffic_type) {
tirc = MLX5_ADDR_OF(create_tir_in, in, ctx); .l3_prot_type = ttconfig.l3_prot_type,
.l4_prot_type = ttconfig.l4_prot_type,
.rx_hash_fields = ttconfig.rx_hash_fields,
};
MLX5_SET(tirc, tirc, transport_domain, hp->tdn); mlx5e_tir_builder_build_rqt(builder, hp->tdn,
MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT); mlx5e_rqt_get_rqtn(&hp->indir_rqt),
MLX5_SET(tirc, tirc, indirect_table, mlx5e_rqt_get_rqtn(&hp->indir_rqt)); false);
mlx5e_build_indir_tir_ctx_hash(&priv->rx_res->rss_params, &ttconfig, mlx5e_tir_builder_build_rss(builder, rss_hash, &rss_tt, false);
tirc, false);
err = mlx5_core_create_tir(hp->func_mdev, in, err = mlx5e_tir_init(&hp->indir_tir[tt], builder, hp->func_mdev, false);
&hp->indir_tirn[tt]);
if (err) { if (err) {
mlx5_core_warn(hp->func_mdev, "create indirect tirs failed, %d\n", err); mlx5_core_warn(hp->func_mdev, "create indirect tirs failed, %d\n", err);
goto err_destroy_tirs; goto err_destroy_tirs;
} }
mlx5e_tir_builder_clear(builder);
} }
return 0;
err_destroy_tirs: out:
for (i = 0; i < tt; i++) mlx5e_tir_builder_free(builder);
mlx5_core_destroy_tir(hp->func_mdev, hp->indir_tirn[i]);
return err; return err;
err_destroy_tirs:
max_tt = tt;
for (tt = 0; tt < max_tt; tt++)
mlx5e_tir_destroy(&hp->indir_tir[tt]);
goto out;
} }
static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp) static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp)
...@@ -552,7 +568,7 @@ static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp) ...@@ -552,7 +568,7 @@ static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp)
int tt; int tt;
for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
mlx5_core_destroy_tir(hp->func_mdev, hp->indir_tirn[tt]); mlx5e_tir_destroy(&hp->indir_tir[tt]);
} }
static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp, static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,
...@@ -563,10 +579,10 @@ static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp, ...@@ -563,10 +579,10 @@ static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,
memset(ttc_params, 0, sizeof(*ttc_params)); memset(ttc_params, 0, sizeof(*ttc_params));
ttc_params->any_tt_tirn = hp->tirn; ttc_params->any_tt_tirn = mlx5e_tir_get_tirn(&hp->direct_tir);
for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
ttc_params->indir_tirn[tt] = hp->indir_tirn[tt]; ttc_params->indir_tirn[tt] = mlx5e_tir_get_tirn(&hp->indir_tir[tt]);
ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE; ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE;
ft_attr->level = MLX5E_TC_TTC_FT_LEVEL; ft_attr->level = MLX5E_TC_TTC_FT_LEVEL;
...@@ -837,7 +853,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, ...@@ -837,7 +853,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
} }
netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x prio %d (log) data %d packets %d\n", netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x prio %d (log) data %d packets %d\n",
hp->tirn, hp->pair->rqn[0], mlx5e_tir_get_tirn(&hp->direct_tir), hp->pair->rqn[0],
dev_name(hp->pair->peer_mdev->device), dev_name(hp->pair->peer_mdev->device),
hp->pair->sqn[0], match_prio, params.log_data_size, params.log_num_packets); hp->pair->sqn[0], match_prio, params.log_data_size, params.log_num_packets);
...@@ -846,7 +862,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, ...@@ -846,7 +862,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
flow_flag_set(flow, HAIRPIN_RSS); flow_flag_set(flow, HAIRPIN_RSS);
flow->attr->nic_attr->hairpin_ft = hpe->hp->ttc.ft.t; flow->attr->nic_attr->hairpin_ft = hpe->hp->ttc.ft.t;
} else { } else {
flow->attr->nic_attr->hairpin_tirn = hpe->hp->tirn; flow->attr->nic_attr->hairpin_tirn = mlx5e_tir_get_tirn(&hpe->hp->direct_tir);
} }
flow->hpe = hpe; flow->hpe = hpe;
......
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