aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/e1000e/ich8lan.c
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-04-07 07:42:33 -0700
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-08-10 20:03:27 -0700
commitdee1ad47f2ee75f5146d83ca757c1b7861c34c3b (patch)
tree47cbdefe3d0f9b729724e378ad6a96eaddfd5fbc /drivers/net/e1000e/ich8lan.c
parentf7917c009c28c941ba151ee66f04dc7f6a2e1e0b (diff)
intel: Move the Intel wired LAN drivers
Moves the Intel wired LAN drivers into drivers/net/ethernet/intel/ and the necessary Kconfig and Makefile changes. Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
-rw-r--r--drivers/net/e1000e/ich8lan.c4111
1 files changed, 0 insertions, 4111 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
deleted file mode 100644
index 4e36978b8fd..00000000000
--- a/drivers/net/e1000e/ich8lan.c
+++ /dev/null
@@ -1,4111 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2011 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:
- 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
-
-*******************************************************************************/
-
-/*
- * 82562G 10/100 Network Connection
- * 82562G-2 10/100 Network Connection
- * 82562GT 10/100 Network Connection
- * 82562GT-2 10/100 Network Connection
- * 82562V 10/100 Network Connection
- * 82562V-2 10/100 Network Connection
- * 82566DC-2 Gigabit Network Connection
- * 82566DC Gigabit Network Connection
- * 82566DM-2 Gigabit Network Connection
- * 82566DM Gigabit Network Connection
- * 82566MC Gigabit Network Connection
- * 82566MM Gigabit Network Connection
- * 82567LM Gigabit Network Connection
- * 82567LF Gigabit Network Connection
- * 82567V Gigabit Network Connection
- * 82567LM-2 Gigabit Network Connection
- * 82567LF-2 Gigabit Network Connection
- * 82567V-2 Gigabit Network Connection
- * 82567LF-3 Gigabit Network Connection
- * 82567LM-3 Gigabit Network Connection
- * 82567LM-4 Gigabit Network Connection
- * 82577LM Gigabit Network Connection
- * 82577LC Gigabit Network Connection
- * 82578DM Gigabit Network Connection
- * 82578DC Gigabit Network Connection
- * 82579LM Gigabit Network Connection
- * 82579V Gigabit Network Connection
- */
-
-#include "e1000.h"
-
-#define ICH_FLASH_GFPREG 0x0000
-#define ICH_FLASH_HSFSTS 0x0004
-#define ICH_FLASH_HSFCTL 0x0006
-#define ICH_FLASH_FADDR 0x0008
-#define ICH_FLASH_FDATA0 0x0010
-#define ICH_FLASH_PR0 0x0074
-
-#define ICH_FLASH_READ_COMMAND_TIMEOUT 500
-#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500
-#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000
-#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
-#define ICH_FLASH_CYCLE_REPEAT_COUNT 10
-
-#define ICH_CYCLE_READ 0
-#define ICH_CYCLE_WRITE 2
-#define ICH_CYCLE_ERASE 3
-
-#define FLASH_GFPREG_BASE_MASK 0x1FFF
-#define FLASH_SECTOR_ADDR_SHIFT 12
-
-#define ICH_FLASH_SEG_SIZE_256 256
-#define ICH_FLASH_SEG_SIZE_4K 4096
-#define ICH_FLASH_SEG_SIZE_8K 8192
-#define ICH_FLASH_SEG_SIZE_64K 65536
-
-
-#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
-/* FW established a valid mode */
-#define E1000_ICH_FWSM_FW_VALID 0x00008000
-
-#define E1000_ICH_MNG_IAMT_MODE 0x2
-
-#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
- (ID_LED_DEF1_OFF2 << 8) | \
- (ID_LED_DEF1_ON2 << 4) | \
- (ID_LED_DEF1_DEF2))
-
-#define E1000_ICH_NVM_SIG_WORD 0x13
-#define E1000_ICH_NVM_SIG_MASK 0xC000
-#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0
-#define E1000_ICH_NVM_SIG_VALUE 0x80
-
-#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
-
-#define E1000_FEXTNVM_SW_CONFIG 1
-#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
-
-#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
-#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
-#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
-
-#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
-
-#define E1000_ICH_RAR_ENTRIES 7
-
-#define PHY_PAGE_SHIFT 5
-#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
- ((reg) & MAX_PHY_REG_ADDRESS))
-#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
-#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
-
-#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
-#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
-#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
-
-#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
-
-#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
-
-/* SMBus Address Phy Register */
-#define HV_SMB_ADDR PHY_REG(768, 26)
-#define HV_SMB_ADDR_MASK 0x007F
-#define HV_SMB_ADDR_PEC_EN 0x0200
-#define HV_SMB_ADDR_VALID 0x0080
-
-/* PHY Power Management Control */
-#define HV_PM_CTRL PHY_REG(770, 17)
-
-/* PHY Low Power Idle Control */
-#define I82579_LPI_CTRL PHY_REG(772, 20)
-#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
-
-/* EMI Registers */
-#define I82579_EMI_ADDR 0x10
-#define I82579_EMI_DATA 0x11
-#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
-
-/* Strapping Option Register - RO */
-#define E1000_STRAP 0x0000C
-#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
-#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
-
-/* OEM Bits Phy Register */
-#define HV_OEM_BITS PHY_REG(768, 25)
-#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */
-#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
-#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
-
-#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
-#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
-
-/* KMRN Mode Control */
-#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
-#define HV_KMRN_MDIO_SLOW 0x0400
-
-/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
-/* Offset 04h HSFSTS */
-union ich8_hws_flash_status {
- struct ich8_hsfsts {
- u16 flcdone :1; /* bit 0 Flash Cycle Done */
- u16 flcerr :1; /* bit 1 Flash Cycle Error */
- u16 dael :1; /* bit 2 Direct Access error Log */
- u16 berasesz :2; /* bit 4:3 Sector Erase Size */
- u16 flcinprog :1; /* bit 5 flash cycle in Progress */
- u16 reserved1 :2; /* bit 13:6 Reserved */
- u16 reserved2 :6; /* bit 13:6 Reserved */
- u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */
- u16 flockdn :1; /* bit 15 Flash Config Lock-Down */
- } hsf_status;
- u16 regval;
-};
-
-/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */
-/* Offset 06h FLCTL */
-union ich8_hws_flash_ctrl {
- struct ich8_hsflctl {
- u16 flcgo :1; /* 0 Flash Cycle Go */
- u16 flcycle :2; /* 2:1 Flash Cycle */
- u16 reserved :5; /* 7:3 Reserved */
- u16 fldbcount :2; /* 9:8 Flash Data Byte Count */
- u16 flockdn :6; /* 15:10 Reserved */
- } hsf_ctrl;
- u16 regval;
-};
-
-/* ICH Flash Region Access Permissions */
-union ich8_hws_flash_regacc {
- struct ich8_flracc {
- u32 grra :8; /* 0:7 GbE region Read Access */
- u32 grwa :8; /* 8:15 GbE region Write Access */
- u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */
- u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */
- } hsf_flregacc;
- u16 regval;
-};
-
-/* ICH Flash Protected Region */
-union ich8_flash_protected_range {
- struct ich8_pr {
- u32 base:13; /* 0:12 Protected Range Base */
- u32 reserved1:2; /* 13:14 Reserved */
- u32 rpe:1; /* 15 Read Protection Enable */
- u32 limit:13; /* 16:28 Protected Range Limit */
- u32 reserved2:2; /* 29:30 Reserved */
- u32 wpe:1; /* 31 Write Protection Enable */
- } range;
- u32 regval;
-};
-
-static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw);
-static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
-static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
-static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
-static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 byte);
-static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 *data);
-static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
- u16 *data);
-static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 *data);
-static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
-static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
-static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
-static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
-static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
-static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
-static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
-static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
-static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
-static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
-static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
-static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
-static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
-static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
-static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
-static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
-static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
-static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
-static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
-static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
-
-static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
-{
- return readw(hw->flash_address + reg);
-}
-
-static inline u32 __er32flash(struct e1000_hw *hw, unsigned long reg)
-{
- return readl(hw->flash_address + reg);
-}
-
-static inline void __ew16flash(struct e1000_hw *hw, unsigned long reg, u16 val)
-{
- writew(val, hw->flash_address + reg);
-}
-
-static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
-{
- writel(val, hw->flash_address + reg);
-}
-
-#define er16flash(reg) __er16flash(hw, (reg))
-#define er32flash(reg) __er32flash(hw, (reg))
-#define ew16flash(reg,val) __ew16flash(hw, (reg), (val))
-#define ew32flash(reg,val) __ew32flash(hw, (reg), (val))
-
-static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
- ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
- ew32(CTRL, ctrl);
- e1e_flush();
- udelay(10);
- ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
- ew32(CTRL, ctrl);
-}
-
-/**
- * e1000_init_phy_params_pchlan - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific PHY parameters and function pointers.
- **/
-static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 fwsm;
- s32 ret_val = 0;
-
- phy->addr = 1;
- phy->reset_delay_us = 100;
-
- phy->ops.set_page = e1000_set_page_igp;
- phy->ops.read_reg = e1000_read_phy_reg_hv;
- phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked;
- phy->ops.read_reg_page = e1000_read_phy_reg_page_hv;
- phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan;
- phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan;
- phy->ops.write_reg = e1000_write_phy_reg_hv;
- phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked;
- phy->ops.write_reg_page = e1000_write_phy_reg_page_hv;
- phy->ops.power_up = e1000_power_up_phy_copper;
- phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
- /*
- * The MAC-PHY interconnect may still be in SMBus mode
- * after Sx->S0. If the manageability engine (ME) is
- * disabled, then toggle the LANPHYPC Value bit to force
- * the interconnect to PCIe mode.
- */
- fwsm = er32(FWSM);
- if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) {
- e1000_toggle_lanphypc_value_ich8lan(hw);
- msleep(50);
-
- /*
- * Gate automatic PHY configuration by hardware on
- * non-managed 82579
- */
- if (hw->mac.type == e1000_pch2lan)
- e1000_gate_hw_phy_config_ich8lan(hw, true);
- }
-
- /*
- * Reset the PHY before any access to it. Doing so, ensures that
- * the PHY is in a known good state before we read/write PHY registers.
- * The generic reset is sufficient here, because we haven't determined
- * the PHY type yet.
- */
- ret_val = e1000e_phy_hw_reset_generic(hw);
- if (ret_val)
- goto out;
-
- /* Ungate automatic PHY configuration on non-managed 82579 */
- if ((hw->mac.type == e1000_pch2lan) &&
- !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
- usleep_range(10000, 20000);
- e1000_gate_hw_phy_config_ich8lan(hw, false);
- }
-
- phy->id = e1000_phy_unknown;
- switch (hw->mac.type) {
- default:
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- goto out;
- if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
- break;
- /* fall-through */
- case e1000_pch2lan:
- /*
- * In case the PHY needs to be in mdio slow mode,
- * set slow mode and try to get the PHY id again.
- */
- ret_val = e1000_set_mdio_slow_mode_hv(hw);
- if (ret_val)
- goto out;
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- goto out;
- break;
- }
- phy->type = e1000e_get_phy_type_from_id(phy->id);
-
- switch (phy->type) {
- case e1000_phy_82577:
- case e1000_phy_82579:
- phy->ops.check_polarity = e1000_check_polarity_82577;
- phy->ops.force_speed_duplex =
- e1000_phy_force_speed_duplex_82577;
- phy->ops.get_cable_length = e1000_get_cable_length_82577;
- phy->ops.get_info = e1000_get_phy_info_82577;
- phy->ops.commit = e1000e_phy_sw_reset;
- break;
- case e1000_phy_82578:
- phy->ops.check_polarity = e1000_check_polarity_m88;
- phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
- phy->ops.get_cable_length = e1000e_get_cable_length_m88;
- phy->ops.get_info = e1000e_get_phy_info_m88;
- break;
- default:
- ret_val = -E1000_ERR_PHY;
- break;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_phy_params_ich8lan - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific PHY parameters and function pointers.
- **/
-static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 i = 0;
-
- phy->addr = 1;
- phy->reset_delay_us = 100;
-
- phy->ops.power_up = e1000_power_up_phy_copper;
- phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
-
- /*
- * We may need to do this twice - once for IGP and if that fails,
- * we'll set BM func pointers and try again
- */
- ret_val = e1000e_determine_phy_address(hw);
- if (ret_val) {
- phy->ops.write_reg = e1000e_write_phy_reg_bm;
- phy->ops.read_reg = e1000e_read_phy_reg_bm;
- ret_val = e1000e_determine_phy_address(hw);
- if (ret_val) {
- e_dbg("Cannot determine PHY addr. Erroring out\n");
- return ret_val;
- }
- }
-
- phy->id = 0;
- while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
- (i++ < 100)) {
- usleep_range(1000, 2000);
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- return ret_val;
- }
-
- /* Verify phy id */
- switch (phy->id) {
- case IGP03E1000_E_PHY_ID:
- phy->type = e1000_phy_igp_3;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->ops.read_reg_locked = e1000e_read_phy_reg_igp_locked;
- phy->ops.write_reg_locked = e1000e_write_phy_reg_igp_locked;
- phy->ops.get_info = e1000e_get_phy_info_igp;
- phy->ops.check_polarity = e1000_check_polarity_igp;
- phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_igp;
- break;
- case IFE_E_PHY_ID:
- case IFE_PLUS_E_PHY_ID:
- case IFE_C_E_PHY_ID:
- phy->type = e1000_phy_ife;
- phy->autoneg_mask = E1000_ALL_NOT_GIG;
- phy->ops.get_info = e1000_get_phy_info_ife;
- phy->ops.check_polarity = e1000_check_polarity_ife;
- phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife;
- break;
- case BME1000_E_PHY_ID:
- phy->type = e1000_phy_bm;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->ops.read_reg = e1000e_read_phy_reg_bm;
- phy->ops.write_reg = e1000e_write_phy_reg_bm;
- phy->ops.commit = e1000e_phy_sw_reset;
- phy->ops.get_info = e1000e_get_phy_info_m88;
- phy->ops.check_polarity = e1000_check_polarity_m88;
- phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000_init_nvm_params_ich8lan - Initialize NVM function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific NVM parameters and function
- * pointers.
- **/
-static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 gfpreg, sector_base_addr, sector_end_addr;
- u16 i;
-
- /* Can't read flash registers if the register set isn't mapped. */
- if (!hw->flash_address) {
- e_dbg("ERROR: Flash registers not mapped\n");
- return -E1000_ERR_CONFIG;
- }
-
- nvm->type = e1000_nvm_flash_sw;
-
- gfpreg = er32flash(ICH_FLASH_GFPREG);
-
- /*
- * sector_X_addr is a "sector"-aligned address (4096 bytes)
- * Add 1 to sector_end_addr since this sector is included in
- * the overall size.
- */
- sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
- sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
-
- /* flash_base_addr is byte-aligned */
- nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
-
- /*
- * find total size of the NVM, then cut in half since the total
- * size represents two separate NVM banks.
- */
- nvm->flash_bank_size = (sector_end_addr - sector_base_addr)
- << FLASH_SECTOR_ADDR_SHIFT;
- nvm->flash_bank_size /= 2;
- /* Adjust to word count */
- nvm->flash_bank_size /= sizeof(u16);
-
- nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
-
- /* Clear shadow ram */
- for (i = 0; i < nvm->word_size; i++) {
- dev_spec->shadow_ram[i].modified = false;
- dev_spec->shadow_ram[i].value = 0xFFFF;
- }
-
- return 0;
-}
-
-/**
- * e1000_init_mac_params_ich8lan - Initialize MAC function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific MAC parameters and function
- * pointers.
- **/
-static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_mac_info *mac = &hw->mac;
-
- /* Set media type function pointer */
- hw->phy.media_type = e1000_media_type_copper;
-
- /* Set mta register count */
- mac->mta_reg_count = 32;
- /* Set rar entry count */
- mac->rar_entry_count = E1000_ICH_RAR_ENTRIES;
- if (mac->type == e1000_ich8lan)
- mac->rar_entry_count--;
- /* FWSM register */
- mac->has_fwsm = true;
- /* ARC subsystem not supported */
- mac->arc_subsystem_valid = false;
- /* Adaptive IFS supported */
- mac->adaptive_ifs = true;
-
- /* LED operations */
- switch (mac->type) {
- case e1000_ich8lan:
- case e1000_ich9lan:
- case e1000_ich10lan:
- /* check management mode */
- mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan;
- /* ID LED init */
- mac->ops.id_led_init = e1000e_id_led_init;
- /* blink LED */
- mac->ops.blink_led = e1000e_blink_led_generic;
- /* setup LED */
- mac->ops.setup_led = e1000e_setup_led_generic;
- /* cleanup LED */
- mac->ops.cleanup_led = e1000_cleanup_led_ich8lan;
- /* turn on/off LED */
- mac->ops.led_on = e1000_led_on_ich8lan;
- mac->ops.led_off = e1000_led_off_ich8lan;
- break;
- case e1000_pchlan:
- case e1000_pch2lan:
- /* check management mode */
- mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
- /* ID LED init */
- mac->ops.id_led_init = e1000_id_led_init_pchlan;
- /* setup LED */
- mac->ops.setup_led = e1000_setup_led_pchlan;
- /* cleanup LED */
- mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
- /* turn on/off LED */
- mac->ops.led_on = e1000_led_on_pchlan;
- mac->ops.led_off = e1000_led_off_pchlan;
- break;
- default:
- break;
- }
-
- /* Enable PCS Lock-loss workaround for ICH8 */
- if (mac->type == e1000_ich8lan)
- e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
-
- /* Gate automatic PHY configuration by hardware on managed 82579 */
- if ((mac->type == e1000_pch2lan) &&
- (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
- e1000_gate_hw_phy_config_ich8lan(hw, true);
-
- return 0;
-}
-
-/**
- * e1000_set_eee_pchlan - Enable/disable EEE support
- * @hw: pointer to the HW structure
- *
- * Enable/disable EEE based on setting in dev_spec structure. The bits in
- * the LPI Control register will remain set only if/when link is up.
- **/
-static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
-{
- s32 ret_val = 0;
- u16 phy_reg;
-
- if (hw->phy.type != e1000_phy_82579)
- goto out;
-
- ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
- if (ret_val)
- goto out;
-
- if (hw->dev_spec.ich8lan.eee_disable)
- phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK;
- else
- phy_reg |= I82579_LPI_CTRL_ENABLE_MASK;
-
- ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
-out:
- return ret_val;
-}
-
-/**
- * e1000_check_for_copper_link_ich8lan - Check for link (Copper)
- * @hw: pointer to the HW structure
- *
- * Checks to see of the link status of the hardware has changed. If a
- * change in link status has been detected, then we read the PHY registers
- * to get the current speed/duplex if link exists.
- **/
-static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
- bool link;
-
- /*
- * We only want to go out to the PHY registers to see if Auto-Neg
- * has completed and/or if our link status has changed. The
- * get_link_status flag is set upon receiving a Link Status
- * Change or Rx Sequence Error interrupt.
- */
- if (!mac->get_link_status) {
- ret_val = 0;
- goto out;
- }
-
- /*
- * First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- */
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- goto out;
-
- if (hw->mac.type == e1000_pchlan) {
- ret_val = e1000_k1_gig_workaround_hv(hw, link);
- if (ret_val)
- goto out;
- }
-
- if (!link)
- goto out; /* No link detected */
-
- mac->get_link_status = false;
-
- if (hw->phy.type == e1000_phy_82578) {
- ret_val = e1000_link_stall_workaround_hv(hw);
- if (ret_val)
- goto out;
- }
-
- if (hw->mac.type == e1000_pch2lan) {
- ret_val = e1000_k1_workaround_lv(hw);
- if (ret_val)
- goto out;
- }
-
- /*
- * Check if there was DownShift, must be checked
- * immediately after link-up
- */
- e1000e_check_downshift(hw);
-
- /* Enable/Disable EEE after link up */
- ret_val = e1000_set_eee_pchlan(hw);
- if (ret_val)
- goto out;
-
- /*
- * If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
- if (!mac->autoneg) {
- ret_val = -E1000_ERR_CONFIG;
- goto out;
- }
-
- /*
- * Auto-Neg is enabled. Auto Speed Detection takes care
- * of MAC speed/duplex configuration. So we only need to
- * configure Collision Distance in the MAC.
- */
- e1000e_config_collision_dist(hw);
-
- /*
- * Configure Flow Control now that Auto-Neg has completed.
- * First, we need to restore the desired flow control
- * settings because we may have had to re-autoneg with a
- * different link partner.
- */
- ret_val = e1000e_config_fc_after_link_up(hw);
- if (ret_val)
- e_dbg("Error configuring flow control\n");
-
-out:
- return ret_val;
-}
-
-static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- s32 rc;
-
- rc = e1000_init_mac_params_ich8lan(adapter);
- if (rc)
- return rc;
-
- rc = e1000_init_nvm_params_ich8lan(hw);
- if (rc)
- return rc;
-
- switch (hw->mac.type) {
- case e1000_ich8lan:
- case e1000_ich9lan:
- case e1000_ich10lan:
- rc = e1000_init_phy_params_ich8lan(hw);
- break;
- case e1000_pchlan:
- case e1000_pch2lan:
- rc = e1000_init_phy_params_pchlan(hw);
- break;
- default:
- break;
- }
- if (rc)
- return rc;
-
- /*
- * Disable Jumbo Frame support on parts with Intel 10/100 PHY or
- * on parts with MACsec enabled in NVM (reflected in CTRL_EXT).
- */
- if ((adapter->hw.phy.type == e1000_phy_ife) ||
- ((adapter->hw.mac.type >= e1000_pch2lan) &&
- (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
- adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
- adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
-
- hw->mac.ops.blink_led = NULL;
- }
-
- if ((adapter->hw.mac.type == e1000_ich8lan) &&
- (adapter->hw.phy.type == e1000_phy_igp_3))
- adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
-
- /* Disable EEE by default until IEEE802.3az spec is finalized */
- if (adapter->flags2 & FLAG2_HAS_EEE)
- adapter->hw.dev_spec.ich8lan.eee_disable = true;
-
- return 0;
-}
-
-static DEFINE_MUTEX(nvm_mutex);
-
-/**
- * e1000_acquire_nvm_ich8lan - Acquire NVM mutex
- * @hw: pointer to the HW structure
- *
- * Acquires the mutex for performing NVM operations.
- **/
-static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw)
-{
- mutex_lock(&nvm_mutex);
-
- return 0;
-}
-
-/**
- * e1000_release_nvm_ich8lan - Release NVM mutex
- * @hw: pointer to the HW structure
- *
- * Releases the mutex used while performing NVM operations.
- **/
-static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
-{
- mutex_unlock(&nvm_mutex);
-}
-
-static DEFINE_MUTEX(swflag_mutex);
-
-/**
- * e1000_acquire_swflag_ich8lan - Acquire software control flag
- * @hw: pointer to the HW structure
- *
- * Acquires the software control flag for performing PHY and select
- * MAC CSR accesses.
- **/
-static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
-{
- u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
- s32 ret_val = 0;
-
- mutex_lock(&swflag_mutex);
-
- while (timeout) {
- extcnf_ctrl = er32(EXTCNF_CTRL);
- if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
- break;
-
- mdelay(1);
- timeout--;
- }
-
- if (!timeout) {
- e_dbg("SW/FW/HW has locked the resource for too long.\n");
- ret_val = -E1000_ERR_CONFIG;
- goto out;
- }
-
- timeout = SW_FLAG_TIMEOUT;
-
- extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
-
- while (timeout) {
- extcnf_ctrl = er32(EXTCNF_CTRL);
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
- break;
-
- mdelay(1);
- timeout--;
- }
-
- if (!timeout) {
- e_dbg("Failed to acquire the semaphore.\n");
- extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- ret_val = -E1000_ERR_CONFIG;
- goto out;
- }
-
-out:
- if (ret_val)
- mutex_unlock(&swflag_mutex);
-
- return ret_val;
-}
-
-/**
- * e1000_release_swflag_ich8lan - Release software control flag
- * @hw: pointer to the HW structure
- *
- * Releases the software control flag for performing PHY and select
- * MAC CSR accesses.
- **/
-static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
-{
- u32 extcnf_ctrl;
-
- extcnf_ctrl = er32(EXTCNF_CTRL);
-
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) {
- extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- } else {
- e_dbg("Semaphore unexpectedly released by sw/fw/hw\n");
- }
-
- mutex_unlock(&swflag_mutex);
-}
-
-/**
- * e1000_check_mng_mode_ich8lan - Checks management mode
- * @hw: pointer to the HW structure
- *
- * This checks if the adapter has any manageability enabled.
- * This is a function pointer entry point only called by read/write
- * routines for the PHY and NVM parts.
- **/
-static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw)
-{
- u32 fwsm;
-
- fwsm = er32(FWSM);
- return (fwsm & E1000_ICH_FWSM_FW_VALID) &&
- ((fwsm & E1000_FWSM_MODE_MASK) ==
- (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
-}
-
-/**
- * e1000_check_mng_mode_pchlan - Checks management mode
- * @hw: pointer to the HW structure
- *
- * This checks if the adapter has iAMT enabled.
- * This is a function pointer entry point only called by read/write
- * routines for the PHY and NVM parts.
- **/
-static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw)
-{
- u32 fwsm;
-
- fwsm = er32(FWSM);
- return (fwsm & E1000_ICH_FWSM_FW_VALID) &&
- (fwsm & (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
-}
-
-/**
- * e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
- * @hw: pointer to the HW structure
- *
- * Checks if firmware is blocking the reset of the PHY.
- * This is a function pointer entry point only called by
- * reset routines.
- **/
-static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
-{
- u32 fwsm;
-
- fwsm = er32(FWSM);
-
- return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET;
-}
-
-/**
- * e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states
- * @hw: pointer to the HW structure
- *
- * Assumes semaphore already acquired.
- *
- **/
-static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
-{
- u16 phy_data;
- u32 strap = er32(STRAP);
- s32 ret_val = 0;
-
- strap &= E1000_STRAP_SMBUS_ADDRESS_MASK;
-
- ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data);
- if (ret_val)
- goto out;
-
- phy_data &= ~HV_SMB_ADDR_MASK;
- phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
- phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
- ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
- * @hw: pointer to the HW structure
- *
- * SW should configure the LCD from the NVM extended configuration region
- * as a workaround for certain parts.
- **/
-static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
- s32 ret_val = 0;
- u16 word_addr, reg_data, reg_addr, phy_page = 0;
-
- /*
- * Initialize the PHY from the NVM on ICH platforms. This
- * is needed due to an issue where the NVM configuration is
- * not properly autoloaded after power transitions.
- * Therefore, after each PHY reset, we will load the
- * configuration data out of the NVM manually.
- */
- switch (hw->mac.type) {
- case e1000_ich8lan:
- if (phy->type != e1000_phy_igp_3)
- return ret_val;
-
- if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
- (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
- break;
- }
- /* Fall-thru */
- case e1000_pchlan:
- case e1000_pch2lan:
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
- break;
- default:
- return ret_val;
- }
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- data = er32(FEXTNVM);
- if (!(data & sw_cfg_mask))
- goto out;
-
- /*
- * Make sure HW does not configure LCD from PHY
- * extended configuration before SW configuration
- */
- data = er32(EXTCNF_CTRL);
- if (!(hw->mac.type == e1000_pch2lan)) {
- if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
- goto out;
- }
-
- cnf_size = er32(EXTCNF_SIZE);
- cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
- cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
- if (!cnf_size)
- goto out;
-
- cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
- cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
-
- if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
- (hw->mac.type == e1000_pchlan)) ||
- (hw->mac.type == e1000_pch2lan)) {
- /*
- * HW configures the SMBus address and LEDs when the
- * OEM and LCD Write Enable bits are set in the NVM.
- * When both NVM bits are cleared, SW will configure
- * them instead.
- */
- ret_val = e1000_write_smbus_addr(hw);
- if (ret_val)
- goto out;
-
- data = er32(LEDCTL);
- ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG,
- (u16)data);
- if (ret_val)
- goto out;
- }
-
- /* Configure LCD from extended configuration region. */
-
- /* cnf_base_addr is in DWORD */
- word_addr = (u16)(cnf_base_addr << 1);
-
- for (i = 0; i < cnf_size; i++) {
- ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1,
- &reg_data);
- if (ret_val)
- goto out;
-
- ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1),
- 1, &reg_addr);
- if (ret_val)
- goto out;
-
- /* Save off the PHY page for future writes. */
- if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
- phy_page = reg_data;
- continue;
- }
-
- reg_addr &= PHY_REG_MASK;
- reg_addr |= phy_page;
-
- ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr,
- reg_data);
- if (ret_val)
- goto out;
- }
-
-out:
- hw->phy.ops.release(hw);
- return ret_val;
-}
-
-/**
- * e1000_k1_gig_workaround_hv - K1 Si workaround