i40e: Enable VF Tx bandwidth setting

Implement the net device op for Tx bandwidth setting. Setting the Tx
bandwidth is done by 'ip link set <PF device> vf <VF num> rate <Tx
rate>', with the rate specified in Mbit/sec. The rate setting is
displayed with 'ip link show'.

Change-ID: I4d45dda8320632fdb6ec92c87d083e51070b46ab
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Acked-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Mitch Williams 2014-03-06 09:02:29 +00:00 committed by Jeff Kirsher
parent f9b4b6278d
commit 6b192891b8
4 changed files with 98 additions and 2 deletions

View File

@ -2252,6 +2252,35 @@ static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
return status;
}
/**
* i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
* @hw: pointer to the hw struct
* @seid: VSI seid
* @credit: BW limit credits (0 = disabled)
* @max_credit: Max BW limit credits
* @cmd_details: pointer to command details structure or NULL
**/
i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
u16 seid, u16 credit, u8 max_credit,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_configure_vsi_bw_limit *cmd =
(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
i40e_status status;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_configure_vsi_bw_limit);
cmd->vsi_seid = cpu_to_le16(seid);
cmd->credit = cpu_to_le16(credit);
cmd->max_credit = max_credit;
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status;
}
/**
* i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
* @hw: pointer to the hw struct

View File

@ -167,6 +167,9 @@ i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
u16 flags, u8 *mac_addr,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
u16 seid, u16 credit, u8 max_credit,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_hmc_resource_profile(struct i40e_hw *hw,

View File

@ -434,6 +434,15 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
if (ret)
dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
/* Set VF bandwidth if specified */
if (vf->tx_rate) {
ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid,
vf->tx_rate / 50, 0, NULL);
if (ret)
dev_err(&pf->pdev->dev, "Unable to set tx rate, VF %d, error code %d.\n",
vf->vf_id, ret);
}
error_alloc_vsi_res:
return ret;
}
@ -2184,7 +2193,61 @@ error_pvid:
**/
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate)
{
return -EOPNOTSUPP;
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
struct i40e_vsi *vsi;
struct i40e_vf *vf;
int speed = 0;
int ret = 0;
/* validate the request */
if (vf_id >= pf->num_alloc_vfs) {
dev_err(&pf->pdev->dev, "Invalid VF Identifier %d.\n", vf_id);
ret = -EINVAL;
goto error;
}
vf = &(pf->vf[vf_id]);
vsi = pf->vsi[vf->lan_vsi_index];
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev, "Uninitialized VF %d.\n", vf_id);
ret = -EINVAL;
goto error;
}
switch (pf->hw.phy.link_info.link_speed) {
case I40E_LINK_SPEED_40GB:
speed = 40000;
break;
case I40E_LINK_SPEED_10GB:
speed = 10000;
break;
case I40E_LINK_SPEED_1GB:
speed = 1000;
break;
default:
break;
}
if (tx_rate > speed) {
dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.",
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);
if (ret) {
dev_err(&pf->pdev->dev, "Unable to set tx rate, error code %d.\n",
ret);
ret = -EIO;
goto error;
}
vf->tx_rate = tx_rate;
error:
return ret;
}
/**
@ -2224,7 +2287,7 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN);
ivi->tx_rate = 0;
ivi->tx_rate = vf->tx_rate;
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;

View File

@ -98,6 +98,7 @@ struct i40e_vf {
unsigned long vf_caps; /* vf's adv. capabilities */
unsigned long vf_states; /* vf's runtime states */
unsigned int tx_rate; /* Tx bandwidth limit in Mbps */
bool link_forced;
bool link_up; /* only valid if vf link is forced */
};