Skip to content

Commit

Permalink
Merge tag 'mlx5-updates-2020-04-20' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2020-04-20

This series includes misc updates and clean ups to mlx5 driver:

1) improve some comments from Hu Haowen.
2) Handles errors of netif_set_real_num_{tx,rx}_queues, from Maxim
3) IPsec and FPGA related code cleanup to prepare for ASIC devices
   IPsec offloads, from Raed
4) Allow partial mask for tunnel options, from Roi.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 20, 2020
2 parents 794867e + 6533380 commit 80ad41f
Show file tree
Hide file tree
Showing 18 changed files with 242 additions and 184 deletions.
19 changes: 14 additions & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,21 @@ int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,

void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
struct mlx5_accel_esp_xfrm *xfrm,
const __be32 saddr[4],
const __be32 daddr[4],
const __be32 spi, bool is_ipv6)
u32 *sa_handle)
{
return mlx5_fpga_ipsec_create_sa_ctx(mdev, xfrm, saddr, daddr,
spi, is_ipv6);
__be32 saddr[4] = {}, daddr[4] = {};

if (!xfrm->attrs.is_ipv6) {
saddr[3] = xfrm->attrs.saddr.a4;
daddr[3] = xfrm->attrs.daddr.a4;
} else {
memcpy(saddr, xfrm->attrs.saddr.a6, sizeof(saddr));
memcpy(daddr, xfrm->attrs.daddr.a6, sizeof(daddr));
}

return mlx5_fpga_ipsec_create_sa_ctx(mdev, xfrm, saddr,
daddr, xfrm->attrs.spi,
xfrm->attrs.is_ipv6, sa_handle);
}

void mlx5_accel_esp_free_hw_context(void *context)
Expand Down
8 changes: 2 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,

void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
struct mlx5_accel_esp_xfrm *xfrm,
const __be32 saddr[4],
const __be32 daddr[4],
const __be32 spi, bool is_ipv6);
u32 *sa_handle);
void mlx5_accel_esp_free_hw_context(void *context);

int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev);
Expand All @@ -64,9 +62,7 @@ void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev);
static inline void *
mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
struct mlx5_accel_esp_xfrm *xfrm,
const __be32 saddr[4],
const __be32 daddr[4],
const __be32 spi, bool is_ipv6)
u32 *sa_handle)
{
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
get_block_timestamp(tracer, &tmp_trace_block[TRACES_PER_BLOCK - 1]);

while (block_timestamp > tracer->last_timestamp) {
/* Check block override if its not the first block */
/* Check block override if it's not the first block */
if (!tracer->last_timestamp) {
u64 *ts_event;
/* To avoid block override be the HW in case of buffer
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static inline void
mlx5e_notify_hw(struct mlx5_wq_cyc *wq, u16 pc, void __iomem *uar_map,
struct mlx5_wqe_ctrl_seg *ctrl)
{
ctrl->fm_ce_se = MLX5_WQE_CTRL_CQ_UPDATE;
ctrl->fm_ce_se |= MLX5_WQE_CTRL_CQ_UPDATE;
/* ensure wqe is visible to device before updating doorbell record */
dma_wmb();

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include "en/txrx.h"

#if IS_ENABLED(CONFIG_GENEVE)
#include <net/geneve.h>

static inline bool mlx5_geneve_tx_allowed(struct mlx5_core_dev *mdev)
{
return mlx5_tx_swp_supported(mdev);
Expand Down
87 changes: 35 additions & 52 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,23 @@ struct xfrm_state *mlx5e_ipsec_sadb_rx_lookup(struct mlx5e_ipsec *ipsec,
return ret;
}

static int mlx5e_ipsec_sadb_rx_add(struct mlx5e_ipsec_sa_entry *sa_entry)
static int mlx5e_ipsec_sadb_rx_add(struct mlx5e_ipsec_sa_entry *sa_entry,
unsigned int handle)
{
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
struct mlx5e_ipsec_sa_entry *_sa_entry;
unsigned long flags;
int ret;

ret = ida_simple_get(&ipsec->halloc, 1, 0, GFP_KERNEL);
if (ret < 0)
return ret;
rcu_read_lock();
hash_for_each_possible_rcu(ipsec->sadb_rx, _sa_entry, hlist, handle)
if (_sa_entry->handle == handle) {
rcu_read_unlock();
return -EEXIST;
}
rcu_read_unlock();

spin_lock_irqsave(&ipsec->sadb_rx_lock, flags);
sa_entry->handle = ret;
sa_entry->handle = handle;
hash_add_rcu(ipsec->sadb_rx, &sa_entry->hlist, sa_entry->handle);
spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags);

Expand All @@ -103,15 +108,6 @@ static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry)
spin_unlock_irqrestore(&ipsec->sadb_rx_lock, flags);
}

static void mlx5e_ipsec_sadb_rx_free(struct mlx5e_ipsec_sa_entry *sa_entry)
{
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;

/* xfrm already doing sync rcu between del and free callbacks */

ida_simple_remove(&ipsec->halloc, sa_entry->handle);
}

static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
{
struct xfrm_replay_state_esn *replay_esn;
Expand Down Expand Up @@ -199,6 +195,14 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
attrs->flags |= (x->props.mode == XFRM_MODE_TRANSPORT) ?
MLX5_ACCEL_ESP_FLAGS_TRANSPORT :
MLX5_ACCEL_ESP_FLAGS_TUNNEL;

/* spi */
attrs->spi = x->id.spi;

/* source , destination ips */
memcpy(&attrs->saddr, x->props.saddr.a6, sizeof(attrs->saddr));
memcpy(&attrs->daddr, x->id.daddr.a6, sizeof(attrs->daddr));
attrs->is_ipv6 = (x->props.family != AF_INET);
}

static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
Expand Down Expand Up @@ -284,8 +288,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
struct net_device *netdev = x->xso.dev;
struct mlx5_accel_esp_xfrm_attrs attrs;
struct mlx5e_priv *priv;
__be32 saddr[4] = {0}, daddr[4] = {0}, spi;
bool is_ipv6 = false;
unsigned int sa_handle;
int err;

priv = netdev_priv(netdev);
Expand All @@ -303,20 +306,6 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
sa_entry->x = x;
sa_entry->ipsec = priv->ipsec;

/* Add the SA to handle processed incoming packets before the add SA
* completion was received
*/
if (x->xso.flags & XFRM_OFFLOAD_INBOUND) {
err = mlx5e_ipsec_sadb_rx_add(sa_entry);
if (err) {
netdev_info(netdev, "Failed adding to SADB_RX: %d\n", err);
goto err_entry;
}
} else {
sa_entry->set_iv_op = (x->props.flags & XFRM_STATE_ESN) ?
mlx5e_ipsec_set_iv_esn : mlx5e_ipsec_set_iv;
}

/* check esn */
mlx5e_ipsec_update_esn_state(sa_entry);

Expand All @@ -327,41 +316,38 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
MLX5_ACCEL_XFRM_FLAG_REQUIRE_METADATA);
if (IS_ERR(sa_entry->xfrm)) {
err = PTR_ERR(sa_entry->xfrm);
goto err_sadb_rx;
goto err_sa_entry;
}

/* create hw context */
if (x->props.family == AF_INET) {
saddr[3] = x->props.saddr.a4;
daddr[3] = x->id.daddr.a4;
} else {
memcpy(saddr, x->props.saddr.a6, sizeof(saddr));
memcpy(daddr, x->id.daddr.a6, sizeof(daddr));
is_ipv6 = true;
}
spi = x->id.spi;
sa_entry->hw_context =
mlx5_accel_esp_create_hw_context(priv->mdev,
sa_entry->xfrm,
saddr, daddr, spi,
is_ipv6);
&sa_handle);
if (IS_ERR(sa_entry->hw_context)) {
err = PTR_ERR(sa_entry->hw_context);
goto err_xfrm;
}

