ixgbe_x540.c revision 295524
1230775Sjfv/****************************************************************************** 2230775Sjfv 3283620Serj Copyright (c) 2001-2015, 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: stable/10/sys/dev/ixgbe/ixgbe_x540.c 295524 2016-02-11 16:16:10Z sbruno $*/ 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; 85283620Serj if (!ixgbe_mng_present(hw)) 86283620Serj phy->ops.set_phy_power = ixgbe_set_copper_phy_power; 87230775Sjfv 88230775Sjfv /* MAC */ 89283620Serj mac->ops.reset_hw = ixgbe_reset_hw_X540; 90283620Serj mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_gen2; 91283620Serj mac->ops.get_media_type = ixgbe_get_media_type_X540; 92230775Sjfv mac->ops.get_supported_physical_layer = 93283620Serj ixgbe_get_supported_physical_layer_X540; 94230775Sjfv mac->ops.read_analog_reg8 = NULL; 95230775Sjfv mac->ops.write_analog_reg8 = NULL; 96283620Serj mac->ops.start_hw = ixgbe_start_hw_X540; 97283620Serj mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic; 98283620Serj mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic; 99283620Serj mac->ops.get_device_caps = ixgbe_get_device_caps_generic; 100283620Serj mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic; 101283620Serj mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic; 102283620Serj mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540; 103283620Serj mac->ops.release_swfw_sync = ixgbe_release_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; 126230775Sjfv 127247822Sjfv 128283620Serj mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; 129283620Serj mac->vft_size = IXGBE_X540_VFT_TBL_SIZE; 130283620Serj mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES; 131283620Serj mac->rx_pb_size = IXGBE_X540_RX_PB_SIZE; 132283620Serj mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES; 133283620Serj mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES; 134230775Sjfv mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); 135230775Sjfv 136230775Sjfv /* 137230775Sjfv * FWSM register 138230775Sjfv * ARC supported; valid only if manageability features are 139230775Sjfv * enabled. 140230775Sjfv */ 141295524Ssbruno mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)) 142295524Ssbruno & IXGBE_FWSM_MODE_MASK); 143230775Sjfv 144230775Sjfv hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf; 145230775Sjfv 146230775Sjfv /* LEDs */ 147230775Sjfv mac->ops.blink_led_start = ixgbe_blink_led_start_X540; 148230775Sjfv mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540; 149230775Sjfv 150230775Sjfv /* Manageability interface */ 151283620Serj mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic; 152230775Sjfv 153283620Serj mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic; 154251964Sjfv 155230775Sjfv return ret_val; 156230775Sjfv} 157230775Sjfv 158230775Sjfv/** 159230775Sjfv * ixgbe_get_link_capabilities_X540 - Determines link capabilities 160230775Sjfv * @hw: pointer to hardware structure 161230775Sjfv * @speed: pointer to link speed 162230775Sjfv * @autoneg: TRUE when autoneg or autotry is enabled 163230775Sjfv * 164230775Sjfv * Determines the link capabilities by reading the AUTOC register. 165230775Sjfv **/ 166230775Sjfvs32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, 167230775Sjfv ixgbe_link_speed *speed, 168230775Sjfv bool *autoneg) 169230775Sjfv{ 170230775Sjfv ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg); 171230775Sjfv 172230775Sjfv return IXGBE_SUCCESS; 173230775Sjfv} 174230775Sjfv 175230775Sjfv/** 176230775Sjfv * ixgbe_get_media_type_X540 - Get media type 177230775Sjfv * @hw: pointer to hardware structure 178230775Sjfv * 179230775Sjfv * Returns the media type (fiber, copper, backplane) 180230775Sjfv **/ 181230775Sjfvenum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) 182230775Sjfv{ 183230775Sjfv UNREFERENCED_1PARAMETER(hw); 184230775Sjfv return ixgbe_media_type_copper; 185230775Sjfv} 186230775Sjfv 187230775Sjfv/** 188230775Sjfv * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities 189230775Sjfv * @hw: pointer to hardware structure 190230775Sjfv * @speed: new link speed 191230775Sjfv * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 192230775Sjfv **/ 193230775Sjfvs32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, 194247822Sjfv ixgbe_link_speed speed, 195230775Sjfv bool autoneg_wait_to_complete) 196230775Sjfv{ 197230775Sjfv DEBUGFUNC("ixgbe_setup_mac_link_X540"); 198247822Sjfv return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); 199230775Sjfv} 200230775Sjfv 201230775Sjfv/** 202230775Sjfv * ixgbe_reset_hw_X540 - Perform hardware reset 203230775Sjfv * @hw: pointer to hardware structure 204230775Sjfv * 205230775Sjfv * Resets the hardware by resetting the transmit and receive units, masks 206230775Sjfv * and clears all interrupts, and perform a reset. 207230775Sjfv **/ 208230775Sjfvs32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) 209230775Sjfv{ 210230775Sjfv s32 status; 211230775Sjfv u32 ctrl, i; 212230775Sjfv 213230775Sjfv DEBUGFUNC("ixgbe_reset_hw_X540"); 214230775Sjfv 215230775Sjfv /* Call adapter stop to disable tx/rx and clear interrupts */ 216230775Sjfv status = hw->mac.ops.stop_adapter(hw); 217230775Sjfv if (status != IXGBE_SUCCESS) 218230775Sjfv goto reset_hw_out; 219230775Sjfv 220230775Sjfv /* flush pending Tx transactions */ 221230775Sjfv ixgbe_clear_tx_pending(hw); 222230775Sjfv 223230775Sjfvmac_reset_top: 224230775Sjfv ctrl = IXGBE_CTRL_RST; 225230775Sjfv ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); 226230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); 227230775Sjfv IXGBE_WRITE_FLUSH(hw); 228230775Sjfv 229230775Sjfv /* Poll for reset bit to self-clear indicating reset is complete */ 230230775Sjfv for (i = 0; i < 10; i++) { 231230775Sjfv usec_delay(1); 232230775Sjfv ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); 233230775Sjfv if (!(ctrl & IXGBE_CTRL_RST_MASK)) 234230775Sjfv break; 235230775Sjfv } 236230775Sjfv 237230775Sjfv if (ctrl & IXGBE_CTRL_RST_MASK) { 238230775Sjfv status = IXGBE_ERR_RESET_FAILED; 239251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 240251964Sjfv "Reset polling failed to complete.\n"); 241230775Sjfv } 242230775Sjfv msec_delay(100); 243230775Sjfv 244230775Sjfv /* 245230775Sjfv * Double resets are required for recovery from certain error 246230775Sjfv * conditions. Between resets, it is necessary to stall to allow time 247230775Sjfv * for any pending HW events to complete. 248230775Sjfv */ 249230775Sjfv if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { 250230775Sjfv hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 251230775Sjfv goto mac_reset_top; 252230775Sjfv } 253230775Sjfv 254230775Sjfv /* Set the Rx packet buffer size. */ 255230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); 256230775Sjfv 257230775Sjfv /* Store the permanent mac address */ 258230775Sjfv hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); 259230775Sjfv 260230775Sjfv /* 261230775Sjfv * Store MAC address from RAR0, clear receive address registers, and 262230775Sjfv * clear the multicast table. Also reset num_rar_entries to 128, 263230775Sjfv * since we modify this value when programming the SAN MAC address. 264230775Sjfv */ 265230775Sjfv hw->mac.num_rar_entries = 128; 266230775Sjfv hw->mac.ops.init_rx_addrs(hw); 267230775Sjfv 268230775Sjfv /* Store the permanent SAN mac address */ 269230775Sjfv hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); 270230775Sjfv 271230775Sjfv /* Add the SAN MAC address to the RAR only if it's a valid address */ 272230775Sjfv if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { 273230775Sjfv hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, 274230775Sjfv hw->mac.san_addr, 0, IXGBE_RAH_AV); 275230775Sjfv 276238149Sjfv /* Save the SAN MAC RAR index */ 277238149Sjfv hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; 278238149Sjfv 279230775Sjfv /* Reserve the last RAR for the SAN MAC address */ 280230775Sjfv hw->mac.num_rar_entries--; 281230775Sjfv } 282230775Sjfv 283230775Sjfv /* Store the alternative WWNN/WWPN prefix */ 284230775Sjfv hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, 285230775Sjfv &hw->mac.wwpn_prefix); 286230775Sjfv 287230775Sjfvreset_hw_out: 288230775Sjfv return status; 289230775Sjfv} 290230775Sjfv 291230775Sjfv/** 292230775Sjfv * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx 293230775Sjfv * @hw: pointer to hardware structure 294230775Sjfv * 295230775Sjfv * Starts the hardware using the generic start_hw function 296230775Sjfv * and the generation start_hw function. 297230775Sjfv * Then performs revision-specific operations, if any. 298230775Sjfv **/ 299230775Sjfvs32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) 300230775Sjfv{ 301230775Sjfv s32 ret_val = IXGBE_SUCCESS; 302230775Sjfv 303230775Sjfv DEBUGFUNC("ixgbe_start_hw_X540"); 304230775Sjfv 305230775Sjfv ret_val = ixgbe_start_hw_generic(hw); 306230775Sjfv if (ret_val != IXGBE_SUCCESS) 307230775Sjfv goto out; 308230775Sjfv 309230775Sjfv ret_val = ixgbe_start_hw_gen2(hw); 310230775Sjfv 311230775Sjfvout: 312230775Sjfv return ret_val; 313230775Sjfv} 314230775Sjfv 315230775Sjfv/** 316230775Sjfv * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type 317230775Sjfv * @hw: pointer to hardware structure 318230775Sjfv * 319230775Sjfv * Determines physical layer capabilities of the current configuration. 320230775Sjfv **/ 321230775Sjfvu32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) 322230775Sjfv{ 323230775Sjfv u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; 324230775Sjfv u16 ext_ability = 0; 325230775Sjfv 326230775Sjfv DEBUGFUNC("ixgbe_get_supported_physical_layer_X540"); 327230775Sjfv 328230775Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, 329230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); 330230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) 331230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; 332230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) 333230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; 334230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) 335230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; 336230775Sjfv 337230775Sjfv return physical_layer; 338230775Sjfv} 339230775Sjfv 340230775Sjfv/** 341230775Sjfv * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params 342230775Sjfv * @hw: pointer to hardware structure 343230775Sjfv * 344230775Sjfv * Initializes the EEPROM parameters ixgbe_eeprom_info within the 345230775Sjfv * ixgbe_hw struct in order to set up EEPROM access. 346230775Sjfv **/ 347230775Sjfvs32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) 348230775Sjfv{ 349230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 350230775Sjfv u32 eec; 351230775Sjfv u16 eeprom_size; 352230775Sjfv 353230775Sjfv DEBUGFUNC("ixgbe_init_eeprom_params_X540"); 354230775Sjfv 355230775Sjfv if (eeprom->type == ixgbe_eeprom_uninitialized) { 356230775Sjfv eeprom->semaphore_delay = 10; 357230775Sjfv eeprom->type = ixgbe_flash; 358230775Sjfv 359295524Ssbruno eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); 360230775Sjfv eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 361230775Sjfv IXGBE_EEC_SIZE_SHIFT); 362230775Sjfv eeprom->word_size = 1 << (eeprom_size + 363230775Sjfv IXGBE_EEPROM_WORD_SIZE_SHIFT); 364230775Sjfv 365230775Sjfv DEBUGOUT2("Eeprom params: type = %d, size = %d\n", 366230775Sjfv eeprom->type, eeprom->word_size); 367230775Sjfv } 368230775Sjfv 369230775Sjfv return IXGBE_SUCCESS; 370230775Sjfv} 371230775Sjfv 372230775Sjfv/** 373230775Sjfv * ixgbe_read_eerd_X540- Read EEPROM word using EERD 374230775Sjfv * @hw: pointer to hardware structure 375230775Sjfv * @offset: offset of word in the EEPROM to read 376230775Sjfv * @data: word read from the EEPROM 377230775Sjfv * 378230775Sjfv * Reads a 16 bit word from the EEPROM using the EERD register. 379230775Sjfv **/ 380230775Sjfvs32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) 381230775Sjfv{ 382230775Sjfv s32 status = IXGBE_SUCCESS; 383230775Sjfv 384230775Sjfv DEBUGFUNC("ixgbe_read_eerd_X540"); 385230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 386251964Sjfv IXGBE_SUCCESS) { 387230775Sjfv status = ixgbe_read_eerd_generic(hw, offset, data); 388251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 389251964Sjfv } else { 390230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 391251964Sjfv } 392230775Sjfv 393230775Sjfv return status; 394230775Sjfv} 395230775Sjfv 396230775Sjfv/** 397230775Sjfv * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD 398230775Sjfv * @hw: pointer to hardware structure 399230775Sjfv * @offset: offset of word in the EEPROM to read 400230775Sjfv * @words: number of words 401230775Sjfv * @data: word(s) read from the EEPROM 402230775Sjfv * 403230775Sjfv * Reads a 16 bit word(s) from the EEPROM using the EERD register. 404230775Sjfv **/ 405230775Sjfvs32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, 406230775Sjfv u16 offset, u16 words, u16 *data) 407230775Sjfv{ 408230775Sjfv s32 status = IXGBE_SUCCESS; 409230775Sjfv 410230775Sjfv DEBUGFUNC("ixgbe_read_eerd_buffer_X540"); 411230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 412251964Sjfv IXGBE_SUCCESS) { 413230775Sjfv status = ixgbe_read_eerd_buffer_generic(hw, offset, 414230775Sjfv words, data); 415251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 416251964Sjfv } else { 417230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 418251964Sjfv } 419230775Sjfv 420230775Sjfv return status; 421230775Sjfv} 422230775Sjfv 423230775Sjfv/** 424230775Sjfv * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR 425230775Sjfv * @hw: pointer to hardware structure 426230775Sjfv * @offset: offset of word in the EEPROM to write 427230775Sjfv * @data: word write to the EEPROM 428230775Sjfv * 429230775Sjfv * Write a 16 bit word to the EEPROM using the EEWR register. 430230775Sjfv **/ 431230775Sjfvs32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) 432230775Sjfv{ 433230775Sjfv s32 status = IXGBE_SUCCESS; 434230775Sjfv 435230775Sjfv DEBUGFUNC("ixgbe_write_eewr_X540"); 436230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 437251964Sjfv IXGBE_SUCCESS) { 438230775Sjfv status = ixgbe_write_eewr_generic(hw, offset, data); 439251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 440251964Sjfv } else { 441230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 442251964Sjfv } 443230775Sjfv 444230775Sjfv return status; 445230775Sjfv} 446230775Sjfv 447230775Sjfv/** 448230775Sjfv * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR 449230775Sjfv * @hw: pointer to hardware structure 450230775Sjfv * @offset: offset of word in the EEPROM to write 451230775Sjfv * @words: number of words 452230775Sjfv * @data: word(s) write to the EEPROM 453230775Sjfv * 454230775Sjfv * Write a 16 bit word(s) to the EEPROM using the EEWR register. 455230775Sjfv **/ 456230775Sjfvs32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, 457230775Sjfv u16 offset, u16 words, u16 *data) 458230775Sjfv{ 459230775Sjfv s32 status = IXGBE_SUCCESS; 460230775Sjfv 461230775Sjfv DEBUGFUNC("ixgbe_write_eewr_buffer_X540"); 462230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 463251964Sjfv IXGBE_SUCCESS) { 464230775Sjfv status = ixgbe_write_eewr_buffer_generic(hw, offset, 465230775Sjfv words, data); 466251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 467251964Sjfv } else { 468230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 469251964Sjfv } 470230775Sjfv 471230775Sjfv return status; 472230775Sjfv} 473230775Sjfv 474230775Sjfv/** 475230775Sjfv * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum 476230775Sjfv * 477230775Sjfv * This function does not use synchronization for EERD and EEWR. It can 478230775Sjfv * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. 479230775Sjfv * 480230775Sjfv * @hw: pointer to hardware structure 481283620Serj * 482283620Serj * Returns a negative error code on error, or the 16-bit checksum 483230775Sjfv **/ 484283620Serjs32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) 485230775Sjfv{ 486283620Serj u16 i, j; 487230775Sjfv u16 checksum = 0; 488230775Sjfv u16 length = 0; 489230775Sjfv u16 pointer = 0; 490230775Sjfv u16 word = 0; 491283620Serj u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM; 492283620Serj u16 ptr_start = IXGBE_PCIE_ANALOG_PTR; 493230775Sjfv 494283620Serj /* Do not use hw->eeprom.ops.read because we do not want to take 495230775Sjfv * the synchronization semaphores here. Instead use 496230775Sjfv * ixgbe_read_eerd_generic 497230775Sjfv */ 498230775Sjfv 499230775Sjfv DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540"); 500230775Sjfv 501230775Sjfv /* Include 0x0-0x3F in the checksum */ 502283620Serj for (i = 0; i <= checksum_last_word; i++) { 503283620Serj if (ixgbe_read_eerd_generic(hw, i, &word)) { 504230775Sjfv DEBUGOUT("EEPROM read failed\n"); 505283620Serj return IXGBE_ERR_EEPROM; 506230775Sjfv } 507283620Serj if (i != IXGBE_EEPROM_CHECKSUM) 508283620Serj checksum += word; 509230775Sjfv } 510230775Sjfv 511283620Serj /* Include all data from pointers 0x3, 0x6-0xE. This excludes the 512230775Sjfv * FW, PHY module, and PCIe Expansion/Option ROM pointers. 513230775Sjfv */ 514283620Serj for (i = ptr_start; i < IXGBE_FW_PTR; i++) { 515230775Sjfv if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 516230775Sjfv continue; 517230775Sjfv 518283620Serj if (ixgbe_read_eerd_generic(hw, i, &pointer)) { 519230775Sjfv DEBUGOUT("EEPROM read failed\n"); 520283620Serj return IXGBE_ERR_EEPROM; 521230775Sjfv } 522230775Sjfv 523230775Sjfv /* Skip pointer section if the pointer is invalid. */ 524230775Sjfv if (pointer == 0xFFFF || pointer == 0 || 525230775Sjfv pointer >= hw->eeprom.word_size) 526230775Sjfv continue; 527230775Sjfv 528283620Serj if (ixgbe_read_eerd_generic(hw, pointer, &length)) { 529230775Sjfv DEBUGOUT("EEPROM read failed\n"); 530283620Serj return IXGBE_ERR_EEPROM; 531230775Sjfv } 532230775Sjfv 533230775Sjfv /* Skip pointer section if length is invalid. */ 534230775Sjfv if (length == 0xFFFF || length == 0 || 535230775Sjfv (pointer + length) >= hw->eeprom.word_size) 536230775Sjfv continue; 537230775Sjfv 538283620Serj for (j = pointer + 1; j <= pointer + length; j++) { 539283620Serj if (ixgbe_read_eerd_generic(hw, j, &word)) { 540230775Sjfv DEBUGOUT("EEPROM read failed\n"); 541283620Serj return IXGBE_ERR_EEPROM; 542230775Sjfv } 543230775Sjfv checksum += word; 544230775Sjfv } 545230775Sjfv } 546230775Sjfv 547230775Sjfv checksum = (u16)IXGBE_EEPROM_SUM - checksum; 548230775Sjfv 549283620Serj return (s32)checksum; 550230775Sjfv} 551230775Sjfv 552230775Sjfv/** 553230775Sjfv * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum 554230775Sjfv * @hw: pointer to hardware structure 555230775Sjfv * @checksum_val: calculated checksum 556230775Sjfv * 557230775Sjfv * Performs checksum calculation and validates the EEPROM checksum. If the 558230775Sjfv * caller does not need checksum_val, the value can be NULL. 559230775Sjfv **/ 560230775Sjfvs32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, 561230775Sjfv u16 *checksum_val) 562230775Sjfv{ 563230775Sjfv s32 status; 564230775Sjfv u16 checksum; 565230775Sjfv u16 read_checksum = 0; 566230775Sjfv 567230775Sjfv DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540"); 568230775Sjfv 569283620Serj /* Read the first word from the EEPROM. If this times out or fails, do 570230775Sjfv * not continue or we could be in for a very long wait while every 571230775Sjfv * EEPROM read fails 572230775Sjfv */ 573230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 574283620Serj if (status) { 575230775Sjfv DEBUGOUT("EEPROM read failed\n"); 576283620Serj return status; 577230775Sjfv } 578230775Sjfv 579283620Serj if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) 580283620Serj return IXGBE_ERR_SWFW_SYNC; 581230775Sjfv 582283620Serj status = hw->eeprom.ops.calc_checksum(hw); 583283620Serj if (status < 0) 584283620Serj goto out; 585230775Sjfv 586283620Serj checksum = (u16)(status & 0xffff); 587230775Sjfv 588283620Serj /* Do not use hw->eeprom.ops.read because we do not want to take 589283620Serj * the synchronization semaphores twice here. 590283620Serj */ 591283620Serj status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, 592283620Serj &read_checksum); 593283620Serj if (status) 594283620Serj goto out; 595283620Serj 596283620Serj /* Verify read checksum from EEPROM is the same as 597283620Serj * calculated checksum 598283620Serj */ 599283620Serj if (read_checksum != checksum) { 600283620Serj ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, 601283620Serj "Invalid EEPROM checksum"); 602283620Serj status = IXGBE_ERR_EEPROM_CHECKSUM; 603230775Sjfv } 604230775Sjfv 605283620Serj /* If the user cares, return the calculated checksum */ 606283620Serj if (checksum_val) 607283620Serj *checksum_val = checksum; 608283620Serj 609230775Sjfvout: 610283620Serj hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 611283620Serj 612230775Sjfv return status; 613230775Sjfv} 614230775Sjfv 615230775Sjfv/** 616230775Sjfv * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash 617230775Sjfv * @hw: pointer to hardware structure 618230775Sjfv * 619230775Sjfv * After writing EEPROM to shadow RAM using EEWR register, software calculates 620230775Sjfv * checksum and updates the EEPROM and instructs the hardware to update 621230775Sjfv * the flash. 622230775Sjfv **/ 623230775Sjfvs32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) 624230775Sjfv{ 625230775Sjfv s32 status; 626230775Sjfv u16 checksum; 627230775Sjfv 628230775Sjfv DEBUGFUNC("ixgbe_update_eeprom_checksum_X540"); 629230775Sjfv 630283620Serj /* Read the first word from the EEPROM. If this times out or fails, do 631230775Sjfv * not continue or we could be in for a very long wait while every 632230775Sjfv * EEPROM read fails 633230775Sjfv */ 634230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 635283620Serj if (status) { 636230775Sjfv DEBUGOUT("EEPROM read failed\n"); 637283620Serj return status; 638283620Serj } 639230775Sjfv 640283620Serj if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) 641283620Serj return IXGBE_ERR_SWFW_SYNC; 642230775Sjfv 643283620Serj status = hw->eeprom.ops.calc_checksum(hw); 644283620Serj if (status < 0) 645283620Serj goto out; 646230775Sjfv 647283620Serj checksum = (u16)(status & 0xffff); 648230775Sjfv 649283620Serj /* Do not use hw->eeprom.ops.write because we do not want to 650283620Serj * take the synchronization semaphores twice here. 651283620Serj */ 652283620Serj status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum); 653283620Serj if (status) 654283620Serj goto out; 655283620Serj 656283620Serj status = ixgbe_update_flash_X540(hw); 657283620Serj 658283620Serjout: 659283620Serj hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 660283620Serj 661230775Sjfv return status; 662230775Sjfv} 663230775Sjfv 664230775Sjfv/** 665230775Sjfv * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device 666230775Sjfv * @hw: pointer to hardware structure 667230775Sjfv * 668230775Sjfv * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy 669230775Sjfv * EEPROM from shadow RAM to the flash device. 670230775Sjfv **/ 671251964Sjfvs32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) 672230775Sjfv{ 673230775Sjfv u32 flup; 674283620Serj s32 status; 675230775Sjfv 676230775Sjfv DEBUGFUNC("ixgbe_update_flash_X540"); 677230775Sjfv 678230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 679230775Sjfv if (status == IXGBE_ERR_EEPROM) { 680230775Sjfv DEBUGOUT("Flash update time out\n"); 681230775Sjfv goto out; 682230775Sjfv } 683230775Sjfv 684295524Ssbruno flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP; 685295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup); 686230775Sjfv 687230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 688230775Sjfv if (status == IXGBE_SUCCESS) 689230775Sjfv DEBUGOUT("Flash update complete\n"); 690230775Sjfv else 691230775Sjfv DEBUGOUT("Flash update time out\n"); 692230775Sjfv 693251964Sjfv if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) { 694295524Ssbruno flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); 695230775Sjfv 696230775Sjfv if (flup & IXGBE_EEC_SEC1VAL) { 697230775Sjfv flup |= IXGBE_EEC_FLUP; 698295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup); 699230775Sjfv } 700230775Sjfv 701230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 702230775Sjfv if (status == IXGBE_SUCCESS) 703230775Sjfv DEBUGOUT("Flash update complete\n"); 704230775Sjfv else 705230775Sjfv DEBUGOUT("Flash update time out\n"); 706230775Sjfv } 707230775Sjfvout: 708230775Sjfv return status; 709230775Sjfv} 710230775Sjfv 711230775Sjfv/** 712230775Sjfv * ixgbe_poll_flash_update_done_X540 - Poll flash update status 713230775Sjfv * @hw: pointer to hardware structure 714230775Sjfv * 715230775Sjfv * Polls the FLUDONE (bit 26) of the EEC Register to determine when the 716230775Sjfv * flash update is done. 717230775Sjfv **/ 718230775Sjfvstatic s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) 719230775Sjfv{ 720230775Sjfv u32 i; 721230775Sjfv u32 reg; 722230775Sjfv s32 status = IXGBE_ERR_EEPROM; 723230775Sjfv 724230775Sjfv DEBUGFUNC("ixgbe_poll_flash_update_done_X540"); 725230775Sjfv 726230775Sjfv for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { 727295524Ssbruno reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)); 728230775Sjfv if (reg & IXGBE_EEC_FLUDONE) { 729230775Sjfv status = IXGBE_SUCCESS; 730230775Sjfv break; 731230775Sjfv } 732283620Serj msec_delay(5); 733230775Sjfv } 734251964Sjfv 735251964Sjfv if (i == IXGBE_FLUDONE_ATTEMPTS) 736251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 737251964Sjfv "Flash update status polling timed out"); 738251964Sjfv 739230775Sjfv return status; 740230775Sjfv} 741230775Sjfv 742230775Sjfv/** 743230775Sjfv * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore 744230775Sjfv * @hw: pointer to hardware structure 745230775Sjfv * @mask: Mask to specify which semaphore to acquire 746230775Sjfv * 747230775Sjfv * Acquires the SWFW semaphore thought the SW_FW_SYNC register for 748230775Sjfv * the specified function (CSR, PHY0, PHY1, NVM, Flash) 749230775Sjfv **/ 750283620Serjs32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) 751230775Sjfv{ 752283620Serj u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK; 753283620Serj u32 fwmask = swmask << 5; 754283620Serj u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK; 755283620Serj u32 timeout = 200; 756283620Serj u32 hwmask = 0; 757230775Sjfv u32 swfw_sync; 758230775Sjfv u32 i; 759230775Sjfv 760230775Sjfv DEBUGFUNC("ixgbe_acquire_swfw_sync_X540"); 761230775Sjfv 762283620Serj if (swmask & IXGBE_GSSR_EEP_SM) 763283620Serj hwmask |= IXGBE_GSSR_FLASH_SM; 764230775Sjfv 765230775Sjfv /* SW only mask doesn't have FW bit pair */ 766283620Serj if (mask & IXGBE_GSSR_SW_MNG_SM) 767283620Serj swmask |= IXGBE_GSSR_SW_MNG_SM; 768230775Sjfv 769283620Serj swmask |= swi2c_mask; 770283620Serj fwmask |= swi2c_mask << 2; 771230775Sjfv for (i = 0; i < timeout; i++) { 772283620Serj /* SW NVM semaphore bit is used for access to all 773230775Sjfv * SW_FW_SYNC bits (not just NVM) 774230775Sjfv */ 775283620Serj if (ixgbe_get_swfw_sync_semaphore(hw)) 776283620Serj return IXGBE_ERR_SWFW_SYNC; 777230775Sjfv 778295524Ssbruno swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 779230775Sjfv if (!(swfw_sync & (fwmask | swmask | hwmask))) { 780230775Sjfv swfw_sync |= swmask; 781295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), 782295524Ssbruno swfw_sync); 783230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 784230775Sjfv msec_delay(5); 785283620Serj return IXGBE_SUCCESS; 786230775Sjfv } 787283620Serj /* Firmware currently using resource (fwmask), hardware 788283620Serj * currently using resource (hwmask), or other software 789283620Serj * thread currently using resource (swmask) 790283620Serj */ 791283620Serj ixgbe_release_swfw_sync_semaphore(hw); 792283620Serj msec_delay(5); 793230775Sjfv } 794230775Sjfv 795230775Sjfv /* Failed to get SW only semaphore */ 796230775Sjfv if (swmask == IXGBE_GSSR_SW_MNG_SM) { 797251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 798251964Sjfv "Failed to get SW only semaphore"); 799283620Serj return IXGBE_ERR_SWFW_SYNC; 800230775Sjfv } 801230775Sjfv 802230775Sjfv /* If the resource is not released by the FW/HW the SW can assume that 803251964Sjfv * the FW/HW malfunctions. In that case the SW should set the SW bit(s) 804230775Sjfv * of the requested resource(s) while ignoring the corresponding FW/HW 805230775Sjfv * bits in the SW_FW_SYNC register. 806230775Sjfv */ 807283620Serj if (ixgbe_get_swfw_sync_semaphore(hw)) 808283620Serj return IXGBE_ERR_SWFW_SYNC; 809295524Ssbruno swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 810230775Sjfv if (swfw_sync & (fwmask | hwmask)) { 811230775Sjfv swfw_sync |= swmask; 812295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); 813230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 814230775Sjfv msec_delay(5); 815283620Serj return IXGBE_SUCCESS; 816230775Sjfv } 817251964Sjfv /* If the resource is not released by other SW the SW can assume that 818251964Sjfv * the other SW malfunctions. In that case the SW should clear all SW 819251964Sjfv * flags that it does not own and then repeat the whole process once 820251964Sjfv * again. 821251964Sjfv */ 822283620Serj if (swfw_sync & swmask) { 823283620Serj u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | 824283620Serj IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM; 825283620Serj 826283620Serj if (swi2c_mask) 827283620Serj rmask |= IXGBE_GSSR_I2C_MASK; 828283620Serj ixgbe_release_swfw_sync_X540(hw, rmask); 829283620Serj ixgbe_release_swfw_sync_semaphore(hw); 830283620Serj return IXGBE_ERR_SWFW_SYNC; 831251964Sjfv } 832283620Serj ixgbe_release_swfw_sync_semaphore(hw); 833230775Sjfv 834283620Serj return IXGBE_ERR_SWFW_SYNC; 835230775Sjfv} 836230775Sjfv 837230775Sjfv/** 838230775Sjfv * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore 839230775Sjfv * @hw: pointer to hardware structure 840230775Sjfv * @mask: Mask to specify which semaphore to release 841230775Sjfv * 842238149Sjfv * Releases the SWFW semaphore through the SW_FW_SYNC register 843230775Sjfv * for the specified function (CSR, PHY0, PHY1, EVM, Flash) 844230775Sjfv **/ 845283620Serjvoid ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) 846230775Sjfv{ 847283620Serj u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM); 848230775Sjfv u32 swfw_sync; 849230775Sjfv 850230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_X540"); 851230775Sjfv 852283620Serj if (mask & IXGBE_GSSR_I2C_MASK) 853283620Serj swmask |= mask & IXGBE_GSSR_I2C_MASK; 854230775Sjfv ixgbe_get_swfw_sync_semaphore(hw); 855230775Sjfv 856295524Ssbruno swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 857230775Sjfv swfw_sync &= ~swmask; 858295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync); 859230775Sjfv 860230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 861283620Serj msec_delay(5); 862230775Sjfv} 863230775Sjfv 864230775Sjfv/** 865283620Serj * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore 866230775Sjfv * @hw: pointer to hardware structure 867230775Sjfv * 868230775Sjfv * Sets the hardware semaphores so SW/FW can gain control of shared resources 869230775Sjfv **/ 870230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) 871230775Sjfv{ 872230775Sjfv s32 status = IXGBE_ERR_EEPROM; 873230775Sjfv u32 timeout = 2000; 874230775Sjfv u32 i; 875230775Sjfv u32 swsm; 876230775Sjfv 877230775Sjfv DEBUGFUNC("ixgbe_get_swfw_sync_semaphore"); 878230775Sjfv 879230775Sjfv /* Get SMBI software semaphore between device drivers first */ 880230775Sjfv for (i = 0; i < timeout; i++) { 881230775Sjfv /* 882230775Sjfv * If the SMBI bit is 0 when we read it, then the bit will be 883230775Sjfv * set and we have the semaphore 884230775Sjfv */ 885295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); 886230775Sjfv if (!(swsm & IXGBE_SWSM_SMBI)) { 887230775Sjfv status = IXGBE_SUCCESS; 888230775Sjfv break; 889230775Sjfv } 890230775Sjfv usec_delay(50); 891230775Sjfv } 892230775Sjfv 893230775Sjfv /* Now get the semaphore between SW/FW through the REGSMP bit */ 894230775Sjfv if (status == IXGBE_SUCCESS) { 895230775Sjfv for (i = 0; i < timeout; i++) { 896295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 897230775Sjfv if (!(swsm & IXGBE_SWFW_REGSMP)) 898230775Sjfv break; 899230775Sjfv 900230775Sjfv usec_delay(50); 901230775Sjfv } 902230775Sjfv 903230775Sjfv /* 904230775Sjfv * Release semaphores and return error if SW NVM semaphore 905230775Sjfv * was not granted because we don't have access to the EEPROM 906230775Sjfv */ 907230775Sjfv if (i >= timeout) { 908251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 909251964Sjfv "REGSMP Software NVM semaphore not granted.\n"); 910230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 911230775Sjfv status = IXGBE_ERR_EEPROM; 912230775Sjfv } 913230775Sjfv } else { 914251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 915251964Sjfv "Software semaphore SMBI between device drivers " 916251964Sjfv "not granted.\n"); 917230775Sjfv } 918230775Sjfv 919230775Sjfv return status; 920230775Sjfv} 921230775Sjfv 922230775Sjfv/** 923283620Serj * ixgbe_release_swfw_sync_semaphore - Release hardware semaphore 924230775Sjfv * @hw: pointer to hardware structure 925230775Sjfv * 926230775Sjfv * This function clears hardware semaphore bits. 927230775Sjfv **/ 928230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) 929230775Sjfv{ 930230775Sjfv u32 swsm; 931230775Sjfv 932230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_semaphore"); 933230775Sjfv 934230775Sjfv /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ 935230775Sjfv 936295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw)); 937283620Serj swsm &= ~IXGBE_SWFW_REGSMP; 938295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm); 939283620Serj 940295524Ssbruno swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw)); 941230775Sjfv swsm &= ~IXGBE_SWSM_SMBI; 942295524Ssbruno IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm); 943230775Sjfv 944230775Sjfv IXGBE_WRITE_FLUSH(hw); 945230775Sjfv} 946230775Sjfv 947230775Sjfv/** 948230775Sjfv * ixgbe_blink_led_start_X540 - Blink LED based on index. 949230775Sjfv * @hw: pointer to hardware structure 950230775Sjfv * @index: led number to blink 951230775Sjfv * 952230775Sjfv * Devices that implement the version 2 interface: 953230775Sjfv * X540 954230775Sjfv **/ 955230775Sjfvs32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) 956230775Sjfv{ 957230775Sjfv u32 macc_reg; 958230775Sjfv u32 ledctl_reg; 959230775Sjfv ixgbe_link_speed speed; 960230775Sjfv bool link_up; 961230775Sjfv 962230775Sjfv DEBUGFUNC("ixgbe_blink_led_start_X540"); 963230775Sjfv 964230775Sjfv /* 965230775Sjfv * Link should be up in order for the blink bit in the LED control 966230775Sjfv * register to work. Force link and speed in the MAC if link is down. 967230775Sjfv * This will be reversed when we stop the blinking. 968230775Sjfv */ 969230775Sjfv hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 970230775Sjfv if (link_up == FALSE) { 971230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 972230775Sjfv macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; 973230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 974230775Sjfv } 975230775Sjfv /* Set the LED to LINK_UP + BLINK. */ 976230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 977230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 978230775Sjfv ledctl_reg |= IXGBE_LED_BLINK(index); 979230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 980230775Sjfv IXGBE_WRITE_FLUSH(hw); 981230775Sjfv 982230775Sjfv return IXGBE_SUCCESS; 983230775Sjfv} 984230775Sjfv 985230775Sjfv/** 986230775Sjfv * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index. 987230775Sjfv * @hw: pointer to hardware structure 988230775Sjfv * @index: led number to stop blinking 989230775Sjfv * 990230775Sjfv * Devices that implement the version 2 interface: 991230775Sjfv * X540 992230775Sjfv **/ 993230775Sjfvs32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) 994230775Sjfv{ 995230775Sjfv u32 macc_reg; 996230775Sjfv u32 ledctl_reg; 997230775Sjfv 998230775Sjfv DEBUGFUNC("ixgbe_blink_led_stop_X540"); 999230775Sjfv 1000230775Sjfv /* Restore the LED to its default value. */ 1001230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 1002230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 1003230775Sjfv ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 1004230775Sjfv ledctl_reg &= ~IXGBE_LED_BLINK(index); 1005230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 1006230775Sjfv 1007230775Sjfv /* Unforce link and speed in the MAC. */ 1008230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 1009230775Sjfv macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS); 1010230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 1011230775Sjfv IXGBE_WRITE_FLUSH(hw); 1012230775Sjfv 1013230775Sjfv return IXGBE_SUCCESS; 1014230775Sjfv} 1015