Skip to content

Commit

Permalink
net/mlx5e: kTLS, Add kTLS RX HW offload support
Browse files Browse the repository at this point in the history
Implement driver support for the kTLS RX HW offload feature.
Resync support is added in a downstream patch.

New offload contexts post their static/progress params WQEs
over the per-channel async ICOSQ, protected under a spin-lock.
The Channel/RQ is selected according to the socket's rxq index.

Feature is OFF by default. Can be turned on by:
$ ethtool -K <if> tls-hw-rx-offload on

A new TLS-RX workqueue is used to allow asynchronous addition of
steering rules, out of the NAPI context.
It will be also used in a downstream patch in the resync procedure.

Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
  • Loading branch information
Tariq Toukan authored and Saeed Mahameed committed Jun 27, 2020
1 parent df8d866 commit 1182f36
Show file tree
Hide file tree
Showing 19 changed files with 529 additions and 32 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ config MLX5_TLS
config MLX5_EN_TLS
bool "TLS cryptography-offload accelaration"
depends on MLX5_CORE_EN
depends on XPS
depends on MLX5_FPGA_TLS || MLX5_TLS
default y
help
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ mlx5_core-$(CONFIG_MLX5_EN_IPSEC) += en_accel/ipsec.o en_accel/ipsec_rxtx.o \

mlx5_core-$(CONFIG_MLX5_EN_TLS) += en_accel/tls.o en_accel/tls_rxtx.o en_accel/tls_stats.o \
en_accel/fs_tcp.o en_accel/ktls.o en_accel/ktls_txrx.o \
en_accel/ktls_tx.o
en_accel/ktls_tx.o en_accel/ktls_rx.o

mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o \
steering/dr_matcher.o steering/dr_rule.o \
Expand Down
19 changes: 18 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,20 @@ int mlx5_ktls_create_key(struct mlx5_core_dev *mdev,
u32 *p_key_id);
void mlx5_ktls_destroy_key(struct mlx5_core_dev *mdev, u32 key_id);

static inline bool mlx5_accel_is_ktls_tx(struct mlx5_core_dev *mdev)
{
return MLX5_CAP_GEN(mdev, tls_tx);
}

static inline bool mlx5_accel_is_ktls_rx(struct mlx5_core_dev *mdev)
{
return MLX5_CAP_GEN(mdev, tls_rx);
}

static inline bool mlx5_accel_is_ktls_device(struct mlx5_core_dev *mdev)
{
if (!MLX5_CAP_GEN(mdev, tls_tx))
if (!mlx5_accel_is_ktls_tx(mdev) &&
!mlx5_accel_is_ktls_rx(mdev))
return false;

if (!MLX5_CAP_GEN(mdev, log_max_dek))
Expand All @@ -67,6 +78,12 @@ static inline bool mlx5e_ktls_type_check(struct mlx5_core_dev *mdev,
return false;
}
#else
static inline bool mlx5_accel_is_ktls_tx(struct mlx5_core_dev *mdev)
{ return false; }

static inline bool mlx5_accel_is_ktls_rx(struct mlx5_core_dev *mdev)
{ return false; }

static inline int
mlx5_ktls_create_key(struct mlx5_core_dev *mdev,
struct tls_crypto_info *crypto_info,
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
enum mlx5e_icosq_wqe_type {
MLX5E_ICOSQ_WQE_NOP,
MLX5E_ICOSQ_WQE_UMR_RX,
#ifdef CONFIG_MLX5_EN_TLS
MLX5E_ICOSQ_WQE_UMR_TLS,
MLX5E_ICOSQ_WQE_SET_PSV_TLS,
#endif
};

static inline bool
Expand Down Expand Up @@ -114,9 +118,16 @@ struct mlx5e_icosq_wqe_info {
struct {
struct mlx5e_rq *rq;
} umr;
#ifdef CONFIG_MLX5_EN_TLS
struct {
struct mlx5e_ktls_offload_context_rx *priv_rx;
} tls_set_params;
#endif
};
};

void mlx5e_free_icosq_descs(struct mlx5e_icosq *sq);

static inline u16 mlx5e_icosq_get_next_pi(struct mlx5e_icosq *sq, u16 size)
{
struct mlx5_wq_cyc *wq = &sq->wq;
Expand Down
20 changes: 20 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include "en_accel/ipsec_rxtx.h"
#include "en_accel/tls.h"
#include "en_accel/tls_rxtx.h"
#include "en.h"
#include "en/txrx.h"
Expand Down Expand Up @@ -147,4 +148,23 @@ static inline bool mlx5e_accel_tx_finish(struct mlx5e_priv *priv,
return true;
}

static inline int mlx5e_accel_sk_get_rxq(struct sock *sk)
{
int rxq = sk_rx_queue_get(sk);

if (unlikely(rxq == -1))
rxq = 0;

return rxq;
}

static inline int mlx5e_accel_init_rx(struct mlx5e_priv *priv)
{
return mlx5e_ktls_init_rx(priv);
}

static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv)
{
mlx5e_ktls_cleanup_rx(priv);
}
#endif /* __MLX5E_EN_ACCEL_H__ */
66 changes: 56 additions & 10 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "en.h"
#include "en_accel/ktls.h"
#include "en_accel/ktls_utils.h"
#include "en_accel/fs_tcp.h"

static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,
enum tls_offload_ctx_dir direction,
Expand All @@ -14,13 +15,13 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,
struct mlx5_core_dev *mdev = priv->mdev;
int err;

if (WARN_ON(direction != TLS_OFFLOAD_CTX_DIR_TX))
return -EINVAL;

if (WARN_ON(!mlx5e_ktls_type_check(mdev, crypto_info)))
return -EOPNOTSUPP;

err = mlx5e_ktls_add_tx(netdev, sk, crypto_info, start_offload_tcp_sn);
if (direction == TLS_OFFLOAD_CTX_DIR_TX)
err = mlx5e_ktls_add_tx(netdev, sk, crypto_info, start_offload_tcp_sn);
else
err = mlx5e_ktls_add_rx(netdev, sk, crypto_info, start_offload_tcp_sn);

return err;
}
Expand All @@ -29,26 +30,71 @@ static void mlx5e_ktls_del(struct net_device *netdev,
struct tls_context *tls_ctx,
enum tls_offload_ctx_dir direction)
{
if (direction != TLS_OFFLOAD_CTX_DIR_TX)
return;
if (direction == TLS_OFFLOAD_CTX_DIR_TX)
mlx5e_ktls_del_tx(netdev, tls_ctx);
else
mlx5e_ktls_del_rx(netdev, tls_ctx);
}

