@@ -2781,6 +2781,103 @@ static int mlx4_slaves_closest_port(struct mlx4_dev *dev, int slave, int port)
2781
2781
return port ;
2782
2782
}
2783
2783
2784
+ static int mlx4_set_vport_qos (struct mlx4_priv * priv , int slave , int port ,
2785
+ int max_tx_rate )
2786
+ {
2787
+ int i ;
2788
+ int err ;
2789
+ struct mlx4_qos_manager * port_qos ;
2790
+ struct mlx4_dev * dev = & priv -> dev ;
2791
+ struct mlx4_vport_qos_param vpp_qos [MLX4_NUM_UP ];
2792
+
2793
+ port_qos = & priv -> mfunc .master .qos_ctl [port ];
2794
+ memset (vpp_qos , 0 , sizeof (struct mlx4_vport_qos_param ) * MLX4_NUM_UP );
2795
+
2796
+ if (slave > port_qos -> num_of_qos_vfs ) {
2797
+ mlx4_info (dev , "No availible VPP resources for this VF\n" );
2798
+ return - EINVAL ;
2799
+ }
2800
+
2801
+ /* Query for default QoS values from Vport 0 is needed */
2802
+ err = mlx4_SET_VPORT_QOS_get (dev , port , 0 , vpp_qos );
2803
+ if (err ) {
2804
+ mlx4_info (dev , "Failed to query Vport 0 QoS values\n" );
2805
+ return err ;
2806
+ }
2807
+
2808
+ for (i = 0 ; i < MLX4_NUM_UP ; i ++ ) {
2809
+ if (test_bit (i , port_qos -> priority_bm ) && max_tx_rate ) {
2810
+ vpp_qos [i ].max_avg_bw = max_tx_rate ;
2811
+ vpp_qos [i ].enable = 1 ;
2812
+ } else {
2813
+ /* if user supplied tx_rate == 0, meaning no rate limit
2814
+ * configuration is required. so we are leaving the
2815
+ * value of max_avg_bw as queried from Vport 0.
2816
+ */
2817
+ vpp_qos [i ].enable = 0 ;
2818
+ }
2819
+ }
2820
+
2821
+ err = mlx4_SET_VPORT_QOS_set (dev , port , slave , vpp_qos );
2822
+ if (err ) {
2823
+ mlx4_info (dev , "Failed to set Vport %d QoS values\n" , slave );
2824
+ return err ;
2825
+ }
2826
+
2827
+ return 0 ;
2828
+ }
2829
+
2830
+ static bool mlx4_is_vf_vst_and_prio_qos (struct mlx4_dev * dev , int port ,
2831
+ struct mlx4_vport_state * vf_admin )
2832
+ {
2833
+ struct mlx4_qos_manager * info ;
2834
+ struct mlx4_priv * priv = mlx4_priv (dev );
2835
+
2836
+ if (!mlx4_is_master (dev ) ||
2837
+ !(dev -> caps .flags2 & MLX4_DEV_CAP_FLAG2_QOS_VPP ))
2838
+ return false;
2839
+
2840
+ info = & priv -> mfunc .master .qos_ctl [port ];
2841
+
2842
+ if (vf_admin -> default_vlan != MLX4_VGT &&
2843
+ test_bit (vf_admin -> default_qos , info -> priority_bm ))
2844
+ return true;
2845
+
2846
+ return false;
2847
+ }
2848
+
2849
+ static bool mlx4_valid_vf_state_change (struct mlx4_dev * dev , int port ,
2850
+ struct mlx4_vport_state * vf_admin ,
2851
+ int vlan , int qos )
2852
+ {
2853
+ struct mlx4_vport_state dummy_admin = {0 };
2854
+
2855
+ if (!mlx4_is_vf_vst_and_prio_qos (dev , port , vf_admin ) ||
2856
+ !vf_admin -> tx_rate )
2857
+ return true;
2858
+
2859
+ dummy_admin .default_qos = qos ;
2860
+ dummy_admin .default_vlan = vlan ;
2861
+
2862
+ /* VF wants to move to other VST state which is valid with current
2863
+ * rate limit. Either differnt default vlan in VST or other
2864
+ * supported QoS priority. Otherwise we don't allow this change when
2865
+ * the TX rate is still configured.
2866
+ */
2867
+ if (mlx4_is_vf_vst_and_prio_qos (dev , port , & dummy_admin ))
2868
+ return true;
2869
+
2870
+ mlx4_info (dev , "Cannot change VF state to %s while rate is set\n" ,
2871
+ (vlan == MLX4_VGT ) ? "VGT" : "VST" );
2872
+
2873
+ if (vlan != MLX4_VGT )
2874
+ mlx4_info (dev , "VST priority %d not supported for QoS\n" , qos );
2875
+
2876
+ mlx4_info (dev , "Please set rate to 0 prior to this VF state change\n" );
2877
+
2878
+ return false;
2879
+ }
2880
+
2784
2881
int mlx4_set_vf_mac (struct mlx4_dev * dev , int port , int vf , u64 mac )
2785
2882
{
2786
2883
struct mlx4_priv * priv = mlx4_priv (dev );
@@ -2824,12 +2921,22 @@ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2824
2921
port = mlx4_slaves_closest_port (dev , slave , port );
2825
2922
vf_admin = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
2826
2923
2924
+ if (!mlx4_valid_vf_state_change (dev , port , vf_admin , vlan , qos ))
2925
+ return - EPERM ;
2926
+
2827
2927
if ((0 == vlan ) && (0 == qos ))
2828
2928
vf_admin -> default_vlan = MLX4_VGT ;
2829
2929
else
2830
2930
vf_admin -> default_vlan = vlan ;
2831
2931
vf_admin -> default_qos = qos ;
2832
2932
2933
+ /* If rate was configured prior to VST, we saved the configured rate
2934
+ * in vf_admin->rate and now, if priority supported we enforce the QoS
2935
+ */
2936
+ if (mlx4_is_vf_vst_and_prio_qos (dev , port , vf_admin ) &&
2937
+ vf_admin -> tx_rate )
2938
+ vf_admin -> qos_vport = slave ;
2939
+
2833
2940
if (mlx4_master_immediate_activate_vlan_qos (priv , slave , port ))
2834
2941
mlx4_info (dev ,
2835
2942
"updating vf %d port %d config will take effect on next VF restart\n" ,
@@ -2838,6 +2945,69 @@ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
2838
2945
}
2839
2946
EXPORT_SYMBOL_GPL (mlx4_set_vf_vlan );
2840
2947
2948
+ int mlx4_set_vf_rate (struct mlx4_dev * dev , int port , int vf , int min_tx_rate ,
2949
+ int max_tx_rate )
2950
+ {
2951
+ int err ;
2952
+ int slave ;
2953
+ struct mlx4_vport_state * vf_admin ;
2954
+ struct mlx4_priv * priv = mlx4_priv (dev );
2955
+
2956
+ if (!mlx4_is_master (dev ) ||
2957
+ !(dev -> caps .flags2 & MLX4_DEV_CAP_FLAG2_QOS_VPP ))
2958
+ return - EPROTONOSUPPORT ;
2959
+
2960
+ if (min_tx_rate ) {
2961
+ mlx4_info (dev , "Minimum BW share not supported\n" );
2962
+ return - EPROTONOSUPPORT ;
2963
+ }
2964
+
2965
+ slave = mlx4_get_slave_indx (dev , vf );
2966
+ if (slave < 0 )
2967
+ return - EINVAL ;
2968
+
2969
+ port = mlx4_slaves_closest_port (dev , slave , port );
2970
+ vf_admin = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
2971
+
2972
+ err = mlx4_set_vport_qos (priv , slave , port , max_tx_rate );
2973
+ if (err ) {
2974
+ mlx4_info (dev , "vf %d failed to set rate %d\n" , vf ,
2975
+ max_tx_rate );
2976
+ return err ;
2977
+ }
2978
+
2979
+ vf_admin -> tx_rate = max_tx_rate ;
2980
+ /* if VF is not in supported mode (VST with supported prio),
2981
+ * we do not change vport configuration for its QPs, but save
2982
+ * the rate, so it will be enforced when it moves to supported
2983
+ * mode next time.
2984
+ */
2985
+ if (!mlx4_is_vf_vst_and_prio_qos (dev , port , vf_admin )) {
2986
+ mlx4_info (dev ,
2987
+ "rate set for VF %d when not in valid state\n" , vf );
2988
+
2989
+ if (vf_admin -> default_vlan != MLX4_VGT )
2990
+ mlx4_info (dev , "VST priority not supported by QoS\n" );
2991
+ else
2992
+ mlx4_info (dev , "VF in VGT mode (needed VST)\n" );
2993
+
2994
+ mlx4_info (dev ,
2995
+ "rate %d take affect when VF moves to valid state\n" ,
2996
+ max_tx_rate );
2997
+ return 0 ;
2998
+ }
2999
+
3000
+ /* If user sets rate 0 assigning default vport for its QPs */
3001
+ vf_admin -> qos_vport = max_tx_rate ? slave : MLX4_VPP_DEFAULT_VPORT ;
3002
+
3003
+ if (priv -> mfunc .master .slave_state [slave ].active &&
3004
+ dev -> caps .flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP )
3005
+ mlx4_master_immediate_activate_vlan_qos (priv , slave , port );
3006
+
3007
+ return 0 ;
3008
+ }
3009
+ EXPORT_SYMBOL_GPL (mlx4_set_vf_rate );
3010
+
2841
3011
/* mlx4_get_slave_default_vlan -
2842
3012
* return true if VST ( default vlan)
2843
3013
* if VST, will return vlan & qos (if not NULL)
@@ -2911,7 +3081,12 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
2911
3081
2912
3082
ivf -> vlan = s_info -> default_vlan ;
2913
3083
ivf -> qos = s_info -> default_qos ;
2914
- ivf -> max_tx_rate = s_info -> tx_rate ;
3084
+
3085
+ if (mlx4_is_vf_vst_and_prio_qos (dev , port , s_info ))
3086
+ ivf -> max_tx_rate = s_info -> tx_rate ;
3087
+ else
3088
+ ivf -> max_tx_rate = 0 ;
3089
+
2915
3090
ivf -> min_tx_rate = 0 ;
2916
3091
ivf -> spoofchk = s_info -> spoofchk ;
2917
3092
ivf -> linkstate = s_info -> link_state ;
0 commit comments