@@ -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+
26102938static void
26112939mlxsw_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}
0 commit comments