Skip to content

Commit 89ee2d9

Browse files
raed-salemPaolo Abeni
authored andcommitted
net/mlx5e: Support PSP offload functionality
Add PSP offload related structs, layouts, and enumerations. Implement .set_config and .rx_spi_alloc PSP device operations. Driver does not need to make use of the .set_config operation. Stub .assoc_add and .assoc_del PSP operations. Introduce the MLX5_EN_PSP configuration option for enabling PSP offload support on mlx5 devices. Signed-off-by: Raed Salem <raeds@nvidia.com> Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com> Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com> Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com> Link: https://patch.msgid.link/20250917000954.859376-12-daniel.zahka@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent e788510 commit 89ee2d9

File tree

7 files changed

+239
-1
lines changed

7 files changed

+239
-1
lines changed

drivers/net/ethernet/mellanox/mlx5/core/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,14 @@ config MLX5_DPLL
207207
help
208208
DPLL support in Mellanox Technologies ConnectX NICs.
209209

210+
config MLX5_EN_PSP
211+
bool "Mellanox Technologies support for PSP cryptography-offload acceleration"
212+
depends on INET_PSP
213+
depends on MLX5_CORE_EN
214+
default y
215+
help
216+
mlx5 device offload support for Google PSP Security Protocol offload.
217+
Adds support for PSP encryption offload and for SPI and key generation
218+
interfaces to PSP Stack which supports PSP crypto offload.
219+
220+
If unsure, say Y.

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ mlx5_core-$(CONFIG_MLX5_EN_TLS) += en_accel/ktls_stats.o \
112112
en_accel/fs_tcp.o en_accel/ktls.o en_accel/ktls_txrx.o \
113113
en_accel/ktls_tx.o en_accel/ktls_rx.o
114114

