Commit 7990b1b5 authored by Roi Dayan's avatar Roi Dayan Committed by Saeed Mahameed

net/mlx5e: loopback test is not supported in switchdev mode

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: default avatarRoi Dayan <roid@nvidia.com>
Reviewed-by: default avatarMaor Dickman <maord@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent c50775d0
...@@ -220,8 +220,6 @@ struct mlx5e_umr_wqe { ...@@ -220,8 +220,6 @@ struct mlx5e_umr_wqe {
struct mlx5_mtt inline_mtts[0]; struct mlx5_mtt inline_mtts[0];
}; };
extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];
enum mlx5e_priv_flag { enum mlx5e_priv_flag {
MLX5E_PFLAG_RX_CQE_BASED_MODER, MLX5E_PFLAG_RX_CQE_BASED_MODER,
MLX5E_PFLAG_TX_CQE_BASED_MODER, MLX5E_PFLAG_TX_CQE_BASED_MODER,
...@@ -916,6 +914,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) ...@@ -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); void mlx5e_init_l2_addr(struct mlx5e_priv *priv);
int mlx5e_self_test_num(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, void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
u64 *buf); u64 *buf);
void mlx5e_set_rx_mode_work(struct work_struct *work); void mlx5e_set_rx_mode_work(struct work_struct *work);
......
...@@ -267,9 +267,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data) ...@@ -267,9 +267,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
break; break;
case ETH_SS_TEST: case ETH_SS_TEST:
for (i = 0; i < mlx5e_self_test_num(priv); i++) mlx5e_self_test_fill_strings(priv, data);
strcpy(data + i * ETH_GSTRING_LEN,
mlx5e_self_tests[i]);
break; break;
case ETH_SS_STATS: case ETH_SS_STATS:
......
...@@ -35,30 +35,7 @@ ...@@ -35,30 +35,7 @@
#include <net/udp.h> #include <net/udp.h>
#include "en.h" #include "en.h"
#include "en/port.h" #include "en/port.h"
#include "eswitch.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);
}
static int mlx5e_test_health_info(struct mlx5e_priv *priv) static int mlx5e_test_health_info(struct mlx5e_priv *priv)
{ {
...@@ -265,6 +242,14 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv, ...@@ -265,6 +242,14 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
mlx5e_refresh_tirs(priv, false, false); 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)) #define MLX5E_LB_VERIFY_TIMEOUT (msecs_to_jiffies(200))
static int mlx5e_test_loopback(struct mlx5e_priv *priv) static int mlx5e_test_loopback(struct mlx5e_priv *priv)
{ {
...@@ -313,37 +298,47 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv) ...@@ -313,37 +298,47 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv)
} }
#endif #endif
static int (*mlx5e_st_func[MLX5E_ST_NUM])(struct mlx5e_priv *) = { typedef int (*mlx5e_st_func)(struct mlx5e_priv *);
mlx5e_test_link_state,
mlx5e_test_link_speed, struct mlx5e_st {
mlx5e_test_health_info, 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 #ifdef CONFIG_INET
mlx5e_test_loopback, { "Loopback Test", mlx5e_test_loopback, mlx5e_cond_loopback },
#endif #endif
}; };
#define MLX5E_ST_NUM ARRAY_SIZE(mlx5e_sts)
void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest, void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
u64 *buf) u64 *buf)
{ {
struct mlx5e_priv *priv = netdev_priv(ndev); struct mlx5e_priv *priv = netdev_priv(ndev);
int i; int i, count = 0;
memset(buf, 0, sizeof(u64) * MLX5E_ST_NUM);
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
netdev_info(ndev, "Self test begin..\n"); netdev_info(ndev, "Self test begin..\n");
for (i = 0; i < MLX5E_ST_NUM; i++) { for (i = 0; i < MLX5E_ST_NUM; i++) {
netdev_info(ndev, "\t[%d] %s start..\n", struct mlx5e_st st = mlx5e_sts[i];
i, mlx5e_self_tests[i]);
buf[i] = mlx5e_st_func[i](priv); if (st.cond_func && st.cond_func(priv))
netdev_info(ndev, "\t[%d] %s end: result(%lld)\n", continue;
i, mlx5e_self_tests[i], buf[i]); 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); mutex_unlock(&priv->state_lock);
for (i = 0; i < MLX5E_ST_NUM; i++) { for (i = 0; i < count; i++) {
if (buf[i]) { if (buf[i]) {
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
break; break;
...@@ -352,3 +347,24 @@ void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest, ...@@ -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", netdev_info(ndev, "Self test out: status flags(0x%x)\n",
etest->flags); 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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment