o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed to have a bandwidth of at least this value. max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth of up to this value. o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced which takes 4 arguments: netdev, VF number, min_tx_rate, max_tx_rate o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler. o Drivers that currently implement ndo_set_vf_tx_rate should now call ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet implemented by driver. o If user enters only one of either min_tx_rate or max_tx_rate, then, userland should read back the other value from driver and set both for IFLA_VF_RATE. Drivers that have not yet implemented IFLA_VF_RATE should always return min_tx_rate as 0 when read from ip tool. o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then IFLA_VF_RATE should override. o Idea is to have consistent display of rate values to user. o Usage example: - ./ip link set p4p1 vf 0 rate 900 ./ip link show p4p1 32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps vf 1 MAC f6:c6:7c:3f:3d:6c vf 2 MAC 56:32:43:98:d7:71 vf 3 MAC d6:be:c3:b5:85:ff vf 4 MAC ee:a9:9a:1e:19:14 vf 5 MAC 4a:d0:4c:07:52:18 vf 6 MAC 3a:76:44:93:62:f9 vf 7 MAC 82:e9:e7:e3:15:1a ./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200 ./ip link show p4p1 32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps, min_tx_rate 200Mbps vf 1 MAC f6:c6:7c:3f:3d:6c vf 2 MAC 56:32:43:98:d7:71 vf 3 MAC d6:be:c3:b5:85:ff vf 4 MAC ee:a9:9a:1e:19:14 vf 5 MAC 4a:d0:4c:07:52:18 vf 6 MAC 3a:76:44:93:62:f9 vf 7 MAC 82:e9:e7:e3:15:1a ./ip link set p4p1 vf 0 max_tx_rate 600 rate 300 ./ip link show p4p1 32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps, min_tx_rate 200Mbps vf 1 MAC f6:c6:7c:3f:3d:6c vf 2 MAC 56:32:43:98:d7:71 vf 3 MAC d6:be:c3:b5:85:ff vf 4 MAC ee:a9:9a:1e:19:14 vf 5 MAC 4a:d0:4c:07:52:18 vf 6 MAC 3a:76:44:93:62:f9 vf 7 MAC 82:e9:e7:e3:15:1a
Unified · Split
| @@ -2576,7 +2576,8 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, · 2575 unmodified lines | ||
| 2576 | 2576 | |
| 2577 | 2577 | ivi->vf = vfidx; |
| 2578 | 2578 | ivi->qos = 0; |
| 2579 | − ivi->tx_rate = 10000; /* always 10G. TBA take from link struct */ | |
| 2579 | + ivi->max_tx_rate = 10000; /* always 10G. TBA take from link struct */ | |
| 2580 | + ivi->min_tx_rate = 0; | |
| 2580 | 2581 | ivi->spoofchk = 1; /*always enabled */ |
| 2581 | 2582 | if (vf->state == VF_ENABLED) { |
| 2582 | 2583 | /* mac and vlan are in vlan_mac objects */ |
| @@ -1302,7 +1302,8 @@ static int be_get_vf_config(struct net_device *netdev, int vf, · 1301 unmodified lines | ||
| 1302 | 1302 | return -EINVAL; |
| 1303 | 1303 | |
| 1304 | 1304 | vi->vf = vf; |
| 1305 | − vi->tx_rate = vf_cfg->tx_rate; | |
| 1305 | + vi->max_tx_rate = vf_cfg->tx_rate; | |
| 1306 | + vi->min_tx_rate = 0; | |
| 1306 | 1307 | vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK; |
| 1307 | 1308 | vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT; |
| 1308 | 1309 | memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); |
| @@ -1342,7 +1343,8 @@ static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) · 33 unmodified lines | ||
| 1342 | 1343 | return status; |
| 1343 | 1344 | } |
| 1344 | 1345 | |
| 1345 | −static int be_set_vf_tx_rate(struct net_device *netdev, int vf, int rate) | |
| 1346 | +static int be_set_vf_tx_rate(struct net_device *netdev, int vf, | |
| 1347 | + int min_tx_rate, int max_tx_rate) | |
| 1346 | 1348 | { |
| 1347 | 1349 | struct be_adapter *adapter = netdev_priv(netdev); |
| 1348 | 1350 | int status = 0; |
| @@ -1353,18 +1355,21 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf, int rate) · 4 unmodified lines | ||
| 1353 | 1355 | if (vf >= adapter->num_vfs) |
| 1354 | 1356 | return -EINVAL; |
| 1355 | 1357 | |
| 1356 | − if (rate < 100 || rate > 10000) { | |
| 1358 | + if (min_tx_rate) | |
| 1359 | + return -EINVAL; | |
| 1360 | + | |
| 1361 | + if (max_tx_rate < 100 || max_tx_rate > 10000) { | |
| 1357 | 1362 | dev_err(&adapter->pdev->dev, |
| 1358 | − "tx rate must be between 100 and 10000 Mbps\n"); | |
| 1363 | + "max tx rate must be between 100 and 10000 Mbps\n"); | |
| 1359 | 1364 | return -EINVAL; |
| 1360 | 1365 | } |
| 1361 | 1366 | |
| 1362 | − status = be_cmd_config_qos(adapter, rate / 10, vf + 1); | |
| 1367 | + status = be_cmd_config_qos(adapter, max_tx_rate / 10, vf + 1); | |
| 1363 | 1368 | if (status) |
| 1364 | 1369 | dev_err(&adapter->pdev->dev, |
| 1365 | − "tx rate %d on VF %d failed\n", rate, vf); | |
| 1370 | + "max tx rate %d on VF %d failed\n", max_tx_rate, vf); | |
| 1366 | 1371 | else |
| 1367 | − adapter->vf_cfg[vf].tx_rate = rate; | |
| 1372 | + adapter->vf_cfg[vf].tx_rate = max_tx_rate; | |
| 1368 | 1373 | return status; |
| 1369 | 1374 | } |
| 1370 | 1375 | static int be_set_vf_link_state(struct net_device *netdev, int vf, |
| @@ -4257,7 +4262,7 @@ static const struct net_device_ops be_netdev_ops = { · 2886 unmodified lines | ||
| 4257 | 4262 | .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, |
| 4258 | 4263 | .ndo_set_vf_mac = be_set_vf_mac, |
| 4259 | 4264 | .ndo_set_vf_vlan = be_set_vf_vlan, |
| 4260 | − .ndo_set_vf_tx_rate = be_set_vf_tx_rate, | |
| 4265 | + .ndo_set_vf_rate = be_set_vf_tx_rate, | |
| 4261 | 4266 | .ndo_get_vf_config = be_get_vf_config, |
| 4262 | 4267 | .ndo_set_vf_link_state = be_set_vf_link_state, |
| 4263 | 4268 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| @@ -6724,7 +6724,7 @@ static const struct net_device_ops i40e_netdev_ops = { · 6723 unmodified lines | ||
| 6724 | 6724 | .ndo_set_features = i40e_set_features, |
| 6725 | 6725 | .ndo_set_vf_mac = i40e_ndo_set_vf_mac, |
| 6726 | 6726 | .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, |
| 6727 | − .ndo_set_vf_tx_rate = i40e_ndo_set_vf_bw, | |
| 6727 | + .ndo_set_vf_rate = i40e_ndo_set_vf_bw, | |
| 6728 | 6728 | .ndo_get_vf_config = i40e_ndo_get_vf_config, |
| 6729 | 6729 | .ndo_set_vf_link_state = i40e_ndo_set_vf_link_state, |
| 6730 | 6730 | #ifdef CONFIG_I40E_VXLAN |
| @@ -2205,7 +2205,8 @@ error_pvid: · 2204 unmodified lines | ||
| 2205 | 2205 | * |
| 2206 | 2206 | * configure vf tx rate |
| 2207 | 2207 | **/ |
| 2208 | −int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate) | |
| 2208 | +int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, | |
| 2209 | + int max_tx_rate) | |
| 2209 | 2210 | { |
| 2210 | 2211 | struct i40e_netdev_priv *np = netdev_priv(netdev); |
| 2211 | 2212 | struct i40e_pf *pf = np->vsi->back; |
| @@ -2221,6 +2222,12 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate) · 9 unmodified lines | ||
| 2221 | 2222 | goto error; |
| 2222 | 2223 | } |
| 2223 | 2224 | |
| 2225 | + if (min_tx_rate) { | |
| 2226 | + dev_err(&pf->pdev->dev, "Invalid min tx rate (%d) (greater than 0) specified for vf %d.\n", | |
| 2227 | + min_tx_rate, vf_id); | |
| 2228 | + return -EINVAL; | |
| 2229 | + } | |
| 2230 | + | |
| 2224 | 2231 | vf = &(pf->vf[vf_id]); |
| 2225 | 2232 | vsi = pf->vsi[vf->lan_vsi_index]; |
| 2226 | 2233 | if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) { |
| @@ -2243,23 +2250,23 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate) · 16 unmodified lines | ||
| 2243 | 2250 | break; |
| 2244 | 2251 | } |
| 2245 | 2252 | |
| 2246 | − if (tx_rate > speed) { | |
| 2247 | − dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.", | |
| 2248 | − tx_rate, vf->vf_id); | |
| 2253 | + if (max_tx_rate > speed) { | |
| 2254 | + dev_err(&pf->pdev->dev, "Invalid max tx rate %d specified for vf %d.", | |
| 2255 | + max_tx_rate, vf->vf_id); | |
| 2249 | 2256 | ret = -EINVAL; |
| 2250 | 2257 | goto error; |
| 2251 | 2258 | } |
| 2252 | 2259 | |
| 2253 | 2260 | /* Tx rate credits are in values of 50Mbps, 0 is disabled*/ |
| 2254 | − ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, tx_rate / 50, 0, | |
| 2255 | − NULL); | |
| 2261 | + ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, max_tx_rate / 50, | |
| 2262 | + 0, NULL); | |
| 2256 | 2263 | if (ret) { |
| 2257 | − dev_err(&pf->pdev->dev, "Unable to set tx rate, error code %d.\n", | |
| 2264 | + dev_err(&pf->pdev->dev, "Unable to set max tx rate, error code %d.\n", | |
| 2258 | 2265 | ret); |
| 2259 | 2266 | ret = -EIO; |
| 2260 | 2267 | goto error; |
| 2261 | 2268 | } |
| 2262 | − vf->tx_rate = tx_rate; | |
| 2269 | + vf->tx_rate = max_tx_rate; | |
| 2263 | 2270 | error: |
| 2264 | 2271 | return ret; |
| 2265 | 2272 | } |
| @@ -2301,7 +2308,8 @@ int i40e_ndo_get_vf_config(struct net_device *netdev, · 35 unmodified lines | ||
| 2301 | 2308 | |
| 2302 | 2309 | memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN); |
| 2303 | 2310 | |
| 2304 | − ivi->tx_rate = vf->tx_rate; | |
| 2311 | + ivi->max_tx_rate = vf->tx_rate; | |
| 2312 | + ivi->min_tx_rate = 0; | |
| 2305 | 2313 | ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK; |
| 2306 | 2314 | ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >> |
| 2307 | 2315 | I40E_VLAN_PRIORITY_SHIFT; |
| @@ -116,7 +116,8 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf); · 115 unmodified lines | ||
| 116 | 116 | int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); |
| 117 | 117 | int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, |
| 118 | 118 | int vf_id, u16 vlan_id, u8 qos); |
| 119 | −int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate); | |
| 119 | +int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, | |
| 120 | + int max_tx_rate); | |
| 120 | 121 | int i40e_ndo_get_vf_config(struct net_device *netdev, |
| 121 | 122 | int vf_id, struct ifla_vf_info *ivi); |
| 122 | 123 | int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link); |
| @@ -169,7 +169,7 @@ static void igb_restore_vf_multicasts(struct igb_adapter *adapter); · 168 unmodified lines | ||
| 169 | 169 | static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac); |
| 170 | 170 | static int igb_ndo_set_vf_vlan(struct net_device *netdev, |
| 171 | 171 | int vf, u16 vlan, u8 qos); |
| 172 | −static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); | |
| 172 | +static int igb_ndo_set_vf_bw(struct net_device *, int, int, int); | |
| 173 | 173 | static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, |
| 174 | 174 | bool setting); |
| 175 | 175 | static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, |
| @@ -2084,7 +2084,7 @@ static const struct net_device_ops igb_netdev_ops = { · 1908 unmodified lines | ||
| 2084 | 2084 | .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, |
| 2085 | 2085 | .ndo_set_vf_mac = igb_ndo_set_vf_mac, |
| 2086 | 2086 | .ndo_set_vf_vlan = igb_ndo_set_vf_vlan, |
| 2087 | − .ndo_set_vf_tx_rate = igb_ndo_set_vf_bw, | |
| 2087 | + .ndo_set_vf_rate = igb_ndo_set_vf_bw, | |
| 2088 | 2088 | .ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk, |
| 2089 | 2089 | .ndo_get_vf_config = igb_ndo_get_vf_config, |
| 2090 | 2090 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| @@ -7879,7 +7879,8 @@ static void igb_check_vf_rate_limit(struct igb_adapter *adapter) · 5788 unmodified lines | ||
| 7879 | 7879 | } |
| 7880 | 7880 | } |
| 7881 | 7881 | |
| 7882 | −static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) | |
| 7882 | +static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, | |
| 7883 | + int min_tx_rate, int max_tx_rate) | |
| 7883 | 7884 | { |
| 7884 | 7885 | struct igb_adapter *adapter = netdev_priv(netdev); |
| 7885 | 7886 | struct e1000_hw *hw = &adapter->hw; |
| @@ -7888,15 +7889,19 @@ static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) · 2 unmodified lines | ||
| 7888 | 7889 | if (hw->mac.type != e1000_82576) |
| 7889 | 7890 | return -EOPNOTSUPP; |
| 7890 | 7891 | |
| 7892 | + if (min_tx_rate) | |
| 7893 | + return -EINVAL; | |
| 7894 | + | |
| 7891 | 7895 | actual_link_speed = igb_link_mbps(adapter->link_speed); |
| 7892 | 7896 | if ((vf >= adapter->vfs_allocated_count) || |
| 7893 | 7897 | (!(rd32(E1000_STATUS) & E1000_STATUS_LU)) || |
| 7894 | − (tx_rate < 0) || (tx_rate > actual_link_speed)) | |
| 7898 | + (max_tx_rate < 0) || | |
| 7899 | + (max_tx_rate > actual_link_speed)) | |
| 7895 | 7900 | return -EINVAL; |
| 7896 | 7901 | |
| 7897 | 7902 | adapter->vf_rate_link_speed = actual_link_speed; |
| 7898 | − adapter->vf_data[vf].tx_rate = (u16)tx_rate; | |
| 7899 | − igb_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed); | |
| 7903 | + adapter->vf_data[vf].tx_rate = (u16)max_tx_rate; | |
| 7904 | + igb_set_vf_rate_limit(hw, vf, max_tx_rate, actual_link_speed); | |
| 7900 | 7905 | |
| 7901 | 7906 | return 0; |
| 7902 | 7907 | } |
| @@ -7936,7 +7941,8 @@ static int igb_ndo_get_vf_config(struct net_device *netdev, · 33 unmodified lines | ||
| 7936 | 7941 | return -EINVAL; |
| 7937 | 7942 | ivi->vf = vf; |
| 7938 | 7943 | memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN); |
| 7939 | − ivi->tx_rate = adapter->vf_data[vf].tx_rate; | |
| 7944 | + ivi->max_tx_rate = adapter->vf_data[vf].tx_rate; | |
| 7945 | + ivi->min_tx_rate = 0; | |
| 7940 | 7946 | ivi->vlan = adapter->vf_data[vf].pf_vlan; |
| 7941 | 7947 | ivi->qos = adapter->vf_data[vf].pf_qos; |
| 7942 | 7948 | ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled; |
| @@ -7926,7 +7926,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { · 7925 unmodified lines | ||
| 7926 | 7926 | .ndo_do_ioctl = ixgbe_ioctl, |
| 7927 | 7927 | .ndo_set_vf_mac = ixgbe_ndo_set_vf_mac, |
| 7928 | 7928 | .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, |
| 7929 | − .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw, | |
| 7929 | + .ndo_set_vf_rate = ixgbe_ndo_set_vf_bw, | |
| 7930 | 7930 | .ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk, |
| 7931 | 7931 | .ndo_get_vf_config = ixgbe_ndo_get_vf_config, |
| 7932 | 7932 | .ndo_get_stats64 = ixgbe_get_stats64, |
| @@ -1222,7 +1222,8 @@ void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter) · 1221 unmodified lines | ||
| 1222 | 1222 | } |
| 1223 | 1223 | } |
| 1224 | 1224 | |
| 1225 | −int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) | |
| 1225 | +int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, | |
| 1226 | + int max_tx_rate) | |
| 1226 | 1227 | { |
| 1227 | 1228 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
| 1228 | 1229 | int link_speed; |
| @@ -1240,13 +1241,16 @@ int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) · 11 unmodified lines | ||
| 1240 | 1241 | if (link_speed != 10000) |
| 1241 | 1242 | return -EINVAL; |
| 1242 | 1243 | |
| 1244 | + if (min_tx_rate) | |
| 1245 | + return -EINVAL; | |
| 1246 | + | |
| 1243 | 1247 | /* rate limit cannot be less than 10Mbs or greater than link speed */ |
| 1244 | − if (tx_rate && ((tx_rate <= 10) || (tx_rate > link_speed))) | |
| 1248 | + if (max_tx_rate && ((max_tx_rate <= 10) || (max_tx_rate > link_speed))) | |
| 1245 | 1249 | return -EINVAL; |
| 1246 | 1250 | |
| 1247 | 1251 | /* store values */ |
| 1248 | 1252 | adapter->vf_rate_link_speed = link_speed; |
| 1249 | − adapter->vfinfo[vf].tx_rate = tx_rate; | |
| 1253 | + adapter->vfinfo[vf].tx_rate = max_tx_rate; | |
| 1250 | 1254 | |
| 1251 | 1255 | /* update hardware configuration */ |
| 1252 | 1256 | ixgbe_set_vf_rate_limit(adapter, vf); |
| @@ -1288,7 +1292,8 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev, · 35 unmodified lines | ||
| 1288 | 1292 | return -EINVAL; |
| 1289 | 1293 | ivi->vf = vf; |
| 1290 | 1294 | memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); |
| 1291 | − ivi->tx_rate = adapter->vfinfo[vf].tx_rate; | |
| 1295 | + ivi->max_tx_rate = adapter->vfinfo[vf].tx_rate; | |
| 1296 | + ivi->min_tx_rate = 0; | |
| 1292 | 1297 | ivi->vlan = adapter->vfinfo[vf].pf_vlan; |
| 1293 | 1298 | ivi->qos = adapter->vfinfo[vf].pf_qos; |
| 1294 | 1299 | ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled; |
| @@ -44,7 +44,8 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); · 43 unmodified lines | ||
| 44 | 44 | int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); |
| 45 | 45 | int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, |
| 46 | 46 | u8 qos); |
| 47 | −int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); | |
| 47 | +int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, | |
| 48 | + int max_tx_rate); | |
| 48 | 49 | int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); |
| 49 | 50 | int ixgbe_ndo_get_vf_config(struct net_device *netdev, |
| 50 | 51 | int vf, struct ifla_vf_info *ivi); |
| @@ -2486,11 +2486,12 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in · 2485 unmodified lines | ||
| 2486 | 2486 | ivf->mac[4] = ((s_info->mac >> (1*8)) & 0xff); |
| 2487 | 2487 | ivf->mac[5] = ((s_info->mac) & 0xff); |
| 2488 | 2488 | |
| 2489 | − ivf->vlan = s_info->default_vlan; | |
| 2490 | − ivf->qos = s_info->default_qos; | |
| 2491 | − ivf->tx_rate = s_info->tx_rate; | |
| 2492 | − ivf->spoofchk = s_info->spoofchk; | |
| 2493 | − ivf->linkstate = s_info->link_state; | |
| 2489 | + ivf->vlan = s_info->default_vlan; | |
| 2490 | + ivf->qos = s_info->default_qos; | |
| 2491 | + ivf->max_tx_rate = s_info->tx_rate; | |
| 2492 | + ivf->min_tx_rate = 0; | |
| 2493 | + ivf->spoofchk = s_info->spoofchk; | |
| 2494 | + ivf->linkstate = s_info->link_state; | |
| 2494 | 2495 | |
| 2495 | 2496 | return 0; |
| 2496 | 2497 | } |
| @@ -1319,6 +1319,7 @@ struct qlcnic_eswitch { · 1318 unmodified lines | ||
| 1319 | 1319 | #define QL_STATUS_INVALID_PARAM -1 |
| 1320 | 1320 | |
| 1321 | 1321 | #define MAX_BW 100 /* % of link speed */ |
| 1322 | +#define MIN_BW 1 /* % of link speed */ | |
| 1322 | 1323 | #define MAX_VLAN_ID 4095 |
| 1323 | 1324 | #define MIN_VLAN_ID 2 |
| 1324 | 1325 | #define DEFAULT_MAC_LEARN 1 |
| @@ -525,7 +525,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { · 524 unmodified lines | ||
| 525 | 525 | #endif |
| 526 | 526 | #ifdef CONFIG_QLCNIC_SRIOV |
| 527 | 527 | .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, |
| 528 | − .ndo_set_vf_tx_rate = qlcnic_sriov_set_vf_tx_rate, | |
| 528 | + .ndo_set_vf_rate = qlcnic_sriov_set_vf_tx_rate, | |
| 529 | 529 | .ndo_get_vf_config = qlcnic_sriov_get_vf_config, |
| 530 | 530 | .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan, |
| 531 | 531 | .ndo_set_vf_spoofchk = qlcnic_sriov_set_vf_spoofchk, |
| @@ -233,7 +233,7 @@ bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *, · 232 unmodified lines | ||
| 233 | 233 | void qlcnic_sriov_pf_reset(struct qlcnic_adapter *); |
| 234 | 234 | int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *); |
| 235 | 235 | int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *); |
| 236 | −int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int); | |
| 236 | +int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int); | |
| 237 | 237 | int qlcnic_sriov_get_vf_config(struct net_device *, int , |
| 238 | 238 | struct ifla_vf_info *); |
| 239 | 239 | int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8); |
| @@ -201,6 +201,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) · 200 unmodified lines | ||
| 201 | 201 | sriov->vf_info[i].vp = vp; |
| 202 | 202 | vp->vlan_mode = QLC_GUEST_VLAN_MODE; |
| 203 | 203 | vp->max_tx_bw = MAX_BW; |
| 204 | + vp->min_tx_bw = MIN_BW; | |
| 204 | 205 | vp->spoofchk = false; |
| 205 | 206 | random_ether_addr(vp->mac); |
| 206 | 207 | dev_info(&adapter->pdev->dev, |
| @@ -1848,7 +1848,8 @@ int qlcnic_sriov_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) · 1847 unmodified lines | ||
| 1848 | 1848 | return 0; |
| 1849 | 1849 | } |
| 1850 | 1850 | |
| 1851 | −int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate) | |
| 1851 | +int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, | |
| 1852 | + int min_tx_rate, int max_tx_rate) | |
| 1852 | 1853 | { |
| 1853 | 1854 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
| 1854 | 1855 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
| @@ -1863,35 +1864,52 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate) · 8 unmodified lines | ||
| 1863 | 1864 | if (vf >= sriov->num_vfs) |
| 1864 | 1865 | return -EINVAL; |
| 1865 | 1866 | |
| 1866 | − if (tx_rate >= 10000 || tx_rate < 100) { | |
| 1867 | + vf_info = &sriov->vf_info[vf]; | |
| 1868 | + vp = vf_info->vp; | |
| 1869 | + vpid = vp->handle; | |
| 1870 | + | |
| 1871 | + if (!min_tx_rate) | |
| 1872 | + min_tx_rate = QLC_VF_MIN_TX_RATE; | |
| 1873 | + | |
| 1874 | + if (max_tx_rate && | |
| 1875 | + (max_tx_rate >= 10000 || max_tx_rate < min_tx_rate)) { | |
| 1867 | 1876 | netdev_err(netdev, |
| 1868 | − "Invalid Tx rate, allowed range is [%d - %d]", | |
| 1869 | − QLC_VF_MIN_TX_RATE, QLC_VF_MAX_TX_RATE); | |
| 1877 | + "Invalid max Tx rate, allowed range is [%d - %d]", | |
| 1878 | + min_tx_rate, QLC_VF_MAX_TX_RATE); | |
| 1870 | 1879 | return -EINVAL; |
| 1871 | 1880 | } |
| 1872 | 1881 | |
| 1873 | − if (tx_rate == 0) | |
| 1874 | − tx_rate = 10000; | |
| 1882 | + if (!max_tx_rate) | |
| 1883 | + max_tx_rate = 10000; | |
| 1875 | 1884 | |
| 1876 | − vf_info = &sriov->vf_info[vf]; | |
| 1877 | − vp = vf_info->vp; | |
| 1878 | − vpid = vp->handle; | |
| 1885 | + if (min_tx_rate && | |
| 1886 | + (min_tx_rate > max_tx_rate || min_tx_rate < QLC_VF_MIN_TX_RATE)) { | |
| 1887 | + netdev_err(netdev, | |
| 1888 | + "Invalid min Tx rate, allowed range is [%d - %d]", | |
| 1889 | + QLC_VF_MIN_TX_RATE, max_tx_rate); | |
| 1890 | + return -EINVAL; | |
| 1891 | + } | |
| 1879 | 1892 | |
| 1880 | 1893 | if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) { |
| 1881 | 1894 | if (qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, vpid)) |
| 1882 | 1895 | return -EIO; |
| 1883 | 1896 | |
| 1884 | − nic_info.max_tx_bw = tx_rate / 100; | |
| 1897 | + nic_info.max_tx_bw = max_tx_rate / 100; | |
| 1898 | + nic_info.min_tx_bw = min_tx_rate / 100; | |
| 1885 | 1899 | nic_info.bit_offsets = BIT_0; |
| 1886 | 1900 | |
| 1887 | 1901 | if (qlcnic_sriov_pf_set_vport_info(adapter, &nic_info, vpid)) |
| 1888 | 1902 | return -EIO; |
| 1889 | 1903 | } |
| 1890 | 1904 | |
| 1891 | − vp->max_tx_bw = tx_rate / 100; | |
| 1905 | + vp->max_tx_bw = max_tx_rate / 100; | |
| 1906 | + netdev_info(netdev, | |
| 1907 | + "Setting Max Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", | |
| 1908 | + max_tx_rate, vp->max_tx_bw, vf); | |
| 1909 | + vp->min_tx_bw = min_tx_rate / 100; | |
| 1892 | 1910 | netdev_info(netdev, |
| 1893 | − "Setting Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", | |
| 1894 | − tx_rate, vp->max_tx_bw, vf); | |
| 1911 | + "Setting Min Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", | |
| 1912 | + min_tx_rate, vp->min_tx_bw, vf); | |
| 1895 | 1913 | return 0; |
| 1896 | 1914 | } |
| 1897 | 1915 | |
| @@ -1990,9 +2008,13 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev, · 92 unmodified lines | ||
| 1990 | 2008 | ivi->qos = vp->qos; |
| 1991 | 2009 | ivi->spoofchk = vp->spoofchk; |
| 1992 | 2010 | if (vp->max_tx_bw == MAX_BW) |
| 1993 | − ivi->tx_rate = 0; | |
| 2011 | + ivi->max_tx_rate = 0; | |
| 2012 | + else | |
| 2013 | + ivi->max_tx_rate = vp->max_tx_bw * 100; | |
| 2014 | + if (vp->min_tx_bw == MIN_BW) | |
| 2015 | + ivi->min_tx_rate = 0; | |
| 1994 | 2016 | else |
| 1995 | − ivi->tx_rate = vp->max_tx_bw * 100; | |
| 2017 | + ivi->min_tx_rate = vp->min_tx_bw * 100; | |
| 1996 | 2018 | |
| 1997 | 2019 | ivi->vf = vf; |
| 1998 | 2020 | return 0; |
| @@ -1633,7 +1633,8 @@ int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, · 1632 unmodified lines | ||
| 1633 | 1633 | |
| 1634 | 1634 | ivi->vf = vf_i; |
| 1635 | 1635 | ether_addr_copy(ivi->mac, vf->addr.mac_addr); |
| 1636 | − ivi->tx_rate = 0; | |
| 1636 | + ivi->max_tx_rate = 0; | |
| 1637 | + ivi->min_tx_rate = 0; | |
| 1637 | 1638 | tci = ntohs(vf->addr.tci); |
| 1638 | 1639 | ivi->vlan = tci & VLAN_VID_MASK; |
| 1639 | 1640 | ivi->qos = (tci >> VLAN_PRIO_SHIFT) & 0x7; |
| @@ -10,8 +10,9 @@ struct ifla_vf_info { · 9 unmodified lines | ||
| 10 | 10 | __u8 mac[32]; |
| 11 | 11 | __u32 vlan; |
| 12 | 12 | __u32 qos; |
| 13 | − __u32 tx_rate; | |
| 14 | 13 | __u32 spoofchk; |
| 15 | 14 | __u32 linkstate; |
| 15 | + __u32 min_tx_rate; | |
| 16 | + __u32 max_tx_rate; | |
| 16 | 17 | }; |
| 17 | 18 | #endif /* _LINUX_IF_LINK_H */ |
| @@ -850,7 +850,8 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, · 849 unmodified lines | ||
| 850 | 850 | * SR-IOV management functions. |
| 851 | 851 | * int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac); |
| 852 | 852 | * int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos); |
| 853 | − * int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate); | |
| 853 | + * int (*ndo_set_vf_rate)(struct net_device *dev, int vf, int min_tx_rate, | |
| 854 | + * int max_tx_rate); | |
| 854 | 855 | * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting); |
| 855 | 856 | * int (*ndo_get_vf_config)(struct net_device *dev, |
| 856 | 857 | * int vf, struct ifla_vf_info *ivf); |
| @@ -1044,8 +1045,9 @@ struct net_device_ops { · 187 unmodified lines | ||
| 1044 | 1045 | int queue, u8 *mac); |
| 1045 | 1046 | int (*ndo_set_vf_vlan)(struct net_device *dev, |
| 1046 | 1047 | int queue, u16 vlan, u8 qos); |
| 1047 | − int (*ndo_set_vf_tx_rate)(struct net_device *dev, | |
| 1048 | − int vf, int rate); | |
| 1048 | + int (*ndo_set_vf_rate)(struct net_device *dev, | |
| 1049 | + int vf, int min_tx_rate, | |
| 1050 | + int max_tx_rate); | |
| 1049 | 1051 | int (*ndo_set_vf_spoofchk)(struct net_device *dev, |
| 1050 | 1052 | int vf, bool setting); |
| 1051 | 1053 | int (*ndo_get_vf_config)(struct net_device *dev, |
| @@ -399,9 +399,10 @@ enum { · 398 unmodified lines | ||
| 399 | 399 | IFLA_VF_UNSPEC, |
| 400 | 400 | IFLA_VF_MAC, /* Hardware queue specific attributes */ |
| 401 | 401 | IFLA_VF_VLAN, |
| 402 | − IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ | |
| 402 | + IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ | |
| 403 | 403 | IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ |
| 404 | 404 | IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ |
| 405 | + IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ | |
| 405 | 406 | __IFLA_VF_MAX, |
| 406 | 407 | }; |
| 407 | 408 | |
| @@ -423,6 +424,12 @@ struct ifla_vf_tx_rate { · 15 unmodified lines | ||
| 423 | 424 | __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ |
| 424 | 425 | }; |
| 425 | 426 | |
| 427 | +struct ifla_vf_rate { | |
| 428 | + __u32 vf; | |
| 429 | + __u32 min_tx_rate; /* Min Bandwidth in Mbps */ | |
| 430 | + __u32 max_tx_rate; /* Max Bandwidth in Mbps */ | |
| 431 | +}; | |
| 432 | + | |
| 426 | 433 | struct ifla_vf_spoofchk { |
| 427 | 434 | __u32 vf; |
| 428 | 435 | __u32 setting; |
| @@ -767,8 +767,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, · 766 unmodified lines | ||
| 767 | 767 | size += num_vfs * |
| 768 | 768 | (nla_total_size(sizeof(struct ifla_vf_mac)) + |
| 769 | 769 | nla_total_size(sizeof(struct ifla_vf_vlan)) + |
| 770 | − nla_total_size(sizeof(struct ifla_vf_tx_rate)) + | |
| 771 | − nla_total_size(sizeof(struct ifla_vf_spoofchk))); | |
| 770 | + nla_total_size(sizeof(struct ifla_vf_spoofchk)) + | |
| 771 | + nla_total_size(sizeof(struct ifla_vf_rate))); | |
| 772 | 772 | return size; |
| 773 | 773 | } else |
| 774 | 774 | return 0; |
| @@ -1034,6 +1034,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, · 259 unmodified lines | ||
| 1034 | 1034 | struct ifla_vf_info ivi; |
| 1035 | 1035 | struct ifla_vf_mac vf_mac; |
| 1036 | 1036 | struct ifla_vf_vlan vf_vlan; |
| 1037 | + struct ifla_vf_rate vf_rate; | |
| 1037 | 1038 | struct ifla_vf_tx_rate vf_tx_rate; |
| 1038 | 1039 | struct ifla_vf_spoofchk vf_spoofchk; |
| 1039 | 1040 | struct ifla_vf_link_state vf_linkstate; |
| @@ -1054,6 +1055,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, · 14 unmodified lines | ||
| 1054 | 1055 | break; |
| 1055 | 1056 | vf_mac.vf = |
| 1056 | 1057 | vf_vlan.vf = |
| 1058 | + vf_rate.vf = | |
| 1057 | 1059 | vf_tx_rate.vf = |
| 1058 | 1060 | vf_spoofchk.vf = |
| 1059 | 1061 | vf_linkstate.vf = ivi.vf; |
| @@ -1061,7 +1063,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, · 1 unmodified line | ||
| 1061 | 1063 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); |
| 1062 | 1064 | vf_vlan.vlan = ivi.vlan; |
| 1063 | 1065 | vf_vlan.qos = ivi.qos; |
| 1064 | − vf_tx_rate.rate = ivi.tx_rate; | |
| 1066 | + vf_tx_rate.rate = ivi.max_tx_rate; | |
| 1067 | + vf_rate.min_tx_rate = ivi.min_tx_rate; | |
| 1068 | + vf_rate.max_tx_rate = ivi.max_tx_rate; | |
| 1065 | 1069 | vf_spoofchk.setting = ivi.spoofchk; |
| 1066 | 1070 | vf_linkstate.link_state = ivi.linkstate; |
| 1067 | 1071 | vf = nla_nest_start(skb, IFLA_VF_INFO); |
| @@ -1071,6 +1075,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, · 3 unmodified lines | ||
| 1071 | 1075 | } |
| 1072 | 1076 | if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) || |
| 1073 | 1077 | nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) || |
| 1078 | + nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate), | |
| 1079 | + &vf_rate) || | |
| 1074 | 1080 | nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), |
| 1075 | 1081 | &vf_tx_rate) || |
| 1076 | 1082 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), |
| @@ -1177,6 +1183,8 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { · 100 unmodified lines | ||
| 1177 | 1183 | .len = sizeof(struct ifla_vf_tx_rate) }, |
| 1178 | 1184 | [IFLA_VF_SPOOFCHK] = { .type = NLA_BINARY, |
| 1179 | 1185 | .len = sizeof(struct ifla_vf_spoofchk) }, |
| 1186 | + [IFLA_VF_RATE] = { .type = NLA_BINARY, | |
| 1187 | + .len = sizeof(struct ifla_vf_rate) }, | |
| 1180 | 1188 | }; |
| 1181 | 1189 | |
| 1182 | 1190 | static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { |
| @@ -1336,11 +1344,29 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) · 153 unmodified lines | ||
| 1336 | 1344 | } |
| 1337 | 1345 | case IFLA_VF_TX_RATE: { |
| 1338 | 1346 | struct ifla_vf_tx_rate *ivt; |
| 1347 | + struct ifla_vf_info ivf; | |
| 1339 | 1348 | ivt = nla_data(vf); |
| 1340 | 1349 | err = -EOPNOTSUPP; |
| 1341 | − if (ops->ndo_set_vf_tx_rate) | |
| 1342 | − err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, | |
| 1343 | − ivt->rate); | |
| 1350 | + if (ops->ndo_get_vf_config) | |
| 1351 | + err = ops->ndo_get_vf_config(dev, ivt->vf, | |
| 1352 | + &ivf); | |
| 1353 | + if (err) | |
| 1354 | + break; | |
| 1355 | + err = -EOPNOTSUPP; | |
| 1356 | + if (ops->ndo_set_vf_rate) | |
| 1357 | + err = ops->ndo_set_vf_rate(dev, ivt->vf, | |
| 1358 | + ivf.min_tx_rate, | |
| 1359 | + ivt->rate); | |
| 1360 | + break; | |
| 1361 | + } | |
| 1362 | + case IFLA_VF_RATE: { | |
| 1363 | + struct ifla_vf_rate *ivt; | |
| 1364 | + ivt = nla_data(vf); | |
| 1365 | + err = -EOPNOTSUPP; | |
| 1366 | + if (ops->ndo_set_vf_rate) | |
| 1367 | + err = ops->ndo_set_vf_rate(dev, ivt->vf, | |
| 1368 | + ivt->min_tx_rate, | |
| 1369 | + ivt->max_tx_rate); | |
| 1344 | 1370 | break; |
| 1345 | 1371 | } |
| 1346 | 1372 | case IFLA_VF_SPOOFCHK: { |