Commit 3c19208e authored by Aya Levin's avatar Aya Levin Committed by Saeed Mahameed

net/mlxe5: Separate between FEC and current speed

FEC mode is per link type, not necessary per speed. This patch access
FEC register by link modes instead of speeds. This patch will allow
further enhacment of link modes supporting FEC with the same speed
(different lane type).
Signed-off-by: default avatarAya Levin <ayal@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 2132b71f
...@@ -343,64 +343,45 @@ int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer) ...@@ -343,64 +343,45 @@ int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
return err; return err;
} }
static u32 fec_supported_speeds[] = { enum mlx5e_fec_supported_link_mode {
10000, MLX5E_FEC_SUPPORTED_LINK_MODES_10G_40G,
40000, MLX5E_FEC_SUPPORTED_LINK_MODES_25G,
25000, MLX5E_FEC_SUPPORTED_LINK_MODES_50G,
50000, MLX5E_FEC_SUPPORTED_LINK_MODES_56G,
56000, MLX5E_FEC_SUPPORTED_LINK_MODES_100G,
100000 MLX5E_MAX_FEC_SUPPORTED_LINK_MODE,
}; };
#define MLX5E_FEC_SUPPORTED_SPEEDS ARRAY_SIZE(fec_supported_speeds) #define MLX5E_FEC_OVERRIDE_ADMIN_POLICY(buf, policy, write, link) \
do { \
u8 *_policy = &(policy); \
u32 *_buf = buf; \
\
if (write) \
MLX5_SET(pplm_reg, _buf, fec_override_admin_##link, *_policy); \
else \
*_policy = MLX5_GET(pplm_reg, _buf, fec_override_admin_##link); \
} while (0)
/* get/set FEC admin field for a given speed */ /* get/set FEC admin field for a given speed */
static int mlx5e_fec_admin_field(u32 *pplm, static int mlx5e_fec_admin_field(u32 *pplm, u8 *fec_policy, bool write,
u8 *fec_policy, enum mlx5e_fec_supported_link_mode link_mode)
bool write,
u32 speed)
{ {
switch (speed) { switch (link_mode) {
case 10000: case MLX5E_FEC_SUPPORTED_LINK_MODES_10G_40G:
case 40000: MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 10g_40g);
if (!write)
*fec_policy = MLX5_GET(pplm_reg, pplm,
fec_override_admin_10g_40g);
else
MLX5_SET(pplm_reg, pplm,
fec_override_admin_10g_40g, *fec_policy);
break; break;
case 25000: case MLX5E_FEC_SUPPORTED_LINK_MODES_25G:
if (!write) MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 25g);
*fec_policy = MLX5_GET(pplm_reg, pplm,
fec_override_admin_25g);
else
MLX5_SET(pplm_reg, pplm,
fec_override_admin_25g, *fec_policy);
break; break;
case 50000: case MLX5E_FEC_SUPPORTED_LINK_MODES_50G:
if (!write) MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 50g);
*fec_policy = MLX5_GET(pplm_reg, pplm,
fec_override_admin_50g);
else
MLX5_SET(pplm_reg, pplm,
fec_override_admin_50g, *fec_policy);
break; break;
case 56000: case MLX5E_FEC_SUPPORTED_LINK_MODES_56G:
if (!write) MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 56g);
*fec_policy = MLX5_GET(pplm_reg, pplm,
fec_override_admin_56g);
else
MLX5_SET(pplm_reg, pplm,
fec_override_admin_56g, *fec_policy);
break; break;
case 100000: case MLX5E_FEC_SUPPORTED_LINK_MODES_100G:
if (!write) MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 100g);
*fec_policy = MLX5_GET(pplm_reg, pplm,
fec_override_admin_100g);
else
MLX5_SET(pplm_reg, pplm,
fec_override_admin_100g, *fec_policy);
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -408,32 +389,28 @@ static int mlx5e_fec_admin_field(u32 *pplm, ...@@ -408,32 +389,28 @@ static int mlx5e_fec_admin_field(u32 *pplm,
return 0; return 0;
} }
#define MLX5E_GET_FEC_OVERRIDE_CAP(buf, link) \
MLX5_GET(pplm_reg, buf, fec_override_cap_##link)
/* returns FEC capabilities for a given speed */ /* returns FEC capabilities for a given speed */
static int mlx5e_get_fec_cap_field(u32 *pplm, static int mlx5e_get_fec_cap_field(u32 *pplm, u8 *fec_cap,
u8 *fec_cap, enum mlx5e_fec_supported_link_mode link_mode)
u32 speed)
{ {
switch (speed) { switch (link_mode) {
case 10000: case MLX5E_FEC_SUPPORTED_LINK_MODES_10G_40G:
case 40000: *fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 10g_40g);
*fec_cap = MLX5_GET(pplm_reg, pplm,
fec_override_cap_10g_40g);
break; break;
case 25000: case MLX5E_FEC_SUPPORTED_LINK_MODES_25G:
*fec_cap = MLX5_GET(pplm_reg, pplm, *fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 25g);
fec_override_cap_25g);
break; break;
case 50000: case MLX5E_FEC_SUPPORTED_LINK_MODES_50G:
*fec_cap = MLX5_GET(pplm_reg, pplm, *fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 50g);
fec_override_cap_50g);
break; break;
case 56000: case MLX5E_FEC_SUPPORTED_LINK_MODES_56G:
*fec_cap = MLX5_GET(pplm_reg, pplm, *fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 56g);
fec_override_cap_56g);
break; break;
case 100000: case MLX5E_FEC_SUPPORTED_LINK_MODES_100G:
*fec_cap = MLX5_GET(pplm_reg, pplm, *fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 100g);
fec_override_cap_100g);
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -460,10 +437,10 @@ bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy) ...@@ -460,10 +437,10 @@ bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
if (err) if (err)
return false; return false;
for (i = 0; i < MLX5E_FEC_SUPPORTED_SPEEDS; i++) { for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
u8 fec_caps; u8 fec_caps;
mlx5e_get_fec_cap_field(out, &fec_caps, fec_supported_speeds[i]); mlx5e_get_fec_cap_field(out, &fec_caps, i);
if (fec_caps & fec_policy) if (fec_caps & fec_policy)
return true; return true;
} }
...@@ -476,8 +453,8 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active, ...@@ -476,8 +453,8 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
int sz = MLX5_ST_SZ_BYTES(pplm_reg); int sz = MLX5_ST_SZ_BYTES(pplm_reg);
u32 link_speed;
int err; int err;
int i;
if (!MLX5_CAP_GEN(dev, pcam_reg)) if (!MLX5_CAP_GEN(dev, pcam_reg))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -493,13 +470,16 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active, ...@@ -493,13 +470,16 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
*fec_mode_active = MLX5_GET(pplm_reg, out, fec_mode_active); *fec_mode_active = MLX5_GET(pplm_reg, out, fec_mode_active);
if (!fec_configured_mode) if (!fec_configured_mode)
return 0; goto out;
err = mlx5e_port_linkspeed(dev, &link_speed);
if (err)
return err;
return mlx5e_fec_admin_field(out, fec_configured_mode, 0, link_speed); *fec_configured_mode = 0;
for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
mlx5e_fec_admin_field(out, fec_configured_mode, 0, i);
if (*fec_configured_mode != 0)
goto out;
}
out:
return 0;
} }
int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy)
...@@ -525,16 +505,14 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) ...@@ -525,16 +505,14 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy)
MLX5_SET(pplm_reg, out, local_port, 1); MLX5_SET(pplm_reg, out, local_port, 1);
for (i = 0; i < MLX5E_FEC_SUPPORTED_SPEEDS; i++) { for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
mlx5e_get_fec_cap_field(out, &fec_caps, fec_supported_speeds[i]); mlx5e_get_fec_cap_field(out, &fec_caps, i);
/* policy supported for link speed */ /* policy supported for link speed */
if (fec_caps & fec_policy) if (fec_caps & fec_policy)
mlx5e_fec_admin_field(out, &fec_policy, 1, mlx5e_fec_admin_field(out, &fec_policy, 1, i);
fec_supported_speeds[i]);
else else
/* set FEC to auto*/ /* set FEC to auto*/
mlx5e_fec_admin_field(out, &fec_policy_auto, 1, mlx5e_fec_admin_field(out, &fec_policy_auto, 1, i);
fec_supported_speeds[i]);
} }
return mlx5_core_access_reg(dev, out, sz, out, sz, MLX5_REG_PPLM, 0, 1); return mlx5_core_access_reg(dev, out, sz, out, sz, MLX5_REG_PPLM, 0, 1);
......
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