summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/mellanox/mlx5/core/en_accel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en_accel')
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c62
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h77
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c773
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c29
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c29
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c176
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.h26
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c1393
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.h47
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_stats.c22
15 files changed, 810 insertions, 1854 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
index bac4717548c6..caa34b9c161e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
@@ -138,7 +138,7 @@ static inline bool mlx5e_accel_tx_begin(struct net_device *dev,
}
#endif
-#ifdef CONFIG_MLX5_EN_MACSEC
+#ifdef CONFIG_MLX5_MACSEC
if (unlikely(mlx5e_macsec_skb_is_offload(skb))) {
struct mlx5e_priv *priv = netdev_priv(dev);
@@ -173,7 +173,7 @@ static inline void mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
mlx5e_ipsec_tx_build_eseg(priv, skb, eseg);
#endif
-#ifdef CONFIG_MLX5_EN_MACSEC
+#ifdef CONFIG_MLX5_MACSEC
if (unlikely(mlx5e_macsec_skb_is_offload(skb)))
mlx5e_macsec_tx_build_eseg(priv->macsec, skb, eseg);
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
index 88a5aed9d678..c7d191f66ad1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
@@ -190,6 +190,7 @@ static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft,
in = kvzalloc(inlen, GFP_KERNEL);
if (!in || !ft->g) {
kfree(ft->g);
+ ft->g = NULL;
kvfree(in);
return -ENOMEM;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
index 891d39b4bfd4..7d4ceb9b9c16 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -38,8 +38,10 @@
#include <net/netevent.h>
#include "en.h"
+#include "eswitch.h"
#include "ipsec.h"
#include "ipsec_rxtx.h"
+#include "en_rep.h"
#define MLX5_IPSEC_RESCHED msecs_to_jiffies(1000)
#define MLX5E_IPSEC_TUNNEL_SA XA_MARK_1
@@ -354,6 +356,12 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
mlx5e_ipsec_init_limits(sa_entry, attrs);
mlx5e_ipsec_init_macs(sa_entry, attrs);
+
+ if (x->encap) {
+ attrs->encap = true;
+ attrs->sport = x->encap->encap_sport;
+ attrs->dport = x->encap->encap_dport;
+ }
}
static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
@@ -387,8 +395,25 @@ static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
return -EINVAL;
}
if (x->encap) {
- NL_SET_ERR_MSG_MOD(extack, "Encapsulated xfrm state may not be offloaded");
- return -EINVAL;
+ if (!(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ESPINUDP)) {
+ NL_SET_ERR_MSG_MOD(extack, "Encapsulation is not supported");
+ return -EINVAL;
+ }
+
+ if (x->encap->encap_type != UDP_ENCAP_ESPINUDP) {
+ NL_SET_ERR_MSG_MOD(extack, "Encapsulation other than UDP is not supported");
+ return -EINVAL;
+ }
+
+ if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) {
+ NL_SET_ERR_MSG_MOD(extack, "Encapsulation is supported in packet offload mode only");
+ return -EINVAL;
+ }
+
+ if (x->props.mode != XFRM_MODE_TRANSPORT) {
+ NL_SET_ERR_MSG_MOD(extack, "Encapsulation is supported in transport mode only");
+ return -EINVAL;
+ }
}
if (!x->aead) {
NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states without aead");
@@ -416,9 +441,9 @@ static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
return -EINVAL;
}
- if (x->sel.proto != IPPROTO_IP &&
- (x->sel.proto != IPPROTO_UDP || x->xso.dir != XFRM_DEV_OFFLOAD_OUT)) {
- NL_SET_ERR_MSG_MOD(extack, "Device does not support upper protocol other than UDP, and only Tx direction");
+ if (x->sel.proto != IPPROTO_IP && x->sel.proto != IPPROTO_UDP &&
+ x->sel.proto != IPPROTO_TCP) {
+ NL_SET_ERR_MSG_MOD(extack, "Device does not support upper protocol other than TCP/UDP");
return -EINVAL;
}
@@ -646,6 +671,11 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
if (err)
goto err_xfrm;
+ if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
+ err = -EBUSY;
+ goto err_xfrm;
+ }
+
/* check esn */
if (x->props.flags & XFRM_STATE_ESN)
mlx5e_ipsec_update_esn_state(sa_entry);
@@ -654,7 +684,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
err = mlx5_ipsec_create_work(sa_entry);
if (err)
- goto err_xfrm;
+ goto unblock_ipsec;
err = mlx5e_ipsec_create_dwork(sa_entry);
if (err)
@@ -711,6 +741,8 @@ release_work:
if (sa_entry->work)
kfree(sa_entry->work->data);
kfree(sa_entry->work);
+unblock_ipsec:
+ mlx5_eswitch_unblock_ipsec(priv->mdev);
err_xfrm:
kfree(sa_entry);
NL_SET_ERR_MSG_WEAK_MOD(extack, "Device failed to offload this state");
@@ -740,6 +772,7 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
{
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
+ struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
goto sa_entry_free;
@@ -756,6 +789,7 @@ static void mlx5e_xfrm_free_state(struct xfrm_state *x)
if (sa_entry->work)
kfree(sa_entry->work->data);
kfree(sa_entry->work);
+ mlx5_eswitch_unblock_ipsec(ipsec->mdev);
sa_entry_free:
kfree(sa_entry);
}
@@ -835,6 +869,7 @@ void mlx5e_ipsec_init(struct mlx5e_priv *priv)
goto clear_aso;
}
+ ipsec->is_uplink_rep = mlx5e_is_uplink_rep(priv);
ret = mlx5e_accel_ipsec_fs_init(ipsec);
if (ret)
goto err_fs_init;
@@ -958,9 +993,10 @@ static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,
return -EINVAL;
}
- if (sel->proto != IPPROTO_IP &&
- (sel->proto != IPPROTO_UDP || x->xdo.dir != XFRM_DEV_OFFLOAD_OUT)) {
- NL_SET_ERR_MSG_MOD(extack, "Device does not support upper protocol other than UDP, and only Tx direction");
+ if (x->selector.proto != IPPROTO_IP &&
+ x->selector.proto != IPPROTO_UDP &&
+ x->selector.proto != IPPROTO_TCP) {
+ NL_SET_ERR_MSG_MOD(extack, "Device does not support upper protocol other than TCP/UDP");
return -EINVAL;
}
@@ -1029,6 +1065,11 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
pol_entry->x = x;
pol_entry->ipsec = priv->ipsec;
+ if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
+ err = -EBUSY;
+ goto ipsec_busy;
+ }
+
mlx5e_ipsec_build_accel_pol_attrs(pol_entry, &pol_entry->attrs);
err = mlx5e_accel_ipsec_fs_add_pol(pol_entry);
if (err)
@@ -1038,6 +1079,8 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
return 0;
err_fs:
+ mlx5_eswitch_unblock_ipsec(priv->mdev);
+ipsec_busy:
kfree(pol_entry);
NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy");
return err;
@@ -1048,6 +1091,7 @@ static void mlx5e_xfrm_del_policy(struct xfrm_policy *x)
struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x);
mlx5e_accel_ipsec_fs_del_pol(pol_entry);
+ mlx5_eswitch_unblock_ipsec(pol_entry->ipsec->mdev);
}
static void mlx5e_xfrm_free_policy(struct xfrm_policy *x)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
index 4e9887171508..9e7c42c2f77b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
@@ -94,13 +94,20 @@ struct mlx5_accel_esp_xfrm_attrs {
u8 dir : 2;
u8 type : 2;
u8 drop : 1;
+ u8 encap : 1;
u8 family;
struct mlx5_replay_esn replay_esn;
u32 authsize;
u32 reqid;
struct mlx5_ipsec_lft lft;
- u8 smac[ETH_ALEN];
- u8 dmac[ETH_ALEN];
+ union {
+ u8 smac[ETH_ALEN];
+ __be16 sport;
+ };
+ union {
+ u8 dmac[ETH_ALEN];
+ __be16 dport;
+ };
};
enum mlx5_ipsec_cap {
@@ -110,6 +117,7 @@ enum mlx5_ipsec_cap {
MLX5_IPSEC_CAP_ROCE = 1 << 3,
MLX5_IPSEC_CAP_PRIO = 1 << 4,
MLX5_IPSEC_CAP_TUNNEL = 1 << 5,
+ MLX5_IPSEC_CAP_ESPINUDP = 1 << 6,
};
struct mlx5e_priv;
@@ -135,7 +143,7 @@ struct mlx5e_ipsec_sw_stats {
atomic64_t ipsec_tx_drop_trailer;
};
-struct mlx5e_ipsec_rx;
+struct mlx5e_ipsec_fc;
struct mlx5e_ipsec_tx;
struct mlx5e_ipsec_work {
@@ -161,6 +169,58 @@ struct mlx5e_ipsec_aso {
spinlock_t lock;
};
+struct mlx5e_ipsec_rx_create_attr {
+ struct mlx5_flow_namespace *ns;
+ struct mlx5_ttc_table *ttc;
+ u32 family;
+ int prio;
+ int pol_level;
+ int sa_level;
+ int status_level;
+ enum mlx5_flow_namespace_type chains_ns;
+};
+
+struct mlx5e_ipsec_ft {
+ struct mutex mutex; /* Protect changes to this struct */
+ struct mlx5_flow_table *pol;
+ struct mlx5_flow_table *sa;
+ struct mlx5_flow_table *status;
+ u32 refcnt;
+};
+
+struct mlx5e_ipsec_rule {
+ struct mlx5_flow_handle *rule;
+ struct mlx5_modify_hdr *modify_hdr;
+ struct mlx5_pkt_reformat *pkt_reformat;
+ struct mlx5_fc *fc;
+};
+
+struct mlx5e_ipsec_miss {
+ struct mlx5_flow_group *group;
+ struct mlx5_flow_handle *rule;
+};
+
+struct mlx5e_ipsec_rx {
+ struct mlx5e_ipsec_ft ft;
+ struct mlx5e_ipsec_miss pol;
+ struct mlx5e_ipsec_miss sa;
+ struct mlx5e_ipsec_rule status;
+ struct mlx5e_ipsec_miss status_drop;
+ struct mlx5_fc *status_drop_cnt;
+ struct mlx5e_ipsec_fc *fc;
+ struct mlx5_fs_chains *chains;
+ u8 allow_tunnel_mode : 1;
+ struct xarray ipsec_obj_id_map;
+};
+
+struct mlx5e_ipsec_tx_create_attr {
+ int prio;
+ int pol_level;
+ int sa_level;
+ int cnt_level;
+ enum mlx5_flow_namespace_type chains_ns;
+};
+
struct mlx5e_ipsec {
struct mlx5_core_dev *mdev;
struct xarray sadb;
@@ -170,11 +230,14 @@ struct mlx5e_ipsec {
struct mlx5e_flow_steering *fs;
struct mlx5e_ipsec_rx *rx_ipv4;
struct mlx5e_ipsec_rx *rx_ipv6;
+ struct mlx5e_ipsec_rx *rx_esw;
struct mlx5e_ipsec_tx *tx;
+ struct mlx5e_ipsec_tx *tx_esw;
struct mlx5e_ipsec_aso *aso;
struct notifier_block nb;
struct notifier_block netevent_nb;
struct mlx5_ipsec_fs *roce;
+ u8 is_uplink_rep: 1;
};
struct mlx5e_ipsec_esn_state {
@@ -183,13 +246,6 @@ struct mlx5e_ipsec_esn_state {
u8 overlap: 1;
};
-struct mlx5e_ipsec_rule {
- struct mlx5_flow_handle *rule;
- struct mlx5_modify_hdr *modify_hdr;
- struct mlx5_pkt_reformat *pkt_reformat;
- struct mlx5_fc *fc;
-};
-
struct mlx5e_ipsec_limits {
u64 round;
u8 soft_limit_hit : 1;
@@ -209,6 +265,7 @@ struct mlx5e_ipsec_sa_entry {
struct mlx5e_ipsec_work *work;
struct mlx5e_ipsec_dwork *dwork;
struct mlx5e_ipsec_limits limits;
+ u32 rx_mapped_id;
};
struct mlx5_accel_pol_xfrm_attrs {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
index dbe87bf89c0d..7dba4221993f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
@@ -9,6 +9,8 @@
#include "fs_core.h"
#include "lib/ipsec_fs_roce.h"
#include "lib/fs_chains.h"
+#include "esw/ipsec_fs.h"
+#include "en_rep.h"
#define NUM_IPSEC_FTE BIT(15)
#define MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE 16
@@ -19,32 +21,10 @@ struct mlx5e_ipsec_fc {
struct mlx5_fc *drop;
};
-struct mlx5e_ipsec_ft {
- struct mutex mutex; /* Protect changes to this struct */
- struct mlx5_flow_table *pol;
- struct mlx5_flow_table *sa;
- struct mlx5_flow_table *status;
- u32 refcnt;
-};
-
-struct mlx5e_ipsec_miss {
- struct mlx5_flow_group *group;
- struct mlx5_flow_handle *rule;
-};
-
-struct mlx5e_ipsec_rx {
- struct mlx5e_ipsec_ft ft;
- struct mlx5e_ipsec_miss pol;
- struct mlx5e_ipsec_miss sa;
- struct mlx5e_ipsec_rule status;
- struct mlx5e_ipsec_fc *fc;
- struct mlx5_fs_chains *chains;
- u8 allow_tunnel_mode : 1;
-};
-
struct mlx5e_ipsec_tx {
struct mlx5e_ipsec_ft ft;
struct mlx5e_ipsec_miss pol;
+ struct mlx5e_ipsec_miss sa;
struct mlx5e_ipsec_rule status;
struct mlx5_flow_namespace *ns;
struct mlx5e_ipsec_fc *fc;
@@ -60,14 +40,25 @@ static enum mlx5_traffic_types family2tt(u32 family)
return MLX5_TT_IPV6_IPSEC_ESP;
}
-static struct mlx5e_ipsec_rx *ipsec_rx(struct mlx5e_ipsec *ipsec, u32 family)
+static struct mlx5e_ipsec_rx *ipsec_rx(struct mlx5e_ipsec *ipsec, u32 family, int type)
{
+ if (ipsec->is_uplink_rep && type == XFRM_DEV_OFFLOAD_PACKET)
+ return ipsec->rx_esw;
+
if (family == AF_INET)
return ipsec->rx_ipv4;
return ipsec->rx_ipv6;
}
+static struct mlx5e_ipsec_tx *ipsec_tx(struct mlx5e_ipsec *ipsec, int type)
+{
+ if (ipsec->is_uplink_rep && type == XFRM_DEV_OFFLOAD_PACKET)
+ return ipsec->tx_esw;
+
+ return ipsec->tx;
+}
+
static struct mlx5_fs_chains *
ipsec_chains_create(struct mlx5_core_dev *mdev, struct mlx5_flow_table *miss_ft,
enum mlx5_flow_namespace_type ns, int base_prio,
@@ -238,13 +229,19 @@ out:
return err;
}
-static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
- struct mlx5e_ipsec_rx *rx, u32 family)
+static void ipsec_rx_ft_disconnect(struct mlx5e_ipsec *ipsec, u32 family)
{
struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
- /* disconnect */
mlx5_ttc_fwd_default_dest(ttc, family2tt(family));
+}
+
+static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
+ struct mlx5e_ipsec_rx *rx, u32 family)
+{
+ /* disconnect */
+ if (rx != ipsec->rx_esw)
+ ipsec_rx_ft_disconnect(ipsec, family);
if (rx->chains) {
ipsec_chains_destroy(rx->chains);
@@ -259,51 +256,105 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
mlx5_destroy_flow_table(rx->ft.sa);
if (rx->allow_tunnel_mode)
mlx5_eswitch_unblock_encap(mdev);
- mlx5_del_flow_rules(rx->status.rule);
- mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
+ if (rx == ipsec->rx_esw) {
+ mlx5_esw_ipsec_rx_status_destroy(ipsec, rx);
+ } else {
+ mlx5_del_flow_rules(rx->status.rule);
+ mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
+ }
mlx5_destroy_flow_table(rx->ft.status);
mlx5_ipsec_fs_roce_rx_destroy(ipsec->roce, family);
}
+static void ipsec_rx_create_attr_set(struct mlx5e_ipsec *ipsec,
+ struct mlx5e_ipsec_rx *rx,
+ u32 family,
+ struct mlx5e_ipsec_rx_create_attr *attr)
+{
+ if (rx == ipsec->rx_esw) {
+ /* For packet offload in switchdev mode, RX & TX use FDB namespace */
+ attr->ns = ipsec->tx_esw->ns;
+ mlx5_esw_ipsec_rx_create_attr_set(ipsec, attr);
+ return;
+ }
+
+ attr->ns = mlx5e_fs_get_ns(ipsec->fs, false);
+ attr->ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
+ attr->family = family;
+ attr->prio = MLX5E_NIC_PRIO;
+ attr->pol_level = MLX5E_ACCEL_FS_POL_FT_LEVEL;
+ attr->sa_level = MLX5E_ACCEL_FS_ESP_FT_LEVEL;
+ attr->status_level = MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL;
+ attr->chains_ns = MLX5_FLOW_NAMESPACE_KERNEL;
+}
+
+static int ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ipsec,
+ struct mlx5e_ipsec_rx *rx,
+ struct mlx5e_ipsec_rx_create_attr *attr,
+ struct mlx5_flow_destination *dest)
+{
+ struct mlx5_flow_table *ft;
+ int err;
+
+ if (rx == ipsec->rx_esw)
+ return mlx5_esw_ipsec_rx_status_pass_dest_get(ipsec, dest);
+
+ *dest = mlx5_ttc_get_default_dest(attr->ttc, family2tt(attr->family));
+ err = mlx5_ipsec_fs_roce_rx_create(ipsec->mdev, ipsec->roce, attr->ns, dest,
+ attr->family, MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,
+ attr->prio);
+ if (err)
+ return err;
+
+ ft = mlx5_ipsec_fs_roce_ft_get(ipsec->roce, attr->family);
+ if (ft) {
+ dest->type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+ dest->ft = ft;
+ }
+
+ return 0;
+}
+
+static void ipsec_rx_ft_connect(struct mlx5e_ipsec *ipsec,
+ struct mlx5e_ipsec_rx *rx,
+ struct mlx5e_ipsec_rx_create_attr *attr)
+{
+ struct mlx5_flow_destination dest = {};
+
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+ dest.ft = rx->ft.pol;
+ mlx5_ttc_fwd_dest(attr->ttc, family2tt(attr->family), &dest);
+}
+
static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
struct mlx5e_ipsec_rx *rx, u32 family)
{
- struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(ipsec->fs, false);
- struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
- struct mlx5_flow_destination default_dest;
+ struct mlx5e_ipsec_rx_create_attr attr;
struct mlx5_flow_destination dest[2];
struct mlx5_flow_table *ft;
u32 flags = 0;
int err;
- default_dest = mlx5_ttc_get_default_dest(ttc, family2tt(family));
- err = mlx5_ipsec_fs_roce_rx_create(mdev, ipsec->roce, ns, &default_dest,
- family, MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,
- MLX5E_NIC_PRIO);
+ ipsec_rx_create_attr_set(ipsec, rx, family, &attr);
+
+ err = ipsec_rx_status_pass_dest_get(ipsec, rx, &attr, &dest[0]);
if (err)
return err;
- ft = ipsec_ft_create(ns, MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL,
- MLX5E_NIC_PRIO, 1, 0);
+ ft = ipsec_ft_create(attr.ns, attr.status_level, attr.prio, 1, 0);
if (IS_ERR(ft)) {
err = PTR_ERR(ft);
goto err_fs_ft_status;
}
-
rx->ft.status = ft;
- ft = mlx5_ipsec_fs_roce_ft_get(ipsec->roce, family);
- if (ft) {
- dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
- dest[0].ft = ft;
- } else {
- dest[0] = default_dest;
- }
-
dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
dest[1].counter_id = mlx5_fc_id(rx->fc->cnt);
- err = ipsec_status_rule(mdev, rx, dest);
+ if (rx == ipsec->rx_esw)
+ err = mlx5_esw_ipsec_rx_status_create(ipsec, rx, dest);
+ else
+ err = ipsec_status_rule(mdev, rx, dest);
if (err)
goto err_add;
@@ -312,8 +363,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
rx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
if (rx->allow_tunnel_mode)
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
- ft = ipsec_ft_create(ns, MLX5E_ACCEL_FS_ESP_FT_LEVEL, MLX5E_NIC_PRIO, 2,
- flags);
+ ft = ipsec_ft_create(attr.ns, attr.sa_level, attr.prio, 2, flags);
if (IS_ERR(ft)) {
err = PTR_ERR(ft);
goto err_fs_ft;
@@ -326,9 +376,9 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PRIO) {
rx->chains = ipsec_chains_create(mdev, rx->ft.sa,
- MLX5_FLOW_NAMESPACE_KERNEL,
- MLX5E_NIC_PRIO,
- MLX5E_ACCEL_FS_POL_FT_LEVEL,
+ attr.chains_ns,
+ attr.prio,
+ attr.pol_level,
&rx->ft.pol);
if (IS_ERR(rx->chains)) {
err = PTR_ERR(rx->chains);
@@ -338,8 +388,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
goto connect;
}
- ft = ipsec_ft_create(ns, MLX5E_ACCEL_FS_POL_FT_LEVEL, MLX5E_NIC_PRIO,
- 2, 0);
+ ft = ipsec_ft_create(attr.ns, attr.pol_level, attr.prio, 2, 0);
if (IS_ERR(ft)) {
err = PTR_ERR(ft);
goto err_pol_ft;
@@ -354,10 +403,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
connect:
/* connect */
- memset(dest, 0x00, sizeof(*dest));
- dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
- dest[0].ft = rx->ft.pol;
- mlx5_ttc_fwd_dest(ttc, family2tt(family), &dest[0]);
+ if (rx != ipsec->rx_esw)
+ ipsec_rx_ft_connect(ipsec, rx, &attr);
return 0;
err_pol_miss:
@@ -387,10 +434,16 @@ static int rx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
if (rx->ft.refcnt)
goto skip;
- err = rx_create(mdev, ipsec, rx, family);
+ err = mlx5_eswitch_block_mode(mdev);
if (err)
return err;
+ err = rx_create(mdev, ipsec, rx, family);
+ if (err) {
+ mlx5_eswitch_unblock_mode(mdev);
+ return err;
+ }
+
skip:
rx->ft.refcnt++;
return 0;
@@ -403,12 +456,14 @@ static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,
return;
rx_destroy(ipsec->mdev, ipsec, rx, family);
+ mlx5_eswitch_unblock_mode(ipsec->mdev);
}
static struct mlx5e_ipsec_rx *rx_ft_get(struct mlx5_core_dev *mdev,
- struct mlx5e_ipsec *ipsec, u32 family)
+ struct mlx5e_ipsec *ipsec, u32 family,
+ int type)
{
- struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family);
+ struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, type);
int err;
mutex_lock(&rx->ft.mutex);
@@ -422,9 +477,9 @@ static struct mlx5e_ipsec_rx *rx_ft_get(struct mlx5_core_dev *mdev,
static struct mlx5_flow_table *rx_ft_get_policy(struct mlx5_core_dev *mdev,
struct mlx5e_ipsec *ipsec,
- u32 family, u32 prio)
+ u32 family, u32 prio, int type)
{
- struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family);
+ struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, type);
struct mlx5_flow_table *ft;
int err;
@@ -449,18 +504,18 @@ err_get:
return ERR_PTR(err);
}
-static void rx_ft_put(struct mlx5e_ipsec *ipsec, u32 family)
+static void rx_ft_put(struct mlx5e_ipsec *ipsec, u32 family, int type)
{
- struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family);
+ struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, type);
mutex_lock(&rx->ft.mutex);
rx_put(ipsec, rx, family);
mutex_unlock(&rx->ft.mutex);
}
-static void rx_ft_put_policy(struct mlx5e_ipsec *ipsec, u32 family, u32 prio)
+static void rx_ft_put_policy(struct mlx5e_ipsec *ipsec, u32 family, u32 prio, int type)
{
- struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family);
+ struct mlx5e_ipsec_rx *rx = ipsec_rx(ipsec, family, type);
mutex_lock(&rx->ft.mutex);
if (rx->chains)
@@ -504,7 +559,7 @@ err_rule:
}
/* IPsec TX flow steering */
-static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
+static void tx_destroy(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
struct mlx5_ipsec_fs *roce)
{
mlx5_ipsec_fs_roce_tx_destroy(roce);
@@ -516,22 +571,45 @@ static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
mlx5_destroy_flow_table(tx->ft.pol);
}
+ if (tx == ipsec->tx_esw) {
+ mlx5_del_flow_rules(tx->sa.rule);
+ mlx5_destroy_flow_group(tx->sa.group);
+ }
mlx5_destroy_flow_table(tx->ft.sa);
if (tx->allow_tunnel_mode)
- mlx5_eswitch_unblock_encap(mdev);
+ mlx5_eswitch_unblock_encap(ipsec->mdev);
mlx5_del_flow_rules(tx->status.rule);
mlx5_destroy_flow_table(tx->ft.status);
}
-static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
+static void ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec,
+ struct mlx5e_ipsec_tx *tx,
+ struct mlx5e_ipsec_tx_create_attr *attr)
+{
+ if (tx == ipsec->tx_esw) {
+ mlx5_esw_ipsec_tx_create_attr_set(ipsec, attr);
+ return;
+ }
+
+ attr->prio = 0;
+ attr->pol_level = 0;
+ attr->sa_level = 1;
+ attr->cnt_level = 2;
+ attr->chains_ns = MLX5_FLOW_NAMESPACE_EGRESS_IPSEC;
+}
+
+static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
struct mlx5_ipsec_fs *roce)
{
+ struct mlx5_core_dev *mdev = ipsec->mdev;
+ struct mlx5e_ipsec_tx_create_attr attr;
struct mlx5_flow_destination dest = {};
struct mlx5_flow_table *ft;
u32 flags = 0;
int err;
- ft = ipsec_ft_create(tx->ns, 2, 0, 1, 0);
+ ipsec_tx_create_attr_set(ipsec, tx, &attr);
+ ft = ipsec_ft_create(tx->ns, attr.cnt_level, attr.prio, 1, 0);
if (IS_ERR(ft))
return PTR_ERR(ft);
tx->ft.status = ft;
@@ -544,16 +622,25 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
tx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
if (tx->allow_tunnel_mode)
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
- ft = ipsec_ft_create(tx->ns, 1, 0, 4, flags);
+ ft = ipsec_ft_create(tx->ns, attr.sa_level, attr.prio, 4, flags);
if (IS_ERR(ft)) {
err = PTR_ERR(ft);
goto err_sa_ft;
}
tx->ft.sa = ft;
+ if (tx == ipsec->tx_esw) {
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+ dest.vport.num = MLX5_VPORT_UPLINK;
+ err = ipsec_miss_create(mdev, tx->ft.sa, &tx->sa, &dest);
+ if (err)
+ goto err_sa_miss;
+ memset(&dest, 0, sizeof(dest));
+ }
+
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PRIO) {
tx->chains = ipsec_chains_create(
- mdev, tx->ft.sa, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC, 0, 0,
+ mdev, tx->ft.sa, attr.chains_ns, attr.prio, attr.pol_level,
&tx->ft.pol);
if (IS_ERR(tx->chains)) {
err = PTR_ERR(tx->chains);
@@ -563,7 +650,7 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
goto connect_roce;
}
- ft = ipsec_ft_create(tx->ns, 0, 0, 2, 0);
+ ft = ipsec_ft_create(tx->ns, attr.pol_level, attr.prio, 2, 0);
if (IS_ERR(ft)) {
err = PTR_ERR(ft);
goto err_pol_ft;
@@ -592,6 +679,11 @@ err_roce:
mlx5_destroy_flow_table(tx->ft.pol);
}
err_pol_ft:
+ if (tx == ipsec->tx_esw) {
+ mlx5_del_flow_rules(tx->sa.rule);
+ mlx5_destroy_flow_group(tx->sa.group);
+ }
+err_sa_miss:
mlx5_destroy_flow_table(tx->ft.sa);
err_sa_ft:
if (tx->allow_tunnel_mode)
@@ -602,6 +694,25 @@ err_status_rule:
return err;
}
+static void ipsec_esw_tx_ft_policy_set(struct mlx5_core_dev *mdev,
+ struct mlx5_flow_table *ft)
+{
+#ifdef CONFIG_MLX5_ESWITCH
+ struct mlx5_eswitch *esw = mdev->priv.eswitch;
+ struct mlx5e_rep_priv *uplink_rpriv;
+ struct mlx5e_priv *priv;
+
+ esw->offloads.ft_ipsec_tx_pol = ft;
+ uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
+ priv = netdev_priv(uplink_rpriv->netdev);
+ if (!priv->channels.num)
+ return;
+
+ mlx5e_rep_deactivate_channels(priv);
+ mlx5e_rep_activate_channels(priv);
+#endif
+}
+
static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
struct mlx5e_ipsec_tx *tx)
{
@@ -610,10 +721,19 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
if (tx->ft.refcnt)
goto skip;
- err = tx_create(mdev, tx, ipsec->roce);
+ err = mlx5_eswitch_block_mode(mdev);
if (err)
return err;
+ err = tx_create(ipsec, tx, ipsec->roce);
+ if (err) {
+ mlx5_eswitch_unblock_mode(mdev);
+ return err;
+ }
+
+ if (tx == ipsec->tx_esw)
+ ipsec_esw_tx_ft_policy_set(mdev, tx->ft.pol);
+
skip:
tx->ft.refcnt++;
return 0;
@@ -624,14 +744,20 @@ static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)
if (--tx->ft.refcnt)
return;
- tx_destroy(ipsec->mdev, tx, ipsec->roce);
+ if (tx == ipsec->tx_esw) {
+ mlx5_esw_ipsec_restore_dest_uplink(ipsec->mdev);
+ ipsec_esw_tx_ft_policy_set(ipsec->mdev, NULL);
+ }
+
+ tx_destroy(ipsec, tx, ipsec->roce);
+ mlx5_eswitch_unblock_mode(ipsec->mdev);
}
static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,
struct mlx5e_ipsec *ipsec,
- u32 prio)
+ u32 prio, int type)
{
- struct mlx5e_ipsec_tx *tx = ipsec->tx;
+ struct mlx5e_ipsec_tx *tx = ipsec_tx(ipsec, type);
struct mlx5_flow_table *ft;
int err;
@@ -657,9 +783,9 @@ err_get:
}
static struct mlx5e_ipsec_tx *tx_ft_get(struct mlx5_core_dev *mdev,
- struct mlx5e_ipsec *ipsec)
+ struct mlx5e_ipsec *ipsec, int type)
{
- struct mlx5e_ipsec_tx *tx = ipsec->tx;
+ struct mlx5e_ipsec_tx *tx = ipsec_tx(ipsec, type);
int err;
mutex_lock(&tx->ft.mutex);
@@ -671,18 +797,18 @@ static struct mlx5e_ipsec_tx *tx_ft_get(struct mlx5_core_dev *mdev,
return tx;
}
-static void tx_ft_put(struct mlx5e_ipsec *ipsec)
+static void tx_ft_put(struct mlx5e_ipsec *ipsec, int type)
{
- struct mlx5e_ipsec_tx *tx = ipsec->tx;
+ struct mlx5e_ipsec_tx *tx = ipsec_tx(ipsec, type);
mutex_lock(&tx->ft.mutex);
tx_put(ipsec, tx);
mutex_unlock(&tx->ft.mutex);
}
-static void tx_ft_put_policy(struct mlx5e_ipsec *ipsec, u32 prio)
+static void tx_ft_put_policy(struct mlx5e_ipsec *ipsec, u32 prio, int type)
{
- struct mlx5e_ipsec_tx *tx = ipsec->tx;
+ struct mlx5e_ipsec_tx *tx = ipsec_tx(ipsec, type);
mutex_lock(&tx->ft.mutex);
if (tx->chains)
@@ -782,43 +908,75 @@ static void setup_fte_reg_a(struct mlx5_flow_spec *spec)
misc_parameters_2.metadata_reg_a, MLX5_ETH_WQE_FT_META_IPSEC);
}
-static void setup_fte_reg_c0(struct mlx5_flow_spec *spec, u32 reqid)
+static void setup_fte_reg_c4(struct mlx5_flow_spec *spec, u32 reqid)
{
/* Pass policy check before choosing this SA */
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2;
- MLX5_SET(fte_match_param, spec->match_criteria,
- misc_parameters_2.metadata_reg_c_0, reqid);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ misc_parameters_2.metadata_reg_c_4);
MLX5_SET(fte_match_param, spec->match_value,
- misc_parameters_2.metadata_reg_c_0, reqid);
+ misc_parameters_2.metadata_reg_c_4, reqid);
}
static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upspec *upspec)
{
- if (upspec->proto != IPPROTO_UDP)
+ switch (upspec->proto) {
+ case IPPROTO_UDP:
+ if (upspec->dport) {
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria,
+ udp_dport, upspec->dport_mask);
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_value,
+ udp_dport, upspec->dport);
+ }
+ if (upspec->sport) {
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria,
+ udp_sport, upspec->sport_mask);
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_value,
+ udp_sport, upspec->sport);
+ }
+ break;
+ case IPPROTO_TCP:
+ if (upspec->dport) {
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria,
+ tcp_dport, upspec->dport_mask);
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_value,
+ tcp_dport, upspec->dport);
+ }
+ if (upspec->sport) {
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria,
+ tcp_sport, upspec->sport_mask);
+ MLX5_SET(fte_match_set_lyr_2_4, spec->match_value,
+ tcp_sport, upspec->sport);
+ }
+ break;
+ default:
return;
+ }
spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, spec->match_criteria, ip_protocol);
MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, ip_protocol, upspec->proto);
- if (upspec->dport) {
- MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport,
- upspec->dport_mask);
- MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->dport);
- }
+}
- if (upspec->sport) {
- MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport,
- upspec->sport_mask);
- MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->sport);
- }
+static enum mlx5_flow_namespace_type ipsec_fs_get_ns(struct mlx5e_ipsec *ipsec,
+ int type, u8 dir)
+{
+ if (ipsec->is_uplink_rep && type == XFRM_DEV_OFFLOAD_PACKET)
+ return MLX5_FLOW_NAMESPACE_FDB;
+
+ if (dir == XFRM_DEV_OFFLOAD_IN)
+ return MLX5_FLOW_NAMESPACE_KERNEL;
+
+ return MLX5_FLOW_NAMESPACE_EGRESS;
}
-static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,
+static int setup_modify_header(struct mlx5e_ipsec *ipsec, int type, u32 val, u8 dir,
struct mlx5_flow_act *flow_act)
{
+ enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns(ipsec, type, dir);
u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
- enum mlx5_flow_namespace_type ns_type;
+ struct mlx5_core_dev *mdev = ipsec->mdev;
struct mlx5_modify_hdr *modify_hdr;
MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);
@@ -826,12 +984,10 @@ static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,
case XFRM_DEV_OFFLOAD_IN:
MLX5_SET(set_action_in, action, field,
MLX5_ACTION_IN_FIELD_METADATA_REG_B);
- ns_type = MLX5_FLOW_NAMESPACE_KERNEL;
break;
case XFRM_DEV_OFFLOAD_OUT:
MLX5_SET(set_action_in, action, field,
- MLX5_ACTION_IN_FIELD_METADATA_REG_C_0);
- ns_type = MLX5_FLOW_NAMESPACE_EGRESS;
+ MLX5_ACTION_IN_FIELD_METADATA_REG_C_4);
break;
default:
return -EINVAL;
@@ -951,37 +1107,70 @@ free_reformatbf:
return -EINVAL;
}
+static int get_reformat_type(struct mlx5_accel_esp_xfrm_attrs *attrs)
+{
+ switch (attrs->dir) {
+ case XFRM_DEV_OFFLOAD_IN:
+ if (attrs->encap)
+ return MLX5_REFORMAT_TYPE_DEL_ESP_TRANSPORT_OVER_UDP;
+ return MLX5_REFORMAT_TYPE_DEL_ESP_TRANSPORT;
+ case XFRM_DEV_OFFLOAD_OUT:
+ if (attrs->family == AF_INET) {
+ if (attrs->encap)
+ return MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_UDPV4;
+ return MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV4;
+ }
+
+ if (attrs->encap)
+ return MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_UDPV6;
+ return MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV6;
+ default:
+ WARN_ON(true);
+ }
+
+ return -EINVAL;
+}
+
static int
setup_pkt_transport_reformat(struct mlx5_accel_esp_xfrm_attrs *attrs,
struct mlx5_pkt_reformat_params *reformat_params)
{
- u8 *reformatbf;
+ struct udphdr *udphdr;
+ char *reformatbf;
+ size_t bfflen;
__be32 spi;
+ void *hdr;
+
+ reformat_params->type = get_reformat_type(attrs);
+ if (reformat_params->type < 0)
+ return reformat_params->type;
switch (attrs->dir) {
case XFRM_DEV_OFFLOAD_IN:
- reformat_params->type = MLX5_REFORMAT_TYPE_DEL_ESP_TRANSPORT;
break;
case XFRM_DEV_OFFLOAD_OUT:
- if (attrs->family == AF_INET)
- reformat_params->type =
- MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV4;
- else
- reformat_params->type =
- MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV6;
-
- reformatbf = kzalloc(MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE,
- GFP_KERNEL);
+ bfflen = MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE;
+ if (attrs->encap)
+ bfflen += sizeof(*udphdr);
+
+ reformatbf = kzalloc(bfflen, GFP_KERNEL);
if (!reformatbf)
return -ENOMEM;
+ hdr = reformatbf;
+ if (attrs->encap) {
+ udphdr = (struct udphdr *)reformatbf;
+ udphdr->source = attrs->sport;
+ udphdr->dest = attrs->dport;
+ hdr += sizeof(*udphdr);
+ }
+
/* convert to network format */
spi = htonl(attrs->spi);
- memcpy(reformatbf, &spi, sizeof(spi));
+ memcpy(hdr, &spi, sizeof(spi));
reformat_params->param_0 = attrs->authsize;
- reformat_params->size =
- MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE;
+ reformat_params->size = bfflen;
reformat_params->data = reformatbf;
break;
default:
@@ -991,26 +1180,17 @@ setup_pkt_transport_reformat(struct mlx5_accel_esp_xfrm_attrs *attrs,
return 0;
}
-static int setup_pkt_reformat(struct mlx5_core_dev *mdev,
+static int setup_pkt_reformat(struct mlx5e_ipsec *ipsec,
struct mlx5_accel_esp_xfrm_attrs *attrs,
struct mlx5_flow_act *flow_act)
{
+ enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns(ipsec, attrs->type,
+ attrs->dir);
struct mlx5_pkt_reformat_params reformat_params = {};
+ struct mlx5_core_dev *mdev = ipsec->mdev;
struct mlx5_pkt_reformat *pkt_reformat;
- enum mlx5_flow_namespace_type ns_type;
int ret;
- switch (attrs->dir) {
- case XFRM_DEV_OFFLOAD_IN:
- ns_type = MLX5_FLOW_NAMESPACE_KERNEL;
- break;
- case XFRM_DEV_OFFLOAD_OUT:
- ns_type = MLX5_FLOW_NAMESPACE_EGRESS;
- break;
- default:
- return -EINVAL;
- }
-
switch (attrs->mode) {
case XFRM_MODE_TRANSPORT:
ret = setup_pkt_transport_reformat(attrs, &reformat_params);
@@ -1047,9 +1227,9 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5_flow_spec *spec;
struct mlx5e_ipsec_rx *rx;
struct mlx5_fc *counter;
- int err;
+ int err = 0;
- rx = rx_ft_get(mdev, ipsec, attrs->family);
+ rx = rx_ft_get(mdev, ipsec, attrs->family, attrs->type);
if (IS_ERR(rx))
return PTR_ERR(rx);
@@ -1067,15 +1247,21 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
setup_fte_spi(spec, attrs->spi);
setup_fte_esp(spec);
setup_fte_no_frags(spec);
+ setup_fte_upper_proto_match(spec, &attrs->upspec);
+
+ if (rx != ipsec->rx_esw)
+ err = setup_modify_header(ipsec, attrs->type,
+ sa_entry->ipsec_obj_id | BIT(31),
+ XFRM_DEV_OFFLOAD_IN, &flow_act);
+ else
+ err = mlx5_esw_ipsec_rx_setup_modify_header(sa_entry, &flow_act);
- err = setup_modify_header(mdev, sa_entry->ipsec_obj_id | BIT(31),
- XFRM_DEV_OFFLOAD_IN, &flow_act);
if (err)
goto err_mod_header;
switch (attrs->type) {
case XFRM_DEV_OFFLOAD_PACKET:
- err = setup_pkt_reformat(mdev, attrs, &flow_act);
+ err = setup_pkt_reformat(ipsec, attrs, &flow_act);
if (err)
goto err_pkt_reformat;
break;
@@ -1125,7 +1311,7 @@ err_pkt_reformat:
err_mod_header:
kvfree(spec);
err_alloc:
- rx_ft_put(ipsec, attrs->family);
+ rx_ft_put(ipsec, attrs->family, attrs->type);
return err;
}
@@ -1142,7 +1328,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5_fc *counter;
int err;
- tx = tx_ft_get(mdev, ipsec);
+ tx = tx_ft_get(mdev, ipsec, attrs->type);
if (IS_ERR(tx))
return PTR_ERR(tx);
@@ -1168,8 +1354,8 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
break;
case XFRM_DEV_OFFLOAD_PACKET:
if (attrs->reqid)
- setup_fte_reg_c0(spec, attrs->reqid);
- err = setup_pkt_reformat(mdev, attrs, &flow_act);
+ setup_fte_reg_c4(spec, attrs->reqid);
+ err = setup_pkt_reformat(ipsec, attrs, &flow_act);
if (err)
goto err_pkt_reformat;
break;
@@ -1218,7 +1404,7 @@ err_add_cnt:
err_pkt_reformat:
kvfree(spec);
err_alloc:
- tx_ft_put(ipsec);
+ tx_ft_put(ipsec, attrs->type);
return err;
}
@@ -1226,15 +1412,16 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
{
struct mlx5_accel_pol_xfrm_attrs *attrs = &pol_entry->attrs;
struct mlx5_core_dev *mdev = mlx5e_ipsec_pol2dev(pol_entry);
- struct mlx5e_ipsec_tx *tx = pol_entry->ipsec->tx;
+ struct mlx5e_ipsec *ipsec = pol_entry->ipsec;
struct mlx5_flow_destination dest[2] = {};
struct mlx5_flow_act flow_act = {};
struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec;
struct mlx5_flow_table *ft;
+ struct mlx5e_ipsec_tx *tx;
int err, dstn = 0;
- ft = tx_ft_get_policy(mdev, pol_entry->ipsec, attrs->prio);
+ ft = tx_ft_get_policy(mdev, ipsec, attrs->prio, attrs->type);
if (IS_ERR(ft))
return PTR_ERR(ft);
@@ -1244,6 +1431,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
goto err_alloc;
}
+ tx = ipsec_tx(ipsec, attrs->type);
if (attrs->family == AF_INET)
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
else
@@ -1258,7 +1446,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
if (!attrs->reqid)
break;
- err = setup_modify_header(mdev, attrs->reqid,
+ err = setup_modify_header(ipsec, attrs->type, attrs->reqid,
XFRM_DEV_OFFLOAD_OUT, &flow_act);
if (err)
goto err_mod_header;
@@ -1277,6 +1465,8 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
}
flow_act.flags |= FLOW_ACT_NO_APPEND;
+ if (tx == ipsec->tx_esw && tx->chains)
+ flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
dest[dstn].ft = tx->ft.sa;
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dstn++;
@@ -1298,7 +1488,7 @@ err_action:
err_mod_header:
kvfree(spec);
err_alloc:
- tx_ft_put_policy(pol_entry->ipsec, attrs->prio);
+ tx_ft_put_policy(ipsec, attrs->prio, attrs->type);
return err;
}
@@ -1306,6 +1496,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
{
struct mlx5_accel_pol_xfrm_attrs *attrs = &pol_entry->attrs;
struct mlx5_core_dev *mdev = mlx5e_ipsec_pol2dev(pol_entry);
+ struct mlx5e_ipsec *ipsec = pol_entry->ipsec;
struct mlx5_flow_destination dest[2];
struct mlx5_flow_act flow_act = {};
struct mlx5_flow_handle *rule;
@@ -1314,11 +1505,12 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
struct mlx5e_ipsec_rx *rx;
int err, dstn = 0;
- ft = rx_ft_get_policy(mdev, pol_entry->ipsec, attrs->family, attrs->prio);
+ ft = rx_ft_get_policy(mdev, pol_entry->ipsec, attrs->family, attrs->prio,
+ attrs->type);
if (IS_ERR(ft))
return PTR_ERR(ft);
- rx = ipsec_rx(pol_entry->ipsec, attrs->family);
+ rx = ipsec_rx(pol_entry->ipsec, attrs->family, attrs->type);
spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
if (!spec) {
@@ -1332,6 +1524,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
setup_fte_no_frags(spec);
+ setup_fte_upper_proto_match(spec, &attrs->upspec);
switch (attrs->action) {
case XFRM_POLICY_ALLOW:
@@ -1350,6 +1543,8 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
}
flow_act.flags |= FLOW_ACT_NO_APPEND;
+ if (rx == ipsec->rx_esw && rx->chains)
+ flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest[dstn].ft = rx->ft.sa;
dstn++;
@@ -1367,88 +1562,110 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
err_action:
kvfree(spec);
err_alloc:
- rx_ft_put_policy(pol_entry->ipsec, attrs->family, attrs->prio);
+ rx_ft_put_policy(pol_entry->ipsec, attrs->family, attrs->prio, attrs->type);
return err;
}
+static void ipsec_fs_destroy_single_counter(struct mlx5_core_dev *mdev,
+ struct mlx5e_ipsec_fc *fc)
+{
+ mlx5_fc_destroy(mdev, fc->drop);
+ mlx5_fc_destroy(mdev, fc->cnt);
+ kfree(fc);
+}
+
static void ipsec_fs_destroy_counters(struct mlx5e_ipsec *ipsec)
{
- struct mlx5e_ipsec_rx *rx_ipv4 = ipsec->rx_ipv4;
struct mlx5_core_dev *mdev = ipsec->mdev;
- struct mlx5e_ipsec_tx *tx = ipsec->tx;
- mlx5_fc_destroy(mdev, tx->fc->drop);
- mlx5_fc_destroy(mdev, tx->fc->cnt);
- kfree(tx->fc);
- mlx5_fc_destroy(mdev, rx_ipv4->fc->drop);
- mlx5_fc_destroy(mdev, rx_ipv4->fc->cnt);
- kfree(rx_ipv4->fc);
+ ipsec_fs_destroy_single_counter(mdev, ipsec->tx->fc);
+ ipsec_fs_destroy_single_counter(mdev, ipsec->rx_ipv4->fc);
+ if (ipsec->is_uplink_rep) {
+ ipsec_fs_destroy_single_counter(mdev, ipsec->tx_esw->fc);
+ ipsec_fs_destroy_single_counter(mdev, ipsec->rx_esw->fc);
+ }
}
-static int ipsec_fs_init_counters(struct mlx5e_ipsec *ipsec)
+static struct mlx5e_ipsec_fc *ipsec_fs_init_single_counter(struct mlx5_core_dev *mdev)
{
- struct mlx5e_ipsec_rx *rx_ipv4 = ipsec->rx_ipv4;
- struct mlx5e_ipsec_rx *rx_ipv6 = ipsec->rx_ipv6;
- struct mlx5_core_dev *mdev = ipsec->mdev;
- struct mlx5e_ipsec_tx *tx = ipsec->tx;
struct mlx5e_ipsec_fc *fc;
struct mlx5_fc *counter;
int err;
- fc = kzalloc(sizeof(*rx_ipv4->fc), GFP_KERNEL);
+ fc = kzalloc(sizeof(*fc), GFP_KERNEL);
if (!fc)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
- /* Both IPv4 and IPv6 point to same flow counters struct. */
- rx_ipv4->fc = fc;
- rx_ipv6->fc = fc;
counter = mlx5_fc_create(mdev, false);
if (IS_ERR(counter)) {
err = PTR_ERR(counter);
- goto err_rx_cnt;
+ goto err_cnt;
}
-
fc->cnt = counter;
+
counter = mlx5_fc_create(mdev, false);
if (IS_ERR(counter)) {
err = PTR_ERR(counter);
- goto err_rx_drop;
+ goto err_drop;
}
-
fc->drop = counter;
- fc = kzalloc(sizeof(*tx->fc), GFP_KERNEL);
- if (!fc) {
- err = -ENOMEM;
- goto err_tx_fc;
+
+ return fc;
+
+err_drop:
+ mlx5_fc_destroy(mdev, fc->cnt);
+err_cnt:
+ kfree(fc);
+ return ERR_PTR(err);
+}
+
+static int ipsec_fs_init_counters(struct mlx5e_ipsec *ipsec)
+{
+ struct mlx5_core_dev *mdev = ipsec->mdev;
+ struct mlx5e_ipsec_fc *fc;
+ int err;
+
+ fc = ipsec_fs_init_single_counter(mdev);
+ if (IS_ERR(fc)) {
+ err = PTR_ERR(fc);
+ goto err_rx_cnt;
}
+ ipsec->rx_ipv4->fc = fc;
- tx->fc = fc;
- counter = mlx5_fc_create(mdev, false);
- if (IS_ERR(counter)) {
- err = PTR_ERR(counter);
+ fc = ipsec_fs_init_single_counter(mdev);
+ if (IS_ERR(fc)) {
+ err = PTR_ERR(fc);
goto err_tx_cnt;
}
+ ipsec->tx->fc = fc;
- fc->cnt = counter;
- counter = mlx5_fc_create(mdev, false);
- if (IS_ERR(counter)) {
- err = PTR_ERR(counter);
- goto err_tx_drop;
+ if (ipsec->is_uplink_rep) {
+ fc = ipsec_fs_init_single_counter(mdev);
+ if (IS_ERR(fc)) {
+ err = PTR_ERR(fc);
+ goto err_rx_esw_cnt;
+ }
+ ipsec->rx_esw->fc = fc;
+
+ fc = ipsec_fs_init_single_counter(mdev);
+ if (IS_ERR(fc)) {
+ err = PTR_ERR(fc);
+ goto err_tx_esw_cnt;
+ }
+ ipsec->tx_esw->fc = fc;
}
- fc->drop = counter;
+ /* Both IPv4 and IPv6 point to same flow counters struct. */
+ ipsec->rx_ipv6->fc = ipsec->rx_ipv4->fc;
return 0;
-err_tx_drop:
- mlx5_fc_destroy(mdev, tx->fc->cnt);
+err_tx_esw_cnt:
+ ipsec_fs_destroy_single_counter(mdev, ipsec->rx_esw->fc);
+err_rx_esw_cnt:
+ ipsec_fs_destroy_single_counter(mdev, ipsec->tx->fc);
err_tx_cnt:
- kfree(tx->fc);
-err_tx_fc:
- mlx5_fc_destroy(mdev, rx_ipv4->fc->drop);
-err_rx_drop:
- mlx5_fc_destroy(mdev, rx_ipv4->fc->cnt);
+ ipsec_fs_destroy_single_counter(mdev, ipsec->rx_ipv4->fc);
err_rx_cnt:
- kfree(rx_ipv4->fc);
return err;
}
@@ -1458,6 +1675,7 @@ void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, void *ipsec_stats)
struct mlx5e_ipsec *ipsec = priv->ipsec;
struct mlx5e_ipsec_hw_stats *stats;
struct mlx5e_ipsec_fc *fc;
+ u64 packets, bytes;
stats = (struct mlx5e_ipsec_hw_stats *)ipsec_stats;
@@ -1479,14 +1697,94 @@ void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, void *ipsec_stats)
mlx5_fc_query(mdev, fc->cnt, &stats->ipsec_tx_pkts, &stats->ipsec_tx_bytes);
mlx5_fc_query(mdev, fc->drop, &stats->ipsec_tx_drop_pkts,
&stats->ipsec_tx_drop_bytes);
+
+ if (ipsec->is_uplink_rep) {
+ fc = ipsec->rx_esw->fc;
+ if (!mlx5_fc_query(mdev, fc->cnt, &packets, &bytes)) {
+ stats->ipsec_rx_pkts += packets;
+ stats->ipsec_rx_bytes += bytes;
+ }
+
+ if (!mlx5_fc_query(mdev, fc->drop, &packets, &bytes)) {
+ stats->ipsec_rx_drop_pkts += packets;
+ stats->ipsec_rx_drop_bytes += bytes;
+ }
+
+ fc = ipsec->tx_esw->fc;
+ if (!mlx5_fc_query(mdev, fc->cnt, &packets, &bytes)) {
+ stats->ipsec_tx_pkts += packets;
+ stats->ipsec_tx_bytes += bytes;
+ }
+
+ if (!mlx5_fc_query(mdev, fc->drop, &packets, &bytes)) {
+ stats->ipsec_tx_drop_pkts += packets;
+ stats->ipsec_tx_drop_bytes += bytes;
+ }
+ }
+}
+
+#ifdef CONFIG_MLX5_ESWITCH
+static int mlx5e_ipsec_block_tc_offload(struct mlx5_core_dev *mdev)
+{
+ struct mlx5_eswitch *esw = mdev->priv.eswitch;
+ int err = 0;
+
+ if (esw)
+ down_write(&esw->mode_lock);
+
+ if (mdev->num_block_ipsec) {
+ err = -EBUSY;
+ goto unlock;
+ }
+
+ mdev->num_block_tc++;
+
+unlock:
+ if (esw)
+ up_write(&esw->mode_lock);
+
+ return err;
+}
+#else
+static int mlx5e_ipsec_block_tc_offload(struct mlx5_core_dev *mdev)
+{
+ if (mdev->num_block_ipsec)
+ return -EBUSY;
+
+ mdev->num_block_tc++;
+ return 0;
+}
+#endif
+
+static void mlx5e_ipsec_unblock_tc_offload(struct mlx5_core_dev *mdev)
+{
+ mdev->num_block_tc++;
}
int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
{
+ int err;
+
+ if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET) {
+ err = mlx5e_ipsec_block_tc_offload(sa_entry->ipsec->mdev);
+ if (err)
+ return err;
+ }
+
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
- return tx_add_rule(sa_entry);
+ err = tx_add_rule(sa_entry);
+ else
+ err = rx_add_rule(sa_entry);
+
+ if (err)
+ goto err_out;
- return rx_add_rule(sa_entry);
+ return 0;
+
+err_out:
+ if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET)
+ mlx5e_ipsec_unblock_tc_offload(sa_entry->ipsec->mdev);
+ return err;
}
void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
@@ -1499,21 +1797,40 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
if (ipsec_rule->pkt_reformat)
mlx5_packet_reformat_dealloc(mdev, ipsec_rule->pkt_reformat);
+ if (sa_entry->attrs.type == XFRM_DEV_OFFLOAD_PACKET)
+ mlx5e_ipsec_unblock_tc_offload(mdev);
+
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT) {
- tx_ft_put(sa_entry->ipsec);
+ tx_ft_put(sa_entry->ipsec, sa_entry->attrs.type);
return;
}
mlx5_modify_header_dealloc(mdev, ipsec_rule->modify_hdr);
- rx_ft_put(sa_entry->ipsec, sa_entry->attrs.family);
+ mlx5_esw_ipsec_rx_id_mapping_remove(sa_entry);
+ rx_ft_put(sa_entry->ipsec, sa_entry->attrs.family, sa_entry->attrs.type);
}
int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
{
+ int err;
+
+ err = mlx5e_ipsec_block_tc_offload(pol_entry->ipsec->mdev);
+ if (err)
+ return err;
+
if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
- return tx_add_policy(pol_entry);
+ err = tx_add_policy(pol_entry);
+ else
+ err = rx_add_policy(pol_entry);
+
+ if (err)
+ goto err_out;
- return rx_add_policy(pol_entry);
+ return 0;
+
+err_out:
+ mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);
+ return err;
}
void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
@@ -1523,16 +1840,18 @@ void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
mlx5_del_flow_rules(ipsec_rule->rule);
+ mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);
+
if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
rx_ft_put_policy(pol_entry->ipsec, pol_entry->attrs.family,
- pol_entry->attrs.prio);
+ pol_entry->attrs.prio, pol_entry->attrs.type);
return;
}
if (ipsec_rule->modify_hdr)
mlx5_modify_header_dealloc(mdev, ipsec_rule->modify_hdr);
- tx_ft_put_policy(pol_entry->ipsec, pol_entry->attrs.prio);
+ tx_ft_put_policy(pol_entry->ipsec, pol_entry->attrs.prio, pol_entry->attrs.type);
}
void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)
@@ -1540,7 +1859,7 @@ void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)
if (!ipsec->tx)
return;
- if (mlx5_ipsec_device_caps(ipsec->mdev) & MLX5_IPSEC_CAP_ROCE)
+ if (ipsec->roce)
mlx5_ipsec_fs_roce_cleanup(ipsec->roce);
ipsec_fs_destroy_counters(ipsec);
@@ -1555,12 +1874,24 @@ void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)
mutex_destroy(&ipsec->rx_ipv6->ft.mutex);
WARN_ON(ipsec->rx_ipv6->ft.refcnt);
kfree(ipsec->rx_ipv6);
+
+ if (ipsec->is_uplink_rep) {
+ xa_destroy(&ipsec->rx_esw->ipsec_obj_id_map);
+
+ mutex_destroy(&ipsec->tx_esw->ft.mutex);
+ WARN_ON(ipsec->tx_esw->ft.refcnt);
+ kfree(ipsec->tx_esw);
+
+ mutex_destroy(&ipsec->rx_esw->ft.mutex);
+ WARN_ON(ipsec->rx_esw->ft.refcnt);
+ kfree(ipsec->rx_esw);
+ }
}
int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec)
{
struct mlx5_core_dev *mdev = ipsec->mdev;
- struct mlx5_flow_namespace *ns;
+ struct mlx5_flow_namespace *ns, *ns_esw;
int err = -ENOMEM;
ns = mlx5_get_flow_namespace(ipsec->mdev,
@@ -1568,9 +1899,23 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec)
if (!ns)
return -EOPNOTSUPP;
+ if (ipsec->is_uplink_rep) {
+ ns_esw = mlx5_get_flow_namespace(mdev, MLX5_FLOW_NAMESPACE_FDB);
+ if (!ns_esw)
+ return -EOPNOTSUPP;
+
+ ipsec->tx_esw = kzalloc(sizeof(*ipsec->tx_esw), GFP_KERNEL);
+ if (!ipsec->tx_esw)
+ return -ENOMEM;
+
+ ipsec->rx_esw = kzalloc(sizeof(*ipsec->rx_esw), GFP_KERNEL);
+ if (!ipsec->rx_esw)
+ goto err_rx_esw;
+ }
+
ipsec->tx = kzalloc(sizeof(*ipsec->tx), GFP_KERNEL);
if (!ipsec->tx)
- return -ENOMEM;
+ goto err_tx;
ipsec->rx_ipv4 = kzalloc(sizeof(*ipsec->rx_ipv4), GFP_KERNEL);
if (!ipsec->rx_ipv4)
@@ -1589,8 +1934,14 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec)
mutex_init(&ipsec->rx_ipv6->ft.mutex);
ipsec->tx->ns = ns;
- if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ROCE)
+ if (ipsec->is_uplink_rep) {
+ mutex_init(&ipsec->tx_esw->ft.mutex);
+ mutex_init(&ipsec->rx_esw->ft.mutex);
+ ipsec->tx_esw->ns = ns_esw;
+ xa_init_flags(&ipsec->rx_esw->ipsec_obj_id_map, XA_FLAGS_ALLOC1);
+ } else if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ROCE) {
ipsec->roce = mlx5_ipsec_fs_roce_init(mdev);
+ }
return 0;
@@ -1600,6 +1951,10 @@ err_rx_ipv6:
kfree(ipsec->rx_ipv4);
err_rx_ipv4:
kfree(ipsec->tx);
+err_tx:
+ kfree(ipsec->rx_esw);
+err_rx_esw:
+ kfree(ipsec->tx_esw);
return err;
}
@@ -1621,10 +1976,12 @@ void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry)
bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry)
{
- struct mlx5e_ipsec_rx *rx =
- ipsec_rx(sa_entry->ipsec, sa_entry->attrs.family);
- struct mlx5e_ipsec_tx *tx = sa_entry->ipsec->tx;
+ struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
+ struct mlx5e_ipsec_rx *rx;
+ struct mlx5e_ipsec_tx *tx;
+ rx = ipsec_rx(sa_entry->ipsec, attrs->family, attrs->type);
+ tx = ipsec_tx(sa_entry->ipsec, attrs->type);
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
return tx->allow_tunnel_mode;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
index a3554bde3e07..3245d1c9d539 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
@@ -45,8 +45,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
MLX5_CAP_FLOWTABLE_NIC_RX(mdev, decap))
caps |= MLX5_IPSEC_CAP_PACKET_OFFLOAD;
- if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
- MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level))
+ if ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
+ MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) ||
+ MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level))
caps |= MLX5_IPSEC_CAP_PRIO;
if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
@@ -54,6 +55,12 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
reformat_l3_esp_tunnel_to_l2))
caps |= MLX5_IPSEC_CAP_TUNNEL;
+
+ if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
+ reformat_add_esp_transport_over_udp) &&
+ MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
+ reformat_del_esp_transport_over_udp))
+ caps |= MLX5_IPSEC_CAP_ESPINUDP;
}
if (mlx5_get_roce_state(mdev) &&
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
index eab5bc718771..51a144246ea6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
@@ -37,6 +37,7 @@
#include "ipsec.h"
#include "ipsec_rxtx.h"
#include "en.h"
+#include "esw/ipsec_fs.h"
enum {
MLX5E_IPSEC_TX_SYNDROME_OFFLOAD = 0x8,
@@ -58,7 +59,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x)
trailer_len = alen + plen + 2;
- pskb_trim(skb, skb->len - trailer_len);
+ ret = pskb_trim(skb, skb->len - trailer_len);
+ if (unlikely(ret))
+ return ret;
if (skb->protocol == htons(ETH_P_IP)) {
ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len);
ip_send_check(ipv4hdr);
@@ -309,9 +312,8 @@ enum {
void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb,
- struct mlx5_cqe64 *cqe)
+ u32 ipsec_meta_data)
{
- u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_ipsec *ipsec = priv->ipsec;
struct mlx5e_ipsec_sa_entry *sa_entry;
@@ -356,3 +358,24 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_syndrome);
}
}
+
+int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metadata)
+{
+ struct mlx5e_ipsec *ipsec = priv->ipsec;
+ u32 ipsec_obj_id;
+ int err;
+
+ if (!ipsec || !ipsec->is_uplink_rep)
+ return -EINVAL;
+
+ err = mlx5_esw_ipsec_rx_ipsec_obj_id_search(priv, id, &ipsec_obj_id);
+ if (err) {
+ atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
+ return err;
+ }
+
+ *metadata = MLX5_IPSEC_METADATA_CREATE(ipsec_obj_id,
+ MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED);
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
index 1878a70b9031..9ee014a8ad24 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
@@ -43,6 +43,7 @@
#define MLX5_IPSEC_METADATA_MARKER(metadata) (((metadata) >> 31) & 0x1)
#define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0))
#define MLX5_IPSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(23, 0))
+#define MLX5_IPSEC_METADATA_CREATE(id, syndrome) ((id) | ((syndrome) << 24))
struct mlx5e_accel_tx_ipsec_state {
struct xfrm_offload *xo;
@@ -66,7 +67,8 @@ void mlx5e_ipsec_handle_tx_wqe(struct mlx5e_tx_wqe *wqe,
struct mlx5_wqe_inline_seg *inlseg);
void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb,
- struct mlx5_cqe64 *cqe);
+ u32 ipsec_meta_data);
+int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metadata);
static inline unsigned int mlx5e_ipsec_tx_ids_len(struct mlx5e_accel_tx_ipsec_state *ipsec_st)
{
return ipsec_st->tailen;
@@ -145,7 +147,7 @@ mlx5e_ipsec_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, struct sk_buff *skb,
static inline
void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb,
- struct mlx5_cqe64 *cqe)
+ u32 ipsec_meta_data)
{}
static inline bool mlx5e_ipsec_eseg_meta(struct mlx5_wqe_eth_seg *eseg)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
index cf704f106b7c..984fa04bd331 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
@@ -188,7 +188,6 @@ static void mlx5e_tls_debugfs_init(struct mlx5e_tls *tls,
int mlx5e_ktls_init(struct mlx5e_priv *priv)
{
- struct mlx5_crypto_dek_pool *dek_pool;
struct mlx5e_tls *tls;
if (!mlx5e_is_ktls_device(priv->mdev))
@@ -199,12 +198,6 @@ int mlx5e_ktls_init(struct mlx5e_priv *priv)
return -ENOMEM;
tls->mdev = priv->mdev;
- dek_pool = mlx5_crypto_dek_pool_create(priv->mdev, MLX5_ACCEL_OBJ_TLS_KEY);
- if (IS_ERR(dek_pool)) {
- kfree(tls);
- return PTR_ERR(dek_pool);
- }
- tls->dek_pool = dek_pool;
priv->tls = tls;
mlx5e_tls_debugfs_init(tls, priv->dfs_root);
@@ -222,7 +215,6 @@ void mlx5e_ktls_cleanup(struct mlx5e_priv *priv)
debugfs_remove_recursive(tls->debugfs.dfs);
tls->debugfs.dfs = NULL;
- mlx5_crypto_dek_pool_destroy(tls->dek_pool);
kfree(priv->tls);
priv->tls = NULL;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
index efb2cf74ad6a..d61be26a4df1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
@@ -908,28 +908,51 @@ static void mlx5e_tls_tx_debugfs_init(struct mlx5e_tls *tls,
int mlx5e_ktls_init_tx(struct mlx5e_priv *priv)
{
+ struct mlx5_crypto_dek_pool *dek_pool;
struct mlx5e_tls *tls = priv->tls;
+ int err;
+
+ if (!mlx5e_is_ktls_device(priv->mdev))
+ return 0;
+
+ /* DEK pool could be used by either or both of TX and RX. But we have to
+ * put the creation here to avoid syndrome when doing devlink reload.
+ */
+ dek_pool = mlx5_crypto_dek_pool_create(priv->mdev, MLX5_ACCEL_OBJ_TLS_KEY);
+ if (IS_ERR(dek_pool))
+ return PTR_ERR(dek_pool);
+ tls->dek_pool = dek_pool;
if (!mlx5e_is_ktls_tx(priv->mdev))
return 0;
priv->tls->tx_pool = mlx5e_tls_tx_pool_init(priv->mdev, &priv->tls->sw_stats);
- if (!priv->tls->tx_pool)
- return -ENOMEM;
+ if (!priv->tls->tx_pool) {
+ err = -ENOMEM;
+ goto err_tx_pool_init;
+ }
mlx5e_tls_tx_debugfs_init(tls, tls->debugfs.dfs);
return 0;
+
+err_tx_pool_init:
+ mlx5_crypto_dek_pool_destroy(dek_pool);
+ return err;
}
void mlx5e_ktls_cleanup_tx(struct mlx5e_priv *priv)
{
if (!mlx5e_is_ktls_tx(priv->mdev))
- return;
+ goto dek_pool_destroy;
debugfs_remove_recursive(priv->tls->debugfs.dfs_tx);
priv->tls->debugfs.dfs_tx = NULL;
mlx5e_tls_tx_pool_cleanup(priv->tls->tx_pool);
priv->tls->tx_pool = NULL;
+
+dek_pool_destroy:
+ if (mlx5e_is_ktls_device(priv->mdev))
+ mlx5_crypto_dek_pool_destroy(priv->tls->dek_pool);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
index 592b165530ff..c9c1db971652 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
@@ -10,7 +10,6 @@
#include "lib/aso.h"
#include "lib/crypto.h"
#include "en_accel/macsec.h"
-#include "en_accel/macsec_fs.h"
#define MLX5_MACSEC_EPN_SCOPE_MID 0x80000000L
#define MLX5E_MACSEC_ASO_CTX_SZ MLX5_ST_SZ_BYTES(macsec_aso)
@@ -66,9 +65,7 @@ struct mlx5e_macsec_sa {
ssci_t ssci;
salt_t salt;
- struct rhash_head hash;
- u32 fs_id;
- union mlx5e_macsec_rule *macsec_rule;
+ union mlx5_macsec_rule *macsec_rule;
struct rcu_head rcu_head;
struct mlx5e_macsec_epn_state epn_state;
};
@@ -106,14 +103,6 @@ struct mlx5e_macsec_aso {
u32 pdn;
};
-static const struct rhashtable_params rhash_sci = {
- .key_len = sizeof_field(struct mlx5e_macsec_sa, sci),
- .key_offset = offsetof(struct mlx5e_macsec_sa, sci),
- .head_offset = offsetof(struct mlx5e_macsec_sa, hash),
- .automatic_shrinking = true,
- .min_size = 1,
-};
-
struct mlx5e_macsec_device {
const struct net_device *netdev;
struct mlx5e_macsec_sa *tx_sa[MACSEC_NUM_AN];
@@ -125,20 +114,13 @@ struct mlx5e_macsec_device {
struct mlx5e_macsec {
struct list_head macsec_device_list_head;
int num_of_devices;
- struct mlx5e_macsec_fs *macsec_fs;
struct mutex lock; /* Protects mlx5e_macsec internal contexts */
- /* Tx sci -> fs id mapping handling */
- struct rhashtable sci_hash; /* sci -> mlx5e_macsec_sa */
-
/* Rx fs_id -> rx_sc mapping */
struct xarray sc_xarray;
struct mlx5_core_dev *mdev;
- /* Stats manage */
- struct mlx5e_macsec_stats stats;
-
/* ASO */
struct mlx5e_macsec_aso aso;
@@ -330,36 +312,30 @@ static void mlx5e_macsec_destroy_object(struct mlx5_core_dev *mdev, u32 macsec_o
static void mlx5e_macsec_cleanup_sa(struct mlx5e_macsec *macsec,
struct mlx5e_macsec_sa *sa,
- bool is_tx)
+ bool is_tx, struct net_device *netdev, u32 fs_id)
{
int action = (is_tx) ? MLX5_ACCEL_MACSEC_ACTION_ENCRYPT :
MLX5_ACCEL_MACSEC_ACTION_DECRYPT;
- if ((is_tx) && sa->fs_id) {
- /* Make sure ongoing datapath readers sees a valid SA */
- rhashtable_remove_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
- sa->fs_id = 0;
- }
-
if (!sa->macsec_rule)
return;
- mlx5e_macsec_fs_del_rule(macsec->macsec_fs, sa->macsec_rule, action);
+ mlx5_macsec_fs_del_rule(macsec->mdev->macsec_fs, sa->macsec_rule, action, netdev,
+ fs_id);
mlx5e_macsec_destroy_object(macsec->mdev, sa->macsec_obj_id);
sa->macsec_rule = NULL;
}
static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
struct mlx5e_macsec_sa *sa,
- bool encrypt,
- bool is_tx)
+ bool encrypt, bool is_tx, u32 *fs_id)
{
struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev);
struct mlx5e_macsec *macsec = priv->macsec;
struct mlx5_macsec_rule_attrs rule_attrs;
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_macsec_obj_attrs obj_attrs;
- union mlx5e_macsec_rule *macsec_rule;
+ union mlx5_macsec_rule *macsec_rule;
int err;
obj_attrs.next_pn = sa->next_pn;
@@ -387,7 +363,7 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
rule_attrs.action = (is_tx) ? MLX5_ACCEL_MACSEC_ACTION_ENCRYPT :
MLX5_ACCEL_MACSEC_ACTION_DECRYPT;
- macsec_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs, &sa->fs_id);
+ macsec_rule = mlx5_macsec_fs_add_rule(mdev->macsec_fs, ctx, &rule_attrs, fs_id);
if (!macsec_rule) {
err = -ENOMEM;
goto destroy_macsec_object;
@@ -395,16 +371,8 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
sa->macsec_rule = macsec_rule;
- if (is_tx) {
- err = rhashtable_insert_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
- if (err)
- goto destroy_macsec_object_and_rule;
- }
-
return 0;
-destroy_macsec_object_and_rule:
- mlx5e_macsec_cleanup_sa(macsec, sa, is_tx);
destroy_macsec_object:
mlx5e_macsec_destroy_object(mdev, sa->macsec_obj_id);
@@ -426,7 +394,7 @@ mlx5e_macsec_get_rx_sc_from_sc_list(const struct list_head *list, sci_t sci)
static int macsec_rx_sa_active_update(struct macsec_context *ctx,
struct mlx5e_macsec_sa *rx_sa,
- bool active)
+ bool active, u32 *fs_id)
{
struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev);
struct mlx5e_macsec *macsec = priv->macsec;
@@ -437,11 +405,11 @@ static int macsec_rx_sa_active_update(struct macsec_context *ctx,
rx_sa->active = active;
if (!active) {
- mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
+ mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, ctx->secy->netdev, *fs_id);
return 0;
}
- err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
+ err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false, fs_id);
if (err)
rx_sa->active = false;
@@ -563,7 +531,7 @@ static int mlx5e_macsec_add_txsa(struct macsec_context *ctx)
!tx_sa->active)
goto out;
- err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true);
+ err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true, NULL);
if (err)
goto destroy_encryption_key;
@@ -627,7 +595,7 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
goto out;
if (ctx_tx_sa->active) {
- err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true);
+ err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true, NULL);
if (err)
goto out;
} else {
@@ -636,7 +604,7 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
goto out;
}
- mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
+ mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
}
out:
mutex_unlock(&macsec->lock);
@@ -669,7 +637,7 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
goto out;
}
- mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
+ mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
kfree_rcu_mightsleep(tx_sa);
macsec_device->tx_sa[assoc_num] = NULL;
@@ -680,20 +648,6 @@ out:
return err;
}
-static u32 mlx5e_macsec_get_sa_from_hashtable(struct rhashtable *sci_hash, sci_t *sci)
-{
- struct mlx5e_macsec_sa *macsec_sa;
- u32 fs_id = 0;
-
- rcu_read_lock();
- macsec_sa = rhashtable_lookup(sci_hash, sci, rhash_sci);
- if (macsec_sa)
- fs_id = macsec_sa->fs_id;
- rcu_read_unlock();
-
- return fs_id;
-}
-
static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx)
{
struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element;
@@ -813,7 +767,8 @@ static int mlx5e_macsec_upd_rxsc(struct macsec_context *ctx)
if (!rx_sa)
continue;
- err = macsec_rx_sa_active_update(ctx, rx_sa, rx_sa->active && ctx_rx_sc->active);
+ err = macsec_rx_sa_active_update(ctx, rx_sa, rx_sa->active && ctx_rx_sc->active,
+ &rx_sc->sc_xarray_element->fs_id);
if (err)
goto out;
}
@@ -824,7 +779,8 @@ out:
return err;
}
-static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec_rx_sc *rx_sc)
+static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec_rx_sc *rx_sc,
+ struct net_device *netdev)
{
struct mlx5e_macsec_sa *rx_sa;
int i;
@@ -834,7 +790,8 @@ static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec
if (!rx_sa)
continue;
- mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
+ mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, netdev,
+ rx_sc->sc_xarray_element->fs_id);
mlx5_destroy_encryption_key(macsec->mdev, rx_sa->enc_key_id);
kfree(rx_sa);
@@ -882,7 +839,7 @@ static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
goto out;
}
- macsec_del_rxsc_ctx(macsec, rx_sc);
+ macsec_del_rxsc_ctx(macsec, rx_sc, ctx->secy->netdev);
out:
mutex_unlock(&macsec->lock);
@@ -941,7 +898,6 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
rx_sa->next_pn = ctx_rx_sa->next_pn;
rx_sa->sci = sci;
rx_sa->assoc_num = assoc_num;
- rx_sa->fs_id = rx_sc->sc_xarray_element->fs_id;
if (ctx->secy->xpn)
update_macsec_epn(rx_sa, &ctx_rx_sa->key, &ctx_rx_sa->next_pn_halves,
@@ -958,7 +914,7 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
goto out;
//TODO - add support for both authentication and encryption flows
- err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
+ err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false, &rx_sc->sc_xarray_element->fs_id);
if (err)
goto destroy_encryption_key;
@@ -1025,7 +981,8 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx)
goto out;
}
- err = macsec_rx_sa_active_update(ctx, rx_sa, ctx_rx_sa->active);
+ err = macsec_rx_sa_active_update(ctx, rx_sa, ctx_rx_sa->active,
+ &rx_sc->sc_xarray_element->fs_id);
out:
mutex_unlock(&macsec->lock);
@@ -1073,7 +1030,8 @@ static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
goto out;
}
- mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
+ mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, ctx->secy->netdev,
+ rx_sc->sc_xarray_element->fs_id);
mlx5_destroy_encryption_key(macsec->mdev, rx_sa->enc_key_id);
kfree(rx_sa);
rx_sc->rx_sa[assoc_num] = NULL;
@@ -1154,7 +1112,8 @@ static int macsec_upd_secy_hw_address(struct macsec_context *ctx,
if (!rx_sa || !rx_sa->macsec_rule)
continue;
- mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
+ mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, ctx->secy->netdev,
+ rx_sc->sc_xarray_element->fs_id);
}
}
@@ -1165,7 +1124,8 @@ static int macsec_upd_secy_hw_address(struct macsec_context *ctx,
continue;
if (rx_sa->active) {
- err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
+ err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false,
+ &rx_sc->sc_xarray_element->fs_id);
if (err)
goto out;
}
@@ -1218,7 +1178,7 @@ static int mlx5e_macsec_upd_secy(struct macsec_context *ctx)
if (!tx_sa)
continue;
- mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
+ mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
}
for (i = 0; i < MACSEC_NUM_AN; ++i) {
@@ -1227,7 +1187,7 @@ static int mlx5e_macsec_upd_secy(struct macsec_context *ctx)
continue;
if (tx_sa->assoc_num == tx_sc->encoding_sa && tx_sa->active) {
- err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true);
+ err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true, NULL);
if (err)
goto out;
}
@@ -1265,7 +1225,7 @@ static int mlx5e_macsec_del_secy(struct macsec_context *ctx)
if (!tx_sa)
continue;
- mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
+ mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
kfree(tx_sa);
macsec_device->tx_sa[i] = NULL;
@@ -1273,7 +1233,7 @@ static int mlx5e_macsec_del_secy(struct macsec_context *ctx)
list = &macsec_device->macsec_rx_sc_list_head;
list_for_each_entry_safe(rx_sc, tmp, list, rx_sc_list_element)
- macsec_del_rxsc_ctx(macsec, rx_sc);
+ macsec_del_rxsc_ctx(macsec, rx_sc, ctx->secy->netdev);
kfree(macsec_device->dev_addr);
macsec_device->dev_addr = NULL;
@@ -1647,50 +1607,6 @@ static void mlx5e_macsec_aso_cleanup(struct mlx5e_macsec_aso *aso, struct mlx5_c
mlx5_core_dealloc_pd(mdev, aso->pdn);
}
-bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev)
-{
- if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
- MLX5_GENERAL_OBJ_TYPES_CAP_MACSEC_OFFLOAD))
- return false;
-
- if (!MLX5_CAP_GEN(mdev, log_max_dek))
- return false;
-
- if (!MLX5_CAP_MACSEC(mdev, log_max_macsec_offload))
- return false;
-
- if (!MLX5_CAP_FLOWTABLE_NIC_RX(mdev, macsec_decrypt) ||
- !MLX5_CAP_FLOWTABLE_NIC_RX(mdev, reformat_remove_macsec))
- return false;
-
- if (!MLX5_CAP_FLOWTABLE_NIC_TX(mdev, macsec_encrypt) ||
- !MLX5_CAP_FLOWTABLE_NIC_TX(mdev, reformat_add_macsec))
- return false;
-
- if (!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_128_encrypt) &&
- !MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_256_encrypt))
- return false;
-
- if (!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_128_decrypt) &&
- !MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_256_decrypt))
- return false;
-
- return true;
-}
-
-void mlx5e_macsec_get_stats_fill(struct mlx5e_macsec *macsec, void *macsec_stats)
-{
- mlx5e_macsec_fs_get_stats_fill(macsec->macsec_fs, macsec_stats);
-}
-
-struct mlx5e_macsec_stats *mlx5e_macsec_get_stats(struct mlx5e_macsec *macsec)
-{
- if (!macsec)
- return NULL;
-
- return &macsec->stats;
-}
-
static const struct macsec_ops macsec_offload_ops = {
.mdo_add_txsa = mlx5e_macsec_add_txsa,
.mdo_upd_txsa = mlx5e_macsec_upd_txsa,
@@ -1711,7 +1627,8 @@ bool mlx5e_macsec_handle_tx_skb(struct mlx5e_macsec *macsec, struct sk_buff *skb
struct metadata_dst *md_dst = skb_metadata_dst(skb);
u32 fs_id;
- fs_id = mlx5e_macsec_get_sa_from_hashtable(&macsec->sci_hash, &md_dst->u.macsec_info.sci);
+ fs_id = mlx5_macsec_fs_get_fs_id_from_hashtable(macsec->mdev->macsec_fs,
+ &md_dst->u.macsec_info.sci);
if (!fs_id)
goto err_out;
@@ -1729,7 +1646,8 @@ void mlx5e_macsec_tx_build_eseg(struct mlx5e_macsec *macsec,
struct metadata_dst *md_dst = skb_metadata_dst(skb);
u32 fs_id;
- fs_id = mlx5e_macsec_get_sa_from_hashtable(&macsec->sci_hash, &md_dst->u.macsec_info.sci);
+ fs_id = mlx5_macsec_fs_get_fs_id_from_hashtable(macsec->mdev->macsec_fs,
+ &md_dst->u.macsec_info.sci);
if (!fs_id)
return;
@@ -1782,7 +1700,7 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_macsec *macsec = NULL;
- struct mlx5e_macsec_fs *macsec_fs;
+ struct mlx5_macsec_fs *macsec_fs;
int err;
if (!mlx5e_is_macsec_device(priv->mdev)) {
@@ -1797,13 +1715,6 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
INIT_LIST_HEAD(&macsec->macsec_device_list_head);
mutex_init(&macsec->lock);
- err = rhashtable_init(&macsec->sci_hash, &rhash_sci);
- if (err) {
- mlx5_core_err(mdev, "MACsec offload: Failed to init SCI hash table, err=%d\n",
- err);
- goto err_hash;
- }
-
err = mlx5e_macsec_aso_init(&macsec->aso, priv->mdev);
if (err) {
mlx5_core_err(mdev, "MACsec offload: Failed to init aso, err=%d\n", err);
@@ -1822,13 +1733,13 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
macsec->mdev = mdev;
- macsec_fs = mlx5e_macsec_fs_init(mdev, priv->netdev);
+ macsec_fs = mlx5_macsec_fs_init(mdev);
if (!macsec_fs) {
err = -ENOMEM;
goto err_out;
}
- macsec->macsec_fs = macsec_fs;
+ mdev->macsec_fs = macsec_fs;
macsec->nb.notifier_call = macsec_obj_change_event;
mlx5_notifier_register(mdev, &macsec->nb);
@@ -1842,8 +1753,6 @@ err_out:
err_wq:
mlx5e_macsec_aso_cleanup(&macsec->aso, priv->mdev);
err_aso:
- rhashtable_destroy(&macsec->sci_hash);
-err_hash:
kfree(macsec);
priv->macsec = NULL;
return err;
@@ -1858,10 +1767,9 @@ void mlx5e_macsec_cleanup(struct mlx5e_priv *priv)
return;
mlx5_notifier_unregister(mdev, &macsec->nb);
- mlx5e_macsec_fs_cleanup(macsec->macsec_fs);
+ mlx5_macsec_fs_cleanup(mdev->macsec_fs);
destroy_workqueue(macsec->wq);
mlx5e_macsec_aso_cleanup(&macsec->aso, mdev);
- rhashtable_destroy(&macsec->sci_hash);
mutex_destroy(&macsec->lock);
kfree(macsec);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.h
index 347380a2cd9c..27df72e23106 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.h
@@ -4,32 +4,16 @@
#ifndef __MLX5_EN_ACCEL_MACSEC_H__
#define __MLX5_EN_ACCEL_MACSEC_H__
-#ifdef CONFIG_MLX5_EN_MACSEC
+#ifdef CONFIG_MLX5_MACSEC
#include <linux/mlx5/driver.h>
#include <net/macsec.h>
#include <net/dst_metadata.h>
-
-/* Bit31 - 30: MACsec marker, Bit15-0: MACsec id */
-#define MLX5_MACEC_RX_FS_ID_MAX USHRT_MAX /* Must be power of two */
-#define MLX5_MACSEC_RX_FS_ID_MASK MLX5_MACEC_RX_FS_ID_MAX
-#define MLX5_MACSEC_METADATA_MARKER(metadata) ((((metadata) >> 30) & 0x3) == 0x1)
-#define MLX5_MACSEC_RX_METADAT_HANDLE(metadata) ((metadata) & MLX5_MACSEC_RX_FS_ID_MASK)
+#include "lib/macsec_fs.h"
struct mlx5e_priv;
struct mlx5e_macsec;
-struct mlx5e_macsec_stats {
- u64 macsec_rx_pkts;
- u64 macsec_rx_bytes;
- u64 macsec_rx_pkts_drop;
- u64 macsec_rx_bytes_drop;
- u64 macsec_tx_pkts;
- u64 macsec_tx_bytes;
- u64 macsec_tx_pkts_drop;
- u64 macsec_tx_bytes_drop;
-};
-
void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv);
int mlx5e_macsec_init(struct mlx5e_priv *priv);
void mlx5e_macsec_cleanup(struct mlx5e_priv *priv);
@@ -52,9 +36,6 @@ static inline bool mlx5e_macsec_is_rx_flow(struct mlx5_cqe64 *cqe)
void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
struct mlx5_cqe64 *cqe);
-bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev);
-void mlx5e_macsec_get_stats_fill(struct mlx5e_macsec *macsec, void *macsec_stats);
-struct mlx5e_macsec_stats *mlx5e_macsec_get_stats(struct mlx5e_macsec *macsec);
#else
@@ -67,7 +48,6 @@ static inline void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb,
struct mlx5_cqe64 *cqe)
{}
-static inline bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev) { return false; }
-#endif /* CONFIG_MLX5_EN_MACSEC */
+#endif /* CONFIG_MLX5_MACSEC */
#endif /* __MLX5_ACCEL_EN_MACSEC_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c
deleted file mode 100644
index 7fc901a6ec5f..000000000000
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c
+++ /dev/null
@@ -1,1393 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
-/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
-
-#include <net/macsec.h>
-#include <linux/netdevice.h>
-#include <linux/mlx5/qp.h>
-#include <linux/if_vlan.h>
-#include "fs_core.h"
-#include "en/fs.h"
-#include "en_accel/macsec_fs.h"
-#include "mlx5_core.h"
-
-/* MACsec TX flow steering */
-#define CRYPTO_NUM_MAXSEC_FTE BIT(15)
-#define CRYPTO_TABLE_DEFAULT_RULE_GROUP_SIZE 1
-
-#define TX_CRYPTO_TABLE_LEVEL 0
-#define TX_CRYPTO_TABLE_NUM_GROUPS 3
-#define TX_CRYPTO_TABLE_MKE_GROUP_SIZE 1
-#define TX_CRYPTO_TABLE_SA_GROUP_SIZE \
- (CRYPTO_NUM_MAXSEC_FTE - (TX_CRYPTO_TABLE_MKE_GROUP_SIZE + \
- CRYPTO_TABLE_DEFAULT_RULE_GROUP_SIZE))
-#define TX_CHECK_TABLE_LEVEL 1
-#define TX_CHECK_TABLE_NUM_FTE 2
-#define RX_CRYPTO_TABLE_LEVEL 0
-#define RX_CHECK_TABLE_LEVEL 1
-#define RX_CHECK_TABLE_NUM_FTE 3
-#define RX_CRYPTO_TABLE_NUM_GROUPS 3
-#define RX_CRYPTO_TABLE_SA_RULE_WITH_SCI_GROUP_SIZE \
- ((CRYPTO_NUM_MAXSEC_FTE - CRYPTO_TABLE_DEFAULT_RULE_GROUP_SIZE) / 2)
-#define RX_CRYPTO_TABLE_SA_RULE_WITHOUT_SCI_GROUP_SIZE \
- (CRYPTO_NUM_MAXSEC_FTE - RX_CRYPTO_TABLE_SA_RULE_WITH_SCI_GROUP_SIZE)
-#define RX_NUM_OF_RULES_PER_SA 2
-
-#define MLX5_MACSEC_TAG_LEN 8 /* SecTAG length with ethertype and without the optional SCI */
-#define MLX5_MACSEC_SECTAG_TCI_AN_FIELD_BITMASK 0x23
-#define MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET 0x8
-#define MLX5_MACSEC_SECTAG_TCI_SC_FIELD_OFFSET 0x5
-#define MLX5_MACSEC_SECTAG_TCI_SC_FIELD_BIT (0x1 << MLX5_MACSEC_SECTAG_TCI_SC_FIELD_OFFSET)
-#define MLX5_SECTAG_HEADER_SIZE_WITHOUT_SCI 0x8
-#define MLX5_SECTAG_HEADER_SIZE_WITH_SCI (MLX5_SECTAG_HEADER_SIZE_WITHOUT_SCI + MACSEC_SCI_LEN)
-
-/* MACsec RX flow steering */
-#define MLX5_ETH_WQE_FT_META_MACSEC_MASK 0x3E
-
-struct mlx5_sectag_header {
- __be16 ethertype;
- u8 tci_an;
- u8 sl;
- u32 pn;
- u8 sci[MACSEC_SCI_LEN]; /* optional */
-} __packed;
-
-struct mlx5e_macsec_tx_rule {
- struct mlx5_flow_handle *rule;
- struct mlx5_pkt_reformat *pkt_reformat;
- u32 fs_id;
-};
-
-struct mlx5e_macsec_tables {
- struct mlx5e_flow_table ft_crypto;
- struct mlx5_flow_handle *crypto_miss_rule;
-
- struct mlx5_flow_table *ft_check;
- struct mlx5_flow_group *ft_check_group;
- struct mlx5_fc *check_miss_rule_counter;
- struct mlx5_flow_handle *check_miss_rule;
- struct mlx5_fc *check_rule_counter;
-
- u32 refcnt;
-};
-
-struct mlx5e_macsec_tx {
- struct mlx5_flow_handle *crypto_mke_rule;
- struct mlx5_flow_handle *check_rule;
-
- struct ida tx_halloc;
-
- struct mlx5e_macsec_tables tables;
-};
-
-struct mlx5e_macsec_rx_rule {
- struct mlx5_flow_handle *rule[RX_NUM_OF_RULES_PER_SA];
- struct mlx5_modify_hdr *meta_modhdr;
-};
-
-struct mlx5e_macsec_rx {
- struct mlx5_flow_handle *check_rule[2];
- struct mlx5_pkt_reformat *check_rule_pkt_reformat[2];
-
- struct mlx5e_macsec_tables tables;
-};
-
-union mlx5e_macsec_rule {
- struct mlx5e_macsec_tx_rule tx_rule;
- struct mlx5e_macsec_rx_rule rx_rule;
-};
-
-struct mlx5e_macsec_fs {
- struct mlx5_core_dev *mdev;
- struct net_device *netdev;
- struct mlx5e_macsec_tx *tx_fs;
- struct mlx5e_macsec_rx *rx_fs;
-};
-
-static void macsec_fs_tx_destroy(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_tx *tx_fs = macsec_fs->tx_fs;
- struct mlx5e_macsec_tables *tx_tables;
-
- tx_tables = &tx_fs->tables;
-
- /* Tx check table */
- if (tx_fs->check_rule) {
- mlx5_del_flow_rules(tx_fs->check_rule);
- tx_fs->check_rule = NULL;
- }
-
- if (tx_tables->check_miss_rule) {
- mlx5_del_flow_rules(tx_tables->check_miss_rule);
- tx_tables->check_miss_rule = NULL;
- }
-
- if (tx_tables->ft_check_group) {
- mlx5_destroy_flow_group(tx_tables->ft_check_group);
- tx_tables->ft_check_group = NULL;
- }
-
- if (tx_tables->ft_check) {
- mlx5_destroy_flow_table(tx_tables->ft_check);
- tx_tables->ft_check = NULL;
- }
-
- /* Tx crypto table */
- if (tx_fs->crypto_mke_rule) {
- mlx5_del_flow_rules(tx_fs->crypto_mke_rule);
- tx_fs->crypto_mke_rule = NULL;
- }
-
- if (tx_tables->crypto_miss_rule) {
- mlx5_del_flow_rules(tx_tables->crypto_miss_rule);
- tx_tables->crypto_miss_rule = NULL;
- }
-
- mlx5e_destroy_flow_table(&tx_tables->ft_crypto);
-}
-
-static int macsec_fs_tx_create_crypto_table_groups(struct mlx5e_flow_table *ft)
-{
- int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
- int mclen = MLX5_ST_SZ_BYTES(fte_match_param);
- int ix = 0;
- u32 *in;
- int err;
- u8 *mc;
-
- ft->g = kcalloc(TX_CRYPTO_TABLE_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
- if (!ft->g)
- return -ENOMEM;
- in = kvzalloc(inlen, GFP_KERNEL);
-
- if (!in) {
- kfree(ft->g);
- return -ENOMEM;
- }
-
- mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
-
- /* Flow Group for MKE match */
- MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
- MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype);
-
- MLX5_SET_CFG(in, start_flow_index, ix);
- ix += TX_CRYPTO_TABLE_MKE_GROUP_SIZE;
- MLX5_SET_CFG(in, end_flow_index, ix - 1);
- ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
- if (IS_ERR(ft->g[ft->num_groups]))
- goto err;
- ft->num_groups++;
-
- /* Flow Group for SA rules */
- memset(in, 0, inlen);
- memset(mc, 0, mclen);
- MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_MISC_PARAMETERS_2);
- MLX5_SET(fte_match_param, mc, misc_parameters_2.metadata_reg_a,
- MLX5_ETH_WQE_FT_META_MACSEC_MASK);
-
- MLX5_SET_CFG(in, start_flow_index, ix);
- ix += TX_CRYPTO_TABLE_SA_GROUP_SIZE;
- MLX5_SET_CFG(in, end_flow_index, ix - 1);
- ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
- if (IS_ERR(ft->g[ft->num_groups]))
- goto err;
- ft->num_groups++;
-
- /* Flow Group for l2 traps */
- memset(in, 0, inlen);
- memset(mc, 0, mclen);
- MLX5_SET_CFG(in, start_flow_index, ix);
- ix += CRYPTO_TABLE_DEFAULT_RULE_GROUP_SIZE;
- MLX5_SET_CFG(in, end_flow_index, ix - 1);
- ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
- if (IS_ERR(ft->g[ft->num_groups]))
- goto err;
- ft->num_groups++;
-
- kvfree(in);
- return 0;
-
-err:
- err = PTR_ERR(ft->g[ft->num_groups]);
- ft->g[ft->num_groups] = NULL;
- kvfree(in);
-
- return err;
-}
-
-static struct mlx5_flow_table
- *macsec_fs_auto_group_table_create(struct mlx5_flow_namespace *ns, int flags,
- int level, int max_fte)
-{
- struct mlx5_flow_table_attr ft_attr = {};
- struct mlx5_flow_table *fdb = NULL;
-
- /* reserve entry for the match all miss group and rule */
- ft_attr.autogroup.num_reserved_entries = 1;
- ft_attr.autogroup.max_num_groups = 1;
- ft_attr.prio = 0;
- ft_attr.flags = flags;
- ft_attr.level = level;
- ft_attr.max_fte = max_fte;
-
- fdb = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
-
- return fdb;
-}
-
-static int macsec_fs_tx_create(struct mlx5e_macsec_fs *macsec_fs)
-{
- int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
- struct mlx5e_macsec_tx *tx_fs = macsec_fs->tx_fs;
- struct net_device *netdev = macsec_fs->netdev;
- struct mlx5_flow_table_attr ft_attr = {};
- struct mlx5_flow_destination dest = {};
- struct mlx5e_macsec_tables *tx_tables;
- struct mlx5_flow_act flow_act = {};
- struct mlx5e_flow_table *ft_crypto;
- struct mlx5_flow_table *flow_table;
- struct mlx5_flow_group *flow_group;
- struct mlx5_flow_namespace *ns;
- struct mlx5_flow_handle *rule;
- struct mlx5_flow_spec *spec;
- u32 *flow_group_in;
- int err;
-
- ns = mlx5_get_flow_namespace(macsec_fs->mdev, MLX5_FLOW_NAMESPACE_EGRESS_MACSEC);
- if (!ns)
- return -ENOMEM;
-
- spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
-
- flow_group_in = kvzalloc(inlen, GFP_KERNEL);
- if (!flow_group_in) {
- err = -ENOMEM;
- goto out_spec;
- }
-
- tx_tables = &tx_fs->tables;
- ft_crypto = &tx_tables->ft_crypto;
-
- /* Tx crypto table */
- ft_attr.flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
- ft_attr.level = TX_CRYPTO_TABLE_LEVEL;
- ft_attr.max_fte = CRYPTO_NUM_MAXSEC_FTE;
-
- flow_table = mlx5_create_flow_table(ns, &ft_attr);
- if (IS_ERR(flow_table)) {
- err = PTR_ERR(flow_table);
- netdev_err(netdev, "Failed to create MACsec Tx crypto table err(%d)\n", err);
- goto out_flow_group;
- }
- ft_crypto->t = flow_table;
-
- /* Tx crypto table groups */
- err = macsec_fs_tx_create_crypto_table_groups(ft_crypto);
- if (err) {
- netdev_err(netdev,
- "Failed to create default flow group for MACsec Tx crypto table err(%d)\n",
- err);
- goto err;
- }
-
- /* Tx crypto table MKE rule - MKE packets shouldn't be offloaded */
- spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
-
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype);
- MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, ETH_P_PAE);
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
-
- rule = mlx5_add_flow_rules(ft_crypto->t, spec, &flow_act, NULL, 0);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to add MACsec TX MKE rule, err=%d\n", err);
- goto err;
- }
- tx_fs->crypto_mke_rule = rule;
-
- /* Tx crypto table Default miss rule */
- memset(&flow_act, 0, sizeof(flow_act));
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
- rule = mlx5_add_flow_rules(ft_crypto->t, NULL, &flow_act, NULL, 0);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to add MACsec Tx table default miss rule %d\n", err);
- goto err;
- }
- tx_tables->crypto_miss_rule = rule;
-
- /* Tx check table */
- flow_table = macsec_fs_auto_group_table_create(ns, 0, TX_CHECK_TABLE_LEVEL,
- TX_CHECK_TABLE_NUM_FTE);
- if (IS_ERR(flow_table)) {
- err = PTR_ERR(flow_table);
- netdev_err(netdev, "fail to create MACsec TX check table, err(%d)\n", err);
- goto err;
- }
- tx_tables->ft_check = flow_table;
-
- /* Tx check table Default miss group/rule */
- memset(flow_group_in, 0, inlen);
- MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_table->max_fte - 1);
- MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_table->max_fte - 1);
- flow_group = mlx5_create_flow_group(tx_tables->ft_check, flow_group_in);
- if (IS_ERR(flow_group)) {
- err = PTR_ERR(flow_group);
- netdev_err(netdev,
- "Failed to create default flow group for MACsec Tx crypto table err(%d)\n",
- err);
- goto err;
- }
- tx_tables->ft_check_group = flow_group;
-
- /* Tx check table default drop rule */
- memset(&dest, 0, sizeof(struct mlx5_flow_destination));
- memset(&flow_act, 0, sizeof(flow_act));
- dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
- dest.counter_id = mlx5_fc_id(tx_tables->check_miss_rule_counter);
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
- rule = mlx5_add_flow_rules(tx_tables->ft_check, NULL, &flow_act, &dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to added MACsec tx check drop rule, err(%d)\n", err);
- goto err;
- }
- tx_tables->check_miss_rule = rule;
-
- /* Tx check table rule */
- memset(spec, 0, sizeof(struct mlx5_flow_spec));
- memset(&dest, 0, sizeof(struct mlx5_flow_destination));
- memset(&flow_act, 0, sizeof(flow_act));
-
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, misc_parameters_2.metadata_reg_c_4);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_2.metadata_reg_c_4, 0);
- spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2;
-
- flow_act.flags = FLOW_ACT_NO_APPEND;
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW | MLX5_FLOW_CONTEXT_ACTION_COUNT;
- dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
- dest.counter_id = mlx5_fc_id(tx_tables->check_rule_counter);
- rule = mlx5_add_flow_rules(tx_tables->ft_check, spec, &flow_act, &dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to add MACsec check rule, err=%d\n", err);
- goto err;
- }
- tx_fs->check_rule = rule;
-
- goto out_flow_group;
-
-err:
- macsec_fs_tx_destroy(macsec_fs);
-out_flow_group:
- kvfree(flow_group_in);
-out_spec:
- kvfree(spec);
- return err;
-}
-
-static int macsec_fs_tx_ft_get(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_tx *tx_fs = macsec_fs->tx_fs;
- struct mlx5e_macsec_tables *tx_tables;
- int err = 0;
-
- tx_tables = &tx_fs->tables;
- if (tx_tables->refcnt)
- goto out;
-
- err = macsec_fs_tx_create(macsec_fs);
- if (err)
- return err;
-
-out:
- tx_tables->refcnt++;
- return err;
-}
-
-static void macsec_fs_tx_ft_put(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_tables *tx_tables = &macsec_fs->tx_fs->tables;
-
- if (--tx_tables->refcnt)
- return;
-
- macsec_fs_tx_destroy(macsec_fs);
-}
-
-static int macsec_fs_tx_setup_fte(struct mlx5e_macsec_fs *macsec_fs,
- struct mlx5_flow_spec *spec,
- struct mlx5_flow_act *flow_act,
- u32 macsec_obj_id,
- u32 *fs_id)
-{
- struct mlx5e_macsec_tx *tx_fs = macsec_fs->tx_fs;
- int err = 0;
- u32 id;
-
- err = ida_alloc_range(&tx_fs->tx_halloc, 1,
- MLX5_MACSEC_NUM_OF_SUPPORTED_INTERFACES,
- GFP_KERNEL);
- if (err < 0)
- return err;
-
- id = err;
- spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2;
-
- /* Metadata match */
- MLX5_SET(fte_match_param, spec->match_criteria, misc_parameters_2.metadata_reg_a,
- MLX5_ETH_WQE_FT_META_MACSEC_MASK);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_2.metadata_reg_a,
- MLX5_ETH_WQE_FT_META_MACSEC | id << 2);
-
- *fs_id = id;
- flow_act->crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_MACSEC;
- flow_act->crypto.obj_id = macsec_obj_id;
-
- mlx5_core_dbg(macsec_fs->mdev, "Tx fte: macsec obj_id %u, fs_id %u\n", macsec_obj_id, id);
- return 0;
-}
-
-static void macsec_fs_tx_create_sectag_header(const struct macsec_context *ctx,
- char *reformatbf,
- size_t *reformat_size)
-{
- const struct macsec_secy *secy = ctx->secy;
- bool sci_present = macsec_send_sci(secy);
- struct mlx5_sectag_header sectag = {};
- const struct macsec_tx_sc *tx_sc;
-
- tx_sc = &secy->tx_sc;
- sectag.ethertype = htons(ETH_P_MACSEC);
-
- if (sci_present) {
- sectag.tci_an |= MACSEC_TCI_SC;
- memcpy(&sectag.sci, &secy->sci,
- sizeof(sectag.sci));
- } else {
- if (tx_sc->end_station)
- sectag.tci_an |= MACSEC_TCI_ES;
- if (tx_sc->scb)
- sectag.tci_an |= MACSEC_TCI_SCB;
- }
-
- /* With GCM, C/E clear for !encrypt, both set for encrypt */
- if (tx_sc->encrypt)
- sectag.tci_an |= MACSEC_TCI_CONFID;
- else if (secy->icv_len != MACSEC_DEFAULT_ICV_LEN)
- sectag.tci_an |= MACSEC_TCI_C;
-
- sectag.tci_an |= tx_sc->encoding_sa;
-
- *reformat_size = MLX5_MACSEC_TAG_LEN + (sci_present ? MACSEC_SCI_LEN : 0);
-
- memcpy(reformatbf, &sectag, *reformat_size);
-}
-
-static void macsec_fs_tx_del_rule(struct mlx5e_macsec_fs *macsec_fs,
- struct mlx5e_macsec_tx_rule *tx_rule)
-{
- if (tx_rule->rule) {
- mlx5_del_flow_rules(tx_rule->rule);
- tx_rule->rule = NULL;
- }
-
- if (tx_rule->pkt_reformat) {
- mlx5_packet_reformat_dealloc(macsec_fs->mdev, tx_rule->pkt_reformat);
- tx_rule->pkt_reformat = NULL;
- }
-
- if (tx_rule->fs_id) {
- ida_free(&macsec_fs->tx_fs->tx_halloc, tx_rule->fs_id);
- tx_rule->fs_id = 0;
- }
-
- kfree(tx_rule);
-
- macsec_fs_tx_ft_put(macsec_fs);
-}
-
-#define MLX5_REFORMAT_PARAM_ADD_MACSEC_OFFSET_4_BYTES 1
-
-static union mlx5e_macsec_rule *
-macsec_fs_tx_add_rule(struct mlx5e_macsec_fs *macsec_fs,
- const struct macsec_context *macsec_ctx,
- struct mlx5_macsec_rule_attrs *attrs,
- u32 *sa_fs_id)
-{
- char reformatbf[MLX5_MACSEC_TAG_LEN + MACSEC_SCI_LEN];
- struct mlx5_pkt_reformat_params reformat_params = {};
- struct mlx5e_macsec_tx *tx_fs = macsec_fs->tx_fs;
- struct net_device *netdev = macsec_fs->netdev;
- union mlx5e_macsec_rule *macsec_rule = NULL;
- struct mlx5_flow_destination dest = {};
- struct mlx5e_macsec_tables *tx_tables;
- struct mlx5e_macsec_tx_rule *tx_rule;
- struct mlx5_flow_act flow_act = {};
- struct mlx5_flow_handle *rule;
- struct mlx5_flow_spec *spec;
- size_t reformat_size;
- int err = 0;
- u32 fs_id;
-
- tx_tables = &tx_fs->tables;
-
- spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return NULL;
-
- err = macsec_fs_tx_ft_get(macsec_fs);
- if (err)
- goto out_spec;
-
- macsec_rule = kzalloc(sizeof(*macsec_rule), GFP_KERNEL);
- if (!macsec_rule) {
- macsec_fs_tx_ft_put(macsec_fs);
- goto out_spec;
- }
-
- tx_rule = &macsec_rule->tx_rule;
-
- /* Tx crypto table crypto rule */
- macsec_fs_tx_create_sectag_header(macsec_ctx, reformatbf, &reformat_size);
-
- reformat_params.type = MLX5_REFORMAT_TYPE_ADD_MACSEC;
- reformat_params.size = reformat_size;
- reformat_params.data = reformatbf;
-
- if (is_vlan_dev(macsec_ctx->netdev))
- reformat_params.param_0 = MLX5_REFORMAT_PARAM_ADD_MACSEC_OFFSET_4_BYTES;
-
- flow_act.pkt_reformat = mlx5_packet_reformat_alloc(macsec_fs->mdev,
- &reformat_params,
- MLX5_FLOW_NAMESPACE_EGRESS_MACSEC);
- if (IS_ERR(flow_act.pkt_reformat)) {
- err = PTR_ERR(flow_act.pkt_reformat);
- netdev_err(netdev, "Failed to allocate MACsec Tx reformat context err=%d\n", err);
- goto err;
- }
- tx_rule->pkt_reformat = flow_act.pkt_reformat;
-
- err = macsec_fs_tx_setup_fte(macsec_fs, spec, &flow_act, attrs->macsec_obj_id, &fs_id);
- if (err) {
- netdev_err(netdev,
- "Failed to add packet reformat for MACsec TX crypto rule, err=%d\n",
- err);
- goto err;
- }
-
- tx_rule->fs_id = fs_id;
- *sa_fs_id = fs_id;
-
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
- MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |
- MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
- dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
- dest.ft = tx_tables->ft_check;
- rule = mlx5_add_flow_rules(tx_tables->ft_crypto.t, spec, &flow_act, &dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to add MACsec TX crypto rule, err=%d\n", err);
- goto err;
- }
- tx_rule->rule = rule;
-
- goto out_spec;
-
-err:
- macsec_fs_tx_del_rule(macsec_fs, tx_rule);
- macsec_rule = NULL;
-out_spec:
- kvfree(spec);
-
- return macsec_rule;
-}
-
-static void macsec_fs_tx_cleanup(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_tx *tx_fs = macsec_fs->tx_fs;
- struct mlx5_core_dev *mdev = macsec_fs->mdev;
- struct mlx5e_macsec_tables *tx_tables;
-
- if (!tx_fs)
- return;
-
- tx_tables = &tx_fs->tables;
- if (tx_tables->refcnt) {
- netdev_err(macsec_fs->netdev,
- "Can't destroy MACsec offload tx_fs, refcnt(%u) isn't 0\n",
- tx_tables->refcnt);
- return;
- }
-
- ida_destroy(&tx_fs->tx_halloc);
-
- if (tx_tables->check_miss_rule_counter) {
- mlx5_fc_destroy(mdev, tx_tables->check_miss_rule_counter);
- tx_tables->check_miss_rule_counter = NULL;
- }
-
- if (tx_tables->check_rule_counter) {
- mlx5_fc_destroy(mdev, tx_tables->check_rule_counter);
- tx_tables->check_rule_counter = NULL;
- }
-
- kfree(tx_fs);
- macsec_fs->tx_fs = NULL;
-}
-
-static int macsec_fs_tx_init(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct net_device *netdev = macsec_fs->netdev;
- struct mlx5_core_dev *mdev = macsec_fs->mdev;
- struct mlx5e_macsec_tables *tx_tables;
- struct mlx5e_macsec_tx *tx_fs;
- struct mlx5_fc *flow_counter;
- int err;
-
- tx_fs = kzalloc(sizeof(*tx_fs), GFP_KERNEL);
- if (!tx_fs)
- return -ENOMEM;
-
- tx_tables = &tx_fs->tables;
-
- flow_counter = mlx5_fc_create(mdev, false);
- if (IS_ERR(flow_counter)) {
- err = PTR_ERR(flow_counter);
- netdev_err(netdev,
- "Failed to create MACsec Tx encrypt flow counter, err(%d)\n",
- err);
- goto err_encrypt_counter;
- }
- tx_tables->check_rule_counter = flow_counter;
-
- flow_counter = mlx5_fc_create(mdev, false);
- if (IS_ERR(flow_counter)) {
- err = PTR_ERR(flow_counter);
- netdev_err(netdev,
- "Failed to create MACsec Tx drop flow counter, err(%d)\n",
- err);
- goto err_drop_counter;
- }
- tx_tables->check_miss_rule_counter = flow_counter;
-
- ida_init(&tx_fs->tx_halloc);
-
- macsec_fs->tx_fs = tx_fs;
-
- return 0;
-
-err_drop_counter:
- mlx5_fc_destroy(mdev, tx_tables->check_rule_counter);
- tx_tables->check_rule_counter = NULL;
-
-err_encrypt_counter:
- kfree(tx_fs);
- macsec_fs->tx_fs = NULL;
-
- return err;
-}
-
-static void macsec_fs_rx_destroy(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_rx *rx_fs = macsec_fs->rx_fs;
- struct mlx5e_macsec_tables *rx_tables;
- int i;
-
- /* Rx check table */
- for (i = 1; i >= 0; --i) {
- if (rx_fs->check_rule[i]) {
- mlx5_del_flow_rules(rx_fs->check_rule[i]);
- rx_fs->check_rule[i] = NULL;
- }
-
- if (rx_fs->check_rule_pkt_reformat[i]) {
- mlx5_packet_reformat_dealloc(macsec_fs->mdev,
- rx_fs->check_rule_pkt_reformat[i]);
- rx_fs->check_rule_pkt_reformat[i] = NULL;
- }
- }
-
- rx_tables = &rx_fs->tables;
-
- if (rx_tables->check_miss_rule) {
- mlx5_del_flow_rules(rx_tables->check_miss_rule);
- rx_tables->check_miss_rule = NULL;
- }
-
- if (rx_tables->ft_check_group) {
- mlx5_destroy_flow_group(rx_tables->ft_check_group);
- rx_tables->ft_check_group = NULL;
- }
-
- if (rx_tables->ft_check) {
- mlx5_destroy_flow_table(rx_tables->ft_check);
- rx_tables->ft_check = NULL;
- }
-
- /* Rx crypto table */
- if (rx_tables->crypto_miss_rule) {
- mlx5_del_flow_rules(rx_tables->crypto_miss_rule);
- rx_tables->crypto_miss_rule = NULL;
- }
-
- mlx5e_destroy_flow_table(&rx_tables->ft_crypto);
-}
-
-static int macsec_fs_rx_create_crypto_table_groups(struct mlx5e_flow_table *ft)
-{
- int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
- int mclen = MLX5_ST_SZ_BYTES(fte_match_param);
- int ix = 0;
- u32 *in;
- int err;
- u8 *mc;
-
- ft->g = kcalloc(RX_CRYPTO_TABLE_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
- if (!ft->g)
- return -ENOMEM;
-
- in = kvzalloc(inlen, GFP_KERNEL);
- if (!in) {
- kfree(ft->g);
- return -ENOMEM;
- }
-
- mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
-
- /* Flow group for SA rule with SCI */
- MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS |
- MLX5_MATCH_MISC_PARAMETERS_5);
- MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype);
-
- MLX5_SET(fte_match_param, mc, misc_parameters_5.macsec_tag_0,
- MLX5_MACSEC_SECTAG_TCI_AN_FIELD_BITMASK <<
- MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET);
- MLX5_SET_TO_ONES(fte_match_param, mc, misc_parameters_5.macsec_tag_2);
- MLX5_SET_TO_ONES(fte_match_param, mc, misc_parameters_5.macsec_tag_3);
-
- MLX5_SET_CFG(in, start_flow_index, ix);
- ix += RX_CRYPTO_TABLE_SA_RULE_WITH_SCI_GROUP_SIZE;
- MLX5_SET_CFG(in, end_flow_index, ix - 1);
- ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
- if (IS_ERR(ft->g[ft->num_groups]))
- goto err;
- ft->num_groups++;
-
- /* Flow group for SA rule without SCI */
- memset(in, 0, inlen);
- memset(mc, 0, mclen);
- MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS |
- MLX5_MATCH_MISC_PARAMETERS_5);
- MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.smac_47_16);
- MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.smac_15_0);
- MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype);
-
- MLX5_SET(fte_match_param, mc, misc_parameters_5.macsec_tag_0,
- MLX5_MACSEC_SECTAG_TCI_AN_FIELD_BITMASK << MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET);
-
- MLX5_SET_CFG(in, start_flow_index, ix);
- ix += RX_CRYPTO_TABLE_SA_RULE_WITHOUT_SCI_GROUP_SIZE;
- MLX5_SET_CFG(in, end_flow_index, ix - 1);
- ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
- if (IS_ERR(ft->g[ft->num_groups]))
- goto err;
- ft->num_groups++;
-
- /* Flow Group for l2 traps */
- memset(in, 0, inlen);
- memset(mc, 0, mclen);
- MLX5_SET_CFG(in, start_flow_index, ix);
- ix += CRYPTO_TABLE_DEFAULT_RULE_GROUP_SIZE;
- MLX5_SET_CFG(in, end_flow_index, ix - 1);
- ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
- if (IS_ERR(ft->g[ft->num_groups]))
- goto err;
- ft->num_groups++;
-
- kvfree(in);
- return 0;
-
-err:
- err = PTR_ERR(ft->g[ft->num_groups]);
- ft->g[ft->num_groups] = NULL;
- kvfree(in);
-
- return err;
-}
-
-static int macsec_fs_rx_create_check_decap_rule(struct mlx5e_macsec_fs *macsec_fs,
- struct mlx5_flow_destination *dest,
- struct mlx5_flow_act *flow_act,
- struct mlx5_flow_spec *spec,
- int reformat_param_size)
-{
- int rule_index = (reformat_param_size == MLX5_SECTAG_HEADER_SIZE_WITH_SCI) ? 0 : 1;
- u8 mlx5_reformat_buf[MLX5_SECTAG_HEADER_SIZE_WITH_SCI];
- struct mlx5_pkt_reformat_params reformat_params = {};
- struct mlx5e_macsec_rx *rx_fs = macsec_fs->rx_fs;
- struct net_device *netdev = macsec_fs->netdev;
- struct mlx5e_macsec_tables *rx_tables;
- struct mlx5_flow_handle *rule;
- int err = 0;
-
- rx_tables = &rx_fs->tables;
-
- /* Rx check table decap 16B rule */
- memset(dest, 0, sizeof(*dest));
- memset(flow_act, 0, sizeof(*flow_act));
- memset(spec, 0, sizeof(*spec));
-
- reformat_params.type = MLX5_REFORMAT_TYPE_DEL_MACSEC;
- reformat_params.size = reformat_param_size;
- reformat_params.data = mlx5_reformat_buf;
- flow_act->pkt_reformat = mlx5_packet_reformat_alloc(macsec_fs->mdev,
- &reformat_params,
- MLX5_FLOW_NAMESPACE_KERNEL_RX_MACSEC);
- if (IS_ERR(flow_act->pkt_reformat)) {
- err = PTR_ERR(flow_act->pkt_reformat);
- netdev_err(netdev, "Failed to allocate MACsec Rx reformat context err=%d\n", err);
- return err;
- }
- rx_fs->check_rule_pkt_reformat[rule_index] = flow_act->pkt_reformat;
-
- spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2;
- /* MACsec syndrome match */
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, misc_parameters_2.macsec_syndrome);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_2.macsec_syndrome, 0);
- /* ASO return reg syndrome match */
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, misc_parameters_2.metadata_reg_c_4);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_2.metadata_reg_c_4, 0);
-
- spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_5;
- /* Sectag TCI SC present bit*/
- MLX5_SET(fte_match_param, spec->match_criteria, misc_parameters_5.macsec_tag_0,
- MLX5_MACSEC_SECTAG_TCI_SC_FIELD_BIT << MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET);
-
- if (reformat_param_size == MLX5_SECTAG_HEADER_SIZE_WITH_SCI)
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_5.macsec_tag_0,
- MLX5_MACSEC_SECTAG_TCI_SC_FIELD_BIT <<
- MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET);
-
- flow_act->flags = FLOW_ACT_NO_APPEND;
- flow_act->action = MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO |
- MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT |
- MLX5_FLOW_CONTEXT_ACTION_COUNT;
- dest->type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
- dest->counter_id = mlx5_fc_id(rx_tables->check_rule_counter);
- rule = mlx5_add_flow_rules(rx_tables->ft_check, spec, flow_act, dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to add MACsec Rx check rule, err=%d\n", err);
- return err;
- }
-
- rx_fs->check_rule[rule_index] = rule;
-
- return 0;
-}
-
-static int macsec_fs_rx_create(struct mlx5e_macsec_fs *macsec_fs)
-{
- int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
- struct mlx5e_macsec_rx *rx_fs = macsec_fs->rx_fs;
- struct net_device *netdev = macsec_fs->netdev;
- struct mlx5_flow_table_attr ft_attr = {};
- struct mlx5_flow_destination dest = {};
- struct mlx5e_macsec_tables *rx_tables;
- struct mlx5e_flow_table *ft_crypto;
- struct mlx5_flow_table *flow_table;
- struct mlx5_flow_group *flow_group;
- struct mlx5_flow_act flow_act = {};
- struct mlx5_flow_namespace *ns;
- struct mlx5_flow_handle *rule;
- struct mlx5_flow_spec *spec;
- u32 *flow_group_in;
- int err;
-
- ns = mlx5_get_flow_namespace(macsec_fs->mdev, MLX5_FLOW_NAMESPACE_KERNEL_RX_MACSEC);
- if (!ns)
- return -ENOMEM;
-
- spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
-
- flow_group_in = kvzalloc(inlen, GFP_KERNEL);
- if (!flow_group_in) {
- err = -ENOMEM;
- goto free_spec;
- }
-
- rx_tables = &rx_fs->tables;
- ft_crypto = &rx_tables->ft_crypto;
-
- /* Rx crypto table */
- ft_attr.level = RX_CRYPTO_TABLE_LEVEL;
- ft_attr.max_fte = CRYPTO_NUM_MAXSEC_FTE;
-
- flow_table = mlx5_create_flow_table(ns, &ft_attr);
- if (IS_ERR(flow_table)) {
- err = PTR_ERR(flow_table);
- netdev_err(netdev, "Failed to create MACsec Rx crypto table err(%d)\n", err);
- goto out_flow_group;
- }
- ft_crypto->t = flow_table;
-
- /* Rx crypto table groups */
- err = macsec_fs_rx_create_crypto_table_groups(ft_crypto);
- if (err) {
- netdev_err(netdev,
- "Failed to create default flow group for MACsec Tx crypto table err(%d)\n",
- err);
- goto err;
- }
-
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
- rule = mlx5_add_flow_rules(ft_crypto->t, NULL, &flow_act, NULL, 0);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev,
- "Failed to add MACsec Rx crypto table default miss rule %d\n",
- err);
- goto err;
- }
- rx_tables->crypto_miss_rule = rule;
-
- /* Rx check table */
- flow_table = macsec_fs_auto_group_table_create(ns,
- MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT,
- RX_CHECK_TABLE_LEVEL,
- RX_CHECK_TABLE_NUM_FTE);
- if (IS_ERR(flow_table)) {
- err = PTR_ERR(flow_table);
- netdev_err(netdev, "fail to create MACsec RX check table, err(%d)\n", err);
- goto err;
- }
- rx_tables->ft_check = flow_table;
-
- /* Rx check table Default miss group/rule */
- MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_table->max_fte - 1);
- MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_table->max_fte - 1);
- flow_group = mlx5_create_flow_group(rx_tables->ft_check, flow_group_in);
- if (IS_ERR(flow_group)) {
- err = PTR_ERR(flow_group);
- netdev_err(netdev,
- "Failed to create default flow group for MACsec Rx check table err(%d)\n",
- err);
- goto err;
- }
- rx_tables->ft_check_group = flow_group;
-
- /* Rx check table default drop rule */
- memset(&flow_act, 0, sizeof(flow_act));
-
- dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
- dest.counter_id = mlx5_fc_id(rx_tables->check_miss_rule_counter);
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
- rule = mlx5_add_flow_rules(rx_tables->ft_check, NULL, &flow_act, &dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev, "Failed to added MACsec Rx check drop rule, err(%d)\n", err);
- goto err;
- }
- rx_tables->check_miss_rule = rule;
-
- /* Rx check table decap rules */
- err = macsec_fs_rx_create_check_decap_rule(macsec_fs, &dest, &flow_act, spec,
- MLX5_SECTAG_HEADER_SIZE_WITH_SCI);
- if (err)
- goto err;
-
- err = macsec_fs_rx_create_check_decap_rule(macsec_fs, &dest, &flow_act, spec,
- MLX5_SECTAG_HEADER_SIZE_WITHOUT_SCI);
- if (err)
- goto err;
-
- goto out_flow_group;
-
-err:
- macsec_fs_rx_destroy(macsec_fs);
-out_flow_group:
- kvfree(flow_group_in);
-free_spec:
- kvfree(spec);
- return err;
-}
-
-static int macsec_fs_rx_ft_get(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_tables *rx_tables = &macsec_fs->rx_fs->tables;
- int err = 0;
-
- if (rx_tables->refcnt)
- goto out;
-
- err = macsec_fs_rx_create(macsec_fs);
- if (err)
- return err;
-
-out:
- rx_tables->refcnt++;
- return err;
-}
-
-static void macsec_fs_rx_ft_put(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_tables *rx_tables = &macsec_fs->rx_fs->tables;
-
- if (--rx_tables->refcnt)
- return;
-
- macsec_fs_rx_destroy(macsec_fs);
-}
-
-static void macsec_fs_rx_del_rule(struct mlx5e_macsec_fs *macsec_fs,
- struct mlx5e_macsec_rx_rule *rx_rule)
-{
- int i;
-
- for (i = 0; i < RX_NUM_OF_RULES_PER_SA; ++i) {
- if (rx_rule->rule[i]) {
- mlx5_del_flow_rules(rx_rule->rule[i]);
- rx_rule->rule[i] = NULL;
- }
- }
-
- if (rx_rule->meta_modhdr) {
- mlx5_modify_header_dealloc(macsec_fs->mdev, rx_rule->meta_modhdr);
- rx_rule->meta_modhdr = NULL;
- }
-
- kfree(rx_rule);
-
- macsec_fs_rx_ft_put(macsec_fs);
-}
-
-static void macsec_fs_rx_setup_fte(struct mlx5_flow_spec *spec,
- struct mlx5_flow_act *flow_act,
- struct mlx5_macsec_rule_attrs *attrs,
- bool sci_present)
-{
- u8 tci_an = (sci_present << MLX5_MACSEC_SECTAG_TCI_SC_FIELD_OFFSET) | attrs->assoc_num;
- struct mlx5_flow_act_crypto_params *crypto_params = &flow_act->crypto;
- __be32 *sci_p = (__be32 *)(&attrs->sci);
-
- spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
-
- /* MACsec ethertype */
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype);
- MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, ETH_P_MACSEC);
-
- spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_5;
-
- /* Sectag AN + TCI SC present bit*/
- MLX5_SET(fte_match_param, spec->match_criteria, misc_parameters_5.macsec_tag_0,
- MLX5_MACSEC_SECTAG_TCI_AN_FIELD_BITMASK << MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_5.macsec_tag_0,
- tci_an << MLX5_MACSEC_SECTAG_TCI_AN_FIELD_OFFSET);
-
- if (sci_present) {
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
- misc_parameters_5.macsec_tag_2);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_5.macsec_tag_2,
- be32_to_cpu(sci_p[0]));
-
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
- misc_parameters_5.macsec_tag_3);
- MLX5_SET(fte_match_param, spec->match_value, misc_parameters_5.macsec_tag_3,
- be32_to_cpu(sci_p[1]));
- } else {
- /* When SCI isn't present in the Sectag, need to match the source */
- /* MAC address only if the SCI contains the default MACsec PORT */
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.smac_47_16);
- MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.smac_15_0);
- memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers.smac_47_16),
- sci_p, ETH_ALEN);
- }
-
- crypto_params->type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_MACSEC;
- crypto_params->obj_id = attrs->macsec_obj_id;
-}
-
-static union mlx5e_macsec_rule *
-macsec_fs_rx_add_rule(struct mlx5e_macsec_fs *macsec_fs,
- struct mlx5_macsec_rule_attrs *attrs,
- u32 fs_id)
-{
- u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
- struct mlx5e_macsec_rx *rx_fs = macsec_fs->rx_fs;
- struct net_device *netdev = macsec_fs->netdev;
- union mlx5e_macsec_rule *macsec_rule = NULL;
- struct mlx5_modify_hdr *modify_hdr = NULL;
- struct mlx5_flow_destination dest = {};
- struct mlx5e_macsec_tables *rx_tables;
- struct mlx5e_macsec_rx_rule *rx_rule;
- struct mlx5_flow_act flow_act = {};
- struct mlx5e_flow_table *ft_crypto;
- struct mlx5_flow_handle *rule;
- struct mlx5_flow_spec *spec;
- int err = 0;
-
- spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return NULL;
-
- err = macsec_fs_rx_ft_get(macsec_fs);
- if (err)
- goto out_spec;
-
- macsec_rule = kzalloc(sizeof(*macsec_rule), GFP_KERNEL);
- if (!macsec_rule) {
- macsec_fs_rx_ft_put(macsec_fs);
- goto out_spec;
- }
-
- rx_rule = &macsec_rule->rx_rule;
- rx_tables = &rx_fs->tables;
- ft_crypto = &rx_tables->ft_crypto;
-
- /* Set bit[31 - 30] macsec marker - 0x01 */
- /* Set bit[15-0] fs id */
- MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);
- MLX5_SET(set_action_in, action, field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);
- MLX5_SET(set_action_in, action, data, MLX5_MACSEC_RX_METADAT_HANDLE(fs_id) | BIT(30));
- MLX5_SET(set_action_in, action, offset, 0);
- MLX5_SET(set_action_in, action, length, 32);
-
- modify_hdr = mlx5_modify_header_alloc(macsec_fs->mdev, MLX5_FLOW_NAMESPACE_KERNEL_RX_MACSEC,
- 1, action);
- if (IS_ERR(modify_hdr)) {
- err = PTR_ERR(modify_hdr);
- netdev_err(netdev, "fail to alloc MACsec set modify_header_id err=%d\n", err);
- modify_hdr = NULL;
- goto err;
- }
- rx_rule->meta_modhdr = modify_hdr;
-
- /* Rx crypto table with SCI rule */
- macsec_fs_rx_setup_fte(spec, &flow_act, attrs, true);
-
- flow_act.modify_hdr = modify_hdr;
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
- MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT |
- MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
-
- dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
- dest.ft = rx_tables->ft_check;
- rule = mlx5_add_flow_rules(ft_crypto->t, spec, &flow_act, &dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev,
- "Failed to add SA with SCI rule to Rx crypto rule, err=%d\n",
- err);
- goto err;
- }
- rx_rule->rule[0] = rule;
-
- /* Rx crypto table without SCI rule */
- if ((cpu_to_be64((__force u64)attrs->sci) & 0xFFFF) == ntohs(MACSEC_PORT_ES)) {
- memset(spec, 0, sizeof(struct mlx5_flow_spec));
- memset(&dest, 0, sizeof(struct mlx5_flow_destination));
- memset(&flow_act, 0, sizeof(flow_act));
-
- macsec_fs_rx_setup_fte(spec, &flow_act, attrs, false);
-
- flow_act.modify_hdr = modify_hdr;
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
- MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT |
- MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
-
- dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
- dest.ft = rx_tables->ft_check;
- rule = mlx5_add_flow_rules(ft_crypto->t, spec, &flow_act, &dest, 1);
- if (IS_ERR(rule)) {
- err = PTR_ERR(rule);
- netdev_err(netdev,
- "Failed to add SA without SCI rule to Rx crypto rule, err=%d\n",
- err);
- goto err;
- }
- rx_rule->rule[1] = rule;
- }
-
- kvfree(spec);
- return macsec_rule;
-
-err:
- macsec_fs_rx_del_rule(macsec_fs, rx_rule);
- macsec_rule = NULL;
-out_spec:
- kvfree(spec);
- return macsec_rule;
-}
-
-static int macsec_fs_rx_init(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct net_device *netdev = macsec_fs->netdev;
- struct mlx5_core_dev *mdev = macsec_fs->mdev;
- struct mlx5e_macsec_tables *rx_tables;
- struct mlx5e_macsec_rx *rx_fs;
- struct mlx5_fc *flow_counter;
- int err;
-
- rx_fs = kzalloc(sizeof(*rx_fs), GFP_KERNEL);
- if (!rx_fs)
- return -ENOMEM;
-
- flow_counter = mlx5_fc_create(mdev, false);
- if (IS_ERR(flow_counter)) {
- err = PTR_ERR(flow_counter);
- netdev_err(netdev,
- "Failed to create MACsec Rx encrypt flow counter, err(%d)\n",
- err);
- goto err_encrypt_counter;
- }
-
- rx_tables = &rx_fs->tables;
- rx_tables->check_rule_counter = flow_counter;
-
- flow_counter = mlx5_fc_create(mdev, false);
- if (IS_ERR(flow_counter)) {
- err = PTR_ERR(flow_counter);
- netdev_err(netdev,
- "Failed to create MACsec Rx drop flow counter, err(%d)\n",
- err);
- goto err_drop_counter;
- }
- rx_tables->check_miss_rule_counter = flow_counter;
-
- macsec_fs->rx_fs = rx_fs;
-
- return 0;
-
-err_drop_counter:
- mlx5_fc_destroy(mdev, rx_tables->check_rule_counter);
- rx_tables->check_rule_counter = NULL;
-
-err_encrypt_counter:
- kfree(rx_fs);
- macsec_fs->rx_fs = NULL;
-
- return err;
-}
-
-static void macsec_fs_rx_cleanup(struct mlx5e_macsec_fs *macsec_fs)
-{
- struct mlx5e_macsec_rx *rx_fs = macsec_fs->rx_fs;
- struct mlx5_core_dev *mdev = macsec_fs->mdev;
- struct mlx5e_macsec_tables *rx_tables;
-
- if (!rx_fs)
- return;
-
- rx_tables = &rx_fs->tables;
-
- if (rx_tables->refcnt) {
- netdev_err(macsec_fs->netdev,
- "Can't destroy MACsec offload rx_fs, refcnt(%u) isn't 0\n",
- rx_tables->refcnt);
- return;
- }
-
- if (rx_tables->check_miss_rule_counter) {
- mlx5_fc_destroy(mdev, rx_tables->check_miss_rule_counter);
- rx_tables->check_miss_rule_counter = NULL;
- }
-
- if (rx_tables->check_rule_counter) {
- mlx5_fc_destroy(mdev, rx_tables->check_rule_counter);
- rx_tables->check_rule_counter = NULL;
- }
-
- kfree(rx_fs);
- macsec_fs->rx_fs = NULL;
-}
-
-void mlx5e_macsec_fs_get_stats_fill(struct mlx5e_macsec_fs *macsec_fs, void *macsec_stats)
-{
- struct mlx5e_macsec_stats *stats = (struct mlx5e_macsec_stats *)macsec_stats;
- struct mlx5e_macsec_tables *tx_tables = &macsec_fs->tx_fs->tables;
- struct mlx5e_macsec_tables *rx_tables = &macsec_fs->rx_fs->tables;
- struct mlx5_core_dev *mdev = macsec_fs->mdev;
-
- if (tx_tables->check_rule_counter)
- mlx5_fc_query(mdev, tx_tables->check_rule_counter,
- &stats->macsec_tx_pkts, &stats->macsec_tx_bytes);
-
- if (tx_tables->check_miss_rule_counter)
- mlx5_fc_query(mdev, tx_tables->check_miss_rule_counter,
- &stats->macsec_tx_pkts_drop, &stats->macsec_tx_bytes_drop);
-
- if (rx_tables->check_rule_counter)
- mlx5_fc_query(mdev, rx_tables->check_rule_counter,
- &stats->macsec_rx_pkts, &stats->macsec_rx_bytes);
-
- if (rx_tables->check_miss_rule_counter)
- mlx5_fc_query(mdev, rx_tables->check_miss_rule_counter,
- &stats->macsec_rx_pkts_drop, &stats->macsec_rx_bytes_drop);
-}
-
-union mlx5e_macsec_rule *
-mlx5e_macsec_fs_add_rule(struct mlx5e_macsec_fs *macsec_fs,
- const struct macsec_context *macsec_ctx,
- struct mlx5_macsec_rule_attrs *attrs,
- u32 *sa_fs_id)
-{
- return (attrs->action == MLX5_ACCEL_MACSEC_ACTION_ENCRYPT) ?
- macsec_fs_tx_add_rule(macsec_fs, macsec_ctx, attrs, sa_fs_id) :
- macsec_fs_rx_add_rule(macsec_fs, attrs, *sa_fs_id);
-}
-
-void mlx5e_macsec_fs_del_rule(struct mlx5e_macsec_fs *macsec_fs,
- union mlx5e_macsec_rule *macsec_rule,
- int action)
-{
- (action == MLX5_ACCEL_MACSEC_ACTION_ENCRYPT) ?
- macsec_fs_tx_del_rule(macsec_fs, &macsec_rule->tx_rule) :
- macsec_fs_rx_del_rule(macsec_fs, &macsec_rule->rx_rule);
-}
-
-void mlx5e_macsec_fs_cleanup(struct mlx5e_macsec_fs *macsec_fs)
-{
- macsec_fs_rx_cleanup(macsec_fs);
- macsec_fs_tx_cleanup(macsec_fs);
- kfree(macsec_fs);
-}
-
-struct mlx5e_macsec_fs *
-mlx5e_macsec_fs_init(struct mlx5_core_dev *mdev,
- struct net_device *netdev)
-{
- struct mlx5e_macsec_fs *macsec_fs;
- int err;
-
- macsec_fs = kzalloc(sizeof(*macsec_fs), GFP_KERNEL);
- if (!macsec_fs)
- return NULL;
-
- macsec_fs->mdev = mdev;
- macsec_fs->netdev = netdev;
-
- err = macsec_fs_tx_init(macsec_fs);
- if (err) {
- netdev_err(netdev, "MACsec offload: Failed to init tx_fs, err=%d\n", err);
- goto err;
- }
-
- err = macsec_fs_rx_init(macsec_fs);
- if (err) {
- netdev_err(netdev, "MACsec offload: Failed to init tx_fs, err=%d\n", err);
- goto tx_cleanup;
- }
-
- return macsec_fs;
-
-tx_cleanup:
- macsec_fs_tx_cleanup(macsec_fs);
-err:
- kfree(macsec_fs);
- return NULL;
-}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.h
deleted file mode 100644
index b429648d4ee7..000000000000
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
-/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
-
-#ifndef __MLX5_MACSEC_STEERING_H__
-#define __MLX5_MACSEC_STEERING_H__
-
-#ifdef CONFIG_MLX5_EN_MACSEC
-
-#include "en_accel/macsec.h"
-
-#define MLX5_MACSEC_NUM_OF_SUPPORTED_INTERFACES 16
-
-struct mlx5e_macsec_fs;
-union mlx5e_macsec_rule;
-
-struct mlx5_macsec_rule_attrs {
- sci_t sci;
- u32 macsec_obj_id;
- u8 assoc_num;
- int action;
-};
-
-enum mlx5_macsec_action {
- MLX5_ACCEL_MACSEC_ACTION_ENCRYPT,
- MLX5_ACCEL_MACSEC_ACTION_DECRYPT,
-};
-
-void mlx5e_macsec_fs_cleanup(struct mlx5e_macsec_fs *macsec_fs);
-
-struct mlx5e_macsec_fs *
-mlx5e_macsec_fs_init(struct mlx5_core_dev *mdev, struct net_device *netdev);
-
-union mlx5e_macsec_rule *
-mlx5e_macsec_fs_add_rule(struct mlx5e_macsec_fs *macsec_fs,
- const struct macsec_context *ctx,
- struct mlx5_macsec_rule_attrs *attrs,
- u32 *sa_fs_id);
-
-void mlx5e_macsec_fs_del_rule(struct mlx5e_macsec_fs *macsec_fs,
- union mlx5e_macsec_rule *macsec_rule,
- int action);
-
-void mlx5e_macsec_fs_get_stats_fill(struct mlx5e_macsec_fs *macsec_fs, void *macsec_stats);
-
-#endif
-
-#endif /* __MLX5_MACSEC_STEERING_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_stats.c
index e50a2e3f3d18..4559ee16a11a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_stats.c
@@ -8,14 +8,14 @@
#include "en_accel/macsec.h"
static const struct counter_desc mlx5e_macsec_hw_stats_desc[] = {
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_pkts) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_bytes) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_pkts_drop) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_bytes_drop) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_pkts) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_bytes) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_pkts_drop) },
- { MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_bytes_drop) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_pkts) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_bytes) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_pkts_drop) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_bytes_drop) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_pkts) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_bytes) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_pkts_drop) },
+ { MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_bytes_drop) },
};
#define NUM_MACSEC_HW_COUNTERS ARRAY_SIZE(mlx5e_macsec_hw_stats_desc)
@@ -52,6 +52,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(macsec_hw)
static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(macsec_hw)
{
+ struct mlx5_macsec_fs *macsec_fs;
int i;
if (!priv->macsec)
@@ -60,9 +61,10 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(macsec_hw)
if (!mlx5e_is_macsec_device(priv->mdev))
return idx;
- mlx5e_macsec_get_stats_fill(priv->macsec, mlx5e_macsec_get_stats(priv->macsec));
+ macsec_fs = priv->mdev->macsec_fs;
+ mlx5_macsec_fs_get_stats_fill(macsec_fs, mlx5_macsec_fs_get_stats(macsec_fs));
for (i = 0; i < NUM_MACSEC_HW_COUNTERS; i++)
- data[idx++] = MLX5E_READ_CTR64_CPU(mlx5e_macsec_get_stats(priv->macsec),
+ data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_macsec_fs_get_stats(macsec_fs),
mlx5e_macsec_hw_stats_desc,
i);