169b5a878SDan McDonald /******************************************************************************
2*48ed61a7SRobert Mustacchi SPDX-License-Identifier: BSD-3-Clause
369b5a878SDan McDonald
4*48ed61a7SRobert Mustacchi Copyright (c) 2001-2017, Intel Corporation
569b5a878SDan McDonald All rights reserved.
6*48ed61a7SRobert Mustacchi
7*48ed61a7SRobert Mustacchi Redistribution and use in source and binary forms, with or without
869b5a878SDan McDonald modification, are permitted provided that the following conditions are met:
9*48ed61a7SRobert Mustacchi
10*48ed61a7SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice,
1169b5a878SDan McDonald this list of conditions and the following disclaimer.
12*48ed61a7SRobert Mustacchi
13*48ed61a7SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright
14*48ed61a7SRobert Mustacchi notice, this list of conditions and the following disclaimer in the
1569b5a878SDan McDonald documentation and/or other materials provided with the distribution.
16*48ed61a7SRobert Mustacchi
17*48ed61a7SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its
18*48ed61a7SRobert Mustacchi contributors may be used to endorse or promote products derived from
1969b5a878SDan McDonald this software without specific prior written permission.
20*48ed61a7SRobert Mustacchi
2169b5a878SDan McDonald THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22*48ed61a7SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*48ed61a7SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*48ed61a7SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25*48ed61a7SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26*48ed61a7SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27*48ed61a7SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28*48ed61a7SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29*48ed61a7SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3069b5a878SDan McDonald ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3169b5a878SDan McDonald POSSIBILITY OF SUCH DAMAGE.
3269b5a878SDan McDonald
3369b5a878SDan McDonald ******************************************************************************/
34dc0cb1cdSDale Ghent /*$FreeBSD$*/
3569b5a878SDan McDonald
3669b5a878SDan McDonald #include "ixgbe_x540.h"
3769b5a878SDan McDonald #include "ixgbe_type.h"
3869b5a878SDan McDonald #include "ixgbe_api.h"
3969b5a878SDan McDonald #include "ixgbe_common.h"
4069b5a878SDan McDonald #include "ixgbe_phy.h"
4169b5a878SDan McDonald
42dc0cb1cdSDale Ghent #define IXGBE_X540_MAX_TX_QUEUES 128
43dc0cb1cdSDale Ghent #define IXGBE_X540_MAX_RX_QUEUES 128
44dc0cb1cdSDale Ghent #define IXGBE_X540_RAR_ENTRIES 128
45dc0cb1cdSDale Ghent #define IXGBE_X540_MC_TBL_SIZE 128
46dc0cb1cdSDale Ghent #define IXGBE_X540_VFT_TBL_SIZE 128
47dc0cb1cdSDale Ghent #define IXGBE_X540_RX_PB_SIZE 384
48dc0cb1cdSDale Ghent
4969b5a878SDan McDonald static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
5069b5a878SDan McDonald static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
5169b5a878SDan McDonald static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
5269b5a878SDan McDonald
5369b5a878SDan McDonald /**
5469b5a878SDan McDonald * ixgbe_init_ops_X540 - Inits func ptrs and MAC type
5569b5a878SDan McDonald * @hw: pointer to hardware structure
5669b5a878SDan McDonald *
5769b5a878SDan McDonald * Initialize the function pointers and assign the MAC type for X540.
5869b5a878SDan McDonald * Does not touch the hardware.
5969b5a878SDan McDonald **/
ixgbe_init_ops_X540(struct ixgbe_hw * hw)6069b5a878SDan McDonald s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
6169b5a878SDan McDonald {
6269b5a878SDan McDonald struct ixgbe_mac_info *mac = &hw->mac;
6369b5a878SDan McDonald struct ixgbe_phy_info *phy = &hw->phy;
6469b5a878SDan McDonald struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
6569b5a878SDan McDonald s32 ret_val;
6669b5a878SDan McDonald
6769b5a878SDan McDonald DEBUGFUNC("ixgbe_init_ops_X540");
6869b5a878SDan McDonald
6969b5a878SDan McDonald ret_val = ixgbe_init_phy_ops_generic(hw);
7069b5a878SDan McDonald ret_val = ixgbe_init_ops_generic(hw);
7169b5a878SDan McDonald
7269b5a878SDan McDonald
7369b5a878SDan McDonald /* EEPROM */
74dc0cb1cdSDale Ghent eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
75dc0cb1cdSDale Ghent eeprom->ops.read = ixgbe_read_eerd_X540;
76dc0cb1cdSDale Ghent eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_X540;
77dc0cb1cdSDale Ghent eeprom->ops.write = ixgbe_write_eewr_X540;
78dc0cb1cdSDale Ghent eeprom->ops.write_buffer = ixgbe_write_eewr_buffer_X540;
79dc0cb1cdSDale Ghent eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X540;
80dc0cb1cdSDale Ghent eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X540;
81dc0cb1cdSDale Ghent eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X540;
8269b5a878SDan McDonald
8369b5a878SDan McDonald /* PHY */
84dc0cb1cdSDale Ghent phy->ops.init = ixgbe_init_phy_ops_generic;
8569b5a878SDan McDonald phy->ops.reset = NULL;
86dc0cb1cdSDale Ghent phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
8769b5a878SDan McDonald
8869b5a878SDan McDonald /* MAC */
89dc0cb1cdSDale Ghent mac->ops.reset_hw = ixgbe_reset_hw_X540;
90dc0cb1cdSDale Ghent mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_gen2;
91dc0cb1cdSDale Ghent mac->ops.get_media_type = ixgbe_get_media_type_X540;
9269b5a878SDan McDonald mac->ops.get_supported_physical_layer =
93dc0cb1cdSDale Ghent ixgbe_get_supported_physical_layer_X540;
9469b5a878SDan McDonald mac->ops.read_analog_reg8 = NULL;
9569b5a878SDan McDonald mac->ops.write_analog_reg8 = NULL;
96dc0cb1cdSDale Ghent mac->ops.start_hw = ixgbe_start_hw_X540;
97dc0cb1cdSDale Ghent mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic;
98dc0cb1cdSDale Ghent mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic;
99dc0cb1cdSDale Ghent mac->ops.get_device_caps = ixgbe_get_device_caps_generic;
100dc0cb1cdSDale Ghent mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic;
101dc0cb1cdSDale Ghent mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic;
102dc0cb1cdSDale Ghent mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540;
103dc0cb1cdSDale Ghent mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540;
104*48ed61a7SRobert Mustacchi mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540;
105dc0cb1cdSDale Ghent mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
106dc0cb1cdSDale Ghent mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
10769b5a878SDan McDonald
10869b5a878SDan McDonald /* RAR, Multicast, VLAN */
109dc0cb1cdSDale Ghent mac->ops.set_vmdq = ixgbe_set_vmdq_generic;
110dc0cb1cdSDale Ghent mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic;
111dc0cb1cdSDale Ghent mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic;
112dc0cb1cdSDale Ghent mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic;
11369b5a878SDan McDonald mac->rar_highwater = 1;
114dc0cb1cdSDale Ghent mac->ops.set_vfta = ixgbe_set_vfta_generic;
115dc0cb1cdSDale Ghent mac->ops.set_vlvf = ixgbe_set_vlvf_generic;
116dc0cb1cdSDale Ghent mac->ops.clear_vfta = ixgbe_clear_vfta_generic;
117dc0cb1cdSDale Ghent mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic;
118dc0cb1cdSDale Ghent mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing;
119dc0cb1cdSDale Ghent mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing;
12069b5a878SDan McDonald
12169b5a878SDan McDonald /* Link */
12269b5a878SDan McDonald mac->ops.get_link_capabilities =
123dc0cb1cdSDale Ghent ixgbe_get_copper_link_capabilities_generic;
124dc0cb1cdSDale Ghent mac->ops.setup_link = ixgbe_setup_mac_link_X540;
125dc0cb1cdSDale Ghent mac->ops.setup_rxpba = ixgbe_set_rxpba_generic;
126dc0cb1cdSDale Ghent mac->ops.check_link = ixgbe_check_mac_link_generic;
127*48ed61a7SRobert Mustacchi mac->ops.bypass_rw = ixgbe_bypass_rw_generic;
128*48ed61a7SRobert Mustacchi mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic;
129*48ed61a7SRobert Mustacchi mac->ops.bypass_set = ixgbe_bypass_set_generic;
130*48ed61a7SRobert Mustacchi mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic;
131dc0cb1cdSDale Ghent
132dc0cb1cdSDale Ghent
133dc0cb1cdSDale Ghent mac->mcft_size = IXGBE_X540_MC_TBL_SIZE;
134dc0cb1cdSDale Ghent mac->vft_size = IXGBE_X540_VFT_TBL_SIZE;
135dc0cb1cdSDale Ghent mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES;
136dc0cb1cdSDale Ghent mac->rx_pb_size = IXGBE_X540_RX_PB_SIZE;
137dc0cb1cdSDale Ghent mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES;
138dc0cb1cdSDale Ghent mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES;
13969b5a878SDan McDonald mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
14069b5a878SDan McDonald
14169b5a878SDan McDonald /*
14269b5a878SDan McDonald * FWSM register
14369b5a878SDan McDonald * ARC supported; valid only if manageability features are
14469b5a878SDan McDonald * enabled.
14569b5a878SDan McDonald */
146dc0cb1cdSDale Ghent mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
147dc0cb1cdSDale Ghent & IXGBE_FWSM_MODE_MASK);
14869b5a878SDan McDonald
14969b5a878SDan McDonald hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
15069b5a878SDan McDonald
15169b5a878SDan McDonald /* LEDs */
15269b5a878SDan McDonald mac->ops.blink_led_start = ixgbe_blink_led_start_X540;
15369b5a878SDan McDonald mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540;
15469b5a878SDan McDonald
15569b5a878SDan McDonald /* Manageability interface */
156dc0cb1cdSDale Ghent mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic;
157dc0cb1cdSDale Ghent
158dc0cb1cdSDale Ghent mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
15969b5a878SDan McDonald
16069b5a878SDan McDonald return ret_val;
16169b5a878SDan McDonald }
16269b5a878SDan McDonald
16369b5a878SDan McDonald /**
16469b5a878SDan McDonald * ixgbe_get_link_capabilities_X540 - Determines link capabilities
16569b5a878SDan McDonald * @hw: pointer to hardware structure
16669b5a878SDan McDonald * @speed: pointer to link speed
16769b5a878SDan McDonald * @autoneg: TRUE when autoneg or autotry is enabled
16869b5a878SDan McDonald *
16969b5a878SDan McDonald * Determines the link capabilities by reading the AUTOC register.
17069b5a878SDan McDonald **/
ixgbe_get_link_capabilities_X540(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)17169b5a878SDan McDonald s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
17269b5a878SDan McDonald ixgbe_link_speed *speed,
17369b5a878SDan McDonald bool *autoneg)
17469b5a878SDan McDonald {
175dc0cb1cdSDale Ghent ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg);
176dc0cb1cdSDale Ghent
177dc0cb1cdSDale Ghent return IXGBE_SUCCESS;
17869b5a878SDan McDonald }
17969b5a878SDan McDonald
18069b5a878SDan McDonald /**
18169b5a878SDan McDonald * ixgbe_get_media_type_X540 - Get media type
18269b5a878SDan McDonald * @hw: pointer to hardware structure
18369b5a878SDan McDonald *
18469b5a878SDan McDonald * Returns the media type (fiber, copper, backplane)
18569b5a878SDan McDonald **/
ixgbe_get_media_type_X540(struct ixgbe_hw * hw)18669b5a878SDan McDonald enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
18769b5a878SDan McDonald {
18869b5a878SDan McDonald UNREFERENCED_1PARAMETER(hw);
18969b5a878SDan McDonald return ixgbe_media_type_copper;
19069b5a878SDan McDonald }
19169b5a878SDan McDonald
19269b5a878SDan McDonald /**
19369b5a878SDan McDonald * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
19469b5a878SDan McDonald * @hw: pointer to hardware structure
19569b5a878SDan McDonald * @speed: new link speed
19669b5a878SDan McDonald * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
19769b5a878SDan McDonald **/
ixgbe_setup_mac_link_X540(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)19869b5a878SDan McDonald s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
199dc0cb1cdSDale Ghent ixgbe_link_speed speed,
20069b5a878SDan McDonald bool autoneg_wait_to_complete)
20169b5a878SDan McDonald {
20269b5a878SDan McDonald DEBUGFUNC("ixgbe_setup_mac_link_X540");
203dc0cb1cdSDale Ghent return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
20469b5a878SDan McDonald }
20569b5a878SDan McDonald
20669b5a878SDan McDonald /**
20769b5a878SDan McDonald * ixgbe_reset_hw_X540 - Perform hardware reset
20869b5a878SDan McDonald * @hw: pointer to hardware structure
20969b5a878SDan McDonald *
21069b5a878SDan McDonald * Resets the hardware by resetting the transmit and receive units, masks
21169b5a878SDan McDonald * and clears all interrupts, and perform a reset.
21269b5a878SDan McDonald **/
ixgbe_reset_hw_X540(struct ixgbe_hw * hw)21369b5a878SDan McDonald s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
21469b5a878SDan McDonald {
21569b5a878SDan McDonald s32 status;
21669b5a878SDan McDonald u32 ctrl, i;
217*48ed61a7SRobert Mustacchi u32 swfw_mask = hw->phy.phy_semaphore_mask;
21869b5a878SDan McDonald
21969b5a878SDan McDonald DEBUGFUNC("ixgbe_reset_hw_X540");
22069b5a878SDan McDonald
22169b5a878SDan McDonald /* Call adapter stop to disable tx/rx and clear interrupts */
22269b5a878SDan McDonald status = hw->mac.ops.stop_adapter(hw);
22369b5a878SDan McDonald if (status != IXGBE_SUCCESS)
22469b5a878SDan McDonald goto reset_hw_out;
22569b5a878SDan McDonald
22669b5a878SDan McDonald /* flush pending Tx transactions */
22769b5a878SDan McDonald ixgbe_clear_tx_pending(hw);
22869b5a878SDan McDonald
22969b5a878SDan McDonald mac_reset_top:
230*48ed61a7SRobert Mustacchi status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
231*48ed61a7SRobert Mustacchi if (status != IXGBE_SUCCESS) {
232*48ed61a7SRobert Mustacchi ERROR_REPORT2(IXGBE_ERROR_CAUTION,
233*48ed61a7SRobert Mustacchi "semaphore failed with %d", status);
234*48ed61a7SRobert Mustacchi return IXGBE_ERR_SWFW_SYNC;
235*48ed61a7SRobert Mustacchi }
23669b5a878SDan McDonald ctrl = IXGBE_CTRL_RST;
23769b5a878SDan McDonald ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
23869b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
23969b5a878SDan McDonald IXGBE_WRITE_FLUSH(hw);
240*48ed61a7SRobert Mustacchi hw->mac.ops.release_swfw_sync(hw, swfw_mask);
24169b5a878SDan McDonald
24269b5a878SDan McDonald /* Poll for reset bit to self-clear indicating reset is complete */
24369b5a878SDan McDonald for (i = 0; i < 10; i++) {
24469b5a878SDan McDonald usec_delay(1);
24569b5a878SDan McDonald ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
24669b5a878SDan McDonald if (!(ctrl & IXGBE_CTRL_RST_MASK))
24769b5a878SDan McDonald break;
24869b5a878SDan McDonald }
24969b5a878SDan McDonald
25069b5a878SDan McDonald if (ctrl & IXGBE_CTRL_RST_MASK) {
25169b5a878SDan McDonald status = IXGBE_ERR_RESET_FAILED;
252dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_POLLING,
253dc0cb1cdSDale Ghent "Reset polling failed to complete.\n");
25469b5a878SDan McDonald }
25569b5a878SDan McDonald msec_delay(100);
25669b5a878SDan McDonald
25769b5a878SDan McDonald /*
25869b5a878SDan McDonald * Double resets are required for recovery from certain error
25969b5a878SDan McDonald * conditions. Between resets, it is necessary to stall to allow time
26069b5a878SDan McDonald * for any pending HW events to complete.
26169b5a878SDan McDonald */
26269b5a878SDan McDonald if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
26369b5a878SDan McDonald hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
26469b5a878SDan McDonald goto mac_reset_top;
26569b5a878SDan McDonald }
26669b5a878SDan McDonald
26769b5a878SDan McDonald /* Set the Rx packet buffer size. */
26869b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
26969b5a878SDan McDonald
27069b5a878SDan McDonald /* Store the permanent mac address */
27169b5a878SDan McDonald hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
27269b5a878SDan McDonald
27369b5a878SDan McDonald /*
27469b5a878SDan McDonald * Store MAC address from RAR0, clear receive address registers, and
27569b5a878SDan McDonald * clear the multicast table. Also reset num_rar_entries to 128,
27669b5a878SDan McDonald * since we modify this value when programming the SAN MAC address.
27769b5a878SDan McDonald */
27869b5a878SDan McDonald hw->mac.num_rar_entries = 128;
27969b5a878SDan McDonald hw->mac.ops.init_rx_addrs(hw);
28069b5a878SDan McDonald
28169b5a878SDan McDonald /* Store the permanent SAN mac address */
28269b5a878SDan McDonald hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
28369b5a878SDan McDonald
28469b5a878SDan McDonald /* Add the SAN MAC address to the RAR only if it's a valid address */
28569b5a878SDan McDonald if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
28669b5a878SDan McDonald /* Save the SAN MAC RAR index */
28769b5a878SDan McDonald hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
28869b5a878SDan McDonald
289*48ed61a7SRobert Mustacchi hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
290*48ed61a7SRobert Mustacchi hw->mac.san_addr, 0, IXGBE_RAH_AV);
291*48ed61a7SRobert Mustacchi
292*48ed61a7SRobert Mustacchi /* clear VMDq pool/queue selection for this RAR */
293*48ed61a7SRobert Mustacchi hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
294*48ed61a7SRobert Mustacchi IXGBE_CLEAR_VMDQ_ALL);
295*48ed61a7SRobert Mustacchi
29669b5a878SDan McDonald /* Reserve the last RAR for the SAN MAC address */
29769b5a878SDan McDonald hw->mac.num_rar_entries--;
29869b5a878SDan McDonald }
29969b5a878SDan McDonald
30069b5a878SDan McDonald /* Store the alternative WWNN/WWPN prefix */
30169b5a878SDan McDonald hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
30269b5a878SDan McDonald &hw->mac.wwpn_prefix);
30369b5a878SDan McDonald
30469b5a878SDan McDonald reset_hw_out:
30569b5a878SDan McDonald return status;
30669b5a878SDan McDonald }
30769b5a878SDan McDonald
30869b5a878SDan McDonald /**
30969b5a878SDan McDonald * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
31069b5a878SDan McDonald * @hw: pointer to hardware structure
31169b5a878SDan McDonald *
31269b5a878SDan McDonald * Starts the hardware using the generic start_hw function
31369b5a878SDan McDonald * and the generation start_hw function.
31469b5a878SDan McDonald * Then performs revision-specific operations, if any.
31569b5a878SDan McDonald **/
ixgbe_start_hw_X540(struct ixgbe_hw * hw)31669b5a878SDan McDonald s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
31769b5a878SDan McDonald {
31869b5a878SDan McDonald s32 ret_val = IXGBE_SUCCESS;
31969b5a878SDan McDonald
32069b5a878SDan McDonald DEBUGFUNC("ixgbe_start_hw_X540");
32169b5a878SDan McDonald
32269b5a878SDan McDonald ret_val = ixgbe_start_hw_generic(hw);
32369b5a878SDan McDonald if (ret_val != IXGBE_SUCCESS)
32469b5a878SDan McDonald goto out;
32569b5a878SDan McDonald
32669b5a878SDan McDonald ret_val = ixgbe_start_hw_gen2(hw);
32769b5a878SDan McDonald
32869b5a878SDan McDonald out:
32969b5a878SDan McDonald return ret_val;
33069b5a878SDan McDonald }
33169b5a878SDan McDonald
33269b5a878SDan McDonald /**
33369b5a878SDan McDonald * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
33469b5a878SDan McDonald * @hw: pointer to hardware structure
33569b5a878SDan McDonald *
33669b5a878SDan McDonald * Determines physical layer capabilities of the current configuration.
33769b5a878SDan McDonald **/
ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw * hw)338*48ed61a7SRobert Mustacchi u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
33969b5a878SDan McDonald {
340*48ed61a7SRobert Mustacchi u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
34169b5a878SDan McDonald u16 ext_ability = 0;
34269b5a878SDan McDonald
34369b5a878SDan McDonald DEBUGFUNC("ixgbe_get_supported_physical_layer_X540");
34469b5a878SDan McDonald
34569b5a878SDan McDonald hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
34669b5a878SDan McDonald IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
34769b5a878SDan McDonald if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
34869b5a878SDan McDonald physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
34969b5a878SDan McDonald if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
35069b5a878SDan McDonald physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
35169b5a878SDan McDonald if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
35269b5a878SDan McDonald physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
35369b5a878SDan McDonald
35469b5a878SDan McDonald return physical_layer;
35569b5a878SDan McDonald }
35669b5a878SDan McDonald
35769b5a878SDan McDonald /**
35869b5a878SDan McDonald * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
35969b5a878SDan McDonald * @hw: pointer to hardware structure
36069b5a878SDan McDonald *
36169b5a878SDan McDonald * Initializes the EEPROM parameters ixgbe_eeprom_info within the
36269b5a878SDan McDonald * ixgbe_hw struct in order to set up EEPROM access.
36369b5a878SDan McDonald **/
ixgbe_init_eeprom_params_X540(struct ixgbe_hw * hw)36469b5a878SDan McDonald s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
36569b5a878SDan McDonald {
36669b5a878SDan McDonald struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
36769b5a878SDan McDonald u32 eec;
36869b5a878SDan McDonald u16 eeprom_size;
36969b5a878SDan McDonald
37069b5a878SDan McDonald DEBUGFUNC("ixgbe_init_eeprom_params_X540");
37169b5a878SDan McDonald
37269b5a878SDan McDonald if (eeprom->type == ixgbe_eeprom_uninitialized) {
37369b5a878SDan McDonald eeprom->semaphore_delay = 10;
37469b5a878SDan McDonald eeprom->type = ixgbe_flash;
37569b5a878SDan McDonald
376dc0cb1cdSDale Ghent eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
37769b5a878SDan McDonald eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
37869b5a878SDan McDonald IXGBE_EEC_SIZE_SHIFT);
37969b5a878SDan McDonald eeprom->word_size = 1 << (eeprom_size +
38069b5a878SDan McDonald IXGBE_EEPROM_WORD_SIZE_SHIFT);
38169b5a878SDan McDonald
38269b5a878SDan McDonald DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
38369b5a878SDan McDonald eeprom->type, eeprom->word_size);
38469b5a878SDan McDonald }
38569b5a878SDan McDonald
38669b5a878SDan McDonald return IXGBE_SUCCESS;
38769b5a878SDan McDonald }
38869b5a878SDan McDonald
38969b5a878SDan McDonald /**
39069b5a878SDan McDonald * ixgbe_read_eerd_X540- Read EEPROM word using EERD
39169b5a878SDan McDonald * @hw: pointer to hardware structure
39269b5a878SDan McDonald * @offset: offset of word in the EEPROM to read
39369b5a878SDan McDonald * @data: word read from the EEPROM
39469b5a878SDan McDonald *
39569b5a878SDan McDonald * Reads a 16 bit word from the EEPROM using the EERD register.
39669b5a878SDan McDonald **/
ixgbe_read_eerd_X540(struct ixgbe_hw * hw,u16 offset,u16 * data)39769b5a878SDan McDonald s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
39869b5a878SDan McDonald {
39969b5a878SDan McDonald s32 status = IXGBE_SUCCESS;
40069b5a878SDan McDonald
40169b5a878SDan McDonald DEBUGFUNC("ixgbe_read_eerd_X540");
40269b5a878SDan McDonald if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
403dc0cb1cdSDale Ghent IXGBE_SUCCESS) {
40469b5a878SDan McDonald status = ixgbe_read_eerd_generic(hw, offset, data);
405dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
406dc0cb1cdSDale Ghent } else {
40769b5a878SDan McDonald status = IXGBE_ERR_SWFW_SYNC;
408dc0cb1cdSDale Ghent }
40969b5a878SDan McDonald
41069b5a878SDan McDonald return status;
41169b5a878SDan McDonald }
41269b5a878SDan McDonald
41369b5a878SDan McDonald /**
41469b5a878SDan McDonald * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD
41569b5a878SDan McDonald * @hw: pointer to hardware structure
41669b5a878SDan McDonald * @offset: offset of word in the EEPROM to read
41769b5a878SDan McDonald * @words: number of words
41869b5a878SDan McDonald * @data: word(s) read from the EEPROM
41969b5a878SDan McDonald *
42069b5a878SDan McDonald * Reads a 16 bit word(s) from the EEPROM using the EERD register.
42169b5a878SDan McDonald **/
ixgbe_read_eerd_buffer_X540(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)42269b5a878SDan McDonald s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
42369b5a878SDan McDonald u16 offset, u16 words, u16 *data)
42469b5a878SDan McDonald {
42569b5a878SDan McDonald s32 status = IXGBE_SUCCESS;
42669b5a878SDan McDonald
42769b5a878SDan McDonald DEBUGFUNC("ixgbe_read_eerd_buffer_X540");
42869b5a878SDan McDonald if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
429dc0cb1cdSDale Ghent IXGBE_SUCCESS) {
43069b5a878SDan McDonald status = ixgbe_read_eerd_buffer_generic(hw, offset,
43169b5a878SDan McDonald words, data);
432dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
433dc0cb1cdSDale Ghent } else {
43469b5a878SDan McDonald status = IXGBE_ERR_SWFW_SYNC;
435dc0cb1cdSDale Ghent }
43669b5a878SDan McDonald
43769b5a878SDan McDonald return status;
43869b5a878SDan McDonald }
43969b5a878SDan McDonald
44069b5a878SDan McDonald /**
44169b5a878SDan McDonald * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
44269b5a878SDan McDonald * @hw: pointer to hardware structure
44369b5a878SDan McDonald * @offset: offset of word in the EEPROM to write
44469b5a878SDan McDonald * @data: word write to the EEPROM
44569b5a878SDan McDonald *
44669b5a878SDan McDonald * Write a 16 bit word to the EEPROM using the EEWR register.
44769b5a878SDan McDonald **/
ixgbe_write_eewr_X540(struct ixgbe_hw * hw,u16 offset,u16 data)44869b5a878SDan McDonald s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
44969b5a878SDan McDonald {
45069b5a878SDan McDonald s32 status = IXGBE_SUCCESS;
45169b5a878SDan McDonald
45269b5a878SDan McDonald DEBUGFUNC("ixgbe_write_eewr_X540");
45369b5a878SDan McDonald if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
454dc0cb1cdSDale Ghent IXGBE_SUCCESS) {
45569b5a878SDan McDonald status = ixgbe_write_eewr_generic(hw, offset, data);
456dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
457dc0cb1cdSDale Ghent } else {
45869b5a878SDan McDonald status = IXGBE_ERR_SWFW_SYNC;
459dc0cb1cdSDale Ghent }
46069b5a878SDan McDonald
46169b5a878SDan McDonald return status;
46269b5a878SDan McDonald }
46369b5a878SDan McDonald
46469b5a878SDan McDonald /**
46569b5a878SDan McDonald * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
46669b5a878SDan McDonald * @hw: pointer to hardware structure
46769b5a878SDan McDonald * @offset: offset of word in the EEPROM to write
46869b5a878SDan McDonald * @words: number of words
46969b5a878SDan McDonald * @data: word(s) write to the EEPROM
47069b5a878SDan McDonald *
47169b5a878SDan McDonald * Write a 16 bit word(s) to the EEPROM using the EEWR register.
47269b5a878SDan McDonald **/
ixgbe_write_eewr_buffer_X540(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)47369b5a878SDan McDonald s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
47469b5a878SDan McDonald u16 offset, u16 words, u16 *data)
47569b5a878SDan McDonald {
47669b5a878SDan McDonald s32 status = IXGBE_SUCCESS;
47769b5a878SDan McDonald
47869b5a878SDan McDonald DEBUGFUNC("ixgbe_write_eewr_buffer_X540");
47969b5a878SDan McDonald if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
480dc0cb1cdSDale Ghent IXGBE_SUCCESS) {
48169b5a878SDan McDonald status = ixgbe_write_eewr_buffer_generic(hw, offset,
48269b5a878SDan McDonald words, data);
483dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
484dc0cb1cdSDale Ghent } else {
48569b5a878SDan McDonald status = IXGBE_ERR_SWFW_SYNC;
486dc0cb1cdSDale Ghent }
48769b5a878SDan McDonald
48869b5a878SDan McDonald return status;
48969b5a878SDan McDonald }
49069b5a878SDan McDonald
49169b5a878SDan McDonald /**
49269b5a878SDan McDonald * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
49369b5a878SDan McDonald *
49469b5a878SDan McDonald * This function does not use synchronization for EERD and EEWR. It can
49569b5a878SDan McDonald * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
49669b5a878SDan McDonald *
49769b5a878SDan McDonald * @hw: pointer to hardware structure
498dc0cb1cdSDale Ghent *
499dc0cb1cdSDale Ghent * Returns a negative error code on error, or the 16-bit checksum
50069b5a878SDan McDonald **/
ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw * hw)501dc0cb1cdSDale Ghent s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
50269b5a878SDan McDonald {
503dc0cb1cdSDale Ghent u16 i, j;
50469b5a878SDan McDonald u16 checksum = 0;
50569b5a878SDan McDonald u16 length = 0;
50669b5a878SDan McDonald u16 pointer = 0;
50769b5a878SDan McDonald u16 word = 0;
508dc0cb1cdSDale Ghent u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
50969b5a878SDan McDonald
510dc0cb1cdSDale Ghent /* Do not use hw->eeprom.ops.read because we do not want to take
51169b5a878SDan McDonald * the synchronization semaphores here. Instead use
51269b5a878SDan McDonald * ixgbe_read_eerd_generic
51369b5a878SDan McDonald */
51469b5a878SDan McDonald
51569b5a878SDan McDonald DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
51669b5a878SDan McDonald
517*48ed61a7SRobert Mustacchi /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the
518*48ed61a7SRobert Mustacchi * checksum itself
519*48ed61a7SRobert Mustacchi */
520*48ed61a7SRobert Mustacchi for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
521dc0cb1cdSDale Ghent if (ixgbe_read_eerd_generic(hw, i, &word)) {
52269b5a878SDan McDonald DEBUGOUT("EEPROM read failed\n");
523dc0cb1cdSDale Ghent return IXGBE_ERR_EEPROM;
52469b5a878SDan McDonald }
525*48ed61a7SRobert Mustacchi checksum += word;
52669b5a878SDan McDonald }
52769b5a878SDan McDonald
528dc0cb1cdSDale Ghent /* Include all data from pointers 0x3, 0x6-0xE. This excludes the
52969b5a878SDan McDonald * FW, PHY module, and PCIe Expansion/Option ROM pointers.
53069b5a878SDan McDonald */
531dc0cb1cdSDale Ghent for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
53269b5a878SDan McDonald if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
53369b5a878SDan McDonald continue;
53469b5a878SDan McDonald
535dc0cb1cdSDale Ghent if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
53669b5a878SDan McDonald DEBUGOUT("EEPROM read failed\n");
537dc0cb1cdSDale Ghent return IXGBE_ERR_EEPROM;
53869b5a878SDan McDonald }
53969b5a878SDan McDonald
54069b5a878SDan McDonald /* Skip pointer section if the pointer is invalid. */
54169b5a878SDan McDonald if (pointer == 0xFFFF || pointer == 0 ||
54269b5a878SDan McDonald pointer >= hw->eeprom.word_size)
54369b5a878SDan McDonald continue;
54469b5a878SDan McDonald
545dc0cb1cdSDale Ghent if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
54669b5a878SDan McDonald DEBUGOUT("EEPROM read failed\n");
547dc0cb1cdSDale Ghent return IXGBE_ERR_EEPROM;
54869b5a878SDan McDonald }
54969b5a878SDan McDonald
55069b5a878SDan McDonald /* Skip pointer section if length is invalid. */
55169b5a878SDan McDonald if (length == 0xFFFF || length == 0 ||
55269b5a878SDan McDonald (pointer + length) >= hw->eeprom.word_size)
55369b5a878SDan McDonald continue;
55469b5a878SDan McDonald
555dc0cb1cdSDale Ghent for (j = pointer + 1; j <= pointer + length; j++) {
556dc0cb1cdSDale Ghent if (ixgbe_read_eerd_generic(hw, j, &word)) {
55769b5a878SDan McDonald DEBUGOUT("EEPROM read failed\n");
558dc0cb1cdSDale Ghent return IXGBE_ERR_EEPROM;
55969b5a878SDan McDonald }
56069b5a878SDan McDonald checksum += word;
56169b5a878SDan McDonald }
56269b5a878SDan McDonald }
56369b5a878SDan McDonald
56469b5a878SDan McDonald checksum = (u16)IXGBE_EEPROM_SUM - checksum;
56569b5a878SDan McDonald
566dc0cb1cdSDale Ghent return (s32)checksum;
56769b5a878SDan McDonald }
56869b5a878SDan McDonald
56969b5a878SDan McDonald /**
57069b5a878SDan McDonald * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
57169b5a878SDan McDonald * @hw: pointer to hardware structure
57269b5a878SDan McDonald * @checksum_val: calculated checksum
57369b5a878SDan McDonald *
57469b5a878SDan McDonald * Performs checksum calculation and validates the EEPROM checksum. If the
57569b5a878SDan McDonald * caller does not need checksum_val, the value can be NULL.
57669b5a878SDan McDonald **/
ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw * hw,u16 * checksum_val)57769b5a878SDan McDonald s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
57869b5a878SDan McDonald u16 *checksum_val)
57969b5a878SDan McDonald {
58069b5a878SDan McDonald s32 status;
58169b5a878SDan McDonald u16 checksum;
58269b5a878SDan McDonald u16 read_checksum = 0;
58369b5a878SDan McDonald
58469b5a878SDan McDonald DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540");
58569b5a878SDan McDonald
586dc0cb1cdSDale Ghent /* Read the first word from the EEPROM. If this times out or fails, do
58769b5a878SDan McDonald * not continue or we could be in for a very long wait while every
58869b5a878SDan McDonald * EEPROM read fails
58969b5a878SDan McDonald */
59069b5a878SDan McDonald status = hw->eeprom.ops.read(hw, 0, &checksum);
591dc0cb1cdSDale Ghent if (status) {
59269b5a878SDan McDonald DEBUGOUT("EEPROM read failed\n");
593dc0cb1cdSDale Ghent return status;
59469b5a878SDan McDonald }
59569b5a878SDan McDonald
596dc0cb1cdSDale Ghent if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
597dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
59869b5a878SDan McDonald
599dc0cb1cdSDale Ghent status = hw->eeprom.ops.calc_checksum(hw);
600dc0cb1cdSDale Ghent if (status < 0)
601dc0cb1cdSDale Ghent goto out;
602dc0cb1cdSDale Ghent
603dc0cb1cdSDale Ghent checksum = (u16)(status & 0xffff);
604dc0cb1cdSDale Ghent
605dc0cb1cdSDale Ghent /* Do not use hw->eeprom.ops.read because we do not want to take
606dc0cb1cdSDale Ghent * the synchronization semaphores twice here.
607dc0cb1cdSDale Ghent */
608dc0cb1cdSDale Ghent status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
609dc0cb1cdSDale Ghent &read_checksum);
610dc0cb1cdSDale Ghent if (status)
611dc0cb1cdSDale Ghent goto out;
612dc0cb1cdSDale Ghent
613dc0cb1cdSDale Ghent /* Verify read checksum from EEPROM is the same as
614dc0cb1cdSDale Ghent * calculated checksum
615dc0cb1cdSDale Ghent */
616dc0cb1cdSDale Ghent if (read_checksum != checksum) {
617dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
618dc0cb1cdSDale Ghent "Invalid EEPROM checksum");
619dc0cb1cdSDale Ghent status = IXGBE_ERR_EEPROM_CHECKSUM;
62069b5a878SDan McDonald }
62169b5a878SDan McDonald
622dc0cb1cdSDale Ghent /* If the user cares, return the calculated checksum */
623dc0cb1cdSDale Ghent if (checksum_val)
624dc0cb1cdSDale Ghent *checksum_val = checksum;
625dc0cb1cdSDale Ghent
62669b5a878SDan McDonald out:
627dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
628dc0cb1cdSDale Ghent
62969b5a878SDan McDonald return status;
63069b5a878SDan McDonald }
63169b5a878SDan McDonald
63269b5a878SDan McDonald /**
63369b5a878SDan McDonald * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
63469b5a878SDan McDonald * @hw: pointer to hardware structure
63569b5a878SDan McDonald *
63669b5a878SDan McDonald * After writing EEPROM to shadow RAM using EEWR register, software calculates
63769b5a878SDan McDonald * checksum and updates the EEPROM and instructs the hardware to update
63869b5a878SDan McDonald * the flash.
63969b5a878SDan McDonald **/
ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw * hw)64069b5a878SDan McDonald s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
64169b5a878SDan McDonald {
64269b5a878SDan McDonald s32 status;
64369b5a878SDan McDonald u16 checksum;
64469b5a878SDan McDonald
64569b5a878SDan McDonald DEBUGFUNC("ixgbe_update_eeprom_checksum_X540");
64669b5a878SDan McDonald
647dc0cb1cdSDale Ghent /* Read the first word from the EEPROM. If this times out or fails, do
64869b5a878SDan McDonald * not continue or we could be in for a very long wait while every
64969b5a878SDan McDonald * EEPROM read fails
65069b5a878SDan McDonald */
65169b5a878SDan McDonald status = hw->eeprom.ops.read(hw, 0, &checksum);
652dc0cb1cdSDale Ghent if (status) {
65369b5a878SDan McDonald DEBUGOUT("EEPROM read failed\n");
654dc0cb1cdSDale Ghent return status;
655dc0cb1cdSDale Ghent }
65669b5a878SDan McDonald
657dc0cb1cdSDale Ghent if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
658dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
65969b5a878SDan McDonald
660dc0cb1cdSDale Ghent status = hw->eeprom.ops.calc_checksum(hw);
661dc0cb1cdSDale Ghent if (status < 0)
662dc0cb1cdSDale Ghent goto out;
66369b5a878SDan McDonald
664dc0cb1cdSDale Ghent checksum = (u16)(status & 0xffff);
66569b5a878SDan McDonald
666dc0cb1cdSDale Ghent /* Do not use hw->eeprom.ops.write because we do not want to
667dc0cb1cdSDale Ghent * take the synchronization semaphores twice here.
668dc0cb1cdSDale Ghent */
669dc0cb1cdSDale Ghent status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
670dc0cb1cdSDale Ghent if (status)
671dc0cb1cdSDale Ghent goto out;
672dc0cb1cdSDale Ghent
673dc0cb1cdSDale Ghent status = ixgbe_update_flash_X540(hw);
674dc0cb1cdSDale Ghent
675dc0cb1cdSDale Ghent out:
67669b5a878SDan McDonald hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
67769b5a878SDan McDonald
67869b5a878SDan McDonald return status;
67969b5a878SDan McDonald }
68069b5a878SDan McDonald
68169b5a878SDan McDonald /**
68269b5a878SDan McDonald * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device
68369b5a878SDan McDonald * @hw: pointer to hardware structure
68469b5a878SDan McDonald *
68569b5a878SDan McDonald * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy
68669b5a878SDan McDonald * EEPROM from shadow RAM to the flash device.
68769b5a878SDan McDonald **/
ixgbe_update_flash_X540(struct ixgbe_hw * hw)688dc0cb1cdSDale Ghent s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
68969b5a878SDan McDonald {
69069b5a878SDan McDonald u32 flup;
691dc0cb1cdSDale Ghent s32 status;
69269b5a878SDan McDonald
69369b5a878SDan McDonald DEBUGFUNC("ixgbe_update_flash_X540");
69469b5a878SDan McDonald
69569b5a878SDan McDonald status = ixgbe_poll_flash_update_done_X540(hw);
69669b5a878SDan McDonald if (status == IXGBE_ERR_EEPROM) {
69769b5a878SDan McDonald DEBUGOUT("Flash update time out\n");
69869b5a878SDan McDonald goto out;
69969b5a878SDan McDonald }
70069b5a878SDan McDonald
701dc0cb1cdSDale Ghent flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP;
702dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
70369b5a878SDan McDonald
70469b5a878SDan McDonald status = ixgbe_poll_flash_update_done_X540(hw);
70569b5a878SDan McDonald if (status == IXGBE_SUCCESS)
70669b5a878SDan McDonald DEBUGOUT("Flash update complete\n");
70769b5a878SDan McDonald else
70869b5a878SDan McDonald DEBUGOUT("Flash update time out\n");
70969b5a878SDan McDonald
710dc0cb1cdSDale Ghent if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) {
711dc0cb1cdSDale Ghent flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
71269b5a878SDan McDonald
71369b5a878SDan McDonald if (flup & IXGBE_EEC_SEC1VAL) {
71469b5a878SDan McDonald flup |= IXGBE_EEC_FLUP;
715dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
71669b5a878SDan McDonald }
71769b5a878SDan McDonald
71869b5a878SDan McDonald status = ixgbe_poll_flash_update_done_X540(hw);
71969b5a878SDan McDonald if (status == IXGBE_SUCCESS)
72069b5a878SDan McDonald DEBUGOUT("Flash update complete\n");
72169b5a878SDan McDonald else
72269b5a878SDan McDonald DEBUGOUT("Flash update time out\n");
72369b5a878SDan McDonald }
72469b5a878SDan McDonald out:
72569b5a878SDan McDonald return status;
72669b5a878SDan McDonald }
72769b5a878SDan McDonald
72869b5a878SDan McDonald /**
72969b5a878SDan McDonald * ixgbe_poll_flash_update_done_X540 - Poll flash update status
73069b5a878SDan McDonald * @hw: pointer to hardware structure
73169b5a878SDan McDonald *
73269b5a878SDan McDonald * Polls the FLUDONE (bit 26) of the EEC Register to determine when the
73369b5a878SDan McDonald * flash update is done.
73469b5a878SDan McDonald **/
ixgbe_poll_flash_update_done_X540(struct ixgbe_hw * hw)73569b5a878SDan McDonald static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
73669b5a878SDan McDonald {
73769b5a878SDan McDonald u32 i;
73869b5a878SDan McDonald u32 reg;
73969b5a878SDan McDonald s32 status = IXGBE_ERR_EEPROM;
74069b5a878SDan McDonald
74169b5a878SDan McDonald DEBUGFUNC("ixgbe_poll_flash_update_done_X540");
74269b5a878SDan McDonald
74369b5a878SDan McDonald for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
744dc0cb1cdSDale Ghent reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
74569b5a878SDan McDonald if (reg & IXGBE_EEC_FLUDONE) {
74669b5a878SDan McDonald status = IXGBE_SUCCESS;
74769b5a878SDan McDonald break;
74869b5a878SDan McDonald }
749dc0cb1cdSDale Ghent msec_delay(5);
75069b5a878SDan McDonald }
751dc0cb1cdSDale Ghent
752dc0cb1cdSDale Ghent if (i == IXGBE_FLUDONE_ATTEMPTS)
753dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_POLLING,
754dc0cb1cdSDale Ghent "Flash update status polling timed out");
755dc0cb1cdSDale Ghent
75669b5a878SDan McDonald return status;
75769b5a878SDan McDonald }
75869b5a878SDan McDonald
75969b5a878SDan McDonald /**
76069b5a878SDan McDonald * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore
76169b5a878SDan McDonald * @hw: pointer to hardware structure
76269b5a878SDan McDonald * @mask: Mask to specify which semaphore to acquire
76369b5a878SDan McDonald *
76469b5a878SDan McDonald * Acquires the SWFW semaphore thought the SW_FW_SYNC register for
76569b5a878SDan McDonald * the specified function (CSR, PHY0, PHY1, NVM, Flash)
76669b5a878SDan McDonald **/
ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw * hw,u32 mask)767dc0cb1cdSDale Ghent s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
76869b5a878SDan McDonald {
769dc0cb1cdSDale Ghent u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK;
770dc0cb1cdSDale Ghent u32 fwmask = swmask << 5;
771dc0cb1cdSDale Ghent u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK;
77269b5a878SDan McDonald u32 timeout = 200;
773dc0cb1cdSDale Ghent u32 hwmask = 0;
774dc0cb1cdSDale Ghent u32 swfw_sync;
77569b5a878SDan McDonald u32 i;
77669b5a878SDan McDonald
77769b5a878SDan McDonald DEBUGFUNC("ixgbe_acquire_swfw_sync_X540");
77869b5a878SDan McDonald
779dc0cb1cdSDale Ghent if (swmask & IXGBE_GSSR_EEP_SM)
780dc0cb1cdSDale Ghent hwmask |= IXGBE_GSSR_FLASH_SM;
78169b5a878SDan McDonald
78269b5a878SDan McDonald /* SW only mask doesn't have FW bit pair */
783dc0cb1cdSDale Ghent if (mask & IXGBE_GSSR_SW_MNG_SM)
784dc0cb1cdSDale Ghent swmask |= IXGBE_GSSR_SW_MNG_SM;
78569b5a878SDan McDonald
786dc0cb1cdSDale Ghent swmask |= swi2c_mask;
787dc0cb1cdSDale Ghent fwmask |= swi2c_mask << 2;
788*48ed61a7SRobert Mustacchi if (hw->mac.type >= ixgbe_mac_X550)
789*48ed61a7SRobert Mustacchi timeout = 1000;
790*48ed61a7SRobert Mustacchi
79169b5a878SDan McDonald for (i = 0; i < timeout; i++) {
792dc0cb1cdSDale Ghent /* SW NVM semaphore bit is used for access to all
79369b5a878SDan McDonald * SW_FW_SYNC bits (not just NVM)
79469b5a878SDan McDonald */
795*48ed61a7SRobert Mustacchi if (ixgbe_get_swfw_sync_semaphore(hw)) {
796*48ed61a7SRobert Mustacchi DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n");
797dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
798*48ed61a7SRobert Mustacchi }
79969b5a878SDan McDonald
800dc0cb1cdSDale Ghent swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
80169b5a878SDan McDonald if (!(swfw_sync & (fwmask | swmask | hwmask))) {
80269b5a878SDan McDonald swfw_sync |= swmask;
803dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw),
804dc0cb1cdSDale Ghent swfw_sync);
80569b5a878SDan McDonald ixgbe_release_swfw_sync_semaphore(hw);
806dc0cb1cdSDale Ghent return IXGBE_SUCCESS;
80769b5a878SDan McDonald }
808dc0cb1cdSDale Ghent /* Firmware currently using resource (fwmask), hardware
809dc0cb1cdSDale Ghent * currently using resource (hwmask), or other software
810dc0cb1cdSDale Ghent * thread currently using resource (swmask)
811dc0cb1cdSDale Ghent */
812dc0cb1cdSDale Ghent ixgbe_release_swfw_sync_semaphore(hw);
813dc0cb1cdSDale Ghent msec_delay(5);
81469b5a878SDan McDonald }
81569b5a878SDan McDonald
81669b5a878SDan McDonald /* If the resource is not released by the FW/HW the SW can assume that
817dc0cb1cdSDale Ghent * the FW/HW malfunctions. In that case the SW should set the SW bit(s)
81869b5a878SDan McDonald * of the requested resource(s) while ignoring the corresponding FW/HW
81969b5a878SDan McDonald * bits in the SW_FW_SYNC register.
82069b5a878SDan McDonald */
821*48ed61a7SRobert Mustacchi if (ixgbe_get_swfw_sync_semaphore(hw)) {
822*48ed61a7SRobert Mustacchi 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");
823dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
824*48ed61a7SRobert Mustacchi }
825dc0cb1cdSDale Ghent swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
82669b5a878SDan McDonald if (swfw_sync & (fwmask | hwmask)) {
82769b5a878SDan McDonald swfw_sync |= swmask;
828dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
82969b5a878SDan McDonald ixgbe_release_swfw_sync_semaphore(hw);
83069b5a878SDan McDonald msec_delay(5);
831dc0cb1cdSDale Ghent return IXGBE_SUCCESS;
83269b5a878SDan McDonald }
833dc0cb1cdSDale Ghent /* If the resource is not released by other SW the SW can assume that
834dc0cb1cdSDale Ghent * the other SW malfunctions. In that case the SW should clear all SW
835dc0cb1cdSDale Ghent * flags that it does not own and then repeat the whole process once
836dc0cb1cdSDale Ghent * again.
837dc0cb1cdSDale Ghent */
838dc0cb1cdSDale Ghent if (swfw_sync & swmask) {
839dc0cb1cdSDale Ghent u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
840*48ed61a7SRobert Mustacchi IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
841*48ed61a7SRobert Mustacchi IXGBE_GSSR_SW_MNG_SM;
84269b5a878SDan McDonald
843dc0cb1cdSDale Ghent if (swi2c_mask)
844dc0cb1cdSDale Ghent rmask |= IXGBE_GSSR_I2C_MASK;
845dc0cb1cdSDale Ghent ixgbe_release_swfw_sync_X540(hw, rmask);
846dc0cb1cdSDale Ghent ixgbe_release_swfw_sync_semaphore(hw);
847*48ed61a7SRobert Mustacchi DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n");
848dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
849dc0cb1cdSDale Ghent }
850dc0cb1cdSDale Ghent ixgbe_release_swfw_sync_semaphore(hw);
851*48ed61a7SRobert Mustacchi DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n");
852dc0cb1cdSDale Ghent
853dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
85469b5a878SDan McDonald }
85569b5a878SDan McDonald
85669b5a878SDan McDonald /**
85769b5a878SDan McDonald * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore
85869b5a878SDan McDonald * @hw: pointer to hardware structure
85969b5a878SDan McDonald * @mask: Mask to specify which semaphore to release
86069b5a878SDan McDonald *
86169b5a878SDan McDonald * Releases the SWFW semaphore through the SW_FW_SYNC register
86269b5a878SDan McDonald * for the specified function (CSR, PHY0, PHY1, EVM, Flash)
86369b5a878SDan McDonald **/
ixgbe_release_swfw_sync_X540(struct ixgbe_hw * hw,u32 mask)864dc0cb1cdSDale Ghent void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
86569b5a878SDan McDonald {
866dc0cb1cdSDale Ghent u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM);
86769b5a878SDan McDonald u32 swfw_sync;
86869b5a878SDan McDonald
86969b5a878SDan McDonald DEBUGFUNC("ixgbe_release_swfw_sync_X540");
87069b5a878SDan McDonald
871dc0cb1cdSDale Ghent if (mask & IXGBE_GSSR_I2C_MASK)
872dc0cb1cdSDale Ghent swmask |= mask & IXGBE_GSSR_I2C_MASK;
873dc0cb1cdSDale Ghent ixgbe_get_swfw_sync_semaphore(hw);
87469b5a878SDan McDonald
875dc0cb1cdSDale Ghent swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
87669b5a878SDan McDonald swfw_sync &= ~swmask;
877dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
87869b5a878SDan McDonald
87969b5a878SDan McDonald ixgbe_release_swfw_sync_semaphore(hw);
880*48ed61a7SRobert Mustacchi msec_delay(2);
88169b5a878SDan McDonald }
88269b5a878SDan McDonald
88369b5a878SDan McDonald /**
884dc0cb1cdSDale Ghent * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore
88569b5a878SDan McDonald * @hw: pointer to hardware structure
88669b5a878SDan McDonald *
88769b5a878SDan McDonald * Sets the hardware semaphores so SW/FW can gain control of shared resources
88869b5a878SDan McDonald **/
ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw * hw)88969b5a878SDan McDonald static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
89069b5a878SDan McDonald {
89169b5a878SDan McDonald s32 status = IXGBE_ERR_EEPROM;
89269b5a878SDan McDonald u32 timeout = 2000;
89369b5a878SDan McDonald u32 i;
89469b5a878SDan McDonald u32 swsm;
89569b5a878SDan McDonald
89669b5a878SDan McDonald DEBUGFUNC("ixgbe_get_swfw_sync_semaphore");
89769b5a878SDan McDonald
89869b5a878SDan McDonald /* Get SMBI software semaphore between device drivers first */
89969b5a878SDan McDonald for (i = 0; i < timeout; i++) {
90069b5a878SDan McDonald /*
90169b5a878SDan McDonald * If the SMBI bit is 0 when we read it, then the bit will be
90269b5a878SDan McDonald * set and we have the semaphore
90369b5a878SDan McDonald */
904dc0cb1cdSDale Ghent swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
90569b5a878SDan McDonald if (!(swsm & IXGBE_SWSM_SMBI)) {
90669b5a878SDan McDonald status = IXGBE_SUCCESS;
90769b5a878SDan McDonald break;
90869b5a878SDan McDonald }
90969b5a878SDan McDonald usec_delay(50);
91069b5a878SDan McDonald }
91169b5a878SDan McDonald
91269b5a878SDan McDonald /* Now get the semaphore between SW/FW through the REGSMP bit */
91369b5a878SDan McDonald if (status == IXGBE_SUCCESS) {
91469b5a878SDan McDonald for (i = 0; i < timeout; i++) {
915dc0cb1cdSDale Ghent swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
91669b5a878SDan McDonald if (!(swsm & IXGBE_SWFW_REGSMP))
91769b5a878SDan McDonald break;
91869b5a878SDan McDonald
91969b5a878SDan McDonald usec_delay(50);
92069b5a878SDan McDonald }
92169b5a878SDan McDonald
92269b5a878SDan McDonald /*
92369b5a878SDan McDonald * Release semaphores and return error if SW NVM semaphore
92469b5a878SDan McDonald * was not granted because we don't have access to the EEPROM
92569b5a878SDan McDonald */
92669b5a878SDan McDonald if (i >= timeout) {
927dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_POLLING,
928dc0cb1cdSDale Ghent "REGSMP Software NVM semaphore not granted.\n");
92969b5a878SDan McDonald ixgbe_release_swfw_sync_semaphore(hw);
93069b5a878SDan McDonald status = IXGBE_ERR_EEPROM;
93169b5a878SDan McDonald }
93269b5a878SDan McDonald } else {
933dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_POLLING,
934dc0cb1cdSDale Ghent "Software semaphore SMBI between device drivers "
935dc0cb1cdSDale Ghent "not granted.\n");
93669b5a878SDan McDonald }
93769b5a878SDan McDonald
93869b5a878SDan McDonald return status;
93969b5a878SDan McDonald }
94069b5a878SDan McDonald
94169b5a878SDan McDonald /**
942dc0cb1cdSDale Ghent * ixgbe_release_swfw_sync_semaphore - Release hardware semaphore
94369b5a878SDan McDonald * @hw: pointer to hardware structure
94469b5a878SDan McDonald *
94569b5a878SDan McDonald * This function clears hardware semaphore bits.
94669b5a878SDan McDonald **/
ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw * hw)94769b5a878SDan McDonald static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
94869b5a878SDan McDonald {
94969b5a878SDan McDonald u32 swsm;
95069b5a878SDan McDonald
95169b5a878SDan McDonald DEBUGFUNC("ixgbe_release_swfw_sync_semaphore");
95269b5a878SDan McDonald
95369b5a878SDan McDonald /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
95469b5a878SDan McDonald
955dc0cb1cdSDale Ghent swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
95669b5a878SDan McDonald swsm &= ~IXGBE_SWFW_REGSMP;
957dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm);
958dc0cb1cdSDale Ghent
959dc0cb1cdSDale Ghent swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
960dc0cb1cdSDale Ghent swsm &= ~IXGBE_SWSM_SMBI;
961dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm);
96269b5a878SDan McDonald
96369b5a878SDan McDonald IXGBE_WRITE_FLUSH(hw);
96469b5a878SDan McDonald }
96569b5a878SDan McDonald
966*48ed61a7SRobert Mustacchi /**
967*48ed61a7SRobert Mustacchi * ixgbe_init_swfw_sync_X540 - Release hardware semaphore
968*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
969*48ed61a7SRobert Mustacchi *
970*48ed61a7SRobert Mustacchi * This function reset hardware semaphore bits for a semaphore that may
971*48ed61a7SRobert Mustacchi * have be left locked due to a catastrophic failure.
972*48ed61a7SRobert Mustacchi **/
ixgbe_init_swfw_sync_X540(struct ixgbe_hw * hw)973*48ed61a7SRobert Mustacchi void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
974*48ed61a7SRobert Mustacchi {
975*48ed61a7SRobert Mustacchi u32 rmask;
976*48ed61a7SRobert Mustacchi
977*48ed61a7SRobert Mustacchi /* First try to grab the semaphore but we don't need to bother
978*48ed61a7SRobert Mustacchi * looking to see whether we got the lock or not since we do
979*48ed61a7SRobert Mustacchi * the same thing regardless of whether we got the lock or not.
980*48ed61a7SRobert Mustacchi * We got the lock - we release it.
981*48ed61a7SRobert Mustacchi * We timeout trying to get the lock - we force its release.
982*48ed61a7SRobert Mustacchi */
983*48ed61a7SRobert Mustacchi ixgbe_get_swfw_sync_semaphore(hw);
984*48ed61a7SRobert Mustacchi ixgbe_release_swfw_sync_semaphore(hw);
985*48ed61a7SRobert Mustacchi
986*48ed61a7SRobert Mustacchi /* Acquire and release all software resources. */
987*48ed61a7SRobert Mustacchi rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
988*48ed61a7SRobert Mustacchi IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
989*48ed61a7SRobert Mustacchi IXGBE_GSSR_SW_MNG_SM;
990*48ed61a7SRobert Mustacchi
991*48ed61a7SRobert Mustacchi rmask |= IXGBE_GSSR_I2C_MASK;
992*48ed61a7SRobert Mustacchi ixgbe_acquire_swfw_sync_X540(hw, rmask);
993*48ed61a7SRobert Mustacchi ixgbe_release_swfw_sync_X540(hw, rmask);
994*48ed61a7SRobert Mustacchi }
995*48ed61a7SRobert Mustacchi
99669b5a878SDan McDonald /**
99769b5a878SDan McDonald * ixgbe_blink_led_start_X540 - Blink LED based on index.
99869b5a878SDan McDonald * @hw: pointer to hardware structure
99969b5a878SDan McDonald * @index: led number to blink
100069b5a878SDan McDonald *
100169b5a878SDan McDonald * Devices that implement the version 2 interface:
100269b5a878SDan McDonald * X540
100369b5a878SDan McDonald **/
ixgbe_blink_led_start_X540(struct ixgbe_hw * hw,u32 index)100469b5a878SDan McDonald s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
100569b5a878SDan McDonald {
100669b5a878SDan McDonald u32 macc_reg;
100769b5a878SDan McDonald u32 ledctl_reg;
100869b5a878SDan McDonald ixgbe_link_speed speed;
100969b5a878SDan McDonald bool link_up;
101069b5a878SDan McDonald
101169b5a878SDan McDonald DEBUGFUNC("ixgbe_blink_led_start_X540");
101269b5a878SDan McDonald
1013*48ed61a7SRobert Mustacchi if (index > 3)
1014*48ed61a7SRobert Mustacchi return IXGBE_ERR_PARAM;
1015*48ed61a7SRobert Mustacchi
101669b5a878SDan McDonald /*
101769b5a878SDan McDonald * Link should be up in order for the blink bit in the LED control
101869b5a878SDan McDonald * register to work. Force link and speed in the MAC if link is down.
101969b5a878SDan McDonald * This will be reversed when we stop the blinking.
102069b5a878SDan McDonald */
102169b5a878SDan McDonald hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
102269b5a878SDan McDonald if (link_up == FALSE) {
102369b5a878SDan McDonald macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
102469b5a878SDan McDonald macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
102569b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
102669b5a878SDan McDonald }
102769b5a878SDan McDonald /* Set the LED to LINK_UP + BLINK. */
102869b5a878SDan McDonald ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
102969b5a878SDan McDonald ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
103069b5a878SDan McDonald ledctl_reg |= IXGBE_LED_BLINK(index);
103169b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
103269b5a878SDan McDonald IXGBE_WRITE_FLUSH(hw);
103369b5a878SDan McDonald
103469b5a878SDan McDonald return IXGBE_SUCCESS;
103569b5a878SDan McDonald }
103669b5a878SDan McDonald
103769b5a878SDan McDonald /**
103869b5a878SDan McDonald * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
103969b5a878SDan McDonald * @hw: pointer to hardware structure
104069b5a878SDan McDonald * @index: led number to stop blinking
104169b5a878SDan McDonald *
104269b5a878SDan McDonald * Devices that implement the version 2 interface:
104369b5a878SDan McDonald * X540
104469b5a878SDan McDonald **/
ixgbe_blink_led_stop_X540(struct ixgbe_hw * hw,u32 index)104569b5a878SDan McDonald s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
104669b5a878SDan McDonald {
104769b5a878SDan McDonald u32 macc_reg;
104869b5a878SDan McDonald u32 ledctl_reg;
104969b5a878SDan McDonald
1050*48ed61a7SRobert Mustacchi if (index > 3)
1051*48ed61a7SRobert Mustacchi return IXGBE_ERR_PARAM;
1052*48ed61a7SRobert Mustacchi
105369b5a878SDan McDonald DEBUGFUNC("ixgbe_blink_led_stop_X540");
105469b5a878SDan McDonald
105569b5a878SDan McDonald /* Restore the LED to its default value. */
105669b5a878SDan McDonald ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
105769b5a878SDan McDonald ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
105869b5a878SDan McDonald ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
105969b5a878SDan McDonald ledctl_reg &= ~IXGBE_LED_BLINK(index);
106069b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
106169b5a878SDan McDonald
106269b5a878SDan McDonald /* Unforce link and speed in the MAC. */
106369b5a878SDan McDonald macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
106469b5a878SDan McDonald macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
106569b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
106669b5a878SDan McDonald IXGBE_WRITE_FLUSH(hw);
106769b5a878SDan McDonald
106869b5a878SDan McDonald return IXGBE_SUCCESS;
106969b5a878SDan McDonald }
1070