115+
mlx5_core-$(CONFIG_MLX5_EN_PSP) += en_accel/psp.o
116+
115117
#
116118
# SW Steering
117119
#

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,9 @@ struct mlx5e_priv {
938938
#ifdef CONFIG_MLX5_EN_IPSEC
939939
struct mlx5e_ipsec *ipsec;
940940
#endif
941+
#ifdef CONFIG_MLX5_EN_PSP
942+
struct mlx5e_psp *psp;
943+
#endif
941944
#ifdef CONFIG_MLX5_EN_TLS
942945
struct mlx5e_tls *tls;
943946
#endif

drivers/net/ethernet/mellanox/mlx5/core/en/params.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "en/port.h"
77
#include "en_accel/en_accel.h"
88
#include "en_accel/ipsec.h"
9+
#include "en_accel/psp.h"
910
#include <linux/dim.h>
1011
#include <net/page_pool/types.h>
1112
#include <net/xdp_sock_drv.h>
@@ -1004,7 +1005,8 @@ void mlx5e_build_sq_param(struct mlx5_core_dev *mdev,
10041005
bool allow_swp;
10051006

10061007
allow_swp = mlx5_geneve_tx_allowed(mdev) ||
1007-
(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO);
1008+
(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO) ||
1009+
mlx5_is_psp_device(mdev);
10081010
mlx5e_build_sq_param_common(mdev, param);
10091011
MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size);
10101012
MLX5_SET(sqc, sqc, allow_swp, allow_swp);
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2+
/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
3+
#include <linux/mlx5/device.h>
4+
#include <net/psp.h>
5+
#include <linux/psp.h>
6+
#include "mlx5_core.h"
7+
#include "psp.h"
8+
#include "lib/crypto.h"
9+
#include "en_accel/psp.h"
10+
11+
static int
12+
mlx5e_psp_set_config(struct psp_dev *psd, struct psp_dev_config *conf,
13+
struct netlink_ext_ack *extack)
14+
{
15+
return 0; /* TODO: this should actually do things to the device */
16+
}
17+
18+
static int
19+
mlx5e_psp_generate_key_spi(struct mlx5_core_dev *mdev,
20+
enum mlx5_psp_gen_spi_in_key_size keysz,
21+
unsigned int keysz_bytes,
22+
struct psp_key_parsed *key)
23+
{
24+
u32 out[MLX5_ST_SZ_DW(psp_gen_spi_out) + MLX5_ST_SZ_DW(key_spi)] = {};
25+
u32 in[MLX5_ST_SZ_DW(psp_gen_spi_in)] = {};
26+
void *outkey;
27+
int err;
28+
29+
WARN_ON_ONCE(keysz_bytes > PSP_MAX_KEY);
30+
31+
MLX5_SET(psp_gen_spi_in, in, opcode, MLX5_CMD_OP_PSP_GEN_SPI);
32+
MLX5_SET(psp_gen_spi_in, in, key_size, keysz);
33+
MLX5_SET(psp_gen_spi_in, in, num_of_spi, 1);
34+
err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
35+
if (err)
36+
return err;
37+
38+
outkey = MLX5_ADDR_OF(psp_gen_spi_out, out, key_spi);
39+
key->spi = cpu_to_be32(MLX5_GET(key_spi, outkey, spi));
40+
memcpy(key->key, MLX5_ADDR_OF(key_spi, outkey, key) + 32 - keysz_bytes,
41+
keysz_bytes);
42+
43+
return 0;
44+
}
45+
46+
static int
47+
mlx5e_psp_rx_spi_alloc(struct psp_dev *psd, u32 version,
48+
struct psp_key_parsed *assoc,
49+
struct netlink_ext_ack *extack)
50+
{
51+
struct mlx5e_priv *priv = netdev_priv(psd->main_netdev);
52+
enum mlx5_psp_gen_spi_in_key_size keysz;
53+
u8 keysz_bytes;
54+
55+
switch (version) {
56+
case PSP_VERSION_HDR0_AES_GCM_128:
57+
keysz = MLX5_PSP_GEN_SPI_IN_KEY_SIZE_128;
58+
keysz_bytes = 16;
59+
break;
60+
case PSP_VERSION_HDR0_AES_GCM_256:
61+
keysz = MLX5_PSP_GEN_SPI_IN_KEY_SIZE_256;
62+
keysz_bytes = 32;
63+
break;
64+
default:
65+
return -EINVAL;
66+
}
67+
68+
return mlx5e_psp_generate_key_spi(priv->mdev, keysz, keysz_bytes, assoc);
69+
}
70+
71+
static int mlx5e_psp_assoc_add(struct psp_dev *psd, struct psp_assoc *pas,
72+
struct netlink_ext_ack *extack)
73+
{
74+
struct mlx5e_priv *priv = netdev_priv(psd->main_netdev);
75+
76+
mlx5_core_dbg(priv->mdev, "PSP assoc add: rx: %u, tx: %u\n",
77+
be32_to_cpu(pas->rx.spi), be32_to_cpu(pas->tx.spi));
78+
79+
return -EINVAL;
80+
}
81+
82+
static void mlx5e_psp_assoc_del(struct psp_dev *psd, struct psp_assoc *pas)
83+
{
84+
}
85+
86+
static struct psp_dev_ops mlx5_psp_ops = {
87+
.set_config = mlx5e_psp_set_config,
88+
.rx_spi_alloc = mlx5e_psp_rx_spi_alloc,
89+
.tx_key_add = mlx5e_psp_assoc_add,
90+
.tx_key_del = mlx5e_psp_assoc_del,
91+
};
92+
93+
void mlx5e_psp_unregister(struct mlx5e_priv *priv)
94+
{
95+
if (!priv->psp || !priv->psp->psp)
96+
return;
97+
98+
psp_dev_unregister(priv->psp->psp);
99+
}
100+
101+
void mlx5e_psp_register(struct mlx5e_priv *priv)
102+
{
103+
/* FW Caps missing */
104+
if (!priv->psp)
105+
return;
106+
107+
priv->psp->caps.assoc_drv_spc = sizeof(u32);
108+
priv->psp->caps.versions = 1 << PSP_VERSION_HDR0_AES_GCM_128;
109+
if (MLX5_CAP_PSP(priv->mdev, psp_crypto_esp_aes_gcm_256_encrypt) &&
110+
MLX5_CAP_PSP(priv->mdev, psp_crypto_esp_aes_gcm_256_decrypt))
111+
priv->psp->caps.versions |= 1 << PSP_VERSION_HDR0_AES_GCM_256;
112+
113+
priv->psp->psp = psp_dev_create(priv->netdev, &mlx5_psp_ops,
114+
&priv->psp->caps, NULL);
115+
if (IS_ERR(priv->psp->psp))
116+
mlx5_core_err(priv->mdev, "PSP failed to register due to %pe\n",
117+
priv->psp->psp);
118+
}
119+
120+
int mlx5e_psp_init(struct mlx5e_priv *priv)
121+
{
122+
struct mlx5_core_dev *mdev = priv->mdev;
123+
struct mlx5e_psp *psp;
124+
125+
if (!mlx5_is_psp_device(mdev)) {
126+
mlx5_core_dbg(mdev, "PSP offload not supported\n");
127+
return -EOPNOTSUPP;
128+
}
129+
130+
if (!MLX5_CAP_ETH(mdev, swp)) {
131+
mlx5_core_dbg(mdev, "SWP not supported\n");
132+
return -EOPNOTSUPP;
133+
}
134+
135+
if (!MLX5_CAP_ETH(mdev, swp_csum)) {
136+
mlx5_core_dbg(mdev, "SWP checksum not supported\n");
137+
return -EOPNOTSUPP;
138+
}
139+
140+
if (!MLX5_CAP_ETH(mdev, swp_csum_l4_partial)) {
141+
mlx5_core_dbg(mdev, "SWP L4 partial checksum not supported\n");
142+
return -EOPNOTSUPP;
143+
}
144+
145+
if (!MLX5_CAP_ETH(mdev, swp_lso)) {
146+
mlx5_core_dbg(mdev, "PSP LSO not supported\n");
147+
return -EOPNOTSUPP;
148+
}
149+
150+
psp = kzalloc(sizeof(*psp), GFP_KERNEL);
151+
if (!psp)
152+
return -ENOMEM;
153+
154+
priv->psp = psp;
155+
mlx5_core_dbg(priv->mdev, "PSP attached to netdevice\n");
156+
return 0;
157+
}
158+
159+
void mlx5e_psp_cleanup(struct mlx5e_priv *priv)
160+
{
161+
struct mlx5e_psp *psp = priv->psp;
162+
163+
if (!psp)
164+
return;
165+
166+
priv->psp = NULL;
167+
kfree(psp);
168+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2+
/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
3+
4+
#ifndef __MLX5E_ACCEL_PSP_H__
5+
#define __MLX5E_ACCEL_PSP_H__
6+
#if IS_ENABLED(CONFIG_MLX5_EN_PSP)
7+
#include <net/psp/types.h>
8+
#include "en.h"
9+
10+
struct mlx5e_psp {
11+
struct psp_dev *psp;
12+
struct psp_dev_caps caps;
13+
};
14+
15+
static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)
16+
{
17+
if (!MLX5_CAP_GEN(mdev, psp))
18+
return false;
19+
20+
if (!MLX5_CAP_PSP(mdev, psp_crypto_offload) ||
21+
!MLX5_CAP_PSP(mdev, psp_crypto_esp_aes_gcm_128_encrypt) ||
22+
!MLX5_CAP_PSP(mdev, psp_crypto_esp_aes_gcm_128_decrypt))
23+
return false;
24+
25+
return true;
26+
}
27+
28+
void mlx5e_psp_register(struct mlx5e_priv *priv);
29+
void mlx5e_psp_unregister(struct mlx5e_priv *priv);
30+
int mlx5e_psp_init(struct mlx5e_priv *priv);
31+
void mlx5e_psp_cleanup(struct mlx5e_priv *priv);
32+
#else
33+
static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)
34+
{
35+
return false;
36+
}
37+
38+
static inline void mlx5e_psp_register(struct mlx5e_priv *priv) { }
39+
static inline void mlx5e_psp_unregister(struct mlx5e_priv *priv) { }
40+
static inline int mlx5e_psp_init(struct mlx5e_priv *priv) { return 0; }
41+
static inline void mlx5e_psp_cleanup(struct mlx5e_priv *priv) { }
42+
#endif /* CONFIG_MLX5_EN_PSP */
43+
#endif /* __MLX5E_ACCEL_PSP_H__ */

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "en_tc.h"
5454
#include "en_rep.h"
5555
#include "en_accel/ipsec.h"
56+
#include "en_accel/psp.h"
5657
#include "en_accel/macsec.h"
5758
#include "en_accel/en_accel.h"
5859
#include "en_accel/ktls.h"
@@ -5931,6 +5932,7 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
59315932
if (take_rtnl)
59325933
rtnl_lock();
59335934

