ixgbe_x540.c revision 238149
1230775Sjfv/****************************************************************************** 2230775Sjfv 3230775Sjfv Copyright (c) 2001-2012, Intel Corporation 4230775Sjfv All rights reserved. 5230775Sjfv 6230775Sjfv Redistribution and use in source and binary forms, with or without 7230775Sjfv modification, are permitted provided that the following conditions are met: 8230775Sjfv 9230775Sjfv 1. Redistributions of source code must retain the above copyright notice, 10230775Sjfv this list of conditions and the following disclaimer. 11230775Sjfv 12230775Sjfv 2. Redistributions in binary form must reproduce the above copyright 13230775Sjfv notice, this list of conditions and the following disclaimer in the 14230775Sjfv documentation and/or other materials provided with the distribution. 15230775Sjfv 16230775Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17230775Sjfv contributors may be used to endorse or promote products derived from 18230775Sjfv this software without specific prior written permission. 19230775Sjfv 20230775Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21230775Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22230775Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23230775Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24230775Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25230775Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26230775Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27230775Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28230775Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29230775Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30230775Sjfv POSSIBILITY OF SUCH DAMAGE. 31230775Sjfv 32230775Sjfv******************************************************************************/ 33230775Sjfv/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.c 238149 2012-07-05 20:51:44Z jfv $*/ 34230775Sjfv 35230775Sjfv#include "ixgbe_x540.h" 36230775Sjfv#include "ixgbe_type.h" 37230775Sjfv#include "ixgbe_api.h" 38230775Sjfv#include "ixgbe_common.h" 39230775Sjfv#include "ixgbe_phy.h" 40230775Sjfv 41230775Sjfvstatic s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); 42230775Sjfvstatic s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); 43230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); 44230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); 45230775Sjfv 46230775Sjfv/** 47230775Sjfv * ixgbe_init_ops_X540 - Inits func ptrs and MAC type 48230775Sjfv * @hw: pointer to hardware structure 49230775Sjfv * 50230775Sjfv * Initialize the function pointers and assign the MAC type for X540. 51230775Sjfv * Does not touch the hardware. 52230775Sjfv **/ 53230775Sjfvs32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) 54230775Sjfv{ 55230775Sjfv struct ixgbe_mac_info *mac = &hw->mac; 56230775Sjfv struct ixgbe_phy_info *phy = &hw->phy; 57230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 58230775Sjfv s32 ret_val; 59230775Sjfv 60230775Sjfv DEBUGFUNC("ixgbe_init_ops_X540"); 61230775Sjfv 62230775Sjfv ret_val = ixgbe_init_phy_ops_generic(hw); 63230775Sjfv ret_val = ixgbe_init_ops_generic(hw); 64230775Sjfv 65230775Sjfv 66230775Sjfv /* EEPROM */ 67230775Sjfv eeprom->ops.init_params = &ixgbe_init_eeprom_params_X540; 68230775Sjfv eeprom->ops.read = &ixgbe_read_eerd_X540; 69230775Sjfv eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_X540; 70230775Sjfv eeprom->ops.write = &ixgbe_write_eewr_X540; 71230775Sjfv eeprom->ops.write_buffer = &ixgbe_write_eewr_buffer_X540; 72230775Sjfv eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_X540; 73230775Sjfv eeprom->ops.validate_checksum = &ixgbe_validate_eeprom_checksum_X540; 74230775Sjfv eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_X540; 75230775Sjfv 76230775Sjfv /* PHY */ 77230775Sjfv phy->ops.init = &ixgbe_init_phy_ops_generic; 78230775Sjfv phy->ops.reset = NULL; 79230775Sjfv 80230775Sjfv /* MAC */ 81230775Sjfv mac->ops.reset_hw = &ixgbe_reset_hw_X540; 82230775Sjfv mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_gen2; 83230775Sjfv mac->ops.get_media_type = &ixgbe_get_media_type_X540; 84230775Sjfv mac->ops.get_supported_physical_layer = 85230775Sjfv &ixgbe_get_supported_physical_layer_X540; 86230775Sjfv mac->ops.read_analog_reg8 = NULL; 87230775Sjfv mac->ops.write_analog_reg8 = NULL; 88230775Sjfv mac->ops.start_hw = &ixgbe_start_hw_X540; 89230775Sjfv mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic; 90230775Sjfv mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic; 91230775Sjfv mac->ops.get_device_caps = &ixgbe_get_device_caps_generic; 92230775Sjfv mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic; 93230775Sjfv mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic; 94230775Sjfv mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540; 95230775Sjfv mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync_X540; 96230775Sjfv mac->ops.disable_sec_rx_path = &ixgbe_disable_sec_rx_path_generic; 97230775Sjfv mac->ops.enable_sec_rx_path = &ixgbe_enable_sec_rx_path_generic; 98230775Sjfv 99230775Sjfv /* RAR, Multicast, VLAN */ 100230775Sjfv mac->ops.set_vmdq = &ixgbe_set_vmdq_generic; 101238149Sjfv mac->ops.set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic; 102230775Sjfv mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic; 103230775Sjfv mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic; 104230775Sjfv mac->rar_highwater = 1; 105230775Sjfv mac->ops.set_vfta = &ixgbe_set_vfta_generic; 106230775Sjfv mac->ops.set_vlvf = &ixgbe_set_vlvf_generic; 107230775Sjfv mac->ops.clear_vfta = &ixgbe_clear_vfta_generic; 108230775Sjfv mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic; 109230775Sjfv mac->ops.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing; 110230775Sjfv mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing; 111230775Sjfv 112230775Sjfv /* Link */ 113230775Sjfv mac->ops.get_link_capabilities = 114230775Sjfv &ixgbe_get_copper_link_capabilities_generic; 115230775Sjfv mac->ops.setup_link = &ixgbe_setup_mac_link_X540; 116230775Sjfv mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic; 117230775Sjfv mac->ops.check_link = &ixgbe_check_mac_link_generic; 118230775Sjfv 119230775Sjfv mac->mcft_size = 128; 120230775Sjfv mac->vft_size = 128; 121230775Sjfv mac->num_rar_entries = 128; 122230775Sjfv mac->rx_pb_size = 384; 123230775Sjfv mac->max_tx_queues = 128; 124230775Sjfv mac->max_rx_queues = 128; 125230775Sjfv mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); 126230775Sjfv 127230775Sjfv /* 128230775Sjfv * FWSM register 129230775Sjfv * ARC supported; valid only if manageability features are 130230775Sjfv * enabled. 131230775Sjfv */ 132230775Sjfv mac->arc_subsystem_valid = (IXGBE_READ_REG(hw, IXGBE_FWSM) & 133230775Sjfv IXGBE_FWSM_MODE_MASK) ? TRUE : FALSE; 134230775Sjfv 135230775Sjfv hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf; 136230775Sjfv 137230775Sjfv /* LEDs */ 138230775Sjfv mac->ops.blink_led_start = ixgbe_blink_led_start_X540; 139230775Sjfv mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540; 140230775Sjfv 141230775Sjfv /* Manageability interface */ 142230775Sjfv mac->ops.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic; 143230775Sjfv 144230775Sjfv return ret_val; 145230775Sjfv} 146230775Sjfv 147230775Sjfv/** 148230775Sjfv * ixgbe_get_link_capabilities_X540 - Determines link capabilities 149230775Sjfv * @hw: pointer to hardware structure 150230775Sjfv * @speed: pointer to link speed 151230775Sjfv * @autoneg: TRUE when autoneg or autotry is enabled 152230775Sjfv * 153230775Sjfv * Determines the link capabilities by reading the AUTOC register. 154230775Sjfv **/ 155230775Sjfvs32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, 156230775Sjfv ixgbe_link_speed *speed, 157230775Sjfv bool *autoneg) 158230775Sjfv{ 159230775Sjfv ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg); 160230775Sjfv 161230775Sjfv return IXGBE_SUCCESS; 162230775Sjfv} 163230775Sjfv 164230775Sjfv/** 165230775Sjfv * ixgbe_get_media_type_X540 - Get media type 166230775Sjfv * @hw: pointer to hardware structure 167230775Sjfv * 168230775Sjfv * Returns the media type (fiber, copper, backplane) 169230775Sjfv **/ 170230775Sjfvenum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) 171230775Sjfv{ 172230775Sjfv UNREFERENCED_1PARAMETER(hw); 173230775Sjfv return ixgbe_media_type_copper; 174230775Sjfv} 175230775Sjfv 176230775Sjfv/** 177230775Sjfv * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities 178230775Sjfv * @hw: pointer to hardware structure 179230775Sjfv * @speed: new link speed 180230775Sjfv * @autoneg: TRUE if autonegotiation enabled 181230775Sjfv * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 182230775Sjfv **/ 183230775Sjfvs32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, 184230775Sjfv ixgbe_link_speed speed, bool autoneg, 185230775Sjfv bool autoneg_wait_to_complete) 186230775Sjfv{ 187230775Sjfv DEBUGFUNC("ixgbe_setup_mac_link_X540"); 188230775Sjfv return hw->phy.ops.setup_link_speed(hw, speed, autoneg, 189230775Sjfv autoneg_wait_to_complete); 190230775Sjfv} 191230775Sjfv 192230775Sjfv/** 193230775Sjfv * ixgbe_reset_hw_X540 - Perform hardware reset 194230775Sjfv * @hw: pointer to hardware structure 195230775Sjfv * 196230775Sjfv * Resets the hardware by resetting the transmit and receive units, masks 197230775Sjfv * and clears all interrupts, and perform a reset. 198230775Sjfv **/ 199230775Sjfvs32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) 200230775Sjfv{ 201230775Sjfv s32 status; 202230775Sjfv u32 ctrl, i; 203230775Sjfv 204230775Sjfv DEBUGFUNC("ixgbe_reset_hw_X540"); 205230775Sjfv 206230775Sjfv /* Call adapter stop to disable tx/rx and clear interrupts */ 207230775Sjfv status = hw->mac.ops.stop_adapter(hw); 208230775Sjfv if (status != IXGBE_SUCCESS) 209230775Sjfv goto reset_hw_out; 210230775Sjfv 211230775Sjfv /* flush pending Tx transactions */ 212230775Sjfv ixgbe_clear_tx_pending(hw); 213230775Sjfv 214230775Sjfvmac_reset_top: 215230775Sjfv ctrl = IXGBE_CTRL_RST; 216230775Sjfv ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); 217230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); 218230775Sjfv IXGBE_WRITE_FLUSH(hw); 219230775Sjfv 220230775Sjfv /* Poll for reset bit to self-clear indicating reset is complete */ 221230775Sjfv for (i = 0; i < 10; i++) { 222230775Sjfv usec_delay(1); 223230775Sjfv ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); 224230775Sjfv if (!(ctrl & IXGBE_CTRL_RST_MASK)) 225230775Sjfv break; 226230775Sjfv } 227230775Sjfv 228230775Sjfv if (ctrl & IXGBE_CTRL_RST_MASK) { 229230775Sjfv status = IXGBE_ERR_RESET_FAILED; 230230775Sjfv DEBUGOUT("Reset polling failed to complete.\n"); 231230775Sjfv } 232230775Sjfv msec_delay(100); 233230775Sjfv 234230775Sjfv /* 235230775Sjfv * Double resets are required for recovery from certain error 236230775Sjfv * conditions. Between resets, it is necessary to stall to allow time 237230775Sjfv * for any pending HW events to complete. 238230775Sjfv */ 239230775Sjfv if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { 240230775Sjfv hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 241230775Sjfv goto mac_reset_top; 242230775Sjfv } 243230775Sjfv 244230775Sjfv /* Set the Rx packet buffer size. */ 245230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); 246230775Sjfv 247230775Sjfv /* Store the permanent mac address */ 248230775Sjfv hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); 249230775Sjfv 250230775Sjfv /* 251230775Sjfv * Store MAC address from RAR0, clear receive address registers, and 252230775Sjfv * clear the multicast table. Also reset num_rar_entries to 128, 253230775Sjfv * since we modify this value when programming the SAN MAC address. 254230775Sjfv */ 255230775Sjfv hw->mac.num_rar_entries = 128; 256230775Sjfv hw->mac.ops.init_rx_addrs(hw); 257230775Sjfv 258230775Sjfv /* Store the permanent SAN mac address */ 259230775Sjfv hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); 260230775Sjfv 261230775Sjfv /* Add the SAN MAC address to the RAR only if it's a valid address */ 262230775Sjfv if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { 263230775Sjfv hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, 264230775Sjfv hw->mac.san_addr, 0, IXGBE_RAH_AV); 265230775Sjfv 266238149Sjfv /* Save the SAN MAC RAR index */ 267238149Sjfv hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; 268238149Sjfv 269230775Sjfv /* Reserve the last RAR for the SAN MAC address */ 270230775Sjfv hw->mac.num_rar_entries--; 271230775Sjfv } 272230775Sjfv 273230775Sjfv /* Store the alternative WWNN/WWPN prefix */ 274230775Sjfv hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, 275230775Sjfv &hw->mac.wwpn_prefix); 276230775Sjfv 277230775Sjfvreset_hw_out: 278230775Sjfv return status; 279230775Sjfv} 280230775Sjfv 281230775Sjfv/** 282230775Sjfv * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx 283230775Sjfv * @hw: pointer to hardware structure 284230775Sjfv * 285230775Sjfv * Starts the hardware using the generic start_hw function 286230775Sjfv * and the generation start_hw function. 287230775Sjfv * Then performs revision-specific operations, if any. 288230775Sjfv **/ 289230775Sjfvs32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) 290230775Sjfv{ 291230775Sjfv s32 ret_val = IXGBE_SUCCESS; 292230775Sjfv 293230775Sjfv DEBUGFUNC("ixgbe_start_hw_X540"); 294230775Sjfv 295230775Sjfv ret_val = ixgbe_start_hw_generic(hw); 296230775Sjfv if (ret_val != IXGBE_SUCCESS) 297230775Sjfv goto out; 298230775Sjfv 299230775Sjfv ret_val = ixgbe_start_hw_gen2(hw); 300230775Sjfv 301230775Sjfvout: 302230775Sjfv return ret_val; 303230775Sjfv} 304230775Sjfv 305230775Sjfv/** 306230775Sjfv * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type 307230775Sjfv * @hw: pointer to hardware structure 308230775Sjfv * 309230775Sjfv * Determines physical layer capabilities of the current configuration. 310230775Sjfv **/ 311230775Sjfvu32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) 312230775Sjfv{ 313230775Sjfv u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; 314230775Sjfv u16 ext_ability = 0; 315230775Sjfv 316230775Sjfv DEBUGFUNC("ixgbe_get_supported_physical_layer_X540"); 317230775Sjfv 318230775Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, 319230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); 320230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) 321230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; 322230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) 323230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; 324230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) 325230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; 326230775Sjfv 327230775Sjfv return physical_layer; 328230775Sjfv} 329230775Sjfv 330230775Sjfv/** 331230775Sjfv * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params 332230775Sjfv * @hw: pointer to hardware structure 333230775Sjfv * 334230775Sjfv * Initializes the EEPROM parameters ixgbe_eeprom_info within the 335230775Sjfv * ixgbe_hw struct in order to set up EEPROM access. 336230775Sjfv **/ 337230775Sjfvs32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) 338230775Sjfv{ 339230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 340230775Sjfv u32 eec; 341230775Sjfv u16 eeprom_size; 342230775Sjfv 343230775Sjfv DEBUGFUNC("ixgbe_init_eeprom_params_X540"); 344230775Sjfv 345230775Sjfv if (eeprom->type == ixgbe_eeprom_uninitialized) { 346230775Sjfv eeprom->semaphore_delay = 10; 347230775Sjfv eeprom->type = ixgbe_flash; 348230775Sjfv 349230775Sjfv eec = IXGBE_READ_REG(hw, IXGBE_EEC); 350230775Sjfv eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 351230775Sjfv IXGBE_EEC_SIZE_SHIFT); 352230775Sjfv eeprom->word_size = 1 << (eeprom_size + 353230775Sjfv IXGBE_EEPROM_WORD_SIZE_SHIFT); 354230775Sjfv 355230775Sjfv DEBUGOUT2("Eeprom params: type = %d, size = %d\n", 356230775Sjfv eeprom->type, eeprom->word_size); 357230775Sjfv } 358230775Sjfv 359230775Sjfv return IXGBE_SUCCESS; 360230775Sjfv} 361230775Sjfv 362230775Sjfv/** 363230775Sjfv * ixgbe_read_eerd_X540- Read EEPROM word using EERD 364230775Sjfv * @hw: pointer to hardware structure 365230775Sjfv * @offset: offset of word in the EEPROM to read 366230775Sjfv * @data: word read from the EEPROM 367230775Sjfv * 368230775Sjfv * Reads a 16 bit word from the EEPROM using the EERD register. 369230775Sjfv **/ 370230775Sjfvs32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) 371230775Sjfv{ 372230775Sjfv s32 status = IXGBE_SUCCESS; 373230775Sjfv 374230775Sjfv DEBUGFUNC("ixgbe_read_eerd_X540"); 375230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 376230775Sjfv IXGBE_SUCCESS) 377230775Sjfv status = ixgbe_read_eerd_generic(hw, offset, data); 378230775Sjfv else 379230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 380230775Sjfv 381230775Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 382230775Sjfv return status; 383230775Sjfv} 384230775Sjfv 385230775Sjfv/** 386230775Sjfv * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD 387230775Sjfv * @hw: pointer to hardware structure 388230775Sjfv * @offset: offset of word in the EEPROM to read 389230775Sjfv * @words: number of words 390230775Sjfv * @data: word(s) read from the EEPROM 391230775Sjfv * 392230775Sjfv * Reads a 16 bit word(s) from the EEPROM using the EERD register. 393230775Sjfv **/ 394230775Sjfvs32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, 395230775Sjfv u16 offset, u16 words, u16 *data) 396230775Sjfv{ 397230775Sjfv s32 status = IXGBE_SUCCESS; 398230775Sjfv 399230775Sjfv DEBUGFUNC("ixgbe_read_eerd_buffer_X540"); 400230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 401230775Sjfv IXGBE_SUCCESS) 402230775Sjfv status = ixgbe_read_eerd_buffer_generic(hw, offset, 403230775Sjfv words, data); 404230775Sjfv else 405230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 406230775Sjfv 407230775Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 408230775Sjfv return status; 409230775Sjfv} 410230775Sjfv 411230775Sjfv/** 412230775Sjfv * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR 413230775Sjfv * @hw: pointer to hardware structure 414230775Sjfv * @offset: offset of word in the EEPROM to write 415230775Sjfv * @data: word write to the EEPROM 416230775Sjfv * 417230775Sjfv * Write a 16 bit word to the EEPROM using the EEWR register. 418230775Sjfv **/ 419230775Sjfvs32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) 420230775Sjfv{ 421230775Sjfv s32 status = IXGBE_SUCCESS; 422230775Sjfv 423230775Sjfv DEBUGFUNC("ixgbe_write_eewr_X540"); 424230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 425230775Sjfv IXGBE_SUCCESS) 426230775Sjfv status = ixgbe_write_eewr_generic(hw, offset, data); 427230775Sjfv else 428230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 429230775Sjfv 430230775Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 431230775Sjfv return status; 432230775Sjfv} 433230775Sjfv 434230775Sjfv/** 435230775Sjfv * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR 436230775Sjfv * @hw: pointer to hardware structure 437230775Sjfv * @offset: offset of word in the EEPROM to write 438230775Sjfv * @words: number of words 439230775Sjfv * @data: word(s) write to the EEPROM 440230775Sjfv * 441230775Sjfv * Write a 16 bit word(s) to the EEPROM using the EEWR register. 442230775Sjfv **/ 443230775Sjfvs32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, 444230775Sjfv u16 offset, u16 words, u16 *data) 445230775Sjfv{ 446230775Sjfv s32 status = IXGBE_SUCCESS; 447230775Sjfv 448230775Sjfv DEBUGFUNC("ixgbe_write_eewr_buffer_X540"); 449230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 450230775Sjfv IXGBE_SUCCESS) 451230775Sjfv status = ixgbe_write_eewr_buffer_generic(hw, offset, 452230775Sjfv words, data); 453230775Sjfv else 454230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 455230775Sjfv 456230775Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 457230775Sjfv return status; 458230775Sjfv} 459230775Sjfv 460230775Sjfv/** 461230775Sjfv * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum 462230775Sjfv * 463230775Sjfv * This function does not use synchronization for EERD and EEWR. It can 464230775Sjfv * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. 465230775Sjfv * 466230775Sjfv * @hw: pointer to hardware structure 467230775Sjfv **/ 468230775Sjfvu16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) 469230775Sjfv{ 470230775Sjfv u16 i; 471230775Sjfv u16 j; 472230775Sjfv u16 checksum = 0; 473230775Sjfv u16 length = 0; 474230775Sjfv u16 pointer = 0; 475230775Sjfv u16 word = 0; 476230775Sjfv 477230775Sjfv /* 478230775Sjfv * Do not use hw->eeprom.ops.read because we do not want to take 479230775Sjfv * the synchronization semaphores here. Instead use 480230775Sjfv * ixgbe_read_eerd_generic 481230775Sjfv */ 482230775Sjfv 483230775Sjfv DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540"); 484230775Sjfv 485230775Sjfv /* Include 0x0-0x3F in the checksum */ 486230775Sjfv for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 487230775Sjfv if (ixgbe_read_eerd_generic(hw, i, &word) != IXGBE_SUCCESS) { 488230775Sjfv DEBUGOUT("EEPROM read failed\n"); 489230775Sjfv break; 490230775Sjfv } 491230775Sjfv checksum += word; 492230775Sjfv } 493230775Sjfv 494230775Sjfv /* 495230775Sjfv * Include all data from pointers 0x3, 0x6-0xE. This excludes the 496230775Sjfv * FW, PHY module, and PCIe Expansion/Option ROM pointers. 497230775Sjfv */ 498230775Sjfv for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 499230775Sjfv if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 500230775Sjfv continue; 501230775Sjfv 502230775Sjfv if (ixgbe_read_eerd_generic(hw, i, &pointer) != IXGBE_SUCCESS) { 503230775Sjfv DEBUGOUT("EEPROM read failed\n"); 504230775Sjfv break; 505230775Sjfv } 506230775Sjfv 507230775Sjfv /* Skip pointer section if the pointer is invalid. */ 508230775Sjfv if (pointer == 0xFFFF || pointer == 0 || 509230775Sjfv pointer >= hw->eeprom.word_size) 510230775Sjfv continue; 511230775Sjfv 512230775Sjfv if (ixgbe_read_eerd_generic(hw, pointer, &length) != 513230775Sjfv IXGBE_SUCCESS) { 514230775Sjfv DEBUGOUT("EEPROM read failed\n"); 515230775Sjfv break; 516230775Sjfv } 517230775Sjfv 518230775Sjfv /* Skip pointer section if length is invalid. */ 519230775Sjfv if (length == 0xFFFF || length == 0 || 520230775Sjfv (pointer + length) >= hw->eeprom.word_size) 521230775Sjfv continue; 522230775Sjfv 523230775Sjfv for (j = pointer+1; j <= pointer+length; j++) { 524230775Sjfv if (ixgbe_read_eerd_generic(hw, j, &word) != 525230775Sjfv IXGBE_SUCCESS) { 526230775Sjfv DEBUGOUT("EEPROM read failed\n"); 527230775Sjfv break; 528230775Sjfv } 529230775Sjfv checksum += word; 530230775Sjfv } 531230775Sjfv } 532230775Sjfv 533230775Sjfv checksum = (u16)IXGBE_EEPROM_SUM - checksum; 534230775Sjfv 535230775Sjfv return checksum; 536230775Sjfv} 537230775Sjfv 538230775Sjfv/** 539230775Sjfv * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum 540230775Sjfv * @hw: pointer to hardware structure 541230775Sjfv * @checksum_val: calculated checksum 542230775Sjfv * 543230775Sjfv * Performs checksum calculation and validates the EEPROM checksum. If the 544230775Sjfv * caller does not need checksum_val, the value can be NULL. 545230775Sjfv **/ 546230775Sjfvs32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, 547230775Sjfv u16 *checksum_val) 548230775Sjfv{ 549230775Sjfv s32 status; 550230775Sjfv u16 checksum; 551230775Sjfv u16 read_checksum = 0; 552230775Sjfv 553230775Sjfv DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540"); 554230775Sjfv 555230775Sjfv /* 556230775Sjfv * Read the first word from the EEPROM. If this times out or fails, do 557230775Sjfv * not continue or we could be in for a very long wait while every 558230775Sjfv * EEPROM read fails 559230775Sjfv */ 560230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 561230775Sjfv 562230775Sjfv if (status != IXGBE_SUCCESS) { 563230775Sjfv DEBUGOUT("EEPROM read failed\n"); 564230775Sjfv goto out; 565230775Sjfv } 566230775Sjfv 567230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 568230775Sjfv IXGBE_SUCCESS) { 569230775Sjfv checksum = hw->eeprom.ops.calc_checksum(hw); 570230775Sjfv 571230775Sjfv /* 572230775Sjfv * Do not use hw->eeprom.ops.read because we do not want to take 573230775Sjfv * the synchronization semaphores twice here. 574230775Sjfv */ 575230775Sjfv ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, 576230775Sjfv &read_checksum); 577230775Sjfv 578230775Sjfv /* 579230775Sjfv * Verify read checksum from EEPROM is the same as 580230775Sjfv * calculated checksum 581230775Sjfv */ 582230775Sjfv if (read_checksum != checksum) 583230775Sjfv status = IXGBE_ERR_EEPROM_CHECKSUM; 584230775Sjfv 585230775Sjfv /* If the user cares, return the calculated checksum */ 586230775Sjfv if (checksum_val) 587230775Sjfv *checksum_val = checksum; 588230775Sjfv } else { 589230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 590230775Sjfv } 591230775Sjfv 592230775Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 593230775Sjfvout: 594230775Sjfv return status; 595230775Sjfv} 596230775Sjfv 597230775Sjfv/** 598230775Sjfv * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash 599230775Sjfv * @hw: pointer to hardware structure 600230775Sjfv * 601230775Sjfv * After writing EEPROM to shadow RAM using EEWR register, software calculates 602230775Sjfv * checksum and updates the EEPROM and instructs the hardware to update 603230775Sjfv * the flash. 604230775Sjfv **/ 605230775Sjfvs32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) 606230775Sjfv{ 607230775Sjfv s32 status; 608230775Sjfv u16 checksum; 609230775Sjfv 610230775Sjfv DEBUGFUNC("ixgbe_update_eeprom_checksum_X540"); 611230775Sjfv 612230775Sjfv /* 613230775Sjfv * Read the first word from the EEPROM. If this times out or fails, do 614230775Sjfv * not continue or we could be in for a very long wait while every 615230775Sjfv * EEPROM read fails 616230775Sjfv */ 617230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 618230775Sjfv 619230775Sjfv if (status != IXGBE_SUCCESS) 620230775Sjfv DEBUGOUT("EEPROM read failed\n"); 621230775Sjfv 622230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 623230775Sjfv IXGBE_SUCCESS) { 624230775Sjfv checksum = hw->eeprom.ops.calc_checksum(hw); 625230775Sjfv 626230775Sjfv /* 627230775Sjfv * Do not use hw->eeprom.ops.write because we do not want to 628230775Sjfv * take the synchronization semaphores twice here. 629230775Sjfv */ 630230775Sjfv status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, 631230775Sjfv checksum); 632230775Sjfv 633230775Sjfv if (status == IXGBE_SUCCESS) 634230775Sjfv status = ixgbe_update_flash_X540(hw); 635230775Sjfv else 636230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 637230775Sjfv } 638230775Sjfv 639230775Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 640230775Sjfv 641230775Sjfv return status; 642230775Sjfv} 643230775Sjfv 644230775Sjfv/** 645230775Sjfv * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device 646230775Sjfv * @hw: pointer to hardware structure 647230775Sjfv * 648230775Sjfv * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy 649230775Sjfv * EEPROM from shadow RAM to the flash device. 650230775Sjfv **/ 651230775Sjfvstatic s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) 652230775Sjfv{ 653230775Sjfv u32 flup; 654230775Sjfv s32 status = IXGBE_ERR_EEPROM; 655230775Sjfv 656230775Sjfv DEBUGFUNC("ixgbe_update_flash_X540"); 657230775Sjfv 658230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 659230775Sjfv if (status == IXGBE_ERR_EEPROM) { 660230775Sjfv DEBUGOUT("Flash update time out\n"); 661230775Sjfv goto out; 662230775Sjfv } 663230775Sjfv 664230775Sjfv flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP; 665230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); 666230775Sjfv 667230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 668230775Sjfv if (status == IXGBE_SUCCESS) 669230775Sjfv DEBUGOUT("Flash update complete\n"); 670230775Sjfv else 671230775Sjfv DEBUGOUT("Flash update time out\n"); 672230775Sjfv 673230775Sjfv if (hw->revision_id == 0) { 674230775Sjfv flup = IXGBE_READ_REG(hw, IXGBE_EEC); 675230775Sjfv 676230775Sjfv if (flup & IXGBE_EEC_SEC1VAL) { 677230775Sjfv flup |= IXGBE_EEC_FLUP; 678230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); 679230775Sjfv } 680230775Sjfv 681230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 682230775Sjfv if (status == IXGBE_SUCCESS) 683230775Sjfv DEBUGOUT("Flash update complete\n"); 684230775Sjfv else 685230775Sjfv DEBUGOUT("Flash update time out\n"); 686230775Sjfv } 687230775Sjfvout: 688230775Sjfv return status; 689230775Sjfv} 690230775Sjfv 691230775Sjfv/** 692230775Sjfv * ixgbe_poll_flash_update_done_X540 - Poll flash update status 693230775Sjfv * @hw: pointer to hardware structure 694230775Sjfv * 695230775Sjfv * Polls the FLUDONE (bit 26) of the EEC Register to determine when the 696230775Sjfv * flash update is done. 697230775Sjfv **/ 698230775Sjfvstatic s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) 699230775Sjfv{ 700230775Sjfv u32 i; 701230775Sjfv u32 reg; 702230775Sjfv s32 status = IXGBE_ERR_EEPROM; 703230775Sjfv 704230775Sjfv DEBUGFUNC("ixgbe_poll_flash_update_done_X540"); 705230775Sjfv 706230775Sjfv for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { 707230775Sjfv reg = IXGBE_READ_REG(hw, IXGBE_EEC); 708230775Sjfv if (reg & IXGBE_EEC_FLUDONE) { 709230775Sjfv status = IXGBE_SUCCESS; 710230775Sjfv break; 711230775Sjfv } 712230775Sjfv usec_delay(5); 713230775Sjfv } 714230775Sjfv return status; 715230775Sjfv} 716230775Sjfv 717230775Sjfv/** 718230775Sjfv * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore 719230775Sjfv * @hw: pointer to hardware structure 720230775Sjfv * @mask: Mask to specify which semaphore to acquire 721230775Sjfv * 722230775Sjfv * Acquires the SWFW semaphore thought the SW_FW_SYNC register for 723230775Sjfv * the specified function (CSR, PHY0, PHY1, NVM, Flash) 724230775Sjfv **/ 725230775Sjfvs32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) 726230775Sjfv{ 727230775Sjfv u32 swfw_sync; 728230775Sjfv u32 swmask = mask; 729230775Sjfv u32 fwmask = mask << 5; 730230775Sjfv u32 hwmask = 0; 731230775Sjfv u32 timeout = 200; 732230775Sjfv u32 i; 733230775Sjfv s32 ret_val = IXGBE_SUCCESS; 734230775Sjfv 735230775Sjfv DEBUGFUNC("ixgbe_acquire_swfw_sync_X540"); 736230775Sjfv 737230775Sjfv if (swmask == IXGBE_GSSR_EEP_SM) 738230775Sjfv hwmask = IXGBE_GSSR_FLASH_SM; 739230775Sjfv 740230775Sjfv /* SW only mask doesn't have FW bit pair */ 741230775Sjfv if (swmask == IXGBE_GSSR_SW_MNG_SM) 742230775Sjfv fwmask = 0; 743230775Sjfv 744230775Sjfv for (i = 0; i < timeout; i++) { 745230775Sjfv /* 746230775Sjfv * SW NVM semaphore bit is used for access to all 747230775Sjfv * SW_FW_SYNC bits (not just NVM) 748230775Sjfv */ 749230775Sjfv if (ixgbe_get_swfw_sync_semaphore(hw)) { 750230775Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 751230775Sjfv goto out; 752230775Sjfv } 753230775Sjfv 754230775Sjfv swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 755230775Sjfv if (!(swfw_sync & (fwmask | swmask | hwmask))) { 756230775Sjfv swfw_sync |= swmask; 757230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); 758230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 759230775Sjfv msec_delay(5); 760230775Sjfv goto out; 761230775Sjfv } else { 762230775Sjfv /* 763230775Sjfv * Firmware currently using resource (fwmask), hardware 764230775Sjfv * currently using resource (hwmask), or other software 765230775Sjfv * thread currently using resource (swmask) 766230775Sjfv */ 767230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 768230775Sjfv msec_delay(5); 769230775Sjfv } 770230775Sjfv } 771230775Sjfv 772230775Sjfv /* Failed to get SW only semaphore */ 773230775Sjfv if (swmask == IXGBE_GSSR_SW_MNG_SM) { 774230775Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 775230775Sjfv goto out; 776230775Sjfv } 777230775Sjfv 778230775Sjfv /* If the resource is not released by the FW/HW the SW can assume that 779230775Sjfv * the FW/HW malfunctions. In that case the SW should sets the SW bit(s) 780230775Sjfv * of the requested resource(s) while ignoring the corresponding FW/HW 781230775Sjfv * bits in the SW_FW_SYNC register. 782230775Sjfv */ 783230775Sjfv swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 784230775Sjfv if (swfw_sync & (fwmask | hwmask)) { 785230775Sjfv if (ixgbe_get_swfw_sync_semaphore(hw)) { 786230775Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 787230775Sjfv goto out; 788230775Sjfv } 789230775Sjfv 790230775Sjfv swfw_sync |= swmask; 791230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); 792230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 793230775Sjfv msec_delay(5); 794230775Sjfv } 795230775Sjfv 796230775Sjfvout: 797230775Sjfv return ret_val; 798230775Sjfv} 799230775Sjfv 800230775Sjfv/** 801230775Sjfv * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore 802230775Sjfv * @hw: pointer to hardware structure 803230775Sjfv * @mask: Mask to specify which semaphore to release 804230775Sjfv * 805238149Sjfv * Releases the SWFW semaphore through the SW_FW_SYNC register 806230775Sjfv * for the specified function (CSR, PHY0, PHY1, EVM, Flash) 807230775Sjfv **/ 808230775Sjfvvoid ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) 809230775Sjfv{ 810230775Sjfv u32 swfw_sync; 811230775Sjfv u32 swmask = mask; 812230775Sjfv 813230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_X540"); 814230775Sjfv 815230775Sjfv ixgbe_get_swfw_sync_semaphore(hw); 816230775Sjfv 817230775Sjfv swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 818230775Sjfv swfw_sync &= ~swmask; 819230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); 820230775Sjfv 821230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 822230775Sjfv msec_delay(5); 823230775Sjfv} 824230775Sjfv 825230775Sjfv/** 826230775Sjfv * ixgbe_get_nvm_semaphore - Get hardware semaphore 827230775Sjfv * @hw: pointer to hardware structure 828230775Sjfv * 829230775Sjfv * Sets the hardware semaphores so SW/FW can gain control of shared resources 830230775Sjfv **/ 831230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) 832230775Sjfv{ 833230775Sjfv s32 status = IXGBE_ERR_EEPROM; 834230775Sjfv u32 timeout = 2000; 835230775Sjfv u32 i; 836230775Sjfv u32 swsm; 837230775Sjfv 838230775Sjfv DEBUGFUNC("ixgbe_get_swfw_sync_semaphore"); 839230775Sjfv 840230775Sjfv /* Get SMBI software semaphore between device drivers first */ 841230775Sjfv for (i = 0; i < timeout; i++) { 842230775Sjfv /* 843230775Sjfv * If the SMBI bit is 0 when we read it, then the bit will be 844230775Sjfv * set and we have the semaphore 845230775Sjfv */ 846230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 847230775Sjfv if (!(swsm & IXGBE_SWSM_SMBI)) { 848230775Sjfv status = IXGBE_SUCCESS; 849230775Sjfv break; 850230775Sjfv } 851230775Sjfv usec_delay(50); 852230775Sjfv } 853230775Sjfv 854230775Sjfv /* Now get the semaphore between SW/FW through the REGSMP bit */ 855230775Sjfv if (status == IXGBE_SUCCESS) { 856230775Sjfv for (i = 0; i < timeout; i++) { 857230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 858230775Sjfv if (!(swsm & IXGBE_SWFW_REGSMP)) 859230775Sjfv break; 860230775Sjfv 861230775Sjfv usec_delay(50); 862230775Sjfv } 863230775Sjfv 864230775Sjfv /* 865230775Sjfv * Release semaphores and return error if SW NVM semaphore 866230775Sjfv * was not granted because we don't have access to the EEPROM 867230775Sjfv */ 868230775Sjfv if (i >= timeout) { 869230775Sjfv DEBUGOUT("REGSMP Software NVM semaphore not " 870230775Sjfv "granted.\n"); 871230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 872230775Sjfv status = IXGBE_ERR_EEPROM; 873230775Sjfv } 874230775Sjfv } else { 875230775Sjfv DEBUGOUT("Software semaphore SMBI between device drivers " 876230775Sjfv "not granted.\n"); 877230775Sjfv } 878230775Sjfv 879230775Sjfv return status; 880230775Sjfv} 881230775Sjfv 882230775Sjfv/** 883230775Sjfv * ixgbe_release_nvm_semaphore - Release hardware semaphore 884230775Sjfv * @hw: pointer to hardware structure 885230775Sjfv * 886230775Sjfv * This function clears hardware semaphore bits. 887230775Sjfv **/ 888230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) 889230775Sjfv{ 890230775Sjfv u32 swsm; 891230775Sjfv 892230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_semaphore"); 893230775Sjfv 894230775Sjfv /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ 895230775Sjfv 896230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 897230775Sjfv swsm &= ~IXGBE_SWSM_SMBI; 898230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 899230775Sjfv 900230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 901230775Sjfv swsm &= ~IXGBE_SWFW_REGSMP; 902230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm); 903230775Sjfv 904230775Sjfv IXGBE_WRITE_FLUSH(hw); 905230775Sjfv} 906230775Sjfv 907230775Sjfv/** 908230775Sjfv * ixgbe_blink_led_start_X540 - Blink LED based on index. 909230775Sjfv * @hw: pointer to hardware structure 910230775Sjfv * @index: led number to blink 911230775Sjfv * 912230775Sjfv * Devices that implement the version 2 interface: 913230775Sjfv * X540 914230775Sjfv **/ 915230775Sjfvs32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) 916230775Sjfv{ 917230775Sjfv u32 macc_reg; 918230775Sjfv u32 ledctl_reg; 919230775Sjfv ixgbe_link_speed speed; 920230775Sjfv bool link_up; 921230775Sjfv 922230775Sjfv DEBUGFUNC("ixgbe_blink_led_start_X540"); 923230775Sjfv 924230775Sjfv /* 925230775Sjfv * Link should be up in order for the blink bit in the LED control 926230775Sjfv * register to work. Force link and speed in the MAC if link is down. 927230775Sjfv * This will be reversed when we stop the blinking. 928230775Sjfv */ 929230775Sjfv hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 930230775Sjfv if (link_up == FALSE) { 931230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 932230775Sjfv macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; 933230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 934230775Sjfv } 935230775Sjfv /* Set the LED to LINK_UP + BLINK. */ 936230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 937230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 938230775Sjfv ledctl_reg |= IXGBE_LED_BLINK(index); 939230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 940230775Sjfv IXGBE_WRITE_FLUSH(hw); 941230775Sjfv 942230775Sjfv return IXGBE_SUCCESS; 943230775Sjfv} 944230775Sjfv 945230775Sjfv/** 946230775Sjfv * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index. 947230775Sjfv * @hw: pointer to hardware structure 948230775Sjfv * @index: led number to stop blinking 949230775Sjfv * 950230775Sjfv * Devices that implement the version 2 interface: 951230775Sjfv * X540 952230775Sjfv **/ 953230775Sjfvs32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) 954230775Sjfv{ 955230775Sjfv u32 macc_reg; 956230775Sjfv u32 ledctl_reg; 957230775Sjfv 958230775Sjfv DEBUGFUNC("ixgbe_blink_led_stop_X540"); 959230775Sjfv 960230775Sjfv /* Restore the LED to its default value. */ 961230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 962230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 963230775Sjfv ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 964230775Sjfv ledctl_reg &= ~IXGBE_LED_BLINK(index); 965230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 966230775Sjfv 967230775Sjfv /* Unforce link and speed in the MAC. */ 968230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 969230775Sjfv macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS); 970230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 971230775Sjfv IXGBE_WRITE_FLUSH(hw); 972230775Sjfv 973230775Sjfv return IXGBE_SUCCESS; 974230775Sjfv} 975230775Sjfv 976