mirror of https://gitee.com/openkylin/linux.git
igb: Fix for devices using ethtool for EEE settings
This patch fixes a problem where using ethtool for EEE setting was not working correctly. This patch also fixes a problem where the function that checks for EEE status on i354 devices was not being called and was causing warnings with static analysis tools. Reported-by: Rashika Kheria <rashika.kheria@gmail.com> Reported-by: Josh Triplett <josh@joshtriplett.org> Reported-by: Stephen Hemminger <stephen@networkplumber.org> Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
42bdf083fe
commit
f4c01e965f
|
@ -265,6 +265,7 @@ u16 igb_rxpbs_adjust_82580(u32 data);
|
||||||
s32 igb_read_emi_reg(struct e1000_hw *, u16 addr, u16 *data);
|
s32 igb_read_emi_reg(struct e1000_hw *, u16 addr, u16 *data);
|
||||||
s32 igb_set_eee_i350(struct e1000_hw *);
|
s32 igb_set_eee_i350(struct e1000_hw *);
|
||||||
s32 igb_set_eee_i354(struct e1000_hw *);
|
s32 igb_set_eee_i354(struct e1000_hw *);
|
||||||
|
s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status);
|
||||||
|
|
||||||
#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
|
#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
|
||||||
#define E1000_EMC_INTERNAL_DATA 0x00
|
#define E1000_EMC_INTERNAL_DATA 0x00
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/i2c-algo-bit.h>
|
#include <linux/i2c-algo-bit.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
#include <linux/mdio.h>
|
||||||
|
|
||||||
struct igb_adapter;
|
struct igb_adapter;
|
||||||
|
|
||||||
|
@ -455,6 +456,7 @@ struct igb_adapter {
|
||||||
unsigned long link_check_timeout;
|
unsigned long link_check_timeout;
|
||||||
int copper_tries;
|
int copper_tries;
|
||||||
struct e1000_info ei;
|
struct e1000_info ei;
|
||||||
|
u16 eee_advert;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IGB_FLAG_HAS_MSI (1 << 0)
|
#define IGB_FLAG_HAS_MSI (1 << 0)
|
||||||
|
@ -471,6 +473,7 @@ struct igb_adapter {
|
||||||
#define IGB_FLAG_MAS_CAPABLE (1 << 11)
|
#define IGB_FLAG_MAS_CAPABLE (1 << 11)
|
||||||
#define IGB_FLAG_MAS_ENABLE (1 << 12)
|
#define IGB_FLAG_MAS_ENABLE (1 << 12)
|
||||||
#define IGB_FLAG_HAS_MSIX (1 << 13)
|
#define IGB_FLAG_HAS_MSIX (1 << 13)
|
||||||
|
#define IGB_FLAG_EEE (1 << 14)
|
||||||
|
|
||||||
/* Media Auto Sense */
|
/* Media Auto Sense */
|
||||||
#define IGB_MAS_ENABLE_0 0X0001
|
#define IGB_MAS_ENABLE_0 0X0001
|
||||||
|
|
|
@ -2587,7 +2587,7 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
||||||
{
|
{
|
||||||
struct igb_adapter *adapter = netdev_priv(netdev);
|
struct igb_adapter *adapter = netdev_priv(netdev);
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
u32 ipcnfg, eeer, ret_val;
|
u32 ret_val;
|
||||||
u16 phy_data;
|
u16 phy_data;
|
||||||
|
|
||||||
if ((hw->mac.type < e1000_i350) ||
|
if ((hw->mac.type < e1000_i350) ||
|
||||||
|
@ -2596,16 +2596,25 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
||||||
|
|
||||||
edata->supported = (SUPPORTED_1000baseT_Full |
|
edata->supported = (SUPPORTED_1000baseT_Full |
|
||||||
SUPPORTED_100baseT_Full);
|
SUPPORTED_100baseT_Full);
|
||||||
|
if (!hw->dev_spec._82575.eee_disable)
|
||||||
|
edata->advertised =
|
||||||
|
mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);
|
||||||
|
|
||||||
|
/* The IPCNFG and EEER registers are not supported on I354. */
|
||||||
|
if (hw->mac.type == e1000_i354) {
|
||||||
|
igb_get_eee_status_i354(hw, (bool *)&edata->eee_active);
|
||||||
|
} else {
|
||||||
|
u32 eeer;
|
||||||
|
|
||||||
ipcnfg = rd32(E1000_IPCNFG);
|
|
||||||
eeer = rd32(E1000_EEER);
|
eeer = rd32(E1000_EEER);
|
||||||
|
|
||||||
/* EEE status on negotiated link */
|
/* EEE status on negotiated link */
|
||||||
if (ipcnfg & E1000_IPCNFG_EEE_1G_AN)
|
if (eeer & E1000_EEER_EEE_NEG)
|
||||||
edata->advertised = ADVERTISED_1000baseT_Full;
|
edata->eee_active = true;
|
||||||
|
|
||||||
if (ipcnfg & E1000_IPCNFG_EEE_100M_AN)
|
if (eeer & E1000_EEER_TX_LPI_EN)
|
||||||
edata->advertised |= ADVERTISED_100baseT_Full;
|
edata->tx_lpi_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* EEE Link Partner Advertised */
|
/* EEE Link Partner Advertised */
|
||||||
switch (hw->mac.type) {
|
switch (hw->mac.type) {
|
||||||
|
@ -2616,8 +2625,8 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
|
edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case e1000_i354:
|
||||||
case e1000_i210:
|
case e1000_i210:
|
||||||
case e1000_i211:
|
case e1000_i211:
|
||||||
ret_val = igb_read_xmdio_reg(hw, E1000_EEE_LP_ADV_ADDR_I210,
|
ret_val = igb_read_xmdio_reg(hw, E1000_EEE_LP_ADV_ADDR_I210,
|
||||||
|
@ -2633,12 +2642,10 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eeer & E1000_EEER_EEE_NEG)
|
|
||||||
edata->eee_active = true;
|
|
||||||
|
|
||||||
edata->eee_enabled = !hw->dev_spec._82575.eee_disable;
|
edata->eee_enabled = !hw->dev_spec._82575.eee_disable;
|
||||||
|
|
||||||
if (eeer & E1000_EEER_TX_LPI_EN)
|
if ((hw->mac.type == e1000_i354) &&
|
||||||
|
(edata->eee_enabled))
|
||||||
edata->tx_lpi_enabled = true;
|
edata->tx_lpi_enabled = true;
|
||||||
|
|
||||||
/* Report correct negotiated EEE status for devices that
|
/* Report correct negotiated EEE status for devices that
|
||||||
|
@ -2686,9 +2693,10 @@ static int igb_set_eee(struct net_device *netdev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eee_curr.advertised != edata->advertised) {
|
if (edata->advertised &
|
||||||
|
~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
|
||||||
dev_err(&adapter->pdev->dev,
|
dev_err(&adapter->pdev->dev,
|
||||||
"Setting EEE Advertisement is not supported\n");
|
"EEE Advertisement supports only 100Tx and or 100T full duplex\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2698,9 +2706,14 @@ static int igb_set_eee(struct net_device *netdev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
|
||||||
if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) {
|
if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) {
|
||||||
hw->dev_spec._82575.eee_disable = !edata->eee_enabled;
|
hw->dev_spec._82575.eee_disable = !edata->eee_enabled;
|
||||||
|
adapter->flags |= IGB_FLAG_EEE;
|
||||||
|
if (hw->mac.type == e1000_i350)
|
||||||
igb_set_eee_i350(hw);
|
igb_set_eee_i350(hw);
|
||||||
|
else
|
||||||
|
igb_set_eee_i354(hw);
|
||||||
|
|
||||||
/* reset link */
|
/* reset link */
|
||||||
if (netif_running(netdev))
|
if (netif_running(netdev))
|
||||||
|
|
|
@ -1726,6 +1726,10 @@ int igb_up(struct igb_adapter *adapter)
|
||||||
hw->mac.get_link_status = 1;
|
hw->mac.get_link_status = 1;
|
||||||
schedule_work(&adapter->watchdog_task);
|
schedule_work(&adapter->watchdog_task);
|
||||||
|
|
||||||
|
if ((adapter->flags & IGB_FLAG_EEE) &&
|
||||||
|
(!hw->dev_spec._82575.eee_disable))
|
||||||
|
adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1974,6 +1978,21 @@ void igb_reset(struct igb_adapter *adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/*Re-establish EEE setting */
|
||||||
|
if (hw->phy.media_type == e1000_media_type_copper) {
|
||||||
|
switch (mac->type) {
|
||||||
|
case e1000_i350:
|
||||||
|
case e1000_i210:
|
||||||
|
case e1000_i211:
|
||||||
|
igb_set_eee_i350(hw);
|
||||||
|
break;
|
||||||
|
case e1000_i354:
|
||||||
|
igb_set_eee_i354(hw);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!netif_running(adapter->netdev))
|
if (!netif_running(adapter->netdev))
|
||||||
igb_power_down_link(adapter);
|
igb_power_down_link(adapter);
|
||||||
|
|
||||||
|
@ -2560,23 +2579,36 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
(adapter->flags & IGB_FLAG_HAS_MSIX) ? "MSI-X" :
|
(adapter->flags & IGB_FLAG_HAS_MSIX) ? "MSI-X" :
|
||||||
(adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
|
(adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
|
||||||
adapter->num_rx_queues, adapter->num_tx_queues);
|
adapter->num_rx_queues, adapter->num_tx_queues);
|
||||||
|
if (hw->phy.media_type == e1000_media_type_copper) {
|
||||||
switch (hw->mac.type) {
|
switch (hw->mac.type) {
|
||||||
case e1000_i350:
|
case e1000_i350:
|
||||||
case e1000_i210:
|
case e1000_i210:
|
||||||
case e1000_i211:
|
case e1000_i211:
|
||||||
igb_set_eee_i350(hw);
|
/* Enable EEE for internal copper PHY devices */
|
||||||
|
err = igb_set_eee_i350(hw);
|
||||||
|
if ((!err) &&
|
||||||
|
(!hw->dev_spec._82575.eee_disable)) {
|
||||||
|
adapter->eee_advert =
|
||||||
|
MDIO_EEE_100TX | MDIO_EEE_1000T;
|
||||||
|
adapter->flags |= IGB_FLAG_EEE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case e1000_i354:
|
case e1000_i354:
|
||||||
if (hw->phy.media_type == e1000_media_type_copper) {
|
|
||||||
if ((rd32(E1000_CTRL_EXT) &
|
if ((rd32(E1000_CTRL_EXT) &
|
||||||
E1000_CTRL_EXT_LINK_MODE_SGMII))
|
E1000_CTRL_EXT_LINK_MODE_SGMII)) {
|
||||||
igb_set_eee_i354(hw);
|
err = igb_set_eee_i354(hw);
|
||||||
|
if ((!err) &&
|
||||||
|
(!hw->dev_spec._82575.eee_disable)) {
|
||||||
|
adapter->eee_advert =
|
||||||
|
MDIO_EEE_100TX | MDIO_EEE_1000T;
|
||||||
|
adapter->flags |= IGB_FLAG_EEE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pm_runtime_put_noidle(&pdev->dev);
|
pm_runtime_put_noidle(&pdev->dev);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -4158,6 +4190,15 @@ static void igb_watchdog_task(struct work_struct *work)
|
||||||
(ctrl & E1000_CTRL_RFCE) ? "RX" :
|
(ctrl & E1000_CTRL_RFCE) ? "RX" :
|
||||||
(ctrl & E1000_CTRL_TFCE) ? "TX" : "None");
|
(ctrl & E1000_CTRL_TFCE) ? "TX" : "None");
|
||||||
|
|
||||||
|
/* disable EEE if enabled */
|
||||||
|
if ((adapter->flags & IGB_FLAG_EEE) &&
|
||||||
|
(adapter->link_duplex == HALF_DUPLEX)) {
|
||||||
|
dev_info(&adapter->pdev->dev,
|
||||||
|
"EEE Disabled: unsupported at half duplex. Re-enable using ethtool when at full duplex.\n");
|
||||||
|
adapter->hw.dev_spec._82575.eee_disable = true;
|
||||||
|
adapter->flags &= ~IGB_FLAG_EEE;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if SmartSpeed worked */
|
/* check if SmartSpeed worked */
|
||||||
igb_check_downshift(hw);
|
igb_check_downshift(hw);
|
||||||
if (phy->speed_downgraded)
|
if (phy->speed_downgraded)
|
||||||
|
|
Loading…
Reference in New Issue