1230775Sjfv/****************************************************************************** 2230775Sjfv 3315333Serj Copyright (c) 2001-2017, Intel Corporation 4230775Sjfv All rights reserved. 5315333Serj 6315333Serj Redistribution and use in source and binary forms, with or without 7230775Sjfv modification, are permitted provided that the following conditions are met: 8315333Serj 9315333Serj 1. Redistributions of source code must retain the above copyright notice, 10230775Sjfv this list of conditions and the following disclaimer. 11315333Serj 12315333Serj 2. Redistributions in binary form must reproduce the above copyright 13315333Serj notice, this list of conditions and the following disclaimer in the 14230775Sjfv documentation and/or other materials provided with the distribution. 15315333Serj 16315333Serj 3. Neither the name of the Intel Corporation nor the names of its 17315333Serj contributors may be used to endorse or promote products derived from 18230775Sjfv this software without specific prior written permission. 19315333Serj 20230775Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21315333Serj AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22315333Serj IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23315333Serj ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24315333Serj LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25315333Serj CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26315333Serj SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27315333Serj INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28315333Serj 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: stable/10/sys/dev/ixgbe/ixgbe_x540.c 315333 2017-03-15 21:20:17Z erj $*/ 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 41283620Serj#define IXGBE_X540_MAX_TX_QUEUES 128 42283620Serj#define IXGBE_X540_MAX_RX_QUEUES 128 43283620Serj#define IXGBE_X540_RAR_ENTRIES 128 44283620Serj#define IXGBE_X540_MC_TBL_SIZE 128 45283620Serj#define IXGBE_X540_VFT_TBL_SIZE 128 46283620Serj#define IXGBE_X540_RX_PB_SIZE 384 47283620Serj 48230775Sjfvstatic s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); 49230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); 50230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); 51230775Sjfv 52230775Sjfv/** 53230775Sjfv * ixgbe_init_ops_X540 - Inits func ptrs and MAC type 54230775Sjfv * @hw: pointer to hardware structure 55230775Sjfv * 56230775Sjfv * Initialize the function pointers and assign the MAC type for X540. 57230775Sjfv * Does not touch the hardware. 58230775Sjfv **/ 59230775Sjfvs32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) 60230775Sjfv{ 61230775Sjfv struct ixgbe_mac_info *mac = &hw->mac; 62230775Sjfv struct ixgbe_phy_info *phy = &hw->phy; 63230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 64230775Sjfv s32 ret_val; 65230775Sjfv 66230775Sjfv DEBUGFUNC("ixgbe_init_ops_X540"); 67230775Sjfv 68230775Sjfv ret_val = ixgbe_init_phy_ops_generic(hw); 69230775Sjfv ret_val = ixgbe_init_ops_generic(hw); 70230775Sjfv 71230775Sjfv 72230775Sjfv /* EEPROM */ 73283620Serj eeprom->ops.init_params = ixgbe_init_eeprom_params_X540; 74283620Serj eeprom->ops.read = ixgbe_read_eerd_X540; 75283620Serj eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_X540; 76283620Serj eeprom->ops.write = ixgbe_write_eewr_X540; 77283620Serj eeprom->ops.write_buffer = ixgbe_write_eewr_buffer_X540; 78283620Serj eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X540; 79283620Serj eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X540; 80283620Serj eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X540; 81230775Sjfv 82230775Sjfv /* PHY */ 83283620Serj phy->ops.init = ixgbe_init_phy_ops_generic; 84230775Sjfv phy->ops.reset = NULL; 85295528Ssmh phy->ops.set_phy_power = ixgbe_set_copper_phy_power; 86230775Sjfv 87230775Sjfv /* MAC */ 88283620Serj mac->ops.reset_hw = ixgbe_reset_hw_X540; 89283620Serj mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_gen2; 90283620Serj mac->ops.get_media_type = ixgbe_get_media_type_X540; 91230775Sjfv mac->ops.get_supported_physical_layer = 92283620Serj ixgbe_get_supported_physical_layer_X540; 93230775Sjfv mac->ops.read_analog_reg8 = NULL; 94230775Sjfv mac->ops.write_analog_reg8 = NULL; 95283620Serj mac->ops.start_hw = ixgbe_start_hw_X540; 96283620Serj mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic; 97283620Serj mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic; 98283620Serj mac->ops.get_device_caps = ixgbe_get_device_caps_generic; 99283620Serj mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic; 100283620Serj mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic; 101283620Serj mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540; 102283620Serj mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540; 103315333Serj mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540; 104283620Serj mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic; 105283620Serj mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic; 106230775Sjfv 107230775Sjfv /* RAR, Multicast, VLAN */ 108283620Serj mac->ops.set_vmdq = ixgbe_set_vmdq_generic; 109283620Serj mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic; 110283620Serj mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic; 111283620Serj mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic; 112230775Sjfv mac->rar_highwater = 1; 113283620Serj mac->ops.set_vfta = ixgbe_set_vfta_generic; 114283620Serj mac->ops.set_vlvf = ixgbe_set_vlvf_generic; 115283620Serj mac->ops.clear_vfta = ixgbe_clear_vfta_generic; 116283620Serj mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic; 117283620Serj mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing; 118283620Serj mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing; 119230775Sjfv 120230775Sjfv /* Link */ 121230775Sjfv mac->ops.get_link_capabilities = 122283620Serj ixgbe_get_copper_link_capabilities_generic; 123283620Serj mac->ops.setup_link = ixgbe_setup_mac_link_X540; 124283620Serj mac->ops.setup_rxpba = ixgbe_set_rxpba_generic; 125283620Serj mac->ops.check_link = ixgbe_check_mac_link_generic; 126315333Serj mac->ops.bypass_rw = ixgbe_bypass_rw_generic; 127315333Serj mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic; 128315333Serj mac->ops.bypass_set = ixgbe_bypass_set_generic; 129315333Serj mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic; 130230775Sjfv 131247822Sjfv 132283620Serj mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; 133283620Serj mac->vft_size = IXGBE_X540_VFT_TBL_SIZE; 134283620Serj mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES; 135283620Serj mac->rx_pb_size = IXGBE_X540_RX_PB_SIZE; 136283620Serj mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES; 137283620Serj mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES; 138230775Sjfv mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); 139230775Sjfv 140230775Sjfv /* 141230775Sjfv * FWSM register 142230775Sjfv * ARC supported; valid only if manageability features are 143230775Sjfv * enabled. 144230775Sjfv */ 145295524Ssbruno mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)) 146295524Ssbruno & IXGBE_FWSM_MODE_MASK); 147230775Sjfv 148230775Sjfv hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf; 149230775Sjfv 150230775Sjfv /* LEDs */ 151230775Sjfv mac->ops.blink_led_start = ixgbe_blink_led_start_X540; 152230775Sjfv mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540; 153230775Sjfv 154230775Sjfv /* Manageability interface */ 155283620Serj mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic; 156230775Sjfv 157283620Serj mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic; 158251964Sjfv 159230775Sjfv return ret_val; 160230775Sjfv} 161230775Sjfv 162230775Sjfv/** 163230775Sjfv * ixgbe_get_link_capabilities_X540 - Determines link capabilities 164230775Sjfv * @hw: pointer to hardware structure 165230775Sjfv * @speed: pointer to link speed 166230775Sjfv * @autoneg: TRUE when autoneg or autotry is enabled 167230775Sjfv * 168230775Sjfv * Determines the link capabilities by reading the AUTOC register. 169230775Sjfv **/ 170230775Sjfvs32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, 171230775Sjfv ixgbe_link_speed *speed, 172230775Sjfv bool *autoneg) 173230775Sjfv{ 174230775Sjfv ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg); 175230775Sjfv 176230775Sjfv return IXGBE_SUCCESS; 177230775Sjfv} 178230775Sjfv 179230775Sjfv/** 180230775Sjfv * ixgbe_get_media_type_X540 - Get media type 181230775Sjfv * @hw: pointer to hardware structure 182230775Sjfv * 183230775Sjfv * Returns the media type (fiber, copper, backplane) 184230775Sjfv **/ 185230775Sjfvenum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) 186230775Sjfv{ 187230775Sjfv UNREFERENCED_1PARAMETER(hw); 188230775Sjfv return ixgbe_media_type_copper; 189230775Sjfv} 190230775Sjfv 191230775Sjfv/** 192230775Sjfv * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities 193230775Sjfv * @hw: pointer to hardware structure 194230775Sjfv * @speed: new link speed 195230775Sjfv * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 196230775Sjfv **/ 197230775Sjfvs32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, 198247822Sjfv ixgbe_link_speed speed, 199230775Sjfv bool autoneg_wait_to_complete) 200230775Sjfv{ 201230775Sjfv DEBUGFUNC("ixgbe_setup_mac_link_X540"); 202247822Sjfv return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); 203230775Sjfv} 204230775Sjfv 205230775Sjfv/** 206230775Sjfv * ixgbe_reset_hw_X540 - Perform hardware reset 207230775Sjfv * @hw: pointer to hardware structure 208230775Sjfv * 209230775Sjfv * Resets the hardware by resetting the transmit and receive units, masks 210230775Sjfv * and clears all interrupts, and perform a reset. 211230775Sjfv **/ 212230775Sjfvs32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) 213230775Sjfv{ 214230775Sjfv s32 status; 215230775Sjfv u32 ctrl, i; 216230775Sjfv 217230775Sjfv DEBUGFUNC("ixgbe_reset_hw_X540"); 218230775Sjfv 219230775Sjfv /* Call adapter stop to disable tx/rx and clear interrupts */ 220230775Sjfv status = hw->mac.ops.stop_adapter(hw); 221230775Sjfv if (status != IXGBE_SUCCESS) 222230775Sjfv goto reset_hw_out; 223230775Sjfv 224230775Sjfv /* flush pending Tx transactions */ 225230775Sjfv ixgbe_clear_tx_pending(hw); 226230775Sjfv 227230775Sjfvmac_reset_top: 228230775Sjfv ctrl = IXGBE_CTRL_RST; 229230775Sjfv ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); 230230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); 231230775Sjfv IXGBE_WRITE_FLUSH(hw); 232230775Sjfv 233230775Sjfv /* Poll for reset bit to self-clear indicating reset is complete */ 234230775Sjfv for (i = 0; i < 10; i++) { 235230775Sjfv usec_delay(1); 236230775Sjfv ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); 237230775Sjfv if (!(ctrl & IXGBE_CTRL_RST_MASK)) 238230775Sjfv break; 239230775Sjfv } 240230775Sjfv 241230775Sjfv if (ctrl & IXGBE_CTRL_RST_MASK) { 242230775Sjfv status = IXGBE_ERR_RESET_FAILED; 243251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 244251964Sjfv "Reset polling failed to complete.\n"); 245230775Sjfv } 246230775Sjfv msec_delay(100); 247230775Sjfv 248230775Sjfv /* 249230775Sjfv * Double resets are required for recovery from certain error 250230775Sjfv * conditions. Between resets, it is necessary to stall to allow time 251230775Sjfv * for any pending HW events to complete. 252230775Sjfv */ 253230775Sjfv if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { 254230775Sjfv hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 255230775Sjfv goto mac_reset_top; 256230775Sjfv } 257230775Sjfv 258230775Sjfv /* Set the Rx packet buffer size. */ 259230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); 260230775Sjfv 261230775Sjfv /* Store the permanent mac address */ 262230775Sjfv hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); 263230775Sjfv 264230775Sjfv /* 265230775Sjfv * Store MAC address from RAR0, clear receive address registers, and 266230775Sjfv * clear the multicast table. Also reset num_rar_entries to 128, 267230775Sjfv * since we modify this value when programming the SAN MAC address. 268230775Sjfv */ 269230775Sjfv hw->mac.num_rar_entries = 128; 270230775Sjfv hw->mac.ops.init_rx_addrs(hw); 271230775Sjfv 272230775Sjfv /* Store the permanent SAN mac address */ 273230775Sjfv hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); 274230775Sjfv 275230775Sjfv /* Add the SAN MAC address to the RAR only if it's a valid address */ 276230775Sjfv if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { 277238149Sjfv /* Save the SAN MAC RAR index */ 278238149Sjfv hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; 279238149Sjfv 280315333Serj hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index, 281315333Serj hw->mac.san_addr, 0, IXGBE_RAH_AV); 282315333Serj 283315333Serj /* clear VMDq pool/queue selection for this RAR */ 284315333Serj hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index, 285315333Serj IXGBE_CLEAR_VMDQ_ALL); 286315333Serj 287230775Sjfv /* Reserve the last RAR for the SAN MAC address */ 288230775Sjfv hw->mac.num_rar_entries--; 289230775Sjfv } 290230775Sjfv 291230775Sjfv /* Store the alternative WWNN/WWPN prefix */ 292230775Sjfv hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, 293230775Sjfv &hw->mac.wwpn_prefix); 294230775Sjfv 295230775Sjfvreset_hw_out: 296230775Sjfv return status; 297230775Sjfv} 298230775Sjfv 299230775Sjfv/** 300230775Sjfv * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx 301230775Sjfv * @hw: pointer to hardware structure 302230775Sjfv * 303230775Sjfv * Starts the hardware using the generic start_hw function 304230775Sjfv * and the generation start_hw function. 305230775Sjfv * Then performs revision-specific operations, if any. 306230775Sjfv **/ 307230775Sjfvs32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) 308230775Sjfv{ 309230775Sjfv s32 ret_val = IXGBE_SUCCESS; 310230775Sjfv 311230775Sjfv DEBUGFUNC("ixgbe_start_hw_X540"); 312230775Sjfv 313230775Sjfv ret_val = ixgbe_start_hw_generic(hw); 314230775Sjfv if (ret_val != IXGBE_SUCCESS) 315230775Sjfv goto out; 316230775Sjfv 317230775Sjfv ret_val = ixgbe_start_hw_gen2(hw); 318230775Sjfv 319230775Sjfvout: 320230775Sjfv return ret_val; 321230775Sjfv} 322230775Sjfv 323230775Sjfv/** 324230775Sjfv * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type 325230775Sjfv * @hw: pointer to hardware structure 326230775Sjfv * 327230775Sjfv * Determines physical layer capabilities of the current configuration. 328230775Sjfv **/ 329230775Sjfvu32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) 330230775Sjfv{ 331230775Sjfv u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; 332230775Sjfv u16 ext_ability = 0; 333230775Sjfv 334230775Sjfv DEBUGFUNC("ixgbe_get_supported_physical_layer_X540"); 335230775Sjfv 336230775Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, 337230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); 338230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) 339230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; 340230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) 341230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; 342230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) 343230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; 344230775Sjfv 345230775Sjfv return physical_layer; 346230775Sjfv} 347230775Sjfv 348230775Sjfv/** 349230775Sjfv * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params 350230775Sjfv * @hw: pointer to hardware structure 351230775Sjfv * 352230775Sjfv * Initializes the EEPROM parameters ixgbe_eeprom_info within the 353230775Sjfv * ixgbe_hw struct in order to set up EEPROM access. 354230775Sjfv **/ 355230775Sjfvs32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) 356230775Sjfv{ 357230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 358230775Sjfv u32 eec; 359230775Sjfv u16 eeprom_size; 360230775Sjfv 361230775Sjfv DEBUGFUNC("ixgbe_init_eeprom_params_X540"); 362230775Sjfv 363230775Sjfv if (eeprom->type == ixgbe_eeprom_uninitialized) { 364230775Sjfv eeprom->semaphore_delay = 10; 365230775Sjfv eeprom->type = ixgbe_flash; 366230775Sjfv 367295524Ssbruno eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); 368230775Sjfv eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 369230775Sjfv IXGBE_EEC_SIZE_SHIFT); 370230775Sjfv eeprom->word_size = 1 << (eeprom_size + 371230775Sjfv IXGBE_EEPROM_WORD_SIZE_SHIFT); 372230775Sjfv 373230775Sjfv DEBUGOUT2("Eeprom params: type = %d, size = %d\n", 374230775Sjfv eeprom->type, eeprom->word_size); 375230775Sjfv } 376230775Sjfv 377230775Sjfv return IXGBE_SUCCESS; 378230775Sjfv} 379230775Sjfv 380230775Sjfv/** 381230775Sjfv * ixgbe_read_eerd_X540- Read EEPROM word using EERD 382230775Sjfv * @hw: pointer to hardware structure 383230775Sjfv * @offset: offset of word in the EEPROM to read 384230775Sjfv * @data: word read from the EEPROM 385230775Sjfv * 386230775Sjfv * Reads a 16 bit word from the EEPROM using the EERD register. 387230775Sjfv **/ 388230775Sjfvs32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) 389230775Sjfv{ 390230775Sjfv s32 status = IXGBE_SUCCESS; 391230775Sjfv 392230775Sjfv DEBUGFUNC("ixgbe_read_eerd_X540"); 393230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 394251964Sjfv IXGBE_SUCCESS) { 395230775Sjfv status = ixgbe_read_eerd_generic(hw, offset, data); 396251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 397251964Sjfv } else { 398230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 399251964Sjfv } 400230775Sjfv 401230775Sjfv return status; 402230775Sjfv} 403230775Sjfv 404230775Sjfv/** 405230775Sjfv * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD 406230775Sjfv * @hw: pointer to hardware structure 407230775Sjfv * @offset: offset of word in the EEPROM to read 408230775Sjfv * @words: number of words 409230775Sjfv * @data: word(s) read from the EEPROM 410230775Sjfv * 411230775Sjfv * Reads a 16 bit word(s) from the EEPROM using the EERD register. 412230775Sjfv **/ 413230775Sjfvs32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, 414230775Sjfv u16 offset, u16 words, u16 *data) 415230775Sjfv{ 416230775Sjfv s32 status = IXGBE_SUCCESS; 417230775Sjfv 418230775Sjfv DEBUGFUNC("ixgbe_read_eerd_buffer_X540"); 419230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 420251964Sjfv IXGBE_SUCCESS) { 421230775Sjfv status = ixgbe_read_eerd_buffer_generic(hw, offset, 422230775Sjfv words, data); 423251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 424251964Sjfv } else { 425230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 426251964Sjfv } 427230775Sjfv 428230775Sjfv return status; 429230775Sjfv} 430230775Sjfv 431230775Sjfv/** 432230775Sjfv * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR 433230775Sjfv * @hw: pointer to hardware structure 434230775Sjfv * @offset: offset of word in the EEPROM to write 435230775Sjfv * @data: word write to the EEPROM 436230775Sjfv * 437230775Sjfv * Write a 16 bit word to the EEPROM using the EEWR register. 438230775Sjfv **/ 439230775Sjfvs32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) 440230775Sjfv{ 441230775Sjfv s32 status = IXGBE_SUCCESS; 442230775Sjfv 443230775Sjfv DEBUGFUNC("ixgbe_write_eewr_X540"); 444230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 445251964Sjfv IXGBE_SUCCESS) { 446230775Sjfv status = ixgbe_write_eewr_generic(hw, offset, data); 447251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 448251964Sjfv } else { 449230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 450251964Sjfv } 451230775Sjfv 452230775Sjfv return status; 453230775Sjfv} 454230775Sjfv 455230775Sjfv/** 456230775Sjfv * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR 457230775Sjfv * @hw: pointer to hardware structure 458230775Sjfv * @offset: offset of word in the EEPROM to write 459230775Sjfv * @words: number of words 460230775Sjfv * @data: word(s) write to the EEPROM 461230775Sjfv * 462230775Sjfv * Write a 16 bit word(s) to the EEPROM using the EEWR register. 463230775Sjfv **/ 464230775Sjfvs32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, 465230775Sjfv u16 offset, u16 words, u16 *data) 466230775Sjfv{ 467230775Sjfv s32 status = IXGBE_SUCCESS; 468230775Sjfv 469230775Sjfv DEBUGFUNC("ixgbe_write_eewr_buffer_X540"); 470230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 471251964Sjfv IXGBE_SUCCESS) { 472230775Sjfv status = ixgbe_write_eewr_buffer_generic(hw, offset, 473230775Sjfv words, data); 474251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 475251964Sjfv } else { 476230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 477251964Sjfv } 478230775Sjfv 479230775Sjfv return status; 480230775Sjfv} 481230775Sjfv 482230775Sjfv/** 483230775Sjfv * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum 484230775Sjfv * 485230775Sjfv * This function does not use synchronization for EERD and EEWR. It can 486230775Sjfv * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. 487230775Sjfv * 488230775Sjfv * @hw: pointer to hardware structure 489283620Serj * 490283620Serj * Returns a negative error code on error, or the 16-bit checksum 491230775Sjfv **/ 492283620Serjs32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) 493230775Sjfv{ 494283620Serj u16 i, j; 495230775Sjfv u16 checksum = 0; 496230775Sjfv u16 length = 0; 497230775Sjfv u16 pointer = 0; 498230775Sjfv u16 word = 0; 499283620Serj u16 ptr_start = IXGBE_PCIE_ANALOG_PTR; 500230775Sjfv 501283620Serj /* Do not use hw->eeprom.ops.read because we do not want to take 502230775Sjfv * the synchronization semaphores here. Instead use 503230775Sjfv * ixgbe_read_eerd_generic 504230775Sjfv */ 505230775Sjfv 506230775Sjfv DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540"); 507230775Sjfv 508315333Serj /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the 509315333Serj * checksum itself 510315333Serj */ 511315333Serj for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 512283620Serj if (ixgbe_read_eerd_generic(hw, i, &word)) { 513230775Sjfv DEBUGOUT("EEPROM read failed\n"); 514283620Serj return IXGBE_ERR_EEPROM; 515230775Sjfv } 516315333Serj checksum += word; 517230775Sjfv } 518230775Sjfv 519283620Serj /* Include all data from pointers 0x3, 0x6-0xE. This excludes the 520230775Sjfv * FW, PHY module, and PCIe Expansion/Option ROM pointers. 521230775Sjfv */ 522283620Serj for (i = ptr_start; i < IXGBE_FW_PTR; i++) { 523230775Sjfv if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 524230775Sjfv continue; 525230775Sjfv 526283620Serj if (ixgbe_read_eerd_generic(hw, i, &pointer)) { 527230775Sjfv DEBUGOUT("EEPROM read failed\n"); 528283620Serj return IXGBE_ERR_EEPROM; 529230775Sjfv } 530230775Sjfv 531230775Sjfv /* Skip pointer section if the pointer is invalid. */ 532230775Sjfv if (pointer == 0xFFFF || pointer == 0 || 533230775Sjfv pointer >= hw->eeprom.word_size) 534230775Sjfv continue; 535230775Sjfv 536283620Serj if (ixgbe_read_eerd_generic(hw, pointer, &length)) { 537230775Sjfv DEBUGOUT("EEPROM read failed\n"); 538283620Serj return IXGBE_ERR_EEPROM; 539230775Sjfv } 540230775Sjfv 541230775Sjfv /* Skip pointer section if length is invalid. */ 542230775Sjfv if (length == 0xFFFF || length == 0 || 543230775Sjfv (pointer + length) >= hw->eeprom.word_size) 544230775Sjfv continue; 545230775Sjfv 546283620Serj for (j = pointer + 1; j <= pointer + length; j++) { 547283620Serj if (ixgbe_read_eerd_generic(hw, j, &word)) { 548230775Sjfv DEBUGOUT("EEPROM read failed\n"); 549283620Serj return IXGBE_ERR_EEPROM; 550230775Sjfv } 551230775Sjfv checksum += word; 552230775Sjfv } 553230775Sjfv } 554230775Sjfv 555230775Sjfv checksum = (u16)IXGBE_EEPROM_SUM - checksum; 556230775Sjfv 557283620Serj return (s32)checksum; 558230775Sjfv} 559230775Sjfv 560230775Sjfv/** 561230775Sjfv * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum 562230775Sjfv * @hw: pointer to hardware structure 563230775Sjfv * @checksum_val: calculated checksum 564230775Sjfv * 565230775Sjfv * Performs checksum calculation and validates the EEPROM checksum. If the 566230775Sjfv * caller does not need checksum_val, the value can be NULL. 567230775Sjfv **/ 568230775Sjfvs32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, 569230775Sjfv u16 *checksum_val) 570230775Sjfv{ 571230775Sjfv s32 status; 572230775Sjfv u16 checksum; 573230775Sjfv u16 read_checksum = 0; 574230775Sjfv 575230775Sjfv DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540"); 576230775Sjfv 577283620Serj /* Read the first word from the EEPROM. If this times out or fails, do 578230775Sjfv * not continue or we could be in for a very long wait while every 579230775Sjfv * EEPROM read fails 580230775Sjfv */ 581230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 582283620Serj if (status) { 583230775Sjfv DEBUGOUT("EEPROM read failed\n"); 584283620Serj return status; 585230775Sjfv } 586230775Sjfv 587283620Serj if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) 588283620Serj return IXGBE_ERR_SWFW_SYNC; 589230775Sjfv 590283620Serj status = hw->eeprom.ops.calc_checksum(hw); 591283620Serj if (status < 0) 592283620Serj goto out; 593230775Sjfv 594283620Serj checksum = (u16)(status & 0xffff); 595230775Sjfv 596283620Serj /* Do not use hw->eeprom.ops.read because we do not want to take 597283620Serj * the synchronization semaphores twice here. 598283620Serj */ 599283620Serj status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, 600283620Serj &read_checksum); 601283620Serj if (status) 602283620Serj goto out; 603283620Serj 604283620Serj /* Verify read checksum from EEPROM is the same as 605283620Serj * calculated checksum 606283620Serj */ 607283620Serj if (read_checksum != checksum) { 608283620Serj ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, 609283620Serj "Invalid EEPROM checksum"); 610283620Serj status = IXGBE_ERR_EEPROM_CHECKSUM; 611230775Sjfv } 612230775Sjfv 613283620Serj /* If the user cares, return the calculated checksum */ 614283620Serj if (checksum_val) 615283620Serj *checksum_val = checksum; 616283620Serj 617230775Sjfvout: 618283620Serj hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 619283620Serj 620230775Sjfv return status; 621230775Sjfv} 622230775Sjfv 623230775Sjfv/** 624230775Sjfv * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash 625230775Sjfv * @hw: pointer to hardware structure 626230775Sjfv * 627230775Sjfv * After writing EEPROM to shadow RAM using EEWR register, software calculates 628230775Sjfv * checksum and updates the EEPROM and instructs the hardware to update 629230775Sjfv * the flash. 630230775Sjfv **/ 631230775Sjfvs32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) 632230775Sjfv{ 633230775Sjfv s32 status; 634230775Sjfv u16 checksum; 635230775Sjfv 636230775Sjfv DEBUGFUNC("ixgbe_update_eeprom_checksum_X540"); 637230775Sjfv 638283620Serj /* Read the first word from the EEPROM. If this times out or fails, do 639230775Sjfv * not continue or we could be in for a very long wait while every 640230775Sjfv * EEPROM read fails 641230775Sjfv */ 642230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 643283620Serj if (status) { 644230775Sjfv DEBUGOUT("EEPROM read failed\n"); 645283620Serj return status; 646283620Serj } 647230775Sjfv 648283620Serj if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) 649283620Serj return IXGBE_ERR_SWFW_SYNC; 650230775Sjfv 651283620Serj status = hw->eeprom.ops.calc_checksum(hw); 652283620Serj if (status < 0) 653283620Serj goto out; 654230775Sjfv 655283620Serj checksum = (u16)(status & 0xffff); 656230775Sjfv 657283620Serj /* Do not use hw->eeprom.ops.write because we do not want to 658283620Serj * take the synchronization semaphores twice here. 659283620Serj */ 660283620Serj status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum); 661283620Serj if (status) 662283620Serj goto out; 663283620Serj 664283620Serj status = ixgbe_update_flash_X540(hw); 665283620Serj 666283620Serjout: 667283620Serj hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 668283620Serj 669230775Sjfv return status; 670230775Sjfv} 671230775Sjfv 672230775Sjfv/** 673230775Sjfv * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device 674230775Sjfv * @hw: pointer to hardware structure 675230775Sjfv * 676230775Sjfv * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy 677230775Sjfv * EEPROM from shadow RAM to the flash device. 678230775Sjfv **/ 679251964Sjfvs32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) 680230775Sjfv{ 681230775Sjfv u32 flup; 682283620Serj s32 status; 683230775Sjfv 684230775Sjfv DEBUGFUNC("ixgbe_update_flash_X540"); 685230775Sjfv 686230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 687230775Sjfv if (status == IXGBE_ERR_EEPROM) { 688230775Sjfv DEBUGOUT("Flash update time out\n"); 689230775Sjfv goto out; 690230775Sjfv } 691230775Sjfv 692295524Ssbruno flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP; 693295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup); 694230775Sjfv 695230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 696230775Sjfv if (status == IXGBE_SUCCESS) 697230775Sjfv DEBUGOUT("Flash update complete\n"); 698230775Sjfv else 699230775Sjfv DEBUGOUT("Flash update time out\n"); 700230775Sjfv 701251964Sjfv if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) { 702295524Ssbruno flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); 703230775Sjfv 704230775Sjfv if (flup & IXGBE_EEC_SEC1VAL) { 705230775Sjfv flup |= IXGBE_EEC_FLUP; 706295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup); 707230775Sjfv } 708230775Sjfv 709230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 710230775Sjfv if (status == IXGBE_SUCCESS) 711230775Sjfv DEBUGOUT("Flash update complete\n"); 712230775Sjfv else 713230775Sjfv DEBUGOUT("Flash update time out\n"); 714230775Sjfv } 715230775Sjfvout: 716230775Sjfv return status; 717230775Sjfv} 718230775Sjfv 719230775Sjfv/** 720230775Sjfv * ixgbe_poll_flash_update_done_X540 - Poll flash update status 721230775Sjfv * @hw: pointer to hardware structure 722230775Sjfv * 723230775Sjfv * Polls the FLUDONE (bit 26) of the EEC Register to determine when the 724230775Sjfv * flash update is done. 725230775Sjfv **/ 726230775Sjfvstatic s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) 727230775Sjfv{ 728230775Sjfv u32 i; 729230775Sjfv u32 reg; 730230775Sjfv s32 status = IXGBE_ERR_EEPROM; 731230775Sjfv 732230775Sjfv DEBUGFUNC("ixgbe_poll_flash_update_done_X540"); 733230775Sjfv 734230775Sjfv for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { 735295524Ssbruno reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); 736230775Sjfv if (reg & IXGBE_EEC_FLUDONE) { 737230775Sjfv status = IXGBE_SUCCESS; 738230775Sjfv break; 739230775Sjfv } 740283620Serj msec_delay(5); 741230775Sjfv } 742251964Sjfv 743251964Sjfv if (i == IXGBE_FLUDONE_ATTEMPTS) 744251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 745251964Sjfv "Flash update status polling timed out"); 746251964Sjfv 747230775Sjfv return status; 748230775Sjfv} 749230775Sjfv 750230775Sjfv/** 751230775Sjfv * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore 752230775Sjfv * @hw: pointer to hardware structure 753230775Sjfv * @mask: Mask to specify which semaphore to acquire 754230775Sjfv * 755230775Sjfv * Acquires the SWFW semaphore thought the SW_FW_SYNC register for 756230775Sjfv * the specified function (CSR, PHY0, PHY1, NVM, Flash) 757230775Sjfv **/ 758283620Serjs32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) 759230775Sjfv{ 760283620Serj u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK; 761283620Serj u32 fwmask = swmask << 5; 762283620Serj u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK; 763283620Serj u32 timeout = 200; 764283620Serj u32 hwmask = 0; 765230775Sjfv u32 swfw_sync; 766230775Sjfv u32 i; 767230775Sjfv 768230775Sjfv DEBUGFUNC("ixgbe_acquire_swfw_sync_X540"); 769230775Sjfv 770283620Serj if (swmask & IXGBE_GSSR_EEP_SM) 771283620Serj hwmask |= IXGBE_GSSR_FLASH_SM; 772230775Sjfv 773230775Sjfv /* SW only mask doesn't have FW bit pair */ 774283620Serj if (mask & IXGBE_GSSR_SW_MNG_SM) 775283620Serj swmask |= IXGBE_GSSR_SW_MNG_SM; 776230775Sjfv 777283620Serj swmask |= swi2c_mask; 778283620Serj fwmask |= swi2c_mask << 2; 779230775Sjfv for (i = 0; i < timeout; i++) { 780283620Serj /* SW NVM semaphore bit is used for access to all 781230775Sjfv * SW_FW_SYNC bits (not just NVM) 782230775Sjfv */ 783315333Serj if (ixgbe_get_swfw_sync_semaphore(hw)) { 784315333Serj DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n"); 785283620Serj return IXGBE_ERR_SWFW_SYNC; 786315333Serj } 787230775Sjfv 788295524Ssbruno swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 789230775Sjfv if (!(swfw_sync & (fwmask | swmask | hwmask))) { 790230775Sjfv swfw_sync |= swmask; 791295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), 792295524Ssbruno swfw_sync); 793230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 794283620Serj return IXGBE_SUCCESS; 795230775Sjfv } 796283620Serj /* Firmware currently using resource (fwmask), hardware 797283620Serj * currently using resource (hwmask), or other software 798283620Serj * thread currently using resource (swmask) 799283620Serj */ 800283620Serj ixgbe_release_swfw_sync_semaphore(hw); 801283620Serj msec_delay(5); 802230775Sjfv } 803230775Sjfv 804230775Sjfv /* Failed to get SW only semaphore */ 805230775Sjfv if (swmask == IXGBE_GSSR_SW_MNG_SM) { 806251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 807251964Sjfv "Failed to get SW only semaphore"); 808315333Serj DEBUGOUT("Failed to get SW only semaphore, returning IXGBE_ERR_SWFW_SYNC\n"); 809283620Serj return IXGBE_ERR_SWFW_SYNC; 810230775Sjfv } 811230775Sjfv 812230775Sjfv /* If the resource is not released by the FW/HW the SW can assume that 813251964Sjfv * the FW/HW malfunctions. In that case the SW should set the SW bit(s) 814230775Sjfv * of the requested resource(s) while ignoring the corresponding FW/HW 815230775Sjfv * bits in the SW_FW_SYNC register. 816230775Sjfv */ 817315333Serj if (ixgbe_get_swfw_sync_semaphore(hw)) { 818315333Serj DEBUGOUT("Failed to get NVM sempahore and register semaphore while forcefully ignoring FW sempahore bit(s) and setting SW semaphore bit(s), returning IXGBE_ERR_SWFW_SYNC\n"); 819283620Serj return IXGBE_ERR_SWFW_SYNC; 820315333Serj } 821295524Ssbruno swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 822230775Sjfv if (swfw_sync & (fwmask | hwmask)) { 823230775Sjfv swfw_sync |= swmask; 824295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); 825230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 826230775Sjfv msec_delay(5); 827283620Serj return IXGBE_SUCCESS; 828230775Sjfv } 829251964Sjfv /* If the resource is not released by other SW the SW can assume that 830251964Sjfv * the other SW malfunctions. In that case the SW should clear all SW 831251964Sjfv * flags that it does not own and then repeat the whole process once 832251964Sjfv * again. 833251964Sjfv */ 834283620Serj if (swfw_sync & swmask) { 835283620Serj u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | 836283620Serj IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM; 837283620Serj 838283620Serj if (swi2c_mask) 839283620Serj rmask |= IXGBE_GSSR_I2C_MASK; 840283620Serj ixgbe_release_swfw_sync_X540(hw, rmask); 841283620Serj ixgbe_release_swfw_sync_semaphore(hw); 842315333Serj DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n"); 843283620Serj return IXGBE_ERR_SWFW_SYNC; 844251964Sjfv } 845283620Serj ixgbe_release_swfw_sync_semaphore(hw); 846315333Serj DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n"); 847230775Sjfv 848283620Serj return IXGBE_ERR_SWFW_SYNC; 849230775Sjfv} 850230775Sjfv 851230775Sjfv/** 852230775Sjfv * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore 853230775Sjfv * @hw: pointer to hardware structure 854230775Sjfv * @mask: Mask to specify which semaphore to release 855230775Sjfv * 856238149Sjfv * Releases the SWFW semaphore through the SW_FW_SYNC register 857230775Sjfv * for the specified function (CSR, PHY0, PHY1, EVM, Flash) 858230775Sjfv **/ 859283620Serjvoid ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) 860230775Sjfv{ 861283620Serj u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM); 862230775Sjfv u32 swfw_sync; 863230775Sjfv 864230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_X540"); 865230775Sjfv 866283620Serj if (mask & IXGBE_GSSR_I2C_MASK) 867283620Serj swmask |= mask & IXGBE_GSSR_I2C_MASK; 868230775Sjfv ixgbe_get_swfw_sync_semaphore(hw); 869230775Sjfv 870295524Ssbruno swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 871230775Sjfv swfw_sync &= ~swmask; 872295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); 873230775Sjfv 874230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 875315333Serj msec_delay(2); 876230775Sjfv} 877230775Sjfv 878230775Sjfv/** 879283620Serj * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore 880230775Sjfv * @hw: pointer to hardware structure 881230775Sjfv * 882230775Sjfv * Sets the hardware semaphores so SW/FW can gain control of shared resources 883230775Sjfv **/ 884230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) 885230775Sjfv{ 886230775Sjfv s32 status = IXGBE_ERR_EEPROM; 887230775Sjfv u32 timeout = 2000; 888230775Sjfv u32 i; 889230775Sjfv u32 swsm; 890230775Sjfv 891230775Sjfv DEBUGFUNC("ixgbe_get_swfw_sync_semaphore"); 892230775Sjfv 893230775Sjfv /* Get SMBI software semaphore between device drivers first */ 894230775Sjfv for (i = 0; i < timeout; i++) { 895230775Sjfv /* 896230775Sjfv * If the SMBI bit is 0 when we read it, then the bit will be 897230775Sjfv * set and we have the semaphore 898230775Sjfv */ 899295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); 900230775Sjfv if (!(swsm & IXGBE_SWSM_SMBI)) { 901230775Sjfv status = IXGBE_SUCCESS; 902230775Sjfv break; 903230775Sjfv } 904230775Sjfv usec_delay(50); 905230775Sjfv } 906230775Sjfv 907230775Sjfv /* Now get the semaphore between SW/FW through the REGSMP bit */ 908230775Sjfv if (status == IXGBE_SUCCESS) { 909230775Sjfv for (i = 0; i < timeout; i++) { 910295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 911230775Sjfv if (!(swsm & IXGBE_SWFW_REGSMP)) 912230775Sjfv break; 913230775Sjfv 914230775Sjfv usec_delay(50); 915230775Sjfv } 916230775Sjfv 917230775Sjfv /* 918230775Sjfv * Release semaphores and return error if SW NVM semaphore 919230775Sjfv * was not granted because we don't have access to the EEPROM 920230775Sjfv */ 921230775Sjfv if (i >= timeout) { 922251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 923251964Sjfv "REGSMP Software NVM semaphore not granted.\n"); 924230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 925230775Sjfv status = IXGBE_ERR_EEPROM; 926230775Sjfv } 927230775Sjfv } else { 928251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 929251964Sjfv "Software semaphore SMBI between device drivers " 930251964Sjfv "not granted.\n"); 931230775Sjfv } 932230775Sjfv 933230775Sjfv return status; 934230775Sjfv} 935230775Sjfv 936230775Sjfv/** 937283620Serj * ixgbe_release_swfw_sync_semaphore - Release hardware semaphore 938230775Sjfv * @hw: pointer to hardware structure 939230775Sjfv * 940230775Sjfv * This function clears hardware semaphore bits. 941230775Sjfv **/ 942230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) 943230775Sjfv{ 944230775Sjfv u32 swsm; 945230775Sjfv 946230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_semaphore"); 947230775Sjfv 948230775Sjfv /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ 949230775Sjfv 950295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 951283620Serj swsm &= ~IXGBE_SWFW_REGSMP; 952295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm); 953283620Serj 954295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); 955230775Sjfv swsm &= ~IXGBE_SWSM_SMBI; 956295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm); 957230775Sjfv 958230775Sjfv IXGBE_WRITE_FLUSH(hw); 959230775Sjfv} 960230775Sjfv 961230775Sjfv/** 962315333Serj * ixgbe_init_swfw_sync_X540 - Release hardware semaphore 963315333Serj * @hw: pointer to hardware structure 964315333Serj * 965315333Serj * This function reset hardware semaphore bits for a semaphore that may 966315333Serj * have be left locked due to a catastrophic failure. 967315333Serj **/ 968315333Serjvoid ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw) 969315333Serj{ 970315333Serj /* First try to grab the semaphore but we don't need to bother 971315333Serj * looking to see whether we got the lock or not since we do 972315333Serj * the same thing regardless of whether we got the lock or not. 973315333Serj * We got the lock - we release it. 974315333Serj * We timeout trying to get the lock - we force its release. 975315333Serj */ 976315333Serj ixgbe_get_swfw_sync_semaphore(hw); 977315333Serj ixgbe_release_swfw_sync_semaphore(hw); 978315333Serj} 979315333Serj 980315333Serj/** 981230775Sjfv * ixgbe_blink_led_start_X540 - Blink LED based on index. 982230775Sjfv * @hw: pointer to hardware structure 983230775Sjfv * @index: led number to blink 984230775Sjfv * 985230775Sjfv * Devices that implement the version 2 interface: 986230775Sjfv * X540 987230775Sjfv **/ 988230775Sjfvs32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) 989230775Sjfv{ 990230775Sjfv u32 macc_reg; 991230775Sjfv u32 ledctl_reg; 992230775Sjfv ixgbe_link_speed speed; 993230775Sjfv bool link_up; 994230775Sjfv 995230775Sjfv DEBUGFUNC("ixgbe_blink_led_start_X540"); 996230775Sjfv 997315333Serj if (index > 3) 998315333Serj return IXGBE_ERR_PARAM; 999315333Serj 1000230775Sjfv /* 1001230775Sjfv * Link should be up in order for the blink bit in the LED control 1002230775Sjfv * register to work. Force link and speed in the MAC if link is down. 1003230775Sjfv * This will be reversed when we stop the blinking. 1004230775Sjfv */ 1005230775Sjfv hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 1006230775Sjfv if (link_up == FALSE) { 1007230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 1008230775Sjfv macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; 1009230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 1010230775Sjfv } 1011230775Sjfv /* Set the LED to LINK_UP + BLINK. */ 1012230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 1013230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 1014230775Sjfv ledctl_reg |= IXGBE_LED_BLINK(index); 1015230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 1016230775Sjfv IXGBE_WRITE_FLUSH(hw); 1017230775Sjfv 1018230775Sjfv return IXGBE_SUCCESS; 1019230775Sjfv} 1020230775Sjfv 1021230775Sjfv/** 1022230775Sjfv * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index. 1023230775Sjfv * @hw: pointer to hardware structure 1024230775Sjfv * @index: led number to stop blinking 1025230775Sjfv * 1026230775Sjfv * Devices that implement the version 2 interface: 1027230775Sjfv * X540 1028230775Sjfv **/ 1029230775Sjfvs32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) 1030230775Sjfv{ 1031230775Sjfv u32 macc_reg; 1032230775Sjfv u32 ledctl_reg; 1033230775Sjfv 1034315333Serj if (index > 3) 1035315333Serj return IXGBE_ERR_PARAM; 1036315333Serj 1037230775Sjfv DEBUGFUNC("ixgbe_blink_led_stop_X540"); 1038230775Sjfv 1039230775Sjfv /* Restore the LED to its default value. */ 1040230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 1041230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 1042230775Sjfv ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 1043230775Sjfv ledctl_reg &= ~IXGBE_LED_BLINK(index); 1044230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 1045230775Sjfv 1046230775Sjfv /* Unforce link and speed in the MAC. */ 1047230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 1048230775Sjfv macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS); 1049230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 1050230775Sjfv IXGBE_WRITE_FLUSH(hw); 1051230775Sjfv 1052230775Sjfv return IXGBE_SUCCESS; 1053230775Sjfv} 1054