diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 151 |
1 files changed, 80 insertions, 71 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index e5570acbeea8..c737d1f40838 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -1,28 +1,25 @@ -/******************************************************************************* - - Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2014 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, see <http://www.gnu.org/licenses/>. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ +/* Intel(R) Gigabit Ethernet Linux driver + * Copyright(c) 2007-2014 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see <http://www.gnu.org/licenses/>. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + */ /* ethtool support for igb */ @@ -144,6 +141,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags; u32 status; + u32 speed; status = rd32(E1000_STATUS); if (hw->phy.media_type == e1000_media_type_copper) { @@ -218,13 +216,13 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) if (status & E1000_STATUS_LU) { if ((status & E1000_STATUS_2P5_SKU) && !(status & E1000_STATUS_2P5_SKU_OVER)) { - ecmd->speed = SPEED_2500; + speed = SPEED_2500; } else if (status & E1000_STATUS_SPEED_1000) { - ecmd->speed = SPEED_1000; + speed = SPEED_1000; } else if (status & E1000_STATUS_SPEED_100) { - ecmd->speed = SPEED_100; + speed = SPEED_100; } else { - ecmd->speed = SPEED_10; + speed = SPEED_10; } if ((status & E1000_STATUS_FD) || hw->phy.media_type != e1000_media_type_copper) @@ -232,9 +230,10 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) else ecmd->duplex = DUPLEX_HALF; } else { - ecmd->speed = -1; - ecmd->duplex = -1; + speed = SPEED_UNKNOWN; + ecmd->duplex = DUPLEX_UNKNOWN; } + ethtool_cmd_speed_set(ecmd, speed); if ((hw->phy.media_type == e1000_media_type_fiber) || hw->mac.autoneg) ecmd->autoneg = AUTONEG_ENABLE; @@ -286,7 +285,7 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) } while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (ecmd->autoneg == AUTONEG_ENABLE) { hw->mac.autoneg = 1; @@ -399,7 +398,7 @@ static int igb_set_pauseparam(struct net_device *netdev, adapter->fc_autoneg = pause->autoneg; while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (adapter->fc_autoneg == AUTONEG_ENABLE) { hw->fc.requested_mode = e1000_fc_default; @@ -886,7 +885,7 @@ static int igb_set_ringparam(struct net_device *netdev, } while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (!netif_running(adapter->netdev)) { for (i = 0; i < adapter->num_tx_queues; i++) @@ -1060,8 +1059,8 @@ static struct igb_reg_test reg_test_i350[] = { { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, { E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1103,8 +1102,8 @@ static struct igb_reg_test reg_test_82580[] = { { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, { E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1132,8 +1131,10 @@ static struct igb_reg_test reg_test_82576[] = { { E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, { E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, /* Enable all RX queues before testing. */ - { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE }, - { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE }, + { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, + E1000_RXDCTL_QUEUE_ENABLE }, + { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, + E1000_RXDCTL_QUEUE_ENABLE }, /* RDH is read-only for 82576, only test RDT. */ { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, { E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, @@ -1149,14 +1150,14 @@ static struct igb_reg_test reg_test_82576[] = { { E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, { E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF }, { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, + { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, { E1000_RA, 0, 16, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF }, { E1000_RA2, 0, 8, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, { E1000_RA2, 0, 8, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF }, - { E1000_MTA, 0, 128,TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, + { E1000_MTA, 0, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, { 0, 0, 0, 0 } }; @@ -1170,7 +1171,8 @@ static struct igb_reg_test reg_test_82575[] = { { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, /* Enable all four RX queues before testing. */ - { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE }, + { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, + E1000_RXDCTL_QUEUE_ENABLE }, /* RDH is read-only for 82575, only test RDT. */ { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 }, @@ -1196,8 +1198,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, { struct e1000_hw *hw = &adapter->hw; u32 pat, val; - static const u32 _test[] = - {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; + static const u32 _test[] = { + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { wr32(reg, (_test[pat] & write)); val = rd32(reg) & mask; @@ -1206,11 +1208,11 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", reg, val, (_test[pat] & write & mask)); *data = reg; - return 1; + return true; } } - return 0; + return false; } static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, @@ -1218,17 +1220,18 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, { struct e1000_hw *hw = &adapter->hw; u32 val; + wr32(reg, write & mask); val = rd32(reg); if ((write & mask) != (val & mask)) { dev_err(&adapter->pdev->dev, - "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg, - (val & mask), (write & mask)); + "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", + reg, (val & mask), (write & mask)); *data = reg; - return 1; + return true; } - return 0; + return false; } #define REG_PATTERN_TEST(reg, mask, write) \ @@ -1387,14 +1390,14 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) /* Hook up test interrupt handler just for this test */ if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (request_irq(adapter->msix_entries[0].vector, - igb_test_intr, 0, netdev->name, adapter)) { + igb_test_intr, 0, netdev->name, adapter)) { *data = 1; return -1; } } else if (adapter->flags & IGB_FLAG_HAS_MSI) { shared_int = false; if (request_irq(irq, - igb_test_intr, 0, netdev->name, adapter)) { + igb_test_intr, 0, netdev->name, adapter)) { *data = 1; return -1; } @@ -1412,7 +1415,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) /* Disable all the interrupts */ wr32(E1000_IMC, ~0); wrfl(); - msleep(10); + usleep_range(10000, 11000); /* Define all writable bits for ICS */ switch (hw->mac.type) { @@ -1459,7 +1462,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_IMC, mask); wr32(E1000_ICS, mask); wrfl(); - msleep(10); + usleep_range(10000, 11000); if (adapter->test_icr & mask) { *data = 3; @@ -1481,7 +1484,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_IMS, mask); wr32(E1000_ICS, mask); wrfl(); - msleep(10); + usleep_range(10000, 11000); if (!(adapter->test_icr & mask)) { *data = 4; @@ -1503,7 +1506,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_IMC, ~mask); wr32(E1000_ICS, ~mask); wrfl(); - msleep(10); + usleep_range(10000, 11000); if (adapter->test_icr & mask) { *data = 5; @@ -1515,7 +1518,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) /* Disable all the interrupts */ wr32(E1000_IMC, ~0); wrfl(); - msleep(10); + usleep_range(10000, 11000); /* Unhook test interrupt handler */ if (adapter->flags & IGB_FLAG_HAS_MSIX) @@ -1664,8 +1667,8 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) || (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) || (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP) || - (hw->device_id == E1000_DEV_ID_I354_SGMII)) { - + (hw->device_id == E1000_DEV_ID_I354_SGMII) || + (hw->device_id == E1000_DEV_ID_I354_BACKPLANE_2_5GBPS)) { /* Enable DH89xxCC MPHY for near end loopback */ reg = rd32(E1000_MPHY_ADDR_CTL); reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK) | @@ -1949,6 +1952,7 @@ static int igb_link_test(struct igb_adapter *adapter, u64 *data) *data = 0; if (hw->phy.media_type == e1000_media_type_internal_serdes) { int i = 0; + hw->mac.serdes_has_link = false; /* On some blade server designs, link establishment @@ -2413,9 +2417,11 @@ static int igb_get_rss_hash_opts(struct igb_adapter *adapter, switch (cmd->flow_type) { case TCP_V4_FLOW: cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* Fall through */ case UDP_V4_FLOW: if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP) cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* Fall through */ case SCTP_V4_FLOW: case AH_ESP_V4_FLOW: case AH_V4_FLOW: @@ -2425,9 +2431,11 @@ static int igb_get_rss_hash_opts(struct igb_adapter *adapter, break; case TCP_V6_FLOW: cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* Fall through */ case UDP_V6_FLOW: if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP) cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* Fall through */ case SCTP_V6_FLOW: case AH_ESP_V6_FLOW: case AH_V6_FLOW: @@ -2730,7 +2738,7 @@ static int igb_get_module_info(struct net_device *netdev, { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 status = E1000_SUCCESS; + u32 status = 0; u16 sff8472_rev, addr_mode; bool page_swap = false; @@ -2740,12 +2748,12 @@ static int igb_get_module_info(struct net_device *netdev, /* Check whether we support SFF-8472 or not */ status = igb_read_phy_reg_i2c(hw, IGB_SFF_8472_COMP, &sff8472_rev); - if (status != E1000_SUCCESS) + if (status) return -EIO; /* addressing mode is not supported */ status = igb_read_phy_reg_i2c(hw, IGB_SFF_8472_SWAP, &addr_mode); - if (status != E1000_SUCCESS) + if (status) return -EIO; /* addressing mode is not supported */ @@ -2772,7 +2780,7 @@ static int igb_get_module_eeprom(struct net_device *netdev, { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 status = E1000_SUCCESS; + u32 status = 0; u16 *dataword; u16 first_word, last_word; int i = 0; @@ -2791,7 +2799,7 @@ static int igb_get_module_eeprom(struct net_device *netdev, /* Read EEPROM block, SFF-8079/SFF-8472, word at a time */ for (i = 0; i < last_word - first_word + 1; i++) { status = igb_read_phy_reg_i2c(hw, first_word + i, &dataword[i]); - if (status != E1000_SUCCESS) { + if (status) { /* Error occurred while reading module */ kfree(dataword); return -EIO; @@ -2824,7 +2832,7 @@ static u32 igb_get_rxfh_indir_size(struct net_device *netdev) return IGB_RETA_SIZE; } -static int igb_get_rxfh_indir(struct net_device *netdev, u32 *indir) +static int igb_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key) { struct igb_adapter *adapter = netdev_priv(netdev); int i; @@ -2870,7 +2878,8 @@ void igb_write_rss_indir_tbl(struct igb_adapter *adapter) } } -static int igb_set_rxfh_indir(struct net_device *netdev, const u32 *indir) +static int igb_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *key) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; @@ -3019,8 +3028,8 @@ static const struct ethtool_ops igb_ethtool_ops = { .get_module_info = igb_get_module_info, .get_module_eeprom = igb_get_module_eeprom, .get_rxfh_indir_size = igb_get_rxfh_indir_size, - .get_rxfh_indir = igb_get_rxfh_indir, - .set_rxfh_indir = igb_set_rxfh_indir, + .get_rxfh = igb_get_rxfh, + .set_rxfh = igb_set_rxfh, .get_channels = igb_get_channels, .set_channels = igb_set_channels, .begin = igb_ethtool_begin, @@ -3029,5 +3038,5 @@ static const struct ethtool_ops igb_ethtool_ops = { void igb_set_ethtool_ops(struct net_device *netdev) { - SET_ETHTOOL_OPS(netdev, &igb_ethtool_ops); + netdev->ethtool_ops = &igb_ethtool_ops; } |