@@ -2235,6 +2235,48 @@ void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter)
22352235 i40evf_free_rx_resources (& adapter -> rx_rings [i ]);
22362236}
22372237
2238+ /**
2239+ * i40evf_validate_tx_bandwidth - validate the max Tx bandwidth
2240+ * @adapter: board private structure
2241+ * @max_tx_rate: max Tx bw for a tc
2242+ **/
2243+ static int i40evf_validate_tx_bandwidth (struct i40evf_adapter * adapter ,
2244+ u64 max_tx_rate )
2245+ {
2246+ int speed = 0 , ret = 0 ;
2247+
2248+ switch (adapter -> link_speed ) {
2249+ case I40E_LINK_SPEED_40GB :
2250+ speed = 40000 ;
2251+ break ;
2252+ case I40E_LINK_SPEED_25GB :
2253+ speed = 25000 ;
2254+ break ;
2255+ case I40E_LINK_SPEED_20GB :
2256+ speed = 20000 ;
2257+ break ;
2258+ case I40E_LINK_SPEED_10GB :
2259+ speed = 10000 ;
2260+ break ;
2261+ case I40E_LINK_SPEED_1GB :
2262+ speed = 1000 ;
2263+ break ;
2264+ case I40E_LINK_SPEED_100MB :
2265+ speed = 100 ;
2266+ break ;
2267+ default :
2268+ break ;
2269+ }
2270+
2271+ if (max_tx_rate > speed ) {
2272+ dev_err (& adapter -> pdev -> dev ,
2273+ "Invalid tx rate specified\n" );
2274+ ret = - EINVAL ;
2275+ }
2276+
2277+ return ret ;
2278+ }
2279+
22382280/**
22392281 * i40evf_validate_channel_config - validate queue mapping info
22402282 * @adapter: board private structure
@@ -2247,24 +2289,35 @@ void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter)
22472289static int i40evf_validate_ch_config (struct i40evf_adapter * adapter ,
22482290 struct tc_mqprio_qopt_offload * mqprio_qopt )
22492291{
2292+ u64 total_max_rate = 0 ;
22502293 int i , num_qps = 0 ;
2294+ u64 tx_rate = 0 ;
2295+ int ret = 0 ;
22512296
22522297 if (mqprio_qopt -> qopt .num_tc > I40EVF_MAX_TRAFFIC_CLASS ||
22532298 mqprio_qopt -> qopt .num_tc < 1 )
22542299 return - EINVAL ;
22552300
22562301 for (i = 0 ; i <= mqprio_qopt -> qopt .num_tc - 1 ; i ++ ) {
22572302 if (!mqprio_qopt -> qopt .count [i ] ||
2258- mqprio_qopt -> min_rate [i ] ||
2259- mqprio_qopt -> max_rate [i ] ||
22602303 mqprio_qopt -> qopt .offset [i ] != num_qps )
22612304 return - EINVAL ;
2305+ if (mqprio_qopt -> min_rate [i ]) {
2306+ dev_err (& adapter -> pdev -> dev ,
2307+ "Invalid min tx rate (greater than 0) specified\n" );
2308+ return - EINVAL ;
2309+ }
2310+ /*convert to Mbps */
2311+ tx_rate = div_u64 (mqprio_qopt -> max_rate [i ],
2312+ I40EVF_MBPS_DIVISOR );
2313+ total_max_rate += tx_rate ;
22622314 num_qps += mqprio_qopt -> qopt .count [i ];
22632315 }
22642316 if (num_qps > MAX_QUEUES )
22652317 return - EINVAL ;
22662318
2267- return 0 ;
2319+ ret = i40evf_validate_tx_bandwidth (adapter , total_max_rate );
2320+ return ret ;
22682321}
22692322
22702323/**
@@ -2285,6 +2338,7 @@ static int __i40evf_setup_tc(struct net_device *netdev, void *type_data)
22852338 struct virtchnl_vf_resource * vfres = adapter -> vf_res ;
22862339 u8 num_tc = 0 , total_qps = 0 ;
22872340 int ret = 0 , netdev_tc = 0 ;
2341+ u64 max_tx_rate ;
22882342 u16 mode ;
22892343 int i ;
22902344
@@ -2332,6 +2386,12 @@ static int __i40evf_setup_tc(struct net_device *netdev, void *type_data)
23322386 adapter -> ch_config .ch_info [i ].offset =
23332387 mqprio_qopt -> qopt .offset [i ];
23342388 total_qps += mqprio_qopt -> qopt .count [i ];
2389+ max_tx_rate = mqprio_qopt -> max_rate [i ];
2390+ /* convert to Mbps */
2391+ max_tx_rate = div_u64 (max_tx_rate ,
2392+ I40EVF_MBPS_DIVISOR );
2393+ adapter -> ch_config .ch_info [i ].max_tx_rate =
2394+ max_tx_rate ;
23352395 } else {
23362396 adapter -> ch_config .ch_info [i ].count = 1 ;
23372397 adapter -> ch_config .ch_info [i ].offset = 0 ;
0 commit comments