5935+
mlx5e_psp_register(priv);
59345936
/* update XDP supported features */
59355937
mlx5e_set_xdp_feature(netdev);
59365938

@@ -5943,6 +5945,7 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
59435945
static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
59445946
{
59455947
mlx5e_health_destroy_reporters(priv);
5948+
mlx5e_psp_unregister(priv);
59465949
mlx5e_ktls_cleanup(priv);
59475950
mlx5e_fs_cleanup(priv->fs);
59485951
debugfs_remove_recursive(priv->dfs_root);
@@ -6070,6 +6073,10 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
60706073
if (err)
60716074
mlx5_core_err(mdev, "MACsec initialization failed, %d\n", err);
60726075

6076+
err = mlx5e_psp_init(priv);
6077+
if (err)
6078+
mlx5_core_err(mdev, "PSP initialization failed, %d\n", err);
6079+
60736080
/* Marking the link as currently not needed by the Driver */
60746081
if (!netif_running(netdev))
60756082
mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN);
@@ -6133,6 +6140,7 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
61336140
mlx5e_disable_async_events(priv);
61346141
mlx5_lag_remove_netdev(mdev, priv->netdev);
61356142
mlx5_vxlan_reset_to_default(mdev->vxlan);
6143+
mlx5e_psp_cleanup(priv);
61366144
mlx5e_macsec_cleanup(priv);
61376145
mlx5e_ipsec_cleanup(priv);
61386146
}
@@ -6791,6 +6799,7 @@ static void _mlx5e_remove(struct auxiliary_device *adev)
67916799
* is already unregistered before changing to NIC profile.
67926800
*/
67936801
if (priv->netdev->reg_state == NETREG_REGISTERED) {
6802+
mlx5e_psp_unregister(priv);
67946803
unregister_netdev(priv->netdev);
67956804
_mlx5e_suspend(adev, false);
67966805
} else {

0 commit comments

Comments
 (0)