@@ -711,6 +711,7 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, u8 idx)
711711 struct i40e_mac_filter * f = NULL ;
712712 struct i40e_pf * pf = vf -> pf ;
713713 struct i40e_vsi * vsi ;
714+ u64 max_tx_rate = 0 ;
714715 int ret = 0 ;
715716
716717 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)
770771
771772 /* Set VF bandwidth if specified */
772773 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 );
773781 ret = i40e_aq_config_vsi_bw_limit (& pf -> hw , vsi -> seid ,
774- vf -> tx_rate / 50 , 0 , NULL );
782+ max_tx_rate , 0 , NULL );
775783 if (ret )
776784 dev_err (& pf -> pdev -> dev , "Unable to set tx rate, VF %d, error code %d.\n" ,
777785 vf -> vf_id , ret );
@@ -2918,7 +2926,8 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
29182926 struct virtchnl_tc_info * tci =
29192927 (struct virtchnl_tc_info * )msg ;
29202928 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 ;
29222931 i40e_status aq_ret = 0 ;
29232932
29242933 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)
29792988 vf -> num_queue_pairs = I40E_MAX_VF_QUEUES ;
29802989 }
29812990
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+
29823018 /* parse data from the queue channel info */
29833019 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+ }
29853034 vf -> ch [i ].num_qps = tci -> list [i ].count ;
3035+ }
29863036
29873037 /* set this flag only after making sure all inputs are sane */
29883038 vf -> adq_enabled = true;
0 commit comments