mlx5e_ktls_del_tx(netdev, tls_ctx);
static int mlx5e_ktls_resync(struct net_device *netdev,
struct sock *sk, u32 seq, u8 *rcd_sn,
enum tls_offload_ctx_dir direction)
{
return -EOPNOTSUPP;
}

static const struct tlsdev_ops mlx5e_ktls_ops = {
.tls_dev_add = mlx5e_ktls_add,
.tls_dev_del = mlx5e_ktls_del,
.tls_dev_resync = mlx5e_ktls_resync,
};

void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv)
{
struct net_device *netdev = priv->netdev;
struct mlx5_core_dev *mdev = priv->mdev;

if (!mlx5_accel_is_ktls_device(priv->mdev))
if (!mlx5_accel_is_ktls_device(mdev))
return;

netdev->hw_features |= NETIF_F_HW_TLS_TX;
netdev->features |= NETIF_F_HW_TLS_TX;
if (mlx5_accel_is_ktls_tx(mdev)) {
netdev->hw_features |= NETIF_F_HW_TLS_TX;
netdev->features |= NETIF_F_HW_TLS_TX;
}

if (mlx5_accel_is_ktls_rx(mdev))
netdev->hw_features |= NETIF_F_HW_TLS_RX;

netdev->tlsdev_ops = &mlx5e_ktls_ops;
}

int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
int err = 0;

mutex_lock(&priv->state_lock);
if (enable)
err = mlx5e_accel_fs_tcp_create(priv);
else
mlx5e_accel_fs_tcp_destroy(priv);
mutex_unlock(&priv->state_lock);

return err;
}

int mlx5e_ktls_init_rx(struct mlx5e_priv *priv)
{
int err = 0;

if (priv->netdev->features & NETIF_F_HW_TLS_RX)
err = mlx5e_accel_fs_tcp_create(priv);

return err;
}

void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv)
{
if (priv->netdev->features & NETIF_F_HW_TLS_RX)
mlx5e_accel_fs_tcp_destroy(priv);
}
19 changes: 18 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,30 @@
#ifdef CONFIG_MLX5_EN_TLS

void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv);

int mlx5e_ktls_init_rx(struct mlx5e_priv *priv);
void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv);
int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable);
#else

static inline void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv)
{
}

static inline int mlx5e_ktls_init_rx(struct mlx5e_priv *priv)
{
return 0;
}

static inline void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv)
{
}

static inline int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable)
{
netdev_warn(netdev, "kTLS is not supported\n");
return -EOPNOTSUPP;
}

#endif

#endif /* __MLX5E_TLS_H__ */
Loading

0 comments on commit 1182f36

Please sign in to comment.