diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb/e1000_82575.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_82575.c | 230 |
1 files changed, 158 insertions, 72 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 79b58353d84..ee74f9536b3 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1,29 +1,25 @@ -/******************************************************************************* - - Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2013 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, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - 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 + */ /* e1000_82575 * e1000_82576 @@ -74,11 +70,8 @@ static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw); static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw); -static const u16 e1000_82580_rxpbs_table[] = - { 36, 72, 144, 1, 2, 4, 8, 16, - 35, 70, 140 }; -#define E1000_82580_RXPBS_TABLE_SIZE \ - (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) +static const u16 e1000_82580_rxpbs_table[] = { + 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; /** * igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO @@ -113,6 +106,59 @@ static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw) } /** + * igb_check_for_link_media_swap - Check which M88E1112 interface linked + * @hw: pointer to the HW structure + * + * Poll the M88E1112 interfaces to see which interface achieved link. + */ +static s32 igb_check_for_link_media_swap(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 data; + u8 port = 0; + + /* Check the copper medium. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0); + if (ret_val) + return ret_val; + + ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data); + if (ret_val) + return ret_val; + + if (data & E1000_M88E1112_STATUS_LINK) + port = E1000_MEDIA_PORT_COPPER; + + /* Check the other medium. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1); + if (ret_val) + return ret_val; + + ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data); + if (ret_val) + return ret_val; + + /* reset page to 0 */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0); + if (ret_val) + return ret_val; + + if (data & E1000_M88E1112_STATUS_LINK) + port = E1000_MEDIA_PORT_OTHER; + + /* Determine if a swap needs to happen. */ + if (port && (hw->dev_spec._82575.media_port != port)) { + hw->dev_spec._82575.media_port = port; + hw->dev_spec._82575.media_changed = true; + } else { + ret_val = igb_check_for_link_82575(hw); + } + + return 0; +} + +/** * igb_init_phy_params_82575 - Init PHY func ptrs. * @hw: pointer to the HW structure **/ @@ -189,6 +235,29 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) else phy->ops.get_cable_length = igb_get_cable_length_m88; phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; + /* Check if this PHY is confgured for media swap. */ + if (phy->id == M88E1112_E_PHY_ID) { + u16 data; + + ret_val = phy->ops.write_reg(hw, + E1000_M88E1112_PAGE_ADDR, + 2); + if (ret_val) + goto out; + + ret_val = phy->ops.read_reg(hw, + E1000_M88E1112_MAC_CTRL_1, + &data); + if (ret_val) + goto out; + + data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >> + E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT; + if (data == E1000_M88E1112_AUTO_COPPER_SGMII || + data == E1000_M88E1112_AUTO_COPPER_BASEX) + hw->mac.ops.check_for_link = + igb_check_for_link_media_swap; + } break; case IGP03E1000_E_PHY_ID: phy->type = e1000_phy_igp_3; @@ -365,6 +434,19 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw) ? igb_setup_copper_link_82575 : igb_setup_serdes_link_82575; + if (mac->type == e1000_82580) { + switch (hw->device_id) { + /* feature not supported on these id's */ + case E1000_DEV_ID_DH89XXCC_SGMII: + case E1000_DEV_ID_DH89XXCC_SERDES: + case E1000_DEV_ID_DH89XXCC_BACKPLANE: + case E1000_DEV_ID_DH89XXCC_SFP: + break; + default: + hw->dev_spec._82575.mas_capable = true; + break; + } + } return 0; } @@ -440,7 +522,7 @@ out: static s32 igb_get_invariants_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575; + struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; s32 ret_val; u32 ctrl_ext = 0; u32 link_mode = 0; @@ -719,6 +801,10 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) u32 ctrl_ext; u32 mdic; + /* Extra read required for some PHY's on i354 */ + if (hw->mac.type == e1000_i354) + igb_get_phy_id(hw); + /* For SGMII PHYs, we try the list of possible addresses until * we find one that works. For non-SGMII PHYs * (e.g. integrated copper PHYs), an address of 1 should @@ -918,7 +1004,6 @@ out: static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = 0; u16 data; data = rd32(E1000_82580_PHY_POWER_MGMT); @@ -942,7 +1027,7 @@ static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) data &= ~E1000_82580_PM_SPD; } wr32(E1000_82580_PHY_POWER_MGMT, data); - return ret_val; + return 0; } /** @@ -962,7 +1047,6 @@ static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) static s32 igb_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = 0; u16 data; data = rd32(E1000_82580_PHY_POWER_MGMT); @@ -987,7 +1071,7 @@ static s32 igb_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) } wr32(E1000_82580_PHY_POWER_MGMT, data); - return ret_val; + return 0; } /** @@ -1090,8 +1174,8 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; - while (igb_get_hw_semaphore(hw) != 0); - /* Empty */ + while (igb_get_hw_semaphore(hw) != 0) + ; /* Empty */ swfw_sync = rd32(E1000_SW_FW_SYNC); swfw_sync &= ~mask; @@ -1113,7 +1197,6 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) static s32 igb_get_cfg_done_82575(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; - s32 ret_val = 0; u32 mask = E1000_NVM_CFG_DONE_PORT_0; if (hw->bus.func == 1) @@ -1126,7 +1209,7 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw) while (timeout) { if (rd32(E1000_EEMNGCTL) & mask) break; - msleep(1); + usleep_range(1000, 2000); timeout--; } if (!timeout) @@ -1137,7 +1220,7 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw) (hw->phy.type == e1000_phy_igp_3)) igb_phy_init_script_igp3(hw); - return ret_val; + return 0; } /** @@ -1179,7 +1262,7 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw) if (hw->phy.media_type != e1000_media_type_copper) { ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed, - &duplex); + &duplex); /* Use this flag to determine if link needs to be checked or * not. If we have link clear the flag so that we do not * continue to check for link. @@ -1226,7 +1309,7 @@ void igb_power_up_serdes_link_82575(struct e1000_hw *hw) /* flush the write to verify completion */ wrfl(); - msleep(1); + usleep_range(1000, 2000); } /** @@ -1321,7 +1404,7 @@ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) /* flush the write to verify completion */ wrfl(); - msleep(1); + usleep_range(1000, 2000); } } @@ -1346,9 +1429,8 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw) /* set the completion timeout for interface */ ret_val = igb_set_pcie_completion_timeout(hw); - if (ret_val) { + if (ret_val) hw_dbg("PCI-E Set completion timeout has failed.\n"); - } hw_dbg("Masking off all interrupts\n"); wr32(E1000_IMC, 0xffffffff); @@ -1357,7 +1439,7 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw) wr32(E1000_TCTL, E1000_TCTL_PSP); wrfl(); - msleep(10); + usleep_range(10000, 20000); ctrl = rd32(E1000_CTRL); @@ -1399,6 +1481,13 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw) s32 ret_val; u16 i, rar_count = mac->rar_entry_count; + if ((hw->mac.type >= e1000_i210) && + !(igb_get_flash_presence_i210(hw))) { + ret_val = igb_pll_workaround_i210(hw); + if (ret_val) + return ret_val; + } + /* Initialize identification LED */ ret_val = igb_id_led_init(hw); if (ret_val) { @@ -1532,7 +1621,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) { u32 ctrl_ext, ctrl_reg, reg, anadv_reg; bool pcs_autoneg; - s32 ret_val = E1000_SUCCESS; + s32 ret_val = 0; u16 data; if ((hw->phy.media_type != e1000_media_type_internal_serdes) && @@ -1586,7 +1675,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) hw->mac.type == e1000_82576) { ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data); if (ret_val) { - printk(KERN_DEBUG "NVM Read Error\n\n"); + hw_dbg(KERN_DEBUG "NVM Read Error\n\n"); return ret_val; } @@ -1599,7 +1688,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) * link either autoneg or be forced to 1000/Full */ ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD | - E1000_CTRL_FD | E1000_CTRL_FRCDPX; + E1000_CTRL_FD | E1000_CTRL_FRCDPX; /* set speed of 1000/Full if speed/duplex is forced */ reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL; @@ -1835,7 +1924,7 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw) } /* Poll all queues to verify they have shut down */ for (ms_wait = 0; ms_wait < 10; ms_wait++) { - msleep(1); + usleep_range(1000, 2000); rx_enabled = 0; for (i = 0; i < 4; i++) rx_enabled |= rd32(E1000_RXDCTL(i)); @@ -1863,7 +1952,7 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw) wr32(E1000_RCTL, temp_rctl); wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN); wrfl(); - msleep(2); + usleep_range(2000, 3000); /* Enable RX queues that were previously enabled and restore our * previous state @@ -1915,14 +2004,14 @@ static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw) * 16ms to 55ms */ ret_val = igb_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, - &pcie_devctl2); + &pcie_devctl2); if (ret_val) goto out; pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms; ret_val = igb_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, - &pcie_devctl2); + &pcie_devctl2); out: /* disable completion timeout resend */ gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND; @@ -2151,7 +2240,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) wr32(E1000_TCTL, E1000_TCTL_PSP); wrfl(); - msleep(10); + usleep_range(10000, 11000); /* Determine whether or not a global dev reset is requested */ if (global_device_reset && @@ -2169,7 +2258,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) /* Add delay to insure DEV_RST has time to complete */ if (global_device_reset) - msleep(5); + usleep_range(5000, 6000); ret_val = igb_get_auto_rd_done(hw); if (ret_val) { @@ -2215,7 +2304,7 @@ u16 igb_rxpbs_adjust_82580(u32 data) { u16 ret_val = 0; - if (data < E1000_82580_RXPBS_TABLE_SIZE) + if (data < ARRAY_SIZE(e1000_82580_rxpbs_table)) ret_val = e1000_82580_rxpbs_table[data]; return ret_val; @@ -2346,8 +2435,7 @@ static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw) ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); if (ret_val) { - hw_dbg("NVM Read Error while updating checksum" - " compatibility bit.\n"); + hw_dbg("NVM Read Error while updating checksum compatibility bit.\n"); goto out; } @@ -2357,8 +2445,7 @@ static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw) ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); if (ret_val) { - hw_dbg("NVM Write Error while updating checksum" - " compatibility bit.\n"); + hw_dbg("NVM Write Error while updating checksum compatibility bit.\n"); goto out; } } @@ -2435,7 +2522,7 @@ out: static s32 __igb_access_emi_reg(struct e1000_hw *hw, u16 address, u16 *data, bool read) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val = 0; ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address); if (ret_val) @@ -2469,7 +2556,6 @@ s32 igb_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data) **/ s32 igb_set_eee_i350(struct e1000_hw *hw) { - s32 ret_val = 0; u32 ipcnfg, eeer; if ((hw->mac.type < e1000_i350) || @@ -2503,7 +2589,7 @@ s32 igb_set_eee_i350(struct e1000_hw *hw) rd32(E1000_EEER); out: - return ret_val; + return 0; } /** @@ -2621,15 +2707,15 @@ static const u8 e1000_emc_therm_limit[4] = { E1000_EMC_DIODE3_THERM_LIMIT }; +#ifdef CONFIG_IGB_HWMON /** * igb_get_thermal_sensor_data_generic - Gathers thermal sensor data * @hw: pointer to hardware structure * * Updates the temperatures in mac.thermal_sensor_data **/ -s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw) +static s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw) { - s32 status = E1000_SUCCESS; u16 ets_offset; u16 ets_cfg; u16 ets_sensor; @@ -2647,7 +2733,7 @@ s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw) /* Return the internal sensor only if ETS is unsupported */ hw->nvm.ops.read(hw, NVM_ETS_CFG, 1, &ets_offset); if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) - return status; + return 0; hw->nvm.ops.read(hw, ets_offset, 1, &ets_cfg); if (((ets_cfg & NVM_ETS_TYPE_MASK) >> NVM_ETS_TYPE_SHIFT) @@ -2671,7 +2757,7 @@ s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw) E1000_I2C_THERMAL_SENSOR_ADDR, &data->sensor[i].temp); } - return status; + return 0; } /** @@ -2681,9 +2767,8 @@ s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw) * Sets the thermal sensor thresholds according to the NVM map * and save off the threshold and location values into mac.thermal_sensor_data **/ -s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *hw) +static s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *hw) { - s32 status = E1000_SUCCESS; u16 ets_offset; u16 ets_cfg; u16 ets_sensor; @@ -2709,7 +2794,7 @@ s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *hw) /* Return the internal sensor only if ETS is unsupported */ hw->nvm.ops.read(hw, NVM_ETS_CFG, 1, &ets_offset); if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) - return status; + return 0; hw->nvm.ops.read(hw, ets_offset, 1, &ets_cfg); if (((ets_cfg & NVM_ETS_TYPE_MASK) >> NVM_ETS_TYPE_SHIFT) @@ -2740,9 +2825,10 @@ s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *hw) low_thresh_delta; } } - return status; + return 0; } +#endif static struct e1000_mac_operations e1000_mac_ops_82575 = { .init_hw = igb_init_hw_82575, .check_for_link = igb_check_for_link_82575, |
