Skip to content

Commit b5ede32

Browse files
ayalevin123Saeed Mahameed
authored andcommitted
net/mlx5e: Add support for FEC modes based on 50G per lane links
Introduce new FEC modes: - RS-FEC-(544,514) - LL_RS-FEC-(272,257+1) Add support in ethtool for set and get callbacks for the new modes above. While RS-FEC-(544,514) is mapped to exsiting RS FEC mode, LL_RS-FEC-(272,257+1) is mapped to a new ethtool link mode: LL-RS. Add support for FEC on 50G per lane link modes up to 400G. The new link modes uses a u16 fields instead of u8 fields for the legacy link modes. Signed-off-by: Aya Levin <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent f623e59 commit b5ede32

File tree

3 files changed

+94
-16
lines changed

3 files changed

+94
-16
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/port.c

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,18 @@ enum mlx5e_fec_supported_link_mode {
349349
MLX5E_FEC_SUPPORTED_LINK_MODES_50G,
350350
MLX5E_FEC_SUPPORTED_LINK_MODES_56G,
351351
MLX5E_FEC_SUPPORTED_LINK_MODES_100G,
352+
MLX5E_FEC_SUPPORTED_LINK_MODE_50G_1X,
353+
MLX5E_FEC_SUPPORTED_LINK_MODE_100G_2X,
354+
MLX5E_FEC_SUPPORTED_LINK_MODE_200G_4X,
355+
MLX5E_FEC_SUPPORTED_LINK_MODE_400G_8X,
352356
MLX5E_MAX_FEC_SUPPORTED_LINK_MODE,
353357
};
354358

