e1000_80003es2lan.c revision 200243
1177867Sjfv/****************************************************************************** 2169240Sjfv 3190872Sjfv Copyright (c) 2001-2009, Intel Corporation 4169240Sjfv All rights reserved. 5169240Sjfv 6169240Sjfv Redistribution and use in source and binary forms, with or without 7169240Sjfv modification, are permitted provided that the following conditions are met: 8169240Sjfv 9169240Sjfv 1. Redistributions of source code must retain the above copyright notice, 10169240Sjfv this list of conditions and the following disclaimer. 11169240Sjfv 12169240Sjfv 2. Redistributions in binary form must reproduce the above copyright 13169240Sjfv notice, this list of conditions and the following disclaimer in the 14169240Sjfv documentation and/or other materials provided with the distribution. 15169240Sjfv 16169240Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17169240Sjfv contributors may be used to endorse or promote products derived from 18169240Sjfv this software without specific prior written permission. 19169240Sjfv 20169240Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21169240Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22169240Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23169240Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24169240Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25169240Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26169240Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27169240Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28169240Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29169240Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30169240Sjfv POSSIBILITY OF SUCH DAMAGE. 31169240Sjfv 32177867Sjfv******************************************************************************/ 33177867Sjfv/*$FreeBSD: head/sys/dev/e1000/e1000_80003es2lan.c 200243 2009-12-08 01:07:44Z jfv $*/ 34169240Sjfv 35185353Sjfv/* 36185353Sjfv * 80003ES2LAN Gigabit Ethernet Controller (Copper) 37185353Sjfv * 80003ES2LAN Gigabit Ethernet Controller (Serdes) 38169240Sjfv */ 39169240Sjfv 40169589Sjfv#include "e1000_api.h" 41169240Sjfv 42177867Sjfvstatic s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw); 43177867Sjfvstatic s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw); 44177867Sjfvstatic s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw); 45177867Sjfvstatic s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); 46177867Sjfvstatic void e1000_release_phy_80003es2lan(struct e1000_hw *hw); 47177867Sjfvstatic s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); 48177867Sjfvstatic void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); 49177867Sjfvstatic s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 50169240Sjfv u32 offset, 51169240Sjfv u16 *data); 52177867Sjfvstatic s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 53169240Sjfv u32 offset, 54169240Sjfv u16 data); 55177867Sjfvstatic s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, 56169240Sjfv u16 words, u16 *data); 57177867Sjfvstatic s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); 58177867Sjfvstatic s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); 59177867Sjfvstatic s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); 60177867Sjfvstatic s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, 61169240Sjfv u16 *duplex); 62177867Sjfvstatic s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); 63177867Sjfvstatic s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); 64177867Sjfvstatic s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); 65177867Sjfvstatic void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); 66169240Sjfvstatic s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); 67169240Sjfvstatic s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); 68169240Sjfvstatic s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); 69185353Sjfvstatic s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw); 70185353Sjfvstatic s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 71185353Sjfv u16 *data); 72185353Sjfvstatic s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 73185353Sjfv u16 data); 74169240Sjfvstatic s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); 75169240Sjfvstatic void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); 76169240Sjfvstatic void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); 77177867Sjfvstatic s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); 78177867Sjfvstatic void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); 79169240Sjfv 80173788Sjfv/* 81173788Sjfv * A table for the GG82563 cable length where the range is defined 82169240Sjfv * with a lower bound at "index" and the upper bound at 83169240Sjfv * "index + 5". 84169240Sjfv */ 85173788Sjfvstatic const u16 e1000_gg82563_cable_length_table[] = 86169240Sjfv { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; 87169240Sjfv#define GG82563_CABLE_LENGTH_TABLE_SIZE \ 88169240Sjfv (sizeof(e1000_gg82563_cable_length_table) / \ 89169240Sjfv sizeof(e1000_gg82563_cable_length_table[0])) 90169240Sjfv 91169240Sjfv/** 92169240Sjfv * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. 93169589Sjfv * @hw: pointer to the HW structure 94169240Sjfv **/ 95177867Sjfvstatic s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) 96169240Sjfv{ 97169240Sjfv struct e1000_phy_info *phy = &hw->phy; 98169240Sjfv s32 ret_val = E1000_SUCCESS; 99169240Sjfv 100169240Sjfv DEBUGFUNC("e1000_init_phy_params_80003es2lan"); 101169240Sjfv 102173788Sjfv if (hw->phy.media_type != e1000_media_type_copper) { 103169240Sjfv phy->type = e1000_phy_none; 104169240Sjfv goto out; 105173788Sjfv } else { 106177867Sjfv phy->ops.power_up = e1000_power_up_phy_copper; 107177867Sjfv phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; 108169240Sjfv } 109169240Sjfv 110169240Sjfv phy->addr = 1; 111169240Sjfv phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 112169240Sjfv phy->reset_delay_us = 100; 113169240Sjfv phy->type = e1000_phy_gg82563; 114169240Sjfv 115177867Sjfv phy->ops.acquire = e1000_acquire_phy_80003es2lan; 116177867Sjfv phy->ops.check_polarity = e1000_check_polarity_m88; 117177867Sjfv phy->ops.check_reset_block = e1000_check_reset_block_generic; 118177867Sjfv phy->ops.commit = e1000_phy_sw_reset_generic; 119177867Sjfv phy->ops.get_cfg_done = e1000_get_cfg_done_80003es2lan; 120177867Sjfv phy->ops.get_info = e1000_get_phy_info_m88; 121177867Sjfv phy->ops.release = e1000_release_phy_80003es2lan; 122177867Sjfv phy->ops.reset = e1000_phy_hw_reset_generic; 123177867Sjfv phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; 124169240Sjfv 125177867Sjfv phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan; 126177867Sjfv phy->ops.get_cable_length = e1000_get_cable_length_80003es2lan; 127177867Sjfv phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; 128177867Sjfv phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; 129169240Sjfv 130185353Sjfv phy->ops.cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan; 131185353Sjfv 132169240Sjfv /* This can only be done after all function pointers are setup. */ 133169240Sjfv ret_val = e1000_get_phy_id(hw); 134169240Sjfv 135169240Sjfv /* Verify phy id */ 136169240Sjfv if (phy->id != GG82563_E_PHY_ID) { 137169240Sjfv ret_val = -E1000_ERR_PHY; 138169240Sjfv goto out; 139169240Sjfv } 140169240Sjfv 141169240Sjfvout: 142169240Sjfv return ret_val; 143169240Sjfv} 144169240Sjfv 145169240Sjfv/** 146169240Sjfv * e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs. 147169589Sjfv * @hw: pointer to the HW structure 148169240Sjfv **/ 149177867Sjfvstatic s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) 150169240Sjfv{ 151169240Sjfv struct e1000_nvm_info *nvm = &hw->nvm; 152169240Sjfv u32 eecd = E1000_READ_REG(hw, E1000_EECD); 153169240Sjfv u16 size; 154169240Sjfv 155169240Sjfv DEBUGFUNC("e1000_init_nvm_params_80003es2lan"); 156169240Sjfv 157169240Sjfv nvm->opcode_bits = 8; 158169240Sjfv nvm->delay_usec = 1; 159169240Sjfv switch (nvm->override) { 160169240Sjfv case e1000_nvm_override_spi_large: 161169240Sjfv nvm->page_size = 32; 162169240Sjfv nvm->address_bits = 16; 163169240Sjfv break; 164169240Sjfv case e1000_nvm_override_spi_small: 165169240Sjfv nvm->page_size = 8; 166169240Sjfv nvm->address_bits = 8; 167169240Sjfv break; 168169240Sjfv default: 169169240Sjfv nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; 170169240Sjfv nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; 171169240Sjfv break; 172169240Sjfv } 173169240Sjfv 174200243Sjfv nvm->type = e1000_nvm_eeprom_spi; 175169240Sjfv 176169240Sjfv size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> 177169240Sjfv E1000_EECD_SIZE_EX_SHIFT); 178169240Sjfv 179173788Sjfv /* 180173788Sjfv * Added to a constant, "size" becomes the left-shift value 181169240Sjfv * for setting word_size. 182169240Sjfv */ 183169240Sjfv size += NVM_WORD_SIZE_BASE_SHIFT; 184173788Sjfv 185173788Sjfv /* EEPROM access above 16k is unsupported */ 186173788Sjfv if (size > 14) 187173788Sjfv size = 14; 188169240Sjfv nvm->word_size = 1 << size; 189169240Sjfv 190169240Sjfv /* Function Pointers */ 191177867Sjfv nvm->ops.acquire = e1000_acquire_nvm_80003es2lan; 192177867Sjfv nvm->ops.read = e1000_read_nvm_eerd; 193177867Sjfv nvm->ops.release = e1000_release_nvm_80003es2lan; 194177867Sjfv nvm->ops.update = e1000_update_nvm_checksum_generic; 195177867Sjfv nvm->ops.valid_led_default = e1000_valid_led_default_generic; 196177867Sjfv nvm->ops.validate = e1000_validate_nvm_checksum_generic; 197177867Sjfv nvm->ops.write = e1000_write_nvm_80003es2lan; 198169240Sjfv 199169240Sjfv return E1000_SUCCESS; 200169240Sjfv} 201169240Sjfv 202169240Sjfv/** 203169240Sjfv * e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs. 204169589Sjfv * @hw: pointer to the HW structure 205169240Sjfv **/ 206177867Sjfvstatic s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) 207169240Sjfv{ 208169240Sjfv struct e1000_mac_info *mac = &hw->mac; 209169240Sjfv 210169240Sjfv DEBUGFUNC("e1000_init_mac_params_80003es2lan"); 211169240Sjfv 212200243Sjfv /* Set media type and media-dependent function pointers */ 213169240Sjfv switch (hw->device_id) { 214169240Sjfv case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: 215173788Sjfv hw->phy.media_type = e1000_media_type_internal_serdes; 216200243Sjfv mac->ops.check_for_link = e1000_check_for_serdes_link_generic; 217200243Sjfv mac->ops.setup_physical_interface = 218200243Sjfv e1000_setup_fiber_serdes_link_generic; 219169240Sjfv break; 220169240Sjfv default: 221173788Sjfv hw->phy.media_type = e1000_media_type_copper; 222200243Sjfv mac->ops.check_for_link = e1000_check_for_copper_link_generic; 223200243Sjfv mac->ops.setup_physical_interface = 224200243Sjfv e1000_setup_copper_link_80003es2lan; 225169240Sjfv break; 226169240Sjfv } 227169240Sjfv 228169240Sjfv /* Set mta register count */ 229169240Sjfv mac->mta_reg_count = 128; 230169240Sjfv /* Set rar entry count */ 231169240Sjfv mac->rar_entry_count = E1000_RAR_ENTRIES; 232169240Sjfv /* Set if part includes ASF firmware */ 233169240Sjfv mac->asf_firmware_present = TRUE; 234169240Sjfv /* Set if manageability features are enabled. */ 235169240Sjfv mac->arc_subsystem_valid = 236169240Sjfv (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) 237169240Sjfv ? TRUE : FALSE; 238200243Sjfv /* Adaptive IFS not supported */ 239200243Sjfv mac->adaptive_ifs = FALSE; 240169240Sjfv 241169240Sjfv /* Function pointers */ 242169240Sjfv 243169240Sjfv /* bus type/speed/width */ 244177867Sjfv mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; 245169240Sjfv /* reset */ 246177867Sjfv mac->ops.reset_hw = e1000_reset_hw_80003es2lan; 247169240Sjfv /* hw initialization */ 248177867Sjfv mac->ops.init_hw = e1000_init_hw_80003es2lan; 249169240Sjfv /* link setup */ 250177867Sjfv mac->ops.setup_link = e1000_setup_link_generic; 251169240Sjfv /* check management mode */ 252177867Sjfv mac->ops.check_mng_mode = e1000_check_mng_mode_generic; 253169240Sjfv /* multicast address update */ 254177867Sjfv mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; 255169240Sjfv /* writing VFTA */ 256177867Sjfv mac->ops.write_vfta = e1000_write_vfta_generic; 257169240Sjfv /* clearing VFTA */ 258177867Sjfv mac->ops.clear_vfta = e1000_clear_vfta_generic; 259169240Sjfv /* setting MTA */ 260177867Sjfv mac->ops.mta_set = e1000_mta_set_generic; 261176667Sjfv /* read mac address */ 262177867Sjfv mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan; 263190872Sjfv /* ID LED init */ 264190872Sjfv mac->ops.id_led_init = e1000_id_led_init_generic; 265169240Sjfv /* blink LED */ 266177867Sjfv mac->ops.blink_led = e1000_blink_led_generic; 267169240Sjfv /* setup LED */ 268177867Sjfv mac->ops.setup_led = e1000_setup_led_generic; 269169240Sjfv /* cleanup LED */ 270177867Sjfv mac->ops.cleanup_led = e1000_cleanup_led_generic; 271169240Sjfv /* turn on/off LED */ 272177867Sjfv mac->ops.led_on = e1000_led_on_generic; 273177867Sjfv mac->ops.led_off = e1000_led_off_generic; 274169240Sjfv /* clear hardware counters */ 275177867Sjfv mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan; 276169240Sjfv /* link info */ 277177867Sjfv mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan; 278169240Sjfv 279200243Sjfv /* set lan id for port to determine which phy lock to use */ 280200243Sjfv hw->mac.ops.set_lan_id(hw); 281200243Sjfv 282200243Sjfv return E1000_SUCCESS; 283169240Sjfv} 284169240Sjfv 285169240Sjfv/** 286169240Sjfv * e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs. 287169589Sjfv * @hw: pointer to the HW structure 288169240Sjfv * 289185353Sjfv * Called to initialize all function pointers and parameters. 290169240Sjfv **/ 291173788Sjfvvoid e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) 292169240Sjfv{ 293169240Sjfv DEBUGFUNC("e1000_init_function_pointers_80003es2lan"); 294169240Sjfv 295177867Sjfv hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan; 296177867Sjfv hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan; 297177867Sjfv hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan; 298169240Sjfv} 299169240Sjfv 300169240Sjfv/** 301169240Sjfv * e1000_acquire_phy_80003es2lan - Acquire rights to access PHY 302169589Sjfv * @hw: pointer to the HW structure 303169240Sjfv * 304185353Sjfv * A wrapper to acquire access rights to the correct PHY. 305169240Sjfv **/ 306177867Sjfvstatic s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) 307169240Sjfv{ 308169240Sjfv u16 mask; 309169240Sjfv 310169240Sjfv DEBUGFUNC("e1000_acquire_phy_80003es2lan"); 311169240Sjfv 312169240Sjfv mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; 313169240Sjfv return e1000_acquire_swfw_sync_80003es2lan(hw, mask); 314169240Sjfv} 315169240Sjfv 316169240Sjfv/** 317169240Sjfv * e1000_release_phy_80003es2lan - Release rights to access PHY 318169589Sjfv * @hw: pointer to the HW structure 319169240Sjfv * 320185353Sjfv * A wrapper to release access rights to the correct PHY. 321169240Sjfv **/ 322177867Sjfvstatic void e1000_release_phy_80003es2lan(struct e1000_hw *hw) 323169240Sjfv{ 324169240Sjfv u16 mask; 325169240Sjfv 326169240Sjfv DEBUGFUNC("e1000_release_phy_80003es2lan"); 327169240Sjfv 328169240Sjfv mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; 329185353Sjfv e1000_release_swfw_sync_80003es2lan(hw, mask); 330185353Sjfv} 331176667Sjfv 332185353Sjfv/** 333185353Sjfv * e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register 334185353Sjfv * @hw: pointer to the HW structure 335185353Sjfv * 336185353Sjfv * Acquire the semaphore to access the Kumeran interface. 337185353Sjfv * 338185353Sjfv **/ 339185353Sjfvstatic s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw) 340185353Sjfv{ 341185353Sjfv u16 mask; 342185353Sjfv 343185353Sjfv DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan"); 344185353Sjfv 345185353Sjfv mask = E1000_SWFW_CSR_SM; 346185353Sjfv 347185353Sjfv return e1000_acquire_swfw_sync_80003es2lan(hw, mask); 348185353Sjfv} 349185353Sjfv 350185353Sjfv/** 351185353Sjfv * e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register 352185353Sjfv * @hw: pointer to the HW structure 353185353Sjfv * 354185353Sjfv * Release the semaphore used to access the Kumeran interface 355185353Sjfv **/ 356185353Sjfvstatic void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw) 357185353Sjfv{ 358185353Sjfv u16 mask; 359185353Sjfv 360185353Sjfv DEBUGFUNC("e1000_release_mac_csr_80003es2lan"); 361185353Sjfv 362185353Sjfv mask = E1000_SWFW_CSR_SM; 363185353Sjfv 364169240Sjfv e1000_release_swfw_sync_80003es2lan(hw, mask); 365169240Sjfv} 366169240Sjfv 367169240Sjfv/** 368169240Sjfv * e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM 369169589Sjfv * @hw: pointer to the HW structure 370169240Sjfv * 371185353Sjfv * Acquire the semaphore to access the EEPROM. 372169240Sjfv **/ 373177867Sjfvstatic s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) 374169240Sjfv{ 375169240Sjfv s32 ret_val; 376169240Sjfv 377169240Sjfv DEBUGFUNC("e1000_acquire_nvm_80003es2lan"); 378169240Sjfv 379169240Sjfv ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); 380169240Sjfv if (ret_val) 381169240Sjfv goto out; 382169240Sjfv 383169240Sjfv ret_val = e1000_acquire_nvm_generic(hw); 384169240Sjfv 385169240Sjfv if (ret_val) 386169240Sjfv e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); 387169240Sjfv 388169240Sjfvout: 389169240Sjfv return ret_val; 390169240Sjfv} 391169240Sjfv 392169240Sjfv/** 393169240Sjfv * e1000_release_nvm_80003es2lan - Relinquish rights to access NVM 394169589Sjfv * @hw: pointer to the HW structure 395169240Sjfv * 396185353Sjfv * Release the semaphore used to access the EEPROM. 397169240Sjfv **/ 398177867Sjfvstatic void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) 399169240Sjfv{ 400169240Sjfv DEBUGFUNC("e1000_release_nvm_80003es2lan"); 401169240Sjfv 402169240Sjfv e1000_release_nvm_generic(hw); 403169240Sjfv e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); 404169240Sjfv} 405169240Sjfv 406169240Sjfv/** 407169240Sjfv * e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore 408169589Sjfv * @hw: pointer to the HW structure 409169589Sjfv * @mask: specifies which semaphore to acquire 410169240Sjfv * 411169240Sjfv * Acquire the SW/FW semaphore to access the PHY or NVM. The mask 412169240Sjfv * will also specify which port we're acquiring the lock for. 413169240Sjfv **/ 414173788Sjfvstatic s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) 415169240Sjfv{ 416169240Sjfv u32 swfw_sync; 417169240Sjfv u32 swmask = mask; 418169240Sjfv u32 fwmask = mask << 16; 419169240Sjfv s32 ret_val = E1000_SUCCESS; 420185353Sjfv s32 i = 0, timeout = 50; 421169240Sjfv 422169240Sjfv DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan"); 423169240Sjfv 424169240Sjfv while (i < timeout) { 425169589Sjfv if (e1000_get_hw_semaphore_generic(hw)) { 426169240Sjfv ret_val = -E1000_ERR_SWFW_SYNC; 427169240Sjfv goto out; 428169240Sjfv } 429169240Sjfv 430169240Sjfv swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); 431169240Sjfv if (!(swfw_sync & (fwmask | swmask))) 432169240Sjfv break; 433169240Sjfv 434173788Sjfv /* 435173788Sjfv * Firmware currently using resource (fwmask) 436173788Sjfv * or other software thread using resource (swmask) 437173788Sjfv */ 438169589Sjfv e1000_put_hw_semaphore_generic(hw); 439169240Sjfv msec_delay_irq(5); 440169240Sjfv i++; 441169240Sjfv } 442169240Sjfv 443169240Sjfv if (i == timeout) { 444169240Sjfv DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 445169240Sjfv ret_val = -E1000_ERR_SWFW_SYNC; 446169240Sjfv goto out; 447169240Sjfv } 448169240Sjfv 449169240Sjfv swfw_sync |= swmask; 450169240Sjfv E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); 451169240Sjfv 452169589Sjfv e1000_put_hw_semaphore_generic(hw); 453169240Sjfv 454169240Sjfvout: 455169240Sjfv return ret_val; 456169240Sjfv} 457169240Sjfv 458169240Sjfv/** 459169240Sjfv * e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore 460169589Sjfv * @hw: pointer to the HW structure 461169589Sjfv * @mask: specifies which semaphore to acquire 462169240Sjfv * 463169240Sjfv * Release the SW/FW semaphore used to access the PHY or NVM. The mask 464169240Sjfv * will also specify which port we're releasing the lock for. 465169240Sjfv **/ 466173788Sjfvstatic void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) 467169240Sjfv{ 468169240Sjfv u32 swfw_sync; 469169240Sjfv 470169240Sjfv DEBUGFUNC("e1000_release_swfw_sync_80003es2lan"); 471169240Sjfv 472185353Sjfv while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) 473185353Sjfv ; /* Empty */ 474169240Sjfv 475169240Sjfv swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); 476169240Sjfv swfw_sync &= ~mask; 477169240Sjfv E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); 478169240Sjfv 479169589Sjfv e1000_put_hw_semaphore_generic(hw); 480169240Sjfv} 481169240Sjfv 482169240Sjfv/** 483169240Sjfv * e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register 484169589Sjfv * @hw: pointer to the HW structure 485169589Sjfv * @offset: offset of the register to read 486169589Sjfv * @data: pointer to the data returned from the operation 487169240Sjfv * 488185353Sjfv * Read the GG82563 PHY register. 489169240Sjfv **/ 490177867Sjfvstatic s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 491173788Sjfv u32 offset, u16 *data) 492169240Sjfv{ 493169240Sjfv s32 ret_val; 494169240Sjfv u32 page_select; 495169240Sjfv u16 temp; 496169240Sjfv 497169240Sjfv DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan"); 498169240Sjfv 499176667Sjfv ret_val = e1000_acquire_phy_80003es2lan(hw); 500176667Sjfv if (ret_val) 501176667Sjfv goto out; 502176667Sjfv 503169240Sjfv /* Select Configuration Page */ 504173788Sjfv if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { 505169240Sjfv page_select = GG82563_PHY_PAGE_SELECT; 506173788Sjfv } else { 507173788Sjfv /* 508173788Sjfv * Use Alternative Page Select register to access 509169240Sjfv * registers 30 and 31 510169240Sjfv */ 511169240Sjfv page_select = GG82563_PHY_PAGE_SELECT_ALT; 512169240Sjfv } 513169240Sjfv 514169240Sjfv temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); 515176667Sjfv ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); 516176667Sjfv if (ret_val) { 517176667Sjfv e1000_release_phy_80003es2lan(hw); 518169240Sjfv goto out; 519176667Sjfv } 520169240Sjfv 521200243Sjfv if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { 522200243Sjfv /* 523200243Sjfv * The "ready" bit in the MDIC register may be incorrectly set 524200243Sjfv * before the device has completed the "Page Select" MDI 525200243Sjfv * transaction. So we wait 200us after each MDI command... 526200243Sjfv */ 527200243Sjfv usec_delay(200); 528169240Sjfv 529200243Sjfv /* ...and verify the command was successful. */ 530200243Sjfv ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); 531169240Sjfv 532200243Sjfv if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { 533200243Sjfv ret_val = -E1000_ERR_PHY; 534200243Sjfv e1000_release_phy_80003es2lan(hw); 535200243Sjfv goto out; 536200243Sjfv } 537169240Sjfv 538200243Sjfv usec_delay(200); 539169240Sjfv 540200243Sjfv ret_val = e1000_read_phy_reg_mdic(hw, 541200243Sjfv MAX_PHY_REG_ADDRESS & offset, 542200243Sjfv data); 543169240Sjfv 544200243Sjfv usec_delay(200); 545200243Sjfv } else { 546200243Sjfv ret_val = e1000_read_phy_reg_mdic(hw, 547200243Sjfv MAX_PHY_REG_ADDRESS & offset, 548200243Sjfv data); 549200243Sjfv } 550200243Sjfv 551176667Sjfv e1000_release_phy_80003es2lan(hw); 552169240Sjfv 553169240Sjfvout: 554169240Sjfv return ret_val; 555169240Sjfv} 556169240Sjfv 557169240Sjfv/** 558169240Sjfv * e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register 559169589Sjfv * @hw: pointer to the HW structure 560169589Sjfv * @offset: offset of the register to read 561169589Sjfv * @data: value to write to the register 562169240Sjfv * 563185353Sjfv * Write to the GG82563 PHY register. 564169240Sjfv **/ 565177867Sjfvstatic s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, 566173788Sjfv u32 offset, u16 data) 567169240Sjfv{ 568169240Sjfv s32 ret_val; 569169240Sjfv u32 page_select; 570169240Sjfv u16 temp; 571169240Sjfv 572169240Sjfv DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan"); 573169240Sjfv 574176667Sjfv ret_val = e1000_acquire_phy_80003es2lan(hw); 575176667Sjfv if (ret_val) 576176667Sjfv goto out; 577176667Sjfv 578169240Sjfv /* Select Configuration Page */ 579173788Sjfv if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { 580169240Sjfv page_select = GG82563_PHY_PAGE_SELECT; 581173788Sjfv } else { 582173788Sjfv /* 583173788Sjfv * Use Alternative Page Select register to access 584169240Sjfv * registers 30 and 31 585169240Sjfv */ 586169240Sjfv page_select = GG82563_PHY_PAGE_SELECT_ALT; 587169240Sjfv } 588169240Sjfv 589169240Sjfv temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); 590176667Sjfv ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); 591176667Sjfv if (ret_val) { 592176667Sjfv e1000_release_phy_80003es2lan(hw); 593169240Sjfv goto out; 594176667Sjfv } 595169240Sjfv 596200243Sjfv if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { 597200243Sjfv /* 598200243Sjfv * The "ready" bit in the MDIC register may be incorrectly set 599200243Sjfv * before the device has completed the "Page Select" MDI 600200243Sjfv * transaction. So we wait 200us after each MDI command... 601200243Sjfv */ 602200243Sjfv usec_delay(200); 603169240Sjfv 604200243Sjfv /* ...and verify the command was successful. */ 605200243Sjfv ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); 606169240Sjfv 607200243Sjfv if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { 608200243Sjfv ret_val = -E1000_ERR_PHY; 609200243Sjfv e1000_release_phy_80003es2lan(hw); 610200243Sjfv goto out; 611200243Sjfv } 612169240Sjfv 613200243Sjfv usec_delay(200); 614169240Sjfv 615200243Sjfv ret_val = e1000_write_phy_reg_mdic(hw, 616200243Sjfv MAX_PHY_REG_ADDRESS & offset, 617200243Sjfv data); 618169240Sjfv 619200243Sjfv usec_delay(200); 620200243Sjfv } else { 621200243Sjfv ret_val = e1000_write_phy_reg_mdic(hw, 622200243Sjfv MAX_PHY_REG_ADDRESS & offset, 623200243Sjfv data); 624200243Sjfv } 625169240Sjfv 626176667Sjfv e1000_release_phy_80003es2lan(hw); 627169240Sjfv 628169240Sjfvout: 629169240Sjfv return ret_val; 630169240Sjfv} 631169240Sjfv 632169240Sjfv/** 633169240Sjfv * e1000_write_nvm_80003es2lan - Write to ESB2 NVM 634169589Sjfv * @hw: pointer to the HW structure 635169589Sjfv * @offset: offset of the register to read 636169589Sjfv * @words: number of words to write 637169589Sjfv * @data: buffer of data to write to the NVM 638169240Sjfv * 639185353Sjfv * Write "words" of data to the ESB2 NVM. 640169240Sjfv **/ 641177867Sjfvstatic s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, 642169240Sjfv u16 words, u16 *data) 643169240Sjfv{ 644169240Sjfv DEBUGFUNC("e1000_write_nvm_80003es2lan"); 645169240Sjfv 646169240Sjfv return e1000_write_nvm_spi(hw, offset, words, data); 647169240Sjfv} 648169240Sjfv 649169240Sjfv/** 650169240Sjfv * e1000_get_cfg_done_80003es2lan - Wait for configuration to complete 651169589Sjfv * @hw: pointer to the HW structure 652169240Sjfv * 653169240Sjfv * Wait a specific amount of time for manageability processes to complete. 654169240Sjfv * This is a function pointer entry point called by the phy module. 655169240Sjfv **/ 656177867Sjfvstatic s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) 657169240Sjfv{ 658169240Sjfv s32 timeout = PHY_CFG_TIMEOUT; 659169240Sjfv s32 ret_val = E1000_SUCCESS; 660169240Sjfv u32 mask = E1000_NVM_CFG_DONE_PORT_0; 661169240Sjfv 662169240Sjfv DEBUGFUNC("e1000_get_cfg_done_80003es2lan"); 663169240Sjfv 664169240Sjfv if (hw->bus.func == 1) 665169240Sjfv mask = E1000_NVM_CFG_DONE_PORT_1; 666169240Sjfv 667169240Sjfv while (timeout) { 668169240Sjfv if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask) 669169240Sjfv break; 670169240Sjfv msec_delay(1); 671169240Sjfv timeout--; 672169240Sjfv } 673169240Sjfv if (!timeout) { 674169240Sjfv DEBUGOUT("MNG configuration cycle has not completed.\n"); 675169240Sjfv ret_val = -E1000_ERR_RESET; 676169240Sjfv goto out; 677169240Sjfv } 678169240Sjfv 679169240Sjfvout: 680169240Sjfv return ret_val; 681169240Sjfv} 682169240Sjfv 683169240Sjfv/** 684169240Sjfv * e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex 685169589Sjfv * @hw: pointer to the HW structure 686169240Sjfv * 687169240Sjfv * Force the speed and duplex settings onto the PHY. This is a 688169240Sjfv * function pointer entry point called by the phy module. 689169240Sjfv **/ 690177867Sjfvstatic s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) 691169240Sjfv{ 692177867Sjfv s32 ret_val = E1000_SUCCESS; 693169240Sjfv u16 phy_data; 694173788Sjfv bool link; 695169240Sjfv 696169240Sjfv DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); 697169240Sjfv 698177867Sjfv if (!(hw->phy.ops.read_reg)) 699177867Sjfv goto out; 700177867Sjfv 701173788Sjfv /* 702173788Sjfv * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI 703169240Sjfv * forced whenever speed and duplex are forced. 704169240Sjfv */ 705177867Sjfv ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); 706169240Sjfv if (ret_val) 707169240Sjfv goto out; 708169240Sjfv 709169240Sjfv phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; 710177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); 711169240Sjfv if (ret_val) 712169240Sjfv goto out; 713169240Sjfv 714169240Sjfv DEBUGOUT1("GG82563 PSCR: %X\n", phy_data); 715169240Sjfv 716177867Sjfv ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data); 717169240Sjfv if (ret_val) 718169240Sjfv goto out; 719169240Sjfv 720169240Sjfv e1000_phy_force_speed_duplex_setup(hw, &phy_data); 721169240Sjfv 722169240Sjfv /* Reset the phy to commit changes. */ 723169240Sjfv phy_data |= MII_CR_RESET; 724169240Sjfv 725177867Sjfv ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data); 726169240Sjfv if (ret_val) 727169240Sjfv goto out; 728169240Sjfv 729169240Sjfv usec_delay(1); 730169240Sjfv 731173788Sjfv if (hw->phy.autoneg_wait_to_complete) { 732169240Sjfv DEBUGOUT("Waiting for forced speed/duplex link " 733169240Sjfv "on GG82563 phy.\n"); 734169240Sjfv 735169240Sjfv ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 736169240Sjfv 100000, &link); 737169240Sjfv if (ret_val) 738169240Sjfv goto out; 739169240Sjfv 740169240Sjfv if (!link) { 741173788Sjfv /* 742173788Sjfv * We didn't get link. 743169240Sjfv * Reset the DSP and cross our fingers. 744169240Sjfv */ 745169240Sjfv ret_val = e1000_phy_reset_dsp_generic(hw); 746169240Sjfv if (ret_val) 747169240Sjfv goto out; 748169240Sjfv } 749169240Sjfv 750169240Sjfv /* Try once more */ 751169240Sjfv ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 752169240Sjfv 100000, &link); 753169240Sjfv if (ret_val) 754169240Sjfv goto out; 755169240Sjfv } 756169240Sjfv 757177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); 758169240Sjfv if (ret_val) 759169240Sjfv goto out; 760169240Sjfv 761173788Sjfv /* 762173788Sjfv * Resetting the phy means we need to verify the TX_CLK corresponds 763169240Sjfv * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. 764169240Sjfv */ 765169240Sjfv phy_data &= ~GG82563_MSCR_TX_CLK_MASK; 766169240Sjfv if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED) 767169240Sjfv phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5; 768169240Sjfv else 769169240Sjfv phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; 770169240Sjfv 771173788Sjfv /* 772173788Sjfv * In addition, we must re-enable CRS on Tx for both half and full 773169240Sjfv * duplex. 774169240Sjfv */ 775169240Sjfv phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; 776177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); 777169240Sjfv 778169240Sjfvout: 779169240Sjfv return ret_val; 780169240Sjfv} 781169240Sjfv 782169240Sjfv/** 783169240Sjfv * e1000_get_cable_length_80003es2lan - Set approximate cable length 784169589Sjfv * @hw: pointer to the HW structure 785169240Sjfv * 786169240Sjfv * Find the approximate cable length as measured by the GG82563 PHY. 787169240Sjfv * This is a function pointer entry point called by the phy module. 788169240Sjfv **/ 789177867Sjfvstatic s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) 790169240Sjfv{ 791169240Sjfv struct e1000_phy_info *phy = &hw->phy; 792177867Sjfv s32 ret_val = E1000_SUCCESS; 793169240Sjfv u16 phy_data, index; 794169240Sjfv 795169240Sjfv DEBUGFUNC("e1000_get_cable_length_80003es2lan"); 796169240Sjfv 797177867Sjfv if (!(hw->phy.ops.read_reg)) 798177867Sjfv goto out; 799177867Sjfv 800177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); 801169240Sjfv if (ret_val) 802169240Sjfv goto out; 803169240Sjfv 804169240Sjfv index = phy_data & GG82563_DSPD_CABLE_LENGTH; 805169240Sjfv 806200243Sjfv if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) { 807200243Sjfv ret_val = -E1000_ERR_PHY; 808190872Sjfv goto out; 809185353Sjfv } 810185353Sjfv 811190872Sjfv phy->min_cable_length = e1000_gg82563_cable_length_table[index]; 812200243Sjfv phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5]; 813190872Sjfv 814190872Sjfv phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; 815190872Sjfv 816169240Sjfvout: 817169240Sjfv return ret_val; 818169240Sjfv} 819169240Sjfv 820169240Sjfv/** 821169240Sjfv * e1000_get_link_up_info_80003es2lan - Report speed and duplex 822169589Sjfv * @hw: pointer to the HW structure 823169589Sjfv * @speed: pointer to speed buffer 824169589Sjfv * @duplex: pointer to duplex buffer 825169240Sjfv * 826169240Sjfv * Retrieve the current speed and duplex configuration. 827169240Sjfv **/ 828177867Sjfvstatic s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, 829173788Sjfv u16 *duplex) 830169240Sjfv{ 831169240Sjfv s32 ret_val; 832169240Sjfv 833169240Sjfv DEBUGFUNC("e1000_get_link_up_info_80003es2lan"); 834169240Sjfv 835173788Sjfv if (hw->phy.media_type == e1000_media_type_copper) { 836169240Sjfv ret_val = e1000_get_speed_and_duplex_copper_generic(hw, 837169240Sjfv speed, 838169240Sjfv duplex); 839185353Sjfv hw->phy.ops.cfg_on_link_up(hw); 840173788Sjfv } else { 841169240Sjfv ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, 842169240Sjfv speed, 843169240Sjfv duplex); 844173788Sjfv } 845169240Sjfv 846169240Sjfv return ret_val; 847169240Sjfv} 848169240Sjfv 849169240Sjfv/** 850169240Sjfv * e1000_reset_hw_80003es2lan - Reset the ESB2 controller 851169589Sjfv * @hw: pointer to the HW structure 852169240Sjfv * 853169240Sjfv * Perform a global reset to the ESB2 controller. 854169240Sjfv **/ 855177867Sjfvstatic s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) 856169240Sjfv{ 857169240Sjfv u32 ctrl, icr; 858169240Sjfv s32 ret_val; 859169240Sjfv 860169240Sjfv DEBUGFUNC("e1000_reset_hw_80003es2lan"); 861169240Sjfv 862173788Sjfv /* 863173788Sjfv * Prevent the PCI-E bus from sticking if there is no TLP connection 864169240Sjfv * on the last TLP read/write transaction when MAC is reset. 865169240Sjfv */ 866169240Sjfv ret_val = e1000_disable_pcie_master_generic(hw); 867185353Sjfv if (ret_val) 868169240Sjfv DEBUGOUT("PCI-E Master disable polling has failed.\n"); 869169240Sjfv 870169240Sjfv DEBUGOUT("Masking off all interrupts\n"); 871169240Sjfv E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 872169240Sjfv 873169240Sjfv E1000_WRITE_REG(hw, E1000_RCTL, 0); 874169240Sjfv E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); 875169240Sjfv E1000_WRITE_FLUSH(hw); 876169240Sjfv 877169240Sjfv msec_delay(10); 878169240Sjfv 879169240Sjfv ctrl = E1000_READ_REG(hw, E1000_CTRL); 880169240Sjfv 881185353Sjfv ret_val = e1000_acquire_phy_80003es2lan(hw); 882169240Sjfv DEBUGOUT("Issuing a global reset to MAC\n"); 883169240Sjfv E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); 884185353Sjfv e1000_release_phy_80003es2lan(hw); 885169240Sjfv 886169240Sjfv ret_val = e1000_get_auto_rd_done_generic(hw); 887169240Sjfv if (ret_val) 888169240Sjfv /* We don't want to continue accessing MAC registers. */ 889169240Sjfv goto out; 890169240Sjfv 891169240Sjfv /* Clear any pending interrupt events. */ 892169240Sjfv E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); 893169240Sjfv icr = E1000_READ_REG(hw, E1000_ICR); 894169240Sjfv 895190872Sjfv ret_val = e1000_check_alt_mac_addr_generic(hw); 896176667Sjfv 897169240Sjfvout: 898169240Sjfv return ret_val; 899169240Sjfv} 900169240Sjfv 901169240Sjfv/** 902169240Sjfv * e1000_init_hw_80003es2lan - Initialize the ESB2 controller 903169589Sjfv * @hw: pointer to the HW structure 904169240Sjfv * 905169240Sjfv * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. 906169240Sjfv **/ 907177867Sjfvstatic s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) 908169240Sjfv{ 909169240Sjfv struct e1000_mac_info *mac = &hw->mac; 910169240Sjfv u32 reg_data; 911169240Sjfv s32 ret_val; 912169240Sjfv u16 i; 913169240Sjfv 914169240Sjfv DEBUGFUNC("e1000_init_hw_80003es2lan"); 915169240Sjfv 916169240Sjfv e1000_initialize_hw_bits_80003es2lan(hw); 917169240Sjfv 918169240Sjfv /* Initialize identification LED */ 919190872Sjfv ret_val = mac->ops.id_led_init(hw); 920200243Sjfv if (ret_val) 921169240Sjfv DEBUGOUT("Error initializing identification LED\n"); 922173788Sjfv /* This is not fatal and we should not stop init due to this */ 923169240Sjfv 924169240Sjfv /* Disabling VLAN filtering */ 925169240Sjfv DEBUGOUT("Initializing the IEEE VLAN\n"); 926177867Sjfv mac->ops.clear_vfta(hw); 927169240Sjfv 928169240Sjfv /* Setup the receive address. */ 929169240Sjfv e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); 930169240Sjfv 931169240Sjfv /* Zero out the Multicast HASH table */ 932169240Sjfv DEBUGOUT("Zeroing the MTA\n"); 933169240Sjfv for (i = 0; i < mac->mta_reg_count; i++) 934169240Sjfv E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); 935169240Sjfv 936169240Sjfv /* Setup link and flow control */ 937177867Sjfv ret_val = mac->ops.setup_link(hw); 938169240Sjfv 939169240Sjfv /* Set the transmit descriptor write-back policy */ 940173788Sjfv reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); 941169240Sjfv reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | 942169240Sjfv E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; 943173788Sjfv E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); 944169240Sjfv 945169240Sjfv /* ...for both queues. */ 946173788Sjfv reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); 947169240Sjfv reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | 948169240Sjfv E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; 949173788Sjfv E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); 950169240Sjfv 951169240Sjfv /* Enable retransmit on late collisions */ 952169240Sjfv reg_data = E1000_READ_REG(hw, E1000_TCTL); 953169240Sjfv reg_data |= E1000_TCTL_RTLC; 954169240Sjfv E1000_WRITE_REG(hw, E1000_TCTL, reg_data); 955169240Sjfv 956169240Sjfv /* Configure Gigabit Carry Extend Padding */ 957169240Sjfv reg_data = E1000_READ_REG(hw, E1000_TCTL_EXT); 958169240Sjfv reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; 959169240Sjfv reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN; 960169240Sjfv E1000_WRITE_REG(hw, E1000_TCTL_EXT, reg_data); 961169240Sjfv 962169240Sjfv /* Configure Transmit Inter-Packet Gap */ 963169240Sjfv reg_data = E1000_READ_REG(hw, E1000_TIPG); 964169240Sjfv reg_data &= ~E1000_TIPG_IPGT_MASK; 965169240Sjfv reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; 966169240Sjfv E1000_WRITE_REG(hw, E1000_TIPG, reg_data); 967169240Sjfv 968169240Sjfv reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001); 969169240Sjfv reg_data &= ~0x00100000; 970169240Sjfv E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); 971169240Sjfv 972200243Sjfv /* default to TRUE to enable the MDIC W/A */ 973200243Sjfv hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE; 974200243Sjfv 975200243Sjfv ret_val = e1000_read_kmrn_reg_80003es2lan(hw, 976200243Sjfv E1000_KMRNCTRLSTA_OFFSET >> 977200243Sjfv E1000_KMRNCTRLSTA_OFFSET_SHIFT, 978200243Sjfv &i); 979200243Sjfv if (!ret_val) { 980200243Sjfv if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == 981200243Sjfv E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) 982200243Sjfv hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE; 983200243Sjfv } 984200243Sjfv 985173788Sjfv /* 986173788Sjfv * Clear all of the statistics registers (clear on read). It is 987169240Sjfv * important that we do this after we have tried to establish link 988169240Sjfv * because the symbol error count will increment wildly if there 989169240Sjfv * is no link. 990169240Sjfv */ 991169240Sjfv e1000_clear_hw_cntrs_80003es2lan(hw); 992169240Sjfv 993169240Sjfv return ret_val; 994169240Sjfv} 995169240Sjfv 996169240Sjfv/** 997169240Sjfv * e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2 998169589Sjfv * @hw: pointer to the HW structure 999169240Sjfv * 1000169240Sjfv * Initializes required hardware-dependent bits needed for normal operation. 1001169240Sjfv **/ 1002173788Sjfvstatic void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) 1003169240Sjfv{ 1004169240Sjfv u32 reg; 1005169240Sjfv 1006169240Sjfv DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan"); 1007169240Sjfv 1008169240Sjfv /* Transmit Descriptor Control 0 */ 1009173788Sjfv reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); 1010169240Sjfv reg |= (1 << 22); 1011173788Sjfv E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); 1012169240Sjfv 1013169240Sjfv /* Transmit Descriptor Control 1 */ 1014173788Sjfv reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); 1015169240Sjfv reg |= (1 << 22); 1016173788Sjfv E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); 1017169240Sjfv 1018169240Sjfv /* Transmit Arbitration Control 0 */ 1019173788Sjfv reg = E1000_READ_REG(hw, E1000_TARC(0)); 1020169240Sjfv reg &= ~(0xF << 27); /* 30:27 */ 1021173788Sjfv if (hw->phy.media_type != e1000_media_type_copper) 1022169240Sjfv reg &= ~(1 << 20); 1023173788Sjfv E1000_WRITE_REG(hw, E1000_TARC(0), reg); 1024169240Sjfv 1025169240Sjfv /* Transmit Arbitration Control 1 */ 1026173788Sjfv reg = E1000_READ_REG(hw, E1000_TARC(1)); 1027169240Sjfv if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) 1028169240Sjfv reg &= ~(1 << 28); 1029169240Sjfv else 1030169240Sjfv reg |= (1 << 28); 1031173788Sjfv E1000_WRITE_REG(hw, E1000_TARC(1), reg); 1032169240Sjfv 1033169240Sjfv return; 1034169240Sjfv} 1035169240Sjfv 1036169240Sjfv/** 1037169240Sjfv * e1000_copper_link_setup_gg82563_80003es2lan - Configure GG82563 Link 1038169589Sjfv * @hw: pointer to the HW structure 1039169240Sjfv * 1040169240Sjfv * Setup some GG82563 PHY registers for obtaining link 1041169240Sjfv **/ 1042173788Sjfvstatic s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) 1043169240Sjfv{ 1044176667Sjfv struct e1000_phy_info *phy = &hw->phy; 1045176667Sjfv s32 ret_val; 1046169240Sjfv u32 ctrl_ext; 1047185353Sjfv u16 data; 1048169240Sjfv 1049169240Sjfv DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); 1050169240Sjfv 1051169240Sjfv if (!phy->reset_disable) { 1052177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, 1053169240Sjfv &data); 1054169240Sjfv if (ret_val) 1055169240Sjfv goto out; 1056169240Sjfv 1057169240Sjfv data |= GG82563_MSCR_ASSERT_CRS_ON_TX; 1058169240Sjfv /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ 1059169240Sjfv data |= GG82563_MSCR_TX_CLK_1000MBPS_25; 1060169240Sjfv 1061177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, 1062169240Sjfv data); 1063169240Sjfv if (ret_val) 1064169240Sjfv goto out; 1065169240Sjfv 1066173788Sjfv /* 1067173788Sjfv * Options: 1068169240Sjfv * MDI/MDI-X = 0 (default) 1069169240Sjfv * 0 - Auto for all speeds 1070169240Sjfv * 1 - MDI mode 1071169240Sjfv * 2 - MDI-X mode 1072169240Sjfv * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) 1073169240Sjfv */ 1074177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); 1075169240Sjfv if (ret_val) 1076169240Sjfv goto out; 1077169240Sjfv 1078169240Sjfv data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; 1079169240Sjfv 1080169240Sjfv switch (phy->mdix) { 1081169240Sjfv case 1: 1082169240Sjfv data |= GG82563_PSCR_CROSSOVER_MODE_MDI; 1083169240Sjfv break; 1084169240Sjfv case 2: 1085169240Sjfv data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; 1086169240Sjfv break; 1087169240Sjfv case 0: 1088169240Sjfv default: 1089169240Sjfv data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; 1090169240Sjfv break; 1091169240Sjfv } 1092169240Sjfv 1093173788Sjfv /* 1094173788Sjfv * Options: 1095169240Sjfv * disable_polarity_correction = 0 (default) 1096169240Sjfv * Automatic Correction for Reversed Cable Polarity 1097169240Sjfv * 0 - Disabled 1098169240Sjfv * 1 - Enabled 1099169240Sjfv */ 1100169240Sjfv data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; 1101173788Sjfv if (phy->disable_polarity_correction) 1102169240Sjfv data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; 1103169240Sjfv 1104177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); 1105169240Sjfv if (ret_val) 1106169240Sjfv goto out; 1107169240Sjfv 1108169240Sjfv /* SW Reset the PHY so all changes take effect */ 1109177867Sjfv ret_val = hw->phy.ops.commit(hw); 1110169240Sjfv if (ret_val) { 1111169240Sjfv DEBUGOUT("Error Resetting the PHY\n"); 1112169240Sjfv goto out; 1113169240Sjfv } 1114169240Sjfv 1115169240Sjfv } 1116169240Sjfv 1117173788Sjfv /* Bypass Rx and Tx FIFO's */ 1118185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 1119190872Sjfv E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, 1120190872Sjfv E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | 1121190872Sjfv E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); 1122169240Sjfv if (ret_val) 1123169240Sjfv goto out; 1124169240Sjfv 1125185353Sjfv ret_val = e1000_read_kmrn_reg_80003es2lan(hw, 1126176667Sjfv E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, 1127176667Sjfv &data); 1128173788Sjfv if (ret_val) 1129173788Sjfv goto out; 1130173788Sjfv data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; 1131185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 1132176667Sjfv E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, 1133176667Sjfv data); 1134173788Sjfv if (ret_val) 1135173788Sjfv goto out; 1136173788Sjfv 1137177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); 1138169240Sjfv if (ret_val) 1139169240Sjfv goto out; 1140169240Sjfv 1141169240Sjfv data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; 1142177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data); 1143169240Sjfv if (ret_val) 1144169240Sjfv goto out; 1145169240Sjfv 1146169240Sjfv ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); 1147169240Sjfv ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); 1148169240Sjfv E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); 1149169240Sjfv 1150177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); 1151169240Sjfv if (ret_val) 1152169240Sjfv goto out; 1153169240Sjfv 1154173788Sjfv /* 1155173788Sjfv * Do not init these registers when the HW is in IAMT mode, since the 1156169240Sjfv * firmware will have already initialized them. We only initialize 1157169240Sjfv * them if the HW is not in IAMT mode. 1158169240Sjfv */ 1159177867Sjfv if (!(hw->mac.ops.check_mng_mode(hw))) { 1160169240Sjfv /* Enable Electrical Idle on the PHY */ 1161169240Sjfv data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; 1162190872Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, 1163185353Sjfv data); 1164169240Sjfv if (ret_val) 1165169240Sjfv goto out; 1166169240Sjfv 1167190872Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 1168190872Sjfv &data); 1169190872Sjfv if (ret_val) 1170190872Sjfv goto out; 1171190872Sjfv 1172169240Sjfv data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; 1173190872Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 1174185353Sjfv data); 1175169240Sjfv if (ret_val) 1176169240Sjfv goto out; 1177169240Sjfv } 1178169240Sjfv 1179173788Sjfv /* 1180173788Sjfv * Workaround: Disable padding in Kumeran interface in the MAC 1181169240Sjfv * and in the PHY to avoid CRC errors. 1182169240Sjfv */ 1183177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data); 1184169240Sjfv if (ret_val) 1185169240Sjfv goto out; 1186169240Sjfv 1187169240Sjfv data |= GG82563_ICR_DIS_PADDING; 1188177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data); 1189169240Sjfv if (ret_val) 1190169240Sjfv goto out; 1191169240Sjfv 1192169240Sjfvout: 1193169240Sjfv return ret_val; 1194169240Sjfv} 1195169240Sjfv 1196169240Sjfv/** 1197169240Sjfv * e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2 1198169589Sjfv * @hw: pointer to the HW structure 1199169240Sjfv * 1200169240Sjfv * Essentially a wrapper for setting up all things "copper" related. 1201169240Sjfv * This is a function pointer entry point called by the mac module. 1202169240Sjfv **/ 1203177867Sjfvstatic s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) 1204169240Sjfv{ 1205169240Sjfv u32 ctrl; 1206185353Sjfv s32 ret_val; 1207169240Sjfv u16 reg_data; 1208169240Sjfv 1209169240Sjfv DEBUGFUNC("e1000_setup_copper_link_80003es2lan"); 1210169240Sjfv 1211169240Sjfv ctrl = E1000_READ_REG(hw, E1000_CTRL); 1212169240Sjfv ctrl |= E1000_CTRL_SLU; 1213169240Sjfv ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); 1214169240Sjfv E1000_WRITE_REG(hw, E1000_CTRL, ctrl); 1215169240Sjfv 1216173788Sjfv /* 1217173788Sjfv * Set the mac to wait the maximum time between each 1218169240Sjfv * iteration and increase the max iterations when 1219173788Sjfv * polling the phy; this fixes erroneous timeouts at 10Mbps. 1220173788Sjfv */ 1221185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4), 1222185353Sjfv 0xFFFF); 1223169240Sjfv if (ret_val) 1224169240Sjfv goto out; 1225185353Sjfv ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), 1226185353Sjfv ®_data); 1227169240Sjfv if (ret_val) 1228169240Sjfv goto out; 1229169240Sjfv reg_data |= 0x3F; 1230185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), 1231185353Sjfv reg_data); 1232169240Sjfv if (ret_val) 1233169240Sjfv goto out; 1234185353Sjfv ret_val = e1000_read_kmrn_reg_80003es2lan(hw, 1235169240Sjfv E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, 1236169240Sjfv ®_data); 1237169240Sjfv if (ret_val) 1238169240Sjfv goto out; 1239169240Sjfv reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; 1240185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 1241169240Sjfv E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, 1242169240Sjfv reg_data); 1243169240Sjfv if (ret_val) 1244169240Sjfv goto out; 1245169240Sjfv 1246169240Sjfv ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw); 1247169240Sjfv if (ret_val) 1248169240Sjfv goto out; 1249169240Sjfv 1250169240Sjfv ret_val = e1000_setup_copper_link_generic(hw); 1251169240Sjfv 1252169240Sjfvout: 1253169240Sjfv return ret_val; 1254169240Sjfv} 1255169240Sjfv 1256169240Sjfv/** 1257185353Sjfv * e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up 1258185353Sjfv * @hw: pointer to the HW structure 1259185353Sjfv * @duplex: current duplex setting 1260185353Sjfv * 1261185353Sjfv * Configure the KMRN interface by applying last minute quirks for 1262185353Sjfv * 10/100 operation. 1263185353Sjfv **/ 1264185353Sjfvstatic s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) 1265185353Sjfv{ 1266185353Sjfv s32 ret_val = E1000_SUCCESS; 1267185353Sjfv u16 speed; 1268185353Sjfv u16 duplex; 1269185353Sjfv 1270185353Sjfv DEBUGFUNC("e1000_configure_on_link_up"); 1271185353Sjfv 1272185353Sjfv if (hw->phy.media_type == e1000_media_type_copper) { 1273185353Sjfv ret_val = e1000_get_speed_and_duplex_copper_generic(hw, 1274185353Sjfv &speed, 1275185353Sjfv &duplex); 1276185353Sjfv if (ret_val) 1277185353Sjfv goto out; 1278185353Sjfv 1279185353Sjfv if (speed == SPEED_1000) 1280185353Sjfv ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); 1281185353Sjfv else 1282185353Sjfv ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex); 1283185353Sjfv } 1284185353Sjfv 1285185353Sjfvout: 1286185353Sjfv return ret_val; 1287185353Sjfv} 1288185353Sjfv 1289185353Sjfv/** 1290169240Sjfv * e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation 1291169589Sjfv * @hw: pointer to the HW structure 1292169589Sjfv * @duplex: current duplex setting 1293169240Sjfv * 1294169240Sjfv * Configure the KMRN interface by applying last minute quirks for 1295169240Sjfv * 10/100 operation. 1296169240Sjfv **/ 1297173788Sjfvstatic s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) 1298169240Sjfv{ 1299169240Sjfv s32 ret_val = E1000_SUCCESS; 1300169240Sjfv u32 tipg; 1301169589Sjfv u32 i = 0; 1302169589Sjfv u16 reg_data, reg_data2; 1303169240Sjfv 1304169240Sjfv DEBUGFUNC("e1000_configure_kmrn_for_10_100"); 1305169240Sjfv 1306169240Sjfv reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; 1307185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 1308169240Sjfv E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, 1309169240Sjfv reg_data); 1310169240Sjfv if (ret_val) 1311169240Sjfv goto out; 1312169240Sjfv 1313169240Sjfv /* Configure Transmit Inter-Packet Gap */ 1314169240Sjfv tipg = E1000_READ_REG(hw, E1000_TIPG); 1315169240Sjfv tipg &= ~E1000_TIPG_IPGT_MASK; 1316169240Sjfv tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; 1317169240Sjfv E1000_WRITE_REG(hw, E1000_TIPG, tipg); 1318169240Sjfv 1319169589Sjfv do { 1320177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 1321185353Sjfv ®_data); 1322169589Sjfv if (ret_val) 1323169589Sjfv goto out; 1324169589Sjfv 1325177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 1326185353Sjfv ®_data2); 1327169589Sjfv if (ret_val) 1328169589Sjfv goto out; 1329169589Sjfv i++; 1330169589Sjfv } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); 1331169589Sjfv 1332169240Sjfv if (duplex == HALF_DUPLEX) 1333169240Sjfv reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; 1334169240Sjfv else 1335169240Sjfv reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; 1336169240Sjfv 1337177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); 1338169240Sjfv 1339169240Sjfvout: 1340169240Sjfv return ret_val; 1341169240Sjfv} 1342169240Sjfv 1343169240Sjfv/** 1344169240Sjfv * e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation 1345169589Sjfv * @hw: pointer to the HW structure 1346169240Sjfv * 1347169240Sjfv * Configure the KMRN interface by applying last minute quirks for 1348169240Sjfv * gigabit operation. 1349169240Sjfv **/ 1350173788Sjfvstatic s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) 1351169240Sjfv{ 1352169240Sjfv s32 ret_val = E1000_SUCCESS; 1353169589Sjfv u16 reg_data, reg_data2; 1354169240Sjfv u32 tipg; 1355169589Sjfv u32 i = 0; 1356169240Sjfv 1357169240Sjfv DEBUGFUNC("e1000_configure_kmrn_for_1000"); 1358169240Sjfv 1359169240Sjfv reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; 1360185353Sjfv ret_val = e1000_write_kmrn_reg_80003es2lan(hw, 1361169240Sjfv E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, 1362169240Sjfv reg_data); 1363169240Sjfv if (ret_val) 1364169240Sjfv goto out; 1365169240Sjfv 1366169240Sjfv /* Configure Transmit Inter-Packet Gap */ 1367169240Sjfv tipg = E1000_READ_REG(hw, E1000_TIPG); 1368169240Sjfv tipg &= ~E1000_TIPG_IPGT_MASK; 1369169240Sjfv tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; 1370169240Sjfv E1000_WRITE_REG(hw, E1000_TIPG, tipg); 1371169240Sjfv 1372169589Sjfv do { 1373177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 1374185353Sjfv ®_data); 1375169589Sjfv if (ret_val) 1376169589Sjfv goto out; 1377169589Sjfv 1378177867Sjfv ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 1379185353Sjfv ®_data2); 1380169589Sjfv if (ret_val) 1381169589Sjfv goto out; 1382169589Sjfv i++; 1383169589Sjfv } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); 1384169589Sjfv 1385169240Sjfv reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; 1386177867Sjfv ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); 1387169240Sjfv 1388169240Sjfvout: 1389169240Sjfv return ret_val; 1390169240Sjfv} 1391169240Sjfv 1392169240Sjfv/** 1393185353Sjfv * e1000_read_kmrn_reg_80003es2lan - Read kumeran register 1394185353Sjfv * @hw: pointer to the HW structure 1395185353Sjfv * @offset: register offset to be read 1396185353Sjfv * @data: pointer to the read data 1397185353Sjfv * 1398185353Sjfv * Acquire semaphore, then read the PHY register at offset 1399185353Sjfv * using the kumeran interface. The information retrieved is stored in data. 1400185353Sjfv * Release the semaphore before exiting. 1401185353Sjfv **/ 1402190872Sjfvstatic s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 1403190872Sjfv u16 *data) 1404185353Sjfv{ 1405185353Sjfv u32 kmrnctrlsta; 1406185353Sjfv s32 ret_val = E1000_SUCCESS; 1407185353Sjfv 1408185353Sjfv DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan"); 1409185353Sjfv 1410185353Sjfv ret_val = e1000_acquire_mac_csr_80003es2lan(hw); 1411185353Sjfv if (ret_val) 1412185353Sjfv goto out; 1413185353Sjfv 1414185353Sjfv kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 1415185353Sjfv E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; 1416185353Sjfv E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); 1417185353Sjfv 1418185353Sjfv usec_delay(2); 1419185353Sjfv 1420185353Sjfv kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); 1421185353Sjfv *data = (u16)kmrnctrlsta; 1422185353Sjfv 1423185353Sjfv e1000_release_mac_csr_80003es2lan(hw); 1424185353Sjfv 1425185353Sjfvout: 1426185353Sjfv return ret_val; 1427185353Sjfv} 1428185353Sjfv 1429185353Sjfv/** 1430185353Sjfv * e1000_write_kmrn_reg_80003es2lan - Write kumeran register 1431185353Sjfv * @hw: pointer to the HW structure 1432185353Sjfv * @offset: register offset to write to 1433185353Sjfv * @data: data to write at register offset 1434185353Sjfv * 1435185353Sjfv * Acquire semaphore, then write the data to PHY register 1436185353Sjfv * at the offset using the kumeran interface. Release semaphore 1437185353Sjfv * before exiting. 1438185353Sjfv **/ 1439190872Sjfvstatic s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 1440190872Sjfv u16 data) 1441185353Sjfv{ 1442185353Sjfv u32 kmrnctrlsta; 1443185353Sjfv s32 ret_val = E1000_SUCCESS; 1444185353Sjfv 1445185353Sjfv DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan"); 1446185353Sjfv 1447185353Sjfv ret_val = e1000_acquire_mac_csr_80003es2lan(hw); 1448185353Sjfv if (ret_val) 1449185353Sjfv goto out; 1450185353Sjfv 1451185353Sjfv kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 1452185353Sjfv E1000_KMRNCTRLSTA_OFFSET) | data; 1453185353Sjfv E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); 1454185353Sjfv 1455185353Sjfv usec_delay(2); 1456185353Sjfv 1457185353Sjfv e1000_release_mac_csr_80003es2lan(hw); 1458185353Sjfv 1459185353Sjfvout: 1460185353Sjfv return ret_val; 1461185353Sjfv} 1462185353Sjfv 1463185353Sjfv/** 1464176667Sjfv * e1000_read_mac_addr_80003es2lan - Read device MAC address 1465176667Sjfv * @hw: pointer to the HW structure 1466176667Sjfv **/ 1467177867Sjfvstatic s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) 1468176667Sjfv{ 1469176667Sjfv s32 ret_val = E1000_SUCCESS; 1470176667Sjfv 1471176667Sjfv DEBUGFUNC("e1000_read_mac_addr_80003es2lan"); 1472176667Sjfv 1473190872Sjfv /* 1474190872Sjfv * If there's an alternate MAC address place it in RAR0 1475190872Sjfv * so that it will override the Si installed default perm 1476190872Sjfv * address. 1477190872Sjfv */ 1478190872Sjfv ret_val = e1000_check_alt_mac_addr_generic(hw); 1479190872Sjfv if (ret_val) 1480190872Sjfv goto out; 1481190872Sjfv 1482190872Sjfv ret_val = e1000_read_mac_addr_generic(hw); 1483190872Sjfv 1484190872Sjfvout: 1485176667Sjfv return ret_val; 1486176667Sjfv} 1487176667Sjfv 1488176667Sjfv/** 1489173788Sjfv * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down 1490173788Sjfv * @hw: pointer to the HW structure 1491173788Sjfv * 1492173788Sjfv * In the case of a PHY power down to save power, or to turn off link during a 1493173788Sjfv * driver unload, or wake on lan is not enabled, remove the link. 1494173788Sjfv **/ 1495177867Sjfvstatic void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) 1496173788Sjfv{ 1497173788Sjfv /* If the management interface is not enabled, then power down */ 1498177867Sjfv if (!(hw->mac.ops.check_mng_mode(hw) || 1499177867Sjfv hw->phy.ops.check_reset_block(hw))) 1500173788Sjfv e1000_power_down_phy_copper(hw); 1501173788Sjfv 1502173788Sjfv return; 1503173788Sjfv} 1504173788Sjfv 1505173788Sjfv/** 1506169240Sjfv * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters 1507169589Sjfv * @hw: pointer to the HW structure 1508169240Sjfv * 1509169240Sjfv * Clears the hardware counters by reading the counter registers. 1510169240Sjfv **/ 1511177867Sjfvstatic void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) 1512169240Sjfv{ 1513169240Sjfv DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan"); 1514169240Sjfv 1515169240Sjfv e1000_clear_hw_cntrs_base_generic(hw); 1516169240Sjfv 1517185353Sjfv E1000_READ_REG(hw, E1000_PRC64); 1518185353Sjfv E1000_READ_REG(hw, E1000_PRC127); 1519185353Sjfv E1000_READ_REG(hw, E1000_PRC255); 1520185353Sjfv E1000_READ_REG(hw, E1000_PRC511); 1521185353Sjfv E1000_READ_REG(hw, E1000_PRC1023); 1522185353Sjfv E1000_READ_REG(hw, E1000_PRC1522); 1523185353Sjfv E1000_READ_REG(hw, E1000_PTC64); 1524185353Sjfv E1000_READ_REG(hw, E1000_PTC127); 1525185353Sjfv E1000_READ_REG(hw, E1000_PTC255); 1526185353Sjfv E1000_READ_REG(hw, E1000_PTC511); 1527185353Sjfv E1000_READ_REG(hw, E1000_PTC1023); 1528185353Sjfv E1000_READ_REG(hw, E1000_PTC1522); 1529169240Sjfv 1530185353Sjfv E1000_READ_REG(hw, E1000_ALGNERRC); 1531185353Sjfv E1000_READ_REG(hw, E1000_RXERRC); 1532185353Sjfv E1000_READ_REG(hw, E1000_TNCRS); 1533185353Sjfv E1000_READ_REG(hw, E1000_CEXTERR); 1534185353Sjfv E1000_READ_REG(hw, E1000_TSCTC); 1535185353Sjfv E1000_READ_REG(hw, E1000_TSCTFC); 1536169240Sjfv 1537185353Sjfv E1000_READ_REG(hw, E1000_MGTPRC); 1538185353Sjfv E1000_READ_REG(hw, E1000_MGTPDC); 1539185353Sjfv E1000_READ_REG(hw, E1000_MGTPTC); 1540169240Sjfv 1541185353Sjfv E1000_READ_REG(hw, E1000_IAC); 1542185353Sjfv E1000_READ_REG(hw, E1000_ICRXOC); 1543169240Sjfv 1544185353Sjfv E1000_READ_REG(hw, E1000_ICRXPTC); 1545185353Sjfv E1000_READ_REG(hw, E1000_ICRXATC); 1546185353Sjfv E1000_READ_REG(hw, E1000_ICTXPTC); 1547185353Sjfv E1000_READ_REG(hw, E1000_ICTXATC); 1548185353Sjfv E1000_READ_REG(hw, E1000_ICTXQEC); 1549185353Sjfv E1000_READ_REG(hw, E1000_ICTXQMTC); 1550185353Sjfv E1000_READ_REG(hw, E1000_ICRXDMTC); 1551169240Sjfv} 1552