if (x->xso.flags & XFRM_OFFLOAD_INBOUND) {
err = mlx5e_ipsec_sadb_rx_add(sa_entry, sa_handle);
if (err)
goto err_hw_ctx;
} else {
sa_entry->set_iv_op = (x->props.flags & XFRM_STATE_ESN) ?
mlx5e_ipsec_set_iv_esn : mlx5e_ipsec_set_iv;
}

x->xso.offload_handle = (unsigned long)sa_entry;
goto out;

err_hw_ctx:
mlx5_accel_esp_free_hw_context(sa_entry->hw_context);
err_xfrm:
mlx5_accel_esp_destroy_xfrm(sa_entry->xfrm);
err_sadb_rx:
if (x->xso.flags & XFRM_OFFLOAD_INBOUND) {
mlx5e_ipsec_sadb_rx_del(sa_entry);
mlx5e_ipsec_sadb_rx_free(sa_entry);
}
err_entry:
err_sa_entry:
kfree(sa_entry);

out:
return err;
}
Expand Down Expand Up @@ -390,9 +376,6 @@ static void mlx5e_xfrm_free_state(struct xfrm_state *x)
mlx5_accel_esp_destroy_xfrm(sa_entry->xfrm);
}

if (x->xso.flags & XFRM_OFFLOAD_INBOUND)
mlx5e_ipsec_sadb_rx_free(sa_entry);

kfree(sa_entry);
}

Expand Down
25 changes: 0 additions & 25 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,6 @@ int mlx5e_ipsec_init(struct mlx5e_priv *priv);
void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv);
void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv);

int mlx5e_ipsec_get_count(struct mlx5e_priv *priv);
int mlx5e_ipsec_get_strings(struct mlx5e_priv *priv, uint8_t *data);
void mlx5e_ipsec_update_stats(struct mlx5e_priv *priv);
int mlx5e_ipsec_get_stats(struct mlx5e_priv *priv, u64 *data);

struct xfrm_state *mlx5e_ipsec_sadb_rx_lookup(struct mlx5e_ipsec *dev,
unsigned int handle);

Expand All @@ -136,26 +131,6 @@ static inline void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
{
}

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

