Skip to content

Commit d3eaf10

Browse files
Shalom Toledodavem330
authored andcommitted
mlxsw: spectrum: Add Spectrum-2 ASIC port type-speed operations
Add Spectrum-2 ASIC port type-speed operations. Since multiple ethtool link modes are represented using a single bit in the ASIC, the driver forces the user to configure all types per a specific speed. For example, if the user wants to advertise 100Gbps 4-lanes speed, he should advertise all the types of 100Gbps 4-lanes speed that are supported by the ASIC as shown below: Supported ethtool bits for 100Gbps 4-lanes: 0x1000000000 100000baseKR4 Full 0x2000000000 100000baseSR4 Full 0x4000000000 100000baseCR4 Full 0x8000000000 100000baseLR4_ER4 Full Command for advertising 100Gbps 4-lanes: ethtool -s enp3s0np1 advertise 0xF000000000 Signed-off-by: Shalom Toledo <shalomt@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 9ce8439 commit d3eaf10

File tree

2 files changed

+330
-1
lines changed

2 files changed

+330
-1
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 329 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,334 @@ mlxsw_sp1_port_type_speed_ops = {
26072607
.reg_ptys_eth_unpack = mlxsw_sp1_reg_ptys_eth_unpack,
26082608
};
26092609

2610+
static const enum ethtool_link_mode_bit_indices
2611+
mlxsw_sp2_mask_ethtool_sgmii_100m[] = {
2612+
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
2613+
};
2614+
2615+
#define MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN \
2616+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_sgmii_100m)
2617+
2618+
static const enum ethtool_link_mode_bit_indices
2619+
mlxsw_sp2_mask_ethtool_1000base_x_sgmii[] = {
2620+
ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
2621+
ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2622+
};
2623+
2624+
#define MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN \
2625+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_1000base_x_sgmii)
2626+
2627+
static const enum ethtool_link_mode_bit_indices
2628+
mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii[] = {
2629+
ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
2630+
};
2631+
2632+
#define MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN \
2633+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii)
2634+
2635+
static const enum ethtool_link_mode_bit_indices
2636+
mlxsw_sp2_mask_ethtool_5gbase_r[] = {
2637+
ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
2638+
};
2639+
2640+
#define MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN \
2641+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_5gbase_r)
2642+
2643+
static const enum ethtool_link_mode_bit_indices
2644+
mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g[] = {
2645+
ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
2646+
ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
2647+
ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
2648+
ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
2649+
ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
2650+
ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
2651+
ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
2652+
};
2653+
2654+
#define MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN \
2655+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g)
2656+
2657+
static const enum ethtool_link_mode_bit_indices
2658+
mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g[] = {
2659+
ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
2660+
ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
2661+
ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
2662+
ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
2663+
};
2664+
2665+
#define MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN \
2666+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g)
2667+
2668+
static const enum ethtool_link_mode_bit_indices
2669+
mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr[] = {
2670+
ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
2671+
ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
2672+
ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
2673+
};
2674+
2675+
#define MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN \
2676+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr)
2677+
2678+
static const enum ethtool_link_mode_bit_indices
2679+
mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2[] = {
2680+
ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
2681+
ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
2682+
ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
2683+
};
2684+
2685+
#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN \
2686+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2)
2687+
2688+
static const enum ethtool_link_mode_bit_indices
2689+
mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4[] = {
2690+
ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
2691+
ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
2692+
ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
2693+
ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
2694+
};
2695+
2696+
#define MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN \
2697+
ARRAY_SIZE(mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4)
2698+
2699+
struct mlxsw_sp2_port_link_mode {
2700+
const enum ethtool_link_mode_bit_indices *mask_ethtool;
2701+
int m_ethtool_len;
2702+
u32 mask;
2703+
u32 speed;
2704+
};
2705+
2706+
static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = {
2707+
{
2708+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M,
2709+
.mask_ethtool = mlxsw_sp2_mask_ethtool_sgmii_100m,
2710+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN,
2711+
.speed = SPEED_100,
2712+
},
2713+
{
2714+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII,
2715+
.mask_ethtool = mlxsw_sp2_mask_ethtool_1000base_x_sgmii,
2716+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN,
2717+
.speed = SPEED_1000,
2718+
},
2719+
{
2720+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_2_5GBASE_X_2_5GMII,
2721+
.mask_ethtool = mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii,
2722+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN,
2723+
.speed = SPEED_2500,
2724+
},
2725+
{
2726+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R,
2727+
.mask_ethtool = mlxsw_sp2_mask_ethtool_5gbase_r,
2728+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN,
2729+
.speed = SPEED_5000,
2730+
},
2731+
{
2732+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G,
2733+
.mask_ethtool = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g,
2734+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN,
2735+
.speed = SPEED_10000,
2736+
},
2737+
{
2738+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G,
2739+
.mask_ethtool = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g,
2740+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN,
2741+
.speed = SPEED_40000,
2742+
},
2743+
{
2744+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR,
2745+
.mask_ethtool = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr,
2746+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN,
2747+
.speed = SPEED_25000,
2748+
},
2749+
{
2750+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
2751+
.mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2,
2752+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN,
2753+
.speed = SPEED_50000,
2754+
},
2755+
{
2756+
.mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4,
2757+
.mask_ethtool = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4,
2758+
.m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN,
2759+
.speed = SPEED_100000,
2760+
},
2761+
};
2762+
2763+
#define MLXSW_SP2_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp2_port_link_mode)
2764+
2765+
static void
2766+
mlxsw_sp2_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
2767+
u32 ptys_eth_proto,
2768+
struct ethtool_link_ksettings *cmd)
2769+
{
2770+
ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
2771+
ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
2772+
}
2773+
2774+
static void
2775+
mlxsw_sp2_set_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
2776+
unsigned long *mode)
2777+
{
2778+
int i;
2779+
2780+
for (i = 0; i < link_mode->m_ethtool_len; i++)
2781+
__set_bit(link_mode->mask_ethtool[i], mode);
2782+
}
2783+
2784+
static void
2785+
mlxsw_sp2_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
2786+
unsigned long *mode)
2787+
{
2788+
int i;
2789+
2790+
for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
2791+
if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask)
2792+
mlxsw_sp2_set_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
2793+
mode);
2794+
}
2795+
}
2796+
2797+
static void
2798+
mlxsw_sp2_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
2799+
u32 ptys_eth_proto,
2800+
struct ethtool_link_ksettings *cmd)
2801+
{
2802+
u32 speed = SPEED_UNKNOWN;
2803+
u8 duplex = DUPLEX_UNKNOWN;
2804+
int i;
2805+
2806+
if (!carrier_ok)
2807+
goto out;
2808+
2809+
for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
2810+
if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask) {
2811+
speed = mlxsw_sp2_port_link_mode[i].speed;
2812+
duplex = DUPLEX_FULL;
2813+
break;
2814+
}
2815+
}
2816+
out:
2817+
cmd->base.speed = speed;
2818+
cmd->base.duplex = duplex;
2819+
}
2820+
2821+
static bool
2822+
mlxsw_sp2_test_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
2823+
const unsigned long *mode)
2824+
{
2825+
int cnt = 0;
2826+
int i;
2827+
2828+
for (i = 0; i < link_mode->m_ethtool_len; i++) {
2829+
if (test_bit(link_mode->mask_ethtool[i], mode))
2830+
cnt++;
2831+
}
2832+
2833+
return cnt == link_mode->m_ethtool_len;
2834+
}
2835+
2836+
static u32
2837+
mlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp,
2838+
const struct ethtool_link_ksettings *cmd)
2839+
{
2840+
u32 ptys_proto = 0;
2841+
int i;
2842+
2843+
for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
2844+
if (mlxsw_sp2_test_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
2845+
cmd->link_modes.advertising))
2846+
ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
2847+
}
2848+
return ptys_proto;
2849+
}
2850+
2851+
static u32 mlxsw_sp2_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 speed)
2852+
{
2853+
u32 ptys_proto = 0;
2854+
int i;
2855+
2856+
for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
2857+
if (speed == mlxsw_sp2_port_link_mode[i].speed)
2858+
ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
2859+
}
2860+
return ptys_proto;
2861+
}
2862+
2863+
static u32
2864+
mlxsw_sp2_to_ptys_upper_speed(struct mlxsw_sp *mlxsw_sp, u32 upper_speed)
2865+
{
2866+
u32 ptys_proto = 0;
2867+
int i;
2868+
2869+
for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
2870+
if (mlxsw_sp2_port_link_mode[i].speed <= upper_speed)
2871+
ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
2872+
}
2873+
return ptys_proto;
2874+
}
2875+
2876+
static int
2877+
mlxsw_sp2_port_speed_base(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2878+
u32 *base_speed)
2879+
{
2880+
char ptys_pl[MLXSW_REG_PTYS_LEN];
2881+
u32 eth_proto_cap;
2882+
int err;
2883+
2884+
/* In Spectrum-2, the speed of 1x can change from port to port, so query
2885+
* it from firmware.
2886+
*/
2887+
mlxsw_reg_ptys_ext_eth_pack(ptys_pl, local_port, 0, false);
2888+
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
2889+
if (err)
2890+
return err;
2891+
mlxsw_reg_ptys_ext_eth_unpack(ptys_pl, &eth_proto_cap, NULL, NULL);
2892+
2893+
if (eth_proto_cap &
2894+
MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR) {
2895+
*base_speed = MLXSW_SP_PORT_BASE_SPEED_50G;
2896+
return 0;
2897+
}
2898+
2899+
if (eth_proto_cap &
2900+
MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR) {
2901+
*base_speed = MLXSW_SP_PORT_BASE_SPEED_25G;
2902+
return 0;
2903+
}
2904+
2905+
return -EIO;
2906+
}
2907+
2908+
static void
2909+
mlxsw_sp2_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
2910+
u8 local_port, u32 proto_admin,
2911+
bool autoneg)
2912+
{
2913+
mlxsw_reg_ptys_ext_eth_pack(payload, local_port, proto_admin, autoneg);
2914+
}
2915+
2916+
static void
2917+
mlxsw_sp2_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
2918+
u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
2919+
u32 *p_eth_proto_oper)
2920+
{
2921+
mlxsw_reg_ptys_ext_eth_unpack(payload, p_eth_proto_cap,
2922+
p_eth_proto_admin, p_eth_proto_oper);
2923+
}
2924+
2925+
static const struct mlxsw_sp_port_type_speed_ops
2926+
mlxsw_sp2_port_type_speed_ops = {
2927+
.from_ptys_supported_port = mlxsw_sp2_from_ptys_supported_port,
2928+
.from_ptys_link = mlxsw_sp2_from_ptys_link,
2929+
.from_ptys_speed_duplex = mlxsw_sp2_from_ptys_speed_duplex,
2930+
.to_ptys_advert_link = mlxsw_sp2_to_ptys_advert_link,
2931+
.to_ptys_speed = mlxsw_sp2_to_ptys_speed,
2932+
.to_ptys_upper_speed = mlxsw_sp2_to_ptys_upper_speed,
2933+
.port_speed_base = mlxsw_sp2_port_speed_base,
2934+
.reg_ptys_eth_pack = mlxsw_sp2_reg_ptys_eth_pack,
2935+
.reg_ptys_eth_unpack = mlxsw_sp2_reg_ptys_eth_unpack,
2936+
};
2937+
26102938
static void
26112939
mlxsw_sp_port_get_link_supported(struct mlxsw_sp *mlxsw_sp, u32 eth_proto_cap,
26122940
struct ethtool_link_ksettings *cmd)
@@ -4189,7 +4517,7 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
41894517
mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
41904518
mlxsw_sp->rif_ops_arr = mlxsw_sp2_rif_ops_arr;
41914519
mlxsw_sp->sb_vals = &mlxsw_sp2_sb_vals;
4192-
mlxsw_sp->port_type_speed_ops = &mlxsw_sp1_port_type_speed_ops;
4520+
mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
41934521

41944522
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
41954523
}

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#define MLXSW_SP_PORTS_PER_CLUSTER_MAX 4
3535

3636
#define MLXSW_SP_PORT_BASE_SPEED_25G 25000 /* Mb/s */
37+
#define MLXSW_SP_PORT_BASE_SPEED_50G 50000 /* Mb/s */
3738

3839
#define MLXSW_SP_KVD_LINEAR_SIZE 98304 /* entries */
3940
#define MLXSW_SP_KVD_GRANULARITY 128

0 commit comments

Comments
 (0)