359+
#define MLX5E_FEC_FIRST_50G_PER_LANE_MODE MLX5E_FEC_SUPPORTED_LINK_MODE_50G_1X
360+
355361
#define MLX5E_FEC_OVERRIDE_ADMIN_POLICY(buf, policy, write, link) \
356362
do { \
357-
u8 *_policy = &(policy); \
363+
u16 *_policy = &(policy); \
358364
u32 *_buf = buf; \
359365
\
360366
if (write) \
@@ -363,8 +369,21 @@ enum mlx5e_fec_supported_link_mode {
363369
*_policy = MLX5_GET(pplm_reg, _buf, fec_override_admin_##link); \
364370
} while (0)
365371

372+
#define MLX5E_FEC_OVERRIDE_ADMIN_50G_POLICY(buf, policy, write, link) \
373+
do { \
374+
u16 *__policy = &(policy); \
375+
bool _write = (write); \
376+
\
377+
if (_write && *__policy) \
378+
*__policy = find_first_bit((u_long *)__policy, \
379+
sizeof(u16) * BITS_PER_BYTE);\
380+
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(buf, *__policy, _write, link); \
381+
if (!_write && *__policy) \
382+
*__policy = 1 << *__policy; \
383+
} while (0)
384+
366385
/* get/set FEC admin field for a given speed */
367-
static int mlx5e_fec_admin_field(u32 *pplm, u8 *fec_policy, bool write,
386+
static int mlx5e_fec_admin_field(u32 *pplm, u16 *fec_policy, bool write,
368387
enum mlx5e_fec_supported_link_mode link_mode)
369388
{
370389
switch (link_mode) {
@@ -383,6 +402,18 @@ static int mlx5e_fec_admin_field(u32 *pplm, u8 *fec_policy, bool write,
383402
case MLX5E_FEC_SUPPORTED_LINK_MODES_100G:
384403
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 100g);
385404
break;
405+
case MLX5E_FEC_SUPPORTED_LINK_MODE_50G_1X:
406+
MLX5E_FEC_OVERRIDE_ADMIN_50G_POLICY(pplm, *fec_policy, write, 50g_1x);
407+
break;
408+
case MLX5E_FEC_SUPPORTED_LINK_MODE_100G_2X:
409+
MLX5E_FEC_OVERRIDE_ADMIN_50G_POLICY(pplm, *fec_policy, write, 100g_2x);
410+
break;
411+
case MLX5E_FEC_SUPPORTED_LINK_MODE_200G_4X:
412+
MLX5E_FEC_OVERRIDE_ADMIN_50G_POLICY(pplm, *fec_policy, write, 200g_4x);
413+
break;
414+
case MLX5E_FEC_SUPPORTED_LINK_MODE_400G_8X:
415+
MLX5E_FEC_OVERRIDE_ADMIN_50G_POLICY(pplm, *fec_policy, write, 400g_8x);
416+
break;
386417
default:
387418
return -EINVAL;
388419
}
@@ -393,7 +424,7 @@ static int mlx5e_fec_admin_field(u32 *pplm, u8 *fec_policy, bool write,
393424
MLX5_GET(pplm_reg, buf, fec_override_cap_##link)
394425

395426
/* returns FEC capabilities for a given speed */
396-
static int mlx5e_get_fec_cap_field(u32 *pplm, u8 *fec_cap,
427+
static int mlx5e_get_fec_cap_field(u32 *pplm, u16 *fec_cap,
397428
enum mlx5e_fec_supported_link_mode link_mode)
398429
{
399430
switch (link_mode) {
@@ -412,6 +443,18 @@ static int mlx5e_get_fec_cap_field(u32 *pplm, u8 *fec_cap,
412443
case MLX5E_FEC_SUPPORTED_LINK_MODES_100G:
413444
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 100g);
414445
break;
446+
case MLX5E_FEC_SUPPORTED_LINK_MODE_50G_1X:
447+
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 50g_1x);
448+
break;
449+
case MLX5E_FEC_SUPPORTED_LINK_MODE_100G_2X:
450+
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 100g_2x);
451+
break;
452+
case MLX5E_FEC_SUPPORTED_LINK_MODE_200G_4X:
453+
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 200g_4x);
454+
break;
455+
case MLX5E_FEC_SUPPORTED_LINK_MODE_400G_8X:
456+
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 400g_8x);
457+
break;
415458
default:
416459
return -EINVAL;
417460
}
@@ -420,6 +463,7 @@ static int mlx5e_get_fec_cap_field(u32 *pplm, u8 *fec_cap,
420463

421464
bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
422465
{
466+
bool fec_50g_per_lane = MLX5_CAP_PCAM_FEATURE(dev, fec_50G_per_lane_in_pplm);
423467
u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
424468
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
425469
int sz = MLX5_ST_SZ_BYTES(pplm_reg);
@@ -438,7 +482,10 @@ bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
438482
return false;
439483

440484
for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
441-
u8 fec_caps;
485+
u16 fec_caps;
486+
487+
if (i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE && !fec_50g_per_lane)
488+
break;
442489

443490
mlx5e_get_fec_cap_field(out, &fec_caps, i);
444491
if (fec_caps & fec_policy)
@@ -448,8 +495,9 @@ bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
448495
}
449496

450497
int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
451-
u8 *fec_configured_mode)
498+
u16 *fec_configured_mode)
452499
{
500+
bool fec_50g_per_lane = MLX5_CAP_PCAM_FEATURE(dev, fec_50G_per_lane_in_pplm);
453501
u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
454502
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
455503
int sz = MLX5_ST_SZ_BYTES(pplm_reg);
@@ -474,6 +522,9 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
474522

475523
*fec_configured_mode = 0;
476524
for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
525+
if (i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE && !fec_50g_per_lane)
526+
break;
527+
477528
mlx5e_fec_admin_field(out, fec_configured_mode, 0, i);
478529
if (*fec_configured_mode != 0)
479530
goto out;
@@ -482,13 +533,13 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
482533
return 0;
483534
}
484535

485-
int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy)
536+
int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
486537
{
538+
bool fec_50g_per_lane = MLX5_CAP_PCAM_FEATURE(dev, fec_50G_per_lane_in_pplm);
487539
u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
488540
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
489541
int sz = MLX5_ST_SZ_BYTES(pplm_reg);
490-
u8 fec_policy_auto = 0;
491-
u8 fec_caps = 0;
542+
u16 fec_policy_auto = 0;
492543
int err;
493544
int i;
494545

@@ -498,6 +549,9 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy)
498549
if (!MLX5_CAP_PCAM_REG(dev, pplm))
499550
return -EOPNOTSUPP;
500551

552+
if (fec_policy >= (1 << MLX5E_FEC_LLRS_272_257_1) && !fec_50g_per_lane)
553+
return -EOPNOTSUPP;
554+
501555
MLX5_SET(pplm_reg, in, local_port, 1);
502556
err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPLM, 0, 0);
503557
if (err)
@@ -506,10 +560,26 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy)
506560
MLX5_SET(pplm_reg, out, local_port, 1);
507561

