xref: /dflybsd-src/sys/dev/netif/ix/ixgbe_x540.c (revision dd5ce676d9b4496101d795200cb99fd0ddf5b254)
179251f5eSSepherosa Ziehau /******************************************************************************
279251f5eSSepherosa Ziehau 
36150453fSSepherosa Ziehau   Copyright (c) 2001-2017, Intel Corporation
479251f5eSSepherosa Ziehau   All rights reserved.
579251f5eSSepherosa Ziehau 
679251f5eSSepherosa Ziehau   Redistribution and use in source and binary forms, with or without
779251f5eSSepherosa Ziehau   modification, are permitted provided that the following conditions are met:
879251f5eSSepherosa Ziehau 
979251f5eSSepherosa Ziehau    1. Redistributions of source code must retain the above copyright notice,
1079251f5eSSepherosa Ziehau       this list of conditions and the following disclaimer.
1179251f5eSSepherosa Ziehau 
1279251f5eSSepherosa Ziehau    2. Redistributions in binary form must reproduce the above copyright
1379251f5eSSepherosa Ziehau       notice, this list of conditions and the following disclaimer in the
1479251f5eSSepherosa Ziehau       documentation and/or other materials provided with the distribution.
1579251f5eSSepherosa Ziehau 
1679251f5eSSepherosa Ziehau    3. Neither the name of the Intel Corporation nor the names of its
1779251f5eSSepherosa Ziehau       contributors may be used to endorse or promote products derived from
1879251f5eSSepherosa Ziehau       this software without specific prior written permission.
1979251f5eSSepherosa Ziehau 
2079251f5eSSepherosa Ziehau   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2179251f5eSSepherosa Ziehau   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2279251f5eSSepherosa Ziehau   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2379251f5eSSepherosa Ziehau   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2479251f5eSSepherosa Ziehau   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2579251f5eSSepherosa Ziehau   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2679251f5eSSepherosa Ziehau   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2779251f5eSSepherosa Ziehau   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2879251f5eSSepherosa Ziehau   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2979251f5eSSepherosa Ziehau   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3079251f5eSSepherosa Ziehau   POSSIBILITY OF SUCH DAMAGE.
3179251f5eSSepherosa Ziehau 
3279251f5eSSepherosa Ziehau ******************************************************************************/
3379251f5eSSepherosa Ziehau /*$FreeBSD$*/
3479251f5eSSepherosa Ziehau 
3579251f5eSSepherosa Ziehau #include "ixgbe_x540.h"
3679251f5eSSepherosa Ziehau #include "ixgbe_type.h"
3779251f5eSSepherosa Ziehau #include "ixgbe_api.h"
3879251f5eSSepherosa Ziehau #include "ixgbe_common.h"
3979251f5eSSepherosa Ziehau #include "ixgbe_phy.h"
4079251f5eSSepherosa Ziehau 
4163d483cdSSepherosa Ziehau #define IXGBE_X540_MAX_TX_QUEUES	128
4263d483cdSSepherosa Ziehau #define IXGBE_X540_MAX_RX_QUEUES	128
4363d483cdSSepherosa Ziehau #define IXGBE_X540_RAR_ENTRIES		128
4463d483cdSSepherosa Ziehau #define IXGBE_X540_MC_TBL_SIZE		128
4563d483cdSSepherosa Ziehau #define IXGBE_X540_VFT_TBL_SIZE		128
4663d483cdSSepherosa Ziehau #define IXGBE_X540_RX_PB_SIZE		384
4763d483cdSSepherosa Ziehau 
4879251f5eSSepherosa Ziehau static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
4979251f5eSSepherosa Ziehau static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
5079251f5eSSepherosa Ziehau static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
5179251f5eSSepherosa Ziehau 
5279251f5eSSepherosa Ziehau /**
5379251f5eSSepherosa Ziehau  *  ixgbe_init_ops_X540 - Inits func ptrs and MAC type
5479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
5579251f5eSSepherosa Ziehau  *
5679251f5eSSepherosa Ziehau  *  Initialize the function pointers and assign the MAC type for X540.
5779251f5eSSepherosa Ziehau  *  Does not touch the hardware.
5879251f5eSSepherosa Ziehau  **/
ixgbe_init_ops_X540(struct ixgbe_hw * hw)5979251f5eSSepherosa Ziehau s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
6079251f5eSSepherosa Ziehau {
6179251f5eSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
6279251f5eSSepherosa Ziehau 	struct ixgbe_phy_info *phy = &hw->phy;
6379251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
6479251f5eSSepherosa Ziehau 	s32 ret_val;
6579251f5eSSepherosa Ziehau 
6679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_X540");
6779251f5eSSepherosa Ziehau 
6879251f5eSSepherosa Ziehau 	ret_val = ixgbe_init_phy_ops_generic(hw);
6979251f5eSSepherosa Ziehau 	ret_val = ixgbe_init_ops_generic(hw);
7079251f5eSSepherosa Ziehau 
7179251f5eSSepherosa Ziehau 
7279251f5eSSepherosa Ziehau 	/* EEPROM */
7363d483cdSSepherosa Ziehau 	eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
7463d483cdSSepherosa Ziehau 	eeprom->ops.read = ixgbe_read_eerd_X540;
7563d483cdSSepherosa Ziehau 	eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_X540;
7663d483cdSSepherosa Ziehau 	eeprom->ops.write = ixgbe_write_eewr_X540;
7763d483cdSSepherosa Ziehau 	eeprom->ops.write_buffer = ixgbe_write_eewr_buffer_X540;
7863d483cdSSepherosa Ziehau 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X540;
7963d483cdSSepherosa Ziehau 	eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X540;
8063d483cdSSepherosa Ziehau 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X540;
8179251f5eSSepherosa Ziehau 
8279251f5eSSepherosa Ziehau 	/* PHY */
8363d483cdSSepherosa Ziehau 	phy->ops.init = ixgbe_init_phy_ops_generic;
8479251f5eSSepherosa Ziehau 	phy->ops.reset = NULL;
8563d483cdSSepherosa Ziehau 	phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
8679251f5eSSepherosa Ziehau 
8779251f5eSSepherosa Ziehau 	/* MAC */
8863d483cdSSepherosa Ziehau 	mac->ops.reset_hw = ixgbe_reset_hw_X540;
8963d483cdSSepherosa Ziehau 	mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_gen2;
9063d483cdSSepherosa Ziehau 	mac->ops.get_media_type = ixgbe_get_media_type_X540;
9179251f5eSSepherosa Ziehau 	mac->ops.get_supported_physical_layer =
9263d483cdSSepherosa Ziehau 				    ixgbe_get_supported_physical_layer_X540;
9379251f5eSSepherosa Ziehau 	mac->ops.read_analog_reg8 = NULL;
9479251f5eSSepherosa Ziehau 	mac->ops.write_analog_reg8 = NULL;
9563d483cdSSepherosa Ziehau 	mac->ops.start_hw = ixgbe_start_hw_X540;
9663d483cdSSepherosa Ziehau 	mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic;
9763d483cdSSepherosa Ziehau 	mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic;
9863d483cdSSepherosa Ziehau 	mac->ops.get_device_caps = ixgbe_get_device_caps_generic;
9963d483cdSSepherosa Ziehau 	mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic;
10063d483cdSSepherosa Ziehau 	mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic;
10163d483cdSSepherosa Ziehau 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540;
10263d483cdSSepherosa Ziehau 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540;
1036150453fSSepherosa Ziehau 	mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540;
10463d483cdSSepherosa Ziehau 	mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
10563d483cdSSepherosa Ziehau 	mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
10679251f5eSSepherosa Ziehau 
10779251f5eSSepherosa Ziehau 	/* RAR, Multicast, VLAN */
10863d483cdSSepherosa Ziehau 	mac->ops.set_vmdq = ixgbe_set_vmdq_generic;
10963d483cdSSepherosa Ziehau 	mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic;
11063d483cdSSepherosa Ziehau 	mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic;
11163d483cdSSepherosa Ziehau 	mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic;
11279251f5eSSepherosa Ziehau 	mac->rar_highwater = 1;
11363d483cdSSepherosa Ziehau 	mac->ops.set_vfta = ixgbe_set_vfta_generic;
11463d483cdSSepherosa Ziehau 	mac->ops.set_vlvf = ixgbe_set_vlvf_generic;
11563d483cdSSepherosa Ziehau 	mac->ops.clear_vfta = ixgbe_clear_vfta_generic;
11663d483cdSSepherosa Ziehau 	mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic;
11763d483cdSSepherosa Ziehau 	mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing;
11863d483cdSSepherosa Ziehau 	mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing;
11979251f5eSSepherosa Ziehau 
12079251f5eSSepherosa Ziehau 	/* Link */
12179251f5eSSepherosa Ziehau 	mac->ops.get_link_capabilities =
12263d483cdSSepherosa Ziehau 				ixgbe_get_copper_link_capabilities_generic;
12363d483cdSSepherosa Ziehau 	mac->ops.setup_link = ixgbe_setup_mac_link_X540;
12463d483cdSSepherosa Ziehau 	mac->ops.setup_rxpba = ixgbe_set_rxpba_generic;
12563d483cdSSepherosa Ziehau 	mac->ops.check_link = ixgbe_check_mac_link_generic;
1266150453fSSepherosa Ziehau 	mac->ops.bypass_rw = ixgbe_bypass_rw_generic;
1276150453fSSepherosa Ziehau 	mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic;
1286150453fSSepherosa Ziehau 	mac->ops.bypass_set = ixgbe_bypass_set_generic;
1296150453fSSepherosa Ziehau 	mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic;
13079251f5eSSepherosa Ziehau 
13179251f5eSSepherosa Ziehau 
13263d483cdSSepherosa Ziehau 	mac->mcft_size		= IXGBE_X540_MC_TBL_SIZE;
13363d483cdSSepherosa Ziehau 	mac->vft_size		= IXGBE_X540_VFT_TBL_SIZE;
13463d483cdSSepherosa Ziehau 	mac->num_rar_entries	= IXGBE_X540_RAR_ENTRIES;
13563d483cdSSepherosa Ziehau 	mac->rx_pb_size		= IXGBE_X540_RX_PB_SIZE;
13663d483cdSSepherosa Ziehau 	mac->max_rx_queues	= IXGBE_X540_MAX_RX_QUEUES;
13763d483cdSSepherosa Ziehau 	mac->max_tx_queues	= IXGBE_X540_MAX_TX_QUEUES;
13879251f5eSSepherosa Ziehau 	mac->max_msix_vectors	= ixgbe_get_pcie_msix_count_generic(hw);
13979251f5eSSepherosa Ziehau 
14079251f5eSSepherosa Ziehau 	/*
14179251f5eSSepherosa Ziehau 	 * FWSM register
14279251f5eSSepherosa Ziehau 	 * ARC supported; valid only if manageability features are
14379251f5eSSepherosa Ziehau 	 * enabled.
14479251f5eSSepherosa Ziehau 	 */
1456150453fSSepherosa Ziehau 	mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
1466150453fSSepherosa Ziehau 				     & IXGBE_FWSM_MODE_MASK);
14779251f5eSSepherosa Ziehau 
14879251f5eSSepherosa Ziehau 	hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
14979251f5eSSepherosa Ziehau 
15079251f5eSSepherosa Ziehau 	/* LEDs */
15179251f5eSSepherosa Ziehau 	mac->ops.blink_led_start = ixgbe_blink_led_start_X540;
15279251f5eSSepherosa Ziehau 	mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540;
15379251f5eSSepherosa Ziehau 
15479251f5eSSepherosa Ziehau 	/* Manageability interface */
15563d483cdSSepherosa Ziehau 	mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic;
15679251f5eSSepherosa Ziehau 
15763d483cdSSepherosa Ziehau 	mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
15879251f5eSSepherosa Ziehau 
15979251f5eSSepherosa Ziehau 	return ret_val;
16079251f5eSSepherosa Ziehau }
16179251f5eSSepherosa Ziehau 
16279251f5eSSepherosa Ziehau /**
16379251f5eSSepherosa Ziehau  *  ixgbe_get_link_capabilities_X540 - Determines link capabilities
16479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
16579251f5eSSepherosa Ziehau  *  @speed: pointer to link speed
16679251f5eSSepherosa Ziehau  *  @autoneg: TRUE when autoneg or autotry is enabled
16779251f5eSSepherosa Ziehau  *
16879251f5eSSepherosa Ziehau  *  Determines the link capabilities by reading the AUTOC register.
16979251f5eSSepherosa Ziehau  **/
ixgbe_get_link_capabilities_X540(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)17079251f5eSSepherosa Ziehau s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
17179251f5eSSepherosa Ziehau 				     ixgbe_link_speed *speed,
17279251f5eSSepherosa Ziehau 				     bool *autoneg)
17379251f5eSSepherosa Ziehau {
17479251f5eSSepherosa Ziehau 	ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg);
17579251f5eSSepherosa Ziehau 
17679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
17779251f5eSSepherosa Ziehau }
17879251f5eSSepherosa Ziehau 
17979251f5eSSepherosa Ziehau /**
18079251f5eSSepherosa Ziehau  *  ixgbe_get_media_type_X540 - Get media type
18179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
18279251f5eSSepherosa Ziehau  *
18379251f5eSSepherosa Ziehau  *  Returns the media type (fiber, copper, backplane)
18479251f5eSSepherosa Ziehau  **/
ixgbe_get_media_type_X540(struct ixgbe_hw * hw)18579251f5eSSepherosa Ziehau enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
18679251f5eSSepherosa Ziehau {
18779251f5eSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(hw);
18879251f5eSSepherosa Ziehau 	return ixgbe_media_type_copper;
18979251f5eSSepherosa Ziehau }
19079251f5eSSepherosa Ziehau 
19179251f5eSSepherosa Ziehau /**
19279251f5eSSepherosa Ziehau  *  ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
19379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
19479251f5eSSepherosa Ziehau  *  @speed: new link speed
19579251f5eSSepherosa Ziehau  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
19679251f5eSSepherosa Ziehau  **/
ixgbe_setup_mac_link_X540(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)19779251f5eSSepherosa Ziehau s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
19879251f5eSSepherosa Ziehau 			      ixgbe_link_speed speed,
19979251f5eSSepherosa Ziehau 			      bool autoneg_wait_to_complete)
20079251f5eSSepherosa Ziehau {
20179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_mac_link_X540");
20279251f5eSSepherosa Ziehau 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
20379251f5eSSepherosa Ziehau }
20479251f5eSSepherosa Ziehau 
20579251f5eSSepherosa Ziehau /**
20679251f5eSSepherosa Ziehau  *  ixgbe_reset_hw_X540 - Perform hardware reset
20779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
20879251f5eSSepherosa Ziehau  *
20979251f5eSSepherosa Ziehau  *  Resets the hardware by resetting the transmit and receive units, masks
21079251f5eSSepherosa Ziehau  *  and clears all interrupts, and perform a reset.
21179251f5eSSepherosa Ziehau  **/
ixgbe_reset_hw_X540(struct ixgbe_hw * hw)21279251f5eSSepherosa Ziehau s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
21379251f5eSSepherosa Ziehau {
21479251f5eSSepherosa Ziehau 	s32 status;
21579251f5eSSepherosa Ziehau 	u32 ctrl, i;
2166150453fSSepherosa Ziehau 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
21779251f5eSSepherosa Ziehau 
21879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_reset_hw_X540");
21979251f5eSSepherosa Ziehau 
22079251f5eSSepherosa Ziehau 	/* Call adapter stop to disable tx/rx and clear interrupts */
22179251f5eSSepherosa Ziehau 	status = hw->mac.ops.stop_adapter(hw);
22279251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
22379251f5eSSepherosa Ziehau 		goto reset_hw_out;
22479251f5eSSepherosa Ziehau 
22579251f5eSSepherosa Ziehau 	/* flush pending Tx transactions */
22679251f5eSSepherosa Ziehau 	ixgbe_clear_tx_pending(hw);
22779251f5eSSepherosa Ziehau 
22879251f5eSSepherosa Ziehau mac_reset_top:
2296150453fSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
2306150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS) {
2316150453fSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
2326150453fSSepherosa Ziehau 			"semaphore failed with %d", status);
2336150453fSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
2346150453fSSepherosa Ziehau 	}
23579251f5eSSepherosa Ziehau 	ctrl = IXGBE_CTRL_RST;
23679251f5eSSepherosa Ziehau 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
23779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
23879251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
2396150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
24079251f5eSSepherosa Ziehau 
24179251f5eSSepherosa Ziehau 	/* Poll for reset bit to self-clear indicating reset is complete */
24279251f5eSSepherosa Ziehau 	for (i = 0; i < 10; i++) {
24379251f5eSSepherosa Ziehau 		usec_delay(1);
24479251f5eSSepherosa Ziehau 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
24579251f5eSSepherosa Ziehau 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
24679251f5eSSepherosa Ziehau 			break;
24779251f5eSSepherosa Ziehau 	}
24879251f5eSSepherosa Ziehau 
24979251f5eSSepherosa Ziehau 	if (ctrl & IXGBE_CTRL_RST_MASK) {
25079251f5eSSepherosa Ziehau 		status = IXGBE_ERR_RESET_FAILED;
25179251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
25279251f5eSSepherosa Ziehau 			     "Reset polling failed to complete.\n");
25379251f5eSSepherosa Ziehau 	}
25479251f5eSSepherosa Ziehau 	msec_delay(100);
25579251f5eSSepherosa Ziehau 
25679251f5eSSepherosa Ziehau 	/*
25779251f5eSSepherosa Ziehau 	 * Double resets are required for recovery from certain error
25879251f5eSSepherosa Ziehau 	 * conditions.  Between resets, it is necessary to stall to allow time
25979251f5eSSepherosa Ziehau 	 * for any pending HW events to complete.
26079251f5eSSepherosa Ziehau 	 */
26179251f5eSSepherosa Ziehau 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
26279251f5eSSepherosa Ziehau 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
26379251f5eSSepherosa Ziehau 		goto mac_reset_top;
26479251f5eSSepherosa Ziehau 	}
26579251f5eSSepherosa Ziehau 
26679251f5eSSepherosa Ziehau 	/* Set the Rx packet buffer size. */
26779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
26879251f5eSSepherosa Ziehau 
26979251f5eSSepherosa Ziehau 	/* Store the permanent mac address */
27079251f5eSSepherosa Ziehau 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
27179251f5eSSepherosa Ziehau 
27279251f5eSSepherosa Ziehau 	/*
27379251f5eSSepherosa Ziehau 	 * Store MAC address from RAR0, clear receive address registers, and
27479251f5eSSepherosa Ziehau 	 * clear the multicast table.  Also reset num_rar_entries to 128,
27579251f5eSSepherosa Ziehau 	 * since we modify this value when programming the SAN MAC address.
27679251f5eSSepherosa Ziehau 	 */
27779251f5eSSepherosa Ziehau 	hw->mac.num_rar_entries = 128;
27879251f5eSSepherosa Ziehau 	hw->mac.ops.init_rx_addrs(hw);
27979251f5eSSepherosa Ziehau 
28079251f5eSSepherosa Ziehau 	/* Store the permanent SAN mac address */
28179251f5eSSepherosa Ziehau 	hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
28279251f5eSSepherosa Ziehau 
28379251f5eSSepherosa Ziehau 	/* Add the SAN MAC address to the RAR only if it's a valid address */
28479251f5eSSepherosa Ziehau 	if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
28579251f5eSSepherosa Ziehau 		/* Save the SAN MAC RAR index */
28679251f5eSSepherosa Ziehau 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
28779251f5eSSepherosa Ziehau 
2886150453fSSepherosa Ziehau 		hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
2896150453fSSepherosa Ziehau 				    hw->mac.san_addr, 0, IXGBE_RAH_AV);
2906150453fSSepherosa Ziehau 
2916150453fSSepherosa Ziehau 		/* clear VMDq pool/queue selection for this RAR */
2926150453fSSepherosa Ziehau 		hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
2936150453fSSepherosa Ziehau 				       IXGBE_CLEAR_VMDQ_ALL);
2946150453fSSepherosa Ziehau 
29579251f5eSSepherosa Ziehau 		/* Reserve the last RAR for the SAN MAC address */
29679251f5eSSepherosa Ziehau 		hw->mac.num_rar_entries--;
29779251f5eSSepherosa Ziehau 	}
29879251f5eSSepherosa Ziehau 
29979251f5eSSepherosa Ziehau 	/* Store the alternative WWNN/WWPN prefix */
30079251f5eSSepherosa Ziehau 	hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
30179251f5eSSepherosa Ziehau 				   &hw->mac.wwpn_prefix);
30279251f5eSSepherosa Ziehau 
30379251f5eSSepherosa Ziehau reset_hw_out:
30479251f5eSSepherosa Ziehau 	return status;
30579251f5eSSepherosa Ziehau }
30679251f5eSSepherosa Ziehau 
30779251f5eSSepherosa Ziehau /**
30879251f5eSSepherosa Ziehau  *  ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
30979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
31079251f5eSSepherosa Ziehau  *
31179251f5eSSepherosa Ziehau  *  Starts the hardware using the generic start_hw function
31279251f5eSSepherosa Ziehau  *  and the generation start_hw function.
31379251f5eSSepherosa Ziehau  *  Then performs revision-specific operations, if any.
31479251f5eSSepherosa Ziehau  **/
ixgbe_start_hw_X540(struct ixgbe_hw * hw)31579251f5eSSepherosa Ziehau s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
31679251f5eSSepherosa Ziehau {
31779251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
31879251f5eSSepherosa Ziehau 
31979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_start_hw_X540");
32079251f5eSSepherosa Ziehau 
32179251f5eSSepherosa Ziehau 	ret_val = ixgbe_start_hw_generic(hw);
32279251f5eSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
32379251f5eSSepherosa Ziehau 		goto out;
32479251f5eSSepherosa Ziehau 
32579251f5eSSepherosa Ziehau 	ret_val = ixgbe_start_hw_gen2(hw);
32679251f5eSSepherosa Ziehau 
32779251f5eSSepherosa Ziehau out:
32879251f5eSSepherosa Ziehau 	return ret_val;
32979251f5eSSepherosa Ziehau }
33079251f5eSSepherosa Ziehau 
33179251f5eSSepherosa Ziehau /**
33279251f5eSSepherosa Ziehau  *  ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
33379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
33479251f5eSSepherosa Ziehau  *
33579251f5eSSepherosa Ziehau  *  Determines physical layer capabilities of the current configuration.
33679251f5eSSepherosa Ziehau  **/
ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw * hw)3376150453fSSepherosa Ziehau u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
33879251f5eSSepherosa Ziehau {
3396150453fSSepherosa Ziehau 	u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
34079251f5eSSepherosa Ziehau 	u16 ext_ability = 0;
34179251f5eSSepherosa Ziehau 
34279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_supported_physical_layer_X540");
34379251f5eSSepherosa Ziehau 
34479251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
34579251f5eSSepherosa Ziehau 	IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
34679251f5eSSepherosa Ziehau 	if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
34779251f5eSSepherosa Ziehau 		physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
34879251f5eSSepherosa Ziehau 	if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
34979251f5eSSepherosa Ziehau 		physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
35079251f5eSSepherosa Ziehau 	if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
35179251f5eSSepherosa Ziehau 		physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
35279251f5eSSepherosa Ziehau 
35379251f5eSSepherosa Ziehau 	return physical_layer;
35479251f5eSSepherosa Ziehau }
35579251f5eSSepherosa Ziehau 
35679251f5eSSepherosa Ziehau /**
35779251f5eSSepherosa Ziehau  *  ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
35879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
35979251f5eSSepherosa Ziehau  *
36079251f5eSSepherosa Ziehau  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
36179251f5eSSepherosa Ziehau  *  ixgbe_hw struct in order to set up EEPROM access.
36279251f5eSSepherosa Ziehau  **/
ixgbe_init_eeprom_params_X540(struct ixgbe_hw * hw)36379251f5eSSepherosa Ziehau s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
36479251f5eSSepherosa Ziehau {
36579251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
36679251f5eSSepherosa Ziehau 	u32 eec;
36779251f5eSSepherosa Ziehau 	u16 eeprom_size;
36879251f5eSSepherosa Ziehau 
36979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_eeprom_params_X540");
37079251f5eSSepherosa Ziehau 
37179251f5eSSepherosa Ziehau 	if (eeprom->type == ixgbe_eeprom_uninitialized) {
37279251f5eSSepherosa Ziehau 		eeprom->semaphore_delay = 10;
37379251f5eSSepherosa Ziehau 		eeprom->type = ixgbe_flash;
37479251f5eSSepherosa Ziehau 
3756150453fSSepherosa Ziehau 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
37679251f5eSSepherosa Ziehau 		eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
37779251f5eSSepherosa Ziehau 				    IXGBE_EEC_SIZE_SHIFT);
37879251f5eSSepherosa Ziehau 		eeprom->word_size = 1 << (eeprom_size +
37979251f5eSSepherosa Ziehau 					  IXGBE_EEPROM_WORD_SIZE_SHIFT);
38079251f5eSSepherosa Ziehau 
38179251f5eSSepherosa Ziehau 		DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
38279251f5eSSepherosa Ziehau 			  eeprom->type, eeprom->word_size);
38379251f5eSSepherosa Ziehau 	}
38479251f5eSSepherosa Ziehau 
38579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
38679251f5eSSepherosa Ziehau }
38779251f5eSSepherosa Ziehau 
38879251f5eSSepherosa Ziehau /**
38979251f5eSSepherosa Ziehau  *  ixgbe_read_eerd_X540- Read EEPROM word using EERD
39079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
39179251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to read
39279251f5eSSepherosa Ziehau  *  @data: word read from the EEPROM
39379251f5eSSepherosa Ziehau  *
39479251f5eSSepherosa Ziehau  *  Reads a 16 bit word from the EEPROM using the EERD register.
39579251f5eSSepherosa Ziehau  **/
ixgbe_read_eerd_X540(struct ixgbe_hw * hw,u16 offset,u16 * data)39679251f5eSSepherosa Ziehau s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
39779251f5eSSepherosa Ziehau {
39879251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
39979251f5eSSepherosa Ziehau 
40079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eerd_X540");
40179251f5eSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
40279251f5eSSepherosa Ziehau 	    IXGBE_SUCCESS) {
40379251f5eSSepherosa Ziehau 		status = ixgbe_read_eerd_generic(hw, offset, data);
40479251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
40579251f5eSSepherosa Ziehau 	} else {
40679251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
40779251f5eSSepherosa Ziehau 	}
40879251f5eSSepherosa Ziehau 
40979251f5eSSepherosa Ziehau 	return status;
41079251f5eSSepherosa Ziehau }
41179251f5eSSepherosa Ziehau 
41279251f5eSSepherosa Ziehau /**
41379251f5eSSepherosa Ziehau  *  ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD
41479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
41579251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to read
41679251f5eSSepherosa Ziehau  *  @words: number of words
41779251f5eSSepherosa Ziehau  *  @data: word(s) read from the EEPROM
41879251f5eSSepherosa Ziehau  *
41979251f5eSSepherosa Ziehau  *  Reads a 16 bit word(s) from the EEPROM using the EERD register.
42079251f5eSSepherosa Ziehau  **/
ixgbe_read_eerd_buffer_X540(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)42179251f5eSSepherosa Ziehau s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
42279251f5eSSepherosa Ziehau 				u16 offset, u16 words, u16 *data)
42379251f5eSSepherosa Ziehau {
42479251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
42579251f5eSSepherosa Ziehau 
42679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eerd_buffer_X540");
42779251f5eSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
42879251f5eSSepherosa Ziehau 	    IXGBE_SUCCESS) {
42979251f5eSSepherosa Ziehau 		status = ixgbe_read_eerd_buffer_generic(hw, offset,
43079251f5eSSepherosa Ziehau 							words, data);
43179251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
43279251f5eSSepherosa Ziehau 	} else {
43379251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
43479251f5eSSepherosa Ziehau 	}
43579251f5eSSepherosa Ziehau 
43679251f5eSSepherosa Ziehau 	return status;
43779251f5eSSepherosa Ziehau }
43879251f5eSSepherosa Ziehau 
43979251f5eSSepherosa Ziehau /**
44079251f5eSSepherosa Ziehau  *  ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
44179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
44279251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
44379251f5eSSepherosa Ziehau  *  @data: word write to the EEPROM
44479251f5eSSepherosa Ziehau  *
44579251f5eSSepherosa Ziehau  *  Write a 16 bit word to the EEPROM using the EEWR register.
44679251f5eSSepherosa Ziehau  **/
ixgbe_write_eewr_X540(struct ixgbe_hw * hw,u16 offset,u16 data)44779251f5eSSepherosa Ziehau s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
44879251f5eSSepherosa Ziehau {
44979251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
45079251f5eSSepherosa Ziehau 
45179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_eewr_X540");
45279251f5eSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
45379251f5eSSepherosa Ziehau 	    IXGBE_SUCCESS) {
45479251f5eSSepherosa Ziehau 		status = ixgbe_write_eewr_generic(hw, offset, data);
45579251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
45679251f5eSSepherosa Ziehau 	} else {
45779251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
45879251f5eSSepherosa Ziehau 	}
45979251f5eSSepherosa Ziehau 
46079251f5eSSepherosa Ziehau 	return status;
46179251f5eSSepherosa Ziehau }
46279251f5eSSepherosa Ziehau 
46379251f5eSSepherosa Ziehau /**
46479251f5eSSepherosa Ziehau  *  ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
46579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
46679251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
46779251f5eSSepherosa Ziehau  *  @words: number of words
46879251f5eSSepherosa Ziehau  *  @data: word(s) write to the EEPROM
46979251f5eSSepherosa Ziehau  *
47079251f5eSSepherosa Ziehau  *  Write a 16 bit word(s) to the EEPROM using the EEWR register.
47179251f5eSSepherosa Ziehau  **/
ixgbe_write_eewr_buffer_X540(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)47279251f5eSSepherosa Ziehau s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
47379251f5eSSepherosa Ziehau 				 u16 offset, u16 words, u16 *data)
47479251f5eSSepherosa Ziehau {
47579251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
47679251f5eSSepherosa Ziehau 
47779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_eewr_buffer_X540");
47879251f5eSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
47979251f5eSSepherosa Ziehau 	    IXGBE_SUCCESS) {
48079251f5eSSepherosa Ziehau 		status = ixgbe_write_eewr_buffer_generic(hw, offset,
48179251f5eSSepherosa Ziehau 							 words, data);
48279251f5eSSepherosa Ziehau 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
48379251f5eSSepherosa Ziehau 	} else {
48479251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
48579251f5eSSepherosa Ziehau 	}
48679251f5eSSepherosa Ziehau 
48779251f5eSSepherosa Ziehau 	return status;
48879251f5eSSepherosa Ziehau }
48979251f5eSSepherosa Ziehau 
49079251f5eSSepherosa Ziehau /**
49179251f5eSSepherosa Ziehau  *  ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
49279251f5eSSepherosa Ziehau  *
49379251f5eSSepherosa Ziehau  *  This function does not use synchronization for EERD and EEWR. It can
49479251f5eSSepherosa Ziehau  *  be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
49579251f5eSSepherosa Ziehau  *
49679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
49763d483cdSSepherosa Ziehau  *
49863d483cdSSepherosa Ziehau  *  Returns a negative error code on error, or the 16-bit checksum
49979251f5eSSepherosa Ziehau  **/
ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw * hw)50063d483cdSSepherosa Ziehau s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
50179251f5eSSepherosa Ziehau {
50263d483cdSSepherosa Ziehau 	u16 i, j;
50379251f5eSSepherosa Ziehau 	u16 checksum = 0;
50479251f5eSSepherosa Ziehau 	u16 length = 0;
50579251f5eSSepherosa Ziehau 	u16 pointer = 0;
50679251f5eSSepherosa Ziehau 	u16 word = 0;
50763d483cdSSepherosa Ziehau 	u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
50879251f5eSSepherosa Ziehau 
50963d483cdSSepherosa Ziehau 	/* Do not use hw->eeprom.ops.read because we do not want to take
51079251f5eSSepherosa Ziehau 	 * the synchronization semaphores here. Instead use
51179251f5eSSepherosa Ziehau 	 * ixgbe_read_eerd_generic
51279251f5eSSepherosa Ziehau 	 */
51379251f5eSSepherosa Ziehau 
51479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
51579251f5eSSepherosa Ziehau 
5166150453fSSepherosa Ziehau 	/* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the
5176150453fSSepherosa Ziehau 	 * checksum itself
5186150453fSSepherosa Ziehau 	 */
5196150453fSSepherosa Ziehau 	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
52063d483cdSSepherosa Ziehau 		if (ixgbe_read_eerd_generic(hw, i, &word)) {
52179251f5eSSepherosa Ziehau 			DEBUGOUT("EEPROM read failed\n");
52263d483cdSSepherosa Ziehau 			return IXGBE_ERR_EEPROM;
52379251f5eSSepherosa Ziehau 		}
52479251f5eSSepherosa Ziehau 		checksum += word;
52579251f5eSSepherosa Ziehau 	}
52679251f5eSSepherosa Ziehau 
52763d483cdSSepherosa Ziehau 	/* Include all data from pointers 0x3, 0x6-0xE.  This excludes the
52879251f5eSSepherosa Ziehau 	 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
52979251f5eSSepherosa Ziehau 	 */
53063d483cdSSepherosa Ziehau 	for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
53179251f5eSSepherosa Ziehau 		if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
53279251f5eSSepherosa Ziehau 			continue;
53379251f5eSSepherosa Ziehau 
53463d483cdSSepherosa Ziehau 		if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
53579251f5eSSepherosa Ziehau 			DEBUGOUT("EEPROM read failed\n");
53663d483cdSSepherosa Ziehau 			return IXGBE_ERR_EEPROM;
53779251f5eSSepherosa Ziehau 		}
53879251f5eSSepherosa Ziehau 
53979251f5eSSepherosa Ziehau 		/* Skip pointer section if the pointer is invalid. */
54079251f5eSSepherosa Ziehau 		if (pointer == 0xFFFF || pointer == 0 ||
54179251f5eSSepherosa Ziehau 		    pointer >= hw->eeprom.word_size)
54279251f5eSSepherosa Ziehau 			continue;
54379251f5eSSepherosa Ziehau 
54463d483cdSSepherosa Ziehau 		if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
54579251f5eSSepherosa Ziehau 			DEBUGOUT("EEPROM read failed\n");
54663d483cdSSepherosa Ziehau 			return IXGBE_ERR_EEPROM;
54779251f5eSSepherosa Ziehau 		}
54879251f5eSSepherosa Ziehau 
54979251f5eSSepherosa Ziehau 		/* Skip pointer section if length is invalid. */
55079251f5eSSepherosa Ziehau 		if (length == 0xFFFF || length == 0 ||
55179251f5eSSepherosa Ziehau 		    (pointer + length) >= hw->eeprom.word_size)
55279251f5eSSepherosa Ziehau 			continue;
55379251f5eSSepherosa Ziehau 
55479251f5eSSepherosa Ziehau 		for (j = pointer + 1; j <= pointer + length; j++) {
55563d483cdSSepherosa Ziehau 			if (ixgbe_read_eerd_generic(hw, j, &word)) {
55679251f5eSSepherosa Ziehau 				DEBUGOUT("EEPROM read failed\n");
55763d483cdSSepherosa Ziehau 				return IXGBE_ERR_EEPROM;
55879251f5eSSepherosa Ziehau 			}
55979251f5eSSepherosa Ziehau 			checksum += word;
56079251f5eSSepherosa Ziehau 		}
56179251f5eSSepherosa Ziehau 	}
56279251f5eSSepherosa Ziehau 
56379251f5eSSepherosa Ziehau 	checksum = (u16)IXGBE_EEPROM_SUM - checksum;
56479251f5eSSepherosa Ziehau 
56563d483cdSSepherosa Ziehau 	return (s32)checksum;
56679251f5eSSepherosa Ziehau }
56779251f5eSSepherosa Ziehau 
56879251f5eSSepherosa Ziehau /**
56979251f5eSSepherosa Ziehau  *  ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
57079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
57179251f5eSSepherosa Ziehau  *  @checksum_val: calculated checksum
57279251f5eSSepherosa Ziehau  *
57379251f5eSSepherosa Ziehau  *  Performs checksum calculation and validates the EEPROM checksum.  If the
57479251f5eSSepherosa Ziehau  *  caller does not need checksum_val, the value can be NULL.
57579251f5eSSepherosa Ziehau  **/
ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw * hw,u16 * checksum_val)57679251f5eSSepherosa Ziehau s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
57779251f5eSSepherosa Ziehau 					u16 *checksum_val)
57879251f5eSSepherosa Ziehau {
57979251f5eSSepherosa Ziehau 	s32 status;
58079251f5eSSepherosa Ziehau 	u16 checksum;
58179251f5eSSepherosa Ziehau 	u16 read_checksum = 0;
58279251f5eSSepherosa Ziehau 
58379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540");
58479251f5eSSepherosa Ziehau 
58563d483cdSSepherosa Ziehau 	/* Read the first word from the EEPROM. If this times out or fails, do
58679251f5eSSepherosa Ziehau 	 * not continue or we could be in for a very long wait while every
58779251f5eSSepherosa Ziehau 	 * EEPROM read fails
58879251f5eSSepherosa Ziehau 	 */
58979251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, 0, &checksum);
59063d483cdSSepherosa Ziehau 	if (status) {
59179251f5eSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
59263d483cdSSepherosa Ziehau 		return status;
59379251f5eSSepherosa Ziehau 	}
59479251f5eSSepherosa Ziehau 
59563d483cdSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
59663d483cdSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
59779251f5eSSepherosa Ziehau 
59863d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.calc_checksum(hw);
59963d483cdSSepherosa Ziehau 	if (status < 0)
60063d483cdSSepherosa Ziehau 		goto out;
60163d483cdSSepherosa Ziehau 
60263d483cdSSepherosa Ziehau 	checksum = (u16)(status & 0xffff);
60363d483cdSSepherosa Ziehau 
60463d483cdSSepherosa Ziehau 	/* Do not use hw->eeprom.ops.read because we do not want to take
60579251f5eSSepherosa Ziehau 	 * the synchronization semaphores twice here.
60679251f5eSSepherosa Ziehau 	 */
60763d483cdSSepherosa Ziehau 	status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
60879251f5eSSepherosa Ziehau 					 &read_checksum);
60963d483cdSSepherosa Ziehau 	if (status)
61063d483cdSSepherosa Ziehau 		goto out;
61179251f5eSSepherosa Ziehau 
61263d483cdSSepherosa Ziehau 	/* Verify read checksum from EEPROM is the same as
61379251f5eSSepherosa Ziehau 	 * calculated checksum
61479251f5eSSepherosa Ziehau 	 */
61579251f5eSSepherosa Ziehau 	if (read_checksum != checksum) {
61679251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
61779251f5eSSepherosa Ziehau 			     "Invalid EEPROM checksum");
61863d483cdSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM_CHECKSUM;
61979251f5eSSepherosa Ziehau 	}
62079251f5eSSepherosa Ziehau 
62179251f5eSSepherosa Ziehau 	/* If the user cares, return the calculated checksum */
62279251f5eSSepherosa Ziehau 	if (checksum_val)
62379251f5eSSepherosa Ziehau 		*checksum_val = checksum;
62479251f5eSSepherosa Ziehau 
62579251f5eSSepherosa Ziehau out:
62663d483cdSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
62763d483cdSSepherosa Ziehau 
62879251f5eSSepherosa Ziehau 	return status;
62979251f5eSSepherosa Ziehau }
63079251f5eSSepherosa Ziehau 
63179251f5eSSepherosa Ziehau /**
63279251f5eSSepherosa Ziehau  * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
63379251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
63479251f5eSSepherosa Ziehau  *
63579251f5eSSepherosa Ziehau  * After writing EEPROM to shadow RAM using EEWR register, software calculates
63679251f5eSSepherosa Ziehau  * checksum and updates the EEPROM and instructs the hardware to update
63779251f5eSSepherosa Ziehau  * the flash.
63879251f5eSSepherosa Ziehau  **/
ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw * hw)63979251f5eSSepherosa Ziehau s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
64079251f5eSSepherosa Ziehau {
64179251f5eSSepherosa Ziehau 	s32 status;
64279251f5eSSepherosa Ziehau 	u16 checksum;
64379251f5eSSepherosa Ziehau 
64479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_eeprom_checksum_X540");
64579251f5eSSepherosa Ziehau 
64663d483cdSSepherosa Ziehau 	/* Read the first word from the EEPROM. If this times out or fails, do
64779251f5eSSepherosa Ziehau 	 * not continue or we could be in for a very long wait while every
64879251f5eSSepherosa Ziehau 	 * EEPROM read fails
64979251f5eSSepherosa Ziehau 	 */
65079251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, 0, &checksum);
65163d483cdSSepherosa Ziehau 	if (status) {
65279251f5eSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
65363d483cdSSepherosa Ziehau 		return status;
65463d483cdSSepherosa Ziehau 	}
65579251f5eSSepherosa Ziehau 
65663d483cdSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
65763d483cdSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
65879251f5eSSepherosa Ziehau 
65963d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.calc_checksum(hw);
66063d483cdSSepherosa Ziehau 	if (status < 0)
66163d483cdSSepherosa Ziehau 		goto out;
66263d483cdSSepherosa Ziehau 
66363d483cdSSepherosa Ziehau 	checksum = (u16)(status & 0xffff);
66463d483cdSSepherosa Ziehau 
66563d483cdSSepherosa Ziehau 	/* Do not use hw->eeprom.ops.write because we do not want to
66679251f5eSSepherosa Ziehau 	 * take the synchronization semaphores twice here.
66779251f5eSSepherosa Ziehau 	 */
66863d483cdSSepherosa Ziehau 	status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
66963d483cdSSepherosa Ziehau 	if (status)
67063d483cdSSepherosa Ziehau 		goto out;
67179251f5eSSepherosa Ziehau 
67279251f5eSSepherosa Ziehau 	status = ixgbe_update_flash_X540(hw);
67363d483cdSSepherosa Ziehau 
67463d483cdSSepherosa Ziehau out:
67579251f5eSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
67679251f5eSSepherosa Ziehau 
67779251f5eSSepherosa Ziehau 	return status;
67879251f5eSSepherosa Ziehau }
67979251f5eSSepherosa Ziehau 
68079251f5eSSepherosa Ziehau /**
68179251f5eSSepherosa Ziehau  *  ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device
68279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
68379251f5eSSepherosa Ziehau  *
68479251f5eSSepherosa Ziehau  *  Set FLUP (bit 23) of the EEC register to instruct Hardware to copy
68579251f5eSSepherosa Ziehau  *  EEPROM from shadow RAM to the flash device.
68679251f5eSSepherosa Ziehau  **/
ixgbe_update_flash_X540(struct ixgbe_hw * hw)68779251f5eSSepherosa Ziehau s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
68879251f5eSSepherosa Ziehau {
68979251f5eSSepherosa Ziehau 	u32 flup;
69063d483cdSSepherosa Ziehau 	s32 status;
69179251f5eSSepherosa Ziehau 
69279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_flash_X540");
69379251f5eSSepherosa Ziehau 
69479251f5eSSepherosa Ziehau 	status = ixgbe_poll_flash_update_done_X540(hw);
69579251f5eSSepherosa Ziehau 	if (status == IXGBE_ERR_EEPROM) {
69679251f5eSSepherosa Ziehau 		DEBUGOUT("Flash update time out\n");
69779251f5eSSepherosa Ziehau 		goto out;
69879251f5eSSepherosa Ziehau 	}
69979251f5eSSepherosa Ziehau 
7006150453fSSepherosa Ziehau 	flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP;
7016150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
70279251f5eSSepherosa Ziehau 
70379251f5eSSepherosa Ziehau 	status = ixgbe_poll_flash_update_done_X540(hw);
70479251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS)
70579251f5eSSepherosa Ziehau 		DEBUGOUT("Flash update complete\n");
70679251f5eSSepherosa Ziehau 	else
70779251f5eSSepherosa Ziehau 		DEBUGOUT("Flash update time out\n");
70879251f5eSSepherosa Ziehau 
70979251f5eSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) {
7106150453fSSepherosa Ziehau 		flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
71179251f5eSSepherosa Ziehau 
71279251f5eSSepherosa Ziehau 		if (flup & IXGBE_EEC_SEC1VAL) {
71379251f5eSSepherosa Ziehau 			flup |= IXGBE_EEC_FLUP;
7146150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
71579251f5eSSepherosa Ziehau 		}
71679251f5eSSepherosa Ziehau 
71779251f5eSSepherosa Ziehau 		status = ixgbe_poll_flash_update_done_X540(hw);
71879251f5eSSepherosa Ziehau 		if (status == IXGBE_SUCCESS)
71979251f5eSSepherosa Ziehau 			DEBUGOUT("Flash update complete\n");
72079251f5eSSepherosa Ziehau 		else
72179251f5eSSepherosa Ziehau 			DEBUGOUT("Flash update time out\n");
72279251f5eSSepherosa Ziehau 	}
72379251f5eSSepherosa Ziehau out:
72479251f5eSSepherosa Ziehau 	return status;
72579251f5eSSepherosa Ziehau }
72679251f5eSSepherosa Ziehau 
72779251f5eSSepherosa Ziehau /**
72879251f5eSSepherosa Ziehau  *  ixgbe_poll_flash_update_done_X540 - Poll flash update status
72979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
73079251f5eSSepherosa Ziehau  *
73179251f5eSSepherosa Ziehau  *  Polls the FLUDONE (bit 26) of the EEC Register to determine when the
73279251f5eSSepherosa Ziehau  *  flash update is done.
73379251f5eSSepherosa Ziehau  **/
ixgbe_poll_flash_update_done_X540(struct ixgbe_hw * hw)73479251f5eSSepherosa Ziehau static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
73579251f5eSSepherosa Ziehau {
73679251f5eSSepherosa Ziehau 	u32 i;
73779251f5eSSepherosa Ziehau 	u32 reg;
73879251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_EEPROM;
73979251f5eSSepherosa Ziehau 
74079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_poll_flash_update_done_X540");
74179251f5eSSepherosa Ziehau 
74279251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
7436150453fSSepherosa Ziehau 		reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
74479251f5eSSepherosa Ziehau 		if (reg & IXGBE_EEC_FLUDONE) {
74579251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
74679251f5eSSepherosa Ziehau 			break;
74779251f5eSSepherosa Ziehau 		}
74863d483cdSSepherosa Ziehau 		msec_delay(5);
74979251f5eSSepherosa Ziehau 	}
75079251f5eSSepherosa Ziehau 
75179251f5eSSepherosa Ziehau 	if (i == IXGBE_FLUDONE_ATTEMPTS)
75279251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
75379251f5eSSepherosa Ziehau 			     "Flash update status polling timed out");
75479251f5eSSepherosa Ziehau 
75579251f5eSSepherosa Ziehau 	return status;
75679251f5eSSepherosa Ziehau }
75779251f5eSSepherosa Ziehau 
75879251f5eSSepherosa Ziehau /**
75979251f5eSSepherosa Ziehau  *  ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore
76079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
76179251f5eSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to acquire
76279251f5eSSepherosa Ziehau  *
76379251f5eSSepherosa Ziehau  *  Acquires the SWFW semaphore thought the SW_FW_SYNC register for
76479251f5eSSepherosa Ziehau  *  the specified function (CSR, PHY0, PHY1, NVM, Flash)
76579251f5eSSepherosa Ziehau  **/
ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw * hw,u32 mask)76663d483cdSSepherosa Ziehau s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
76779251f5eSSepherosa Ziehau {
76863d483cdSSepherosa Ziehau 	u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK;
76963d483cdSSepherosa Ziehau 	u32 fwmask = swmask << 5;
77063d483cdSSepherosa Ziehau 	u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK;
77179251f5eSSepherosa Ziehau 	u32 timeout = 200;
77263d483cdSSepherosa Ziehau 	u32 hwmask = 0;
77363d483cdSSepherosa Ziehau 	u32 swfw_sync;
77479251f5eSSepherosa Ziehau 	u32 i;
77579251f5eSSepherosa Ziehau 
77679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_acquire_swfw_sync_X540");
77779251f5eSSepherosa Ziehau 
77863d483cdSSepherosa Ziehau 	if (swmask & IXGBE_GSSR_EEP_SM)
77963d483cdSSepherosa Ziehau 		hwmask |= IXGBE_GSSR_FLASH_SM;
78079251f5eSSepherosa Ziehau 
78179251f5eSSepherosa Ziehau 	/* SW only mask doesn't have FW bit pair */
78263d483cdSSepherosa Ziehau 	if (mask & IXGBE_GSSR_SW_MNG_SM)
78363d483cdSSepherosa Ziehau 		swmask |= IXGBE_GSSR_SW_MNG_SM;
78479251f5eSSepherosa Ziehau 
78563d483cdSSepherosa Ziehau 	swmask |= swi2c_mask;
78663d483cdSSepherosa Ziehau 	fwmask |= swi2c_mask << 2;
787*dd5ce676SSepherosa Ziehau 	if (hw->mac.type >= ixgbe_mac_X550)
7886150453fSSepherosa Ziehau 		timeout = 1000;
7896150453fSSepherosa Ziehau 
79079251f5eSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
79163d483cdSSepherosa Ziehau 		/* SW NVM semaphore bit is used for access to all
79279251f5eSSepherosa Ziehau 		 * SW_FW_SYNC bits (not just NVM)
79379251f5eSSepherosa Ziehau 		 */
7946150453fSSepherosa Ziehau 		if (ixgbe_get_swfw_sync_semaphore(hw)) {
7956150453fSSepherosa Ziehau 			DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n");
79663d483cdSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
7976150453fSSepherosa Ziehau 		}
79879251f5eSSepherosa Ziehau 
7996150453fSSepherosa Ziehau 		swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
80079251f5eSSepherosa Ziehau 		if (!(swfw_sync & (fwmask | swmask | hwmask))) {
80179251f5eSSepherosa Ziehau 			swfw_sync |= swmask;
8026150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw),
8036150453fSSepherosa Ziehau 					swfw_sync);
80479251f5eSSepherosa Ziehau 			ixgbe_release_swfw_sync_semaphore(hw);
80563d483cdSSepherosa Ziehau 			return IXGBE_SUCCESS;
80663d483cdSSepherosa Ziehau 		}
80763d483cdSSepherosa Ziehau 		/* Firmware currently using resource (fwmask), hardware
80879251f5eSSepherosa Ziehau 		 * currently using resource (hwmask), or other software
80979251f5eSSepherosa Ziehau 		 * thread currently using resource (swmask)
81079251f5eSSepherosa Ziehau 		 */
81179251f5eSSepherosa Ziehau 		ixgbe_release_swfw_sync_semaphore(hw);
81279251f5eSSepherosa Ziehau 		msec_delay(5);
81379251f5eSSepherosa Ziehau 	}
81479251f5eSSepherosa Ziehau 
81579251f5eSSepherosa Ziehau 	/* If the resource is not released by the FW/HW the SW can assume that
81679251f5eSSepherosa Ziehau 	 * the FW/HW malfunctions. In that case the SW should set the SW bit(s)
81779251f5eSSepherosa Ziehau 	 * of the requested resource(s) while ignoring the corresponding FW/HW
81879251f5eSSepherosa Ziehau 	 * bits in the SW_FW_SYNC register.
81979251f5eSSepherosa Ziehau 	 */
8206150453fSSepherosa Ziehau 	if (ixgbe_get_swfw_sync_semaphore(hw)) {
8216150453fSSepherosa Ziehau 		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");
82263d483cdSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
8236150453fSSepherosa Ziehau 	}
8246150453fSSepherosa Ziehau 	swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
82579251f5eSSepherosa Ziehau 	if (swfw_sync & (fwmask | hwmask)) {
82679251f5eSSepherosa Ziehau 		swfw_sync |= swmask;
8276150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
82879251f5eSSepherosa Ziehau 		ixgbe_release_swfw_sync_semaphore(hw);
82979251f5eSSepherosa Ziehau 		msec_delay(5);
83063d483cdSSepherosa Ziehau 		return IXGBE_SUCCESS;
83179251f5eSSepherosa Ziehau 	}
83279251f5eSSepherosa Ziehau 	/* If the resource is not released by other SW the SW can assume that
83379251f5eSSepherosa Ziehau 	 * the other SW malfunctions. In that case the SW should clear all SW
83479251f5eSSepherosa Ziehau 	 * flags that it does not own and then repeat the whole process once
83579251f5eSSepherosa Ziehau 	 * again.
83679251f5eSSepherosa Ziehau 	 */
83763d483cdSSepherosa Ziehau 	if (swfw_sync & swmask) {
83863d483cdSSepherosa Ziehau 		u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
8396150453fSSepherosa Ziehau 			    IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
8406150453fSSepherosa Ziehau 			    IXGBE_GSSR_SW_MNG_SM;
84179251f5eSSepherosa Ziehau 
84263d483cdSSepherosa Ziehau 		if (swi2c_mask)
84363d483cdSSepherosa Ziehau 			rmask |= IXGBE_GSSR_I2C_MASK;
84463d483cdSSepherosa Ziehau 		ixgbe_release_swfw_sync_X540(hw, rmask);
84563d483cdSSepherosa Ziehau 		ixgbe_release_swfw_sync_semaphore(hw);
8466150453fSSepherosa Ziehau 		DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n");
84763d483cdSSepherosa Ziehau 		return IXGBE_ERR_SWFW_SYNC;
84863d483cdSSepherosa Ziehau 	}
84963d483cdSSepherosa Ziehau 	ixgbe_release_swfw_sync_semaphore(hw);
8506150453fSSepherosa Ziehau 	DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n");
85163d483cdSSepherosa Ziehau 
85263d483cdSSepherosa Ziehau 	return IXGBE_ERR_SWFW_SYNC;
85379251f5eSSepherosa Ziehau }
85479251f5eSSepherosa Ziehau 
85579251f5eSSepherosa Ziehau /**
85679251f5eSSepherosa Ziehau  *  ixgbe_release_swfw_sync_X540 - Release SWFW semaphore
85779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
85879251f5eSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to release
85979251f5eSSepherosa Ziehau  *
86079251f5eSSepherosa Ziehau  *  Releases the SWFW semaphore through the SW_FW_SYNC register
86179251f5eSSepherosa Ziehau  *  for the specified function (CSR, PHY0, PHY1, EVM, Flash)
86279251f5eSSepherosa Ziehau  **/
ixgbe_release_swfw_sync_X540(struct ixgbe_hw * hw,u32 mask)86363d483cdSSepherosa Ziehau void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
86479251f5eSSepherosa Ziehau {
86563d483cdSSepherosa Ziehau 	u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM);
86679251f5eSSepherosa Ziehau 	u32 swfw_sync;
86779251f5eSSepherosa Ziehau 
86879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_swfw_sync_X540");
86979251f5eSSepherosa Ziehau 
87063d483cdSSepherosa Ziehau 	if (mask & IXGBE_GSSR_I2C_MASK)
87163d483cdSSepherosa Ziehau 		swmask |= mask & IXGBE_GSSR_I2C_MASK;
87279251f5eSSepherosa Ziehau 	ixgbe_get_swfw_sync_semaphore(hw);
87379251f5eSSepherosa Ziehau 
8746150453fSSepherosa Ziehau 	swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
87579251f5eSSepherosa Ziehau 	swfw_sync &= ~swmask;
8766150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
87779251f5eSSepherosa Ziehau 
87879251f5eSSepherosa Ziehau 	ixgbe_release_swfw_sync_semaphore(hw);
8796150453fSSepherosa Ziehau 	msec_delay(2);
88079251f5eSSepherosa Ziehau }
88179251f5eSSepherosa Ziehau 
88279251f5eSSepherosa Ziehau /**
88363d483cdSSepherosa Ziehau  *  ixgbe_get_swfw_sync_semaphore - Get hardware semaphore
88479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
88579251f5eSSepherosa Ziehau  *
88679251f5eSSepherosa Ziehau  *  Sets the hardware semaphores so SW/FW can gain control of shared resources
88779251f5eSSepherosa Ziehau  **/
ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw * hw)88879251f5eSSepherosa Ziehau static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
88979251f5eSSepherosa Ziehau {
89079251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_EEPROM;
89179251f5eSSepherosa Ziehau 	u32 timeout = 2000;
89279251f5eSSepherosa Ziehau 	u32 i;
89379251f5eSSepherosa Ziehau 	u32 swsm;
89479251f5eSSepherosa Ziehau 
89579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_swfw_sync_semaphore");
89679251f5eSSepherosa Ziehau 
89779251f5eSSepherosa Ziehau 	/* Get SMBI software semaphore between device drivers first */
89879251f5eSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
89979251f5eSSepherosa Ziehau 		/*
90079251f5eSSepherosa Ziehau 		 * If the SMBI bit is 0 when we read it, then the bit will be
90179251f5eSSepherosa Ziehau 		 * set and we have the semaphore
90279251f5eSSepherosa Ziehau 		 */
9036150453fSSepherosa Ziehau 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
90479251f5eSSepherosa Ziehau 		if (!(swsm & IXGBE_SWSM_SMBI)) {
90579251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
90679251f5eSSepherosa Ziehau 			break;
90779251f5eSSepherosa Ziehau 		}
90879251f5eSSepherosa Ziehau 		usec_delay(50);
90979251f5eSSepherosa Ziehau 	}
91079251f5eSSepherosa Ziehau 
91179251f5eSSepherosa Ziehau 	/* Now get the semaphore between SW/FW through the REGSMP bit */
91279251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
91379251f5eSSepherosa Ziehau 		for (i = 0; i < timeout; i++) {
9146150453fSSepherosa Ziehau 			swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
91579251f5eSSepherosa Ziehau 			if (!(swsm & IXGBE_SWFW_REGSMP))
91679251f5eSSepherosa Ziehau 				break;
91779251f5eSSepherosa Ziehau 
91879251f5eSSepherosa Ziehau 			usec_delay(50);
91979251f5eSSepherosa Ziehau 		}
92079251f5eSSepherosa Ziehau 
92179251f5eSSepherosa Ziehau 		/*
92279251f5eSSepherosa Ziehau 		 * Release semaphores and return error if SW NVM semaphore
92379251f5eSSepherosa Ziehau 		 * was not granted because we don't have access to the EEPROM
92479251f5eSSepherosa Ziehau 		 */
92579251f5eSSepherosa Ziehau 		if (i >= timeout) {
92679251f5eSSepherosa Ziehau 			ERROR_REPORT1(IXGBE_ERROR_POLLING,
92779251f5eSSepherosa Ziehau 				"REGSMP Software NVM semaphore not granted.\n");
92879251f5eSSepherosa Ziehau 			ixgbe_release_swfw_sync_semaphore(hw);
92979251f5eSSepherosa Ziehau 			status = IXGBE_ERR_EEPROM;
93079251f5eSSepherosa Ziehau 		}
93179251f5eSSepherosa Ziehau 	} else {
93279251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
93379251f5eSSepherosa Ziehau 			     "Software semaphore SMBI between device drivers "
93479251f5eSSepherosa Ziehau 			     "not granted.\n");
93579251f5eSSepherosa Ziehau 	}
93679251f5eSSepherosa Ziehau 
93779251f5eSSepherosa Ziehau 	return status;
93879251f5eSSepherosa Ziehau }
93979251f5eSSepherosa Ziehau 
94079251f5eSSepherosa Ziehau /**
94163d483cdSSepherosa Ziehau  *  ixgbe_release_swfw_sync_semaphore - Release hardware semaphore
94279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
94379251f5eSSepherosa Ziehau  *
94479251f5eSSepherosa Ziehau  *  This function clears hardware semaphore bits.
94579251f5eSSepherosa Ziehau  **/
ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw * hw)94679251f5eSSepherosa Ziehau static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
94779251f5eSSepherosa Ziehau {
94879251f5eSSepherosa Ziehau 	u32 swsm;
94979251f5eSSepherosa Ziehau 
95079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_swfw_sync_semaphore");
95179251f5eSSepherosa Ziehau 
95279251f5eSSepherosa Ziehau 	/* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
95379251f5eSSepherosa Ziehau 
9546150453fSSepherosa Ziehau 	swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
95579251f5eSSepherosa Ziehau 	swsm &= ~IXGBE_SWFW_REGSMP;
9566150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm);
95779251f5eSSepherosa Ziehau 
9586150453fSSepherosa Ziehau 	swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
95963d483cdSSepherosa Ziehau 	swsm &= ~IXGBE_SWSM_SMBI;
9606150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm);
96163d483cdSSepherosa Ziehau 
96279251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
96379251f5eSSepherosa Ziehau }
96479251f5eSSepherosa Ziehau 
96579251f5eSSepherosa Ziehau /**
9666150453fSSepherosa Ziehau  *  ixgbe_init_swfw_sync_X540 - Release hardware semaphore
9676150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
9686150453fSSepherosa Ziehau  *
9696150453fSSepherosa Ziehau  *  This function reset hardware semaphore bits for a semaphore that may
9706150453fSSepherosa Ziehau  *  have be left locked due to a catastrophic failure.
9716150453fSSepherosa Ziehau  **/
ixgbe_init_swfw_sync_X540(struct ixgbe_hw * hw)9726150453fSSepherosa Ziehau void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
9736150453fSSepherosa Ziehau {
9746150453fSSepherosa Ziehau 	u32 rmask;
9756150453fSSepherosa Ziehau 
9766150453fSSepherosa Ziehau 	/* First try to grab the semaphore but we don't need to bother
9776150453fSSepherosa Ziehau 	 * looking to see whether we got the lock or not since we do
9786150453fSSepherosa Ziehau 	 * the same thing regardless of whether we got the lock or not.
9796150453fSSepherosa Ziehau 	 * We got the lock - we release it.
9806150453fSSepherosa Ziehau 	 * We timeout trying to get the lock - we force its release.
9816150453fSSepherosa Ziehau 	 */
9826150453fSSepherosa Ziehau 	ixgbe_get_swfw_sync_semaphore(hw);
9836150453fSSepherosa Ziehau 	ixgbe_release_swfw_sync_semaphore(hw);
9846150453fSSepherosa Ziehau 
9856150453fSSepherosa Ziehau 	/* Acquire and release all software resources. */
9866150453fSSepherosa Ziehau 	rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
9876150453fSSepherosa Ziehau 		IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
9886150453fSSepherosa Ziehau 		IXGBE_GSSR_SW_MNG_SM;
9896150453fSSepherosa Ziehau 
9906150453fSSepherosa Ziehau 	rmask |= IXGBE_GSSR_I2C_MASK;
9916150453fSSepherosa Ziehau 	ixgbe_acquire_swfw_sync_X540(hw, rmask);
9926150453fSSepherosa Ziehau 	ixgbe_release_swfw_sync_X540(hw, rmask);
9936150453fSSepherosa Ziehau }
9946150453fSSepherosa Ziehau 
9956150453fSSepherosa Ziehau /**
99679251f5eSSepherosa Ziehau  * ixgbe_blink_led_start_X540 - Blink LED based on index.
99779251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
99879251f5eSSepherosa Ziehau  * @index: led number to blink
99979251f5eSSepherosa Ziehau  *
100079251f5eSSepherosa Ziehau  * Devices that implement the version 2 interface:
100179251f5eSSepherosa Ziehau  *   X540
100279251f5eSSepherosa Ziehau  **/
ixgbe_blink_led_start_X540(struct ixgbe_hw * hw,u32 index)100379251f5eSSepherosa Ziehau s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
100479251f5eSSepherosa Ziehau {
100579251f5eSSepherosa Ziehau 	u32 macc_reg;
100679251f5eSSepherosa Ziehau 	u32 ledctl_reg;
100779251f5eSSepherosa Ziehau 	ixgbe_link_speed speed;
100879251f5eSSepherosa Ziehau 	bool link_up;
100979251f5eSSepherosa Ziehau 
101079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_blink_led_start_X540");
101179251f5eSSepherosa Ziehau 
10126150453fSSepherosa Ziehau 	if (index > 3)
10136150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
10146150453fSSepherosa Ziehau 
101579251f5eSSepherosa Ziehau 	/*
101679251f5eSSepherosa Ziehau 	 * Link should be up in order for the blink bit in the LED control
101779251f5eSSepherosa Ziehau 	 * register to work. Force link and speed in the MAC if link is down.
101879251f5eSSepherosa Ziehau 	 * This will be reversed when we stop the blinking.
101979251f5eSSepherosa Ziehau 	 */
102079251f5eSSepherosa Ziehau 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
102179251f5eSSepherosa Ziehau 	if (link_up == FALSE) {
102279251f5eSSepherosa Ziehau 		macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
102379251f5eSSepherosa Ziehau 		macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
102479251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
102579251f5eSSepherosa Ziehau 	}
102679251f5eSSepherosa Ziehau 	/* Set the LED to LINK_UP + BLINK. */
102779251f5eSSepherosa Ziehau 	ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
102879251f5eSSepherosa Ziehau 	ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
102979251f5eSSepherosa Ziehau 	ledctl_reg |= IXGBE_LED_BLINK(index);
103079251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
103179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
103279251f5eSSepherosa Ziehau 
103379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
103479251f5eSSepherosa Ziehau }
103579251f5eSSepherosa Ziehau 
103679251f5eSSepherosa Ziehau /**
103779251f5eSSepherosa Ziehau  * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
103879251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
103979251f5eSSepherosa Ziehau  * @index: led number to stop blinking
104079251f5eSSepherosa Ziehau  *
104179251f5eSSepherosa Ziehau  * Devices that implement the version 2 interface:
104279251f5eSSepherosa Ziehau  *   X540
104379251f5eSSepherosa Ziehau  **/
ixgbe_blink_led_stop_X540(struct ixgbe_hw * hw,u32 index)104479251f5eSSepherosa Ziehau s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
104579251f5eSSepherosa Ziehau {
104679251f5eSSepherosa Ziehau 	u32 macc_reg;
104779251f5eSSepherosa Ziehau 	u32 ledctl_reg;
104879251f5eSSepherosa Ziehau 
10496150453fSSepherosa Ziehau 	if (index > 3)
10506150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
10516150453fSSepherosa Ziehau 
105279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_blink_led_stop_X540");
105379251f5eSSepherosa Ziehau 
105479251f5eSSepherosa Ziehau 	/* Restore the LED to its default value. */
105579251f5eSSepherosa Ziehau 	ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
105679251f5eSSepherosa Ziehau 	ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
105779251f5eSSepherosa Ziehau 	ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
105879251f5eSSepherosa Ziehau 	ledctl_reg &= ~IXGBE_LED_BLINK(index);
105979251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
106079251f5eSSepherosa Ziehau 
106179251f5eSSepherosa Ziehau 	/* Unforce link and speed in the MAC. */
106279251f5eSSepherosa Ziehau 	macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
106379251f5eSSepherosa Ziehau 	macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
106479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
106579251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
106679251f5eSSepherosa Ziehau 
106779251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
106879251f5eSSepherosa Ziehau }
1069