@@ -711,6 +711,7 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, u8 idx)
711
711
struct i40e_mac_filter * f = NULL ;
712
712
struct i40e_pf * pf = vf -> pf ;
713
713
struct i40e_vsi * vsi ;
714
+ u64 max_tx_rate = 0 ;
714
715
int ret = 0 ;
715
716
716
717
vsi = i40e_vsi_setup (pf , I40E_VSI_SRIOV , pf -> vsi [pf -> lan_vsi ]-> seid ,
@@ -770,8 +771,15 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, u8 idx)
770
771
771
772
/* Set VF bandwidth if specified */
772
773
if (vf -> tx_rate ) {
774
+ max_tx_rate = vf -> tx_rate ;
775
+ } else if (vf -> ch [idx ].max_tx_rate ) {
776
+ max_tx_rate = vf -> ch [idx ].max_tx_rate ;
777
+ }
778
+
779
+ if (max_tx_rate ) {
780
+ max_tx_rate = div_u64 (max_tx_rate , I40E_BW_CREDIT_DIVISOR );
773
781
ret = i40e_aq_config_vsi_bw_limit (& pf -> hw , vsi -> seid ,
774
- vf -> tx_rate / 50 , 0 , NULL );
782
+ max_tx_rate , 0 , NULL );
775
783
if (ret )
776
784
dev_err (& pf -> pdev -> dev , "Unable to set tx rate, VF %d, error code %d.\n" ,
777
785
vf -> vf_id , ret );
@@ -2918,7 +2926,8 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
2918
2926
struct virtchnl_tc_info * tci =
2919
2927
(struct virtchnl_tc_info * )msg ;
2920
2928
struct i40e_pf * pf = vf -> pf ;
2921
- int i , adq_request_qps = 0 ;
2929
+ struct i40e_link_status * ls = & pf -> hw .phy .link_info ;
2930
+ int i , adq_request_qps = 0 , speed = 0 ;
2922
2931
i40e_status aq_ret = 0 ;
2923
2932
2924
2933
if (!test_bit (I40E_VF_STATE_ACTIVE , & vf -> vf_states )) {
@@ -2979,10 +2988,51 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
2979
2988
vf -> num_queue_pairs = I40E_MAX_VF_QUEUES ;
2980
2989
}
2981
2990
2991
+ /* get link speed in MB to validate rate limit */
2992
+ switch (ls -> link_speed ) {
2993
+ case VIRTCHNL_LINK_SPEED_100MB :
2994
+ speed = SPEED_100 ;
2995
+ break ;
2996
+ case VIRTCHNL_LINK_SPEED_1GB :
2997
+ speed = SPEED_1000 ;
2998
+ break ;
2999
+ case VIRTCHNL_LINK_SPEED_10GB :
3000
+ speed = SPEED_10000 ;
3001
+ break ;
3002
+ case VIRTCHNL_LINK_SPEED_20GB :
3003
+ speed = SPEED_20000 ;
3004
+ break ;
3005
+ case VIRTCHNL_LINK_SPEED_25GB :
3006
+ speed = SPEED_25000 ;
3007
+ break ;
3008
+ case VIRTCHNL_LINK_SPEED_40GB :
3009
+ speed = SPEED_40000 ;
3010
+ break ;
3011
+ default :
3012
+ dev_err (& pf -> pdev -> dev ,
3013
+ "Cannot detect link speed\n" );
3014
+ aq_ret = I40E_ERR_PARAM ;
3015
+ goto err ;
3016
+ }
3017
+
2982
3018
/* parse data from the queue channel info */
2983
3019
vf -> num_tc = tci -> num_tc ;
2984
- for (i = 0 ; i < vf -> num_tc ; i ++ )
3020
+ for (i = 0 ; i < vf -> num_tc ; i ++ ) {
3021
+ if (tci -> list [i ].max_tx_rate ) {
3022
+ if (tci -> list [i ].max_tx_rate > speed ) {
3023
+ dev_err (& pf -> pdev -> dev ,
3024
+ "Invalid max tx rate %llu specified for VF %d." ,
3025
+ tci -> list [i ].max_tx_rate ,
3026
+ vf -> vf_id );
3027
+ aq_ret = I40E_ERR_PARAM ;
3028
+ goto err ;
3029
+ } else {
3030
+ vf -> ch [i ].max_tx_rate =
3031
+ tci -> list [i ].max_tx_rate ;
3032
+ }
3033
+ }
2985
3034
vf -> ch [i ].num_qps = tci -> list [i ].count ;
3035
+ }
2986
3036
2987
3037
/* set this flag only after making sure all inputs are sane */
2988
3038
vf -> adq_enabled = true;
0 commit comments