175eba5b6SRobert Mustacchi /****************************************************************************** 275eba5b6SRobert Mustacchi 3*42cc51e0SRobert Mustacchi Copyright (c) 2001-2015, Intel Corporation 475eba5b6SRobert Mustacchi All rights reserved. 575eba5b6SRobert Mustacchi 675eba5b6SRobert Mustacchi Redistribution and use in source and binary forms, with or without 775eba5b6SRobert Mustacchi modification, are permitted provided that the following conditions are met: 875eba5b6SRobert Mustacchi 975eba5b6SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice, 1075eba5b6SRobert Mustacchi this list of conditions and the following disclaimer. 1175eba5b6SRobert Mustacchi 1275eba5b6SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright 1375eba5b6SRobert Mustacchi notice, this list of conditions and the following disclaimer in the 1475eba5b6SRobert Mustacchi documentation and/or other materials provided with the distribution. 1575eba5b6SRobert Mustacchi 1675eba5b6SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its 1775eba5b6SRobert Mustacchi contributors may be used to endorse or promote products derived from 1875eba5b6SRobert Mustacchi this software without specific prior written permission. 1975eba5b6SRobert Mustacchi 2075eba5b6SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2175eba5b6SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2275eba5b6SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2375eba5b6SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2475eba5b6SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2575eba5b6SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2675eba5b6SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2775eba5b6SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2875eba5b6SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2975eba5b6SRobert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3075eba5b6SRobert Mustacchi POSSIBILITY OF SUCH DAMAGE. 3175eba5b6SRobert Mustacchi 3275eba5b6SRobert Mustacchi ******************************************************************************/ 3375eba5b6SRobert Mustacchi /*$FreeBSD$*/ 3475eba5b6SRobert Mustacchi 35c124a83eSRobert Mustacchi /* 80003ES2LAN Gigabit Ethernet Controller (Copper) 3675eba5b6SRobert Mustacchi * 80003ES2LAN Gigabit Ethernet Controller (Serdes) 3775eba5b6SRobert Mustacchi */ 3875eba5b6SRobert Mustacchi 3975eba5b6SRobert Mustacchi #include "e1000_api.h" 4075eba5b6SRobert Mustacchi 4175eba5b6SRobert Mustacchi static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); 4275eba5b6SRobert Mustacchi static void e1000_release_phy_80003es2lan(struct e1000_hw *hw); 4375eba5b6SRobert Mustacchi static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); 4475eba5b6SRobert Mustacchi static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); 4575eba5b6SRobert Mustacchi static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 4675eba5b6SRobert Mustacchi u32 offset, 4775eba5b6SRobert Mustacchi u16 *data); 4875eba5b6SRobert Mustacchi static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 4975eba5b6SRobert Mustacchi u32 offset, 5075eba5b6SRobert Mustacchi u16 data); 5175eba5b6SRobert Mustacchi static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, 5275eba5b6SRobert Mustacchi u16 words, u16 *data); 5375eba5b6SRobert Mustacchi static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); 5475eba5b6SRobert Mustacchi static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); 5575eba5b6SRobert Mustacchi static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); 5675eba5b6SRobert Mustacchi static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, 5775eba5b6SRobert Mustacchi u16 *duplex); 5875eba5b6SRobert Mustacchi static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); 5975eba5b6SRobert Mustacchi static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); 6075eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); 6175eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); 6275eba5b6SRobert Mustacchi static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); 6375eba5b6SRobert Mustacchi static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); 6475eba5b6SRobert Mustacchi static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); 6575eba5b6SRobert Mustacchi static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw); 6675eba5b6SRobert Mustacchi static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 6775eba5b6SRobert Mustacchi u16 *data); 6875eba5b6SRobert Mustacchi static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 6975eba5b6SRobert Mustacchi u16 data); 7075eba5b6SRobert Mustacchi static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); 7175eba5b6SRobert Mustacchi static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); 7275eba5b6SRobert Mustacchi static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); 7375eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); 7475eba5b6SRobert Mustacchi 75c124a83eSRobert Mustacchi /* A table for the GG82563 cable length where the range is defined 7675eba5b6SRobert Mustacchi * with a lower bound at "index" and the upper bound at 7775eba5b6SRobert Mustacchi * "index + 5". 7875eba5b6SRobert Mustacchi */ 7975eba5b6SRobert Mustacchi static const u16 e1000_gg82563_cable_length_table[] = { 8075eba5b6SRobert Mustacchi 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; 8175eba5b6SRobert Mustacchi #define GG82563_CABLE_LENGTH_TABLE_SIZE \ 8275eba5b6SRobert Mustacchi (sizeof(e1000_gg82563_cable_length_table) / \ 8375eba5b6SRobert Mustacchi sizeof(e1000_gg82563_cable_length_table[0])) 8475eba5b6SRobert Mustacchi 8575eba5b6SRobert Mustacchi /** 8675eba5b6SRobert Mustacchi * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. 8775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 8875eba5b6SRobert Mustacchi **/ 8975eba5b6SRobert Mustacchi static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) 9075eba5b6SRobert Mustacchi { 9175eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 92c124a83eSRobert Mustacchi s32 ret_val; 9375eba5b6SRobert Mustacchi 9475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_phy_params_80003es2lan"); 9575eba5b6SRobert Mustacchi 9675eba5b6SRobert Mustacchi if (hw->phy.media_type != e1000_media_type_copper) { 9775eba5b6SRobert Mustacchi phy->type = e1000_phy_none; 98c124a83eSRobert Mustacchi return E1000_SUCCESS; 9975eba5b6SRobert Mustacchi } else { 10075eba5b6SRobert Mustacchi phy->ops.power_up = e1000_power_up_phy_copper; 10175eba5b6SRobert Mustacchi phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; 10275eba5b6SRobert Mustacchi } 10375eba5b6SRobert Mustacchi 10475eba5b6SRobert Mustacchi phy->addr = 1; 10575eba5b6SRobert Mustacchi phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 10675eba5b6SRobert Mustacchi phy->reset_delay_us = 100; 10775eba5b6SRobert Mustacchi phy->type = e1000_phy_gg82563; 10875eba5b6SRobert Mustacchi 10975eba5b6SRobert Mustacchi phy->ops.acquire = e1000_acquire_phy_80003es2lan; 11075eba5b6SRobert Mustacchi phy->ops.check_polarity = e1000_check_polarity_m88; 11175eba5b6SRobert Mustacchi phy->ops.check_reset_block = e1000_check_reset_block_generic; 11275eba5b6SRobert Mustacchi phy->ops.commit = e1000_phy_sw_reset_generic; 11375eba5b6SRobert Mustacchi phy->ops.get_cfg_done = e1000_get_cfg_done_80003es2lan; 11475eba5b6SRobert Mustacchi phy->ops.get_info = e1000_get_phy_info_m88; 11575eba5b6SRobert Mustacchi phy->ops.release = e1000_release_phy_80003es2lan; 11675eba5b6SRobert Mustacchi phy->ops.reset = e1000_phy_hw_reset_generic; 11775eba5b6SRobert Mustacchi phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; 11875eba5b6SRobert Mustacchi 11975eba5b6SRobert Mustacchi phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan; 12075eba5b6SRobert Mustacchi phy->ops.get_cable_length = e1000_get_cable_length_80003es2lan; 12175eba5b6SRobert Mustacchi phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; 12275eba5b6SRobert Mustacchi phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; 12375eba5b6SRobert Mustacchi 12475eba5b6SRobert Mustacchi phy->ops.cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan; 12575eba5b6SRobert Mustacchi 12675eba5b6SRobert Mustacchi /* This can only be done after all function pointers are setup. */ 12775eba5b6SRobert Mustacchi ret_val = e1000_get_phy_id(hw); 12875eba5b6SRobert Mustacchi 12975eba5b6SRobert Mustacchi /* Verify phy id */ 130c124a83eSRobert Mustacchi if (phy->id != GG82563_E_PHY_ID) 131c124a83eSRobert Mustacchi return -E1000_ERR_PHY; 13275eba5b6SRobert Mustacchi 13375eba5b6SRobert Mustacchi return ret_val; 13475eba5b6SRobert Mustacchi } 13575eba5b6SRobert Mustacchi 13675eba5b6SRobert Mustacchi /** 13775eba5b6SRobert Mustacchi * e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs. 13875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 13975eba5b6SRobert Mustacchi **/ 14075eba5b6SRobert Mustacchi static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) 14175eba5b6SRobert Mustacchi { 14275eba5b6SRobert Mustacchi struct e1000_nvm_info *nvm = &hw->nvm; 14375eba5b6SRobert Mustacchi u32 eecd = E1000_READ_REG(hw, E1000_EECD); 14475eba5b6SRobert Mustacchi u16 size; 14575eba5b6SRobert Mustacchi 14675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_nvm_params_80003es2lan"); 14775eba5b6SRobert Mustacchi 14875eba5b6SRobert Mustacchi nvm->opcode_bits = 8; 14975eba5b6SRobert Mustacchi nvm->delay_usec = 1; 15075eba5b6SRobert Mustacchi switch (nvm->override) { 15175eba5b6SRobert Mustacchi case e1000_nvm_override_spi_large: 15275eba5b6SRobert Mustacchi nvm->page_size = 32; 15375eba5b6SRobert Mustacchi nvm->address_bits = 16; 15475eba5b6SRobert Mustacchi break; 15575eba5b6SRobert Mustacchi case e1000_nvm_override_spi_small: 15675eba5b6SRobert Mustacchi nvm->page_size = 8; 15775eba5b6SRobert Mustacchi nvm->address_bits = 8; 15875eba5b6SRobert Mustacchi break; 15975eba5b6SRobert Mustacchi default: 16075eba5b6SRobert Mustacchi nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; 16175eba5b6SRobert Mustacchi nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; 16275eba5b6SRobert Mustacchi break; 16375eba5b6SRobert Mustacchi } 16475eba5b6SRobert Mustacchi 16575eba5b6SRobert Mustacchi nvm->type = e1000_nvm_eeprom_spi; 16675eba5b6SRobert Mustacchi 16775eba5b6SRobert Mustacchi size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> 16875eba5b6SRobert Mustacchi E1000_EECD_SIZE_EX_SHIFT); 16975eba5b6SRobert Mustacchi 170c124a83eSRobert Mustacchi /* Added to a constant, "size" becomes the left-shift value 17175eba5b6SRobert Mustacchi * for setting word_size. 17275eba5b6SRobert Mustacchi */ 17375eba5b6SRobert Mustacchi size += NVM_WORD_SIZE_BASE_SHIFT; 17475eba5b6SRobert Mustacchi 17575eba5b6SRobert Mustacchi /* EEPROM access above 16k is unsupported */ 17675eba5b6SRobert Mustacchi if (size > 14) 17775eba5b6SRobert Mustacchi size = 14; 17875eba5b6SRobert Mustacchi nvm->word_size = 1 << size; 17975eba5b6SRobert Mustacchi 18075eba5b6SRobert Mustacchi /* Function Pointers */ 18175eba5b6SRobert Mustacchi nvm->ops.acquire = e1000_acquire_nvm_80003es2lan; 18275eba5b6SRobert Mustacchi nvm->ops.read = e1000_read_nvm_eerd; 18375eba5b6SRobert Mustacchi nvm->ops.release = e1000_release_nvm_80003es2lan; 18475eba5b6SRobert Mustacchi nvm->ops.update = e1000_update_nvm_checksum_generic; 18575eba5b6SRobert Mustacchi nvm->ops.valid_led_default = e1000_valid_led_default_generic; 18675eba5b6SRobert Mustacchi nvm->ops.validate = e1000_validate_nvm_checksum_generic; 18775eba5b6SRobert Mustacchi nvm->ops.write = e1000_write_nvm_80003es2lan; 18875eba5b6SRobert Mustacchi 18975eba5b6SRobert Mustacchi return E1000_SUCCESS; 19075eba5b6SRobert Mustacchi } 19175eba5b6SRobert Mustacchi 19275eba5b6SRobert Mustacchi /** 19375eba5b6SRobert Mustacchi * e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs. 19475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 19575eba5b6SRobert Mustacchi **/ 19675eba5b6SRobert Mustacchi static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) 19775eba5b6SRobert Mustacchi { 19875eba5b6SRobert Mustacchi struct e1000_mac_info *mac = &hw->mac; 19975eba5b6SRobert Mustacchi 20075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_mac_params_80003es2lan"); 20175eba5b6SRobert Mustacchi 20275eba5b6SRobert Mustacchi /* Set media type and media-dependent function pointers */ 20375eba5b6SRobert Mustacchi switch (hw->device_id) { 20475eba5b6SRobert Mustacchi case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: 20575eba5b6SRobert Mustacchi hw->phy.media_type = e1000_media_type_internal_serdes; 20675eba5b6SRobert Mustacchi mac->ops.check_for_link = e1000_check_for_serdes_link_generic; 20775eba5b6SRobert Mustacchi mac->ops.setup_physical_interface = 20875eba5b6SRobert Mustacchi e1000_setup_fiber_serdes_link_generic; 20975eba5b6SRobert Mustacchi break; 21075eba5b6SRobert Mustacchi default: 21175eba5b6SRobert Mustacchi hw->phy.media_type = e1000_media_type_copper; 21275eba5b6SRobert Mustacchi mac->ops.check_for_link = e1000_check_for_copper_link_generic; 21375eba5b6SRobert Mustacchi mac->ops.setup_physical_interface = 21475eba5b6SRobert Mustacchi e1000_setup_copper_link_80003es2lan; 21575eba5b6SRobert Mustacchi break; 21675eba5b6SRobert Mustacchi } 21775eba5b6SRobert Mustacchi 21875eba5b6SRobert Mustacchi /* Set mta register count */ 21975eba5b6SRobert Mustacchi mac->mta_reg_count = 128; 22075eba5b6SRobert Mustacchi /* Set rar entry count */ 22175eba5b6SRobert Mustacchi mac->rar_entry_count = E1000_RAR_ENTRIES; 22275eba5b6SRobert Mustacchi /* Set if part includes ASF firmware */ 22375eba5b6SRobert Mustacchi mac->asf_firmware_present = TRUE; 22475eba5b6SRobert Mustacchi /* FWSM register */ 22575eba5b6SRobert Mustacchi mac->has_fwsm = TRUE; 22675eba5b6SRobert Mustacchi /* ARC supported; valid only if manageability features are enabled. */ 227c124a83eSRobert Mustacchi mac->arc_subsystem_valid = !!(E1000_READ_REG(hw, E1000_FWSM) & 228c124a83eSRobert Mustacchi E1000_FWSM_MODE_MASK); 22975eba5b6SRobert Mustacchi /* Adaptive IFS not supported */ 23075eba5b6SRobert Mustacchi mac->adaptive_ifs = FALSE; 23175eba5b6SRobert Mustacchi 23275eba5b6SRobert Mustacchi /* Function pointers */ 23375eba5b6SRobert Mustacchi 23475eba5b6SRobert Mustacchi /* bus type/speed/width */ 23575eba5b6SRobert Mustacchi mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; 23675eba5b6SRobert Mustacchi /* reset */ 23775eba5b6SRobert Mustacchi mac->ops.reset_hw = e1000_reset_hw_80003es2lan; 23875eba5b6SRobert Mustacchi /* hw initialization */ 23975eba5b6SRobert Mustacchi mac->ops.init_hw = e1000_init_hw_80003es2lan; 24075eba5b6SRobert Mustacchi /* link setup */ 24175eba5b6SRobert Mustacchi mac->ops.setup_link = e1000_setup_link_generic; 24275eba5b6SRobert Mustacchi /* check management mode */ 24375eba5b6SRobert Mustacchi mac->ops.check_mng_mode = e1000_check_mng_mode_generic; 24475eba5b6SRobert Mustacchi /* multicast address update */ 24575eba5b6SRobert Mustacchi mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; 24675eba5b6SRobert Mustacchi /* writing VFTA */ 24775eba5b6SRobert Mustacchi mac->ops.write_vfta = e1000_write_vfta_generic; 24875eba5b6SRobert Mustacchi /* clearing VFTA */ 24975eba5b6SRobert Mustacchi mac->ops.clear_vfta = e1000_clear_vfta_generic; 25075eba5b6SRobert Mustacchi /* read mac address */ 25175eba5b6SRobert Mustacchi mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan; 25275eba5b6SRobert Mustacchi /* ID LED init */ 25375eba5b6SRobert Mustacchi mac->ops.id_led_init = e1000_id_led_init_generic; 25475eba5b6SRobert Mustacchi /* blink LED */ 25575eba5b6SRobert Mustacchi mac->ops.blink_led = e1000_blink_led_generic; 25675eba5b6SRobert Mustacchi /* setup LED */ 25775eba5b6SRobert Mustacchi mac->ops.setup_led = e1000_setup_led_generic; 25875eba5b6SRobert Mustacchi /* cleanup LED */ 25975eba5b6SRobert Mustacchi mac->ops.cleanup_led = e1000_cleanup_led_generic; 26075eba5b6SRobert Mustacchi /* turn on/off LED */ 26175eba5b6SRobert Mustacchi mac->ops.led_on = e1000_led_on_generic; 26275eba5b6SRobert Mustacchi mac->ops.led_off = e1000_led_off_generic; 26375eba5b6SRobert Mustacchi /* clear hardware counters */ 26475eba5b6SRobert Mustacchi mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan; 26575eba5b6SRobert Mustacchi /* link info */ 26675eba5b6SRobert Mustacchi mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan; 26775eba5b6SRobert Mustacchi 26875eba5b6SRobert Mustacchi /* set lan id for port to determine which phy lock to use */ 26975eba5b6SRobert Mustacchi hw->mac.ops.set_lan_id(hw); 27075eba5b6SRobert Mustacchi 27175eba5b6SRobert Mustacchi return E1000_SUCCESS; 27275eba5b6SRobert Mustacchi } 27375eba5b6SRobert Mustacchi 27475eba5b6SRobert Mustacchi /** 27575eba5b6SRobert Mustacchi * e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs. 27675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 27775eba5b6SRobert Mustacchi * 27875eba5b6SRobert Mustacchi * Called to initialize all function pointers and parameters. 27975eba5b6SRobert Mustacchi **/ 28075eba5b6SRobert Mustacchi void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) 28175eba5b6SRobert Mustacchi { 28275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_function_pointers_80003es2lan"); 28375eba5b6SRobert Mustacchi 28475eba5b6SRobert Mustacchi hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan; 28575eba5b6SRobert Mustacchi hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan; 28675eba5b6SRobert Mustacchi hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan; 28775eba5b6SRobert Mustacchi } 28875eba5b6SRobert Mustacchi 28975eba5b6SRobert Mustacchi /** 29075eba5b6SRobert Mustacchi * e1000_acquire_phy_80003es2lan - Acquire rights to access PHY 29175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 29275eba5b6SRobert Mustacchi * 29375eba5b6SRobert Mustacchi * A wrapper to acquire access rights to the correct PHY. 29475eba5b6SRobert Mustacchi **/ 29575eba5b6SRobert Mustacchi static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) 29675eba5b6SRobert Mustacchi { 29775eba5b6SRobert Mustacchi u16 mask; 29875eba5b6SRobert Mustacchi 29975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_phy_80003es2lan"); 30075eba5b6SRobert Mustacchi 30175eba5b6SRobert Mustacchi mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; 30275eba5b6SRobert Mustacchi return e1000_acquire_swfw_sync_80003es2lan(hw, mask); 30375eba5b6SRobert Mustacchi } 30475eba5b6SRobert Mustacchi 30575eba5b6SRobert Mustacchi /** 30675eba5b6SRobert Mustacchi * e1000_release_phy_80003es2lan - Release rights to access PHY 30775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 30875eba5b6SRobert Mustacchi * 30975eba5b6SRobert Mustacchi * A wrapper to release access rights to the correct PHY. 31075eba5b6SRobert Mustacchi **/ 31175eba5b6SRobert Mustacchi static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) 31275eba5b6SRobert Mustacchi { 31375eba5b6SRobert Mustacchi u16 mask; 31475eba5b6SRobert Mustacchi 31575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_phy_80003es2lan"); 31675eba5b6SRobert Mustacchi 31775eba5b6SRobert Mustacchi mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; 31875eba5b6SRobert Mustacchi e1000_release_swfw_sync_80003es2lan(hw, mask); 31975eba5b6SRobert Mustacchi } 32075eba5b6SRobert Mustacchi 32175eba5b6SRobert Mustacchi /** 32275eba5b6SRobert Mustacchi * e1000_acquire_mac_csr_80003es2lan - Acquire right to access Kumeran register 32375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 32475eba5b6SRobert Mustacchi * 32575eba5b6SRobert Mustacchi * Acquire the semaphore to access the Kumeran interface. 32675eba5b6SRobert Mustacchi * 32775eba5b6SRobert Mustacchi **/ 32875eba5b6SRobert Mustacchi static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw) 32975eba5b6SRobert Mustacchi { 33075eba5b6SRobert Mustacchi u16 mask; 33175eba5b6SRobert Mustacchi 33275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan"); 33375eba5b6SRobert Mustacchi 33475eba5b6SRobert Mustacchi mask = E1000_SWFW_CSR_SM; 33575eba5b6SRobert Mustacchi 33675eba5b6SRobert Mustacchi return e1000_acquire_swfw_sync_80003es2lan(hw, mask); 33775eba5b6SRobert Mustacchi } 33875eba5b6SRobert Mustacchi 33975eba5b6SRobert Mustacchi /** 34075eba5b6SRobert Mustacchi * e1000_release_mac_csr_80003es2lan - Release right to access Kumeran Register 34175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 34275eba5b6SRobert Mustacchi * 34375eba5b6SRobert Mustacchi * Release the semaphore used to access the Kumeran interface 34475eba5b6SRobert Mustacchi **/ 34575eba5b6SRobert Mustacchi static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw) 34675eba5b6SRobert Mustacchi { 34775eba5b6SRobert Mustacchi u16 mask; 34875eba5b6SRobert Mustacchi 34975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_mac_csr_80003es2lan"); 35075eba5b6SRobert Mustacchi 35175eba5b6SRobert Mustacchi mask = E1000_SWFW_CSR_SM; 35275eba5b6SRobert Mustacchi 35375eba5b6SRobert Mustacchi e1000_release_swfw_sync_80003es2lan(hw, mask); 35475eba5b6SRobert Mustacchi } 35575eba5b6SRobert Mustacchi 35675eba5b6SRobert Mustacchi /** 35775eba5b6SRobert Mustacchi * e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM 35875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 35975eba5b6SRobert Mustacchi * 36075eba5b6SRobert Mustacchi * Acquire the semaphore to access the EEPROM. 36175eba5b6SRobert Mustacchi **/ 36275eba5b6SRobert Mustacchi static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) 36375eba5b6SRobert Mustacchi { 36475eba5b6SRobert Mustacchi s32 ret_val; 36575eba5b6SRobert Mustacchi 36675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_nvm_80003es2lan"); 36775eba5b6SRobert Mustacchi 36875eba5b6SRobert Mustacchi ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); 36975eba5b6SRobert Mustacchi if (ret_val) 370c124a83eSRobert Mustacchi return ret_val; 37175eba5b6SRobert Mustacchi 37275eba5b6SRobert Mustacchi ret_val = e1000_acquire_nvm_generic(hw); 37375eba5b6SRobert Mustacchi 37475eba5b6SRobert Mustacchi if (ret_val) 37575eba5b6SRobert Mustacchi e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); 37675eba5b6SRobert Mustacchi 37775eba5b6SRobert Mustacchi return ret_val; 37875eba5b6SRobert Mustacchi } 37975eba5b6SRobert Mustacchi 38075eba5b6SRobert Mustacchi /** 38175eba5b6SRobert Mustacchi * e1000_release_nvm_80003es2lan - Relinquish rights to access NVM 38275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 38375eba5b6SRobert Mustacchi * 38475eba5b6SRobert Mustacchi * Release the semaphore used to access the EEPROM. 38575eba5b6SRobert Mustacchi **/ 38675eba5b6SRobert Mustacchi static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) 38775eba5b6SRobert Mustacchi { 38875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_nvm_80003es2lan"); 38975eba5b6SRobert Mustacchi 39075eba5b6SRobert Mustacchi e1000_release_nvm_generic(hw); 39175eba5b6SRobert Mustacchi e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); 39275eba5b6SRobert Mustacchi } 39375eba5b6SRobert Mustacchi 39475eba5b6SRobert Mustacchi /** 39575eba5b6SRobert Mustacchi * e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore 39675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 39775eba5b6SRobert Mustacchi * @mask: specifies which semaphore to acquire 39875eba5b6SRobert Mustacchi * 39975eba5b6SRobert Mustacchi * Acquire the SW/FW semaphore to access the PHY or NVM. The mask 40075eba5b6SRobert Mustacchi * will also specify which port we're acquiring the lock for. 40175eba5b6SRobert Mustacchi **/ 40275eba5b6SRobert Mustacchi static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) 40375eba5b6SRobert Mustacchi { 40475eba5b6SRobert Mustacchi u32 swfw_sync; 40575eba5b6SRobert Mustacchi u32 swmask = mask; 40675eba5b6SRobert Mustacchi u32 fwmask = mask << 16; 407c124a83eSRobert Mustacchi s32 i = 0; 408c124a83eSRobert Mustacchi s32 timeout = 50; 40975eba5b6SRobert Mustacchi 41075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan"); 41175eba5b6SRobert Mustacchi 41275eba5b6SRobert Mustacchi while (i < timeout) { 413c124a83eSRobert Mustacchi if (e1000_get_hw_semaphore_generic(hw)) 414c124a83eSRobert Mustacchi return -E1000_ERR_SWFW_SYNC; 41575eba5b6SRobert Mustacchi 41675eba5b6SRobert Mustacchi swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); 41775eba5b6SRobert Mustacchi if (!(swfw_sync & (fwmask | swmask))) 41875eba5b6SRobert Mustacchi break; 41975eba5b6SRobert Mustacchi 420c124a83eSRobert Mustacchi /* Firmware currently using resource (fwmask) 42175eba5b6SRobert Mustacchi * or other software thread using resource (swmask) 42275eba5b6SRobert Mustacchi */ 42375eba5b6SRobert Mustacchi e1000_put_hw_semaphore_generic(hw); 42475eba5b6SRobert Mustacchi msec_delay_irq(5); 42575eba5b6SRobert Mustacchi i++; 42675eba5b6SRobert Mustacchi } 42775eba5b6SRobert Mustacchi 42875eba5b6SRobert Mustacchi if (i == timeout) { 42975eba5b6SRobert Mustacchi DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 430c124a83eSRobert Mustacchi return -E1000_ERR_SWFW_SYNC; 43175eba5b6SRobert Mustacchi } 43275eba5b6SRobert Mustacchi 43375eba5b6SRobert Mustacchi swfw_sync |= swmask; 43475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); 43575eba5b6SRobert Mustacchi 43675eba5b6SRobert Mustacchi e1000_put_hw_semaphore_generic(hw); 43775eba5b6SRobert Mustacchi 438c124a83eSRobert Mustacchi return E1000_SUCCESS; 43975eba5b6SRobert Mustacchi } 44075eba5b6SRobert Mustacchi 44175eba5b6SRobert Mustacchi /** 44275eba5b6SRobert Mustacchi * e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore 44375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 44475eba5b6SRobert Mustacchi * @mask: specifies which semaphore to acquire 44575eba5b6SRobert Mustacchi * 44675eba5b6SRobert Mustacchi * Release the SW/FW semaphore used to access the PHY or NVM. The mask 44775eba5b6SRobert Mustacchi * will also specify which port we're releasing the lock for. 44875eba5b6SRobert Mustacchi **/ 44975eba5b6SRobert Mustacchi static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) 45075eba5b6SRobert Mustacchi { 45175eba5b6SRobert Mustacchi u32 swfw_sync; 45275eba5b6SRobert Mustacchi 45375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_release_swfw_sync_80003es2lan"); 45475eba5b6SRobert Mustacchi 45575eba5b6SRobert Mustacchi while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) 45675eba5b6SRobert Mustacchi ; /* Empty */ 45775eba5b6SRobert Mustacchi 45875eba5b6SRobert Mustacchi swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); 45975eba5b6SRobert Mustacchi swfw_sync &= ~mask; 46075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); 46175eba5b6SRobert Mustacchi 46275eba5b6SRobert Mustacchi e1000_put_hw_semaphore_generic(hw); 46375eba5b6SRobert Mustacchi } 46475eba5b6SRobert Mustacchi 46575eba5b6SRobert Mustacchi /** 46675eba5b6SRobert Mustacchi * e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register 46775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 46875eba5b6SRobert Mustacchi * @offset: offset of the register to read 46975eba5b6SRobert Mustacchi * @data: pointer to the data returned from the operation 47075eba5b6SRobert Mustacchi * 47175eba5b6SRobert Mustacchi * Read the GG82563 PHY register. 47275eba5b6SRobert Mustacchi **/ 47375eba5b6SRobert Mustacchi static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 47475eba5b6SRobert Mustacchi u32 offset, u16 *data) 47575eba5b6SRobert Mustacchi { 47675eba5b6SRobert Mustacchi s32 ret_val; 47775eba5b6SRobert Mustacchi u32 page_select; 47875eba5b6SRobert Mustacchi u16 temp; 47975eba5b6SRobert Mustacchi 48075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan"); 48175eba5b6SRobert Mustacchi 48275eba5b6SRobert Mustacchi ret_val = e1000_acquire_phy_80003es2lan(hw); 48375eba5b6SRobert Mustacchi if (ret_val) 484c124a83eSRobert Mustacchi return ret_val; 48575eba5b6SRobert Mustacchi 48675eba5b6SRobert Mustacchi /* Select Configuration Page */ 48775eba5b6SRobert Mustacchi if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { 48875eba5b6SRobert Mustacchi page_select = GG82563_PHY_PAGE_SELECT; 48975eba5b6SRobert Mustacchi } else { 490c124a83eSRobert Mustacchi /* Use Alternative Page Select register to access 49175eba5b6SRobert Mustacchi * registers 30 and 31 49275eba5b6SRobert Mustacchi */ 49375eba5b6SRobert Mustacchi page_select = GG82563_PHY_PAGE_SELECT_ALT; 49475eba5b6SRobert Mustacchi } 49575eba5b6SRobert Mustacchi 49675eba5b6SRobert Mustacchi temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); 49775eba5b6SRobert Mustacchi ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); 49875eba5b6SRobert Mustacchi if (ret_val) { 49975eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 500c124a83eSRobert Mustacchi return ret_val; 50175eba5b6SRobert Mustacchi } 50275eba5b6SRobert Mustacchi 503c124a83eSRobert Mustacchi if (hw->dev_spec._80003es2lan.mdic_wa_enable) { 504c124a83eSRobert Mustacchi /* The "ready" bit in the MDIC register may be incorrectly set 50575eba5b6SRobert Mustacchi * before the device has completed the "Page Select" MDI 50675eba5b6SRobert Mustacchi * transaction. So we wait 200us after each MDI command... 50775eba5b6SRobert Mustacchi */ 50875eba5b6SRobert Mustacchi usec_delay(200); 50975eba5b6SRobert Mustacchi 51075eba5b6SRobert Mustacchi /* ...and verify the command was successful. */ 51175eba5b6SRobert Mustacchi ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); 51275eba5b6SRobert Mustacchi 51375eba5b6SRobert Mustacchi if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { 51475eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 515c124a83eSRobert Mustacchi return -E1000_ERR_PHY; 51675eba5b6SRobert Mustacchi } 51775eba5b6SRobert Mustacchi 51875eba5b6SRobert Mustacchi usec_delay(200); 51975eba5b6SRobert Mustacchi 52075eba5b6SRobert Mustacchi ret_val = e1000_read_phy_reg_mdic(hw, 52175eba5b6SRobert Mustacchi MAX_PHY_REG_ADDRESS & offset, 52275eba5b6SRobert Mustacchi data); 52375eba5b6SRobert Mustacchi 52475eba5b6SRobert Mustacchi usec_delay(200); 52575eba5b6SRobert Mustacchi } else { 52675eba5b6SRobert Mustacchi ret_val = e1000_read_phy_reg_mdic(hw, 52775eba5b6SRobert Mustacchi MAX_PHY_REG_ADDRESS & offset, 52875eba5b6SRobert Mustacchi data); 52975eba5b6SRobert Mustacchi } 53075eba5b6SRobert Mustacchi 53175eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 53275eba5b6SRobert Mustacchi 53375eba5b6SRobert Mustacchi return ret_val; 53475eba5b6SRobert Mustacchi } 53575eba5b6SRobert Mustacchi 53675eba5b6SRobert Mustacchi /** 53775eba5b6SRobert Mustacchi * e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register 53875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 53975eba5b6SRobert Mustacchi * @offset: offset of the register to read 54075eba5b6SRobert Mustacchi * @data: value to write to the register 54175eba5b6SRobert Mustacchi * 54275eba5b6SRobert Mustacchi * Write to the GG82563 PHY register. 54375eba5b6SRobert Mustacchi **/ 54475eba5b6SRobert Mustacchi static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 54575eba5b6SRobert Mustacchi u32 offset, u16 data) 54675eba5b6SRobert Mustacchi { 54775eba5b6SRobert Mustacchi s32 ret_val; 54875eba5b6SRobert Mustacchi u32 page_select; 54975eba5b6SRobert Mustacchi u16 temp; 55075eba5b6SRobert Mustacchi 55175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan"); 55275eba5b6SRobert Mustacchi 55375eba5b6SRobert Mustacchi ret_val = e1000_acquire_phy_80003es2lan(hw); 55475eba5b6SRobert Mustacchi if (ret_val) 555c124a83eSRobert Mustacchi return ret_val; 55675eba5b6SRobert Mustacchi 55775eba5b6SRobert Mustacchi /* Select Configuration Page */ 55875eba5b6SRobert Mustacchi if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { 55975eba5b6SRobert Mustacchi page_select = GG82563_PHY_PAGE_SELECT; 56075eba5b6SRobert Mustacchi } else { 561c124a83eSRobert Mustacchi /* Use Alternative Page Select register to access 56275eba5b6SRobert Mustacchi * registers 30 and 31 56375eba5b6SRobert Mustacchi */ 56475eba5b6SRobert Mustacchi page_select = GG82563_PHY_PAGE_SELECT_ALT; 56575eba5b6SRobert Mustacchi } 56675eba5b6SRobert Mustacchi 56775eba5b6SRobert Mustacchi temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); 56875eba5b6SRobert Mustacchi ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); 56975eba5b6SRobert Mustacchi if (ret_val) { 57075eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 571c124a83eSRobert Mustacchi return ret_val; 57275eba5b6SRobert Mustacchi } 57375eba5b6SRobert Mustacchi 574c124a83eSRobert Mustacchi if (hw->dev_spec._80003es2lan.mdic_wa_enable) { 575c124a83eSRobert Mustacchi /* The "ready" bit in the MDIC register may be incorrectly set 57675eba5b6SRobert Mustacchi * before the device has completed the "Page Select" MDI 57775eba5b6SRobert Mustacchi * transaction. So we wait 200us after each MDI command... 57875eba5b6SRobert Mustacchi */ 57975eba5b6SRobert Mustacchi usec_delay(200); 58075eba5b6SRobert Mustacchi 58175eba5b6SRobert Mustacchi /* ...and verify the command was successful. */ 58275eba5b6SRobert Mustacchi ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); 58375eba5b6SRobert Mustacchi 58475eba5b6SRobert Mustacchi if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { 58575eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 586c124a83eSRobert Mustacchi return -E1000_ERR_PHY; 58775eba5b6SRobert Mustacchi } 58875eba5b6SRobert Mustacchi 58975eba5b6SRobert Mustacchi usec_delay(200); 59075eba5b6SRobert Mustacchi 59175eba5b6SRobert Mustacchi ret_val = e1000_write_phy_reg_mdic(hw, 59275eba5b6SRobert Mustacchi MAX_PHY_REG_ADDRESS & offset, 59375eba5b6SRobert Mustacchi data); 59475eba5b6SRobert Mustacchi 59575eba5b6SRobert Mustacchi usec_delay(200); 59675eba5b6SRobert Mustacchi } else { 59775eba5b6SRobert Mustacchi ret_val = e1000_write_phy_reg_mdic(hw, 59875eba5b6SRobert Mustacchi MAX_PHY_REG_ADDRESS & offset, 59975eba5b6SRobert Mustacchi data); 60075eba5b6SRobert Mustacchi } 60175eba5b6SRobert Mustacchi 60275eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 60375eba5b6SRobert Mustacchi 60475eba5b6SRobert Mustacchi return ret_val; 60575eba5b6SRobert Mustacchi } 60675eba5b6SRobert Mustacchi 60775eba5b6SRobert Mustacchi /** 60875eba5b6SRobert Mustacchi * e1000_write_nvm_80003es2lan - Write to ESB2 NVM 60975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 61075eba5b6SRobert Mustacchi * @offset: offset of the register to read 61175eba5b6SRobert Mustacchi * @words: number of words to write 61275eba5b6SRobert Mustacchi * @data: buffer of data to write to the NVM 61375eba5b6SRobert Mustacchi * 61475eba5b6SRobert Mustacchi * Write "words" of data to the ESB2 NVM. 61575eba5b6SRobert Mustacchi **/ 61675eba5b6SRobert Mustacchi static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, 61775eba5b6SRobert Mustacchi u16 words, u16 *data) 61875eba5b6SRobert Mustacchi { 61975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_nvm_80003es2lan"); 62075eba5b6SRobert Mustacchi 62175eba5b6SRobert Mustacchi return e1000_write_nvm_spi(hw, offset, words, data); 62275eba5b6SRobert Mustacchi } 62375eba5b6SRobert Mustacchi 62475eba5b6SRobert Mustacchi /** 62575eba5b6SRobert Mustacchi * e1000_get_cfg_done_80003es2lan - Wait for configuration to complete 62675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 62775eba5b6SRobert Mustacchi * 62875eba5b6SRobert Mustacchi * Wait a specific amount of time for manageability processes to complete. 62975eba5b6SRobert Mustacchi * This is a function pointer entry point called by the phy module. 63075eba5b6SRobert Mustacchi **/ 63175eba5b6SRobert Mustacchi static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) 63275eba5b6SRobert Mustacchi { 63375eba5b6SRobert Mustacchi s32 timeout = PHY_CFG_TIMEOUT; 63475eba5b6SRobert Mustacchi u32 mask = E1000_NVM_CFG_DONE_PORT_0; 63575eba5b6SRobert Mustacchi 63675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_cfg_done_80003es2lan"); 63775eba5b6SRobert Mustacchi 63875eba5b6SRobert Mustacchi if (hw->bus.func == 1) 63975eba5b6SRobert Mustacchi mask = E1000_NVM_CFG_DONE_PORT_1; 64075eba5b6SRobert Mustacchi 64175eba5b6SRobert Mustacchi while (timeout) { 64275eba5b6SRobert Mustacchi if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask) 64375eba5b6SRobert Mustacchi break; 64475eba5b6SRobert Mustacchi msec_delay(1); 64575eba5b6SRobert Mustacchi timeout--; 64675eba5b6SRobert Mustacchi } 64775eba5b6SRobert Mustacchi if (!timeout) { 64875eba5b6SRobert Mustacchi DEBUGOUT("MNG configuration cycle has not completed.\n"); 649c124a83eSRobert Mustacchi return -E1000_ERR_RESET; 65075eba5b6SRobert Mustacchi } 65175eba5b6SRobert Mustacchi 652c124a83eSRobert Mustacchi return E1000_SUCCESS; 65375eba5b6SRobert Mustacchi } 65475eba5b6SRobert Mustacchi 65575eba5b6SRobert Mustacchi /** 65675eba5b6SRobert Mustacchi * e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex 65775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 65875eba5b6SRobert Mustacchi * 65975eba5b6SRobert Mustacchi * Force the speed and duplex settings onto the PHY. This is a 66075eba5b6SRobert Mustacchi * function pointer entry point called by the phy module. 66175eba5b6SRobert Mustacchi **/ 66275eba5b6SRobert Mustacchi static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) 66375eba5b6SRobert Mustacchi { 664c124a83eSRobert Mustacchi s32 ret_val; 66575eba5b6SRobert Mustacchi u16 phy_data; 66675eba5b6SRobert Mustacchi bool link; 66775eba5b6SRobert Mustacchi 66875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); 66975eba5b6SRobert Mustacchi 67075eba5b6SRobert Mustacchi if (!(hw->phy.ops.read_reg)) 671c124a83eSRobert Mustacchi return E1000_SUCCESS; 67275eba5b6SRobert Mustacchi 673c124a83eSRobert Mustacchi /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI 67475eba5b6SRobert Mustacchi * forced whenever speed and duplex are forced. 67575eba5b6SRobert Mustacchi */ 67675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); 67775eba5b6SRobert Mustacchi if (ret_val) 678c124a83eSRobert Mustacchi return ret_val; 67975eba5b6SRobert Mustacchi 68075eba5b6SRobert Mustacchi phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; 68175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); 68275eba5b6SRobert Mustacchi if (ret_val) 683c124a83eSRobert Mustacchi return ret_val; 68475eba5b6SRobert Mustacchi 68575eba5b6SRobert Mustacchi DEBUGOUT1("GG82563 PSCR: %X\n", phy_data); 68675eba5b6SRobert Mustacchi 68775eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data); 68875eba5b6SRobert Mustacchi if (ret_val) 689c124a83eSRobert Mustacchi return ret_val; 69075eba5b6SRobert Mustacchi 69175eba5b6SRobert Mustacchi e1000_phy_force_speed_duplex_setup(hw, &phy_data); 69275eba5b6SRobert Mustacchi 69375eba5b6SRobert Mustacchi /* Reset the phy to commit changes. */ 69475eba5b6SRobert Mustacchi phy_data |= MII_CR_RESET; 69575eba5b6SRobert Mustacchi 69675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data); 69775eba5b6SRobert Mustacchi if (ret_val) 698c124a83eSRobert Mustacchi return ret_val; 69975eba5b6SRobert Mustacchi 70075eba5b6SRobert Mustacchi usec_delay(1); 70175eba5b6SRobert Mustacchi 70275eba5b6SRobert Mustacchi if (hw->phy.autoneg_wait_to_complete) { 70375eba5b6SRobert Mustacchi DEBUGOUT("Waiting for forced speed/duplex link on GG82563 phy.\n"); 70475eba5b6SRobert Mustacchi 70575eba5b6SRobert Mustacchi ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 70675eba5b6SRobert Mustacchi 100000, &link); 70775eba5b6SRobert Mustacchi if (ret_val) 708c124a83eSRobert Mustacchi return ret_val; 70975eba5b6SRobert Mustacchi 71075eba5b6SRobert Mustacchi if (!link) { 711c124a83eSRobert Mustacchi /* We didn't get link. 71275eba5b6SRobert Mustacchi * Reset the DSP and cross our fingers. 71375eba5b6SRobert Mustacchi */ 71475eba5b6SRobert Mustacchi ret_val = e1000_phy_reset_dsp_generic(hw); 71575eba5b6SRobert Mustacchi if (ret_val) 716c124a83eSRobert Mustacchi return ret_val; 71775eba5b6SRobert Mustacchi } 71875eba5b6SRobert Mustacchi 71975eba5b6SRobert Mustacchi /* Try once more */ 72075eba5b6SRobert Mustacchi ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 72175eba5b6SRobert Mustacchi 100000, &link); 72275eba5b6SRobert Mustacchi if (ret_val) 723c124a83eSRobert Mustacchi return ret_val; 72475eba5b6SRobert Mustacchi } 72575eba5b6SRobert Mustacchi 72675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, 72775eba5b6SRobert Mustacchi &phy_data); 72875eba5b6SRobert Mustacchi if (ret_val) 729c124a83eSRobert Mustacchi return ret_val; 73075eba5b6SRobert Mustacchi 731c124a83eSRobert Mustacchi /* Resetting the phy means we need to verify the TX_CLK corresponds 73275eba5b6SRobert Mustacchi * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. 73375eba5b6SRobert Mustacchi */ 73475eba5b6SRobert Mustacchi phy_data &= ~GG82563_MSCR_TX_CLK_MASK; 73575eba5b6SRobert Mustacchi if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED) 73675eba5b6SRobert Mustacchi phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5; 73775eba5b6SRobert Mustacchi else 73875eba5b6SRobert Mustacchi phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; 73975eba5b6SRobert Mustacchi 740c124a83eSRobert Mustacchi /* In addition, we must re-enable CRS on Tx for both half and full 74175eba5b6SRobert Mustacchi * duplex. 74275eba5b6SRobert Mustacchi */ 74375eba5b6SRobert Mustacchi phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; 74475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, 74575eba5b6SRobert Mustacchi phy_data); 74675eba5b6SRobert Mustacchi 74775eba5b6SRobert Mustacchi return ret_val; 74875eba5b6SRobert Mustacchi } 74975eba5b6SRobert Mustacchi 75075eba5b6SRobert Mustacchi /** 75175eba5b6SRobert Mustacchi * e1000_get_cable_length_80003es2lan - Set approximate cable length 75275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 75375eba5b6SRobert Mustacchi * 75475eba5b6SRobert Mustacchi * Find the approximate cable length as measured by the GG82563 PHY. 75575eba5b6SRobert Mustacchi * This is a function pointer entry point called by the phy module. 75675eba5b6SRobert Mustacchi **/ 75775eba5b6SRobert Mustacchi static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) 75875eba5b6SRobert Mustacchi { 75975eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 760c124a83eSRobert Mustacchi s32 ret_val; 76175eba5b6SRobert Mustacchi u16 phy_data, index; 76275eba5b6SRobert Mustacchi 76375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_cable_length_80003es2lan"); 76475eba5b6SRobert Mustacchi 76575eba5b6SRobert Mustacchi if (!(hw->phy.ops.read_reg)) 766c124a83eSRobert Mustacchi return E1000_SUCCESS; 76775eba5b6SRobert Mustacchi 76875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); 76975eba5b6SRobert Mustacchi if (ret_val) 770c124a83eSRobert Mustacchi return ret_val; 77175eba5b6SRobert Mustacchi 77275eba5b6SRobert Mustacchi index = phy_data & GG82563_DSPD_CABLE_LENGTH; 77375eba5b6SRobert Mustacchi 774c124a83eSRobert Mustacchi if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) 775c124a83eSRobert Mustacchi return -E1000_ERR_PHY; 77675eba5b6SRobert Mustacchi 77775eba5b6SRobert Mustacchi phy->min_cable_length = e1000_gg82563_cable_length_table[index]; 77875eba5b6SRobert Mustacchi phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5]; 77975eba5b6SRobert Mustacchi 78075eba5b6SRobert Mustacchi phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; 78175eba5b6SRobert Mustacchi 782c124a83eSRobert Mustacchi return E1000_SUCCESS; 78375eba5b6SRobert Mustacchi } 78475eba5b6SRobert Mustacchi 78575eba5b6SRobert Mustacchi /** 78675eba5b6SRobert Mustacchi * e1000_get_link_up_info_80003es2lan - Report speed and duplex 78775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 78875eba5b6SRobert Mustacchi * @speed: pointer to speed buffer 78975eba5b6SRobert Mustacchi * @duplex: pointer to duplex buffer 79075eba5b6SRobert Mustacchi * 79175eba5b6SRobert Mustacchi * Retrieve the current speed and duplex configuration. 79275eba5b6SRobert Mustacchi **/ 79375eba5b6SRobert Mustacchi static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, 79475eba5b6SRobert Mustacchi u16 *duplex) 79575eba5b6SRobert Mustacchi { 79675eba5b6SRobert Mustacchi s32 ret_val; 79775eba5b6SRobert Mustacchi 79875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_get_link_up_info_80003es2lan"); 79975eba5b6SRobert Mustacchi 80075eba5b6SRobert Mustacchi if (hw->phy.media_type == e1000_media_type_copper) { 80175eba5b6SRobert Mustacchi ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, 80275eba5b6SRobert Mustacchi duplex); 80375eba5b6SRobert Mustacchi hw->phy.ops.cfg_on_link_up(hw); 80475eba5b6SRobert Mustacchi } else { 80575eba5b6SRobert Mustacchi ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, 80675eba5b6SRobert Mustacchi speed, 80775eba5b6SRobert Mustacchi duplex); 80875eba5b6SRobert Mustacchi } 80975eba5b6SRobert Mustacchi 81075eba5b6SRobert Mustacchi return ret_val; 81175eba5b6SRobert Mustacchi } 81275eba5b6SRobert Mustacchi 81375eba5b6SRobert Mustacchi /** 81475eba5b6SRobert Mustacchi * e1000_reset_hw_80003es2lan - Reset the ESB2 controller 81575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 81675eba5b6SRobert Mustacchi * 81775eba5b6SRobert Mustacchi * Perform a global reset to the ESB2 controller. 81875eba5b6SRobert Mustacchi **/ 81975eba5b6SRobert Mustacchi static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) 82075eba5b6SRobert Mustacchi { 82175eba5b6SRobert Mustacchi u32 ctrl; 82275eba5b6SRobert Mustacchi s32 ret_val; 823c124a83eSRobert Mustacchi u16 kum_reg_data; 82475eba5b6SRobert Mustacchi 82575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_reset_hw_80003es2lan"); 82675eba5b6SRobert Mustacchi 827c124a83eSRobert Mustacchi /* Prevent the PCI-E bus from sticking if there is no TLP connection 82875eba5b6SRobert Mustacchi * on the last TLP read/write transaction when MAC is reset. 82975eba5b6SRobert Mustacchi */ 83075eba5b6SRobert Mustacchi ret_val = e1000_disable_pcie_master_generic(hw); 83175eba5b6SRobert Mustacchi if (ret_val) 83275eba5b6SRobert Mustacchi DEBUGOUT("PCI-E Master disable polling has failed.\n"); 83375eba5b6SRobert Mustacchi 83475eba5b6SRobert Mustacchi DEBUGOUT("Masking off all interrupts\n"); 83575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 83675eba5b6SRobert Mustacchi 83775eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_RCTL, 0); 83875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); 83975eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 84075eba5b6SRobert Mustacchi 84175eba5b6SRobert Mustacchi msec_delay(10); 84275eba5b6SRobert Mustacchi 84375eba5b6SRobert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL); 84475eba5b6SRobert Mustacchi 84575eba5b6SRobert Mustacchi ret_val = e1000_acquire_phy_80003es2lan(hw); 846c124a83eSRobert Mustacchi if (ret_val) 847c124a83eSRobert Mustacchi return ret_val; 848c124a83eSRobert Mustacchi 84975eba5b6SRobert Mustacchi DEBUGOUT("Issuing a global reset to MAC\n"); 85075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); 85175eba5b6SRobert Mustacchi e1000_release_phy_80003es2lan(hw); 85275eba5b6SRobert Mustacchi 853c124a83eSRobert Mustacchi /* Disable IBIST slave mode (far-end loopback) */ 854*42cc51e0SRobert Mustacchi ret_val = e1000_read_kmrn_reg_80003es2lan(hw, 855*42cc51e0SRobert Mustacchi E1000_KMRNCTRLSTA_INBAND_PARAM, &kum_reg_data); 856*42cc51e0SRobert Mustacchi if (!ret_val) { 857c124a83eSRobert Mustacchi kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE; 858*42cc51e0SRobert Mustacchi ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 859*42cc51e0SRobert Mustacchi E1000_KMRNCTRLSTA_INBAND_PARAM, 860c124a83eSRobert Mustacchi kum_reg_data); 861*42cc51e0SRobert Mustacchi if (ret_val) 862*42cc51e0SRobert Mustacchi DEBUGOUT("Error disabling far-end loopback\n"); 863*42cc51e0SRobert Mustacchi } else 864*42cc51e0SRobert Mustacchi DEBUGOUT("Error disabling far-end loopback\n"); 865c124a83eSRobert Mustacchi 86675eba5b6SRobert Mustacchi ret_val = e1000_get_auto_rd_done_generic(hw); 86775eba5b6SRobert Mustacchi if (ret_val) 86875eba5b6SRobert Mustacchi /* We don't want to continue accessing MAC registers. */ 869c124a83eSRobert Mustacchi return ret_val; 87075eba5b6SRobert Mustacchi 87175eba5b6SRobert Mustacchi /* Clear any pending interrupt events. */ 87275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 87375eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICR); 87475eba5b6SRobert Mustacchi 875c124a83eSRobert Mustacchi return e1000_check_alt_mac_addr_generic(hw); 87675eba5b6SRobert Mustacchi } 87775eba5b6SRobert Mustacchi 87875eba5b6SRobert Mustacchi /** 87975eba5b6SRobert Mustacchi * e1000_init_hw_80003es2lan - Initialize the ESB2 controller 88075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 88175eba5b6SRobert Mustacchi * 88275eba5b6SRobert Mustacchi * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. 88375eba5b6SRobert Mustacchi **/ 88475eba5b6SRobert Mustacchi static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) 88575eba5b6SRobert Mustacchi { 88675eba5b6SRobert Mustacchi struct e1000_mac_info *mac = &hw->mac; 88775eba5b6SRobert Mustacchi u32 reg_data; 88875eba5b6SRobert Mustacchi s32 ret_val; 88975eba5b6SRobert Mustacchi u16 kum_reg_data; 89075eba5b6SRobert Mustacchi u16 i; 89175eba5b6SRobert Mustacchi 89275eba5b6SRobert Mustacchi DEBUGFUNC("e1000_init_hw_80003es2lan"); 89375eba5b6SRobert Mustacchi 89475eba5b6SRobert Mustacchi e1000_initialize_hw_bits_80003es2lan(hw); 89575eba5b6SRobert Mustacchi 89675eba5b6SRobert Mustacchi /* Initialize identification LED */ 89775eba5b6SRobert Mustacchi ret_val = mac->ops.id_led_init(hw); 898c124a83eSRobert Mustacchi /* An error is not fatal and we should not stop init due to this */ 89975eba5b6SRobert Mustacchi if (ret_val) 90075eba5b6SRobert Mustacchi DEBUGOUT("Error initializing identification LED\n"); 90175eba5b6SRobert Mustacchi 90275eba5b6SRobert Mustacchi /* Disabling VLAN filtering */ 90375eba5b6SRobert Mustacchi DEBUGOUT("Initializing the IEEE VLAN\n"); 90475eba5b6SRobert Mustacchi mac->ops.clear_vfta(hw); 90575eba5b6SRobert Mustacchi 90675eba5b6SRobert Mustacchi /* Setup the receive address. */ 90775eba5b6SRobert Mustacchi e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); 90875eba5b6SRobert Mustacchi 90975eba5b6SRobert Mustacchi /* Zero out the Multicast HASH table */ 91075eba5b6SRobert Mustacchi DEBUGOUT("Zeroing the MTA\n"); 91175eba5b6SRobert Mustacchi for (i = 0; i < mac->mta_reg_count; i++) 91275eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); 91375eba5b6SRobert Mustacchi 91475eba5b6SRobert Mustacchi /* Setup link and flow control */ 91575eba5b6SRobert Mustacchi ret_val = mac->ops.setup_link(hw); 916c124a83eSRobert Mustacchi if (ret_val) 917c124a83eSRobert Mustacchi return ret_val; 91875eba5b6SRobert Mustacchi 91975eba5b6SRobert Mustacchi /* Disable IBIST slave mode (far-end loopback) */ 920*42cc51e0SRobert Mustacchi ret_val = 92175eba5b6SRobert Mustacchi e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, 92275eba5b6SRobert Mustacchi &kum_reg_data); 923*42cc51e0SRobert Mustacchi if (!ret_val) { 92475eba5b6SRobert Mustacchi kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE; 925*42cc51e0SRobert Mustacchi ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 926*42cc51e0SRobert Mustacchi E1000_KMRNCTRLSTA_INBAND_PARAM, 92775eba5b6SRobert Mustacchi kum_reg_data); 928*42cc51e0SRobert Mustacchi if (ret_val) 929*42cc51e0SRobert Mustacchi DEBUGOUT("Error disabling far-end loopback\n"); 930*42cc51e0SRobert Mustacchi } else 931*42cc51e0SRobert Mustacchi DEBUGOUT("Error disabling far-end loopback\n"); 93275eba5b6SRobert Mustacchi 93375eba5b6SRobert Mustacchi /* Set the transmit descriptor write-back policy */ 93475eba5b6SRobert Mustacchi reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); 935c124a83eSRobert Mustacchi reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | 936c124a83eSRobert Mustacchi E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); 93775eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); 93875eba5b6SRobert Mustacchi 93975eba5b6SRobert Mustacchi /* ...for both queues. */ 94075eba5b6SRobert Mustacchi reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); 941c124a83eSRobert Mustacchi reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | 942c124a83eSRobert Mustacchi E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); 94375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); 94475eba5b6SRobert Mustacchi 94575eba5b6SRobert Mustacchi /* Enable retransmit on late collisions */ 94675eba5b6SRobert Mustacchi reg_data = E1000_READ_REG(hw, E1000_TCTL); 94775eba5b6SRobert Mustacchi reg_data |= E1000_TCTL_RTLC; 94875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL, reg_data); 94975eba5b6SRobert Mustacchi 95075eba5b6SRobert Mustacchi /* Configure Gigabit Carry Extend Padding */ 95175eba5b6SRobert Mustacchi reg_data = E1000_READ_REG(hw, E1000_TCTL_EXT); 95275eba5b6SRobert Mustacchi reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; 95375eba5b6SRobert Mustacchi reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN; 95475eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TCTL_EXT, reg_data); 95575eba5b6SRobert Mustacchi 95675eba5b6SRobert Mustacchi /* Configure Transmit Inter-Packet Gap */ 95775eba5b6SRobert Mustacchi reg_data = E1000_READ_REG(hw, E1000_TIPG); 95875eba5b6SRobert Mustacchi reg_data &= ~E1000_TIPG_IPGT_MASK; 95975eba5b6SRobert Mustacchi reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; 96075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TIPG, reg_data); 96175eba5b6SRobert Mustacchi 96275eba5b6SRobert Mustacchi reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001); 96375eba5b6SRobert Mustacchi reg_data &= ~0x00100000; 96475eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); 96575eba5b6SRobert Mustacchi 96675eba5b6SRobert Mustacchi /* default to TRUE to enable the MDIC W/A */ 96775eba5b6SRobert Mustacchi hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE; 96875eba5b6SRobert Mustacchi 969c124a83eSRobert Mustacchi ret_val = 970c124a83eSRobert Mustacchi e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET >> 971c124a83eSRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET_SHIFT, &i); 97275eba5b6SRobert Mustacchi if (!ret_val) { 97375eba5b6SRobert Mustacchi if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == 97475eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) 97575eba5b6SRobert Mustacchi hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE; 97675eba5b6SRobert Mustacchi } 97775eba5b6SRobert Mustacchi 978c124a83eSRobert Mustacchi /* Clear all of the statistics registers (clear on read). It is 97975eba5b6SRobert Mustacchi * important that we do this after we have tried to establish link 98075eba5b6SRobert Mustacchi * because the symbol error count will increment wildly if there 98175eba5b6SRobert Mustacchi * is no link. 98275eba5b6SRobert Mustacchi */ 98375eba5b6SRobert Mustacchi e1000_clear_hw_cntrs_80003es2lan(hw); 98475eba5b6SRobert Mustacchi 98575eba5b6SRobert Mustacchi return ret_val; 98675eba5b6SRobert Mustacchi } 98775eba5b6SRobert Mustacchi 98875eba5b6SRobert Mustacchi /** 98975eba5b6SRobert Mustacchi * e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2 99075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 99175eba5b6SRobert Mustacchi * 99275eba5b6SRobert Mustacchi * Initializes required hardware-dependent bits needed for normal operation. 99375eba5b6SRobert Mustacchi **/ 99475eba5b6SRobert Mustacchi static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) 99575eba5b6SRobert Mustacchi { 99675eba5b6SRobert Mustacchi u32 reg; 99775eba5b6SRobert Mustacchi 99875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan"); 99975eba5b6SRobert Mustacchi 100075eba5b6SRobert Mustacchi /* Transmit Descriptor Control 0 */ 100175eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); 100275eba5b6SRobert Mustacchi reg |= (1 << 22); 100375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); 100475eba5b6SRobert Mustacchi 100575eba5b6SRobert Mustacchi /* Transmit Descriptor Control 1 */ 100675eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); 100775eba5b6SRobert Mustacchi reg |= (1 << 22); 100875eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); 100975eba5b6SRobert Mustacchi 101075eba5b6SRobert Mustacchi /* Transmit Arbitration Control 0 */ 101175eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TARC(0)); 101275eba5b6SRobert Mustacchi reg &= ~(0xF << 27); /* 30:27 */ 101375eba5b6SRobert Mustacchi if (hw->phy.media_type != e1000_media_type_copper) 101475eba5b6SRobert Mustacchi reg &= ~(1 << 20); 101575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TARC(0), reg); 101675eba5b6SRobert Mustacchi 101775eba5b6SRobert Mustacchi /* Transmit Arbitration Control 1 */ 101875eba5b6SRobert Mustacchi reg = E1000_READ_REG(hw, E1000_TARC(1)); 101975eba5b6SRobert Mustacchi if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) 102075eba5b6SRobert Mustacchi reg &= ~(1 << 28); 102175eba5b6SRobert Mustacchi else 102275eba5b6SRobert Mustacchi reg |= (1 << 28); 102375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TARC(1), reg); 102475eba5b6SRobert Mustacchi 1025c124a83eSRobert Mustacchi /* Disable IPv6 extension header parsing because some malformed 1026c124a83eSRobert Mustacchi * IPv6 headers can hang the Rx. 1027c124a83eSRobert Mustacchi */ 1028c124a83eSRobert Mustacchi reg = E1000_READ_REG(hw, E1000_RFCTL); 1029c124a83eSRobert Mustacchi reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); 1030c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_RFCTL, reg); 1031c124a83eSRobert Mustacchi 103275eba5b6SRobert Mustacchi return; 103375eba5b6SRobert Mustacchi } 103475eba5b6SRobert Mustacchi 103575eba5b6SRobert Mustacchi /** 103675eba5b6SRobert Mustacchi * e1000_copper_link_setup_gg82563_80003es2lan - Configure GG82563 Link 103775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 103875eba5b6SRobert Mustacchi * 103975eba5b6SRobert Mustacchi * Setup some GG82563 PHY registers for obtaining link 104075eba5b6SRobert Mustacchi **/ 104175eba5b6SRobert Mustacchi static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) 104275eba5b6SRobert Mustacchi { 104375eba5b6SRobert Mustacchi struct e1000_phy_info *phy = &hw->phy; 104475eba5b6SRobert Mustacchi s32 ret_val; 1045c124a83eSRobert Mustacchi u32 reg; 104675eba5b6SRobert Mustacchi u16 data; 104775eba5b6SRobert Mustacchi 104875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); 104975eba5b6SRobert Mustacchi 105075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &data); 105175eba5b6SRobert Mustacchi if (ret_val) 1052c124a83eSRobert Mustacchi return ret_val; 105375eba5b6SRobert Mustacchi 105475eba5b6SRobert Mustacchi data |= GG82563_MSCR_ASSERT_CRS_ON_TX; 105575eba5b6SRobert Mustacchi /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ 105675eba5b6SRobert Mustacchi data |= GG82563_MSCR_TX_CLK_1000MBPS_25; 105775eba5b6SRobert Mustacchi 105875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, data); 105975eba5b6SRobert Mustacchi if (ret_val) 1060c124a83eSRobert Mustacchi return ret_val; 106175eba5b6SRobert Mustacchi 1062c124a83eSRobert Mustacchi /* Options: 106375eba5b6SRobert Mustacchi * MDI/MDI-X = 0 (default) 106475eba5b6SRobert Mustacchi * 0 - Auto for all speeds 106575eba5b6SRobert Mustacchi * 1 - MDI mode 106675eba5b6SRobert Mustacchi * 2 - MDI-X mode 106775eba5b6SRobert Mustacchi * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) 106875eba5b6SRobert Mustacchi */ 106975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); 107075eba5b6SRobert Mustacchi if (ret_val) 1071c124a83eSRobert Mustacchi return ret_val; 107275eba5b6SRobert Mustacchi 107375eba5b6SRobert Mustacchi data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; 107475eba5b6SRobert Mustacchi 107575eba5b6SRobert Mustacchi switch (phy->mdix) { 107675eba5b6SRobert Mustacchi case 1: 107775eba5b6SRobert Mustacchi data |= GG82563_PSCR_CROSSOVER_MODE_MDI; 107875eba5b6SRobert Mustacchi break; 107975eba5b6SRobert Mustacchi case 2: 108075eba5b6SRobert Mustacchi data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; 108175eba5b6SRobert Mustacchi break; 108275eba5b6SRobert Mustacchi case 0: 108375eba5b6SRobert Mustacchi default: 108475eba5b6SRobert Mustacchi data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; 108575eba5b6SRobert Mustacchi break; 108675eba5b6SRobert Mustacchi } 108775eba5b6SRobert Mustacchi 1088c124a83eSRobert Mustacchi /* Options: 108975eba5b6SRobert Mustacchi * disable_polarity_correction = 0 (default) 109075eba5b6SRobert Mustacchi * Automatic Correction for Reversed Cable Polarity 109175eba5b6SRobert Mustacchi * 0 - Disabled 109275eba5b6SRobert Mustacchi * 1 - Enabled 109375eba5b6SRobert Mustacchi */ 109475eba5b6SRobert Mustacchi data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; 109575eba5b6SRobert Mustacchi if (phy->disable_polarity_correction) 109675eba5b6SRobert Mustacchi data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; 109775eba5b6SRobert Mustacchi 109875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); 109975eba5b6SRobert Mustacchi if (ret_val) 1100c124a83eSRobert Mustacchi return ret_val; 110175eba5b6SRobert Mustacchi 110275eba5b6SRobert Mustacchi /* SW Reset the PHY so all changes take effect */ 110375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.commit(hw); 110475eba5b6SRobert Mustacchi if (ret_val) { 110575eba5b6SRobert Mustacchi DEBUGOUT("Error Resetting the PHY\n"); 1106c124a83eSRobert Mustacchi return ret_val; 110775eba5b6SRobert Mustacchi } 110875eba5b6SRobert Mustacchi 110975eba5b6SRobert Mustacchi /* Bypass Rx and Tx FIFO's */ 1110c124a83eSRobert Mustacchi reg = E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL; 1111c124a83eSRobert Mustacchi data = (E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | 111275eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); 1113c124a83eSRobert Mustacchi ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data); 111475eba5b6SRobert Mustacchi if (ret_val) 1115c124a83eSRobert Mustacchi return ret_val; 111675eba5b6SRobert Mustacchi 1117c124a83eSRobert Mustacchi reg = E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE; 1118c124a83eSRobert Mustacchi ret_val = e1000_read_kmrn_reg_80003es2lan(hw, reg, &data); 111975eba5b6SRobert Mustacchi if (ret_val) 1120c124a83eSRobert Mustacchi return ret_val; 112175eba5b6SRobert Mustacchi data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; 1122c124a83eSRobert Mustacchi ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data); 112375eba5b6SRobert Mustacchi if (ret_val) 1124c124a83eSRobert Mustacchi return ret_val; 112575eba5b6SRobert Mustacchi 112675eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); 112775eba5b6SRobert Mustacchi if (ret_val) 1128c124a83eSRobert Mustacchi return ret_val; 112975eba5b6SRobert Mustacchi 113075eba5b6SRobert Mustacchi data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; 113175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data); 113275eba5b6SRobert Mustacchi if (ret_val) 1133c124a83eSRobert Mustacchi return ret_val; 113475eba5b6SRobert Mustacchi 1135c124a83eSRobert Mustacchi reg = E1000_READ_REG(hw, E1000_CTRL_EXT); 1136c124a83eSRobert Mustacchi reg &= ~E1000_CTRL_EXT_LINK_MODE_MASK; 1137c124a83eSRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); 113875eba5b6SRobert Mustacchi 113975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); 114075eba5b6SRobert Mustacchi if (ret_val) 1141c124a83eSRobert Mustacchi return ret_val; 114275eba5b6SRobert Mustacchi 1143c124a83eSRobert Mustacchi /* Do not init these registers when the HW is in IAMT mode, since the 114475eba5b6SRobert Mustacchi * firmware will have already initialized them. We only initialize 114575eba5b6SRobert Mustacchi * them if the HW is not in IAMT mode. 114675eba5b6SRobert Mustacchi */ 1147c124a83eSRobert Mustacchi if (!hw->mac.ops.check_mng_mode(hw)) { 114875eba5b6SRobert Mustacchi /* Enable Electrical Idle on the PHY */ 114975eba5b6SRobert Mustacchi data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; 115075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, 115175eba5b6SRobert Mustacchi data); 115275eba5b6SRobert Mustacchi if (ret_val) 1153c124a83eSRobert Mustacchi return ret_val; 115475eba5b6SRobert Mustacchi 115575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 115675eba5b6SRobert Mustacchi &data); 115775eba5b6SRobert Mustacchi if (ret_val) 1158c124a83eSRobert Mustacchi return ret_val; 115975eba5b6SRobert Mustacchi 116075eba5b6SRobert Mustacchi data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; 116175eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 116275eba5b6SRobert Mustacchi data); 116375eba5b6SRobert Mustacchi if (ret_val) 1164c124a83eSRobert Mustacchi return ret_val; 116575eba5b6SRobert Mustacchi } 116675eba5b6SRobert Mustacchi 1167c124a83eSRobert Mustacchi /* Workaround: Disable padding in Kumeran interface in the MAC 116875eba5b6SRobert Mustacchi * and in the PHY to avoid CRC errors. 116975eba5b6SRobert Mustacchi */ 117075eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data); 117175eba5b6SRobert Mustacchi if (ret_val) 1172c124a83eSRobert Mustacchi return ret_val; 117375eba5b6SRobert Mustacchi 117475eba5b6SRobert Mustacchi data |= GG82563_ICR_DIS_PADDING; 117575eba5b6SRobert Mustacchi ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data); 117675eba5b6SRobert Mustacchi if (ret_val) 117775eba5b6SRobert Mustacchi return ret_val; 1178c124a83eSRobert Mustacchi 1179c124a83eSRobert Mustacchi return E1000_SUCCESS; 118075eba5b6SRobert Mustacchi } 118175eba5b6SRobert Mustacchi 118275eba5b6SRobert Mustacchi /** 118375eba5b6SRobert Mustacchi * e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2 118475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 118575eba5b6SRobert Mustacchi * 118675eba5b6SRobert Mustacchi * Essentially a wrapper for setting up all things "copper" related. 118775eba5b6SRobert Mustacchi * This is a function pointer entry point called by the mac module. 118875eba5b6SRobert Mustacchi **/ 118975eba5b6SRobert Mustacchi static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) 119075eba5b6SRobert Mustacchi { 119175eba5b6SRobert Mustacchi u32 ctrl; 119275eba5b6SRobert Mustacchi s32 ret_val; 119375eba5b6SRobert Mustacchi u16 reg_data; 119475eba5b6SRobert Mustacchi 119575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_setup_copper_link_80003es2lan"); 119675eba5b6SRobert Mustacchi 119775eba5b6SRobert Mustacchi ctrl = E1000_READ_REG(hw, E1000_CTRL); 119875eba5b6SRobert Mustacchi ctrl |= E1000_CTRL_SLU; 119975eba5b6SRobert Mustacchi ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 120075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 120175eba5b6SRobert Mustacchi 1202c124a83eSRobert Mustacchi /* Set the mac to wait the maximum time between each 120375eba5b6SRobert Mustacchi * iteration and increase the max iterations when 120475eba5b6SRobert Mustacchi * polling the phy; this fixes erroneous timeouts at 10Mbps. 120575eba5b6SRobert Mustacchi */ 120675eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4), 120775eba5b6SRobert Mustacchi 0xFFFF); 120875eba5b6SRobert Mustacchi if (ret_val) 1209c124a83eSRobert Mustacchi return ret_val; 121075eba5b6SRobert Mustacchi ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), 121175eba5b6SRobert Mustacchi ®_data); 121275eba5b6SRobert Mustacchi if (ret_val) 1213c124a83eSRobert Mustacchi return ret_val; 121475eba5b6SRobert Mustacchi reg_data |= 0x3F; 121575eba5b6SRobert Mustacchi ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), 121675eba5b6SRobert Mustacchi reg_data); 121775eba5b6SRobert Mustacchi if (ret_val) 1218c124a83eSRobert Mustacchi return ret_val; 1219c124a83eSRobert Mustacchi ret_val = 1220c124a83eSRobert Mustacchi e1000_read_kmrn_reg_80003es2lan(hw, 1221c124a83eSRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, 1222c124a83eSRobert Mustacchi ®_data); 122375eba5b6SRobert Mustacchi if (ret_val) 1224c124a83eSRobert Mustacchi return ret_val; 122575eba5b6SRobert Mustacchi reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; 1226c124a83eSRobert Mustacchi ret_val = 1227c124a83eSRobert Mustacchi e1000_write_kmrn_reg_80003es2lan(hw, 1228c124a83eSRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, 1229c124a83eSRobert Mustacchi reg_data); 123075eba5b6SRobert Mustacchi if (ret_val) 1231c124a83eSRobert Mustacchi return ret_val; 123275eba5b6SRobert Mustacchi 123375eba5b6SRobert Mustacchi ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw); 123475eba5b6SRobert Mustacchi if (ret_val) 123575eba5b6SRobert Mustacchi return ret_val; 1236c124a83eSRobert Mustacchi 1237c124a83eSRobert Mustacchi return e1000_setup_copper_link_generic(hw); 123875eba5b6SRobert Mustacchi } 123975eba5b6SRobert Mustacchi 124075eba5b6SRobert Mustacchi /** 124175eba5b6SRobert Mustacchi * e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up 124275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 124375eba5b6SRobert Mustacchi * @duplex: current duplex setting 124475eba5b6SRobert Mustacchi * 124575eba5b6SRobert Mustacchi * Configure the KMRN interface by applying last minute quirks for 124675eba5b6SRobert Mustacchi * 10/100 operation. 124775eba5b6SRobert Mustacchi **/ 124875eba5b6SRobert Mustacchi static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) 124975eba5b6SRobert Mustacchi { 125075eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 125175eba5b6SRobert Mustacchi u16 speed; 125275eba5b6SRobert Mustacchi u16 duplex; 125375eba5b6SRobert Mustacchi 125475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_configure_on_link_up"); 125575eba5b6SRobert Mustacchi 125675eba5b6SRobert Mustacchi if (hw->phy.media_type == e1000_media_type_copper) { 125775eba5b6SRobert Mustacchi ret_val = e1000_get_speed_and_duplex_copper_generic(hw, &speed, 125875eba5b6SRobert Mustacchi &duplex); 125975eba5b6SRobert Mustacchi if (ret_val) 1260c124a83eSRobert Mustacchi return ret_val; 126175eba5b6SRobert Mustacchi 126275eba5b6SRobert Mustacchi if (speed == SPEED_1000) 126375eba5b6SRobert Mustacchi ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); 126475eba5b6SRobert Mustacchi else 126575eba5b6SRobert Mustacchi ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex); 126675eba5b6SRobert Mustacchi } 126775eba5b6SRobert Mustacchi 126875eba5b6SRobert Mustacchi return ret_val; 126975eba5b6SRobert Mustacchi } 127075eba5b6SRobert Mustacchi 127175eba5b6SRobert Mustacchi /** 127275eba5b6SRobert Mustacchi * e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation 127375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 127475eba5b6SRobert Mustacchi * @duplex: current duplex setting 127575eba5b6SRobert Mustacchi * 127675eba5b6SRobert Mustacchi * Configure the KMRN interface by applying last minute quirks for 127775eba5b6SRobert Mustacchi * 10/100 operation. 127875eba5b6SRobert Mustacchi **/ 127975eba5b6SRobert Mustacchi static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) 128075eba5b6SRobert Mustacchi { 1281c124a83eSRobert Mustacchi s32 ret_val; 128275eba5b6SRobert Mustacchi u32 tipg; 128375eba5b6SRobert Mustacchi u32 i = 0; 128475eba5b6SRobert Mustacchi u16 reg_data, reg_data2; 128575eba5b6SRobert Mustacchi 128675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_configure_kmrn_for_10_100"); 128775eba5b6SRobert Mustacchi 128875eba5b6SRobert Mustacchi reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; 1289c124a83eSRobert Mustacchi ret_val = 1290c124a83eSRobert Mustacchi e1000_write_kmrn_reg_80003es2lan(hw, 129175eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, 129275eba5b6SRobert Mustacchi reg_data); 129375eba5b6SRobert Mustacchi if (ret_val) 1294c124a83eSRobert Mustacchi return ret_val; 129575eba5b6SRobert Mustacchi 129675eba5b6SRobert Mustacchi /* Configure Transmit Inter-Packet Gap */ 129775eba5b6SRobert Mustacchi tipg = E1000_READ_REG(hw, E1000_TIPG); 129875eba5b6SRobert Mustacchi tipg &= ~E1000_TIPG_IPGT_MASK; 129975eba5b6SRobert Mustacchi tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; 130075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TIPG, tipg); 130175eba5b6SRobert Mustacchi 130275eba5b6SRobert Mustacchi do { 130375eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 130475eba5b6SRobert Mustacchi ®_data); 130575eba5b6SRobert Mustacchi if (ret_val) 1306c124a83eSRobert Mustacchi return ret_val; 130775eba5b6SRobert Mustacchi 130875eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 130975eba5b6SRobert Mustacchi ®_data2); 131075eba5b6SRobert Mustacchi if (ret_val) 1311c124a83eSRobert Mustacchi return ret_val; 131275eba5b6SRobert Mustacchi i++; 131375eba5b6SRobert Mustacchi } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); 131475eba5b6SRobert Mustacchi 131575eba5b6SRobert Mustacchi if (duplex == HALF_DUPLEX) 131675eba5b6SRobert Mustacchi reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; 131775eba5b6SRobert Mustacchi else 131875eba5b6SRobert Mustacchi reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; 131975eba5b6SRobert Mustacchi 1320c124a83eSRobert Mustacchi return hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); 132175eba5b6SRobert Mustacchi } 132275eba5b6SRobert Mustacchi 132375eba5b6SRobert Mustacchi /** 132475eba5b6SRobert Mustacchi * e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation 132575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 132675eba5b6SRobert Mustacchi * 132775eba5b6SRobert Mustacchi * Configure the KMRN interface by applying last minute quirks for 132875eba5b6SRobert Mustacchi * gigabit operation. 132975eba5b6SRobert Mustacchi **/ 133075eba5b6SRobert Mustacchi static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) 133175eba5b6SRobert Mustacchi { 1332c124a83eSRobert Mustacchi s32 ret_val; 133375eba5b6SRobert Mustacchi u16 reg_data, reg_data2; 133475eba5b6SRobert Mustacchi u32 tipg; 133575eba5b6SRobert Mustacchi u32 i = 0; 133675eba5b6SRobert Mustacchi 133775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_configure_kmrn_for_1000"); 133875eba5b6SRobert Mustacchi 133975eba5b6SRobert Mustacchi reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; 1340c124a83eSRobert Mustacchi ret_val = 1341c124a83eSRobert Mustacchi e1000_write_kmrn_reg_80003es2lan(hw, 1342c124a83eSRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, 1343c124a83eSRobert Mustacchi reg_data); 134475eba5b6SRobert Mustacchi if (ret_val) 1345c124a83eSRobert Mustacchi return ret_val; 134675eba5b6SRobert Mustacchi 134775eba5b6SRobert Mustacchi /* Configure Transmit Inter-Packet Gap */ 134875eba5b6SRobert Mustacchi tipg = E1000_READ_REG(hw, E1000_TIPG); 134975eba5b6SRobert Mustacchi tipg &= ~E1000_TIPG_IPGT_MASK; 135075eba5b6SRobert Mustacchi tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; 135175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_TIPG, tipg); 135275eba5b6SRobert Mustacchi 135375eba5b6SRobert Mustacchi do { 135475eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 135575eba5b6SRobert Mustacchi ®_data); 135675eba5b6SRobert Mustacchi if (ret_val) 1357c124a83eSRobert Mustacchi return ret_val; 135875eba5b6SRobert Mustacchi 135975eba5b6SRobert Mustacchi ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 136075eba5b6SRobert Mustacchi ®_data2); 136175eba5b6SRobert Mustacchi if (ret_val) 1362c124a83eSRobert Mustacchi return ret_val; 136375eba5b6SRobert Mustacchi i++; 136475eba5b6SRobert Mustacchi } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); 136575eba5b6SRobert Mustacchi 136675eba5b6SRobert Mustacchi reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; 136775eba5b6SRobert Mustacchi 1368c124a83eSRobert Mustacchi return hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); 136975eba5b6SRobert Mustacchi } 137075eba5b6SRobert Mustacchi 137175eba5b6SRobert Mustacchi /** 137275eba5b6SRobert Mustacchi * e1000_read_kmrn_reg_80003es2lan - Read kumeran register 137375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 137475eba5b6SRobert Mustacchi * @offset: register offset to be read 137575eba5b6SRobert Mustacchi * @data: pointer to the read data 137675eba5b6SRobert Mustacchi * 137775eba5b6SRobert Mustacchi * Acquire semaphore, then read the PHY register at offset 137875eba5b6SRobert Mustacchi * using the kumeran interface. The information retrieved is stored in data. 137975eba5b6SRobert Mustacchi * Release the semaphore before exiting. 138075eba5b6SRobert Mustacchi **/ 138175eba5b6SRobert Mustacchi static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 138275eba5b6SRobert Mustacchi u16 *data) 138375eba5b6SRobert Mustacchi { 138475eba5b6SRobert Mustacchi u32 kmrnctrlsta; 1385c124a83eSRobert Mustacchi s32 ret_val; 138675eba5b6SRobert Mustacchi 138775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan"); 138875eba5b6SRobert Mustacchi 138975eba5b6SRobert Mustacchi ret_val = e1000_acquire_mac_csr_80003es2lan(hw); 139075eba5b6SRobert Mustacchi if (ret_val) 1391c124a83eSRobert Mustacchi return ret_val; 139275eba5b6SRobert Mustacchi 139375eba5b6SRobert Mustacchi kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 139475eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; 139575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); 139675eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 139775eba5b6SRobert Mustacchi 139875eba5b6SRobert Mustacchi usec_delay(2); 139975eba5b6SRobert Mustacchi 140075eba5b6SRobert Mustacchi kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); 140175eba5b6SRobert Mustacchi *data = (u16)kmrnctrlsta; 140275eba5b6SRobert Mustacchi 140375eba5b6SRobert Mustacchi e1000_release_mac_csr_80003es2lan(hw); 140475eba5b6SRobert Mustacchi 140575eba5b6SRobert Mustacchi return ret_val; 140675eba5b6SRobert Mustacchi } 140775eba5b6SRobert Mustacchi 140875eba5b6SRobert Mustacchi /** 140975eba5b6SRobert Mustacchi * e1000_write_kmrn_reg_80003es2lan - Write kumeran register 141075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 141175eba5b6SRobert Mustacchi * @offset: register offset to write to 141275eba5b6SRobert Mustacchi * @data: data to write at register offset 141375eba5b6SRobert Mustacchi * 141475eba5b6SRobert Mustacchi * Acquire semaphore, then write the data to PHY register 141575eba5b6SRobert Mustacchi * at the offset using the kumeran interface. Release semaphore 141675eba5b6SRobert Mustacchi * before exiting. 141775eba5b6SRobert Mustacchi **/ 141875eba5b6SRobert Mustacchi static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 141975eba5b6SRobert Mustacchi u16 data) 142075eba5b6SRobert Mustacchi { 142175eba5b6SRobert Mustacchi u32 kmrnctrlsta; 1422c124a83eSRobert Mustacchi s32 ret_val; 142375eba5b6SRobert Mustacchi 142475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan"); 142575eba5b6SRobert Mustacchi 142675eba5b6SRobert Mustacchi ret_val = e1000_acquire_mac_csr_80003es2lan(hw); 142775eba5b6SRobert Mustacchi if (ret_val) 1428c124a83eSRobert Mustacchi return ret_val; 142975eba5b6SRobert Mustacchi 143075eba5b6SRobert Mustacchi kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 143175eba5b6SRobert Mustacchi E1000_KMRNCTRLSTA_OFFSET) | data; 143275eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); 143375eba5b6SRobert Mustacchi E1000_WRITE_FLUSH(hw); 143475eba5b6SRobert Mustacchi 143575eba5b6SRobert Mustacchi usec_delay(2); 143675eba5b6SRobert Mustacchi 143775eba5b6SRobert Mustacchi e1000_release_mac_csr_80003es2lan(hw); 143875eba5b6SRobert Mustacchi 143975eba5b6SRobert Mustacchi return ret_val; 144075eba5b6SRobert Mustacchi } 144175eba5b6SRobert Mustacchi 144275eba5b6SRobert Mustacchi /** 144375eba5b6SRobert Mustacchi * e1000_read_mac_addr_80003es2lan - Read device MAC address 144475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 144575eba5b6SRobert Mustacchi **/ 144675eba5b6SRobert Mustacchi static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) 144775eba5b6SRobert Mustacchi { 1448c124a83eSRobert Mustacchi s32 ret_val; 144975eba5b6SRobert Mustacchi 145075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mac_addr_80003es2lan"); 145175eba5b6SRobert Mustacchi 1452c124a83eSRobert Mustacchi /* If there's an alternate MAC address place it in RAR0 145375eba5b6SRobert Mustacchi * so that it will override the Si installed default perm 145475eba5b6SRobert Mustacchi * address. 145575eba5b6SRobert Mustacchi */ 145675eba5b6SRobert Mustacchi ret_val = e1000_check_alt_mac_addr_generic(hw); 145775eba5b6SRobert Mustacchi if (ret_val) 145875eba5b6SRobert Mustacchi return ret_val; 1459c124a83eSRobert Mustacchi 1460c124a83eSRobert Mustacchi return e1000_read_mac_addr_generic(hw); 146175eba5b6SRobert Mustacchi } 146275eba5b6SRobert Mustacchi 146375eba5b6SRobert Mustacchi /** 146475eba5b6SRobert Mustacchi * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down 146575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 146675eba5b6SRobert Mustacchi * 146775eba5b6SRobert Mustacchi * In the case of a PHY power down to save power, or to turn off link during a 146875eba5b6SRobert Mustacchi * driver unload, or wake on lan is not enabled, remove the link. 146975eba5b6SRobert Mustacchi **/ 147075eba5b6SRobert Mustacchi static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) 147175eba5b6SRobert Mustacchi { 147275eba5b6SRobert Mustacchi /* If the management interface is not enabled, then power down */ 147375eba5b6SRobert Mustacchi if (!(hw->mac.ops.check_mng_mode(hw) || 147475eba5b6SRobert Mustacchi hw->phy.ops.check_reset_block(hw))) 147575eba5b6SRobert Mustacchi e1000_power_down_phy_copper(hw); 147675eba5b6SRobert Mustacchi 147775eba5b6SRobert Mustacchi return; 147875eba5b6SRobert Mustacchi } 147975eba5b6SRobert Mustacchi 148075eba5b6SRobert Mustacchi /** 148175eba5b6SRobert Mustacchi * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters 148275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 148375eba5b6SRobert Mustacchi * 148475eba5b6SRobert Mustacchi * Clears the hardware counters by reading the counter registers. 148575eba5b6SRobert Mustacchi **/ 148675eba5b6SRobert Mustacchi static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) 148775eba5b6SRobert Mustacchi { 148875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan"); 148975eba5b6SRobert Mustacchi 149075eba5b6SRobert Mustacchi e1000_clear_hw_cntrs_base_generic(hw); 149175eba5b6SRobert Mustacchi 149275eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PRC64); 149375eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PRC127); 149475eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PRC255); 149575eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PRC511); 149675eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PRC1023); 149775eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PRC1522); 149875eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PTC64); 149975eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PTC127); 150075eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PTC255); 150175eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PTC511); 150275eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PTC1023); 150375eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_PTC1522); 150475eba5b6SRobert Mustacchi 150575eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ALGNERRC); 150675eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_RXERRC); 150775eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_TNCRS); 150875eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_CEXTERR); 150975eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_TSCTC); 151075eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_TSCTFC); 151175eba5b6SRobert Mustacchi 151275eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_MGTPRC); 151375eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_MGTPDC); 151475eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_MGTPTC); 151575eba5b6SRobert Mustacchi 151675eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_IAC); 151775eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICRXOC); 151875eba5b6SRobert Mustacchi 151975eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICRXPTC); 152075eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICRXATC); 152175eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICTXPTC); 152275eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICTXATC); 152375eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICTXQEC); 152475eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICTXQMTC); 152575eba5b6SRobert Mustacchi E1000_READ_REG(hw, E1000_ICRXDMTC); 152675eba5b6SRobert Mustacchi } 1527