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>
This commit is contained in:

committed by
David S. Miller

parent
307f099520
commit
ed616689a3
@@ -6724,7 +6724,7 @@ static const struct net_device_ops i40e_netdev_ops = {
|
||||
.ndo_set_features = i40e_set_features,
|
||||
.ndo_set_vf_mac = i40e_ndo_set_vf_mac,
|
||||
.ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan,
|
||||
.ndo_set_vf_tx_rate = i40e_ndo_set_vf_bw,
|
||||
.ndo_set_vf_rate = i40e_ndo_set_vf_bw,
|
||||
.ndo_get_vf_config = i40e_ndo_get_vf_config,
|
||||
.ndo_set_vf_link_state = i40e_ndo_set_vf_link_state,
|
||||
#ifdef CONFIG_I40E_VXLAN
|
||||
|
@@ -2205,7 +2205,8 @@ error_pvid:
|
||||
*
|
||||
* configure vf tx rate
|
||||
**/
|
||||
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate)
|
||||
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
|
||||
int max_tx_rate)
|
||||
{
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
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)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (min_tx_rate) {
|
||||
dev_err(&pf->pdev->dev, "Invalid min tx rate (%d) (greater than 0) specified for vf %d.\n",
|
||||
min_tx_rate, vf_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vf = &(pf->vf[vf_id]);
|
||||
vsi = pf->vsi[vf->lan_vsi_index];
|
||||
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)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx_rate > speed) {
|
||||
dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.",
|
||||
tx_rate, vf->vf_id);
|
||||
if (max_tx_rate > speed) {
|
||||
dev_err(&pf->pdev->dev, "Invalid max tx rate %d specified for vf %d.",
|
||||
max_tx_rate, vf->vf_id);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Tx rate credits are in values of 50Mbps, 0 is disabled*/
|
||||
ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, tx_rate / 50, 0,
|
||||
NULL);
|
||||
ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, max_tx_rate / 50,
|
||||
0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&pf->pdev->dev, "Unable to set tx rate, error code %d.\n",
|
||||
dev_err(&pf->pdev->dev, "Unable to set max tx rate, error code %d.\n",
|
||||
ret);
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
}
|
||||
vf->tx_rate = tx_rate;
|
||||
vf->tx_rate = max_tx_rate;
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
@@ -2301,7 +2308,8 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
|
||||
|
||||
memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN);
|
||||
|
||||
ivi->tx_rate = vf->tx_rate;
|
||||
ivi->max_tx_rate = vf->tx_rate;
|
||||
ivi->min_tx_rate = 0;
|
||||
ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK;
|
||||
ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >>
|
||||
I40E_VLAN_PRIORITY_SHIFT;
|
||||
|
@@ -116,7 +116,8 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf);
|
||||
int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
|
||||
int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
|
||||
int vf_id, u16 vlan_id, u8 qos);
|
||||
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate);
|
||||
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
|
||||
int max_tx_rate);
|
||||
int i40e_ndo_get_vf_config(struct net_device *netdev,
|
||||
int vf_id, struct ifla_vf_info *ivi);
|
||||
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);
|
||||
static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac);
|
||||
static int igb_ndo_set_vf_vlan(struct net_device *netdev,
|
||||
int vf, u16 vlan, u8 qos);
|
||||
static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
|
||||
static int igb_ndo_set_vf_bw(struct net_device *, int, int, int);
|
||||
static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
|
||||
bool setting);
|
||||
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 = {
|
||||
.ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid,
|
||||
.ndo_set_vf_mac = igb_ndo_set_vf_mac,
|
||||
.ndo_set_vf_vlan = igb_ndo_set_vf_vlan,
|
||||
.ndo_set_vf_tx_rate = igb_ndo_set_vf_bw,
|
||||
.ndo_set_vf_rate = igb_ndo_set_vf_bw,
|
||||
.ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk,
|
||||
.ndo_get_vf_config = igb_ndo_get_vf_config,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
@@ -7879,7 +7879,8 @@ static void igb_check_vf_rate_limit(struct igb_adapter *adapter)
|
||||
}
|
||||
}
|
||||
|
||||
static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
|
||||
static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf,
|
||||
int min_tx_rate, int max_tx_rate)
|
||||
{
|
||||
struct igb_adapter *adapter = netdev_priv(netdev);
|
||||
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)
|
||||
if (hw->mac.type != e1000_82576)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (min_tx_rate)
|
||||
return -EINVAL;
|
||||
|
||||
actual_link_speed = igb_link_mbps(adapter->link_speed);
|
||||
if ((vf >= adapter->vfs_allocated_count) ||
|
||||
(!(rd32(E1000_STATUS) & E1000_STATUS_LU)) ||
|
||||
(tx_rate < 0) || (tx_rate > actual_link_speed))
|
||||
(max_tx_rate < 0) ||
|
||||
(max_tx_rate > actual_link_speed))
|
||||
return -EINVAL;
|
||||
|
||||
adapter->vf_rate_link_speed = actual_link_speed;
|
||||
adapter->vf_data[vf].tx_rate = (u16)tx_rate;
|
||||
igb_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed);
|
||||
adapter->vf_data[vf].tx_rate = (u16)max_tx_rate;
|
||||
igb_set_vf_rate_limit(hw, vf, max_tx_rate, actual_link_speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -7936,7 +7941,8 @@ static int igb_ndo_get_vf_config(struct net_device *netdev,
|
||||
return -EINVAL;
|
||||
ivi->vf = vf;
|
||||
memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN);
|
||||
ivi->tx_rate = adapter->vf_data[vf].tx_rate;
|
||||
ivi->max_tx_rate = adapter->vf_data[vf].tx_rate;
|
||||
ivi->min_tx_rate = 0;
|
||||
ivi->vlan = adapter->vf_data[vf].pf_vlan;
|
||||
ivi->qos = adapter->vf_data[vf].pf_qos;
|
||||
ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled;
|
||||
|
@@ -7926,7 +7926,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
|
||||
.ndo_do_ioctl = ixgbe_ioctl,
|
||||
.ndo_set_vf_mac = ixgbe_ndo_set_vf_mac,
|
||||
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
|
||||
.ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw,
|
||||
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
|
||||
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
|
||||
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
|
||||
.ndo_get_stats64 = ixgbe_get_stats64,
|
||||
|
@@ -1222,7 +1222,8 @@ void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)
|
||||
}
|
||||
}
|
||||
|
||||
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
|
||||
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
|
||||
int max_tx_rate)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = netdev_priv(netdev);
|
||||
int link_speed;
|
||||
@@ -1240,13 +1241,16 @@ int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
|
||||
if (link_speed != 10000)
|
||||
return -EINVAL;
|
||||
|
||||
if (min_tx_rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* rate limit cannot be less than 10Mbs or greater than link speed */
|
||||
if (tx_rate && ((tx_rate <= 10) || (tx_rate > link_speed)))
|
||||
if (max_tx_rate && ((max_tx_rate <= 10) || (max_tx_rate > link_speed)))
|
||||
return -EINVAL;
|
||||
|
||||
/* store values */
|
||||
adapter->vf_rate_link_speed = link_speed;
|
||||
adapter->vfinfo[vf].tx_rate = tx_rate;
|
||||
adapter->vfinfo[vf].tx_rate = max_tx_rate;
|
||||
|
||||
/* update hardware configuration */
|
||||
ixgbe_set_vf_rate_limit(adapter, vf);
|
||||
@@ -1288,7 +1292,8 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
|
||||
return -EINVAL;
|
||||
ivi->vf = vf;
|
||||
memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);
|
||||
ivi->tx_rate = adapter->vfinfo[vf].tx_rate;
|
||||
ivi->max_tx_rate = adapter->vfinfo[vf].tx_rate;
|
||||
ivi->min_tx_rate = 0;
|
||||
ivi->vlan = adapter->vfinfo[vf].pf_vlan;
|
||||
ivi->qos = adapter->vfinfo[vf].pf_qos;
|
||||
ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled;
|
||||
|
@@ -44,7 +44,8 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
|
||||
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
|
||||
int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
|
||||
u8 qos);
|
||||
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
|
||||
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
|
||||
int max_tx_rate);
|
||||
int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
|
||||
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
|
||||
int vf, struct ifla_vf_info *ivi);
|
||||
|
Reference in New Issue
Block a user