static inline int mlx5e_ipsec_get_strings(struct mlx5e_priv *priv,
uint8_t *data)
{
return 0;
}

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

static inline int mlx5e_ipsec_get_stats(struct mlx5e_priv *priv, u64 *data)
{
return 0;
}

#endif

#endif /* __MLX5E_IPSEC_H__ */
88 changes: 51 additions & 37 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "accel/ipsec.h"
#include "fpga/sdk.h"
#include "en_accel/ipsec.h"
#include "fpga/ipsec.h"

static const struct counter_desc mlx5e_ipsec_hw_stats_desc[] = {
{ MLX5E_DECLARE_STAT(struct mlx5e_ipsec_stats, ipsec_dec_in_packets) },
Expand Down Expand Up @@ -73,61 +74,74 @@ static const struct counter_desc mlx5e_ipsec_sw_stats_desc[] = {
#define NUM_IPSEC_HW_COUNTERS ARRAY_SIZE(mlx5e_ipsec_hw_stats_desc)
#define NUM_IPSEC_SW_COUNTERS ARRAY_SIZE(mlx5e_ipsec_sw_stats_desc)

#define NUM_IPSEC_COUNTERS (NUM_IPSEC_HW_COUNTERS + NUM_IPSEC_SW_COUNTERS)

int mlx5e_ipsec_get_count(struct mlx5e_priv *priv)
static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(ipsec_sw)
{
if (!priv->ipsec)
return 0;

return NUM_IPSEC_COUNTERS;
return NUM_IPSEC_SW_COUNTERS;
}

int mlx5e_ipsec_get_strings(struct mlx5e_priv *priv, uint8_t *data)
{
unsigned int i, idx = 0;
static inline MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ipsec_sw) {}

if (!priv->ipsec)
return 0;
static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ipsec_sw)
{
unsigned int i;

for (i = 0; i < NUM_IPSEC_HW_COUNTERS; i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
mlx5e_ipsec_hw_stats_desc[i].format);
if (priv->ipsec)
for (i = 0; i < NUM_IPSEC_SW_COUNTERS; i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
mlx5e_ipsec_sw_stats_desc[i].format);
return idx;
}

for (i = 0; i < NUM_IPSEC_SW_COUNTERS; i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
mlx5e_ipsec_sw_stats_desc[i].format);
static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(ipsec_sw)
{
int i;

return NUM_IPSEC_COUNTERS;
if (priv->ipsec)
for (i = 0; i < NUM_IPSEC_SW_COUNTERS; i++)
data[idx++] = MLX5E_READ_CTR_ATOMIC64(&priv->ipsec->sw_stats,
mlx5e_ipsec_sw_stats_desc, i);
return idx;
}

void mlx5e_ipsec_update_stats(struct mlx5e_priv *priv)
static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(ipsec_hw)
{
int ret;
return (mlx5_fpga_ipsec_device_caps(priv->mdev)) ? NUM_IPSEC_HW_COUNTERS : 0;
}

if (!priv->ipsec)
return;
static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ipsec_hw)
{
int ret = 0;

ret = mlx5_accel_ipsec_counters_read(priv->mdev, (u64 *)&priv->ipsec->stats,
NUM_IPSEC_HW_COUNTERS);
if (priv->ipsec)
ret = mlx5_accel_ipsec_counters_read(priv->mdev, (u64 *)&priv->ipsec->stats,
NUM_IPSEC_HW_COUNTERS);
if (ret)
memset(&priv->ipsec->stats, 0, sizeof(priv->ipsec->stats));
}

int mlx5e_ipsec_get_stats(struct mlx5e_priv *priv, u64 *data)
static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ipsec_hw)
{
int i, idx = 0;

if (!priv->ipsec)
return 0;
unsigned int i;

for (i = 0; i < NUM_IPSEC_HW_COUNTERS; i++)
data[idx++] = MLX5E_READ_CTR64_CPU(&priv->ipsec->stats,
mlx5e_ipsec_hw_stats_desc, i);
if (priv->ipsec && mlx5_fpga_ipsec_device_caps(priv->mdev))
for (i = 0; i < NUM_IPSEC_HW_COUNTERS; i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
mlx5e_ipsec_hw_stats_desc[i].format);

for (i = 0; i < NUM_IPSEC_SW_COUNTERS; i++)
data[idx++] = MLX5E_READ_CTR_ATOMIC64(&priv->ipsec->sw_stats,
mlx5e_ipsec_sw_stats_desc, i);
return idx;
}

return NUM_IPSEC_COUNTERS;
static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(ipsec_hw)
{
int i;

if (priv->ipsec && mlx5_fpga_ipsec_device_caps(priv->mdev))
for (i = 0; i < NUM_IPSEC_HW_COUNTERS; i++)
data[idx++] = MLX5E_READ_CTR64_CPU(&priv->ipsec->stats,
mlx5e_ipsec_hw_stats_desc,
i);
return idx;
}

MLX5E_DEFINE_STATS_GRP(ipsec_sw, 0);
MLX5E_DEFINE_STATS_GRP(ipsec_hw, 0);
Loading

0 comments on commit 80ad41f

Please sign in to comment.