diff options
author | Catherine Sullivan <catherine.sullivan@intel.com> | 2014-06-04 04:45:27 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-07-02 22:02:22 -0400 |
commit | 2becc35aa74cbaf9c84e6ae166faab7a321d25ca (patch) | |
tree | 9887a103d7bd6d6fba4b7a3074462fced4508b6f /drivers/net/ethernet/intel/i40e/i40e_ethtool.c | |
parent | c56999f94876b21cf18301076b9687ecdafdc9e5 (diff) |
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>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 6508a1b64a7e..fc86761950d0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c | |||
@@ -457,6 +457,81 @@ static void i40e_get_pauseparam(struct net_device *netdev, | |||
457 | } | 457 | } |
458 | } | 458 | } |
459 | 459 | ||
460 | /** | ||
461 | * i40e_set_pauseparam - Set Flow Control parameter | ||
462 | * @netdev: network interface device structure | ||
463 | * @pause: return tx/rx flow control status | ||
464 | **/ | ||
465 | static int i40e_set_pauseparam(struct net_device *netdev, | ||
466 | struct ethtool_pauseparam *pause) | ||
467 | { | ||
468 | struct i40e_netdev_priv *np = netdev_priv(netdev); | ||
469 | struct i40e_pf *pf = np->vsi->back; | ||
470 | struct i40e_vsi *vsi = np->vsi; | ||
471 | struct i40e_hw *hw = &pf->hw; | ||
472 | struct i40e_link_status *hw_link_info = &hw->phy.link_info; | ||
473 | bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP; | ||
474 | i40e_status status; | ||
475 | u8 aq_failures; | ||
476 | int err; | ||
477 | |||
478 | if (vsi != pf->vsi[pf->lan_vsi]) | ||
479 | return -EOPNOTSUPP; | ||
480 | |||
481 | if (pause->autoneg != ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ? | ||
482 | AUTONEG_ENABLE : AUTONEG_DISABLE)) { | ||
483 | netdev_info(netdev, "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n"); | ||
484 | return -EOPNOTSUPP; | ||
485 | } | ||
486 | |||
487 | /* If we have link and don't have autoneg */ | ||
488 | if (!test_bit(__I40E_DOWN, &pf->state) && | ||
489 | !(hw_link_info->an_info & I40E_AQ_AN_COMPLETED)) { | ||
490 | /* Send message that it might not necessarily work*/ | ||
491 | netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n"); | ||
492 | } | ||
493 | |||
494 | if (hw->fc.current_mode == I40E_FC_PFC) { | ||
495 | netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n"); | ||
496 | return -EOPNOTSUPP; | ||
497 | } | ||
498 | |||
499 | if (pause->rx_pause && pause->tx_pause) | ||
500 | hw->fc.requested_mode = I40E_FC_FULL; | ||
501 | else if (pause->rx_pause && !pause->tx_pause) | ||
502 | hw->fc.requested_mode = I40E_FC_RX_PAUSE; | ||
503 | else if (!pause->rx_pause && pause->tx_pause) | ||
504 | hw->fc.requested_mode = I40E_FC_TX_PAUSE; | ||
505 | else if (!pause->rx_pause && !pause->tx_pause) | ||
506 | hw->fc.requested_mode = I40E_FC_NONE; | ||
507 | else | ||
508 | return -EINVAL; | ||
509 | |||
510 | /* Set the fc mode and only restart an if link is up*/ | ||
511 | status = i40e_set_fc(hw, &aq_failures, link_up); | ||
512 | |||
513 | if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) { | ||
514 | netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with error %d and status %d\n", | ||
515 | status, hw->aq.asq_last_status); | ||
516 | err = -EAGAIN; | ||
517 | } | ||
518 | if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) { | ||
519 | netdev_info(netdev, "Set fc failed on the set_phy_config call with error %d and status %d\n", | ||
520 | status, hw->aq.asq_last_status); | ||
521 | err = -EAGAIN; | ||
522 | } | ||
523 | if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) { | ||
524 | netdev_info(netdev, "Set fc failed on the update_link_info call with error %d and status %d\n", | ||
525 | status, hw->aq.asq_last_status); | ||
526 | err = -EAGAIN; | ||
527 | } | ||
528 | |||
529 | if (!test_bit(__I40E_DOWN, &pf->state)) | ||
530 | return i40e_nway_reset(netdev); | ||
531 | |||
532 | return err; | ||
533 | } | ||
534 | |||
460 | static u32 i40e_get_msglevel(struct net_device *netdev) | 535 | static u32 i40e_get_msglevel(struct net_device *netdev) |
461 | { | 536 | { |
462 | struct i40e_netdev_priv *np = netdev_priv(netdev); | 537 | struct i40e_netdev_priv *np = netdev_priv(netdev); |
@@ -1866,6 +1941,7 @@ static const struct ethtool_ops i40e_ethtool_ops = { | |||
1866 | .get_ringparam = i40e_get_ringparam, | 1941 | .get_ringparam = i40e_get_ringparam, |
1867 | .set_ringparam = i40e_set_ringparam, | 1942 | .set_ringparam = i40e_set_ringparam, |
1868 | .get_pauseparam = i40e_get_pauseparam, | 1943 | .get_pauseparam = i40e_get_pauseparam, |
1944 | .set_pauseparam = i40e_set_pauseparam, | ||
1869 | .get_msglevel = i40e_get_msglevel, | 1945 | .get_msglevel = i40e_get_msglevel, |
1870 | .set_msglevel = i40e_set_msglevel, | 1946 | .set_msglevel = i40e_set_msglevel, |
1871 | .get_rxnfc = i40e_get_rxnfc, | 1947 | .get_rxnfc = i40e_get_rxnfc, |