xref: /dflybsd-src/sys/dev/netif/ix/ixgbe_common.c (revision 663b0ef6a01d0fffb45f7acc6da5040d3a4f75e4)
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_common.h"
3679251f5eSSepherosa Ziehau #include "ixgbe_phy.h"
3779251f5eSSepherosa Ziehau #include "ixgbe_dcb.h"
3879251f5eSSepherosa Ziehau #include "ixgbe_dcb_82599.h"
3979251f5eSSepherosa Ziehau #include "ixgbe_api.h"
4079251f5eSSepherosa Ziehau 
4179251f5eSSepherosa Ziehau static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
4279251f5eSSepherosa Ziehau static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
4379251f5eSSepherosa Ziehau static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
4479251f5eSSepherosa Ziehau static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
4579251f5eSSepherosa Ziehau static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
4679251f5eSSepherosa Ziehau static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
4779251f5eSSepherosa Ziehau 					u16 count);
4879251f5eSSepherosa Ziehau static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
4979251f5eSSepherosa Ziehau static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
5079251f5eSSepherosa Ziehau static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
5179251f5eSSepherosa Ziehau static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
5279251f5eSSepherosa Ziehau 
5379251f5eSSepherosa Ziehau static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
5479251f5eSSepherosa Ziehau static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
5579251f5eSSepherosa Ziehau 					 u16 *san_mac_offset);
5679251f5eSSepherosa Ziehau static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
5779251f5eSSepherosa Ziehau 					     u16 words, u16 *data);
5879251f5eSSepherosa Ziehau static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
5979251f5eSSepherosa Ziehau 					      u16 words, u16 *data);
6079251f5eSSepherosa Ziehau static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
6179251f5eSSepherosa Ziehau 						 u16 offset);
6279251f5eSSepherosa Ziehau 
6379251f5eSSepherosa Ziehau /**
6479251f5eSSepherosa Ziehau  *  ixgbe_init_ops_generic - Inits function ptrs
6579251f5eSSepherosa Ziehau  *  @hw: pointer to the hardware structure
6679251f5eSSepherosa Ziehau  *
6779251f5eSSepherosa Ziehau  *  Initialize the function pointers.
6879251f5eSSepherosa Ziehau  **/
ixgbe_init_ops_generic(struct ixgbe_hw * hw)6979251f5eSSepherosa Ziehau s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
7079251f5eSSepherosa Ziehau {
7179251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
7279251f5eSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
736150453fSSepherosa Ziehau 	u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
7479251f5eSSepherosa Ziehau 
7579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_ops_generic");
7679251f5eSSepherosa Ziehau 
7779251f5eSSepherosa Ziehau 	/* EEPROM */
7863d483cdSSepherosa Ziehau 	eeprom->ops.init_params = ixgbe_init_eeprom_params_generic;
7979251f5eSSepherosa Ziehau 	/* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */
8079251f5eSSepherosa Ziehau 	if (eec & IXGBE_EEC_PRES) {
8163d483cdSSepherosa Ziehau 		eeprom->ops.read = ixgbe_read_eerd_generic;
8263d483cdSSepherosa Ziehau 		eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_generic;
8379251f5eSSepherosa Ziehau 	} else {
8463d483cdSSepherosa Ziehau 		eeprom->ops.read = ixgbe_read_eeprom_bit_bang_generic;
8579251f5eSSepherosa Ziehau 		eeprom->ops.read_buffer =
8663d483cdSSepherosa Ziehau 				 ixgbe_read_eeprom_buffer_bit_bang_generic;
8779251f5eSSepherosa Ziehau 	}
8863d483cdSSepherosa Ziehau 	eeprom->ops.write = ixgbe_write_eeprom_generic;
8963d483cdSSepherosa Ziehau 	eeprom->ops.write_buffer = ixgbe_write_eeprom_buffer_bit_bang_generic;
9079251f5eSSepherosa Ziehau 	eeprom->ops.validate_checksum =
9163d483cdSSepherosa Ziehau 				      ixgbe_validate_eeprom_checksum_generic;
9263d483cdSSepherosa Ziehau 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_generic;
9363d483cdSSepherosa Ziehau 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_generic;
9479251f5eSSepherosa Ziehau 
9579251f5eSSepherosa Ziehau 	/* MAC */
9663d483cdSSepherosa Ziehau 	mac->ops.init_hw = ixgbe_init_hw_generic;
9779251f5eSSepherosa Ziehau 	mac->ops.reset_hw = NULL;
9863d483cdSSepherosa Ziehau 	mac->ops.start_hw = ixgbe_start_hw_generic;
9963d483cdSSepherosa Ziehau 	mac->ops.clear_hw_cntrs = ixgbe_clear_hw_cntrs_generic;
10079251f5eSSepherosa Ziehau 	mac->ops.get_media_type = NULL;
10179251f5eSSepherosa Ziehau 	mac->ops.get_supported_physical_layer = NULL;
10263d483cdSSepherosa Ziehau 	mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_generic;
10363d483cdSSepherosa Ziehau 	mac->ops.get_mac_addr = ixgbe_get_mac_addr_generic;
10463d483cdSSepherosa Ziehau 	mac->ops.stop_adapter = ixgbe_stop_adapter_generic;
10563d483cdSSepherosa Ziehau 	mac->ops.get_bus_info = ixgbe_get_bus_info_generic;
10663d483cdSSepherosa Ziehau 	mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie;
10763d483cdSSepherosa Ziehau 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync;
10863d483cdSSepherosa Ziehau 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync;
10963d483cdSSepherosa Ziehau 	mac->ops.prot_autoc_read = prot_autoc_read_generic;
11063d483cdSSepherosa Ziehau 	mac->ops.prot_autoc_write = prot_autoc_write_generic;
11179251f5eSSepherosa Ziehau 
11279251f5eSSepherosa Ziehau 	/* LEDs */
11363d483cdSSepherosa Ziehau 	mac->ops.led_on = ixgbe_led_on_generic;
11463d483cdSSepherosa Ziehau 	mac->ops.led_off = ixgbe_led_off_generic;
11563d483cdSSepherosa Ziehau 	mac->ops.blink_led_start = ixgbe_blink_led_start_generic;
11663d483cdSSepherosa Ziehau 	mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic;
1176150453fSSepherosa Ziehau 	mac->ops.init_led_link_act = ixgbe_init_led_link_act_generic;
11879251f5eSSepherosa Ziehau 
11979251f5eSSepherosa Ziehau 	/* RAR, Multicast, VLAN */
12063d483cdSSepherosa Ziehau 	mac->ops.set_rar = ixgbe_set_rar_generic;
12163d483cdSSepherosa Ziehau 	mac->ops.clear_rar = ixgbe_clear_rar_generic;
12279251f5eSSepherosa Ziehau 	mac->ops.insert_mac_addr = NULL;
12379251f5eSSepherosa Ziehau 	mac->ops.set_vmdq = NULL;
12479251f5eSSepherosa Ziehau 	mac->ops.clear_vmdq = NULL;
12563d483cdSSepherosa Ziehau 	mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic;
12663d483cdSSepherosa Ziehau 	mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic;
12763d483cdSSepherosa Ziehau 	mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic;
12863d483cdSSepherosa Ziehau 	mac->ops.enable_mc = ixgbe_enable_mc_generic;
12963d483cdSSepherosa Ziehau 	mac->ops.disable_mc = ixgbe_disable_mc_generic;
13079251f5eSSepherosa Ziehau 	mac->ops.clear_vfta = NULL;
13179251f5eSSepherosa Ziehau 	mac->ops.set_vfta = NULL;
13279251f5eSSepherosa Ziehau 	mac->ops.set_vlvf = NULL;
13379251f5eSSepherosa Ziehau 	mac->ops.init_uta_tables = NULL;
13463d483cdSSepherosa Ziehau 	mac->ops.enable_rx = ixgbe_enable_rx_generic;
13563d483cdSSepherosa Ziehau 	mac->ops.disable_rx = ixgbe_disable_rx_generic;
13679251f5eSSepherosa Ziehau 
13779251f5eSSepherosa Ziehau 	/* Flow Control */
13863d483cdSSepherosa Ziehau 	mac->ops.fc_enable = ixgbe_fc_enable_generic;
13963d483cdSSepherosa Ziehau 	mac->ops.setup_fc = ixgbe_setup_fc_generic;
1406150453fSSepherosa Ziehau 	mac->ops.fc_autoneg = ixgbe_fc_autoneg;
14179251f5eSSepherosa Ziehau 
14279251f5eSSepherosa Ziehau 	/* Link */
14379251f5eSSepherosa Ziehau 	mac->ops.get_link_capabilities = NULL;
14479251f5eSSepherosa Ziehau 	mac->ops.setup_link = NULL;
14579251f5eSSepherosa Ziehau 	mac->ops.check_link = NULL;
14679251f5eSSepherosa Ziehau 	mac->ops.dmac_config = NULL;
14779251f5eSSepherosa Ziehau 	mac->ops.dmac_update_tcs = NULL;
14879251f5eSSepherosa Ziehau 	mac->ops.dmac_config_tcs = NULL;
14979251f5eSSepherosa Ziehau 
15079251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
15179251f5eSSepherosa Ziehau }
15279251f5eSSepherosa Ziehau 
15379251f5eSSepherosa Ziehau /**
15479251f5eSSepherosa Ziehau  * ixgbe_device_supports_autoneg_fc - Check if device supports autonegotiation
15579251f5eSSepherosa Ziehau  * of flow control
15679251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
15779251f5eSSepherosa Ziehau  *
15879251f5eSSepherosa Ziehau  * This function returns TRUE if the device supports flow control
15979251f5eSSepherosa Ziehau  * autonegotiation, and FALSE if it does not.
16079251f5eSSepherosa Ziehau  *
16179251f5eSSepherosa Ziehau  **/
ixgbe_device_supports_autoneg_fc(struct ixgbe_hw * hw)16279251f5eSSepherosa Ziehau bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
16379251f5eSSepherosa Ziehau {
16479251f5eSSepherosa Ziehau 	bool supported = FALSE;
16579251f5eSSepherosa Ziehau 	ixgbe_link_speed speed;
16679251f5eSSepherosa Ziehau 	bool link_up;
16779251f5eSSepherosa Ziehau 
16879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
16979251f5eSSepherosa Ziehau 
17079251f5eSSepherosa Ziehau 	switch (hw->phy.media_type) {
17179251f5eSSepherosa Ziehau 	case ixgbe_media_type_fiber_fixed:
17263d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber_qsfp:
17379251f5eSSepherosa Ziehau 	case ixgbe_media_type_fiber:
1746150453fSSepherosa Ziehau 		/* flow control autoneg black list */
1756150453fSSepherosa Ziehau 		switch (hw->device_id) {
1766150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_SFP:
1776150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_SFP_N:
1786150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_QSFP:
1796150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_QSFP_N:
1806150453fSSepherosa Ziehau 			supported = FALSE;
1816150453fSSepherosa Ziehau 			break;
1826150453fSSepherosa Ziehau 		default:
18379251f5eSSepherosa Ziehau 			hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
18479251f5eSSepherosa Ziehau 			/* if link is down, assume supported */
18579251f5eSSepherosa Ziehau 			if (link_up)
18679251f5eSSepherosa Ziehau 				supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
18779251f5eSSepherosa Ziehau 				TRUE : FALSE;
18879251f5eSSepherosa Ziehau 			else
18979251f5eSSepherosa Ziehau 				supported = TRUE;
1906150453fSSepherosa Ziehau 		}
1916150453fSSepherosa Ziehau 
19279251f5eSSepherosa Ziehau 		break;
19379251f5eSSepherosa Ziehau 	case ixgbe_media_type_backplane:
1946150453fSSepherosa Ziehau 		if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI)
1956150453fSSepherosa Ziehau 			supported = FALSE;
1966150453fSSepherosa Ziehau 		else
19779251f5eSSepherosa Ziehau 			supported = TRUE;
19879251f5eSSepherosa Ziehau 		break;
19979251f5eSSepherosa Ziehau 	case ixgbe_media_type_copper:
20079251f5eSSepherosa Ziehau 		/* only some copper devices support flow control autoneg */
20179251f5eSSepherosa Ziehau 		switch (hw->device_id) {
20279251f5eSSepherosa Ziehau 		case IXGBE_DEV_ID_82599_T3_LOM:
20379251f5eSSepherosa Ziehau 		case IXGBE_DEV_ID_X540T:
20463d483cdSSepherosa Ziehau 		case IXGBE_DEV_ID_X540T1:
20579251f5eSSepherosa Ziehau 		case IXGBE_DEV_ID_X540_BYPASS:
20663d483cdSSepherosa Ziehau 		case IXGBE_DEV_ID_X550T:
2076150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550T1:
20863d483cdSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_X_10G_T:
2096150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_10G_T:
2106150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_1G_T:
2116150453fSSepherosa Ziehau 		case IXGBE_DEV_ID_X550EM_A_1G_T_L:
21279251f5eSSepherosa Ziehau 			supported = TRUE;
21379251f5eSSepherosa Ziehau 			break;
21479251f5eSSepherosa Ziehau 		default:
21579251f5eSSepherosa Ziehau 			supported = FALSE;
21679251f5eSSepherosa Ziehau 		}
21779251f5eSSepherosa Ziehau 	default:
21879251f5eSSepherosa Ziehau 		break;
21979251f5eSSepherosa Ziehau 	}
22079251f5eSSepherosa Ziehau 
2216150453fSSepherosa Ziehau 	if (!supported)
22279251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
22379251f5eSSepherosa Ziehau 			      "Device %x does not support flow control autoneg",
22479251f5eSSepherosa Ziehau 			      hw->device_id);
22579251f5eSSepherosa Ziehau 	return supported;
22679251f5eSSepherosa Ziehau }
22779251f5eSSepherosa Ziehau 
22879251f5eSSepherosa Ziehau /**
22963d483cdSSepherosa Ziehau  *  ixgbe_setup_fc_generic - Set up flow control
23079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
23179251f5eSSepherosa Ziehau  *
23279251f5eSSepherosa Ziehau  *  Called at init time to set up flow control.
23379251f5eSSepherosa Ziehau  **/
ixgbe_setup_fc_generic(struct ixgbe_hw * hw)23463d483cdSSepherosa Ziehau s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
23579251f5eSSepherosa Ziehau {
23679251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
23779251f5eSSepherosa Ziehau 	u32 reg = 0, reg_bp = 0;
23879251f5eSSepherosa Ziehau 	u16 reg_cu = 0;
23963d483cdSSepherosa Ziehau 	bool locked = FALSE;
24079251f5eSSepherosa Ziehau 
24163d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_fc_generic");
24279251f5eSSepherosa Ziehau 
24363d483cdSSepherosa Ziehau 	/* Validate the requested mode */
24479251f5eSSepherosa Ziehau 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
24579251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
24679251f5eSSepherosa Ziehau 			   "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
24779251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
24879251f5eSSepherosa Ziehau 		goto out;
24979251f5eSSepherosa Ziehau 	}
25079251f5eSSepherosa Ziehau 
25179251f5eSSepherosa Ziehau 	/*
25279251f5eSSepherosa Ziehau 	 * 10gig parts do not have a word in the EEPROM to determine the
25379251f5eSSepherosa Ziehau 	 * default flow control setting, so we explicitly set it to full.
25479251f5eSSepherosa Ziehau 	 */
25579251f5eSSepherosa Ziehau 	if (hw->fc.requested_mode == ixgbe_fc_default)
25679251f5eSSepherosa Ziehau 		hw->fc.requested_mode = ixgbe_fc_full;
25779251f5eSSepherosa Ziehau 
25879251f5eSSepherosa Ziehau 	/*
25979251f5eSSepherosa Ziehau 	 * Set up the 1G and 10G flow control advertisement registers so the
26079251f5eSSepherosa Ziehau 	 * HW will be able to do fc autoneg once the cable is plugged in.  If
26179251f5eSSepherosa Ziehau 	 * we link at 10G, the 1G advertisement is harmless and vice versa.
26279251f5eSSepherosa Ziehau 	 */
26379251f5eSSepherosa Ziehau 	switch (hw->phy.media_type) {
26479251f5eSSepherosa Ziehau 	case ixgbe_media_type_backplane:
26563d483cdSSepherosa Ziehau 		/* some MAC's need RMW protection on AUTOC */
26663d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &reg_bp);
26763d483cdSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
26863d483cdSSepherosa Ziehau 			goto out;
26963d483cdSSepherosa Ziehau 
2706150453fSSepherosa Ziehau 		/* fall through - only backplane uses autoc */
27163d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber_fixed:
27263d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber_qsfp:
27363d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber:
27479251f5eSSepherosa Ziehau 		reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
27563d483cdSSepherosa Ziehau 
27679251f5eSSepherosa Ziehau 		break;
27779251f5eSSepherosa Ziehau 	case ixgbe_media_type_copper:
27879251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
27979251f5eSSepherosa Ziehau 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg_cu);
28079251f5eSSepherosa Ziehau 		break;
28179251f5eSSepherosa Ziehau 	default:
28279251f5eSSepherosa Ziehau 		break;
28379251f5eSSepherosa Ziehau 	}
28479251f5eSSepherosa Ziehau 
28579251f5eSSepherosa Ziehau 	/*
28679251f5eSSepherosa Ziehau 	 * The possible values of fc.requested_mode are:
28779251f5eSSepherosa Ziehau 	 * 0: Flow control is completely disabled
28879251f5eSSepherosa Ziehau 	 * 1: Rx flow control is enabled (we can receive pause frames,
28979251f5eSSepherosa Ziehau 	 *    but not send pause frames).
29079251f5eSSepherosa Ziehau 	 * 2: Tx flow control is enabled (we can send pause frames but
29179251f5eSSepherosa Ziehau 	 *    we do not support receiving pause frames).
29279251f5eSSepherosa Ziehau 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
29379251f5eSSepherosa Ziehau 	 * other: Invalid.
29479251f5eSSepherosa Ziehau 	 */
29579251f5eSSepherosa Ziehau 	switch (hw->fc.requested_mode) {
29679251f5eSSepherosa Ziehau 	case ixgbe_fc_none:
29779251f5eSSepherosa Ziehau 		/* Flow control completely disabled by software override. */
29879251f5eSSepherosa Ziehau 		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
29979251f5eSSepherosa Ziehau 		if (hw->phy.media_type == ixgbe_media_type_backplane)
30079251f5eSSepherosa Ziehau 			reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
30179251f5eSSepherosa Ziehau 				    IXGBE_AUTOC_ASM_PAUSE);
30279251f5eSSepherosa Ziehau 		else if (hw->phy.media_type == ixgbe_media_type_copper)
30379251f5eSSepherosa Ziehau 			reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
30479251f5eSSepherosa Ziehau 		break;
30579251f5eSSepherosa Ziehau 	case ixgbe_fc_tx_pause:
30679251f5eSSepherosa Ziehau 		/*
30779251f5eSSepherosa Ziehau 		 * Tx Flow control is enabled, and Rx Flow control is
30879251f5eSSepherosa Ziehau 		 * disabled by software override.
30979251f5eSSepherosa Ziehau 		 */
31079251f5eSSepherosa Ziehau 		reg |= IXGBE_PCS1GANA_ASM_PAUSE;
31179251f5eSSepherosa Ziehau 		reg &= ~IXGBE_PCS1GANA_SYM_PAUSE;
31279251f5eSSepherosa Ziehau 		if (hw->phy.media_type == ixgbe_media_type_backplane) {
31379251f5eSSepherosa Ziehau 			reg_bp |= IXGBE_AUTOC_ASM_PAUSE;
31479251f5eSSepherosa Ziehau 			reg_bp &= ~IXGBE_AUTOC_SYM_PAUSE;
31579251f5eSSepherosa Ziehau 		} else if (hw->phy.media_type == ixgbe_media_type_copper) {
31679251f5eSSepherosa Ziehau 			reg_cu |= IXGBE_TAF_ASM_PAUSE;
31779251f5eSSepherosa Ziehau 			reg_cu &= ~IXGBE_TAF_SYM_PAUSE;
31879251f5eSSepherosa Ziehau 		}
31979251f5eSSepherosa Ziehau 		break;
32079251f5eSSepherosa Ziehau 	case ixgbe_fc_rx_pause:
32179251f5eSSepherosa Ziehau 		/*
32279251f5eSSepherosa Ziehau 		 * Rx Flow control is enabled and Tx Flow control is
32379251f5eSSepherosa Ziehau 		 * disabled by software override. Since there really
32479251f5eSSepherosa Ziehau 		 * isn't a way to advertise that we are capable of RX
32579251f5eSSepherosa Ziehau 		 * Pause ONLY, we will advertise that we support both
32679251f5eSSepherosa Ziehau 		 * symmetric and asymmetric Rx PAUSE, as such we fall
32779251f5eSSepherosa Ziehau 		 * through to the fc_full statement.  Later, we will
32879251f5eSSepherosa Ziehau 		 * disable the adapter's ability to send PAUSE frames.
32979251f5eSSepherosa Ziehau 		 */
33079251f5eSSepherosa Ziehau 	case ixgbe_fc_full:
33179251f5eSSepherosa Ziehau 		/* Flow control (both Rx and Tx) is enabled by SW override. */
33279251f5eSSepherosa Ziehau 		reg |= IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE;
33379251f5eSSepherosa Ziehau 		if (hw->phy.media_type == ixgbe_media_type_backplane)
33479251f5eSSepherosa Ziehau 			reg_bp |= IXGBE_AUTOC_SYM_PAUSE |
33579251f5eSSepherosa Ziehau 				  IXGBE_AUTOC_ASM_PAUSE;
33679251f5eSSepherosa Ziehau 		else if (hw->phy.media_type == ixgbe_media_type_copper)
33779251f5eSSepherosa Ziehau 			reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE;
33879251f5eSSepherosa Ziehau 		break;
33979251f5eSSepherosa Ziehau 	default:
34079251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
34179251f5eSSepherosa Ziehau 			     "Flow control param set incorrectly\n");
34279251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_CONFIG;
34379251f5eSSepherosa Ziehau 		goto out;
34479251f5eSSepherosa Ziehau 		break;
34579251f5eSSepherosa Ziehau 	}
34679251f5eSSepherosa Ziehau 
34763d483cdSSepherosa Ziehau 	if (hw->mac.type < ixgbe_mac_X540) {
34879251f5eSSepherosa Ziehau 		/*
34979251f5eSSepherosa Ziehau 		 * Enable auto-negotiation between the MAC & PHY;
35079251f5eSSepherosa Ziehau 		 * the MAC will advertise clause 37 flow control.
35179251f5eSSepherosa Ziehau 		 */
35279251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
35379251f5eSSepherosa Ziehau 		reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
35479251f5eSSepherosa Ziehau 
35579251f5eSSepherosa Ziehau 		/* Disable AN timeout */
35679251f5eSSepherosa Ziehau 		if (hw->fc.strict_ieee)
35779251f5eSSepherosa Ziehau 			reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
35879251f5eSSepherosa Ziehau 
35979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
36079251f5eSSepherosa Ziehau 		DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
36179251f5eSSepherosa Ziehau 	}
36279251f5eSSepherosa Ziehau 
36379251f5eSSepherosa Ziehau 	/*
36479251f5eSSepherosa Ziehau 	 * AUTOC restart handles negotiation of 1G and 10G on backplane
36579251f5eSSepherosa Ziehau 	 * and copper. There is no need to set the PCS1GCTL register.
36679251f5eSSepherosa Ziehau 	 *
36779251f5eSSepherosa Ziehau 	 */
36879251f5eSSepherosa Ziehau 	if (hw->phy.media_type == ixgbe_media_type_backplane) {
36979251f5eSSepherosa Ziehau 		reg_bp |= IXGBE_AUTOC_AN_RESTART;
37063d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
37163d483cdSSepherosa Ziehau 		if (ret_val)
37279251f5eSSepherosa Ziehau 			goto out;
37379251f5eSSepherosa Ziehau 	} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
37479251f5eSSepherosa Ziehau 		    (ixgbe_device_supports_autoneg_fc(hw))) {
37579251f5eSSepherosa Ziehau 		hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
37679251f5eSSepherosa Ziehau 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu);
37779251f5eSSepherosa Ziehau 	}
37879251f5eSSepherosa Ziehau 
37963d483cdSSepherosa Ziehau 	DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
38079251f5eSSepherosa Ziehau out:
38179251f5eSSepherosa Ziehau 	return ret_val;
38279251f5eSSepherosa Ziehau }
38379251f5eSSepherosa Ziehau 
38479251f5eSSepherosa Ziehau /**
38579251f5eSSepherosa Ziehau  *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
38679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
38779251f5eSSepherosa Ziehau  *
38879251f5eSSepherosa Ziehau  *  Starts the hardware by filling the bus info structure and media type, clears
38979251f5eSSepherosa Ziehau  *  all on chip counters, initializes receive address registers, multicast
39079251f5eSSepherosa Ziehau  *  table, VLAN filter table, calls routine to set up link and flow control
39179251f5eSSepherosa Ziehau  *  settings, and leaves transmit and receive units disabled and uninitialized
39279251f5eSSepherosa Ziehau  **/
ixgbe_start_hw_generic(struct ixgbe_hw * hw)39379251f5eSSepherosa Ziehau s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
39479251f5eSSepherosa Ziehau {
39579251f5eSSepherosa Ziehau 	s32 ret_val;
39679251f5eSSepherosa Ziehau 	u32 ctrl_ext;
3976150453fSSepherosa Ziehau 	u16 device_caps;
39879251f5eSSepherosa Ziehau 
39979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_start_hw_generic");
40079251f5eSSepherosa Ziehau 
40179251f5eSSepherosa Ziehau 	/* Set the media type */
40279251f5eSSepherosa Ziehau 	hw->phy.media_type = hw->mac.ops.get_media_type(hw);
40379251f5eSSepherosa Ziehau 
40479251f5eSSepherosa Ziehau 	/* PHY ops initialization must be done in reset_hw() */
40579251f5eSSepherosa Ziehau 
40679251f5eSSepherosa Ziehau 	/* Clear the VLAN filter table */
40779251f5eSSepherosa Ziehau 	hw->mac.ops.clear_vfta(hw);
40879251f5eSSepherosa Ziehau 
40979251f5eSSepherosa Ziehau 	/* Clear statistics registers */
41079251f5eSSepherosa Ziehau 	hw->mac.ops.clear_hw_cntrs(hw);
41179251f5eSSepherosa Ziehau 
41279251f5eSSepherosa Ziehau 	/* Set No Snoop Disable */
41379251f5eSSepherosa Ziehau 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
41479251f5eSSepherosa Ziehau 	ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
41579251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
41679251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
41779251f5eSSepherosa Ziehau 
41879251f5eSSepherosa Ziehau 	/* Setup flow control */
41979251f5eSSepherosa Ziehau 	ret_val = ixgbe_setup_fc(hw);
4206150453fSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED) {
4216150453fSSepherosa Ziehau 		DEBUGOUT1("Flow control setup failed, returning %d\n", ret_val);
4226150453fSSepherosa Ziehau 		return ret_val;
4236150453fSSepherosa Ziehau 	}
4246150453fSSepherosa Ziehau 
4256150453fSSepherosa Ziehau 	/* Cache bit indicating need for crosstalk fix */
4266150453fSSepherosa Ziehau 	switch (hw->mac.type) {
4276150453fSSepherosa Ziehau 	case ixgbe_mac_82599EB:
4286150453fSSepherosa Ziehau 	case ixgbe_mac_X550EM_x:
4296150453fSSepherosa Ziehau 	case ixgbe_mac_X550EM_a:
4306150453fSSepherosa Ziehau 		hw->mac.ops.get_device_caps(hw, &device_caps);
4316150453fSSepherosa Ziehau 		if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR)
4326150453fSSepherosa Ziehau 			hw->need_crosstalk_fix = FALSE;
4336150453fSSepherosa Ziehau 		else
4346150453fSSepherosa Ziehau 			hw->need_crosstalk_fix = TRUE;
4356150453fSSepherosa Ziehau 		break;
4366150453fSSepherosa Ziehau 	default:
4376150453fSSepherosa Ziehau 		hw->need_crosstalk_fix = FALSE;
4386150453fSSepherosa Ziehau 		break;
4396150453fSSepherosa Ziehau 	}
44079251f5eSSepherosa Ziehau 
44179251f5eSSepherosa Ziehau 	/* Clear adapter stopped flag */
44279251f5eSSepherosa Ziehau 	hw->adapter_stopped = FALSE;
44379251f5eSSepherosa Ziehau 
4446150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
44579251f5eSSepherosa Ziehau }
44679251f5eSSepherosa Ziehau 
44779251f5eSSepherosa Ziehau /**
44879251f5eSSepherosa Ziehau  *  ixgbe_start_hw_gen2 - Init sequence for common device family
44979251f5eSSepherosa Ziehau  *  @hw: pointer to hw structure
45079251f5eSSepherosa Ziehau  *
45179251f5eSSepherosa Ziehau  * Performs the init sequence common to the second generation
45279251f5eSSepherosa Ziehau  * of 10 GbE devices.
45379251f5eSSepherosa Ziehau  * Devices in the second generation:
45479251f5eSSepherosa Ziehau  *     82599
45579251f5eSSepherosa Ziehau  *     X540
45679251f5eSSepherosa Ziehau  **/
ixgbe_start_hw_gen2(struct ixgbe_hw * hw)45779251f5eSSepherosa Ziehau s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
45879251f5eSSepherosa Ziehau {
45979251f5eSSepherosa Ziehau 	u32 i;
46079251f5eSSepherosa Ziehau 	u32 regval;
46179251f5eSSepherosa Ziehau 
46279251f5eSSepherosa Ziehau 	/* Clear the rate limiters */
46379251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_tx_queues; i++) {
46479251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
46579251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
46679251f5eSSepherosa Ziehau 	}
46779251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
46879251f5eSSepherosa Ziehau 
46979251f5eSSepherosa Ziehau 	/* Disable relaxed ordering */
47079251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_tx_queues; i++) {
47179251f5eSSepherosa Ziehau 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
47279251f5eSSepherosa Ziehau 		regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
47379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
47479251f5eSSepherosa Ziehau 	}
47579251f5eSSepherosa Ziehau 
47679251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_rx_queues; i++) {
47779251f5eSSepherosa Ziehau 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
47879251f5eSSepherosa Ziehau 		regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
47979251f5eSSepherosa Ziehau 			    IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
48079251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
48179251f5eSSepherosa Ziehau 	}
48279251f5eSSepherosa Ziehau 
48379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
48479251f5eSSepherosa Ziehau }
48579251f5eSSepherosa Ziehau 
48679251f5eSSepherosa Ziehau /**
48779251f5eSSepherosa Ziehau  *  ixgbe_init_hw_generic - Generic hardware initialization
48879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
48979251f5eSSepherosa Ziehau  *
49079251f5eSSepherosa Ziehau  *  Initialize the hardware by resetting the hardware, filling the bus info
49179251f5eSSepherosa Ziehau  *  structure and media type, clears all on chip counters, initializes receive
49279251f5eSSepherosa Ziehau  *  address registers, multicast table, VLAN filter table, calls routine to set
49379251f5eSSepherosa Ziehau  *  up link and flow control settings, and leaves transmit and receive units
49479251f5eSSepherosa Ziehau  *  disabled and uninitialized
49579251f5eSSepherosa Ziehau  **/
ixgbe_init_hw_generic(struct ixgbe_hw * hw)49679251f5eSSepherosa Ziehau s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
49779251f5eSSepherosa Ziehau {
49879251f5eSSepherosa Ziehau 	s32 status;
49979251f5eSSepherosa Ziehau 
50079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_hw_generic");
50179251f5eSSepherosa Ziehau 
50279251f5eSSepherosa Ziehau 	/* Reset the hardware */
50379251f5eSSepherosa Ziehau 	status = hw->mac.ops.reset_hw(hw);
50479251f5eSSepherosa Ziehau 
5056150453fSSepherosa Ziehau 	if (status == IXGBE_SUCCESS || status == IXGBE_ERR_SFP_NOT_PRESENT) {
50679251f5eSSepherosa Ziehau 		/* Start the HW */
50779251f5eSSepherosa Ziehau 		status = hw->mac.ops.start_hw(hw);
50879251f5eSSepherosa Ziehau 	}
50979251f5eSSepherosa Ziehau 
5106150453fSSepherosa Ziehau 	/* Initialize the LED link active for LED blink support */
5116150453fSSepherosa Ziehau 	if (hw->mac.ops.init_led_link_act)
5126150453fSSepherosa Ziehau 		hw->mac.ops.init_led_link_act(hw);
5136150453fSSepherosa Ziehau 
5146150453fSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
5156150453fSSepherosa Ziehau 		DEBUGOUT1("Failed to initialize HW, STATUS = %d\n", status);
5166150453fSSepherosa Ziehau 
51779251f5eSSepherosa Ziehau 	return status;
51879251f5eSSepherosa Ziehau }
51979251f5eSSepherosa Ziehau 
52079251f5eSSepherosa Ziehau /**
52179251f5eSSepherosa Ziehau  *  ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
52279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
52379251f5eSSepherosa Ziehau  *
52479251f5eSSepherosa Ziehau  *  Clears all hardware statistics counters by reading them from the hardware
52579251f5eSSepherosa Ziehau  *  Statistics counters are clear on read.
52679251f5eSSepherosa Ziehau  **/
ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw * hw)52779251f5eSSepherosa Ziehau s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
52879251f5eSSepherosa Ziehau {
52979251f5eSSepherosa Ziehau 	u16 i = 0;
53079251f5eSSepherosa Ziehau 
53179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clear_hw_cntrs_generic");
53279251f5eSSepherosa Ziehau 
53379251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_CRCERRS);
53479251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_ILLERRC);
53579251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_ERRBC);
53679251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MSPDC);
53779251f5eSSepherosa Ziehau 	for (i = 0; i < 8; i++)
53879251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_MPC(i));
53979251f5eSSepherosa Ziehau 
54079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MLFC);
54179251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MRFC);
54279251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_RLEC);
54379251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_LXONTXC);
54479251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
54579251f5eSSepherosa Ziehau 	if (hw->mac.type >= ixgbe_mac_82599EB) {
54679251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
54779251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
54879251f5eSSepherosa Ziehau 	} else {
54979251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_LXONRXC);
55079251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
55179251f5eSSepherosa Ziehau 	}
55279251f5eSSepherosa Ziehau 
55379251f5eSSepherosa Ziehau 	for (i = 0; i < 8; i++) {
55479251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
55579251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
55679251f5eSSepherosa Ziehau 		if (hw->mac.type >= ixgbe_mac_82599EB) {
55779251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
55879251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
55979251f5eSSepherosa Ziehau 		} else {
56079251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
56179251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
56279251f5eSSepherosa Ziehau 		}
56379251f5eSSepherosa Ziehau 	}
56479251f5eSSepherosa Ziehau 	if (hw->mac.type >= ixgbe_mac_82599EB)
56579251f5eSSepherosa Ziehau 		for (i = 0; i < 8; i++)
56679251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
56779251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PRC64);
56879251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PRC127);
56979251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PRC255);
57079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PRC511);
57179251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PRC1023);
57279251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PRC1522);
57379251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_GPRC);
57479251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_BPRC);
57579251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MPRC);
57679251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_GPTC);
57779251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_GORCL);
57879251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_GORCH);
57979251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_GOTCL);
58079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_GOTCH);
58179251f5eSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_82598EB)
58279251f5eSSepherosa Ziehau 		for (i = 0; i < 8; i++)
58379251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_RNBC(i));
58479251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_RUC);
58579251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_RFC);
58679251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_ROC);
58779251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_RJC);
58879251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MNGPRC);
58979251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MNGPDC);
59079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MNGPTC);
59179251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_TORL);
59279251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_TORH);
59379251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_TPR);
59479251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_TPT);
59579251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PTC64);
59679251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PTC127);
59779251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PTC255);
59879251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PTC511);
59979251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PTC1023);
60079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_PTC1522);
60179251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_MPTC);
60279251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_BPTC);
60379251f5eSSepherosa Ziehau 	for (i = 0; i < 16; i++) {
60479251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_QPRC(i));
60579251f5eSSepherosa Ziehau 		IXGBE_READ_REG(hw, IXGBE_QPTC(i));
60679251f5eSSepherosa Ziehau 		if (hw->mac.type >= ixgbe_mac_82599EB) {
60779251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QBRC_L(i));
60879251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QBRC_H(i));
60979251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
61079251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QBTC_H(i));
61179251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
61279251f5eSSepherosa Ziehau 		} else {
61379251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QBRC(i));
61479251f5eSSepherosa Ziehau 			IXGBE_READ_REG(hw, IXGBE_QBTC(i));
61579251f5eSSepherosa Ziehau 		}
61679251f5eSSepherosa Ziehau 	}
61779251f5eSSepherosa Ziehau 
61863d483cdSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_X550 || hw->mac.type == ixgbe_mac_X540) {
61979251f5eSSepherosa Ziehau 		if (hw->phy.id == 0)
62079251f5eSSepherosa Ziehau 			ixgbe_identify_phy(hw);
62179251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL,
62279251f5eSSepherosa Ziehau 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
62379251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH,
62479251f5eSSepherosa Ziehau 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
62579251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_LDPCECL,
62679251f5eSSepherosa Ziehau 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
62779251f5eSSepherosa Ziehau 		hw->phy.ops.read_reg(hw, IXGBE_LDPCECH,
62879251f5eSSepherosa Ziehau 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
62979251f5eSSepherosa Ziehau 	}
63079251f5eSSepherosa Ziehau 
63179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
63279251f5eSSepherosa Ziehau }
63379251f5eSSepherosa Ziehau 
63479251f5eSSepherosa Ziehau /**
63579251f5eSSepherosa Ziehau  *  ixgbe_read_pba_string_generic - Reads part number string from EEPROM
63679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
63779251f5eSSepherosa Ziehau  *  @pba_num: stores the part number string from the EEPROM
63879251f5eSSepherosa Ziehau  *  @pba_num_size: part number string buffer length
63979251f5eSSepherosa Ziehau  *
64079251f5eSSepherosa Ziehau  *  Reads the part number string from the EEPROM.
64179251f5eSSepherosa Ziehau  **/
ixgbe_read_pba_string_generic(struct ixgbe_hw * hw,u8 * pba_num,u32 pba_num_size)64279251f5eSSepherosa Ziehau s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
64379251f5eSSepherosa Ziehau 				  u32 pba_num_size)
64479251f5eSSepherosa Ziehau {
64579251f5eSSepherosa Ziehau 	s32 ret_val;
64679251f5eSSepherosa Ziehau 	u16 data;
64779251f5eSSepherosa Ziehau 	u16 pba_ptr;
64879251f5eSSepherosa Ziehau 	u16 offset;
64979251f5eSSepherosa Ziehau 	u16 length;
65079251f5eSSepherosa Ziehau 
65179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_pba_string_generic");
65279251f5eSSepherosa Ziehau 
65379251f5eSSepherosa Ziehau 	if (pba_num == NULL) {
65479251f5eSSepherosa Ziehau 		DEBUGOUT("PBA string buffer was null\n");
65579251f5eSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
65679251f5eSSepherosa Ziehau 	}
65779251f5eSSepherosa Ziehau 
65879251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
65979251f5eSSepherosa Ziehau 	if (ret_val) {
66079251f5eSSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
66179251f5eSSepherosa Ziehau 		return ret_val;
66279251f5eSSepherosa Ziehau 	}
66379251f5eSSepherosa Ziehau 
66479251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr);
66579251f5eSSepherosa Ziehau 	if (ret_val) {
66679251f5eSSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
66779251f5eSSepherosa Ziehau 		return ret_val;
66879251f5eSSepherosa Ziehau 	}
66979251f5eSSepherosa Ziehau 
67079251f5eSSepherosa Ziehau 	/*
67179251f5eSSepherosa Ziehau 	 * if data is not ptr guard the PBA must be in legacy format which
67279251f5eSSepherosa Ziehau 	 * means pba_ptr is actually our second data word for the PBA number
67379251f5eSSepherosa Ziehau 	 * and we can decode it into an ascii string
67479251f5eSSepherosa Ziehau 	 */
67579251f5eSSepherosa Ziehau 	if (data != IXGBE_PBANUM_PTR_GUARD) {
67679251f5eSSepherosa Ziehau 		DEBUGOUT("NVM PBA number is not stored as string\n");
67779251f5eSSepherosa Ziehau 
67879251f5eSSepherosa Ziehau 		/* we will need 11 characters to store the PBA */
67979251f5eSSepherosa Ziehau 		if (pba_num_size < 11) {
68079251f5eSSepherosa Ziehau 			DEBUGOUT("PBA string buffer too small\n");
68179251f5eSSepherosa Ziehau 			return IXGBE_ERR_NO_SPACE;
68279251f5eSSepherosa Ziehau 		}
68379251f5eSSepherosa Ziehau 
68479251f5eSSepherosa Ziehau 		/* extract hex string from data and pba_ptr */
68579251f5eSSepherosa Ziehau 		pba_num[0] = (data >> 12) & 0xF;
68679251f5eSSepherosa Ziehau 		pba_num[1] = (data >> 8) & 0xF;
68779251f5eSSepherosa Ziehau 		pba_num[2] = (data >> 4) & 0xF;
68879251f5eSSepherosa Ziehau 		pba_num[3] = data & 0xF;
68979251f5eSSepherosa Ziehau 		pba_num[4] = (pba_ptr >> 12) & 0xF;
69079251f5eSSepherosa Ziehau 		pba_num[5] = (pba_ptr >> 8) & 0xF;
69179251f5eSSepherosa Ziehau 		pba_num[6] = '-';
69279251f5eSSepherosa Ziehau 		pba_num[7] = 0;
69379251f5eSSepherosa Ziehau 		pba_num[8] = (pba_ptr >> 4) & 0xF;
69479251f5eSSepherosa Ziehau 		pba_num[9] = pba_ptr & 0xF;
69579251f5eSSepherosa Ziehau 
69679251f5eSSepherosa Ziehau 		/* put a null character on the end of our string */
69779251f5eSSepherosa Ziehau 		pba_num[10] = '\0';
69879251f5eSSepherosa Ziehau 
69979251f5eSSepherosa Ziehau 		/* switch all the data but the '-' to hex char */
70079251f5eSSepherosa Ziehau 		for (offset = 0; offset < 10; offset++) {
70179251f5eSSepherosa Ziehau 			if (pba_num[offset] < 0xA)
70279251f5eSSepherosa Ziehau 				pba_num[offset] += '0';
70379251f5eSSepherosa Ziehau 			else if (pba_num[offset] < 0x10)
70479251f5eSSepherosa Ziehau 				pba_num[offset] += 'A' - 0xA;
70579251f5eSSepherosa Ziehau 		}
70679251f5eSSepherosa Ziehau 
70779251f5eSSepherosa Ziehau 		return IXGBE_SUCCESS;
70879251f5eSSepherosa Ziehau 	}
70979251f5eSSepherosa Ziehau 
71079251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length);
71179251f5eSSepherosa Ziehau 	if (ret_val) {
71279251f5eSSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
71379251f5eSSepherosa Ziehau 		return ret_val;
71479251f5eSSepherosa Ziehau 	}
71579251f5eSSepherosa Ziehau 
71679251f5eSSepherosa Ziehau 	if (length == 0xFFFF || length == 0) {
71779251f5eSSepherosa Ziehau 		DEBUGOUT("NVM PBA number section invalid length\n");
71879251f5eSSepherosa Ziehau 		return IXGBE_ERR_PBA_SECTION;
71979251f5eSSepherosa Ziehau 	}
72079251f5eSSepherosa Ziehau 
72179251f5eSSepherosa Ziehau 	/* check if pba_num buffer is big enough */
72279251f5eSSepherosa Ziehau 	if (pba_num_size  < (((u32)length * 2) - 1)) {
72379251f5eSSepherosa Ziehau 		DEBUGOUT("PBA string buffer too small\n");
72479251f5eSSepherosa Ziehau 		return IXGBE_ERR_NO_SPACE;
72579251f5eSSepherosa Ziehau 	}
72679251f5eSSepherosa Ziehau 
72779251f5eSSepherosa Ziehau 	/* trim pba length from start of string */
72879251f5eSSepherosa Ziehau 	pba_ptr++;
72979251f5eSSepherosa Ziehau 	length--;
73079251f5eSSepherosa Ziehau 
73179251f5eSSepherosa Ziehau 	for (offset = 0; offset < length; offset++) {
73279251f5eSSepherosa Ziehau 		ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data);
73379251f5eSSepherosa Ziehau 		if (ret_val) {
73479251f5eSSepherosa Ziehau 			DEBUGOUT("NVM Read Error\n");
73579251f5eSSepherosa Ziehau 			return ret_val;
73679251f5eSSepherosa Ziehau 		}
73779251f5eSSepherosa Ziehau 		pba_num[offset * 2] = (u8)(data >> 8);
73879251f5eSSepherosa Ziehau 		pba_num[(offset * 2) + 1] = (u8)(data & 0xFF);
73979251f5eSSepherosa Ziehau 	}
74079251f5eSSepherosa Ziehau 	pba_num[offset * 2] = '\0';
74179251f5eSSepherosa Ziehau 
74279251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
74379251f5eSSepherosa Ziehau }
74479251f5eSSepherosa Ziehau 
74579251f5eSSepherosa Ziehau /**
74679251f5eSSepherosa Ziehau  *  ixgbe_read_pba_num_generic - Reads part number from EEPROM
74779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
74879251f5eSSepherosa Ziehau  *  @pba_num: stores the part number from the EEPROM
74979251f5eSSepherosa Ziehau  *
75079251f5eSSepherosa Ziehau  *  Reads the part number from the EEPROM.
75179251f5eSSepherosa Ziehau  **/
ixgbe_read_pba_num_generic(struct ixgbe_hw * hw,u32 * pba_num)75279251f5eSSepherosa Ziehau s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
75379251f5eSSepherosa Ziehau {
75479251f5eSSepherosa Ziehau 	s32 ret_val;
75579251f5eSSepherosa Ziehau 	u16 data;
75679251f5eSSepherosa Ziehau 
75779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_pba_num_generic");
75879251f5eSSepherosa Ziehau 
75979251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
76079251f5eSSepherosa Ziehau 	if (ret_val) {
76179251f5eSSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
76279251f5eSSepherosa Ziehau 		return ret_val;
76379251f5eSSepherosa Ziehau 	} else if (data == IXGBE_PBANUM_PTR_GUARD) {
76479251f5eSSepherosa Ziehau 		DEBUGOUT("NVM Not supported\n");
76579251f5eSSepherosa Ziehau 		return IXGBE_NOT_IMPLEMENTED;
76679251f5eSSepherosa Ziehau 	}
76779251f5eSSepherosa Ziehau 	*pba_num = (u32)(data << 16);
76879251f5eSSepherosa Ziehau 
76979251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
77079251f5eSSepherosa Ziehau 	if (ret_val) {
77179251f5eSSepherosa Ziehau 		DEBUGOUT("NVM Read Error\n");
77279251f5eSSepherosa Ziehau 		return ret_val;
77379251f5eSSepherosa Ziehau 	}
77479251f5eSSepherosa Ziehau 	*pba_num |= data;
77579251f5eSSepherosa Ziehau 
77679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
77779251f5eSSepherosa Ziehau }
77879251f5eSSepherosa Ziehau 
77979251f5eSSepherosa Ziehau /**
78079251f5eSSepherosa Ziehau  *  ixgbe_read_pba_raw
78179251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
78279251f5eSSepherosa Ziehau  *  @eeprom_buf: optional pointer to EEPROM image
78379251f5eSSepherosa Ziehau  *  @eeprom_buf_size: size of EEPROM image in words
78479251f5eSSepherosa Ziehau  *  @max_pba_block_size: PBA block size limit
78579251f5eSSepherosa Ziehau  *  @pba: pointer to output PBA structure
78679251f5eSSepherosa Ziehau  *
78779251f5eSSepherosa Ziehau  *  Reads PBA from EEPROM image when eeprom_buf is not NULL.
78879251f5eSSepherosa Ziehau  *  Reads PBA from physical EEPROM device when eeprom_buf is NULL.
78979251f5eSSepherosa Ziehau  *
79079251f5eSSepherosa Ziehau  **/
ixgbe_read_pba_raw(struct ixgbe_hw * hw,u16 * eeprom_buf,u32 eeprom_buf_size,u16 max_pba_block_size,struct ixgbe_pba * pba)79179251f5eSSepherosa Ziehau s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
79279251f5eSSepherosa Ziehau 		       u32 eeprom_buf_size, u16 max_pba_block_size,
79379251f5eSSepherosa Ziehau 		       struct ixgbe_pba *pba)
79479251f5eSSepherosa Ziehau {
79579251f5eSSepherosa Ziehau 	s32 ret_val;
79679251f5eSSepherosa Ziehau 	u16 pba_block_size;
79779251f5eSSepherosa Ziehau 
79879251f5eSSepherosa Ziehau 	if (pba == NULL)
79979251f5eSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
80079251f5eSSepherosa Ziehau 
80179251f5eSSepherosa Ziehau 	if (eeprom_buf == NULL) {
80279251f5eSSepherosa Ziehau 		ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
80379251f5eSSepherosa Ziehau 						     &pba->word[0]);
80479251f5eSSepherosa Ziehau 		if (ret_val)
80579251f5eSSepherosa Ziehau 			return ret_val;
80679251f5eSSepherosa Ziehau 	} else {
80779251f5eSSepherosa Ziehau 		if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
80879251f5eSSepherosa Ziehau 			pba->word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
80979251f5eSSepherosa Ziehau 			pba->word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
81079251f5eSSepherosa Ziehau 		} else {
81179251f5eSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
81279251f5eSSepherosa Ziehau 		}
81379251f5eSSepherosa Ziehau 	}
81479251f5eSSepherosa Ziehau 
81579251f5eSSepherosa Ziehau 	if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
81679251f5eSSepherosa Ziehau 		if (pba->pba_block == NULL)
81779251f5eSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
81879251f5eSSepherosa Ziehau 
81979251f5eSSepherosa Ziehau 		ret_val = ixgbe_get_pba_block_size(hw, eeprom_buf,
82079251f5eSSepherosa Ziehau 						   eeprom_buf_size,
82179251f5eSSepherosa Ziehau 						   &pba_block_size);
82279251f5eSSepherosa Ziehau 		if (ret_val)
82379251f5eSSepherosa Ziehau 			return ret_val;
82479251f5eSSepherosa Ziehau 
82579251f5eSSepherosa Ziehau 		if (pba_block_size > max_pba_block_size)
82679251f5eSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
82779251f5eSSepherosa Ziehau 
82879251f5eSSepherosa Ziehau 		if (eeprom_buf == NULL) {
82979251f5eSSepherosa Ziehau 			ret_val = hw->eeprom.ops.read_buffer(hw, pba->word[1],
83079251f5eSSepherosa Ziehau 							     pba_block_size,
83179251f5eSSepherosa Ziehau 							     pba->pba_block);
83279251f5eSSepherosa Ziehau 			if (ret_val)
83379251f5eSSepherosa Ziehau 				return ret_val;
83479251f5eSSepherosa Ziehau 		} else {
83579251f5eSSepherosa Ziehau 			if (eeprom_buf_size > (u32)(pba->word[1] +
83663d483cdSSepherosa Ziehau 					      pba_block_size)) {
83779251f5eSSepherosa Ziehau 				memcpy(pba->pba_block,
83879251f5eSSepherosa Ziehau 				       &eeprom_buf[pba->word[1]],
83979251f5eSSepherosa Ziehau 				       pba_block_size * sizeof(u16));
84079251f5eSSepherosa Ziehau 			} else {
84179251f5eSSepherosa Ziehau 				return IXGBE_ERR_PARAM;
84279251f5eSSepherosa Ziehau 			}
84379251f5eSSepherosa Ziehau 		}
84479251f5eSSepherosa Ziehau 	}
84579251f5eSSepherosa Ziehau 
84679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
84779251f5eSSepherosa Ziehau }
84879251f5eSSepherosa Ziehau 
84979251f5eSSepherosa Ziehau /**
85079251f5eSSepherosa Ziehau  *  ixgbe_write_pba_raw
85179251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
85279251f5eSSepherosa Ziehau  *  @eeprom_buf: optional pointer to EEPROM image
85379251f5eSSepherosa Ziehau  *  @eeprom_buf_size: size of EEPROM image in words
85479251f5eSSepherosa Ziehau  *  @pba: pointer to PBA structure
85579251f5eSSepherosa Ziehau  *
85679251f5eSSepherosa Ziehau  *  Writes PBA to EEPROM image when eeprom_buf is not NULL.
85779251f5eSSepherosa Ziehau  *  Writes PBA to physical EEPROM device when eeprom_buf is NULL.
85879251f5eSSepherosa Ziehau  *
85979251f5eSSepherosa Ziehau  **/
ixgbe_write_pba_raw(struct ixgbe_hw * hw,u16 * eeprom_buf,u32 eeprom_buf_size,struct ixgbe_pba * pba)86079251f5eSSepherosa Ziehau s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
86179251f5eSSepherosa Ziehau 			u32 eeprom_buf_size, struct ixgbe_pba *pba)
86279251f5eSSepherosa Ziehau {
86379251f5eSSepherosa Ziehau 	s32 ret_val;
86479251f5eSSepherosa Ziehau 
86579251f5eSSepherosa Ziehau 	if (pba == NULL)
86679251f5eSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
86779251f5eSSepherosa Ziehau 
86879251f5eSSepherosa Ziehau 	if (eeprom_buf == NULL) {
86979251f5eSSepherosa Ziehau 		ret_val = hw->eeprom.ops.write_buffer(hw, IXGBE_PBANUM0_PTR, 2,
87079251f5eSSepherosa Ziehau 						      &pba->word[0]);
87179251f5eSSepherosa Ziehau 		if (ret_val)
87279251f5eSSepherosa Ziehau 			return ret_val;
87379251f5eSSepherosa Ziehau 	} else {
87479251f5eSSepherosa Ziehau 		if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
87579251f5eSSepherosa Ziehau 			eeprom_buf[IXGBE_PBANUM0_PTR] = pba->word[0];
87679251f5eSSepherosa Ziehau 			eeprom_buf[IXGBE_PBANUM1_PTR] = pba->word[1];
87779251f5eSSepherosa Ziehau 		} else {
87879251f5eSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
87979251f5eSSepherosa Ziehau 		}
88079251f5eSSepherosa Ziehau 	}
88179251f5eSSepherosa Ziehau 
88279251f5eSSepherosa Ziehau 	if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
88379251f5eSSepherosa Ziehau 		if (pba->pba_block == NULL)
88479251f5eSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
88579251f5eSSepherosa Ziehau 
88679251f5eSSepherosa Ziehau 		if (eeprom_buf == NULL) {
88779251f5eSSepherosa Ziehau 			ret_val = hw->eeprom.ops.write_buffer(hw, pba->word[1],
88879251f5eSSepherosa Ziehau 							      pba->pba_block[0],
88979251f5eSSepherosa Ziehau 							      pba->pba_block);
89079251f5eSSepherosa Ziehau 			if (ret_val)
89179251f5eSSepherosa Ziehau 				return ret_val;
89279251f5eSSepherosa Ziehau 		} else {
89379251f5eSSepherosa Ziehau 			if (eeprom_buf_size > (u32)(pba->word[1] +
89479251f5eSSepherosa Ziehau 					      pba->pba_block[0])) {
89579251f5eSSepherosa Ziehau 				memcpy(&eeprom_buf[pba->word[1]],
89679251f5eSSepherosa Ziehau 				       pba->pba_block,
89779251f5eSSepherosa Ziehau 				       pba->pba_block[0] * sizeof(u16));
89879251f5eSSepherosa Ziehau 			} else {
89979251f5eSSepherosa Ziehau 				return IXGBE_ERR_PARAM;
90079251f5eSSepherosa Ziehau 			}
90179251f5eSSepherosa Ziehau 		}
90279251f5eSSepherosa Ziehau 	}
90379251f5eSSepherosa Ziehau 
90479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
90579251f5eSSepherosa Ziehau }
90679251f5eSSepherosa Ziehau 
90779251f5eSSepherosa Ziehau /**
90879251f5eSSepherosa Ziehau  *  ixgbe_get_pba_block_size
90979251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
91079251f5eSSepherosa Ziehau  *  @eeprom_buf: optional pointer to EEPROM image
91179251f5eSSepherosa Ziehau  *  @eeprom_buf_size: size of EEPROM image in words
91279251f5eSSepherosa Ziehau  *  @pba_data_size: pointer to output variable
91379251f5eSSepherosa Ziehau  *
91479251f5eSSepherosa Ziehau  *  Returns the size of the PBA block in words. Function operates on EEPROM
91579251f5eSSepherosa Ziehau  *  image if the eeprom_buf pointer is not NULL otherwise it accesses physical
91679251f5eSSepherosa Ziehau  *  EEPROM device.
91779251f5eSSepherosa Ziehau  *
91879251f5eSSepherosa Ziehau  **/
ixgbe_get_pba_block_size(struct ixgbe_hw * hw,u16 * eeprom_buf,u32 eeprom_buf_size,u16 * pba_block_size)91979251f5eSSepherosa Ziehau s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
92079251f5eSSepherosa Ziehau 			     u32 eeprom_buf_size, u16 *pba_block_size)
92179251f5eSSepherosa Ziehau {
92279251f5eSSepherosa Ziehau 	s32 ret_val;
92379251f5eSSepherosa Ziehau 	u16 pba_word[2];
92479251f5eSSepherosa Ziehau 	u16 length;
92579251f5eSSepherosa Ziehau 
92679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_pba_block_size");
92779251f5eSSepherosa Ziehau 
92879251f5eSSepherosa Ziehau 	if (eeprom_buf == NULL) {
92979251f5eSSepherosa Ziehau 		ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
93079251f5eSSepherosa Ziehau 						     &pba_word[0]);
93179251f5eSSepherosa Ziehau 		if (ret_val)
93279251f5eSSepherosa Ziehau 			return ret_val;
93379251f5eSSepherosa Ziehau 	} else {
93479251f5eSSepherosa Ziehau 		if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
93579251f5eSSepherosa Ziehau 			pba_word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
93679251f5eSSepherosa Ziehau 			pba_word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
93779251f5eSSepherosa Ziehau 		} else {
93879251f5eSSepherosa Ziehau 			return IXGBE_ERR_PARAM;
93979251f5eSSepherosa Ziehau 		}
94079251f5eSSepherosa Ziehau 	}
94179251f5eSSepherosa Ziehau 
94279251f5eSSepherosa Ziehau 	if (pba_word[0] == IXGBE_PBANUM_PTR_GUARD) {
94379251f5eSSepherosa Ziehau 		if (eeprom_buf == NULL) {
94479251f5eSSepherosa Ziehau 			ret_val = hw->eeprom.ops.read(hw, pba_word[1] + 0,
94579251f5eSSepherosa Ziehau 						      &length);
94679251f5eSSepherosa Ziehau 			if (ret_val)
94779251f5eSSepherosa Ziehau 				return ret_val;
94879251f5eSSepherosa Ziehau 		} else {
94979251f5eSSepherosa Ziehau 			if (eeprom_buf_size > pba_word[1])
95079251f5eSSepherosa Ziehau 				length = eeprom_buf[pba_word[1] + 0];
95179251f5eSSepherosa Ziehau 			else
95279251f5eSSepherosa Ziehau 				return IXGBE_ERR_PARAM;
95379251f5eSSepherosa Ziehau 		}
95479251f5eSSepherosa Ziehau 
95579251f5eSSepherosa Ziehau 		if (length == 0xFFFF || length == 0)
95679251f5eSSepherosa Ziehau 			return IXGBE_ERR_PBA_SECTION;
95779251f5eSSepherosa Ziehau 	} else {
95879251f5eSSepherosa Ziehau 		/* PBA number in legacy format, there is no PBA Block. */
95979251f5eSSepherosa Ziehau 		length = 0;
96079251f5eSSepherosa Ziehau 	}
96179251f5eSSepherosa Ziehau 
96279251f5eSSepherosa Ziehau 	if (pba_block_size != NULL)
96379251f5eSSepherosa Ziehau 		*pba_block_size = length;
96479251f5eSSepherosa Ziehau 
96579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
96679251f5eSSepherosa Ziehau }
96779251f5eSSepherosa Ziehau 
96879251f5eSSepherosa Ziehau /**
96979251f5eSSepherosa Ziehau  *  ixgbe_get_mac_addr_generic - Generic get MAC address
97079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
97179251f5eSSepherosa Ziehau  *  @mac_addr: Adapter MAC address
97279251f5eSSepherosa Ziehau  *
97379251f5eSSepherosa Ziehau  *  Reads the adapter's MAC address from first Receive Address Register (RAR0)
97479251f5eSSepherosa Ziehau  *  A reset of the adapter must be performed prior to calling this function
97579251f5eSSepherosa Ziehau  *  in order for the MAC address to have been loaded from the EEPROM into RAR0
97679251f5eSSepherosa Ziehau  **/
ixgbe_get_mac_addr_generic(struct ixgbe_hw * hw,u8 * mac_addr)97779251f5eSSepherosa Ziehau s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
97879251f5eSSepherosa Ziehau {
97979251f5eSSepherosa Ziehau 	u32 rar_high;
98079251f5eSSepherosa Ziehau 	u32 rar_low;
98179251f5eSSepherosa Ziehau 	u16 i;
98279251f5eSSepherosa Ziehau 
98379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_mac_addr_generic");
98479251f5eSSepherosa Ziehau 
98579251f5eSSepherosa Ziehau 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0));
98679251f5eSSepherosa Ziehau 	rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0));
98779251f5eSSepherosa Ziehau 
98879251f5eSSepherosa Ziehau 	for (i = 0; i < 4; i++)
98979251f5eSSepherosa Ziehau 		mac_addr[i] = (u8)(rar_low >> (i*8));
99079251f5eSSepherosa Ziehau 
99179251f5eSSepherosa Ziehau 	for (i = 0; i < 2; i++)
99279251f5eSSepherosa Ziehau 		mac_addr[i+4] = (u8)(rar_high >> (i*8));
99379251f5eSSepherosa Ziehau 
99479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
99579251f5eSSepherosa Ziehau }
99679251f5eSSepherosa Ziehau 
99779251f5eSSepherosa Ziehau /**
99879251f5eSSepherosa Ziehau  *  ixgbe_set_pci_config_data_generic - Generic store PCI bus info
99979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
100079251f5eSSepherosa Ziehau  *  @link_status: the link status returned by the PCI config space
100179251f5eSSepherosa Ziehau  *
100279251f5eSSepherosa Ziehau  *  Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure
100379251f5eSSepherosa Ziehau  **/
ixgbe_set_pci_config_data_generic(struct ixgbe_hw * hw,u16 link_status)100479251f5eSSepherosa Ziehau void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status)
100579251f5eSSepherosa Ziehau {
100679251f5eSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
100779251f5eSSepherosa Ziehau 
100863d483cdSSepherosa Ziehau 	if (hw->bus.type == ixgbe_bus_type_unknown)
100979251f5eSSepherosa Ziehau 		hw->bus.type = ixgbe_bus_type_pci_express;
101079251f5eSSepherosa Ziehau 
101179251f5eSSepherosa Ziehau 	switch (link_status & IXGBE_PCI_LINK_WIDTH) {
101279251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_WIDTH_1:
101379251f5eSSepherosa Ziehau 		hw->bus.width = ixgbe_bus_width_pcie_x1;
101479251f5eSSepherosa Ziehau 		break;
101579251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_WIDTH_2:
101679251f5eSSepherosa Ziehau 		hw->bus.width = ixgbe_bus_width_pcie_x2;
101779251f5eSSepherosa Ziehau 		break;
101879251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_WIDTH_4:
101979251f5eSSepherosa Ziehau 		hw->bus.width = ixgbe_bus_width_pcie_x4;
102079251f5eSSepherosa Ziehau 		break;
102179251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_WIDTH_8:
102279251f5eSSepherosa Ziehau 		hw->bus.width = ixgbe_bus_width_pcie_x8;
102379251f5eSSepherosa Ziehau 		break;
102479251f5eSSepherosa Ziehau 	default:
102579251f5eSSepherosa Ziehau 		hw->bus.width = ixgbe_bus_width_unknown;
102679251f5eSSepherosa Ziehau 		break;
102779251f5eSSepherosa Ziehau 	}
102879251f5eSSepherosa Ziehau 
102979251f5eSSepherosa Ziehau 	switch (link_status & IXGBE_PCI_LINK_SPEED) {
103079251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_SPEED_2500:
103179251f5eSSepherosa Ziehau 		hw->bus.speed = ixgbe_bus_speed_2500;
103279251f5eSSepherosa Ziehau 		break;
103379251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_SPEED_5000:
103479251f5eSSepherosa Ziehau 		hw->bus.speed = ixgbe_bus_speed_5000;
103579251f5eSSepherosa Ziehau 		break;
103679251f5eSSepherosa Ziehau 	case IXGBE_PCI_LINK_SPEED_8000:
103779251f5eSSepherosa Ziehau 		hw->bus.speed = ixgbe_bus_speed_8000;
103879251f5eSSepherosa Ziehau 		break;
103979251f5eSSepherosa Ziehau 	default:
104079251f5eSSepherosa Ziehau 		hw->bus.speed = ixgbe_bus_speed_unknown;
104179251f5eSSepherosa Ziehau 		break;
104279251f5eSSepherosa Ziehau 	}
104379251f5eSSepherosa Ziehau 
104479251f5eSSepherosa Ziehau 	mac->ops.set_lan_id(hw);
104579251f5eSSepherosa Ziehau }
104679251f5eSSepherosa Ziehau 
104779251f5eSSepherosa Ziehau /**
104879251f5eSSepherosa Ziehau  *  ixgbe_get_bus_info_generic - Generic set PCI bus info
104979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
105079251f5eSSepherosa Ziehau  *
105179251f5eSSepherosa Ziehau  *  Gets the PCI bus info (speed, width, type) then calls helper function to
105279251f5eSSepherosa Ziehau  *  store this data within the ixgbe_hw structure.
105379251f5eSSepherosa Ziehau  **/
ixgbe_get_bus_info_generic(struct ixgbe_hw * hw)105479251f5eSSepherosa Ziehau s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
105579251f5eSSepherosa Ziehau {
105679251f5eSSepherosa Ziehau 	u16 link_status;
105779251f5eSSepherosa Ziehau 
105879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_bus_info_generic");
105979251f5eSSepherosa Ziehau 
106079251f5eSSepherosa Ziehau 	/* Get the negotiated link width and speed from PCI config space */
106179251f5eSSepherosa Ziehau 	link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS);
106279251f5eSSepherosa Ziehau 
106379251f5eSSepherosa Ziehau 	ixgbe_set_pci_config_data_generic(hw, link_status);
106479251f5eSSepherosa Ziehau 
106579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
106679251f5eSSepherosa Ziehau }
106779251f5eSSepherosa Ziehau 
106879251f5eSSepherosa Ziehau /**
106979251f5eSSepherosa Ziehau  *  ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
107079251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
107179251f5eSSepherosa Ziehau  *
10726150453fSSepherosa Ziehau  *  Determines the LAN function id by reading memory-mapped registers and swaps
10736150453fSSepherosa Ziehau  *  the port value if requested, and set MAC instance for devices that share
10746150453fSSepherosa Ziehau  *  CS4227.
107579251f5eSSepherosa Ziehau  **/
ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw * hw)107679251f5eSSepherosa Ziehau void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
107779251f5eSSepherosa Ziehau {
107879251f5eSSepherosa Ziehau 	struct ixgbe_bus_info *bus = &hw->bus;
107979251f5eSSepherosa Ziehau 	u32 reg;
10806150453fSSepherosa Ziehau 	u16 ee_ctrl_4;
108179251f5eSSepherosa Ziehau 
108279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie");
108379251f5eSSepherosa Ziehau 
108479251f5eSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
108579251f5eSSepherosa Ziehau 	bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
10866150453fSSepherosa Ziehau 	bus->lan_id = (u8)bus->func;
108779251f5eSSepherosa Ziehau 
108879251f5eSSepherosa Ziehau 	/* check for a port swap */
10896150453fSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw));
109079251f5eSSepherosa Ziehau 	if (reg & IXGBE_FACTPS_LFS)
109179251f5eSSepherosa Ziehau 		bus->func ^= 0x1;
10926150453fSSepherosa Ziehau 
10936150453fSSepherosa Ziehau 	/* Get MAC instance from EEPROM for configuring CS4227 */
10946150453fSSepherosa Ziehau 	if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) {
10956150453fSSepherosa Ziehau 		hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4);
10966150453fSSepherosa Ziehau 		bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >>
10976150453fSSepherosa Ziehau 				   IXGBE_EE_CTRL_4_INST_ID_SHIFT;
10986150453fSSepherosa Ziehau 	}
109979251f5eSSepherosa Ziehau }
110079251f5eSSepherosa Ziehau 
110179251f5eSSepherosa Ziehau /**
110279251f5eSSepherosa Ziehau  *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
110379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
110479251f5eSSepherosa Ziehau  *
110579251f5eSSepherosa Ziehau  *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
110679251f5eSSepherosa Ziehau  *  disables transmit and receive units. The adapter_stopped flag is used by
110779251f5eSSepherosa Ziehau  *  the shared code and drivers to determine if the adapter is in a stopped
110879251f5eSSepherosa Ziehau  *  state and should not touch the hardware.
110979251f5eSSepherosa Ziehau  **/
ixgbe_stop_adapter_generic(struct ixgbe_hw * hw)111079251f5eSSepherosa Ziehau s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
111179251f5eSSepherosa Ziehau {
111279251f5eSSepherosa Ziehau 	u32 reg_val;
111379251f5eSSepherosa Ziehau 	u16 i;
111479251f5eSSepherosa Ziehau 
111579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_stop_adapter_generic");
111679251f5eSSepherosa Ziehau 
111779251f5eSSepherosa Ziehau 	/*
111879251f5eSSepherosa Ziehau 	 * Set the adapter_stopped flag so other driver functions stop touching
111979251f5eSSepherosa Ziehau 	 * the hardware
112079251f5eSSepherosa Ziehau 	 */
112179251f5eSSepherosa Ziehau 	hw->adapter_stopped = TRUE;
112279251f5eSSepherosa Ziehau 
112379251f5eSSepherosa Ziehau 	/* Disable the receive unit */
112463d483cdSSepherosa Ziehau 	ixgbe_disable_rx(hw);
112579251f5eSSepherosa Ziehau 
112679251f5eSSepherosa Ziehau 	/* Clear interrupt mask to stop interrupts from being generated */
112779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
112879251f5eSSepherosa Ziehau 
112979251f5eSSepherosa Ziehau 	/* Clear any pending interrupts, flush previous writes */
113079251f5eSSepherosa Ziehau 	IXGBE_READ_REG(hw, IXGBE_EICR);
113179251f5eSSepherosa Ziehau 
113279251f5eSSepherosa Ziehau 	/* Disable the transmit unit.  Each queue must be disabled. */
113379251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_tx_queues; i++)
113479251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH);
113579251f5eSSepherosa Ziehau 
113679251f5eSSepherosa Ziehau 	/* Disable the receive unit by stopping each queue */
113779251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_rx_queues; i++) {
113879251f5eSSepherosa Ziehau 		reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
113979251f5eSSepherosa Ziehau 		reg_val &= ~IXGBE_RXDCTL_ENABLE;
114079251f5eSSepherosa Ziehau 		reg_val |= IXGBE_RXDCTL_SWFLSH;
114179251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
114279251f5eSSepherosa Ziehau 	}
114379251f5eSSepherosa Ziehau 
114479251f5eSSepherosa Ziehau 	/* flush all queues disables */
114579251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
114679251f5eSSepherosa Ziehau 	msec_delay(2);
114779251f5eSSepherosa Ziehau 
114879251f5eSSepherosa Ziehau 	/*
114963d483cdSSepherosa Ziehau 	 * Prevent the PCI-E bus from hanging by disabling PCI-E master
115079251f5eSSepherosa Ziehau 	 * access and verify no pending requests
115179251f5eSSepherosa Ziehau 	 */
115279251f5eSSepherosa Ziehau 	return ixgbe_disable_pcie_master(hw);
115379251f5eSSepherosa Ziehau }
115479251f5eSSepherosa Ziehau 
115579251f5eSSepherosa Ziehau /**
11566150453fSSepherosa Ziehau  *  ixgbe_init_led_link_act_generic - Store the LED index link/activity.
11576150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
11586150453fSSepherosa Ziehau  *
11596150453fSSepherosa Ziehau  *  Store the index for the link active LED. This will be used to support
11606150453fSSepherosa Ziehau  *  blinking the LED.
11616150453fSSepherosa Ziehau  **/
ixgbe_init_led_link_act_generic(struct ixgbe_hw * hw)11626150453fSSepherosa Ziehau s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw)
11636150453fSSepherosa Ziehau {
11646150453fSSepherosa Ziehau 	struct ixgbe_mac_info *mac = &hw->mac;
11656150453fSSepherosa Ziehau 	u32 led_reg, led_mode;
11666150453fSSepherosa Ziehau 	u8 i;
11676150453fSSepherosa Ziehau 
11686150453fSSepherosa Ziehau 	led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
11696150453fSSepherosa Ziehau 
11706150453fSSepherosa Ziehau 	/* Get LED link active from the LEDCTL register */
11716150453fSSepherosa Ziehau 	for (i = 0; i < 4; i++) {
11726150453fSSepherosa Ziehau 		led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i);
11736150453fSSepherosa Ziehau 
11746150453fSSepherosa Ziehau 		if ((led_mode & IXGBE_LED_MODE_MASK_BASE) ==
11756150453fSSepherosa Ziehau 		     IXGBE_LED_LINK_ACTIVE) {
11766150453fSSepherosa Ziehau 			mac->led_link_act = i;
11776150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
11786150453fSSepherosa Ziehau 		}
11796150453fSSepherosa Ziehau 	}
11806150453fSSepherosa Ziehau 
11816150453fSSepherosa Ziehau 	/*
11826150453fSSepherosa Ziehau 	 * If LEDCTL register does not have the LED link active set, then use
11836150453fSSepherosa Ziehau 	 * known MAC defaults.
11846150453fSSepherosa Ziehau 	 */
11856150453fSSepherosa Ziehau 	switch (hw->mac.type) {
11866150453fSSepherosa Ziehau 	case ixgbe_mac_X550EM_a:
11876150453fSSepherosa Ziehau 	case ixgbe_mac_X550EM_x:
11886150453fSSepherosa Ziehau 		mac->led_link_act = 1;
11896150453fSSepherosa Ziehau 		break;
11906150453fSSepherosa Ziehau 	default:
11916150453fSSepherosa Ziehau 		mac->led_link_act = 2;
11926150453fSSepherosa Ziehau 	}
11936150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
11946150453fSSepherosa Ziehau }
11956150453fSSepherosa Ziehau 
11966150453fSSepherosa Ziehau /**
119779251f5eSSepherosa Ziehau  *  ixgbe_led_on_generic - Turns on the software controllable LEDs.
119879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
119979251f5eSSepherosa Ziehau  *  @index: led number to turn on
120079251f5eSSepherosa Ziehau  **/
ixgbe_led_on_generic(struct ixgbe_hw * hw,u32 index)120179251f5eSSepherosa Ziehau s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
120279251f5eSSepherosa Ziehau {
120379251f5eSSepherosa Ziehau 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
120479251f5eSSepherosa Ziehau 
120579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_led_on_generic");
120679251f5eSSepherosa Ziehau 
12076150453fSSepherosa Ziehau 	if (index > 3)
12086150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
12096150453fSSepherosa Ziehau 
121079251f5eSSepherosa Ziehau 	/* To turn on the LED, set mode to ON. */
121179251f5eSSepherosa Ziehau 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
121279251f5eSSepherosa Ziehau 	led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
121379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
121479251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
121579251f5eSSepherosa Ziehau 
121679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
121779251f5eSSepherosa Ziehau }
121879251f5eSSepherosa Ziehau 
121979251f5eSSepherosa Ziehau /**
122079251f5eSSepherosa Ziehau  *  ixgbe_led_off_generic - Turns off the software controllable LEDs.
122179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
122279251f5eSSepherosa Ziehau  *  @index: led number to turn off
122379251f5eSSepherosa Ziehau  **/
ixgbe_led_off_generic(struct ixgbe_hw * hw,u32 index)122479251f5eSSepherosa Ziehau s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
122579251f5eSSepherosa Ziehau {
122679251f5eSSepherosa Ziehau 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
122779251f5eSSepherosa Ziehau 
122879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_led_off_generic");
122979251f5eSSepherosa Ziehau 
12306150453fSSepherosa Ziehau 	if (index > 3)
12316150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
12326150453fSSepherosa Ziehau 
123379251f5eSSepherosa Ziehau 	/* To turn off the LED, set mode to OFF. */
123479251f5eSSepherosa Ziehau 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
123579251f5eSSepherosa Ziehau 	led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
123679251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
123779251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
123879251f5eSSepherosa Ziehau 
123979251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
124079251f5eSSepherosa Ziehau }
124179251f5eSSepherosa Ziehau 
124279251f5eSSepherosa Ziehau /**
124379251f5eSSepherosa Ziehau  *  ixgbe_init_eeprom_params_generic - Initialize EEPROM params
124479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
124579251f5eSSepherosa Ziehau  *
124679251f5eSSepherosa Ziehau  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
124779251f5eSSepherosa Ziehau  *  ixgbe_hw struct in order to set up EEPROM access.
124879251f5eSSepherosa Ziehau  **/
ixgbe_init_eeprom_params_generic(struct ixgbe_hw * hw)124979251f5eSSepherosa Ziehau s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
125079251f5eSSepherosa Ziehau {
125179251f5eSSepherosa Ziehau 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
125279251f5eSSepherosa Ziehau 	u32 eec;
125379251f5eSSepherosa Ziehau 	u16 eeprom_size;
125479251f5eSSepherosa Ziehau 
125579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_eeprom_params_generic");
125679251f5eSSepherosa Ziehau 
125779251f5eSSepherosa Ziehau 	if (eeprom->type == ixgbe_eeprom_uninitialized) {
125879251f5eSSepherosa Ziehau 		eeprom->type = ixgbe_eeprom_none;
125979251f5eSSepherosa Ziehau 		/* Set default semaphore delay to 10ms which is a well
126079251f5eSSepherosa Ziehau 		 * tested value */
126179251f5eSSepherosa Ziehau 		eeprom->semaphore_delay = 10;
126279251f5eSSepherosa Ziehau 		/* Clear EEPROM page size, it will be initialized as needed */
126379251f5eSSepherosa Ziehau 		eeprom->word_page_size = 0;
126479251f5eSSepherosa Ziehau 
126579251f5eSSepherosa Ziehau 		/*
126679251f5eSSepherosa Ziehau 		 * Check for EEPROM present first.
126779251f5eSSepherosa Ziehau 		 * If not present leave as none
126879251f5eSSepherosa Ziehau 		 */
12696150453fSSepherosa Ziehau 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
127079251f5eSSepherosa Ziehau 		if (eec & IXGBE_EEC_PRES) {
127179251f5eSSepherosa Ziehau 			eeprom->type = ixgbe_eeprom_spi;
127279251f5eSSepherosa Ziehau 
127379251f5eSSepherosa Ziehau 			/*
127479251f5eSSepherosa Ziehau 			 * SPI EEPROM is assumed here.  This code would need to
127579251f5eSSepherosa Ziehau 			 * change if a future EEPROM is not SPI.
127679251f5eSSepherosa Ziehau 			 */
127779251f5eSSepherosa Ziehau 			eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
127879251f5eSSepherosa Ziehau 					    IXGBE_EEC_SIZE_SHIFT);
127979251f5eSSepherosa Ziehau 			eeprom->word_size = 1 << (eeprom_size +
128079251f5eSSepherosa Ziehau 					     IXGBE_EEPROM_WORD_SIZE_SHIFT);
128179251f5eSSepherosa Ziehau 		}
128279251f5eSSepherosa Ziehau 
128379251f5eSSepherosa Ziehau 		if (eec & IXGBE_EEC_ADDR_SIZE)
128479251f5eSSepherosa Ziehau 			eeprom->address_bits = 16;
128579251f5eSSepherosa Ziehau 		else
128679251f5eSSepherosa Ziehau 			eeprom->address_bits = 8;
128779251f5eSSepherosa Ziehau 		DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: "
128879251f5eSSepherosa Ziehau 			  "%d\n", eeprom->type, eeprom->word_size,
128979251f5eSSepherosa Ziehau 			  eeprom->address_bits);
129079251f5eSSepherosa Ziehau 	}
129179251f5eSSepherosa Ziehau 
129279251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
129379251f5eSSepherosa Ziehau }
129479251f5eSSepherosa Ziehau 
129579251f5eSSepherosa Ziehau /**
129679251f5eSSepherosa Ziehau  *  ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
129779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
129879251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to write
129979251f5eSSepherosa Ziehau  *  @words: number of word(s)
130079251f5eSSepherosa Ziehau  *  @data: 16 bit word(s) to write to EEPROM
130179251f5eSSepherosa Ziehau  *
130279251f5eSSepherosa Ziehau  *  Reads 16 bit word(s) from EEPROM through bit-bang method
130379251f5eSSepherosa Ziehau  **/
ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)130479251f5eSSepherosa Ziehau s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
130579251f5eSSepherosa Ziehau 					       u16 words, u16 *data)
130679251f5eSSepherosa Ziehau {
130779251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
130879251f5eSSepherosa Ziehau 	u16 i, count;
130979251f5eSSepherosa Ziehau 
131079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang_generic");
131179251f5eSSepherosa Ziehau 
131279251f5eSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
131379251f5eSSepherosa Ziehau 
131479251f5eSSepherosa Ziehau 	if (words == 0) {
131579251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_ARGUMENT;
131679251f5eSSepherosa Ziehau 		goto out;
131779251f5eSSepherosa Ziehau 	}
131879251f5eSSepherosa Ziehau 
131979251f5eSSepherosa Ziehau 	if (offset + words > hw->eeprom.word_size) {
132079251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
132179251f5eSSepherosa Ziehau 		goto out;
132279251f5eSSepherosa Ziehau 	}
132379251f5eSSepherosa Ziehau 
132479251f5eSSepherosa Ziehau 	/*
132579251f5eSSepherosa Ziehau 	 * The EEPROM page size cannot be queried from the chip. We do lazy
132679251f5eSSepherosa Ziehau 	 * initialization. It is worth to do that when we write large buffer.
132779251f5eSSepherosa Ziehau 	 */
132879251f5eSSepherosa Ziehau 	if ((hw->eeprom.word_page_size == 0) &&
132979251f5eSSepherosa Ziehau 	    (words > IXGBE_EEPROM_PAGE_SIZE_MAX))
133079251f5eSSepherosa Ziehau 		ixgbe_detect_eeprom_page_size_generic(hw, offset);
133179251f5eSSepherosa Ziehau 
133279251f5eSSepherosa Ziehau 	/*
133379251f5eSSepherosa Ziehau 	 * We cannot hold synchronization semaphores for too long
133479251f5eSSepherosa Ziehau 	 * to avoid other entity starvation. However it is more efficient
133579251f5eSSepherosa Ziehau 	 * to read in bursts than synchronizing access for each word.
133679251f5eSSepherosa Ziehau 	 */
133779251f5eSSepherosa Ziehau 	for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
133879251f5eSSepherosa Ziehau 		count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
133979251f5eSSepherosa Ziehau 			IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
134079251f5eSSepherosa Ziehau 		status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
134179251f5eSSepherosa Ziehau 							    count, &data[i]);
134279251f5eSSepherosa Ziehau 
134379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
134479251f5eSSepherosa Ziehau 			break;
134579251f5eSSepherosa Ziehau 	}
134679251f5eSSepherosa Ziehau 
134779251f5eSSepherosa Ziehau out:
134879251f5eSSepherosa Ziehau 	return status;
134979251f5eSSepherosa Ziehau }
135079251f5eSSepherosa Ziehau 
135179251f5eSSepherosa Ziehau /**
135279251f5eSSepherosa Ziehau  *  ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
135379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
135479251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to be written to
135579251f5eSSepherosa Ziehau  *  @words: number of word(s)
135679251f5eSSepherosa Ziehau  *  @data: 16 bit word(s) to be written to the EEPROM
135779251f5eSSepherosa Ziehau  *
135879251f5eSSepherosa Ziehau  *  If ixgbe_eeprom_update_checksum is not called after this function, the
135979251f5eSSepherosa Ziehau  *  EEPROM will most likely contain an invalid checksum.
136079251f5eSSepherosa Ziehau  **/
ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)136179251f5eSSepherosa Ziehau static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
136279251f5eSSepherosa Ziehau 					      u16 words, u16 *data)
136379251f5eSSepherosa Ziehau {
136479251f5eSSepherosa Ziehau 	s32 status;
136579251f5eSSepherosa Ziehau 	u16 word;
136679251f5eSSepherosa Ziehau 	u16 page_size;
136779251f5eSSepherosa Ziehau 	u16 i;
136879251f5eSSepherosa Ziehau 	u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
136979251f5eSSepherosa Ziehau 
137079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang");
137179251f5eSSepherosa Ziehau 
137279251f5eSSepherosa Ziehau 	/* Prepare the EEPROM for writing  */
137379251f5eSSepherosa Ziehau 	status = ixgbe_acquire_eeprom(hw);
137479251f5eSSepherosa Ziehau 
137579251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
137679251f5eSSepherosa Ziehau 		if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) {
137779251f5eSSepherosa Ziehau 			ixgbe_release_eeprom(hw);
137879251f5eSSepherosa Ziehau 			status = IXGBE_ERR_EEPROM;
137979251f5eSSepherosa Ziehau 		}
138079251f5eSSepherosa Ziehau 	}
138179251f5eSSepherosa Ziehau 
138279251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
138379251f5eSSepherosa Ziehau 		for (i = 0; i < words; i++) {
138479251f5eSSepherosa Ziehau 			ixgbe_standby_eeprom(hw);
138579251f5eSSepherosa Ziehau 
138679251f5eSSepherosa Ziehau 			/*  Send the WRITE ENABLE command (8 bit opcode )  */
138779251f5eSSepherosa Ziehau 			ixgbe_shift_out_eeprom_bits(hw,
138879251f5eSSepherosa Ziehau 						   IXGBE_EEPROM_WREN_OPCODE_SPI,
138979251f5eSSepherosa Ziehau 						   IXGBE_EEPROM_OPCODE_BITS);
139079251f5eSSepherosa Ziehau 
139179251f5eSSepherosa Ziehau 			ixgbe_standby_eeprom(hw);
139279251f5eSSepherosa Ziehau 
139379251f5eSSepherosa Ziehau 			/*
139479251f5eSSepherosa Ziehau 			 * Some SPI eeproms use the 8th address bit embedded
139579251f5eSSepherosa Ziehau 			 * in the opcode
139679251f5eSSepherosa Ziehau 			 */
139779251f5eSSepherosa Ziehau 			if ((hw->eeprom.address_bits == 8) &&
139879251f5eSSepherosa Ziehau 			    ((offset + i) >= 128))
139979251f5eSSepherosa Ziehau 				write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
140079251f5eSSepherosa Ziehau 
140179251f5eSSepherosa Ziehau 			/* Send the Write command (8-bit opcode + addr) */
140279251f5eSSepherosa Ziehau 			ixgbe_shift_out_eeprom_bits(hw, write_opcode,
140379251f5eSSepherosa Ziehau 						    IXGBE_EEPROM_OPCODE_BITS);
140479251f5eSSepherosa Ziehau 			ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
140579251f5eSSepherosa Ziehau 						    hw->eeprom.address_bits);
140679251f5eSSepherosa Ziehau 
140779251f5eSSepherosa Ziehau 			page_size = hw->eeprom.word_page_size;
140879251f5eSSepherosa Ziehau 
140979251f5eSSepherosa Ziehau 			/* Send the data in burst via SPI*/
141079251f5eSSepherosa Ziehau 			do {
141179251f5eSSepherosa Ziehau 				word = data[i];
141279251f5eSSepherosa Ziehau 				word = (word >> 8) | (word << 8);
141379251f5eSSepherosa Ziehau 				ixgbe_shift_out_eeprom_bits(hw, word, 16);
141479251f5eSSepherosa Ziehau 
141579251f5eSSepherosa Ziehau 				if (page_size == 0)
141679251f5eSSepherosa Ziehau 					break;
141779251f5eSSepherosa Ziehau 
141879251f5eSSepherosa Ziehau 				/* do not wrap around page */
141979251f5eSSepherosa Ziehau 				if (((offset + i) & (page_size - 1)) ==
142079251f5eSSepherosa Ziehau 				    (page_size - 1))
142179251f5eSSepherosa Ziehau 					break;
142279251f5eSSepherosa Ziehau 			} while (++i < words);
142379251f5eSSepherosa Ziehau 
142479251f5eSSepherosa Ziehau 			ixgbe_standby_eeprom(hw);
142579251f5eSSepherosa Ziehau 			msec_delay(10);
142679251f5eSSepherosa Ziehau 		}
142779251f5eSSepherosa Ziehau 		/* Done with writing - release the EEPROM */
142879251f5eSSepherosa Ziehau 		ixgbe_release_eeprom(hw);
142979251f5eSSepherosa Ziehau 	}
143079251f5eSSepherosa Ziehau 
143179251f5eSSepherosa Ziehau 	return status;
143279251f5eSSepherosa Ziehau }
143379251f5eSSepherosa Ziehau 
143479251f5eSSepherosa Ziehau /**
143579251f5eSSepherosa Ziehau  *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
143679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
143779251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to be written to
143879251f5eSSepherosa Ziehau  *  @data: 16 bit word to be written to the EEPROM
143979251f5eSSepherosa Ziehau  *
144079251f5eSSepherosa Ziehau  *  If ixgbe_eeprom_update_checksum is not called after this function, the
144179251f5eSSepherosa Ziehau  *  EEPROM will most likely contain an invalid checksum.
144279251f5eSSepherosa Ziehau  **/
ixgbe_write_eeprom_generic(struct ixgbe_hw * hw,u16 offset,u16 data)144379251f5eSSepherosa Ziehau s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
144479251f5eSSepherosa Ziehau {
144579251f5eSSepherosa Ziehau 	s32 status;
144679251f5eSSepherosa Ziehau 
144779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_eeprom_generic");
144879251f5eSSepherosa Ziehau 
144979251f5eSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
145079251f5eSSepherosa Ziehau 
145179251f5eSSepherosa Ziehau 	if (offset >= hw->eeprom.word_size) {
145279251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
145379251f5eSSepherosa Ziehau 		goto out;
145479251f5eSSepherosa Ziehau 	}
145579251f5eSSepherosa Ziehau 
145679251f5eSSepherosa Ziehau 	status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
145779251f5eSSepherosa Ziehau 
145879251f5eSSepherosa Ziehau out:
145979251f5eSSepherosa Ziehau 	return status;
146079251f5eSSepherosa Ziehau }
146179251f5eSSepherosa Ziehau 
146279251f5eSSepherosa Ziehau /**
146379251f5eSSepherosa Ziehau  *  ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
146479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
146579251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to be read
146679251f5eSSepherosa Ziehau  *  @data: read 16 bit words(s) from EEPROM
146779251f5eSSepherosa Ziehau  *  @words: number of word(s)
146879251f5eSSepherosa Ziehau  *
146979251f5eSSepherosa Ziehau  *  Reads 16 bit word(s) from EEPROM through bit-bang method
147079251f5eSSepherosa Ziehau  **/
ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)147179251f5eSSepherosa Ziehau s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
147279251f5eSSepherosa Ziehau 					      u16 words, u16 *data)
147379251f5eSSepherosa Ziehau {
147479251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
147579251f5eSSepherosa Ziehau 	u16 i, count;
147679251f5eSSepherosa Ziehau 
147779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang_generic");
147879251f5eSSepherosa Ziehau 
147979251f5eSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
148079251f5eSSepherosa Ziehau 
148179251f5eSSepherosa Ziehau 	if (words == 0) {
148279251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_ARGUMENT;
148379251f5eSSepherosa Ziehau 		goto out;
148479251f5eSSepherosa Ziehau 	}
148579251f5eSSepherosa Ziehau 
148679251f5eSSepherosa Ziehau 	if (offset + words > hw->eeprom.word_size) {
148779251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
148879251f5eSSepherosa Ziehau 		goto out;
148979251f5eSSepherosa Ziehau 	}
149079251f5eSSepherosa Ziehau 
149179251f5eSSepherosa Ziehau 	/*
149279251f5eSSepherosa Ziehau 	 * We cannot hold synchronization semaphores for too long
149379251f5eSSepherosa Ziehau 	 * to avoid other entity starvation. However it is more efficient
149479251f5eSSepherosa Ziehau 	 * to read in bursts than synchronizing access for each word.
149579251f5eSSepherosa Ziehau 	 */
149679251f5eSSepherosa Ziehau 	for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
149779251f5eSSepherosa Ziehau 		count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
149879251f5eSSepherosa Ziehau 			IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
149979251f5eSSepherosa Ziehau 
150079251f5eSSepherosa Ziehau 		status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
150179251f5eSSepherosa Ziehau 							   count, &data[i]);
150279251f5eSSepherosa Ziehau 
150379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
150479251f5eSSepherosa Ziehau 			break;
150579251f5eSSepherosa Ziehau 	}
150679251f5eSSepherosa Ziehau 
150779251f5eSSepherosa Ziehau out:
150879251f5eSSepherosa Ziehau 	return status;
150979251f5eSSepherosa Ziehau }
151079251f5eSSepherosa Ziehau 
151179251f5eSSepherosa Ziehau /**
151279251f5eSSepherosa Ziehau  *  ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
151379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
151479251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to be read
151579251f5eSSepherosa Ziehau  *  @words: number of word(s)
151679251f5eSSepherosa Ziehau  *  @data: read 16 bit word(s) from EEPROM
151779251f5eSSepherosa Ziehau  *
151879251f5eSSepherosa Ziehau  *  Reads 16 bit word(s) from EEPROM through bit-bang method
151979251f5eSSepherosa Ziehau  **/
ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)152079251f5eSSepherosa Ziehau static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
152179251f5eSSepherosa Ziehau 					     u16 words, u16 *data)
152279251f5eSSepherosa Ziehau {
152379251f5eSSepherosa Ziehau 	s32 status;
152479251f5eSSepherosa Ziehau 	u16 word_in;
152579251f5eSSepherosa Ziehau 	u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
152679251f5eSSepherosa Ziehau 	u16 i;
152779251f5eSSepherosa Ziehau 
152879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang");
152979251f5eSSepherosa Ziehau 
153079251f5eSSepherosa Ziehau 	/* Prepare the EEPROM for reading  */
153179251f5eSSepherosa Ziehau 	status = ixgbe_acquire_eeprom(hw);
153279251f5eSSepherosa Ziehau 
153379251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
153479251f5eSSepherosa Ziehau 		if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) {
153579251f5eSSepherosa Ziehau 			ixgbe_release_eeprom(hw);
153679251f5eSSepherosa Ziehau 			status = IXGBE_ERR_EEPROM;
153779251f5eSSepherosa Ziehau 		}
153879251f5eSSepherosa Ziehau 	}
153979251f5eSSepherosa Ziehau 
154079251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
154179251f5eSSepherosa Ziehau 		for (i = 0; i < words; i++) {
154279251f5eSSepherosa Ziehau 			ixgbe_standby_eeprom(hw);
154379251f5eSSepherosa Ziehau 			/*
154479251f5eSSepherosa Ziehau 			 * Some SPI eeproms use the 8th address bit embedded
154579251f5eSSepherosa Ziehau 			 * in the opcode
154679251f5eSSepherosa Ziehau 			 */
154779251f5eSSepherosa Ziehau 			if ((hw->eeprom.address_bits == 8) &&
154879251f5eSSepherosa Ziehau 			    ((offset + i) >= 128))
154979251f5eSSepherosa Ziehau 				read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
155079251f5eSSepherosa Ziehau 
155179251f5eSSepherosa Ziehau 			/* Send the READ command (opcode + addr) */
155279251f5eSSepherosa Ziehau 			ixgbe_shift_out_eeprom_bits(hw, read_opcode,
155379251f5eSSepherosa Ziehau 						    IXGBE_EEPROM_OPCODE_BITS);
155479251f5eSSepherosa Ziehau 			ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
155579251f5eSSepherosa Ziehau 						    hw->eeprom.address_bits);
155679251f5eSSepherosa Ziehau 
155779251f5eSSepherosa Ziehau 			/* Read the data. */
155879251f5eSSepherosa Ziehau 			word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
155979251f5eSSepherosa Ziehau 			data[i] = (word_in >> 8) | (word_in << 8);
156079251f5eSSepherosa Ziehau 		}
156179251f5eSSepherosa Ziehau 
156279251f5eSSepherosa Ziehau 		/* End this read operation */
156379251f5eSSepherosa Ziehau 		ixgbe_release_eeprom(hw);
156479251f5eSSepherosa Ziehau 	}
156579251f5eSSepherosa Ziehau 
156679251f5eSSepherosa Ziehau 	return status;
156779251f5eSSepherosa Ziehau }
156879251f5eSSepherosa Ziehau 
156979251f5eSSepherosa Ziehau /**
157079251f5eSSepherosa Ziehau  *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
157179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
157279251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to be read
157379251f5eSSepherosa Ziehau  *  @data: read 16 bit value from EEPROM
157479251f5eSSepherosa Ziehau  *
157579251f5eSSepherosa Ziehau  *  Reads 16 bit value from EEPROM through bit-bang method
157679251f5eSSepherosa Ziehau  **/
ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw * hw,u16 offset,u16 * data)157779251f5eSSepherosa Ziehau s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
157879251f5eSSepherosa Ziehau 				       u16 *data)
157979251f5eSSepherosa Ziehau {
158079251f5eSSepherosa Ziehau 	s32 status;
158179251f5eSSepherosa Ziehau 
158279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic");
158379251f5eSSepherosa Ziehau 
158479251f5eSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
158579251f5eSSepherosa Ziehau 
158679251f5eSSepherosa Ziehau 	if (offset >= hw->eeprom.word_size) {
158779251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
158879251f5eSSepherosa Ziehau 		goto out;
158979251f5eSSepherosa Ziehau 	}
159079251f5eSSepherosa Ziehau 
159179251f5eSSepherosa Ziehau 	status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
159279251f5eSSepherosa Ziehau 
159379251f5eSSepherosa Ziehau out:
159479251f5eSSepherosa Ziehau 	return status;
159579251f5eSSepherosa Ziehau }
159679251f5eSSepherosa Ziehau 
159779251f5eSSepherosa Ziehau /**
159879251f5eSSepherosa Ziehau  *  ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
159979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
160079251f5eSSepherosa Ziehau  *  @offset: offset of word in the EEPROM to read
160179251f5eSSepherosa Ziehau  *  @words: number of word(s)
160279251f5eSSepherosa Ziehau  *  @data: 16 bit word(s) from the EEPROM
160379251f5eSSepherosa Ziehau  *
160479251f5eSSepherosa Ziehau  *  Reads a 16 bit word(s) from the EEPROM using the EERD register.
160579251f5eSSepherosa Ziehau  **/
ixgbe_read_eerd_buffer_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)160679251f5eSSepherosa Ziehau s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
160779251f5eSSepherosa Ziehau 				   u16 words, u16 *data)
160879251f5eSSepherosa Ziehau {
160979251f5eSSepherosa Ziehau 	u32 eerd;
161079251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
161179251f5eSSepherosa Ziehau 	u32 i;
161279251f5eSSepherosa Ziehau 
161379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_read_eerd_buffer_generic");
161479251f5eSSepherosa Ziehau 
161579251f5eSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
161679251f5eSSepherosa Ziehau 
161779251f5eSSepherosa Ziehau 	if (words == 0) {
161879251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_ARGUMENT;
161979251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
162079251f5eSSepherosa Ziehau 		goto out;
162179251f5eSSepherosa Ziehau 	}
162279251f5eSSepherosa Ziehau 
162379251f5eSSepherosa Ziehau 	if (offset >= hw->eeprom.word_size) {
162479251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
162579251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
162679251f5eSSepherosa Ziehau 		goto out;
162779251f5eSSepherosa Ziehau 	}
162879251f5eSSepherosa Ziehau 
162979251f5eSSepherosa Ziehau 	for (i = 0; i < words; i++) {
163079251f5eSSepherosa Ziehau 		eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
163179251f5eSSepherosa Ziehau 		       IXGBE_EEPROM_RW_REG_START;
163279251f5eSSepherosa Ziehau 
163379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
163479251f5eSSepherosa Ziehau 		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
163579251f5eSSepherosa Ziehau 
163679251f5eSSepherosa Ziehau 		if (status == IXGBE_SUCCESS) {
163779251f5eSSepherosa Ziehau 			data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
163879251f5eSSepherosa Ziehau 				   IXGBE_EEPROM_RW_REG_DATA);
163979251f5eSSepherosa Ziehau 		} else {
164079251f5eSSepherosa Ziehau 			DEBUGOUT("Eeprom read timed out\n");
164179251f5eSSepherosa Ziehau 			goto out;
164279251f5eSSepherosa Ziehau 		}
164379251f5eSSepherosa Ziehau 	}
164479251f5eSSepherosa Ziehau out:
164579251f5eSSepherosa Ziehau 	return status;
164679251f5eSSepherosa Ziehau }
164779251f5eSSepherosa Ziehau 
164879251f5eSSepherosa Ziehau /**
164979251f5eSSepherosa Ziehau  *  ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
165079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
165179251f5eSSepherosa Ziehau  *  @offset: offset within the EEPROM to be used as a scratch pad
165279251f5eSSepherosa Ziehau  *
165379251f5eSSepherosa Ziehau  *  Discover EEPROM page size by writing marching data at given offset.
165479251f5eSSepherosa Ziehau  *  This function is called only when we are writing a new large buffer
165579251f5eSSepherosa Ziehau  *  at given offset so the data would be overwritten anyway.
165679251f5eSSepherosa Ziehau  **/
ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw * hw,u16 offset)165779251f5eSSepherosa Ziehau static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
165879251f5eSSepherosa Ziehau 						 u16 offset)
165979251f5eSSepherosa Ziehau {
166079251f5eSSepherosa Ziehau 	u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
166179251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
166279251f5eSSepherosa Ziehau 	u16 i;
166379251f5eSSepherosa Ziehau 
166479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_detect_eeprom_page_size_generic");
166579251f5eSSepherosa Ziehau 
166679251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
166779251f5eSSepherosa Ziehau 		data[i] = i;
166879251f5eSSepherosa Ziehau 
166979251f5eSSepherosa Ziehau 	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
167079251f5eSSepherosa Ziehau 	status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
167179251f5eSSepherosa Ziehau 					     IXGBE_EEPROM_PAGE_SIZE_MAX, data);
167279251f5eSSepherosa Ziehau 	hw->eeprom.word_page_size = 0;
167379251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
167479251f5eSSepherosa Ziehau 		goto out;
167579251f5eSSepherosa Ziehau 
167679251f5eSSepherosa Ziehau 	status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
167779251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
167879251f5eSSepherosa Ziehau 		goto out;
167979251f5eSSepherosa Ziehau 
168079251f5eSSepherosa Ziehau 	/*
168179251f5eSSepherosa Ziehau 	 * When writing in burst more than the actual page size
168279251f5eSSepherosa Ziehau 	 * EEPROM address wraps around current page.
168379251f5eSSepherosa Ziehau 	 */
168479251f5eSSepherosa Ziehau 	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
168579251f5eSSepherosa Ziehau 
168679251f5eSSepherosa Ziehau 	DEBUGOUT1("Detected EEPROM page size = %d words.",
168779251f5eSSepherosa Ziehau 		  hw->eeprom.word_page_size);
168879251f5eSSepherosa Ziehau out:
168979251f5eSSepherosa Ziehau 	return status;
169079251f5eSSepherosa Ziehau }
169179251f5eSSepherosa Ziehau 
169279251f5eSSepherosa Ziehau /**
169379251f5eSSepherosa Ziehau  *  ixgbe_read_eerd_generic - Read EEPROM word using EERD
169479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
169579251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to read
169679251f5eSSepherosa Ziehau  *  @data: word read from the EEPROM
169779251f5eSSepherosa Ziehau  *
169879251f5eSSepherosa Ziehau  *  Reads a 16 bit word from the EEPROM using the EERD register.
169979251f5eSSepherosa Ziehau  **/
ixgbe_read_eerd_generic(struct ixgbe_hw * hw,u16 offset,u16 * data)170079251f5eSSepherosa Ziehau s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
170179251f5eSSepherosa Ziehau {
170279251f5eSSepherosa Ziehau 	return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
170379251f5eSSepherosa Ziehau }
170479251f5eSSepherosa Ziehau 
170579251f5eSSepherosa Ziehau /**
170679251f5eSSepherosa Ziehau  *  ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
170779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
170879251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
170979251f5eSSepherosa Ziehau  *  @words: number of word(s)
171079251f5eSSepherosa Ziehau  *  @data: word(s) write to the EEPROM
171179251f5eSSepherosa Ziehau  *
171279251f5eSSepherosa Ziehau  *  Write a 16 bit word(s) to the EEPROM using the EEWR register.
171379251f5eSSepherosa Ziehau  **/
ixgbe_write_eewr_buffer_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)171479251f5eSSepherosa Ziehau s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
171579251f5eSSepherosa Ziehau 				    u16 words, u16 *data)
171679251f5eSSepherosa Ziehau {
171779251f5eSSepherosa Ziehau 	u32 eewr;
171879251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
171979251f5eSSepherosa Ziehau 	u16 i;
172079251f5eSSepherosa Ziehau 
172179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_write_eewr_generic");
172279251f5eSSepherosa Ziehau 
172379251f5eSSepherosa Ziehau 	hw->eeprom.ops.init_params(hw);
172479251f5eSSepherosa Ziehau 
172579251f5eSSepherosa Ziehau 	if (words == 0) {
172679251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_ARGUMENT;
172779251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
172879251f5eSSepherosa Ziehau 		goto out;
172979251f5eSSepherosa Ziehau 	}
173079251f5eSSepherosa Ziehau 
173179251f5eSSepherosa Ziehau 	if (offset >= hw->eeprom.word_size) {
173279251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
173379251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
173479251f5eSSepherosa Ziehau 		goto out;
173579251f5eSSepherosa Ziehau 	}
173679251f5eSSepherosa Ziehau 
173779251f5eSSepherosa Ziehau 	for (i = 0; i < words; i++) {
173879251f5eSSepherosa Ziehau 		eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
173979251f5eSSepherosa Ziehau 			(data[i] << IXGBE_EEPROM_RW_REG_DATA) |
174079251f5eSSepherosa Ziehau 			IXGBE_EEPROM_RW_REG_START;
174179251f5eSSepherosa Ziehau 
174279251f5eSSepherosa Ziehau 		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
174379251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS) {
174479251f5eSSepherosa Ziehau 			DEBUGOUT("Eeprom write EEWR timed out\n");
174579251f5eSSepherosa Ziehau 			goto out;
174679251f5eSSepherosa Ziehau 		}
174779251f5eSSepherosa Ziehau 
174879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
174979251f5eSSepherosa Ziehau 
175079251f5eSSepherosa Ziehau 		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
175179251f5eSSepherosa Ziehau 		if (status != IXGBE_SUCCESS) {
175279251f5eSSepherosa Ziehau 			DEBUGOUT("Eeprom write EEWR timed out\n");
175379251f5eSSepherosa Ziehau 			goto out;
175479251f5eSSepherosa Ziehau 		}
175579251f5eSSepherosa Ziehau 	}
175679251f5eSSepherosa Ziehau 
175779251f5eSSepherosa Ziehau out:
175879251f5eSSepherosa Ziehau 	return status;
175979251f5eSSepherosa Ziehau }
176079251f5eSSepherosa Ziehau 
176179251f5eSSepherosa Ziehau /**
176279251f5eSSepherosa Ziehau  *  ixgbe_write_eewr_generic - Write EEPROM word using EEWR
176379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
176479251f5eSSepherosa Ziehau  *  @offset: offset of  word in the EEPROM to write
176579251f5eSSepherosa Ziehau  *  @data: word write to the EEPROM
176679251f5eSSepherosa Ziehau  *
176779251f5eSSepherosa Ziehau  *  Write a 16 bit word to the EEPROM using the EEWR register.
176879251f5eSSepherosa Ziehau  **/
ixgbe_write_eewr_generic(struct ixgbe_hw * hw,u16 offset,u16 data)176979251f5eSSepherosa Ziehau s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
177079251f5eSSepherosa Ziehau {
177179251f5eSSepherosa Ziehau 	return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
177279251f5eSSepherosa Ziehau }
177379251f5eSSepherosa Ziehau 
177479251f5eSSepherosa Ziehau /**
177579251f5eSSepherosa Ziehau  *  ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
177679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
177779251f5eSSepherosa Ziehau  *  @ee_reg: EEPROM flag for polling
177879251f5eSSepherosa Ziehau  *
177979251f5eSSepherosa Ziehau  *  Polls the status bit (bit 1) of the EERD or EEWR to determine when the
178079251f5eSSepherosa Ziehau  *  read or write is done respectively.
178179251f5eSSepherosa Ziehau  **/
ixgbe_poll_eerd_eewr_done(struct ixgbe_hw * hw,u32 ee_reg)178279251f5eSSepherosa Ziehau s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
178379251f5eSSepherosa Ziehau {
178479251f5eSSepherosa Ziehau 	u32 i;
178579251f5eSSepherosa Ziehau 	u32 reg;
178679251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_EEPROM;
178779251f5eSSepherosa Ziehau 
178879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_poll_eerd_eewr_done");
178979251f5eSSepherosa Ziehau 
179079251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) {
179179251f5eSSepherosa Ziehau 		if (ee_reg == IXGBE_NVM_POLL_READ)
179279251f5eSSepherosa Ziehau 			reg = IXGBE_READ_REG(hw, IXGBE_EERD);
179379251f5eSSepherosa Ziehau 		else
179479251f5eSSepherosa Ziehau 			reg = IXGBE_READ_REG(hw, IXGBE_EEWR);
179579251f5eSSepherosa Ziehau 
179679251f5eSSepherosa Ziehau 		if (reg & IXGBE_EEPROM_RW_REG_DONE) {
179779251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
179879251f5eSSepherosa Ziehau 			break;
179979251f5eSSepherosa Ziehau 		}
180079251f5eSSepherosa Ziehau 		usec_delay(5);
180179251f5eSSepherosa Ziehau 	}
180279251f5eSSepherosa Ziehau 
180379251f5eSSepherosa Ziehau 	if (i == IXGBE_EERD_EEWR_ATTEMPTS)
180479251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
180579251f5eSSepherosa Ziehau 			     "EEPROM read/write done polling timed out");
180679251f5eSSepherosa Ziehau 
180779251f5eSSepherosa Ziehau 	return status;
180879251f5eSSepherosa Ziehau }
180979251f5eSSepherosa Ziehau 
181079251f5eSSepherosa Ziehau /**
181179251f5eSSepherosa Ziehau  *  ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
181279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
181379251f5eSSepherosa Ziehau  *
181479251f5eSSepherosa Ziehau  *  Prepares EEPROM for access using bit-bang method. This function should
181579251f5eSSepherosa Ziehau  *  be called before issuing a command to the EEPROM.
181679251f5eSSepherosa Ziehau  **/
ixgbe_acquire_eeprom(struct ixgbe_hw * hw)181779251f5eSSepherosa Ziehau static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
181879251f5eSSepherosa Ziehau {
181979251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
182079251f5eSSepherosa Ziehau 	u32 eec;
182179251f5eSSepherosa Ziehau 	u32 i;
182279251f5eSSepherosa Ziehau 
182379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_acquire_eeprom");
182479251f5eSSepherosa Ziehau 
182579251f5eSSepherosa Ziehau 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)
182679251f5eSSepherosa Ziehau 	    != IXGBE_SUCCESS)
182779251f5eSSepherosa Ziehau 		status = IXGBE_ERR_SWFW_SYNC;
182879251f5eSSepherosa Ziehau 
182979251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
18306150453fSSepherosa Ziehau 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
183179251f5eSSepherosa Ziehau 
183279251f5eSSepherosa Ziehau 		/* Request EEPROM Access */
183379251f5eSSepherosa Ziehau 		eec |= IXGBE_EEC_REQ;
18346150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
183579251f5eSSepherosa Ziehau 
183679251f5eSSepherosa Ziehau 		for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
18376150453fSSepherosa Ziehau 			eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
183879251f5eSSepherosa Ziehau 			if (eec & IXGBE_EEC_GNT)
183979251f5eSSepherosa Ziehau 				break;
184079251f5eSSepherosa Ziehau 			usec_delay(5);
184179251f5eSSepherosa Ziehau 		}
184279251f5eSSepherosa Ziehau 
184379251f5eSSepherosa Ziehau 		/* Release if grant not acquired */
184479251f5eSSepherosa Ziehau 		if (!(eec & IXGBE_EEC_GNT)) {
184579251f5eSSepherosa Ziehau 			eec &= ~IXGBE_EEC_REQ;
18466150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
184779251f5eSSepherosa Ziehau 			DEBUGOUT("Could not acquire EEPROM grant\n");
184879251f5eSSepherosa Ziehau 
184979251f5eSSepherosa Ziehau 			hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
185079251f5eSSepherosa Ziehau 			status = IXGBE_ERR_EEPROM;
185179251f5eSSepherosa Ziehau 		}
185279251f5eSSepherosa Ziehau 
185379251f5eSSepherosa Ziehau 		/* Setup EEPROM for Read/Write */
185479251f5eSSepherosa Ziehau 		if (status == IXGBE_SUCCESS) {
185579251f5eSSepherosa Ziehau 			/* Clear CS and SK */
185679251f5eSSepherosa Ziehau 			eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
18576150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
185879251f5eSSepherosa Ziehau 			IXGBE_WRITE_FLUSH(hw);
185979251f5eSSepherosa Ziehau 			usec_delay(1);
186079251f5eSSepherosa Ziehau 		}
186179251f5eSSepherosa Ziehau 	}
186279251f5eSSepherosa Ziehau 	return status;
186379251f5eSSepherosa Ziehau }
186479251f5eSSepherosa Ziehau 
186579251f5eSSepherosa Ziehau /**
186679251f5eSSepherosa Ziehau  *  ixgbe_get_eeprom_semaphore - Get hardware semaphore
186779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
186879251f5eSSepherosa Ziehau  *
186979251f5eSSepherosa Ziehau  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
187079251f5eSSepherosa Ziehau  **/
ixgbe_get_eeprom_semaphore(struct ixgbe_hw * hw)187179251f5eSSepherosa Ziehau static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
187279251f5eSSepherosa Ziehau {
187379251f5eSSepherosa Ziehau 	s32 status = IXGBE_ERR_EEPROM;
187479251f5eSSepherosa Ziehau 	u32 timeout = 2000;
187579251f5eSSepherosa Ziehau 	u32 i;
187679251f5eSSepherosa Ziehau 	u32 swsm;
187779251f5eSSepherosa Ziehau 
187879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_eeprom_semaphore");
187979251f5eSSepherosa Ziehau 
188079251f5eSSepherosa Ziehau 
188179251f5eSSepherosa Ziehau 	/* Get SMBI software semaphore between device drivers first */
188279251f5eSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
188379251f5eSSepherosa Ziehau 		/*
188479251f5eSSepherosa Ziehau 		 * If the SMBI bit is 0 when we read it, then the bit will be
188579251f5eSSepherosa Ziehau 		 * set and we have the semaphore
188679251f5eSSepherosa Ziehau 		 */
18876150453fSSepherosa Ziehau 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
188879251f5eSSepherosa Ziehau 		if (!(swsm & IXGBE_SWSM_SMBI)) {
188979251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
189079251f5eSSepherosa Ziehau 			break;
189179251f5eSSepherosa Ziehau 		}
189279251f5eSSepherosa Ziehau 		usec_delay(50);
189379251f5eSSepherosa Ziehau 	}
189479251f5eSSepherosa Ziehau 
189579251f5eSSepherosa Ziehau 	if (i == timeout) {
189679251f5eSSepherosa Ziehau 		DEBUGOUT("Driver can't access the Eeprom - SMBI Semaphore "
189779251f5eSSepherosa Ziehau 			 "not granted.\n");
189879251f5eSSepherosa Ziehau 		/*
189979251f5eSSepherosa Ziehau 		 * this release is particularly important because our attempts
190079251f5eSSepherosa Ziehau 		 * above to get the semaphore may have succeeded, and if there
190179251f5eSSepherosa Ziehau 		 * was a timeout, we should unconditionally clear the semaphore
190279251f5eSSepherosa Ziehau 		 * bits to free the driver to make progress
190379251f5eSSepherosa Ziehau 		 */
190479251f5eSSepherosa Ziehau 		ixgbe_release_eeprom_semaphore(hw);
190579251f5eSSepherosa Ziehau 
190679251f5eSSepherosa Ziehau 		usec_delay(50);
190779251f5eSSepherosa Ziehau 		/*
190879251f5eSSepherosa Ziehau 		 * one last try
190979251f5eSSepherosa Ziehau 		 * If the SMBI bit is 0 when we read it, then the bit will be
191079251f5eSSepherosa Ziehau 		 * set and we have the semaphore
191179251f5eSSepherosa Ziehau 		 */
19126150453fSSepherosa Ziehau 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
191379251f5eSSepherosa Ziehau 		if (!(swsm & IXGBE_SWSM_SMBI))
191479251f5eSSepherosa Ziehau 			status = IXGBE_SUCCESS;
191579251f5eSSepherosa Ziehau 	}
191679251f5eSSepherosa Ziehau 
191779251f5eSSepherosa Ziehau 	/* Now get the semaphore between SW/FW through the SWESMBI bit */
191879251f5eSSepherosa Ziehau 	if (status == IXGBE_SUCCESS) {
191979251f5eSSepherosa Ziehau 		for (i = 0; i < timeout; i++) {
19206150453fSSepherosa Ziehau 			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
192179251f5eSSepherosa Ziehau 
192279251f5eSSepherosa Ziehau 			/* Set the SW EEPROM semaphore bit to request access */
192379251f5eSSepherosa Ziehau 			swsm |= IXGBE_SWSM_SWESMBI;
19246150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm);
192579251f5eSSepherosa Ziehau 
192679251f5eSSepherosa Ziehau 			/*
192779251f5eSSepherosa Ziehau 			 * If we set the bit successfully then we got the
192879251f5eSSepherosa Ziehau 			 * semaphore.
192979251f5eSSepherosa Ziehau 			 */
19306150453fSSepherosa Ziehau 			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
193179251f5eSSepherosa Ziehau 			if (swsm & IXGBE_SWSM_SWESMBI)
193279251f5eSSepherosa Ziehau 				break;
193379251f5eSSepherosa Ziehau 
193479251f5eSSepherosa Ziehau 			usec_delay(50);
193579251f5eSSepherosa Ziehau 		}
193679251f5eSSepherosa Ziehau 
193779251f5eSSepherosa Ziehau 		/*
193879251f5eSSepherosa Ziehau 		 * Release semaphores and return error if SW EEPROM semaphore
193979251f5eSSepherosa Ziehau 		 * was not granted because we don't have access to the EEPROM
194079251f5eSSepherosa Ziehau 		 */
194179251f5eSSepherosa Ziehau 		if (i >= timeout) {
194279251f5eSSepherosa Ziehau 			ERROR_REPORT1(IXGBE_ERROR_POLLING,
194379251f5eSSepherosa Ziehau 			    "SWESMBI Software EEPROM semaphore not granted.\n");
194479251f5eSSepherosa Ziehau 			ixgbe_release_eeprom_semaphore(hw);
194579251f5eSSepherosa Ziehau 			status = IXGBE_ERR_EEPROM;
194679251f5eSSepherosa Ziehau 		}
194779251f5eSSepherosa Ziehau 	} else {
194879251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
194979251f5eSSepherosa Ziehau 			     "Software semaphore SMBI between device drivers "
195079251f5eSSepherosa Ziehau 			     "not granted.\n");
195179251f5eSSepherosa Ziehau 	}
195279251f5eSSepherosa Ziehau 
195379251f5eSSepherosa Ziehau 	return status;
195479251f5eSSepherosa Ziehau }
195579251f5eSSepherosa Ziehau 
195679251f5eSSepherosa Ziehau /**
195779251f5eSSepherosa Ziehau  *  ixgbe_release_eeprom_semaphore - Release hardware semaphore
195879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
195979251f5eSSepherosa Ziehau  *
196079251f5eSSepherosa Ziehau  *  This function clears hardware semaphore bits.
196179251f5eSSepherosa Ziehau  **/
ixgbe_release_eeprom_semaphore(struct ixgbe_hw * hw)196279251f5eSSepherosa Ziehau static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
196379251f5eSSepherosa Ziehau {
196479251f5eSSepherosa Ziehau 	u32 swsm;
196579251f5eSSepherosa Ziehau 
196679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_eeprom_semaphore");
196779251f5eSSepherosa Ziehau 
196879251f5eSSepherosa Ziehau 	swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
196979251f5eSSepherosa Ziehau 
197079251f5eSSepherosa Ziehau 	/* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
197179251f5eSSepherosa Ziehau 	swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
197279251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
197379251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
197479251f5eSSepherosa Ziehau }
197579251f5eSSepherosa Ziehau 
197679251f5eSSepherosa Ziehau /**
197779251f5eSSepherosa Ziehau  *  ixgbe_ready_eeprom - Polls for EEPROM ready
197879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
197979251f5eSSepherosa Ziehau  **/
ixgbe_ready_eeprom(struct ixgbe_hw * hw)198079251f5eSSepherosa Ziehau static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
198179251f5eSSepherosa Ziehau {
198279251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
198379251f5eSSepherosa Ziehau 	u16 i;
198479251f5eSSepherosa Ziehau 	u8 spi_stat_reg;
198579251f5eSSepherosa Ziehau 
198679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_ready_eeprom");
198779251f5eSSepherosa Ziehau 
198879251f5eSSepherosa Ziehau 	/*
198979251f5eSSepherosa Ziehau 	 * Read "Status Register" repeatedly until the LSB is cleared.  The
199079251f5eSSepherosa Ziehau 	 * EEPROM will signal that the command has been completed by clearing
199179251f5eSSepherosa Ziehau 	 * bit 0 of the internal status register.  If it's not cleared within
199279251f5eSSepherosa Ziehau 	 * 5 milliseconds, then error out.
199379251f5eSSepherosa Ziehau 	 */
199479251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
199579251f5eSSepherosa Ziehau 		ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
199679251f5eSSepherosa Ziehau 					    IXGBE_EEPROM_OPCODE_BITS);
199779251f5eSSepherosa Ziehau 		spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
199879251f5eSSepherosa Ziehau 		if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
199979251f5eSSepherosa Ziehau 			break;
200079251f5eSSepherosa Ziehau 
200179251f5eSSepherosa Ziehau 		usec_delay(5);
200279251f5eSSepherosa Ziehau 		ixgbe_standby_eeprom(hw);
200363d483cdSSepherosa Ziehau 	};
200479251f5eSSepherosa Ziehau 
200579251f5eSSepherosa Ziehau 	/*
200679251f5eSSepherosa Ziehau 	 * On some parts, SPI write time could vary from 0-20mSec on 3.3V
200779251f5eSSepherosa Ziehau 	 * devices (and only 0-5mSec on 5V devices)
200879251f5eSSepherosa Ziehau 	 */
200979251f5eSSepherosa Ziehau 	if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
201079251f5eSSepherosa Ziehau 		DEBUGOUT("SPI EEPROM Status error\n");
201179251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM;
201279251f5eSSepherosa Ziehau 	}
201379251f5eSSepherosa Ziehau 
201479251f5eSSepherosa Ziehau 	return status;
201579251f5eSSepherosa Ziehau }
201679251f5eSSepherosa Ziehau 
201779251f5eSSepherosa Ziehau /**
201879251f5eSSepherosa Ziehau  *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
201979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
202079251f5eSSepherosa Ziehau  **/
ixgbe_standby_eeprom(struct ixgbe_hw * hw)202179251f5eSSepherosa Ziehau static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
202279251f5eSSepherosa Ziehau {
202379251f5eSSepherosa Ziehau 	u32 eec;
202479251f5eSSepherosa Ziehau 
202579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_standby_eeprom");
202679251f5eSSepherosa Ziehau 
20276150453fSSepherosa Ziehau 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
202879251f5eSSepherosa Ziehau 
202979251f5eSSepherosa Ziehau 	/* Toggle CS to flush commands */
203079251f5eSSepherosa Ziehau 	eec |= IXGBE_EEC_CS;
20316150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
203279251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
203379251f5eSSepherosa Ziehau 	usec_delay(1);
203479251f5eSSepherosa Ziehau 	eec &= ~IXGBE_EEC_CS;
20356150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
203679251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
203779251f5eSSepherosa Ziehau 	usec_delay(1);
203879251f5eSSepherosa Ziehau }
203979251f5eSSepherosa Ziehau 
204079251f5eSSepherosa Ziehau /**
204179251f5eSSepherosa Ziehau  *  ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
204279251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
204379251f5eSSepherosa Ziehau  *  @data: data to send to the EEPROM
204479251f5eSSepherosa Ziehau  *  @count: number of bits to shift out
204579251f5eSSepherosa Ziehau  **/
ixgbe_shift_out_eeprom_bits(struct ixgbe_hw * hw,u16 data,u16 count)204679251f5eSSepherosa Ziehau static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
204779251f5eSSepherosa Ziehau 					u16 count)
204879251f5eSSepherosa Ziehau {
204979251f5eSSepherosa Ziehau 	u32 eec;
205079251f5eSSepherosa Ziehau 	u32 mask;
205179251f5eSSepherosa Ziehau 	u32 i;
205279251f5eSSepherosa Ziehau 
205379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_shift_out_eeprom_bits");
205479251f5eSSepherosa Ziehau 
20556150453fSSepherosa Ziehau 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
205679251f5eSSepherosa Ziehau 
205779251f5eSSepherosa Ziehau 	/*
205879251f5eSSepherosa Ziehau 	 * Mask is used to shift "count" bits of "data" out to the EEPROM
205979251f5eSSepherosa Ziehau 	 * one bit at a time.  Determine the starting bit based on count
206079251f5eSSepherosa Ziehau 	 */
206179251f5eSSepherosa Ziehau 	mask = 0x01 << (count - 1);
206279251f5eSSepherosa Ziehau 
206379251f5eSSepherosa Ziehau 	for (i = 0; i < count; i++) {
206479251f5eSSepherosa Ziehau 		/*
206579251f5eSSepherosa Ziehau 		 * A "1" is shifted out to the EEPROM by setting bit "DI" to a
206679251f5eSSepherosa Ziehau 		 * "1", and then raising and then lowering the clock (the SK
206779251f5eSSepherosa Ziehau 		 * bit controls the clock input to the EEPROM).  A "0" is
206879251f5eSSepherosa Ziehau 		 * shifted out to the EEPROM by setting "DI" to "0" and then
206979251f5eSSepherosa Ziehau 		 * raising and then lowering the clock.
207079251f5eSSepherosa Ziehau 		 */
207179251f5eSSepherosa Ziehau 		if (data & mask)
207279251f5eSSepherosa Ziehau 			eec |= IXGBE_EEC_DI;
207379251f5eSSepherosa Ziehau 		else
207479251f5eSSepherosa Ziehau 			eec &= ~IXGBE_EEC_DI;
207579251f5eSSepherosa Ziehau 
20766150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
207779251f5eSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
207879251f5eSSepherosa Ziehau 
207979251f5eSSepherosa Ziehau 		usec_delay(1);
208079251f5eSSepherosa Ziehau 
208179251f5eSSepherosa Ziehau 		ixgbe_raise_eeprom_clk(hw, &eec);
208279251f5eSSepherosa Ziehau 		ixgbe_lower_eeprom_clk(hw, &eec);
208379251f5eSSepherosa Ziehau 
208479251f5eSSepherosa Ziehau 		/*
208579251f5eSSepherosa Ziehau 		 * Shift mask to signify next bit of data to shift in to the
208679251f5eSSepherosa Ziehau 		 * EEPROM
208779251f5eSSepherosa Ziehau 		 */
208879251f5eSSepherosa Ziehau 		mask = mask >> 1;
208963d483cdSSepherosa Ziehau 	};
209079251f5eSSepherosa Ziehau 
209179251f5eSSepherosa Ziehau 	/* We leave the "DI" bit set to "0" when we leave this routine. */
209279251f5eSSepherosa Ziehau 	eec &= ~IXGBE_EEC_DI;
20936150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
209479251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
209579251f5eSSepherosa Ziehau }
209679251f5eSSepherosa Ziehau 
209779251f5eSSepherosa Ziehau /**
209879251f5eSSepherosa Ziehau  *  ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
209979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
2100dd5ce676SSepherosa Ziehau  *  @count: number of bits to shift
210179251f5eSSepherosa Ziehau  **/
ixgbe_shift_in_eeprom_bits(struct ixgbe_hw * hw,u16 count)210279251f5eSSepherosa Ziehau static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
210379251f5eSSepherosa Ziehau {
210479251f5eSSepherosa Ziehau 	u32 eec;
210579251f5eSSepherosa Ziehau 	u32 i;
210679251f5eSSepherosa Ziehau 	u16 data = 0;
210779251f5eSSepherosa Ziehau 
210879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_shift_in_eeprom_bits");
210979251f5eSSepherosa Ziehau 
211079251f5eSSepherosa Ziehau 	/*
211179251f5eSSepherosa Ziehau 	 * In order to read a register from the EEPROM, we need to shift
211279251f5eSSepherosa Ziehau 	 * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
211379251f5eSSepherosa Ziehau 	 * the clock input to the EEPROM (setting the SK bit), and then reading
211479251f5eSSepherosa Ziehau 	 * the value of the "DO" bit.  During this "shifting in" process the
211579251f5eSSepherosa Ziehau 	 * "DI" bit should always be clear.
211679251f5eSSepherosa Ziehau 	 */
21176150453fSSepherosa Ziehau 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
211879251f5eSSepherosa Ziehau 
211979251f5eSSepherosa Ziehau 	eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
212079251f5eSSepherosa Ziehau 
212179251f5eSSepherosa Ziehau 	for (i = 0; i < count; i++) {
212279251f5eSSepherosa Ziehau 		data = data << 1;
212379251f5eSSepherosa Ziehau 		ixgbe_raise_eeprom_clk(hw, &eec);
212479251f5eSSepherosa Ziehau 
21256150453fSSepherosa Ziehau 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
212679251f5eSSepherosa Ziehau 
212779251f5eSSepherosa Ziehau 		eec &= ~(IXGBE_EEC_DI);
212879251f5eSSepherosa Ziehau 		if (eec & IXGBE_EEC_DO)
212979251f5eSSepherosa Ziehau 			data |= 1;
213079251f5eSSepherosa Ziehau 
213179251f5eSSepherosa Ziehau 		ixgbe_lower_eeprom_clk(hw, &eec);
213279251f5eSSepherosa Ziehau 	}
213379251f5eSSepherosa Ziehau 
213479251f5eSSepherosa Ziehau 	return data;
213579251f5eSSepherosa Ziehau }
213679251f5eSSepherosa Ziehau 
213779251f5eSSepherosa Ziehau /**
213879251f5eSSepherosa Ziehau  *  ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
213979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
214079251f5eSSepherosa Ziehau  *  @eec: EEC register's current value
214179251f5eSSepherosa Ziehau  **/
ixgbe_raise_eeprom_clk(struct ixgbe_hw * hw,u32 * eec)214279251f5eSSepherosa Ziehau static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
214379251f5eSSepherosa Ziehau {
214479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_raise_eeprom_clk");
214579251f5eSSepherosa Ziehau 
214679251f5eSSepherosa Ziehau 	/*
214779251f5eSSepherosa Ziehau 	 * Raise the clock input to the EEPROM
214879251f5eSSepherosa Ziehau 	 * (setting the SK bit), then delay
214979251f5eSSepherosa Ziehau 	 */
215079251f5eSSepherosa Ziehau 	*eec = *eec | IXGBE_EEC_SK;
21516150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec);
215279251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
215379251f5eSSepherosa Ziehau 	usec_delay(1);
215479251f5eSSepherosa Ziehau }
215579251f5eSSepherosa Ziehau 
215679251f5eSSepherosa Ziehau /**
215779251f5eSSepherosa Ziehau  *  ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
215879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
2159dd5ce676SSepherosa Ziehau  *  @eec: EEC's current value
216079251f5eSSepherosa Ziehau  **/
ixgbe_lower_eeprom_clk(struct ixgbe_hw * hw,u32 * eec)216179251f5eSSepherosa Ziehau static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
216279251f5eSSepherosa Ziehau {
216379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_lower_eeprom_clk");
216479251f5eSSepherosa Ziehau 
216579251f5eSSepherosa Ziehau 	/*
216679251f5eSSepherosa Ziehau 	 * Lower the clock input to the EEPROM (clearing the SK bit), then
216779251f5eSSepherosa Ziehau 	 * delay
216879251f5eSSepherosa Ziehau 	 */
216979251f5eSSepherosa Ziehau 	*eec = *eec & ~IXGBE_EEC_SK;
21706150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec);
217179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
217279251f5eSSepherosa Ziehau 	usec_delay(1);
217379251f5eSSepherosa Ziehau }
217479251f5eSSepherosa Ziehau 
217579251f5eSSepherosa Ziehau /**
217679251f5eSSepherosa Ziehau  *  ixgbe_release_eeprom - Release EEPROM, release semaphores
217779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
217879251f5eSSepherosa Ziehau  **/
ixgbe_release_eeprom(struct ixgbe_hw * hw)217979251f5eSSepherosa Ziehau static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
218079251f5eSSepherosa Ziehau {
218179251f5eSSepherosa Ziehau 	u32 eec;
218279251f5eSSepherosa Ziehau 
218379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_eeprom");
218479251f5eSSepherosa Ziehau 
21856150453fSSepherosa Ziehau 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
218679251f5eSSepherosa Ziehau 
218779251f5eSSepherosa Ziehau 	eec |= IXGBE_EEC_CS;  /* Pull CS high */
218879251f5eSSepherosa Ziehau 	eec &= ~IXGBE_EEC_SK; /* Lower SCK */
218979251f5eSSepherosa Ziehau 
21906150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
219179251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
219279251f5eSSepherosa Ziehau 
219379251f5eSSepherosa Ziehau 	usec_delay(1);
219479251f5eSSepherosa Ziehau 
219579251f5eSSepherosa Ziehau 	/* Stop requesting EEPROM access */
219679251f5eSSepherosa Ziehau 	eec &= ~IXGBE_EEC_REQ;
21976150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
219879251f5eSSepherosa Ziehau 
219979251f5eSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
220079251f5eSSepherosa Ziehau 
220179251f5eSSepherosa Ziehau 	/* Delay before attempt to obtain semaphore again to allow FW access */
220279251f5eSSepherosa Ziehau 	msec_delay(hw->eeprom.semaphore_delay);
220379251f5eSSepherosa Ziehau }
220479251f5eSSepherosa Ziehau 
220579251f5eSSepherosa Ziehau /**
220679251f5eSSepherosa Ziehau  *  ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
220779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
220863d483cdSSepherosa Ziehau  *
220963d483cdSSepherosa Ziehau  *  Returns a negative error code on error, or the 16-bit checksum
221079251f5eSSepherosa Ziehau  **/
ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw * hw)221163d483cdSSepherosa Ziehau s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
221279251f5eSSepherosa Ziehau {
221379251f5eSSepherosa Ziehau 	u16 i;
221479251f5eSSepherosa Ziehau 	u16 j;
221579251f5eSSepherosa Ziehau 	u16 checksum = 0;
221679251f5eSSepherosa Ziehau 	u16 length = 0;
221779251f5eSSepherosa Ziehau 	u16 pointer = 0;
221879251f5eSSepherosa Ziehau 	u16 word = 0;
221979251f5eSSepherosa Ziehau 
222079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic");
222179251f5eSSepherosa Ziehau 
222279251f5eSSepherosa Ziehau 	/* Include 0x0-0x3F in the checksum */
222379251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
222463d483cdSSepherosa Ziehau 		if (hw->eeprom.ops.read(hw, i, &word)) {
222579251f5eSSepherosa Ziehau 			DEBUGOUT("EEPROM read failed\n");
222663d483cdSSepherosa Ziehau 			return IXGBE_ERR_EEPROM;
222779251f5eSSepherosa Ziehau 		}
222879251f5eSSepherosa Ziehau 		checksum += word;
222979251f5eSSepherosa Ziehau 	}
223079251f5eSSepherosa Ziehau 
223179251f5eSSepherosa Ziehau 	/* Include all data from pointers except for the fw pointer */
223279251f5eSSepherosa Ziehau 	for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
223363d483cdSSepherosa Ziehau 		if (hw->eeprom.ops.read(hw, i, &pointer)) {
223463d483cdSSepherosa Ziehau 			DEBUGOUT("EEPROM read failed\n");
223563d483cdSSepherosa Ziehau 			return IXGBE_ERR_EEPROM;
223663d483cdSSepherosa Ziehau 		}
223779251f5eSSepherosa Ziehau 
223863d483cdSSepherosa Ziehau 		/* If the pointer seems invalid */
223963d483cdSSepherosa Ziehau 		if (pointer == 0xFFFF || pointer == 0)
224063d483cdSSepherosa Ziehau 			continue;
224179251f5eSSepherosa Ziehau 
224263d483cdSSepherosa Ziehau 		if (hw->eeprom.ops.read(hw, pointer, &length)) {
224363d483cdSSepherosa Ziehau 			DEBUGOUT("EEPROM read failed\n");
224463d483cdSSepherosa Ziehau 			return IXGBE_ERR_EEPROM;
224563d483cdSSepherosa Ziehau 		}
224663d483cdSSepherosa Ziehau 
224763d483cdSSepherosa Ziehau 		if (length == 0xFFFF || length == 0)
224863d483cdSSepherosa Ziehau 			continue;
224963d483cdSSepherosa Ziehau 
225079251f5eSSepherosa Ziehau 		for (j = pointer + 1; j <= pointer + length; j++) {
225163d483cdSSepherosa Ziehau 			if (hw->eeprom.ops.read(hw, j, &word)) {
225263d483cdSSepherosa Ziehau 				DEBUGOUT("EEPROM read failed\n");
225363d483cdSSepherosa Ziehau 				return IXGBE_ERR_EEPROM;
225463d483cdSSepherosa Ziehau 			}
225579251f5eSSepherosa Ziehau 			checksum += word;
225679251f5eSSepherosa Ziehau 		}
225779251f5eSSepherosa Ziehau 	}
225879251f5eSSepherosa Ziehau 
225979251f5eSSepherosa Ziehau 	checksum = (u16)IXGBE_EEPROM_SUM - checksum;
226079251f5eSSepherosa Ziehau 
226163d483cdSSepherosa Ziehau 	return (s32)checksum;
226279251f5eSSepherosa Ziehau }
226379251f5eSSepherosa Ziehau 
226479251f5eSSepherosa Ziehau /**
226579251f5eSSepherosa Ziehau  *  ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
226679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
226779251f5eSSepherosa Ziehau  *  @checksum_val: calculated checksum
226879251f5eSSepherosa Ziehau  *
226979251f5eSSepherosa Ziehau  *  Performs checksum calculation and validates the EEPROM checksum.  If the
227079251f5eSSepherosa Ziehau  *  caller does not need checksum_val, the value can be NULL.
227179251f5eSSepherosa Ziehau  **/
ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw * hw,u16 * checksum_val)227279251f5eSSepherosa Ziehau s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
227379251f5eSSepherosa Ziehau 					   u16 *checksum_val)
227479251f5eSSepherosa Ziehau {
227579251f5eSSepherosa Ziehau 	s32 status;
227679251f5eSSepherosa Ziehau 	u16 checksum;
227779251f5eSSepherosa Ziehau 	u16 read_checksum = 0;
227879251f5eSSepherosa Ziehau 
227979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic");
228079251f5eSSepherosa Ziehau 
228163d483cdSSepherosa Ziehau 	/* Read the first word from the EEPROM. If this times out or fails, do
228279251f5eSSepherosa Ziehau 	 * not continue or we could be in for a very long wait while every
228379251f5eSSepherosa Ziehau 	 * EEPROM read fails
228479251f5eSSepherosa Ziehau 	 */
228579251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, 0, &checksum);
228663d483cdSSepherosa Ziehau 	if (status) {
228763d483cdSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
228863d483cdSSepherosa Ziehau 		return status;
228963d483cdSSepherosa Ziehau 	}
229079251f5eSSepherosa Ziehau 
229163d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.calc_checksum(hw);
229263d483cdSSepherosa Ziehau 	if (status < 0)
229363d483cdSSepherosa Ziehau 		return status;
229479251f5eSSepherosa Ziehau 
229563d483cdSSepherosa Ziehau 	checksum = (u16)(status & 0xffff);
229679251f5eSSepherosa Ziehau 
229763d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
229863d483cdSSepherosa Ziehau 	if (status) {
229963d483cdSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
230063d483cdSSepherosa Ziehau 		return status;
230163d483cdSSepherosa Ziehau 	}
230263d483cdSSepherosa Ziehau 
230363d483cdSSepherosa Ziehau 	/* Verify read checksum from EEPROM is the same as
230479251f5eSSepherosa Ziehau 	 * calculated checksum
230579251f5eSSepherosa Ziehau 	 */
230679251f5eSSepherosa Ziehau 	if (read_checksum != checksum)
230779251f5eSSepherosa Ziehau 		status = IXGBE_ERR_EEPROM_CHECKSUM;
230879251f5eSSepherosa Ziehau 
230979251f5eSSepherosa Ziehau 	/* If the user cares, return the calculated checksum */
231079251f5eSSepherosa Ziehau 	if (checksum_val)
231179251f5eSSepherosa Ziehau 		*checksum_val = checksum;
231279251f5eSSepherosa Ziehau 
231379251f5eSSepherosa Ziehau 	return status;
231479251f5eSSepherosa Ziehau }
231579251f5eSSepherosa Ziehau 
231679251f5eSSepherosa Ziehau /**
231779251f5eSSepherosa Ziehau  *  ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
231879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
231979251f5eSSepherosa Ziehau  **/
ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw * hw)232079251f5eSSepherosa Ziehau s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
232179251f5eSSepherosa Ziehau {
232279251f5eSSepherosa Ziehau 	s32 status;
232379251f5eSSepherosa Ziehau 	u16 checksum;
232479251f5eSSepherosa Ziehau 
232579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_eeprom_checksum_generic");
232679251f5eSSepherosa Ziehau 
232763d483cdSSepherosa Ziehau 	/* Read the first word from the EEPROM. If this times out or fails, do
232879251f5eSSepherosa Ziehau 	 * not continue or we could be in for a very long wait while every
232979251f5eSSepherosa Ziehau 	 * EEPROM read fails
233079251f5eSSepherosa Ziehau 	 */
233179251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, 0, &checksum);
233263d483cdSSepherosa Ziehau 	if (status) {
233379251f5eSSepherosa Ziehau 		DEBUGOUT("EEPROM read failed\n");
233463d483cdSSepherosa Ziehau 		return status;
233579251f5eSSepherosa Ziehau 	}
233679251f5eSSepherosa Ziehau 
233763d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.calc_checksum(hw);
233863d483cdSSepherosa Ziehau 	if (status < 0)
233963d483cdSSepherosa Ziehau 		return status;
234063d483cdSSepherosa Ziehau 
234163d483cdSSepherosa Ziehau 	checksum = (u16)(status & 0xffff);
234263d483cdSSepherosa Ziehau 
234363d483cdSSepherosa Ziehau 	status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum);
234463d483cdSSepherosa Ziehau 
234579251f5eSSepherosa Ziehau 	return status;
234679251f5eSSepherosa Ziehau }
234779251f5eSSepherosa Ziehau 
234879251f5eSSepherosa Ziehau /**
234979251f5eSSepherosa Ziehau  *  ixgbe_validate_mac_addr - Validate MAC address
235079251f5eSSepherosa Ziehau  *  @mac_addr: pointer to MAC address.
235179251f5eSSepherosa Ziehau  *
23526150453fSSepherosa Ziehau  *  Tests a MAC address to ensure it is a valid Individual Address.
235379251f5eSSepherosa Ziehau  **/
ixgbe_validate_mac_addr(u8 * mac_addr)235479251f5eSSepherosa Ziehau s32 ixgbe_validate_mac_addr(u8 *mac_addr)
235579251f5eSSepherosa Ziehau {
235679251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
235779251f5eSSepherosa Ziehau 
235879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_validate_mac_addr");
235979251f5eSSepherosa Ziehau 
236079251f5eSSepherosa Ziehau 	/* Make sure it is not a multicast address */
236179251f5eSSepherosa Ziehau 	if (IXGBE_IS_MULTICAST(mac_addr)) {
236279251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_MAC_ADDR;
236379251f5eSSepherosa Ziehau 	/* Not a broadcast address */
236479251f5eSSepherosa Ziehau 	} else if (IXGBE_IS_BROADCAST(mac_addr)) {
236579251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_MAC_ADDR;
236679251f5eSSepherosa Ziehau 	/* Reject the zero address */
236779251f5eSSepherosa Ziehau 	} else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
236879251f5eSSepherosa Ziehau 		   mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
236979251f5eSSepherosa Ziehau 		status = IXGBE_ERR_INVALID_MAC_ADDR;
237079251f5eSSepherosa Ziehau 	}
237179251f5eSSepherosa Ziehau 	return status;
237279251f5eSSepherosa Ziehau }
237379251f5eSSepherosa Ziehau 
237479251f5eSSepherosa Ziehau /**
237579251f5eSSepherosa Ziehau  *  ixgbe_set_rar_generic - Set Rx address register
237679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
237779251f5eSSepherosa Ziehau  *  @index: Receive address register to write
237879251f5eSSepherosa Ziehau  *  @addr: Address to put into receive address register
237979251f5eSSepherosa Ziehau  *  @vmdq: VMDq "set" or "pool" index
238079251f5eSSepherosa Ziehau  *  @enable_addr: set flag that address is active
238179251f5eSSepherosa Ziehau  *
238279251f5eSSepherosa Ziehau  *  Puts an ethernet address into a receive address register.
238379251f5eSSepherosa Ziehau  **/
ixgbe_set_rar_generic(struct ixgbe_hw * hw,u32 index,u8 * addr,u32 vmdq,u32 enable_addr)238479251f5eSSepherosa Ziehau s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
238579251f5eSSepherosa Ziehau 			  u32 enable_addr)
238679251f5eSSepherosa Ziehau {
238779251f5eSSepherosa Ziehau 	u32 rar_low, rar_high;
238879251f5eSSepherosa Ziehau 	u32 rar_entries = hw->mac.num_rar_entries;
238979251f5eSSepherosa Ziehau 
239079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_rar_generic");
239179251f5eSSepherosa Ziehau 
239279251f5eSSepherosa Ziehau 	/* Make sure we are using a valid rar index range */
239379251f5eSSepherosa Ziehau 	if (index >= rar_entries) {
239479251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
239579251f5eSSepherosa Ziehau 			     "RAR index %d is out of range.\n", index);
239679251f5eSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
239779251f5eSSepherosa Ziehau 	}
239879251f5eSSepherosa Ziehau 
239979251f5eSSepherosa Ziehau 	/* setup VMDq pool selection before this RAR gets enabled */
240079251f5eSSepherosa Ziehau 	hw->mac.ops.set_vmdq(hw, index, vmdq);
240179251f5eSSepherosa Ziehau 
240279251f5eSSepherosa Ziehau 	/*
240379251f5eSSepherosa Ziehau 	 * HW expects these in little endian so we reverse the byte
240479251f5eSSepherosa Ziehau 	 * order from network order (big endian) to little endian
240579251f5eSSepherosa Ziehau 	 */
240679251f5eSSepherosa Ziehau 	rar_low = ((u32)addr[0] |
240779251f5eSSepherosa Ziehau 		   ((u32)addr[1] << 8) |
240879251f5eSSepherosa Ziehau 		   ((u32)addr[2] << 16) |
240979251f5eSSepherosa Ziehau 		   ((u32)addr[3] << 24));
241079251f5eSSepherosa Ziehau 	/*
241179251f5eSSepherosa Ziehau 	 * Some parts put the VMDq setting in the extra RAH bits,
241279251f5eSSepherosa Ziehau 	 * so save everything except the lower 16 bits that hold part
241379251f5eSSepherosa Ziehau 	 * of the address and the address valid bit.
241479251f5eSSepherosa Ziehau 	 */
241579251f5eSSepherosa Ziehau 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
241679251f5eSSepherosa Ziehau 	rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
241779251f5eSSepherosa Ziehau 	rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
241879251f5eSSepherosa Ziehau 
241979251f5eSSepherosa Ziehau 	if (enable_addr != 0)
242079251f5eSSepherosa Ziehau 		rar_high |= IXGBE_RAH_AV;
242179251f5eSSepherosa Ziehau 
242279251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
242379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
242479251f5eSSepherosa Ziehau 
242579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
242679251f5eSSepherosa Ziehau }
242779251f5eSSepherosa Ziehau 
242879251f5eSSepherosa Ziehau /**
242979251f5eSSepherosa Ziehau  *  ixgbe_clear_rar_generic - Remove Rx address register
243079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
243179251f5eSSepherosa Ziehau  *  @index: Receive address register to write
243279251f5eSSepherosa Ziehau  *
243379251f5eSSepherosa Ziehau  *  Clears an ethernet address from a receive address register.
243479251f5eSSepherosa Ziehau  **/
ixgbe_clear_rar_generic(struct ixgbe_hw * hw,u32 index)243579251f5eSSepherosa Ziehau s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
243679251f5eSSepherosa Ziehau {
243779251f5eSSepherosa Ziehau 	u32 rar_high;
243879251f5eSSepherosa Ziehau 	u32 rar_entries = hw->mac.num_rar_entries;
243979251f5eSSepherosa Ziehau 
244079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clear_rar_generic");
244179251f5eSSepherosa Ziehau 
244279251f5eSSepherosa Ziehau 	/* Make sure we are using a valid rar index range */
244379251f5eSSepherosa Ziehau 	if (index >= rar_entries) {
244479251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
244579251f5eSSepherosa Ziehau 			     "RAR index %d is out of range.\n", index);
244679251f5eSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
244779251f5eSSepherosa Ziehau 	}
244879251f5eSSepherosa Ziehau 
244979251f5eSSepherosa Ziehau 	/*
245079251f5eSSepherosa Ziehau 	 * Some parts put the VMDq setting in the extra RAH bits,
245179251f5eSSepherosa Ziehau 	 * so save everything except the lower 16 bits that hold part
245279251f5eSSepherosa Ziehau 	 * of the address and the address valid bit.
245379251f5eSSepherosa Ziehau 	 */
245479251f5eSSepherosa Ziehau 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
245579251f5eSSepherosa Ziehau 	rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
245679251f5eSSepherosa Ziehau 
245779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
245879251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
245979251f5eSSepherosa Ziehau 
246079251f5eSSepherosa Ziehau 	/* clear VMDq pool/queue selection for this RAR */
246179251f5eSSepherosa Ziehau 	hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
246279251f5eSSepherosa Ziehau 
246379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
246479251f5eSSepherosa Ziehau }
246579251f5eSSepherosa Ziehau 
246679251f5eSSepherosa Ziehau /**
246779251f5eSSepherosa Ziehau  *  ixgbe_init_rx_addrs_generic - Initializes receive address filters.
246879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
246979251f5eSSepherosa Ziehau  *
247079251f5eSSepherosa Ziehau  *  Places the MAC address in receive address register 0 and clears the rest
247179251f5eSSepherosa Ziehau  *  of the receive address registers. Clears the multicast table. Assumes
247279251f5eSSepherosa Ziehau  *  the receiver is in reset when the routine is called.
247379251f5eSSepherosa Ziehau  **/
ixgbe_init_rx_addrs_generic(struct ixgbe_hw * hw)247479251f5eSSepherosa Ziehau s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
247579251f5eSSepherosa Ziehau {
247679251f5eSSepherosa Ziehau 	u32 i;
247779251f5eSSepherosa Ziehau 	u32 rar_entries = hw->mac.num_rar_entries;
247879251f5eSSepherosa Ziehau 
247979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_rx_addrs_generic");
248079251f5eSSepherosa Ziehau 
248179251f5eSSepherosa Ziehau 	/*
248279251f5eSSepherosa Ziehau 	 * If the current mac address is valid, assume it is a software override
248379251f5eSSepherosa Ziehau 	 * to the permanent address.
248479251f5eSSepherosa Ziehau 	 * Otherwise, use the permanent address from the eeprom.
248579251f5eSSepherosa Ziehau 	 */
248679251f5eSSepherosa Ziehau 	if (ixgbe_validate_mac_addr(hw->mac.addr) ==
248779251f5eSSepherosa Ziehau 	    IXGBE_ERR_INVALID_MAC_ADDR) {
248879251f5eSSepherosa Ziehau 		/* Get the MAC address from the RAR0 for later reference */
248979251f5eSSepherosa Ziehau 		hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
249079251f5eSSepherosa Ziehau 
249179251f5eSSepherosa Ziehau 		DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
249279251f5eSSepherosa Ziehau 			  hw->mac.addr[0], hw->mac.addr[1],
249379251f5eSSepherosa Ziehau 			  hw->mac.addr[2]);
249479251f5eSSepherosa Ziehau 		DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
249579251f5eSSepherosa Ziehau 			  hw->mac.addr[4], hw->mac.addr[5]);
249679251f5eSSepherosa Ziehau 	} else {
249779251f5eSSepherosa Ziehau 		/* Setup the receive address. */
249879251f5eSSepherosa Ziehau 		DEBUGOUT("Overriding MAC Address in RAR[0]\n");
249979251f5eSSepherosa Ziehau 		DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ",
250079251f5eSSepherosa Ziehau 			  hw->mac.addr[0], hw->mac.addr[1],
250179251f5eSSepherosa Ziehau 			  hw->mac.addr[2]);
250279251f5eSSepherosa Ziehau 		DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
250379251f5eSSepherosa Ziehau 			  hw->mac.addr[4], hw->mac.addr[5]);
250479251f5eSSepherosa Ziehau 
250579251f5eSSepherosa Ziehau 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
25066150453fSSepherosa Ziehau 	}
250779251f5eSSepherosa Ziehau 
250879251f5eSSepherosa Ziehau 	/* clear VMDq pool/queue selection for RAR 0 */
250979251f5eSSepherosa Ziehau 	hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
25106150453fSSepherosa Ziehau 
251179251f5eSSepherosa Ziehau 	hw->addr_ctrl.overflow_promisc = 0;
251279251f5eSSepherosa Ziehau 
251379251f5eSSepherosa Ziehau 	hw->addr_ctrl.rar_used_count = 1;
251479251f5eSSepherosa Ziehau 
251579251f5eSSepherosa Ziehau 	/* Zero out the other receive addresses. */
251679251f5eSSepherosa Ziehau 	DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1);
251779251f5eSSepherosa Ziehau 	for (i = 1; i < rar_entries; i++) {
251879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
251979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
252079251f5eSSepherosa Ziehau 	}
252179251f5eSSepherosa Ziehau 
252279251f5eSSepherosa Ziehau 	/* Clear the MTA */
252379251f5eSSepherosa Ziehau 	hw->addr_ctrl.mta_in_use = 0;
252479251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
252579251f5eSSepherosa Ziehau 
252679251f5eSSepherosa Ziehau 	DEBUGOUT(" Clearing MTA\n");
252779251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.mcft_size; i++)
252879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
252979251f5eSSepherosa Ziehau 
253079251f5eSSepherosa Ziehau 	ixgbe_init_uta_tables(hw);
253179251f5eSSepherosa Ziehau 
253279251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
253379251f5eSSepherosa Ziehau }
253479251f5eSSepherosa Ziehau 
253579251f5eSSepherosa Ziehau /**
253679251f5eSSepherosa Ziehau  *  ixgbe_add_uc_addr - Adds a secondary unicast address.
253779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
253879251f5eSSepherosa Ziehau  *  @addr: new address
2539dd5ce676SSepherosa Ziehau  *  @vmdq: VMDq "set" or "pool" index
254079251f5eSSepherosa Ziehau  *
254179251f5eSSepherosa Ziehau  *  Adds it to unused receive address register or goes into promiscuous mode.
254279251f5eSSepherosa Ziehau  **/
ixgbe_add_uc_addr(struct ixgbe_hw * hw,u8 * addr,u32 vmdq)254379251f5eSSepherosa Ziehau void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
254479251f5eSSepherosa Ziehau {
254579251f5eSSepherosa Ziehau 	u32 rar_entries = hw->mac.num_rar_entries;
254679251f5eSSepherosa Ziehau 	u32 rar;
254779251f5eSSepherosa Ziehau 
254879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_add_uc_addr");
254979251f5eSSepherosa Ziehau 
255079251f5eSSepherosa Ziehau 	DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
255179251f5eSSepherosa Ziehau 		  addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
255279251f5eSSepherosa Ziehau 
255379251f5eSSepherosa Ziehau 	/*
255479251f5eSSepherosa Ziehau 	 * Place this address in the RAR if there is room,
255579251f5eSSepherosa Ziehau 	 * else put the controller into promiscuous mode
255679251f5eSSepherosa Ziehau 	 */
255779251f5eSSepherosa Ziehau 	if (hw->addr_ctrl.rar_used_count < rar_entries) {
255879251f5eSSepherosa Ziehau 		rar = hw->addr_ctrl.rar_used_count;
255979251f5eSSepherosa Ziehau 		hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
256079251f5eSSepherosa Ziehau 		DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar);
256179251f5eSSepherosa Ziehau 		hw->addr_ctrl.rar_used_count++;
256279251f5eSSepherosa Ziehau 	} else {
256379251f5eSSepherosa Ziehau 		hw->addr_ctrl.overflow_promisc++;
256479251f5eSSepherosa Ziehau 	}
256579251f5eSSepherosa Ziehau 
256679251f5eSSepherosa Ziehau 	DEBUGOUT("ixgbe_add_uc_addr Complete\n");
256779251f5eSSepherosa Ziehau }
256879251f5eSSepherosa Ziehau 
256979251f5eSSepherosa Ziehau /**
257079251f5eSSepherosa Ziehau  *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
257179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
257279251f5eSSepherosa Ziehau  *  @addr_list: the list of new addresses
257379251f5eSSepherosa Ziehau  *  @addr_count: number of addresses
257479251f5eSSepherosa Ziehau  *  @next: iterator function to walk the address list
257579251f5eSSepherosa Ziehau  *
257679251f5eSSepherosa Ziehau  *  The given list replaces any existing list.  Clears the secondary addrs from
257779251f5eSSepherosa Ziehau  *  receive address registers.  Uses unused receive address registers for the
257879251f5eSSepherosa Ziehau  *  first secondary addresses, and falls back to promiscuous mode as needed.
257979251f5eSSepherosa Ziehau  *
258079251f5eSSepherosa Ziehau  *  Drivers using secondary unicast addresses must set user_set_promisc when
258179251f5eSSepherosa Ziehau  *  manually putting the device into promiscuous mode.
258279251f5eSSepherosa Ziehau  **/
ixgbe_update_uc_addr_list_generic(struct ixgbe_hw * hw,u8 * addr_list,u32 addr_count,ixgbe_mc_addr_itr next)258379251f5eSSepherosa Ziehau s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
258479251f5eSSepherosa Ziehau 				      u32 addr_count, ixgbe_mc_addr_itr next)
258579251f5eSSepherosa Ziehau {
258679251f5eSSepherosa Ziehau 	u8 *addr;
258779251f5eSSepherosa Ziehau 	u32 i;
258879251f5eSSepherosa Ziehau 	u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
258979251f5eSSepherosa Ziehau 	u32 uc_addr_in_use;
259079251f5eSSepherosa Ziehau 	u32 fctrl;
259179251f5eSSepherosa Ziehau 	u32 vmdq;
259279251f5eSSepherosa Ziehau 
259379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_uc_addr_list_generic");
259479251f5eSSepherosa Ziehau 
259579251f5eSSepherosa Ziehau 	/*
259679251f5eSSepherosa Ziehau 	 * Clear accounting of old secondary address list,
259779251f5eSSepherosa Ziehau 	 * don't count RAR[0]
259879251f5eSSepherosa Ziehau 	 */
259979251f5eSSepherosa Ziehau 	uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
260079251f5eSSepherosa Ziehau 	hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
260179251f5eSSepherosa Ziehau 	hw->addr_ctrl.overflow_promisc = 0;
260279251f5eSSepherosa Ziehau 
260379251f5eSSepherosa Ziehau 	/* Zero out the other receive addresses */
260479251f5eSSepherosa Ziehau 	DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use+1);
260579251f5eSSepherosa Ziehau 	for (i = 0; i < uc_addr_in_use; i++) {
260679251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0);
260779251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0);
260879251f5eSSepherosa Ziehau 	}
260979251f5eSSepherosa Ziehau 
261079251f5eSSepherosa Ziehau 	/* Add the new addresses */
261179251f5eSSepherosa Ziehau 	for (i = 0; i < addr_count; i++) {
261279251f5eSSepherosa Ziehau 		DEBUGOUT(" Adding the secondary addresses:\n");
261379251f5eSSepherosa Ziehau 		addr = next(hw, &addr_list, &vmdq);
261479251f5eSSepherosa Ziehau 		ixgbe_add_uc_addr(hw, addr, vmdq);
261579251f5eSSepherosa Ziehau 	}
261679251f5eSSepherosa Ziehau 
261779251f5eSSepherosa Ziehau 	if (hw->addr_ctrl.overflow_promisc) {
261879251f5eSSepherosa Ziehau 		/* enable promisc if not already in overflow or set by user */
261979251f5eSSepherosa Ziehau 		if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
262079251f5eSSepherosa Ziehau 			DEBUGOUT(" Entering address overflow promisc mode\n");
262179251f5eSSepherosa Ziehau 			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
262279251f5eSSepherosa Ziehau 			fctrl |= IXGBE_FCTRL_UPE;
262379251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
262479251f5eSSepherosa Ziehau 		}
262579251f5eSSepherosa Ziehau 	} else {
262679251f5eSSepherosa Ziehau 		/* only disable if set by overflow, not by user */
262779251f5eSSepherosa Ziehau 		if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
262879251f5eSSepherosa Ziehau 			DEBUGOUT(" Leaving address overflow promisc mode\n");
262979251f5eSSepherosa Ziehau 			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
263079251f5eSSepherosa Ziehau 			fctrl &= ~IXGBE_FCTRL_UPE;
263179251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
263279251f5eSSepherosa Ziehau 		}
263379251f5eSSepherosa Ziehau 	}
263479251f5eSSepherosa Ziehau 
263579251f5eSSepherosa Ziehau 	DEBUGOUT("ixgbe_update_uc_addr_list_generic Complete\n");
263679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
263779251f5eSSepherosa Ziehau }
263879251f5eSSepherosa Ziehau 
263979251f5eSSepherosa Ziehau /**
264079251f5eSSepherosa Ziehau  *  ixgbe_mta_vector - Determines bit-vector in multicast table to set
264179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
264279251f5eSSepherosa Ziehau  *  @mc_addr: the multicast address
264379251f5eSSepherosa Ziehau  *
264479251f5eSSepherosa Ziehau  *  Extracts the 12 bits, from a multicast address, to determine which
264579251f5eSSepherosa Ziehau  *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
264679251f5eSSepherosa Ziehau  *  incoming rx multicast addresses, to determine the bit-vector to check in
264779251f5eSSepherosa Ziehau  *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
264879251f5eSSepherosa Ziehau  *  by the MO field of the MCSTCTRL. The MO field is set during initialization
264979251f5eSSepherosa Ziehau  *  to mc_filter_type.
265079251f5eSSepherosa Ziehau  **/
ixgbe_mta_vector(struct ixgbe_hw * hw,u8 * mc_addr)265179251f5eSSepherosa Ziehau static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
265279251f5eSSepherosa Ziehau {
265379251f5eSSepherosa Ziehau 	u32 vector = 0;
265479251f5eSSepherosa Ziehau 
265579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_mta_vector");
265679251f5eSSepherosa Ziehau 
265779251f5eSSepherosa Ziehau 	switch (hw->mac.mc_filter_type) {
265879251f5eSSepherosa Ziehau 	case 0:   /* use bits [47:36] of the address */
265979251f5eSSepherosa Ziehau 		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
266079251f5eSSepherosa Ziehau 		break;
266179251f5eSSepherosa Ziehau 	case 1:   /* use bits [46:35] of the address */
266279251f5eSSepherosa Ziehau 		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
266379251f5eSSepherosa Ziehau 		break;
266479251f5eSSepherosa Ziehau 	case 2:   /* use bits [45:34] of the address */
266579251f5eSSepherosa Ziehau 		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
266679251f5eSSepherosa Ziehau 		break;
266779251f5eSSepherosa Ziehau 	case 3:   /* use bits [43:32] of the address */
266879251f5eSSepherosa Ziehau 		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
266979251f5eSSepherosa Ziehau 		break;
267079251f5eSSepherosa Ziehau 	default:  /* Invalid mc_filter_type */
267179251f5eSSepherosa Ziehau 		DEBUGOUT("MC filter type param set incorrectly\n");
267279251f5eSSepherosa Ziehau 		ASSERT(0);
267379251f5eSSepherosa Ziehau 		break;
267479251f5eSSepherosa Ziehau 	}
267579251f5eSSepherosa Ziehau 
267679251f5eSSepherosa Ziehau 	/* vector can only be 12-bits or boundary will be exceeded */
267779251f5eSSepherosa Ziehau 	vector &= 0xFFF;
267879251f5eSSepherosa Ziehau 	return vector;
267979251f5eSSepherosa Ziehau }
268079251f5eSSepherosa Ziehau 
268179251f5eSSepherosa Ziehau /**
268279251f5eSSepherosa Ziehau  *  ixgbe_set_mta - Set bit-vector in multicast table
268379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
2684dd5ce676SSepherosa Ziehau  *  @mc_addr: Multicast address
268579251f5eSSepherosa Ziehau  *
268679251f5eSSepherosa Ziehau  *  Sets the bit-vector in the multicast table.
268779251f5eSSepherosa Ziehau  **/
ixgbe_set_mta(struct ixgbe_hw * hw,u8 * mc_addr)268879251f5eSSepherosa Ziehau void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
268979251f5eSSepherosa Ziehau {
269079251f5eSSepherosa Ziehau 	u32 vector;
269179251f5eSSepherosa Ziehau 	u32 vector_bit;
269279251f5eSSepherosa Ziehau 	u32 vector_reg;
269379251f5eSSepherosa Ziehau 
269479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_mta");
269579251f5eSSepherosa Ziehau 
269679251f5eSSepherosa Ziehau 	hw->addr_ctrl.mta_in_use++;
269779251f5eSSepherosa Ziehau 
269879251f5eSSepherosa Ziehau 	vector = ixgbe_mta_vector(hw, mc_addr);
269979251f5eSSepherosa Ziehau 	DEBUGOUT1(" bit-vector = 0x%03X\n", vector);
270079251f5eSSepherosa Ziehau 
270179251f5eSSepherosa Ziehau 	/*
270279251f5eSSepherosa Ziehau 	 * The MTA is a register array of 128 32-bit registers. It is treated
270379251f5eSSepherosa Ziehau 	 * like an array of 4096 bits.  We want to set bit
270479251f5eSSepherosa Ziehau 	 * BitArray[vector_value]. So we figure out what register the bit is
270579251f5eSSepherosa Ziehau 	 * in, read it, OR in the new bit, then write back the new value.  The
270679251f5eSSepherosa Ziehau 	 * register is determined by the upper 7 bits of the vector value and
270779251f5eSSepherosa Ziehau 	 * the bit within that register are determined by the lower 5 bits of
270879251f5eSSepherosa Ziehau 	 * the value.
270979251f5eSSepherosa Ziehau 	 */
271079251f5eSSepherosa Ziehau 	vector_reg = (vector >> 5) & 0x7F;
271179251f5eSSepherosa Ziehau 	vector_bit = vector & 0x1F;
271279251f5eSSepherosa Ziehau 	hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
271379251f5eSSepherosa Ziehau }
271479251f5eSSepherosa Ziehau 
271579251f5eSSepherosa Ziehau /**
271679251f5eSSepherosa Ziehau  *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
271779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
271879251f5eSSepherosa Ziehau  *  @mc_addr_list: the list of new multicast addresses
271979251f5eSSepherosa Ziehau  *  @mc_addr_count: number of addresses
272079251f5eSSepherosa Ziehau  *  @next: iterator function to walk the multicast address list
272179251f5eSSepherosa Ziehau  *  @clear: flag, when set clears the table beforehand
272279251f5eSSepherosa Ziehau  *
272379251f5eSSepherosa Ziehau  *  When the clear flag is set, the given list replaces any existing list.
272479251f5eSSepherosa Ziehau  *  Hashes the given addresses into the multicast table.
272579251f5eSSepherosa Ziehau  **/
ixgbe_update_mc_addr_list_generic(struct ixgbe_hw * hw,u8 * mc_addr_list,u32 mc_addr_count,ixgbe_mc_addr_itr next,bool clear)272679251f5eSSepherosa Ziehau s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
272779251f5eSSepherosa Ziehau 				      u32 mc_addr_count, ixgbe_mc_addr_itr next,
272879251f5eSSepherosa Ziehau 				      bool clear)
272979251f5eSSepherosa Ziehau {
273079251f5eSSepherosa Ziehau 	u32 i;
273179251f5eSSepherosa Ziehau 	u32 vmdq;
273279251f5eSSepherosa Ziehau 
273379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_update_mc_addr_list_generic");
273479251f5eSSepherosa Ziehau 
273579251f5eSSepherosa Ziehau 	/*
273679251f5eSSepherosa Ziehau 	 * Set the new number of MC addresses that we are being requested to
273779251f5eSSepherosa Ziehau 	 * use.
273879251f5eSSepherosa Ziehau 	 */
273979251f5eSSepherosa Ziehau 	hw->addr_ctrl.num_mc_addrs = mc_addr_count;
274079251f5eSSepherosa Ziehau 	hw->addr_ctrl.mta_in_use = 0;
274179251f5eSSepherosa Ziehau 
274279251f5eSSepherosa Ziehau 	/* Clear mta_shadow */
274379251f5eSSepherosa Ziehau 	if (clear) {
274479251f5eSSepherosa Ziehau 		DEBUGOUT(" Clearing MTA\n");
274579251f5eSSepherosa Ziehau 		memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
274679251f5eSSepherosa Ziehau 	}
274779251f5eSSepherosa Ziehau 
274879251f5eSSepherosa Ziehau 	/* Update mta_shadow */
274979251f5eSSepherosa Ziehau 	for (i = 0; i < mc_addr_count; i++) {
275079251f5eSSepherosa Ziehau 		DEBUGOUT(" Adding the multicast addresses:\n");
275179251f5eSSepherosa Ziehau 		ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
275279251f5eSSepherosa Ziehau 	}
275379251f5eSSepherosa Ziehau 
275479251f5eSSepherosa Ziehau 	/* Enable mta */
275579251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.mcft_size; i++)
275679251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i,
275779251f5eSSepherosa Ziehau 				      hw->mac.mta_shadow[i]);
275879251f5eSSepherosa Ziehau 
275979251f5eSSepherosa Ziehau 	if (hw->addr_ctrl.mta_in_use > 0)
276079251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
276179251f5eSSepherosa Ziehau 				IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
276279251f5eSSepherosa Ziehau 
276379251f5eSSepherosa Ziehau 	DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n");
276479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
276579251f5eSSepherosa Ziehau }
276679251f5eSSepherosa Ziehau 
276779251f5eSSepherosa Ziehau /**
276879251f5eSSepherosa Ziehau  *  ixgbe_enable_mc_generic - Enable multicast address in RAR
276979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
277079251f5eSSepherosa Ziehau  *
277179251f5eSSepherosa Ziehau  *  Enables multicast address in RAR and the use of the multicast hash table.
277279251f5eSSepherosa Ziehau  **/
ixgbe_enable_mc_generic(struct ixgbe_hw * hw)277379251f5eSSepherosa Ziehau s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
277479251f5eSSepherosa Ziehau {
277579251f5eSSepherosa Ziehau 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
277679251f5eSSepherosa Ziehau 
277779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_mc_generic");
277879251f5eSSepherosa Ziehau 
277979251f5eSSepherosa Ziehau 	if (a->mta_in_use > 0)
278079251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
278179251f5eSSepherosa Ziehau 				hw->mac.mc_filter_type);
278279251f5eSSepherosa Ziehau 
278379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
278479251f5eSSepherosa Ziehau }
278579251f5eSSepherosa Ziehau 
278679251f5eSSepherosa Ziehau /**
278779251f5eSSepherosa Ziehau  *  ixgbe_disable_mc_generic - Disable multicast address in RAR
278879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
278979251f5eSSepherosa Ziehau  *
279079251f5eSSepherosa Ziehau  *  Disables multicast address in RAR and the use of the multicast hash table.
279179251f5eSSepherosa Ziehau  **/
ixgbe_disable_mc_generic(struct ixgbe_hw * hw)279279251f5eSSepherosa Ziehau s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
279379251f5eSSepherosa Ziehau {
279479251f5eSSepherosa Ziehau 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
279579251f5eSSepherosa Ziehau 
279679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_disable_mc_generic");
279779251f5eSSepherosa Ziehau 
279879251f5eSSepherosa Ziehau 	if (a->mta_in_use > 0)
279979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
280079251f5eSSepherosa Ziehau 
280179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
280279251f5eSSepherosa Ziehau }
280379251f5eSSepherosa Ziehau 
280479251f5eSSepherosa Ziehau /**
280579251f5eSSepherosa Ziehau  *  ixgbe_fc_enable_generic - Enable flow control
280679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
280779251f5eSSepherosa Ziehau  *
280879251f5eSSepherosa Ziehau  *  Enable flow control according to the current settings.
280979251f5eSSepherosa Ziehau  **/
ixgbe_fc_enable_generic(struct ixgbe_hw * hw)281079251f5eSSepherosa Ziehau s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
281179251f5eSSepherosa Ziehau {
281279251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
281379251f5eSSepherosa Ziehau 	u32 mflcn_reg, fccfg_reg;
281479251f5eSSepherosa Ziehau 	u32 reg;
281579251f5eSSepherosa Ziehau 	u32 fcrtl, fcrth;
281679251f5eSSepherosa Ziehau 	int i;
281779251f5eSSepherosa Ziehau 
281879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fc_enable_generic");
281979251f5eSSepherosa Ziehau 
282079251f5eSSepherosa Ziehau 	/* Validate the water mark configuration */
282179251f5eSSepherosa Ziehau 	if (!hw->fc.pause_time) {
282279251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
282379251f5eSSepherosa Ziehau 		goto out;
282479251f5eSSepherosa Ziehau 	}
282579251f5eSSepherosa Ziehau 
282679251f5eSSepherosa Ziehau 	/* Low water mark of zero causes XOFF floods */
282779251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
282879251f5eSSepherosa Ziehau 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
282979251f5eSSepherosa Ziehau 		    hw->fc.high_water[i]) {
283079251f5eSSepherosa Ziehau 			if (!hw->fc.low_water[i] ||
283179251f5eSSepherosa Ziehau 			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
283279251f5eSSepherosa Ziehau 				DEBUGOUT("Invalid water mark configuration\n");
283379251f5eSSepherosa Ziehau 				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
283479251f5eSSepherosa Ziehau 				goto out;
283579251f5eSSepherosa Ziehau 			}
283679251f5eSSepherosa Ziehau 		}
283779251f5eSSepherosa Ziehau 	}
283879251f5eSSepherosa Ziehau 
283979251f5eSSepherosa Ziehau 	/* Negotiate the fc mode to use */
28406150453fSSepherosa Ziehau 	hw->mac.ops.fc_autoneg(hw);
284179251f5eSSepherosa Ziehau 
284279251f5eSSepherosa Ziehau 	/* Disable any previous flow control settings */
284379251f5eSSepherosa Ziehau 	mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
284479251f5eSSepherosa Ziehau 	mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
284579251f5eSSepherosa Ziehau 
284679251f5eSSepherosa Ziehau 	fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
284779251f5eSSepherosa Ziehau 	fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
284879251f5eSSepherosa Ziehau 
284979251f5eSSepherosa Ziehau 	/*
285079251f5eSSepherosa Ziehau 	 * The possible values of fc.current_mode are:
285179251f5eSSepherosa Ziehau 	 * 0: Flow control is completely disabled
285279251f5eSSepherosa Ziehau 	 * 1: Rx flow control is enabled (we can receive pause frames,
285379251f5eSSepherosa Ziehau 	 *    but not send pause frames).
285479251f5eSSepherosa Ziehau 	 * 2: Tx flow control is enabled (we can send pause frames but
285579251f5eSSepherosa Ziehau 	 *    we do not support receiving pause frames).
285679251f5eSSepherosa Ziehau 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
285779251f5eSSepherosa Ziehau 	 * other: Invalid.
285879251f5eSSepherosa Ziehau 	 */
285979251f5eSSepherosa Ziehau 	switch (hw->fc.current_mode) {
286079251f5eSSepherosa Ziehau 	case ixgbe_fc_none:
286179251f5eSSepherosa Ziehau 		/*
286279251f5eSSepherosa Ziehau 		 * Flow control is disabled by software override or autoneg.
286379251f5eSSepherosa Ziehau 		 * The code below will actually disable it in the HW.
286479251f5eSSepherosa Ziehau 		 */
286579251f5eSSepherosa Ziehau 		break;
286679251f5eSSepherosa Ziehau 	case ixgbe_fc_rx_pause:
286779251f5eSSepherosa Ziehau 		/*
286879251f5eSSepherosa Ziehau 		 * Rx Flow control is enabled and Tx Flow control is
286979251f5eSSepherosa Ziehau 		 * disabled by software override. Since there really
287079251f5eSSepherosa Ziehau 		 * isn't a way to advertise that we are capable of RX
287179251f5eSSepherosa Ziehau 		 * Pause ONLY, we will advertise that we support both
287279251f5eSSepherosa Ziehau 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
287379251f5eSSepherosa Ziehau 		 * disable the adapter's ability to send PAUSE frames.
287479251f5eSSepherosa Ziehau 		 */
287579251f5eSSepherosa Ziehau 		mflcn_reg |= IXGBE_MFLCN_RFCE;
287679251f5eSSepherosa Ziehau 		break;
287779251f5eSSepherosa Ziehau 	case ixgbe_fc_tx_pause:
287879251f5eSSepherosa Ziehau 		/*
287979251f5eSSepherosa Ziehau 		 * Tx Flow control is enabled, and Rx Flow control is
288079251f5eSSepherosa Ziehau 		 * disabled by software override.
288179251f5eSSepherosa Ziehau 		 */
288279251f5eSSepherosa Ziehau 		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
288379251f5eSSepherosa Ziehau 		break;
288479251f5eSSepherosa Ziehau 	case ixgbe_fc_full:
288579251f5eSSepherosa Ziehau 		/* Flow control (both Rx and Tx) is enabled by SW override. */
288679251f5eSSepherosa Ziehau 		mflcn_reg |= IXGBE_MFLCN_RFCE;
288779251f5eSSepherosa Ziehau 		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
288879251f5eSSepherosa Ziehau 		break;
288979251f5eSSepherosa Ziehau 	default:
289079251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
289179251f5eSSepherosa Ziehau 			     "Flow control param set incorrectly\n");
289279251f5eSSepherosa Ziehau 		ret_val = IXGBE_ERR_CONFIG;
289379251f5eSSepherosa Ziehau 		goto out;
289479251f5eSSepherosa Ziehau 		break;
289579251f5eSSepherosa Ziehau 	}
289679251f5eSSepherosa Ziehau 
289779251f5eSSepherosa Ziehau 	/* Set 802.3x based flow control settings. */
289879251f5eSSepherosa Ziehau 	mflcn_reg |= IXGBE_MFLCN_DPF;
289979251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
290079251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
290179251f5eSSepherosa Ziehau 
290279251f5eSSepherosa Ziehau 
290379251f5eSSepherosa Ziehau 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
290479251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
290579251f5eSSepherosa Ziehau 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
290679251f5eSSepherosa Ziehau 		    hw->fc.high_water[i]) {
290779251f5eSSepherosa Ziehau 			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
290879251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
290979251f5eSSepherosa Ziehau 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
291079251f5eSSepherosa Ziehau 		} else {
291179251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
291279251f5eSSepherosa Ziehau 			/*
291379251f5eSSepherosa Ziehau 			 * In order to prevent Tx hangs when the internal Tx
291479251f5eSSepherosa Ziehau 			 * switch is enabled we must set the high water mark
291563d483cdSSepherosa Ziehau 			 * to the Rx packet buffer size - 24KB.  This allows
291663d483cdSSepherosa Ziehau 			 * the Tx switch to function even under heavy Rx
291763d483cdSSepherosa Ziehau 			 * workloads.
291879251f5eSSepherosa Ziehau 			 */
291963d483cdSSepherosa Ziehau 			fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
292079251f5eSSepherosa Ziehau 		}
292179251f5eSSepherosa Ziehau 
292279251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
292379251f5eSSepherosa Ziehau 	}
292479251f5eSSepherosa Ziehau 
292579251f5eSSepherosa Ziehau 	/* Configure pause time (2 TCs per register) */
292679251f5eSSepherosa Ziehau 	reg = hw->fc.pause_time * 0x00010001;
292779251f5eSSepherosa Ziehau 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
292879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
292979251f5eSSepherosa Ziehau 
293079251f5eSSepherosa Ziehau 	/* Configure flow control refresh threshold value */
293179251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
293279251f5eSSepherosa Ziehau 
293379251f5eSSepherosa Ziehau out:
293479251f5eSSepherosa Ziehau 	return ret_val;
293579251f5eSSepherosa Ziehau }
293679251f5eSSepherosa Ziehau 
293779251f5eSSepherosa Ziehau /**
293879251f5eSSepherosa Ziehau  *  ixgbe_negotiate_fc - Negotiate flow control
293979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
294079251f5eSSepherosa Ziehau  *  @adv_reg: flow control advertised settings
294179251f5eSSepherosa Ziehau  *  @lp_reg: link partner's flow control settings
294279251f5eSSepherosa Ziehau  *  @adv_sym: symmetric pause bit in advertisement
294379251f5eSSepherosa Ziehau  *  @adv_asm: asymmetric pause bit in advertisement
294479251f5eSSepherosa Ziehau  *  @lp_sym: symmetric pause bit in link partner advertisement
294579251f5eSSepherosa Ziehau  *  @lp_asm: asymmetric pause bit in link partner advertisement
294679251f5eSSepherosa Ziehau  *
294779251f5eSSepherosa Ziehau  *  Find the intersection between advertised settings and link partner's
294879251f5eSSepherosa Ziehau  *  advertised settings
294979251f5eSSepherosa Ziehau  **/
ixgbe_negotiate_fc(struct ixgbe_hw * hw,u32 adv_reg,u32 lp_reg,u32 adv_sym,u32 adv_asm,u32 lp_sym,u32 lp_asm)29506150453fSSepherosa Ziehau s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
295179251f5eSSepherosa Ziehau 		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
295279251f5eSSepherosa Ziehau {
295379251f5eSSepherosa Ziehau 	if ((!(adv_reg)) ||  (!(lp_reg))) {
295479251f5eSSepherosa Ziehau 		ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED,
295579251f5eSSepherosa Ziehau 			     "Local or link partner's advertised flow control "
295679251f5eSSepherosa Ziehau 			     "settings are NULL. Local: %x, link partner: %x\n",
295779251f5eSSepherosa Ziehau 			     adv_reg, lp_reg);
295879251f5eSSepherosa Ziehau 		return IXGBE_ERR_FC_NOT_NEGOTIATED;
295979251f5eSSepherosa Ziehau 	}
296079251f5eSSepherosa Ziehau 
296179251f5eSSepherosa Ziehau 	if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
296279251f5eSSepherosa Ziehau 		/*
296379251f5eSSepherosa Ziehau 		 * Now we need to check if the user selected Rx ONLY
296479251f5eSSepherosa Ziehau 		 * of pause frames.  In this case, we had to advertise
296579251f5eSSepherosa Ziehau 		 * FULL flow control because we could not advertise RX
296679251f5eSSepherosa Ziehau 		 * ONLY. Hence, we must now check to see if we need to
296779251f5eSSepherosa Ziehau 		 * turn OFF the TRANSMISSION of PAUSE frames.
296879251f5eSSepherosa Ziehau 		 */
296979251f5eSSepherosa Ziehau 		if (hw->fc.requested_mode == ixgbe_fc_full) {
297079251f5eSSepherosa Ziehau 			hw->fc.current_mode = ixgbe_fc_full;
297179251f5eSSepherosa Ziehau 			DEBUGOUT("Flow Control = FULL.\n");
297279251f5eSSepherosa Ziehau 		} else {
297379251f5eSSepherosa Ziehau 			hw->fc.current_mode = ixgbe_fc_rx_pause;
297479251f5eSSepherosa Ziehau 			DEBUGOUT("Flow Control=RX PAUSE frames only\n");
297579251f5eSSepherosa Ziehau 		}
297679251f5eSSepherosa Ziehau 	} else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
297779251f5eSSepherosa Ziehau 		   (lp_reg & lp_sym) && (lp_reg & lp_asm)) {
297879251f5eSSepherosa Ziehau 		hw->fc.current_mode = ixgbe_fc_tx_pause;
297979251f5eSSepherosa Ziehau 		DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
298079251f5eSSepherosa Ziehau 	} else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
298179251f5eSSepherosa Ziehau 		   !(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
298279251f5eSSepherosa Ziehau 		hw->fc.current_mode = ixgbe_fc_rx_pause;
298379251f5eSSepherosa Ziehau 		DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
298479251f5eSSepherosa Ziehau 	} else {
298579251f5eSSepherosa Ziehau 		hw->fc.current_mode = ixgbe_fc_none;
298679251f5eSSepherosa Ziehau 		DEBUGOUT("Flow Control = NONE.\n");
298779251f5eSSepherosa Ziehau 	}
298879251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
298979251f5eSSepherosa Ziehau }
299079251f5eSSepherosa Ziehau 
299179251f5eSSepherosa Ziehau /**
299279251f5eSSepherosa Ziehau  *  ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
299379251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
299479251f5eSSepherosa Ziehau  *
299579251f5eSSepherosa Ziehau  *  Enable flow control according on 1 gig fiber.
299679251f5eSSepherosa Ziehau  **/
ixgbe_fc_autoneg_fiber(struct ixgbe_hw * hw)299779251f5eSSepherosa Ziehau static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
299879251f5eSSepherosa Ziehau {
299979251f5eSSepherosa Ziehau 	u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
300079251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
300179251f5eSSepherosa Ziehau 
300279251f5eSSepherosa Ziehau 	/*
300379251f5eSSepherosa Ziehau 	 * On multispeed fiber at 1g, bail out if
300479251f5eSSepherosa Ziehau 	 * - link is up but AN did not complete, or if
300579251f5eSSepherosa Ziehau 	 * - link is up and AN completed but timed out
300679251f5eSSepherosa Ziehau 	 */
300779251f5eSSepherosa Ziehau 
300879251f5eSSepherosa Ziehau 	linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
300963d483cdSSepherosa Ziehau 	if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
301063d483cdSSepherosa Ziehau 	    (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
301163d483cdSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete or timed out\n");
301279251f5eSSepherosa Ziehau 		goto out;
301379251f5eSSepherosa Ziehau 	}
301479251f5eSSepherosa Ziehau 
301579251f5eSSepherosa Ziehau 	pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
301679251f5eSSepherosa Ziehau 	pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
301779251f5eSSepherosa Ziehau 
301879251f5eSSepherosa Ziehau 	ret_val =  ixgbe_negotiate_fc(hw, pcs_anadv_reg,
301979251f5eSSepherosa Ziehau 				      pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE,
302079251f5eSSepherosa Ziehau 				      IXGBE_PCS1GANA_ASM_PAUSE,
302179251f5eSSepherosa Ziehau 				      IXGBE_PCS1GANA_SYM_PAUSE,
302279251f5eSSepherosa Ziehau 				      IXGBE_PCS1GANA_ASM_PAUSE);
302379251f5eSSepherosa Ziehau 
302479251f5eSSepherosa Ziehau out:
302579251f5eSSepherosa Ziehau 	return ret_val;
302679251f5eSSepherosa Ziehau }
302779251f5eSSepherosa Ziehau 
302879251f5eSSepherosa Ziehau /**
302979251f5eSSepherosa Ziehau  *  ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
303079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
303179251f5eSSepherosa Ziehau  *
303279251f5eSSepherosa Ziehau  *  Enable flow control according to IEEE clause 37.
303379251f5eSSepherosa Ziehau  **/
ixgbe_fc_autoneg_backplane(struct ixgbe_hw * hw)303479251f5eSSepherosa Ziehau static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
303579251f5eSSepherosa Ziehau {
303679251f5eSSepherosa Ziehau 	u32 links2, anlp1_reg, autoc_reg, links;
303779251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
303879251f5eSSepherosa Ziehau 
303979251f5eSSepherosa Ziehau 	/*
304079251f5eSSepherosa Ziehau 	 * On backplane, bail out if
304179251f5eSSepherosa Ziehau 	 * - backplane autoneg was not completed, or if
304279251f5eSSepherosa Ziehau 	 * - we are 82599 and link partner is not AN enabled
304379251f5eSSepherosa Ziehau 	 */
304479251f5eSSepherosa Ziehau 	links = IXGBE_READ_REG(hw, IXGBE_LINKS);
304579251f5eSSepherosa Ziehau 	if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) {
304663d483cdSSepherosa Ziehau 		DEBUGOUT("Auto-Negotiation did not complete\n");
304779251f5eSSepherosa Ziehau 		goto out;
304879251f5eSSepherosa Ziehau 	}
304979251f5eSSepherosa Ziehau 
305079251f5eSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_82599EB) {
305179251f5eSSepherosa Ziehau 		links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
305279251f5eSSepherosa Ziehau 		if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) {
305363d483cdSSepherosa Ziehau 			DEBUGOUT("Link partner is not AN enabled\n");
305479251f5eSSepherosa Ziehau 			goto out;
305579251f5eSSepherosa Ziehau 		}
305679251f5eSSepherosa Ziehau 	}
305779251f5eSSepherosa Ziehau 	/*
305879251f5eSSepherosa Ziehau 	 * Read the 10g AN autoc and LP ability registers and resolve
305979251f5eSSepherosa Ziehau 	 * local flow control settings accordingly
306079251f5eSSepherosa Ziehau 	 */
306179251f5eSSepherosa Ziehau 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
306279251f5eSSepherosa Ziehau 	anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
306379251f5eSSepherosa Ziehau 
306479251f5eSSepherosa Ziehau 	ret_val = ixgbe_negotiate_fc(hw, autoc_reg,
306579251f5eSSepherosa Ziehau 		anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE,
306679251f5eSSepherosa Ziehau 		IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE);
306779251f5eSSepherosa Ziehau 
306879251f5eSSepherosa Ziehau out:
306979251f5eSSepherosa Ziehau 	return ret_val;
307079251f5eSSepherosa Ziehau }
307179251f5eSSepherosa Ziehau 
307279251f5eSSepherosa Ziehau /**
307379251f5eSSepherosa Ziehau  *  ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
307479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
307579251f5eSSepherosa Ziehau  *
307679251f5eSSepherosa Ziehau  *  Enable flow control according to IEEE clause 37.
307779251f5eSSepherosa Ziehau  **/
ixgbe_fc_autoneg_copper(struct ixgbe_hw * hw)307879251f5eSSepherosa Ziehau static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
307979251f5eSSepherosa Ziehau {
308079251f5eSSepherosa Ziehau 	u16 technology_ability_reg = 0;
308179251f5eSSepherosa Ziehau 	u16 lp_technology_ability_reg = 0;
308279251f5eSSepherosa Ziehau 
308379251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
308479251f5eSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
308579251f5eSSepherosa Ziehau 			     &technology_ability_reg);
308679251f5eSSepherosa Ziehau 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP,
308779251f5eSSepherosa Ziehau 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
308879251f5eSSepherosa Ziehau 			     &lp_technology_ability_reg);
308979251f5eSSepherosa Ziehau 
309079251f5eSSepherosa Ziehau 	return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg,
309179251f5eSSepherosa Ziehau 				  (u32)lp_technology_ability_reg,
309279251f5eSSepherosa Ziehau 				  IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE,
309379251f5eSSepherosa Ziehau 				  IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE);
309479251f5eSSepherosa Ziehau }
309579251f5eSSepherosa Ziehau 
309679251f5eSSepherosa Ziehau /**
309779251f5eSSepherosa Ziehau  *  ixgbe_fc_autoneg - Configure flow control
309879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
309979251f5eSSepherosa Ziehau  *
310079251f5eSSepherosa Ziehau  *  Compares our advertised flow control capabilities to those advertised by
310179251f5eSSepherosa Ziehau  *  our link partner, and determines the proper flow control mode to use.
310279251f5eSSepherosa Ziehau  **/
ixgbe_fc_autoneg(struct ixgbe_hw * hw)310379251f5eSSepherosa Ziehau void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
310479251f5eSSepherosa Ziehau {
310579251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
310679251f5eSSepherosa Ziehau 	ixgbe_link_speed speed;
310779251f5eSSepherosa Ziehau 	bool link_up;
310879251f5eSSepherosa Ziehau 
310979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_fc_autoneg");
311079251f5eSSepherosa Ziehau 
311179251f5eSSepherosa Ziehau 	/*
311279251f5eSSepherosa Ziehau 	 * AN should have completed when the cable was plugged in.
311379251f5eSSepherosa Ziehau 	 * Look for reasons to bail out.  Bail out if:
311479251f5eSSepherosa Ziehau 	 * - FC autoneg is disabled, or if
311579251f5eSSepherosa Ziehau 	 * - link is not up.
311679251f5eSSepherosa Ziehau 	 */
311779251f5eSSepherosa Ziehau 	if (hw->fc.disable_fc_autoneg) {
311879251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
311979251f5eSSepherosa Ziehau 			     "Flow control autoneg is disabled");
312079251f5eSSepherosa Ziehau 		goto out;
312179251f5eSSepherosa Ziehau 	}
312279251f5eSSepherosa Ziehau 
312379251f5eSSepherosa Ziehau 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
312479251f5eSSepherosa Ziehau 	if (!link_up) {
312579251f5eSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
312679251f5eSSepherosa Ziehau 		goto out;
312779251f5eSSepherosa Ziehau 	}
312879251f5eSSepherosa Ziehau 
312979251f5eSSepherosa Ziehau 	switch (hw->phy.media_type) {
313079251f5eSSepherosa Ziehau 	/* Autoneg flow control on fiber adapters */
313179251f5eSSepherosa Ziehau 	case ixgbe_media_type_fiber_fixed:
313263d483cdSSepherosa Ziehau 	case ixgbe_media_type_fiber_qsfp:
313379251f5eSSepherosa Ziehau 	case ixgbe_media_type_fiber:
313479251f5eSSepherosa Ziehau 		if (speed == IXGBE_LINK_SPEED_1GB_FULL)
313579251f5eSSepherosa Ziehau 			ret_val = ixgbe_fc_autoneg_fiber(hw);
313679251f5eSSepherosa Ziehau 		break;
313779251f5eSSepherosa Ziehau 
313879251f5eSSepherosa Ziehau 	/* Autoneg flow control on backplane adapters */
313979251f5eSSepherosa Ziehau 	case ixgbe_media_type_backplane:
314079251f5eSSepherosa Ziehau 		ret_val = ixgbe_fc_autoneg_backplane(hw);
314179251f5eSSepherosa Ziehau 		break;
314279251f5eSSepherosa Ziehau 
314379251f5eSSepherosa Ziehau 	/* Autoneg flow control on copper adapters */
314479251f5eSSepherosa Ziehau 	case ixgbe_media_type_copper:
314579251f5eSSepherosa Ziehau 		if (ixgbe_device_supports_autoneg_fc(hw))
314679251f5eSSepherosa Ziehau 			ret_val = ixgbe_fc_autoneg_copper(hw);
314779251f5eSSepherosa Ziehau 		break;
314879251f5eSSepherosa Ziehau 
314979251f5eSSepherosa Ziehau 	default:
315079251f5eSSepherosa Ziehau 		break;
315179251f5eSSepherosa Ziehau 	}
315279251f5eSSepherosa Ziehau 
315379251f5eSSepherosa Ziehau out:
315479251f5eSSepherosa Ziehau 	if (ret_val == IXGBE_SUCCESS) {
315579251f5eSSepherosa Ziehau 		hw->fc.fc_was_autonegged = TRUE;
315679251f5eSSepherosa Ziehau 	} else {
315779251f5eSSepherosa Ziehau 		hw->fc.fc_was_autonegged = FALSE;
315879251f5eSSepherosa Ziehau 		hw->fc.current_mode = hw->fc.requested_mode;
315979251f5eSSepherosa Ziehau 	}
316079251f5eSSepherosa Ziehau }
316179251f5eSSepherosa Ziehau 
316279251f5eSSepherosa Ziehau /*
316379251f5eSSepherosa Ziehau  * ixgbe_pcie_timeout_poll - Return number of times to poll for completion
316479251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
316579251f5eSSepherosa Ziehau  *
316679251f5eSSepherosa Ziehau  * System-wide timeout range is encoded in PCIe Device Control2 register.
316779251f5eSSepherosa Ziehau  *
316879251f5eSSepherosa Ziehau  * Add 10% to specified maximum and return the number of times to poll for
316979251f5eSSepherosa Ziehau  * completion timeout, in units of 100 microsec.  Never return less than
317079251f5eSSepherosa Ziehau  * 800 = 80 millisec.
317179251f5eSSepherosa Ziehau  */
ixgbe_pcie_timeout_poll(struct ixgbe_hw * hw)317279251f5eSSepherosa Ziehau static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw)
317379251f5eSSepherosa Ziehau {
317479251f5eSSepherosa Ziehau 	s16 devctl2;
317579251f5eSSepherosa Ziehau 	u32 pollcnt;
317679251f5eSSepherosa Ziehau 
317779251f5eSSepherosa Ziehau 	devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
317879251f5eSSepherosa Ziehau 	devctl2 &= IXGBE_PCIDEVCTRL2_TIMEO_MASK;
317979251f5eSSepherosa Ziehau 
318079251f5eSSepherosa Ziehau 	switch (devctl2) {
318179251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_65_130ms:
318279251f5eSSepherosa Ziehau 		pollcnt = 1300;		/* 130 millisec */
318379251f5eSSepherosa Ziehau 		break;
318479251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_260_520ms:
318579251f5eSSepherosa Ziehau 		pollcnt = 5200;		/* 520 millisec */
318679251f5eSSepherosa Ziehau 		break;
318779251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_1_2s:
318879251f5eSSepherosa Ziehau 		pollcnt = 20000;	/* 2 sec */
318979251f5eSSepherosa Ziehau 		break;
319079251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_4_8s:
319179251f5eSSepherosa Ziehau 		pollcnt = 80000;	/* 8 sec */
319279251f5eSSepherosa Ziehau 		break;
319379251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_17_34s:
319479251f5eSSepherosa Ziehau 		pollcnt = 34000;	/* 34 sec */
319579251f5eSSepherosa Ziehau 		break;
319679251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_50_100us:	/* 100 microsecs */
319779251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_1_2ms:		/* 2 millisecs */
319879251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_16_32ms:		/* 32 millisec */
319979251f5eSSepherosa Ziehau 	case IXGBE_PCIDEVCTRL2_16_32ms_def:	/* 32 millisec default */
320079251f5eSSepherosa Ziehau 	default:
320179251f5eSSepherosa Ziehau 		pollcnt = 800;		/* 80 millisec minimum */
320279251f5eSSepherosa Ziehau 		break;
320379251f5eSSepherosa Ziehau 	}
320479251f5eSSepherosa Ziehau 
320579251f5eSSepherosa Ziehau 	/* add 10% to spec maximum */
320679251f5eSSepherosa Ziehau 	return (pollcnt * 11) / 10;
320779251f5eSSepherosa Ziehau }
320879251f5eSSepherosa Ziehau 
320979251f5eSSepherosa Ziehau /**
321079251f5eSSepherosa Ziehau  *  ixgbe_disable_pcie_master - Disable PCI-express master access
321179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
321279251f5eSSepherosa Ziehau  *
321379251f5eSSepherosa Ziehau  *  Disables PCI-Express master access and verifies there are no pending
321479251f5eSSepherosa Ziehau  *  requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable
321579251f5eSSepherosa Ziehau  *  bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS
321679251f5eSSepherosa Ziehau  *  is returned signifying master requests disabled.
321779251f5eSSepherosa Ziehau  **/
ixgbe_disable_pcie_master(struct ixgbe_hw * hw)321879251f5eSSepherosa Ziehau s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
321979251f5eSSepherosa Ziehau {
322079251f5eSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
322179251f5eSSepherosa Ziehau 	u32 i, poll;
322263d483cdSSepherosa Ziehau 	u16 value;
322379251f5eSSepherosa Ziehau 
322479251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_disable_pcie_master");
322579251f5eSSepherosa Ziehau 
322679251f5eSSepherosa Ziehau 	/* Always set this bit to ensure any future transactions are blocked */
322779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
322879251f5eSSepherosa Ziehau 
322979251f5eSSepherosa Ziehau 	/* Exit if master requests are blocked */
323063d483cdSSepherosa Ziehau 	if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
323163d483cdSSepherosa Ziehau 	    IXGBE_REMOVED(hw->hw_addr))
323279251f5eSSepherosa Ziehau 		goto out;
323379251f5eSSepherosa Ziehau 
323479251f5eSSepherosa Ziehau 	/* Poll for master request bit to clear */
323579251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
323679251f5eSSepherosa Ziehau 		usec_delay(100);
323779251f5eSSepherosa Ziehau 		if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
323879251f5eSSepherosa Ziehau 			goto out;
323979251f5eSSepherosa Ziehau 	}
324079251f5eSSepherosa Ziehau 
324179251f5eSSepherosa Ziehau 	/*
324279251f5eSSepherosa Ziehau 	 * Two consecutive resets are required via CTRL.RST per datasheet
324379251f5eSSepherosa Ziehau 	 * 5.2.5.3.2 Master Disable.  We set a flag to inform the reset routine
324479251f5eSSepherosa Ziehau 	 * of this need.  The first reset prevents new master requests from
324579251f5eSSepherosa Ziehau 	 * being issued by our device.  We then must wait 1usec or more for any
324679251f5eSSepherosa Ziehau 	 * remaining completions from the PCIe bus to trickle in, and then reset
324779251f5eSSepherosa Ziehau 	 * again to clear out any effects they may have had on our device.
324879251f5eSSepherosa Ziehau 	 */
324979251f5eSSepherosa Ziehau 	DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n");
325079251f5eSSepherosa Ziehau 	hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
325179251f5eSSepherosa Ziehau 
32526150453fSSepherosa Ziehau 	if (hw->mac.type >= ixgbe_mac_X550)
32536150453fSSepherosa Ziehau 		goto out;
32546150453fSSepherosa Ziehau 
325579251f5eSSepherosa Ziehau 	/*
325679251f5eSSepherosa Ziehau 	 * Before proceeding, make sure that the PCIe block does not have
325779251f5eSSepherosa Ziehau 	 * transactions pending.
325879251f5eSSepherosa Ziehau 	 */
325979251f5eSSepherosa Ziehau 	poll = ixgbe_pcie_timeout_poll(hw);
326079251f5eSSepherosa Ziehau 	for (i = 0; i < poll; i++) {
326179251f5eSSepherosa Ziehau 		usec_delay(100);
326263d483cdSSepherosa Ziehau 		value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS);
326363d483cdSSepherosa Ziehau 		if (IXGBE_REMOVED(hw->hw_addr))
326463d483cdSSepherosa Ziehau 			goto out;
326563d483cdSSepherosa Ziehau 		if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
326679251f5eSSepherosa Ziehau 			goto out;
326779251f5eSSepherosa Ziehau 	}
326879251f5eSSepherosa Ziehau 
326979251f5eSSepherosa Ziehau 	ERROR_REPORT1(IXGBE_ERROR_POLLING,
327079251f5eSSepherosa Ziehau 		     "PCIe transaction pending bit also did not clear.\n");
327179251f5eSSepherosa Ziehau 	status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
327279251f5eSSepherosa Ziehau 
327379251f5eSSepherosa Ziehau out:
327479251f5eSSepherosa Ziehau 	return status;
327579251f5eSSepherosa Ziehau }
327679251f5eSSepherosa Ziehau 
327779251f5eSSepherosa Ziehau /**
327879251f5eSSepherosa Ziehau  *  ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
327979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
328079251f5eSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to acquire
328179251f5eSSepherosa Ziehau  *
328279251f5eSSepherosa Ziehau  *  Acquires the SWFW semaphore through the GSSR register for the specified
328379251f5eSSepherosa Ziehau  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
328479251f5eSSepherosa Ziehau  **/
ixgbe_acquire_swfw_sync(struct ixgbe_hw * hw,u32 mask)328563d483cdSSepherosa Ziehau s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask)
328679251f5eSSepherosa Ziehau {
328779251f5eSSepherosa Ziehau 	u32 gssr = 0;
328879251f5eSSepherosa Ziehau 	u32 swmask = mask;
328979251f5eSSepherosa Ziehau 	u32 fwmask = mask << 5;
329079251f5eSSepherosa Ziehau 	u32 timeout = 200;
329179251f5eSSepherosa Ziehau 	u32 i;
329279251f5eSSepherosa Ziehau 
329379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_acquire_swfw_sync");
329479251f5eSSepherosa Ziehau 
329579251f5eSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
329679251f5eSSepherosa Ziehau 		/*
329779251f5eSSepherosa Ziehau 		 * SW NVM semaphore bit is used for access to all
329879251f5eSSepherosa Ziehau 		 * SW_FW_SYNC bits (not just NVM)
329979251f5eSSepherosa Ziehau 		 */
330079251f5eSSepherosa Ziehau 		if (ixgbe_get_eeprom_semaphore(hw))
330179251f5eSSepherosa Ziehau 			return IXGBE_ERR_SWFW_SYNC;
330279251f5eSSepherosa Ziehau 
330379251f5eSSepherosa Ziehau 		gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
330479251f5eSSepherosa Ziehau 		if (!(gssr & (fwmask | swmask))) {
330579251f5eSSepherosa Ziehau 			gssr |= swmask;
330679251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
330779251f5eSSepherosa Ziehau 			ixgbe_release_eeprom_semaphore(hw);
330879251f5eSSepherosa Ziehau 			return IXGBE_SUCCESS;
330979251f5eSSepherosa Ziehau 		} else {
331079251f5eSSepherosa Ziehau 			/* Resource is currently in use by FW or SW */
331179251f5eSSepherosa Ziehau 			ixgbe_release_eeprom_semaphore(hw);
331279251f5eSSepherosa Ziehau 			msec_delay(5);
331379251f5eSSepherosa Ziehau 		}
331479251f5eSSepherosa Ziehau 	}
331579251f5eSSepherosa Ziehau 
331679251f5eSSepherosa Ziehau 	/* If time expired clear the bits holding the lock and retry */
331779251f5eSSepherosa Ziehau 	if (gssr & (fwmask | swmask))
331879251f5eSSepherosa Ziehau 		ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
331979251f5eSSepherosa Ziehau 
332079251f5eSSepherosa Ziehau 	msec_delay(5);
332179251f5eSSepherosa Ziehau 	return IXGBE_ERR_SWFW_SYNC;
332279251f5eSSepherosa Ziehau }
332379251f5eSSepherosa Ziehau 
332479251f5eSSepherosa Ziehau /**
332579251f5eSSepherosa Ziehau  *  ixgbe_release_swfw_sync - Release SWFW semaphore
332679251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
332779251f5eSSepherosa Ziehau  *  @mask: Mask to specify which semaphore to release
332879251f5eSSepherosa Ziehau  *
332979251f5eSSepherosa Ziehau  *  Releases the SWFW semaphore through the GSSR register for the specified
333079251f5eSSepherosa Ziehau  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
333179251f5eSSepherosa Ziehau  **/
ixgbe_release_swfw_sync(struct ixgbe_hw * hw,u32 mask)333263d483cdSSepherosa Ziehau void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask)
333379251f5eSSepherosa Ziehau {
333479251f5eSSepherosa Ziehau 	u32 gssr;
333579251f5eSSepherosa Ziehau 	u32 swmask = mask;
333679251f5eSSepherosa Ziehau 
333779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_release_swfw_sync");
333879251f5eSSepherosa Ziehau 
333979251f5eSSepherosa Ziehau 	ixgbe_get_eeprom_semaphore(hw);
334079251f5eSSepherosa Ziehau 
334179251f5eSSepherosa Ziehau 	gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
334279251f5eSSepherosa Ziehau 	gssr &= ~swmask;
334379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
334479251f5eSSepherosa Ziehau 
334579251f5eSSepherosa Ziehau 	ixgbe_release_eeprom_semaphore(hw);
334679251f5eSSepherosa Ziehau }
334779251f5eSSepherosa Ziehau 
334879251f5eSSepherosa Ziehau /**
334979251f5eSSepherosa Ziehau  *  ixgbe_disable_sec_rx_path_generic - Stops the receive data path
335079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
335179251f5eSSepherosa Ziehau  *
335279251f5eSSepherosa Ziehau  *  Stops the receive data path and waits for the HW to internally empty
335379251f5eSSepherosa Ziehau  *  the Rx security block
335479251f5eSSepherosa Ziehau  **/
ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw * hw)335579251f5eSSepherosa Ziehau s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
335679251f5eSSepherosa Ziehau {
33576150453fSSepherosa Ziehau #define IXGBE_MAX_SECRX_POLL 4000
335879251f5eSSepherosa Ziehau 
335979251f5eSSepherosa Ziehau 	int i;
336079251f5eSSepherosa Ziehau 	int secrxreg;
336179251f5eSSepherosa Ziehau 
336279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_disable_sec_rx_path_generic");
336379251f5eSSepherosa Ziehau 
336479251f5eSSepherosa Ziehau 
336579251f5eSSepherosa Ziehau 	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
336679251f5eSSepherosa Ziehau 	secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
336779251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
336879251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
336979251f5eSSepherosa Ziehau 		secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
337079251f5eSSepherosa Ziehau 		if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
337179251f5eSSepherosa Ziehau 			break;
337279251f5eSSepherosa Ziehau 		else
337379251f5eSSepherosa Ziehau 			/* Use interrupt-safe sleep just in case */
33746150453fSSepherosa Ziehau 			usec_delay(10);
337579251f5eSSepherosa Ziehau 	}
337679251f5eSSepherosa Ziehau 
337779251f5eSSepherosa Ziehau 	/* For informational purposes only */
337879251f5eSSepherosa Ziehau 	if (i >= IXGBE_MAX_SECRX_POLL)
337979251f5eSSepherosa Ziehau 		DEBUGOUT("Rx unit being enabled before security "
338079251f5eSSepherosa Ziehau 			 "path fully disabled.  Continuing with init.\n");
338179251f5eSSepherosa Ziehau 
338279251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
338379251f5eSSepherosa Ziehau }
338479251f5eSSepherosa Ziehau 
338579251f5eSSepherosa Ziehau /**
338663d483cdSSepherosa Ziehau  *  prot_autoc_read_generic - Hides MAC differences needed for AUTOC read
338763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
3388dd5ce676SSepherosa Ziehau  *  @locked: bool to indicate whether the SW/FW lock was taken
338963d483cdSSepherosa Ziehau  *  @reg_val: Value we read from AUTOC
339063d483cdSSepherosa Ziehau  *
339163d483cdSSepherosa Ziehau  *  The default case requires no protection so just to the register read.
339263d483cdSSepherosa Ziehau  */
prot_autoc_read_generic(struct ixgbe_hw * hw,bool * locked,u32 * reg_val)339363d483cdSSepherosa Ziehau s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
339463d483cdSSepherosa Ziehau {
339563d483cdSSepherosa Ziehau 	*locked = FALSE;
339663d483cdSSepherosa Ziehau 	*reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
339763d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
339863d483cdSSepherosa Ziehau }
339963d483cdSSepherosa Ziehau 
340063d483cdSSepherosa Ziehau /**
340163d483cdSSepherosa Ziehau  * prot_autoc_write_generic - Hides MAC differences needed for AUTOC write
340263d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
340363d483cdSSepherosa Ziehau  * @reg_val: value to write to AUTOC
340463d483cdSSepherosa Ziehau  * @locked: bool to indicate whether the SW/FW lock was already taken by
340563d483cdSSepherosa Ziehau  *           previous read.
340663d483cdSSepherosa Ziehau  *
340763d483cdSSepherosa Ziehau  * The default case requires no protection so just to the register write.
340863d483cdSSepherosa Ziehau  */
prot_autoc_write_generic(struct ixgbe_hw * hw,u32 reg_val,bool locked)340963d483cdSSepherosa Ziehau s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked)
341063d483cdSSepherosa Ziehau {
341163d483cdSSepherosa Ziehau 	UNREFERENCED_1PARAMETER(locked);
341263d483cdSSepherosa Ziehau 
341363d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_val);
341463d483cdSSepherosa Ziehau 	return IXGBE_SUCCESS;
341563d483cdSSepherosa Ziehau }
341663d483cdSSepherosa Ziehau 
341763d483cdSSepherosa Ziehau /**
341879251f5eSSepherosa Ziehau  *  ixgbe_enable_sec_rx_path_generic - Enables the receive data path
341979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
342079251f5eSSepherosa Ziehau  *
342179251f5eSSepherosa Ziehau  *  Enables the receive data path.
342279251f5eSSepherosa Ziehau  **/
ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw * hw)342379251f5eSSepherosa Ziehau s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw)
342479251f5eSSepherosa Ziehau {
34256150453fSSepherosa Ziehau 	u32 secrxreg;
342679251f5eSSepherosa Ziehau 
342779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_sec_rx_path_generic");
342879251f5eSSepherosa Ziehau 
342979251f5eSSepherosa Ziehau 	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
343079251f5eSSepherosa Ziehau 	secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
343179251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
343279251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
343379251f5eSSepherosa Ziehau 
343479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
343579251f5eSSepherosa Ziehau }
343679251f5eSSepherosa Ziehau 
343779251f5eSSepherosa Ziehau /**
343879251f5eSSepherosa Ziehau  *  ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
343979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
344079251f5eSSepherosa Ziehau  *  @regval: register value to write to RXCTRL
344179251f5eSSepherosa Ziehau  *
344279251f5eSSepherosa Ziehau  *  Enables the Rx DMA unit
344379251f5eSSepherosa Ziehau  **/
ixgbe_enable_rx_dma_generic(struct ixgbe_hw * hw,u32 regval)344479251f5eSSepherosa Ziehau s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
344579251f5eSSepherosa Ziehau {
344679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_rx_dma_generic");
344779251f5eSSepherosa Ziehau 
344863d483cdSSepherosa Ziehau 	if (regval & IXGBE_RXCTRL_RXEN)
344963d483cdSSepherosa Ziehau 		ixgbe_enable_rx(hw);
345063d483cdSSepherosa Ziehau 	else
345163d483cdSSepherosa Ziehau 		ixgbe_disable_rx(hw);
345279251f5eSSepherosa Ziehau 
345379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
345479251f5eSSepherosa Ziehau }
345579251f5eSSepherosa Ziehau 
345679251f5eSSepherosa Ziehau /**
345779251f5eSSepherosa Ziehau  *  ixgbe_blink_led_start_generic - Blink LED based on index.
345879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
345979251f5eSSepherosa Ziehau  *  @index: led number to blink
346079251f5eSSepherosa Ziehau  **/
ixgbe_blink_led_start_generic(struct ixgbe_hw * hw,u32 index)346179251f5eSSepherosa Ziehau s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
346279251f5eSSepherosa Ziehau {
346379251f5eSSepherosa Ziehau 	ixgbe_link_speed speed = 0;
346479251f5eSSepherosa Ziehau 	bool link_up = 0;
346563d483cdSSepherosa Ziehau 	u32 autoc_reg = 0;
346679251f5eSSepherosa Ziehau 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
346779251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
346863d483cdSSepherosa Ziehau 	bool locked = FALSE;
346979251f5eSSepherosa Ziehau 
347079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_blink_led_start_generic");
347179251f5eSSepherosa Ziehau 
34726150453fSSepherosa Ziehau 	if (index > 3)
34736150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
34746150453fSSepherosa Ziehau 
347579251f5eSSepherosa Ziehau 	/*
347679251f5eSSepherosa Ziehau 	 * Link must be up to auto-blink the LEDs;
347779251f5eSSepherosa Ziehau 	 * Force it if link is down.
347879251f5eSSepherosa Ziehau 	 */
347979251f5eSSepherosa Ziehau 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
348079251f5eSSepherosa Ziehau 
348179251f5eSSepherosa Ziehau 	if (!link_up) {
348263d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
348363d483cdSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
348479251f5eSSepherosa Ziehau 			goto out;
348579251f5eSSepherosa Ziehau 
348679251f5eSSepherosa Ziehau 		autoc_reg |= IXGBE_AUTOC_AN_RESTART;
348779251f5eSSepherosa Ziehau 		autoc_reg |= IXGBE_AUTOC_FLU;
348879251f5eSSepherosa Ziehau 
348963d483cdSSepherosa Ziehau 		ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
349063d483cdSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
349163d483cdSSepherosa Ziehau 			goto out;
349263d483cdSSepherosa Ziehau 
349363d483cdSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
349479251f5eSSepherosa Ziehau 		msec_delay(10);
349579251f5eSSepherosa Ziehau 	}
349679251f5eSSepherosa Ziehau 
349779251f5eSSepherosa Ziehau 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
349879251f5eSSepherosa Ziehau 	led_reg |= IXGBE_LED_BLINK(index);
349979251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
350079251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
350179251f5eSSepherosa Ziehau 
350279251f5eSSepherosa Ziehau out:
350379251f5eSSepherosa Ziehau 	return ret_val;
350479251f5eSSepherosa Ziehau }
350579251f5eSSepherosa Ziehau 
350679251f5eSSepherosa Ziehau /**
350779251f5eSSepherosa Ziehau  *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
350879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
350979251f5eSSepherosa Ziehau  *  @index: led number to stop blinking
351079251f5eSSepherosa Ziehau  **/
ixgbe_blink_led_stop_generic(struct ixgbe_hw * hw,u32 index)351179251f5eSSepherosa Ziehau s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
351279251f5eSSepherosa Ziehau {
351363d483cdSSepherosa Ziehau 	u32 autoc_reg = 0;
351479251f5eSSepherosa Ziehau 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
351579251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
351663d483cdSSepherosa Ziehau 	bool locked = FALSE;
351779251f5eSSepherosa Ziehau 
351879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_blink_led_stop_generic");
351979251f5eSSepherosa Ziehau 
35206150453fSSepherosa Ziehau 	if (index > 3)
35216150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
35226150453fSSepherosa Ziehau 
35236150453fSSepherosa Ziehau 
352463d483cdSSepherosa Ziehau 	ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
352563d483cdSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
352663d483cdSSepherosa Ziehau 		goto out;
352779251f5eSSepherosa Ziehau 
352879251f5eSSepherosa Ziehau 	autoc_reg &= ~IXGBE_AUTOC_FLU;
352979251f5eSSepherosa Ziehau 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
353079251f5eSSepherosa Ziehau 
353163d483cdSSepherosa Ziehau 	ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
353263d483cdSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS)
353363d483cdSSepherosa Ziehau 		goto out;
353479251f5eSSepherosa Ziehau 
353579251f5eSSepherosa Ziehau 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
353679251f5eSSepherosa Ziehau 	led_reg &= ~IXGBE_LED_BLINK(index);
353779251f5eSSepherosa Ziehau 	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
353879251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
353979251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
354079251f5eSSepherosa Ziehau 
354179251f5eSSepherosa Ziehau out:
354279251f5eSSepherosa Ziehau 	return ret_val;
354379251f5eSSepherosa Ziehau }
354479251f5eSSepherosa Ziehau 
354579251f5eSSepherosa Ziehau /**
354679251f5eSSepherosa Ziehau  *  ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM
354779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
354879251f5eSSepherosa Ziehau  *  @san_mac_offset: SAN MAC address offset
354979251f5eSSepherosa Ziehau  *
355079251f5eSSepherosa Ziehau  *  This function will read the EEPROM location for the SAN MAC address
355179251f5eSSepherosa Ziehau  *  pointer, and returns the value at that location.  This is used in both
355279251f5eSSepherosa Ziehau  *  get and set mac_addr routines.
355379251f5eSSepherosa Ziehau  **/
ixgbe_get_san_mac_addr_offset(struct ixgbe_hw * hw,u16 * san_mac_offset)355479251f5eSSepherosa Ziehau static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
355579251f5eSSepherosa Ziehau 					 u16 *san_mac_offset)
355679251f5eSSepherosa Ziehau {
355779251f5eSSepherosa Ziehau 	s32 ret_val;
355879251f5eSSepherosa Ziehau 
355979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_san_mac_addr_offset");
356079251f5eSSepherosa Ziehau 
356179251f5eSSepherosa Ziehau 	/*
356279251f5eSSepherosa Ziehau 	 * First read the EEPROM pointer to see if the MAC addresses are
356379251f5eSSepherosa Ziehau 	 * available.
356479251f5eSSepherosa Ziehau 	 */
356579251f5eSSepherosa Ziehau 	ret_val = hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR,
356679251f5eSSepherosa Ziehau 				      san_mac_offset);
356779251f5eSSepherosa Ziehau 	if (ret_val) {
356879251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
356979251f5eSSepherosa Ziehau 			      "eeprom at offset %d failed",
357079251f5eSSepherosa Ziehau 			      IXGBE_SAN_MAC_ADDR_PTR);
357179251f5eSSepherosa Ziehau 	}
357279251f5eSSepherosa Ziehau 
357379251f5eSSepherosa Ziehau 	return ret_val;
357479251f5eSSepherosa Ziehau }
357579251f5eSSepherosa Ziehau 
357679251f5eSSepherosa Ziehau /**
357779251f5eSSepherosa Ziehau  *  ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM
357879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
357979251f5eSSepherosa Ziehau  *  @san_mac_addr: SAN MAC address
358079251f5eSSepherosa Ziehau  *
358179251f5eSSepherosa Ziehau  *  Reads the SAN MAC address from the EEPROM, if it's available.  This is
358279251f5eSSepherosa Ziehau  *  per-port, so set_lan_id() must be called before reading the addresses.
358379251f5eSSepherosa Ziehau  *  set_lan_id() is called by identify_sfp(), but this cannot be relied
358479251f5eSSepherosa Ziehau  *  upon for non-SFP connections, so we must call it here.
358579251f5eSSepherosa Ziehau  **/
ixgbe_get_san_mac_addr_generic(struct ixgbe_hw * hw,u8 * san_mac_addr)358679251f5eSSepherosa Ziehau s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
358779251f5eSSepherosa Ziehau {
358879251f5eSSepherosa Ziehau 	u16 san_mac_data, san_mac_offset;
358979251f5eSSepherosa Ziehau 	u8 i;
359079251f5eSSepherosa Ziehau 	s32 ret_val;
359179251f5eSSepherosa Ziehau 
359279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_san_mac_addr_generic");
359379251f5eSSepherosa Ziehau 
359479251f5eSSepherosa Ziehau 	/*
359579251f5eSSepherosa Ziehau 	 * First read the EEPROM pointer to see if the MAC addresses are
359679251f5eSSepherosa Ziehau 	 * available.  If they're not, no point in calling set_lan_id() here.
359779251f5eSSepherosa Ziehau 	 */
359879251f5eSSepherosa Ziehau 	ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
359979251f5eSSepherosa Ziehau 	if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)
360079251f5eSSepherosa Ziehau 		goto san_mac_addr_out;
360179251f5eSSepherosa Ziehau 
360279251f5eSSepherosa Ziehau 	/* make sure we know which port we need to program */
360379251f5eSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
360479251f5eSSepherosa Ziehau 	/* apply the port offset to the address offset */
360579251f5eSSepherosa Ziehau 	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
360679251f5eSSepherosa Ziehau 			 (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
360779251f5eSSepherosa Ziehau 	for (i = 0; i < 3; i++) {
360879251f5eSSepherosa Ziehau 		ret_val = hw->eeprom.ops.read(hw, san_mac_offset,
360979251f5eSSepherosa Ziehau 					      &san_mac_data);
361079251f5eSSepherosa Ziehau 		if (ret_val) {
361179251f5eSSepherosa Ziehau 			ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
361279251f5eSSepherosa Ziehau 				      "eeprom read at offset %d failed",
361379251f5eSSepherosa Ziehau 				      san_mac_offset);
361479251f5eSSepherosa Ziehau 			goto san_mac_addr_out;
361579251f5eSSepherosa Ziehau 		}
361679251f5eSSepherosa Ziehau 		san_mac_addr[i * 2] = (u8)(san_mac_data);
361779251f5eSSepherosa Ziehau 		san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
361879251f5eSSepherosa Ziehau 		san_mac_offset++;
361979251f5eSSepherosa Ziehau 	}
362079251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
362179251f5eSSepherosa Ziehau 
362279251f5eSSepherosa Ziehau san_mac_addr_out:
362379251f5eSSepherosa Ziehau 	/*
362479251f5eSSepherosa Ziehau 	 * No addresses available in this EEPROM.  It's not an
362579251f5eSSepherosa Ziehau 	 * error though, so just wipe the local address and return.
362679251f5eSSepherosa Ziehau 	 */
362779251f5eSSepherosa Ziehau 	for (i = 0; i < 6; i++)
362879251f5eSSepherosa Ziehau 		san_mac_addr[i] = 0xFF;
362979251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
363079251f5eSSepherosa Ziehau }
363179251f5eSSepherosa Ziehau 
363279251f5eSSepherosa Ziehau /**
363379251f5eSSepherosa Ziehau  *  ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM
363479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
363579251f5eSSepherosa Ziehau  *  @san_mac_addr: SAN MAC address
363679251f5eSSepherosa Ziehau  *
363779251f5eSSepherosa Ziehau  *  Write a SAN MAC address to the EEPROM.
363879251f5eSSepherosa Ziehau  **/
ixgbe_set_san_mac_addr_generic(struct ixgbe_hw * hw,u8 * san_mac_addr)363979251f5eSSepherosa Ziehau s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
364079251f5eSSepherosa Ziehau {
364179251f5eSSepherosa Ziehau 	s32 ret_val;
364279251f5eSSepherosa Ziehau 	u16 san_mac_data, san_mac_offset;
364379251f5eSSepherosa Ziehau 	u8 i;
364479251f5eSSepherosa Ziehau 
364579251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_san_mac_addr_generic");
364679251f5eSSepherosa Ziehau 
364779251f5eSSepherosa Ziehau 	/* Look for SAN mac address pointer.  If not defined, return */
364879251f5eSSepherosa Ziehau 	ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
364979251f5eSSepherosa Ziehau 	if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)
365079251f5eSSepherosa Ziehau 		return IXGBE_ERR_NO_SAN_ADDR_PTR;
365179251f5eSSepherosa Ziehau 
365279251f5eSSepherosa Ziehau 	/* Make sure we know which port we need to write */
365379251f5eSSepherosa Ziehau 	hw->mac.ops.set_lan_id(hw);
365479251f5eSSepherosa Ziehau 	/* Apply the port offset to the address offset */
365579251f5eSSepherosa Ziehau 	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
365679251f5eSSepherosa Ziehau 			 (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
365779251f5eSSepherosa Ziehau 
365879251f5eSSepherosa Ziehau 	for (i = 0; i < 3; i++) {
365979251f5eSSepherosa Ziehau 		san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8);
366079251f5eSSepherosa Ziehau 		san_mac_data |= (u16)(san_mac_addr[i * 2]);
366179251f5eSSepherosa Ziehau 		hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data);
366279251f5eSSepherosa Ziehau 		san_mac_offset++;
366379251f5eSSepherosa Ziehau 	}
366479251f5eSSepherosa Ziehau 
366579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
366679251f5eSSepherosa Ziehau }
366779251f5eSSepherosa Ziehau 
366879251f5eSSepherosa Ziehau /**
366979251f5eSSepherosa Ziehau  *  ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count
367079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
367179251f5eSSepherosa Ziehau  *
367279251f5eSSepherosa Ziehau  *  Read PCIe configuration space, and get the MSI-X vector count from
367379251f5eSSepherosa Ziehau  *  the capabilities table.
367479251f5eSSepherosa Ziehau  **/
ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw * hw)367579251f5eSSepherosa Ziehau u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
367679251f5eSSepherosa Ziehau {
367779251f5eSSepherosa Ziehau 	u16 msix_count = 1;
367879251f5eSSepherosa Ziehau 	u16 max_msix_count;
367979251f5eSSepherosa Ziehau 	u16 pcie_offset;
368079251f5eSSepherosa Ziehau 
368179251f5eSSepherosa Ziehau 	switch (hw->mac.type) {
368279251f5eSSepherosa Ziehau 	case ixgbe_mac_82598EB:
368379251f5eSSepherosa Ziehau 		pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS;
368479251f5eSSepherosa Ziehau 		max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598;
368579251f5eSSepherosa Ziehau 		break;
368679251f5eSSepherosa Ziehau 	case ixgbe_mac_82599EB:
368779251f5eSSepherosa Ziehau 	case ixgbe_mac_X540:
368863d483cdSSepherosa Ziehau 	case ixgbe_mac_X550:
368963d483cdSSepherosa Ziehau 	case ixgbe_mac_X550EM_x:
369063d483cdSSepherosa Ziehau 	case ixgbe_mac_X550EM_a:
369179251f5eSSepherosa Ziehau 		pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
369279251f5eSSepherosa Ziehau 		max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
369379251f5eSSepherosa Ziehau 		break;
369479251f5eSSepherosa Ziehau 	default:
369579251f5eSSepherosa Ziehau 		return msix_count;
369679251f5eSSepherosa Ziehau 	}
369779251f5eSSepherosa Ziehau 
369879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_pcie_msix_count_generic");
369979251f5eSSepherosa Ziehau 	msix_count = IXGBE_READ_PCIE_WORD(hw, pcie_offset);
370063d483cdSSepherosa Ziehau 	if (IXGBE_REMOVED(hw->hw_addr))
370163d483cdSSepherosa Ziehau 		msix_count = 0;
370279251f5eSSepherosa Ziehau 	msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
370379251f5eSSepherosa Ziehau 
370479251f5eSSepherosa Ziehau 	/* MSI-X count is zero-based in HW */
370579251f5eSSepherosa Ziehau 	msix_count++;
370679251f5eSSepherosa Ziehau 
370779251f5eSSepherosa Ziehau 	if (msix_count > max_msix_count)
370879251f5eSSepherosa Ziehau 		msix_count = max_msix_count;
370979251f5eSSepherosa Ziehau 
371079251f5eSSepherosa Ziehau 	return msix_count;
371179251f5eSSepherosa Ziehau }
371279251f5eSSepherosa Ziehau 
371379251f5eSSepherosa Ziehau /**
371479251f5eSSepherosa Ziehau  *  ixgbe_insert_mac_addr_generic - Find a RAR for this mac address
371579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
371679251f5eSSepherosa Ziehau  *  @addr: Address to put into receive address register
371779251f5eSSepherosa Ziehau  *  @vmdq: VMDq pool to assign
371879251f5eSSepherosa Ziehau  *
371979251f5eSSepherosa Ziehau  *  Puts an ethernet address into a receive address register, or
372079251f5eSSepherosa Ziehau  *  finds the rar that it is aleady in; adds to the pool list
372179251f5eSSepherosa Ziehau  **/
ixgbe_insert_mac_addr_generic(struct ixgbe_hw * hw,u8 * addr,u32 vmdq)372279251f5eSSepherosa Ziehau s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
372379251f5eSSepherosa Ziehau {
372479251f5eSSepherosa Ziehau 	static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF;
372579251f5eSSepherosa Ziehau 	u32 first_empty_rar = NO_EMPTY_RAR_FOUND;
372679251f5eSSepherosa Ziehau 	u32 rar;
372779251f5eSSepherosa Ziehau 	u32 rar_low, rar_high;
372879251f5eSSepherosa Ziehau 	u32 addr_low, addr_high;
372979251f5eSSepherosa Ziehau 
373079251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_insert_mac_addr_generic");
373179251f5eSSepherosa Ziehau 
373279251f5eSSepherosa Ziehau 	/* swap bytes for HW little endian */
373379251f5eSSepherosa Ziehau 	addr_low  = addr[0] | (addr[1] << 8)
373479251f5eSSepherosa Ziehau 			    | (addr[2] << 16)
373579251f5eSSepherosa Ziehau 			    | (addr[3] << 24);
373679251f5eSSepherosa Ziehau 	addr_high = addr[4] | (addr[5] << 8);
373779251f5eSSepherosa Ziehau 
373879251f5eSSepherosa Ziehau 	/*
373979251f5eSSepherosa Ziehau 	 * Either find the mac_id in rar or find the first empty space.
374079251f5eSSepherosa Ziehau 	 * rar_highwater points to just after the highest currently used
374179251f5eSSepherosa Ziehau 	 * rar in order to shorten the search.  It grows when we add a new
374279251f5eSSepherosa Ziehau 	 * rar to the top.
374379251f5eSSepherosa Ziehau 	 */
374479251f5eSSepherosa Ziehau 	for (rar = 0; rar < hw->mac.rar_highwater; rar++) {
374579251f5eSSepherosa Ziehau 		rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
374679251f5eSSepherosa Ziehau 
374779251f5eSSepherosa Ziehau 		if (((IXGBE_RAH_AV & rar_high) == 0)
374879251f5eSSepherosa Ziehau 		    && first_empty_rar == NO_EMPTY_RAR_FOUND) {
374979251f5eSSepherosa Ziehau 			first_empty_rar = rar;
375079251f5eSSepherosa Ziehau 		} else if ((rar_high & 0xFFFF) == addr_high) {
375179251f5eSSepherosa Ziehau 			rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar));
375279251f5eSSepherosa Ziehau 			if (rar_low == addr_low)
375379251f5eSSepherosa Ziehau 				break;    /* found it already in the rars */
375479251f5eSSepherosa Ziehau 		}
375579251f5eSSepherosa Ziehau 	}
375679251f5eSSepherosa Ziehau 
375779251f5eSSepherosa Ziehau 	if (rar < hw->mac.rar_highwater) {
375879251f5eSSepherosa Ziehau 		/* already there so just add to the pool bits */
375979251f5eSSepherosa Ziehau 		ixgbe_set_vmdq(hw, rar, vmdq);
376079251f5eSSepherosa Ziehau 	} else if (first_empty_rar != NO_EMPTY_RAR_FOUND) {
376179251f5eSSepherosa Ziehau 		/* stick it into first empty RAR slot we found */
376279251f5eSSepherosa Ziehau 		rar = first_empty_rar;
376379251f5eSSepherosa Ziehau 		ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
376479251f5eSSepherosa Ziehau 	} else if (rar == hw->mac.rar_highwater) {
376579251f5eSSepherosa Ziehau 		/* add it to the top of the list and inc the highwater mark */
376679251f5eSSepherosa Ziehau 		ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
376779251f5eSSepherosa Ziehau 		hw->mac.rar_highwater++;
376879251f5eSSepherosa Ziehau 	} else if (rar >= hw->mac.num_rar_entries) {
376979251f5eSSepherosa Ziehau 		return IXGBE_ERR_INVALID_MAC_ADDR;
377079251f5eSSepherosa Ziehau 	}
377179251f5eSSepherosa Ziehau 
377279251f5eSSepherosa Ziehau 	/*
377379251f5eSSepherosa Ziehau 	 * If we found rar[0], make sure the default pool bit (we use pool 0)
377479251f5eSSepherosa Ziehau 	 * remains cleared to be sure default pool packets will get delivered
377579251f5eSSepherosa Ziehau 	 */
377679251f5eSSepherosa Ziehau 	if (rar == 0)
377779251f5eSSepherosa Ziehau 		ixgbe_clear_vmdq(hw, rar, 0);
377879251f5eSSepherosa Ziehau 
377979251f5eSSepherosa Ziehau 	return rar;
378079251f5eSSepherosa Ziehau }
378179251f5eSSepherosa Ziehau 
378279251f5eSSepherosa Ziehau /**
378379251f5eSSepherosa Ziehau  *  ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address
378479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware struct
378579251f5eSSepherosa Ziehau  *  @rar: receive address register index to disassociate
378679251f5eSSepherosa Ziehau  *  @vmdq: VMDq pool index to remove from the rar
378779251f5eSSepherosa Ziehau  **/
ixgbe_clear_vmdq_generic(struct ixgbe_hw * hw,u32 rar,u32 vmdq)378879251f5eSSepherosa Ziehau s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
378979251f5eSSepherosa Ziehau {
379079251f5eSSepherosa Ziehau 	u32 mpsar_lo, mpsar_hi;
379179251f5eSSepherosa Ziehau 	u32 rar_entries = hw->mac.num_rar_entries;
379279251f5eSSepherosa Ziehau 
379379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clear_vmdq_generic");
379479251f5eSSepherosa Ziehau 
379579251f5eSSepherosa Ziehau 	/* Make sure we are using a valid rar index range */
379679251f5eSSepherosa Ziehau 	if (rar >= rar_entries) {
379779251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
379879251f5eSSepherosa Ziehau 			     "RAR index %d is out of range.\n", rar);
379979251f5eSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
380079251f5eSSepherosa Ziehau 	}
380179251f5eSSepherosa Ziehau 
380279251f5eSSepherosa Ziehau 	mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
380379251f5eSSepherosa Ziehau 	mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
380479251f5eSSepherosa Ziehau 
380563d483cdSSepherosa Ziehau 	if (IXGBE_REMOVED(hw->hw_addr))
380663d483cdSSepherosa Ziehau 		goto done;
380763d483cdSSepherosa Ziehau 
380879251f5eSSepherosa Ziehau 	if (!mpsar_lo && !mpsar_hi)
380979251f5eSSepherosa Ziehau 		goto done;
381079251f5eSSepherosa Ziehau 
381179251f5eSSepherosa Ziehau 	if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
381279251f5eSSepherosa Ziehau 		if (mpsar_lo) {
381379251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
381479251f5eSSepherosa Ziehau 			mpsar_lo = 0;
381579251f5eSSepherosa Ziehau 		}
381679251f5eSSepherosa Ziehau 		if (mpsar_hi) {
381779251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
381879251f5eSSepherosa Ziehau 			mpsar_hi = 0;
381979251f5eSSepherosa Ziehau 		}
382079251f5eSSepherosa Ziehau 	} else if (vmdq < 32) {
382179251f5eSSepherosa Ziehau 		mpsar_lo &= ~(1 << vmdq);
382279251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
382379251f5eSSepherosa Ziehau 	} else {
382479251f5eSSepherosa Ziehau 		mpsar_hi &= ~(1 << (vmdq - 32));
382579251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
382679251f5eSSepherosa Ziehau 	}
382779251f5eSSepherosa Ziehau 
382879251f5eSSepherosa Ziehau 	/* was that the last pool using this rar? */
38296150453fSSepherosa Ziehau 	if (mpsar_lo == 0 && mpsar_hi == 0 &&
38306150453fSSepherosa Ziehau 	    rar != 0 && rar != hw->mac.san_mac_rar_index)
383179251f5eSSepherosa Ziehau 		hw->mac.ops.clear_rar(hw, rar);
383279251f5eSSepherosa Ziehau done:
383379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
383479251f5eSSepherosa Ziehau }
383579251f5eSSepherosa Ziehau 
383679251f5eSSepherosa Ziehau /**
383779251f5eSSepherosa Ziehau  *  ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address
383879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware struct
383979251f5eSSepherosa Ziehau  *  @rar: receive address register index to associate with a VMDq index
384079251f5eSSepherosa Ziehau  *  @vmdq: VMDq pool index
384179251f5eSSepherosa Ziehau  **/
ixgbe_set_vmdq_generic(struct ixgbe_hw * hw,u32 rar,u32 vmdq)384279251f5eSSepherosa Ziehau s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
384379251f5eSSepherosa Ziehau {
384479251f5eSSepherosa Ziehau 	u32 mpsar;
384579251f5eSSepherosa Ziehau 	u32 rar_entries = hw->mac.num_rar_entries;
384679251f5eSSepherosa Ziehau 
384779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_vmdq_generic");
384879251f5eSSepherosa Ziehau 
384979251f5eSSepherosa Ziehau 	/* Make sure we are using a valid rar index range */
385079251f5eSSepherosa Ziehau 	if (rar >= rar_entries) {
385179251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
385279251f5eSSepherosa Ziehau 			     "RAR index %d is out of range.\n", rar);
385379251f5eSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
385479251f5eSSepherosa Ziehau 	}
385579251f5eSSepherosa Ziehau 
385679251f5eSSepherosa Ziehau 	if (vmdq < 32) {
385779251f5eSSepherosa Ziehau 		mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
385879251f5eSSepherosa Ziehau 		mpsar |= 1 << vmdq;
385979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
386079251f5eSSepherosa Ziehau 	} else {
386179251f5eSSepherosa Ziehau 		mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
386279251f5eSSepherosa Ziehau 		mpsar |= 1 << (vmdq - 32);
386379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
386479251f5eSSepherosa Ziehau 	}
386579251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
386679251f5eSSepherosa Ziehau }
386779251f5eSSepherosa Ziehau 
386879251f5eSSepherosa Ziehau /**
386979251f5eSSepherosa Ziehau  *  This function should only be involved in the IOV mode.
387079251f5eSSepherosa Ziehau  *  In IOV mode, Default pool is next pool after the number of
387179251f5eSSepherosa Ziehau  *  VFs advertized and not 0.
387279251f5eSSepherosa Ziehau  *  MPSAR table needs to be updated for SAN_MAC RAR [hw->mac.san_mac_rar_index]
387379251f5eSSepherosa Ziehau  *
387479251f5eSSepherosa Ziehau  *  ixgbe_set_vmdq_san_mac - Associate default VMDq pool index with a rx address
387579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware struct
387679251f5eSSepherosa Ziehau  *  @vmdq: VMDq pool index
387779251f5eSSepherosa Ziehau  **/
ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw * hw,u32 vmdq)387879251f5eSSepherosa Ziehau s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq)
387979251f5eSSepherosa Ziehau {
388079251f5eSSepherosa Ziehau 	u32 rar = hw->mac.san_mac_rar_index;
388179251f5eSSepherosa Ziehau 
388279251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_vmdq_san_mac");
388379251f5eSSepherosa Ziehau 
388479251f5eSSepherosa Ziehau 	if (vmdq < 32) {
388579251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 1 << vmdq);
388679251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
388779251f5eSSepherosa Ziehau 	} else {
388879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
388979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 1 << (vmdq - 32));
389079251f5eSSepherosa Ziehau 	}
389179251f5eSSepherosa Ziehau 
389279251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
389379251f5eSSepherosa Ziehau }
389479251f5eSSepherosa Ziehau 
389579251f5eSSepherosa Ziehau /**
389679251f5eSSepherosa Ziehau  *  ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array
389779251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
389879251f5eSSepherosa Ziehau  **/
ixgbe_init_uta_tables_generic(struct ixgbe_hw * hw)389979251f5eSSepherosa Ziehau s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
390079251f5eSSepherosa Ziehau {
390179251f5eSSepherosa Ziehau 	int i;
390279251f5eSSepherosa Ziehau 
390379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_init_uta_tables_generic");
390479251f5eSSepherosa Ziehau 	DEBUGOUT(" Clearing UTA\n");
390579251f5eSSepherosa Ziehau 
390679251f5eSSepherosa Ziehau 	for (i = 0; i < 128; i++)
390779251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
390879251f5eSSepherosa Ziehau 
390979251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
391079251f5eSSepherosa Ziehau }
391179251f5eSSepherosa Ziehau 
391279251f5eSSepherosa Ziehau /**
391379251f5eSSepherosa Ziehau  *  ixgbe_find_vlvf_slot - find the vlanid or the first empty slot
391479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
391579251f5eSSepherosa Ziehau  *  @vlan: VLAN id to write to VLAN filter
3916dd5ce676SSepherosa Ziehau  *  @vlvf_bypass: TRUE to find vlanid only, FALSE returns first empty slot if
3917dd5ce676SSepherosa Ziehau  *		  vlanid not found
3918dd5ce676SSepherosa Ziehau  *
391979251f5eSSepherosa Ziehau  *
392079251f5eSSepherosa Ziehau  *  return the VLVF index where this VLAN id should be placed
392179251f5eSSepherosa Ziehau  *
392279251f5eSSepherosa Ziehau  **/
ixgbe_find_vlvf_slot(struct ixgbe_hw * hw,u32 vlan,bool vlvf_bypass)39236150453fSSepherosa Ziehau s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
392479251f5eSSepherosa Ziehau {
39256150453fSSepherosa Ziehau 	s32 regindex, first_empty_slot;
39266150453fSSepherosa Ziehau 	u32 bits;
392779251f5eSSepherosa Ziehau 
392879251f5eSSepherosa Ziehau 	/* short cut the special case */
392979251f5eSSepherosa Ziehau 	if (vlan == 0)
393079251f5eSSepherosa Ziehau 		return 0;
393179251f5eSSepherosa Ziehau 
39326150453fSSepherosa Ziehau 	/* if vlvf_bypass is set we don't want to use an empty slot, we
39336150453fSSepherosa Ziehau 	 * will simply bypass the VLVF if there are no entries present in the
39346150453fSSepherosa Ziehau 	 * VLVF that contain our VLAN
393579251f5eSSepherosa Ziehau 	 */
39366150453fSSepherosa Ziehau 	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
39376150453fSSepherosa Ziehau 
39386150453fSSepherosa Ziehau 	/* add VLAN enable bit for comparison */
39396150453fSSepherosa Ziehau 	vlan |= IXGBE_VLVF_VIEN;
39406150453fSSepherosa Ziehau 
39416150453fSSepherosa Ziehau 	/* Search for the vlan id in the VLVF entries. Save off the first empty
39426150453fSSepherosa Ziehau 	 * slot found along the way.
39436150453fSSepherosa Ziehau 	 *
39446150453fSSepherosa Ziehau 	 * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
39456150453fSSepherosa Ziehau 	 */
39466150453fSSepherosa Ziehau 	for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
394779251f5eSSepherosa Ziehau 		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
39486150453fSSepherosa Ziehau 		if (bits == vlan)
394979251f5eSSepherosa Ziehau 			return regindex;
39506150453fSSepherosa Ziehau 		if (!first_empty_slot && !bits)
39516150453fSSepherosa Ziehau 			first_empty_slot = regindex;
39526150453fSSepherosa Ziehau 	}
39536150453fSSepherosa Ziehau 
39546150453fSSepherosa Ziehau 	/* If we are here then we didn't find the VLAN.  Return first empty
39556150453fSSepherosa Ziehau 	 * slot we found during our search, else error.
39566150453fSSepherosa Ziehau 	 */
39576150453fSSepherosa Ziehau 	if (!first_empty_slot)
39586150453fSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "No space in VLVF.\n");
39596150453fSSepherosa Ziehau 
39606150453fSSepherosa Ziehau 	return first_empty_slot ? first_empty_slot : IXGBE_ERR_NO_SPACE;
396179251f5eSSepherosa Ziehau }
396279251f5eSSepherosa Ziehau 
396379251f5eSSepherosa Ziehau /**
396479251f5eSSepherosa Ziehau  *  ixgbe_set_vfta_generic - Set VLAN filter table
396579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
396679251f5eSSepherosa Ziehau  *  @vlan: VLAN id to write to VLAN filter
39676150453fSSepherosa Ziehau  *  @vind: VMDq output index that maps queue to VLAN id in VLVFB
39686150453fSSepherosa Ziehau  *  @vlan_on: boolean flag to turn on/off VLAN
39696150453fSSepherosa Ziehau  *  @vlvf_bypass: boolean flag indicating updating default pool is okay
397079251f5eSSepherosa Ziehau  *
397179251f5eSSepherosa Ziehau  *  Turn on/off specified VLAN in the VLAN filter table.
397279251f5eSSepherosa Ziehau  **/
ixgbe_set_vfta_generic(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,bool vlvf_bypass)397379251f5eSSepherosa Ziehau s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
39746150453fSSepherosa Ziehau 			   bool vlan_on, bool vlvf_bypass)
397579251f5eSSepherosa Ziehau {
39766150453fSSepherosa Ziehau 	u32 regidx, vfta_delta, vfta;
39776150453fSSepherosa Ziehau 	s32 ret_val;
397879251f5eSSepherosa Ziehau 
397979251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_vfta_generic");
398079251f5eSSepherosa Ziehau 
39816150453fSSepherosa Ziehau 	if (vlan > 4095 || vind > 63)
398279251f5eSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
398379251f5eSSepherosa Ziehau 
398479251f5eSSepherosa Ziehau 	/*
398579251f5eSSepherosa Ziehau 	 * this is a 2 part operation - first the VFTA, then the
398679251f5eSSepherosa Ziehau 	 * VLVF and VLVFB if VT Mode is set
398779251f5eSSepherosa Ziehau 	 * We don't write the VFTA until we know the VLVF part succeeded.
398879251f5eSSepherosa Ziehau 	 */
398979251f5eSSepherosa Ziehau 
399079251f5eSSepherosa Ziehau 	/* Part 1
399179251f5eSSepherosa Ziehau 	 * The VFTA is a bitstring made up of 128 32-bit registers
399279251f5eSSepherosa Ziehau 	 * that enable the particular VLAN id, much like the MTA:
399379251f5eSSepherosa Ziehau 	 *    bits[11-5]: which register
399479251f5eSSepherosa Ziehau 	 *    bits[4-0]:  which bit in the register
399579251f5eSSepherosa Ziehau 	 */
39966150453fSSepherosa Ziehau 	regidx = vlan / 32;
39976150453fSSepherosa Ziehau 	vfta_delta = 1 << (vlan % 32);
39986150453fSSepherosa Ziehau 	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
399979251f5eSSepherosa Ziehau 
40006150453fSSepherosa Ziehau 	/*
40016150453fSSepherosa Ziehau 	 * vfta_delta represents the difference between the current value
40026150453fSSepherosa Ziehau 	 * of vfta and the value we want in the register.  Since the diff
40036150453fSSepherosa Ziehau 	 * is an XOR mask we can just update the vfta using an XOR
40046150453fSSepherosa Ziehau 	 */
40056150453fSSepherosa Ziehau 	vfta_delta &= vlan_on ? ~vfta : vfta;
40066150453fSSepherosa Ziehau 	vfta ^= vfta_delta;
400779251f5eSSepherosa Ziehau 
400879251f5eSSepherosa Ziehau 	/* Part 2
400979251f5eSSepherosa Ziehau 	 * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF
401079251f5eSSepherosa Ziehau 	 */
40116150453fSSepherosa Ziehau 	ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, &vfta_delta,
40126150453fSSepherosa Ziehau 					 vfta, vlvf_bypass);
40136150453fSSepherosa Ziehau 	if (ret_val != IXGBE_SUCCESS) {
40146150453fSSepherosa Ziehau 		if (vlvf_bypass)
40156150453fSSepherosa Ziehau 			goto vfta_update;
401679251f5eSSepherosa Ziehau 		return ret_val;
40176150453fSSepherosa Ziehau 	}
401879251f5eSSepherosa Ziehau 
40196150453fSSepherosa Ziehau vfta_update:
40206150453fSSepherosa Ziehau 	/* Update VFTA now that we are ready for traffic */
40216150453fSSepherosa Ziehau 	if (vfta_delta)
40226150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
402379251f5eSSepherosa Ziehau 
402479251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
402579251f5eSSepherosa Ziehau }
402679251f5eSSepherosa Ziehau 
402779251f5eSSepherosa Ziehau /**
402879251f5eSSepherosa Ziehau  *  ixgbe_set_vlvf_generic - Set VLAN Pool Filter
402979251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
403079251f5eSSepherosa Ziehau  *  @vlan: VLAN id to write to VLAN filter
40316150453fSSepherosa Ziehau  *  @vind: VMDq output index that maps queue to VLAN id in VLVFB
40326150453fSSepherosa Ziehau  *  @vlan_on: boolean flag to turn on/off VLAN in VLVF
40336150453fSSepherosa Ziehau  *  @vfta_delta: pointer to the difference between the current value of VFTA
40346150453fSSepherosa Ziehau  *		 and the desired value
40356150453fSSepherosa Ziehau  *  @vfta: the desired value of the VFTA
40366150453fSSepherosa Ziehau  *  @vlvf_bypass: boolean flag indicating updating default pool is okay
403779251f5eSSepherosa Ziehau  *
403879251f5eSSepherosa Ziehau  *  Turn on/off specified bit in VLVF table.
403979251f5eSSepherosa Ziehau  **/
ixgbe_set_vlvf_generic(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,u32 * vfta_delta,u32 vfta,bool vlvf_bypass)404079251f5eSSepherosa Ziehau s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
40416150453fSSepherosa Ziehau 			   bool vlan_on, u32 *vfta_delta, u32 vfta,
40426150453fSSepherosa Ziehau 			   bool vlvf_bypass)
404379251f5eSSepherosa Ziehau {
40446150453fSSepherosa Ziehau 	u32 bits;
40456150453fSSepherosa Ziehau 	s32 vlvf_index;
404679251f5eSSepherosa Ziehau 
404779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_vlvf_generic");
404879251f5eSSepherosa Ziehau 
40496150453fSSepherosa Ziehau 	if (vlan > 4095 || vind > 63)
405079251f5eSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
405179251f5eSSepherosa Ziehau 
405279251f5eSSepherosa Ziehau 	/* If VT Mode is set
405379251f5eSSepherosa Ziehau 	 *   Either vlan_on
405479251f5eSSepherosa Ziehau 	 *     make sure the vlan is in VLVF
405579251f5eSSepherosa Ziehau 	 *     set the vind bit in the matching VLVFB
405679251f5eSSepherosa Ziehau 	 *   Or !vlan_on
405779251f5eSSepherosa Ziehau 	 *     clear the pool bit and possibly the vind
405879251f5eSSepherosa Ziehau 	 */
40596150453fSSepherosa Ziehau 	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
40606150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
406179251f5eSSepherosa Ziehau 
40626150453fSSepherosa Ziehau 	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
406379251f5eSSepherosa Ziehau 	if (vlvf_index < 0)
406479251f5eSSepherosa Ziehau 		return vlvf_index;
406579251f5eSSepherosa Ziehau 
40666150453fSSepherosa Ziehau 	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
40676150453fSSepherosa Ziehau 
406879251f5eSSepherosa Ziehau 	/* set the pool bit */
40696150453fSSepherosa Ziehau 	bits |= 1 << (vind % 32);
40706150453fSSepherosa Ziehau 	if (vlan_on)
40716150453fSSepherosa Ziehau 		goto vlvf_update;
40726150453fSSepherosa Ziehau 
407379251f5eSSepherosa Ziehau 	/* clear the pool bit */
40746150453fSSepherosa Ziehau 	bits ^= 1 << (vind % 32);
40756150453fSSepherosa Ziehau 
40766150453fSSepherosa Ziehau 	if (!bits &&
40776150453fSSepherosa Ziehau 	    !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
40786150453fSSepherosa Ziehau 		/* Clear VFTA first, then disable VLVF.  Otherwise
40796150453fSSepherosa Ziehau 		 * we run the risk of stray packets leaking into
40806150453fSSepherosa Ziehau 		 * the PF via the default pool
40816150453fSSepherosa Ziehau 		 */
40826150453fSSepherosa Ziehau 		if (*vfta_delta)
40836150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_VFTA(vlan / 32), vfta);
40846150453fSSepherosa Ziehau 
40856150453fSSepherosa Ziehau 		/* disable VLVF and clear remaining bit from pool */
40866150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
40876150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
40886150453fSSepherosa Ziehau 
40896150453fSSepherosa Ziehau 		return IXGBE_SUCCESS;
409079251f5eSSepherosa Ziehau 	}
409179251f5eSSepherosa Ziehau 
40926150453fSSepherosa Ziehau 	/* If there are still bits set in the VLVFB registers
409379251f5eSSepherosa Ziehau 	 * for the VLAN ID indicated we need to see if the
409479251f5eSSepherosa Ziehau 	 * caller is requesting that we clear the VFTA entry bit.
409579251f5eSSepherosa Ziehau 	 * If the caller has requested that we clear the VFTA
409679251f5eSSepherosa Ziehau 	 * entry bit but there are still pools/VFs using this VLAN
409779251f5eSSepherosa Ziehau 	 * ID entry then ignore the request.  We're not worried
409879251f5eSSepherosa Ziehau 	 * about the case where we're turning the VFTA VLAN ID
409979251f5eSSepherosa Ziehau 	 * entry bit on, only when requested to turn it off as
410079251f5eSSepherosa Ziehau 	 * there may be multiple pools and/or VFs using the
410179251f5eSSepherosa Ziehau 	 * VLAN ID entry.  In that case we cannot clear the
410279251f5eSSepherosa Ziehau 	 * VFTA bit until all pools/VFs using that VLAN ID have also
410379251f5eSSepherosa Ziehau 	 * been cleared.  This will be indicated by "bits" being
410479251f5eSSepherosa Ziehau 	 * zero.
410579251f5eSSepherosa Ziehau 	 */
41066150453fSSepherosa Ziehau 	*vfta_delta = 0;
41076150453fSSepherosa Ziehau 
41086150453fSSepherosa Ziehau vlvf_update:
41096150453fSSepherosa Ziehau 	/* record pool change and enable VLAN ID if not already enabled */
41106150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
41116150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
411279251f5eSSepherosa Ziehau 
411379251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
411479251f5eSSepherosa Ziehau }
411579251f5eSSepherosa Ziehau 
411679251f5eSSepherosa Ziehau /**
411779251f5eSSepherosa Ziehau  *  ixgbe_clear_vfta_generic - Clear VLAN filter table
411879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
411979251f5eSSepherosa Ziehau  *
412079251f5eSSepherosa Ziehau  *  Clears the VLAN filer table, and the VMDq index associated with the filter
412179251f5eSSepherosa Ziehau  **/
ixgbe_clear_vfta_generic(struct ixgbe_hw * hw)412279251f5eSSepherosa Ziehau s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
412379251f5eSSepherosa Ziehau {
412479251f5eSSepherosa Ziehau 	u32 offset;
412579251f5eSSepherosa Ziehau 
412679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_clear_vfta_generic");
412779251f5eSSepherosa Ziehau 
412879251f5eSSepherosa Ziehau 	for (offset = 0; offset < hw->mac.vft_size; offset++)
412979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
413079251f5eSSepherosa Ziehau 
413179251f5eSSepherosa Ziehau 	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
413279251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
413379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
41346150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0);
413579251f5eSSepherosa Ziehau 	}
413679251f5eSSepherosa Ziehau 
413779251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
413879251f5eSSepherosa Ziehau }
413979251f5eSSepherosa Ziehau 
414079251f5eSSepherosa Ziehau /**
41416150453fSSepherosa Ziehau  *  ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix
41426150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
41436150453fSSepherosa Ziehau  *
41446150453fSSepherosa Ziehau  *  Contains the logic to identify if we need to verify link for the
41456150453fSSepherosa Ziehau  *  crosstalk fix
41466150453fSSepherosa Ziehau  **/
ixgbe_need_crosstalk_fix(struct ixgbe_hw * hw)41476150453fSSepherosa Ziehau static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw)
41486150453fSSepherosa Ziehau {
41496150453fSSepherosa Ziehau 
41506150453fSSepherosa Ziehau 	/* Does FW say we need the fix */
41516150453fSSepherosa Ziehau 	if (!hw->need_crosstalk_fix)
41526150453fSSepherosa Ziehau 		return FALSE;
41536150453fSSepherosa Ziehau 
41546150453fSSepherosa Ziehau 	/* Only consider SFP+ PHYs i.e. media type fiber */
41556150453fSSepherosa Ziehau 	switch (hw->mac.ops.get_media_type(hw)) {
41566150453fSSepherosa Ziehau 	case ixgbe_media_type_fiber:
41576150453fSSepherosa Ziehau 	case ixgbe_media_type_fiber_qsfp:
41586150453fSSepherosa Ziehau 		break;
41596150453fSSepherosa Ziehau 	default:
41606150453fSSepherosa Ziehau 		return FALSE;
41616150453fSSepherosa Ziehau 	}
41626150453fSSepherosa Ziehau 
41636150453fSSepherosa Ziehau 	return TRUE;
41646150453fSSepherosa Ziehau }
41656150453fSSepherosa Ziehau 
41666150453fSSepherosa Ziehau /**
416779251f5eSSepherosa Ziehau  *  ixgbe_check_mac_link_generic - Determine link and speed status
416879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
416979251f5eSSepherosa Ziehau  *  @speed: pointer to link speed
417079251f5eSSepherosa Ziehau  *  @link_up: TRUE when link is up
417179251f5eSSepherosa Ziehau  *  @link_up_wait_to_complete: bool used to wait for link up or not
417279251f5eSSepherosa Ziehau  *
417379251f5eSSepherosa Ziehau  *  Reads the links register to determine if link is up and the current speed
417479251f5eSSepherosa Ziehau  **/
ixgbe_check_mac_link_generic(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)417579251f5eSSepherosa Ziehau s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
417679251f5eSSepherosa Ziehau 				 bool *link_up, bool link_up_wait_to_complete)
417779251f5eSSepherosa Ziehau {
417879251f5eSSepherosa Ziehau 	u32 links_reg, links_orig;
417979251f5eSSepherosa Ziehau 	u32 i;
418079251f5eSSepherosa Ziehau 
418179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_check_mac_link_generic");
418279251f5eSSepherosa Ziehau 
41836150453fSSepherosa Ziehau 	/* If Crosstalk fix enabled do the sanity check of making sure
41846150453fSSepherosa Ziehau 	 * the SFP+ cage is full.
41856150453fSSepherosa Ziehau 	 */
41866150453fSSepherosa Ziehau 	if (ixgbe_need_crosstalk_fix(hw)) {
41876150453fSSepherosa Ziehau 		u32 sfp_cage_full;
41886150453fSSepherosa Ziehau 
41896150453fSSepherosa Ziehau 		switch (hw->mac.type) {
41906150453fSSepherosa Ziehau 		case ixgbe_mac_82599EB:
41916150453fSSepherosa Ziehau 			sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
41926150453fSSepherosa Ziehau 					IXGBE_ESDP_SDP2;
41936150453fSSepherosa Ziehau 			break;
41946150453fSSepherosa Ziehau 		case ixgbe_mac_X550EM_x:
41956150453fSSepherosa Ziehau 		case ixgbe_mac_X550EM_a:
41966150453fSSepherosa Ziehau 			sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
41976150453fSSepherosa Ziehau 					IXGBE_ESDP_SDP0;
41986150453fSSepherosa Ziehau 			break;
41996150453fSSepherosa Ziehau 		default:
42006150453fSSepherosa Ziehau 			/* sanity check - No SFP+ devices here */
42016150453fSSepherosa Ziehau 			sfp_cage_full = FALSE;
42026150453fSSepherosa Ziehau 			break;
42036150453fSSepherosa Ziehau 		}
42046150453fSSepherosa Ziehau 
42056150453fSSepherosa Ziehau 		if (!sfp_cage_full) {
42066150453fSSepherosa Ziehau 			*link_up = FALSE;
42076150453fSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_UNKNOWN;
42086150453fSSepherosa Ziehau 			return IXGBE_SUCCESS;
42096150453fSSepherosa Ziehau 		}
42106150453fSSepherosa Ziehau 	}
42116150453fSSepherosa Ziehau 
421279251f5eSSepherosa Ziehau 	/* clear the old state */
421379251f5eSSepherosa Ziehau 	links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
421479251f5eSSepherosa Ziehau 
421579251f5eSSepherosa Ziehau 	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
421679251f5eSSepherosa Ziehau 
421779251f5eSSepherosa Ziehau 	if (links_orig != links_reg) {
421879251f5eSSepherosa Ziehau 		DEBUGOUT2("LINKS changed from %08X to %08X\n",
421979251f5eSSepherosa Ziehau 			  links_orig, links_reg);
422079251f5eSSepherosa Ziehau 	}
422179251f5eSSepherosa Ziehau 
422279251f5eSSepherosa Ziehau 	if (link_up_wait_to_complete) {
42236150453fSSepherosa Ziehau 		for (i = 0; i < hw->mac.max_link_up_time; i++) {
422479251f5eSSepherosa Ziehau 			if (links_reg & IXGBE_LINKS_UP) {
422579251f5eSSepherosa Ziehau 				*link_up = TRUE;
422679251f5eSSepherosa Ziehau 				break;
422779251f5eSSepherosa Ziehau 			} else {
422879251f5eSSepherosa Ziehau 				*link_up = FALSE;
422979251f5eSSepherosa Ziehau 			}
423079251f5eSSepherosa Ziehau 			msec_delay(100);
423179251f5eSSepherosa Ziehau 			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
423279251f5eSSepherosa Ziehau 		}
423379251f5eSSepherosa Ziehau 	} else {
423479251f5eSSepherosa Ziehau 		if (links_reg & IXGBE_LINKS_UP)
423579251f5eSSepherosa Ziehau 			*link_up = TRUE;
423679251f5eSSepherosa Ziehau 		else
423779251f5eSSepherosa Ziehau 			*link_up = FALSE;
423879251f5eSSepherosa Ziehau 	}
423979251f5eSSepherosa Ziehau 
424063d483cdSSepherosa Ziehau 	switch (links_reg & IXGBE_LINKS_SPEED_82599) {
424163d483cdSSepherosa Ziehau 	case IXGBE_LINKS_SPEED_10G_82599:
424279251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
424363d483cdSSepherosa Ziehau 		if (hw->mac.type >= ixgbe_mac_X550) {
424463d483cdSSepherosa Ziehau 			if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
424563d483cdSSepherosa Ziehau 				*speed = IXGBE_LINK_SPEED_2_5GB_FULL;
424663d483cdSSepherosa Ziehau 		}
424763d483cdSSepherosa Ziehau 		break;
424863d483cdSSepherosa Ziehau 	case IXGBE_LINKS_SPEED_1G_82599:
424979251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
425063d483cdSSepherosa Ziehau 		break;
425163d483cdSSepherosa Ziehau 	case IXGBE_LINKS_SPEED_100_82599:
425279251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_100_FULL;
42536150453fSSepherosa Ziehau 		if (hw->mac.type == ixgbe_mac_X550) {
425463d483cdSSepherosa Ziehau 			if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
425563d483cdSSepherosa Ziehau 				*speed = IXGBE_LINK_SPEED_5GB_FULL;
425663d483cdSSepherosa Ziehau 		}
425763d483cdSSepherosa Ziehau 		break;
42586150453fSSepherosa Ziehau 	case IXGBE_LINKS_SPEED_10_X550EM_A:
42596150453fSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
42606150453fSSepherosa Ziehau 		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
42616150453fSSepherosa Ziehau 		    hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
42626150453fSSepherosa Ziehau 			*speed = IXGBE_LINK_SPEED_10_FULL;
42636150453fSSepherosa Ziehau 		break;
426463d483cdSSepherosa Ziehau 	default:
426579251f5eSSepherosa Ziehau 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
426663d483cdSSepherosa Ziehau 	}
426779251f5eSSepherosa Ziehau 
426879251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
426979251f5eSSepherosa Ziehau }
427079251f5eSSepherosa Ziehau 
427179251f5eSSepherosa Ziehau /**
427279251f5eSSepherosa Ziehau  *  ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from
427379251f5eSSepherosa Ziehau  *  the EEPROM
427479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
427579251f5eSSepherosa Ziehau  *  @wwnn_prefix: the alternative WWNN prefix
427679251f5eSSepherosa Ziehau  *  @wwpn_prefix: the alternative WWPN prefix
427779251f5eSSepherosa Ziehau  *
427879251f5eSSepherosa Ziehau  *  This function will read the EEPROM from the alternative SAN MAC address
427979251f5eSSepherosa Ziehau  *  block to check the support for the alternative WWNN/WWPN prefix support.
428079251f5eSSepherosa Ziehau  **/
ixgbe_get_wwn_prefix_generic(struct ixgbe_hw * hw,u16 * wwnn_prefix,u16 * wwpn_prefix)428179251f5eSSepherosa Ziehau s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
428279251f5eSSepherosa Ziehau 				 u16 *wwpn_prefix)
428379251f5eSSepherosa Ziehau {
428479251f5eSSepherosa Ziehau 	u16 offset, caps;
428579251f5eSSepherosa Ziehau 	u16 alt_san_mac_blk_offset;
428679251f5eSSepherosa Ziehau 
428779251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_wwn_prefix_generic");
428879251f5eSSepherosa Ziehau 
428979251f5eSSepherosa Ziehau 	/* clear output first */
429079251f5eSSepherosa Ziehau 	*wwnn_prefix = 0xFFFF;
429179251f5eSSepherosa Ziehau 	*wwpn_prefix = 0xFFFF;
429279251f5eSSepherosa Ziehau 
429379251f5eSSepherosa Ziehau 	/* check if alternative SAN MAC is supported */
429479251f5eSSepherosa Ziehau 	offset = IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR;
429579251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, offset, &alt_san_mac_blk_offset))
429679251f5eSSepherosa Ziehau 		goto wwn_prefix_err;
429779251f5eSSepherosa Ziehau 
429879251f5eSSepherosa Ziehau 	if ((alt_san_mac_blk_offset == 0) ||
429979251f5eSSepherosa Ziehau 	    (alt_san_mac_blk_offset == 0xFFFF))
430079251f5eSSepherosa Ziehau 		goto wwn_prefix_out;
430179251f5eSSepherosa Ziehau 
430279251f5eSSepherosa Ziehau 	/* check capability in alternative san mac address block */
430379251f5eSSepherosa Ziehau 	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
430479251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, offset, &caps))
430579251f5eSSepherosa Ziehau 		goto wwn_prefix_err;
430679251f5eSSepherosa Ziehau 	if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
430779251f5eSSepherosa Ziehau 		goto wwn_prefix_out;
430879251f5eSSepherosa Ziehau 
430979251f5eSSepherosa Ziehau 	/* get the corresponding prefix for WWNN/WWPN */
431079251f5eSSepherosa Ziehau 	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
431179251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, offset, wwnn_prefix)) {
431279251f5eSSepherosa Ziehau 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
431379251f5eSSepherosa Ziehau 			      "eeprom read at offset %d failed", offset);
431479251f5eSSepherosa Ziehau 	}
431579251f5eSSepherosa Ziehau 
431679251f5eSSepherosa Ziehau 	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
431779251f5eSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, offset, wwpn_prefix))
431879251f5eSSepherosa Ziehau 		goto wwn_prefix_err;
431979251f5eSSepherosa Ziehau 
432079251f5eSSepherosa Ziehau wwn_prefix_out:
432179251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
432279251f5eSSepherosa Ziehau 
432379251f5eSSepherosa Ziehau wwn_prefix_err:
432479251f5eSSepherosa Ziehau 	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
432579251f5eSSepherosa Ziehau 		      "eeprom read at offset %d failed", offset);
432679251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
432779251f5eSSepherosa Ziehau }
432879251f5eSSepherosa Ziehau 
432979251f5eSSepherosa Ziehau /**
433079251f5eSSepherosa Ziehau  *  ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM
433179251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
433279251f5eSSepherosa Ziehau  *  @bs: the fcoe boot status
433379251f5eSSepherosa Ziehau  *
433479251f5eSSepherosa Ziehau  *  This function will read the FCOE boot status from the iSCSI FCOE block
433579251f5eSSepherosa Ziehau  **/
ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw * hw,u16 * bs)433679251f5eSSepherosa Ziehau s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs)
433779251f5eSSepherosa Ziehau {
433879251f5eSSepherosa Ziehau 	u16 offset, caps, flags;
433979251f5eSSepherosa Ziehau 	s32 status;
434079251f5eSSepherosa Ziehau 
434179251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_fcoe_boot_status_generic");
434279251f5eSSepherosa Ziehau 
434379251f5eSSepherosa Ziehau 	/* clear output first */
434479251f5eSSepherosa Ziehau 	*bs = ixgbe_fcoe_bootstatus_unavailable;
434579251f5eSSepherosa Ziehau 
434679251f5eSSepherosa Ziehau 	/* check if FCOE IBA block is present */
434779251f5eSSepherosa Ziehau 	offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR;
434879251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, offset, &caps);
434979251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
435079251f5eSSepherosa Ziehau 		goto out;
435179251f5eSSepherosa Ziehau 
435279251f5eSSepherosa Ziehau 	if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE))
435379251f5eSSepherosa Ziehau 		goto out;
435479251f5eSSepherosa Ziehau 
435579251f5eSSepherosa Ziehau 	/* check if iSCSI FCOE block is populated */
435679251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset);
435779251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
435879251f5eSSepherosa Ziehau 		goto out;
435979251f5eSSepherosa Ziehau 
436079251f5eSSepherosa Ziehau 	if ((offset == 0) || (offset == 0xFFFF))
436179251f5eSSepherosa Ziehau 		goto out;
436279251f5eSSepherosa Ziehau 
436379251f5eSSepherosa Ziehau 	/* read fcoe flags in iSCSI FCOE block */
436479251f5eSSepherosa Ziehau 	offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET;
436579251f5eSSepherosa Ziehau 	status = hw->eeprom.ops.read(hw, offset, &flags);
436679251f5eSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
436779251f5eSSepherosa Ziehau 		goto out;
436879251f5eSSepherosa Ziehau 
436979251f5eSSepherosa Ziehau 	if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE)
437079251f5eSSepherosa Ziehau 		*bs = ixgbe_fcoe_bootstatus_enabled;
437179251f5eSSepherosa Ziehau 	else
437279251f5eSSepherosa Ziehau 		*bs = ixgbe_fcoe_bootstatus_disabled;
437379251f5eSSepherosa Ziehau 
437479251f5eSSepherosa Ziehau out:
437579251f5eSSepherosa Ziehau 	return status;
437679251f5eSSepherosa Ziehau }
437779251f5eSSepherosa Ziehau 
437879251f5eSSepherosa Ziehau /**
437979251f5eSSepherosa Ziehau  *  ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
438079251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
43816150453fSSepherosa Ziehau  *  @enable: enable or disable switch for MAC anti-spoofing
43826150453fSSepherosa Ziehau  *  @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing
438379251f5eSSepherosa Ziehau  *
438479251f5eSSepherosa Ziehau  **/
ixgbe_set_mac_anti_spoofing(struct ixgbe_hw * hw,bool enable,int vf)43856150453fSSepherosa Ziehau void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
438679251f5eSSepherosa Ziehau {
43876150453fSSepherosa Ziehau 	int vf_target_reg = vf >> 3;
43886150453fSSepherosa Ziehau 	int vf_target_shift = vf % 8;
43896150453fSSepherosa Ziehau 	u32 pfvfspoof;
439079251f5eSSepherosa Ziehau 
439179251f5eSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_82598EB)
439279251f5eSSepherosa Ziehau 		return;
439379251f5eSSepherosa Ziehau 
43946150453fSSepherosa Ziehau 	pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
439579251f5eSSepherosa Ziehau 	if (enable)
43966150453fSSepherosa Ziehau 		pfvfspoof |= (1 << vf_target_shift);
43976150453fSSepherosa Ziehau 	else
43986150453fSSepherosa Ziehau 		pfvfspoof &= ~(1 << vf_target_shift);
43996150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
440079251f5eSSepherosa Ziehau }
440179251f5eSSepherosa Ziehau 
440279251f5eSSepherosa Ziehau /**
440379251f5eSSepherosa Ziehau  *  ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
440479251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
440579251f5eSSepherosa Ziehau  *  @enable: enable or disable switch for VLAN anti-spoofing
440663d483cdSSepherosa Ziehau  *  @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing
440779251f5eSSepherosa Ziehau  *
440879251f5eSSepherosa Ziehau  **/
ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw * hw,bool enable,int vf)440979251f5eSSepherosa Ziehau void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
441079251f5eSSepherosa Ziehau {
441179251f5eSSepherosa Ziehau 	int vf_target_reg = vf >> 3;
441279251f5eSSepherosa Ziehau 	int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT;
441379251f5eSSepherosa Ziehau 	u32 pfvfspoof;
441479251f5eSSepherosa Ziehau 
441579251f5eSSepherosa Ziehau 	if (hw->mac.type == ixgbe_mac_82598EB)
441679251f5eSSepherosa Ziehau 		return;
441779251f5eSSepherosa Ziehau 
441879251f5eSSepherosa Ziehau 	pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
441979251f5eSSepherosa Ziehau 	if (enable)
442079251f5eSSepherosa Ziehau 		pfvfspoof |= (1 << vf_target_shift);
442179251f5eSSepherosa Ziehau 	else
442279251f5eSSepherosa Ziehau 		pfvfspoof &= ~(1 << vf_target_shift);
442379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
442479251f5eSSepherosa Ziehau }
442579251f5eSSepherosa Ziehau 
442679251f5eSSepherosa Ziehau /**
442779251f5eSSepherosa Ziehau  *  ixgbe_get_device_caps_generic - Get additional device capabilities
442879251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
442979251f5eSSepherosa Ziehau  *  @device_caps: the EEPROM word with the extra device capabilities
443079251f5eSSepherosa Ziehau  *
443179251f5eSSepherosa Ziehau  *  This function will read the EEPROM location for the device capabilities,
443279251f5eSSepherosa Ziehau  *  and return the word through device_caps.
443379251f5eSSepherosa Ziehau  **/
ixgbe_get_device_caps_generic(struct ixgbe_hw * hw,u16 * device_caps)443479251f5eSSepherosa Ziehau s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
443579251f5eSSepherosa Ziehau {
443679251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_get_device_caps_generic");
443779251f5eSSepherosa Ziehau 
443879251f5eSSepherosa Ziehau 	hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
443979251f5eSSepherosa Ziehau 
444079251f5eSSepherosa Ziehau 	return IXGBE_SUCCESS;
444179251f5eSSepherosa Ziehau }
444279251f5eSSepherosa Ziehau 
444379251f5eSSepherosa Ziehau /**
444479251f5eSSepherosa Ziehau  *  ixgbe_enable_relaxed_ordering_gen2 - Enable relaxed ordering
444579251f5eSSepherosa Ziehau  *  @hw: pointer to hardware structure
444679251f5eSSepherosa Ziehau  *
444779251f5eSSepherosa Ziehau  **/
ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw * hw)444879251f5eSSepherosa Ziehau void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
444979251f5eSSepherosa Ziehau {
445079251f5eSSepherosa Ziehau 	u32 regval;
445179251f5eSSepherosa Ziehau 	u32 i;
445279251f5eSSepherosa Ziehau 
445379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_enable_relaxed_ordering_gen2");
445479251f5eSSepherosa Ziehau 
445579251f5eSSepherosa Ziehau 	/* Enable relaxed ordering */
445679251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_tx_queues; i++) {
445779251f5eSSepherosa Ziehau 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
445879251f5eSSepherosa Ziehau 		regval |= IXGBE_DCA_TXCTRL_DESC_WRO_EN;
445979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
446079251f5eSSepherosa Ziehau 	}
446179251f5eSSepherosa Ziehau 
446279251f5eSSepherosa Ziehau 	for (i = 0; i < hw->mac.max_rx_queues; i++) {
446379251f5eSSepherosa Ziehau 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
446479251f5eSSepherosa Ziehau 		regval |= IXGBE_DCA_RXCTRL_DATA_WRO_EN |
446579251f5eSSepherosa Ziehau 			  IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
446679251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
446779251f5eSSepherosa Ziehau 	}
446879251f5eSSepherosa Ziehau 
446979251f5eSSepherosa Ziehau }
447079251f5eSSepherosa Ziehau 
447179251f5eSSepherosa Ziehau /**
447279251f5eSSepherosa Ziehau  *  ixgbe_calculate_checksum - Calculate checksum for buffer
447379251f5eSSepherosa Ziehau  *  @buffer: pointer to EEPROM
447479251f5eSSepherosa Ziehau  *  @length: size of EEPROM to calculate a checksum for
447579251f5eSSepherosa Ziehau  *  Calculates the checksum for some buffer on a specified length.  The
447679251f5eSSepherosa Ziehau  *  checksum calculated is returned.
447779251f5eSSepherosa Ziehau  **/
ixgbe_calculate_checksum(u8 * buffer,u32 length)447879251f5eSSepherosa Ziehau u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
447979251f5eSSepherosa Ziehau {
448079251f5eSSepherosa Ziehau 	u32 i;
448179251f5eSSepherosa Ziehau 	u8 sum = 0;
448279251f5eSSepherosa Ziehau 
448379251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_calculate_checksum");
448479251f5eSSepherosa Ziehau 
448579251f5eSSepherosa Ziehau 	if (!buffer)
448679251f5eSSepherosa Ziehau 		return 0;
448779251f5eSSepherosa Ziehau 
448879251f5eSSepherosa Ziehau 	for (i = 0; i < length; i++)
448979251f5eSSepherosa Ziehau 		sum += buffer[i];
449079251f5eSSepherosa Ziehau 
449179251f5eSSepherosa Ziehau 	return (u8) (0 - sum);
449279251f5eSSepherosa Ziehau }
449379251f5eSSepherosa Ziehau 
449479251f5eSSepherosa Ziehau /**
44956150453fSSepherosa Ziehau  *  ixgbe_hic_unlocked - Issue command to manageability block unlocked
449679251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
44976150453fSSepherosa Ziehau  *  @buffer: command to write and where the return status will be placed
449879251f5eSSepherosa Ziehau  *  @length: length of buffer, must be multiple of 4 bytes
449963d483cdSSepherosa Ziehau  *  @timeout: time in ms to wait for command completion
450079251f5eSSepherosa Ziehau  *
450179251f5eSSepherosa Ziehau  *  Communicates with the manageability block. On success return IXGBE_SUCCESS
45026150453fSSepherosa Ziehau  *  else returns semaphore error when encountering an error acquiring
45036150453fSSepherosa Ziehau  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
45046150453fSSepherosa Ziehau  *
45056150453fSSepherosa Ziehau  *  This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held
45066150453fSSepherosa Ziehau  *  by the caller.
450779251f5eSSepherosa Ziehau  **/
ixgbe_hic_unlocked(struct ixgbe_hw * hw,u32 * buffer,u32 length,u32 timeout)45086150453fSSepherosa Ziehau s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length,
45096150453fSSepherosa Ziehau 		       u32 timeout)
451079251f5eSSepherosa Ziehau {
45116150453fSSepherosa Ziehau 	u32 hicr, i, fwsts;
451263d483cdSSepherosa Ziehau 	u16 dword_len;
451379251f5eSSepherosa Ziehau 
45146150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_hic_unlocked");
451579251f5eSSepherosa Ziehau 
45166150453fSSepherosa Ziehau 	if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
451763d483cdSSepherosa Ziehau 		DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
451863d483cdSSepherosa Ziehau 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
451979251f5eSSepherosa Ziehau 	}
45206150453fSSepherosa Ziehau 
452163d483cdSSepherosa Ziehau 	/* Set bit 9 of FWSTS clearing FW reset indication */
452263d483cdSSepherosa Ziehau 	fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
452363d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI);
452479251f5eSSepherosa Ziehau 
452579251f5eSSepherosa Ziehau 	/* Check that the host interface is enabled. */
452679251f5eSSepherosa Ziehau 	hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
45276150453fSSepherosa Ziehau 	if (!(hicr & IXGBE_HICR_EN)) {
452879251f5eSSepherosa Ziehau 		DEBUGOUT("IXGBE_HOST_EN bit disabled.\n");
452963d483cdSSepherosa Ziehau 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
453079251f5eSSepherosa Ziehau 	}
453179251f5eSSepherosa Ziehau 
453263d483cdSSepherosa Ziehau 	/* Calculate length in DWORDs. We must be DWORD aligned */
45336150453fSSepherosa Ziehau 	if (length % sizeof(u32)) {
453463d483cdSSepherosa Ziehau 		DEBUGOUT("Buffer length failure, not aligned to dword");
453563d483cdSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
453663d483cdSSepherosa Ziehau 	}
453763d483cdSSepherosa Ziehau 
453879251f5eSSepherosa Ziehau 	dword_len = length >> 2;
453979251f5eSSepherosa Ziehau 
454063d483cdSSepherosa Ziehau 	/* The device driver writes the relevant command block
454179251f5eSSepherosa Ziehau 	 * into the ram area.
454279251f5eSSepherosa Ziehau 	 */
454379251f5eSSepherosa Ziehau 	for (i = 0; i < dword_len; i++)
454479251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG,
454579251f5eSSepherosa Ziehau 				      i, IXGBE_CPU_TO_LE32(buffer[i]));
454679251f5eSSepherosa Ziehau 
454779251f5eSSepherosa Ziehau 	/* Setting this bit tells the ARC that a new command is pending. */
454879251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
454979251f5eSSepherosa Ziehau 
455063d483cdSSepherosa Ziehau 	for (i = 0; i < timeout; i++) {
455179251f5eSSepherosa Ziehau 		hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
455279251f5eSSepherosa Ziehau 		if (!(hicr & IXGBE_HICR_C))
455379251f5eSSepherosa Ziehau 			break;
455479251f5eSSepherosa Ziehau 		msec_delay(1);
455579251f5eSSepherosa Ziehau 	}
455679251f5eSSepherosa Ziehau 
455763d483cdSSepherosa Ziehau 	/* Check command completion */
45586150453fSSepherosa Ziehau 	if ((timeout && i == timeout) ||
455963d483cdSSepherosa Ziehau 	    !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) {
456063d483cdSSepherosa Ziehau 		ERROR_REPORT1(IXGBE_ERROR_CAUTION,
456163d483cdSSepherosa Ziehau 			     "Command has failed with no status valid.\n");
456263d483cdSSepherosa Ziehau 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
456379251f5eSSepherosa Ziehau 	}
456479251f5eSSepherosa Ziehau 
45656150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
45666150453fSSepherosa Ziehau }
45676150453fSSepherosa Ziehau 
45686150453fSSepherosa Ziehau /**
45696150453fSSepherosa Ziehau  *  ixgbe_host_interface_command - Issue command to manageability block
45706150453fSSepherosa Ziehau  *  @hw: pointer to the HW structure
45716150453fSSepherosa Ziehau  *  @buffer: contains the command to write and where the return status will
45726150453fSSepherosa Ziehau  *   be placed
45736150453fSSepherosa Ziehau  *  @length: length of buffer, must be multiple of 4 bytes
45746150453fSSepherosa Ziehau  *  @timeout: time in ms to wait for command completion
45756150453fSSepherosa Ziehau  *  @return_data: read and return data from the buffer (TRUE) or not (FALSE)
45766150453fSSepherosa Ziehau  *   Needed because FW structures are big endian and decoding of
45776150453fSSepherosa Ziehau  *   these fields can be 8 bit or 16 bit based on command. Decoding
45786150453fSSepherosa Ziehau  *   is not easily understood without making a table of commands.
45796150453fSSepherosa Ziehau  *   So we will leave this up to the caller to read back the data
45806150453fSSepherosa Ziehau  *   in these cases.
45816150453fSSepherosa Ziehau  *
45826150453fSSepherosa Ziehau  *  Communicates with the manageability block. On success return IXGBE_SUCCESS
45836150453fSSepherosa Ziehau  *  else returns semaphore error when encountering an error acquiring
45846150453fSSepherosa Ziehau  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
45856150453fSSepherosa Ziehau  **/
ixgbe_host_interface_command(struct ixgbe_hw * hw,u32 * buffer,u32 length,u32 timeout,bool return_data)45866150453fSSepherosa Ziehau s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
45876150453fSSepherosa Ziehau 				 u32 length, u32 timeout, bool return_data)
45886150453fSSepherosa Ziehau {
45896150453fSSepherosa Ziehau 	u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
4590dd5ce676SSepherosa Ziehau 	struct ixgbe_hic_hdr *resp = (struct ixgbe_hic_hdr *)buffer;
45916150453fSSepherosa Ziehau 	u16 buf_len;
45926150453fSSepherosa Ziehau 	s32 status;
45936150453fSSepherosa Ziehau 	u32 bi;
4594dd5ce676SSepherosa Ziehau 	u32 dword_len;
45956150453fSSepherosa Ziehau 
45966150453fSSepherosa Ziehau 	DEBUGFUNC("ixgbe_host_interface_command");
45976150453fSSepherosa Ziehau 
45986150453fSSepherosa Ziehau 	if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
45996150453fSSepherosa Ziehau 		DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
46006150453fSSepherosa Ziehau 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
46016150453fSSepherosa Ziehau 	}
46026150453fSSepherosa Ziehau 
46036150453fSSepherosa Ziehau 	/* Take management host interface semaphore */
46046150453fSSepherosa Ziehau 	status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
46056150453fSSepherosa Ziehau 	if (status)
46066150453fSSepherosa Ziehau 		return status;
46076150453fSSepherosa Ziehau 
46086150453fSSepherosa Ziehau 	status = ixgbe_hic_unlocked(hw, buffer, length, timeout);
46096150453fSSepherosa Ziehau 	if (status)
46106150453fSSepherosa Ziehau 		goto rel_out;
46116150453fSSepherosa Ziehau 
461263d483cdSSepherosa Ziehau 	if (!return_data)
46136150453fSSepherosa Ziehau 		goto rel_out;
461463d483cdSSepherosa Ziehau 
461579251f5eSSepherosa Ziehau 	/* Calculate length in DWORDs */
461679251f5eSSepherosa Ziehau 	dword_len = hdr_size >> 2;
461779251f5eSSepherosa Ziehau 
461879251f5eSSepherosa Ziehau 	/* first pull in the header so we know the buffer length */
461979251f5eSSepherosa Ziehau 	for (bi = 0; bi < dword_len; bi++) {
462079251f5eSSepherosa Ziehau 		buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
462179251f5eSSepherosa Ziehau 		IXGBE_LE32_TO_CPUS(&buffer[bi]);
462279251f5eSSepherosa Ziehau 	}
462379251f5eSSepherosa Ziehau 
4624dd5ce676SSepherosa Ziehau 	/*
4625dd5ce676SSepherosa Ziehau 	 * If there is any thing in data position pull it in
4626dd5ce676SSepherosa Ziehau 	 * Read Flash command requires reading buffer length from
4627dd5ce676SSepherosa Ziehau 	 * two byes instead of one byte
4628dd5ce676SSepherosa Ziehau 	 */
4629dd5ce676SSepherosa Ziehau 	if (resp->cmd == 0x30) {
4630dd5ce676SSepherosa Ziehau 		for (; bi < dword_len + 2; bi++) {
4631dd5ce676SSepherosa Ziehau 			buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
4632dd5ce676SSepherosa Ziehau 							  bi);
4633dd5ce676SSepherosa Ziehau 			IXGBE_LE32_TO_CPUS(&buffer[bi]);
4634dd5ce676SSepherosa Ziehau 		}
4635dd5ce676SSepherosa Ziehau 		buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
4636dd5ce676SSepherosa Ziehau 				  & 0xF00) | resp->buf_len;
4637dd5ce676SSepherosa Ziehau 		hdr_size += (2 << 2);
4638dd5ce676SSepherosa Ziehau 	} else {
4639dd5ce676SSepherosa Ziehau 		buf_len = resp->buf_len;
4640dd5ce676SSepherosa Ziehau 	}
46416150453fSSepherosa Ziehau 	if (!buf_len)
46426150453fSSepherosa Ziehau 		goto rel_out;
464379251f5eSSepherosa Ziehau 
464463d483cdSSepherosa Ziehau 	if (length < buf_len + hdr_size) {
464579251f5eSSepherosa Ziehau 		DEBUGOUT("Buffer not large enough for reply message.\n");
46466150453fSSepherosa Ziehau 		status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
46476150453fSSepherosa Ziehau 		goto rel_out;
464879251f5eSSepherosa Ziehau 	}
464979251f5eSSepherosa Ziehau 
465079251f5eSSepherosa Ziehau 	/* Calculate length in DWORDs, add 3 for odd lengths */
465179251f5eSSepherosa Ziehau 	dword_len = (buf_len + 3) >> 2;
465279251f5eSSepherosa Ziehau 
465379251f5eSSepherosa Ziehau 	/* Pull in the rest of the buffer (bi is where we left off) */
465479251f5eSSepherosa Ziehau 	for (; bi <= dword_len; bi++) {
465579251f5eSSepherosa Ziehau 		buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
465679251f5eSSepherosa Ziehau 		IXGBE_LE32_TO_CPUS(&buffer[bi]);
465779251f5eSSepherosa Ziehau 	}
465879251f5eSSepherosa Ziehau 
46596150453fSSepherosa Ziehau rel_out:
46606150453fSSepherosa Ziehau 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
46616150453fSSepherosa Ziehau 
46626150453fSSepherosa Ziehau 	return status;
466379251f5eSSepherosa Ziehau }
466479251f5eSSepherosa Ziehau 
466579251f5eSSepherosa Ziehau /**
466679251f5eSSepherosa Ziehau  *  ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware
466779251f5eSSepherosa Ziehau  *  @hw: pointer to the HW structure
466879251f5eSSepherosa Ziehau  *  @maj: driver version major number
466979251f5eSSepherosa Ziehau  *  @min: driver version minor number
467079251f5eSSepherosa Ziehau  *  @build: driver version build number
467179251f5eSSepherosa Ziehau  *  @sub: driver version sub build number
4672dd5ce676SSepherosa Ziehau  *  @len: unused
4673dd5ce676SSepherosa Ziehau  *  @driver_ver: unused
467479251f5eSSepherosa Ziehau  *
467579251f5eSSepherosa Ziehau  *  Sends driver version number to firmware through the manageability
467679251f5eSSepherosa Ziehau  *  block.  On success return IXGBE_SUCCESS
467779251f5eSSepherosa Ziehau  *  else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
467879251f5eSSepherosa Ziehau  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
467979251f5eSSepherosa Ziehau  **/
ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw * hw,u8 maj,u8 min,u8 build,u8 sub,u16 len,const char * driver_ver)468079251f5eSSepherosa Ziehau s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
46816150453fSSepherosa Ziehau 				 u8 build, u8 sub, u16 len,
46826150453fSSepherosa Ziehau 				 const char *driver_ver)
468379251f5eSSepherosa Ziehau {
468479251f5eSSepherosa Ziehau 	struct ixgbe_hic_drv_info fw_cmd;
468579251f5eSSepherosa Ziehau 	int i;
468679251f5eSSepherosa Ziehau 	s32 ret_val = IXGBE_SUCCESS;
468779251f5eSSepherosa Ziehau 
468879251f5eSSepherosa Ziehau 	DEBUGFUNC("ixgbe_set_fw_drv_ver_generic");
46896150453fSSepherosa Ziehau 	UNREFERENCED_2PARAMETER(len, driver_ver);
469079251f5eSSepherosa Ziehau 
469179251f5eSSepherosa Ziehau 	fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
469279251f5eSSepherosa Ziehau 	fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
469379251f5eSSepherosa Ziehau 	fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
469479251f5eSSepherosa Ziehau 	fw_cmd.port_num = (u8)hw->bus.func;
469579251f5eSSepherosa Ziehau 	fw_cmd.ver_maj = maj;
469679251f5eSSepherosa Ziehau 	fw_cmd.ver_min = min;
469779251f5eSSepherosa Ziehau 	fw_cmd.ver_build = build;
469879251f5eSSepherosa Ziehau 	fw_cmd.ver_sub = sub;
469979251f5eSSepherosa Ziehau 	fw_cmd.hdr.checksum = 0;
470079251f5eSSepherosa Ziehau 	fw_cmd.pad = 0;
470179251f5eSSepherosa Ziehau 	fw_cmd.pad2 = 0;
47026150453fSSepherosa Ziehau 	fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
47036150453fSSepherosa Ziehau 				(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
470479251f5eSSepherosa Ziehau 
470579251f5eSSepherosa Ziehau 	for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
470679251f5eSSepherosa Ziehau 		ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
470763d483cdSSepherosa Ziehau 						       sizeof(fw_cmd),
470863d483cdSSepherosa Ziehau 						       IXGBE_HI_COMMAND_TIMEOUT,
470963d483cdSSepherosa Ziehau 						       TRUE);
471079251f5eSSepherosa Ziehau 		if (ret_val != IXGBE_SUCCESS)
471179251f5eSSepherosa Ziehau 			continue;
471279251f5eSSepherosa Ziehau 
471379251f5eSSepherosa Ziehau 		if (fw_cmd.hdr.cmd_or_resp.ret_status ==
471479251f5eSSepherosa Ziehau 		    FW_CEM_RESP_STATUS_SUCCESS)
471579251f5eSSepherosa Ziehau 			ret_val = IXGBE_SUCCESS;
471679251f5eSSepherosa Ziehau 		else
471779251f5eSSepherosa Ziehau 			ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
471879251f5eSSepherosa Ziehau 
471979251f5eSSepherosa Ziehau 		break;
472079251f5eSSepherosa Ziehau 	}
472179251f5eSSepherosa Ziehau 
472279251f5eSSepherosa Ziehau 	return ret_val;
472379251f5eSSepherosa Ziehau }
472479251f5eSSepherosa Ziehau 
472579251f5eSSepherosa Ziehau /**
472679251f5eSSepherosa Ziehau  * ixgbe_set_rxpba_generic - Initialize Rx packet buffer
472779251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
472879251f5eSSepherosa Ziehau  * @num_pb: number of packet buffers to allocate
472979251f5eSSepherosa Ziehau  * @headroom: reserve n KB of headroom
473079251f5eSSepherosa Ziehau  * @strategy: packet buffer allocation strategy
473179251f5eSSepherosa Ziehau  **/
ixgbe_set_rxpba_generic(struct ixgbe_hw * hw,int num_pb,u32 headroom,int strategy)473279251f5eSSepherosa Ziehau void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
473379251f5eSSepherosa Ziehau 			     int strategy)
473479251f5eSSepherosa Ziehau {
473579251f5eSSepherosa Ziehau 	u32 pbsize = hw->mac.rx_pb_size;
473679251f5eSSepherosa Ziehau 	int i = 0;
473779251f5eSSepherosa Ziehau 	u32 rxpktsize, txpktsize, txpbthresh;
473879251f5eSSepherosa Ziehau 
473979251f5eSSepherosa Ziehau 	/* Reserve headroom */
474079251f5eSSepherosa Ziehau 	pbsize -= headroom;
474179251f5eSSepherosa Ziehau 
474279251f5eSSepherosa Ziehau 	if (!num_pb)
474379251f5eSSepherosa Ziehau 		num_pb = 1;
474479251f5eSSepherosa Ziehau 
474579251f5eSSepherosa Ziehau 	/* Divide remaining packet buffer space amongst the number of packet
474679251f5eSSepherosa Ziehau 	 * buffers requested using supplied strategy.
474779251f5eSSepherosa Ziehau 	 */
474879251f5eSSepherosa Ziehau 	switch (strategy) {
474979251f5eSSepherosa Ziehau 	case PBA_STRATEGY_WEIGHTED:
475079251f5eSSepherosa Ziehau 		/* ixgbe_dcb_pba_80_48 strategy weight first half of packet
475179251f5eSSepherosa Ziehau 		 * buffer with 5/8 of the packet buffer space.
475279251f5eSSepherosa Ziehau 		 */
475379251f5eSSepherosa Ziehau 		rxpktsize = (pbsize * 5) / (num_pb * 4);
475479251f5eSSepherosa Ziehau 		pbsize -= rxpktsize * (num_pb / 2);
475579251f5eSSepherosa Ziehau 		rxpktsize <<= IXGBE_RXPBSIZE_SHIFT;
475679251f5eSSepherosa Ziehau 		for (; i < (num_pb / 2); i++)
475779251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
47586150453fSSepherosa Ziehau 		/* fall through - configure remaining packet buffers */
475979251f5eSSepherosa Ziehau 	case PBA_STRATEGY_EQUAL:
476079251f5eSSepherosa Ziehau 		rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
476179251f5eSSepherosa Ziehau 		for (; i < num_pb; i++)
476279251f5eSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
476379251f5eSSepherosa Ziehau 		break;
476479251f5eSSepherosa Ziehau 	default:
476579251f5eSSepherosa Ziehau 		break;
476679251f5eSSepherosa Ziehau 	}
476779251f5eSSepherosa Ziehau 
476879251f5eSSepherosa Ziehau 	/* Only support an equally distributed Tx packet buffer strategy. */
476979251f5eSSepherosa Ziehau 	txpktsize = IXGBE_TXPBSIZE_MAX / num_pb;
477079251f5eSSepherosa Ziehau 	txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX;
477179251f5eSSepherosa Ziehau 	for (i = 0; i < num_pb; i++) {
477279251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize);
477379251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh);
477479251f5eSSepherosa Ziehau 	}
477579251f5eSSepherosa Ziehau 
477679251f5eSSepherosa Ziehau 	/* Clear unused TCs, if any, to zero buffer size*/
477779251f5eSSepherosa Ziehau 	for (; i < IXGBE_MAX_PB; i++) {
477879251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
477979251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0);
478079251f5eSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0);
478179251f5eSSepherosa Ziehau 	}
478279251f5eSSepherosa Ziehau }
478379251f5eSSepherosa Ziehau 
478479251f5eSSepherosa Ziehau /**
478579251f5eSSepherosa Ziehau  * ixgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo
478679251f5eSSepherosa Ziehau  * @hw: pointer to the hardware structure
478779251f5eSSepherosa Ziehau  *
478879251f5eSSepherosa Ziehau  * The 82599 and x540 MACs can experience issues if TX work is still pending
478979251f5eSSepherosa Ziehau  * when a reset occurs.  This function prevents this by flushing the PCIe
479079251f5eSSepherosa Ziehau  * buffers on the system.
479179251f5eSSepherosa Ziehau  **/
ixgbe_clear_tx_pending(struct ixgbe_hw * hw)479279251f5eSSepherosa Ziehau void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
479379251f5eSSepherosa Ziehau {
479463d483cdSSepherosa Ziehau 	u32 gcr_ext, hlreg0, i, poll;
479563d483cdSSepherosa Ziehau 	u16 value;
479679251f5eSSepherosa Ziehau 
479779251f5eSSepherosa Ziehau 	/*
479879251f5eSSepherosa Ziehau 	 * If double reset is not requested then all transactions should
479979251f5eSSepherosa Ziehau 	 * already be clear and as such there is no work to do
480079251f5eSSepherosa Ziehau 	 */
480179251f5eSSepherosa Ziehau 	if (!(hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED))
480279251f5eSSepherosa Ziehau 		return;
480379251f5eSSepherosa Ziehau 
480479251f5eSSepherosa Ziehau 	/*
480579251f5eSSepherosa Ziehau 	 * Set loopback enable to prevent any transmits from being sent
480679251f5eSSepherosa Ziehau 	 * should the link come up.  This assumes that the RXCTRL.RXEN bit
480779251f5eSSepherosa Ziehau 	 * has already been cleared.
480879251f5eSSepherosa Ziehau 	 */
480979251f5eSSepherosa Ziehau 	hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
481079251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK);
481179251f5eSSepherosa Ziehau 
481263d483cdSSepherosa Ziehau 	/* Wait for a last completion before clearing buffers */
481363d483cdSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
481463d483cdSSepherosa Ziehau 	msec_delay(3);
481563d483cdSSepherosa Ziehau 
481663d483cdSSepherosa Ziehau 	/*
481763d483cdSSepherosa Ziehau 	 * Before proceeding, make sure that the PCIe block does not have
481863d483cdSSepherosa Ziehau 	 * transactions pending.
481963d483cdSSepherosa Ziehau 	 */
482063d483cdSSepherosa Ziehau 	poll = ixgbe_pcie_timeout_poll(hw);
482163d483cdSSepherosa Ziehau 	for (i = 0; i < poll; i++) {
482263d483cdSSepherosa Ziehau 		usec_delay(100);
482363d483cdSSepherosa Ziehau 		value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS);
482463d483cdSSepherosa Ziehau 		if (IXGBE_REMOVED(hw->hw_addr))
482563d483cdSSepherosa Ziehau 			goto out;
482663d483cdSSepherosa Ziehau 		if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
482763d483cdSSepherosa Ziehau 			goto out;
482863d483cdSSepherosa Ziehau 	}
482963d483cdSSepherosa Ziehau 
483063d483cdSSepherosa Ziehau out:
483179251f5eSSepherosa Ziehau 	/* initiate cleaning flow for buffers in the PCIe transaction layer */
483279251f5eSSepherosa Ziehau 	gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
483379251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT,
483479251f5eSSepherosa Ziehau 			gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR);
483579251f5eSSepherosa Ziehau 
483679251f5eSSepherosa Ziehau 	/* Flush all writes and allow 20usec for all transactions to clear */
483779251f5eSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
483879251f5eSSepherosa Ziehau 	usec_delay(20);
483979251f5eSSepherosa Ziehau 
484079251f5eSSepherosa Ziehau 	/* restore previous register values */
484179251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
484279251f5eSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
484379251f5eSSepherosa Ziehau }
484479251f5eSSepherosa Ziehau 
48456150453fSSepherosa Ziehau /**
48466150453fSSepherosa Ziehau  *  ixgbe_bypass_rw_generic - Bit bang data into by_pass FW
48476150453fSSepherosa Ziehau  *
48486150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
48496150453fSSepherosa Ziehau  *  @cmd: Command we send to the FW
48506150453fSSepherosa Ziehau  *  @status: The reply from the FW
48516150453fSSepherosa Ziehau  *
48526150453fSSepherosa Ziehau  *  Bit-bangs the cmd to the by_pass FW status points to what is returned.
48536150453fSSepherosa Ziehau  **/
48546150453fSSepherosa Ziehau #define IXGBE_BYPASS_BB_WAIT 1
ixgbe_bypass_rw_generic(struct ixgbe_hw * hw,u32 cmd,u32 * status)48556150453fSSepherosa Ziehau s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status)
48566150453fSSepherosa Ziehau {
48576150453fSSepherosa Ziehau 	int i;
48586150453fSSepherosa Ziehau 	u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo;
48596150453fSSepherosa Ziehau 	u32 esdp;
48606150453fSSepherosa Ziehau 
48616150453fSSepherosa Ziehau 	if (!status)
48626150453fSSepherosa Ziehau 		return IXGBE_ERR_PARAM;
48636150453fSSepherosa Ziehau 
48646150453fSSepherosa Ziehau 	*status = 0;
48656150453fSSepherosa Ziehau 
48666150453fSSepherosa Ziehau 	/* SDP vary by MAC type */
48676150453fSSepherosa Ziehau 	switch (hw->mac.type) {
48686150453fSSepherosa Ziehau 	case ixgbe_mac_82599EB:
48696150453fSSepherosa Ziehau 		sck = IXGBE_ESDP_SDP7;
48706150453fSSepherosa Ziehau 		sdi = IXGBE_ESDP_SDP0;
48716150453fSSepherosa Ziehau 		sdo = IXGBE_ESDP_SDP6;
48726150453fSSepherosa Ziehau 		dir_sck = IXGBE_ESDP_SDP7_DIR;
48736150453fSSepherosa Ziehau 		dir_sdi = IXGBE_ESDP_SDP0_DIR;
48746150453fSSepherosa Ziehau 		dir_sdo = IXGBE_ESDP_SDP6_DIR;
48756150453fSSepherosa Ziehau 		break;
48766150453fSSepherosa Ziehau 	case ixgbe_mac_X540:
48776150453fSSepherosa Ziehau 		sck = IXGBE_ESDP_SDP2;
48786150453fSSepherosa Ziehau 		sdi = IXGBE_ESDP_SDP0;
48796150453fSSepherosa Ziehau 		sdo = IXGBE_ESDP_SDP1;
48806150453fSSepherosa Ziehau 		dir_sck = IXGBE_ESDP_SDP2_DIR;
48816150453fSSepherosa Ziehau 		dir_sdi = IXGBE_ESDP_SDP0_DIR;
48826150453fSSepherosa Ziehau 		dir_sdo = IXGBE_ESDP_SDP1_DIR;
48836150453fSSepherosa Ziehau 		break;
48846150453fSSepherosa Ziehau 	default:
48856150453fSSepherosa Ziehau 		return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
48866150453fSSepherosa Ziehau 	}
48876150453fSSepherosa Ziehau 
48886150453fSSepherosa Ziehau 	/* Set SDP pins direction */
48896150453fSSepherosa Ziehau 	esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
48906150453fSSepherosa Ziehau 	esdp |= dir_sck;	/* SCK as output */
48916150453fSSepherosa Ziehau 	esdp |= dir_sdi;	/* SDI as output */
48926150453fSSepherosa Ziehau 	esdp &= ~dir_sdo;	/* SDO as input */
48936150453fSSepherosa Ziehau 	esdp |= sck;
48946150453fSSepherosa Ziehau 	esdp |= sdi;
48956150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
48966150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
48976150453fSSepherosa Ziehau 	msec_delay(IXGBE_BYPASS_BB_WAIT);
48986150453fSSepherosa Ziehau 
48996150453fSSepherosa Ziehau 	/* Generate start condition */
49006150453fSSepherosa Ziehau 	esdp &= ~sdi;
49016150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49026150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
49036150453fSSepherosa Ziehau 	msec_delay(IXGBE_BYPASS_BB_WAIT);
49046150453fSSepherosa Ziehau 
49056150453fSSepherosa Ziehau 	esdp &= ~sck;
49066150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49076150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
49086150453fSSepherosa Ziehau 	msec_delay(IXGBE_BYPASS_BB_WAIT);
49096150453fSSepherosa Ziehau 
49106150453fSSepherosa Ziehau 	/* Clock out the new control word and clock in the status */
49116150453fSSepherosa Ziehau 	for (i = 0; i < 32; i++) {
49126150453fSSepherosa Ziehau 		if ((cmd >> (31 - i)) & 0x01) {
49136150453fSSepherosa Ziehau 			esdp |= sdi;
49146150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49156150453fSSepherosa Ziehau 		} else {
49166150453fSSepherosa Ziehau 			esdp &= ~sdi;
49176150453fSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49186150453fSSepherosa Ziehau 		}
49196150453fSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
49206150453fSSepherosa Ziehau 		msec_delay(IXGBE_BYPASS_BB_WAIT);
49216150453fSSepherosa Ziehau 
49226150453fSSepherosa Ziehau 		esdp |= sck;
49236150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49246150453fSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
49256150453fSSepherosa Ziehau 		msec_delay(IXGBE_BYPASS_BB_WAIT);
49266150453fSSepherosa Ziehau 
49276150453fSSepherosa Ziehau 		esdp &= ~sck;
49286150453fSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49296150453fSSepherosa Ziehau 		IXGBE_WRITE_FLUSH(hw);
49306150453fSSepherosa Ziehau 		msec_delay(IXGBE_BYPASS_BB_WAIT);
49316150453fSSepherosa Ziehau 
49326150453fSSepherosa Ziehau 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
49336150453fSSepherosa Ziehau 		if (esdp & sdo)
49346150453fSSepherosa Ziehau 			*status = (*status << 1) | 0x01;
49356150453fSSepherosa Ziehau 		else
49366150453fSSepherosa Ziehau 			*status = (*status << 1) | 0x00;
49376150453fSSepherosa Ziehau 		msec_delay(IXGBE_BYPASS_BB_WAIT);
49386150453fSSepherosa Ziehau 	}
49396150453fSSepherosa Ziehau 
49406150453fSSepherosa Ziehau 	/* stop condition */
49416150453fSSepherosa Ziehau 	esdp |= sck;
49426150453fSSepherosa Ziehau 	esdp &= ~sdi;
49436150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49446150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
49456150453fSSepherosa Ziehau 	msec_delay(IXGBE_BYPASS_BB_WAIT);
49466150453fSSepherosa Ziehau 
49476150453fSSepherosa Ziehau 	esdp |= sdi;
49486150453fSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
49496150453fSSepherosa Ziehau 	IXGBE_WRITE_FLUSH(hw);
49506150453fSSepherosa Ziehau 
49516150453fSSepherosa Ziehau 	/* set the page bits to match the cmd that the status it belongs to */
49526150453fSSepherosa Ziehau 	*status = (*status & 0x3fffffff) | (cmd & 0xc0000000);
49536150453fSSepherosa Ziehau 
49546150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
49556150453fSSepherosa Ziehau }
49566150453fSSepherosa Ziehau 
49576150453fSSepherosa Ziehau /**
49586150453fSSepherosa Ziehau  * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang.
49596150453fSSepherosa Ziehau  *
49606150453fSSepherosa Ziehau  * If we send a write we can't be sure it took until we can read back
49616150453fSSepherosa Ziehau  * that same register.  It can be a problem as some of the feilds may
49626150453fSSepherosa Ziehau  * for valid reasons change inbetween the time wrote the register and
49636150453fSSepherosa Ziehau  * we read it again to verify.  So this function check everything we
49646150453fSSepherosa Ziehau  * can check and then assumes it worked.
49656150453fSSepherosa Ziehau  *
49666150453fSSepherosa Ziehau  * @u32 in_reg - The register cmd for the bit-bang read.
49676150453fSSepherosa Ziehau  * @u32 out_reg - The register returned from a bit-bang read.
49686150453fSSepherosa Ziehau  **/
ixgbe_bypass_valid_rd_generic(u32 in_reg,u32 out_reg)49696150453fSSepherosa Ziehau bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg)
49706150453fSSepherosa Ziehau {
49716150453fSSepherosa Ziehau 	u32 mask;
49726150453fSSepherosa Ziehau 
49736150453fSSepherosa Ziehau 	/* Page must match for all control pages */
49746150453fSSepherosa Ziehau 	if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M))
49756150453fSSepherosa Ziehau 		return FALSE;
49766150453fSSepherosa Ziehau 
49776150453fSSepherosa Ziehau 	switch (in_reg & BYPASS_PAGE_M) {
49786150453fSSepherosa Ziehau 	case BYPASS_PAGE_CTL0:
49796150453fSSepherosa Ziehau 		/* All the following can't change since the last write
49806150453fSSepherosa Ziehau 		 *  - All the event actions
49816150453fSSepherosa Ziehau 		 *  - The timeout value
49826150453fSSepherosa Ziehau 		 */
49836150453fSSepherosa Ziehau 		mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M |
49846150453fSSepherosa Ziehau 		       BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M |
49856150453fSSepherosa Ziehau 		       BYPASS_WDTIMEOUT_M |
49866150453fSSepherosa Ziehau 		       BYPASS_WDT_VALUE_M;
49876150453fSSepherosa Ziehau 		if ((out_reg & mask) != (in_reg & mask))
49886150453fSSepherosa Ziehau 			return FALSE;
49896150453fSSepherosa Ziehau 
49906150453fSSepherosa Ziehau 		/* 0x0 is never a valid value for bypass status */
49916150453fSSepherosa Ziehau 		if (!(out_reg & BYPASS_STATUS_OFF_M))
49926150453fSSepherosa Ziehau 			return FALSE;
49936150453fSSepherosa Ziehau 		break;
49946150453fSSepherosa Ziehau 	case BYPASS_PAGE_CTL1:
49956150453fSSepherosa Ziehau 		/* All the following can't change since the last write
49966150453fSSepherosa Ziehau 		 *  - time valid bit
49976150453fSSepherosa Ziehau 		 *  - time we last sent
49986150453fSSepherosa Ziehau 		 */
49996150453fSSepherosa Ziehau 		mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M;
50006150453fSSepherosa Ziehau 		if ((out_reg & mask) != (in_reg & mask))
50016150453fSSepherosa Ziehau 			return FALSE;
50026150453fSSepherosa Ziehau 		break;
50036150453fSSepherosa Ziehau 	case BYPASS_PAGE_CTL2:
50046150453fSSepherosa Ziehau 		/* All we can check in this page is control number
50056150453fSSepherosa Ziehau 		 * which is already done above.
50066150453fSSepherosa Ziehau 		 */
50076150453fSSepherosa Ziehau 		break;
50086150453fSSepherosa Ziehau 	}
50096150453fSSepherosa Ziehau 
50106150453fSSepherosa Ziehau 	/* We are as sure as we can be return TRUE */
50116150453fSSepherosa Ziehau 	return TRUE;
50126150453fSSepherosa Ziehau }
50136150453fSSepherosa Ziehau 
50146150453fSSepherosa Ziehau /**
50156150453fSSepherosa Ziehau  *  ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter.
50166150453fSSepherosa Ziehau  *
50176150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
50186150453fSSepherosa Ziehau  *  @cmd: The control word we are setting.
50196150453fSSepherosa Ziehau  *  @event: The event we are setting in the FW.  This also happens to
50206150453fSSepherosa Ziehau  *	    be the mask for the event we are setting (handy)
50216150453fSSepherosa Ziehau  *  @action: The action we set the event to in the FW. This is in a
50226150453fSSepherosa Ziehau  *	     bit field that happens to be what we want to put in
50236150453fSSepherosa Ziehau  *	     the event spot (also handy)
50246150453fSSepherosa Ziehau  **/
ixgbe_bypass_set_generic(struct ixgbe_hw * hw,u32 ctrl,u32 event,u32 action)50256150453fSSepherosa Ziehau s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event,
50266150453fSSepherosa Ziehau 			     u32 action)
50276150453fSSepherosa Ziehau {
50286150453fSSepherosa Ziehau 	u32 by_ctl = 0;
50296150453fSSepherosa Ziehau 	u32 cmd, verify;
50306150453fSSepherosa Ziehau 	u32 count = 0;
50316150453fSSepherosa Ziehau 
50326150453fSSepherosa Ziehau 	/* Get current values */
50336150453fSSepherosa Ziehau 	cmd = ctrl;	/* just reading only need control number */
50346150453fSSepherosa Ziehau 	if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
50356150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
50366150453fSSepherosa Ziehau 
50376150453fSSepherosa Ziehau 	/* Set to new action */
50386150453fSSepherosa Ziehau 	cmd = (by_ctl & ~event) | BYPASS_WE | action;
50396150453fSSepherosa Ziehau 	if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
50406150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
50416150453fSSepherosa Ziehau 
50426150453fSSepherosa Ziehau 	/* Page 0 force a FW eeprom write which is slow so verify */
50436150453fSSepherosa Ziehau 	if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) {
50446150453fSSepherosa Ziehau 		verify = BYPASS_PAGE_CTL0;
50456150453fSSepherosa Ziehau 		do {
50466150453fSSepherosa Ziehau 			if (count++ > 5)
50476150453fSSepherosa Ziehau 				return IXGBE_BYPASS_FW_WRITE_FAILURE;
50486150453fSSepherosa Ziehau 
50496150453fSSepherosa Ziehau 			if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl))
50506150453fSSepherosa Ziehau 				return IXGBE_ERR_INVALID_ARGUMENT;
50516150453fSSepherosa Ziehau 		} while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl));
50526150453fSSepherosa Ziehau 	} else {
50536150453fSSepherosa Ziehau 		/* We have give the FW time for the write to stick */
50546150453fSSepherosa Ziehau 		msec_delay(100);
50556150453fSSepherosa Ziehau 	}
50566150453fSSepherosa Ziehau 
50576150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
50586150453fSSepherosa Ziehau }
50596150453fSSepherosa Ziehau 
50606150453fSSepherosa Ziehau /**
50616150453fSSepherosa Ziehau  *  ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom addres.
50626150453fSSepherosa Ziehau  *
50636150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
50646150453fSSepherosa Ziehau  *  @addr: The bypass eeprom address to read.
50656150453fSSepherosa Ziehau  *  @value: The 8b of data at the address above.
50666150453fSSepherosa Ziehau  **/
ixgbe_bypass_rd_eep_generic(struct ixgbe_hw * hw,u32 addr,u8 * value)50676150453fSSepherosa Ziehau s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value)
50686150453fSSepherosa Ziehau {
50696150453fSSepherosa Ziehau 	u32 cmd;
50706150453fSSepherosa Ziehau 	u32 status;
50716150453fSSepherosa Ziehau 
50726150453fSSepherosa Ziehau 
50736150453fSSepherosa Ziehau 	/* send the request */
50746150453fSSepherosa Ziehau 	cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
50756150453fSSepherosa Ziehau 	cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
50766150453fSSepherosa Ziehau 	if (ixgbe_bypass_rw_generic(hw, cmd, &status))
50776150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
50786150453fSSepherosa Ziehau 
50796150453fSSepherosa Ziehau 	/* We have give the FW time for the write to stick */
50806150453fSSepherosa Ziehau 	msec_delay(100);
50816150453fSSepherosa Ziehau 
50826150453fSSepherosa Ziehau 	/* now read the results */
50836150453fSSepherosa Ziehau 	cmd &= ~BYPASS_WE;
50846150453fSSepherosa Ziehau 	if (ixgbe_bypass_rw_generic(hw, cmd, &status))
50856150453fSSepherosa Ziehau 		return IXGBE_ERR_INVALID_ARGUMENT;
50866150453fSSepherosa Ziehau 
50876150453fSSepherosa Ziehau 	*value = status & BYPASS_CTL2_DATA_M;
50886150453fSSepherosa Ziehau 
50896150453fSSepherosa Ziehau 	return IXGBE_SUCCESS;
50906150453fSSepherosa Ziehau }
50916150453fSSepherosa Ziehau 
50926150453fSSepherosa Ziehau /**
50936150453fSSepherosa Ziehau  *  ixgbe_get_orom_version - Return option ROM from EEPROM
50946150453fSSepherosa Ziehau  *
50956150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
50966150453fSSepherosa Ziehau  *  @nvm_ver: pointer to output structure
50976150453fSSepherosa Ziehau  *
50986150453fSSepherosa Ziehau  *  if valid option ROM version, nvm_ver->or_valid set to TRUE
50996150453fSSepherosa Ziehau  *  else nvm_ver->or_valid is FALSE.
51006150453fSSepherosa Ziehau  **/
ixgbe_get_orom_version(struct ixgbe_hw * hw,struct ixgbe_nvm_version * nvm_ver)51016150453fSSepherosa Ziehau void ixgbe_get_orom_version(struct ixgbe_hw *hw,
51026150453fSSepherosa Ziehau 			    struct ixgbe_nvm_version *nvm_ver)
51036150453fSSepherosa Ziehau {
51046150453fSSepherosa Ziehau 	u16 offset, eeprom_cfg_blkh, eeprom_cfg_blkl;
51056150453fSSepherosa Ziehau 
51066150453fSSepherosa Ziehau 	nvm_ver->or_valid = FALSE;
51076150453fSSepherosa Ziehau 	/* Option Rom may or may not be present.  Start with pointer */
51086150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, NVM_OROM_OFFSET, &offset);
51096150453fSSepherosa Ziehau 
51106150453fSSepherosa Ziehau 	/* make sure offset is valid */
51116150453fSSepherosa Ziehau 	if ((offset == 0x0) || (offset == NVM_INVALID_PTR))
51126150453fSSepherosa Ziehau 		return;
51136150453fSSepherosa Ziehau 
51146150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_HI, &eeprom_cfg_blkh);
51156150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_LOW, &eeprom_cfg_blkl);
51166150453fSSepherosa Ziehau 
51176150453fSSepherosa Ziehau 	/* option rom exists and is valid */
51186150453fSSepherosa Ziehau 	if ((eeprom_cfg_blkl | eeprom_cfg_blkh) == 0x0 ||
51196150453fSSepherosa Ziehau 	    eeprom_cfg_blkl == NVM_VER_INVALID ||
51206150453fSSepherosa Ziehau 	    eeprom_cfg_blkh == NVM_VER_INVALID)
51216150453fSSepherosa Ziehau 		return;
51226150453fSSepherosa Ziehau 
51236150453fSSepherosa Ziehau 	nvm_ver->or_valid = TRUE;
51246150453fSSepherosa Ziehau 	nvm_ver->or_major = eeprom_cfg_blkl >> NVM_OROM_SHIFT;
51256150453fSSepherosa Ziehau 	nvm_ver->or_build = (eeprom_cfg_blkl << NVM_OROM_SHIFT) |
51266150453fSSepherosa Ziehau 			    (eeprom_cfg_blkh >> NVM_OROM_SHIFT);
51276150453fSSepherosa Ziehau 	nvm_ver->or_patch = eeprom_cfg_blkh & NVM_OROM_PATCH_MASK;
51286150453fSSepherosa Ziehau }
51296150453fSSepherosa Ziehau 
51306150453fSSepherosa Ziehau /**
51316150453fSSepherosa Ziehau  *  ixgbe_get_oem_prod_version - Return OEM Product version
51326150453fSSepherosa Ziehau  *
51336150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
51346150453fSSepherosa Ziehau  *  @nvm_ver: pointer to output structure
51356150453fSSepherosa Ziehau  *
51366150453fSSepherosa Ziehau  *  if valid OEM product version, nvm_ver->oem_valid set to TRUE
51376150453fSSepherosa Ziehau  *  else nvm_ver->oem_valid is FALSE.
51386150453fSSepherosa Ziehau  **/
ixgbe_get_oem_prod_version(struct ixgbe_hw * hw,struct ixgbe_nvm_version * nvm_ver)51396150453fSSepherosa Ziehau void ixgbe_get_oem_prod_version(struct ixgbe_hw *hw,
51406150453fSSepherosa Ziehau 				struct ixgbe_nvm_version *nvm_ver)
51416150453fSSepherosa Ziehau {
51426150453fSSepherosa Ziehau 	u16 rel_num, prod_ver, mod_len, cap, offset;
51436150453fSSepherosa Ziehau 
51446150453fSSepherosa Ziehau 	nvm_ver->oem_valid = FALSE;
51456150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, NVM_OEM_PROD_VER_PTR, &offset);
51466150453fSSepherosa Ziehau 
51476150453fSSepherosa Ziehau 	/* Return is offset to OEM Product Version block is invalid */
5148*663b0ef6SSascha Wildner 	if (offset == 0x0 || offset == NVM_INVALID_PTR)
51496150453fSSepherosa Ziehau 		return;
51506150453fSSepherosa Ziehau 
51516150453fSSepherosa Ziehau 	/* Read product version block */
51526150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, offset, &mod_len);
51536150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_CAP_OFF, &cap);
51546150453fSSepherosa Ziehau 
51556150453fSSepherosa Ziehau 	/* Return if OEM product version block is invalid */
51566150453fSSepherosa Ziehau 	if (mod_len != NVM_OEM_PROD_VER_MOD_LEN ||
51576150453fSSepherosa Ziehau 	    (cap & NVM_OEM_PROD_VER_CAP_MASK) != 0x0)
51586150453fSSepherosa Ziehau 		return;
51596150453fSSepherosa Ziehau 
51606150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_L, &prod_ver);
51616150453fSSepherosa Ziehau 	hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_H, &rel_num);
51626150453fSSepherosa Ziehau 
51636150453fSSepherosa Ziehau 	/* Return if version is invalid */
51646150453fSSepherosa Ziehau 	if ((rel_num | prod_ver) == 0x0 ||
51656150453fSSepherosa Ziehau 	    rel_num == NVM_VER_INVALID || prod_ver == NVM_VER_INVALID)
51666150453fSSepherosa Ziehau 		return;
51676150453fSSepherosa Ziehau 
51686150453fSSepherosa Ziehau 	nvm_ver->oem_major = prod_ver >> NVM_VER_SHIFT;
51696150453fSSepherosa Ziehau 	nvm_ver->oem_minor = prod_ver & NVM_VER_MASK;
51706150453fSSepherosa Ziehau 	nvm_ver->oem_release = rel_num;
51716150453fSSepherosa Ziehau 	nvm_ver->oem_valid = TRUE;
51726150453fSSepherosa Ziehau }
51736150453fSSepherosa Ziehau 
51746150453fSSepherosa Ziehau /**
51756150453fSSepherosa Ziehau  *  ixgbe_get_etk_id - Return Etrack ID from EEPROM
51766150453fSSepherosa Ziehau  *
51776150453fSSepherosa Ziehau  *  @hw: pointer to hardware structure
51786150453fSSepherosa Ziehau  *  @nvm_ver: pointer to output structure
51796150453fSSepherosa Ziehau  *
51806150453fSSepherosa Ziehau  *  word read errors will return 0xFFFF
51816150453fSSepherosa Ziehau  **/
ixgbe_get_etk_id(struct ixgbe_hw * hw,struct ixgbe_nvm_version * nvm_ver)51826150453fSSepherosa Ziehau void ixgbe_get_etk_id(struct ixgbe_hw *hw, struct ixgbe_nvm_version *nvm_ver)
51836150453fSSepherosa Ziehau {
51846150453fSSepherosa Ziehau 	u16 etk_id_l, etk_id_h;
51856150453fSSepherosa Ziehau 
51866150453fSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_LOW, &etk_id_l))
51876150453fSSepherosa Ziehau 		etk_id_l = NVM_VER_INVALID;
51886150453fSSepherosa Ziehau 	if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_HI, &etk_id_h))
51896150453fSSepherosa Ziehau 		etk_id_h = NVM_VER_INVALID;
51906150453fSSepherosa Ziehau 
51916150453fSSepherosa Ziehau 	/* The word order for the version format is determined by high order
51926150453fSSepherosa Ziehau 	 * word bit 15.
51936150453fSSepherosa Ziehau 	 */
51946150453fSSepherosa Ziehau 	if ((etk_id_h & NVM_ETK_VALID) == 0) {
51956150453fSSepherosa Ziehau 		nvm_ver->etk_id = etk_id_h;
51966150453fSSepherosa Ziehau 		nvm_ver->etk_id |= (etk_id_l << NVM_ETK_SHIFT);
51976150453fSSepherosa Ziehau 	} else {
51986150453fSSepherosa Ziehau 		nvm_ver->etk_id = etk_id_l;
51996150453fSSepherosa Ziehau 		nvm_ver->etk_id |= (etk_id_h << NVM_ETK_SHIFT);
52006150453fSSepherosa Ziehau 	}
52016150453fSSepherosa Ziehau }
52026150453fSSepherosa Ziehau 
520379251f5eSSepherosa Ziehau 
520479251f5eSSepherosa Ziehau /**
520579251f5eSSepherosa Ziehau  * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg
520679251f5eSSepherosa Ziehau  * @hw: pointer to hardware structure
520779251f5eSSepherosa Ziehau  * @map: pointer to u8 arr for returning map
520879251f5eSSepherosa Ziehau  *
520979251f5eSSepherosa Ziehau  * Read the rtrup2tc HW register and resolve its content into map
521079251f5eSSepherosa Ziehau  **/
ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw * hw,u8 * map)521179251f5eSSepherosa Ziehau void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map)
521279251f5eSSepherosa Ziehau {
521379251f5eSSepherosa Ziehau 	u32 reg, i;
521479251f5eSSepherosa Ziehau 
521579251f5eSSepherosa Ziehau 	reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
521679251f5eSSepherosa Ziehau 	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
521779251f5eSSepherosa Ziehau 		map[i] = IXGBE_RTRUP2TC_UP_MASK &
521879251f5eSSepherosa Ziehau 			(reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
521979251f5eSSepherosa Ziehau 	return;
522079251f5eSSepherosa Ziehau }
522163d483cdSSepherosa Ziehau 
ixgbe_disable_rx_generic(struct ixgbe_hw * hw)522263d483cdSSepherosa Ziehau void ixgbe_disable_rx_generic(struct ixgbe_hw *hw)
522363d483cdSSepherosa Ziehau {
522463d483cdSSepherosa Ziehau 	u32 pfdtxgswc;
522563d483cdSSepherosa Ziehau 	u32 rxctrl;
522663d483cdSSepherosa Ziehau 
522763d483cdSSepherosa Ziehau 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
522863d483cdSSepherosa Ziehau 	if (rxctrl & IXGBE_RXCTRL_RXEN) {
522963d483cdSSepherosa Ziehau 		if (hw->mac.type != ixgbe_mac_82598EB) {
523063d483cdSSepherosa Ziehau 			pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
523163d483cdSSepherosa Ziehau 			if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
523263d483cdSSepherosa Ziehau 				pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
523363d483cdSSepherosa Ziehau 				IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
523463d483cdSSepherosa Ziehau 				hw->mac.set_lben = TRUE;
523563d483cdSSepherosa Ziehau 			} else {
523663d483cdSSepherosa Ziehau 				hw->mac.set_lben = FALSE;
523763d483cdSSepherosa Ziehau 			}
523863d483cdSSepherosa Ziehau 		}
523963d483cdSSepherosa Ziehau 		rxctrl &= ~IXGBE_RXCTRL_RXEN;
524063d483cdSSepherosa Ziehau 		IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
524163d483cdSSepherosa Ziehau 	}
524263d483cdSSepherosa Ziehau }
524363d483cdSSepherosa Ziehau 
ixgbe_enable_rx_generic(struct ixgbe_hw * hw)524463d483cdSSepherosa Ziehau void ixgbe_enable_rx_generic(struct ixgbe_hw *hw)
524563d483cdSSepherosa Ziehau {
524663d483cdSSepherosa Ziehau 	u32 pfdtxgswc;
524763d483cdSSepherosa Ziehau 	u32 rxctrl;
524863d483cdSSepherosa Ziehau 
524963d483cdSSepherosa Ziehau 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
525063d483cdSSepherosa Ziehau 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, (rxctrl | IXGBE_RXCTRL_RXEN));
525163d483cdSSepherosa Ziehau 
525263d483cdSSepherosa Ziehau 	if (hw->mac.type != ixgbe_mac_82598EB) {
525363d483cdSSepherosa Ziehau 		if (hw->mac.set_lben) {
525463d483cdSSepherosa Ziehau 			pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
525563d483cdSSepherosa Ziehau 			pfdtxgswc |= IXGBE_PFDTXGSWC_VT_LBEN;
525663d483cdSSepherosa Ziehau 			IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
525763d483cdSSepherosa Ziehau 			hw->mac.set_lben = FALSE;
525863d483cdSSepherosa Ziehau 		}
525963d483cdSSepherosa Ziehau 	}
526063d483cdSSepherosa Ziehau }
526163d483cdSSepherosa Ziehau 
526263d483cdSSepherosa Ziehau /**
526363d483cdSSepherosa Ziehau  * ixgbe_mng_present - returns TRUE when management capability is present
526463d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
526563d483cdSSepherosa Ziehau  */
ixgbe_mng_present(struct ixgbe_hw * hw)526663d483cdSSepherosa Ziehau bool ixgbe_mng_present(struct ixgbe_hw *hw)
526763d483cdSSepherosa Ziehau {
526863d483cdSSepherosa Ziehau 	u32 fwsm;
526963d483cdSSepherosa Ziehau 
527063d483cdSSepherosa Ziehau 	if (hw->mac.type < ixgbe_mac_82599EB)
527163d483cdSSepherosa Ziehau 		return FALSE;
527263d483cdSSepherosa Ziehau 
52736150453fSSepherosa Ziehau 	fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
52746150453fSSepherosa Ziehau 
52756150453fSSepherosa Ziehau 	return !!(fwsm & IXGBE_FWSM_FW_MODE_PT);
527663d483cdSSepherosa Ziehau }
527763d483cdSSepherosa Ziehau 
527863d483cdSSepherosa Ziehau /**
527963d483cdSSepherosa Ziehau  * ixgbe_mng_enabled - Is the manageability engine enabled?
528063d483cdSSepherosa Ziehau  * @hw: pointer to hardware structure
528163d483cdSSepherosa Ziehau  *
528263d483cdSSepherosa Ziehau  * Returns TRUE if the manageability engine is enabled.
528363d483cdSSepherosa Ziehau  **/
ixgbe_mng_enabled(struct ixgbe_hw * hw)528463d483cdSSepherosa Ziehau bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
528563d483cdSSepherosa Ziehau {
528663d483cdSSepherosa Ziehau 	u32 fwsm, manc, factps;
528763d483cdSSepherosa Ziehau 
52886150453fSSepherosa Ziehau 	fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
528963d483cdSSepherosa Ziehau 	if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
529063d483cdSSepherosa Ziehau 		return FALSE;
529163d483cdSSepherosa Ziehau 
529263d483cdSSepherosa Ziehau 	manc = IXGBE_READ_REG(hw, IXGBE_MANC);
529363d483cdSSepherosa Ziehau 	if (!(manc & IXGBE_MANC_RCV_TCO_EN))
529463d483cdSSepherosa Ziehau 		return FALSE;
529563d483cdSSepherosa Ziehau 
529663d483cdSSepherosa Ziehau 	if (hw->mac.type <= ixgbe_mac_X540) {
52976150453fSSepherosa Ziehau 		factps = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw));
529863d483cdSSepherosa Ziehau 		if (factps & IXGBE_FACTPS_MNGCG)
529963d483cdSSepherosa Ziehau 			return FALSE;
530063d483cdSSepherosa Ziehau 	}
530163d483cdSSepherosa Ziehau 
530263d483cdSSepherosa Ziehau 	return TRUE;
530363d483cdSSepherosa Ziehau }
530463d483cdSSepherosa Ziehau 
530563d483cdSSepherosa Ziehau /**
530663d483cdSSepherosa Ziehau  *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
530763d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
530863d483cdSSepherosa Ziehau  *  @speed: new link speed
530963d483cdSSepherosa Ziehau  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
531063d483cdSSepherosa Ziehau  *
531163d483cdSSepherosa Ziehau  *  Set the link speed in the MAC and/or PHY register and restarts link.
531263d483cdSSepherosa Ziehau  **/
ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)531363d483cdSSepherosa Ziehau s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
531463d483cdSSepherosa Ziehau 					  ixgbe_link_speed speed,
531563d483cdSSepherosa Ziehau 					  bool autoneg_wait_to_complete)
531663d483cdSSepherosa Ziehau {
531763d483cdSSepherosa Ziehau 	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
531863d483cdSSepherosa Ziehau 	ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
531963d483cdSSepherosa Ziehau 	s32 status = IXGBE_SUCCESS;
532063d483cdSSepherosa Ziehau 	u32 speedcnt = 0;
532163d483cdSSepherosa Ziehau 	u32 i = 0;
532263d483cdSSepherosa Ziehau 	bool autoneg, link_up = FALSE;
532363d483cdSSepherosa Ziehau 
532463d483cdSSepherosa Ziehau 	DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
532563d483cdSSepherosa Ziehau 
532663d483cdSSepherosa Ziehau 	/* Mask off requested but non-supported speeds */
532763d483cdSSepherosa Ziehau 	status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg);
532863d483cdSSepherosa Ziehau 	if (status != IXGBE_SUCCESS)
532963d483cdSSepherosa Ziehau 		return status;
533063d483cdSSepherosa Ziehau 
533163d483cdSSepherosa Ziehau 	speed &= link_speed;
533263d483cdSSepherosa Ziehau 
533363d483cdSSepherosa Ziehau 	/* Try each speed one by one, highest priority first.  We do this in
533463d483cdSSepherosa Ziehau 	 * software because 10Gb fiber doesn't support speed autonegotiation.
533563d483cdSSepherosa Ziehau 	 */
533663d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
533763d483cdSSepherosa Ziehau 		speedcnt++;
533863d483cdSSepherosa Ziehau 		highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
533963d483cdSSepherosa Ziehau 
534063d483cdSSepherosa Ziehau 		/* Set the module link speed */
534163d483cdSSepherosa Ziehau 		switch (hw->phy.media_type) {
534263d483cdSSepherosa Ziehau 		case ixgbe_media_type_fiber_fixed:
534363d483cdSSepherosa Ziehau 		case ixgbe_media_type_fiber:
534463d483cdSSepherosa Ziehau 			ixgbe_set_rate_select_speed(hw,
534563d483cdSSepherosa Ziehau 						    IXGBE_LINK_SPEED_10GB_FULL);
534663d483cdSSepherosa Ziehau 			break;
534763d483cdSSepherosa Ziehau 		case ixgbe_media_type_fiber_qsfp:
534863d483cdSSepherosa Ziehau 			/* QSFP module automatically detects MAC link speed */
534963d483cdSSepherosa Ziehau 			break;
535063d483cdSSepherosa Ziehau 		default:
535163d483cdSSepherosa Ziehau 			DEBUGOUT("Unexpected media type.\n");
535263d483cdSSepherosa Ziehau 			break;
535363d483cdSSepherosa Ziehau 		}
535463d483cdSSepherosa Ziehau 
535563d483cdSSepherosa Ziehau 		/* Allow module to change analog characteristics (1G->10G) */
535663d483cdSSepherosa Ziehau 		msec_delay(40);
535763d483cdSSepherosa Ziehau 
535863d483cdSSepherosa Ziehau 		status = ixgbe_setup_mac_link(hw,
535963d483cdSSepherosa Ziehau 					      IXGBE_LINK_SPEED_10GB_FULL,
536063d483cdSSepherosa Ziehau 					      autoneg_wait_to_complete);
536163d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
536263d483cdSSepherosa Ziehau 			return status;
536363d483cdSSepherosa Ziehau 
536463d483cdSSepherosa Ziehau 		/* Flap the Tx laser if it has not already been done */
536563d483cdSSepherosa Ziehau 		ixgbe_flap_tx_laser(hw);
536663d483cdSSepherosa Ziehau 
536763d483cdSSepherosa Ziehau 		/* Wait for the controller to acquire link.  Per IEEE 802.3ap,
536863d483cdSSepherosa Ziehau 		 * Section 73.10.2, we may have to wait up to 500ms if KR is
536963d483cdSSepherosa Ziehau 		 * attempted.  82599 uses the same timing for 10g SFI.
537063d483cdSSepherosa Ziehau 		 */
537163d483cdSSepherosa Ziehau 		for (i = 0; i < 5; i++) {
537263d483cdSSepherosa Ziehau 			/* Wait for the link partner to also set speed */
537363d483cdSSepherosa Ziehau 			msec_delay(100);
537463d483cdSSepherosa Ziehau 
537563d483cdSSepherosa Ziehau 			/* If we have link, just jump out */
537663d483cdSSepherosa Ziehau 			status = ixgbe_check_link(hw, &link_speed,
537763d483cdSSepherosa Ziehau 						  &link_up, FALSE);
537863d483cdSSepherosa Ziehau 			if (status != IXGBE_SUCCESS)
537963d483cdSSepherosa Ziehau 				return status;
538063d483cdSSepherosa Ziehau 
538163d483cdSSepherosa Ziehau 			if (link_up)
538263d483cdSSepherosa Ziehau 				goto out;
538363d483cdSSepherosa Ziehau 		}
538463d483cdSSepherosa Ziehau 	}
538563d483cdSSepherosa Ziehau 
538663d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
538763d483cdSSepherosa Ziehau 		speedcnt++;
538863d483cdSSepherosa Ziehau 		if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
538963d483cdSSepherosa Ziehau 			highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
539063d483cdSSepherosa Ziehau 
539163d483cdSSepherosa Ziehau 		/* Set the module link speed */
539263d483cdSSepherosa Ziehau 		switch (hw->phy.media_type) {
539363d483cdSSepherosa Ziehau 		case ixgbe_media_type_fiber_fixed:
539463d483cdSSepherosa Ziehau 		case ixgbe_media_type_fiber:
539563d483cdSSepherosa Ziehau 			ixgbe_set_rate_select_speed(hw,
539663d483cdSSepherosa Ziehau 						    IXGBE_LINK_SPEED_1GB_FULL);
539763d483cdSSepherosa Ziehau 			break;
539863d483cdSSepherosa Ziehau 		case ixgbe_media_type_fiber_qsfp:
539963d483cdSSepherosa Ziehau 			/* QSFP module automatically detects link speed */
540063d483cdSSepherosa Ziehau 			break;
540163d483cdSSepherosa Ziehau 		default:
540263d483cdSSepherosa Ziehau 			DEBUGOUT("Unexpected media type.\n");
540363d483cdSSepherosa Ziehau 			break;
540463d483cdSSepherosa Ziehau 		}
540563d483cdSSepherosa Ziehau 
540663d483cdSSepherosa Ziehau 		/* Allow module to change analog characteristics (10G->1G) */
540763d483cdSSepherosa Ziehau 		msec_delay(40);
540863d483cdSSepherosa Ziehau 
540963d483cdSSepherosa Ziehau 		status = ixgbe_setup_mac_link(hw,
541063d483cdSSepherosa Ziehau 					      IXGBE_LINK_SPEED_1GB_FULL,
541163d483cdSSepherosa Ziehau 					      autoneg_wait_to_complete);
541263d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
541363d483cdSSepherosa Ziehau 			return status;
541463d483cdSSepherosa Ziehau 
541563d483cdSSepherosa Ziehau 		/* Flap the Tx laser if it has not already been done */
541663d483cdSSepherosa Ziehau 		ixgbe_flap_tx_laser(hw);
541763d483cdSSepherosa Ziehau 
541863d483cdSSepherosa Ziehau 		/* Wait for the link partner to also set speed */
541963d483cdSSepherosa Ziehau 		msec_delay(100);
542063d483cdSSepherosa Ziehau 
542163d483cdSSepherosa Ziehau 		/* If we have link, just jump out */
542263d483cdSSepherosa Ziehau 		status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE);
542363d483cdSSepherosa Ziehau 		if (status != IXGBE_SUCCESS)
542463d483cdSSepherosa Ziehau 			return status;
542563d483cdSSepherosa Ziehau 
542663d483cdSSepherosa Ziehau 		if (link_up)
542763d483cdSSepherosa Ziehau 			goto out;
542863d483cdSSepherosa Ziehau 	}
542963d483cdSSepherosa Ziehau 
543063d483cdSSepherosa Ziehau 	/* We didn't get link.  Configure back to the highest speed we tried,
543163d483cdSSepherosa Ziehau 	 * (if there was more than one).  We call ourselves back with just the
543263d483cdSSepherosa Ziehau 	 * single highest speed that the user requested.
543363d483cdSSepherosa Ziehau 	 */
543463d483cdSSepherosa Ziehau 	if (speedcnt > 1)
543563d483cdSSepherosa Ziehau 		status = ixgbe_setup_mac_link_multispeed_fiber(hw,
543663d483cdSSepherosa Ziehau 						      highest_link_speed,
543763d483cdSSepherosa Ziehau 						      autoneg_wait_to_complete);
543863d483cdSSepherosa Ziehau 
543963d483cdSSepherosa Ziehau out:
544063d483cdSSepherosa Ziehau 	/* Set autoneg_advertised value based on input link speed */
544163d483cdSSepherosa Ziehau 	hw->phy.autoneg_advertised = 0;
544263d483cdSSepherosa Ziehau 
544363d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
544463d483cdSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
544563d483cdSSepherosa Ziehau 
544663d483cdSSepherosa Ziehau 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
544763d483cdSSepherosa Ziehau 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
544863d483cdSSepherosa Ziehau 
544963d483cdSSepherosa Ziehau 	return status;
545063d483cdSSepherosa Ziehau }
545163d483cdSSepherosa Ziehau 
545263d483cdSSepherosa Ziehau /**
545363d483cdSSepherosa Ziehau  *  ixgbe_set_soft_rate_select_speed - Set module link speed
545463d483cdSSepherosa Ziehau  *  @hw: pointer to hardware structure
545563d483cdSSepherosa Ziehau  *  @speed: link speed to set
545663d483cdSSepherosa Ziehau  *
545763d483cdSSepherosa Ziehau  *  Set module link speed via the soft rate select.
545863d483cdSSepherosa Ziehau  */
ixgbe_set_soft_rate_select_speed(struct ixgbe_hw * hw,ixgbe_link_speed speed)545963d483cdSSepherosa Ziehau void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
546063d483cdSSepherosa Ziehau 					ixgbe_link_speed speed)
546163d483cdSSepherosa Ziehau {
546263d483cdSSepherosa Ziehau 	s32 status;
546363d483cdSSepherosa Ziehau 	u8 rs, eeprom_data;
546463d483cdSSepherosa Ziehau 
546563d483cdSSepherosa Ziehau 	switch (speed) {
546663d483cdSSepherosa Ziehau 	case IXGBE_LINK_SPEED_10GB_FULL:
546763d483cdSSepherosa Ziehau 		/* one bit mask same as setting on */
546863d483cdSSepherosa Ziehau 		rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
546963d483cdSSepherosa Ziehau 		break;
547063d483cdSSepherosa Ziehau 	case IXGBE_LINK_SPEED_1GB_FULL:
547163d483cdSSepherosa Ziehau 		rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
547263d483cdSSepherosa Ziehau 		break;
547363d483cdSSepherosa Ziehau 	default:
547463d483cdSSepherosa Ziehau 		DEBUGOUT("Invalid fixed module speed\n");
547563d483cdSSepherosa Ziehau 		return;
547663d483cdSSepherosa Ziehau 	}
547763d483cdSSepherosa Ziehau 
547863d483cdSSepherosa Ziehau 	/* Set RS0 */
547963d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
548063d483cdSSepherosa Ziehau 					   IXGBE_I2C_EEPROM_DEV_ADDR2,
548163d483cdSSepherosa Ziehau 					   &eeprom_data);
548263d483cdSSepherosa Ziehau 	if (status) {
548363d483cdSSepherosa Ziehau 		DEBUGOUT("Failed to read Rx Rate Select RS0\n");
548463d483cdSSepherosa Ziehau 		goto out;
548563d483cdSSepherosa Ziehau 	}
548663d483cdSSepherosa Ziehau 
548763d483cdSSepherosa Ziehau 	eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs;
548863d483cdSSepherosa Ziehau 
548963d483cdSSepherosa Ziehau 	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
549063d483cdSSepherosa Ziehau 					    IXGBE_I2C_EEPROM_DEV_ADDR2,
549163d483cdSSepherosa Ziehau 					    eeprom_data);
549263d483cdSSepherosa Ziehau 	if (status) {
549363d483cdSSepherosa Ziehau 		DEBUGOUT("Failed to write Rx Rate Select RS0\n");
549463d483cdSSepherosa Ziehau 		goto out;
549563d483cdSSepherosa Ziehau 	}
549663d483cdSSepherosa Ziehau 
549763d483cdSSepherosa Ziehau 	/* Set RS1 */
549863d483cdSSepherosa Ziehau 	status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
549963d483cdSSepherosa Ziehau 					   IXGBE_I2C_EEPROM_DEV_ADDR2,
550063d483cdSSepherosa Ziehau 					   &eeprom_data);
550163d483cdSSepherosa Ziehau 	if (status) {
550263d483cdSSepherosa Ziehau 		DEBUGOUT("Failed to read Rx Rate Select RS1\n");
550363d483cdSSepherosa Ziehau 		goto out;
550463d483cdSSepherosa Ziehau 	}
550563d483cdSSepherosa Ziehau 
550663d483cdSSepherosa Ziehau 	eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs;
550763d483cdSSepherosa Ziehau 
550863d483cdSSepherosa Ziehau 	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
550963d483cdSSepherosa Ziehau 					    IXGBE_I2C_EEPROM_DEV_ADDR2,
551063d483cdSSepherosa Ziehau 					    eeprom_data);
551163d483cdSSepherosa Ziehau 	if (status) {
551263d483cdSSepherosa Ziehau 		DEBUGOUT("Failed to write Rx Rate Select RS1\n");
551363d483cdSSepherosa Ziehau 		goto out;
551463d483cdSSepherosa Ziehau 	}
551563d483cdSSepherosa Ziehau out:
551663d483cdSSepherosa Ziehau 	return;
551763d483cdSSepherosa Ziehau }
5518