Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates 2014-09-06 This series contains updates to e1000 and igb. Krzysztof provides a patch to cleanup the coding style in e1000 to quiet checkpatch.pl warnings. Todd adds two boolean flags to igb to allow for changes in the advertised EEE speeds from ethtool. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8b3bfffc41
5 changed files with 128 additions and 94 deletions
|
@ -1,35 +1,30 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
* Intel PRO/1000 Linux driver
|
||||||
Intel PRO/1000 Linux driver
|
* Copyright(c) 1999 - 2006 Intel Corporation.
|
||||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
This program is free software; you can redistribute it and/or modify it
|
* under the terms and conditions of the GNU General Public License,
|
||||||
under the terms and conditions of the GNU General Public License,
|
* version 2, as published by the Free Software Foundation.
|
||||||
version 2, as published by the Free Software Foundation.
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
This program is distributed in the hope it will be useful, but WITHOUT
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* more details.
|
||||||
more details.
|
*
|
||||||
|
* The full GNU General Public License is included in this distribution in
|
||||||
You should have received a copy of the GNU General Public License along with
|
* the file called "COPYING".
|
||||||
this program; if not, write to the Free Software Foundation, Inc.,
|
*
|
||||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
* Contact Information:
|
||||||
|
* Linux NICS <linux.nics@intel.com>
|
||||||
The full GNU General Public License is included in this distribution in
|
* e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||||
the file called "COPYING".
|
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||||
|
*
|
||||||
Contact Information:
|
******************************************************************************/
|
||||||
Linux NICS <linux.nics@intel.com>
|
|
||||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
|
||||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
/* ethtool support for e1000 */
|
/* ethtool support for e1000 */
|
||||||
|
|
||||||
#include "e1000.h"
|
#include "e1000.h"
|
||||||
#include <asm/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
enum {NETDEV_STATS, E1000_STATS};
|
enum {NETDEV_STATS, E1000_STATS};
|
||||||
|
|
||||||
|
@ -104,6 +99,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
|
||||||
"Interrupt test (offline)", "Loopback test (offline)",
|
"Interrupt test (offline)", "Loopback test (offline)",
|
||||||
"Link test (on/offline)"
|
"Link test (on/offline)"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
|
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
|
||||||
|
|
||||||
static int e1000_get_settings(struct net_device *netdev,
|
static int e1000_get_settings(struct net_device *netdev,
|
||||||
|
@ -113,7 +109,6 @@ static int e1000_get_settings(struct net_device *netdev,
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
|
|
||||||
if (hw->media_type == e1000_media_type_copper) {
|
if (hw->media_type == e1000_media_type_copper) {
|
||||||
|
|
||||||
ecmd->supported = (SUPPORTED_10baseT_Half |
|
ecmd->supported = (SUPPORTED_10baseT_Half |
|
||||||
SUPPORTED_10baseT_Full |
|
SUPPORTED_10baseT_Full |
|
||||||
SUPPORTED_100baseT_Half |
|
SUPPORTED_100baseT_Half |
|
||||||
|
@ -155,7 +150,6 @@ static int e1000_get_settings(struct net_device *netdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (er32(STATUS) & E1000_STATUS_LU) {
|
if (er32(STATUS) & E1000_STATUS_LU) {
|
||||||
|
|
||||||
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
|
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
|
||||||
&adapter->link_duplex);
|
&adapter->link_duplex);
|
||||||
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
|
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
|
||||||
|
@ -247,9 +241,9 @@ static int e1000_set_settings(struct net_device *netdev,
|
||||||
if (netif_running(adapter->netdev)) {
|
if (netif_running(adapter->netdev)) {
|
||||||
e1000_down(adapter);
|
e1000_down(adapter);
|
||||||
e1000_up(adapter);
|
e1000_up(adapter);
|
||||||
} else
|
} else {
|
||||||
e1000_reset(adapter);
|
e1000_reset(adapter);
|
||||||
|
}
|
||||||
clear_bit(__E1000_RESETTING, &adapter->flags);
|
clear_bit(__E1000_RESETTING, &adapter->flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -279,11 +273,11 @@ static void e1000_get_pauseparam(struct net_device *netdev,
|
||||||
pause->autoneg =
|
pause->autoneg =
|
||||||
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
|
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
|
||||||
|
|
||||||
if (hw->fc == E1000_FC_RX_PAUSE)
|
if (hw->fc == E1000_FC_RX_PAUSE) {
|
||||||
pause->rx_pause = 1;
|
pause->rx_pause = 1;
|
||||||
else if (hw->fc == E1000_FC_TX_PAUSE)
|
} else if (hw->fc == E1000_FC_TX_PAUSE) {
|
||||||
pause->tx_pause = 1;
|
pause->tx_pause = 1;
|
||||||
else if (hw->fc == E1000_FC_FULL) {
|
} else if (hw->fc == E1000_FC_FULL) {
|
||||||
pause->rx_pause = 1;
|
pause->rx_pause = 1;
|
||||||
pause->tx_pause = 1;
|
pause->tx_pause = 1;
|
||||||
}
|
}
|
||||||
|
@ -316,8 +310,9 @@ static int e1000_set_pauseparam(struct net_device *netdev,
|
||||||
if (netif_running(adapter->netdev)) {
|
if (netif_running(adapter->netdev)) {
|
||||||
e1000_down(adapter);
|
e1000_down(adapter);
|
||||||
e1000_up(adapter);
|
e1000_up(adapter);
|
||||||
} else
|
} else {
|
||||||
e1000_reset(adapter);
|
e1000_reset(adapter);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
retval = ((hw->media_type == e1000_media_type_fiber) ?
|
retval = ((hw->media_type == e1000_media_type_fiber) ?
|
||||||
e1000_setup_link(hw) : e1000_force_mac_fc(hw));
|
e1000_setup_link(hw) : e1000_force_mac_fc(hw));
|
||||||
|
@ -329,12 +324,14 @@ static int e1000_set_pauseparam(struct net_device *netdev,
|
||||||
static u32 e1000_get_msglevel(struct net_device *netdev)
|
static u32 e1000_get_msglevel(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
return adapter->msg_enable;
|
return adapter->msg_enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void e1000_set_msglevel(struct net_device *netdev, u32 data)
|
static void e1000_set_msglevel(struct net_device *netdev, u32 data)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
adapter->msg_enable = data;
|
adapter->msg_enable = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,7 +619,6 @@ static int e1000_set_ringparam(struct net_device *netdev,
|
||||||
rxdr->count = min(rxdr->count, (u32)(mac_type < e1000_82544 ?
|
rxdr->count = min(rxdr->count, (u32)(mac_type < e1000_82544 ?
|
||||||
E1000_MAX_RXD : E1000_MAX_82544_RXD));
|
E1000_MAX_RXD : E1000_MAX_82544_RXD));
|
||||||
rxdr->count = ALIGN(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
|
rxdr->count = ALIGN(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
|
||||||
|
|
||||||
txdr->count = max(ring->tx_pending, (u32)E1000_MIN_TXD);
|
txdr->count = max(ring->tx_pending, (u32)E1000_MIN_TXD);
|
||||||
txdr->count = min(txdr->count, (u32)(mac_type < e1000_82544 ?
|
txdr->count = min(txdr->count, (u32)(mac_type < e1000_82544 ?
|
||||||
E1000_MAX_TXD : E1000_MAX_82544_TXD));
|
E1000_MAX_TXD : E1000_MAX_82544_TXD));
|
||||||
|
@ -680,8 +676,9 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg,
|
||||||
u32 mask, u32 write)
|
u32 mask, u32 write)
|
||||||
{
|
{
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
static const u32 test[] =
|
static const u32 test[] = {
|
||||||
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
|
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
|
||||||
|
};
|
||||||
u8 __iomem *address = hw->hw_addr + reg;
|
u8 __iomem *address = hw->hw_addr + reg;
|
||||||
u32 read;
|
u32 read;
|
||||||
int i;
|
int i;
|
||||||
|
@ -793,8 +790,8 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
||||||
REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
|
REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
|
||||||
value = E1000_RAR_ENTRIES;
|
value = E1000_RAR_ENTRIES;
|
||||||
for (i = 0; i < value; i++) {
|
for (i = 0; i < value; i++) {
|
||||||
REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
|
REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2),
|
||||||
0xFFFFFFFF);
|
0x8003FFFF, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF);
|
REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF);
|
||||||
|
@ -877,7 +874,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
|
||||||
|
|
||||||
/* Test each interrupt */
|
/* Test each interrupt */
|
||||||
for (; i < 10; i++) {
|
for (; i < 10; i++) {
|
||||||
|
|
||||||
/* Interrupt to test */
|
/* Interrupt to test */
|
||||||
mask = 1 << i;
|
mask = 1 << i;
|
||||||
|
|
||||||
|
@ -1149,8 +1145,7 @@ static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter)
|
||||||
*/
|
*/
|
||||||
e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
|
e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
|
||||||
phy_reg |= M88E1000_EPSCR_TX_CLK_25;
|
phy_reg |= M88E1000_EPSCR_TX_CLK_25;
|
||||||
e1000_write_phy_reg(hw,
|
e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_reg);
|
||||||
M88E1000_EXT_PHY_SPEC_CTRL, phy_reg);
|
|
||||||
|
|
||||||
/* In addition, because of the s/w reset above, we need to enable
|
/* In addition, because of the s/w reset above, we need to enable
|
||||||
* CRS on TX. This must be set for both full and half duplex
|
* CRS on TX. This must be set for both full and half duplex
|
||||||
|
@ -1158,8 +1153,7 @@ static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter)
|
||||||
*/
|
*/
|
||||||
e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
|
e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
|
||||||
phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
|
phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
|
||||||
e1000_write_phy_reg(hw,
|
e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_reg);
|
||||||
M88E1000_PHY_SPEC_CTRL, phy_reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
|
static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
|
||||||
|
@ -1348,8 +1342,9 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
|
||||||
ew32(RCTL, rctl);
|
ew32(RCTL, rctl);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (hw->media_type == e1000_media_type_copper)
|
} else if (hw->media_type == e1000_media_type_copper) {
|
||||||
return e1000_set_phy_loopback(adapter);
|
return e1000_set_phy_loopback(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
|
@ -1395,9 +1390,9 @@ static int e1000_check_lbtest_frame(struct sk_buff *skb,
|
||||||
unsigned int frame_size)
|
unsigned int frame_size)
|
||||||
{
|
{
|
||||||
frame_size &= ~1;
|
frame_size &= ~1;
|
||||||
if (*(skb->data + 3) == 0xFF) {
|
if (skb->data[3] == 0xFF) {
|
||||||
if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
|
if (skb->data[frame_size / 2 + 10] == 0xBE &&
|
||||||
(*(skb->data + frame_size / 2 + 12) == 0xAF)) {
|
skb->data[frame_size / 2 + 12] == 0xAF) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1434,7 +1429,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
|
||||||
txdr->buffer_info[k].dma,
|
txdr->buffer_info[k].dma,
|
||||||
txdr->buffer_info[k].length,
|
txdr->buffer_info[k].length,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
if (unlikely(++k == txdr->count)) k = 0;
|
if (unlikely(++k == txdr->count))
|
||||||
|
k = 0;
|
||||||
}
|
}
|
||||||
ew32(TDT, k);
|
ew32(TDT, k);
|
||||||
E1000_WRITE_FLUSH();
|
E1000_WRITE_FLUSH();
|
||||||
|
@ -1452,7 +1448,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
|
||||||
1024);
|
1024);
|
||||||
if (!ret_val)
|
if (!ret_val)
|
||||||
good_cnt++;
|
good_cnt++;
|
||||||
if (unlikely(++l == rxdr->count)) l = 0;
|
if (unlikely(++l == rxdr->count))
|
||||||
|
l = 0;
|
||||||
/* time + 20 msecs (200 msecs on 2.4) is more than
|
/* time + 20 msecs (200 msecs on 2.4) is more than
|
||||||
* enough time to complete the receives, if it's
|
* enough time to complete the receives, if it's
|
||||||
* exceeded, break and error off
|
* exceeded, break and error off
|
||||||
|
@ -1494,6 +1491,7 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
|
||||||
*data = 0;
|
*data = 0;
|
||||||
if (hw->media_type == e1000_media_type_internal_serdes) {
|
if (hw->media_type == e1000_media_type_internal_serdes) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
hw->serdes_has_link = false;
|
hw->serdes_has_link = false;
|
||||||
|
|
||||||
/* On some blade server designs, link establishment
|
/* On some blade server designs, link establishment
|
||||||
|
@ -1512,10 +1510,9 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
|
||||||
if (hw->autoneg) /* if auto_neg is set wait for it */
|
if (hw->autoneg) /* if auto_neg is set wait for it */
|
||||||
msleep(4000);
|
msleep(4000);
|
||||||
|
|
||||||
if (!(er32(STATUS) & E1000_STATUS_LU)) {
|
if (!(er32(STATUS) & E1000_STATUS_LU))
|
||||||
*data = 1;
|
*data = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return *data;
|
return *data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1665,8 +1662,7 @@ static void e1000_get_wol(struct net_device *netdev,
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
|
|
||||||
wol->supported = WAKE_UCAST | WAKE_MCAST |
|
wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
|
||||||
WAKE_BCAST | WAKE_MAGIC;
|
|
||||||
wol->wolopts = 0;
|
wol->wolopts = 0;
|
||||||
|
|
||||||
/* this function will set ->supported = 0 and return 1 if wol is not
|
/* this function will set ->supported = 0 and return 1 if wol is not
|
||||||
|
@ -1819,6 +1815,7 @@ static int e1000_set_coalesce(struct net_device *netdev,
|
||||||
static int e1000_nway_reset(struct net_device *netdev)
|
static int e1000_nway_reset(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
if (netif_running(netdev))
|
if (netif_running(netdev))
|
||||||
e1000_reinit_locked(adapter);
|
e1000_reinit_locked(adapter);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1830,22 +1827,29 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
int i;
|
int i;
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
const struct e1000_stats *stat = e1000_gstrings_stats;
|
||||||
|
|
||||||
e1000_update_stats(adapter);
|
e1000_update_stats(adapter);
|
||||||
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
|
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
|
||||||
switch (e1000_gstrings_stats[i].type) {
|
switch (stat->type) {
|
||||||
case NETDEV_STATS:
|
case NETDEV_STATS:
|
||||||
p = (char *) netdev +
|
p = (char *)netdev + stat->stat_offset;
|
||||||
e1000_gstrings_stats[i].stat_offset;
|
|
||||||
break;
|
break;
|
||||||
case E1000_STATS:
|
case E1000_STATS:
|
||||||
p = (char *) adapter +
|
p = (char *)adapter + stat->stat_offset;
|
||||||
e1000_gstrings_stats[i].stat_offset;
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
|
||||||
|
stat->type, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
|
if (stat->sizeof_stat == sizeof(u64))
|
||||||
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
|
data[i] = *(u64 *)p;
|
||||||
|
else
|
||||||
|
data[i] = *(u32 *)p;
|
||||||
|
|
||||||
|
stat++;
|
||||||
}
|
}
|
||||||
/* BUG_ON(i != E1000_STATS_LEN); */
|
/* BUG_ON(i != E1000_STATS_LEN); */
|
||||||
}
|
}
|
||||||
|
@ -1858,8 +1862,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
|
||||||
|
|
||||||
switch (stringset) {
|
switch (stringset) {
|
||||||
case ETH_SS_TEST:
|
case ETH_SS_TEST:
|
||||||
memcpy(data, *e1000_gstrings_test,
|
memcpy(data, e1000_gstrings_test, sizeof(e1000_gstrings_test));
|
||||||
sizeof(e1000_gstrings_test));
|
|
||||||
break;
|
break;
|
||||||
case ETH_SS_STATS:
|
case ETH_SS_STATS:
|
||||||
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
|
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
|
||||||
|
|
|
@ -2548,11 +2548,13 @@ s32 igb_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
|
||||||
/**
|
/**
|
||||||
* igb_set_eee_i350 - Enable/disable EEE support
|
* igb_set_eee_i350 - Enable/disable EEE support
|
||||||
* @hw: pointer to the HW structure
|
* @hw: pointer to the HW structure
|
||||||
|
* @adv1G: boolean flag enabling 1G EEE advertisement
|
||||||
|
* @adv100m: boolean flag enabling 100M EEE advertisement
|
||||||
*
|
*
|
||||||
* Enable/disable EEE based on setting in dev_spec structure.
|
* Enable/disable EEE based on setting in dev_spec structure.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
s32 igb_set_eee_i350(struct e1000_hw *hw)
|
s32 igb_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
|
||||||
{
|
{
|
||||||
u32 ipcnfg, eeer;
|
u32 ipcnfg, eeer;
|
||||||
|
|
||||||
|
@ -2566,7 +2568,16 @@ s32 igb_set_eee_i350(struct e1000_hw *hw)
|
||||||
if (!(hw->dev_spec._82575.eee_disable)) {
|
if (!(hw->dev_spec._82575.eee_disable)) {
|
||||||
u32 eee_su = rd32(E1000_EEE_SU);
|
u32 eee_su = rd32(E1000_EEE_SU);
|
||||||
|
|
||||||
ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
|
if (adv100M)
|
||||||
|
ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
|
||||||
|
else
|
||||||
|
ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
|
||||||
|
|
||||||
|
if (adv1G)
|
||||||
|
ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
|
||||||
|
else
|
||||||
|
ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
|
||||||
|
|
||||||
eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
|
eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
|
||||||
E1000_EEER_LPI_FC);
|
E1000_EEER_LPI_FC);
|
||||||
|
|
||||||
|
@ -2593,11 +2604,13 @@ out:
|
||||||
/**
|
/**
|
||||||
* igb_set_eee_i354 - Enable/disable EEE support
|
* igb_set_eee_i354 - Enable/disable EEE support
|
||||||
* @hw: pointer to the HW structure
|
* @hw: pointer to the HW structure
|
||||||
|
* @adv1G: boolean flag enabling 1G EEE advertisement
|
||||||
|
* @adv100m: boolean flag enabling 100M EEE advertisement
|
||||||
*
|
*
|
||||||
* Enable/disable EEE legacy mode based on setting in dev_spec structure.
|
* Enable/disable EEE legacy mode based on setting in dev_spec structure.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
s32 igb_set_eee_i354(struct e1000_hw *hw)
|
s32 igb_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
|
||||||
{
|
{
|
||||||
struct e1000_phy_info *phy = &hw->phy;
|
struct e1000_phy_info *phy = &hw->phy;
|
||||||
s32 ret_val = 0;
|
s32 ret_val = 0;
|
||||||
|
@ -2636,8 +2649,16 @@ s32 igb_set_eee_i354(struct e1000_hw *hw)
|
||||||
if (ret_val)
|
if (ret_val)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
phy_data |= E1000_EEE_ADV_100_SUPPORTED |
|
if (adv100M)
|
||||||
E1000_EEE_ADV_1000_SUPPORTED;
|
phy_data |= E1000_EEE_ADV_100_SUPPORTED;
|
||||||
|
else
|
||||||
|
phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
|
||||||
|
|
||||||
|
if (adv1G)
|
||||||
|
phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
|
||||||
|
else
|
||||||
|
phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
|
||||||
|
|
||||||
ret_val = igb_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
|
ret_val = igb_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
|
||||||
E1000_EEE_ADV_DEV_I354,
|
E1000_EEE_ADV_DEV_I354,
|
||||||
phy_data);
|
phy_data);
|
||||||
|
|
|
@ -263,8 +263,8 @@ void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
|
||||||
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
|
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
|
||||||
u16 igb_rxpbs_adjust_82580(u32 data);
|
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 *, bool adv1G, bool adv100M);
|
||||||
s32 igb_set_eee_i354(struct e1000_hw *);
|
s32 igb_set_eee_i354(struct e1000_hw *, bool adv1G, bool adv100M);
|
||||||
s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status);
|
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
|
||||||
|
|
|
@ -2675,6 +2675,7 @@ static int igb_set_eee(struct net_device *netdev,
|
||||||
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;
|
||||||
struct ethtool_eee eee_curr;
|
struct ethtool_eee eee_curr;
|
||||||
|
bool adv1g_eee = true, adv100m_eee = true;
|
||||||
s32 ret_val;
|
s32 ret_val;
|
||||||
|
|
||||||
if ((hw->mac.type < e1000_i350) ||
|
if ((hw->mac.type < e1000_i350) ||
|
||||||
|
@ -2701,12 +2702,14 @@ static int igb_set_eee(struct net_device *netdev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (edata->advertised &
|
if (!edata->advertised || (edata->advertised &
|
||||||
~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
|
~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL))) {
|
||||||
dev_err(&adapter->pdev->dev,
|
dev_err(&adapter->pdev->dev,
|
||||||
"EEE Advertisement supports only 100Tx and or 100T full duplex\n");
|
"EEE Advertisement supports only 100Tx and/or 100T full duplex\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
adv100m_eee = !!(edata->advertised & ADVERTISE_100_FULL);
|
||||||
|
adv1g_eee = !!(edata->advertised & ADVERTISE_1000_FULL);
|
||||||
|
|
||||||
} else if (!edata->eee_enabled) {
|
} else if (!edata->eee_enabled) {
|
||||||
dev_err(&adapter->pdev->dev,
|
dev_err(&adapter->pdev->dev,
|
||||||
|
@ -2718,10 +2721,6 @@ static int igb_set_eee(struct net_device *netdev,
|
||||||
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;
|
adapter->flags |= IGB_FLAG_EEE;
|
||||||
if (hw->mac.type == e1000_i350)
|
|
||||||
igb_set_eee_i350(hw);
|
|
||||||
else
|
|
||||||
igb_set_eee_i354(hw);
|
|
||||||
|
|
||||||
/* reset link */
|
/* reset link */
|
||||||
if (netif_running(netdev))
|
if (netif_running(netdev))
|
||||||
|
@ -2730,6 +2729,17 @@ static int igb_set_eee(struct net_device *netdev,
|
||||||
igb_reset(adapter);
|
igb_reset(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hw->mac.type == e1000_i354)
|
||||||
|
ret_val = igb_set_eee_i354(hw, adv1g_eee, adv100m_eee);
|
||||||
|
else
|
||||||
|
ret_val = igb_set_eee_i350(hw, adv1g_eee, adv100m_eee);
|
||||||
|
|
||||||
|
if (ret_val) {
|
||||||
|
dev_err(&adapter->pdev->dev,
|
||||||
|
"Problem setting EEE advertisement options\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2012,10 +2012,10 @@ void igb_reset(struct igb_adapter *adapter)
|
||||||
case e1000_i350:
|
case e1000_i350:
|
||||||
case e1000_i210:
|
case e1000_i210:
|
||||||
case e1000_i211:
|
case e1000_i211:
|
||||||
igb_set_eee_i350(hw);
|
igb_set_eee_i350(hw, true, true);
|
||||||
break;
|
break;
|
||||||
case e1000_i354:
|
case e1000_i354:
|
||||||
igb_set_eee_i354(hw);
|
igb_set_eee_i354(hw, true, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -2619,7 +2619,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
case e1000_i210:
|
case e1000_i210:
|
||||||
case e1000_i211:
|
case e1000_i211:
|
||||||
/* Enable EEE for internal copper PHY devices */
|
/* Enable EEE for internal copper PHY devices */
|
||||||
err = igb_set_eee_i350(hw);
|
err = igb_set_eee_i350(hw, true, true);
|
||||||
if ((!err) &&
|
if ((!err) &&
|
||||||
(!hw->dev_spec._82575.eee_disable)) {
|
(!hw->dev_spec._82575.eee_disable)) {
|
||||||
adapter->eee_advert =
|
adapter->eee_advert =
|
||||||
|
@ -2630,7 +2630,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
case e1000_i354:
|
case e1000_i354:
|
||||||
if ((rd32(E1000_CTRL_EXT) &
|
if ((rd32(E1000_CTRL_EXT) &
|
||||||
E1000_CTRL_EXT_LINK_MODE_SGMII)) {
|
E1000_CTRL_EXT_LINK_MODE_SGMII)) {
|
||||||
err = igb_set_eee_i354(hw);
|
err = igb_set_eee_i354(hw, true, true);
|
||||||
if ((!err) &&
|
if ((!err) &&
|
||||||
(!hw->dev_spec._82575.eee_disable)) {
|
(!hw->dev_spec._82575.eee_disable)) {
|
||||||
adapter->eee_advert =
|
adapter->eee_advert =
|
||||||
|
|
Loading…
Add table
Reference in a new issue