aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorAkeem G. Abodunrin <akeem.g.abodunrin@intel.com>2012-11-12 23:03:25 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-13 14:18:15 -0500
commit24a372cd0b87c15f8d98275d045326249155af55 (patch)
tree61e0c62e05903e3abff13a2ffdfc9415470c620b /drivers/net/ethernet/intel
parent80d0759e5e714cb738c50d32edf3364b713453ff (diff)
igb: Ethtool support to enable and disable EEE
This patch allows users to enable and disable EEE using Ethtool. It also allows users to get EEE settings, as supported by the device. Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c100
2 files changed, 101 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index e647cff9a5e3..198d14848820 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -874,6 +874,7 @@
874#define E1000_EEER_FRC_AN 0x10000000 /* Enable EEE in loopback */ 874#define E1000_EEER_FRC_AN 0x10000000 /* Enable EEE in loopback */
875#define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */ 875#define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */
876#define E1000_EEE_SU_LPI_CLK_STP 0X00800000 /* EEE LPI Clock Stop */ 876#define E1000_EEE_SU_LPI_CLK_STP 0X00800000 /* EEE LPI Clock Stop */
877#define E1000_EEER_EEE_NEG 0x20000000 /* EEE capability nego */
877 878
878/* SerDes Control */ 879/* SerDes Control */
879#define E1000_GEN_CTL_READY 0x80000000 880#define E1000_GEN_CTL_READY 0x80000000
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 2b82a53f4ab3..0acf590d4a83 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -2529,6 +2529,104 @@ static int igb_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
2529 return ret; 2529 return ret;
2530} 2530}
2531 2531
2532static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
2533{
2534 struct igb_adapter *adapter = netdev_priv(netdev);
2535 struct e1000_hw *hw = &adapter->hw;
2536 u32 ipcnfg, eeer;
2537
2538 if ((hw->mac.type < e1000_i350) ||
2539 (hw->phy.media_type != e1000_media_type_copper))
2540 return -EOPNOTSUPP;
2541
2542 edata->supported = (SUPPORTED_1000baseT_Full |
2543 SUPPORTED_100baseT_Full);
2544
2545 ipcnfg = rd32(E1000_IPCNFG);
2546 eeer = rd32(E1000_EEER);
2547
2548 /* EEE status on negotiated link */
2549 if (ipcnfg & E1000_IPCNFG_EEE_1G_AN)
2550 edata->advertised = ADVERTISED_1000baseT_Full;
2551
2552 if (ipcnfg & E1000_IPCNFG_EEE_100M_AN)
2553 edata->advertised |= ADVERTISED_100baseT_Full;
2554
2555 if (eeer & E1000_EEER_EEE_NEG)
2556 edata->eee_active = true;
2557
2558 edata->eee_enabled = !hw->dev_spec._82575.eee_disable;
2559
2560 if (eeer & E1000_EEER_TX_LPI_EN)
2561 edata->tx_lpi_enabled = true;
2562
2563 /* Report correct negotiated EEE status for devices that
2564 * wrongly report EEE at half-duplex
2565 */
2566 if (adapter->link_duplex == HALF_DUPLEX) {
2567 edata->eee_enabled = false;
2568 edata->eee_active = false;
2569 edata->tx_lpi_enabled = false;
2570 edata->advertised &= ~edata->advertised;
2571 }
2572
2573 return 0;
2574}
2575
2576static int igb_set_eee(struct net_device *netdev,
2577 struct ethtool_eee *edata)
2578{
2579 struct igb_adapter *adapter = netdev_priv(netdev);
2580 struct e1000_hw *hw = &adapter->hw;
2581 struct ethtool_eee eee_curr;
2582 s32 ret_val;
2583
2584 if ((hw->mac.type < e1000_i350) ||
2585 (hw->phy.media_type != e1000_media_type_copper))
2586 return -EOPNOTSUPP;
2587
2588 ret_val = igb_get_eee(netdev, &eee_curr);
2589 if (ret_val)
2590 return ret_val;
2591
2592 if (eee_curr.eee_enabled) {
2593 if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
2594 dev_err(&adapter->pdev->dev,
2595 "Setting EEE tx-lpi is not supported\n");
2596 return -EINVAL;
2597 }
2598
2599 /* Tx LPI timer is not implemented currently */
2600 if (edata->tx_lpi_timer) {
2601 dev_err(&adapter->pdev->dev,
2602 "Setting EEE Tx LPI timer is not supported\n");
2603 return -EINVAL;
2604 }
2605
2606 if (eee_curr.advertised != edata->advertised) {
2607 dev_err(&adapter->pdev->dev,
2608 "Setting EEE Advertisement is not supported\n");
2609 return -EINVAL;
2610 }
2611
2612 } else if (!edata->eee_enabled) {
2613 dev_err(&adapter->pdev->dev,
2614 "Setting EEE options are not supported with EEE disabled\n");
2615 return -EINVAL;
2616 }
2617
2618 if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) {
2619 hw->dev_spec._82575.eee_disable = !edata->eee_enabled;
2620 igb_set_eee_i350(hw);
2621
2622 /* reset link */
2623 if (!netif_running(netdev))
2624 igb_reset(adapter);
2625 }
2626
2627 return 0;
2628}
2629
2532static int igb_ethtool_begin(struct net_device *netdev) 2630static int igb_ethtool_begin(struct net_device *netdev)
2533{ 2631{
2534 struct igb_adapter *adapter = netdev_priv(netdev); 2632 struct igb_adapter *adapter = netdev_priv(netdev);
@@ -2571,6 +2669,8 @@ static const struct ethtool_ops igb_ethtool_ops = {
2571 .get_ts_info = igb_get_ts_info, 2669 .get_ts_info = igb_get_ts_info,
2572 .get_rxnfc = igb_get_rxnfc, 2670 .get_rxnfc = igb_get_rxnfc,
2573 .set_rxnfc = igb_set_rxnfc, 2671 .set_rxnfc = igb_set_rxnfc,
2672 .get_eee = igb_get_eee,
2673 .set_eee = igb_set_eee,
2574 .begin = igb_ethtool_begin, 2674 .begin = igb_ethtool_begin,
2575 .complete = igb_ethtool_complete, 2675 .complete = igb_ethtool_complete,
2576}; 2676};