Skip to content

Commit

Permalink
net/mlx5e: loopback test is not supported in switchdev mode
Browse files Browse the repository at this point in the history
In switchdev mode we insert steering rules to eswitch that
make sure packets can't be looped back.
Modify the self tests infra and have flags per test.
Add a flag for tests that needs to be skipped in switchdev mode.

Before this commit:

$ ethtool --test enp8s0f0
 The test result is FAIL
 The test extra info:
 Link Test        0
 Speed Test       0
 Health Test      0
 Loopback Test    1

After this commit:

$ ethtool --test enp8s0f0
 The test result is PASS
 The test extra info:
 Link Test        0
 Speed Test       0
 Health Test      0

Example output in dmesg:

enp8s0f0: Self test begin..
enp8s0f0:         [0] Link Test start..
enp8s0f0:         [0] Link Test end: result(0)
enp8s0f0:         [1] Speed Test start..
enp8s0f0:         [1] Speed Test end: result(0)
enp8s0f0:         [2] Health Test start..
enp8s0f0:         [2] Health Test end: result(0)
enp8s0f0: Self test out: status flags(0x1)

Signed-off-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Maor Dickman <maord@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
  • Loading branch information
roidayan authored and Saeed Mahameed committed Sep 24, 2021
1 parent c50775d commit 7990b1b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 43 deletions.
3 changes: 1 addition & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Expand Up @@ -220,8 +220,6 @@ struct mlx5e_umr_wqe {
struct mlx5_mtt inline_mtts[0];
};

extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];

enum mlx5e_priv_flag {
MLX5E_PFLAG_RX_CQE_BASED_MODER,
MLX5E_PFLAG_TX_CQE_BASED_MODER,
Expand Down Expand Up @@ -916,6 +914,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)

void mlx5e_init_l2_addr(struct mlx5e_priv *priv);
int mlx5e_self_test_num(struct mlx5e_priv *priv);
int mlx5e_self_test_fill_strings(struct mlx5e_priv *priv, u8 *data);
void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
u64 *buf);
void mlx5e_set_rx_mode_work(struct work_struct *work);
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Expand Up @@ -267,9 +267,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
break;

case ETH_SS_TEST:
for (i = 0; i < mlx5e_self_test_num(priv); i++)
strcpy(data + i * ETH_GSTRING_LEN,
mlx5e_self_tests[i]);
mlx5e_self_test_fill_strings(priv, data);
break;

case ETH_SS_STATS:
Expand Down
92 changes: 54 additions & 38 deletions drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
Expand Up @@ -35,30 +35,7 @@
#include <net/udp.h>
#include "en.h"
#include "en/port.h"

enum {
MLX5E_ST_LINK_STATE,
MLX5E_ST_LINK_SPEED,
MLX5E_ST_HEALTH_INFO,
#ifdef CONFIG_INET
MLX5E_ST_LOOPBACK,
#endif
MLX5E_ST_NUM,
};

const char mlx5e_self_tests[MLX5E_ST_NUM][ETH_GSTRING_LEN] = {
"Link Test",
"Speed Test",
"Health Test",
#ifdef CONFIG_INET
"Loopback Test",
#endif
};

int mlx5e_self_test_num(struct mlx5e_priv *priv)
{
return ARRAY_SIZE(mlx5e_self_tests);
}
#include "eswitch.h"

static int mlx5e_test_health_info(struct mlx5e_priv *priv)
{
Expand Down Expand Up @@ -265,6 +242,14 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
mlx5e_refresh_tirs(priv, false, false);
}

static int mlx5e_cond_loopback(struct mlx5e_priv *priv)
{
if (is_mdev_switchdev_mode(priv->mdev))
return -EOPNOTSUPP;

return 0;
}

#define MLX5E_LB_VERIFY_TIMEOUT (msecs_to_jiffies(200))
static int mlx5e_test_loopback(struct mlx5e_priv *priv)
{
Expand Down Expand Up @@ -313,37 +298,47 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv)
}
#endif

static int (*mlx5e_st_func[MLX5E_ST_NUM])(struct mlx5e_priv *) = {
mlx5e_test_link_state,
mlx5e_test_link_speed,
mlx5e_test_health_info,
typedef int (*mlx5e_st_func)(struct mlx5e_priv *);

struct mlx5e_st {
char name[ETH_GSTRING_LEN];
mlx5e_st_func st_func;
mlx5e_st_func cond_func;
};

static struct mlx5e_st mlx5e_sts[] = {
{ "Link Test", mlx5e_test_link_state },
{ "Speed Test", mlx5e_test_link_speed },
{ "Health Test", mlx5e_test_health_info },
#ifdef CONFIG_INET
mlx5e_test_loopback,
{ "Loopback Test", mlx5e_test_loopback, mlx5e_cond_loopback },
#endif
};

#define MLX5E_ST_NUM ARRAY_SIZE(mlx5e_sts)

void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
u64 *buf)
{
struct mlx5e_priv *priv = netdev_priv(ndev);
int i;

memset(buf, 0, sizeof(u64) * MLX5E_ST_NUM);
int i, count = 0;

mutex_lock(&priv->state_lock);
netdev_info(ndev, "Self test begin..\n");

for (i = 0; i < MLX5E_ST_NUM; i++) {
netdev_info(ndev, "\t[%d] %s start..\n",
i, mlx5e_self_tests[i]);
buf[i] = mlx5e_st_func[i](priv);
netdev_info(ndev, "\t[%d] %s end: result(%lld)\n",
i, mlx5e_self_tests[i], buf[i]);
struct mlx5e_st st = mlx5e_sts[i];

if (st.cond_func && st.cond_func(priv))
continue;
netdev_info(ndev, "\t[%d] %s start..\n", i, st.name);
buf[count] = st.st_func(priv);
netdev_info(ndev, "\t[%d] %s end: result(%lld)\n", i, st.name, buf[count]);
}

mutex_unlock(&priv->state_lock);

for (i = 0; i < MLX5E_ST_NUM; i++) {
for (i = 0; i < count; i++) {
if (buf[i]) {
etest->flags |= ETH_TEST_FL_FAILED;
break;
Expand All @@ -352,3 +347,24 @@ void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
netdev_info(ndev, "Self test out: status flags(0x%x)\n",
etest->flags);
}

int mlx5e_self_test_fill_strings(struct mlx5e_priv *priv, u8 *data)
{
int i, count = 0;

for (i = 0; i < MLX5E_ST_NUM; i++) {
struct mlx5e_st st = mlx5e_sts[i];

if (st.cond_func && st.cond_func(priv))
continue;
if (data)
strcpy(data + count * ETH_GSTRING_LEN, st.name);
count++;
}
return count;
}

int mlx5e_self_test_num(struct mlx5e_priv *priv)
{
return mlx5e_self_test_fill_strings(priv, NULL);
}

0 comments on commit 7990b1b

Please sign in to comment.