aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorSucheta Chakraborty <sucheta.chakraborty@qlogic.com>2014-05-22 09:59:05 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-23 15:04:02 -0400
commited616689a3d95eb6c9bdbb1ef74b0f50cbdf276a (patch)
tree50be50b40071bd5307b7a1efbfe04b3c06e178b3 /drivers/net/ethernet
parent307f099520b66504cf6c5638f3f404c48b9fb45b (diff)
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
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 Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c3
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c21
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c26
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h3
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c20
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c13
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c11
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c52
-rw-r--r--drivers/net/ethernet/sfc/siena_sriov.c3
16 files changed, 109 insertions, 56 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 81cc2d9831c2..8d0479d5be8e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -2576,7 +2576,8 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
2576 2576
2577 ivi->vf = vfidx; 2577 ivi->vf = vfidx;
2578 ivi->qos = 0; 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 ivi->spoofchk = 1; /*always enabled */ 2581 ivi->spoofchk = 1; /*always enabled */
2581 if (vf->state == VF_ENABLED) { 2582 if (vf->state == VF_ENABLED) {
2582 /* mac and vlan are in vlan_mac objects */ 2583 /* mac and vlan are in vlan_mac objects */
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index dcc5e5c69743..4693d004a223 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1302,7 +1302,8 @@ static int be_get_vf_config(struct net_device *netdev, int vf,
1302 return -EINVAL; 1302 return -EINVAL;
1303 1303
1304 vi->vf = vf; 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 vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK; 1307 vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK;
1307 vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT; 1308 vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT;
1308 memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); 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)
1342 return status; 1343 return status;
1343} 1344}
1344 1345
1345static int be_set_vf_tx_rate(struct net_device *netdev, int vf, int rate) 1346static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
1347 int min_tx_rate, int max_tx_rate)
1346{ 1348{
1347 struct be_adapter *adapter = netdev_priv(netdev); 1349 struct be_adapter *adapter = netdev_priv(netdev);
1348 int status = 0; 1350 int status = 0;
@@ -1353,18 +1355,21 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf, int rate)
1353 if (vf >= adapter->num_vfs) 1355 if (vf >= adapter->num_vfs)
1354 return -EINVAL; 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 dev_err(&adapter->pdev->dev, 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 return -EINVAL; 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 if (status) 1368 if (status)
1364 dev_err(&adapter->pdev->dev, 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 else 1371 else
1367 adapter->vf_cfg[vf].tx_rate = rate; 1372 adapter->vf_cfg[vf].tx_rate = max_tx_rate;
1368 return status; 1373 return status;
1369} 1374}
1370static int be_set_vf_link_state(struct net_device *netdev, int vf, 1375static 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 = {
4257 .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, 4262 .ndo_vlan_rx_kill_vid = be_vlan_rem_vid,
4258 .ndo_set_vf_mac = be_set_vf_mac, 4263 .ndo_set_vf_mac = be_set_vf_mac,
4259 .ndo_set_vf_vlan = be_set_vf_vlan, 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 .ndo_get_vf_config = be_get_vf_config, 4266 .ndo_get_vf_config = be_get_vf_config,
4262 .ndo_set_vf_link_state = be_set_vf_link_state, 4267 .ndo_set_vf_link_state = be_set_vf_link_state,
4263#ifdef CONFIG_NET_POLL_CONTROLLER 4268#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index e0e5c6a867b1..96f7fabd8758 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -6724,7 +6724,7 @@ static const struct net_device_ops i40e_netdev_ops = {
6724 .ndo_set_features = i40e_set_features, 6724 .ndo_set_features = i40e_set_features,
6725 .ndo_set_vf_mac = i40e_ndo_set_vf_mac, 6725 .ndo_set_vf_mac = i40e_ndo_set_vf_mac,
6726 .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, 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 .ndo_get_vf_config = i40e_ndo_get_vf_config, 6728 .ndo_get_vf_config = i40e_ndo_get_vf_config,
6729 .ndo_set_vf_link_state = i40e_ndo_set_vf_link_state, 6729 .ndo_set_vf_link_state = i40e_ndo_set_vf_link_state,
6730#ifdef CONFIG_I40E_VXLAN 6730#ifdef CONFIG_I40E_VXLAN
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 4d219566a04d..8564b0939dc4 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2205,7 +2205,8 @@ error_pvid:
2205 * 2205 *
2206 * configure vf tx rate 2206 * configure vf tx rate
2207 **/ 2207 **/
2208int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate) 2208int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
2209 int max_tx_rate)
2209{ 2210{
2210 struct i40e_netdev_priv *np = netdev_priv(netdev); 2211 struct i40e_netdev_priv *np = netdev_priv(netdev);
2211 struct i40e_pf *pf = np->vsi->back; 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)
2221 goto error; 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 vf = &(pf->vf[vf_id]); 2231 vf = &(pf->vf[vf_id]);
2225 vsi = pf->vsi[vf->lan_vsi_index]; 2232 vsi = pf->vsi[vf->lan_vsi_index];
2226 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) { 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)
2243 break; 2250 break;
2244 } 2251 }
2245 2252
2246 if (tx_rate > speed) { 2253 if (max_tx_rate > speed) {
2247 dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.", 2254 dev_err(&pf->pdev->dev, "Invalid max tx rate %d specified for vf %d.",
2248 tx_rate, vf->vf_id); 2255 max_tx_rate, vf->vf_id);
2249 ret = -EINVAL; 2256 ret = -EINVAL;
2250 goto error; 2257 goto error;
2251 } 2258 }
2252 2259
2253 /* Tx rate credits are in values of 50Mbps, 0 is disabled*/ 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, 2261 ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, max_tx_rate / 50,
2255 NULL); 2262 0, NULL);
2256 if (ret) { 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 ret); 2265 ret);
2259 ret = -EIO; 2266 ret = -EIO;
2260 goto error; 2267 goto error;
2261 } 2268 }
2262 vf->tx_rate = tx_rate; 2269 vf->tx_rate = max_tx_rate;
2263error: 2270error:
2264 return ret; 2271 return ret;
2265} 2272}
@@ -2301,7 +2308,8 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
2301 2308
2302 memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN); 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 ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK; 2313 ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK;
2306 ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >> 2314 ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >>
2307 I40E_VLAN_PRIORITY_SHIFT; 2315 I40E_VLAN_PRIORITY_SHIFT;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index ba3d1f8414be..5a559be4ba2c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -116,7 +116,8 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf);
116int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); 116int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
117int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, 117int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
118 int vf_id, u16 vlan_id, u8 qos); 118 int vf_id, u16 vlan_id, u8 qos);
119int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate); 119int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
120 int max_tx_rate);
120int i40e_ndo_get_vf_config(struct net_device *netdev, 121int i40e_ndo_get_vf_config(struct net_device *netdev,
121 int vf_id, struct ifla_vf_info *ivi); 122 int vf_id, struct ifla_vf_info *ivi);
122int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link); 123int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index bfcda8a455f4..1075b3f8c415 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -169,7 +169,7 @@ static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
169static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac); 169static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac);
170static int igb_ndo_set_vf_vlan(struct net_device *netdev, 170static int igb_ndo_set_vf_vlan(struct net_device *netdev,
171 int vf, u16 vlan, u8 qos); 171 int vf, u16 vlan, u8 qos);
172static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); 172static int igb_ndo_set_vf_bw(struct net_device *, int, int, int);
173static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, 173static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
174 bool setting); 174 bool setting);
175static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, 175static 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 = {
2084 .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, 2084 .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid,
2085 .ndo_set_vf_mac = igb_ndo_set_vf_mac, 2085 .ndo_set_vf_mac = igb_ndo_set_vf_mac,
2086 .ndo_set_vf_vlan = igb_ndo_set_vf_vlan, 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 .ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk, 2088 .ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk,
2089 .ndo_get_vf_config = igb_ndo_get_vf_config, 2089 .ndo_get_vf_config = igb_ndo_get_vf_config,
2090#ifdef CONFIG_NET_POLL_CONTROLLER 2090#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -7879,7 +7879,8 @@ static void igb_check_vf_rate_limit(struct igb_adapter *adapter)
7879 } 7879 }
7880} 7880}
7881 7881
7882static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) 7882static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf,
7883 int min_tx_rate, int max_tx_rate)
7883{ 7884{
7884 struct igb_adapter *adapter = netdev_priv(netdev); 7885 struct igb_adapter *adapter = netdev_priv(netdev);
7885 struct e1000_hw *hw = &adapter->hw; 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)
7888 if (hw->mac.type != e1000_82576) 7889 if (hw->mac.type != e1000_82576)
7889 return -EOPNOTSUPP; 7890 return -EOPNOTSUPP;
7890 7891
7892 if (min_tx_rate)
7893 return -EINVAL;
7894
7891 actual_link_speed = igb_link_mbps(adapter->link_speed); 7895 actual_link_speed = igb_link_mbps(adapter->link_speed);
7892 if ((vf >= adapter->vfs_allocated_count) || 7896 if ((vf >= adapter->vfs_allocated_count) ||
7893 (!(rd32(E1000_STATUS) & E1000_STATUS_LU)) || 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 return -EINVAL; 7900 return -EINVAL;
7896 7901
7897 adapter->vf_rate_link_speed = actual_link_speed; 7902 adapter->vf_rate_link_speed = actual_link_speed;
7898 adapter->vf_data[vf].tx_rate = (u16)tx_rate; 7903 adapter->vf_data[vf].tx_rate = (u16)max_tx_rate;
7899 igb_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed); 7904 igb_set_vf_rate_limit(hw, vf, max_tx_rate, actual_link_speed);
7900 7905
7901 return 0; 7906 return 0;
7902} 7907}
@@ -7936,7 +7941,8 @@ static int igb_ndo_get_vf_config(struct net_device *netdev,
7936 return -EINVAL; 7941 return -EINVAL;
7937 ivi->vf = vf; 7942 ivi->vf = vf;
7938 memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN); 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 ivi->vlan = adapter->vf_data[vf].pf_vlan; 7946 ivi->vlan = adapter->vf_data[vf].pf_vlan;
7941 ivi->qos = adapter->vf_data[vf].pf_qos; 7947 ivi->qos = adapter->vf_data[vf].pf_qos;
7942 ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled; 7948 ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8089ea9f2fba..a5332389620a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7926,7 +7926,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
7926 .ndo_do_ioctl = ixgbe_ioctl, 7926 .ndo_do_ioctl = ixgbe_ioctl,
7927 .ndo_set_vf_mac = ixgbe_ndo_set_vf_mac, 7927 .ndo_set_vf_mac = ixgbe_ndo_set_vf_mac,
7928 .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, 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 .ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk, 7930 .ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
7931 .ndo_get_vf_config = ixgbe_ndo_get_vf_config, 7931 .ndo_get_vf_config = ixgbe_ndo_get_vf_config,
7932 .ndo_get_stats64 = ixgbe_get_stats64, 7932 .ndo_get_stats64 = ixgbe_get_stats64,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index a01417c06620..3248e208c9dc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1222,7 +1222,8 @@ void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)
1222 } 1222 }
1223} 1223}
1224 1224
1225int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) 1225int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
1226 int max_tx_rate)
1226{ 1227{
1227 struct ixgbe_adapter *adapter = netdev_priv(netdev); 1228 struct ixgbe_adapter *adapter = netdev_priv(netdev);
1228 int link_speed; 1229 int link_speed;
@@ -1240,13 +1241,16 @@ int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
1240 if (link_speed != 10000) 1241 if (link_speed != 10000)
1241 return -EINVAL; 1242 return -EINVAL;
1242 1243
1244 if (min_tx_rate)
1245 return -EINVAL;
1246
1243 /* rate limit cannot be less than 10Mbs or greater than link speed */ 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 return -EINVAL; 1249 return -EINVAL;
1246 1250
1247 /* store values */ 1251 /* store values */
1248 adapter->vf_rate_link_speed = link_speed; 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 /* update hardware configuration */ 1255 /* update hardware configuration */
1252 ixgbe_set_vf_rate_limit(adapter, vf); 1256 ixgbe_set_vf_rate_limit(adapter, vf);
@@ -1288,7 +1292,8 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
1288 return -EINVAL; 1292 return -EINVAL;
1289 ivi->vf = vf; 1293 ivi->vf = vf;
1290 memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); 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 ivi->vlan = adapter->vfinfo[vf].pf_vlan; 1297 ivi->vlan = adapter->vfinfo[vf].pf_vlan;
1293 ivi->qos = adapter->vfinfo[vf].pf_qos; 1298 ivi->qos = adapter->vfinfo[vf].pf_qos;
1294 ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled; 1299 ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index cea640147604..32c26d586c01 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -44,7 +44,8 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
44int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); 44int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
45int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, 45int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
46 u8 qos); 46 u8 qos);
47int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); 47int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
48 int max_tx_rate);
48int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); 49int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
49int ixgbe_ndo_get_vf_config(struct net_device *netdev, 50int ixgbe_ndo_get_vf_config(struct net_device *netdev,
50 int vf, struct ifla_vf_info *ivi); 51 int vf, struct ifla_vf_info *ivi);
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 59c7fd406805..ca8e7cb5a8e4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -2486,11 +2486,12 @@ int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_in
2486 ivf->mac[4] = ((s_info->mac >> (1*8)) & 0xff); 2486 ivf->mac[4] = ((s_info->mac >> (1*8)) & 0xff);
2487 ivf->mac[5] = ((s_info->mac) & 0xff); 2487 ivf->mac[5] = ((s_info->mac) & 0xff);
2488 2488
2489 ivf->vlan = s_info->default_vlan; 2489 ivf->vlan = s_info->default_vlan;
2490 ivf->qos = s_info->default_qos; 2490 ivf->qos = s_info->default_qos;
2491 ivf->tx_rate = s_info->tx_rate; 2491 ivf->max_tx_rate = s_info->tx_rate;
2492 ivf->spoofchk = s_info->spoofchk; 2492 ivf->min_tx_rate = 0;
2493 ivf->linkstate = s_info->link_state; 2493 ivf->spoofchk = s_info->spoofchk;
2494 ivf->linkstate = s_info->link_state;
2494 2495
2495 return 0; 2496 return 0;
2496} 2497}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 6e7527e2b595..41abe6070466 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1319,6 +1319,7 @@ struct qlcnic_eswitch {
1319#define QL_STATUS_INVALID_PARAM -1 1319#define QL_STATUS_INVALID_PARAM -1
1320 1320
1321#define MAX_BW 100 /* % of link speed */ 1321#define MAX_BW 100 /* % of link speed */
1322#define MIN_BW 1 /* % of link speed */
1322#define MAX_VLAN_ID 4095 1323#define MAX_VLAN_ID 4095
1323#define MIN_VLAN_ID 2 1324#define MIN_VLAN_ID 2
1324#define DEFAULT_MAC_LEARN 1 1325#define DEFAULT_MAC_LEARN 1
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index f0a285359e66..f06ba90b4282 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -525,7 +525,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
525#endif 525#endif
526#ifdef CONFIG_QLCNIC_SRIOV 526#ifdef CONFIG_QLCNIC_SRIOV
527 .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, 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 .ndo_get_vf_config = qlcnic_sriov_get_vf_config, 529 .ndo_get_vf_config = qlcnic_sriov_get_vf_config,
530 .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan, 530 .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan,
531 .ndo_set_vf_spoofchk = qlcnic_sriov_set_vf_spoofchk, 531 .ndo_set_vf_spoofchk = qlcnic_sriov_set_vf_spoofchk,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
index 335b50f7bd3e..4677b2edccca 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
@@ -233,7 +233,7 @@ bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *,
233void qlcnic_sriov_pf_reset(struct qlcnic_adapter *); 233void qlcnic_sriov_pf_reset(struct qlcnic_adapter *);
234int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *); 234int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *);
235int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *); 235int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *);
236int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int); 236int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int);
237int qlcnic_sriov_get_vf_config(struct net_device *, int , 237int qlcnic_sriov_get_vf_config(struct net_device *, int ,
238 struct ifla_vf_info *); 238 struct ifla_vf_info *);
239int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8); 239int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 498fa6350c8d..2bdd9deffb38 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -201,6 +201,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
201 sriov->vf_info[i].vp = vp; 201 sriov->vf_info[i].vp = vp;
202 vp->vlan_mode = QLC_GUEST_VLAN_MODE; 202 vp->vlan_mode = QLC_GUEST_VLAN_MODE;
203 vp->max_tx_bw = MAX_BW; 203 vp->max_tx_bw = MAX_BW;
204 vp->min_tx_bw = MIN_BW;
204 vp->spoofchk = false; 205 vp->spoofchk = false;
205 random_ether_addr(vp->mac); 206 random_ether_addr(vp->mac);
206 dev_info(&adapter->pdev->dev, 207 dev_info(&adapter->pdev->dev,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index 6d2f72f114f2..a29538b86edf 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -1848,7 +1848,8 @@ int qlcnic_sriov_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
1848 return 0; 1848 return 0;
1849} 1849}
1850 1850
1851int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate) 1851int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf,
1852 int min_tx_rate, int max_tx_rate)
1852{ 1853{
1853 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1854 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1854 struct qlcnic_sriov *sriov = adapter->ahw->sriov; 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)
1863 if (vf >= sriov->num_vfs) 1864 if (vf >= sriov->num_vfs)
1864 return -EINVAL; 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 netdev_err(netdev, 1876 netdev_err(netdev,
1868 "Invalid Tx rate, allowed range is [%d - %d]", 1877 "Invalid max Tx rate, allowed range is [%d - %d]",
1869 QLC_VF_MIN_TX_RATE, QLC_VF_MAX_TX_RATE); 1878 min_tx_rate, QLC_VF_MAX_TX_RATE);
1870 return -EINVAL; 1879 return -EINVAL;
1871 } 1880 }
1872 1881
1873 if (tx_rate == 0) 1882 if (!max_tx_rate)
1874 tx_rate = 10000; 1883 max_tx_rate = 10000;
1875 1884
1876 vf_info = &sriov->vf_info[vf]; 1885 if (min_tx_rate &&
1877 vp = vf_info->vp; 1886 (min_tx_rate > max_tx_rate || min_tx_rate < QLC_VF_MIN_TX_RATE)) {
1878 vpid = vp->handle; 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 if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) { 1893 if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
1881 if (qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, vpid)) 1894 if (qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, vpid))
1882 return -EIO; 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 nic_info.bit_offsets = BIT_0; 1899 nic_info.bit_offsets = BIT_0;
1886 1900
1887 if (qlcnic_sriov_pf_set_vport_info(adapter, &nic_info, vpid)) 1901 if (qlcnic_sriov_pf_set_vport_info(adapter, &nic_info, vpid))
1888 return -EIO; 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 netdev_info(netdev, 1910 netdev_info(netdev,
1893 "Setting Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n", 1911 "Setting Min Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n",
1894 tx_rate, vp->max_tx_bw, vf); 1912 min_tx_rate, vp->min_tx_bw, vf);
1895 return 0; 1913 return 0;
1896} 1914}
1897 1915
@@ -1990,9 +2008,13 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev,
1990 ivi->qos = vp->qos; 2008 ivi->qos = vp->qos;
1991 ivi->spoofchk = vp->spoofchk; 2009 ivi->spoofchk = vp->spoofchk;
1992 if (vp->max_tx_bw == MAX_BW) 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 else 2016 else
1995 ivi->tx_rate = vp->max_tx_bw * 100; 2017 ivi->min_tx_rate = vp->min_tx_bw * 100;
1996 2018
1997 ivi->vf = vf; 2019 ivi->vf = vf;
1998 return 0; 2020 return 0;
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
index 9a9205e77896..43d2e64546ed 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -1633,7 +1633,8 @@ int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
1633 1633
1634 ivi->vf = vf_i; 1634 ivi->vf = vf_i;
1635 ether_addr_copy(ivi->mac, vf->addr.mac_addr); 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 tci = ntohs(vf->addr.tci); 1638 tci = ntohs(vf->addr.tci);
1638 ivi->vlan = tci & VLAN_VID_MASK; 1639 ivi->vlan = tci & VLAN_VID_MASK;
1639 ivi->qos = (tci >> VLAN_PRIO_SHIFT) & 0x7; 1640 ivi->qos = (tci >> VLAN_PRIO_SHIFT) & 0x7;