i40e: Add set_pauseparam to ethtool
Add i40e implementation of setpauseparam to ethtool. Change-ID: Ie7766b2091ec8f934737573c9ffd426081966718 Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com> Tested-by: Jim Young <jamesx.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
c56999f948
commit
2becc35aa7
|
@ -457,6 +457,81 @@ static void i40e_get_pauseparam(struct net_device *netdev,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_set_pauseparam - Set Flow Control parameter
|
||||
* @netdev: network interface device structure
|
||||
* @pause: return tx/rx flow control status
|
||||
**/
|
||||
static int i40e_set_pauseparam(struct net_device *netdev,
|
||||
struct ethtool_pauseparam *pause)
|
||||
{
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
struct i40e_pf *pf = np->vsi->back;
|
||||
struct i40e_vsi *vsi = np->vsi;
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
struct i40e_link_status *hw_link_info = &hw->phy.link_info;
|
||||
bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
|
||||
i40e_status status;
|
||||
u8 aq_failures;
|
||||
int err;
|
||||
|
||||
if (vsi != pf->vsi[pf->lan_vsi])
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (pause->autoneg != ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
|
||||
AUTONEG_ENABLE : AUTONEG_DISABLE)) {
|
||||
netdev_info(netdev, "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* If we have link and don't have autoneg */
|
||||
if (!test_bit(__I40E_DOWN, &pf->state) &&
|
||||
!(hw_link_info->an_info & I40E_AQ_AN_COMPLETED)) {
|
||||
/* Send message that it might not necessarily work*/
|
||||
netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n");
|
||||
}
|
||||
|
||||
if (hw->fc.current_mode == I40E_FC_PFC) {
|
||||
netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (pause->rx_pause && pause->tx_pause)
|
||||
hw->fc.requested_mode = I40E_FC_FULL;
|
||||
else if (pause->rx_pause && !pause->tx_pause)
|
||||
hw->fc.requested_mode = I40E_FC_RX_PAUSE;
|
||||
else if (!pause->rx_pause && pause->tx_pause)
|
||||
hw->fc.requested_mode = I40E_FC_TX_PAUSE;
|
||||
else if (!pause->rx_pause && !pause->tx_pause)
|
||||
hw->fc.requested_mode = I40E_FC_NONE;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
/* Set the fc mode and only restart an if link is up*/
|
||||
status = i40e_set_fc(hw, &aq_failures, link_up);
|
||||
|
||||
if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) {
|
||||
netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with error %d and status %d\n",
|
||||
status, hw->aq.asq_last_status);
|
||||
err = -EAGAIN;
|
||||
}
|
||||
if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) {
|
||||
netdev_info(netdev, "Set fc failed on the set_phy_config call with error %d and status %d\n",
|
||||
status, hw->aq.asq_last_status);
|
||||
err = -EAGAIN;
|
||||
}
|
||||
if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) {
|
||||
netdev_info(netdev, "Set fc failed on the update_link_info call with error %d and status %d\n",
|
||||
status, hw->aq.asq_last_status);
|
||||
err = -EAGAIN;
|
||||
}
|
||||
|
||||
if (!test_bit(__I40E_DOWN, &pf->state))
|
||||
return i40e_nway_reset(netdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32 i40e_get_msglevel(struct net_device *netdev)
|
||||
{
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
|
@ -1866,6 +1941,7 @@ static const struct ethtool_ops i40e_ethtool_ops = {
|
|||
.get_ringparam = i40e_get_ringparam,
|
||||
.set_ringparam = i40e_set_ringparam,
|
||||
.get_pauseparam = i40e_get_pauseparam,
|
||||
.set_pauseparam = i40e_set_pauseparam,
|
||||
.get_msglevel = i40e_get_msglevel,
|
||||
.set_msglevel = i40e_set_msglevel,
|
||||
.get_rxnfc = i40e_get_rxnfc,
|
||||
|
|
Loading…
Reference in New Issue