ixgbe_x540.c revision 251964
1230775Sjfv/****************************************************************************** 2230775Sjfv 3247822Sjfv Copyright (c) 2001-2013, 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 251964 2013-06-18 21:28:19Z 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_poll_flash_update_done_X540(struct ixgbe_hw *hw); 42230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); 43230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); 44230775Sjfv 45230775Sjfv/** 46230775Sjfv * ixgbe_init_ops_X540 - Inits func ptrs and MAC type 47230775Sjfv * @hw: pointer to hardware structure 48230775Sjfv * 49230775Sjfv * Initialize the function pointers and assign the MAC type for X540. 50230775Sjfv * Does not touch the hardware. 51230775Sjfv **/ 52230775Sjfvs32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) 53230775Sjfv{ 54230775Sjfv struct ixgbe_mac_info *mac = &hw->mac; 55230775Sjfv struct ixgbe_phy_info *phy = &hw->phy; 56230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 57230775Sjfv s32 ret_val; 58230775Sjfv 59230775Sjfv DEBUGFUNC("ixgbe_init_ops_X540"); 60230775Sjfv 61230775Sjfv ret_val = ixgbe_init_phy_ops_generic(hw); 62230775Sjfv ret_val = ixgbe_init_ops_generic(hw); 63230775Sjfv 64230775Sjfv 65230775Sjfv /* EEPROM */ 66230775Sjfv eeprom->ops.init_params = &ixgbe_init_eeprom_params_X540; 67230775Sjfv eeprom->ops.read = &ixgbe_read_eerd_X540; 68230775Sjfv eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_X540; 69230775Sjfv eeprom->ops.write = &ixgbe_write_eewr_X540; 70230775Sjfv eeprom->ops.write_buffer = &ixgbe_write_eewr_buffer_X540; 71230775Sjfv eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_X540; 72230775Sjfv eeprom->ops.validate_checksum = &ixgbe_validate_eeprom_checksum_X540; 73230775Sjfv eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_X540; 74230775Sjfv 75230775Sjfv /* PHY */ 76230775Sjfv phy->ops.init = &ixgbe_init_phy_ops_generic; 77230775Sjfv phy->ops.reset = NULL; 78230775Sjfv 79230775Sjfv /* MAC */ 80230775Sjfv mac->ops.reset_hw = &ixgbe_reset_hw_X540; 81230775Sjfv mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_gen2; 82230775Sjfv mac->ops.get_media_type = &ixgbe_get_media_type_X540; 83230775Sjfv mac->ops.get_supported_physical_layer = 84230775Sjfv &ixgbe_get_supported_physical_layer_X540; 85230775Sjfv mac->ops.read_analog_reg8 = NULL; 86230775Sjfv mac->ops.write_analog_reg8 = NULL; 87230775Sjfv mac->ops.start_hw = &ixgbe_start_hw_X540; 88230775Sjfv mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic; 89230775Sjfv mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic; 90230775Sjfv mac->ops.get_device_caps = &ixgbe_get_device_caps_generic; 91230775Sjfv mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic; 92230775Sjfv mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic; 93230775Sjfv mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540; 94230775Sjfv mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync_X540; 95230775Sjfv mac->ops.disable_sec_rx_path = &ixgbe_disable_sec_rx_path_generic; 96230775Sjfv mac->ops.enable_sec_rx_path = &ixgbe_enable_sec_rx_path_generic; 97230775Sjfv 98230775Sjfv /* RAR, Multicast, VLAN */ 99230775Sjfv mac->ops.set_vmdq = &ixgbe_set_vmdq_generic; 100238149Sjfv mac->ops.set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic; 101230775Sjfv mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic; 102230775Sjfv mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic; 103230775Sjfv mac->rar_highwater = 1; 104230775Sjfv mac->ops.set_vfta = &ixgbe_set_vfta_generic; 105230775Sjfv mac->ops.set_vlvf = &ixgbe_set_vlvf_generic; 106230775Sjfv mac->ops.clear_vfta = &ixgbe_clear_vfta_generic; 107230775Sjfv mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic; 108230775Sjfv mac->ops.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing; 109230775Sjfv mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing; 110230775Sjfv 111230775Sjfv /* Link */ 112230775Sjfv mac->ops.get_link_capabilities = 113230775Sjfv &ixgbe_get_copper_link_capabilities_generic; 114230775Sjfv mac->ops.setup_link = &ixgbe_setup_mac_link_X540; 115230775Sjfv mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic; 116230775Sjfv mac->ops.check_link = &ixgbe_check_mac_link_generic; 117230775Sjfv 118247822Sjfv 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 144251964Sjfv mac->ops.get_rtrup2tc = &ixgbe_dcb_get_rtrup2tc_generic; 145251964Sjfv 146230775Sjfv return ret_val; 147230775Sjfv} 148230775Sjfv 149230775Sjfv/** 150230775Sjfv * ixgbe_get_link_capabilities_X540 - Determines link capabilities 151230775Sjfv * @hw: pointer to hardware structure 152230775Sjfv * @speed: pointer to link speed 153230775Sjfv * @autoneg: TRUE when autoneg or autotry is enabled 154230775Sjfv * 155230775Sjfv * Determines the link capabilities by reading the AUTOC register. 156230775Sjfv **/ 157230775Sjfvs32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, 158230775Sjfv ixgbe_link_speed *speed, 159230775Sjfv bool *autoneg) 160230775Sjfv{ 161230775Sjfv ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg); 162230775Sjfv 163230775Sjfv return IXGBE_SUCCESS; 164230775Sjfv} 165230775Sjfv 166230775Sjfv/** 167230775Sjfv * ixgbe_get_media_type_X540 - Get media type 168230775Sjfv * @hw: pointer to hardware structure 169230775Sjfv * 170230775Sjfv * Returns the media type (fiber, copper, backplane) 171230775Sjfv **/ 172230775Sjfvenum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) 173230775Sjfv{ 174230775Sjfv UNREFERENCED_1PARAMETER(hw); 175230775Sjfv return ixgbe_media_type_copper; 176230775Sjfv} 177230775Sjfv 178230775Sjfv/** 179230775Sjfv * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities 180230775Sjfv * @hw: pointer to hardware structure 181230775Sjfv * @speed: new link speed 182230775Sjfv * @autoneg_wait_to_complete: TRUE when waiting for completion is needed 183230775Sjfv **/ 184230775Sjfvs32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, 185247822Sjfv ixgbe_link_speed speed, 186230775Sjfv bool autoneg_wait_to_complete) 187230775Sjfv{ 188230775Sjfv DEBUGFUNC("ixgbe_setup_mac_link_X540"); 189247822Sjfv return hw->phy.ops.setup_link_speed(hw, speed, 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; 230251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 231251964Sjfv "Reset polling failed to complete.\n"); 232230775Sjfv } 233230775Sjfv msec_delay(100); 234230775Sjfv 235230775Sjfv /* 236230775Sjfv * Double resets are required for recovery from certain error 237230775Sjfv * conditions. Between resets, it is necessary to stall to allow time 238230775Sjfv * for any pending HW events to complete. 239230775Sjfv */ 240230775Sjfv if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { 241230775Sjfv hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 242230775Sjfv goto mac_reset_top; 243230775Sjfv } 244230775Sjfv 245230775Sjfv /* Set the Rx packet buffer size. */ 246230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); 247230775Sjfv 248230775Sjfv /* Store the permanent mac address */ 249230775Sjfv hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); 250230775Sjfv 251230775Sjfv /* 252230775Sjfv * Store MAC address from RAR0, clear receive address registers, and 253230775Sjfv * clear the multicast table. Also reset num_rar_entries to 128, 254230775Sjfv * since we modify this value when programming the SAN MAC address. 255230775Sjfv */ 256230775Sjfv hw->mac.num_rar_entries = 128; 257230775Sjfv hw->mac.ops.init_rx_addrs(hw); 258230775Sjfv 259230775Sjfv /* Store the permanent SAN mac address */ 260230775Sjfv hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); 261230775Sjfv 262230775Sjfv /* Add the SAN MAC address to the RAR only if it's a valid address */ 263230775Sjfv if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { 264230775Sjfv hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, 265230775Sjfv hw->mac.san_addr, 0, IXGBE_RAH_AV); 266230775Sjfv 267238149Sjfv /* Save the SAN MAC RAR index */ 268238149Sjfv hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; 269238149Sjfv 270230775Sjfv /* Reserve the last RAR for the SAN MAC address */ 271230775Sjfv hw->mac.num_rar_entries--; 272230775Sjfv } 273230775Sjfv 274230775Sjfv /* Store the alternative WWNN/WWPN prefix */ 275230775Sjfv hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, 276230775Sjfv &hw->mac.wwpn_prefix); 277230775Sjfv 278230775Sjfvreset_hw_out: 279230775Sjfv return status; 280230775Sjfv} 281230775Sjfv 282230775Sjfv/** 283230775Sjfv * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx 284230775Sjfv * @hw: pointer to hardware structure 285230775Sjfv * 286230775Sjfv * Starts the hardware using the generic start_hw function 287230775Sjfv * and the generation start_hw function. 288230775Sjfv * Then performs revision-specific operations, if any. 289230775Sjfv **/ 290230775Sjfvs32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) 291230775Sjfv{ 292230775Sjfv s32 ret_val = IXGBE_SUCCESS; 293230775Sjfv 294230775Sjfv DEBUGFUNC("ixgbe_start_hw_X540"); 295230775Sjfv 296230775Sjfv ret_val = ixgbe_start_hw_generic(hw); 297230775Sjfv if (ret_val != IXGBE_SUCCESS) 298230775Sjfv goto out; 299230775Sjfv 300230775Sjfv ret_val = ixgbe_start_hw_gen2(hw); 301230775Sjfv 302230775Sjfvout: 303230775Sjfv return ret_val; 304230775Sjfv} 305230775Sjfv 306230775Sjfv/** 307230775Sjfv * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type 308230775Sjfv * @hw: pointer to hardware structure 309230775Sjfv * 310230775Sjfv * Determines physical layer capabilities of the current configuration. 311230775Sjfv **/ 312230775Sjfvu32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) 313230775Sjfv{ 314230775Sjfv u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; 315230775Sjfv u16 ext_ability = 0; 316230775Sjfv 317230775Sjfv DEBUGFUNC("ixgbe_get_supported_physical_layer_X540"); 318230775Sjfv 319230775Sjfv hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, 320230775Sjfv IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); 321230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) 322230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; 323230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) 324230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; 325230775Sjfv if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) 326230775Sjfv physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; 327230775Sjfv 328230775Sjfv return physical_layer; 329230775Sjfv} 330230775Sjfv 331230775Sjfv/** 332230775Sjfv * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params 333230775Sjfv * @hw: pointer to hardware structure 334230775Sjfv * 335230775Sjfv * Initializes the EEPROM parameters ixgbe_eeprom_info within the 336230775Sjfv * ixgbe_hw struct in order to set up EEPROM access. 337230775Sjfv **/ 338230775Sjfvs32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) 339230775Sjfv{ 340230775Sjfv struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 341230775Sjfv u32 eec; 342230775Sjfv u16 eeprom_size; 343230775Sjfv 344230775Sjfv DEBUGFUNC("ixgbe_init_eeprom_params_X540"); 345230775Sjfv 346230775Sjfv if (eeprom->type == ixgbe_eeprom_uninitialized) { 347230775Sjfv eeprom->semaphore_delay = 10; 348230775Sjfv eeprom->type = ixgbe_flash; 349230775Sjfv 350230775Sjfv eec = IXGBE_READ_REG(hw, IXGBE_EEC); 351230775Sjfv eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 352230775Sjfv IXGBE_EEC_SIZE_SHIFT); 353230775Sjfv eeprom->word_size = 1 << (eeprom_size + 354230775Sjfv IXGBE_EEPROM_WORD_SIZE_SHIFT); 355230775Sjfv 356230775Sjfv DEBUGOUT2("Eeprom params: type = %d, size = %d\n", 357230775Sjfv eeprom->type, eeprom->word_size); 358230775Sjfv } 359230775Sjfv 360230775Sjfv return IXGBE_SUCCESS; 361230775Sjfv} 362230775Sjfv 363230775Sjfv/** 364230775Sjfv * ixgbe_read_eerd_X540- Read EEPROM word using EERD 365230775Sjfv * @hw: pointer to hardware structure 366230775Sjfv * @offset: offset of word in the EEPROM to read 367230775Sjfv * @data: word read from the EEPROM 368230775Sjfv * 369230775Sjfv * Reads a 16 bit word from the EEPROM using the EERD register. 370230775Sjfv **/ 371230775Sjfvs32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) 372230775Sjfv{ 373230775Sjfv s32 status = IXGBE_SUCCESS; 374230775Sjfv 375230775Sjfv DEBUGFUNC("ixgbe_read_eerd_X540"); 376230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 377251964Sjfv IXGBE_SUCCESS) { 378230775Sjfv status = ixgbe_read_eerd_generic(hw, offset, data); 379251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 380251964Sjfv } else { 381230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 382251964Sjfv } 383230775Sjfv 384230775Sjfv return status; 385230775Sjfv} 386230775Sjfv 387230775Sjfv/** 388230775Sjfv * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD 389230775Sjfv * @hw: pointer to hardware structure 390230775Sjfv * @offset: offset of word in the EEPROM to read 391230775Sjfv * @words: number of words 392230775Sjfv * @data: word(s) read from the EEPROM 393230775Sjfv * 394230775Sjfv * Reads a 16 bit word(s) from the EEPROM using the EERD register. 395230775Sjfv **/ 396230775Sjfvs32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, 397230775Sjfv u16 offset, u16 words, u16 *data) 398230775Sjfv{ 399230775Sjfv s32 status = IXGBE_SUCCESS; 400230775Sjfv 401230775Sjfv DEBUGFUNC("ixgbe_read_eerd_buffer_X540"); 402230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 403251964Sjfv IXGBE_SUCCESS) { 404230775Sjfv status = ixgbe_read_eerd_buffer_generic(hw, offset, 405230775Sjfv words, data); 406251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 407251964Sjfv } else { 408230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 409251964Sjfv } 410230775Sjfv 411230775Sjfv return status; 412230775Sjfv} 413230775Sjfv 414230775Sjfv/** 415230775Sjfv * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR 416230775Sjfv * @hw: pointer to hardware structure 417230775Sjfv * @offset: offset of word in the EEPROM to write 418230775Sjfv * @data: word write to the EEPROM 419230775Sjfv * 420230775Sjfv * Write a 16 bit word to the EEPROM using the EEWR register. 421230775Sjfv **/ 422230775Sjfvs32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) 423230775Sjfv{ 424230775Sjfv s32 status = IXGBE_SUCCESS; 425230775Sjfv 426230775Sjfv DEBUGFUNC("ixgbe_write_eewr_X540"); 427230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 428251964Sjfv IXGBE_SUCCESS) { 429230775Sjfv status = ixgbe_write_eewr_generic(hw, offset, data); 430251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 431251964Sjfv } else { 432230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 433251964Sjfv } 434230775Sjfv 435230775Sjfv return status; 436230775Sjfv} 437230775Sjfv 438230775Sjfv/** 439230775Sjfv * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR 440230775Sjfv * @hw: pointer to hardware structure 441230775Sjfv * @offset: offset of word in the EEPROM to write 442230775Sjfv * @words: number of words 443230775Sjfv * @data: word(s) write to the EEPROM 444230775Sjfv * 445230775Sjfv * Write a 16 bit word(s) to the EEPROM using the EEWR register. 446230775Sjfv **/ 447230775Sjfvs32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, 448230775Sjfv u16 offset, u16 words, u16 *data) 449230775Sjfv{ 450230775Sjfv s32 status = IXGBE_SUCCESS; 451230775Sjfv 452230775Sjfv DEBUGFUNC("ixgbe_write_eewr_buffer_X540"); 453230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 454251964Sjfv IXGBE_SUCCESS) { 455230775Sjfv status = ixgbe_write_eewr_buffer_generic(hw, offset, 456230775Sjfv words, data); 457251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 458251964Sjfv } else { 459230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 460251964Sjfv } 461230775Sjfv 462230775Sjfv return status; 463230775Sjfv} 464230775Sjfv 465230775Sjfv/** 466230775Sjfv * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum 467230775Sjfv * 468230775Sjfv * This function does not use synchronization for EERD and EEWR. It can 469230775Sjfv * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. 470230775Sjfv * 471230775Sjfv * @hw: pointer to hardware structure 472230775Sjfv **/ 473230775Sjfvu16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) 474230775Sjfv{ 475230775Sjfv u16 i; 476230775Sjfv u16 j; 477230775Sjfv u16 checksum = 0; 478230775Sjfv u16 length = 0; 479230775Sjfv u16 pointer = 0; 480230775Sjfv u16 word = 0; 481230775Sjfv 482230775Sjfv /* 483230775Sjfv * Do not use hw->eeprom.ops.read because we do not want to take 484230775Sjfv * the synchronization semaphores here. Instead use 485230775Sjfv * ixgbe_read_eerd_generic 486230775Sjfv */ 487230775Sjfv 488230775Sjfv DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540"); 489230775Sjfv 490230775Sjfv /* Include 0x0-0x3F in the checksum */ 491230775Sjfv for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 492230775Sjfv if (ixgbe_read_eerd_generic(hw, i, &word) != IXGBE_SUCCESS) { 493230775Sjfv DEBUGOUT("EEPROM read failed\n"); 494230775Sjfv break; 495230775Sjfv } 496230775Sjfv checksum += word; 497230775Sjfv } 498230775Sjfv 499230775Sjfv /* 500230775Sjfv * Include all data from pointers 0x3, 0x6-0xE. This excludes the 501230775Sjfv * FW, PHY module, and PCIe Expansion/Option ROM pointers. 502230775Sjfv */ 503230775Sjfv for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 504230775Sjfv if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 505230775Sjfv continue; 506230775Sjfv 507230775Sjfv if (ixgbe_read_eerd_generic(hw, i, &pointer) != IXGBE_SUCCESS) { 508230775Sjfv DEBUGOUT("EEPROM read failed\n"); 509230775Sjfv break; 510230775Sjfv } 511230775Sjfv 512230775Sjfv /* Skip pointer section if the pointer is invalid. */ 513230775Sjfv if (pointer == 0xFFFF || pointer == 0 || 514230775Sjfv pointer >= hw->eeprom.word_size) 515230775Sjfv continue; 516230775Sjfv 517230775Sjfv if (ixgbe_read_eerd_generic(hw, pointer, &length) != 518230775Sjfv IXGBE_SUCCESS) { 519230775Sjfv DEBUGOUT("EEPROM read failed\n"); 520230775Sjfv break; 521230775Sjfv } 522230775Sjfv 523230775Sjfv /* Skip pointer section if length is invalid. */ 524230775Sjfv if (length == 0xFFFF || length == 0 || 525230775Sjfv (pointer + length) >= hw->eeprom.word_size) 526230775Sjfv continue; 527230775Sjfv 528230775Sjfv for (j = pointer+1; j <= pointer+length; j++) { 529230775Sjfv if (ixgbe_read_eerd_generic(hw, j, &word) != 530230775Sjfv IXGBE_SUCCESS) { 531230775Sjfv DEBUGOUT("EEPROM read failed\n"); 532230775Sjfv break; 533230775Sjfv } 534230775Sjfv checksum += word; 535230775Sjfv } 536230775Sjfv } 537230775Sjfv 538230775Sjfv checksum = (u16)IXGBE_EEPROM_SUM - checksum; 539230775Sjfv 540230775Sjfv return checksum; 541230775Sjfv} 542230775Sjfv 543230775Sjfv/** 544230775Sjfv * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum 545230775Sjfv * @hw: pointer to hardware structure 546230775Sjfv * @checksum_val: calculated checksum 547230775Sjfv * 548230775Sjfv * Performs checksum calculation and validates the EEPROM checksum. If the 549230775Sjfv * caller does not need checksum_val, the value can be NULL. 550230775Sjfv **/ 551230775Sjfvs32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, 552230775Sjfv u16 *checksum_val) 553230775Sjfv{ 554230775Sjfv s32 status; 555230775Sjfv u16 checksum; 556230775Sjfv u16 read_checksum = 0; 557230775Sjfv 558230775Sjfv DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540"); 559230775Sjfv 560230775Sjfv /* 561230775Sjfv * Read the first word from the EEPROM. If this times out or fails, do 562230775Sjfv * not continue or we could be in for a very long wait while every 563230775Sjfv * EEPROM read fails 564230775Sjfv */ 565230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 566230775Sjfv 567230775Sjfv if (status != IXGBE_SUCCESS) { 568230775Sjfv DEBUGOUT("EEPROM read failed\n"); 569230775Sjfv goto out; 570230775Sjfv } 571230775Sjfv 572230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 573230775Sjfv IXGBE_SUCCESS) { 574230775Sjfv checksum = hw->eeprom.ops.calc_checksum(hw); 575230775Sjfv 576230775Sjfv /* 577230775Sjfv * Do not use hw->eeprom.ops.read because we do not want to take 578230775Sjfv * the synchronization semaphores twice here. 579230775Sjfv */ 580230775Sjfv ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, 581230775Sjfv &read_checksum); 582230775Sjfv 583230775Sjfv /* 584230775Sjfv * Verify read checksum from EEPROM is the same as 585230775Sjfv * calculated checksum 586230775Sjfv */ 587251964Sjfv if (read_checksum != checksum) { 588230775Sjfv status = IXGBE_ERR_EEPROM_CHECKSUM; 589251964Sjfv ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, 590251964Sjfv "Invalid EEPROM checksum"); 591251964Sjfv } 592230775Sjfv 593230775Sjfv /* If the user cares, return the calculated checksum */ 594230775Sjfv if (checksum_val) 595230775Sjfv *checksum_val = checksum; 596251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 597230775Sjfv } else { 598230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 599230775Sjfv } 600230775Sjfv 601230775Sjfvout: 602230775Sjfv return status; 603230775Sjfv} 604230775Sjfv 605230775Sjfv/** 606230775Sjfv * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash 607230775Sjfv * @hw: pointer to hardware structure 608230775Sjfv * 609230775Sjfv * After writing EEPROM to shadow RAM using EEWR register, software calculates 610230775Sjfv * checksum and updates the EEPROM and instructs the hardware to update 611230775Sjfv * the flash. 612230775Sjfv **/ 613230775Sjfvs32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) 614230775Sjfv{ 615230775Sjfv s32 status; 616230775Sjfv u16 checksum; 617230775Sjfv 618230775Sjfv DEBUGFUNC("ixgbe_update_eeprom_checksum_X540"); 619230775Sjfv 620230775Sjfv /* 621230775Sjfv * Read the first word from the EEPROM. If this times out or fails, do 622230775Sjfv * not continue or we could be in for a very long wait while every 623230775Sjfv * EEPROM read fails 624230775Sjfv */ 625230775Sjfv status = hw->eeprom.ops.read(hw, 0, &checksum); 626230775Sjfv 627230775Sjfv if (status != IXGBE_SUCCESS) 628230775Sjfv DEBUGOUT("EEPROM read failed\n"); 629230775Sjfv 630230775Sjfv if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 631230775Sjfv IXGBE_SUCCESS) { 632230775Sjfv checksum = hw->eeprom.ops.calc_checksum(hw); 633230775Sjfv 634230775Sjfv /* 635230775Sjfv * Do not use hw->eeprom.ops.write because we do not want to 636230775Sjfv * take the synchronization semaphores twice here. 637230775Sjfv */ 638230775Sjfv status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, 639230775Sjfv checksum); 640230775Sjfv 641251964Sjfv if (status == IXGBE_SUCCESS) 642251964Sjfv status = ixgbe_update_flash_X540(hw); 643251964Sjfv hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 644251964Sjfv } else { 645230775Sjfv status = IXGBE_ERR_SWFW_SYNC; 646230775Sjfv } 647230775Sjfv 648230775Sjfv return status; 649230775Sjfv} 650230775Sjfv 651230775Sjfv/** 652230775Sjfv * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device 653230775Sjfv * @hw: pointer to hardware structure 654230775Sjfv * 655230775Sjfv * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy 656230775Sjfv * EEPROM from shadow RAM to the flash device. 657230775Sjfv **/ 658251964Sjfvs32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) 659230775Sjfv{ 660230775Sjfv u32 flup; 661230775Sjfv s32 status = IXGBE_ERR_EEPROM; 662230775Sjfv 663230775Sjfv DEBUGFUNC("ixgbe_update_flash_X540"); 664230775Sjfv 665230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 666230775Sjfv if (status == IXGBE_ERR_EEPROM) { 667230775Sjfv DEBUGOUT("Flash update time out\n"); 668230775Sjfv goto out; 669230775Sjfv } 670230775Sjfv 671230775Sjfv flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP; 672230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); 673230775Sjfv 674230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 675230775Sjfv if (status == IXGBE_SUCCESS) 676230775Sjfv DEBUGOUT("Flash update complete\n"); 677230775Sjfv else 678230775Sjfv DEBUGOUT("Flash update time out\n"); 679230775Sjfv 680251964Sjfv if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) { 681230775Sjfv flup = IXGBE_READ_REG(hw, IXGBE_EEC); 682230775Sjfv 683230775Sjfv if (flup & IXGBE_EEC_SEC1VAL) { 684230775Sjfv flup |= IXGBE_EEC_FLUP; 685230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); 686230775Sjfv } 687230775Sjfv 688230775Sjfv status = ixgbe_poll_flash_update_done_X540(hw); 689230775Sjfv if (status == IXGBE_SUCCESS) 690230775Sjfv DEBUGOUT("Flash update complete\n"); 691230775Sjfv else 692230775Sjfv DEBUGOUT("Flash update time out\n"); 693230775Sjfv } 694230775Sjfvout: 695230775Sjfv return status; 696230775Sjfv} 697230775Sjfv 698230775Sjfv/** 699230775Sjfv * ixgbe_poll_flash_update_done_X540 - Poll flash update status 700230775Sjfv * @hw: pointer to hardware structure 701230775Sjfv * 702230775Sjfv * Polls the FLUDONE (bit 26) of the EEC Register to determine when the 703230775Sjfv * flash update is done. 704230775Sjfv **/ 705230775Sjfvstatic s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) 706230775Sjfv{ 707230775Sjfv u32 i; 708230775Sjfv u32 reg; 709230775Sjfv s32 status = IXGBE_ERR_EEPROM; 710230775Sjfv 711230775Sjfv DEBUGFUNC("ixgbe_poll_flash_update_done_X540"); 712230775Sjfv 713230775Sjfv for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { 714230775Sjfv reg = IXGBE_READ_REG(hw, IXGBE_EEC); 715230775Sjfv if (reg & IXGBE_EEC_FLUDONE) { 716230775Sjfv status = IXGBE_SUCCESS; 717230775Sjfv break; 718230775Sjfv } 719230775Sjfv usec_delay(5); 720230775Sjfv } 721251964Sjfv 722251964Sjfv if (i == IXGBE_FLUDONE_ATTEMPTS) 723251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 724251964Sjfv "Flash update status polling timed out"); 725251964Sjfv 726230775Sjfv return status; 727230775Sjfv} 728230775Sjfv 729230775Sjfv/** 730230775Sjfv * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore 731230775Sjfv * @hw: pointer to hardware structure 732230775Sjfv * @mask: Mask to specify which semaphore to acquire 733230775Sjfv * 734230775Sjfv * Acquires the SWFW semaphore thought the SW_FW_SYNC register for 735230775Sjfv * the specified function (CSR, PHY0, PHY1, NVM, Flash) 736230775Sjfv **/ 737230775Sjfvs32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) 738230775Sjfv{ 739230775Sjfv u32 swfw_sync; 740230775Sjfv u32 swmask = mask; 741230775Sjfv u32 fwmask = mask << 5; 742230775Sjfv u32 hwmask = 0; 743230775Sjfv u32 timeout = 200; 744230775Sjfv u32 i; 745230775Sjfv s32 ret_val = IXGBE_SUCCESS; 746230775Sjfv 747230775Sjfv DEBUGFUNC("ixgbe_acquire_swfw_sync_X540"); 748230775Sjfv 749230775Sjfv if (swmask == IXGBE_GSSR_EEP_SM) 750230775Sjfv hwmask = IXGBE_GSSR_FLASH_SM; 751230775Sjfv 752230775Sjfv /* SW only mask doesn't have FW bit pair */ 753230775Sjfv if (swmask == IXGBE_GSSR_SW_MNG_SM) 754230775Sjfv fwmask = 0; 755230775Sjfv 756230775Sjfv for (i = 0; i < timeout; i++) { 757230775Sjfv /* 758230775Sjfv * SW NVM semaphore bit is used for access to all 759230775Sjfv * SW_FW_SYNC bits (not just NVM) 760230775Sjfv */ 761230775Sjfv if (ixgbe_get_swfw_sync_semaphore(hw)) { 762230775Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 763230775Sjfv goto out; 764230775Sjfv } 765230775Sjfv 766230775Sjfv swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 767230775Sjfv if (!(swfw_sync & (fwmask | swmask | hwmask))) { 768230775Sjfv swfw_sync |= swmask; 769230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); 770230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 771230775Sjfv goto out; 772230775Sjfv } else { 773230775Sjfv /* 774230775Sjfv * Firmware currently using resource (fwmask), hardware 775230775Sjfv * currently using resource (hwmask), or other software 776230775Sjfv * thread currently using resource (swmask) 777230775Sjfv */ 778230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 779230775Sjfv msec_delay(5); 780230775Sjfv } 781230775Sjfv } 782230775Sjfv 783230775Sjfv /* Failed to get SW only semaphore */ 784230775Sjfv if (swmask == IXGBE_GSSR_SW_MNG_SM) { 785230775Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 786251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 787251964Sjfv "Failed to get SW only semaphore"); 788230775Sjfv goto out; 789230775Sjfv } 790230775Sjfv 791230775Sjfv /* If the resource is not released by the FW/HW the SW can assume that 792251964Sjfv * the FW/HW malfunctions. In that case the SW should set the SW bit(s) 793230775Sjfv * of the requested resource(s) while ignoring the corresponding FW/HW 794230775Sjfv * bits in the SW_FW_SYNC register. 795230775Sjfv */ 796230775Sjfv swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 797230775Sjfv if (swfw_sync & (fwmask | hwmask)) { 798230775Sjfv if (ixgbe_get_swfw_sync_semaphore(hw)) { 799230775Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 800230775Sjfv goto out; 801230775Sjfv } 802230775Sjfv 803230775Sjfv swfw_sync |= swmask; 804230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); 805230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 806230775Sjfv msec_delay(5); 807230775Sjfv } 808251964Sjfv /* If the resource is not released by other SW the SW can assume that 809251964Sjfv * the other SW malfunctions. In that case the SW should clear all SW 810251964Sjfv * flags that it does not own and then repeat the whole process once 811251964Sjfv * again. 812251964Sjfv */ 813251964Sjfv else if (swfw_sync & swmask) { 814251964Sjfv ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM | 815251964Sjfv IXGBE_GSSR_PHY0_SM | IXGBE_GSSR_PHY1_SM | 816251964Sjfv IXGBE_GSSR_MAC_CSR_SM); 817251964Sjfv ret_val = IXGBE_ERR_SWFW_SYNC; 818251964Sjfv } 819230775Sjfv 820230775Sjfvout: 821230775Sjfv return ret_val; 822230775Sjfv} 823230775Sjfv 824230775Sjfv/** 825230775Sjfv * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore 826230775Sjfv * @hw: pointer to hardware structure 827230775Sjfv * @mask: Mask to specify which semaphore to release 828230775Sjfv * 829238149Sjfv * Releases the SWFW semaphore through the SW_FW_SYNC register 830230775Sjfv * for the specified function (CSR, PHY0, PHY1, EVM, Flash) 831230775Sjfv **/ 832230775Sjfvvoid ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) 833230775Sjfv{ 834230775Sjfv u32 swfw_sync; 835230775Sjfv u32 swmask = mask; 836230775Sjfv 837230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_X540"); 838230775Sjfv 839230775Sjfv ixgbe_get_swfw_sync_semaphore(hw); 840230775Sjfv 841230775Sjfv swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 842230775Sjfv swfw_sync &= ~swmask; 843230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); 844230775Sjfv 845230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 846230775Sjfv} 847230775Sjfv 848230775Sjfv/** 849230775Sjfv * ixgbe_get_nvm_semaphore - Get hardware semaphore 850230775Sjfv * @hw: pointer to hardware structure 851230775Sjfv * 852230775Sjfv * Sets the hardware semaphores so SW/FW can gain control of shared resources 853230775Sjfv **/ 854230775Sjfvstatic s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) 855230775Sjfv{ 856230775Sjfv s32 status = IXGBE_ERR_EEPROM; 857230775Sjfv u32 timeout = 2000; 858230775Sjfv u32 i; 859230775Sjfv u32 swsm; 860230775Sjfv 861230775Sjfv DEBUGFUNC("ixgbe_get_swfw_sync_semaphore"); 862230775Sjfv 863230775Sjfv /* Get SMBI software semaphore between device drivers first */ 864230775Sjfv for (i = 0; i < timeout; i++) { 865230775Sjfv /* 866230775Sjfv * If the SMBI bit is 0 when we read it, then the bit will be 867230775Sjfv * set and we have the semaphore 868230775Sjfv */ 869230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 870230775Sjfv if (!(swsm & IXGBE_SWSM_SMBI)) { 871230775Sjfv status = IXGBE_SUCCESS; 872230775Sjfv break; 873230775Sjfv } 874230775Sjfv usec_delay(50); 875230775Sjfv } 876230775Sjfv 877230775Sjfv /* Now get the semaphore between SW/FW through the REGSMP bit */ 878230775Sjfv if (status == IXGBE_SUCCESS) { 879230775Sjfv for (i = 0; i < timeout; i++) { 880230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 881230775Sjfv if (!(swsm & IXGBE_SWFW_REGSMP)) 882230775Sjfv break; 883230775Sjfv 884230775Sjfv usec_delay(50); 885230775Sjfv } 886230775Sjfv 887230775Sjfv /* 888230775Sjfv * Release semaphores and return error if SW NVM semaphore 889230775Sjfv * was not granted because we don't have access to the EEPROM 890230775Sjfv */ 891230775Sjfv if (i >= timeout) { 892251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 893251964Sjfv "REGSMP Software NVM semaphore not granted.\n"); 894230775Sjfv ixgbe_release_swfw_sync_semaphore(hw); 895230775Sjfv status = IXGBE_ERR_EEPROM; 896230775Sjfv } 897230775Sjfv } else { 898251964Sjfv ERROR_REPORT1(IXGBE_ERROR_POLLING, 899251964Sjfv "Software semaphore SMBI between device drivers " 900251964Sjfv "not granted.\n"); 901230775Sjfv } 902230775Sjfv 903230775Sjfv return status; 904230775Sjfv} 905230775Sjfv 906230775Sjfv/** 907230775Sjfv * ixgbe_release_nvm_semaphore - Release hardware semaphore 908230775Sjfv * @hw: pointer to hardware structure 909230775Sjfv * 910230775Sjfv * This function clears hardware semaphore bits. 911230775Sjfv **/ 912230775Sjfvstatic void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) 913230775Sjfv{ 914230775Sjfv u32 swsm; 915230775Sjfv 916230775Sjfv DEBUGFUNC("ixgbe_release_swfw_sync_semaphore"); 917230775Sjfv 918230775Sjfv /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ 919230775Sjfv 920230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 921230775Sjfv swsm &= ~IXGBE_SWSM_SMBI; 922230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 923230775Sjfv 924230775Sjfv swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); 925230775Sjfv swsm &= ~IXGBE_SWFW_REGSMP; 926230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm); 927230775Sjfv 928230775Sjfv IXGBE_WRITE_FLUSH(hw); 929230775Sjfv} 930230775Sjfv 931230775Sjfv/** 932230775Sjfv * ixgbe_blink_led_start_X540 - Blink LED based on index. 933230775Sjfv * @hw: pointer to hardware structure 934230775Sjfv * @index: led number to blink 935230775Sjfv * 936230775Sjfv * Devices that implement the version 2 interface: 937230775Sjfv * X540 938230775Sjfv **/ 939230775Sjfvs32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) 940230775Sjfv{ 941230775Sjfv u32 macc_reg; 942230775Sjfv u32 ledctl_reg; 943230775Sjfv ixgbe_link_speed speed; 944230775Sjfv bool link_up; 945230775Sjfv 946230775Sjfv DEBUGFUNC("ixgbe_blink_led_start_X540"); 947230775Sjfv 948230775Sjfv /* 949230775Sjfv * Link should be up in order for the blink bit in the LED control 950230775Sjfv * register to work. Force link and speed in the MAC if link is down. 951230775Sjfv * This will be reversed when we stop the blinking. 952230775Sjfv */ 953230775Sjfv hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 954230775Sjfv if (link_up == FALSE) { 955230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 956230775Sjfv macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; 957230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 958230775Sjfv } 959230775Sjfv /* Set the LED to LINK_UP + BLINK. */ 960230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 961230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 962230775Sjfv ledctl_reg |= IXGBE_LED_BLINK(index); 963230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 964230775Sjfv IXGBE_WRITE_FLUSH(hw); 965230775Sjfv 966230775Sjfv return IXGBE_SUCCESS; 967230775Sjfv} 968230775Sjfv 969230775Sjfv/** 970230775Sjfv * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index. 971230775Sjfv * @hw: pointer to hardware structure 972230775Sjfv * @index: led number to stop blinking 973230775Sjfv * 974230775Sjfv * Devices that implement the version 2 interface: 975230775Sjfv * X540 976230775Sjfv **/ 977230775Sjfvs32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) 978230775Sjfv{ 979230775Sjfv u32 macc_reg; 980230775Sjfv u32 ledctl_reg; 981230775Sjfv 982230775Sjfv DEBUGFUNC("ixgbe_blink_led_stop_X540"); 983230775Sjfv 984230775Sjfv /* Restore the LED to its default value. */ 985230775Sjfv ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 986230775Sjfv ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); 987230775Sjfv ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 988230775Sjfv ledctl_reg &= ~IXGBE_LED_BLINK(index); 989230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); 990230775Sjfv 991230775Sjfv /* Unforce link and speed in the MAC. */ 992230775Sjfv macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); 993230775Sjfv macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS); 994230775Sjfv IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); 995230775Sjfv IXGBE_WRITE_FLUSH(hw); 996230775Sjfv 997230775Sjfv return IXGBE_SUCCESS; 998230775Sjfv} 999230775Sjfv 1000247822Sjfv 1001