xref: /illumos-gate/usr/src/uts/common/io/ixgbe/core/ixgbe_common.c (revision 48ed61a721b0db9229d5bad4d87f5b019867fbf1)
15fc77b81SRobert Mustacchi /******************************************************************************
2*48ed61a7SRobert Mustacchi   SPDX-License-Identifier: BSD-3-Clause
35fc77b81SRobert Mustacchi 
4*48ed61a7SRobert Mustacchi   Copyright (c) 2001-2017, Intel Corporation
55fc77b81SRobert Mustacchi   All rights reserved.
65fc77b81SRobert Mustacchi 
75fc77b81SRobert Mustacchi   Redistribution and use in source and binary forms, with or without
85fc77b81SRobert Mustacchi   modification, are permitted provided that the following conditions are met:
95fc77b81SRobert Mustacchi 
105fc77b81SRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
115fc77b81SRobert Mustacchi       this list of conditions and the following disclaimer.
125fc77b81SRobert Mustacchi 
135fc77b81SRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
145fc77b81SRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
155fc77b81SRobert Mustacchi       documentation and/or other materials provided with the distribution.
165fc77b81SRobert Mustacchi 
175fc77b81SRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
185fc77b81SRobert Mustacchi       contributors may be used to endorse or promote products derived from
195fc77b81SRobert Mustacchi       this software without specific prior written permission.
205fc77b81SRobert Mustacchi 
215fc77b81SRobert Mustacchi   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
225fc77b81SRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
235fc77b81SRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
245fc77b81SRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
255fc77b81SRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
265fc77b81SRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
275fc77b81SRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
285fc77b81SRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
295fc77b81SRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
305fc77b81SRobert Mustacchi   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
315fc77b81SRobert Mustacchi   POSSIBILITY OF SUCH DAMAGE.
325fc77b81SRobert Mustacchi 
335fc77b81SRobert Mustacchi ******************************************************************************/
34dc0cb1cdSDale Ghent /*$FreeBSD$*/
355fc77b81SRobert Mustacchi 
365fc77b81SRobert Mustacchi #include "ixgbe_common.h"
375fc77b81SRobert Mustacchi #include "ixgbe_phy.h"
38dc0cb1cdSDale Ghent #include "ixgbe_dcb.h"
39dc0cb1cdSDale Ghent #include "ixgbe_dcb_82599.h"
405fc77b81SRobert Mustacchi #include "ixgbe_api.h"
415fc77b81SRobert Mustacchi 
425fc77b81SRobert Mustacchi static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
435fc77b81SRobert Mustacchi static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
445fc77b81SRobert Mustacchi static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
455fc77b81SRobert Mustacchi static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
465fc77b81SRobert Mustacchi static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
475fc77b81SRobert Mustacchi static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
485fc77b81SRobert Mustacchi 					u16 count);
495fc77b81SRobert Mustacchi static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
505fc77b81SRobert Mustacchi static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
515fc77b81SRobert Mustacchi static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
525fc77b81SRobert Mustacchi static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
535fc77b81SRobert Mustacchi 
545fc77b81SRobert Mustacchi static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
555fc77b81SRobert Mustacchi static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
565fc77b81SRobert Mustacchi 					 u16 *san_mac_offset);
575fc77b81SRobert Mustacchi static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
585fc77b81SRobert Mustacchi 					     u16 words, u16 *data);
595fc77b81SRobert Mustacchi static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
605fc77b81SRobert Mustacchi 					      u16 words, u16 *data);
615fc77b81SRobert Mustacchi static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
625fc77b81SRobert Mustacchi 						 u16 offset);
635fc77b81SRobert Mustacchi 
645fc77b81SRobert Mustacchi /**
655fc77b81SRobert Mustacchi  *  ixgbe_init_ops_generic - Inits function ptrs
665fc77b81SRobert Mustacchi  *  @hw: pointer to the hardware structure
675fc77b81SRobert Mustacchi  *
685fc77b81SRobert Mustacchi  *  Initialize the function pointers.
695fc77b81SRobert Mustacchi  **/
ixgbe_init_ops_generic(struct ixgbe_hw * hw)705fc77b81SRobert Mustacchi s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
715fc77b81SRobert Mustacchi {
725fc77b81SRobert Mustacchi 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
735fc77b81SRobert Mustacchi 	struct ixgbe_mac_info *mac = &hw->mac;
74dc0cb1cdSDale Ghent 	u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
755fc77b81SRobert Mustacchi 
765fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_init_ops_generic");
775fc77b81SRobert Mustacchi 
785fc77b81SRobert Mustacchi 	/* EEPROM */
79dc0cb1cdSDale Ghent 	eeprom->ops.init_params = ixgbe_init_eeprom_params_generic;
805fc77b81SRobert Mustacchi 	/* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */
815fc77b81SRobert Mustacchi 	if (eec & IXGBE_EEC_PRES) {
82dc0cb1cdSDale Ghent 		eeprom->ops.read = ixgbe_read_eerd_generic;
83dc0cb1cdSDale Ghent 		eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_generic;
845fc77b81SRobert Mustacchi 	} else {
85dc0cb1cdSDale Ghent 		eeprom->ops.read = ixgbe_read_eeprom_bit_bang_generic;
865fc77b81SRobert Mustacchi 		eeprom->ops.read_buffer =
87dc0cb1cdSDale Ghent 				 ixgbe_read_eeprom_buffer_bit_bang_generic;
885fc77b81SRobert Mustacchi 	}
89dc0cb1cdSDale Ghent 	eeprom->ops.write = ixgbe_write_eeprom_generic;
90dc0cb1cdSDale Ghent 	eeprom->ops.write_buffer = ixgbe_write_eeprom_buffer_bit_bang_generic;
915fc77b81SRobert Mustacchi 	eeprom->ops.validate_checksum =
92dc0cb1cdSDale Ghent 				      ixgbe_validate_eeprom_checksum_generic;
93dc0cb1cdSDale Ghent 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_generic;
94dc0cb1cdSDale Ghent 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_generic;
955fc77b81SRobert Mustacchi 
965fc77b81SRobert Mustacchi 	/* MAC */
97dc0cb1cdSDale Ghent 	mac->ops.init_hw = ixgbe_init_hw_generic;
985fc77b81SRobert Mustacchi 	mac->ops.reset_hw = NULL;
99dc0cb1cdSDale Ghent 	mac->ops.start_hw = ixgbe_start_hw_generic;
100dc0cb1cdSDale Ghent 	mac->ops.clear_hw_cntrs = ixgbe_clear_hw_cntrs_generic;
1015fc77b81SRobert Mustacchi 	mac->ops.get_media_type = NULL;
1025fc77b81SRobert Mustacchi 	mac->ops.get_supported_physical_layer = NULL;
103dc0cb1cdSDale Ghent 	mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_generic;
104dc0cb1cdSDale Ghent 	mac->ops.get_mac_addr = ixgbe_get_mac_addr_generic;
105dc0cb1cdSDale Ghent 	mac->ops.stop_adapter = ixgbe_stop_adapter_generic;
106dc0cb1cdSDale Ghent 	mac->ops.get_bus_info = ixgbe_get_bus_info_generic;
107dc0cb1cdSDale Ghent 	mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie;
108dc0cb1cdSDale Ghent 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync;
109dc0cb1cdSDale Ghent 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync;
110dc0cb1cdSDale Ghent 	mac->ops.prot_autoc_read = prot_autoc_read_generic;
111dc0cb1cdSDale Ghent 	mac->ops.prot_autoc_write = prot_autoc_write_generic;
1125fc77b81SRobert Mustacchi 
1135fc77b81SRobert Mustacchi 	/* LEDs */
114dc0cb1cdSDale Ghent 	mac->ops.led_on = ixgbe_led_on_generic;
115dc0cb1cdSDale Ghent 	mac->ops.led_off = ixgbe_led_off_generic;
116dc0cb1cdSDale Ghent 	mac->ops.blink_led_start = ixgbe_blink_led_start_generic;
117dc0cb1cdSDale Ghent 	mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic;
118*48ed61a7SRobert Mustacchi 	mac->ops.init_led_link_act = ixgbe_init_led_link_act_generic;
1195fc77b81SRobert Mustacchi 
1205fc77b81SRobert Mustacchi 	/* RAR, Multicast, VLAN */
121dc0cb1cdSDale Ghent 	mac->ops.set_rar = ixgbe_set_rar_generic;
122dc0cb1cdSDale Ghent 	mac->ops.clear_rar = ixgbe_clear_rar_generic;
1235fc77b81SRobert Mustacchi 	mac->ops.insert_mac_addr = NULL;
1245fc77b81SRobert Mustacchi 	mac->ops.set_vmdq = NULL;
1255fc77b81SRobert Mustacchi 	mac->ops.clear_vmdq = NULL;
126dc0cb1cdSDale Ghent 	mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic;
127dc0cb1cdSDale Ghent 	mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic;
128dc0cb1cdSDale Ghent 	mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic;
129dc0cb1cdSDale Ghent 	mac->ops.enable_mc = ixgbe_enable_mc_generic;
130dc0cb1cdSDale Ghent 	mac->ops.disable_mc = ixgbe_disable_mc_generic;
1315fc77b81SRobert Mustacchi 	mac->ops.clear_vfta = NULL;
1325fc77b81SRobert Mustacchi 	mac->ops.set_vfta = NULL;
1335fc77b81SRobert Mustacchi 	mac->ops.set_vlvf = NULL;
1345fc77b81SRobert Mustacchi 	mac->ops.init_uta_tables = NULL;
135dc0cb1cdSDale Ghent 	mac->ops.enable_rx = ixgbe_enable_rx_generic;
136dc0cb1cdSDale Ghent 	mac->ops.disable_rx = ixgbe_disable_rx_generic;
1375fc77b81SRobert Mustacchi 
1385fc77b81SRobert Mustacchi 	/* Flow Control */
139dc0cb1cdSDale Ghent 	mac->ops.fc_enable = ixgbe_fc_enable_generic;
140dc0cb1cdSDale Ghent 	mac->ops.setup_fc = ixgbe_setup_fc_generic;
141*48ed61a7SRobert Mustacchi 	mac->ops.fc_autoneg = ixgbe_fc_autoneg;
1425fc77b81SRobert Mustacchi 
1435fc77b81SRobert Mustacchi 	/* Link */
1445fc77b81SRobert Mustacchi 	mac->ops.get_link_capabilities = NULL;
1455fc77b81SRobert Mustacchi 	mac->ops.setup_link = NULL;
1465fc77b81SRobert Mustacchi 	mac->ops.check_link = NULL;
147dc0cb1cdSDale Ghent 	mac->ops.dmac_config = NULL;
148dc0cb1cdSDale Ghent 	mac->ops.dmac_update_tcs = NULL;
149dc0cb1cdSDale Ghent 	mac->ops.dmac_config_tcs = NULL;
1505fc77b81SRobert Mustacchi 
1515fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
1525fc77b81SRobert Mustacchi }
1535fc77b81SRobert Mustacchi 
1545fc77b81SRobert Mustacchi /**
155dc0cb1cdSDale Ghent  * ixgbe_device_supports_autoneg_fc - Check if device supports autonegotiation
156dc0cb1cdSDale Ghent  * of flow control
1575fc77b81SRobert Mustacchi  * @hw: pointer to hardware structure
1585fc77b81SRobert Mustacchi  *
159dc0cb1cdSDale Ghent  * This function returns TRUE if the device supports flow control
160dc0cb1cdSDale Ghent  * autonegotiation, and FALSE if it does not.
161dc0cb1cdSDale Ghent  *
1625fc77b81SRobert Mustacchi  **/
ixgbe_device_supports_autoneg_fc(struct ixgbe_hw * hw)163dc0cb1cdSDale Ghent bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
1645fc77b81SRobert Mustacchi {
165dc0cb1cdSDale Ghent 	bool supported = FALSE;
166dc0cb1cdSDale Ghent 	ixgbe_link_speed speed;
167dc0cb1cdSDale Ghent 	bool link_up;
1685fc77b81SRobert Mustacchi 
1695fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
1705fc77b81SRobert Mustacchi 
171dc0cb1cdSDale Ghent 	switch (hw->phy.media_type) {
172dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber_fixed:
173dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber_qsfp:
174dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber:
175*48ed61a7SRobert Mustacchi 		/* flow control autoneg black list */
176*48ed61a7SRobert Mustacchi 		switch (hw->device_id) {
177*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_SFP:
178*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_SFP_N:
179*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_QSFP:
180*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_QSFP_N:
181*48ed61a7SRobert Mustacchi 			supported = FALSE;
182*48ed61a7SRobert Mustacchi 			break;
183*48ed61a7SRobert Mustacchi 		default:
184dc0cb1cdSDale Ghent 			hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
185dc0cb1cdSDale Ghent 			/* if link is down, assume supported */
186dc0cb1cdSDale Ghent 			if (link_up)
187dc0cb1cdSDale Ghent 				supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
188dc0cb1cdSDale Ghent 				TRUE : FALSE;
189dc0cb1cdSDale Ghent 			else
190dc0cb1cdSDale Ghent 				supported = TRUE;
191*48ed61a7SRobert Mustacchi 		}
192*48ed61a7SRobert Mustacchi 
193dc0cb1cdSDale Ghent 		break;
194dc0cb1cdSDale Ghent 	case ixgbe_media_type_backplane:
195*48ed61a7SRobert Mustacchi 		if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI)
196*48ed61a7SRobert Mustacchi 			supported = FALSE;
197*48ed61a7SRobert Mustacchi 		else
198dc0cb1cdSDale Ghent 			supported = TRUE;
199dc0cb1cdSDale Ghent 		break;
200dc0cb1cdSDale Ghent 	case ixgbe_media_type_copper:
201dc0cb1cdSDale Ghent 		/* only some copper devices support flow control autoneg */
2025fc77b81SRobert Mustacchi 		switch (hw->device_id) {
203dc0cb1cdSDale Ghent 		case IXGBE_DEV_ID_82599_T3_LOM:
2045fc77b81SRobert Mustacchi 		case IXGBE_DEV_ID_X540T:
2055fc77b81SRobert Mustacchi 		case IXGBE_DEV_ID_X540T1:
206dc0cb1cdSDale Ghent 		case IXGBE_DEV_ID_X540_BYPASS:
207dc0cb1cdSDale Ghent 		case IXGBE_DEV_ID_X550T:
208dc0cb1cdSDale Ghent 		case IXGBE_DEV_ID_X550T1:
209dc0cb1cdSDale Ghent 		case IXGBE_DEV_ID_X550EM_X_10G_T:
210*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_10G_T:
211*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_1G_T:
212*48ed61a7SRobert Mustacchi 		case IXGBE_DEV_ID_X550EM_A_1G_T_L:
213dc0cb1cdSDale Ghent 			supported = TRUE;
214dc0cb1cdSDale Ghent 			break;
2155fc77b81SRobert Mustacchi 		default:
216dc0cb1cdSDale Ghent 			supported = FALSE;
2175fc77b81SRobert Mustacchi 		}
218dc0cb1cdSDale Ghent 	default:
219dc0cb1cdSDale Ghent 		break;
220dc0cb1cdSDale Ghent 	}
221dc0cb1cdSDale Ghent 
222*48ed61a7SRobert Mustacchi 	if (!supported)
223dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
224dc0cb1cdSDale Ghent 			      "Device %x does not support flow control autoneg",
225dc0cb1cdSDale Ghent 			      hw->device_id);
226dc0cb1cdSDale Ghent 
227dc0cb1cdSDale Ghent 	return supported;
2285fc77b81SRobert Mustacchi }
2295fc77b81SRobert Mustacchi 
2305fc77b81SRobert Mustacchi /**
231dc0cb1cdSDale Ghent  *  ixgbe_setup_fc_generic - Set up flow control
2325fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
2335fc77b81SRobert Mustacchi  *
2345fc77b81SRobert Mustacchi  *  Called at init time to set up flow control.
2355fc77b81SRobert Mustacchi  **/
ixgbe_setup_fc_generic(struct ixgbe_hw * hw)236dc0cb1cdSDale Ghent s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
2375fc77b81SRobert Mustacchi {
2385fc77b81SRobert Mustacchi 	s32 ret_val = IXGBE_SUCCESS;
2395fc77b81SRobert Mustacchi 	u32 reg = 0, reg_bp = 0;
2405fc77b81SRobert Mustacchi 	u16 reg_cu = 0;
241dc0cb1cdSDale Ghent 	bool locked = FALSE;
2425fc77b81SRobert Mustacchi 
243dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_setup_fc_generic");
2445fc77b81SRobert Mustacchi 
245dc0cb1cdSDale Ghent 	/* Validate the requested mode */
2465fc77b81SRobert Mustacchi 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
247dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
248dc0cb1cdSDale Ghent 			   "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
2495fc77b81SRobert Mustacchi 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
2505fc77b81SRobert Mustacchi 		goto out;
2515fc77b81SRobert Mustacchi 	}
2525fc77b81SRobert Mustacchi 
2535fc77b81SRobert Mustacchi 	/*
2545fc77b81SRobert Mustacchi 	 * 10gig parts do not have a word in the EEPROM to determine the
2555fc77b81SRobert Mustacchi 	 * default flow control setting, so we explicitly set it to full.
2565fc77b81SRobert Mustacchi 	 */
2575fc77b81SRobert Mustacchi 	if (hw->fc.requested_mode == ixgbe_fc_default)
2585fc77b81SRobert Mustacchi 		hw->fc.requested_mode = ixgbe_fc_full;
2595fc77b81SRobert Mustacchi 
2605fc77b81SRobert Mustacchi 	/*
2615fc77b81SRobert Mustacchi 	 * Set up the 1G and 10G flow control advertisement registers so the
2625fc77b81SRobert Mustacchi 	 * HW will be able to do fc autoneg once the cable is plugged in.  If
2635fc77b81SRobert Mustacchi 	 * we link at 10G, the 1G advertisement is harmless and vice versa.
2645fc77b81SRobert Mustacchi 	 */
2655fc77b81SRobert Mustacchi 	switch (hw->phy.media_type) {
2665fc77b81SRobert Mustacchi 	case ixgbe_media_type_backplane:
267dc0cb1cdSDale Ghent 		/* some MAC's need RMW protection on AUTOC */
268dc0cb1cdSDale Ghent 		ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &reg_bp);
269dc0cb1cdSDale Ghent 		if (ret_val != IXGBE_SUCCESS)
270dc0cb1cdSDale Ghent 			goto out;
271dc0cb1cdSDale Ghent 
272e5c421abSToomas Soome 		/* only backplane uses autoc */
273e5c421abSToomas Soome 		/* FALLTHROUGH */
274dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber_fixed:
275dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber_qsfp:
276dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber:
2775fc77b81SRobert Mustacchi 		reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
278dc0cb1cdSDale Ghent 
2795fc77b81SRobert Mustacchi 		break;
2805fc77b81SRobert Mustacchi 	case ixgbe_media_type_copper:
2815fc77b81SRobert Mustacchi 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
2825fc77b81SRobert Mustacchi 				     IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg_cu);
2835fc77b81SRobert Mustacchi 		break;
2845fc77b81SRobert Mustacchi 	default:
2855fc77b81SRobert Mustacchi 		break;
2865fc77b81SRobert Mustacchi 	}
2875fc77b81SRobert Mustacchi 
2885fc77b81SRobert Mustacchi 	/*
2895fc77b81SRobert Mustacchi 	 * The possible values of fc.requested_mode are:
2905fc77b81SRobert Mustacchi 	 * 0: Flow control is completely disabled
2915fc77b81SRobert Mustacchi 	 * 1: Rx flow control is enabled (we can receive pause frames,
2925fc77b81SRobert Mustacchi 	 *    but not send pause frames).
2935fc77b81SRobert Mustacchi 	 * 2: Tx flow control is enabled (we can send pause frames but
2945fc77b81SRobert Mustacchi 	 *    we do not support receiving pause frames).
2955fc77b81SRobert Mustacchi 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
2965fc77b81SRobert Mustacchi 	 * other: Invalid.
2975fc77b81SRobert Mustacchi 	 */
2985fc77b81SRobert Mustacchi 	switch (hw->fc.requested_mode) {
2995fc77b81SRobert Mustacchi 	case ixgbe_fc_none:
3005fc77b81SRobert Mustacchi 		/* Flow control completely disabled by software override. */
3015fc77b81SRobert Mustacchi 		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
3025fc77b81SRobert Mustacchi 		if (hw->phy.media_type == ixgbe_media_type_backplane)
3035fc77b81SRobert Mustacchi 			reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
3045fc77b81SRobert Mustacchi 				    IXGBE_AUTOC_ASM_PAUSE);
3055fc77b81SRobert Mustacchi 		else if (hw->phy.media_type == ixgbe_media_type_copper)
3065fc77b81SRobert Mustacchi 			reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
3075fc77b81SRobert Mustacchi 		break;
3085fc77b81SRobert Mustacchi 	case ixgbe_fc_tx_pause:
3095fc77b81SRobert Mustacchi 		/*
3105fc77b81SRobert Mustacchi 		 * Tx Flow control is enabled, and Rx Flow control is
3115fc77b81SRobert Mustacchi 		 * disabled by software override.
3125fc77b81SRobert Mustacchi 		 */
3135fc77b81SRobert Mustacchi 		reg |= IXGBE_PCS1GANA_ASM_PAUSE;
3145fc77b81SRobert Mustacchi 		reg &= ~IXGBE_PCS1GANA_SYM_PAUSE;
3155fc77b81SRobert Mustacchi 		if (hw->phy.media_type == ixgbe_media_type_backplane) {
3165fc77b81SRobert Mustacchi 			reg_bp |= IXGBE_AUTOC_ASM_PAUSE;
3175fc77b81SRobert Mustacchi 			reg_bp &= ~IXGBE_AUTOC_SYM_PAUSE;
3185fc77b81SRobert Mustacchi 		} else if (hw->phy.media_type == ixgbe_media_type_copper) {
3195fc77b81SRobert Mustacchi 			reg_cu |= IXGBE_TAF_ASM_PAUSE;
3205fc77b81SRobert Mustacchi 			reg_cu &= ~IXGBE_TAF_SYM_PAUSE;
3215fc77b81SRobert Mustacchi 		}
3225fc77b81SRobert Mustacchi 		break;
3235fc77b81SRobert Mustacchi 	case ixgbe_fc_rx_pause:
3245fc77b81SRobert Mustacchi 		/*
3255fc77b81SRobert Mustacchi 		 * Rx Flow control is enabled and Tx Flow control is
3265fc77b81SRobert Mustacchi 		 * disabled by software override. Since there really
3275fc77b81SRobert Mustacchi 		 * isn't a way to advertise that we are capable of RX
3285fc77b81SRobert Mustacchi 		 * Pause ONLY, we will advertise that we support both
3295fc77b81SRobert Mustacchi 		 * symmetric and asymmetric Rx PAUSE, as such we fall
3305fc77b81SRobert Mustacchi 		 * through to the fc_full statement.  Later, we will
3315fc77b81SRobert Mustacchi 		 * disable the adapter's ability to send PAUSE frames.
3325fc77b81SRobert Mustacchi 		 */
3335fc77b81SRobert Mustacchi 	case ixgbe_fc_full:
3345fc77b81SRobert Mustacchi 		/* Flow control (both Rx and Tx) is enabled by SW override. */
3355fc77b81SRobert Mustacchi 		reg |= IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE;
3365fc77b81SRobert Mustacchi 		if (hw->phy.media_type == ixgbe_media_type_backplane)
3375fc77b81SRobert Mustacchi 			reg_bp |= IXGBE_AUTOC_SYM_PAUSE |
3385fc77b81SRobert Mustacchi 				  IXGBE_AUTOC_ASM_PAUSE;
3395fc77b81SRobert Mustacchi 		else if (hw->phy.media_type == ixgbe_media_type_copper)
3405fc77b81SRobert Mustacchi 			reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE;
3415fc77b81SRobert Mustacchi 		break;
3425fc77b81SRobert Mustacchi 	default:
343dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
344dc0cb1cdSDale Ghent 			     "Flow control param set incorrectly\n");
3455fc77b81SRobert Mustacchi 		ret_val = IXGBE_ERR_CONFIG;
3465fc77b81SRobert Mustacchi 		goto out;
347dc0cb1cdSDale Ghent 		break;
3485fc77b81SRobert Mustacchi 	}
3495fc77b81SRobert Mustacchi 
350dc0cb1cdSDale Ghent 	if (hw->mac.type < ixgbe_mac_X540) {
3515fc77b81SRobert Mustacchi 		/*
3525fc77b81SRobert Mustacchi 		 * Enable auto-negotiation between the MAC & PHY;
3535fc77b81SRobert Mustacchi 		 * the MAC will advertise clause 37 flow control.
3545fc77b81SRobert Mustacchi 		 */
3555fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
3565fc77b81SRobert Mustacchi 		reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
3575fc77b81SRobert Mustacchi 
3585fc77b81SRobert Mustacchi 		/* Disable AN timeout */
3595fc77b81SRobert Mustacchi 		if (hw->fc.strict_ieee)
3605fc77b81SRobert Mustacchi 			reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
3615fc77b81SRobert Mustacchi 
3625fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
3635fc77b81SRobert Mustacchi 		DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
3645fc77b81SRobert Mustacchi 	}
3655fc77b81SRobert Mustacchi 
3665fc77b81SRobert Mustacchi 	/*
3675fc77b81SRobert Mustacchi 	 * AUTOC restart handles negotiation of 1G and 10G on backplane
3685fc77b81SRobert Mustacchi 	 * and copper. There is no need to set the PCS1GCTL register.
3695fc77b81SRobert Mustacchi 	 *
3705fc77b81SRobert Mustacchi 	 */
3715fc77b81SRobert Mustacchi 	if (hw->phy.media_type == ixgbe_media_type_backplane) {
3725fc77b81SRobert Mustacchi 		reg_bp |= IXGBE_AUTOC_AN_RESTART;
373dc0cb1cdSDale Ghent 		ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
374dc0cb1cdSDale Ghent 		if (ret_val)
375dc0cb1cdSDale Ghent 			goto out;
3765fc77b81SRobert Mustacchi 	} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
377dc0cb1cdSDale Ghent 		    (ixgbe_device_supports_autoneg_fc(hw))) {
3785fc77b81SRobert Mustacchi 		hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
3795fc77b81SRobert Mustacchi 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu);
3805fc77b81SRobert Mustacchi 	}
3815fc77b81SRobert Mustacchi 
382dc0cb1cdSDale Ghent 	DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
3835fc77b81SRobert Mustacchi out:
3845fc77b81SRobert Mustacchi 	return ret_val;
3855fc77b81SRobert Mustacchi }
3865fc77b81SRobert Mustacchi 
3875fc77b81SRobert Mustacchi /**
3885fc77b81SRobert Mustacchi  *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
3895fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
3905fc77b81SRobert Mustacchi  *
3915fc77b81SRobert Mustacchi  *  Starts the hardware by filling the bus info structure and media type, clears
3925fc77b81SRobert Mustacchi  *  all on chip counters, initializes receive address registers, multicast
3935fc77b81SRobert Mustacchi  *  table, VLAN filter table, calls routine to set up link and flow control
3945fc77b81SRobert Mustacchi  *  settings, and leaves transmit and receive units disabled and uninitialized
3955fc77b81SRobert Mustacchi  **/
ixgbe_start_hw_generic(struct ixgbe_hw * hw)3965fc77b81SRobert Mustacchi s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
3975fc77b81SRobert Mustacchi {
3985fc77b81SRobert Mustacchi 	s32 ret_val;
3995fc77b81SRobert Mustacchi 	u32 ctrl_ext;
400*48ed61a7SRobert Mustacchi 	u16 device_caps;
4015fc77b81SRobert Mustacchi 
4025fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_start_hw_generic");
4035fc77b81SRobert Mustacchi 
4045fc77b81SRobert Mustacchi 	/* Set the media type */
4055fc77b81SRobert Mustacchi 	hw->phy.media_type = hw->mac.ops.get_media_type(hw);
4065fc77b81SRobert Mustacchi 
4075fc77b81SRobert Mustacchi 	/* PHY ops initialization must be done in reset_hw() */
4085fc77b81SRobert Mustacchi 
4095fc77b81SRobert Mustacchi 	/* Clear the VLAN filter table */
4105fc77b81SRobert Mustacchi 	hw->mac.ops.clear_vfta(hw);
4115fc77b81SRobert Mustacchi 
4125fc77b81SRobert Mustacchi 	/* Clear statistics registers */
4135fc77b81SRobert Mustacchi 	hw->mac.ops.clear_hw_cntrs(hw);
4145fc77b81SRobert Mustacchi 
4155fc77b81SRobert Mustacchi 	/* Set No Snoop Disable */
4165fc77b81SRobert Mustacchi 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
4175fc77b81SRobert Mustacchi 	ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
4185fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
4195fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4205fc77b81SRobert Mustacchi 
4215fc77b81SRobert Mustacchi 	/* Setup flow control */
4225fc77b81SRobert Mustacchi 	ret_val = ixgbe_setup_fc(hw);
423*48ed61a7SRobert Mustacchi 	if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED) {
424*48ed61a7SRobert Mustacchi 		DEBUGOUT1("Flow control setup failed, returning %d\n", ret_val);
425*48ed61a7SRobert Mustacchi 		return ret_val;
426*48ed61a7SRobert Mustacchi 	}
427*48ed61a7SRobert Mustacchi 
428*48ed61a7SRobert Mustacchi 	/* Cache bit indicating need for crosstalk fix */
429*48ed61a7SRobert Mustacchi 	switch (hw->mac.type) {
430*48ed61a7SRobert Mustacchi 	case ixgbe_mac_82599EB:
431*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_x:
432*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
433*48ed61a7SRobert Mustacchi 		hw->mac.ops.get_device_caps(hw, &device_caps);
434*48ed61a7SRobert Mustacchi 		if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR)
435*48ed61a7SRobert Mustacchi 			hw->need_crosstalk_fix = FALSE;
436*48ed61a7SRobert Mustacchi 		else
437*48ed61a7SRobert Mustacchi 			hw->need_crosstalk_fix = TRUE;
438*48ed61a7SRobert Mustacchi 		break;
439*48ed61a7SRobert Mustacchi 	default:
440*48ed61a7SRobert Mustacchi 		hw->need_crosstalk_fix = FALSE;
441*48ed61a7SRobert Mustacchi 		break;
442*48ed61a7SRobert Mustacchi 	}
4435fc77b81SRobert Mustacchi 
4445fc77b81SRobert Mustacchi 	/* Clear adapter stopped flag */
4455fc77b81SRobert Mustacchi 	hw->adapter_stopped = FALSE;
4465fc77b81SRobert Mustacchi 
447*48ed61a7SRobert Mustacchi 	return IXGBE_SUCCESS;
4485fc77b81SRobert Mustacchi }
4495fc77b81SRobert Mustacchi 
4505fc77b81SRobert Mustacchi /**
4515fc77b81SRobert Mustacchi  *  ixgbe_start_hw_gen2 - Init sequence for common device family
4525fc77b81SRobert Mustacchi  *  @hw: pointer to hw structure
4535fc77b81SRobert Mustacchi  *
4545fc77b81SRobert Mustacchi  * Performs the init sequence common to the second generation
4555fc77b81SRobert Mustacchi  * of 10 GbE devices.
4565fc77b81SRobert Mustacchi  * Devices in the second generation:
4575fc77b81SRobert Mustacchi  *     82599
4585fc77b81SRobert Mustacchi  *     X540
4595fc77b81SRobert Mustacchi  **/
ixgbe_start_hw_gen2(struct ixgbe_hw * hw)4605fc77b81SRobert Mustacchi s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
4615fc77b81SRobert Mustacchi {
4625fc77b81SRobert Mustacchi 	u32 i;
4635fc77b81SRobert Mustacchi 	u32 regval;
4645fc77b81SRobert Mustacchi 
4655fc77b81SRobert Mustacchi 	/* Clear the rate limiters */
4665fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_tx_queues; i++) {
4675fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
4685fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
4695fc77b81SRobert Mustacchi 	}
4705fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4715fc77b81SRobert Mustacchi 
4725fc77b81SRobert Mustacchi 	/* Disable relaxed ordering */
4735fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_tx_queues; i++) {
4745fc77b81SRobert Mustacchi 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
4755fc77b81SRobert Mustacchi 		regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
4765fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
4775fc77b81SRobert Mustacchi 	}
4785fc77b81SRobert Mustacchi 
4795fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_rx_queues; i++) {
4805fc77b81SRobert Mustacchi 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
4815fc77b81SRobert Mustacchi 		regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
4825fc77b81SRobert Mustacchi 			    IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
4835fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
4845fc77b81SRobert Mustacchi 	}
4855fc77b81SRobert Mustacchi 
4865fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
4875fc77b81SRobert Mustacchi }
4885fc77b81SRobert Mustacchi 
4895fc77b81SRobert Mustacchi /**
4905fc77b81SRobert Mustacchi  *  ixgbe_init_hw_generic - Generic hardware initialization
4915fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
4925fc77b81SRobert Mustacchi  *
4935fc77b81SRobert Mustacchi  *  Initialize the hardware by resetting the hardware, filling the bus info
4945fc77b81SRobert Mustacchi  *  structure and media type, clears all on chip counters, initializes receive
4955fc77b81SRobert Mustacchi  *  address registers, multicast table, VLAN filter table, calls routine to set
4965fc77b81SRobert Mustacchi  *  up link and flow control settings, and leaves transmit and receive units
4975fc77b81SRobert Mustacchi  *  disabled and uninitialized
4985fc77b81SRobert Mustacchi  **/
ixgbe_init_hw_generic(struct ixgbe_hw * hw)4995fc77b81SRobert Mustacchi s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
5005fc77b81SRobert Mustacchi {
5015fc77b81SRobert Mustacchi 	s32 status;
5025fc77b81SRobert Mustacchi 
5035fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_init_hw_generic");
5045fc77b81SRobert Mustacchi 
5055fc77b81SRobert Mustacchi 	/* Reset the hardware */
5065fc77b81SRobert Mustacchi 	status = hw->mac.ops.reset_hw(hw);
5075fc77b81SRobert Mustacchi 
508*48ed61a7SRobert Mustacchi 	if (status == IXGBE_SUCCESS || status == IXGBE_ERR_SFP_NOT_PRESENT) {
5095fc77b81SRobert Mustacchi 		/* Start the HW */
5105fc77b81SRobert Mustacchi 		status = hw->mac.ops.start_hw(hw);
5115fc77b81SRobert Mustacchi 	}
5125fc77b81SRobert Mustacchi 
513*48ed61a7SRobert Mustacchi 	/* Initialize the LED link active for LED blink support */
514*48ed61a7SRobert Mustacchi 	if (hw->mac.ops.init_led_link_act)
515*48ed61a7SRobert Mustacchi 		hw->mac.ops.init_led_link_act(hw);
516*48ed61a7SRobert Mustacchi 
517*48ed61a7SRobert Mustacchi 	if (status != IXGBE_SUCCESS)
518*48ed61a7SRobert Mustacchi 		DEBUGOUT1("Failed to initialize HW, STATUS = %d\n", status);
519*48ed61a7SRobert Mustacchi 
5205fc77b81SRobert Mustacchi 	return status;
5215fc77b81SRobert Mustacchi }
5225fc77b81SRobert Mustacchi 
5235fc77b81SRobert Mustacchi /**
5245fc77b81SRobert Mustacchi  *  ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
5255fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
5265fc77b81SRobert Mustacchi  *
5275fc77b81SRobert Mustacchi  *  Clears all hardware statistics counters by reading them from the hardware
5285fc77b81SRobert Mustacchi  *  Statistics counters are clear on read.
5295fc77b81SRobert Mustacchi  **/
ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw * hw)5305fc77b81SRobert Mustacchi s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
5315fc77b81SRobert Mustacchi {
5325fc77b81SRobert Mustacchi 	u16 i = 0;
5335fc77b81SRobert Mustacchi 
5345fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_clear_hw_cntrs_generic");
5355fc77b81SRobert Mustacchi 
536dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_CRCERRS);
537dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_ILLERRC);
538dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_ERRBC);
539dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MSPDC);
5405fc77b81SRobert Mustacchi 	for (i = 0; i < 8; i++)
541dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_MPC(i));
5425fc77b81SRobert Mustacchi 
543dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MLFC);
544dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MRFC);
545dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_RLEC);
546dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_LXONTXC);
547dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
5485fc77b81SRobert Mustacchi 	if (hw->mac.type >= ixgbe_mac_82599EB) {
549dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
550dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
5515fc77b81SRobert Mustacchi 	} else {
552dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_LXONRXC);
553dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
5545fc77b81SRobert Mustacchi 	}
5555fc77b81SRobert Mustacchi 
5565fc77b81SRobert Mustacchi 	for (i = 0; i < 8; i++) {
557dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
558dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
5595fc77b81SRobert Mustacchi 		if (hw->mac.type >= ixgbe_mac_82599EB) {
560dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
561dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
5625fc77b81SRobert Mustacchi 		} else {
563dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
564dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
5655fc77b81SRobert Mustacchi 		}
5665fc77b81SRobert Mustacchi 	}
5675fc77b81SRobert Mustacchi 	if (hw->mac.type >= ixgbe_mac_82599EB)
5685fc77b81SRobert Mustacchi 		for (i = 0; i < 8; i++)
569dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
570dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PRC64);
571dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PRC127);
572dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PRC255);
573dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PRC511);
574dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PRC1023);
575dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PRC1522);
576dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_GPRC);
577dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_BPRC);
578dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MPRC);
579dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_GPTC);
580dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_GORCL);
581dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_GORCH);
582dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_GOTCL);
583dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_GOTCH);
5845fc77b81SRobert Mustacchi 	if (hw->mac.type == ixgbe_mac_82598EB)
5855fc77b81SRobert Mustacchi 		for (i = 0; i < 8; i++)
586dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_RNBC(i));
587dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_RUC);
588dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_RFC);
589dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_ROC);
590dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_RJC);
591dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MNGPRC);
592dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MNGPDC);
593dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MNGPTC);
594dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_TORL);
595dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_TORH);
596dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_TPR);
597dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_TPT);
598dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PTC64);
599dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PTC127);
600dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PTC255);
601dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PTC511);
602dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PTC1023);
603dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_PTC1522);
604dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_MPTC);
605dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_BPTC);
6065fc77b81SRobert Mustacchi 	for (i = 0; i < 16; i++) {
607dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_QPRC(i));
608dc0cb1cdSDale Ghent 		IXGBE_READ_REG(hw, IXGBE_QPTC(i));
6095fc77b81SRobert Mustacchi 		if (hw->mac.type >= ixgbe_mac_82599EB) {
610dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QBRC_L(i));
611dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QBRC_H(i));
612dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
613dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QBTC_H(i));
614dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
6155fc77b81SRobert Mustacchi 		} else {
616dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QBRC(i));
617dc0cb1cdSDale Ghent 			IXGBE_READ_REG(hw, IXGBE_QBTC(i));
6185fc77b81SRobert Mustacchi 		}
6195fc77b81SRobert Mustacchi 	}
6205fc77b81SRobert Mustacchi 
621dc0cb1cdSDale Ghent 	if (hw->mac.type == ixgbe_mac_X550 || hw->mac.type == ixgbe_mac_X540) {
6225fc77b81SRobert Mustacchi 		if (hw->phy.id == 0)
623dc0cb1cdSDale Ghent 			ixgbe_identify_phy(hw);
6245fc77b81SRobert Mustacchi 		hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL,
6255fc77b81SRobert Mustacchi 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
6265fc77b81SRobert Mustacchi 		hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH,
6275fc77b81SRobert Mustacchi 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
6285fc77b81SRobert Mustacchi 		hw->phy.ops.read_reg(hw, IXGBE_LDPCECL,
6295fc77b81SRobert Mustacchi 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
6305fc77b81SRobert Mustacchi 		hw->phy.ops.read_reg(hw, IXGBE_LDPCECH,
6315fc77b81SRobert Mustacchi 				     IXGBE_MDIO_PCS_DEV_TYPE, &i);
6325fc77b81SRobert Mustacchi 	}
6335fc77b81SRobert Mustacchi 
6345fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
6355fc77b81SRobert Mustacchi }
6365fc77b81SRobert Mustacchi 
6375fc77b81SRobert Mustacchi /**
6385fc77b81SRobert Mustacchi  *  ixgbe_read_pba_string_generic - Reads part number string from EEPROM
6395fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
6405fc77b81SRobert Mustacchi  *  @pba_num: stores the part number string from the EEPROM
6415fc77b81SRobert Mustacchi  *  @pba_num_size: part number string buffer length
6425fc77b81SRobert Mustacchi  *
6435fc77b81SRobert Mustacchi  *  Reads the part number string from the EEPROM.
6445fc77b81SRobert Mustacchi  **/
ixgbe_read_pba_string_generic(struct ixgbe_hw * hw,u8 * pba_num,u32 pba_num_size)6455fc77b81SRobert Mustacchi s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
6465fc77b81SRobert Mustacchi 				  u32 pba_num_size)
6475fc77b81SRobert Mustacchi {
6485fc77b81SRobert Mustacchi 	s32 ret_val;
6495fc77b81SRobert Mustacchi 	u16 data;
6505fc77b81SRobert Mustacchi 	u16 pba_ptr;
6515fc77b81SRobert Mustacchi 	u16 offset;
6525fc77b81SRobert Mustacchi 	u16 length;
6535fc77b81SRobert Mustacchi 
6545fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_read_pba_string_generic");
6555fc77b81SRobert Mustacchi 
6565fc77b81SRobert Mustacchi 	if (pba_num == NULL) {
6575fc77b81SRobert Mustacchi 		DEBUGOUT("PBA string buffer was null\n");
6585fc77b81SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
6595fc77b81SRobert Mustacchi 	}
6605fc77b81SRobert Mustacchi 
6615fc77b81SRobert Mustacchi 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
6625fc77b81SRobert Mustacchi 	if (ret_val) {
6635fc77b81SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
6645fc77b81SRobert Mustacchi 		return ret_val;
6655fc77b81SRobert Mustacchi 	}
6665fc77b81SRobert Mustacchi 
6675fc77b81SRobert Mustacchi 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr);
6685fc77b81SRobert Mustacchi 	if (ret_val) {
6695fc77b81SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
6705fc77b81SRobert Mustacchi 		return ret_val;
6715fc77b81SRobert Mustacchi 	}
6725fc77b81SRobert Mustacchi 
6735fc77b81SRobert Mustacchi 	/*
6745fc77b81SRobert Mustacchi 	 * if data is not ptr guard the PBA must be in legacy format which
6755fc77b81SRobert Mustacchi 	 * means pba_ptr is actually our second data word for the PBA number
6765fc77b81SRobert Mustacchi 	 * and we can decode it into an ascii string
6775fc77b81SRobert Mustacchi 	 */
6785fc77b81SRobert Mustacchi 	if (data != IXGBE_PBANUM_PTR_GUARD) {
6795fc77b81SRobert Mustacchi 		DEBUGOUT("NVM PBA number is not stored as string\n");
6805fc77b81SRobert Mustacchi 
6815fc77b81SRobert Mustacchi 		/* we will need 11 characters to store the PBA */
6825fc77b81SRobert Mustacchi 		if (pba_num_size < 11) {
6835fc77b81SRobert Mustacchi 			DEBUGOUT("PBA string buffer too small\n");
6845fc77b81SRobert Mustacchi 			return IXGBE_ERR_NO_SPACE;
6855fc77b81SRobert Mustacchi 		}
6865fc77b81SRobert Mustacchi 
6875fc77b81SRobert Mustacchi 		/* extract hex string from data and pba_ptr */
6885fc77b81SRobert Mustacchi 		pba_num[0] = (data >> 12) & 0xF;
6895fc77b81SRobert Mustacchi 		pba_num[1] = (data >> 8) & 0xF;
6905fc77b81SRobert Mustacchi 		pba_num[2] = (data >> 4) & 0xF;
6915fc77b81SRobert Mustacchi 		pba_num[3] = data & 0xF;
6925fc77b81SRobert Mustacchi 		pba_num[4] = (pba_ptr >> 12) & 0xF;
6935fc77b81SRobert Mustacchi 		pba_num[5] = (pba_ptr >> 8) & 0xF;
6945fc77b81SRobert Mustacchi 		pba_num[6] = '-';
6955fc77b81SRobert Mustacchi 		pba_num[7] = 0;
6965fc77b81SRobert Mustacchi 		pba_num[8] = (pba_ptr >> 4) & 0xF;
6975fc77b81SRobert Mustacchi 		pba_num[9] = pba_ptr & 0xF;
6985fc77b81SRobert Mustacchi 
6995fc77b81SRobert Mustacchi 		/* put a null character on the end of our string */
7005fc77b81SRobert Mustacchi 		pba_num[10] = '\0';
7015fc77b81SRobert Mustacchi 
7025fc77b81SRobert Mustacchi 		/* switch all the data but the '-' to hex char */
7035fc77b81SRobert Mustacchi 		for (offset = 0; offset < 10; offset++) {
7045fc77b81SRobert Mustacchi 			if (pba_num[offset] < 0xA)
7055fc77b81SRobert Mustacchi 				pba_num[offset] += '0';
7065fc77b81SRobert Mustacchi 			else if (pba_num[offset] < 0x10)
7075fc77b81SRobert Mustacchi 				pba_num[offset] += 'A' - 0xA;
7085fc77b81SRobert Mustacchi 		}
7095fc77b81SRobert Mustacchi 
7105fc77b81SRobert Mustacchi 		return IXGBE_SUCCESS;
7115fc77b81SRobert Mustacchi 	}
7125fc77b81SRobert Mustacchi 
7135fc77b81SRobert Mustacchi 	ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length);
7145fc77b81SRobert Mustacchi 	if (ret_val) {
7155fc77b81SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
7165fc77b81SRobert Mustacchi 		return ret_val;
7175fc77b81SRobert Mustacchi 	}
7185fc77b81SRobert Mustacchi 
7195fc77b81SRobert Mustacchi 	if (length == 0xFFFF || length == 0) {
7205fc77b81SRobert Mustacchi 		DEBUGOUT("NVM PBA number section invalid length\n");
7215fc77b81SRobert Mustacchi 		return IXGBE_ERR_PBA_SECTION;
7225fc77b81SRobert Mustacchi 	}
7235fc77b81SRobert Mustacchi 
7245fc77b81SRobert Mustacchi 	/* check if pba_num buffer is big enough */
7255fc77b81SRobert Mustacchi 	if (pba_num_size  < (((u32)length * 2) - 1)) {
7265fc77b81SRobert Mustacchi 		DEBUGOUT("PBA string buffer too small\n");
7275fc77b81SRobert Mustacchi 		return IXGBE_ERR_NO_SPACE;
7285fc77b81SRobert Mustacchi 	}
7295fc77b81SRobert Mustacchi 
7305fc77b81SRobert Mustacchi 	/* trim pba length from start of string */
7315fc77b81SRobert Mustacchi 	pba_ptr++;
7325fc77b81SRobert Mustacchi 	length--;
7335fc77b81SRobert Mustacchi 
7345fc77b81SRobert Mustacchi 	for (offset = 0; offset < length; offset++) {
7355fc77b81SRobert Mustacchi 		ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data);
7365fc77b81SRobert Mustacchi 		if (ret_val) {
7375fc77b81SRobert Mustacchi 			DEBUGOUT("NVM Read Error\n");
7385fc77b81SRobert Mustacchi 			return ret_val;
7395fc77b81SRobert Mustacchi 		}
7405fc77b81SRobert Mustacchi 		pba_num[offset * 2] = (u8)(data >> 8);
7415fc77b81SRobert Mustacchi 		pba_num[(offset * 2) + 1] = (u8)(data & 0xFF);
7425fc77b81SRobert Mustacchi 	}
7435fc77b81SRobert Mustacchi 	pba_num[offset * 2] = '\0';
7445fc77b81SRobert Mustacchi 
7455fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
7465fc77b81SRobert Mustacchi }
7475fc77b81SRobert Mustacchi 
7485fc77b81SRobert Mustacchi /**
7495fc77b81SRobert Mustacchi  *  ixgbe_read_pba_num_generic - Reads part number from EEPROM
7505fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
7515fc77b81SRobert Mustacchi  *  @pba_num: stores the part number from the EEPROM
7525fc77b81SRobert Mustacchi  *
7535fc77b81SRobert Mustacchi  *  Reads the part number from the EEPROM.
7545fc77b81SRobert Mustacchi  **/
ixgbe_read_pba_num_generic(struct ixgbe_hw * hw,u32 * pba_num)7555fc77b81SRobert Mustacchi s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
7565fc77b81SRobert Mustacchi {
7575fc77b81SRobert Mustacchi 	s32 ret_val;
7585fc77b81SRobert Mustacchi 	u16 data;
7595fc77b81SRobert Mustacchi 
7605fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_read_pba_num_generic");
7615fc77b81SRobert Mustacchi 
7625fc77b81SRobert Mustacchi 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
7635fc77b81SRobert Mustacchi 	if (ret_val) {
7645fc77b81SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
7655fc77b81SRobert Mustacchi 		return ret_val;
7665fc77b81SRobert Mustacchi 	} else if (data == IXGBE_PBANUM_PTR_GUARD) {
7675fc77b81SRobert Mustacchi 		DEBUGOUT("NVM Not supported\n");
7685fc77b81SRobert Mustacchi 		return IXGBE_NOT_IMPLEMENTED;
7695fc77b81SRobert Mustacchi 	}
7705fc77b81SRobert Mustacchi 	*pba_num = (u32)(data << 16);
7715fc77b81SRobert Mustacchi 
7725fc77b81SRobert Mustacchi 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
7735fc77b81SRobert Mustacchi 	if (ret_val) {
7745fc77b81SRobert Mustacchi 		DEBUGOUT("NVM Read Error\n");
7755fc77b81SRobert Mustacchi 		return ret_val;
7765fc77b81SRobert Mustacchi 	}
7775fc77b81SRobert Mustacchi 	*pba_num |= data;
7785fc77b81SRobert Mustacchi 
7795fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
7805fc77b81SRobert Mustacchi }
7815fc77b81SRobert Mustacchi 
7825fc77b81SRobert Mustacchi /**
783dc0cb1cdSDale Ghent  *  ixgbe_read_pba_raw
784dc0cb1cdSDale Ghent  *  @hw: pointer to the HW structure
785dc0cb1cdSDale Ghent  *  @eeprom_buf: optional pointer to EEPROM image
786dc0cb1cdSDale Ghent  *  @eeprom_buf_size: size of EEPROM image in words
787dc0cb1cdSDale Ghent  *  @max_pba_block_size: PBA block size limit
788dc0cb1cdSDale Ghent  *  @pba: pointer to output PBA structure
789dc0cb1cdSDale Ghent  *
790dc0cb1cdSDale Ghent  *  Reads PBA from EEPROM image when eeprom_buf is not NULL.
791dc0cb1cdSDale Ghent  *  Reads PBA from physical EEPROM device when eeprom_buf is NULL.
792dc0cb1cdSDale Ghent  *
793dc0cb1cdSDale Ghent  **/
ixgbe_read_pba_raw(struct ixgbe_hw * hw,u16 * eeprom_buf,u32 eeprom_buf_size,u16 max_pba_block_size,struct ixgbe_pba * pba)794dc0cb1cdSDale Ghent s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
795dc0cb1cdSDale Ghent 		       u32 eeprom_buf_size, u16 max_pba_block_size,
796dc0cb1cdSDale Ghent 		       struct ixgbe_pba *pba)
797dc0cb1cdSDale Ghent {
798dc0cb1cdSDale Ghent 	s32 ret_val;
799dc0cb1cdSDale Ghent 	u16 pba_block_size;
800dc0cb1cdSDale Ghent 
801dc0cb1cdSDale Ghent 	if (pba == NULL)
802dc0cb1cdSDale Ghent 		return IXGBE_ERR_PARAM;
803dc0cb1cdSDale Ghent 
804dc0cb1cdSDale Ghent 	if (eeprom_buf == NULL) {
805dc0cb1cdSDale Ghent 		ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
806dc0cb1cdSDale Ghent 						     &pba->word[0]);
807dc0cb1cdSDale Ghent 		if (ret_val)
808dc0cb1cdSDale Ghent 			return ret_val;
809dc0cb1cdSDale Ghent 	} else {
810dc0cb1cdSDale Ghent 		if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
811dc0cb1cdSDale Ghent 			pba->word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
812dc0cb1cdSDale Ghent 			pba->word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
813dc0cb1cdSDale Ghent 		} else {
814dc0cb1cdSDale Ghent 			return IXGBE_ERR_PARAM;
815dc0cb1cdSDale Ghent 		}
816dc0cb1cdSDale Ghent 	}
817dc0cb1cdSDale Ghent 
818dc0cb1cdSDale Ghent 	if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
819dc0cb1cdSDale Ghent 		if (pba->pba_block == NULL)
820dc0cb1cdSDale Ghent 			return IXGBE_ERR_PARAM;
821dc0cb1cdSDale Ghent 
822dc0cb1cdSDale Ghent 		ret_val = ixgbe_get_pba_block_size(hw, eeprom_buf,
823dc0cb1cdSDale Ghent 						   eeprom_buf_size,
824dc0cb1cdSDale Ghent 						   &pba_block_size);
825dc0cb1cdSDale Ghent 		if (ret_val)
826dc0cb1cdSDale Ghent 			return ret_val;
827dc0cb1cdSDale Ghent 
828dc0cb1cdSDale Ghent 		if (pba_block_size > max_pba_block_size)
829dc0cb1cdSDale Ghent 			return IXGBE_ERR_PARAM;
830dc0cb1cdSDale Ghent 
831dc0cb1cdSDale Ghent 		if (eeprom_buf == NULL) {
832dc0cb1cdSDale Ghent 			ret_val = hw->eeprom.ops.read_buffer(hw, pba->word[1],
833dc0cb1cdSDale Ghent 							     pba_block_size,
834dc0cb1cdSDale Ghent 							     pba->pba_block);
835dc0cb1cdSDale Ghent 			if (ret_val)
836dc0cb1cdSDale Ghent 				return ret_val;
837dc0cb1cdSDale Ghent 		} else {
838dc0cb1cdSDale Ghent 			if (eeprom_buf_size > (u32)(pba->word[1] +
839dc0cb1cdSDale Ghent 					      pba_block_size)) {
840dc0cb1cdSDale Ghent 				memcpy(pba->pba_block,
841dc0cb1cdSDale Ghent 				       &eeprom_buf[pba->word[1]],
842dc0cb1cdSDale Ghent 				       pba_block_size * sizeof(u16));
843dc0cb1cdSDale Ghent 			} else {
844dc0cb1cdSDale Ghent 				return IXGBE_ERR_PARAM;
845dc0cb1cdSDale Ghent 			}
846dc0cb1cdSDale Ghent 		}
847dc0cb1cdSDale Ghent 	}
848dc0cb1cdSDale Ghent 
849dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
850dc0cb1cdSDale Ghent }
851dc0cb1cdSDale Ghent 
852dc0cb1cdSDale Ghent /**
853dc0cb1cdSDale Ghent  *  ixgbe_write_pba_raw
854dc0cb1cdSDale Ghent  *  @hw: pointer to the HW structure
855dc0cb1cdSDale Ghent  *  @eeprom_buf: optional pointer to EEPROM image
856dc0cb1cdSDale Ghent  *  @eeprom_buf_size: size of EEPROM image in words
857dc0cb1cdSDale Ghent  *  @pba: pointer to PBA structure
858dc0cb1cdSDale Ghent  *
859dc0cb1cdSDale Ghent  *  Writes PBA to EEPROM image when eeprom_buf is not NULL.
860dc0cb1cdSDale Ghent  *  Writes PBA to physical EEPROM device when eeprom_buf is NULL.
861dc0cb1cdSDale Ghent  *
862dc0cb1cdSDale Ghent  **/
ixgbe_write_pba_raw(struct ixgbe_hw * hw,u16 * eeprom_buf,u32 eeprom_buf_size,struct ixgbe_pba * pba)863dc0cb1cdSDale Ghent s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
864dc0cb1cdSDale Ghent 			u32 eeprom_buf_size, struct ixgbe_pba *pba)
865dc0cb1cdSDale Ghent {
866dc0cb1cdSDale Ghent 	s32 ret_val;
867dc0cb1cdSDale Ghent 
868dc0cb1cdSDale Ghent 	if (pba == NULL)
869dc0cb1cdSDale Ghent 		return IXGBE_ERR_PARAM;
870dc0cb1cdSDale Ghent 
871dc0cb1cdSDale Ghent 	if (eeprom_buf == NULL) {
872dc0cb1cdSDale Ghent 		ret_val = hw->eeprom.ops.write_buffer(hw, IXGBE_PBANUM0_PTR, 2,
873dc0cb1cdSDale Ghent 						      &pba->word[0]);
874dc0cb1cdSDale Ghent 		if (ret_val)
875dc0cb1cdSDale Ghent 			return ret_val;
876dc0cb1cdSDale Ghent 	} else {
877dc0cb1cdSDale Ghent 		if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
878dc0cb1cdSDale Ghent 			eeprom_buf[IXGBE_PBANUM0_PTR] = pba->word[0];
879dc0cb1cdSDale Ghent 			eeprom_buf[IXGBE_PBANUM1_PTR] = pba->word[1];
880dc0cb1cdSDale Ghent 		} else {
881dc0cb1cdSDale Ghent 			return IXGBE_ERR_PARAM;
882dc0cb1cdSDale Ghent 		}
883dc0cb1cdSDale Ghent 	}
884dc0cb1cdSDale Ghent 
885dc0cb1cdSDale Ghent 	if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
886dc0cb1cdSDale Ghent 		if (pba->pba_block == NULL)
887dc0cb1cdSDale Ghent 			return IXGBE_ERR_PARAM;
888dc0cb1cdSDale Ghent 
889dc0cb1cdSDale Ghent 		if (eeprom_buf == NULL) {
890dc0cb1cdSDale Ghent 			ret_val = hw->eeprom.ops.write_buffer(hw, pba->word[1],
891dc0cb1cdSDale Ghent 							      pba->pba_block[0],
892dc0cb1cdSDale Ghent 							      pba->pba_block);
893dc0cb1cdSDale Ghent 			if (ret_val)
894dc0cb1cdSDale Ghent 				return ret_val;
895dc0cb1cdSDale Ghent 		} else {
896dc0cb1cdSDale Ghent 			if (eeprom_buf_size > (u32)(pba->word[1] +
897dc0cb1cdSDale Ghent 					      pba->pba_block[0])) {
898dc0cb1cdSDale Ghent 				memcpy(&eeprom_buf[pba->word[1]],
899dc0cb1cdSDale Ghent 				       pba->pba_block,
900dc0cb1cdSDale Ghent 				       pba->pba_block[0] * sizeof(u16));
901dc0cb1cdSDale Ghent 			} else {
902dc0cb1cdSDale Ghent 				return IXGBE_ERR_PARAM;
903dc0cb1cdSDale Ghent 			}
904dc0cb1cdSDale Ghent 		}
905dc0cb1cdSDale Ghent 	}
906dc0cb1cdSDale Ghent 
907dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
908dc0cb1cdSDale Ghent }
909dc0cb1cdSDale Ghent 
910dc0cb1cdSDale Ghent /**
911dc0cb1cdSDale Ghent  *  ixgbe_get_pba_block_size
912dc0cb1cdSDale Ghent  *  @hw: pointer to the HW structure
913dc0cb1cdSDale Ghent  *  @eeprom_buf: optional pointer to EEPROM image
914dc0cb1cdSDale Ghent  *  @eeprom_buf_size: size of EEPROM image in words
915dc0cb1cdSDale Ghent  *  @pba_data_size: pointer to output variable
916dc0cb1cdSDale Ghent  *
917dc0cb1cdSDale Ghent  *  Returns the size of the PBA block in words. Function operates on EEPROM
918dc0cb1cdSDale Ghent  *  image if the eeprom_buf pointer is not NULL otherwise it accesses physical
919dc0cb1cdSDale Ghent  *  EEPROM device.
920dc0cb1cdSDale Ghent  *
921dc0cb1cdSDale Ghent  **/
ixgbe_get_pba_block_size(struct ixgbe_hw * hw,u16 * eeprom_buf,u32 eeprom_buf_size,u16 * pba_block_size)922dc0cb1cdSDale Ghent s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
923dc0cb1cdSDale Ghent 			     u32 eeprom_buf_size, u16 *pba_block_size)
924dc0cb1cdSDale Ghent {
925dc0cb1cdSDale Ghent 	s32 ret_val;
926dc0cb1cdSDale Ghent 	u16 pba_word[2];
927dc0cb1cdSDale Ghent 	u16 length;
928dc0cb1cdSDale Ghent 
929dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_get_pba_block_size");
930dc0cb1cdSDale Ghent 
931dc0cb1cdSDale Ghent 	if (eeprom_buf == NULL) {
932dc0cb1cdSDale Ghent 		ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
933dc0cb1cdSDale Ghent 						     &pba_word[0]);
934dc0cb1cdSDale Ghent 		if (ret_val)
935dc0cb1cdSDale Ghent 			return ret_val;
936dc0cb1cdSDale Ghent 	} else {
937dc0cb1cdSDale Ghent 		if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
938dc0cb1cdSDale Ghent 			pba_word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
939dc0cb1cdSDale Ghent 			pba_word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
940dc0cb1cdSDale Ghent 		} else {
941dc0cb1cdSDale Ghent 			return IXGBE_ERR_PARAM;
942dc0cb1cdSDale Ghent 		}
943dc0cb1cdSDale Ghent 	}
944dc0cb1cdSDale Ghent 
945dc0cb1cdSDale Ghent 	if (pba_word[0] == IXGBE_PBANUM_PTR_GUARD) {
946dc0cb1cdSDale Ghent 		if (eeprom_buf == NULL) {
947dc0cb1cdSDale Ghent 			ret_val = hw->eeprom.ops.read(hw, pba_word[1] + 0,
948dc0cb1cdSDale Ghent 						      &length);
949dc0cb1cdSDale Ghent 			if (ret_val)
950dc0cb1cdSDale Ghent 				return ret_val;
951dc0cb1cdSDale Ghent 		} else {
952dc0cb1cdSDale Ghent 			if (eeprom_buf_size > pba_word[1])
953dc0cb1cdSDale Ghent 				length = eeprom_buf[pba_word[1] + 0];
954dc0cb1cdSDale Ghent 			else
955dc0cb1cdSDale Ghent 				return IXGBE_ERR_PARAM;
956dc0cb1cdSDale Ghent 		}
957dc0cb1cdSDale Ghent 
958dc0cb1cdSDale Ghent 		if (length == 0xFFFF || length == 0)
959dc0cb1cdSDale Ghent 			return IXGBE_ERR_PBA_SECTION;
960dc0cb1cdSDale Ghent 	} else {
961dc0cb1cdSDale Ghent 		/* PBA number in legacy format, there is no PBA Block. */
962dc0cb1cdSDale Ghent 		length = 0;
963dc0cb1cdSDale Ghent 	}
964dc0cb1cdSDale Ghent 
965dc0cb1cdSDale Ghent 	if (pba_block_size != NULL)
966dc0cb1cdSDale Ghent 		*pba_block_size = length;
967dc0cb1cdSDale Ghent 
968dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
969dc0cb1cdSDale Ghent }
970dc0cb1cdSDale Ghent 
971dc0cb1cdSDale Ghent /**
9725fc77b81SRobert Mustacchi  *  ixgbe_get_mac_addr_generic - Generic get MAC address
9735fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
9745fc77b81SRobert Mustacchi  *  @mac_addr: Adapter MAC address
9755fc77b81SRobert Mustacchi  *
9765fc77b81SRobert Mustacchi  *  Reads the adapter's MAC address from first Receive Address Register (RAR0)
9775fc77b81SRobert Mustacchi  *  A reset of the adapter must be performed prior to calling this function
9785fc77b81SRobert Mustacchi  *  in order for the MAC address to have been loaded from the EEPROM into RAR0
9795fc77b81SRobert Mustacchi  **/
ixgbe_get_mac_addr_generic(struct ixgbe_hw * hw,u8 * mac_addr)9805fc77b81SRobert Mustacchi s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
9815fc77b81SRobert Mustacchi {
9825fc77b81SRobert Mustacchi 	u32 rar_high;
9835fc77b81SRobert Mustacchi 	u32 rar_low;
9845fc77b81SRobert Mustacchi 	u16 i;
9855fc77b81SRobert Mustacchi 
9865fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_mac_addr_generic");
9875fc77b81SRobert Mustacchi 
9885fc77b81SRobert Mustacchi 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0));
9895fc77b81SRobert Mustacchi 	rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0));
9905fc77b81SRobert Mustacchi 
9915fc77b81SRobert Mustacchi 	for (i = 0; i < 4; i++)
9925fc77b81SRobert Mustacchi 		mac_addr[i] = (u8)(rar_low >> (i*8));
9935fc77b81SRobert Mustacchi 
9945fc77b81SRobert Mustacchi 	for (i = 0; i < 2; i++)
9955fc77b81SRobert Mustacchi 		mac_addr[i+4] = (u8)(rar_high >> (i*8));
9965fc77b81SRobert Mustacchi 
9975fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
9985fc77b81SRobert Mustacchi }
9995fc77b81SRobert Mustacchi 
10005fc77b81SRobert Mustacchi /**
1001dc0cb1cdSDale Ghent  *  ixgbe_set_pci_config_data_generic - Generic store PCI bus info
10025fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
1003dc0cb1cdSDale Ghent  *  @link_status: the link status returned by the PCI config space
10045fc77b81SRobert Mustacchi  *
1005dc0cb1cdSDale Ghent  *  Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure
10065fc77b81SRobert Mustacchi  **/
ixgbe_set_pci_config_data_generic(struct ixgbe_hw * hw,u16 link_status)1007dc0cb1cdSDale Ghent void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status)
10085fc77b81SRobert Mustacchi {
10095fc77b81SRobert Mustacchi 	struct ixgbe_mac_info *mac = &hw->mac;
10105fc77b81SRobert Mustacchi 
1011dc0cb1cdSDale Ghent 	if (hw->bus.type == ixgbe_bus_type_unknown)
10125fc77b81SRobert Mustacchi 		hw->bus.type = ixgbe_bus_type_pci_express;
10135fc77b81SRobert Mustacchi 
10145fc77b81SRobert Mustacchi 	switch (link_status & IXGBE_PCI_LINK_WIDTH) {
10155fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_WIDTH_1:
10165fc77b81SRobert Mustacchi 		hw->bus.width = ixgbe_bus_width_pcie_x1;
10175fc77b81SRobert Mustacchi 		break;
10185fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_WIDTH_2:
10195fc77b81SRobert Mustacchi 		hw->bus.width = ixgbe_bus_width_pcie_x2;
10205fc77b81SRobert Mustacchi 		break;
10215fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_WIDTH_4:
10225fc77b81SRobert Mustacchi 		hw->bus.width = ixgbe_bus_width_pcie_x4;
10235fc77b81SRobert Mustacchi 		break;
10245fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_WIDTH_8:
10255fc77b81SRobert Mustacchi 		hw->bus.width = ixgbe_bus_width_pcie_x8;
10265fc77b81SRobert Mustacchi 		break;
10275fc77b81SRobert Mustacchi 	default:
10285fc77b81SRobert Mustacchi 		hw->bus.width = ixgbe_bus_width_unknown;
10295fc77b81SRobert Mustacchi 		break;
10305fc77b81SRobert Mustacchi 	}
10315fc77b81SRobert Mustacchi 
10325fc77b81SRobert Mustacchi 	switch (link_status & IXGBE_PCI_LINK_SPEED) {
10335fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_SPEED_2500:
10345fc77b81SRobert Mustacchi 		hw->bus.speed = ixgbe_bus_speed_2500;
10355fc77b81SRobert Mustacchi 		break;
10365fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_SPEED_5000:
10375fc77b81SRobert Mustacchi 		hw->bus.speed = ixgbe_bus_speed_5000;
10385fc77b81SRobert Mustacchi 		break;
10395fc77b81SRobert Mustacchi 	case IXGBE_PCI_LINK_SPEED_8000:
10405fc77b81SRobert Mustacchi 		hw->bus.speed = ixgbe_bus_speed_8000;
10415fc77b81SRobert Mustacchi 		break;
10425fc77b81SRobert Mustacchi 	default:
10435fc77b81SRobert Mustacchi 		hw->bus.speed = ixgbe_bus_speed_unknown;
10445fc77b81SRobert Mustacchi 		break;
10455fc77b81SRobert Mustacchi 	}
10465fc77b81SRobert Mustacchi 
10475fc77b81SRobert Mustacchi 	mac->ops.set_lan_id(hw);
1048dc0cb1cdSDale Ghent }
1049dc0cb1cdSDale Ghent 
1050dc0cb1cdSDale Ghent /**
1051dc0cb1cdSDale Ghent  *  ixgbe_get_bus_info_generic - Generic set PCI bus info
1052dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
1053dc0cb1cdSDale Ghent  *
1054dc0cb1cdSDale Ghent  *  Gets the PCI bus info (speed, width, type) then calls helper function to
1055dc0cb1cdSDale Ghent  *  store this data within the ixgbe_hw structure.
1056dc0cb1cdSDale Ghent  **/
ixgbe_get_bus_info_generic(struct ixgbe_hw * hw)1057dc0cb1cdSDale Ghent s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
1058dc0cb1cdSDale Ghent {
1059dc0cb1cdSDale Ghent 	u16 link_status;
1060dc0cb1cdSDale Ghent 
1061dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_get_bus_info_generic");
1062dc0cb1cdSDale Ghent 
1063dc0cb1cdSDale Ghent 	/* Get the negotiated link width and speed from PCI config space */
1064dc0cb1cdSDale Ghent 	link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS);
1065dc0cb1cdSDale Ghent 
1066dc0cb1cdSDale Ghent 	ixgbe_set_pci_config_data_generic(hw, link_status);
10675fc77b81SRobert Mustacchi 
10685fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
10695fc77b81SRobert Mustacchi }
10705fc77b81SRobert Mustacchi 
10715fc77b81SRobert Mustacchi /**
10725fc77b81SRobert Mustacchi  *  ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
10735fc77b81SRobert Mustacchi  *  @hw: pointer to the HW structure
10745fc77b81SRobert Mustacchi  *
1075*48ed61a7SRobert Mustacchi  *  Determines the LAN function id by reading memory-mapped registers and swaps
1076*48ed61a7SRobert Mustacchi  *  the port value if requested, and set MAC instance for devices that share
1077*48ed61a7SRobert Mustacchi  *  CS4227.
10785fc77b81SRobert Mustacchi  **/
ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw * hw)10795fc77b81SRobert Mustacchi void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
10805fc77b81SRobert Mustacchi {
10815fc77b81SRobert Mustacchi 	struct ixgbe_bus_info *bus = &hw->bus;
10825fc77b81SRobert Mustacchi 	u32 reg;
1083*48ed61a7SRobert Mustacchi 	u16 ee_ctrl_4;
10845fc77b81SRobert Mustacchi 
10855fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie");
10865fc77b81SRobert Mustacchi 
10875fc77b81SRobert Mustacchi 	reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
10885fc77b81SRobert Mustacchi 	bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
1089*48ed61a7SRobert Mustacchi 	bus->lan_id = (u8)bus->func;
10905fc77b81SRobert Mustacchi 
10915fc77b81SRobert Mustacchi 	/* check for a port swap */
1092dc0cb1cdSDale Ghent 	reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw));
10935fc77b81SRobert Mustacchi 	if (reg & IXGBE_FACTPS_LFS)
10945fc77b81SRobert Mustacchi 		bus->func ^= 0x1;
1095*48ed61a7SRobert Mustacchi 
1096*48ed61a7SRobert Mustacchi 	/* Get MAC instance from EEPROM for configuring CS4227 */
1097*48ed61a7SRobert Mustacchi 	if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) {
1098*48ed61a7SRobert Mustacchi 		hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4);
1099*48ed61a7SRobert Mustacchi 		bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >>
1100*48ed61a7SRobert Mustacchi 				   IXGBE_EE_CTRL_4_INST_ID_SHIFT;
1101*48ed61a7SRobert Mustacchi 	}
11025fc77b81SRobert Mustacchi }
11035fc77b81SRobert Mustacchi 
11045fc77b81SRobert Mustacchi /**
11055fc77b81SRobert Mustacchi  *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
11065fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
11075fc77b81SRobert Mustacchi  *
11085fc77b81SRobert Mustacchi  *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
11095fc77b81SRobert Mustacchi  *  disables transmit and receive units. The adapter_stopped flag is used by
11105fc77b81SRobert Mustacchi  *  the shared code and drivers to determine if the adapter is in a stopped
11115fc77b81SRobert Mustacchi  *  state and should not touch the hardware.
11125fc77b81SRobert Mustacchi  **/
ixgbe_stop_adapter_generic(struct ixgbe_hw * hw)11135fc77b81SRobert Mustacchi s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
11145fc77b81SRobert Mustacchi {
11155fc77b81SRobert Mustacchi 	u32 reg_val;
11165fc77b81SRobert Mustacchi 	u16 i;
11175fc77b81SRobert Mustacchi 
11185fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_stop_adapter_generic");
11195fc77b81SRobert Mustacchi 
11205fc77b81SRobert Mustacchi 	/*
11215fc77b81SRobert Mustacchi 	 * Set the adapter_stopped flag so other driver functions stop touching
11225fc77b81SRobert Mustacchi 	 * the hardware
11235fc77b81SRobert Mustacchi 	 */
11245fc77b81SRobert Mustacchi 	hw->adapter_stopped = TRUE;
11255fc77b81SRobert Mustacchi 
11265fc77b81SRobert Mustacchi 	/* Disable the receive unit */
1127dc0cb1cdSDale Ghent 	ixgbe_disable_rx(hw);
11285fc77b81SRobert Mustacchi 
11295fc77b81SRobert Mustacchi 	/* Clear interrupt mask to stop interrupts from being generated */
11305fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
11315fc77b81SRobert Mustacchi 
11325fc77b81SRobert Mustacchi 	/* Clear any pending interrupts, flush previous writes */
1133dc0cb1cdSDale Ghent 	IXGBE_READ_REG(hw, IXGBE_EICR);
11345fc77b81SRobert Mustacchi 
11355fc77b81SRobert Mustacchi 	/* Disable the transmit unit.  Each queue must be disabled. */
11365fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_tx_queues; i++)
11375fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH);
11385fc77b81SRobert Mustacchi 
11395fc77b81SRobert Mustacchi 	/* Disable the receive unit by stopping each queue */
11405fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_rx_queues; i++) {
11415fc77b81SRobert Mustacchi 		reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
11425fc77b81SRobert Mustacchi 		reg_val &= ~IXGBE_RXDCTL_ENABLE;
11435fc77b81SRobert Mustacchi 		reg_val |= IXGBE_RXDCTL_SWFLSH;
11445fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
11455fc77b81SRobert Mustacchi 	}
11465fc77b81SRobert Mustacchi 
11475fc77b81SRobert Mustacchi 	/* flush all queues disables */
11485fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
11495fc77b81SRobert Mustacchi 	msec_delay(2);
11505fc77b81SRobert Mustacchi 
11515fc77b81SRobert Mustacchi 	/*
1152dc0cb1cdSDale Ghent 	 * Prevent the PCI-E bus from hanging by disabling PCI-E master
11535fc77b81SRobert Mustacchi 	 * access and verify no pending requests
11545fc77b81SRobert Mustacchi 	 */
11555fc77b81SRobert Mustacchi 	return ixgbe_disable_pcie_master(hw);
11565fc77b81SRobert Mustacchi }
11575fc77b81SRobert Mustacchi 
11585fc77b81SRobert Mustacchi /**
1159*48ed61a7SRobert Mustacchi  *  ixgbe_init_led_link_act_generic - Store the LED index link/activity.
1160*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
1161*48ed61a7SRobert Mustacchi  *
1162*48ed61a7SRobert Mustacchi  *  Store the index for the link active LED. This will be used to support
1163*48ed61a7SRobert Mustacchi  *  blinking the LED.
1164*48ed61a7SRobert Mustacchi  **/
ixgbe_init_led_link_act_generic(struct ixgbe_hw * hw)1165*48ed61a7SRobert Mustacchi s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw)
1166*48ed61a7SRobert Mustacchi {
1167*48ed61a7SRobert Mustacchi 	struct ixgbe_mac_info *mac = &hw->mac;
1168*48ed61a7SRobert Mustacchi 	u32 led_reg, led_mode;
1169*48ed61a7SRobert Mustacchi 	u8 i;
1170*48ed61a7SRobert Mustacchi 
1171*48ed61a7SRobert Mustacchi 	led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
1172*48ed61a7SRobert Mustacchi 
1173*48ed61a7SRobert Mustacchi 	/* Get LED link active from the LEDCTL register */
1174*48ed61a7SRobert Mustacchi 	for (i = 0; i < 4; i++) {
1175*48ed61a7SRobert Mustacchi 		led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i);
1176*48ed61a7SRobert Mustacchi 
1177*48ed61a7SRobert Mustacchi 		if ((led_mode & IXGBE_LED_MODE_MASK_BASE) ==
1178*48ed61a7SRobert Mustacchi 		     IXGBE_LED_LINK_ACTIVE) {
1179*48ed61a7SRobert Mustacchi 			mac->led_link_act = i;
1180*48ed61a7SRobert Mustacchi 			return IXGBE_SUCCESS;
1181*48ed61a7SRobert Mustacchi 		}
1182*48ed61a7SRobert Mustacchi 	}
1183*48ed61a7SRobert Mustacchi 
1184*48ed61a7SRobert Mustacchi 	/*
1185*48ed61a7SRobert Mustacchi 	 * If LEDCTL register does not have the LED link active set, then use
1186*48ed61a7SRobert Mustacchi 	 * known MAC defaults.
1187*48ed61a7SRobert Mustacchi 	 */
1188*48ed61a7SRobert Mustacchi 	switch (hw->mac.type) {
1189*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
1190*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_x:
1191*48ed61a7SRobert Mustacchi 		mac->led_link_act = 1;
1192*48ed61a7SRobert Mustacchi 		break;
1193*48ed61a7SRobert Mustacchi 	default:
1194*48ed61a7SRobert Mustacchi 		mac->led_link_act = 2;
1195*48ed61a7SRobert Mustacchi 	}
1196*48ed61a7SRobert Mustacchi 	return IXGBE_SUCCESS;
1197*48ed61a7SRobert Mustacchi }
1198*48ed61a7SRobert Mustacchi 
1199*48ed61a7SRobert Mustacchi /**
12005fc77b81SRobert Mustacchi  *  ixgbe_led_on_generic - Turns on the software controllable LEDs.
12015fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
12025fc77b81SRobert Mustacchi  *  @index: led number to turn on
12035fc77b81SRobert Mustacchi  **/
ixgbe_led_on_generic(struct ixgbe_hw * hw,u32 index)12045fc77b81SRobert Mustacchi s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
12055fc77b81SRobert Mustacchi {
12065fc77b81SRobert Mustacchi 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
12075fc77b81SRobert Mustacchi 
12085fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_led_on_generic");
12095fc77b81SRobert Mustacchi 
1210*48ed61a7SRobert Mustacchi 	if (index > 3)
1211*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_PARAM;
1212*48ed61a7SRobert Mustacchi 
12135fc77b81SRobert Mustacchi 	/* To turn on the LED, set mode to ON. */
12145fc77b81SRobert Mustacchi 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
12155fc77b81SRobert Mustacchi 	led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
12165fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
12175fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
12185fc77b81SRobert Mustacchi 
12195fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
12205fc77b81SRobert Mustacchi }
12215fc77b81SRobert Mustacchi 
12225fc77b81SRobert Mustacchi /**
12235fc77b81SRobert Mustacchi  *  ixgbe_led_off_generic - Turns off the software controllable LEDs.
12245fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
12255fc77b81SRobert Mustacchi  *  @index: led number to turn off
12265fc77b81SRobert Mustacchi  **/
ixgbe_led_off_generic(struct ixgbe_hw * hw,u32 index)12275fc77b81SRobert Mustacchi s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
12285fc77b81SRobert Mustacchi {
12295fc77b81SRobert Mustacchi 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
12305fc77b81SRobert Mustacchi 
12315fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_led_off_generic");
12325fc77b81SRobert Mustacchi 
1233*48ed61a7SRobert Mustacchi 	if (index > 3)
1234*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_PARAM;
1235*48ed61a7SRobert Mustacchi 
12365fc77b81SRobert Mustacchi 	/* To turn off the LED, set mode to OFF. */
12375fc77b81SRobert Mustacchi 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
12385fc77b81SRobert Mustacchi 	led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
12395fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
12405fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
12415fc77b81SRobert Mustacchi 
12425fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
12435fc77b81SRobert Mustacchi }
12445fc77b81SRobert Mustacchi 
12455fc77b81SRobert Mustacchi /**
12465fc77b81SRobert Mustacchi  *  ixgbe_init_eeprom_params_generic - Initialize EEPROM params
12475fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
12485fc77b81SRobert Mustacchi  *
12495fc77b81SRobert Mustacchi  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
12505fc77b81SRobert Mustacchi  *  ixgbe_hw struct in order to set up EEPROM access.
12515fc77b81SRobert Mustacchi  **/
ixgbe_init_eeprom_params_generic(struct ixgbe_hw * hw)12525fc77b81SRobert Mustacchi s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
12535fc77b81SRobert Mustacchi {
12545fc77b81SRobert Mustacchi 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
12555fc77b81SRobert Mustacchi 	u32 eec;
12565fc77b81SRobert Mustacchi 	u16 eeprom_size;
12575fc77b81SRobert Mustacchi 
12585fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_init_eeprom_params_generic");
12595fc77b81SRobert Mustacchi 
12605fc77b81SRobert Mustacchi 	if (eeprom->type == ixgbe_eeprom_uninitialized) {
12615fc77b81SRobert Mustacchi 		eeprom->type = ixgbe_eeprom_none;
12625fc77b81SRobert Mustacchi 		/* Set default semaphore delay to 10ms which is a well
12635fc77b81SRobert Mustacchi 		 * tested value */
12645fc77b81SRobert Mustacchi 		eeprom->semaphore_delay = 10;
12655fc77b81SRobert Mustacchi 		/* Clear EEPROM page size, it will be initialized as needed */
12665fc77b81SRobert Mustacchi 		eeprom->word_page_size = 0;
12675fc77b81SRobert Mustacchi 
12685fc77b81SRobert Mustacchi 		/*
12695fc77b81SRobert Mustacchi 		 * Check for EEPROM present first.
12705fc77b81SRobert Mustacchi 		 * If not present leave as none
12715fc77b81SRobert Mustacchi 		 */
1272dc0cb1cdSDale Ghent 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
12735fc77b81SRobert Mustacchi 		if (eec & IXGBE_EEC_PRES) {
12745fc77b81SRobert Mustacchi 			eeprom->type = ixgbe_eeprom_spi;
12755fc77b81SRobert Mustacchi 
12765fc77b81SRobert Mustacchi 			/*
12775fc77b81SRobert Mustacchi 			 * SPI EEPROM is assumed here.  This code would need to
12785fc77b81SRobert Mustacchi 			 * change if a future EEPROM is not SPI.
12795fc77b81SRobert Mustacchi 			 */
12805fc77b81SRobert Mustacchi 			eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
12815fc77b81SRobert Mustacchi 					    IXGBE_EEC_SIZE_SHIFT);
12825fc77b81SRobert Mustacchi 			eeprom->word_size = 1 << (eeprom_size +
12835fc77b81SRobert Mustacchi 					     IXGBE_EEPROM_WORD_SIZE_SHIFT);
12845fc77b81SRobert Mustacchi 		}
12855fc77b81SRobert Mustacchi 
12865fc77b81SRobert Mustacchi 		if (eec & IXGBE_EEC_ADDR_SIZE)
12875fc77b81SRobert Mustacchi 			eeprom->address_bits = 16;
12885fc77b81SRobert Mustacchi 		else
12895fc77b81SRobert Mustacchi 			eeprom->address_bits = 8;
12905fc77b81SRobert Mustacchi 		DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: "
12915fc77b81SRobert Mustacchi 			  "%d\n", eeprom->type, eeprom->word_size,
12925fc77b81SRobert Mustacchi 			  eeprom->address_bits);
12935fc77b81SRobert Mustacchi 	}
12945fc77b81SRobert Mustacchi 
12955fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
12965fc77b81SRobert Mustacchi }
12975fc77b81SRobert Mustacchi 
12985fc77b81SRobert Mustacchi /**
12995fc77b81SRobert Mustacchi  *  ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
13005fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
13015fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to write
13025fc77b81SRobert Mustacchi  *  @words: number of word(s)
13035fc77b81SRobert Mustacchi  *  @data: 16 bit word(s) to write to EEPROM
13045fc77b81SRobert Mustacchi  *
13055fc77b81SRobert Mustacchi  *  Reads 16 bit word(s) from EEPROM through bit-bang method
13065fc77b81SRobert Mustacchi  **/
ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)13075fc77b81SRobert Mustacchi s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
13085fc77b81SRobert Mustacchi 					       u16 words, u16 *data)
13095fc77b81SRobert Mustacchi {
13105fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
13115fc77b81SRobert Mustacchi 	u16 i, count;
13125fc77b81SRobert Mustacchi 
13135fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang_generic");
13145fc77b81SRobert Mustacchi 
13155fc77b81SRobert Mustacchi 	hw->eeprom.ops.init_params(hw);
13165fc77b81SRobert Mustacchi 
13175fc77b81SRobert Mustacchi 	if (words == 0) {
13185fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_ARGUMENT;
13195fc77b81SRobert Mustacchi 		goto out;
13205fc77b81SRobert Mustacchi 	}
13215fc77b81SRobert Mustacchi 
13225fc77b81SRobert Mustacchi 	if (offset + words > hw->eeprom.word_size) {
13235fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
13245fc77b81SRobert Mustacchi 		goto out;
13255fc77b81SRobert Mustacchi 	}
13265fc77b81SRobert Mustacchi 
13275fc77b81SRobert Mustacchi 	/*
13285fc77b81SRobert Mustacchi 	 * The EEPROM page size cannot be queried from the chip. We do lazy
13295fc77b81SRobert Mustacchi 	 * initialization. It is worth to do that when we write large buffer.
13305fc77b81SRobert Mustacchi 	 */
13315fc77b81SRobert Mustacchi 	if ((hw->eeprom.word_page_size == 0) &&
13325fc77b81SRobert Mustacchi 	    (words > IXGBE_EEPROM_PAGE_SIZE_MAX))
1333dc0cb1cdSDale Ghent 		ixgbe_detect_eeprom_page_size_generic(hw, offset);
13345fc77b81SRobert Mustacchi 
13355fc77b81SRobert Mustacchi 	/*
13365fc77b81SRobert Mustacchi 	 * We cannot hold synchronization semaphores for too long
13375fc77b81SRobert Mustacchi 	 * to avoid other entity starvation. However it is more efficient
13385fc77b81SRobert Mustacchi 	 * to read in bursts than synchronizing access for each word.
13395fc77b81SRobert Mustacchi 	 */
13405fc77b81SRobert Mustacchi 	for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
13415fc77b81SRobert Mustacchi 		count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
13425fc77b81SRobert Mustacchi 			IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
13435fc77b81SRobert Mustacchi 		status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
13445fc77b81SRobert Mustacchi 							    count, &data[i]);
13455fc77b81SRobert Mustacchi 
13465fc77b81SRobert Mustacchi 		if (status != IXGBE_SUCCESS)
13475fc77b81SRobert Mustacchi 			break;
13485fc77b81SRobert Mustacchi 	}
13495fc77b81SRobert Mustacchi 
13505fc77b81SRobert Mustacchi out:
13515fc77b81SRobert Mustacchi 	return status;
13525fc77b81SRobert Mustacchi }
13535fc77b81SRobert Mustacchi 
13545fc77b81SRobert Mustacchi /**
13555fc77b81SRobert Mustacchi  *  ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
13565fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
13575fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to be written to
13585fc77b81SRobert Mustacchi  *  @words: number of word(s)
13595fc77b81SRobert Mustacchi  *  @data: 16 bit word(s) to be written to the EEPROM
13605fc77b81SRobert Mustacchi  *
13615fc77b81SRobert Mustacchi  *  If ixgbe_eeprom_update_checksum is not called after this function, the
13625fc77b81SRobert Mustacchi  *  EEPROM will most likely contain an invalid checksum.
13635fc77b81SRobert Mustacchi  **/
ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)13645fc77b81SRobert Mustacchi static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
13655fc77b81SRobert Mustacchi 					      u16 words, u16 *data)
13665fc77b81SRobert Mustacchi {
13675fc77b81SRobert Mustacchi 	s32 status;
13685fc77b81SRobert Mustacchi 	u16 word;
13695fc77b81SRobert Mustacchi 	u16 page_size;
13705fc77b81SRobert Mustacchi 	u16 i;
13715fc77b81SRobert Mustacchi 	u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
13725fc77b81SRobert Mustacchi 
13735fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang");
13745fc77b81SRobert Mustacchi 
13755fc77b81SRobert Mustacchi 	/* Prepare the EEPROM for writing  */
13765fc77b81SRobert Mustacchi 	status = ixgbe_acquire_eeprom(hw);
13775fc77b81SRobert Mustacchi 
13785fc77b81SRobert Mustacchi 	if (status == IXGBE_SUCCESS) {
13795fc77b81SRobert Mustacchi 		if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) {
13805fc77b81SRobert Mustacchi 			ixgbe_release_eeprom(hw);
13815fc77b81SRobert Mustacchi 			status = IXGBE_ERR_EEPROM;
13825fc77b81SRobert Mustacchi 		}
13835fc77b81SRobert Mustacchi 	}
13845fc77b81SRobert Mustacchi 
13855fc77b81SRobert Mustacchi 	if (status == IXGBE_SUCCESS) {
13865fc77b81SRobert Mustacchi 		for (i = 0; i < words; i++) {
13875fc77b81SRobert Mustacchi 			ixgbe_standby_eeprom(hw);
13885fc77b81SRobert Mustacchi 
13895fc77b81SRobert Mustacchi 			/*  Send the WRITE ENABLE command (8 bit opcode )  */
13905fc77b81SRobert Mustacchi 			ixgbe_shift_out_eeprom_bits(hw,
13915fc77b81SRobert Mustacchi 						   IXGBE_EEPROM_WREN_OPCODE_SPI,
13925fc77b81SRobert Mustacchi 						   IXGBE_EEPROM_OPCODE_BITS);
13935fc77b81SRobert Mustacchi 
13945fc77b81SRobert Mustacchi 			ixgbe_standby_eeprom(hw);
13955fc77b81SRobert Mustacchi 
13965fc77b81SRobert Mustacchi 			/*
13975fc77b81SRobert Mustacchi 			 * Some SPI eeproms use the 8th address bit embedded
13985fc77b81SRobert Mustacchi 			 * in the opcode
13995fc77b81SRobert Mustacchi 			 */
14005fc77b81SRobert Mustacchi 			if ((hw->eeprom.address_bits == 8) &&
14015fc77b81SRobert Mustacchi 			    ((offset + i) >= 128))
14025fc77b81SRobert Mustacchi 				write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
14035fc77b81SRobert Mustacchi 
14045fc77b81SRobert Mustacchi 			/* Send the Write command (8-bit opcode + addr) */
14055fc77b81SRobert Mustacchi 			ixgbe_shift_out_eeprom_bits(hw, write_opcode,
14065fc77b81SRobert Mustacchi 						    IXGBE_EEPROM_OPCODE_BITS);
14075fc77b81SRobert Mustacchi 			ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
14085fc77b81SRobert Mustacchi 						    hw->eeprom.address_bits);
14095fc77b81SRobert Mustacchi 
14105fc77b81SRobert Mustacchi 			page_size = hw->eeprom.word_page_size;
14115fc77b81SRobert Mustacchi 
14125fc77b81SRobert Mustacchi 			/* Send the data in burst via SPI*/
14135fc77b81SRobert Mustacchi 			do {
14145fc77b81SRobert Mustacchi 				word = data[i];
14155fc77b81SRobert Mustacchi 				word = (word >> 8) | (word << 8);
14165fc77b81SRobert Mustacchi 				ixgbe_shift_out_eeprom_bits(hw, word, 16);
14175fc77b81SRobert Mustacchi 
14185fc77b81SRobert Mustacchi 				if (page_size == 0)
14195fc77b81SRobert Mustacchi 					break;
14205fc77b81SRobert Mustacchi 
14215fc77b81SRobert Mustacchi 				/* do not wrap around page */
14225fc77b81SRobert Mustacchi 				if (((offset + i) & (page_size - 1)) ==
14235fc77b81SRobert Mustacchi 				    (page_size - 1))
14245fc77b81SRobert Mustacchi 					break;
14255fc77b81SRobert Mustacchi 			} while (++i < words);
14265fc77b81SRobert Mustacchi 
14275fc77b81SRobert Mustacchi 			ixgbe_standby_eeprom(hw);
14285fc77b81SRobert Mustacchi 			msec_delay(10);
14295fc77b81SRobert Mustacchi 		}
14305fc77b81SRobert Mustacchi 		/* Done with writing - release the EEPROM */
14315fc77b81SRobert Mustacchi 		ixgbe_release_eeprom(hw);
14325fc77b81SRobert Mustacchi 	}
14335fc77b81SRobert Mustacchi 
14345fc77b81SRobert Mustacchi 	return status;
14355fc77b81SRobert Mustacchi }
14365fc77b81SRobert Mustacchi 
14375fc77b81SRobert Mustacchi /**
14385fc77b81SRobert Mustacchi  *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
14395fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
14405fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to be written to
14415fc77b81SRobert Mustacchi  *  @data: 16 bit word to be written to the EEPROM
14425fc77b81SRobert Mustacchi  *
14435fc77b81SRobert Mustacchi  *  If ixgbe_eeprom_update_checksum is not called after this function, the
14445fc77b81SRobert Mustacchi  *  EEPROM will most likely contain an invalid checksum.
14455fc77b81SRobert Mustacchi  **/
ixgbe_write_eeprom_generic(struct ixgbe_hw * hw,u16 offset,u16 data)14465fc77b81SRobert Mustacchi s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
14475fc77b81SRobert Mustacchi {
14485fc77b81SRobert Mustacchi 	s32 status;
14495fc77b81SRobert Mustacchi 
14505fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_write_eeprom_generic");
14515fc77b81SRobert Mustacchi 
14525fc77b81SRobert Mustacchi 	hw->eeprom.ops.init_params(hw);
14535fc77b81SRobert Mustacchi 
14545fc77b81SRobert Mustacchi 	if (offset >= hw->eeprom.word_size) {
14555fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
14565fc77b81SRobert Mustacchi 		goto out;
14575fc77b81SRobert Mustacchi 	}
14585fc77b81SRobert Mustacchi 
14595fc77b81SRobert Mustacchi 	status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
14605fc77b81SRobert Mustacchi 
14615fc77b81SRobert Mustacchi out:
14625fc77b81SRobert Mustacchi 	return status;
14635fc77b81SRobert Mustacchi }
14645fc77b81SRobert Mustacchi 
14655fc77b81SRobert Mustacchi /**
14665fc77b81SRobert Mustacchi  *  ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
14675fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
14685fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to be read
14695fc77b81SRobert Mustacchi  *  @data: read 16 bit words(s) from EEPROM
14705fc77b81SRobert Mustacchi  *  @words: number of word(s)
14715fc77b81SRobert Mustacchi  *
14725fc77b81SRobert Mustacchi  *  Reads 16 bit word(s) from EEPROM through bit-bang method
14735fc77b81SRobert Mustacchi  **/
ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)14745fc77b81SRobert Mustacchi s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
14755fc77b81SRobert Mustacchi 					      u16 words, u16 *data)
14765fc77b81SRobert Mustacchi {
14775fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
14785fc77b81SRobert Mustacchi 	u16 i, count;
14795fc77b81SRobert Mustacchi 
14805fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang_generic");
14815fc77b81SRobert Mustacchi 
14825fc77b81SRobert Mustacchi 	hw->eeprom.ops.init_params(hw);
14835fc77b81SRobert Mustacchi 
14845fc77b81SRobert Mustacchi 	if (words == 0) {
14855fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_ARGUMENT;
14865fc77b81SRobert Mustacchi 		goto out;
14875fc77b81SRobert Mustacchi 	}
14885fc77b81SRobert Mustacchi 
14895fc77b81SRobert Mustacchi 	if (offset + words > hw->eeprom.word_size) {
14905fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
14915fc77b81SRobert Mustacchi 		goto out;
14925fc77b81SRobert Mustacchi 	}
14935fc77b81SRobert Mustacchi 
14945fc77b81SRobert Mustacchi 	/*
14955fc77b81SRobert Mustacchi 	 * We cannot hold synchronization semaphores for too long
14965fc77b81SRobert Mustacchi 	 * to avoid other entity starvation. However it is more efficient
14975fc77b81SRobert Mustacchi 	 * to read in bursts than synchronizing access for each word.
14985fc77b81SRobert Mustacchi 	 */
14995fc77b81SRobert Mustacchi 	for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
15005fc77b81SRobert Mustacchi 		count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
15015fc77b81SRobert Mustacchi 			IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
15025fc77b81SRobert Mustacchi 
15035fc77b81SRobert Mustacchi 		status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
15045fc77b81SRobert Mustacchi 							   count, &data[i]);
15055fc77b81SRobert Mustacchi 
15065fc77b81SRobert Mustacchi 		if (status != IXGBE_SUCCESS)
15075fc77b81SRobert Mustacchi 			break;
15085fc77b81SRobert Mustacchi 	}
15095fc77b81SRobert Mustacchi 
15105fc77b81SRobert Mustacchi out:
15115fc77b81SRobert Mustacchi 	return status;
15125fc77b81SRobert Mustacchi }
15135fc77b81SRobert Mustacchi 
15145fc77b81SRobert Mustacchi /**
15155fc77b81SRobert Mustacchi  *  ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
15165fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
15175fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to be read
15185fc77b81SRobert Mustacchi  *  @words: number of word(s)
15195fc77b81SRobert Mustacchi  *  @data: read 16 bit word(s) from EEPROM
15205fc77b81SRobert Mustacchi  *
15215fc77b81SRobert Mustacchi  *  Reads 16 bit word(s) from EEPROM through bit-bang method
15225fc77b81SRobert Mustacchi  **/
ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)15235fc77b81SRobert Mustacchi static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
15245fc77b81SRobert Mustacchi 					     u16 words, u16 *data)
15255fc77b81SRobert Mustacchi {
15265fc77b81SRobert Mustacchi 	s32 status;
15275fc77b81SRobert Mustacchi 	u16 word_in;
15285fc77b81SRobert Mustacchi 	u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
15295fc77b81SRobert Mustacchi 	u16 i;
15305fc77b81SRobert Mustacchi 
15315fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang");
15325fc77b81SRobert Mustacchi 
15335fc77b81SRobert Mustacchi 	/* Prepare the EEPROM for reading  */
15345fc77b81SRobert Mustacchi 	status = ixgbe_acquire_eeprom(hw);
15355fc77b81SRobert Mustacchi 
15365fc77b81SRobert Mustacchi 	if (status == IXGBE_SUCCESS) {
15375fc77b81SRobert Mustacchi 		if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) {
15385fc77b81SRobert Mustacchi 			ixgbe_release_eeprom(hw);
15395fc77b81SRobert Mustacchi 			status = IXGBE_ERR_EEPROM;
15405fc77b81SRobert Mustacchi 		}
15415fc77b81SRobert Mustacchi 	}
15425fc77b81SRobert Mustacchi 
15435fc77b81SRobert Mustacchi 	if (status == IXGBE_SUCCESS) {
15445fc77b81SRobert Mustacchi 		for (i = 0; i < words; i++) {
15455fc77b81SRobert Mustacchi 			ixgbe_standby_eeprom(hw);
15465fc77b81SRobert Mustacchi 			/*
15475fc77b81SRobert Mustacchi 			 * Some SPI eeproms use the 8th address bit embedded
15485fc77b81SRobert Mustacchi 			 * in the opcode
15495fc77b81SRobert Mustacchi 			 */
15505fc77b81SRobert Mustacchi 			if ((hw->eeprom.address_bits == 8) &&
15515fc77b81SRobert Mustacchi 			    ((offset + i) >= 128))
15525fc77b81SRobert Mustacchi 				read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
15535fc77b81SRobert Mustacchi 
15545fc77b81SRobert Mustacchi 			/* Send the READ command (opcode + addr) */
15555fc77b81SRobert Mustacchi 			ixgbe_shift_out_eeprom_bits(hw, read_opcode,
15565fc77b81SRobert Mustacchi 						    IXGBE_EEPROM_OPCODE_BITS);
15575fc77b81SRobert Mustacchi 			ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
15585fc77b81SRobert Mustacchi 						    hw->eeprom.address_bits);
15595fc77b81SRobert Mustacchi 
15605fc77b81SRobert Mustacchi 			/* Read the data. */
15615fc77b81SRobert Mustacchi 			word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
15625fc77b81SRobert Mustacchi 			data[i] = (word_in >> 8) | (word_in << 8);
15635fc77b81SRobert Mustacchi 		}
15645fc77b81SRobert Mustacchi 
15655fc77b81SRobert Mustacchi 		/* End this read operation */
15665fc77b81SRobert Mustacchi 		ixgbe_release_eeprom(hw);
15675fc77b81SRobert Mustacchi 	}
15685fc77b81SRobert Mustacchi 
15695fc77b81SRobert Mustacchi 	return status;
15705fc77b81SRobert Mustacchi }
15715fc77b81SRobert Mustacchi 
15725fc77b81SRobert Mustacchi /**
15735fc77b81SRobert Mustacchi  *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
15745fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
15755fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to be read
15765fc77b81SRobert Mustacchi  *  @data: read 16 bit value from EEPROM
15775fc77b81SRobert Mustacchi  *
15785fc77b81SRobert Mustacchi  *  Reads 16 bit value from EEPROM through bit-bang method
15795fc77b81SRobert Mustacchi  **/
ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw * hw,u16 offset,u16 * data)15805fc77b81SRobert Mustacchi s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
15815fc77b81SRobert Mustacchi 				       u16 *data)
15825fc77b81SRobert Mustacchi {
15835fc77b81SRobert Mustacchi 	s32 status;
15845fc77b81SRobert Mustacchi 
15855fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic");
15865fc77b81SRobert Mustacchi 
15875fc77b81SRobert Mustacchi 	hw->eeprom.ops.init_params(hw);
15885fc77b81SRobert Mustacchi 
15895fc77b81SRobert Mustacchi 	if (offset >= hw->eeprom.word_size) {
15905fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
15915fc77b81SRobert Mustacchi 		goto out;
15925fc77b81SRobert Mustacchi 	}
15935fc77b81SRobert Mustacchi 
15945fc77b81SRobert Mustacchi 	status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
15955fc77b81SRobert Mustacchi 
15965fc77b81SRobert Mustacchi out:
15975fc77b81SRobert Mustacchi 	return status;
15985fc77b81SRobert Mustacchi }
15995fc77b81SRobert Mustacchi 
16005fc77b81SRobert Mustacchi /**
16015fc77b81SRobert Mustacchi  *  ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
16025fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
16035fc77b81SRobert Mustacchi  *  @offset: offset of word in the EEPROM to read
16045fc77b81SRobert Mustacchi  *  @words: number of word(s)
16055fc77b81SRobert Mustacchi  *  @data: 16 bit word(s) from the EEPROM
16065fc77b81SRobert Mustacchi  *
16075fc77b81SRobert Mustacchi  *  Reads a 16 bit word(s) from the EEPROM using the EERD register.
16085fc77b81SRobert Mustacchi  **/
ixgbe_read_eerd_buffer_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)16095fc77b81SRobert Mustacchi s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
16105fc77b81SRobert Mustacchi 				   u16 words, u16 *data)
16115fc77b81SRobert Mustacchi {
16125fc77b81SRobert Mustacchi 	u32 eerd;
16135fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
16145fc77b81SRobert Mustacchi 	u32 i;
16155fc77b81SRobert Mustacchi 
16165fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_read_eerd_buffer_generic");
16175fc77b81SRobert Mustacchi 
16185fc77b81SRobert Mustacchi 	hw->eeprom.ops.init_params(hw);
16195fc77b81SRobert Mustacchi 
16205fc77b81SRobert Mustacchi 	if (words == 0) {
16215fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_ARGUMENT;
1622dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
16235fc77b81SRobert Mustacchi 		goto out;
16245fc77b81SRobert Mustacchi 	}
16255fc77b81SRobert Mustacchi 
16265fc77b81SRobert Mustacchi 	if (offset >= hw->eeprom.word_size) {
16275fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
1628dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
16295fc77b81SRobert Mustacchi 		goto out;
16305fc77b81SRobert Mustacchi 	}
16315fc77b81SRobert Mustacchi 
16325fc77b81SRobert Mustacchi 	for (i = 0; i < words; i++) {
1633dc0cb1cdSDale Ghent 		eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
16345fc77b81SRobert Mustacchi 		       IXGBE_EEPROM_RW_REG_START;
16355fc77b81SRobert Mustacchi 
16365fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
16375fc77b81SRobert Mustacchi 		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
16385fc77b81SRobert Mustacchi 
16395fc77b81SRobert Mustacchi 		if (status == IXGBE_SUCCESS) {
16405fc77b81SRobert Mustacchi 			data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
16415fc77b81SRobert Mustacchi 				   IXGBE_EEPROM_RW_REG_DATA);
16425fc77b81SRobert Mustacchi 		} else {
16435fc77b81SRobert Mustacchi 			DEBUGOUT("Eeprom read timed out\n");
16445fc77b81SRobert Mustacchi 			goto out;
16455fc77b81SRobert Mustacchi 		}
16465fc77b81SRobert Mustacchi 	}
16475fc77b81SRobert Mustacchi out:
16485fc77b81SRobert Mustacchi 	return status;
16495fc77b81SRobert Mustacchi }
16505fc77b81SRobert Mustacchi 
16515fc77b81SRobert Mustacchi /**
16525fc77b81SRobert Mustacchi  *  ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
16535fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
16545fc77b81SRobert Mustacchi  *  @offset: offset within the EEPROM to be used as a scratch pad
16555fc77b81SRobert Mustacchi  *
16565fc77b81SRobert Mustacchi  *  Discover EEPROM page size by writing marching data at given offset.
16575fc77b81SRobert Mustacchi  *  This function is called only when we are writing a new large buffer
16585fc77b81SRobert Mustacchi  *  at given offset so the data would be overwritten anyway.
16595fc77b81SRobert Mustacchi  **/
ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw * hw,u16 offset)16605fc77b81SRobert Mustacchi static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
16615fc77b81SRobert Mustacchi 						 u16 offset)
16625fc77b81SRobert Mustacchi {
16635fc77b81SRobert Mustacchi 	u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
16645fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
16655fc77b81SRobert Mustacchi 	u16 i;
16665fc77b81SRobert Mustacchi 
16675fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_detect_eeprom_page_size_generic");
16685fc77b81SRobert Mustacchi 
16695fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
16705fc77b81SRobert Mustacchi 		data[i] = i;
16715fc77b81SRobert Mustacchi 
16725fc77b81SRobert Mustacchi 	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
16735fc77b81SRobert Mustacchi 	status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
16745fc77b81SRobert Mustacchi 					     IXGBE_EEPROM_PAGE_SIZE_MAX, data);
16755fc77b81SRobert Mustacchi 	hw->eeprom.word_page_size = 0;
16765fc77b81SRobert Mustacchi 	if (status != IXGBE_SUCCESS)
16775fc77b81SRobert Mustacchi 		goto out;
16785fc77b81SRobert Mustacchi 
16795fc77b81SRobert Mustacchi 	status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
16805fc77b81SRobert Mustacchi 	if (status != IXGBE_SUCCESS)
16815fc77b81SRobert Mustacchi 		goto out;
16825fc77b81SRobert Mustacchi 
16835fc77b81SRobert Mustacchi 	/*
16845fc77b81SRobert Mustacchi 	 * When writing in burst more than the actual page size
16855fc77b81SRobert Mustacchi 	 * EEPROM address wraps around current page.
16865fc77b81SRobert Mustacchi 	 */
16875fc77b81SRobert Mustacchi 	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
16885fc77b81SRobert Mustacchi 
16895fc77b81SRobert Mustacchi 	DEBUGOUT1("Detected EEPROM page size = %d words.",
16905fc77b81SRobert Mustacchi 		  hw->eeprom.word_page_size);
16915fc77b81SRobert Mustacchi out:
16925fc77b81SRobert Mustacchi 	return status;
16935fc77b81SRobert Mustacchi }
16945fc77b81SRobert Mustacchi 
16955fc77b81SRobert Mustacchi /**
16965fc77b81SRobert Mustacchi  *  ixgbe_read_eerd_generic - Read EEPROM word using EERD
16975fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
16985fc77b81SRobert Mustacchi  *  @offset: offset of  word in the EEPROM to read
16995fc77b81SRobert Mustacchi  *  @data: word read from the EEPROM
17005fc77b81SRobert Mustacchi  *
17015fc77b81SRobert Mustacchi  *  Reads a 16 bit word from the EEPROM using the EERD register.
17025fc77b81SRobert Mustacchi  **/
ixgbe_read_eerd_generic(struct ixgbe_hw * hw,u16 offset,u16 * data)17035fc77b81SRobert Mustacchi s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
17045fc77b81SRobert Mustacchi {
17055fc77b81SRobert Mustacchi 	return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
17065fc77b81SRobert Mustacchi }
17075fc77b81SRobert Mustacchi 
17085fc77b81SRobert Mustacchi /**
17095fc77b81SRobert Mustacchi  *  ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
17105fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
17115fc77b81SRobert Mustacchi  *  @offset: offset of  word in the EEPROM to write
17125fc77b81SRobert Mustacchi  *  @words: number of word(s)
17135fc77b81SRobert Mustacchi  *  @data: word(s) write to the EEPROM
17145fc77b81SRobert Mustacchi  *
17155fc77b81SRobert Mustacchi  *  Write a 16 bit word(s) to the EEPROM using the EEWR register.
17165fc77b81SRobert Mustacchi  **/
ixgbe_write_eewr_buffer_generic(struct ixgbe_hw * hw,u16 offset,u16 words,u16 * data)17175fc77b81SRobert Mustacchi s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
17185fc77b81SRobert Mustacchi 				    u16 words, u16 *data)
17195fc77b81SRobert Mustacchi {
17205fc77b81SRobert Mustacchi 	u32 eewr;
17215fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
17225fc77b81SRobert Mustacchi 	u16 i;
17235fc77b81SRobert Mustacchi 
17245fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_write_eewr_generic");
17255fc77b81SRobert Mustacchi 
17265fc77b81SRobert Mustacchi 	hw->eeprom.ops.init_params(hw);
17275fc77b81SRobert Mustacchi 
17285fc77b81SRobert Mustacchi 	if (words == 0) {
17295fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_ARGUMENT;
1730dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
17315fc77b81SRobert Mustacchi 		goto out;
17325fc77b81SRobert Mustacchi 	}
17335fc77b81SRobert Mustacchi 
17345fc77b81SRobert Mustacchi 	if (offset >= hw->eeprom.word_size) {
17355fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
1736dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
17375fc77b81SRobert Mustacchi 		goto out;
17385fc77b81SRobert Mustacchi 	}
17395fc77b81SRobert Mustacchi 
17405fc77b81SRobert Mustacchi 	for (i = 0; i < words; i++) {
17415fc77b81SRobert Mustacchi 		eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
17425fc77b81SRobert Mustacchi 			(data[i] << IXGBE_EEPROM_RW_REG_DATA) |
17435fc77b81SRobert Mustacchi 			IXGBE_EEPROM_RW_REG_START;
17445fc77b81SRobert Mustacchi 
17455fc77b81SRobert Mustacchi 		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
17465fc77b81SRobert Mustacchi 		if (status != IXGBE_SUCCESS) {
17475fc77b81SRobert Mustacchi 			DEBUGOUT("Eeprom write EEWR timed out\n");
17485fc77b81SRobert Mustacchi 			goto out;
17495fc77b81SRobert Mustacchi 		}
17505fc77b81SRobert Mustacchi 
17515fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
17525fc77b81SRobert Mustacchi 
17535fc77b81SRobert Mustacchi 		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
17545fc77b81SRobert Mustacchi 		if (status != IXGBE_SUCCESS) {
17555fc77b81SRobert Mustacchi 			DEBUGOUT("Eeprom write EEWR timed out\n");
17565fc77b81SRobert Mustacchi 			goto out;
17575fc77b81SRobert Mustacchi 		}
17585fc77b81SRobert Mustacchi 	}
17595fc77b81SRobert Mustacchi 
17605fc77b81SRobert Mustacchi out:
17615fc77b81SRobert Mustacchi 	return status;
17625fc77b81SRobert Mustacchi }
17635fc77b81SRobert Mustacchi 
17645fc77b81SRobert Mustacchi /**
17655fc77b81SRobert Mustacchi  *  ixgbe_write_eewr_generic - Write EEPROM word using EEWR
17665fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
17675fc77b81SRobert Mustacchi  *  @offset: offset of  word in the EEPROM to write
17685fc77b81SRobert Mustacchi  *  @data: word write to the EEPROM
17695fc77b81SRobert Mustacchi  *
17705fc77b81SRobert Mustacchi  *  Write a 16 bit word to the EEPROM using the EEWR register.
17715fc77b81SRobert Mustacchi  **/
ixgbe_write_eewr_generic(struct ixgbe_hw * hw,u16 offset,u16 data)17725fc77b81SRobert Mustacchi s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
17735fc77b81SRobert Mustacchi {
17745fc77b81SRobert Mustacchi 	return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
17755fc77b81SRobert Mustacchi }
17765fc77b81SRobert Mustacchi 
17775fc77b81SRobert Mustacchi /**
17785fc77b81SRobert Mustacchi  *  ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
17795fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
17805fc77b81SRobert Mustacchi  *  @ee_reg: EEPROM flag for polling
17815fc77b81SRobert Mustacchi  *
17825fc77b81SRobert Mustacchi  *  Polls the status bit (bit 1) of the EERD or EEWR to determine when the
17835fc77b81SRobert Mustacchi  *  read or write is done respectively.
17845fc77b81SRobert Mustacchi  **/
ixgbe_poll_eerd_eewr_done(struct ixgbe_hw * hw,u32 ee_reg)17855fc77b81SRobert Mustacchi s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
17865fc77b81SRobert Mustacchi {
17875fc77b81SRobert Mustacchi 	u32 i;
17885fc77b81SRobert Mustacchi 	u32 reg;
17895fc77b81SRobert Mustacchi 	s32 status = IXGBE_ERR_EEPROM;
17905fc77b81SRobert Mustacchi 
17915fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_poll_eerd_eewr_done");
17925fc77b81SRobert Mustacchi 
17935fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) {
17945fc77b81SRobert Mustacchi 		if (ee_reg == IXGBE_NVM_POLL_READ)
17955fc77b81SRobert Mustacchi 			reg = IXGBE_READ_REG(hw, IXGBE_EERD);
17965fc77b81SRobert Mustacchi 		else
17975fc77b81SRobert Mustacchi 			reg = IXGBE_READ_REG(hw, IXGBE_EEWR);
17985fc77b81SRobert Mustacchi 
17995fc77b81SRobert Mustacchi 		if (reg & IXGBE_EEPROM_RW_REG_DONE) {
18005fc77b81SRobert Mustacchi 			status = IXGBE_SUCCESS;
18015fc77b81SRobert Mustacchi 			break;
18025fc77b81SRobert Mustacchi 		}
18035fc77b81SRobert Mustacchi 		usec_delay(5);
18045fc77b81SRobert Mustacchi 	}
1805dc0cb1cdSDale Ghent 
1806dc0cb1cdSDale Ghent 	if (i == IXGBE_EERD_EEWR_ATTEMPTS)
1807dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
1808dc0cb1cdSDale Ghent 			     "EEPROM read/write done polling timed out");
1809dc0cb1cdSDale Ghent 
18105fc77b81SRobert Mustacchi 	return status;
18115fc77b81SRobert Mustacchi }
18125fc77b81SRobert Mustacchi 
18135fc77b81SRobert Mustacchi /**
18145fc77b81SRobert Mustacchi  *  ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
18155fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
18165fc77b81SRobert Mustacchi  *
18175fc77b81SRobert Mustacchi  *  Prepares EEPROM for access using bit-bang method. This function should
18185fc77b81SRobert Mustacchi  *  be called before issuing a command to the EEPROM.
18195fc77b81SRobert Mustacchi  **/
ixgbe_acquire_eeprom(struct ixgbe_hw * hw)18205fc77b81SRobert Mustacchi static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
18215fc77b81SRobert Mustacchi {
18225fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
18235fc77b81SRobert Mustacchi 	u32 eec;
18245fc77b81SRobert Mustacchi 	u32 i;
18255fc77b81SRobert Mustacchi 
18265fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_acquire_eeprom");
18275fc77b81SRobert Mustacchi 
18285fc77b81SRobert Mustacchi 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)
18295fc77b81SRobert Mustacchi 	    != IXGBE_SUCCESS)
18305fc77b81SRobert Mustacchi 		status = IXGBE_ERR_SWFW_SYNC;
18315fc77b81SRobert Mustacchi 
18325fc77b81SRobert Mustacchi 	if (status == IXGBE_SUCCESS) {
1833dc0cb1cdSDale Ghent 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
18345fc77b81SRobert Mustacchi 
18355fc77b81SRobert Mustacchi 		/* Request EEPROM Access */
18365fc77b81SRobert Mustacchi 		eec |= IXGBE_EEC_REQ;
1837dc0cb1cdSDale Ghent 		IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
18385fc77b81SRobert Mustacchi 
18395fc77b81SRobert Mustacchi 		for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
1840dc0cb1cdSDale Ghent 			eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
18415fc77b81SRobert Mustacchi 			if (eec & IXGBE_EEC_GNT)
18425fc77b81SRobert Mustacchi 				break;
18435fc77b81SRobert Mustacchi 			usec_delay(5);
18445fc77b81SRobert Mustacchi 		}
18455fc77b81SRobert Mustacchi 
18465fc77b81SRobert Mustacchi 		/* Release if grant not acquired */
18475fc77b81SRobert Mustacchi 		if (!(eec & IXGBE_EEC_GNT)) {
18485fc77b81SRobert Mustacchi 			eec &= ~IXGBE_EEC_REQ;
1849dc0cb1cdSDale Ghent 			IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
18505fc77b81SRobert Mustacchi 			DEBUGOUT("Could not acquire EEPROM grant\n");
18515fc77b81SRobert Mustacchi 
18525fc77b81SRobert Mustacchi 			hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
18535fc77b81SRobert Mustacchi 			status = IXGBE_ERR_EEPROM;
18545fc77b81SRobert Mustacchi 		}
18555fc77b81SRobert Mustacchi 
18565fc77b81SRobert Mustacchi 		/* Setup EEPROM for Read/Write */
18575fc77b81SRobert Mustacchi 		if (status == IXGBE_SUCCESS) {
18585fc77b81SRobert Mustacchi 			/* Clear CS and SK */
18595fc77b81SRobert Mustacchi 			eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
1860dc0cb1cdSDale Ghent 			IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
18615fc77b81SRobert Mustacchi 			IXGBE_WRITE_FLUSH(hw);
18625fc77b81SRobert Mustacchi 			usec_delay(1);
18635fc77b81SRobert Mustacchi 		}
18645fc77b81SRobert Mustacchi 	}
18655fc77b81SRobert Mustacchi 	return status;
18665fc77b81SRobert Mustacchi }
18675fc77b81SRobert Mustacchi 
18685fc77b81SRobert Mustacchi /**
18695fc77b81SRobert Mustacchi  *  ixgbe_get_eeprom_semaphore - Get hardware semaphore
18705fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
18715fc77b81SRobert Mustacchi  *
18725fc77b81SRobert Mustacchi  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
18735fc77b81SRobert Mustacchi  **/
ixgbe_get_eeprom_semaphore(struct ixgbe_hw * hw)18745fc77b81SRobert Mustacchi static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
18755fc77b81SRobert Mustacchi {
18765fc77b81SRobert Mustacchi 	s32 status = IXGBE_ERR_EEPROM;
18775fc77b81SRobert Mustacchi 	u32 timeout = 2000;
18785fc77b81SRobert Mustacchi 	u32 i;
18795fc77b81SRobert Mustacchi 	u32 swsm;
18805fc77b81SRobert Mustacchi 
18815fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_eeprom_semaphore");
18825fc77b81SRobert Mustacchi 
18835fc77b81SRobert Mustacchi 
18845fc77b81SRobert Mustacchi 	/* Get SMBI software semaphore between device drivers first */
18855fc77b81SRobert Mustacchi 	for (i = 0; i < timeout; i++) {
18865fc77b81SRobert Mustacchi 		/*
18875fc77b81SRobert Mustacchi 		 * If the SMBI bit is 0 when we read it, then the bit will be
18885fc77b81SRobert Mustacchi 		 * set and we have the semaphore
18895fc77b81SRobert Mustacchi 		 */
1890dc0cb1cdSDale Ghent 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
18915fc77b81SRobert Mustacchi 		if (!(swsm & IXGBE_SWSM_SMBI)) {
18925fc77b81SRobert Mustacchi 			status = IXGBE_SUCCESS;
18935fc77b81SRobert Mustacchi 			break;
18945fc77b81SRobert Mustacchi 		}
18955fc77b81SRobert Mustacchi 		usec_delay(50);
18965fc77b81SRobert Mustacchi 	}
18975fc77b81SRobert Mustacchi 
18985fc77b81SRobert Mustacchi 	if (i == timeout) {
18995fc77b81SRobert Mustacchi 		DEBUGOUT("Driver can't access the Eeprom - SMBI Semaphore "
19005fc77b81SRobert Mustacchi 			 "not granted.\n");
19015fc77b81SRobert Mustacchi 		/*
19025fc77b81SRobert Mustacchi 		 * this release is particularly important because our attempts
19035fc77b81SRobert Mustacchi 		 * above to get the semaphore may have succeeded, and if there
19045fc77b81SRobert Mustacchi 		 * was a timeout, we should unconditionally clear the semaphore
19055fc77b81SRobert Mustacchi 		 * bits to free the driver to make progress
19065fc77b81SRobert Mustacchi 		 */
19075fc77b81SRobert Mustacchi 		ixgbe_release_eeprom_semaphore(hw);
19085fc77b81SRobert Mustacchi 
19095fc77b81SRobert Mustacchi 		usec_delay(50);
19105fc77b81SRobert Mustacchi 		/*
19115fc77b81SRobert Mustacchi 		 * one last try
19125fc77b81SRobert Mustacchi 		 * If the SMBI bit is 0 when we read it, then the bit will be
19135fc77b81SRobert Mustacchi 		 * set and we have the semaphore
19145fc77b81SRobert Mustacchi 		 */
1915dc0cb1cdSDale Ghent 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
19165fc77b81SRobert Mustacchi 		if (!(swsm & IXGBE_SWSM_SMBI))
19175fc77b81SRobert Mustacchi 			status = IXGBE_SUCCESS;
19185fc77b81SRobert Mustacchi 	}
19195fc77b81SRobert Mustacchi 
19205fc77b81SRobert Mustacchi 	/* Now get the semaphore between SW/FW through the SWESMBI bit */
19215fc77b81SRobert Mustacchi 	if (status == IXGBE_SUCCESS) {
19225fc77b81SRobert Mustacchi 		for (i = 0; i < timeout; i++) {
1923dc0cb1cdSDale Ghent 			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
19245fc77b81SRobert Mustacchi 
19255fc77b81SRobert Mustacchi 			/* Set the SW EEPROM semaphore bit to request access */
19265fc77b81SRobert Mustacchi 			swsm |= IXGBE_SWSM_SWESMBI;
1927dc0cb1cdSDale Ghent 			IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm);
19285fc77b81SRobert Mustacchi 
19295fc77b81SRobert Mustacchi 			/*
19305fc77b81SRobert Mustacchi 			 * If we set the bit successfully then we got the
19315fc77b81SRobert Mustacchi 			 * semaphore.
19325fc77b81SRobert Mustacchi 			 */
1933dc0cb1cdSDale Ghent 			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
19345fc77b81SRobert Mustacchi 			if (swsm & IXGBE_SWSM_SWESMBI)
19355fc77b81SRobert Mustacchi 				break;
19365fc77b81SRobert Mustacchi 
19375fc77b81SRobert Mustacchi 			usec_delay(50);
19385fc77b81SRobert Mustacchi 		}
19395fc77b81SRobert Mustacchi 
19405fc77b81SRobert Mustacchi 		/*
19415fc77b81SRobert Mustacchi 		 * Release semaphores and return error if SW EEPROM semaphore
19425fc77b81SRobert Mustacchi 		 * was not granted because we don't have access to the EEPROM
19435fc77b81SRobert Mustacchi 		 */
19445fc77b81SRobert Mustacchi 		if (i >= timeout) {
1945dc0cb1cdSDale Ghent 			ERROR_REPORT1(IXGBE_ERROR_POLLING,
1946dc0cb1cdSDale Ghent 			    "SWESMBI Software EEPROM semaphore not granted.\n");
19475fc77b81SRobert Mustacchi 			ixgbe_release_eeprom_semaphore(hw);
19485fc77b81SRobert Mustacchi 			status = IXGBE_ERR_EEPROM;
19495fc77b81SRobert Mustacchi 		}
19505fc77b81SRobert Mustacchi 	} else {
1951dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_POLLING,
1952dc0cb1cdSDale Ghent 			     "Software semaphore SMBI between device drivers "
19535fc77b81SRobert Mustacchi 			     "not granted.\n");
19545fc77b81SRobert Mustacchi 	}
19555fc77b81SRobert Mustacchi 
19565fc77b81SRobert Mustacchi 	return status;
19575fc77b81SRobert Mustacchi }
19585fc77b81SRobert Mustacchi 
19595fc77b81SRobert Mustacchi /**
19605fc77b81SRobert Mustacchi  *  ixgbe_release_eeprom_semaphore - Release hardware semaphore
19615fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
19625fc77b81SRobert Mustacchi  *
19635fc77b81SRobert Mustacchi  *  This function clears hardware semaphore bits.
19645fc77b81SRobert Mustacchi  **/
ixgbe_release_eeprom_semaphore(struct ixgbe_hw * hw)19655fc77b81SRobert Mustacchi static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
19665fc77b81SRobert Mustacchi {
19675fc77b81SRobert Mustacchi 	u32 swsm;
19685fc77b81SRobert Mustacchi 
19695fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_release_eeprom_semaphore");
19705fc77b81SRobert Mustacchi 
19715fc77b81SRobert Mustacchi 	swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
19725fc77b81SRobert Mustacchi 
19735fc77b81SRobert Mustacchi 	/* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
19745fc77b81SRobert Mustacchi 	swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
19755fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
19765fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
19775fc77b81SRobert Mustacchi }
19785fc77b81SRobert Mustacchi 
19795fc77b81SRobert Mustacchi /**
19805fc77b81SRobert Mustacchi  *  ixgbe_ready_eeprom - Polls for EEPROM ready
19815fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
19825fc77b81SRobert Mustacchi  **/
ixgbe_ready_eeprom(struct ixgbe_hw * hw)19835fc77b81SRobert Mustacchi static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
19845fc77b81SRobert Mustacchi {
19855fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
19865fc77b81SRobert Mustacchi 	u16 i;
19875fc77b81SRobert Mustacchi 	u8 spi_stat_reg;
19885fc77b81SRobert Mustacchi 
19895fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_ready_eeprom");
19905fc77b81SRobert Mustacchi 
19915fc77b81SRobert Mustacchi 	/*
19925fc77b81SRobert Mustacchi 	 * Read "Status Register" repeatedly until the LSB is cleared.  The
19935fc77b81SRobert Mustacchi 	 * EEPROM will signal that the command has been completed by clearing
19945fc77b81SRobert Mustacchi 	 * bit 0 of the internal status register.  If it's not cleared within
19955fc77b81SRobert Mustacchi 	 * 5 milliseconds, then error out.
19965fc77b81SRobert Mustacchi 	 */
19975fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
19985fc77b81SRobert Mustacchi 		ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
19995fc77b81SRobert Mustacchi 					    IXGBE_EEPROM_OPCODE_BITS);
20005fc77b81SRobert Mustacchi 		spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
20015fc77b81SRobert Mustacchi 		if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
20025fc77b81SRobert Mustacchi 			break;
20035fc77b81SRobert Mustacchi 
20045fc77b81SRobert Mustacchi 		usec_delay(5);
20055fc77b81SRobert Mustacchi 		ixgbe_standby_eeprom(hw);
2006dc0cb1cdSDale Ghent 	}
20075fc77b81SRobert Mustacchi 
20085fc77b81SRobert Mustacchi 	/*
20095fc77b81SRobert Mustacchi 	 * On some parts, SPI write time could vary from 0-20mSec on 3.3V
20105fc77b81SRobert Mustacchi 	 * devices (and only 0-5mSec on 5V devices)
20115fc77b81SRobert Mustacchi 	 */
20125fc77b81SRobert Mustacchi 	if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
20135fc77b81SRobert Mustacchi 		DEBUGOUT("SPI EEPROM Status error\n");
20145fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM;
20155fc77b81SRobert Mustacchi 	}
20165fc77b81SRobert Mustacchi 
20175fc77b81SRobert Mustacchi 	return status;
20185fc77b81SRobert Mustacchi }
20195fc77b81SRobert Mustacchi 
20205fc77b81SRobert Mustacchi /**
20215fc77b81SRobert Mustacchi  *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
20225fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
20235fc77b81SRobert Mustacchi  **/
ixgbe_standby_eeprom(struct ixgbe_hw * hw)20245fc77b81SRobert Mustacchi static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
20255fc77b81SRobert Mustacchi {
20265fc77b81SRobert Mustacchi 	u32 eec;
20275fc77b81SRobert Mustacchi 
20285fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_standby_eeprom");
20295fc77b81SRobert Mustacchi 
2030dc0cb1cdSDale Ghent 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
20315fc77b81SRobert Mustacchi 
20325fc77b81SRobert Mustacchi 	/* Toggle CS to flush commands */
20335fc77b81SRobert Mustacchi 	eec |= IXGBE_EEC_CS;
2034dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
20355fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
20365fc77b81SRobert Mustacchi 	usec_delay(1);
20375fc77b81SRobert Mustacchi 	eec &= ~IXGBE_EEC_CS;
2038dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
20395fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
20405fc77b81SRobert Mustacchi 	usec_delay(1);
20415fc77b81SRobert Mustacchi }
20425fc77b81SRobert Mustacchi 
20435fc77b81SRobert Mustacchi /**
20445fc77b81SRobert Mustacchi  *  ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
20455fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
20465fc77b81SRobert Mustacchi  *  @data: data to send to the EEPROM
20475fc77b81SRobert Mustacchi  *  @count: number of bits to shift out
20485fc77b81SRobert Mustacchi  **/
ixgbe_shift_out_eeprom_bits(struct ixgbe_hw * hw,u16 data,u16 count)20495fc77b81SRobert Mustacchi static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
20505fc77b81SRobert Mustacchi 					u16 count)
20515fc77b81SRobert Mustacchi {
20525fc77b81SRobert Mustacchi 	u32 eec;
20535fc77b81SRobert Mustacchi 	u32 mask;
20545fc77b81SRobert Mustacchi 	u32 i;
20555fc77b81SRobert Mustacchi 
20565fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_shift_out_eeprom_bits");
20575fc77b81SRobert Mustacchi 
2058dc0cb1cdSDale Ghent 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
20595fc77b81SRobert Mustacchi 
20605fc77b81SRobert Mustacchi 	/*
20615fc77b81SRobert Mustacchi 	 * Mask is used to shift "count" bits of "data" out to the EEPROM
20625fc77b81SRobert Mustacchi 	 * one bit at a time.  Determine the starting bit based on count
20635fc77b81SRobert Mustacchi 	 */
20645fc77b81SRobert Mustacchi 	mask = 0x01 << (count - 1);
20655fc77b81SRobert Mustacchi 
20665fc77b81SRobert Mustacchi 	for (i = 0; i < count; i++) {
20675fc77b81SRobert Mustacchi 		/*
20685fc77b81SRobert Mustacchi 		 * A "1" is shifted out to the EEPROM by setting bit "DI" to a
20695fc77b81SRobert Mustacchi 		 * "1", and then raising and then lowering the clock (the SK
20705fc77b81SRobert Mustacchi 		 * bit controls the clock input to the EEPROM).  A "0" is
20715fc77b81SRobert Mustacchi 		 * shifted out to the EEPROM by setting "DI" to "0" and then
20725fc77b81SRobert Mustacchi 		 * raising and then lowering the clock.
20735fc77b81SRobert Mustacchi 		 */
20745fc77b81SRobert Mustacchi 		if (data & mask)
20755fc77b81SRobert Mustacchi 			eec |= IXGBE_EEC_DI;
20765fc77b81SRobert Mustacchi 		else
20775fc77b81SRobert Mustacchi 			eec &= ~IXGBE_EEC_DI;
20785fc77b81SRobert Mustacchi 
2079dc0cb1cdSDale Ghent 		IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
20805fc77b81SRobert Mustacchi 		IXGBE_WRITE_FLUSH(hw);
20815fc77b81SRobert Mustacchi 
20825fc77b81SRobert Mustacchi 		usec_delay(1);
20835fc77b81SRobert Mustacchi 
20845fc77b81SRobert Mustacchi 		ixgbe_raise_eeprom_clk(hw, &eec);
20855fc77b81SRobert Mustacchi 		ixgbe_lower_eeprom_clk(hw, &eec);
20865fc77b81SRobert Mustacchi 
20875fc77b81SRobert Mustacchi 		/*
20885fc77b81SRobert Mustacchi 		 * Shift mask to signify next bit of data to shift in to the
20895fc77b81SRobert Mustacchi 		 * EEPROM
20905fc77b81SRobert Mustacchi 		 */
20915fc77b81SRobert Mustacchi 		mask = mask >> 1;
2092dc0cb1cdSDale Ghent 	}
20935fc77b81SRobert Mustacchi 
20945fc77b81SRobert Mustacchi 	/* We leave the "DI" bit set to "0" when we leave this routine. */
20955fc77b81SRobert Mustacchi 	eec &= ~IXGBE_EEC_DI;
2096dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
20975fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
20985fc77b81SRobert Mustacchi }
20995fc77b81SRobert Mustacchi 
21005fc77b81SRobert Mustacchi /**
21015fc77b81SRobert Mustacchi  *  ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
21025fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
2103*48ed61a7SRobert Mustacchi  *  @count: number of bits to shift
21045fc77b81SRobert Mustacchi  **/
ixgbe_shift_in_eeprom_bits(struct ixgbe_hw * hw,u16 count)21055fc77b81SRobert Mustacchi static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
21065fc77b81SRobert Mustacchi {
21075fc77b81SRobert Mustacchi 	u32 eec;
21085fc77b81SRobert Mustacchi 	u32 i;
21095fc77b81SRobert Mustacchi 	u16 data = 0;
21105fc77b81SRobert Mustacchi 
21115fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_shift_in_eeprom_bits");
21125fc77b81SRobert Mustacchi 
21135fc77b81SRobert Mustacchi 	/*
21145fc77b81SRobert Mustacchi 	 * In order to read a register from the EEPROM, we need to shift
21155fc77b81SRobert Mustacchi 	 * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
21165fc77b81SRobert Mustacchi 	 * the clock input to the EEPROM (setting the SK bit), and then reading
21175fc77b81SRobert Mustacchi 	 * the value of the "DO" bit.  During this "shifting in" process the
21185fc77b81SRobert Mustacchi 	 * "DI" bit should always be clear.
21195fc77b81SRobert Mustacchi 	 */
2120dc0cb1cdSDale Ghent 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
21215fc77b81SRobert Mustacchi 
21225fc77b81SRobert Mustacchi 	eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
21235fc77b81SRobert Mustacchi 
21245fc77b81SRobert Mustacchi 	for (i = 0; i < count; i++) {
21255fc77b81SRobert Mustacchi 		data = data << 1;
21265fc77b81SRobert Mustacchi 		ixgbe_raise_eeprom_clk(hw, &eec);
21275fc77b81SRobert Mustacchi 
2128dc0cb1cdSDale Ghent 		eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
21295fc77b81SRobert Mustacchi 
21305fc77b81SRobert Mustacchi 		eec &= ~(IXGBE_EEC_DI);
21315fc77b81SRobert Mustacchi 		if (eec & IXGBE_EEC_DO)
21325fc77b81SRobert Mustacchi 			data |= 1;
21335fc77b81SRobert Mustacchi 
21345fc77b81SRobert Mustacchi 		ixgbe_lower_eeprom_clk(hw, &eec);
21355fc77b81SRobert Mustacchi 	}
21365fc77b81SRobert Mustacchi 
21375fc77b81SRobert Mustacchi 	return data;
21385fc77b81SRobert Mustacchi }
21395fc77b81SRobert Mustacchi 
21405fc77b81SRobert Mustacchi /**
21415fc77b81SRobert Mustacchi  *  ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
21425fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
21435fc77b81SRobert Mustacchi  *  @eec: EEC register's current value
21445fc77b81SRobert Mustacchi  **/
ixgbe_raise_eeprom_clk(struct ixgbe_hw * hw,u32 * eec)21455fc77b81SRobert Mustacchi static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
21465fc77b81SRobert Mustacchi {
21475fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_raise_eeprom_clk");
21485fc77b81SRobert Mustacchi 
21495fc77b81SRobert Mustacchi 	/*
21505fc77b81SRobert Mustacchi 	 * Raise the clock input to the EEPROM
21515fc77b81SRobert Mustacchi 	 * (setting the SK bit), then delay
21525fc77b81SRobert Mustacchi 	 */
21535fc77b81SRobert Mustacchi 	*eec = *eec | IXGBE_EEC_SK;
2154dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec);
21555fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
21565fc77b81SRobert Mustacchi 	usec_delay(1);
21575fc77b81SRobert Mustacchi }
21585fc77b81SRobert Mustacchi 
21595fc77b81SRobert Mustacchi /**
21605fc77b81SRobert Mustacchi  *  ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
21615fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
2162*48ed61a7SRobert Mustacchi  *  @eec: EEC's current value
21635fc77b81SRobert Mustacchi  **/
ixgbe_lower_eeprom_clk(struct ixgbe_hw * hw,u32 * eec)21645fc77b81SRobert Mustacchi static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
21655fc77b81SRobert Mustacchi {
21665fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_lower_eeprom_clk");
21675fc77b81SRobert Mustacchi 
21685fc77b81SRobert Mustacchi 	/*
21695fc77b81SRobert Mustacchi 	 * Lower the clock input to the EEPROM (clearing the SK bit), then
21705fc77b81SRobert Mustacchi 	 * delay
21715fc77b81SRobert Mustacchi 	 */
21725fc77b81SRobert Mustacchi 	*eec = *eec & ~IXGBE_EEC_SK;
2173dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), *eec);
21745fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
21755fc77b81SRobert Mustacchi 	usec_delay(1);
21765fc77b81SRobert Mustacchi }
21775fc77b81SRobert Mustacchi 
21785fc77b81SRobert Mustacchi /**
21795fc77b81SRobert Mustacchi  *  ixgbe_release_eeprom - Release EEPROM, release semaphores
21805fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
21815fc77b81SRobert Mustacchi  **/
ixgbe_release_eeprom(struct ixgbe_hw * hw)21825fc77b81SRobert Mustacchi static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
21835fc77b81SRobert Mustacchi {
21845fc77b81SRobert Mustacchi 	u32 eec;
21855fc77b81SRobert Mustacchi 
21865fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_release_eeprom");
21875fc77b81SRobert Mustacchi 
2188dc0cb1cdSDale Ghent 	eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
21895fc77b81SRobert Mustacchi 
21905fc77b81SRobert Mustacchi 	eec |= IXGBE_EEC_CS;  /* Pull CS high */
21915fc77b81SRobert Mustacchi 	eec &= ~IXGBE_EEC_SK; /* Lower SCK */
21925fc77b81SRobert Mustacchi 
2193dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
21945fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
21955fc77b81SRobert Mustacchi 
21965fc77b81SRobert Mustacchi 	usec_delay(1);
21975fc77b81SRobert Mustacchi 
21985fc77b81SRobert Mustacchi 	/* Stop requesting EEPROM access */
21995fc77b81SRobert Mustacchi 	eec &= ~IXGBE_EEC_REQ;
2200dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), eec);
22015fc77b81SRobert Mustacchi 
22025fc77b81SRobert Mustacchi 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
22035fc77b81SRobert Mustacchi 
22045fc77b81SRobert Mustacchi 	/* Delay before attempt to obtain semaphore again to allow FW access */
22055fc77b81SRobert Mustacchi 	msec_delay(hw->eeprom.semaphore_delay);
22065fc77b81SRobert Mustacchi }
22075fc77b81SRobert Mustacchi 
22085fc77b81SRobert Mustacchi /**
22095fc77b81SRobert Mustacchi  *  ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
22105fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
2211dc0cb1cdSDale Ghent  *
2212dc0cb1cdSDale Ghent  *  Returns a negative error code on error, or the 16-bit checksum
22135fc77b81SRobert Mustacchi  **/
ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw * hw)2214dc0cb1cdSDale Ghent s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
22155fc77b81SRobert Mustacchi {
22165fc77b81SRobert Mustacchi 	u16 i;
22175fc77b81SRobert Mustacchi 	u16 j;
22185fc77b81SRobert Mustacchi 	u16 checksum = 0;
22195fc77b81SRobert Mustacchi 	u16 length = 0;
22205fc77b81SRobert Mustacchi 	u16 pointer = 0;
22215fc77b81SRobert Mustacchi 	u16 word = 0;
22225fc77b81SRobert Mustacchi 
22235fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic");
22245fc77b81SRobert Mustacchi 
22255fc77b81SRobert Mustacchi 	/* Include 0x0-0x3F in the checksum */
22265fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
2227dc0cb1cdSDale Ghent 		if (hw->eeprom.ops.read(hw, i, &word)) {
22285fc77b81SRobert Mustacchi 			DEBUGOUT("EEPROM read failed\n");
2229dc0cb1cdSDale Ghent 			return IXGBE_ERR_EEPROM;
22305fc77b81SRobert Mustacchi 		}
22315fc77b81SRobert Mustacchi 		checksum += word;
22325fc77b81SRobert Mustacchi 	}
22335fc77b81SRobert Mustacchi 
22345fc77b81SRobert Mustacchi 	/* Include all data from pointers except for the fw pointer */
22355fc77b81SRobert Mustacchi 	for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
2236dc0cb1cdSDale Ghent 		if (hw->eeprom.ops.read(hw, i, &pointer)) {
2237dc0cb1cdSDale Ghent 			DEBUGOUT("EEPROM read failed\n");
2238dc0cb1cdSDale Ghent 			return IXGBE_ERR_EEPROM;
2239dc0cb1cdSDale Ghent 		}
22405fc77b81SRobert Mustacchi 
2241dc0cb1cdSDale Ghent 		/* If the pointer seems invalid */
2242dc0cb1cdSDale Ghent 		if (pointer == 0xFFFF || pointer == 0)
2243dc0cb1cdSDale Ghent 			continue;
22445fc77b81SRobert Mustacchi 
2245dc0cb1cdSDale Ghent 		if (hw->eeprom.ops.read(hw, pointer, &length)) {
2246dc0cb1cdSDale Ghent 			DEBUGOUT("EEPROM read failed\n");
2247dc0cb1cdSDale Ghent 			return IXGBE_ERR_EEPROM;
2248dc0cb1cdSDale Ghent 		}
2249dc0cb1cdSDale Ghent 
2250dc0cb1cdSDale Ghent 		if (length == 0xFFFF || length == 0)
2251dc0cb1cdSDale Ghent 			continue;
2252dc0cb1cdSDale Ghent 
22535fc77b81SRobert Mustacchi 		for (j = pointer + 1; j <= pointer + length; j++) {
2254dc0cb1cdSDale Ghent 			if (hw->eeprom.ops.read(hw, j, &word)) {
2255dc0cb1cdSDale Ghent 				DEBUGOUT("EEPROM read failed\n");
2256dc0cb1cdSDale Ghent 				return IXGBE_ERR_EEPROM;
2257dc0cb1cdSDale Ghent 			}
22585fc77b81SRobert Mustacchi 			checksum += word;
22595fc77b81SRobert Mustacchi 		}
22605fc77b81SRobert Mustacchi 	}
22615fc77b81SRobert Mustacchi 
22625fc77b81SRobert Mustacchi 	checksum = (u16)IXGBE_EEPROM_SUM - checksum;
22635fc77b81SRobert Mustacchi 
2264dc0cb1cdSDale Ghent 	return (s32)checksum;
22655fc77b81SRobert Mustacchi }
22665fc77b81SRobert Mustacchi 
22675fc77b81SRobert Mustacchi /**
22685fc77b81SRobert Mustacchi  *  ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
22695fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
22705fc77b81SRobert Mustacchi  *  @checksum_val: calculated checksum
22715fc77b81SRobert Mustacchi  *
22725fc77b81SRobert Mustacchi  *  Performs checksum calculation and validates the EEPROM checksum.  If the
22735fc77b81SRobert Mustacchi  *  caller does not need checksum_val, the value can be NULL.
22745fc77b81SRobert Mustacchi  **/
ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw * hw,u16 * checksum_val)22755fc77b81SRobert Mustacchi s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
22765fc77b81SRobert Mustacchi 					   u16 *checksum_val)
22775fc77b81SRobert Mustacchi {
22785fc77b81SRobert Mustacchi 	s32 status;
22795fc77b81SRobert Mustacchi 	u16 checksum;
22805fc77b81SRobert Mustacchi 	u16 read_checksum = 0;
22815fc77b81SRobert Mustacchi 
22825fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic");
22835fc77b81SRobert Mustacchi 
2284dc0cb1cdSDale Ghent 	/* Read the first word from the EEPROM. If this times out or fails, do
22855fc77b81SRobert Mustacchi 	 * not continue or we could be in for a very long wait while every
22865fc77b81SRobert Mustacchi 	 * EEPROM read fails
22875fc77b81SRobert Mustacchi 	 */
22885fc77b81SRobert Mustacchi 	status = hw->eeprom.ops.read(hw, 0, &checksum);
2289dc0cb1cdSDale Ghent 	if (status) {
2290dc0cb1cdSDale Ghent 		DEBUGOUT("EEPROM read failed\n");
2291dc0cb1cdSDale Ghent 		return status;
2292dc0cb1cdSDale Ghent 	}
22935fc77b81SRobert Mustacchi 
2294dc0cb1cdSDale Ghent 	status = hw->eeprom.ops.calc_checksum(hw);
2295dc0cb1cdSDale Ghent 	if (status < 0)
2296dc0cb1cdSDale Ghent 		return status;
22975fc77b81SRobert Mustacchi 
2298dc0cb1cdSDale Ghent 	checksum = (u16)(status & 0xffff);
22995fc77b81SRobert Mustacchi 
2300dc0cb1cdSDale Ghent 	status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
2301dc0cb1cdSDale Ghent 	if (status) {
2302dc0cb1cdSDale Ghent 		DEBUGOUT("EEPROM read failed\n");
2303dc0cb1cdSDale Ghent 		return status;
2304dc0cb1cdSDale Ghent 	}
2305dc0cb1cdSDale Ghent 
2306dc0cb1cdSDale Ghent 	/* Verify read checksum from EEPROM is the same as
23075fc77b81SRobert Mustacchi 	 * calculated checksum
23085fc77b81SRobert Mustacchi 	 */
23095fc77b81SRobert Mustacchi 	if (read_checksum != checksum)
23105fc77b81SRobert Mustacchi 		status = IXGBE_ERR_EEPROM_CHECKSUM;
23115fc77b81SRobert Mustacchi 
23125fc77b81SRobert Mustacchi 	/* If the user cares, return the calculated checksum */
23135fc77b81SRobert Mustacchi 	if (checksum_val)
23145fc77b81SRobert Mustacchi 		*checksum_val = checksum;
23155fc77b81SRobert Mustacchi 
23165fc77b81SRobert Mustacchi 	return status;
23175fc77b81SRobert Mustacchi }
23185fc77b81SRobert Mustacchi 
23195fc77b81SRobert Mustacchi /**
23205fc77b81SRobert Mustacchi  *  ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
23215fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
23225fc77b81SRobert Mustacchi  **/
ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw * hw)23235fc77b81SRobert Mustacchi s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
23245fc77b81SRobert Mustacchi {
23255fc77b81SRobert Mustacchi 	s32 status;
23265fc77b81SRobert Mustacchi 	u16 checksum;
23275fc77b81SRobert Mustacchi 
23285fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_update_eeprom_checksum_generic");
23295fc77b81SRobert Mustacchi 
2330dc0cb1cdSDale Ghent 	/* Read the first word from the EEPROM. If this times out or fails, do
23315fc77b81SRobert Mustacchi 	 * not continue or we could be in for a very long wait while every
23325fc77b81SRobert Mustacchi 	 * EEPROM read fails
23335fc77b81SRobert Mustacchi 	 */
23345fc77b81SRobert Mustacchi 	status = hw->eeprom.ops.read(hw, 0, &checksum);
2335dc0cb1cdSDale Ghent 	if (status) {
23365fc77b81SRobert Mustacchi 		DEBUGOUT("EEPROM read failed\n");
2337dc0cb1cdSDale Ghent 		return status;
23385fc77b81SRobert Mustacchi 	}
23395fc77b81SRobert Mustacchi 
2340dc0cb1cdSDale Ghent 	status = hw->eeprom.ops.calc_checksum(hw);
2341dc0cb1cdSDale Ghent 	if (status < 0)
2342dc0cb1cdSDale Ghent 		return status;
2343dc0cb1cdSDale Ghent 
2344dc0cb1cdSDale Ghent 	checksum = (u16)(status & 0xffff);
2345dc0cb1cdSDale Ghent 
2346dc0cb1cdSDale Ghent 	status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum);
2347dc0cb1cdSDale Ghent 
23485fc77b81SRobert Mustacchi 	return status;
23495fc77b81SRobert Mustacchi }
23505fc77b81SRobert Mustacchi 
23515fc77b81SRobert Mustacchi /**
23525fc77b81SRobert Mustacchi  *  ixgbe_validate_mac_addr - Validate MAC address
23535fc77b81SRobert Mustacchi  *  @mac_addr: pointer to MAC address.
23545fc77b81SRobert Mustacchi  *
2355*48ed61a7SRobert Mustacchi  *  Tests a MAC address to ensure it is a valid Individual Address.
23565fc77b81SRobert Mustacchi  **/
ixgbe_validate_mac_addr(u8 * mac_addr)23575fc77b81SRobert Mustacchi s32 ixgbe_validate_mac_addr(u8 *mac_addr)
23585fc77b81SRobert Mustacchi {
23595fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
23605fc77b81SRobert Mustacchi 
23615fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_validate_mac_addr");
23625fc77b81SRobert Mustacchi 
23635fc77b81SRobert Mustacchi 	/* Make sure it is not a multicast address */
23645fc77b81SRobert Mustacchi 	if (IXGBE_IS_MULTICAST(mac_addr)) {
23655fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_MAC_ADDR;
23665fc77b81SRobert Mustacchi 	/* Not a broadcast address */
23675fc77b81SRobert Mustacchi 	} else if (IXGBE_IS_BROADCAST(mac_addr)) {
23685fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_MAC_ADDR;
23695fc77b81SRobert Mustacchi 	/* Reject the zero address */
23705fc77b81SRobert Mustacchi 	} else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
23715fc77b81SRobert Mustacchi 		   mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
23725fc77b81SRobert Mustacchi 		status = IXGBE_ERR_INVALID_MAC_ADDR;
23735fc77b81SRobert Mustacchi 	}
23745fc77b81SRobert Mustacchi 	return status;
23755fc77b81SRobert Mustacchi }
23765fc77b81SRobert Mustacchi 
23775fc77b81SRobert Mustacchi /**
23785fc77b81SRobert Mustacchi  *  ixgbe_set_rar_generic - Set Rx address register
23795fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
23805fc77b81SRobert Mustacchi  *  @index: Receive address register to write
23815fc77b81SRobert Mustacchi  *  @addr: Address to put into receive address register
23825fc77b81SRobert Mustacchi  *  @vmdq: VMDq "set" or "pool" index
23835fc77b81SRobert Mustacchi  *  @enable_addr: set flag that address is active
23845fc77b81SRobert Mustacchi  *
23855fc77b81SRobert Mustacchi  *  Puts an ethernet address into a receive address register.
23865fc77b81SRobert Mustacchi  **/
ixgbe_set_rar_generic(struct ixgbe_hw * hw,u32 index,u8 * addr,u32 vmdq,u32 enable_addr)23875fc77b81SRobert Mustacchi s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
23885fc77b81SRobert Mustacchi 			  u32 enable_addr)
23895fc77b81SRobert Mustacchi {
23905fc77b81SRobert Mustacchi 	u32 rar_low, rar_high;
23915fc77b81SRobert Mustacchi 	u32 rar_entries = hw->mac.num_rar_entries;
23925fc77b81SRobert Mustacchi 
23935fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_rar_generic");
23945fc77b81SRobert Mustacchi 
23955fc77b81SRobert Mustacchi 	/* Make sure we are using a valid rar index range */
23965fc77b81SRobert Mustacchi 	if (index >= rar_entries) {
2397dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
2398dc0cb1cdSDale Ghent 			     "RAR index %d is out of range.\n", index);
23995fc77b81SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
24005fc77b81SRobert Mustacchi 	}
24015fc77b81SRobert Mustacchi 
24025fc77b81SRobert Mustacchi 	/* setup VMDq pool selection before this RAR gets enabled */
24035fc77b81SRobert Mustacchi 	hw->mac.ops.set_vmdq(hw, index, vmdq);
24045fc77b81SRobert Mustacchi 
24055fc77b81SRobert Mustacchi 	/*
24065fc77b81SRobert Mustacchi 	 * HW expects these in little endian so we reverse the byte
24075fc77b81SRobert Mustacchi 	 * order from network order (big endian) to little endian
24085fc77b81SRobert Mustacchi 	 */
24095fc77b81SRobert Mustacchi 	rar_low = ((u32)addr[0] |
24105fc77b81SRobert Mustacchi 		   ((u32)addr[1] << 8) |
24115fc77b81SRobert Mustacchi 		   ((u32)addr[2] << 16) |
24125fc77b81SRobert Mustacchi 		   ((u32)addr[3] << 24));
24135fc77b81SRobert Mustacchi 	/*
24145fc77b81SRobert Mustacchi 	 * Some parts put the VMDq setting in the extra RAH bits,
24155fc77b81SRobert Mustacchi 	 * so save everything except the lower 16 bits that hold part
24165fc77b81SRobert Mustacchi 	 * of the address and the address valid bit.
24175fc77b81SRobert Mustacchi 	 */
24185fc77b81SRobert Mustacchi 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
24195fc77b81SRobert Mustacchi 	rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
24205fc77b81SRobert Mustacchi 	rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
24215fc77b81SRobert Mustacchi 
24225fc77b81SRobert Mustacchi 	if (enable_addr != 0)
24235fc77b81SRobert Mustacchi 		rar_high |= IXGBE_RAH_AV;
24245fc77b81SRobert Mustacchi 
24255fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
24265fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
24275fc77b81SRobert Mustacchi 
24285fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
24295fc77b81SRobert Mustacchi }
24305fc77b81SRobert Mustacchi 
24315fc77b81SRobert Mustacchi /**
24325fc77b81SRobert Mustacchi  *  ixgbe_clear_rar_generic - Remove Rx address register
24335fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
24345fc77b81SRobert Mustacchi  *  @index: Receive address register to write
24355fc77b81SRobert Mustacchi  *
24365fc77b81SRobert Mustacchi  *  Clears an ethernet address from a receive address register.
24375fc77b81SRobert Mustacchi  **/
ixgbe_clear_rar_generic(struct ixgbe_hw * hw,u32 index)24385fc77b81SRobert Mustacchi s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
24395fc77b81SRobert Mustacchi {
24405fc77b81SRobert Mustacchi 	u32 rar_high;
24415fc77b81SRobert Mustacchi 	u32 rar_entries = hw->mac.num_rar_entries;
24425fc77b81SRobert Mustacchi 
24435fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_clear_rar_generic");
24445fc77b81SRobert Mustacchi 
24455fc77b81SRobert Mustacchi 	/* Make sure we are using a valid rar index range */
24465fc77b81SRobert Mustacchi 	if (index >= rar_entries) {
2447dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
2448dc0cb1cdSDale Ghent 			     "RAR index %d is out of range.\n", index);
24495fc77b81SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
24505fc77b81SRobert Mustacchi 	}
24515fc77b81SRobert Mustacchi 
24525fc77b81SRobert Mustacchi 	/*
24535fc77b81SRobert Mustacchi 	 * Some parts put the VMDq setting in the extra RAH bits,
24545fc77b81SRobert Mustacchi 	 * so save everything except the lower 16 bits that hold part
24555fc77b81SRobert Mustacchi 	 * of the address and the address valid bit.
24565fc77b81SRobert Mustacchi 	 */
24575fc77b81SRobert Mustacchi 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
24585fc77b81SRobert Mustacchi 	rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
24595fc77b81SRobert Mustacchi 
24605fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
24615fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
24625fc77b81SRobert Mustacchi 
24635fc77b81SRobert Mustacchi 	/* clear VMDq pool/queue selection for this RAR */
24645fc77b81SRobert Mustacchi 	hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
24655fc77b81SRobert Mustacchi 
24665fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
24675fc77b81SRobert Mustacchi }
24685fc77b81SRobert Mustacchi 
24695fc77b81SRobert Mustacchi /**
24705fc77b81SRobert Mustacchi  *  ixgbe_init_rx_addrs_generic - Initializes receive address filters.
24715fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
24725fc77b81SRobert Mustacchi  *
24735fc77b81SRobert Mustacchi  *  Places the MAC address in receive address register 0 and clears the rest
24745fc77b81SRobert Mustacchi  *  of the receive address registers. Clears the multicast table. Assumes
24755fc77b81SRobert Mustacchi  *  the receiver is in reset when the routine is called.
24765fc77b81SRobert Mustacchi  **/
ixgbe_init_rx_addrs_generic(struct ixgbe_hw * hw)24775fc77b81SRobert Mustacchi s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
24785fc77b81SRobert Mustacchi {
24795fc77b81SRobert Mustacchi 	u32 i;
24805fc77b81SRobert Mustacchi 	u32 rar_entries = hw->mac.num_rar_entries;
24815fc77b81SRobert Mustacchi 
24825fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_init_rx_addrs_generic");
24835fc77b81SRobert Mustacchi 
24845fc77b81SRobert Mustacchi 	/*
24855fc77b81SRobert Mustacchi 	 * If the current mac address is valid, assume it is a software override
24865fc77b81SRobert Mustacchi 	 * to the permanent address.
24875fc77b81SRobert Mustacchi 	 * Otherwise, use the permanent address from the eeprom.
24885fc77b81SRobert Mustacchi 	 */
24895fc77b81SRobert Mustacchi 	if (ixgbe_validate_mac_addr(hw->mac.addr) ==
24905fc77b81SRobert Mustacchi 	    IXGBE_ERR_INVALID_MAC_ADDR) {
24915fc77b81SRobert Mustacchi 		/* Get the MAC address from the RAR0 for later reference */
24925fc77b81SRobert Mustacchi 		hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
24935fc77b81SRobert Mustacchi 
24945fc77b81SRobert Mustacchi 		DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
24955fc77b81SRobert Mustacchi 			  hw->mac.addr[0], hw->mac.addr[1],
24965fc77b81SRobert Mustacchi 			  hw->mac.addr[2]);
24975fc77b81SRobert Mustacchi 		DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
24985fc77b81SRobert Mustacchi 			  hw->mac.addr[4], hw->mac.addr[5]);
24995fc77b81SRobert Mustacchi 	} else {
25005fc77b81SRobert Mustacchi 		/* Setup the receive address. */
25015fc77b81SRobert Mustacchi 		DEBUGOUT("Overriding MAC Address in RAR[0]\n");
25025fc77b81SRobert Mustacchi 		DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ",
25035fc77b81SRobert Mustacchi 			  hw->mac.addr[0], hw->mac.addr[1],
25045fc77b81SRobert Mustacchi 			  hw->mac.addr[2]);
25055fc77b81SRobert Mustacchi 		DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
25065fc77b81SRobert Mustacchi 			  hw->mac.addr[4], hw->mac.addr[5]);
25075fc77b81SRobert Mustacchi 
25085fc77b81SRobert Mustacchi 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
2509*48ed61a7SRobert Mustacchi 	}
25105fc77b81SRobert Mustacchi 
25115fc77b81SRobert Mustacchi 	/* clear VMDq pool/queue selection for RAR 0 */
25125fc77b81SRobert Mustacchi 	hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
2513*48ed61a7SRobert Mustacchi 
25145fc77b81SRobert Mustacchi 	hw->addr_ctrl.overflow_promisc = 0;
25155fc77b81SRobert Mustacchi 
25165fc77b81SRobert Mustacchi 	hw->addr_ctrl.rar_used_count = 1;
25175fc77b81SRobert Mustacchi 
25185fc77b81SRobert Mustacchi 	/* Zero out the other receive addresses. */
25195fc77b81SRobert Mustacchi 	DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1);
25205fc77b81SRobert Mustacchi 	for (i = 1; i < rar_entries; i++) {
25215fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
25225fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
25235fc77b81SRobert Mustacchi 	}
25245fc77b81SRobert Mustacchi 
25255fc77b81SRobert Mustacchi 	/* Clear the MTA */
25265fc77b81SRobert Mustacchi 	hw->addr_ctrl.mta_in_use = 0;
25275fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
25285fc77b81SRobert Mustacchi 
25295fc77b81SRobert Mustacchi 	DEBUGOUT(" Clearing MTA\n");
25305fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.mcft_size; i++)
25315fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
25325fc77b81SRobert Mustacchi 
2533dc0cb1cdSDale Ghent 	ixgbe_init_uta_tables(hw);
2534dc0cb1cdSDale Ghent 
2535dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
25365fc77b81SRobert Mustacchi }
25375fc77b81SRobert Mustacchi 
25385fc77b81SRobert Mustacchi /**
25395fc77b81SRobert Mustacchi  *  ixgbe_add_uc_addr - Adds a secondary unicast address.
25405fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
25415fc77b81SRobert Mustacchi  *  @addr: new address
2542*48ed61a7SRobert Mustacchi  *  @vmdq: VMDq "set" or "pool" index
25435fc77b81SRobert Mustacchi  *
25445fc77b81SRobert Mustacchi  *  Adds it to unused receive address register or goes into promiscuous mode.
25455fc77b81SRobert Mustacchi  **/
ixgbe_add_uc_addr(struct ixgbe_hw * hw,u8 * addr,u32 vmdq)25465fc77b81SRobert Mustacchi void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
25475fc77b81SRobert Mustacchi {
25485fc77b81SRobert Mustacchi 	u32 rar_entries = hw->mac.num_rar_entries;
25495fc77b81SRobert Mustacchi 	u32 rar;
25505fc77b81SRobert Mustacchi 
25515fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_add_uc_addr");
25525fc77b81SRobert Mustacchi 
25535fc77b81SRobert Mustacchi 	DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
25545fc77b81SRobert Mustacchi 		  addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
25555fc77b81SRobert Mustacchi 
25565fc77b81SRobert Mustacchi 	/*
25575fc77b81SRobert Mustacchi 	 * Place this address in the RAR if there is room,
25585fc77b81SRobert Mustacchi 	 * else put the controller into promiscuous mode
25595fc77b81SRobert Mustacchi 	 */
25605fc77b81SRobert Mustacchi 	if (hw->addr_ctrl.rar_used_count < rar_entries) {
25615fc77b81SRobert Mustacchi 		rar = hw->addr_ctrl.rar_used_count;
25625fc77b81SRobert Mustacchi 		hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
25635fc77b81SRobert Mustacchi 		DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar);
25645fc77b81SRobert Mustacchi 		hw->addr_ctrl.rar_used_count++;
25655fc77b81SRobert Mustacchi 	} else {
25665fc77b81SRobert Mustacchi 		hw->addr_ctrl.overflow_promisc++;
25675fc77b81SRobert Mustacchi 	}
25685fc77b81SRobert Mustacchi 
25695fc77b81SRobert Mustacchi 	DEBUGOUT("ixgbe_add_uc_addr Complete\n");
25705fc77b81SRobert Mustacchi }
25715fc77b81SRobert Mustacchi 
25725fc77b81SRobert Mustacchi /**
25735fc77b81SRobert Mustacchi  *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
25745fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
25755fc77b81SRobert Mustacchi  *  @addr_list: the list of new addresses
25765fc77b81SRobert Mustacchi  *  @addr_count: number of addresses
25775fc77b81SRobert Mustacchi  *  @next: iterator function to walk the address list
25785fc77b81SRobert Mustacchi  *
25795fc77b81SRobert Mustacchi  *  The given list replaces any existing list.  Clears the secondary addrs from
25805fc77b81SRobert Mustacchi  *  receive address registers.  Uses unused receive address registers for the
25815fc77b81SRobert Mustacchi  *  first secondary addresses, and falls back to promiscuous mode as needed.
25825fc77b81SRobert Mustacchi  *
25835fc77b81SRobert Mustacchi  *  Drivers using secondary unicast addresses must set user_set_promisc when
25845fc77b81SRobert Mustacchi  *  manually putting the device into promiscuous mode.
25855fc77b81SRobert Mustacchi  **/
ixgbe_update_uc_addr_list_generic(struct ixgbe_hw * hw,u8 * addr_list,u32 addr_count,ixgbe_mc_addr_itr next)25865fc77b81SRobert Mustacchi s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
25875fc77b81SRobert Mustacchi 				      u32 addr_count, ixgbe_mc_addr_itr next)
25885fc77b81SRobert Mustacchi {
25895fc77b81SRobert Mustacchi 	u8 *addr;
25905fc77b81SRobert Mustacchi 	u32 i;
25915fc77b81SRobert Mustacchi 	u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
25925fc77b81SRobert Mustacchi 	u32 uc_addr_in_use;
25935fc77b81SRobert Mustacchi 	u32 fctrl;
25945fc77b81SRobert Mustacchi 	u32 vmdq;
25955fc77b81SRobert Mustacchi 
25965fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_update_uc_addr_list_generic");
25975fc77b81SRobert Mustacchi 
25985fc77b81SRobert Mustacchi 	/*
25995fc77b81SRobert Mustacchi 	 * Clear accounting of old secondary address list,
26005fc77b81SRobert Mustacchi 	 * don't count RAR[0]
26015fc77b81SRobert Mustacchi 	 */
26025fc77b81SRobert Mustacchi 	uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
26035fc77b81SRobert Mustacchi 	hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
26045fc77b81SRobert Mustacchi 	hw->addr_ctrl.overflow_promisc = 0;
26055fc77b81SRobert Mustacchi 
26065fc77b81SRobert Mustacchi 	/* Zero out the other receive addresses */
26075fc77b81SRobert Mustacchi 	DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use+1);
26085fc77b81SRobert Mustacchi 	for (i = 0; i < uc_addr_in_use; i++) {
26095fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0);
26105fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0);
26115fc77b81SRobert Mustacchi 	}
26125fc77b81SRobert Mustacchi 
26135fc77b81SRobert Mustacchi 	/* Add the new addresses */
26145fc77b81SRobert Mustacchi 	for (i = 0; i < addr_count; i++) {
26155fc77b81SRobert Mustacchi 		DEBUGOUT(" Adding the secondary addresses:\n");
26165fc77b81SRobert Mustacchi 		addr = next(hw, &addr_list, &vmdq);
26175fc77b81SRobert Mustacchi 		ixgbe_add_uc_addr(hw, addr, vmdq);
26185fc77b81SRobert Mustacchi 	}
26195fc77b81SRobert Mustacchi 
26205fc77b81SRobert Mustacchi 	if (hw->addr_ctrl.overflow_promisc) {
26215fc77b81SRobert Mustacchi 		/* enable promisc if not already in overflow or set by user */
26225fc77b81SRobert Mustacchi 		if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
26235fc77b81SRobert Mustacchi 			DEBUGOUT(" Entering address overflow promisc mode\n");
26245fc77b81SRobert Mustacchi 			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
26255fc77b81SRobert Mustacchi 			fctrl |= IXGBE_FCTRL_UPE;
26265fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
26275fc77b81SRobert Mustacchi 		}
26285fc77b81SRobert Mustacchi 	} else {
26295fc77b81SRobert Mustacchi 		/* only disable if set by overflow, not by user */
26305fc77b81SRobert Mustacchi 		if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
26315fc77b81SRobert Mustacchi 			DEBUGOUT(" Leaving address overflow promisc mode\n");
26325fc77b81SRobert Mustacchi 			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
26335fc77b81SRobert Mustacchi 			fctrl &= ~IXGBE_FCTRL_UPE;
26345fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
26355fc77b81SRobert Mustacchi 		}
26365fc77b81SRobert Mustacchi 	}
26375fc77b81SRobert Mustacchi 
26385fc77b81SRobert Mustacchi 	DEBUGOUT("ixgbe_update_uc_addr_list_generic Complete\n");
26395fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
26405fc77b81SRobert Mustacchi }
26415fc77b81SRobert Mustacchi 
26425fc77b81SRobert Mustacchi /**
26435fc77b81SRobert Mustacchi  *  ixgbe_mta_vector - Determines bit-vector in multicast table to set
26445fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
26455fc77b81SRobert Mustacchi  *  @mc_addr: the multicast address
26465fc77b81SRobert Mustacchi  *
26475fc77b81SRobert Mustacchi  *  Extracts the 12 bits, from a multicast address, to determine which
26485fc77b81SRobert Mustacchi  *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
26495fc77b81SRobert Mustacchi  *  incoming rx multicast addresses, to determine the bit-vector to check in
26505fc77b81SRobert Mustacchi  *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
26515fc77b81SRobert Mustacchi  *  by the MO field of the MCSTCTRL. The MO field is set during initialization
26525fc77b81SRobert Mustacchi  *  to mc_filter_type.
26535fc77b81SRobert Mustacchi  **/
ixgbe_mta_vector(struct ixgbe_hw * hw,u8 * mc_addr)26545fc77b81SRobert Mustacchi static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
26555fc77b81SRobert Mustacchi {
26565fc77b81SRobert Mustacchi 	u32 vector = 0;
26575fc77b81SRobert Mustacchi 
26585fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_mta_vector");
26595fc77b81SRobert Mustacchi 
26605fc77b81SRobert Mustacchi 	switch (hw->mac.mc_filter_type) {
26615fc77b81SRobert Mustacchi 	case 0:   /* use bits [47:36] of the address */
26625fc77b81SRobert Mustacchi 		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
26635fc77b81SRobert Mustacchi 		break;
26645fc77b81SRobert Mustacchi 	case 1:   /* use bits [46:35] of the address */
26655fc77b81SRobert Mustacchi 		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
26665fc77b81SRobert Mustacchi 		break;
26675fc77b81SRobert Mustacchi 	case 2:   /* use bits [45:34] of the address */
26685fc77b81SRobert Mustacchi 		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
26695fc77b81SRobert Mustacchi 		break;
26705fc77b81SRobert Mustacchi 	case 3:   /* use bits [43:32] of the address */
26715fc77b81SRobert Mustacchi 		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
26725fc77b81SRobert Mustacchi 		break;
26735fc77b81SRobert Mustacchi 	default:  /* Invalid mc_filter_type */
26745fc77b81SRobert Mustacchi 		DEBUGOUT("MC filter type param set incorrectly\n");
26755fc77b81SRobert Mustacchi 		ASSERT(0);
26765fc77b81SRobert Mustacchi 		break;
26775fc77b81SRobert Mustacchi 	}
26785fc77b81SRobert Mustacchi 
26795fc77b81SRobert Mustacchi 	/* vector can only be 12-bits or boundary will be exceeded */
26805fc77b81SRobert Mustacchi 	vector &= 0xFFF;
26815fc77b81SRobert Mustacchi 	return vector;
26825fc77b81SRobert Mustacchi }
26835fc77b81SRobert Mustacchi 
26845fc77b81SRobert Mustacchi /**
26855fc77b81SRobert Mustacchi  *  ixgbe_set_mta - Set bit-vector in multicast table
26865fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
2687*48ed61a7SRobert Mustacchi  *  @mc_addr: Multicast address
26885fc77b81SRobert Mustacchi  *
26895fc77b81SRobert Mustacchi  *  Sets the bit-vector in the multicast table.
26905fc77b81SRobert Mustacchi  **/
ixgbe_set_mta(struct ixgbe_hw * hw,u8 * mc_addr)26915fc77b81SRobert Mustacchi void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
26925fc77b81SRobert Mustacchi {
26935fc77b81SRobert Mustacchi 	u32 vector;
26945fc77b81SRobert Mustacchi 	u32 vector_bit;
26955fc77b81SRobert Mustacchi 	u32 vector_reg;
26965fc77b81SRobert Mustacchi 
26975fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_mta");
26985fc77b81SRobert Mustacchi 
26995fc77b81SRobert Mustacchi 	hw->addr_ctrl.mta_in_use++;
27005fc77b81SRobert Mustacchi 
27015fc77b81SRobert Mustacchi 	vector = ixgbe_mta_vector(hw, mc_addr);
27025fc77b81SRobert Mustacchi 	DEBUGOUT1(" bit-vector = 0x%03X\n", vector);
27035fc77b81SRobert Mustacchi 
27045fc77b81SRobert Mustacchi 	/*
27055fc77b81SRobert Mustacchi 	 * The MTA is a register array of 128 32-bit registers. It is treated
27065fc77b81SRobert Mustacchi 	 * like an array of 4096 bits.  We want to set bit
27075fc77b81SRobert Mustacchi 	 * BitArray[vector_value]. So we figure out what register the bit is
27085fc77b81SRobert Mustacchi 	 * in, read it, OR in the new bit, then write back the new value.  The
27095fc77b81SRobert Mustacchi 	 * register is determined by the upper 7 bits of the vector value and
27105fc77b81SRobert Mustacchi 	 * the bit within that register are determined by the lower 5 bits of
27115fc77b81SRobert Mustacchi 	 * the value.
27125fc77b81SRobert Mustacchi 	 */
27135fc77b81SRobert Mustacchi 	vector_reg = (vector >> 5) & 0x7F;
27145fc77b81SRobert Mustacchi 	vector_bit = vector & 0x1F;
27155fc77b81SRobert Mustacchi 	hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
27165fc77b81SRobert Mustacchi }
27175fc77b81SRobert Mustacchi 
27185fc77b81SRobert Mustacchi /**
27195fc77b81SRobert Mustacchi  *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
27205fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
27215fc77b81SRobert Mustacchi  *  @mc_addr_list: the list of new multicast addresses
27225fc77b81SRobert Mustacchi  *  @mc_addr_count: number of addresses
27235fc77b81SRobert Mustacchi  *  @next: iterator function to walk the multicast address list
27245fc77b81SRobert Mustacchi  *  @clear: flag, when set clears the table beforehand
27255fc77b81SRobert Mustacchi  *
27265fc77b81SRobert Mustacchi  *  When the clear flag is set, the given list replaces any existing list.
27275fc77b81SRobert Mustacchi  *  Hashes the given addresses into the multicast table.
27285fc77b81SRobert Mustacchi  **/
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)27295fc77b81SRobert Mustacchi s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
27305fc77b81SRobert Mustacchi 				      u32 mc_addr_count, ixgbe_mc_addr_itr next,
27315fc77b81SRobert Mustacchi 				      bool clear)
27325fc77b81SRobert Mustacchi {
27335fc77b81SRobert Mustacchi 	u32 i;
27345fc77b81SRobert Mustacchi 	u32 vmdq;
27355fc77b81SRobert Mustacchi 
27365fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_update_mc_addr_list_generic");
27375fc77b81SRobert Mustacchi 
27385fc77b81SRobert Mustacchi 	/*
27395fc77b81SRobert Mustacchi 	 * Set the new number of MC addresses that we are being requested to
27405fc77b81SRobert Mustacchi 	 * use.
27415fc77b81SRobert Mustacchi 	 */
27425fc77b81SRobert Mustacchi 	hw->addr_ctrl.num_mc_addrs = mc_addr_count;
27435fc77b81SRobert Mustacchi 	hw->addr_ctrl.mta_in_use = 0;
27445fc77b81SRobert Mustacchi 
27455fc77b81SRobert Mustacchi 	/* Clear mta_shadow */
27465fc77b81SRobert Mustacchi 	if (clear) {
27475fc77b81SRobert Mustacchi 		DEBUGOUT(" Clearing MTA\n");
2748dc0cb1cdSDale Ghent 		memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
27495fc77b81SRobert Mustacchi 	}
27505fc77b81SRobert Mustacchi 
27515fc77b81SRobert Mustacchi 	/* Update mta_shadow */
27525fc77b81SRobert Mustacchi 	for (i = 0; i < mc_addr_count; i++) {
27535fc77b81SRobert Mustacchi 		DEBUGOUT(" Adding the multicast addresses:\n");
27545fc77b81SRobert Mustacchi 		ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
27555fc77b81SRobert Mustacchi 	}
27565fc77b81SRobert Mustacchi 
27575fc77b81SRobert Mustacchi 	/* Enable mta */
27585fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.mcft_size; i++)
27595fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i,
27605fc77b81SRobert Mustacchi 				      hw->mac.mta_shadow[i]);
27615fc77b81SRobert Mustacchi 
27625fc77b81SRobert Mustacchi 	if (hw->addr_ctrl.mta_in_use > 0)
27635fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
27645fc77b81SRobert Mustacchi 				IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
27655fc77b81SRobert Mustacchi 
27665fc77b81SRobert Mustacchi 	DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n");
27675fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
27685fc77b81SRobert Mustacchi }
27695fc77b81SRobert Mustacchi 
27705fc77b81SRobert Mustacchi /**
27715fc77b81SRobert Mustacchi  *  ixgbe_enable_mc_generic - Enable multicast address in RAR
27725fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
27735fc77b81SRobert Mustacchi  *
27745fc77b81SRobert Mustacchi  *  Enables multicast address in RAR and the use of the multicast hash table.
27755fc77b81SRobert Mustacchi  **/
ixgbe_enable_mc_generic(struct ixgbe_hw * hw)27765fc77b81SRobert Mustacchi s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
27775fc77b81SRobert Mustacchi {
27785fc77b81SRobert Mustacchi 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
27795fc77b81SRobert Mustacchi 
27805fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_enable_mc_generic");
27815fc77b81SRobert Mustacchi 
27825fc77b81SRobert Mustacchi 	if (a->mta_in_use > 0)
27835fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
27845fc77b81SRobert Mustacchi 				hw->mac.mc_filter_type);
27855fc77b81SRobert Mustacchi 
27865fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
27875fc77b81SRobert Mustacchi }
27885fc77b81SRobert Mustacchi 
27895fc77b81SRobert Mustacchi /**
27905fc77b81SRobert Mustacchi  *  ixgbe_disable_mc_generic - Disable multicast address in RAR
27915fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
27925fc77b81SRobert Mustacchi  *
27935fc77b81SRobert Mustacchi  *  Disables multicast address in RAR and the use of the multicast hash table.
27945fc77b81SRobert Mustacchi  **/
ixgbe_disable_mc_generic(struct ixgbe_hw * hw)27955fc77b81SRobert Mustacchi s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
27965fc77b81SRobert Mustacchi {
27975fc77b81SRobert Mustacchi 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
27985fc77b81SRobert Mustacchi 
27995fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_disable_mc_generic");
28005fc77b81SRobert Mustacchi 
28015fc77b81SRobert Mustacchi 	if (a->mta_in_use > 0)
28025fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
28035fc77b81SRobert Mustacchi 
28045fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
28055fc77b81SRobert Mustacchi }
28065fc77b81SRobert Mustacchi 
28075fc77b81SRobert Mustacchi /**
28085fc77b81SRobert Mustacchi  *  ixgbe_fc_enable_generic - Enable flow control
28095fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
28105fc77b81SRobert Mustacchi  *
28115fc77b81SRobert Mustacchi  *  Enable flow control according to the current settings.
28125fc77b81SRobert Mustacchi  **/
ixgbe_fc_enable_generic(struct ixgbe_hw * hw)28135fc77b81SRobert Mustacchi s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
28145fc77b81SRobert Mustacchi {
28155fc77b81SRobert Mustacchi 	s32 ret_val = IXGBE_SUCCESS;
28165fc77b81SRobert Mustacchi 	u32 mflcn_reg, fccfg_reg;
28175fc77b81SRobert Mustacchi 	u32 reg;
28185fc77b81SRobert Mustacchi 	u32 fcrtl, fcrth;
28195fc77b81SRobert Mustacchi 	int i;
28205fc77b81SRobert Mustacchi 
28215fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_fc_enable_generic");
28225fc77b81SRobert Mustacchi 
28235fc77b81SRobert Mustacchi 	/* Validate the water mark configuration */
28245fc77b81SRobert Mustacchi 	if (!hw->fc.pause_time) {
28255fc77b81SRobert Mustacchi 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
28265fc77b81SRobert Mustacchi 		goto out;
28275fc77b81SRobert Mustacchi 	}
28285fc77b81SRobert Mustacchi 
28295fc77b81SRobert Mustacchi 	/* Low water mark of zero causes XOFF floods */
28305fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
28315fc77b81SRobert Mustacchi 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
28325fc77b81SRobert Mustacchi 		    hw->fc.high_water[i]) {
28335fc77b81SRobert Mustacchi 			if (!hw->fc.low_water[i] ||
28345fc77b81SRobert Mustacchi 			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
28355fc77b81SRobert Mustacchi 				DEBUGOUT("Invalid water mark configuration\n");
28365fc77b81SRobert Mustacchi 				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
28375fc77b81SRobert Mustacchi 				goto out;
28385fc77b81SRobert Mustacchi 			}
28395fc77b81SRobert Mustacchi 		}
28405fc77b81SRobert Mustacchi 	}
28415fc77b81SRobert Mustacchi 
28425fc77b81SRobert Mustacchi 	/* Negotiate the fc mode to use */
2843*48ed61a7SRobert Mustacchi 	hw->mac.ops.fc_autoneg(hw);
28445fc77b81SRobert Mustacchi 
28455fc77b81SRobert Mustacchi 	/* Disable any previous flow control settings */
28465fc77b81SRobert Mustacchi 	mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
28475fc77b81SRobert Mustacchi 	mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
28485fc77b81SRobert Mustacchi 
28495fc77b81SRobert Mustacchi 	fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
28505fc77b81SRobert Mustacchi 	fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
28515fc77b81SRobert Mustacchi 
28525fc77b81SRobert Mustacchi 	/*
28535fc77b81SRobert Mustacchi 	 * The possible values of fc.current_mode are:
28545fc77b81SRobert Mustacchi 	 * 0: Flow control is completely disabled
28555fc77b81SRobert Mustacchi 	 * 1: Rx flow control is enabled (we can receive pause frames,
28565fc77b81SRobert Mustacchi 	 *    but not send pause frames).
28575fc77b81SRobert Mustacchi 	 * 2: Tx flow control is enabled (we can send pause frames but
28585fc77b81SRobert Mustacchi 	 *    we do not support receiving pause frames).
28595fc77b81SRobert Mustacchi 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
28605fc77b81SRobert Mustacchi 	 * other: Invalid.
28615fc77b81SRobert Mustacchi 	 */
28625fc77b81SRobert Mustacchi 	switch (hw->fc.current_mode) {
28635fc77b81SRobert Mustacchi 	case ixgbe_fc_none:
28645fc77b81SRobert Mustacchi 		/*
28655fc77b81SRobert Mustacchi 		 * Flow control is disabled by software override or autoneg.
28665fc77b81SRobert Mustacchi 		 * The code below will actually disable it in the HW.
28675fc77b81SRobert Mustacchi 		 */
28685fc77b81SRobert Mustacchi 		break;
28695fc77b81SRobert Mustacchi 	case ixgbe_fc_rx_pause:
28705fc77b81SRobert Mustacchi 		/*
28715fc77b81SRobert Mustacchi 		 * Rx Flow control is enabled and Tx Flow control is
28725fc77b81SRobert Mustacchi 		 * disabled by software override. Since there really
28735fc77b81SRobert Mustacchi 		 * isn't a way to advertise that we are capable of RX
28745fc77b81SRobert Mustacchi 		 * Pause ONLY, we will advertise that we support both
28755fc77b81SRobert Mustacchi 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
28765fc77b81SRobert Mustacchi 		 * disable the adapter's ability to send PAUSE frames.
28775fc77b81SRobert Mustacchi 		 */
28785fc77b81SRobert Mustacchi 		mflcn_reg |= IXGBE_MFLCN_RFCE;
28795fc77b81SRobert Mustacchi 		break;
28805fc77b81SRobert Mustacchi 	case ixgbe_fc_tx_pause:
28815fc77b81SRobert Mustacchi 		/*
28825fc77b81SRobert Mustacchi 		 * Tx Flow control is enabled, and Rx Flow control is
28835fc77b81SRobert Mustacchi 		 * disabled by software override.
28845fc77b81SRobert Mustacchi 		 */
28855fc77b81SRobert Mustacchi 		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
28865fc77b81SRobert Mustacchi 		break;
28875fc77b81SRobert Mustacchi 	case ixgbe_fc_full:
28885fc77b81SRobert Mustacchi 		/* Flow control (both Rx and Tx) is enabled by SW override. */
28895fc77b81SRobert Mustacchi 		mflcn_reg |= IXGBE_MFLCN_RFCE;
28905fc77b81SRobert Mustacchi 		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
28915fc77b81SRobert Mustacchi 		break;
28925fc77b81SRobert Mustacchi 	default:
2893dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
2894dc0cb1cdSDale Ghent 			     "Flow control param set incorrectly\n");
28955fc77b81SRobert Mustacchi 		ret_val = IXGBE_ERR_CONFIG;
28965fc77b81SRobert Mustacchi 		goto out;
2897dc0cb1cdSDale Ghent 		break;
28985fc77b81SRobert Mustacchi 	}
28995fc77b81SRobert Mustacchi 
29005fc77b81SRobert Mustacchi 	/* Set 802.3x based flow control settings. */
29015fc77b81SRobert Mustacchi 	mflcn_reg |= IXGBE_MFLCN_DPF;
29025fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
29035fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
29045fc77b81SRobert Mustacchi 
29055fc77b81SRobert Mustacchi 
29065fc77b81SRobert Mustacchi 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
29075fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
29085fc77b81SRobert Mustacchi 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
29095fc77b81SRobert Mustacchi 		    hw->fc.high_water[i]) {
29105fc77b81SRobert Mustacchi 			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
29115fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
29125fc77b81SRobert Mustacchi 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
29135fc77b81SRobert Mustacchi 		} else {
29145fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
29155fc77b81SRobert Mustacchi 			/*
29165fc77b81SRobert Mustacchi 			 * In order to prevent Tx hangs when the internal Tx
29175fc77b81SRobert Mustacchi 			 * switch is enabled we must set the high water mark
2918dc0cb1cdSDale Ghent 			 * to the Rx packet buffer size - 24KB.  This allows
2919dc0cb1cdSDale Ghent 			 * the Tx switch to function even under heavy Rx
2920dc0cb1cdSDale Ghent 			 * workloads.
29215fc77b81SRobert Mustacchi 			 */
2922dc0cb1cdSDale Ghent 			fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
29235fc77b81SRobert Mustacchi 		}
29245fc77b81SRobert Mustacchi 
29255fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
29265fc77b81SRobert Mustacchi 	}
29275fc77b81SRobert Mustacchi 
29285fc77b81SRobert Mustacchi 	/* Configure pause time (2 TCs per register) */
29295fc77b81SRobert Mustacchi 	reg = hw->fc.pause_time * 0x00010001;
29305fc77b81SRobert Mustacchi 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
29315fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
29325fc77b81SRobert Mustacchi 
29335fc77b81SRobert Mustacchi 	/* Configure flow control refresh threshold value */
29345fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
29355fc77b81SRobert Mustacchi 
29365fc77b81SRobert Mustacchi out:
29375fc77b81SRobert Mustacchi 	return ret_val;
29385fc77b81SRobert Mustacchi }
29395fc77b81SRobert Mustacchi 
29405fc77b81SRobert Mustacchi /**
29415fc77b81SRobert Mustacchi  *  ixgbe_negotiate_fc - Negotiate flow control
29425fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
29435fc77b81SRobert Mustacchi  *  @adv_reg: flow control advertised settings
29445fc77b81SRobert Mustacchi  *  @lp_reg: link partner's flow control settings
29455fc77b81SRobert Mustacchi  *  @adv_sym: symmetric pause bit in advertisement
29465fc77b81SRobert Mustacchi  *  @adv_asm: asymmetric pause bit in advertisement
29475fc77b81SRobert Mustacchi  *  @lp_sym: symmetric pause bit in link partner advertisement
29485fc77b81SRobert Mustacchi  *  @lp_asm: asymmetric pause bit in link partner advertisement
29495fc77b81SRobert Mustacchi  *
29505fc77b81SRobert Mustacchi  *  Find the intersection between advertised settings and link partner's
29515fc77b81SRobert Mustacchi  *  advertised settings
29525fc77b81SRobert Mustacchi  **/
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)2953*48ed61a7SRobert Mustacchi s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
29545fc77b81SRobert Mustacchi 		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
29555fc77b81SRobert Mustacchi {
2956dc0cb1cdSDale Ghent 	if ((!(adv_reg)) ||  (!(lp_reg))) {
2957dc0cb1cdSDale Ghent 		ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED,
2958dc0cb1cdSDale Ghent 			     "Local or link partner's advertised flow control "
2959dc0cb1cdSDale Ghent 			     "settings are NULL. Local: %x, link partner: %x\n",
2960dc0cb1cdSDale Ghent 			     adv_reg, lp_reg);
29615fc77b81SRobert Mustacchi 		return IXGBE_ERR_FC_NOT_NEGOTIATED;
2962dc0cb1cdSDale Ghent 	}
29635fc77b81SRobert Mustacchi 
29645fc77b81SRobert Mustacchi 	if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
29655fc77b81SRobert Mustacchi 		/*
29665fc77b81SRobert Mustacchi 		 * Now we need to check if the user selected Rx ONLY
29675fc77b81SRobert Mustacchi 		 * of pause frames.  In this case, we had to advertise
29685fc77b81SRobert Mustacchi 		 * FULL flow control because we could not advertise RX
29695fc77b81SRobert Mustacchi 		 * ONLY. Hence, we must now check to see if we need to
29705fc77b81SRobert Mustacchi 		 * turn OFF the TRANSMISSION of PAUSE frames.
29715fc77b81SRobert Mustacchi 		 */
29725fc77b81SRobert Mustacchi 		if (hw->fc.requested_mode == ixgbe_fc_full) {
29735fc77b81SRobert Mustacchi 			hw->fc.current_mode = ixgbe_fc_full;
29745fc77b81SRobert Mustacchi 			DEBUGOUT("Flow Control = FULL.\n");
29755fc77b81SRobert Mustacchi 		} else {
29765fc77b81SRobert Mustacchi 			hw->fc.current_mode = ixgbe_fc_rx_pause;
29775fc77b81SRobert Mustacchi 			DEBUGOUT("Flow Control=RX PAUSE frames only\n");
29785fc77b81SRobert Mustacchi 		}
29795fc77b81SRobert Mustacchi 	} else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
29805fc77b81SRobert Mustacchi 		   (lp_reg & lp_sym) && (lp_reg & lp_asm)) {
29815fc77b81SRobert Mustacchi 		hw->fc.current_mode = ixgbe_fc_tx_pause;
29825fc77b81SRobert Mustacchi 		DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
29835fc77b81SRobert Mustacchi 	} else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
29845fc77b81SRobert Mustacchi 		   !(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
29855fc77b81SRobert Mustacchi 		hw->fc.current_mode = ixgbe_fc_rx_pause;
29865fc77b81SRobert Mustacchi 		DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
29875fc77b81SRobert Mustacchi 	} else {
29885fc77b81SRobert Mustacchi 		hw->fc.current_mode = ixgbe_fc_none;
29895fc77b81SRobert Mustacchi 		DEBUGOUT("Flow Control = NONE.\n");
29905fc77b81SRobert Mustacchi 	}
29915fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
29925fc77b81SRobert Mustacchi }
29935fc77b81SRobert Mustacchi 
29945fc77b81SRobert Mustacchi /**
29955fc77b81SRobert Mustacchi  *  ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
29965fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
29975fc77b81SRobert Mustacchi  *
29985fc77b81SRobert Mustacchi  *  Enable flow control according on 1 gig fiber.
29995fc77b81SRobert Mustacchi  **/
ixgbe_fc_autoneg_fiber(struct ixgbe_hw * hw)30005fc77b81SRobert Mustacchi static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
30015fc77b81SRobert Mustacchi {
30025fc77b81SRobert Mustacchi 	u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
30035fc77b81SRobert Mustacchi 	s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
30045fc77b81SRobert Mustacchi 
30055fc77b81SRobert Mustacchi 	/*
30065fc77b81SRobert Mustacchi 	 * On multispeed fiber at 1g, bail out if
30075fc77b81SRobert Mustacchi 	 * - link is up but AN did not complete, or if
30085fc77b81SRobert Mustacchi 	 * - link is up and AN completed but timed out
30095fc77b81SRobert Mustacchi 	 */
30105fc77b81SRobert Mustacchi 
30115fc77b81SRobert Mustacchi 	linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
30125fc77b81SRobert Mustacchi 	if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
3013dc0cb1cdSDale Ghent 	    (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
3014dc0cb1cdSDale Ghent 		DEBUGOUT("Auto-Negotiation did not complete or timed out\n");
30155fc77b81SRobert Mustacchi 		goto out;
3016dc0cb1cdSDale Ghent 	}
30175fc77b81SRobert Mustacchi 
30185fc77b81SRobert Mustacchi 	pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
30195fc77b81SRobert Mustacchi 	pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
30205fc77b81SRobert Mustacchi 
30215fc77b81SRobert Mustacchi 	ret_val =  ixgbe_negotiate_fc(hw, pcs_anadv_reg,
30225fc77b81SRobert Mustacchi 				      pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE,
30235fc77b81SRobert Mustacchi 				      IXGBE_PCS1GANA_ASM_PAUSE,
30245fc77b81SRobert Mustacchi 				      IXGBE_PCS1GANA_SYM_PAUSE,
30255fc77b81SRobert Mustacchi 				      IXGBE_PCS1GANA_ASM_PAUSE);
30265fc77b81SRobert Mustacchi 
30275fc77b81SRobert Mustacchi out:
30285fc77b81SRobert Mustacchi 	return ret_val;
30295fc77b81SRobert Mustacchi }
30305fc77b81SRobert Mustacchi 
30315fc77b81SRobert Mustacchi /**
30325fc77b81SRobert Mustacchi  *  ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
30335fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
30345fc77b81SRobert Mustacchi  *
30355fc77b81SRobert Mustacchi  *  Enable flow control according to IEEE clause 37.
30365fc77b81SRobert Mustacchi  **/
ixgbe_fc_autoneg_backplane(struct ixgbe_hw * hw)30375fc77b81SRobert Mustacchi static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
30385fc77b81SRobert Mustacchi {
30395fc77b81SRobert Mustacchi 	u32 links2, anlp1_reg, autoc_reg, links;
30405fc77b81SRobert Mustacchi 	s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
30415fc77b81SRobert Mustacchi 
30425fc77b81SRobert Mustacchi 	/*
30435fc77b81SRobert Mustacchi 	 * On backplane, bail out if
30445fc77b81SRobert Mustacchi 	 * - backplane autoneg was not completed, or if
30455fc77b81SRobert Mustacchi 	 * - we are 82599 and link partner is not AN enabled
30465fc77b81SRobert Mustacchi 	 */
30475fc77b81SRobert Mustacchi 	links = IXGBE_READ_REG(hw, IXGBE_LINKS);
3048dc0cb1cdSDale Ghent 	if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) {
3049dc0cb1cdSDale Ghent 		DEBUGOUT("Auto-Negotiation did not complete\n");
30505fc77b81SRobert Mustacchi 		goto out;
3051dc0cb1cdSDale Ghent 	}
30525fc77b81SRobert Mustacchi 
30535fc77b81SRobert Mustacchi 	if (hw->mac.type == ixgbe_mac_82599EB) {
30545fc77b81SRobert Mustacchi 		links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
3055dc0cb1cdSDale Ghent 		if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) {
3056dc0cb1cdSDale Ghent 			DEBUGOUT("Link partner is not AN enabled\n");
30575fc77b81SRobert Mustacchi 			goto out;
30585fc77b81SRobert Mustacchi 		}
3059dc0cb1cdSDale Ghent 	}
30605fc77b81SRobert Mustacchi 	/*
30615fc77b81SRobert Mustacchi 	 * Read the 10g AN autoc and LP ability registers and resolve
30625fc77b81SRobert Mustacchi 	 * local flow control settings accordingly
30635fc77b81SRobert Mustacchi 	 */
30645fc77b81SRobert Mustacchi 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
30655fc77b81SRobert Mustacchi 	anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
30665fc77b81SRobert Mustacchi 
30675fc77b81SRobert Mustacchi 	ret_val = ixgbe_negotiate_fc(hw, autoc_reg,
30685fc77b81SRobert Mustacchi 		anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE,
30695fc77b81SRobert Mustacchi 		IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE);
30705fc77b81SRobert Mustacchi 
30715fc77b81SRobert Mustacchi out:
30725fc77b81SRobert Mustacchi 	return ret_val;
30735fc77b81SRobert Mustacchi }
30745fc77b81SRobert Mustacchi 
30755fc77b81SRobert Mustacchi /**
30765fc77b81SRobert Mustacchi  *  ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
30775fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
30785fc77b81SRobert Mustacchi  *
30795fc77b81SRobert Mustacchi  *  Enable flow control according to IEEE clause 37.
30805fc77b81SRobert Mustacchi  **/
ixgbe_fc_autoneg_copper(struct ixgbe_hw * hw)30815fc77b81SRobert Mustacchi static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
30825fc77b81SRobert Mustacchi {
30835fc77b81SRobert Mustacchi 	u16 technology_ability_reg = 0;
30845fc77b81SRobert Mustacchi 	u16 lp_technology_ability_reg = 0;
30855fc77b81SRobert Mustacchi 
30865fc77b81SRobert Mustacchi 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
30875fc77b81SRobert Mustacchi 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
30885fc77b81SRobert Mustacchi 			     &technology_ability_reg);
30895fc77b81SRobert Mustacchi 	hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP,
30905fc77b81SRobert Mustacchi 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
30915fc77b81SRobert Mustacchi 			     &lp_technology_ability_reg);
30925fc77b81SRobert Mustacchi 
30935fc77b81SRobert Mustacchi 	return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg,
30945fc77b81SRobert Mustacchi 				  (u32)lp_technology_ability_reg,
30955fc77b81SRobert Mustacchi 				  IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE,
30965fc77b81SRobert Mustacchi 				  IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE);
30975fc77b81SRobert Mustacchi }
30985fc77b81SRobert Mustacchi 
30995fc77b81SRobert Mustacchi /**
31005fc77b81SRobert Mustacchi  *  ixgbe_fc_autoneg - Configure flow control
31015fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
31025fc77b81SRobert Mustacchi  *
31035fc77b81SRobert Mustacchi  *  Compares our advertised flow control capabilities to those advertised by
31045fc77b81SRobert Mustacchi  *  our link partner, and determines the proper flow control mode to use.
31055fc77b81SRobert Mustacchi  **/
ixgbe_fc_autoneg(struct ixgbe_hw * hw)31065fc77b81SRobert Mustacchi void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
31075fc77b81SRobert Mustacchi {
31085fc77b81SRobert Mustacchi 	s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
31095fc77b81SRobert Mustacchi 	ixgbe_link_speed speed;
31105fc77b81SRobert Mustacchi 	bool link_up;
31115fc77b81SRobert Mustacchi 
31125fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_fc_autoneg");
31135fc77b81SRobert Mustacchi 
31145fc77b81SRobert Mustacchi 	/*
31155fc77b81SRobert Mustacchi 	 * AN should have completed when the cable was plugged in.
31165fc77b81SRobert Mustacchi 	 * Look for reasons to bail out.  Bail out if:
31175fc77b81SRobert Mustacchi 	 * - FC autoneg is disabled, or if
31185fc77b81SRobert Mustacchi 	 * - link is not up.
31195fc77b81SRobert Mustacchi 	 */
3120dc0cb1cdSDale Ghent 	if (hw->fc.disable_fc_autoneg) {
3121dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3122dc0cb1cdSDale Ghent 			     "Flow control autoneg is disabled");
31235fc77b81SRobert Mustacchi 		goto out;
3124dc0cb1cdSDale Ghent 	}
31255fc77b81SRobert Mustacchi 
31265fc77b81SRobert Mustacchi 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
3127dc0cb1cdSDale Ghent 	if (!link_up) {
3128dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
31295fc77b81SRobert Mustacchi 		goto out;
3130dc0cb1cdSDale Ghent 	}
31315fc77b81SRobert Mustacchi 
31325fc77b81SRobert Mustacchi 	switch (hw->phy.media_type) {
31335fc77b81SRobert Mustacchi 	/* Autoneg flow control on fiber adapters */
3134dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber_fixed:
3135dc0cb1cdSDale Ghent 	case ixgbe_media_type_fiber_qsfp:
31365fc77b81SRobert Mustacchi 	case ixgbe_media_type_fiber:
31375fc77b81SRobert Mustacchi 		if (speed == IXGBE_LINK_SPEED_1GB_FULL)
31385fc77b81SRobert Mustacchi 			ret_val = ixgbe_fc_autoneg_fiber(hw);
31395fc77b81SRobert Mustacchi 		break;
31405fc77b81SRobert Mustacchi 
31415fc77b81SRobert Mustacchi 	/* Autoneg flow control on backplane adapters */
31425fc77b81SRobert Mustacchi 	case ixgbe_media_type_backplane:
31435fc77b81SRobert Mustacchi 		ret_val = ixgbe_fc_autoneg_backplane(hw);
31445fc77b81SRobert Mustacchi 		break;
31455fc77b81SRobert Mustacchi 
31465fc77b81SRobert Mustacchi 	/* Autoneg flow control on copper adapters */
31475fc77b81SRobert Mustacchi 	case ixgbe_media_type_copper:
3148dc0cb1cdSDale Ghent 		if (ixgbe_device_supports_autoneg_fc(hw))
31495fc77b81SRobert Mustacchi 			ret_val = ixgbe_fc_autoneg_copper(hw);
31505fc77b81SRobert Mustacchi 		break;
31515fc77b81SRobert Mustacchi 
31525fc77b81SRobert Mustacchi 	default:
31535fc77b81SRobert Mustacchi 		break;
31545fc77b81SRobert Mustacchi 	}
31555fc77b81SRobert Mustacchi 
31565fc77b81SRobert Mustacchi out:
31575fc77b81SRobert Mustacchi 	if (ret_val == IXGBE_SUCCESS) {
31585fc77b81SRobert Mustacchi 		hw->fc.fc_was_autonegged = TRUE;
31595fc77b81SRobert Mustacchi 	} else {
31605fc77b81SRobert Mustacchi 		hw->fc.fc_was_autonegged = FALSE;
31615fc77b81SRobert Mustacchi 		hw->fc.current_mode = hw->fc.requested_mode;
31625fc77b81SRobert Mustacchi 	}
31635fc77b81SRobert Mustacchi }
31645fc77b81SRobert Mustacchi 
3165dc0cb1cdSDale Ghent /*
3166dc0cb1cdSDale Ghent  * ixgbe_pcie_timeout_poll - Return number of times to poll for completion
3167dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
3168dc0cb1cdSDale Ghent  *
3169dc0cb1cdSDale Ghent  * System-wide timeout range is encoded in PCIe Device Control2 register.
3170dc0cb1cdSDale Ghent  *
3171dc0cb1cdSDale Ghent  * Add 10% to specified maximum and return the number of times to poll for
3172dc0cb1cdSDale Ghent  * completion timeout, in units of 100 microsec.  Never return less than
3173dc0cb1cdSDale Ghent  * 800 = 80 millisec.
3174dc0cb1cdSDale Ghent  */
ixgbe_pcie_timeout_poll(struct ixgbe_hw * hw)3175dc0cb1cdSDale Ghent static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw)
3176dc0cb1cdSDale Ghent {
3177dc0cb1cdSDale Ghent 	s16 devctl2;
3178dc0cb1cdSDale Ghent 	u32 pollcnt;
3179dc0cb1cdSDale Ghent 
3180dc0cb1cdSDale Ghent 	devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
3181dc0cb1cdSDale Ghent 	devctl2 &= IXGBE_PCIDEVCTRL2_TIMEO_MASK;
3182dc0cb1cdSDale Ghent 
3183dc0cb1cdSDale Ghent 	switch (devctl2) {
3184dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_65_130ms:
3185dc0cb1cdSDale Ghent 		pollcnt = 1300;		/* 130 millisec */
3186dc0cb1cdSDale Ghent 		break;
3187dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_260_520ms:
3188dc0cb1cdSDale Ghent 		pollcnt = 5200;		/* 520 millisec */
3189dc0cb1cdSDale Ghent 		break;
3190dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_1_2s:
3191dc0cb1cdSDale Ghent 		pollcnt = 20000;	/* 2 sec */
3192dc0cb1cdSDale Ghent 		break;
3193dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_4_8s:
3194dc0cb1cdSDale Ghent 		pollcnt = 80000;	/* 8 sec */
3195dc0cb1cdSDale Ghent 		break;
3196dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_17_34s:
3197dc0cb1cdSDale Ghent 		pollcnt = 34000;	/* 34 sec */
3198dc0cb1cdSDale Ghent 		break;
3199dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_50_100us:	/* 100 microsecs */
3200dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_1_2ms:		/* 2 millisecs */
3201dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_16_32ms:		/* 32 millisec */
3202dc0cb1cdSDale Ghent 	case IXGBE_PCIDEVCTRL2_16_32ms_def:	/* 32 millisec default */
3203dc0cb1cdSDale Ghent 	default:
3204dc0cb1cdSDale Ghent 		pollcnt = 800;		/* 80 millisec minimum */
3205dc0cb1cdSDale Ghent 		break;
3206dc0cb1cdSDale Ghent 	}
3207dc0cb1cdSDale Ghent 
3208dc0cb1cdSDale Ghent 	/* add 10% to spec maximum */
3209dc0cb1cdSDale Ghent 	return (pollcnt * 11) / 10;
3210dc0cb1cdSDale Ghent }
3211dc0cb1cdSDale Ghent 
32125fc77b81SRobert Mustacchi /**
32135fc77b81SRobert Mustacchi  *  ixgbe_disable_pcie_master - Disable PCI-express master access
32145fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
32155fc77b81SRobert Mustacchi  *
32165fc77b81SRobert Mustacchi  *  Disables PCI-Express master access and verifies there are no pending
32175fc77b81SRobert Mustacchi  *  requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable
32185fc77b81SRobert Mustacchi  *  bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS
32195fc77b81SRobert Mustacchi  *  is returned signifying master requests disabled.
32205fc77b81SRobert Mustacchi  **/
ixgbe_disable_pcie_master(struct ixgbe_hw * hw)32215fc77b81SRobert Mustacchi s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
32225fc77b81SRobert Mustacchi {
32235fc77b81SRobert Mustacchi 	s32 status = IXGBE_SUCCESS;
3224dc0cb1cdSDale Ghent 	u32 i, poll;
3225dc0cb1cdSDale Ghent 	u16 value;
32265fc77b81SRobert Mustacchi 
32275fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_disable_pcie_master");
32285fc77b81SRobert Mustacchi 
32295fc77b81SRobert Mustacchi 	/* Always set this bit to ensure any future transactions are blocked */
32305fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
32315fc77b81SRobert Mustacchi 
3232dc0cb1cdSDale Ghent 	/* Exit if master requests are blocked */
3233dc0cb1cdSDale Ghent 	if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
323474b989c3SRobert Mustacchi 	    IXGBE_REMOVED(hw))
32355fc77b81SRobert Mustacchi 		goto out;
32365fc77b81SRobert Mustacchi 
32375fc77b81SRobert Mustacchi 	/* Poll for master request bit to clear */
32385fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
32395fc77b81SRobert Mustacchi 		usec_delay(100);
32405fc77b81SRobert Mustacchi 		if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
32415fc77b81SRobert Mustacchi 			goto out;
32425fc77b81SRobert Mustacchi 	}
32435fc77b81SRobert Mustacchi 
32445fc77b81SRobert Mustacchi 	/*
32455fc77b81SRobert Mustacchi 	 * Two consecutive resets are required via CTRL.RST per datasheet
32465fc77b81SRobert Mustacchi 	 * 5.2.5.3.2 Master Disable.  We set a flag to inform the reset routine
32475fc77b81SRobert Mustacchi 	 * of this need.  The first reset prevents new master requests from
32485fc77b81SRobert Mustacchi 	 * being issued by our device.  We then must wait 1usec or more for any
32495fc77b81SRobert Mustacchi 	 * remaining completions from the PCIe bus to trickle in, and then reset
32505fc77b81SRobert Mustacchi 	 * again to clear out any effects they may have had on our device.
32515fc77b81SRobert Mustacchi 	 */
32525fc77b81SRobert Mustacchi 	DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n");
32535fc77b81SRobert Mustacchi 	hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
32545fc77b81SRobert Mustacchi 
3255dc0cb1cdSDale Ghent 	if (hw->mac.type >= ixgbe_mac_X550)
3256dc0cb1cdSDale Ghent 		goto out;
3257dc0cb1cdSDale Ghent 
32585fc77b81SRobert Mustacchi 	/*
32595fc77b81SRobert Mustacchi 	 * Before proceeding, make sure that the PCIe block does not have
32605fc77b81SRobert Mustacchi 	 * transactions pending.
32615fc77b81SRobert Mustacchi 	 */
3262dc0cb1cdSDale Ghent 	poll = ixgbe_pcie_timeout_poll(hw);
3263dc0cb1cdSDale Ghent 	for (i = 0; i < poll; i++) {
32645fc77b81SRobert Mustacchi 		usec_delay(100);
3265dc0cb1cdSDale Ghent 		value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS);
326674b989c3SRobert Mustacchi 		if (IXGBE_REMOVED(hw))
3267dc0cb1cdSDale Ghent 			goto out;
3268dc0cb1cdSDale Ghent 		if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
32695fc77b81SRobert Mustacchi 			goto out;
32705fc77b81SRobert Mustacchi 	}
32715fc77b81SRobert Mustacchi 
3272dc0cb1cdSDale Ghent 	ERROR_REPORT1(IXGBE_ERROR_POLLING,
3273dc0cb1cdSDale Ghent 		     "PCIe transaction pending bit also did not clear.\n");
32745fc77b81SRobert Mustacchi 	status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
32755fc77b81SRobert Mustacchi 
32765fc77b81SRobert Mustacchi out:
32775fc77b81SRobert Mustacchi 	return status;
32785fc77b81SRobert Mustacchi }
32795fc77b81SRobert Mustacchi 
32805fc77b81SRobert Mustacchi /**
32815fc77b81SRobert Mustacchi  *  ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
32825fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
32835fc77b81SRobert Mustacchi  *  @mask: Mask to specify which semaphore to acquire
32845fc77b81SRobert Mustacchi  *
32855fc77b81SRobert Mustacchi  *  Acquires the SWFW semaphore through the GSSR register for the specified
32865fc77b81SRobert Mustacchi  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
32875fc77b81SRobert Mustacchi  **/
ixgbe_acquire_swfw_sync(struct ixgbe_hw * hw,u32 mask)3288dc0cb1cdSDale Ghent s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask)
32895fc77b81SRobert Mustacchi {
3290dc0cb1cdSDale Ghent 	u32 gssr = 0;
32915fc77b81SRobert Mustacchi 	u32 swmask = mask;
32925fc77b81SRobert Mustacchi 	u32 fwmask = mask << 5;
3293dc0cb1cdSDale Ghent 	u32 timeout = 200;
3294dc0cb1cdSDale Ghent 	u32 i;
32955fc77b81SRobert Mustacchi 
32965fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_acquire_swfw_sync");
32975fc77b81SRobert Mustacchi 
3298dc0cb1cdSDale Ghent 	for (i = 0; i < timeout; i++) {
32995fc77b81SRobert Mustacchi 		/*
3300dc0cb1cdSDale Ghent 		 * SW NVM semaphore bit is used for access to all
3301dc0cb1cdSDale Ghent 		 * SW_FW_SYNC bits (not just NVM)
33025fc77b81SRobert Mustacchi 		 */
33035fc77b81SRobert Mustacchi 		if (ixgbe_get_eeprom_semaphore(hw))
33045fc77b81SRobert Mustacchi 			return IXGBE_ERR_SWFW_SYNC;
33055fc77b81SRobert Mustacchi 
33065fc77b81SRobert Mustacchi 		gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
3307dc0cb1cdSDale Ghent 		if (!(gssr & (fwmask | swmask))) {
33085fc77b81SRobert Mustacchi 			gssr |= swmask;
33095fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
33105fc77b81SRobert Mustacchi 			ixgbe_release_eeprom_semaphore(hw);
33115fc77b81SRobert Mustacchi 			return IXGBE_SUCCESS;
3312dc0cb1cdSDale Ghent 		} else {
3313dc0cb1cdSDale Ghent 			/* Resource is currently in use by FW or SW */
3314dc0cb1cdSDale Ghent 			ixgbe_release_eeprom_semaphore(hw);
3315dc0cb1cdSDale Ghent 			msec_delay(5);
3316dc0cb1cdSDale Ghent 		}
3317dc0cb1cdSDale Ghent 	}
3318dc0cb1cdSDale Ghent 
3319dc0cb1cdSDale Ghent 	/* If time expired clear the bits holding the lock and retry */
3320dc0cb1cdSDale Ghent 	if (gssr & (fwmask | swmask))
3321dc0cb1cdSDale Ghent 		ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
3322dc0cb1cdSDale Ghent 
3323dc0cb1cdSDale Ghent 	msec_delay(5);
3324dc0cb1cdSDale Ghent 	return IXGBE_ERR_SWFW_SYNC;
33255fc77b81SRobert Mustacchi }
33265fc77b81SRobert Mustacchi 
33275fc77b81SRobert Mustacchi /**
33285fc77b81SRobert Mustacchi  *  ixgbe_release_swfw_sync - Release SWFW semaphore
33295fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
33305fc77b81SRobert Mustacchi  *  @mask: Mask to specify which semaphore to release
33315fc77b81SRobert Mustacchi  *
33325fc77b81SRobert Mustacchi  *  Releases the SWFW semaphore through the GSSR register for the specified
33335fc77b81SRobert Mustacchi  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
33345fc77b81SRobert Mustacchi  **/
ixgbe_release_swfw_sync(struct ixgbe_hw * hw,u32 mask)3335dc0cb1cdSDale Ghent void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask)
33365fc77b81SRobert Mustacchi {
33375fc77b81SRobert Mustacchi 	u32 gssr;
33385fc77b81SRobert Mustacchi 	u32 swmask = mask;
33395fc77b81SRobert Mustacchi 
33405fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_release_swfw_sync");
33415fc77b81SRobert Mustacchi 
3342dc0cb1cdSDale Ghent 	ixgbe_get_eeprom_semaphore(hw);
33435fc77b81SRobert Mustacchi 
33445fc77b81SRobert Mustacchi 	gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
33455fc77b81SRobert Mustacchi 	gssr &= ~swmask;
33465fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
33475fc77b81SRobert Mustacchi 
33485fc77b81SRobert Mustacchi 	ixgbe_release_eeprom_semaphore(hw);
33495fc77b81SRobert Mustacchi }
33505fc77b81SRobert Mustacchi 
33515fc77b81SRobert Mustacchi /**
33525fc77b81SRobert Mustacchi  *  ixgbe_disable_sec_rx_path_generic - Stops the receive data path
33535fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
33545fc77b81SRobert Mustacchi  *
33555fc77b81SRobert Mustacchi  *  Stops the receive data path and waits for the HW to internally empty
33565fc77b81SRobert Mustacchi  *  the Rx security block
33575fc77b81SRobert Mustacchi  **/
ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw * hw)33585fc77b81SRobert Mustacchi s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
33595fc77b81SRobert Mustacchi {
33605fc77b81SRobert Mustacchi #define IXGBE_MAX_SECRX_POLL 40
33615fc77b81SRobert Mustacchi 
33625fc77b81SRobert Mustacchi 	int i;
33635fc77b81SRobert Mustacchi 	int secrxreg;
33645fc77b81SRobert Mustacchi 
33655fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_disable_sec_rx_path_generic");
33665fc77b81SRobert Mustacchi 
33675fc77b81SRobert Mustacchi 
33685fc77b81SRobert Mustacchi 	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
33695fc77b81SRobert Mustacchi 	secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
33705fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
33715fc77b81SRobert Mustacchi 	for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
33725fc77b81SRobert Mustacchi 		secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
33735fc77b81SRobert Mustacchi 		if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
33745fc77b81SRobert Mustacchi 			break;
33755fc77b81SRobert Mustacchi 		else
33765fc77b81SRobert Mustacchi 			/* Use interrupt-safe sleep just in case */
33775fc77b81SRobert Mustacchi 			usec_delay(1000);
33785fc77b81SRobert Mustacchi 	}
33795fc77b81SRobert Mustacchi 
33805fc77b81SRobert Mustacchi 	/* For informational purposes only */
33815fc77b81SRobert Mustacchi 	if (i >= IXGBE_MAX_SECRX_POLL)
33825fc77b81SRobert Mustacchi 		DEBUGOUT("Rx unit being enabled before security "
33835fc77b81SRobert Mustacchi 			 "path fully disabled.  Continuing with init.\n");
33845fc77b81SRobert Mustacchi 
33855fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
33865fc77b81SRobert Mustacchi }
33875fc77b81SRobert Mustacchi 
33885fc77b81SRobert Mustacchi /**
3389dc0cb1cdSDale Ghent  *  prot_autoc_read_generic - Hides MAC differences needed for AUTOC read
3390dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
3391*48ed61a7SRobert Mustacchi  *  @locked: bool to indicate whether the SW/FW lock was taken
3392dc0cb1cdSDale Ghent  *  @reg_val: Value we read from AUTOC
3393dc0cb1cdSDale Ghent  *
3394dc0cb1cdSDale Ghent  *  The default case requires no protection so just to the register read.
3395dc0cb1cdSDale Ghent  */
prot_autoc_read_generic(struct ixgbe_hw * hw,bool * locked,u32 * reg_val)3396dc0cb1cdSDale Ghent s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
3397dc0cb1cdSDale Ghent {
3398dc0cb1cdSDale Ghent 	*locked = FALSE;
3399dc0cb1cdSDale Ghent 	*reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
3400dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
3401dc0cb1cdSDale Ghent }
3402dc0cb1cdSDale Ghent 
3403dc0cb1cdSDale Ghent /**
3404dc0cb1cdSDale Ghent  * prot_autoc_write_generic - Hides MAC differences needed for AUTOC write
3405dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
3406dc0cb1cdSDale Ghent  * @reg_val: value to write to AUTOC
3407dc0cb1cdSDale Ghent  * @locked: bool to indicate whether the SW/FW lock was already taken by
3408dc0cb1cdSDale Ghent  *           previous read.
3409dc0cb1cdSDale Ghent  *
3410dc0cb1cdSDale Ghent  * The default case requires no protection so just to the register write.
3411dc0cb1cdSDale Ghent  */
prot_autoc_write_generic(struct ixgbe_hw * hw,u32 reg_val,bool locked)3412dc0cb1cdSDale Ghent s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked)
3413dc0cb1cdSDale Ghent {
3414dc0cb1cdSDale Ghent 	UNREFERENCED_1PARAMETER(locked);
3415dc0cb1cdSDale Ghent 
3416dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_val);
3417dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
3418dc0cb1cdSDale Ghent }
3419dc0cb1cdSDale Ghent 
3420dc0cb1cdSDale Ghent /**
34215fc77b81SRobert Mustacchi  *  ixgbe_enable_sec_rx_path_generic - Enables the receive data path
34225fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
34235fc77b81SRobert Mustacchi  *
34245fc77b81SRobert Mustacchi  *  Enables the receive data path.
34255fc77b81SRobert Mustacchi  **/
ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw * hw)34265fc77b81SRobert Mustacchi s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw)
34275fc77b81SRobert Mustacchi {
3428*48ed61a7SRobert Mustacchi 	u32 secrxreg;
34295fc77b81SRobert Mustacchi 
34305fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_enable_sec_rx_path_generic");
34315fc77b81SRobert Mustacchi 
34325fc77b81SRobert Mustacchi 	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
34335fc77b81SRobert Mustacchi 	secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
34345fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
34355fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
34365fc77b81SRobert Mustacchi 
34375fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
34385fc77b81SRobert Mustacchi }
34395fc77b81SRobert Mustacchi 
34405fc77b81SRobert Mustacchi /**
34415fc77b81SRobert Mustacchi  *  ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
34425fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
34435fc77b81SRobert Mustacchi  *  @regval: register value to write to RXCTRL
34445fc77b81SRobert Mustacchi  *
34455fc77b81SRobert Mustacchi  *  Enables the Rx DMA unit
34465fc77b81SRobert Mustacchi  **/
ixgbe_enable_rx_dma_generic(struct ixgbe_hw * hw,u32 regval)34475fc77b81SRobert Mustacchi s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
34485fc77b81SRobert Mustacchi {
34495fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_enable_rx_dma_generic");
34505fc77b81SRobert Mustacchi 
3451dc0cb1cdSDale Ghent 	if (regval & IXGBE_RXCTRL_RXEN)
3452dc0cb1cdSDale Ghent 		ixgbe_enable_rx(hw);
3453dc0cb1cdSDale Ghent 	else
3454dc0cb1cdSDale Ghent 		ixgbe_disable_rx(hw);
34555fc77b81SRobert Mustacchi 
34565fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
34575fc77b81SRobert Mustacchi }
34585fc77b81SRobert Mustacchi 
34595fc77b81SRobert Mustacchi /**
34605fc77b81SRobert Mustacchi  *  ixgbe_blink_led_start_generic - Blink LED based on index.
34615fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
34625fc77b81SRobert Mustacchi  *  @index: led number to blink
34635fc77b81SRobert Mustacchi  **/
ixgbe_blink_led_start_generic(struct ixgbe_hw * hw,u32 index)34645fc77b81SRobert Mustacchi s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
34655fc77b81SRobert Mustacchi {
34665fc77b81SRobert Mustacchi 	ixgbe_link_speed speed = 0;
34675fc77b81SRobert Mustacchi 	bool link_up = 0;
3468dc0cb1cdSDale Ghent 	u32 autoc_reg = 0;
34695fc77b81SRobert Mustacchi 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
3470dc0cb1cdSDale Ghent 	s32 ret_val = IXGBE_SUCCESS;
3471dc0cb1cdSDale Ghent 	bool locked = FALSE;
34725fc77b81SRobert Mustacchi 
34735fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_blink_led_start_generic");
34745fc77b81SRobert Mustacchi 
3475*48ed61a7SRobert Mustacchi 	if (index > 3)
3476*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_PARAM;
3477*48ed61a7SRobert Mustacchi 
34785fc77b81SRobert Mustacchi 	/*
34795fc77b81SRobert Mustacchi 	 * Link must be up to auto-blink the LEDs;
34805fc77b81SRobert Mustacchi 	 * Force it if link is down.
34815fc77b81SRobert Mustacchi 	 */
34825fc77b81SRobert Mustacchi 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
34835fc77b81SRobert Mustacchi 
34845fc77b81SRobert Mustacchi 	if (!link_up) {
3485dc0cb1cdSDale Ghent 		ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
3486dc0cb1cdSDale Ghent 		if (ret_val != IXGBE_SUCCESS)
3487dc0cb1cdSDale Ghent 			goto out;
3488dc0cb1cdSDale Ghent 
34895fc77b81SRobert Mustacchi 		autoc_reg |= IXGBE_AUTOC_AN_RESTART;
34905fc77b81SRobert Mustacchi 		autoc_reg |= IXGBE_AUTOC_FLU;
3491dc0cb1cdSDale Ghent 
3492dc0cb1cdSDale Ghent 		ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
3493dc0cb1cdSDale Ghent 		if (ret_val != IXGBE_SUCCESS)
3494dc0cb1cdSDale Ghent 			goto out;
3495dc0cb1cdSDale Ghent 
34965fc77b81SRobert Mustacchi 		IXGBE_WRITE_FLUSH(hw);
34975fc77b81SRobert Mustacchi 		msec_delay(10);
34985fc77b81SRobert Mustacchi 	}
34995fc77b81SRobert Mustacchi 
35005fc77b81SRobert Mustacchi 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
35015fc77b81SRobert Mustacchi 	led_reg |= IXGBE_LED_BLINK(index);
35025fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
35035fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
35045fc77b81SRobert Mustacchi 
3505dc0cb1cdSDale Ghent out:
3506dc0cb1cdSDale Ghent 	return ret_val;
35075fc77b81SRobert Mustacchi }
35085fc77b81SRobert Mustacchi 
35095fc77b81SRobert Mustacchi /**
35105fc77b81SRobert Mustacchi  *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
35115fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
35125fc77b81SRobert Mustacchi  *  @index: led number to stop blinking
35135fc77b81SRobert Mustacchi  **/
ixgbe_blink_led_stop_generic(struct ixgbe_hw * hw,u32 index)35145fc77b81SRobert Mustacchi s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
35155fc77b81SRobert Mustacchi {
3516dc0cb1cdSDale Ghent 	u32 autoc_reg = 0;
35175fc77b81SRobert Mustacchi 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
3518dc0cb1cdSDale Ghent 	s32 ret_val = IXGBE_SUCCESS;
3519dc0cb1cdSDale Ghent 	bool locked = FALSE;
35205fc77b81SRobert Mustacchi 
35215fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_blink_led_stop_generic");
35225fc77b81SRobert Mustacchi 
3523*48ed61a7SRobert Mustacchi 	if (index > 3)
3524*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_PARAM;
3525*48ed61a7SRobert Mustacchi 
3526dc0cb1cdSDale Ghent 	ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
3527dc0cb1cdSDale Ghent 	if (ret_val != IXGBE_SUCCESS)
3528dc0cb1cdSDale Ghent 		goto out;
35295fc77b81SRobert Mustacchi 
35305fc77b81SRobert Mustacchi 	autoc_reg &= ~IXGBE_AUTOC_FLU;
35315fc77b81SRobert Mustacchi 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
3532dc0cb1cdSDale Ghent 
3533dc0cb1cdSDale Ghent 	ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
3534dc0cb1cdSDale Ghent 	if (ret_val != IXGBE_SUCCESS)
3535dc0cb1cdSDale Ghent 		goto out;
35365fc77b81SRobert Mustacchi 
35375fc77b81SRobert Mustacchi 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
35385fc77b81SRobert Mustacchi 	led_reg &= ~IXGBE_LED_BLINK(index);
35395fc77b81SRobert Mustacchi 	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
35405fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
35415fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
35425fc77b81SRobert Mustacchi 
3543dc0cb1cdSDale Ghent out:
3544dc0cb1cdSDale Ghent 	return ret_val;
35455fc77b81SRobert Mustacchi }
35465fc77b81SRobert Mustacchi 
35475fc77b81SRobert Mustacchi /**
35485fc77b81SRobert Mustacchi  *  ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM
35495fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
35505fc77b81SRobert Mustacchi  *  @san_mac_offset: SAN MAC address offset
35515fc77b81SRobert Mustacchi  *
35525fc77b81SRobert Mustacchi  *  This function will read the EEPROM location for the SAN MAC address
35535fc77b81SRobert Mustacchi  *  pointer, and returns the value at that location.  This is used in both
35545fc77b81SRobert Mustacchi  *  get and set mac_addr routines.
35555fc77b81SRobert Mustacchi  **/
ixgbe_get_san_mac_addr_offset(struct ixgbe_hw * hw,u16 * san_mac_offset)35565fc77b81SRobert Mustacchi static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
35575fc77b81SRobert Mustacchi 					 u16 *san_mac_offset)
35585fc77b81SRobert Mustacchi {
3559dc0cb1cdSDale Ghent 	s32 ret_val;
3560dc0cb1cdSDale Ghent 
35615fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_san_mac_addr_offset");
35625fc77b81SRobert Mustacchi 
35635fc77b81SRobert Mustacchi 	/*
35645fc77b81SRobert Mustacchi 	 * First read the EEPROM pointer to see if the MAC addresses are
35655fc77b81SRobert Mustacchi 	 * available.
35665fc77b81SRobert Mustacchi 	 */
3567dc0cb1cdSDale Ghent 	ret_val = hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR,
3568dc0cb1cdSDale Ghent 				      san_mac_offset);
3569dc0cb1cdSDale Ghent 	if (ret_val) {
3570dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
3571dc0cb1cdSDale Ghent 			      "eeprom at offset %d failed",
3572dc0cb1cdSDale Ghent 			      IXGBE_SAN_MAC_ADDR_PTR);
3573dc0cb1cdSDale Ghent 	}
35745fc77b81SRobert Mustacchi 
3575dc0cb1cdSDale Ghent 	return ret_val;
35765fc77b81SRobert Mustacchi }
35775fc77b81SRobert Mustacchi 
35785fc77b81SRobert Mustacchi /**
35795fc77b81SRobert Mustacchi  *  ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM
35805fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
35815fc77b81SRobert Mustacchi  *  @san_mac_addr: SAN MAC address
35825fc77b81SRobert Mustacchi  *
35835fc77b81SRobert Mustacchi  *  Reads the SAN MAC address from the EEPROM, if it's available.  This is
35845fc77b81SRobert Mustacchi  *  per-port, so set_lan_id() must be called before reading the addresses.
35855fc77b81SRobert Mustacchi  *  set_lan_id() is called by identify_sfp(), but this cannot be relied
35865fc77b81SRobert Mustacchi  *  upon for non-SFP connections, so we must call it here.
35875fc77b81SRobert Mustacchi  **/
ixgbe_get_san_mac_addr_generic(struct ixgbe_hw * hw,u8 * san_mac_addr)35885fc77b81SRobert Mustacchi s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
35895fc77b81SRobert Mustacchi {
35905fc77b81SRobert Mustacchi 	u16 san_mac_data, san_mac_offset;
35915fc77b81SRobert Mustacchi 	u8 i;
3592dc0cb1cdSDale Ghent 	s32 ret_val;
35935fc77b81SRobert Mustacchi 
35945fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_san_mac_addr_generic");
35955fc77b81SRobert Mustacchi 
35965fc77b81SRobert Mustacchi 	/*
35975fc77b81SRobert Mustacchi 	 * First read the EEPROM pointer to see if the MAC addresses are
35985fc77b81SRobert Mustacchi 	 * available.  If they're not, no point in calling set_lan_id() here.
35995fc77b81SRobert Mustacchi 	 */
3600dc0cb1cdSDale Ghent 	ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
3601dc0cb1cdSDale Ghent 	if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)
36025fc77b81SRobert Mustacchi 		goto san_mac_addr_out;
36035fc77b81SRobert Mustacchi 
36045fc77b81SRobert Mustacchi 	/* make sure we know which port we need to program */
36055fc77b81SRobert Mustacchi 	hw->mac.ops.set_lan_id(hw);
36065fc77b81SRobert Mustacchi 	/* apply the port offset to the address offset */
36075fc77b81SRobert Mustacchi 	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
36085fc77b81SRobert Mustacchi 			 (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
36095fc77b81SRobert Mustacchi 	for (i = 0; i < 3; i++) {
3610dc0cb1cdSDale Ghent 		ret_val = hw->eeprom.ops.read(hw, san_mac_offset,
3611dc0cb1cdSDale Ghent 					      &san_mac_data);
3612dc0cb1cdSDale Ghent 		if (ret_val) {
3613dc0cb1cdSDale Ghent 			ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
3614dc0cb1cdSDale Ghent 				      "eeprom read at offset %d failed",
3615dc0cb1cdSDale Ghent 				      san_mac_offset);
3616dc0cb1cdSDale Ghent 			goto san_mac_addr_out;
3617dc0cb1cdSDale Ghent 		}
36185fc77b81SRobert Mustacchi 		san_mac_addr[i * 2] = (u8)(san_mac_data);
36195fc77b81SRobert Mustacchi 		san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
36205fc77b81SRobert Mustacchi 		san_mac_offset++;
36215fc77b81SRobert Mustacchi 	}
3622dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
36235fc77b81SRobert Mustacchi 
36245fc77b81SRobert Mustacchi san_mac_addr_out:
3625dc0cb1cdSDale Ghent 	/*
3626dc0cb1cdSDale Ghent 	 * No addresses available in this EEPROM.  It's not an
3627dc0cb1cdSDale Ghent 	 * error though, so just wipe the local address and return.
3628dc0cb1cdSDale Ghent 	 */
3629dc0cb1cdSDale Ghent 	for (i = 0; i < 6; i++)
3630dc0cb1cdSDale Ghent 		san_mac_addr[i] = 0xFF;
36315fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
36325fc77b81SRobert Mustacchi }
36335fc77b81SRobert Mustacchi 
36345fc77b81SRobert Mustacchi /**
36355fc77b81SRobert Mustacchi  *  ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM
36365fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
36375fc77b81SRobert Mustacchi  *  @san_mac_addr: SAN MAC address
36385fc77b81SRobert Mustacchi  *
36395fc77b81SRobert Mustacchi  *  Write a SAN MAC address to the EEPROM.
36405fc77b81SRobert Mustacchi  **/
ixgbe_set_san_mac_addr_generic(struct ixgbe_hw * hw,u8 * san_mac_addr)36415fc77b81SRobert Mustacchi s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
36425fc77b81SRobert Mustacchi {
3643dc0cb1cdSDale Ghent 	s32 ret_val;
36445fc77b81SRobert Mustacchi 	u16 san_mac_data, san_mac_offset;
36455fc77b81SRobert Mustacchi 	u8 i;
36465fc77b81SRobert Mustacchi 
36475fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_san_mac_addr_generic");
36485fc77b81SRobert Mustacchi 
36495fc77b81SRobert Mustacchi 	/* Look for SAN mac address pointer.  If not defined, return */
3650dc0cb1cdSDale Ghent 	ret_val = ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
3651dc0cb1cdSDale Ghent 	if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF)
3652dc0cb1cdSDale Ghent 		return IXGBE_ERR_NO_SAN_ADDR_PTR;
36535fc77b81SRobert Mustacchi 
36545fc77b81SRobert Mustacchi 	/* Make sure we know which port we need to write */
36555fc77b81SRobert Mustacchi 	hw->mac.ops.set_lan_id(hw);
36565fc77b81SRobert Mustacchi 	/* Apply the port offset to the address offset */
36575fc77b81SRobert Mustacchi 	(hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
36585fc77b81SRobert Mustacchi 			 (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
36595fc77b81SRobert Mustacchi 
36605fc77b81SRobert Mustacchi 	for (i = 0; i < 3; i++) {
36615fc77b81SRobert Mustacchi 		san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8);
36625fc77b81SRobert Mustacchi 		san_mac_data |= (u16)(san_mac_addr[i * 2]);
36635fc77b81SRobert Mustacchi 		hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data);
36645fc77b81SRobert Mustacchi 		san_mac_offset++;
36655fc77b81SRobert Mustacchi 	}
36665fc77b81SRobert Mustacchi 
3667dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
36685fc77b81SRobert Mustacchi }
36695fc77b81SRobert Mustacchi 
36705fc77b81SRobert Mustacchi /**
36715fc77b81SRobert Mustacchi  *  ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count
36725fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
36735fc77b81SRobert Mustacchi  *
36745fc77b81SRobert Mustacchi  *  Read PCIe configuration space, and get the MSI-X vector count from
36755fc77b81SRobert Mustacchi  *  the capabilities table.
36765fc77b81SRobert Mustacchi  **/
ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw * hw)36775fc77b81SRobert Mustacchi u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
36785fc77b81SRobert Mustacchi {
36795fc77b81SRobert Mustacchi 	u16 msix_count = 1;
36805fc77b81SRobert Mustacchi 	u16 max_msix_count;
36815fc77b81SRobert Mustacchi 	u16 pcie_offset;
36825fc77b81SRobert Mustacchi 
36835fc77b81SRobert Mustacchi 	switch (hw->mac.type) {
36845fc77b81SRobert Mustacchi 	case ixgbe_mac_82598EB:
36855fc77b81SRobert Mustacchi 		pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS;
36865fc77b81SRobert Mustacchi 		max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598;
36875fc77b81SRobert Mustacchi 		break;
36885fc77b81SRobert Mustacchi 	case ixgbe_mac_82599EB:
36895fc77b81SRobert Mustacchi 	case ixgbe_mac_X540:
3690dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
3691dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
3692*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
36935fc77b81SRobert Mustacchi 		pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
36945fc77b81SRobert Mustacchi 		max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
36955fc77b81SRobert Mustacchi 		break;
36965fc77b81SRobert Mustacchi 	default:
36975fc77b81SRobert Mustacchi 		return msix_count;
36985fc77b81SRobert Mustacchi 	}
36995fc77b81SRobert Mustacchi 
37005fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_pcie_msix_count_generic");
37015fc77b81SRobert Mustacchi 	msix_count = IXGBE_READ_PCIE_WORD(hw, pcie_offset);
370274b989c3SRobert Mustacchi 	if (IXGBE_REMOVED(hw))
3703dc0cb1cdSDale Ghent 		msix_count = 0;
37045fc77b81SRobert Mustacchi 	msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
37055fc77b81SRobert Mustacchi 
37065fc77b81SRobert Mustacchi 	/* MSI-X count is zero-based in HW */
37075fc77b81SRobert Mustacchi 	msix_count++;
37085fc77b81SRobert Mustacchi 
37095fc77b81SRobert Mustacchi 	if (msix_count > max_msix_count)
37105fc77b81SRobert Mustacchi 		msix_count = max_msix_count;
37115fc77b81SRobert Mustacchi 
37125fc77b81SRobert Mustacchi 	return msix_count;
37135fc77b81SRobert Mustacchi }
37145fc77b81SRobert Mustacchi 
37155fc77b81SRobert Mustacchi /**
37165fc77b81SRobert Mustacchi  *  ixgbe_insert_mac_addr_generic - Find a RAR for this mac address
37175fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
37185fc77b81SRobert Mustacchi  *  @addr: Address to put into receive address register
37195fc77b81SRobert Mustacchi  *  @vmdq: VMDq pool to assign
37205fc77b81SRobert Mustacchi  *
37215fc77b81SRobert Mustacchi  *  Puts an ethernet address into a receive address register, or
3722dc0cb1cdSDale Ghent  *  finds the rar that it is already in; adds to the pool list
37235fc77b81SRobert Mustacchi  **/
ixgbe_insert_mac_addr_generic(struct ixgbe_hw * hw,u8 * addr,u32 vmdq)37245fc77b81SRobert Mustacchi s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
37255fc77b81SRobert Mustacchi {
37265fc77b81SRobert Mustacchi 	static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF;
37275fc77b81SRobert Mustacchi 	u32 first_empty_rar = NO_EMPTY_RAR_FOUND;
37285fc77b81SRobert Mustacchi 	u32 rar;
37295fc77b81SRobert Mustacchi 	u32 rar_low, rar_high;
37305fc77b81SRobert Mustacchi 	u32 addr_low, addr_high;
37315fc77b81SRobert Mustacchi 
37325fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_insert_mac_addr_generic");
37335fc77b81SRobert Mustacchi 
37345fc77b81SRobert Mustacchi 	/* swap bytes for HW little endian */
37355fc77b81SRobert Mustacchi 	addr_low  = addr[0] | (addr[1] << 8)
37365fc77b81SRobert Mustacchi 			    | (addr[2] << 16)
37375fc77b81SRobert Mustacchi 			    | (addr[3] << 24);
37385fc77b81SRobert Mustacchi 	addr_high = addr[4] | (addr[5] << 8);
37395fc77b81SRobert Mustacchi 
37405fc77b81SRobert Mustacchi 	/*
37415fc77b81SRobert Mustacchi 	 * Either find the mac_id in rar or find the first empty space.
37425fc77b81SRobert Mustacchi 	 * rar_highwater points to just after the highest currently used
37435fc77b81SRobert Mustacchi 	 * rar in order to shorten the search.  It grows when we add a new
37445fc77b81SRobert Mustacchi 	 * rar to the top.
37455fc77b81SRobert Mustacchi 	 */
37465fc77b81SRobert Mustacchi 	for (rar = 0; rar < hw->mac.rar_highwater; rar++) {
37475fc77b81SRobert Mustacchi 		rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
37485fc77b81SRobert Mustacchi 
37495fc77b81SRobert Mustacchi 		if (((IXGBE_RAH_AV & rar_high) == 0)
37505fc77b81SRobert Mustacchi 		    && first_empty_rar == NO_EMPTY_RAR_FOUND) {
37515fc77b81SRobert Mustacchi 			first_empty_rar = rar;
37525fc77b81SRobert Mustacchi 		} else if ((rar_high & 0xFFFF) == addr_high) {
37535fc77b81SRobert Mustacchi 			rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar));
37545fc77b81SRobert Mustacchi 			if (rar_low == addr_low)
37555fc77b81SRobert Mustacchi 				break;    /* found it already in the rars */
37565fc77b81SRobert Mustacchi 		}
37575fc77b81SRobert Mustacchi 	}
37585fc77b81SRobert Mustacchi 
37595fc77b81SRobert Mustacchi 	if (rar < hw->mac.rar_highwater) {
37605fc77b81SRobert Mustacchi 		/* already there so just add to the pool bits */
3761dc0cb1cdSDale Ghent 		ixgbe_set_vmdq(hw, rar, vmdq);
37625fc77b81SRobert Mustacchi 	} else if (first_empty_rar != NO_EMPTY_RAR_FOUND) {
37635fc77b81SRobert Mustacchi 		/* stick it into first empty RAR slot we found */
37645fc77b81SRobert Mustacchi 		rar = first_empty_rar;
3765dc0cb1cdSDale Ghent 		ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
37665fc77b81SRobert Mustacchi 	} else if (rar == hw->mac.rar_highwater) {
37675fc77b81SRobert Mustacchi 		/* add it to the top of the list and inc the highwater mark */
3768dc0cb1cdSDale Ghent 		ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
37695fc77b81SRobert Mustacchi 		hw->mac.rar_highwater++;
37705fc77b81SRobert Mustacchi 	} else if (rar >= hw->mac.num_rar_entries) {
37715fc77b81SRobert Mustacchi 		return IXGBE_ERR_INVALID_MAC_ADDR;
37725fc77b81SRobert Mustacchi 	}
37735fc77b81SRobert Mustacchi 
37745fc77b81SRobert Mustacchi 	/*
37755fc77b81SRobert Mustacchi 	 * If we found rar[0], make sure the default pool bit (we use pool 0)
37765fc77b81SRobert Mustacchi 	 * remains cleared to be sure default pool packets will get delivered
37775fc77b81SRobert Mustacchi 	 */
37785fc77b81SRobert Mustacchi 	if (rar == 0)
3779dc0cb1cdSDale Ghent 		ixgbe_clear_vmdq(hw, rar, 0);
37805fc77b81SRobert Mustacchi 
37815fc77b81SRobert Mustacchi 	return rar;
37825fc77b81SRobert Mustacchi }
37835fc77b81SRobert Mustacchi 
37845fc77b81SRobert Mustacchi /**
37855fc77b81SRobert Mustacchi  *  ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address
37865fc77b81SRobert Mustacchi  *  @hw: pointer to hardware struct
37875fc77b81SRobert Mustacchi  *  @rar: receive address register index to disassociate
37885fc77b81SRobert Mustacchi  *  @vmdq: VMDq pool index to remove from the rar
37895fc77b81SRobert Mustacchi  **/
ixgbe_clear_vmdq_generic(struct ixgbe_hw * hw,u32 rar,u32 vmdq)37905fc77b81SRobert Mustacchi s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
37915fc77b81SRobert Mustacchi {
37925fc77b81SRobert Mustacchi 	u32 mpsar_lo, mpsar_hi;
37935fc77b81SRobert Mustacchi 	u32 rar_entries = hw->mac.num_rar_entries;
37945fc77b81SRobert Mustacchi 
37955fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_clear_vmdq_generic");
37965fc77b81SRobert Mustacchi 
37975fc77b81SRobert Mustacchi 	/* Make sure we are using a valid rar index range */
37985fc77b81SRobert Mustacchi 	if (rar >= rar_entries) {
3799dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
3800dc0cb1cdSDale Ghent 			     "RAR index %d is out of range.\n", rar);
38015fc77b81SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
38025fc77b81SRobert Mustacchi 	}
38035fc77b81SRobert Mustacchi 
38045fc77b81SRobert Mustacchi 	mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
38055fc77b81SRobert Mustacchi 	mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
38065fc77b81SRobert Mustacchi 
380774b989c3SRobert Mustacchi 	if (IXGBE_REMOVED(hw))
3808dc0cb1cdSDale Ghent 		goto done;
3809dc0cb1cdSDale Ghent 
38105fc77b81SRobert Mustacchi 	if (!mpsar_lo && !mpsar_hi)
38115fc77b81SRobert Mustacchi 		goto done;
38125fc77b81SRobert Mustacchi 
38135fc77b81SRobert Mustacchi 	if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
38145fc77b81SRobert Mustacchi 		if (mpsar_lo) {
38155fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
38165fc77b81SRobert Mustacchi 			mpsar_lo = 0;
38175fc77b81SRobert Mustacchi 		}
38185fc77b81SRobert Mustacchi 		if (mpsar_hi) {
38195fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
38205fc77b81SRobert Mustacchi 			mpsar_hi = 0;
38215fc77b81SRobert Mustacchi 		}
38225fc77b81SRobert Mustacchi 	} else if (vmdq < 32) {
38235fc77b81SRobert Mustacchi 		mpsar_lo &= ~(1 << vmdq);
38245fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
38255fc77b81SRobert Mustacchi 	} else {
38265fc77b81SRobert Mustacchi 		mpsar_hi &= ~(1 << (vmdq - 32));
38275fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
38285fc77b81SRobert Mustacchi 	}
38295fc77b81SRobert Mustacchi 
38305fc77b81SRobert Mustacchi 	/* was that the last pool using this rar? */
3831*48ed61a7SRobert Mustacchi 	if (mpsar_lo == 0 && mpsar_hi == 0 &&
3832*48ed61a7SRobert Mustacchi 	    rar != 0 && rar != hw->mac.san_mac_rar_index)
38335fc77b81SRobert Mustacchi 		hw->mac.ops.clear_rar(hw, rar);
38345fc77b81SRobert Mustacchi done:
38355fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
38365fc77b81SRobert Mustacchi }
38375fc77b81SRobert Mustacchi 
38385fc77b81SRobert Mustacchi /**
38395fc77b81SRobert Mustacchi  *  ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address
38405fc77b81SRobert Mustacchi  *  @hw: pointer to hardware struct
38415fc77b81SRobert Mustacchi  *  @rar: receive address register index to associate with a VMDq index
38425fc77b81SRobert Mustacchi  *  @vmdq: VMDq pool index
38435fc77b81SRobert Mustacchi  **/
ixgbe_set_vmdq_generic(struct ixgbe_hw * hw,u32 rar,u32 vmdq)38445fc77b81SRobert Mustacchi s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
38455fc77b81SRobert Mustacchi {
38465fc77b81SRobert Mustacchi 	u32 mpsar;
38475fc77b81SRobert Mustacchi 	u32 rar_entries = hw->mac.num_rar_entries;
38485fc77b81SRobert Mustacchi 
38495fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_vmdq_generic");
38505fc77b81SRobert Mustacchi 
38515fc77b81SRobert Mustacchi 	/* Make sure we are using a valid rar index range */
38525fc77b81SRobert Mustacchi 	if (rar >= rar_entries) {
3853dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
3854dc0cb1cdSDale Ghent 			     "RAR index %d is out of range.\n", rar);
38555fc77b81SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
38565fc77b81SRobert Mustacchi 	}
38575fc77b81SRobert Mustacchi 
38585fc77b81SRobert Mustacchi 	if (vmdq < 32) {
38595fc77b81SRobert Mustacchi 		mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
38605fc77b81SRobert Mustacchi 		mpsar |= 1 << vmdq;
38615fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
38625fc77b81SRobert Mustacchi 	} else {
38635fc77b81SRobert Mustacchi 		mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
38645fc77b81SRobert Mustacchi 		mpsar |= 1 << (vmdq - 32);
38655fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
38665fc77b81SRobert Mustacchi 	}
38675fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
38685fc77b81SRobert Mustacchi }
38695fc77b81SRobert Mustacchi 
38705fc77b81SRobert Mustacchi /**
38715fc77b81SRobert Mustacchi  *  This function should only be involved in the IOV mode.
38725fc77b81SRobert Mustacchi  *  In IOV mode, Default pool is next pool after the number of
38735fc77b81SRobert Mustacchi  *  VFs advertized and not 0.
38745fc77b81SRobert Mustacchi  *  MPSAR table needs to be updated for SAN_MAC RAR [hw->mac.san_mac_rar_index]
38755fc77b81SRobert Mustacchi  *
38765fc77b81SRobert Mustacchi  *  ixgbe_set_vmdq_san_mac - Associate default VMDq pool index with a rx address
38775fc77b81SRobert Mustacchi  *  @hw: pointer to hardware struct
38785fc77b81SRobert Mustacchi  *  @vmdq: VMDq pool index
38795fc77b81SRobert Mustacchi  **/
ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw * hw,u32 vmdq)38805fc77b81SRobert Mustacchi s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq)
38815fc77b81SRobert Mustacchi {
38825fc77b81SRobert Mustacchi 	u32 rar = hw->mac.san_mac_rar_index;
38835fc77b81SRobert Mustacchi 
38845fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_vmdq_san_mac");
38855fc77b81SRobert Mustacchi 
38865fc77b81SRobert Mustacchi 	if (vmdq < 32) {
38875fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 1 << vmdq);
38885fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
38895fc77b81SRobert Mustacchi 	} else {
38905fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
38915fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 1 << (vmdq - 32));
38925fc77b81SRobert Mustacchi 	}
38935fc77b81SRobert Mustacchi 
38945fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
38955fc77b81SRobert Mustacchi }
38965fc77b81SRobert Mustacchi 
38975fc77b81SRobert Mustacchi /**
38985fc77b81SRobert Mustacchi  *  ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array
38995fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
39005fc77b81SRobert Mustacchi  **/
ixgbe_init_uta_tables_generic(struct ixgbe_hw * hw)39015fc77b81SRobert Mustacchi s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
39025fc77b81SRobert Mustacchi {
39035fc77b81SRobert Mustacchi 	int i;
39045fc77b81SRobert Mustacchi 
39055fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_init_uta_tables_generic");
39065fc77b81SRobert Mustacchi 	DEBUGOUT(" Clearing UTA\n");
39075fc77b81SRobert Mustacchi 
39085fc77b81SRobert Mustacchi 	for (i = 0; i < 128; i++)
39095fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
39105fc77b81SRobert Mustacchi 
39115fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
39125fc77b81SRobert Mustacchi }
39135fc77b81SRobert Mustacchi 
39145fc77b81SRobert Mustacchi /**
39155fc77b81SRobert Mustacchi  *  ixgbe_find_vlvf_slot - find the vlanid or the first empty slot
39165fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
39175fc77b81SRobert Mustacchi  *  @vlan: VLAN id to write to VLAN filter
3918*48ed61a7SRobert Mustacchi  *  @vlvf_bypass: TRUE to find vlanid only, FALSE returns first empty slot if
3919*48ed61a7SRobert Mustacchi  *		  vlanid not found
3920*48ed61a7SRobert Mustacchi  *
39215fc77b81SRobert Mustacchi  *
39225fc77b81SRobert Mustacchi  *  return the VLVF index where this VLAN id should be placed
39235fc77b81SRobert Mustacchi  *
39245fc77b81SRobert Mustacchi  **/
ixgbe_find_vlvf_slot(struct ixgbe_hw * hw,u32 vlan,bool vlvf_bypass)3925*48ed61a7SRobert Mustacchi s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
39265fc77b81SRobert Mustacchi {
3927*48ed61a7SRobert Mustacchi 	s32 regindex, first_empty_slot;
3928*48ed61a7SRobert Mustacchi 	u32 bits;
39295fc77b81SRobert Mustacchi 
39305fc77b81SRobert Mustacchi 	/* short cut the special case */
39315fc77b81SRobert Mustacchi 	if (vlan == 0)
39325fc77b81SRobert Mustacchi 		return 0;
39335fc77b81SRobert Mustacchi 
3934*48ed61a7SRobert Mustacchi 	/* if vlvf_bypass is set we don't want to use an empty slot, we
3935*48ed61a7SRobert Mustacchi 	 * will simply bypass the VLVF if there are no entries present in the
3936*48ed61a7SRobert Mustacchi 	 * VLVF that contain our VLAN
39375fc77b81SRobert Mustacchi 	 */
3938*48ed61a7SRobert Mustacchi 	first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
3939*48ed61a7SRobert Mustacchi 
3940*48ed61a7SRobert Mustacchi 	/* add VLAN enable bit for comparison */
3941*48ed61a7SRobert Mustacchi 	vlan |= IXGBE_VLVF_VIEN;
3942*48ed61a7SRobert Mustacchi 
3943*48ed61a7SRobert Mustacchi 	/* Search for the vlan id in the VLVF entries. Save off the first empty
3944*48ed61a7SRobert Mustacchi 	 * slot found along the way.
3945*48ed61a7SRobert Mustacchi 	 *
3946*48ed61a7SRobert Mustacchi 	 * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
3947*48ed61a7SRobert Mustacchi 	 */
3948*48ed61a7SRobert Mustacchi 	for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
39495fc77b81SRobert Mustacchi 		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
3950*48ed61a7SRobert Mustacchi 		if (bits == vlan)
39515fc77b81SRobert Mustacchi 			return regindex;
3952*48ed61a7SRobert Mustacchi 		if (!first_empty_slot && !bits)
3953*48ed61a7SRobert Mustacchi 			first_empty_slot = regindex;
3954*48ed61a7SRobert Mustacchi 	}
3955*48ed61a7SRobert Mustacchi 
3956*48ed61a7SRobert Mustacchi 	/* If we are here then we didn't find the VLAN.  Return first empty
3957*48ed61a7SRobert Mustacchi 	 * slot we found during our search, else error.
3958*48ed61a7SRobert Mustacchi 	 */
3959*48ed61a7SRobert Mustacchi 	if (!first_empty_slot)
3960*48ed61a7SRobert Mustacchi 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "No space in VLVF.\n");
3961*48ed61a7SRobert Mustacchi 
3962*48ed61a7SRobert Mustacchi 	return first_empty_slot ? first_empty_slot : IXGBE_ERR_NO_SPACE;
39635fc77b81SRobert Mustacchi }
39645fc77b81SRobert Mustacchi 
39655fc77b81SRobert Mustacchi /**
39665fc77b81SRobert Mustacchi  *  ixgbe_set_vfta_generic - Set VLAN filter table
39675fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
39685fc77b81SRobert Mustacchi  *  @vlan: VLAN id to write to VLAN filter
3969*48ed61a7SRobert Mustacchi  *  @vind: VMDq output index that maps queue to VLAN id in VLVFB
3970*48ed61a7SRobert Mustacchi  *  @vlan_on: boolean flag to turn on/off VLAN
3971*48ed61a7SRobert Mustacchi  *  @vlvf_bypass: boolean flag indicating updating default pool is okay
39725fc77b81SRobert Mustacchi  *
39735fc77b81SRobert Mustacchi  *  Turn on/off specified VLAN in the VLAN filter table.
39745fc77b81SRobert Mustacchi  **/
ixgbe_set_vfta_generic(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,bool vlvf_bypass)39755fc77b81SRobert Mustacchi s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
3976*48ed61a7SRobert Mustacchi 			   bool vlan_on, bool vlvf_bypass)
39775fc77b81SRobert Mustacchi {
3978*48ed61a7SRobert Mustacchi 	u32 regidx, vfta_delta, vfta;
3979*48ed61a7SRobert Mustacchi 	s32 ret_val;
39805fc77b81SRobert Mustacchi 
39815fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_vfta_generic");
39825fc77b81SRobert Mustacchi 
3983*48ed61a7SRobert Mustacchi 	if (vlan > 4095 || vind > 63)
39845fc77b81SRobert Mustacchi 		return IXGBE_ERR_PARAM;
39855fc77b81SRobert Mustacchi 
39865fc77b81SRobert Mustacchi 	/*
39875fc77b81SRobert Mustacchi 	 * this is a 2 part operation - first the VFTA, then the
39885fc77b81SRobert Mustacchi 	 * VLVF and VLVFB if VT Mode is set
39895fc77b81SRobert Mustacchi 	 * We don't write the VFTA until we know the VLVF part succeeded.
39905fc77b81SRobert Mustacchi 	 */
39915fc77b81SRobert Mustacchi 
39925fc77b81SRobert Mustacchi 	/* Part 1
39935fc77b81SRobert Mustacchi 	 * The VFTA is a bitstring made up of 128 32-bit registers
39945fc77b81SRobert Mustacchi 	 * that enable the particular VLAN id, much like the MTA:
39955fc77b81SRobert Mustacchi 	 *    bits[11-5]: which register
39965fc77b81SRobert Mustacchi 	 *    bits[4-0]:  which bit in the register
39975fc77b81SRobert Mustacchi 	 */
3998*48ed61a7SRobert Mustacchi 	regidx = vlan / 32;
3999*48ed61a7SRobert Mustacchi 	vfta_delta = 1 << (vlan % 32);
4000*48ed61a7SRobert Mustacchi 	vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
40015fc77b81SRobert Mustacchi 
4002*48ed61a7SRobert Mustacchi 	/*
4003*48ed61a7SRobert Mustacchi 	 * vfta_delta represents the difference between the current value
4004*48ed61a7SRobert Mustacchi 	 * of vfta and the value we want in the register.  Since the diff
4005*48ed61a7SRobert Mustacchi 	 * is an XOR mask we can just update the vfta using an XOR
4006*48ed61a7SRobert Mustacchi 	 */
4007*48ed61a7SRobert Mustacchi 	vfta_delta &= vlan_on ? ~vfta : vfta;
4008*48ed61a7SRobert Mustacchi 	vfta ^= vfta_delta;
40095fc77b81SRobert Mustacchi 
40105fc77b81SRobert Mustacchi 	/* Part 2
40115fc77b81SRobert Mustacchi 	 * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF
40125fc77b81SRobert Mustacchi 	 */
4013*48ed61a7SRobert Mustacchi 	ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, &vfta_delta,
4014*48ed61a7SRobert Mustacchi 					 vfta, vlvf_bypass);
4015*48ed61a7SRobert Mustacchi 	if (ret_val != IXGBE_SUCCESS) {
4016*48ed61a7SRobert Mustacchi 		if (vlvf_bypass)
4017*48ed61a7SRobert Mustacchi 			goto vfta_update;
40185fc77b81SRobert Mustacchi 		return ret_val;
4019*48ed61a7SRobert Mustacchi 	}
40205fc77b81SRobert Mustacchi 
4021*48ed61a7SRobert Mustacchi vfta_update:
4022*48ed61a7SRobert Mustacchi 	/* Update VFTA now that we are ready for traffic */
4023*48ed61a7SRobert Mustacchi 	if (vfta_delta)
4024*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
40255fc77b81SRobert Mustacchi 
40265fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
40275fc77b81SRobert Mustacchi }
40285fc77b81SRobert Mustacchi 
40295fc77b81SRobert Mustacchi /**
40305fc77b81SRobert Mustacchi  *  ixgbe_set_vlvf_generic - Set VLAN Pool Filter
40315fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
40325fc77b81SRobert Mustacchi  *  @vlan: VLAN id to write to VLAN filter
4033*48ed61a7SRobert Mustacchi  *  @vind: VMDq output index that maps queue to VLAN id in VLVFB
4034*48ed61a7SRobert Mustacchi  *  @vlan_on: boolean flag to turn on/off VLAN in VLVF
4035*48ed61a7SRobert Mustacchi  *  @vfta_delta: pointer to the difference between the current value of VFTA
4036*48ed61a7SRobert Mustacchi  *		 and the desired value
4037*48ed61a7SRobert Mustacchi  *  @vfta: the desired value of the VFTA
4038*48ed61a7SRobert Mustacchi  *  @vlvf_bypass: boolean flag indicating updating default pool is okay
40395fc77b81SRobert Mustacchi  *
40405fc77b81SRobert Mustacchi  *  Turn on/off specified bit in VLVF table.
40415fc77b81SRobert Mustacchi  **/
ixgbe_set_vlvf_generic(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,u32 * vfta_delta,u32 vfta,bool vlvf_bypass)40425fc77b81SRobert Mustacchi s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
4043*48ed61a7SRobert Mustacchi 			   bool vlan_on, u32 *vfta_delta, u32 vfta,
4044*48ed61a7SRobert Mustacchi 			   bool vlvf_bypass)
40455fc77b81SRobert Mustacchi {
4046*48ed61a7SRobert Mustacchi 	u32 bits;
4047*48ed61a7SRobert Mustacchi 	s32 vlvf_index;
40485fc77b81SRobert Mustacchi 
40495fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_vlvf_generic");
40505fc77b81SRobert Mustacchi 
4051*48ed61a7SRobert Mustacchi 	if (vlan > 4095 || vind > 63)
40525fc77b81SRobert Mustacchi 		return IXGBE_ERR_PARAM;
40535fc77b81SRobert Mustacchi 
40545fc77b81SRobert Mustacchi 	/* If VT Mode is set
40555fc77b81SRobert Mustacchi 	 *   Either vlan_on
40565fc77b81SRobert Mustacchi 	 *     make sure the vlan is in VLVF
40575fc77b81SRobert Mustacchi 	 *     set the vind bit in the matching VLVFB
40585fc77b81SRobert Mustacchi 	 *   Or !vlan_on
40595fc77b81SRobert Mustacchi 	 *     clear the pool bit and possibly the vind
40605fc77b81SRobert Mustacchi 	 */
4061*48ed61a7SRobert Mustacchi 	if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
4062*48ed61a7SRobert Mustacchi 		return IXGBE_SUCCESS;
40635fc77b81SRobert Mustacchi 
4064*48ed61a7SRobert Mustacchi 	vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
40655fc77b81SRobert Mustacchi 	if (vlvf_index < 0)
40665fc77b81SRobert Mustacchi 		return vlvf_index;
40675fc77b81SRobert Mustacchi 
4068*48ed61a7SRobert Mustacchi 	bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
4069*48ed61a7SRobert Mustacchi 
40705fc77b81SRobert Mustacchi 	/* set the pool bit */
4071*48ed61a7SRobert Mustacchi 	bits |= 1 << (vind % 32);
4072*48ed61a7SRobert Mustacchi 	if (vlan_on)
4073*48ed61a7SRobert Mustacchi 		goto vlvf_update;
4074*48ed61a7SRobert Mustacchi 
40755fc77b81SRobert Mustacchi 	/* clear the pool bit */
4076*48ed61a7SRobert Mustacchi 	bits ^= 1 << (vind % 32);
4077*48ed61a7SRobert Mustacchi 
4078*48ed61a7SRobert Mustacchi 	if (!bits &&
4079*48ed61a7SRobert Mustacchi 	    !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
4080*48ed61a7SRobert Mustacchi 		/* Clear VFTA first, then disable VLVF.  Otherwise
4081*48ed61a7SRobert Mustacchi 		 * we run the risk of stray packets leaking into
4082*48ed61a7SRobert Mustacchi 		 * the PF via the default pool
4083*48ed61a7SRobert Mustacchi 		 */
4084*48ed61a7SRobert Mustacchi 		if (*vfta_delta)
4085*48ed61a7SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_VFTA(vlan / 32), vfta);
4086*48ed61a7SRobert Mustacchi 
4087*48ed61a7SRobert Mustacchi 		/* disable VLVF and clear remaining bit from pool */
4088*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
4089*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
4090*48ed61a7SRobert Mustacchi 
4091*48ed61a7SRobert Mustacchi 		return IXGBE_SUCCESS;
40925fc77b81SRobert Mustacchi 	}
40935fc77b81SRobert Mustacchi 
4094*48ed61a7SRobert Mustacchi 	/* If there are still bits set in the VLVFB registers
40955fc77b81SRobert Mustacchi 	 * for the VLAN ID indicated we need to see if the
40965fc77b81SRobert Mustacchi 	 * caller is requesting that we clear the VFTA entry bit.
40975fc77b81SRobert Mustacchi 	 * If the caller has requested that we clear the VFTA
40985fc77b81SRobert Mustacchi 	 * entry bit but there are still pools/VFs using this VLAN
40995fc77b81SRobert Mustacchi 	 * ID entry then ignore the request.  We're not worried
41005fc77b81SRobert Mustacchi 	 * about the case where we're turning the VFTA VLAN ID
41015fc77b81SRobert Mustacchi 	 * entry bit on, only when requested to turn it off as
41025fc77b81SRobert Mustacchi 	 * there may be multiple pools and/or VFs using the
41035fc77b81SRobert Mustacchi 	 * VLAN ID entry.  In that case we cannot clear the
41045fc77b81SRobert Mustacchi 	 * VFTA bit until all pools/VFs using that VLAN ID have also
41055fc77b81SRobert Mustacchi 	 * been cleared.  This will be indicated by "bits" being
41065fc77b81SRobert Mustacchi 	 * zero.
41075fc77b81SRobert Mustacchi 	 */
4108*48ed61a7SRobert Mustacchi 	*vfta_delta = 0;
4109*48ed61a7SRobert Mustacchi 
4110*48ed61a7SRobert Mustacchi vlvf_update:
4111*48ed61a7SRobert Mustacchi 	/* record pool change and enable VLAN ID if not already enabled */
4112*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
4113*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
41145fc77b81SRobert Mustacchi 
41155fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
41165fc77b81SRobert Mustacchi }
41175fc77b81SRobert Mustacchi 
41185fc77b81SRobert Mustacchi /**
41195fc77b81SRobert Mustacchi  *  ixgbe_clear_vfta_generic - Clear VLAN filter table
41205fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
41215fc77b81SRobert Mustacchi  *
41225fc77b81SRobert Mustacchi  *  Clears the VLAN filer table, and the VMDq index associated with the filter
41235fc77b81SRobert Mustacchi  **/
ixgbe_clear_vfta_generic(struct ixgbe_hw * hw)41245fc77b81SRobert Mustacchi s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
41255fc77b81SRobert Mustacchi {
41265fc77b81SRobert Mustacchi 	u32 offset;
41275fc77b81SRobert Mustacchi 
41285fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_clear_vfta_generic");
41295fc77b81SRobert Mustacchi 
41305fc77b81SRobert Mustacchi 	for (offset = 0; offset < hw->mac.vft_size; offset++)
41315fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
41325fc77b81SRobert Mustacchi 
41335fc77b81SRobert Mustacchi 	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
41345fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
41355fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
41365fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
41375fc77b81SRobert Mustacchi 	}
41385fc77b81SRobert Mustacchi 
41395fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
41405fc77b81SRobert Mustacchi }
41415fc77b81SRobert Mustacchi 
41425fc77b81SRobert Mustacchi /**
4143*48ed61a7SRobert Mustacchi  *  ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix
4144*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
4145*48ed61a7SRobert Mustacchi  *
4146*48ed61a7SRobert Mustacchi  *  Contains the logic to identify if we need to verify link for the
4147*48ed61a7SRobert Mustacchi  *  crosstalk fix
4148*48ed61a7SRobert Mustacchi  **/
ixgbe_need_crosstalk_fix(struct ixgbe_hw * hw)4149*48ed61a7SRobert Mustacchi static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw)
4150*48ed61a7SRobert Mustacchi {
4151*48ed61a7SRobert Mustacchi 
4152*48ed61a7SRobert Mustacchi 	/* Does FW say we need the fix */
4153*48ed61a7SRobert Mustacchi 	if (!hw->need_crosstalk_fix)
4154*48ed61a7SRobert Mustacchi 		return FALSE;
4155*48ed61a7SRobert Mustacchi 
4156*48ed61a7SRobert Mustacchi 	/* Only consider SFP+ PHYs i.e. media type fiber */
4157*48ed61a7SRobert Mustacchi 	switch (hw->mac.ops.get_media_type(hw)) {
4158*48ed61a7SRobert Mustacchi 	case ixgbe_media_type_fiber:
4159*48ed61a7SRobert Mustacchi 	case ixgbe_media_type_fiber_qsfp:
4160*48ed61a7SRobert Mustacchi 		break;
4161*48ed61a7SRobert Mustacchi 	default:
4162*48ed61a7SRobert Mustacchi 		return FALSE;
4163*48ed61a7SRobert Mustacchi 	}
4164*48ed61a7SRobert Mustacchi 
4165*48ed61a7SRobert Mustacchi 	return TRUE;
4166*48ed61a7SRobert Mustacchi }
4167*48ed61a7SRobert Mustacchi 
4168*48ed61a7SRobert Mustacchi /**
41695fc77b81SRobert Mustacchi  *  ixgbe_check_mac_link_generic - Determine link and speed status
41705fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
41715fc77b81SRobert Mustacchi  *  @speed: pointer to link speed
41725fc77b81SRobert Mustacchi  *  @link_up: TRUE when link is up
41735fc77b81SRobert Mustacchi  *  @link_up_wait_to_complete: bool used to wait for link up or not
41745fc77b81SRobert Mustacchi  *
41755fc77b81SRobert Mustacchi  *  Reads the links register to determine if link is up and the current speed
41765fc77b81SRobert Mustacchi  **/
ixgbe_check_mac_link_generic(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)41775fc77b81SRobert Mustacchi s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
41785fc77b81SRobert Mustacchi 				 bool *link_up, bool link_up_wait_to_complete)
41795fc77b81SRobert Mustacchi {
41805fc77b81SRobert Mustacchi 	u32 links_reg, links_orig;
41815fc77b81SRobert Mustacchi 	u32 i;
41825fc77b81SRobert Mustacchi 
41835fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_check_mac_link_generic");
41845fc77b81SRobert Mustacchi 
4185*48ed61a7SRobert Mustacchi 	/* If Crosstalk fix enabled do the sanity check of making sure
4186*48ed61a7SRobert Mustacchi 	 * the SFP+ cage is full.
4187*48ed61a7SRobert Mustacchi 	 */
4188*48ed61a7SRobert Mustacchi 	if (ixgbe_need_crosstalk_fix(hw)) {
4189*48ed61a7SRobert Mustacchi 		u32 sfp_cage_full;
4190*48ed61a7SRobert Mustacchi 
4191*48ed61a7SRobert Mustacchi 		switch (hw->mac.type) {
4192*48ed61a7SRobert Mustacchi 		case ixgbe_mac_82599EB:
4193*48ed61a7SRobert Mustacchi 			sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
4194*48ed61a7SRobert Mustacchi 					IXGBE_ESDP_SDP2;
4195*48ed61a7SRobert Mustacchi 			break;
4196*48ed61a7SRobert Mustacchi 		case ixgbe_mac_X550EM_x:
4197*48ed61a7SRobert Mustacchi 		case ixgbe_mac_X550EM_a:
4198*48ed61a7SRobert Mustacchi 			sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
4199*48ed61a7SRobert Mustacchi 					IXGBE_ESDP_SDP0;
4200*48ed61a7SRobert Mustacchi 			break;
4201*48ed61a7SRobert Mustacchi 		default:
4202*48ed61a7SRobert Mustacchi 			/* sanity check - No SFP+ devices here */
4203*48ed61a7SRobert Mustacchi 			sfp_cage_full = FALSE;
4204*48ed61a7SRobert Mustacchi 			break;
4205*48ed61a7SRobert Mustacchi 		}
4206*48ed61a7SRobert Mustacchi 
4207*48ed61a7SRobert Mustacchi 		if (!sfp_cage_full) {
4208*48ed61a7SRobert Mustacchi 			*link_up = FALSE;
4209*48ed61a7SRobert Mustacchi 			*speed = IXGBE_LINK_SPEED_UNKNOWN;
4210*48ed61a7SRobert Mustacchi 			return IXGBE_SUCCESS;
4211*48ed61a7SRobert Mustacchi 		}
4212*48ed61a7SRobert Mustacchi 	}
4213*48ed61a7SRobert Mustacchi 
42145fc77b81SRobert Mustacchi 	/* clear the old state */
42155fc77b81SRobert Mustacchi 	links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
42165fc77b81SRobert Mustacchi 
42175fc77b81SRobert Mustacchi 	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
42185fc77b81SRobert Mustacchi 
42195fc77b81SRobert Mustacchi 	if (links_orig != links_reg) {
42205fc77b81SRobert Mustacchi 		DEBUGOUT2("LINKS changed from %08X to %08X\n",
42215fc77b81SRobert Mustacchi 			  links_orig, links_reg);
42225fc77b81SRobert Mustacchi 	}
42235fc77b81SRobert Mustacchi 
42245fc77b81SRobert Mustacchi 	if (link_up_wait_to_complete) {
4225dc0cb1cdSDale Ghent 		for (i = 0; i < hw->mac.max_link_up_time; i++) {
42265fc77b81SRobert Mustacchi 			if (links_reg & IXGBE_LINKS_UP) {
42275fc77b81SRobert Mustacchi 				*link_up = TRUE;
42285fc77b81SRobert Mustacchi 				break;
42295fc77b81SRobert Mustacchi 			} else {
42305fc77b81SRobert Mustacchi 				*link_up = FALSE;
42315fc77b81SRobert Mustacchi 			}
42325fc77b81SRobert Mustacchi 			msec_delay(100);
42335fc77b81SRobert Mustacchi 			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
42345fc77b81SRobert Mustacchi 		}
42355fc77b81SRobert Mustacchi 	} else {
42365fc77b81SRobert Mustacchi 		if (links_reg & IXGBE_LINKS_UP)
42375fc77b81SRobert Mustacchi 			*link_up = TRUE;
42385fc77b81SRobert Mustacchi 		else
42395fc77b81SRobert Mustacchi 			*link_up = FALSE;
42405fc77b81SRobert Mustacchi 	}
42415fc77b81SRobert Mustacchi 
4242dc0cb1cdSDale Ghent 	switch (links_reg & IXGBE_LINKS_SPEED_82599) {
4243dc0cb1cdSDale Ghent 	case IXGBE_LINKS_SPEED_10G_82599:
42445fc77b81SRobert Mustacchi 		*speed = IXGBE_LINK_SPEED_10GB_FULL;
4245dc0cb1cdSDale Ghent 		if (hw->mac.type >= ixgbe_mac_X550) {
4246dc0cb1cdSDale Ghent 			if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
4247dc0cb1cdSDale Ghent 				*speed = IXGBE_LINK_SPEED_2_5GB_FULL;
4248dc0cb1cdSDale Ghent 		}
4249dc0cb1cdSDale Ghent 		break;
4250dc0cb1cdSDale Ghent 	case IXGBE_LINKS_SPEED_1G_82599:
42515fc77b81SRobert Mustacchi 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
4252dc0cb1cdSDale Ghent 		break;
4253dc0cb1cdSDale Ghent 	case IXGBE_LINKS_SPEED_100_82599:
42545fc77b81SRobert Mustacchi 		*speed = IXGBE_LINK_SPEED_100_FULL;
4255*48ed61a7SRobert Mustacchi 		if (hw->mac.type == ixgbe_mac_X550) {
4256dc0cb1cdSDale Ghent 			if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
4257dc0cb1cdSDale Ghent 				*speed = IXGBE_LINK_SPEED_5GB_FULL;
4258dc0cb1cdSDale Ghent 		}
4259dc0cb1cdSDale Ghent 		break;
4260*48ed61a7SRobert Mustacchi 	case IXGBE_LINKS_SPEED_10_X550EM_A:
4261*48ed61a7SRobert Mustacchi 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
4262*48ed61a7SRobert Mustacchi 		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
4263*48ed61a7SRobert Mustacchi 		    hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
4264*48ed61a7SRobert Mustacchi 			*speed = IXGBE_LINK_SPEED_10_FULL;
4265*48ed61a7SRobert Mustacchi 		break;
4266dc0cb1cdSDale Ghent 	default:
42675fc77b81SRobert Mustacchi 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
4268dc0cb1cdSDale Ghent 	}
42695fc77b81SRobert Mustacchi 
42705fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
42715fc77b81SRobert Mustacchi }
42725fc77b81SRobert Mustacchi 
42735fc77b81SRobert Mustacchi /**
42745fc77b81SRobert Mustacchi  *  ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from
42755fc77b81SRobert Mustacchi  *  the EEPROM
42765fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
42775fc77b81SRobert Mustacchi  *  @wwnn_prefix: the alternative WWNN prefix
42785fc77b81SRobert Mustacchi  *  @wwpn_prefix: the alternative WWPN prefix
42795fc77b81SRobert Mustacchi  *
42805fc77b81SRobert Mustacchi  *  This function will read the EEPROM from the alternative SAN MAC address
42815fc77b81SRobert Mustacchi  *  block to check the support for the alternative WWNN/WWPN prefix support.
42825fc77b81SRobert Mustacchi  **/
ixgbe_get_wwn_prefix_generic(struct ixgbe_hw * hw,u16 * wwnn_prefix,u16 * wwpn_prefix)42835fc77b81SRobert Mustacchi s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
42845fc77b81SRobert Mustacchi 				 u16 *wwpn_prefix)
42855fc77b81SRobert Mustacchi {
42865fc77b81SRobert Mustacchi 	u16 offset, caps;
42875fc77b81SRobert Mustacchi 	u16 alt_san_mac_blk_offset;
42885fc77b81SRobert Mustacchi 
42895fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_wwn_prefix_generic");
42905fc77b81SRobert Mustacchi 
42915fc77b81SRobert Mustacchi 	/* clear output first */
42925fc77b81SRobert Mustacchi 	*wwnn_prefix = 0xFFFF;
42935fc77b81SRobert Mustacchi 	*wwpn_prefix = 0xFFFF;
42945fc77b81SRobert Mustacchi 
42955fc77b81SRobert Mustacchi 	/* check if alternative SAN MAC is supported */
4296dc0cb1cdSDale Ghent 	offset = IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR;
4297dc0cb1cdSDale Ghent 	if (hw->eeprom.ops.read(hw, offset, &alt_san_mac_blk_offset))
4298dc0cb1cdSDale Ghent 		goto wwn_prefix_err;
42995fc77b81SRobert Mustacchi 
43005fc77b81SRobert Mustacchi 	if ((alt_san_mac_blk_offset == 0) ||
43015fc77b81SRobert Mustacchi 	    (alt_san_mac_blk_offset == 0xFFFF))
43025fc77b81SRobert Mustacchi 		goto wwn_prefix_out;
43035fc77b81SRobert Mustacchi 
43045fc77b81SRobert Mustacchi 	/* check capability in alternative san mac address block */
43055fc77b81SRobert Mustacchi 	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
4306dc0cb1cdSDale Ghent 	if (hw->eeprom.ops.read(hw, offset, &caps))
4307dc0cb1cdSDale Ghent 		goto wwn_prefix_err;
43085fc77b81SRobert Mustacchi 	if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
43095fc77b81SRobert Mustacchi 		goto wwn_prefix_out;
43105fc77b81SRobert Mustacchi 
43115fc77b81SRobert Mustacchi 	/* get the corresponding prefix for WWNN/WWPN */
43125fc77b81SRobert Mustacchi 	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
4313dc0cb1cdSDale Ghent 	if (hw->eeprom.ops.read(hw, offset, wwnn_prefix)) {
4314dc0cb1cdSDale Ghent 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
4315dc0cb1cdSDale Ghent 			      "eeprom read at offset %d failed", offset);
4316dc0cb1cdSDale Ghent 	}
43175fc77b81SRobert Mustacchi 
43185fc77b81SRobert Mustacchi 	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
4319dc0cb1cdSDale Ghent 	if (hw->eeprom.ops.read(hw, offset, wwpn_prefix))
4320dc0cb1cdSDale Ghent 		goto wwn_prefix_err;
43215fc77b81SRobert Mustacchi 
43225fc77b81SRobert Mustacchi wwn_prefix_out:
43235fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
4324dc0cb1cdSDale Ghent 
4325dc0cb1cdSDale Ghent wwn_prefix_err:
4326dc0cb1cdSDale Ghent 	ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
4327dc0cb1cdSDale Ghent 		      "eeprom read at offset %d failed", offset);
4328dc0cb1cdSDale Ghent 	return IXGBE_SUCCESS;
43295fc77b81SRobert Mustacchi }
43305fc77b81SRobert Mustacchi 
43315fc77b81SRobert Mustacchi /**
43325fc77b81SRobert Mustacchi  *  ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM
43335fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
43345fc77b81SRobert Mustacchi  *  @bs: the fcoe boot status
43355fc77b81SRobert Mustacchi  *
43365fc77b81SRobert Mustacchi  *  This function will read the FCOE boot status from the iSCSI FCOE block
43375fc77b81SRobert Mustacchi  **/
ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw * hw,u16 * bs)43385fc77b81SRobert Mustacchi s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs)
43395fc77b81SRobert Mustacchi {
43405fc77b81SRobert Mustacchi 	u16 offset, caps, flags;
43415fc77b81SRobert Mustacchi 	s32 status;
43425fc77b81SRobert Mustacchi 
43435fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_fcoe_boot_status_generic");
43445fc77b81SRobert Mustacchi 
43455fc77b81SRobert Mustacchi 	/* clear output first */
43465fc77b81SRobert Mustacchi 	*bs = ixgbe_fcoe_bootstatus_unavailable;
43475fc77b81SRobert Mustacchi 
43485fc77b81SRobert Mustacchi 	/* check if FCOE IBA block is present */
43495fc77b81SRobert Mustacchi 	offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR;
43505fc77b81SRobert Mustacchi 	status = hw->eeprom.ops.read(hw, offset, &caps);
43515fc77b81SRobert Mustacchi 	if (status != IXGBE_SUCCESS)
43525fc77b81SRobert Mustacchi 		goto out;
43535fc77b81SRobert Mustacchi 
43545fc77b81SRobert Mustacchi 	if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE))
43555fc77b81SRobert Mustacchi 		goto out;
43565fc77b81SRobert Mustacchi 
43575fc77b81SRobert Mustacchi 	/* check if iSCSI FCOE block is populated */
43585fc77b81SRobert Mustacchi 	status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset);
43595fc77b81SRobert Mustacchi 	if (status != IXGBE_SUCCESS)
43605fc77b81SRobert Mustacchi 		goto out;
43615fc77b81SRobert Mustacchi 
43625fc77b81SRobert Mustacchi 	if ((offset == 0) || (offset == 0xFFFF))
43635fc77b81SRobert Mustacchi 		goto out;
43645fc77b81SRobert Mustacchi 
43655fc77b81SRobert Mustacchi 	/* read fcoe flags in iSCSI FCOE block */
43665fc77b81SRobert Mustacchi 	offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET;
43675fc77b81SRobert Mustacchi 	status = hw->eeprom.ops.read(hw, offset, &flags);
43685fc77b81SRobert Mustacchi 	if (status != IXGBE_SUCCESS)
43695fc77b81SRobert Mustacchi 		goto out;
43705fc77b81SRobert Mustacchi 
43715fc77b81SRobert Mustacchi 	if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE)
43725fc77b81SRobert Mustacchi 		*bs = ixgbe_fcoe_bootstatus_enabled;
43735fc77b81SRobert Mustacchi 	else
43745fc77b81SRobert Mustacchi 		*bs = ixgbe_fcoe_bootstatus_disabled;
43755fc77b81SRobert Mustacchi 
43765fc77b81SRobert Mustacchi out:
43775fc77b81SRobert Mustacchi 	return status;
43785fc77b81SRobert Mustacchi }
43795fc77b81SRobert Mustacchi 
43805fc77b81SRobert Mustacchi /**
43815fc77b81SRobert Mustacchi  *  ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
43825fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
4383*48ed61a7SRobert Mustacchi  *  @enable: enable or disable switch for MAC anti-spoofing
4384*48ed61a7SRobert Mustacchi  *  @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing
43855fc77b81SRobert Mustacchi  *
43865fc77b81SRobert Mustacchi  **/
ixgbe_set_mac_anti_spoofing(struct ixgbe_hw * hw,bool enable,int vf)4387*48ed61a7SRobert Mustacchi void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
43885fc77b81SRobert Mustacchi {
4389*48ed61a7SRobert Mustacchi 	int vf_target_reg = vf >> 3;
4390*48ed61a7SRobert Mustacchi 	int vf_target_shift = vf % 8;
4391*48ed61a7SRobert Mustacchi 	u32 pfvfspoof;
43925fc77b81SRobert Mustacchi 
43935fc77b81SRobert Mustacchi 	if (hw->mac.type == ixgbe_mac_82598EB)
43945fc77b81SRobert Mustacchi 		return;
43955fc77b81SRobert Mustacchi 
4396*48ed61a7SRobert Mustacchi 	pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
43975fc77b81SRobert Mustacchi 	if (enable)
4398*48ed61a7SRobert Mustacchi 		pfvfspoof |= (1 << vf_target_shift);
4399*48ed61a7SRobert Mustacchi 	else
4400*48ed61a7SRobert Mustacchi 		pfvfspoof &= ~(1 << vf_target_shift);
4401*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
44025fc77b81SRobert Mustacchi }
44035fc77b81SRobert Mustacchi 
44045fc77b81SRobert Mustacchi /**
44055fc77b81SRobert Mustacchi  *  ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
44065fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
44075fc77b81SRobert Mustacchi  *  @enable: enable or disable switch for VLAN anti-spoofing
4408dc0cb1cdSDale Ghent  *  @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing
44095fc77b81SRobert Mustacchi  *
44105fc77b81SRobert Mustacchi  **/
ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw * hw,bool enable,int vf)44115fc77b81SRobert Mustacchi void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
44125fc77b81SRobert Mustacchi {
44135fc77b81SRobert Mustacchi 	int vf_target_reg = vf >> 3;
44145fc77b81SRobert Mustacchi 	int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT;
44155fc77b81SRobert Mustacchi 	u32 pfvfspoof;
44165fc77b81SRobert Mustacchi 
44175fc77b81SRobert Mustacchi 	if (hw->mac.type == ixgbe_mac_82598EB)
44185fc77b81SRobert Mustacchi 		return;
44195fc77b81SRobert Mustacchi 
44205fc77b81SRobert Mustacchi 	pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
44215fc77b81SRobert Mustacchi 	if (enable)
44225fc77b81SRobert Mustacchi 		pfvfspoof |= (1 << vf_target_shift);
44235fc77b81SRobert Mustacchi 	else
44245fc77b81SRobert Mustacchi 		pfvfspoof &= ~(1 << vf_target_shift);
44255fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
44265fc77b81SRobert Mustacchi }
44275fc77b81SRobert Mustacchi 
44285fc77b81SRobert Mustacchi /**
44295fc77b81SRobert Mustacchi  *  ixgbe_get_device_caps_generic - Get additional device capabilities
44305fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
44315fc77b81SRobert Mustacchi  *  @device_caps: the EEPROM word with the extra device capabilities
44325fc77b81SRobert Mustacchi  *
44335fc77b81SRobert Mustacchi  *  This function will read the EEPROM location for the device capabilities,
44345fc77b81SRobert Mustacchi  *  and return the word through device_caps.
44355fc77b81SRobert Mustacchi  **/
ixgbe_get_device_caps_generic(struct ixgbe_hw * hw,u16 * device_caps)44365fc77b81SRobert Mustacchi s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
44375fc77b81SRobert Mustacchi {
44385fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_get_device_caps_generic");
44395fc77b81SRobert Mustacchi 
44405fc77b81SRobert Mustacchi 	hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
44415fc77b81SRobert Mustacchi 
44425fc77b81SRobert Mustacchi 	return IXGBE_SUCCESS;
44435fc77b81SRobert Mustacchi }
44445fc77b81SRobert Mustacchi 
44455fc77b81SRobert Mustacchi /**
44465fc77b81SRobert Mustacchi  *  ixgbe_enable_relaxed_ordering_gen2 - Enable relaxed ordering
44475fc77b81SRobert Mustacchi  *  @hw: pointer to hardware structure
44485fc77b81SRobert Mustacchi  *
44495fc77b81SRobert Mustacchi  **/
ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw * hw)44505fc77b81SRobert Mustacchi void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
44515fc77b81SRobert Mustacchi {
44525fc77b81SRobert Mustacchi 	u32 regval;
44535fc77b81SRobert Mustacchi 	u32 i;
44545fc77b81SRobert Mustacchi 
44555fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_enable_relaxed_ordering_gen2");
44565fc77b81SRobert Mustacchi 
44575fc77b81SRobert Mustacchi 	/* Enable relaxed ordering */
44585fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_tx_queues; i++) {
44595fc77b81SRobert Mustacchi 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
44605fc77b81SRobert Mustacchi 		regval |= IXGBE_DCA_TXCTRL_DESC_WRO_EN;
44615fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
44625fc77b81SRobert Mustacchi 	}
44635fc77b81SRobert Mustacchi 
44645fc77b81SRobert Mustacchi 	for (i = 0; i < hw->mac.max_rx_queues; i++) {
44655fc77b81SRobert Mustacchi 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
44665fc77b81SRobert Mustacchi 		regval |= IXGBE_DCA_RXCTRL_DATA_WRO_EN |
44675fc77b81SRobert Mustacchi 			  IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
44685fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
44695fc77b81SRobert Mustacchi 	}
44705fc77b81SRobert Mustacchi 
44715fc77b81SRobert Mustacchi }
44725fc77b81SRobert Mustacchi 
44735fc77b81SRobert Mustacchi /**
44745fc77b81SRobert Mustacchi  *  ixgbe_calculate_checksum - Calculate checksum for buffer
44755fc77b81SRobert Mustacchi  *  @buffer: pointer to EEPROM
44765fc77b81SRobert Mustacchi  *  @length: size of EEPROM to calculate a checksum for
44775fc77b81SRobert Mustacchi  *  Calculates the checksum for some buffer on a specified length.  The
44785fc77b81SRobert Mustacchi  *  checksum calculated is returned.
44795fc77b81SRobert Mustacchi  **/
ixgbe_calculate_checksum(u8 * buffer,u32 length)4480dc0cb1cdSDale Ghent u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
44815fc77b81SRobert Mustacchi {
44825fc77b81SRobert Mustacchi 	u32 i;
44835fc77b81SRobert Mustacchi 	u8 sum = 0;
44845fc77b81SRobert Mustacchi 
44855fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_calculate_checksum");
44865fc77b81SRobert Mustacchi 
44875fc77b81SRobert Mustacchi 	if (!buffer)
44885fc77b81SRobert Mustacchi 		return 0;
44895fc77b81SRobert Mustacchi 
44905fc77b81SRobert Mustacchi 	for (i = 0; i < length; i++)
44915fc77b81SRobert Mustacchi 		sum += buffer[i];
44925fc77b81SRobert Mustacchi 
44935fc77b81SRobert Mustacchi 	return (u8) (0 - sum);
44945fc77b81SRobert Mustacchi }
44955fc77b81SRobert Mustacchi 
44965fc77b81SRobert Mustacchi /**
4497*48ed61a7SRobert Mustacchi  *  ixgbe_hic_unlocked - Issue command to manageability block unlocked
44985fc77b81SRobert Mustacchi  *  @hw: pointer to the HW structure
4499*48ed61a7SRobert Mustacchi  *  @buffer: command to write and where the return status will be placed
45005fc77b81SRobert Mustacchi  *  @length: length of buffer, must be multiple of 4 bytes
4501dc0cb1cdSDale Ghent  *  @timeout: time in ms to wait for command completion
45025fc77b81SRobert Mustacchi  *
45035fc77b81SRobert Mustacchi  *  Communicates with the manageability block. On success return IXGBE_SUCCESS
4504*48ed61a7SRobert Mustacchi  *  else returns semaphore error when encountering an error acquiring
4505*48ed61a7SRobert Mustacchi  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
4506*48ed61a7SRobert Mustacchi  *
4507*48ed61a7SRobert Mustacchi  *  This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held
4508*48ed61a7SRobert Mustacchi  *  by the caller.
45095fc77b81SRobert Mustacchi  **/
ixgbe_hic_unlocked(struct ixgbe_hw * hw,u32 * buffer,u32 length,u32 timeout)4510*48ed61a7SRobert Mustacchi s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length,
4511*48ed61a7SRobert Mustacchi 		       u32 timeout)
45125fc77b81SRobert Mustacchi {
4513*48ed61a7SRobert Mustacchi 	u32 hicr, i, fwsts;
4514dc0cb1cdSDale Ghent 	u16 dword_len;
45155fc77b81SRobert Mustacchi 
4516*48ed61a7SRobert Mustacchi 	DEBUGFUNC("ixgbe_hic_unlocked");
45175fc77b81SRobert Mustacchi 
4518*48ed61a7SRobert Mustacchi 	if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
4519dc0cb1cdSDale Ghent 		DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
4520dc0cb1cdSDale Ghent 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
45215fc77b81SRobert Mustacchi 	}
4522*48ed61a7SRobert Mustacchi 
4523dc0cb1cdSDale Ghent 	/* Set bit 9 of FWSTS clearing FW reset indication */
4524dc0cb1cdSDale Ghent 	fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
4525dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI);
45265fc77b81SRobert Mustacchi 
45275fc77b81SRobert Mustacchi 	/* Check that the host interface is enabled. */
45285fc77b81SRobert Mustacchi 	hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
4529*48ed61a7SRobert Mustacchi 	if (!(hicr & IXGBE_HICR_EN)) {
45305fc77b81SRobert Mustacchi 		DEBUGOUT("IXGBE_HOST_EN bit disabled.\n");
4531dc0cb1cdSDale Ghent 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
45325fc77b81SRobert Mustacchi 	}
45335fc77b81SRobert Mustacchi 
4534dc0cb1cdSDale Ghent 	/* Calculate length in DWORDs. We must be DWORD aligned */
4535*48ed61a7SRobert Mustacchi 	if (length % sizeof(u32)) {
4536dc0cb1cdSDale Ghent 		DEBUGOUT("Buffer length failure, not aligned to dword");
4537dc0cb1cdSDale Ghent 		return IXGBE_ERR_INVALID_ARGUMENT;
4538dc0cb1cdSDale Ghent 	}
4539dc0cb1cdSDale Ghent 
45405fc77b81SRobert Mustacchi 	dword_len = length >> 2;
45415fc77b81SRobert Mustacchi 
4542dc0cb1cdSDale Ghent 	/* The device driver writes the relevant command block
45435fc77b81SRobert Mustacchi 	 * into the ram area.
45445fc77b81SRobert Mustacchi 	 */
45455fc77b81SRobert Mustacchi 	for (i = 0; i < dword_len; i++)
45465fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG,
45475fc77b81SRobert Mustacchi 				      i, IXGBE_CPU_TO_LE32(buffer[i]));
45485fc77b81SRobert Mustacchi 
45495fc77b81SRobert Mustacchi 	/* Setting this bit tells the ARC that a new command is pending. */
45505fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
45515fc77b81SRobert Mustacchi 
4552dc0cb1cdSDale Ghent 	for (i = 0; i < timeout; i++) {
45535fc77b81SRobert Mustacchi 		hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
45545fc77b81SRobert Mustacchi 		if (!(hicr & IXGBE_HICR_C))
45555fc77b81SRobert Mustacchi 			break;
45565fc77b81SRobert Mustacchi 		msec_delay(1);
45575fc77b81SRobert Mustacchi 	}
45585fc77b81SRobert Mustacchi 
4559dc0cb1cdSDale Ghent 	/* Check command completion */
4560*48ed61a7SRobert Mustacchi 	if ((timeout && i == timeout) ||
4561dc0cb1cdSDale Ghent 	    !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) {
4562dc0cb1cdSDale Ghent 		ERROR_REPORT1(IXGBE_ERROR_CAUTION,
4563dc0cb1cdSDale Ghent 			     "Command has failed with no status valid.\n");
4564dc0cb1cdSDale Ghent 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
45655fc77b81SRobert Mustacchi 	}
45665fc77b81SRobert Mustacchi 
4567*48ed61a7SRobert Mustacchi 	return IXGBE_SUCCESS;
4568*48ed61a7SRobert Mustacchi }
4569*48ed61a7SRobert Mustacchi 
4570*48ed61a7SRobert Mustacchi /**
4571*48ed61a7SRobert Mustacchi  *  ixgbe_host_interface_command - Issue command to manageability block
4572*48ed61a7SRobert Mustacchi  *  @hw: pointer to the HW structure
4573*48ed61a7SRobert Mustacchi  *  @buffer: contains the command to write and where the return status will
4574*48ed61a7SRobert Mustacchi  *   be placed
4575*48ed61a7SRobert Mustacchi  *  @length: length of buffer, must be multiple of 4 bytes
4576*48ed61a7SRobert Mustacchi  *  @timeout: time in ms to wait for command completion
4577*48ed61a7SRobert Mustacchi  *  @return_data: read and return data from the buffer (TRUE) or not (FALSE)
4578*48ed61a7SRobert Mustacchi  *   Needed because FW structures are big endian and decoding of
4579*48ed61a7SRobert Mustacchi  *   these fields can be 8 bit or 16 bit based on command. Decoding
4580*48ed61a7SRobert Mustacchi  *   is not easily understood without making a table of commands.
4581*48ed61a7SRobert Mustacchi  *   So we will leave this up to the caller to read back the data
4582*48ed61a7SRobert Mustacchi  *   in these cases.
4583*48ed61a7SRobert Mustacchi  *
4584*48ed61a7SRobert Mustacchi  *  Communicates with the manageability block. On success return IXGBE_SUCCESS
4585*48ed61a7SRobert Mustacchi  *  else returns semaphore error when encountering an error acquiring
4586*48ed61a7SRobert Mustacchi  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
4587*48ed61a7SRobert Mustacchi  **/
ixgbe_host_interface_command(struct ixgbe_hw * hw,u32 * buffer,u32 length,u32 timeout,bool return_data)4588*48ed61a7SRobert Mustacchi s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
4589*48ed61a7SRobert Mustacchi 				 u32 length, u32 timeout, bool return_data)
4590*48ed61a7SRobert Mustacchi {
4591*48ed61a7SRobert Mustacchi 	u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
4592*48ed61a7SRobert Mustacchi 	struct ixgbe_hic_hdr *resp = (struct ixgbe_hic_hdr *)buffer;
4593*48ed61a7SRobert Mustacchi 	u16 buf_len;
4594*48ed61a7SRobert Mustacchi 	s32 status;
4595*48ed61a7SRobert Mustacchi 	u32 bi;
4596*48ed61a7SRobert Mustacchi 	u32 dword_len;
4597*48ed61a7SRobert Mustacchi 
4598*48ed61a7SRobert Mustacchi 	DEBUGFUNC("ixgbe_host_interface_command");
4599*48ed61a7SRobert Mustacchi 
4600*48ed61a7SRobert Mustacchi 	if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
4601*48ed61a7SRobert Mustacchi 		DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
4602*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
4603*48ed61a7SRobert Mustacchi 	}
4604*48ed61a7SRobert Mustacchi 
4605*48ed61a7SRobert Mustacchi 	/* Take management host interface semaphore */
4606*48ed61a7SRobert Mustacchi 	status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
4607*48ed61a7SRobert Mustacchi 	if (status)
4608*48ed61a7SRobert Mustacchi 		return status;
4609*48ed61a7SRobert Mustacchi 
4610*48ed61a7SRobert Mustacchi 	status = ixgbe_hic_unlocked(hw, buffer, length, timeout);
4611*48ed61a7SRobert Mustacchi 	if (status)
4612*48ed61a7SRobert Mustacchi 		goto rel_out;
4613*48ed61a7SRobert Mustacchi 
4614dc0cb1cdSDale Ghent 	if (!return_data)
4615*48ed61a7SRobert Mustacchi 		goto rel_out;
4616dc0cb1cdSDale Ghent 
46175fc77b81SRobert Mustacchi 	/* Calculate length in DWORDs */
46185fc77b81SRobert Mustacchi 	dword_len = hdr_size >> 2;
46195fc77b81SRobert Mustacchi 
46205fc77b81SRobert Mustacchi 	/* first pull in the header so we know the buffer length */
46215fc77b81SRobert Mustacchi 	for (bi = 0; bi < dword_len; bi++) {
46225fc77b81SRobert Mustacchi 		buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
4623*48ed61a7SRobert Mustacchi 		IXGBE_LE32_TO_CPUS(&buffer[bi]);
46245fc77b81SRobert Mustacchi 	}
46255fc77b81SRobert Mustacchi 
4626*48ed61a7SRobert Mustacchi 	/*
4627*48ed61a7SRobert Mustacchi 	 * If there is any thing in data position pull it in
4628*48ed61a7SRobert Mustacchi 	 * Read Flash command requires reading buffer length from
4629*48ed61a7SRobert Mustacchi 	 * two byes instead of one byte
4630*48ed61a7SRobert Mustacchi 	 */
4631*48ed61a7SRobert Mustacchi 	if (resp->cmd == 0x30) {
4632*48ed61a7SRobert Mustacchi 		for (; bi < dword_len + 2; bi++) {
4633*48ed61a7SRobert Mustacchi 			buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
4634*48ed61a7SRobert Mustacchi 							  bi);
4635*48ed61a7SRobert Mustacchi 			IXGBE_LE32_TO_CPUS(&buffer[bi]);
4636*48ed61a7SRobert Mustacchi 		}
4637*48ed61a7SRobert Mustacchi 		buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
4638*48ed61a7SRobert Mustacchi 				  & 0xF00) | resp->buf_len;
4639*48ed61a7SRobert Mustacchi 		hdr_size += (2 << 2);
4640*48ed61a7SRobert Mustacchi 	} else {
4641*48ed61a7SRobert Mustacchi 		buf_len = resp->buf_len;
4642*48ed61a7SRobert Mustacchi 	}
4643*48ed61a7SRobert Mustacchi 	if (!buf_len)
4644*48ed61a7SRobert Mustacchi 		goto rel_out;
46455fc77b81SRobert Mustacchi 
4646dc0cb1cdSDale Ghent 	if (length < buf_len + hdr_size) {
46475fc77b81SRobert Mustacchi 		DEBUGOUT("Buffer not large enough for reply message.\n");
4648*48ed61a7SRobert Mustacchi 		status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
4649*48ed61a7SRobert Mustacchi 		goto rel_out;
46505fc77b81SRobert Mustacchi 	}
46515fc77b81SRobert Mustacchi 
46525fc77b81SRobert Mustacchi 	/* Calculate length in DWORDs, add 3 for odd lengths */
46535fc77b81SRobert Mustacchi 	dword_len = (buf_len + 3) >> 2;
46545fc77b81SRobert Mustacchi 
46555fc77b81SRobert Mustacchi 	/* Pull in the rest of the buffer (bi is where we left off) */
46565fc77b81SRobert Mustacchi 	for (; bi <= dword_len; bi++) {
46575fc77b81SRobert Mustacchi 		buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
4658*48ed61a7SRobert Mustacchi 		IXGBE_LE32_TO_CPUS(&buffer[bi]);
46595fc77b81SRobert Mustacchi 	}
46605fc77b81SRobert Mustacchi 
4661*48ed61a7SRobert Mustacchi rel_out:
4662*48ed61a7SRobert Mustacchi 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
4663*48ed61a7SRobert Mustacchi 
4664*48ed61a7SRobert Mustacchi 	return status;
46655fc77b81SRobert Mustacchi }
46665fc77b81SRobert Mustacchi 
46675fc77b81SRobert Mustacchi /**
46685fc77b81SRobert Mustacchi  *  ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware
46695fc77b81SRobert Mustacchi  *  @hw: pointer to the HW structure
46705fc77b81SRobert Mustacchi  *  @maj: driver version major number
46715fc77b81SRobert Mustacchi  *  @min: driver version minor number
46725fc77b81SRobert Mustacchi  *  @build: driver version build number
46735fc77b81SRobert Mustacchi  *  @sub: driver version sub build number
4674*48ed61a7SRobert Mustacchi  *  @len: unused
4675*48ed61a7SRobert Mustacchi  *  @driver_ver: unused
46765fc77b81SRobert Mustacchi  *
46775fc77b81SRobert Mustacchi  *  Sends driver version number to firmware through the manageability
46785fc77b81SRobert Mustacchi  *  block.  On success return IXGBE_SUCCESS
46795fc77b81SRobert Mustacchi  *  else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
46805fc77b81SRobert Mustacchi  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
46815fc77b81SRobert Mustacchi  **/
ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw * hw,u8 maj,u8 min,u8 build,u8 sub,u16 len,const char * driver_ver)46825fc77b81SRobert Mustacchi s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
4683*48ed61a7SRobert Mustacchi 				 u8 build, u8 sub, u16 len,
4684*48ed61a7SRobert Mustacchi 				 const char *driver_ver)
46855fc77b81SRobert Mustacchi {
46865fc77b81SRobert Mustacchi 	struct ixgbe_hic_drv_info fw_cmd;
46875fc77b81SRobert Mustacchi 	int i;
46885fc77b81SRobert Mustacchi 	s32 ret_val = IXGBE_SUCCESS;
46895fc77b81SRobert Mustacchi 
46905fc77b81SRobert Mustacchi 	DEBUGFUNC("ixgbe_set_fw_drv_ver_generic");
4691*48ed61a7SRobert Mustacchi 	UNREFERENCED_2PARAMETER(len, driver_ver);
46925fc77b81SRobert Mustacchi 
46935fc77b81SRobert Mustacchi 	fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
46945fc77b81SRobert Mustacchi 	fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
46955fc77b81SRobert Mustacchi 	fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
46965fc77b81SRobert Mustacchi 	fw_cmd.port_num = (u8)hw->bus.func;
46975fc77b81SRobert Mustacchi 	fw_cmd.ver_maj = maj;
46985fc77b81SRobert Mustacchi 	fw_cmd.ver_min = min;
46995fc77b81SRobert Mustacchi 	fw_cmd.ver_build = build;
47005fc77b81SRobert Mustacchi 	fw_cmd.ver_sub = sub;
47015fc77b81SRobert Mustacchi 	fw_cmd.hdr.checksum = 0;
47025fc77b81SRobert Mustacchi 	fw_cmd.pad = 0;
47035fc77b81SRobert Mustacchi 	fw_cmd.pad2 = 0;
4704*48ed61a7SRobert Mustacchi 	fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
4705*48ed61a7SRobert Mustacchi 				(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
47065fc77b81SRobert Mustacchi 
47075fc77b81SRobert Mustacchi 	for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
47085fc77b81SRobert Mustacchi 		ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
4709dc0cb1cdSDale Ghent 						       sizeof(fw_cmd),
4710dc0cb1cdSDale Ghent 						       IXGBE_HI_COMMAND_TIMEOUT,
4711dc0cb1cdSDale Ghent 						       TRUE);
47125fc77b81SRobert Mustacchi 		if (ret_val != IXGBE_SUCCESS)
47135fc77b81SRobert Mustacchi 			continue;
47145fc77b81SRobert Mustacchi 
47155fc77b81SRobert Mustacchi 		if (fw_cmd.hdr.cmd_or_resp.ret_status ==
47165fc77b81SRobert Mustacchi 		    FW_CEM_RESP_STATUS_SUCCESS)
47175fc77b81SRobert Mustacchi 			ret_val = IXGBE_SUCCESS;
47185fc77b81SRobert Mustacchi 		else
47195fc77b81SRobert Mustacchi 			ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
47205fc77b81SRobert Mustacchi 
47215fc77b81SRobert Mustacchi 		break;
47225fc77b81SRobert Mustacchi 	}
47235fc77b81SRobert Mustacchi 
47245fc77b81SRobert Mustacchi 	return ret_val;
47255fc77b81SRobert Mustacchi }
47265fc77b81SRobert Mustacchi 
47275fc77b81SRobert Mustacchi /**
47285fc77b81SRobert Mustacchi  * ixgbe_set_rxpba_generic - Initialize Rx packet buffer
47295fc77b81SRobert Mustacchi  * @hw: pointer to hardware structure
47305fc77b81SRobert Mustacchi  * @num_pb: number of packet buffers to allocate
47315fc77b81SRobert Mustacchi  * @headroom: reserve n KB of headroom
47325fc77b81SRobert Mustacchi  * @strategy: packet buffer allocation strategy
47335fc77b81SRobert Mustacchi  **/
ixgbe_set_rxpba_generic(struct ixgbe_hw * hw,int num_pb,u32 headroom,int strategy)47345fc77b81SRobert Mustacchi void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
47355fc77b81SRobert Mustacchi 			     int strategy)
47365fc77b81SRobert Mustacchi {
47375fc77b81SRobert Mustacchi 	u32 pbsize = hw->mac.rx_pb_size;
47385fc77b81SRobert Mustacchi 	int i = 0;
47395fc77b81SRobert Mustacchi 	u32 rxpktsize, txpktsize, txpbthresh;
47405fc77b81SRobert Mustacchi 
47415fc77b81SRobert Mustacchi 	/* Reserve headroom */
47425fc77b81SRobert Mustacchi 	pbsize -= headroom;
47435fc77b81SRobert Mustacchi 
47445fc77b81SRobert Mustacchi 	if (!num_pb)
47455fc77b81SRobert Mustacchi 		num_pb = 1;
47465fc77b81SRobert Mustacchi 
47475fc77b81SRobert Mustacchi 	/* Divide remaining packet buffer space amongst the number of packet
47485fc77b81SRobert Mustacchi 	 * buffers requested using supplied strategy.
47495fc77b81SRobert Mustacchi 	 */
47505fc77b81SRobert Mustacchi 	switch (strategy) {
47515fc77b81SRobert Mustacchi 	case PBA_STRATEGY_WEIGHTED:
47525fc77b81SRobert Mustacchi 		/* ixgbe_dcb_pba_80_48 strategy weight first half of packet
47535fc77b81SRobert Mustacchi 		 * buffer with 5/8 of the packet buffer space.
47545fc77b81SRobert Mustacchi 		 */
47555fc77b81SRobert Mustacchi 		rxpktsize = (pbsize * 5) / (num_pb * 4);
47565fc77b81SRobert Mustacchi 		pbsize -= rxpktsize * (num_pb / 2);
47575fc77b81SRobert Mustacchi 		rxpktsize <<= IXGBE_RXPBSIZE_SHIFT;
47585fc77b81SRobert Mustacchi 		for (; i < (num_pb / 2); i++)
47595fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
4760*48ed61a7SRobert Mustacchi 		/* configure remaining packet buffers */
4761e5c421abSToomas Soome 		/* FALLTHROUGH */
47625fc77b81SRobert Mustacchi 	case PBA_STRATEGY_EQUAL:
47635fc77b81SRobert Mustacchi 		rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
47645fc77b81SRobert Mustacchi 		for (; i < num_pb; i++)
47655fc77b81SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
47665fc77b81SRobert Mustacchi 		break;
47675fc77b81SRobert Mustacchi 	default:
47685fc77b81SRobert Mustacchi 		break;
47695fc77b81SRobert Mustacchi 	}
47705fc77b81SRobert Mustacchi 
47715fc77b81SRobert Mustacchi 	/* Only support an equally distributed Tx packet buffer strategy. */
47725fc77b81SRobert Mustacchi 	txpktsize = IXGBE_TXPBSIZE_MAX / num_pb;
47735fc77b81SRobert Mustacchi 	txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX;
47745fc77b81SRobert Mustacchi 	for (i = 0; i < num_pb; i++) {
47755fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize);
47765fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh);
47775fc77b81SRobert Mustacchi 	}
47785fc77b81SRobert Mustacchi 
47795fc77b81SRobert Mustacchi 	/* Clear unused TCs, if any, to zero buffer size*/
47805fc77b81SRobert Mustacchi 	for (; i < IXGBE_MAX_PB; i++) {
47815fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
47825fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0);
47835fc77b81SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0);
47845fc77b81SRobert Mustacchi 	}
47855fc77b81SRobert Mustacchi }
47865fc77b81SRobert Mustacchi 
47875fc77b81SRobert Mustacchi /**
47885fc77b81SRobert Mustacchi  * ixgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo
47895fc77b81SRobert Mustacchi  * @hw: pointer to the hardware structure
47905fc77b81SRobert Mustacchi  *
47915fc77b81SRobert Mustacchi  * The 82599 and x540 MACs can experience issues if TX work is still pending
47925fc77b81SRobert Mustacchi  * when a reset occurs.  This function prevents this by flushing the PCIe
47935fc77b81SRobert Mustacchi  * buffers on the system.
47945fc77b81SRobert Mustacchi  **/
ixgbe_clear_tx_pending(struct ixgbe_hw * hw)47955fc77b81SRobert Mustacchi void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
47965fc77b81SRobert Mustacchi {
4797dc0cb1cdSDale Ghent 	u32 gcr_ext, hlreg0, i, poll;
4798dc0cb1cdSDale Ghent 	u16 value;
47995fc77b81SRobert Mustacchi 
48005fc77b81SRobert Mustacchi 	/*
48015fc77b81SRobert Mustacchi 	 * If double reset is not requested then all transactions should
48025fc77b81SRobert Mustacchi 	 * already be clear and as such there is no work to do
48035fc77b81SRobert Mustacchi 	 */
48045fc77b81SRobert Mustacchi 	if (!(hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED))
48055fc77b81SRobert Mustacchi 		return;
48065fc77b81SRobert Mustacchi 
48075fc77b81SRobert Mustacchi 	/*
48085fc77b81SRobert Mustacchi 	 * Set loopback enable to prevent any transmits from being sent
48095fc77b81SRobert Mustacchi 	 * should the link come up.  This assumes that the RXCTRL.RXEN bit
48105fc77b81SRobert Mustacchi 	 * has already been cleared.
48115fc77b81SRobert Mustacchi 	 */
48125fc77b81SRobert Mustacchi 	hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
48135fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK);
48145fc77b81SRobert Mustacchi 
4815dc0cb1cdSDale Ghent 	/* Wait for a last completion before clearing buffers */
4816dc0cb1cdSDale Ghent 	IXGBE_WRITE_FLUSH(hw);
4817dc0cb1cdSDale Ghent 	msec_delay(3);
4818dc0cb1cdSDale Ghent 
4819dc0cb1cdSDale Ghent 	/*
4820dc0cb1cdSDale Ghent 	 * Before proceeding, make sure that the PCIe block does not have
4821dc0cb1cdSDale Ghent 	 * transactions pending.
4822dc0cb1cdSDale Ghent 	 */
4823dc0cb1cdSDale Ghent 	poll = ixgbe_pcie_timeout_poll(hw);
4824dc0cb1cdSDale Ghent 	for (i = 0; i < poll; i++) {
4825dc0cb1cdSDale Ghent 		usec_delay(100);
4826dc0cb1cdSDale Ghent 		value = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS);
482774b989c3SRobert Mustacchi 		if (IXGBE_REMOVED(hw))
4828dc0cb1cdSDale Ghent 			goto out;
4829dc0cb1cdSDale Ghent 		if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
4830dc0cb1cdSDale Ghent 			goto out;
4831dc0cb1cdSDale Ghent 	}
4832dc0cb1cdSDale Ghent 
4833dc0cb1cdSDale Ghent out:
48345fc77b81SRobert Mustacchi 	/* initiate cleaning flow for buffers in the PCIe transaction layer */
48355fc77b81SRobert Mustacchi 	gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
48365fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT,
48375fc77b81SRobert Mustacchi 			gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR);
48385fc77b81SRobert Mustacchi 
48395fc77b81SRobert Mustacchi 	/* Flush all writes and allow 20usec for all transactions to clear */
48405fc77b81SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
48415fc77b81SRobert Mustacchi 	usec_delay(20);
48425fc77b81SRobert Mustacchi 
48435fc77b81SRobert Mustacchi 	/* restore previous register values */
48445fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
48455fc77b81SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
48465fc77b81SRobert Mustacchi }
48475fc77b81SRobert Mustacchi 
4848*48ed61a7SRobert Mustacchi /**
4849*48ed61a7SRobert Mustacchi  *  ixgbe_bypass_rw_generic - Bit bang data into by_pass FW
4850*48ed61a7SRobert Mustacchi  *
4851*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
4852*48ed61a7SRobert Mustacchi  *  @cmd: Command we send to the FW
4853*48ed61a7SRobert Mustacchi  *  @status: The reply from the FW
4854*48ed61a7SRobert Mustacchi  *
4855*48ed61a7SRobert Mustacchi  *  Bit-bangs the cmd to the by_pass FW status points to what is returned.
4856*48ed61a7SRobert Mustacchi  **/
4857*48ed61a7SRobert Mustacchi #define IXGBE_BYPASS_BB_WAIT 1
ixgbe_bypass_rw_generic(struct ixgbe_hw * hw,u32 cmd,u32 * status)4858*48ed61a7SRobert Mustacchi s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status)
4859*48ed61a7SRobert Mustacchi {
4860*48ed61a7SRobert Mustacchi 	int i;
4861*48ed61a7SRobert Mustacchi 	u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo;
4862*48ed61a7SRobert Mustacchi 	u32 esdp;
4863*48ed61a7SRobert Mustacchi 
4864*48ed61a7SRobert Mustacchi 	if (!status)
4865*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_PARAM;
4866*48ed61a7SRobert Mustacchi 
4867*48ed61a7SRobert Mustacchi 	*status = 0;
4868*48ed61a7SRobert Mustacchi 
4869*48ed61a7SRobert Mustacchi 	/* SDP vary by MAC type */
4870*48ed61a7SRobert Mustacchi 	switch (hw->mac.type) {
4871*48ed61a7SRobert Mustacchi 	case ixgbe_mac_82599EB:
4872*48ed61a7SRobert Mustacchi 		sck = IXGBE_ESDP_SDP7;
4873*48ed61a7SRobert Mustacchi 		sdi = IXGBE_ESDP_SDP0;
4874*48ed61a7SRobert Mustacchi 		sdo = IXGBE_ESDP_SDP6;
4875*48ed61a7SRobert Mustacchi 		dir_sck = IXGBE_ESDP_SDP7_DIR;
4876*48ed61a7SRobert Mustacchi 		dir_sdi = IXGBE_ESDP_SDP0_DIR;
4877*48ed61a7SRobert Mustacchi 		dir_sdo = IXGBE_ESDP_SDP6_DIR;
4878*48ed61a7SRobert Mustacchi 		break;
4879*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X540:
4880*48ed61a7SRobert Mustacchi 		sck = IXGBE_ESDP_SDP2;
4881*48ed61a7SRobert Mustacchi 		sdi = IXGBE_ESDP_SDP0;
4882*48ed61a7SRobert Mustacchi 		sdo = IXGBE_ESDP_SDP1;
4883*48ed61a7SRobert Mustacchi 		dir_sck = IXGBE_ESDP_SDP2_DIR;
4884*48ed61a7SRobert Mustacchi 		dir_sdi = IXGBE_ESDP_SDP0_DIR;
4885*48ed61a7SRobert Mustacchi 		dir_sdo = IXGBE_ESDP_SDP1_DIR;
4886*48ed61a7SRobert Mustacchi 		break;
4887*48ed61a7SRobert Mustacchi 	default:
4888*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
4889*48ed61a7SRobert Mustacchi 	}
4890*48ed61a7SRobert Mustacchi 
4891*48ed61a7SRobert Mustacchi 	/* Set SDP pins direction */
4892*48ed61a7SRobert Mustacchi 	esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
4893*48ed61a7SRobert Mustacchi 	esdp |= dir_sck;	/* SCK as output */
4894*48ed61a7SRobert Mustacchi 	esdp |= dir_sdi;	/* SDI as output */
4895*48ed61a7SRobert Mustacchi 	esdp &= ~dir_sdo;	/* SDO as input */
4896*48ed61a7SRobert Mustacchi 	esdp |= sck;
4897*48ed61a7SRobert Mustacchi 	esdp |= sdi;
4898*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4899*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4900*48ed61a7SRobert Mustacchi 	msec_delay(IXGBE_BYPASS_BB_WAIT);
4901*48ed61a7SRobert Mustacchi 
4902*48ed61a7SRobert Mustacchi 	/* Generate start condition */
4903*48ed61a7SRobert Mustacchi 	esdp &= ~sdi;
4904*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4905*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4906*48ed61a7SRobert Mustacchi 	msec_delay(IXGBE_BYPASS_BB_WAIT);
4907*48ed61a7SRobert Mustacchi 
4908*48ed61a7SRobert Mustacchi 	esdp &= ~sck;
4909*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4910*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4911*48ed61a7SRobert Mustacchi 	msec_delay(IXGBE_BYPASS_BB_WAIT);
4912*48ed61a7SRobert Mustacchi 
4913*48ed61a7SRobert Mustacchi 	/* Clock out the new control word and clock in the status */
4914*48ed61a7SRobert Mustacchi 	for (i = 0; i < 32; i++) {
4915*48ed61a7SRobert Mustacchi 		if ((cmd >> (31 - i)) & 0x01) {
4916*48ed61a7SRobert Mustacchi 			esdp |= sdi;
4917*48ed61a7SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4918*48ed61a7SRobert Mustacchi 		} else {
4919*48ed61a7SRobert Mustacchi 			esdp &= ~sdi;
4920*48ed61a7SRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4921*48ed61a7SRobert Mustacchi 		}
4922*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_FLUSH(hw);
4923*48ed61a7SRobert Mustacchi 		msec_delay(IXGBE_BYPASS_BB_WAIT);
4924*48ed61a7SRobert Mustacchi 
4925*48ed61a7SRobert Mustacchi 		esdp |= sck;
4926*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4927*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_FLUSH(hw);
4928*48ed61a7SRobert Mustacchi 		msec_delay(IXGBE_BYPASS_BB_WAIT);
4929*48ed61a7SRobert Mustacchi 
4930*48ed61a7SRobert Mustacchi 		esdp &= ~sck;
4931*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4932*48ed61a7SRobert Mustacchi 		IXGBE_WRITE_FLUSH(hw);
4933*48ed61a7SRobert Mustacchi 		msec_delay(IXGBE_BYPASS_BB_WAIT);
4934*48ed61a7SRobert Mustacchi 
4935*48ed61a7SRobert Mustacchi 		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
4936*48ed61a7SRobert Mustacchi 		if (esdp & sdo)
4937*48ed61a7SRobert Mustacchi 			*status = (*status << 1) | 0x01;
4938*48ed61a7SRobert Mustacchi 		else
4939*48ed61a7SRobert Mustacchi 			*status = (*status << 1) | 0x00;
4940*48ed61a7SRobert Mustacchi 		msec_delay(IXGBE_BYPASS_BB_WAIT);
4941*48ed61a7SRobert Mustacchi 	}
4942*48ed61a7SRobert Mustacchi 
4943*48ed61a7SRobert Mustacchi 	/* stop condition */
4944*48ed61a7SRobert Mustacchi 	esdp |= sck;
4945*48ed61a7SRobert Mustacchi 	esdp &= ~sdi;
4946*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4947*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4948*48ed61a7SRobert Mustacchi 	msec_delay(IXGBE_BYPASS_BB_WAIT);
4949*48ed61a7SRobert Mustacchi 
4950*48ed61a7SRobert Mustacchi 	esdp |= sdi;
4951*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4952*48ed61a7SRobert Mustacchi 	IXGBE_WRITE_FLUSH(hw);
4953*48ed61a7SRobert Mustacchi 
4954*48ed61a7SRobert Mustacchi 	/* set the page bits to match the cmd that the status it belongs to */
4955*48ed61a7SRobert Mustacchi 	*status = (*status & 0x3fffffff) | (cmd & 0xc0000000);
4956*48ed61a7SRobert Mustacchi 
4957*48ed61a7SRobert Mustacchi 	return IXGBE_SUCCESS;
4958*48ed61a7SRobert Mustacchi }
4959*48ed61a7SRobert Mustacchi 
4960*48ed61a7SRobert Mustacchi /**
4961*48ed61a7SRobert Mustacchi  * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang.
4962*48ed61a7SRobert Mustacchi  *
4963*48ed61a7SRobert Mustacchi  * If we send a write we can't be sure it took until we can read back
4964*48ed61a7SRobert Mustacchi  * that same register.  It can be a problem as some of the feilds may
4965*48ed61a7SRobert Mustacchi  * for valid reasons change inbetween the time wrote the register and
4966*48ed61a7SRobert Mustacchi  * we read it again to verify.  So this function check everything we
4967*48ed61a7SRobert Mustacchi  * can check and then assumes it worked.
4968*48ed61a7SRobert Mustacchi  *
4969*48ed61a7SRobert Mustacchi  * @u32 in_reg - The register cmd for the bit-bang read.
4970*48ed61a7SRobert Mustacchi  * @u32 out_reg - The register returned from a bit-bang read.
4971*48ed61a7SRobert Mustacchi  **/
ixgbe_bypass_valid_rd_generic(u32 in_reg,u32 out_reg)4972*48ed61a7SRobert Mustacchi bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg)
4973*48ed61a7SRobert Mustacchi {
4974*48ed61a7SRobert Mustacchi 	u32 mask;
4975*48ed61a7SRobert Mustacchi 
4976*48ed61a7SRobert Mustacchi 	/* Page must match for all control pages */
4977*48ed61a7SRobert Mustacchi 	if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M))
4978*48ed61a7SRobert Mustacchi 		return FALSE;
4979*48ed61a7SRobert Mustacchi 
4980*48ed61a7SRobert Mustacchi 	switch (in_reg & BYPASS_PAGE_M) {
4981*48ed61a7SRobert Mustacchi 	case BYPASS_PAGE_CTL0:
4982*48ed61a7SRobert Mustacchi 		/* All the following can't change since the last write
4983*48ed61a7SRobert Mustacchi 		 *  - All the event actions
4984*48ed61a7SRobert Mustacchi 		 *  - The timeout value
4985*48ed61a7SRobert Mustacchi 		 */
4986*48ed61a7SRobert Mustacchi 		mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M |
4987*48ed61a7SRobert Mustacchi 		       BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M |
4988*48ed61a7SRobert Mustacchi 		       BYPASS_WDTIMEOUT_M |
4989*48ed61a7SRobert Mustacchi 		       BYPASS_WDT_VALUE_M;
4990*48ed61a7SRobert Mustacchi 		if ((out_reg & mask) != (in_reg & mask))
4991*48ed61a7SRobert Mustacchi 			return FALSE;
4992*48ed61a7SRobert Mustacchi 
4993*48ed61a7SRobert Mustacchi 		/* 0x0 is never a valid value for bypass status */
4994*48ed61a7SRobert Mustacchi 		if (!(out_reg & BYPASS_STATUS_OFF_M))
4995*48ed61a7SRobert Mustacchi 			return FALSE;
4996*48ed61a7SRobert Mustacchi 		break;
4997*48ed61a7SRobert Mustacchi 	case BYPASS_PAGE_CTL1:
4998*48ed61a7SRobert Mustacchi 		/* All the following can't change since the last write
4999*48ed61a7SRobert Mustacchi 		 *  - time valid bit
5000*48ed61a7SRobert Mustacchi 		 *  - time we last sent
5001*48ed61a7SRobert Mustacchi 		 */
5002*48ed61a7SRobert Mustacchi 		mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M;
5003*48ed61a7SRobert Mustacchi 		if ((out_reg & mask) != (in_reg & mask))
5004*48ed61a7SRobert Mustacchi 			return FALSE;
5005*48ed61a7SRobert Mustacchi 		break;
5006*48ed61a7SRobert Mustacchi 	case BYPASS_PAGE_CTL2:
5007*48ed61a7SRobert Mustacchi 		/* All we can check in this page is control number
5008*48ed61a7SRobert Mustacchi 		 * which is already done above.
5009*48ed61a7SRobert Mustacchi 		 */
5010*48ed61a7SRobert Mustacchi 		break;
5011*48ed61a7SRobert Mustacchi 	}
5012*48ed61a7SRobert Mustacchi 
5013*48ed61a7SRobert Mustacchi 	/* We are as sure as we can be return TRUE */
5014*48ed61a7SRobert Mustacchi 	return TRUE;
5015*48ed61a7SRobert Mustacchi }
5016*48ed61a7SRobert Mustacchi 
5017*48ed61a7SRobert Mustacchi /**
5018*48ed61a7SRobert Mustacchi  *  ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter.
5019*48ed61a7SRobert Mustacchi  *
5020*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
5021*48ed61a7SRobert Mustacchi  *  @cmd: The control word we are setting.
5022*48ed61a7SRobert Mustacchi  *  @event: The event we are setting in the FW.  This also happens to
5023*48ed61a7SRobert Mustacchi  *	    be the mask for the event we are setting (handy)
5024*48ed61a7SRobert Mustacchi  *  @action: The action we set the event to in the FW. This is in a
5025*48ed61a7SRobert Mustacchi  *	     bit field that happens to be what we want to put in
5026*48ed61a7SRobert Mustacchi  *	     the event spot (also handy)
5027*48ed61a7SRobert Mustacchi  **/
ixgbe_bypass_set_generic(struct ixgbe_hw * hw,u32 ctrl,u32 event,u32 action)5028*48ed61a7SRobert Mustacchi s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event,
5029*48ed61a7SRobert Mustacchi 			     u32 action)
5030*48ed61a7SRobert Mustacchi {
5031*48ed61a7SRobert Mustacchi 	u32 by_ctl = 0;
5032*48ed61a7SRobert Mustacchi 	u32 cmd, verify;
5033*48ed61a7SRobert Mustacchi 	u32 count = 0;
5034*48ed61a7SRobert Mustacchi 
5035*48ed61a7SRobert Mustacchi 	/* Get current values */
5036*48ed61a7SRobert Mustacchi 	cmd = ctrl;	/* just reading only need control number */
5037*48ed61a7SRobert Mustacchi 	if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
5038*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
5039*48ed61a7SRobert Mustacchi 
5040*48ed61a7SRobert Mustacchi 	/* Set to new action */
5041*48ed61a7SRobert Mustacchi 	cmd = (by_ctl & ~event) | BYPASS_WE | action;
5042*48ed61a7SRobert Mustacchi 	if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
5043*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
5044*48ed61a7SRobert Mustacchi 
5045*48ed61a7SRobert Mustacchi 	/* Page 0 force a FW eeprom write which is slow so verify */
5046*48ed61a7SRobert Mustacchi 	if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) {
5047*48ed61a7SRobert Mustacchi 		verify = BYPASS_PAGE_CTL0;
5048*48ed61a7SRobert Mustacchi 		do {
5049*48ed61a7SRobert Mustacchi 			if (count++ > 5)
5050*48ed61a7SRobert Mustacchi 				return IXGBE_BYPASS_FW_WRITE_FAILURE;
5051*48ed61a7SRobert Mustacchi 
5052*48ed61a7SRobert Mustacchi 			if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl))
5053*48ed61a7SRobert Mustacchi 				return IXGBE_ERR_INVALID_ARGUMENT;
5054*48ed61a7SRobert Mustacchi 		} while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl));
5055*48ed61a7SRobert Mustacchi 	} else {
5056*48ed61a7SRobert Mustacchi 		/* We have give the FW time for the write to stick */
5057*48ed61a7SRobert Mustacchi 		msec_delay(100);
5058*48ed61a7SRobert Mustacchi 	}
5059*48ed61a7SRobert Mustacchi 
5060*48ed61a7SRobert Mustacchi 	return IXGBE_SUCCESS;
5061*48ed61a7SRobert Mustacchi }
5062*48ed61a7SRobert Mustacchi 
5063*48ed61a7SRobert Mustacchi /**
5064*48ed61a7SRobert Mustacchi  *  ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom addres.
5065*48ed61a7SRobert Mustacchi  *
5066*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
5067*48ed61a7SRobert Mustacchi  *  @addr: The bypass eeprom address to read.
5068*48ed61a7SRobert Mustacchi  *  @value: The 8b of data at the address above.
5069*48ed61a7SRobert Mustacchi  **/
ixgbe_bypass_rd_eep_generic(struct ixgbe_hw * hw,u32 addr,u8 * value)5070*48ed61a7SRobert Mustacchi s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value)
5071*48ed61a7SRobert Mustacchi {
5072*48ed61a7SRobert Mustacchi 	u32 cmd;
5073*48ed61a7SRobert Mustacchi 	u32 status;
5074*48ed61a7SRobert Mustacchi 
5075*48ed61a7SRobert Mustacchi 
5076*48ed61a7SRobert Mustacchi 	/* send the request */
5077*48ed61a7SRobert Mustacchi 	cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
5078*48ed61a7SRobert Mustacchi 	cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
5079*48ed61a7SRobert Mustacchi 	if (ixgbe_bypass_rw_generic(hw, cmd, &status))
5080*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
5081*48ed61a7SRobert Mustacchi 
5082*48ed61a7SRobert Mustacchi 	/* We have give the FW time for the write to stick */
5083*48ed61a7SRobert Mustacchi 	msec_delay(100);
5084*48ed61a7SRobert Mustacchi 
5085*48ed61a7SRobert Mustacchi 	/* now read the results */
5086*48ed61a7SRobert Mustacchi 	cmd &= ~BYPASS_WE;
5087*48ed61a7SRobert Mustacchi 	if (ixgbe_bypass_rw_generic(hw, cmd, &status))
5088*48ed61a7SRobert Mustacchi 		return IXGBE_ERR_INVALID_ARGUMENT;
5089*48ed61a7SRobert Mustacchi 
5090*48ed61a7SRobert Mustacchi 	*value = status & BYPASS_CTL2_DATA_M;
5091*48ed61a7SRobert Mustacchi 
5092*48ed61a7SRobert Mustacchi 	return IXGBE_SUCCESS;
5093*48ed61a7SRobert Mustacchi }
5094*48ed61a7SRobert Mustacchi 
5095*48ed61a7SRobert Mustacchi /**
5096*48ed61a7SRobert Mustacchi  *  ixgbe_get_orom_version - Return option ROM from EEPROM
5097*48ed61a7SRobert Mustacchi  *
5098*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
5099*48ed61a7SRobert Mustacchi  *  @nvm_ver: pointer to output structure
5100*48ed61a7SRobert Mustacchi  *
5101*48ed61a7SRobert Mustacchi  *  if valid option ROM version, nvm_ver->or_valid set to TRUE
5102*48ed61a7SRobert Mustacchi  *  else nvm_ver->or_valid is FALSE.
5103*48ed61a7SRobert Mustacchi  **/
ixgbe_get_orom_version(struct ixgbe_hw * hw,struct ixgbe_nvm_version * nvm_ver)5104*48ed61a7SRobert Mustacchi void ixgbe_get_orom_version(struct ixgbe_hw *hw,
5105*48ed61a7SRobert Mustacchi 			    struct ixgbe_nvm_version *nvm_ver)
5106*48ed61a7SRobert Mustacchi {
5107*48ed61a7SRobert Mustacchi 	u16 offset, eeprom_cfg_blkh, eeprom_cfg_blkl;
5108*48ed61a7SRobert Mustacchi 
5109*48ed61a7SRobert Mustacchi 	nvm_ver->or_valid = FALSE;
5110*48ed61a7SRobert Mustacchi 	/* Option Rom may or may not be present.  Start with pointer */
5111*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, NVM_OROM_OFFSET, &offset);
5112*48ed61a7SRobert Mustacchi 
5113*48ed61a7SRobert Mustacchi 	/* make sure offset is valid */
5114*48ed61a7SRobert Mustacchi 	if ((offset == 0x0) || (offset == NVM_INVALID_PTR))
5115*48ed61a7SRobert Mustacchi 		return;
5116*48ed61a7SRobert Mustacchi 
5117*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_HI, &eeprom_cfg_blkh);
5118*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, offset + NVM_OROM_BLK_LOW, &eeprom_cfg_blkl);
5119*48ed61a7SRobert Mustacchi 
5120*48ed61a7SRobert Mustacchi 	/* option rom exists and is valid */
5121*48ed61a7SRobert Mustacchi 	if ((eeprom_cfg_blkl | eeprom_cfg_blkh) == 0x0 ||
5122*48ed61a7SRobert Mustacchi 	    eeprom_cfg_blkl == NVM_VER_INVALID ||
5123*48ed61a7SRobert Mustacchi 	    eeprom_cfg_blkh == NVM_VER_INVALID)
5124*48ed61a7SRobert Mustacchi 		return;
5125*48ed61a7SRobert Mustacchi 
5126*48ed61a7SRobert Mustacchi 	nvm_ver->or_valid = TRUE;
5127*48ed61a7SRobert Mustacchi 	nvm_ver->or_major = eeprom_cfg_blkl >> NVM_OROM_SHIFT;
5128*48ed61a7SRobert Mustacchi 	nvm_ver->or_build = (eeprom_cfg_blkl << NVM_OROM_SHIFT) |
5129*48ed61a7SRobert Mustacchi 			    (eeprom_cfg_blkh >> NVM_OROM_SHIFT);
5130*48ed61a7SRobert Mustacchi 	nvm_ver->or_patch = eeprom_cfg_blkh & NVM_OROM_PATCH_MASK;
5131*48ed61a7SRobert Mustacchi }
5132*48ed61a7SRobert Mustacchi 
5133*48ed61a7SRobert Mustacchi /**
5134*48ed61a7SRobert Mustacchi  *  ixgbe_get_oem_prod_version - Return OEM Product version
5135*48ed61a7SRobert Mustacchi  *
5136*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
5137*48ed61a7SRobert Mustacchi  *  @nvm_ver: pointer to output structure
5138*48ed61a7SRobert Mustacchi  *
5139*48ed61a7SRobert Mustacchi  *  if valid OEM product version, nvm_ver->oem_valid set to TRUE
5140*48ed61a7SRobert Mustacchi  *  else nvm_ver->oem_valid is FALSE.
5141*48ed61a7SRobert Mustacchi  **/
ixgbe_get_oem_prod_version(struct ixgbe_hw * hw,struct ixgbe_nvm_version * nvm_ver)5142*48ed61a7SRobert Mustacchi void ixgbe_get_oem_prod_version(struct ixgbe_hw *hw,
5143*48ed61a7SRobert Mustacchi 				struct ixgbe_nvm_version *nvm_ver)
5144*48ed61a7SRobert Mustacchi {
5145*48ed61a7SRobert Mustacchi 	u16 rel_num, prod_ver, mod_len, cap, offset;
5146*48ed61a7SRobert Mustacchi 
5147*48ed61a7SRobert Mustacchi 	nvm_ver->oem_valid = FALSE;
5148*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, NVM_OEM_PROD_VER_PTR, &offset);
5149*48ed61a7SRobert Mustacchi 
5150*48ed61a7SRobert Mustacchi 	/* Return is offset to OEM Product Version block is invalid */
5151*48ed61a7SRobert Mustacchi 	if (offset == 0x0 || offset == NVM_INVALID_PTR)
5152*48ed61a7SRobert Mustacchi 		return;
5153*48ed61a7SRobert Mustacchi 
5154*48ed61a7SRobert Mustacchi 	/* Read product version block */
5155*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, offset, &mod_len);
5156*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_CAP_OFF, &cap);
5157*48ed61a7SRobert Mustacchi 
5158*48ed61a7SRobert Mustacchi 	/* Return if OEM product version block is invalid */
5159*48ed61a7SRobert Mustacchi 	if (mod_len != NVM_OEM_PROD_VER_MOD_LEN ||
5160*48ed61a7SRobert Mustacchi 	    (cap & NVM_OEM_PROD_VER_CAP_MASK) != 0x0)
5161*48ed61a7SRobert Mustacchi 		return;
5162*48ed61a7SRobert Mustacchi 
5163*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_L, &prod_ver);
5164*48ed61a7SRobert Mustacchi 	hw->eeprom.ops.read(hw, offset + NVM_OEM_PROD_VER_OFF_H, &rel_num);
5165*48ed61a7SRobert Mustacchi 
5166*48ed61a7SRobert Mustacchi 	/* Return if version is invalid */
5167*48ed61a7SRobert Mustacchi 	if ((rel_num | prod_ver) == 0x0 ||
5168*48ed61a7SRobert Mustacchi 	    rel_num == NVM_VER_INVALID || prod_ver == NVM_VER_INVALID)
5169*48ed61a7SRobert Mustacchi 		return;
5170*48ed61a7SRobert Mustacchi 
5171*48ed61a7SRobert Mustacchi 	nvm_ver->oem_major = prod_ver >> NVM_VER_SHIFT;
5172*48ed61a7SRobert Mustacchi 	nvm_ver->oem_minor = prod_ver & NVM_VER_MASK;
5173*48ed61a7SRobert Mustacchi 	nvm_ver->oem_release = rel_num;
5174*48ed61a7SRobert Mustacchi 	nvm_ver->oem_valid = TRUE;
5175*48ed61a7SRobert Mustacchi }
5176*48ed61a7SRobert Mustacchi 
5177*48ed61a7SRobert Mustacchi /**
5178*48ed61a7SRobert Mustacchi  *  ixgbe_get_etk_id - Return Etrack ID from EEPROM
5179*48ed61a7SRobert Mustacchi  *
5180*48ed61a7SRobert Mustacchi  *  @hw: pointer to hardware structure
5181*48ed61a7SRobert Mustacchi  *  @nvm_ver: pointer to output structure
5182*48ed61a7SRobert Mustacchi  *
5183*48ed61a7SRobert Mustacchi  *  word read errors will return 0xFFFF
5184*48ed61a7SRobert Mustacchi  **/
ixgbe_get_etk_id(struct ixgbe_hw * hw,struct ixgbe_nvm_version * nvm_ver)5185*48ed61a7SRobert Mustacchi void ixgbe_get_etk_id(struct ixgbe_hw *hw, struct ixgbe_nvm_version *nvm_ver)
5186*48ed61a7SRobert Mustacchi {
5187*48ed61a7SRobert Mustacchi 	u16 etk_id_l, etk_id_h;
5188*48ed61a7SRobert Mustacchi 
5189*48ed61a7SRobert Mustacchi 	if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_LOW, &etk_id_l))
5190*48ed61a7SRobert Mustacchi 		etk_id_l = NVM_VER_INVALID;
5191*48ed61a7SRobert Mustacchi 	if (hw->eeprom.ops.read(hw, NVM_ETK_OFF_HI, &etk_id_h))
5192*48ed61a7SRobert Mustacchi 		etk_id_h = NVM_VER_INVALID;
5193*48ed61a7SRobert Mustacchi 
5194*48ed61a7SRobert Mustacchi 	/* The word order for the version format is determined by high order
5195*48ed61a7SRobert Mustacchi 	 * word bit 15.
5196*48ed61a7SRobert Mustacchi 	 */
5197*48ed61a7SRobert Mustacchi 	if ((etk_id_h & NVM_ETK_VALID) == 0) {
5198*48ed61a7SRobert Mustacchi 		nvm_ver->etk_id = etk_id_h;
5199*48ed61a7SRobert Mustacchi 		nvm_ver->etk_id |= (etk_id_l << NVM_ETK_SHIFT);
5200*48ed61a7SRobert Mustacchi 	} else {
5201*48ed61a7SRobert Mustacchi 		nvm_ver->etk_id = etk_id_l;
5202*48ed61a7SRobert Mustacchi 		nvm_ver->etk_id |= (etk_id_h << NVM_ETK_SHIFT);
5203*48ed61a7SRobert Mustacchi 	}
5204*48ed61a7SRobert Mustacchi }
5205*48ed61a7SRobert Mustacchi 
5206dc0cb1cdSDale Ghent 
5207dc0cb1cdSDale Ghent /**
5208dc0cb1cdSDale Ghent  * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg
5209dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
5210dc0cb1cdSDale Ghent  * @map: pointer to u8 arr for returning map
5211dc0cb1cdSDale Ghent  *
5212dc0cb1cdSDale Ghent  * Read the rtrup2tc HW register and resolve its content into map
5213dc0cb1cdSDale Ghent  **/
ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw * hw,u8 * map)5214dc0cb1cdSDale Ghent void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map)
5215dc0cb1cdSDale Ghent {
5216dc0cb1cdSDale Ghent 	u32 reg, i;
5217dc0cb1cdSDale Ghent 
5218dc0cb1cdSDale Ghent 	reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
5219dc0cb1cdSDale Ghent 	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
5220dc0cb1cdSDale Ghent 		map[i] = IXGBE_RTRUP2TC_UP_MASK &
5221dc0cb1cdSDale Ghent 			(reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
5222dc0cb1cdSDale Ghent 	return;
5223dc0cb1cdSDale Ghent }
5224dc0cb1cdSDale Ghent 
ixgbe_disable_rx_generic(struct ixgbe_hw * hw)5225dc0cb1cdSDale Ghent void ixgbe_disable_rx_generic(struct ixgbe_hw *hw)
5226dc0cb1cdSDale Ghent {
5227dc0cb1cdSDale Ghent 	u32 pfdtxgswc;
5228dc0cb1cdSDale Ghent 	u32 rxctrl;
5229dc0cb1cdSDale Ghent 
5230dc0cb1cdSDale Ghent 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
5231dc0cb1cdSDale Ghent 	if (rxctrl & IXGBE_RXCTRL_RXEN) {
5232dc0cb1cdSDale Ghent 		if (hw->mac.type != ixgbe_mac_82598EB) {
5233dc0cb1cdSDale Ghent 			pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
5234dc0cb1cdSDale Ghent 			if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
5235dc0cb1cdSDale Ghent 				pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
5236dc0cb1cdSDale Ghent 				IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
5237dc0cb1cdSDale Ghent 				hw->mac.set_lben = TRUE;
5238dc0cb1cdSDale Ghent 			} else {
5239dc0cb1cdSDale Ghent 				hw->mac.set_lben = FALSE;
5240dc0cb1cdSDale Ghent 			}
5241dc0cb1cdSDale Ghent 		}
5242dc0cb1cdSDale Ghent 		rxctrl &= ~IXGBE_RXCTRL_RXEN;
5243dc0cb1cdSDale Ghent 		IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
5244dc0cb1cdSDale Ghent 	}
5245dc0cb1cdSDale Ghent }
5246dc0cb1cdSDale Ghent 
ixgbe_enable_rx_generic(struct ixgbe_hw * hw)5247dc0cb1cdSDale Ghent void ixgbe_enable_rx_generic(struct ixgbe_hw *hw)
5248dc0cb1cdSDale Ghent {
5249dc0cb1cdSDale Ghent 	u32 pfdtxgswc;
5250dc0cb1cdSDale Ghent 	u32 rxctrl;
5251dc0cb1cdSDale Ghent 
5252dc0cb1cdSDale Ghent 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
5253dc0cb1cdSDale Ghent 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, (rxctrl | IXGBE_RXCTRL_RXEN));
5254dc0cb1cdSDale Ghent 
5255dc0cb1cdSDale Ghent 	if (hw->mac.type != ixgbe_mac_82598EB) {
5256dc0cb1cdSDale Ghent 		if (hw->mac.set_lben) {
5257dc0cb1cdSDale Ghent 			pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
5258dc0cb1cdSDale Ghent 			pfdtxgswc |= IXGBE_PFDTXGSWC_VT_LBEN;
5259dc0cb1cdSDale Ghent 			IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
5260dc0cb1cdSDale Ghent 			hw->mac.set_lben = FALSE;
5261dc0cb1cdSDale Ghent 		}
5262dc0cb1cdSDale Ghent 	}
5263dc0cb1cdSDale Ghent }
5264dc0cb1cdSDale Ghent 
5265dc0cb1cdSDale Ghent /**
5266dc0cb1cdSDale Ghent  * ixgbe_mng_present - returns TRUE when management capability is present
5267dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
5268dc0cb1cdSDale Ghent  */
ixgbe_mng_present(struct ixgbe_hw * hw)5269dc0cb1cdSDale Ghent bool ixgbe_mng_present(struct ixgbe_hw *hw)
5270dc0cb1cdSDale Ghent {
5271dc0cb1cdSDale Ghent 	u32 fwsm;
5272dc0cb1cdSDale Ghent 
5273dc0cb1cdSDale Ghent 	if (hw->mac.type < ixgbe_mac_82599EB)
5274dc0cb1cdSDale Ghent 		return FALSE;
5275dc0cb1cdSDale Ghent 
5276dc0cb1cdSDale Ghent 	fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
5277*48ed61a7SRobert Mustacchi 
5278*48ed61a7SRobert Mustacchi 	return !!(fwsm & IXGBE_FWSM_FW_MODE_PT);
5279dc0cb1cdSDale Ghent }
5280dc0cb1cdSDale Ghent 
5281dc0cb1cdSDale Ghent /**
5282dc0cb1cdSDale Ghent  * ixgbe_mng_enabled - Is the manageability engine enabled?
5283dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
5284dc0cb1cdSDale Ghent  *
5285dc0cb1cdSDale Ghent  * Returns TRUE if the manageability engine is enabled.
5286dc0cb1cdSDale Ghent  **/
ixgbe_mng_enabled(struct ixgbe_hw * hw)5287dc0cb1cdSDale Ghent bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
5288dc0cb1cdSDale Ghent {
5289dc0cb1cdSDale Ghent 	u32 fwsm, manc, factps;
5290dc0cb1cdSDale Ghent 
5291dc0cb1cdSDale Ghent 	fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw));
5292dc0cb1cdSDale Ghent 	if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
5293dc0cb1cdSDale Ghent 		return FALSE;
5294dc0cb1cdSDale Ghent 
5295dc0cb1cdSDale Ghent 	manc = IXGBE_READ_REG(hw, IXGBE_MANC);
5296dc0cb1cdSDale Ghent 	if (!(manc & IXGBE_MANC_RCV_TCO_EN))
5297dc0cb1cdSDale Ghent 		return FALSE;
5298dc0cb1cdSDale Ghent 
5299dc0cb1cdSDale Ghent 	if (hw->mac.type <= ixgbe_mac_X540) {
5300dc0cb1cdSDale Ghent 		factps = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw));
5301dc0cb1cdSDale Ghent 		if (factps & IXGBE_FACTPS_MNGCG)
5302dc0cb1cdSDale Ghent 			return FALSE;
5303dc0cb1cdSDale Ghent 	}
5304dc0cb1cdSDale Ghent 
5305dc0cb1cdSDale Ghent 	return TRUE;
5306dc0cb1cdSDale Ghent }
5307dc0cb1cdSDale Ghent 
5308dc0cb1cdSDale Ghent /**
5309dc0cb1cdSDale Ghent  *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
5310dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
5311dc0cb1cdSDale Ghent  *  @speed: new link speed
5312dc0cb1cdSDale Ghent  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
5313dc0cb1cdSDale Ghent  *
5314dc0cb1cdSDale Ghent  *  Set the link speed in the MAC and/or PHY register and restarts link.
5315dc0cb1cdSDale Ghent  **/
ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)5316dc0cb1cdSDale Ghent s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
5317dc0cb1cdSDale Ghent 					  ixgbe_link_speed speed,
5318dc0cb1cdSDale Ghent 					  bool autoneg_wait_to_complete)
5319dc0cb1cdSDale Ghent {
5320dc0cb1cdSDale Ghent 	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
5321dc0cb1cdSDale Ghent 	ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
5322dc0cb1cdSDale Ghent 	s32 status = IXGBE_SUCCESS;
5323dc0cb1cdSDale Ghent 	u32 speedcnt = 0;
5324dc0cb1cdSDale Ghent 	u32 i = 0;
5325dc0cb1cdSDale Ghent 	bool autoneg, link_up = FALSE;
5326dc0cb1cdSDale Ghent 
5327dc0cb1cdSDale Ghent 	DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
5328dc0cb1cdSDale Ghent 
5329dc0cb1cdSDale Ghent 	/* Mask off requested but non-supported speeds */
5330dc0cb1cdSDale Ghent 	status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg);
5331dc0cb1cdSDale Ghent 	if (status != IXGBE_SUCCESS)
5332dc0cb1cdSDale Ghent 		return status;
5333dc0cb1cdSDale Ghent 
5334dc0cb1cdSDale Ghent 	speed &= link_speed;
5335dc0cb1cdSDale Ghent 
5336dc0cb1cdSDale Ghent 	/* Try each speed one by one, highest priority first.  We do this in
5337dc0cb1cdSDale Ghent 	 * software because 10Gb fiber doesn't support speed autonegotiation.
5338dc0cb1cdSDale Ghent 	 */
5339dc0cb1cdSDale Ghent 	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
5340dc0cb1cdSDale Ghent 		speedcnt++;
5341dc0cb1cdSDale Ghent 		highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
5342dc0cb1cdSDale Ghent 
5343dc0cb1cdSDale Ghent 		/* Set the module link speed */
5344dc0cb1cdSDale Ghent 		switch (hw->phy.media_type) {
5345dc0cb1cdSDale Ghent 		case ixgbe_media_type_fiber_fixed:
5346dc0cb1cdSDale Ghent 		case ixgbe_media_type_fiber:
5347dc0cb1cdSDale Ghent 			ixgbe_set_rate_select_speed(hw,
5348dc0cb1cdSDale Ghent 						    IXGBE_LINK_SPEED_10GB_FULL);
5349dc0cb1cdSDale Ghent 			break;
5350dc0cb1cdSDale Ghent 		case ixgbe_media_type_fiber_qsfp:
5351dc0cb1cdSDale Ghent 			/* QSFP module automatically detects MAC link speed */
5352dc0cb1cdSDale Ghent 			break;
5353dc0cb1cdSDale Ghent 		default:
5354dc0cb1cdSDale Ghent 			DEBUGOUT("Unexpected media type.\n");
5355dc0cb1cdSDale Ghent 			break;
5356dc0cb1cdSDale Ghent 		}
5357dc0cb1cdSDale Ghent 
5358dc0cb1cdSDale Ghent 		/* Allow module to change analog characteristics (1G->10G) */
5359dc0cb1cdSDale Ghent 		msec_delay(40);
5360dc0cb1cdSDale Ghent 
5361dc0cb1cdSDale Ghent 		status = ixgbe_setup_mac_link(hw,
5362dc0cb1cdSDale Ghent 					      IXGBE_LINK_SPEED_10GB_FULL,
5363dc0cb1cdSDale Ghent 					      autoneg_wait_to_complete);
5364dc0cb1cdSDale Ghent 		if (status != IXGBE_SUCCESS)
5365dc0cb1cdSDale Ghent 			return status;
5366dc0cb1cdSDale Ghent 
5367dc0cb1cdSDale Ghent 		/* Flap the Tx laser if it has not already been done */
5368dc0cb1cdSDale Ghent 		ixgbe_flap_tx_laser(hw);
5369dc0cb1cdSDale Ghent 
5370dc0cb1cdSDale Ghent 		/* Wait for the controller to acquire link.  Per IEEE 802.3ap,
5371dc0cb1cdSDale Ghent 		 * Section 73.10.2, we may have to wait up to 500ms if KR is
5372dc0cb1cdSDale Ghent 		 * attempted.  82599 uses the same timing for 10g SFI.
5373dc0cb1cdSDale Ghent 		 */
5374dc0cb1cdSDale Ghent 		for (i = 0; i < 5; i++) {
5375dc0cb1cdSDale Ghent 			/* Wait for the link partner to also set speed */
5376dc0cb1cdSDale Ghent 			msec_delay(100);
5377dc0cb1cdSDale Ghent 
5378dc0cb1cdSDale Ghent 			/* If we have link, just jump out */
5379dc0cb1cdSDale Ghent 			status = ixgbe_check_link(hw, &link_speed,
5380dc0cb1cdSDale Ghent 						  &link_up, FALSE);
5381dc0cb1cdSDale Ghent 			if (status != IXGBE_SUCCESS)
5382dc0cb1cdSDale Ghent 				return status;
5383dc0cb1cdSDale Ghent 
5384dc0cb1cdSDale Ghent 			if (link_up)
5385dc0cb1cdSDale Ghent 				goto out;
5386dc0cb1cdSDale Ghent 		}
5387dc0cb1cdSDale Ghent 	}
5388dc0cb1cdSDale Ghent 
5389dc0cb1cdSDale Ghent 	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
5390dc0cb1cdSDale Ghent 		speedcnt++;
5391dc0cb1cdSDale Ghent 		if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
5392dc0cb1cdSDale Ghent 			highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
5393dc0cb1cdSDale Ghent 
5394dc0cb1cdSDale Ghent 		/* Set the module link speed */
5395dc0cb1cdSDale Ghent 		switch (hw->phy.media_type) {
5396dc0cb1cdSDale Ghent 		case ixgbe_media_type_fiber_fixed:
5397dc0cb1cdSDale Ghent 		case ixgbe_media_type_fiber:
5398dc0cb1cdSDale Ghent 			ixgbe_set_rate_select_speed(hw,
5399dc0cb1cdSDale Ghent 						    IXGBE_LINK_SPEED_1GB_FULL);
5400dc0cb1cdSDale Ghent 			break;
5401dc0cb1cdSDale Ghent 		case ixgbe_media_type_fiber_qsfp:
5402dc0cb1cdSDale Ghent 			/* QSFP module automatically detects link speed */
5403dc0cb1cdSDale Ghent 			break;
5404dc0cb1cdSDale Ghent 		default:
5405dc0cb1cdSDale Ghent 			DEBUGOUT("Unexpected media type.\n");
5406dc0cb1cdSDale Ghent 			break;
5407dc0cb1cdSDale Ghent 		}
5408dc0cb1cdSDale Ghent 
5409dc0cb1cdSDale Ghent 		/* Allow module to change analog characteristics (10G->1G) */
5410dc0cb1cdSDale Ghent 		msec_delay(40);
5411dc0cb1cdSDale Ghent 
5412dc0cb1cdSDale Ghent 		status = ixgbe_setup_mac_link(hw,
5413dc0cb1cdSDale Ghent 					      IXGBE_LINK_SPEED_1GB_FULL,
5414dc0cb1cdSDale Ghent 					      autoneg_wait_to_complete);
5415dc0cb1cdSDale Ghent 		if (status != IXGBE_SUCCESS)
5416dc0cb1cdSDale Ghent 			return status;
5417dc0cb1cdSDale Ghent 
5418dc0cb1cdSDale Ghent 		/* Flap the Tx laser if it has not already been done */
5419dc0cb1cdSDale Ghent 		ixgbe_flap_tx_laser(hw);
5420dc0cb1cdSDale Ghent 
5421dc0cb1cdSDale Ghent 		/* Wait for the link partner to also set speed */
5422dc0cb1cdSDale Ghent 		msec_delay(100);
5423dc0cb1cdSDale Ghent 
5424dc0cb1cdSDale Ghent 		/* If we have link, just jump out */
5425dc0cb1cdSDale Ghent 		status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE);
5426dc0cb1cdSDale Ghent 		if (status != IXGBE_SUCCESS)
5427dc0cb1cdSDale Ghent 			return status;
5428dc0cb1cdSDale Ghent 
5429dc0cb1cdSDale Ghent 		if (link_up)
5430dc0cb1cdSDale Ghent 			goto out;
5431dc0cb1cdSDale Ghent 	}
5432dc0cb1cdSDale Ghent 
5433dc0cb1cdSDale Ghent 	/* We didn't get link.  Configure back to the highest speed we tried,
5434dc0cb1cdSDale Ghent 	 * (if there was more than one).  We call ourselves back with just the
5435dc0cb1cdSDale Ghent 	 * single highest speed that the user requested.
5436dc0cb1cdSDale Ghent 	 */
5437dc0cb1cdSDale Ghent 	if (speedcnt > 1)
5438dc0cb1cdSDale Ghent 		status = ixgbe_setup_mac_link_multispeed_fiber(hw,
5439dc0cb1cdSDale Ghent 						      highest_link_speed,
5440dc0cb1cdSDale Ghent 						      autoneg_wait_to_complete);
5441dc0cb1cdSDale Ghent 
5442dc0cb1cdSDale Ghent out:
5443dc0cb1cdSDale Ghent 	/* Set autoneg_advertised value based on input link speed */
5444dc0cb1cdSDale Ghent 	hw->phy.autoneg_advertised = 0;
5445dc0cb1cdSDale Ghent 
5446dc0cb1cdSDale Ghent 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
5447dc0cb1cdSDale Ghent 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
5448dc0cb1cdSDale Ghent 
5449dc0cb1cdSDale Ghent 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
5450dc0cb1cdSDale Ghent 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
5451dc0cb1cdSDale Ghent 
5452dc0cb1cdSDale Ghent 	return status;
5453dc0cb1cdSDale Ghent }
5454dc0cb1cdSDale Ghent 
5455dc0cb1cdSDale Ghent /**
5456dc0cb1cdSDale Ghent  *  ixgbe_set_soft_rate_select_speed - Set module link speed
5457dc0cb1cdSDale Ghent  *  @hw: pointer to hardware structure
5458dc0cb1cdSDale Ghent  *  @speed: link speed to set
5459dc0cb1cdSDale Ghent  *
5460dc0cb1cdSDale Ghent  *  Set module link speed via the soft rate select.
5461dc0cb1cdSDale Ghent  */
ixgbe_set_soft_rate_select_speed(struct ixgbe_hw * hw,ixgbe_link_speed speed)5462dc0cb1cdSDale Ghent void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
5463dc0cb1cdSDale Ghent 					ixgbe_link_speed speed)
5464dc0cb1cdSDale Ghent {
5465dc0cb1cdSDale Ghent 	s32 status;
5466dc0cb1cdSDale Ghent 	u8 rs, eeprom_data;
5467dc0cb1cdSDale Ghent 
5468dc0cb1cdSDale Ghent 	switch (speed) {
5469dc0cb1cdSDale Ghent 	case IXGBE_LINK_SPEED_10GB_FULL:
5470dc0cb1cdSDale Ghent 		/* one bit mask same as setting on */
5471dc0cb1cdSDale Ghent 		rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
5472dc0cb1cdSDale Ghent 		break;
5473dc0cb1cdSDale Ghent 	case IXGBE_LINK_SPEED_1GB_FULL:
5474dc0cb1cdSDale Ghent 		rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
5475dc0cb1cdSDale Ghent 		break;
5476dc0cb1cdSDale Ghent 	default:
5477dc0cb1cdSDale Ghent 		DEBUGOUT("Invalid fixed module speed\n");
5478dc0cb1cdSDale Ghent 		return;
5479dc0cb1cdSDale Ghent 	}
5480dc0cb1cdSDale Ghent 
5481dc0cb1cdSDale Ghent 	/* Set RS0 */
5482dc0cb1cdSDale Ghent 	status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
5483dc0cb1cdSDale Ghent 					   IXGBE_I2C_EEPROM_DEV_ADDR2,
5484dc0cb1cdSDale Ghent 					   &eeprom_data);
5485dc0cb1cdSDale Ghent 	if (status) {
5486dc0cb1cdSDale Ghent 		DEBUGOUT("Failed to read Rx Rate Select RS0\n");
5487dc0cb1cdSDale Ghent 		goto out;
5488dc0cb1cdSDale Ghent 	}
5489dc0cb1cdSDale Ghent 
5490dc0cb1cdSDale Ghent 	eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs;
5491dc0cb1cdSDale Ghent 
5492dc0cb1cdSDale Ghent 	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
5493dc0cb1cdSDale Ghent 					    IXGBE_I2C_EEPROM_DEV_ADDR2,
5494dc0cb1cdSDale Ghent 					    eeprom_data);
5495dc0cb1cdSDale Ghent 	if (status) {
5496dc0cb1cdSDale Ghent 		DEBUGOUT("Failed to write Rx Rate Select RS0\n");
5497dc0cb1cdSDale Ghent 		goto out;
5498dc0cb1cdSDale Ghent 	}
5499dc0cb1cdSDale Ghent 
5500dc0cb1cdSDale Ghent 	/* Set RS1 */
5501dc0cb1cdSDale Ghent 	status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
5502dc0cb1cdSDale Ghent 					   IXGBE_I2C_EEPROM_DEV_ADDR2,
5503dc0cb1cdSDale Ghent 					   &eeprom_data);
5504dc0cb1cdSDale Ghent 	if (status) {
5505dc0cb1cdSDale Ghent 		DEBUGOUT("Failed to read Rx Rate Select RS1\n");
5506dc0cb1cdSDale Ghent 		goto out;
5507dc0cb1cdSDale Ghent 	}
5508dc0cb1cdSDale Ghent 
5509dc0cb1cdSDale Ghent 	eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs;
5510dc0cb1cdSDale Ghent 
5511dc0cb1cdSDale Ghent 	status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
5512dc0cb1cdSDale Ghent 					    IXGBE_I2C_EEPROM_DEV_ADDR2,
5513dc0cb1cdSDale Ghent 					    eeprom_data);
5514dc0cb1cdSDale Ghent 	if (status) {
5515dc0cb1cdSDale Ghent 		DEBUGOUT("Failed to write Rx Rate Select RS1\n");
5516dc0cb1cdSDale Ghent 		goto out;
5517dc0cb1cdSDale Ghent 	}
5518dc0cb1cdSDale Ghent out:
5519dc0cb1cdSDale Ghent 	return;
5520dc0cb1cdSDale Ghent }
5521