508562
for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
563+
u16 conf_fec = fec_policy;
564+
u16 fec_caps = 0;
565+
566+
if (i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE && !fec_50g_per_lane)
567+
break;
568+
569+
/* RS fec in ethtool is mapped to MLX5E_FEC_RS_528_514
570+
* to link modes up to 25G per lane and to
571+
* MLX5E_FEC_RS_544_514 in the new link modes based on
572+
* 50 G per lane
573+
*/
574+
if (conf_fec == (1 << MLX5E_FEC_RS_528_514) &&
575+
i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE)
576+
conf_fec = (1 << MLX5E_FEC_RS_544_514);
577+
509578
mlx5e_get_fec_cap_field(out, &fec_caps, i);
579+
510580
/* policy supported for link speed */
511-
if (fec_caps & fec_policy)
512-
mlx5e_fec_admin_field(out, &fec_policy, 1, i);
581+
if (fec_caps & conf_fec)
582+
mlx5e_fec_admin_field(out, &conf_fec, 1, i);
513583
else
514584
/* set FEC to auto*/
515585
mlx5e_fec_admin_field(out, &fec_policy_auto, 1, i);

drivers/net/ethernet/mellanox/mlx5/core/en/port.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
6262

6363
bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy);
6464
int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
65-
u8 *fec_configured_mode);
66-
int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy);
65+
u16 *fec_configured_mode);
66+
int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy);
6767

6868
enum {
6969
MLX5E_FEC_NOFEC,
7070
MLX5E_FEC_FIRECODE,
7171
MLX5E_FEC_RS_528_514,
72+
MLX5E_FEC_RS_544_514 = 7,
73+
MLX5E_FEC_LLRS_272_257_1 = 9,
7274
};
7375

7476
#endif

drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,8 @@ static const u32 pplm_fec_2_ethtool[] = {
633633
[MLX5E_FEC_NOFEC] = ETHTOOL_FEC_OFF,
634634
[MLX5E_FEC_FIRECODE] = ETHTOOL_FEC_BASER,
635635
[MLX5E_FEC_RS_528_514] = ETHTOOL_FEC_RS,
636+
[MLX5E_FEC_RS_544_514] = ETHTOOL_FEC_RS,
637+
[MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_FEC_LLRS,
636638
};
637639

638640
static u32 pplm2ethtool_fec(u_long fec_mode, unsigned long size)
@@ -661,6 +663,8 @@ static const u32 pplm_fec_2_ethtool_linkmodes[] = {
661663
[MLX5E_FEC_NOFEC] = ETHTOOL_LINK_MODE_FEC_NONE_BIT,
662664
[MLX5E_FEC_FIRECODE] = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
663665
[MLX5E_FEC_RS_528_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
666+
[MLX5E_FEC_RS_544_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
667+
[MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
664668
};
665669

666670
static int get_fec_supported_advertised(struct mlx5_core_dev *dev,
@@ -680,6 +684,8 @@ static int get_fec_supported_advertised(struct mlx5_core_dev *dev,
680684
ETHTOOL_LINK_MODE_FEC_BASER_BIT);
681685
MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_RS_528_514,
682686
ETHTOOL_LINK_MODE_FEC_RS_BIT);
687+
MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_LLRS_272_257_1,
688+
ETHTOOL_LINK_MODE_FEC_LLRS_BIT);
683689

684690
/* active fec is a bit set, find out which bit is set and
685691
* advertise the corresponding ethtool bit
@@ -1510,7 +1516,7 @@ static int mlx5e_get_fecparam(struct net_device *netdev,
15101516
{
15111517
struct mlx5e_priv *priv = netdev_priv(netdev);
15121518
struct mlx5_core_dev *mdev = priv->mdev;
1513-
u8 fec_configured = 0;
1519+
u16 fec_configured = 0;
15141520
u32 fec_active = 0;
15151521
int err;
15161522

@@ -1526,7 +1532,7 @@ static int mlx5e_get_fecparam(struct net_device *netdev,
15261532
return -EOPNOTSUPP;
15271533

15281534
fecparam->fec = pplm2ethtool_fec((u_long)fec_configured,
1529-
sizeof(u8) * BITS_PER_BYTE);
1535+
sizeof(u16) * BITS_PER_BYTE);
15301536

15311537
return 0;
15321538
}
@@ -1536,12 +1542,12 @@ static int mlx5e_set_fecparam(struct net_device *netdev,
15361542
{
15371543
struct mlx5e_priv *priv = netdev_priv(netdev);
15381544
struct mlx5_core_dev *mdev = priv->mdev;
1539-
u8 fec_policy = 0;
1545+
u16 fec_policy = 0;
15401546
int mode;
15411547
int err;
15421548

15431549
if (bitmap_weight((unsigned long *)&fecparam->fec,
1544-
ETHTOOL_FEC_BASER_BIT + 1) > 1)
1550+
ETHTOOL_FEC_LLRS_BIT + 1) > 1)
15451551
return -EOPNOTSUPP;
15461552

15471553
for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) {

0 commit comments

Comments
 (0)