@@ -2263,7 +2263,8 @@ void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv)
22632263 ETH_MAX_MTU );
22642264}
22652265
2266- static int mlx5e_netdev_set_tcs (struct net_device * netdev , u16 nch , u8 ntc )
2266+ static int mlx5e_netdev_set_tcs (struct net_device * netdev , u16 nch , u8 ntc ,
2267+ struct tc_mqprio_qopt_offload * mqprio )
22672268{
22682269 int tc , err ;
22692270
@@ -2278,11 +2279,16 @@ static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc)
22782279 return err ;
22792280 }
22802281
2281- /* Map netdev TCs to offset 0
2282- * We have our own UP to TXQ mapping for QoS
2283- */
2284- for (tc = 0 ; tc < ntc ; tc ++ )
2285- netdev_set_tc_queue (netdev , tc , nch , 0 );
2282+ for (tc = 0 ; tc < ntc ; tc ++ ) {
2283+ u16 count , offset ;
2284+
2285+ /* For DCB mode, map netdev TCs to offset 0
2286+ * We have our own UP to TXQ mapping for QoS
2287+ */
2288+ count = mqprio ? mqprio -> qopt .count [tc ] : nch ;
2289+ offset = mqprio ? mqprio -> qopt .offset [tc ] : 0 ;
2290+ netdev_set_tc_queue (netdev , tc , count , offset );
2291+ }
22862292
22872293 return 0 ;
22882294}
@@ -2321,7 +2327,7 @@ static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
23212327 ntc = mlx5e_get_dcb_num_tc (& priv -> channels .params );
23222328 num_rxqs = nch * priv -> profile -> rq_groups ;
23232329
2324- err = mlx5e_netdev_set_tcs (netdev , nch , ntc );
2330+ err = mlx5e_netdev_set_tcs (netdev , nch , ntc , NULL );
23252331 if (err )
23262332 goto err_out ;
23272333 err = mlx5e_update_tx_netdev_queues (priv );
@@ -2344,7 +2350,7 @@ static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
23442350 WARN_ON_ONCE (netif_set_real_num_tx_queues (netdev , old_num_txqs ));
23452351
23462352err_tcs :
2347- mlx5e_netdev_set_tcs (netdev , old_num_txqs / old_ntc , old_ntc );
2353+ mlx5e_netdev_set_tcs (netdev , old_num_txqs / old_ntc , old_ntc , NULL );
23482354err_out :
23492355 return err ;
23502356}
@@ -2879,6 +2885,81 @@ static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv,
28792885 return err ;
28802886}
28812887
2888+ static int mlx5e_mqprio_channel_validate (struct mlx5e_priv * priv ,
2889+ struct tc_mqprio_qopt_offload * mqprio )
2890+ {
2891+ struct net_device * netdev = priv -> netdev ;
2892+ int agg_count = 0 ;
2893+ int i ;
2894+
2895+ if (mqprio -> qopt .offset [0 ] != 0 || mqprio -> qopt .num_tc < 1 ||
2896+ mqprio -> qopt .num_tc > MLX5E_MAX_NUM_MQPRIO_CH_TC )
2897+ return - EINVAL ;
2898+
2899+ for (i = 0 ; i < mqprio -> qopt .num_tc ; i ++ ) {
2900+ if (!mqprio -> qopt .count [i ]) {
2901+ netdev_err (netdev , "Zero size for queue-group (%d) is not supported\n" , i );
2902+ return - EINVAL ;
2903+ }
2904+ if (mqprio -> min_rate [i ]) {
2905+ netdev_err (netdev , "Min tx rate is not supported\n" );
2906+ return - EINVAL ;
2907+ }
2908+ if (mqprio -> max_rate [i ]) {
2909+ netdev_err (netdev , "Max tx rate is not supported\n" );
2910+ return - EINVAL ;
2911+ }
2912+
2913+ if (mqprio -> qopt .offset [i ] != agg_count ) {
2914+ netdev_err (netdev , "Discontinuous queues config is not supported\n" );
2915+ return - EINVAL ;
2916+ }
2917+ agg_count += mqprio -> qopt .count [i ];
2918+ }
2919+
2920+ if (priv -> channels .params .num_channels < agg_count ) {
2921+ netdev_err (netdev , "Num of queues (%d) exceeds available (%d)\n" ,
2922+ agg_count , priv -> channels .params .num_channels );
2923+ return - EINVAL ;
2924+ }
2925+
2926+ return 0 ;
2927+ }
2928+
2929+ static int mlx5e_mqprio_channel_set_tcs_ctx (struct mlx5e_priv * priv , void * ctx )
2930+ {
2931+ struct tc_mqprio_qopt_offload * mqprio = (struct tc_mqprio_qopt_offload * )ctx ;
2932+ struct net_device * netdev = priv -> netdev ;
2933+ u8 num_tc ;
2934+
2935+ if (priv -> channels .params .mqprio .mode != TC_MQPRIO_MODE_CHANNEL )
2936+ return - EINVAL ;
2937+
2938+ num_tc = priv -> channels .params .mqprio .num_tc ;
2939+ mlx5e_netdev_set_tcs (netdev , 0 , num_tc , mqprio );
2940+
2941+ return 0 ;
2942+ }
2943+
2944+ static int mlx5e_setup_tc_mqprio_channel (struct mlx5e_priv * priv ,
2945+ struct tc_mqprio_qopt_offload * mqprio )
2946+ {
2947+ struct mlx5e_params new_params ;
2948+ int err ;
2949+
2950+ err = mlx5e_mqprio_channel_validate (priv , mqprio );
2951+ if (err )
2952+ return err ;
2953+
2954+ new_params = priv -> channels .params ;
2955+ new_params .mqprio .mode = TC_MQPRIO_MODE_CHANNEL ;
2956+ new_params .mqprio .num_tc = mqprio -> qopt .num_tc ;
2957+ err = mlx5e_safe_switch_params (priv , & new_params ,
2958+ mlx5e_mqprio_channel_set_tcs_ctx , mqprio , true);
2959+
2960+ return err ;
2961+ }
2962+
28822963static int mlx5e_setup_tc_mqprio (struct mlx5e_priv * priv ,
28832964 struct tc_mqprio_qopt_offload * mqprio )
28842965{
@@ -2891,6 +2972,8 @@ static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
28912972 switch (mqprio -> mode ) {
28922973 case TC_MQPRIO_MODE_DCB :
28932974 return mlx5e_setup_tc_mqprio_dcb (priv , & mqprio -> qopt );
2975+ case TC_MQPRIO_MODE_CHANNEL :
2976+ return mlx5e_setup_tc_mqprio_channel (priv , mqprio );
28942977 default :
28952978 return - EOPNOTSUPP ;
28962979 }
0 commit comments