xref: /freebsd/sys/dev/ixgbe/ixgbe_common.c (revision 0ac6dfec68247cda47a7ca53c69ee8fc50e776b3)
19ca4041bSJack F Vogel /******************************************************************************
213705f88SJack F Vogel 
30ac6dfecSJack F Vogel   Copyright (c) 2001-2009, Intel Corporation
413705f88SJack F Vogel   All rights reserved.
513705f88SJack F Vogel 
613705f88SJack F Vogel   Redistribution and use in source and binary forms, with or without
713705f88SJack F Vogel   modification, are permitted provided that the following conditions are met:
813705f88SJack F Vogel 
913705f88SJack F Vogel    1. Redistributions of source code must retain the above copyright notice,
1013705f88SJack F Vogel       this list of conditions and the following disclaimer.
1113705f88SJack F Vogel 
1213705f88SJack F Vogel    2. Redistributions in binary form must reproduce the above copyright
1313705f88SJack F Vogel       notice, this list of conditions and the following disclaimer in the
1413705f88SJack F Vogel       documentation and/or other materials provided with the distribution.
1513705f88SJack F Vogel 
1613705f88SJack F Vogel    3. Neither the name of the Intel Corporation nor the names of its
1713705f88SJack F Vogel       contributors may be used to endorse or promote products derived from
1813705f88SJack F Vogel       this software without specific prior written permission.
1913705f88SJack F Vogel 
2013705f88SJack F Vogel   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2113705f88SJack F Vogel   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2213705f88SJack F Vogel   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2313705f88SJack F Vogel   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2413705f88SJack F Vogel   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2513705f88SJack F Vogel   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2613705f88SJack F Vogel   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2713705f88SJack F Vogel   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2813705f88SJack F Vogel   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2913705f88SJack F Vogel   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3013705f88SJack F Vogel   POSSIBILITY OF SUCH DAMAGE.
3113705f88SJack F Vogel 
329ca4041bSJack F Vogel ******************************************************************************/
3313705f88SJack F Vogel /*$FreeBSD$*/
3413705f88SJack F Vogel 
3513705f88SJack F Vogel #include "ixgbe_common.h"
3613705f88SJack F Vogel #include "ixgbe_api.h"
3713705f88SJack F Vogel 
3813705f88SJack F Vogel static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw);
3913705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
4013705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
4113705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
4213705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
4313705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
4413705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
4513705f88SJack F Vogel                                         u16 count);
4613705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
4713705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
4813705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
4913705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
5013705f88SJack F Vogel static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
5113705f88SJack F Vogel 
5213705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
5313705f88SJack F Vogel 
5413705f88SJack F Vogel /**
559ca4041bSJack F Vogel  *  ixgbe_init_ops_generic - Inits function ptrs
569ca4041bSJack F Vogel  *  @hw: pointer to the hardware structure
5713705f88SJack F Vogel  *
589ca4041bSJack F Vogel  *  Initialize the function pointers.
5913705f88SJack F Vogel  **/
609ca4041bSJack F Vogel s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
6113705f88SJack F Vogel {
629ca4041bSJack F Vogel 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
639ca4041bSJack F Vogel 	struct ixgbe_mac_info *mac = &hw->mac;
649ca4041bSJack F Vogel 	u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
6513705f88SJack F Vogel 
6613705f88SJack F Vogel 	/* EEPROM */
679ca4041bSJack F Vogel 	eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic;
689ca4041bSJack F Vogel 	/* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */
699ca4041bSJack F Vogel 	if (eec & (1 << 8))
709ca4041bSJack F Vogel 		eeprom->ops.read = &ixgbe_read_eeprom_generic;
719ca4041bSJack F Vogel 	else
729ca4041bSJack F Vogel 		eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic;
739ca4041bSJack F Vogel 	eeprom->ops.write = &ixgbe_write_eeprom_generic;
749ca4041bSJack F Vogel 	eeprom->ops.validate_checksum =
7513705f88SJack F Vogel 	                              &ixgbe_validate_eeprom_checksum_generic;
769ca4041bSJack F Vogel 	eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic;
779ca4041bSJack F Vogel 
789ca4041bSJack F Vogel 	/* MAC */
799ca4041bSJack F Vogel 	mac->ops.init_hw = &ixgbe_init_hw_generic;
809ca4041bSJack F Vogel 	mac->ops.reset_hw = NULL;
819ca4041bSJack F Vogel 	mac->ops.start_hw = &ixgbe_start_hw_generic;
829ca4041bSJack F Vogel 	mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic;
839ca4041bSJack F Vogel 	mac->ops.get_media_type = NULL;
841b6e0dbaSJack F Vogel 	mac->ops.get_supported_physical_layer = NULL;
850ac6dfecSJack F Vogel 	mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic;
869ca4041bSJack F Vogel 	mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic;
879ca4041bSJack F Vogel 	mac->ops.stop_adapter = &ixgbe_stop_adapter_generic;
889ca4041bSJack F Vogel 	mac->ops.get_bus_info = &ixgbe_get_bus_info_generic;
891b6e0dbaSJack F Vogel 	mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie;
909ca4041bSJack F Vogel 
919ca4041bSJack F Vogel 	/* LEDs */
929ca4041bSJack F Vogel 	mac->ops.led_on = &ixgbe_led_on_generic;
939ca4041bSJack F Vogel 	mac->ops.led_off = &ixgbe_led_off_generic;
940ac6dfecSJack F Vogel 	mac->ops.blink_led_start = &ixgbe_blink_led_start_generic;
950ac6dfecSJack F Vogel 	mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic;
969ca4041bSJack F Vogel 
9713705f88SJack F Vogel 	/* RAR, Multicast, VLAN */
989ca4041bSJack F Vogel 	mac->ops.set_rar = &ixgbe_set_rar_generic;
995b7f4cedSJack F Vogel 	mac->ops.clear_rar = &ixgbe_clear_rar_generic;
1000ac6dfecSJack F Vogel 	mac->ops.insert_mac_addr = NULL;
1019ca4041bSJack F Vogel 	mac->ops.set_vmdq = NULL;
1025b7f4cedSJack F Vogel 	mac->ops.clear_vmdq = NULL;
1039ca4041bSJack F Vogel 	mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic;
1049ca4041bSJack F Vogel 	mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic;
1059ca4041bSJack F Vogel 	mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic;
1069ca4041bSJack F Vogel 	mac->ops.enable_mc = &ixgbe_enable_mc_generic;
1079ca4041bSJack F Vogel 	mac->ops.disable_mc = &ixgbe_disable_mc_generic;
1085b7f4cedSJack F Vogel 	mac->ops.clear_vfta = NULL;
1095b7f4cedSJack F Vogel 	mac->ops.set_vfta = NULL;
1105b7f4cedSJack F Vogel 	mac->ops.init_uta_tables = NULL;
1119ca4041bSJack F Vogel 
1120ac6dfecSJack F Vogel 	/* Flow Control */
1130ac6dfecSJack F Vogel 	mac->ops.fc_enable = &ixgbe_fc_enable_generic;
1149ca4041bSJack F Vogel 
1159ca4041bSJack F Vogel 	/* Link */
1169ca4041bSJack F Vogel 	mac->ops.get_link_capabilities = NULL;
1179ca4041bSJack F Vogel 	mac->ops.setup_link = NULL;
1189ca4041bSJack F Vogel 	mac->ops.setup_link_speed = NULL;
1199ca4041bSJack F Vogel 	mac->ops.check_link = NULL;
12013705f88SJack F Vogel 
12113705f88SJack F Vogel 	return IXGBE_SUCCESS;
12213705f88SJack F Vogel }
12313705f88SJack F Vogel 
12413705f88SJack F Vogel /**
1259ca4041bSJack F Vogel  *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
12613705f88SJack F Vogel  *  @hw: pointer to hardware structure
12713705f88SJack F Vogel  *
12813705f88SJack F Vogel  *  Starts the hardware by filling the bus info structure and media type, clears
12913705f88SJack F Vogel  *  all on chip counters, initializes receive address registers, multicast
13013705f88SJack F Vogel  *  table, VLAN filter table, calls routine to set up link and flow control
13113705f88SJack F Vogel  *  settings, and leaves transmit and receive units disabled and uninitialized
13213705f88SJack F Vogel  **/
13313705f88SJack F Vogel s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
13413705f88SJack F Vogel {
13513705f88SJack F Vogel 	u32 ctrl_ext;
1360ac6dfecSJack F Vogel 	s32 ret_val = IXGBE_SUCCESS;
13713705f88SJack F Vogel 
13813705f88SJack F Vogel 	/* Set the media type */
1399ca4041bSJack F Vogel 	hw->phy.media_type = hw->mac.ops.get_media_type(hw);
14013705f88SJack F Vogel 
1410ac6dfecSJack F Vogel 	/* PHY ops initialization must be done in reset_hw() */
14213705f88SJack F Vogel 
14313705f88SJack F Vogel 	/* Clear the VLAN filter table */
1449ca4041bSJack F Vogel 	hw->mac.ops.clear_vfta(hw);
14513705f88SJack F Vogel 
14613705f88SJack F Vogel 	/* Clear statistics registers */
1479ca4041bSJack F Vogel 	hw->mac.ops.clear_hw_cntrs(hw);
14813705f88SJack F Vogel 
14913705f88SJack F Vogel 	/* Set No Snoop Disable */
15013705f88SJack F Vogel 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
15113705f88SJack F Vogel 	ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
15213705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
1539ca4041bSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
15413705f88SJack F Vogel 
1550ac6dfecSJack F Vogel 	/* Setup flow control */
1560ac6dfecSJack F Vogel 	ixgbe_setup_fc(hw, 0);
1570ac6dfecSJack F Vogel 
15813705f88SJack F Vogel 	/* Clear adapter stopped flag */
15913705f88SJack F Vogel 	hw->adapter_stopped = FALSE;
16013705f88SJack F Vogel 
1610ac6dfecSJack F Vogel 	return ret_val;
16213705f88SJack F Vogel }
16313705f88SJack F Vogel 
16413705f88SJack F Vogel /**
16513705f88SJack F Vogel  *  ixgbe_init_hw_generic - Generic hardware initialization
16613705f88SJack F Vogel  *  @hw: pointer to hardware structure
16713705f88SJack F Vogel  *
1689ca4041bSJack F Vogel  *  Initialize the hardware by resetting the hardware, filling the bus info
16913705f88SJack F Vogel  *  structure and media type, clears all on chip counters, initializes receive
17013705f88SJack F Vogel  *  address registers, multicast table, VLAN filter table, calls routine to set
17113705f88SJack F Vogel  *  up link and flow control settings, and leaves transmit and receive units
17213705f88SJack F Vogel  *  disabled and uninitialized
17313705f88SJack F Vogel  **/
17413705f88SJack F Vogel s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
17513705f88SJack F Vogel {
1760ac6dfecSJack F Vogel 	s32 status = IXGBE_SUCCESS;
1770ac6dfecSJack F Vogel 
17813705f88SJack F Vogel 	/* Reset the hardware */
1790ac6dfecSJack F Vogel 	status = hw->mac.ops.reset_hw(hw);
18013705f88SJack F Vogel 
1810ac6dfecSJack F Vogel 	if (status == IXGBE_SUCCESS) {
18213705f88SJack F Vogel 		/* Start the HW */
1830ac6dfecSJack F Vogel 		status = hw->mac.ops.start_hw(hw);
1840ac6dfecSJack F Vogel 	}
18513705f88SJack F Vogel 
1860ac6dfecSJack F Vogel 	return status;
18713705f88SJack F Vogel }
18813705f88SJack F Vogel 
18913705f88SJack F Vogel /**
19013705f88SJack F Vogel  *  ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
19113705f88SJack F Vogel  *  @hw: pointer to hardware structure
19213705f88SJack F Vogel  *
19313705f88SJack F Vogel  *  Clears all hardware statistics counters by reading them from the hardware
19413705f88SJack F Vogel  *  Statistics counters are clear on read.
19513705f88SJack F Vogel  **/
19613705f88SJack F Vogel s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
19713705f88SJack F Vogel {
19813705f88SJack F Vogel 	u16 i = 0;
19913705f88SJack F Vogel 
20013705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_CRCERRS);
20113705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_ILLERRC);
20213705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_ERRBC);
20313705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MSPDC);
20413705f88SJack F Vogel 	for (i = 0; i < 8; i++)
20513705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_MPC(i));
20613705f88SJack F Vogel 
20713705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MLFC);
20813705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MRFC);
20913705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_RLEC);
21013705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_LXONTXC);
21113705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
2120ac6dfecSJack F Vogel 	if (hw->mac.type >= ixgbe_mac_82599EB) {
2130ac6dfecSJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
2140ac6dfecSJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
2150ac6dfecSJack F Vogel 	} else {
2161b6e0dbaSJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_LXONRXC);
21713705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
2180ac6dfecSJack F Vogel 	}
21913705f88SJack F Vogel 
22013705f88SJack F Vogel 	for (i = 0; i < 8; i++) {
22113705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
22213705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
2230ac6dfecSJack F Vogel 		if (hw->mac.type >= ixgbe_mac_82599EB) {
2240ac6dfecSJack F Vogel 			IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
2250ac6dfecSJack F Vogel 			IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
2260ac6dfecSJack F Vogel 		} else {
2271b6e0dbaSJack F Vogel 			IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
22813705f88SJack F Vogel 			IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
22913705f88SJack F Vogel 		}
2300ac6dfecSJack F Vogel 	}
2310ac6dfecSJack F Vogel 	if (hw->mac.type >= ixgbe_mac_82599EB)
2320ac6dfecSJack F Vogel 		for (i = 0; i < 8; i++)
2330ac6dfecSJack F Vogel 			IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
23413705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PRC64);
23513705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PRC127);
23613705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PRC255);
23713705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PRC511);
23813705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PRC1023);
23913705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PRC1522);
24013705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_GPRC);
24113705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_BPRC);
24213705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MPRC);
24313705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_GPTC);
24413705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_GORCL);
24513705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_GORCH);
24613705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_GOTCL);
24713705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_GOTCH);
24813705f88SJack F Vogel 	for (i = 0; i < 8; i++)
24913705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_RNBC(i));
25013705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_RUC);
25113705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_RFC);
25213705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_ROC);
25313705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_RJC);
25413705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MNGPRC);
25513705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MNGPDC);
25613705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MNGPTC);
25713705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_TORL);
25813705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_TORH);
25913705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_TPR);
26013705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_TPT);
26113705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PTC64);
26213705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PTC127);
26313705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PTC255);
26413705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PTC511);
26513705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PTC1023);
26613705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_PTC1522);
26713705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_MPTC);
26813705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_BPTC);
26913705f88SJack F Vogel 	for (i = 0; i < 16; i++) {
27013705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_QPRC(i));
27113705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_QBRC(i));
27213705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_QPTC(i));
27313705f88SJack F Vogel 		IXGBE_READ_REG(hw, IXGBE_QBTC(i));
27413705f88SJack F Vogel 	}
27513705f88SJack F Vogel 
27613705f88SJack F Vogel 	return IXGBE_SUCCESS;
27713705f88SJack F Vogel }
27813705f88SJack F Vogel 
27913705f88SJack F Vogel /**
2801b6e0dbaSJack F Vogel  *  ixgbe_read_pba_num_generic - Reads part number from EEPROM
2819ca4041bSJack F Vogel  *  @hw: pointer to hardware structure
2829ca4041bSJack F Vogel  *  @pba_num: stores the part number from the EEPROM
2839ca4041bSJack F Vogel  *
2849ca4041bSJack F Vogel  *  Reads the part number from the EEPROM.
2859ca4041bSJack F Vogel  **/
2869ca4041bSJack F Vogel s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
2879ca4041bSJack F Vogel {
2889ca4041bSJack F Vogel 	s32 ret_val;
2899ca4041bSJack F Vogel 	u16 data;
2909ca4041bSJack F Vogel 
2919ca4041bSJack F Vogel 	DEBUGFUNC("ixgbe_read_pba_num_generic");
2929ca4041bSJack F Vogel 
2939ca4041bSJack F Vogel 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
2949ca4041bSJack F Vogel 	if (ret_val) {
2959ca4041bSJack F Vogel 		DEBUGOUT("NVM Read Error\n");
2969ca4041bSJack F Vogel 		return ret_val;
2979ca4041bSJack F Vogel 	}
2989ca4041bSJack F Vogel 	*pba_num = (u32)(data << 16);
2999ca4041bSJack F Vogel 
3009ca4041bSJack F Vogel 	ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
3019ca4041bSJack F Vogel 	if (ret_val) {
3029ca4041bSJack F Vogel 		DEBUGOUT("NVM Read Error\n");
3039ca4041bSJack F Vogel 		return ret_val;
3049ca4041bSJack F Vogel 	}
3059ca4041bSJack F Vogel 	*pba_num |= data;
3069ca4041bSJack F Vogel 
3079ca4041bSJack F Vogel 	return IXGBE_SUCCESS;
3089ca4041bSJack F Vogel }
3099ca4041bSJack F Vogel 
3109ca4041bSJack F Vogel /**
31113705f88SJack F Vogel  *  ixgbe_get_mac_addr_generic - Generic get MAC address
31213705f88SJack F Vogel  *  @hw: pointer to hardware structure
31313705f88SJack F Vogel  *  @mac_addr: Adapter MAC address
31413705f88SJack F Vogel  *
31513705f88SJack F Vogel  *  Reads the adapter's MAC address from first Receive Address Register (RAR0)
31613705f88SJack F Vogel  *  A reset of the adapter must be performed prior to calling this function
31713705f88SJack F Vogel  *  in order for the MAC address to have been loaded from the EEPROM into RAR0
31813705f88SJack F Vogel  **/
31913705f88SJack F Vogel s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
32013705f88SJack F Vogel {
32113705f88SJack F Vogel 	u32 rar_high;
32213705f88SJack F Vogel 	u32 rar_low;
32313705f88SJack F Vogel 	u16 i;
32413705f88SJack F Vogel 
32513705f88SJack F Vogel 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0));
32613705f88SJack F Vogel 	rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0));
32713705f88SJack F Vogel 
32813705f88SJack F Vogel 	for (i = 0; i < 4; i++)
32913705f88SJack F Vogel 		mac_addr[i] = (u8)(rar_low >> (i*8));
33013705f88SJack F Vogel 
33113705f88SJack F Vogel 	for (i = 0; i < 2; i++)
33213705f88SJack F Vogel 		mac_addr[i+4] = (u8)(rar_high >> (i*8));
33313705f88SJack F Vogel 
33413705f88SJack F Vogel 	return IXGBE_SUCCESS;
33513705f88SJack F Vogel }
33613705f88SJack F Vogel 
33713705f88SJack F Vogel /**
33813705f88SJack F Vogel  *  ixgbe_get_bus_info_generic - Generic set PCI bus info
33913705f88SJack F Vogel  *  @hw: pointer to hardware structure
34013705f88SJack F Vogel  *
34113705f88SJack F Vogel  *  Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure
34213705f88SJack F Vogel  **/
34313705f88SJack F Vogel s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
34413705f88SJack F Vogel {
3451b6e0dbaSJack F Vogel 	struct ixgbe_mac_info *mac = &hw->mac;
34613705f88SJack F Vogel 	u16 link_status;
34713705f88SJack F Vogel 
34813705f88SJack F Vogel 	hw->bus.type = ixgbe_bus_type_pci_express;
34913705f88SJack F Vogel 
35013705f88SJack F Vogel 	/* Get the negotiated link width and speed from PCI config space */
35113705f88SJack F Vogel 	link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS);
35213705f88SJack F Vogel 
35313705f88SJack F Vogel 	switch (link_status & IXGBE_PCI_LINK_WIDTH) {
35413705f88SJack F Vogel 	case IXGBE_PCI_LINK_WIDTH_1:
35513705f88SJack F Vogel 		hw->bus.width = ixgbe_bus_width_pcie_x1;
35613705f88SJack F Vogel 		break;
35713705f88SJack F Vogel 	case IXGBE_PCI_LINK_WIDTH_2:
35813705f88SJack F Vogel 		hw->bus.width = ixgbe_bus_width_pcie_x2;
35913705f88SJack F Vogel 		break;
36013705f88SJack F Vogel 	case IXGBE_PCI_LINK_WIDTH_4:
36113705f88SJack F Vogel 		hw->bus.width = ixgbe_bus_width_pcie_x4;
36213705f88SJack F Vogel 		break;
36313705f88SJack F Vogel 	case IXGBE_PCI_LINK_WIDTH_8:
36413705f88SJack F Vogel 		hw->bus.width = ixgbe_bus_width_pcie_x8;
36513705f88SJack F Vogel 		break;
36613705f88SJack F Vogel 	default:
36713705f88SJack F Vogel 		hw->bus.width = ixgbe_bus_width_unknown;
36813705f88SJack F Vogel 		break;
36913705f88SJack F Vogel 	}
37013705f88SJack F Vogel 
37113705f88SJack F Vogel 	switch (link_status & IXGBE_PCI_LINK_SPEED) {
37213705f88SJack F Vogel 	case IXGBE_PCI_LINK_SPEED_2500:
37313705f88SJack F Vogel 		hw->bus.speed = ixgbe_bus_speed_2500;
37413705f88SJack F Vogel 		break;
37513705f88SJack F Vogel 	case IXGBE_PCI_LINK_SPEED_5000:
37613705f88SJack F Vogel 		hw->bus.speed = ixgbe_bus_speed_5000;
37713705f88SJack F Vogel 		break;
37813705f88SJack F Vogel 	default:
37913705f88SJack F Vogel 		hw->bus.speed = ixgbe_bus_speed_unknown;
38013705f88SJack F Vogel 		break;
38113705f88SJack F Vogel 	}
38213705f88SJack F Vogel 
3831b6e0dbaSJack F Vogel 	mac->ops.set_lan_id(hw);
3841b6e0dbaSJack F Vogel 
38513705f88SJack F Vogel 	return IXGBE_SUCCESS;
38613705f88SJack F Vogel }
38713705f88SJack F Vogel 
38813705f88SJack F Vogel /**
3891b6e0dbaSJack F Vogel  *  ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
3901b6e0dbaSJack F Vogel  *  @hw: pointer to the HW structure
3911b6e0dbaSJack F Vogel  *
3921b6e0dbaSJack F Vogel  *  Determines the LAN function id by reading memory-mapped registers
3931b6e0dbaSJack F Vogel  *  and swaps the port value if requested.
3941b6e0dbaSJack F Vogel  **/
3951b6e0dbaSJack F Vogel void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
3961b6e0dbaSJack F Vogel {
3971b6e0dbaSJack F Vogel 	struct ixgbe_bus_info *bus = &hw->bus;
3981b6e0dbaSJack F Vogel 	u32 reg;
3991b6e0dbaSJack F Vogel 
4001b6e0dbaSJack F Vogel 	reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
4011b6e0dbaSJack F Vogel 	bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
4020ac6dfecSJack F Vogel 	bus->lan_id = bus->func;
4031b6e0dbaSJack F Vogel 
4041b6e0dbaSJack F Vogel 	/* check for a port swap */
4051b6e0dbaSJack F Vogel 	reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
4061b6e0dbaSJack F Vogel 	if (reg & IXGBE_FACTPS_LFS)
4071b6e0dbaSJack F Vogel 		bus->func ^= 0x1;
4081b6e0dbaSJack F Vogel }
4091b6e0dbaSJack F Vogel 
4101b6e0dbaSJack F Vogel /**
4119ca4041bSJack F Vogel  *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
41213705f88SJack F Vogel  *  @hw: pointer to hardware structure
41313705f88SJack F Vogel  *
41413705f88SJack F Vogel  *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
41513705f88SJack F Vogel  *  disables transmit and receive units. The adapter_stopped flag is used by
41613705f88SJack F Vogel  *  the shared code and drivers to determine if the adapter is in a stopped
41713705f88SJack F Vogel  *  state and should not touch the hardware.
41813705f88SJack F Vogel  **/
41913705f88SJack F Vogel s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
42013705f88SJack F Vogel {
42113705f88SJack F Vogel 	u32 number_of_queues;
42213705f88SJack F Vogel 	u32 reg_val;
42313705f88SJack F Vogel 	u16 i;
42413705f88SJack F Vogel 
42513705f88SJack F Vogel 	/*
42613705f88SJack F Vogel 	 * Set the adapter_stopped flag so other driver functions stop touching
42713705f88SJack F Vogel 	 * the hardware
42813705f88SJack F Vogel 	 */
42913705f88SJack F Vogel 	hw->adapter_stopped = TRUE;
43013705f88SJack F Vogel 
43113705f88SJack F Vogel 	/* Disable the receive unit */
43213705f88SJack F Vogel 	reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
43313705f88SJack F Vogel 	reg_val &= ~(IXGBE_RXCTRL_RXEN);
43413705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
4359ca4041bSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
43613705f88SJack F Vogel 	msec_delay(2);
43713705f88SJack F Vogel 
43813705f88SJack F Vogel 	/* Clear interrupt mask to stop from interrupts being generated */
43913705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
44013705f88SJack F Vogel 
44113705f88SJack F Vogel 	/* Clear any pending interrupts */
44213705f88SJack F Vogel 	IXGBE_READ_REG(hw, IXGBE_EICR);
44313705f88SJack F Vogel 
44413705f88SJack F Vogel 	/* Disable the transmit unit.  Each queue must be disabled. */
4459ca4041bSJack F Vogel 	number_of_queues = hw->mac.max_tx_queues;
44613705f88SJack F Vogel 	for (i = 0; i < number_of_queues; i++) {
44713705f88SJack F Vogel 		reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
44813705f88SJack F Vogel 		if (reg_val & IXGBE_TXDCTL_ENABLE) {
44913705f88SJack F Vogel 			reg_val &= ~IXGBE_TXDCTL_ENABLE;
45013705f88SJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), reg_val);
45113705f88SJack F Vogel 		}
45213705f88SJack F Vogel 	}
45313705f88SJack F Vogel 
4549ca4041bSJack F Vogel 	/*
4559ca4041bSJack F Vogel 	 * Prevent the PCI-E bus from from hanging by disabling PCI-E master
4569ca4041bSJack F Vogel 	 * access and verify no pending requests
4579ca4041bSJack F Vogel 	 */
4581b6e0dbaSJack F Vogel 	if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS)
4599ca4041bSJack F Vogel 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
4609ca4041bSJack F Vogel 
46113705f88SJack F Vogel 	return IXGBE_SUCCESS;
46213705f88SJack F Vogel }
46313705f88SJack F Vogel 
46413705f88SJack F Vogel /**
46513705f88SJack F Vogel  *  ixgbe_led_on_generic - Turns on the software controllable LEDs.
46613705f88SJack F Vogel  *  @hw: pointer to hardware structure
46713705f88SJack F Vogel  *  @index: led number to turn on
46813705f88SJack F Vogel  **/
46913705f88SJack F Vogel s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
47013705f88SJack F Vogel {
47113705f88SJack F Vogel 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
47213705f88SJack F Vogel 
47313705f88SJack F Vogel 	/* To turn on the LED, set mode to ON. */
47413705f88SJack F Vogel 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
47513705f88SJack F Vogel 	led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
47613705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
4779ca4041bSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
47813705f88SJack F Vogel 
47913705f88SJack F Vogel 	return IXGBE_SUCCESS;
48013705f88SJack F Vogel }
48113705f88SJack F Vogel 
48213705f88SJack F Vogel /**
48313705f88SJack F Vogel  *  ixgbe_led_off_generic - Turns off the software controllable LEDs.
48413705f88SJack F Vogel  *  @hw: pointer to hardware structure
48513705f88SJack F Vogel  *  @index: led number to turn off
48613705f88SJack F Vogel  **/
48713705f88SJack F Vogel s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
48813705f88SJack F Vogel {
48913705f88SJack F Vogel 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
49013705f88SJack F Vogel 
49113705f88SJack F Vogel 	/* To turn off the LED, set mode to OFF. */
49213705f88SJack F Vogel 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
49313705f88SJack F Vogel 	led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
49413705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
4959ca4041bSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
49613705f88SJack F Vogel 
49713705f88SJack F Vogel 	return IXGBE_SUCCESS;
49813705f88SJack F Vogel }
49913705f88SJack F Vogel 
50013705f88SJack F Vogel /**
50113705f88SJack F Vogel  *  ixgbe_init_eeprom_params_generic - Initialize EEPROM params
50213705f88SJack F Vogel  *  @hw: pointer to hardware structure
50313705f88SJack F Vogel  *
50413705f88SJack F Vogel  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
50513705f88SJack F Vogel  *  ixgbe_hw struct in order to set up EEPROM access.
50613705f88SJack F Vogel  **/
50713705f88SJack F Vogel s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
50813705f88SJack F Vogel {
50913705f88SJack F Vogel 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
51013705f88SJack F Vogel 	u32 eec;
51113705f88SJack F Vogel 	u16 eeprom_size;
51213705f88SJack F Vogel 
51313705f88SJack F Vogel 	if (eeprom->type == ixgbe_eeprom_uninitialized) {
51413705f88SJack F Vogel 		eeprom->type = ixgbe_eeprom_none;
5155b7f4cedSJack F Vogel 		/* Set default semaphore delay to 10ms which is a well
5165b7f4cedSJack F Vogel 		 * tested value */
5175b7f4cedSJack F Vogel 		eeprom->semaphore_delay = 10;
51813705f88SJack F Vogel 
51913705f88SJack F Vogel 		/*
52013705f88SJack F Vogel 		 * Check for EEPROM present first.
52113705f88SJack F Vogel 		 * If not present leave as none
52213705f88SJack F Vogel 		 */
52313705f88SJack F Vogel 		eec = IXGBE_READ_REG(hw, IXGBE_EEC);
52413705f88SJack F Vogel 		if (eec & IXGBE_EEC_PRES) {
52513705f88SJack F Vogel 			eeprom->type = ixgbe_eeprom_spi;
52613705f88SJack F Vogel 
52713705f88SJack F Vogel 			/*
52813705f88SJack F Vogel 			 * SPI EEPROM is assumed here.  This code would need to
52913705f88SJack F Vogel 			 * change if a future EEPROM is not SPI.
53013705f88SJack F Vogel 			 */
53113705f88SJack F Vogel 			eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
53213705f88SJack F Vogel 			                    IXGBE_EEC_SIZE_SHIFT);
53313705f88SJack F Vogel 			eeprom->word_size = 1 << (eeprom_size +
53413705f88SJack F Vogel 			                         IXGBE_EEPROM_WORD_SIZE_SHIFT);
53513705f88SJack F Vogel 		}
53613705f88SJack F Vogel 
53713705f88SJack F Vogel 		if (eec & IXGBE_EEC_ADDR_SIZE)
53813705f88SJack F Vogel 			eeprom->address_bits = 16;
53913705f88SJack F Vogel 		else
54013705f88SJack F Vogel 			eeprom->address_bits = 8;
54113705f88SJack F Vogel 		DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: "
54213705f88SJack F Vogel 		          "%d\n", eeprom->type, eeprom->word_size,
54313705f88SJack F Vogel 		          eeprom->address_bits);
54413705f88SJack F Vogel 	}
54513705f88SJack F Vogel 
54613705f88SJack F Vogel 	return IXGBE_SUCCESS;
54713705f88SJack F Vogel }
54813705f88SJack F Vogel 
54913705f88SJack F Vogel /**
55013705f88SJack F Vogel  *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
55113705f88SJack F Vogel  *  @hw: pointer to hardware structure
55213705f88SJack F Vogel  *  @offset: offset within the EEPROM to be written to
55313705f88SJack F Vogel  *  @data: 16 bit word to be written to the EEPROM
55413705f88SJack F Vogel  *
55513705f88SJack F Vogel  *  If ixgbe_eeprom_update_checksum is not called after this function, the
55613705f88SJack F Vogel  *  EEPROM will most likely contain an invalid checksum.
55713705f88SJack F Vogel  **/
55813705f88SJack F Vogel s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
55913705f88SJack F Vogel {
56013705f88SJack F Vogel 	s32 status;
56113705f88SJack F Vogel 	u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
56213705f88SJack F Vogel 
5639ca4041bSJack F Vogel 	hw->eeprom.ops.init_params(hw);
5649ca4041bSJack F Vogel 
5659ca4041bSJack F Vogel 	if (offset >= hw->eeprom.word_size) {
5669ca4041bSJack F Vogel 		status = IXGBE_ERR_EEPROM;
5679ca4041bSJack F Vogel 		goto out;
5689ca4041bSJack F Vogel 	}
5699ca4041bSJack F Vogel 
57013705f88SJack F Vogel 	/* Prepare the EEPROM for writing  */
57113705f88SJack F Vogel 	status = ixgbe_acquire_eeprom(hw);
57213705f88SJack F Vogel 
57313705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
57413705f88SJack F Vogel 		if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) {
57513705f88SJack F Vogel 			ixgbe_release_eeprom(hw);
57613705f88SJack F Vogel 			status = IXGBE_ERR_EEPROM;
57713705f88SJack F Vogel 		}
57813705f88SJack F Vogel 	}
57913705f88SJack F Vogel 
58013705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
58113705f88SJack F Vogel 		ixgbe_standby_eeprom(hw);
58213705f88SJack F Vogel 
58313705f88SJack F Vogel 		/*  Send the WRITE ENABLE command (8 bit opcode )  */
58413705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
58513705f88SJack F Vogel 		                            IXGBE_EEPROM_OPCODE_BITS);
58613705f88SJack F Vogel 
58713705f88SJack F Vogel 		ixgbe_standby_eeprom(hw);
58813705f88SJack F Vogel 
58913705f88SJack F Vogel 		/*
59013705f88SJack F Vogel 		 * Some SPI eeproms use the 8th address bit embedded in the
59113705f88SJack F Vogel 		 * opcode
59213705f88SJack F Vogel 		 */
59313705f88SJack F Vogel 		if ((hw->eeprom.address_bits == 8) && (offset >= 128))
59413705f88SJack F Vogel 			write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
59513705f88SJack F Vogel 
59613705f88SJack F Vogel 		/* Send the Write command (8-bit opcode + addr) */
59713705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, write_opcode,
59813705f88SJack F Vogel 		                            IXGBE_EEPROM_OPCODE_BITS);
59913705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
60013705f88SJack F Vogel 		                            hw->eeprom.address_bits);
60113705f88SJack F Vogel 
60213705f88SJack F Vogel 		/* Send the data */
60313705f88SJack F Vogel 		data = (data >> 8) | (data << 8);
60413705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, data, 16);
60513705f88SJack F Vogel 		ixgbe_standby_eeprom(hw);
60613705f88SJack F Vogel 
60713705f88SJack F Vogel 		/* Done with writing - release the EEPROM */
60813705f88SJack F Vogel 		ixgbe_release_eeprom(hw);
60913705f88SJack F Vogel 	}
61013705f88SJack F Vogel 
6119ca4041bSJack F Vogel out:
61213705f88SJack F Vogel 	return status;
61313705f88SJack F Vogel }
61413705f88SJack F Vogel 
61513705f88SJack F Vogel /**
61613705f88SJack F Vogel  *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
61713705f88SJack F Vogel  *  @hw: pointer to hardware structure
61813705f88SJack F Vogel  *  @offset: offset within the EEPROM to be read
61913705f88SJack F Vogel  *  @data: read 16 bit value from EEPROM
62013705f88SJack F Vogel  *
62113705f88SJack F Vogel  *  Reads 16 bit value from EEPROM through bit-bang method
62213705f88SJack F Vogel  **/
62313705f88SJack F Vogel s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
62413705f88SJack F Vogel                                        u16 *data)
62513705f88SJack F Vogel {
62613705f88SJack F Vogel 	s32 status;
62713705f88SJack F Vogel 	u16 word_in;
62813705f88SJack F Vogel 	u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
62913705f88SJack F Vogel 
6309ca4041bSJack F Vogel 	hw->eeprom.ops.init_params(hw);
6319ca4041bSJack F Vogel 
6329ca4041bSJack F Vogel 	if (offset >= hw->eeprom.word_size) {
6339ca4041bSJack F Vogel 		status = IXGBE_ERR_EEPROM;
6349ca4041bSJack F Vogel 		goto out;
6359ca4041bSJack F Vogel 	}
6369ca4041bSJack F Vogel 
63713705f88SJack F Vogel 	/* Prepare the EEPROM for reading  */
63813705f88SJack F Vogel 	status = ixgbe_acquire_eeprom(hw);
63913705f88SJack F Vogel 
64013705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
64113705f88SJack F Vogel 		if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) {
64213705f88SJack F Vogel 			ixgbe_release_eeprom(hw);
64313705f88SJack F Vogel 			status = IXGBE_ERR_EEPROM;
64413705f88SJack F Vogel 		}
64513705f88SJack F Vogel 	}
64613705f88SJack F Vogel 
64713705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
64813705f88SJack F Vogel 		ixgbe_standby_eeprom(hw);
64913705f88SJack F Vogel 
65013705f88SJack F Vogel 		/*
65113705f88SJack F Vogel 		 * Some SPI eeproms use the 8th address bit embedded in the
65213705f88SJack F Vogel 		 * opcode
65313705f88SJack F Vogel 		 */
65413705f88SJack F Vogel 		if ((hw->eeprom.address_bits == 8) && (offset >= 128))
65513705f88SJack F Vogel 			read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
65613705f88SJack F Vogel 
65713705f88SJack F Vogel 		/* Send the READ command (opcode + addr) */
65813705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, read_opcode,
65913705f88SJack F Vogel 		                            IXGBE_EEPROM_OPCODE_BITS);
66013705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
66113705f88SJack F Vogel 		                            hw->eeprom.address_bits);
66213705f88SJack F Vogel 
66313705f88SJack F Vogel 		/* Read the data. */
66413705f88SJack F Vogel 		word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
66513705f88SJack F Vogel 		*data = (word_in >> 8) | (word_in << 8);
66613705f88SJack F Vogel 
66713705f88SJack F Vogel 		/* End this read operation */
66813705f88SJack F Vogel 		ixgbe_release_eeprom(hw);
66913705f88SJack F Vogel 	}
67013705f88SJack F Vogel 
6719ca4041bSJack F Vogel out:
67213705f88SJack F Vogel 	return status;
67313705f88SJack F Vogel }
67413705f88SJack F Vogel 
67513705f88SJack F Vogel /**
67613705f88SJack F Vogel  *  ixgbe_read_eeprom_generic - Read EEPROM word using EERD
67713705f88SJack F Vogel  *  @hw: pointer to hardware structure
67813705f88SJack F Vogel  *  @offset: offset of  word in the EEPROM to read
67913705f88SJack F Vogel  *  @data: word read from the EEPROM
68013705f88SJack F Vogel  *
68113705f88SJack F Vogel  *  Reads a 16 bit word from the EEPROM using the EERD register.
68213705f88SJack F Vogel  **/
68313705f88SJack F Vogel s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
68413705f88SJack F Vogel {
68513705f88SJack F Vogel 	u32 eerd;
68613705f88SJack F Vogel 	s32 status;
68713705f88SJack F Vogel 
6889ca4041bSJack F Vogel 	hw->eeprom.ops.init_params(hw);
6899ca4041bSJack F Vogel 
6909ca4041bSJack F Vogel 	if (offset >= hw->eeprom.word_size) {
6919ca4041bSJack F Vogel 		status = IXGBE_ERR_EEPROM;
6929ca4041bSJack F Vogel 		goto out;
6939ca4041bSJack F Vogel 	}
6949ca4041bSJack F Vogel 
69513705f88SJack F Vogel 	eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) +
69613705f88SJack F Vogel 	       IXGBE_EEPROM_READ_REG_START;
69713705f88SJack F Vogel 
69813705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
69913705f88SJack F Vogel 	status = ixgbe_poll_eeprom_eerd_done(hw);
70013705f88SJack F Vogel 
70113705f88SJack F Vogel 	if (status == IXGBE_SUCCESS)
70213705f88SJack F Vogel 		*data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
70313705f88SJack F Vogel 		         IXGBE_EEPROM_READ_REG_DATA);
70413705f88SJack F Vogel 	else
70513705f88SJack F Vogel 		DEBUGOUT("Eeprom read timed out\n");
70613705f88SJack F Vogel 
7079ca4041bSJack F Vogel out:
70813705f88SJack F Vogel 	return status;
70913705f88SJack F Vogel }
71013705f88SJack F Vogel 
71113705f88SJack F Vogel /**
71213705f88SJack F Vogel  *  ixgbe_poll_eeprom_eerd_done - Poll EERD status
71313705f88SJack F Vogel  *  @hw: pointer to hardware structure
71413705f88SJack F Vogel  *
71513705f88SJack F Vogel  *  Polls the status bit (bit 1) of the EERD to determine when the read is done.
71613705f88SJack F Vogel  **/
71713705f88SJack F Vogel static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw)
71813705f88SJack F Vogel {
71913705f88SJack F Vogel 	u32 i;
72013705f88SJack F Vogel 	u32 reg;
72113705f88SJack F Vogel 	s32 status = IXGBE_ERR_EEPROM;
72213705f88SJack F Vogel 
72313705f88SJack F Vogel 	for (i = 0; i < IXGBE_EERD_ATTEMPTS; i++) {
72413705f88SJack F Vogel 		reg = IXGBE_READ_REG(hw, IXGBE_EERD);
72513705f88SJack F Vogel 		if (reg & IXGBE_EEPROM_READ_REG_DONE) {
72613705f88SJack F Vogel 			status = IXGBE_SUCCESS;
72713705f88SJack F Vogel 			break;
72813705f88SJack F Vogel 		}
72913705f88SJack F Vogel 		usec_delay(5);
73013705f88SJack F Vogel 	}
73113705f88SJack F Vogel 	return status;
73213705f88SJack F Vogel }
73313705f88SJack F Vogel 
73413705f88SJack F Vogel /**
73513705f88SJack F Vogel  *  ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
73613705f88SJack F Vogel  *  @hw: pointer to hardware structure
73713705f88SJack F Vogel  *
73813705f88SJack F Vogel  *  Prepares EEPROM for access using bit-bang method. This function should
73913705f88SJack F Vogel  *  be called before issuing a command to the EEPROM.
74013705f88SJack F Vogel  **/
74113705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
74213705f88SJack F Vogel {
74313705f88SJack F Vogel 	s32 status = IXGBE_SUCCESS;
74413705f88SJack F Vogel 	u32 eec;
74513705f88SJack F Vogel 	u32 i;
74613705f88SJack F Vogel 
74713705f88SJack F Vogel 	if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS)
74813705f88SJack F Vogel 		status = IXGBE_ERR_SWFW_SYNC;
74913705f88SJack F Vogel 
75013705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
75113705f88SJack F Vogel 		eec = IXGBE_READ_REG(hw, IXGBE_EEC);
75213705f88SJack F Vogel 
75313705f88SJack F Vogel 		/* Request EEPROM Access */
75413705f88SJack F Vogel 		eec |= IXGBE_EEC_REQ;
75513705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
75613705f88SJack F Vogel 
75713705f88SJack F Vogel 		for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
75813705f88SJack F Vogel 			eec = IXGBE_READ_REG(hw, IXGBE_EEC);
75913705f88SJack F Vogel 			if (eec & IXGBE_EEC_GNT)
76013705f88SJack F Vogel 				break;
76113705f88SJack F Vogel 			usec_delay(5);
76213705f88SJack F Vogel 		}
76313705f88SJack F Vogel 
7649ca4041bSJack F Vogel 		/* Release if grant not acquired */
76513705f88SJack F Vogel 		if (!(eec & IXGBE_EEC_GNT)) {
76613705f88SJack F Vogel 			eec &= ~IXGBE_EEC_REQ;
76713705f88SJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
76813705f88SJack F Vogel 			DEBUGOUT("Could not acquire EEPROM grant\n");
76913705f88SJack F Vogel 
77013705f88SJack F Vogel 			ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
77113705f88SJack F Vogel 			status = IXGBE_ERR_EEPROM;
77213705f88SJack F Vogel 		}
77313705f88SJack F Vogel 	}
77413705f88SJack F Vogel 
77513705f88SJack F Vogel 	/* Setup EEPROM for Read/Write */
77613705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
77713705f88SJack F Vogel 		/* Clear CS and SK */
77813705f88SJack F Vogel 		eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
77913705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
78013705f88SJack F Vogel 		IXGBE_WRITE_FLUSH(hw);
78113705f88SJack F Vogel 		usec_delay(1);
78213705f88SJack F Vogel 	}
78313705f88SJack F Vogel 	return status;
78413705f88SJack F Vogel }
78513705f88SJack F Vogel 
78613705f88SJack F Vogel /**
78713705f88SJack F Vogel  *  ixgbe_get_eeprom_semaphore - Get hardware semaphore
78813705f88SJack F Vogel  *  @hw: pointer to hardware structure
78913705f88SJack F Vogel  *
79013705f88SJack F Vogel  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
79113705f88SJack F Vogel  **/
79213705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
79313705f88SJack F Vogel {
79413705f88SJack F Vogel 	s32 status = IXGBE_ERR_EEPROM;
79513705f88SJack F Vogel 	u32 timeout;
79613705f88SJack F Vogel 	u32 i;
79713705f88SJack F Vogel 	u32 swsm;
79813705f88SJack F Vogel 
79913705f88SJack F Vogel 	/* Set timeout value based on size of EEPROM */
80013705f88SJack F Vogel 	timeout = hw->eeprom.word_size + 1;
80113705f88SJack F Vogel 
80213705f88SJack F Vogel 	/* Get SMBI software semaphore between device drivers first */
80313705f88SJack F Vogel 	for (i = 0; i < timeout; i++) {
80413705f88SJack F Vogel 		/*
80513705f88SJack F Vogel 		 * If the SMBI bit is 0 when we read it, then the bit will be
80613705f88SJack F Vogel 		 * set and we have the semaphore
80713705f88SJack F Vogel 		 */
80813705f88SJack F Vogel 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
80913705f88SJack F Vogel 		if (!(swsm & IXGBE_SWSM_SMBI)) {
81013705f88SJack F Vogel 			status = IXGBE_SUCCESS;
81113705f88SJack F Vogel 			break;
81213705f88SJack F Vogel 		}
8130ac6dfecSJack F Vogel 		usec_delay(50);
81413705f88SJack F Vogel 	}
81513705f88SJack F Vogel 
81613705f88SJack F Vogel 	/* Now get the semaphore between SW/FW through the SWESMBI bit */
81713705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
81813705f88SJack F Vogel 		for (i = 0; i < timeout; i++) {
81913705f88SJack F Vogel 			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
82013705f88SJack F Vogel 
82113705f88SJack F Vogel 			/* Set the SW EEPROM semaphore bit to request access */
82213705f88SJack F Vogel 			swsm |= IXGBE_SWSM_SWESMBI;
82313705f88SJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
82413705f88SJack F Vogel 
82513705f88SJack F Vogel 			/*
82613705f88SJack F Vogel 			 * If we set the bit successfully then we got the
82713705f88SJack F Vogel 			 * semaphore.
82813705f88SJack F Vogel 			 */
82913705f88SJack F Vogel 			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
83013705f88SJack F Vogel 			if (swsm & IXGBE_SWSM_SWESMBI)
83113705f88SJack F Vogel 				break;
83213705f88SJack F Vogel 
83313705f88SJack F Vogel 			usec_delay(50);
83413705f88SJack F Vogel 		}
83513705f88SJack F Vogel 
83613705f88SJack F Vogel 		/*
83713705f88SJack F Vogel 		 * Release semaphores and return error if SW EEPROM semaphore
83813705f88SJack F Vogel 		 * was not granted because we don't have access to the EEPROM
83913705f88SJack F Vogel 		 */
84013705f88SJack F Vogel 		if (i >= timeout) {
8410ac6dfecSJack F Vogel 			DEBUGOUT("SWESMBI Software EEPROM semaphore "
84213705f88SJack F Vogel 			         "not granted.\n");
84313705f88SJack F Vogel 			ixgbe_release_eeprom_semaphore(hw);
84413705f88SJack F Vogel 			status = IXGBE_ERR_EEPROM;
84513705f88SJack F Vogel 		}
8460ac6dfecSJack F Vogel 	} else {
8470ac6dfecSJack F Vogel 		DEBUGOUT("Software semaphore SMBI between device drivers "
8480ac6dfecSJack F Vogel 		         "not granted.\n");
84913705f88SJack F Vogel 	}
85013705f88SJack F Vogel 
85113705f88SJack F Vogel 	return status;
85213705f88SJack F Vogel }
85313705f88SJack F Vogel 
85413705f88SJack F Vogel /**
85513705f88SJack F Vogel  *  ixgbe_release_eeprom_semaphore - Release hardware semaphore
85613705f88SJack F Vogel  *  @hw: pointer to hardware structure
85713705f88SJack F Vogel  *
85813705f88SJack F Vogel  *  This function clears hardware semaphore bits.
85913705f88SJack F Vogel  **/
86013705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
86113705f88SJack F Vogel {
86213705f88SJack F Vogel 	u32 swsm;
86313705f88SJack F Vogel 
86413705f88SJack F Vogel 	swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
86513705f88SJack F Vogel 
86613705f88SJack F Vogel 	/* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
86713705f88SJack F Vogel 	swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
86813705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
8699ca4041bSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
87013705f88SJack F Vogel }
87113705f88SJack F Vogel 
87213705f88SJack F Vogel /**
87313705f88SJack F Vogel  *  ixgbe_ready_eeprom - Polls for EEPROM ready
87413705f88SJack F Vogel  *  @hw: pointer to hardware structure
87513705f88SJack F Vogel  **/
87613705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
87713705f88SJack F Vogel {
87813705f88SJack F Vogel 	s32 status = IXGBE_SUCCESS;
87913705f88SJack F Vogel 	u16 i;
88013705f88SJack F Vogel 	u8 spi_stat_reg;
88113705f88SJack F Vogel 
88213705f88SJack F Vogel 	/*
88313705f88SJack F Vogel 	 * Read "Status Register" repeatedly until the LSB is cleared.  The
88413705f88SJack F Vogel 	 * EEPROM will signal that the command has been completed by clearing
88513705f88SJack F Vogel 	 * bit 0 of the internal status register.  If it's not cleared within
88613705f88SJack F Vogel 	 * 5 milliseconds, then error out.
88713705f88SJack F Vogel 	 */
88813705f88SJack F Vogel 	for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
88913705f88SJack F Vogel 		ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
89013705f88SJack F Vogel 		                            IXGBE_EEPROM_OPCODE_BITS);
89113705f88SJack F Vogel 		spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
89213705f88SJack F Vogel 		if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
89313705f88SJack F Vogel 			break;
89413705f88SJack F Vogel 
89513705f88SJack F Vogel 		usec_delay(5);
89613705f88SJack F Vogel 		ixgbe_standby_eeprom(hw);
89713705f88SJack F Vogel 	};
89813705f88SJack F Vogel 
89913705f88SJack F Vogel 	/*
90013705f88SJack F Vogel 	 * On some parts, SPI write time could vary from 0-20mSec on 3.3V
90113705f88SJack F Vogel 	 * devices (and only 0-5mSec on 5V devices)
90213705f88SJack F Vogel 	 */
90313705f88SJack F Vogel 	if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
90413705f88SJack F Vogel 		DEBUGOUT("SPI EEPROM Status error\n");
90513705f88SJack F Vogel 		status = IXGBE_ERR_EEPROM;
90613705f88SJack F Vogel 	}
90713705f88SJack F Vogel 
90813705f88SJack F Vogel 	return status;
90913705f88SJack F Vogel }
91013705f88SJack F Vogel 
91113705f88SJack F Vogel /**
91213705f88SJack F Vogel  *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
91313705f88SJack F Vogel  *  @hw: pointer to hardware structure
91413705f88SJack F Vogel  **/
91513705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
91613705f88SJack F Vogel {
91713705f88SJack F Vogel 	u32 eec;
91813705f88SJack F Vogel 
91913705f88SJack F Vogel 	eec = IXGBE_READ_REG(hw, IXGBE_EEC);
92013705f88SJack F Vogel 
92113705f88SJack F Vogel 	/* Toggle CS to flush commands */
92213705f88SJack F Vogel 	eec |= IXGBE_EEC_CS;
92313705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
92413705f88SJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
92513705f88SJack F Vogel 	usec_delay(1);
92613705f88SJack F Vogel 	eec &= ~IXGBE_EEC_CS;
92713705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
92813705f88SJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
92913705f88SJack F Vogel 	usec_delay(1);
93013705f88SJack F Vogel }
93113705f88SJack F Vogel 
93213705f88SJack F Vogel /**
93313705f88SJack F Vogel  *  ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
93413705f88SJack F Vogel  *  @hw: pointer to hardware structure
93513705f88SJack F Vogel  *  @data: data to send to the EEPROM
93613705f88SJack F Vogel  *  @count: number of bits to shift out
93713705f88SJack F Vogel  **/
93813705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
93913705f88SJack F Vogel                                         u16 count)
94013705f88SJack F Vogel {
94113705f88SJack F Vogel 	u32 eec;
94213705f88SJack F Vogel 	u32 mask;
94313705f88SJack F Vogel 	u32 i;
94413705f88SJack F Vogel 
94513705f88SJack F Vogel 	eec = IXGBE_READ_REG(hw, IXGBE_EEC);
94613705f88SJack F Vogel 
94713705f88SJack F Vogel 	/*
94813705f88SJack F Vogel 	 * Mask is used to shift "count" bits of "data" out to the EEPROM
94913705f88SJack F Vogel 	 * one bit at a time.  Determine the starting bit based on count
95013705f88SJack F Vogel 	 */
95113705f88SJack F Vogel 	mask = 0x01 << (count - 1);
95213705f88SJack F Vogel 
95313705f88SJack F Vogel 	for (i = 0; i < count; i++) {
95413705f88SJack F Vogel 		/*
95513705f88SJack F Vogel 		 * A "1" is shifted out to the EEPROM by setting bit "DI" to a
95613705f88SJack F Vogel 		 * "1", and then raising and then lowering the clock (the SK
95713705f88SJack F Vogel 		 * bit controls the clock input to the EEPROM).  A "0" is
95813705f88SJack F Vogel 		 * shifted out to the EEPROM by setting "DI" to "0" and then
95913705f88SJack F Vogel 		 * raising and then lowering the clock.
96013705f88SJack F Vogel 		 */
96113705f88SJack F Vogel 		if (data & mask)
96213705f88SJack F Vogel 			eec |= IXGBE_EEC_DI;
96313705f88SJack F Vogel 		else
96413705f88SJack F Vogel 			eec &= ~IXGBE_EEC_DI;
96513705f88SJack F Vogel 
96613705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
96713705f88SJack F Vogel 		IXGBE_WRITE_FLUSH(hw);
96813705f88SJack F Vogel 
96913705f88SJack F Vogel 		usec_delay(1);
97013705f88SJack F Vogel 
97113705f88SJack F Vogel 		ixgbe_raise_eeprom_clk(hw, &eec);
97213705f88SJack F Vogel 		ixgbe_lower_eeprom_clk(hw, &eec);
97313705f88SJack F Vogel 
97413705f88SJack F Vogel 		/*
97513705f88SJack F Vogel 		 * Shift mask to signify next bit of data to shift in to the
97613705f88SJack F Vogel 		 * EEPROM
97713705f88SJack F Vogel 		 */
97813705f88SJack F Vogel 		mask = mask >> 1;
97913705f88SJack F Vogel 	};
98013705f88SJack F Vogel 
98113705f88SJack F Vogel 	/* We leave the "DI" bit set to "0" when we leave this routine. */
98213705f88SJack F Vogel 	eec &= ~IXGBE_EEC_DI;
98313705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
98413705f88SJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
98513705f88SJack F Vogel }
98613705f88SJack F Vogel 
98713705f88SJack F Vogel /**
98813705f88SJack F Vogel  *  ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
98913705f88SJack F Vogel  *  @hw: pointer to hardware structure
99013705f88SJack F Vogel  **/
99113705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
99213705f88SJack F Vogel {
99313705f88SJack F Vogel 	u32 eec;
99413705f88SJack F Vogel 	u32 i;
99513705f88SJack F Vogel 	u16 data = 0;
99613705f88SJack F Vogel 
99713705f88SJack F Vogel 	/*
99813705f88SJack F Vogel 	 * In order to read a register from the EEPROM, we need to shift
99913705f88SJack F Vogel 	 * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
100013705f88SJack F Vogel 	 * the clock input to the EEPROM (setting the SK bit), and then reading
100113705f88SJack F Vogel 	 * the value of the "DO" bit.  During this "shifting in" process the
100213705f88SJack F Vogel 	 * "DI" bit should always be clear.
100313705f88SJack F Vogel 	 */
100413705f88SJack F Vogel 	eec = IXGBE_READ_REG(hw, IXGBE_EEC);
100513705f88SJack F Vogel 
100613705f88SJack F Vogel 	eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
100713705f88SJack F Vogel 
100813705f88SJack F Vogel 	for (i = 0; i < count; i++) {
100913705f88SJack F Vogel 		data = data << 1;
101013705f88SJack F Vogel 		ixgbe_raise_eeprom_clk(hw, &eec);
101113705f88SJack F Vogel 
101213705f88SJack F Vogel 		eec = IXGBE_READ_REG(hw, IXGBE_EEC);
101313705f88SJack F Vogel 
101413705f88SJack F Vogel 		eec &= ~(IXGBE_EEC_DI);
101513705f88SJack F Vogel 		if (eec & IXGBE_EEC_DO)
101613705f88SJack F Vogel 			data |= 1;
101713705f88SJack F Vogel 
101813705f88SJack F Vogel 		ixgbe_lower_eeprom_clk(hw, &eec);
101913705f88SJack F Vogel 	}
102013705f88SJack F Vogel 
102113705f88SJack F Vogel 	return data;
102213705f88SJack F Vogel }
102313705f88SJack F Vogel 
102413705f88SJack F Vogel /**
102513705f88SJack F Vogel  *  ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
102613705f88SJack F Vogel  *  @hw: pointer to hardware structure
102713705f88SJack F Vogel  *  @eec: EEC register's current value
102813705f88SJack F Vogel  **/
102913705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
103013705f88SJack F Vogel {
103113705f88SJack F Vogel 	/*
103213705f88SJack F Vogel 	 * Raise the clock input to the EEPROM
103313705f88SJack F Vogel 	 * (setting the SK bit), then delay
103413705f88SJack F Vogel 	 */
103513705f88SJack F Vogel 	*eec = *eec | IXGBE_EEC_SK;
103613705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
103713705f88SJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
103813705f88SJack F Vogel 	usec_delay(1);
103913705f88SJack F Vogel }
104013705f88SJack F Vogel 
104113705f88SJack F Vogel /**
104213705f88SJack F Vogel  *  ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
104313705f88SJack F Vogel  *  @hw: pointer to hardware structure
104413705f88SJack F Vogel  *  @eecd: EECD's current value
104513705f88SJack F Vogel  **/
104613705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
104713705f88SJack F Vogel {
104813705f88SJack F Vogel 	/*
104913705f88SJack F Vogel 	 * Lower the clock input to the EEPROM (clearing the SK bit), then
105013705f88SJack F Vogel 	 * delay
105113705f88SJack F Vogel 	 */
105213705f88SJack F Vogel 	*eec = *eec & ~IXGBE_EEC_SK;
105313705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
105413705f88SJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
105513705f88SJack F Vogel 	usec_delay(1);
105613705f88SJack F Vogel }
105713705f88SJack F Vogel 
105813705f88SJack F Vogel /**
105913705f88SJack F Vogel  *  ixgbe_release_eeprom - Release EEPROM, release semaphores
106013705f88SJack F Vogel  *  @hw: pointer to hardware structure
106113705f88SJack F Vogel  **/
106213705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
106313705f88SJack F Vogel {
106413705f88SJack F Vogel 	u32 eec;
106513705f88SJack F Vogel 
106613705f88SJack F Vogel 	eec = IXGBE_READ_REG(hw, IXGBE_EEC);
106713705f88SJack F Vogel 
106813705f88SJack F Vogel 	eec |= IXGBE_EEC_CS;  /* Pull CS high */
106913705f88SJack F Vogel 	eec &= ~IXGBE_EEC_SK; /* Lower SCK */
107013705f88SJack F Vogel 
107113705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
107213705f88SJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
107313705f88SJack F Vogel 
107413705f88SJack F Vogel 	usec_delay(1);
107513705f88SJack F Vogel 
107613705f88SJack F Vogel 	/* Stop requesting EEPROM access */
107713705f88SJack F Vogel 	eec &= ~IXGBE_EEC_REQ;
107813705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
107913705f88SJack F Vogel 
108013705f88SJack F Vogel 	ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
108113705f88SJack F Vogel }
108213705f88SJack F Vogel 
108313705f88SJack F Vogel /**
108413705f88SJack F Vogel  *  ixgbe_calc_eeprom_checksum - Calculates and returns the checksum
108513705f88SJack F Vogel  *  @hw: pointer to hardware structure
108613705f88SJack F Vogel  **/
108713705f88SJack F Vogel static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
108813705f88SJack F Vogel {
108913705f88SJack F Vogel 	u16 i;
109013705f88SJack F Vogel 	u16 j;
109113705f88SJack F Vogel 	u16 checksum = 0;
109213705f88SJack F Vogel 	u16 length = 0;
109313705f88SJack F Vogel 	u16 pointer = 0;
109413705f88SJack F Vogel 	u16 word = 0;
109513705f88SJack F Vogel 
109613705f88SJack F Vogel 	/* Include 0x0-0x3F in the checksum */
109713705f88SJack F Vogel 	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
10989ca4041bSJack F Vogel 		if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) {
109913705f88SJack F Vogel 			DEBUGOUT("EEPROM read failed\n");
110013705f88SJack F Vogel 			break;
110113705f88SJack F Vogel 		}
110213705f88SJack F Vogel 		checksum += word;
110313705f88SJack F Vogel 	}
110413705f88SJack F Vogel 
110513705f88SJack F Vogel 	/* Include all data from pointers except for the fw pointer */
110613705f88SJack F Vogel 	for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
11079ca4041bSJack F Vogel 		hw->eeprom.ops.read(hw, i, &pointer);
110813705f88SJack F Vogel 
110913705f88SJack F Vogel 		/* Make sure the pointer seems valid */
111013705f88SJack F Vogel 		if (pointer != 0xFFFF && pointer != 0) {
11119ca4041bSJack F Vogel 			hw->eeprom.ops.read(hw, pointer, &length);
111213705f88SJack F Vogel 
111313705f88SJack F Vogel 			if (length != 0xFFFF && length != 0) {
111413705f88SJack F Vogel 				for (j = pointer+1; j <= pointer+length; j++) {
11159ca4041bSJack F Vogel 					hw->eeprom.ops.read(hw, j, &word);
111613705f88SJack F Vogel 					checksum += word;
111713705f88SJack F Vogel 				}
111813705f88SJack F Vogel 			}
111913705f88SJack F Vogel 		}
112013705f88SJack F Vogel 	}
112113705f88SJack F Vogel 
112213705f88SJack F Vogel 	checksum = (u16)IXGBE_EEPROM_SUM - checksum;
112313705f88SJack F Vogel 
112413705f88SJack F Vogel 	return checksum;
112513705f88SJack F Vogel }
112613705f88SJack F Vogel 
112713705f88SJack F Vogel /**
112813705f88SJack F Vogel  *  ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
112913705f88SJack F Vogel  *  @hw: pointer to hardware structure
113013705f88SJack F Vogel  *  @checksum_val: calculated checksum
113113705f88SJack F Vogel  *
113213705f88SJack F Vogel  *  Performs checksum calculation and validates the EEPROM checksum.  If the
113313705f88SJack F Vogel  *  caller does not need checksum_val, the value can be NULL.
113413705f88SJack F Vogel  **/
113513705f88SJack F Vogel s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
113613705f88SJack F Vogel                                            u16 *checksum_val)
113713705f88SJack F Vogel {
113813705f88SJack F Vogel 	s32 status;
113913705f88SJack F Vogel 	u16 checksum;
114013705f88SJack F Vogel 	u16 read_checksum = 0;
114113705f88SJack F Vogel 
114213705f88SJack F Vogel 	/*
114313705f88SJack F Vogel 	 * Read the first word from the EEPROM. If this times out or fails, do
114413705f88SJack F Vogel 	 * not continue or we could be in for a very long wait while every
114513705f88SJack F Vogel 	 * EEPROM read fails
114613705f88SJack F Vogel 	 */
11479ca4041bSJack F Vogel 	status = hw->eeprom.ops.read(hw, 0, &checksum);
114813705f88SJack F Vogel 
114913705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
115013705f88SJack F Vogel 		checksum = ixgbe_calc_eeprom_checksum(hw);
115113705f88SJack F Vogel 
11529ca4041bSJack F Vogel 		hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
115313705f88SJack F Vogel 
115413705f88SJack F Vogel 		/*
115513705f88SJack F Vogel 		 * Verify read checksum from EEPROM is the same as
115613705f88SJack F Vogel 		 * calculated checksum
115713705f88SJack F Vogel 		 */
11589ca4041bSJack F Vogel 		if (read_checksum != checksum)
115913705f88SJack F Vogel 			status = IXGBE_ERR_EEPROM_CHECKSUM;
116013705f88SJack F Vogel 
116113705f88SJack F Vogel 		/* If the user cares, return the calculated checksum */
11629ca4041bSJack F Vogel 		if (checksum_val)
116313705f88SJack F Vogel 			*checksum_val = checksum;
116413705f88SJack F Vogel 	} else {
116513705f88SJack F Vogel 		DEBUGOUT("EEPROM read failed\n");
116613705f88SJack F Vogel 	}
116713705f88SJack F Vogel 
116813705f88SJack F Vogel 	return status;
116913705f88SJack F Vogel }
117013705f88SJack F Vogel 
117113705f88SJack F Vogel /**
11729ca4041bSJack F Vogel  *  ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
117313705f88SJack F Vogel  *  @hw: pointer to hardware structure
117413705f88SJack F Vogel  **/
117513705f88SJack F Vogel s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
117613705f88SJack F Vogel {
117713705f88SJack F Vogel 	s32 status;
117813705f88SJack F Vogel 	u16 checksum;
117913705f88SJack F Vogel 
118013705f88SJack F Vogel 	/*
118113705f88SJack F Vogel 	 * Read the first word from the EEPROM. If this times out or fails, do
118213705f88SJack F Vogel 	 * not continue or we could be in for a very long wait while every
118313705f88SJack F Vogel 	 * EEPROM read fails
118413705f88SJack F Vogel 	 */
11859ca4041bSJack F Vogel 	status = hw->eeprom.ops.read(hw, 0, &checksum);
118613705f88SJack F Vogel 
118713705f88SJack F Vogel 	if (status == IXGBE_SUCCESS) {
118813705f88SJack F Vogel 		checksum = ixgbe_calc_eeprom_checksum(hw);
11899ca4041bSJack F Vogel 		status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
119013705f88SJack F Vogel 		                              checksum);
119113705f88SJack F Vogel 	} else {
119213705f88SJack F Vogel 		DEBUGOUT("EEPROM read failed\n");
119313705f88SJack F Vogel 	}
119413705f88SJack F Vogel 
119513705f88SJack F Vogel 	return status;
119613705f88SJack F Vogel }
119713705f88SJack F Vogel 
119813705f88SJack F Vogel /**
119913705f88SJack F Vogel  *  ixgbe_validate_mac_addr - Validate MAC address
120013705f88SJack F Vogel  *  @mac_addr: pointer to MAC address.
120113705f88SJack F Vogel  *
120213705f88SJack F Vogel  *  Tests a MAC address to ensure it is a valid Individual Address
120313705f88SJack F Vogel  **/
120413705f88SJack F Vogel s32 ixgbe_validate_mac_addr(u8 *mac_addr)
120513705f88SJack F Vogel {
120613705f88SJack F Vogel 	s32 status = IXGBE_SUCCESS;
120713705f88SJack F Vogel 
120813705f88SJack F Vogel 	/* Make sure it is not a multicast address */
120913705f88SJack F Vogel 	if (IXGBE_IS_MULTICAST(mac_addr)) {
121013705f88SJack F Vogel 		DEBUGOUT("MAC address is multicast\n");
121113705f88SJack F Vogel 		status = IXGBE_ERR_INVALID_MAC_ADDR;
121213705f88SJack F Vogel 	/* Not a broadcast address */
121313705f88SJack F Vogel 	} else if (IXGBE_IS_BROADCAST(mac_addr)) {
121413705f88SJack F Vogel 		DEBUGOUT("MAC address is broadcast\n");
121513705f88SJack F Vogel 		status = IXGBE_ERR_INVALID_MAC_ADDR;
121613705f88SJack F Vogel 	/* Reject the zero address */
121713705f88SJack F Vogel 	} else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
121813705f88SJack F Vogel 	           mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
121913705f88SJack F Vogel 		DEBUGOUT("MAC address is all zeros\n");
122013705f88SJack F Vogel 		status = IXGBE_ERR_INVALID_MAC_ADDR;
122113705f88SJack F Vogel 	}
122213705f88SJack F Vogel 	return status;
122313705f88SJack F Vogel }
122413705f88SJack F Vogel 
122513705f88SJack F Vogel /**
12269ca4041bSJack F Vogel  *  ixgbe_set_rar_generic - Set Rx address register
122713705f88SJack F Vogel  *  @hw: pointer to hardware structure
122813705f88SJack F Vogel  *  @index: Receive address register to write
12299ca4041bSJack F Vogel  *  @addr: Address to put into receive address register
12309ca4041bSJack F Vogel  *  @vmdq: VMDq "set" or "pool" index
123113705f88SJack F Vogel  *  @enable_addr: set flag that address is active
123213705f88SJack F Vogel  *
123313705f88SJack F Vogel  *  Puts an ethernet address into a receive address register.
123413705f88SJack F Vogel  **/
12359ca4041bSJack F Vogel s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
123613705f88SJack F Vogel                           u32 enable_addr)
123713705f88SJack F Vogel {
123813705f88SJack F Vogel 	u32 rar_low, rar_high;
12399ca4041bSJack F Vogel 	u32 rar_entries = hw->mac.num_rar_entries;
124013705f88SJack F Vogel 
12419ca4041bSJack F Vogel 	/* setup VMDq pool selection before this RAR gets enabled */
12429ca4041bSJack F Vogel 	hw->mac.ops.set_vmdq(hw, index, vmdq);
12439ca4041bSJack F Vogel 
12449ca4041bSJack F Vogel 	/* Make sure we are using a valid rar index range */
12459ca4041bSJack F Vogel 	if (index < rar_entries) {
124613705f88SJack F Vogel 		/*
12479ca4041bSJack F Vogel 		 * HW expects these in little endian so we reverse the byte
12489ca4041bSJack F Vogel 		 * order from network order (big endian) to little endian
124913705f88SJack F Vogel 		 */
125013705f88SJack F Vogel 		rar_low = ((u32)addr[0] |
125113705f88SJack F Vogel 		           ((u32)addr[1] << 8) |
125213705f88SJack F Vogel 		           ((u32)addr[2] << 16) |
125313705f88SJack F Vogel 		           ((u32)addr[3] << 24));
12549ca4041bSJack F Vogel 		/*
12559ca4041bSJack F Vogel 		 * Some parts put the VMDq setting in the extra RAH bits,
12569ca4041bSJack F Vogel 		 * so save everything except the lower 16 bits that hold part
12579ca4041bSJack F Vogel 		 * of the address and the address valid bit.
12589ca4041bSJack F Vogel 		 */
12599ca4041bSJack F Vogel 		rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
12609ca4041bSJack F Vogel 		rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
12619ca4041bSJack F Vogel 		rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
126213705f88SJack F Vogel 
126313705f88SJack F Vogel 		if (enable_addr != 0)
126413705f88SJack F Vogel 			rar_high |= IXGBE_RAH_AV;
126513705f88SJack F Vogel 
126613705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
126713705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
12689ca4041bSJack F Vogel 	} else {
12695b7f4cedSJack F Vogel 		DEBUGOUT1("RAR index %d is out of range.\n", index);
12709ca4041bSJack F Vogel 	}
127113705f88SJack F Vogel 
127213705f88SJack F Vogel 	return IXGBE_SUCCESS;
127313705f88SJack F Vogel }
127413705f88SJack F Vogel 
127513705f88SJack F Vogel /**
12765b7f4cedSJack F Vogel  *  ixgbe_clear_rar_generic - Remove Rx address register
12775b7f4cedSJack F Vogel  *  @hw: pointer to hardware structure
12785b7f4cedSJack F Vogel  *  @index: Receive address register to write
12795b7f4cedSJack F Vogel  *
12805b7f4cedSJack F Vogel  *  Clears an ethernet address from a receive address register.
12815b7f4cedSJack F Vogel  **/
12825b7f4cedSJack F Vogel s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
12835b7f4cedSJack F Vogel {
12845b7f4cedSJack F Vogel 	u32 rar_high;
12855b7f4cedSJack F Vogel 	u32 rar_entries = hw->mac.num_rar_entries;
12865b7f4cedSJack F Vogel 
12875b7f4cedSJack F Vogel 	/* Make sure we are using a valid rar index range */
12885b7f4cedSJack F Vogel 	if (index < rar_entries) {
12895b7f4cedSJack F Vogel 		/*
12905b7f4cedSJack F Vogel 		 * Some parts put the VMDq setting in the extra RAH bits,
12915b7f4cedSJack F Vogel 		 * so save everything except the lower 16 bits that hold part
12925b7f4cedSJack F Vogel 		 * of the address and the address valid bit.
12935b7f4cedSJack F Vogel 		 */
12945b7f4cedSJack F Vogel 		rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
12955b7f4cedSJack F Vogel 		rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
12965b7f4cedSJack F Vogel 
12975b7f4cedSJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
12985b7f4cedSJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
12995b7f4cedSJack F Vogel 	} else {
13005b7f4cedSJack F Vogel 		DEBUGOUT1("RAR index %d is out of range.\n", index);
13015b7f4cedSJack F Vogel 	}
13025b7f4cedSJack F Vogel 
13035b7f4cedSJack F Vogel 	/* clear VMDq pool/queue selection for this RAR */
13045b7f4cedSJack F Vogel 	hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
13055b7f4cedSJack F Vogel 
13065b7f4cedSJack F Vogel 	return IXGBE_SUCCESS;
13075b7f4cedSJack F Vogel }
13085b7f4cedSJack F Vogel 
13095b7f4cedSJack F Vogel /**
131013705f88SJack F Vogel  *  ixgbe_init_rx_addrs_generic - Initializes receive address filters.
131113705f88SJack F Vogel  *  @hw: pointer to hardware structure
131213705f88SJack F Vogel  *
131313705f88SJack F Vogel  *  Places the MAC address in receive address register 0 and clears the rest
13149ca4041bSJack F Vogel  *  of the receive address registers. Clears the multicast table. Assumes
131513705f88SJack F Vogel  *  the receiver is in reset when the routine is called.
131613705f88SJack F Vogel  **/
131713705f88SJack F Vogel s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
131813705f88SJack F Vogel {
131913705f88SJack F Vogel 	u32 i;
13209ca4041bSJack F Vogel 	u32 rar_entries = hw->mac.num_rar_entries;
132113705f88SJack F Vogel 
132213705f88SJack F Vogel 	/*
132313705f88SJack F Vogel 	 * If the current mac address is valid, assume it is a software override
132413705f88SJack F Vogel 	 * to the permanent address.
132513705f88SJack F Vogel 	 * Otherwise, use the permanent address from the eeprom.
132613705f88SJack F Vogel 	 */
132713705f88SJack F Vogel 	if (ixgbe_validate_mac_addr(hw->mac.addr) ==
132813705f88SJack F Vogel 	    IXGBE_ERR_INVALID_MAC_ADDR) {
132913705f88SJack F Vogel 		/* Get the MAC address from the RAR0 for later reference */
13309ca4041bSJack F Vogel 		hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
133113705f88SJack F Vogel 
133213705f88SJack F Vogel 		DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
133313705f88SJack F Vogel 		          hw->mac.addr[0], hw->mac.addr[1],
133413705f88SJack F Vogel 		          hw->mac.addr[2]);
133513705f88SJack F Vogel 		DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
133613705f88SJack F Vogel 		          hw->mac.addr[4], hw->mac.addr[5]);
133713705f88SJack F Vogel 	} else {
133813705f88SJack F Vogel 		/* Setup the receive address. */
133913705f88SJack F Vogel 		DEBUGOUT("Overriding MAC Address in RAR[0]\n");
134013705f88SJack F Vogel 		DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ",
134113705f88SJack F Vogel 		          hw->mac.addr[0], hw->mac.addr[1],
134213705f88SJack F Vogel 		          hw->mac.addr[2]);
134313705f88SJack F Vogel 		DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3],
134413705f88SJack F Vogel 		          hw->mac.addr[4], hw->mac.addr[5]);
134513705f88SJack F Vogel 
13469ca4041bSJack F Vogel 		hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
134713705f88SJack F Vogel 	}
13489ca4041bSJack F Vogel 	hw->addr_ctrl.overflow_promisc = 0;
134913705f88SJack F Vogel 
135013705f88SJack F Vogel 	hw->addr_ctrl.rar_used_count = 1;
135113705f88SJack F Vogel 
135213705f88SJack F Vogel 	/* Zero out the other receive addresses. */
13539ca4041bSJack F Vogel 	DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1);
135413705f88SJack F Vogel 	for (i = 1; i < rar_entries; i++) {
135513705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
135613705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
135713705f88SJack F Vogel 	}
135813705f88SJack F Vogel 
135913705f88SJack F Vogel 	/* Clear the MTA */
136013705f88SJack F Vogel 	hw->addr_ctrl.mta_in_use = 0;
136113705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
136213705f88SJack F Vogel 
136313705f88SJack F Vogel 	DEBUGOUT(" Clearing MTA\n");
13649ca4041bSJack F Vogel 	for (i = 0; i < hw->mac.mcft_size; i++)
136513705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
136613705f88SJack F Vogel 
13675b7f4cedSJack F Vogel 	ixgbe_init_uta_tables(hw);
13685b7f4cedSJack F Vogel 
136913705f88SJack F Vogel 	return IXGBE_SUCCESS;
137013705f88SJack F Vogel }
137113705f88SJack F Vogel 
137213705f88SJack F Vogel /**
13739ca4041bSJack F Vogel  *  ixgbe_add_uc_addr - Adds a secondary unicast address.
13749ca4041bSJack F Vogel  *  @hw: pointer to hardware structure
13759ca4041bSJack F Vogel  *  @addr: new address
13769ca4041bSJack F Vogel  *
13779ca4041bSJack F Vogel  *  Adds it to unused receive address register or goes into promiscuous mode.
13789ca4041bSJack F Vogel  **/
13799ca4041bSJack F Vogel void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
13809ca4041bSJack F Vogel {
13819ca4041bSJack F Vogel 	u32 rar_entries = hw->mac.num_rar_entries;
13829ca4041bSJack F Vogel 	u32 rar;
13839ca4041bSJack F Vogel 
13849ca4041bSJack F Vogel 	DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
13859ca4041bSJack F Vogel 	          addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
13869ca4041bSJack F Vogel 
13879ca4041bSJack F Vogel 	/*
13889ca4041bSJack F Vogel 	 * Place this address in the RAR if there is room,
13899ca4041bSJack F Vogel 	 * else put the controller into promiscuous mode
13909ca4041bSJack F Vogel 	 */
13919ca4041bSJack F Vogel 	if (hw->addr_ctrl.rar_used_count < rar_entries) {
13920ac6dfecSJack F Vogel 		rar = hw->addr_ctrl.rar_used_count;
13939ca4041bSJack F Vogel 		hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
13949ca4041bSJack F Vogel 		DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar);
13959ca4041bSJack F Vogel 		hw->addr_ctrl.rar_used_count++;
13969ca4041bSJack F Vogel 	} else {
13979ca4041bSJack F Vogel 		hw->addr_ctrl.overflow_promisc++;
13989ca4041bSJack F Vogel 	}
13999ca4041bSJack F Vogel 
14009ca4041bSJack F Vogel 	DEBUGOUT("ixgbe_add_uc_addr Complete\n");
14019ca4041bSJack F Vogel }
14029ca4041bSJack F Vogel 
14039ca4041bSJack F Vogel /**
14049ca4041bSJack F Vogel  *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
14059ca4041bSJack F Vogel  *  @hw: pointer to hardware structure
14069ca4041bSJack F Vogel  *  @addr_list: the list of new addresses
14079ca4041bSJack F Vogel  *  @addr_count: number of addresses
14089ca4041bSJack F Vogel  *  @next: iterator function to walk the address list
14099ca4041bSJack F Vogel  *
14109ca4041bSJack F Vogel  *  The given list replaces any existing list.  Clears the secondary addrs from
14119ca4041bSJack F Vogel  *  receive address registers.  Uses unused receive address registers for the
14129ca4041bSJack F Vogel  *  first secondary addresses, and falls back to promiscuous mode as needed.
14139ca4041bSJack F Vogel  *
14149ca4041bSJack F Vogel  *  Drivers using secondary unicast addresses must set user_set_promisc when
14159ca4041bSJack F Vogel  *  manually putting the device into promiscuous mode.
14169ca4041bSJack F Vogel  **/
14179ca4041bSJack F Vogel s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
14189ca4041bSJack F Vogel                                       u32 addr_count, ixgbe_mc_addr_itr next)
14199ca4041bSJack F Vogel {
14209ca4041bSJack F Vogel 	u8 *addr;
14219ca4041bSJack F Vogel 	u32 i;
14229ca4041bSJack F Vogel 	u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
14239ca4041bSJack F Vogel 	u32 uc_addr_in_use;
14249ca4041bSJack F Vogel 	u32 fctrl;
14259ca4041bSJack F Vogel 	u32 vmdq;
14269ca4041bSJack F Vogel 
14279ca4041bSJack F Vogel 	/*
14289ca4041bSJack F Vogel 	 * Clear accounting of old secondary address list,
14299ca4041bSJack F Vogel 	 * don't count RAR[0]
14309ca4041bSJack F Vogel 	 */
14310ac6dfecSJack F Vogel 	uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
14329ca4041bSJack F Vogel 	hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
14339ca4041bSJack F Vogel 	hw->addr_ctrl.overflow_promisc = 0;
14349ca4041bSJack F Vogel 
14359ca4041bSJack F Vogel 	/* Zero out the other receive addresses */
14360ac6dfecSJack F Vogel 	DEBUGOUT1("Clearing RAR[1-%d]\n", hw->addr_ctrl.rar_used_count);
14370ac6dfecSJack F Vogel 	for (i = 1; i <= hw->addr_ctrl.rar_used_count; i++) {
14389ca4041bSJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
14399ca4041bSJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
14409ca4041bSJack F Vogel 	}
14419ca4041bSJack F Vogel 
14429ca4041bSJack F Vogel 	/* Add the new addresses */
14439ca4041bSJack F Vogel 	for (i = 0; i < addr_count; i++) {
14449ca4041bSJack F Vogel 		DEBUGOUT(" Adding the secondary addresses:\n");
14459ca4041bSJack F Vogel 		addr = next(hw, &addr_list, &vmdq);
14469ca4041bSJack F Vogel 		ixgbe_add_uc_addr(hw, addr, vmdq);
14479ca4041bSJack F Vogel 	}
14489ca4041bSJack F Vogel 
14499ca4041bSJack F Vogel 	if (hw->addr_ctrl.overflow_promisc) {
14509ca4041bSJack F Vogel 		/* enable promisc if not already in overflow or set by user */
14519ca4041bSJack F Vogel 		if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
14529ca4041bSJack F Vogel 			DEBUGOUT(" Entering address overflow promisc mode\n");
14539ca4041bSJack F Vogel 			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
14549ca4041bSJack F Vogel 			fctrl |= IXGBE_FCTRL_UPE;
14559ca4041bSJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
14569ca4041bSJack F Vogel 		}
14579ca4041bSJack F Vogel 	} else {
14589ca4041bSJack F Vogel 		/* only disable if set by overflow, not by user */
14599ca4041bSJack F Vogel 		if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
14609ca4041bSJack F Vogel 			DEBUGOUT(" Leaving address overflow promisc mode\n");
14619ca4041bSJack F Vogel 			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
14629ca4041bSJack F Vogel 			fctrl &= ~IXGBE_FCTRL_UPE;
14639ca4041bSJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
14649ca4041bSJack F Vogel 		}
14659ca4041bSJack F Vogel 	}
14669ca4041bSJack F Vogel 
14679ca4041bSJack F Vogel 	DEBUGOUT("ixgbe_update_uc_addr_list_generic Complete\n");
14689ca4041bSJack F Vogel 	return IXGBE_SUCCESS;
14699ca4041bSJack F Vogel }
14709ca4041bSJack F Vogel 
14719ca4041bSJack F Vogel /**
147213705f88SJack F Vogel  *  ixgbe_mta_vector - Determines bit-vector in multicast table to set
147313705f88SJack F Vogel  *  @hw: pointer to hardware structure
147413705f88SJack F Vogel  *  @mc_addr: the multicast address
147513705f88SJack F Vogel  *
147613705f88SJack F Vogel  *  Extracts the 12 bits, from a multicast address, to determine which
147713705f88SJack F Vogel  *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
147813705f88SJack F Vogel  *  incoming rx multicast addresses, to determine the bit-vector to check in
147913705f88SJack F Vogel  *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
14809ca4041bSJack F Vogel  *  by the MO field of the MCSTCTRL. The MO field is set during initialization
148113705f88SJack F Vogel  *  to mc_filter_type.
148213705f88SJack F Vogel  **/
148313705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
148413705f88SJack F Vogel {
148513705f88SJack F Vogel 	u32 vector = 0;
148613705f88SJack F Vogel 
148713705f88SJack F Vogel 	switch (hw->mac.mc_filter_type) {
148813705f88SJack F Vogel 	case 0:   /* use bits [47:36] of the address */
148913705f88SJack F Vogel 		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
149013705f88SJack F Vogel 		break;
149113705f88SJack F Vogel 	case 1:   /* use bits [46:35] of the address */
149213705f88SJack F Vogel 		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
149313705f88SJack F Vogel 		break;
149413705f88SJack F Vogel 	case 2:   /* use bits [45:34] of the address */
149513705f88SJack F Vogel 		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
149613705f88SJack F Vogel 		break;
149713705f88SJack F Vogel 	case 3:   /* use bits [43:32] of the address */
149813705f88SJack F Vogel 		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
149913705f88SJack F Vogel 		break;
150013705f88SJack F Vogel 	default:  /* Invalid mc_filter_type */
150113705f88SJack F Vogel 		DEBUGOUT("MC filter type param set incorrectly\n");
150213705f88SJack F Vogel 		ASSERT(0);
150313705f88SJack F Vogel 		break;
150413705f88SJack F Vogel 	}
150513705f88SJack F Vogel 
150613705f88SJack F Vogel 	/* vector can only be 12-bits or boundary will be exceeded */
150713705f88SJack F Vogel 	vector &= 0xFFF;
150813705f88SJack F Vogel 	return vector;
150913705f88SJack F Vogel }
151013705f88SJack F Vogel 
151113705f88SJack F Vogel /**
151213705f88SJack F Vogel  *  ixgbe_set_mta - Set bit-vector in multicast table
151313705f88SJack F Vogel  *  @hw: pointer to hardware structure
151413705f88SJack F Vogel  *  @hash_value: Multicast address hash value
151513705f88SJack F Vogel  *
151613705f88SJack F Vogel  *  Sets the bit-vector in the multicast table.
151713705f88SJack F Vogel  **/
151813705f88SJack F Vogel void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
151913705f88SJack F Vogel {
152013705f88SJack F Vogel 	u32 vector;
152113705f88SJack F Vogel 	u32 vector_bit;
152213705f88SJack F Vogel 	u32 vector_reg;
152313705f88SJack F Vogel 	u32 mta_reg;
152413705f88SJack F Vogel 
152513705f88SJack F Vogel 	hw->addr_ctrl.mta_in_use++;
152613705f88SJack F Vogel 
152713705f88SJack F Vogel 	vector = ixgbe_mta_vector(hw, mc_addr);
152813705f88SJack F Vogel 	DEBUGOUT1(" bit-vector = 0x%03X\n", vector);
152913705f88SJack F Vogel 
153013705f88SJack F Vogel 	/*
153113705f88SJack F Vogel 	 * The MTA is a register array of 128 32-bit registers. It is treated
153213705f88SJack F Vogel 	 * like an array of 4096 bits.  We want to set bit
153313705f88SJack F Vogel 	 * BitArray[vector_value]. So we figure out what register the bit is
153413705f88SJack F Vogel 	 * in, read it, OR in the new bit, then write back the new value.  The
153513705f88SJack F Vogel 	 * register is determined by the upper 7 bits of the vector value and
153613705f88SJack F Vogel 	 * the bit within that register are determined by the lower 5 bits of
153713705f88SJack F Vogel 	 * the value.
153813705f88SJack F Vogel 	 */
153913705f88SJack F Vogel 	vector_reg = (vector >> 5) & 0x7F;
154013705f88SJack F Vogel 	vector_bit = vector & 0x1F;
154113705f88SJack F Vogel 	mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));
154213705f88SJack F Vogel 	mta_reg |= (1 << vector_bit);
154313705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
154413705f88SJack F Vogel }
154513705f88SJack F Vogel 
154613705f88SJack F Vogel /**
154713705f88SJack F Vogel  *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
154813705f88SJack F Vogel  *  @hw: pointer to hardware structure
154913705f88SJack F Vogel  *  @mc_addr_list: the list of new multicast addresses
155013705f88SJack F Vogel  *  @mc_addr_count: number of addresses
15519ca4041bSJack F Vogel  *  @next: iterator function to walk the multicast address list
155213705f88SJack F Vogel  *
155313705f88SJack F Vogel  *  The given list replaces any existing list. Clears the MC addrs from receive
15549ca4041bSJack F Vogel  *  address registers and the multicast table. Uses unused receive address
155513705f88SJack F Vogel  *  registers for the first multicast addresses, and hashes the rest into the
155613705f88SJack F Vogel  *  multicast table.
155713705f88SJack F Vogel  **/
155813705f88SJack F Vogel s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
15599ca4041bSJack F Vogel                                       u32 mc_addr_count, ixgbe_mc_addr_itr next)
156013705f88SJack F Vogel {
156113705f88SJack F Vogel 	u32 i;
15629ca4041bSJack F Vogel 	u32 vmdq;
156313705f88SJack F Vogel 
156413705f88SJack F Vogel 	/*
156513705f88SJack F Vogel 	 * Set the new number of MC addresses that we are being requested to
156613705f88SJack F Vogel 	 * use.
156713705f88SJack F Vogel 	 */
156813705f88SJack F Vogel 	hw->addr_ctrl.num_mc_addrs = mc_addr_count;
156913705f88SJack F Vogel 	hw->addr_ctrl.mta_in_use = 0;
157013705f88SJack F Vogel 
157113705f88SJack F Vogel 	/* Clear the MTA */
157213705f88SJack F Vogel 	DEBUGOUT(" Clearing MTA\n");
15739ca4041bSJack F Vogel 	for (i = 0; i < hw->mac.mcft_size; i++)
157413705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
157513705f88SJack F Vogel 
157613705f88SJack F Vogel 	/* Add the new addresses */
157713705f88SJack F Vogel 	for (i = 0; i < mc_addr_count; i++) {
157813705f88SJack F Vogel 		DEBUGOUT(" Adding the multicast addresses:\n");
15790ac6dfecSJack F Vogel 		ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
158013705f88SJack F Vogel 	}
158113705f88SJack F Vogel 
158213705f88SJack F Vogel 	/* Enable mta */
158313705f88SJack F Vogel 	if (hw->addr_ctrl.mta_in_use > 0)
158413705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
158513705f88SJack F Vogel 		                IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
158613705f88SJack F Vogel 
158713705f88SJack F Vogel 	DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n");
158813705f88SJack F Vogel 	return IXGBE_SUCCESS;
158913705f88SJack F Vogel }
159013705f88SJack F Vogel 
159113705f88SJack F Vogel /**
159213705f88SJack F Vogel  *  ixgbe_enable_mc_generic - Enable multicast address in RAR
159313705f88SJack F Vogel  *  @hw: pointer to hardware structure
159413705f88SJack F Vogel  *
159513705f88SJack F Vogel  *  Enables multicast address in RAR and the use of the multicast hash table.
159613705f88SJack F Vogel  **/
159713705f88SJack F Vogel s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
159813705f88SJack F Vogel {
159913705f88SJack F Vogel 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
160013705f88SJack F Vogel 
160113705f88SJack F Vogel 	if (a->mta_in_use > 0)
160213705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
160313705f88SJack F Vogel 		                hw->mac.mc_filter_type);
160413705f88SJack F Vogel 
160513705f88SJack F Vogel 	return IXGBE_SUCCESS;
160613705f88SJack F Vogel }
160713705f88SJack F Vogel 
160813705f88SJack F Vogel /**
16099ca4041bSJack F Vogel  *  ixgbe_disable_mc_generic - Disable multicast address in RAR
161013705f88SJack F Vogel  *  @hw: pointer to hardware structure
161113705f88SJack F Vogel  *
161213705f88SJack F Vogel  *  Disables multicast address in RAR and the use of the multicast hash table.
161313705f88SJack F Vogel  **/
161413705f88SJack F Vogel s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
161513705f88SJack F Vogel {
161613705f88SJack F Vogel 	struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
161713705f88SJack F Vogel 
161813705f88SJack F Vogel 	if (a->mta_in_use > 0)
161913705f88SJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
162013705f88SJack F Vogel 
162113705f88SJack F Vogel 	return IXGBE_SUCCESS;
162213705f88SJack F Vogel }
162313705f88SJack F Vogel 
16241b6e0dbaSJack F Vogel /**
16250ac6dfecSJack F Vogel  *  ixgbe_fc_enable_generic - Enable flow control
16261b6e0dbaSJack F Vogel  *  @hw: pointer to hardware structure
16270ac6dfecSJack F Vogel  *  @packetbuf_num: packet buffer number (0-7)
16281b6e0dbaSJack F Vogel  *
16290ac6dfecSJack F Vogel  *  Enable flow control according to the current settings.
16301b6e0dbaSJack F Vogel  **/
16310ac6dfecSJack F Vogel s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
16321b6e0dbaSJack F Vogel {
16331b6e0dbaSJack F Vogel 	s32 ret_val = IXGBE_SUCCESS;
16340ac6dfecSJack F Vogel 	u32 mflcn_reg, fccfg_reg;
16350ac6dfecSJack F Vogel 	u32 reg;
16361b6e0dbaSJack F Vogel 
16370ac6dfecSJack F Vogel 	DEBUGFUNC("ixgbe_fc_enable_generic");
16381b6e0dbaSJack F Vogel 
16390ac6dfecSJack F Vogel 	/* Negotiate the fc mode to use */
16400ac6dfecSJack F Vogel 	ret_val = ixgbe_fc_autoneg(hw);
16410ac6dfecSJack F Vogel 	if (ret_val)
16420ac6dfecSJack F Vogel 		goto out;
16430ac6dfecSJack F Vogel 
16440ac6dfecSJack F Vogel 	/* Disable any previous flow control settings */
16450ac6dfecSJack F Vogel 	mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
16460ac6dfecSJack F Vogel 	mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
16470ac6dfecSJack F Vogel 
16480ac6dfecSJack F Vogel 	fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
16490ac6dfecSJack F Vogel 	fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
16501b6e0dbaSJack F Vogel 
16511b6e0dbaSJack F Vogel 	/*
16521b6e0dbaSJack F Vogel 	 * The possible values of fc.current_mode are:
16531b6e0dbaSJack F Vogel 	 * 0: Flow control is completely disabled
16541b6e0dbaSJack F Vogel 	 * 1: Rx flow control is enabled (we can receive pause frames,
16551b6e0dbaSJack F Vogel 	 *    but not send pause frames).
16561b6e0dbaSJack F Vogel 	 * 2: Tx flow control is enabled (we can send pause frames but
16571b6e0dbaSJack F Vogel 	 *    we do not support receiving pause frames).
16581b6e0dbaSJack F Vogel 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
16591b6e0dbaSJack F Vogel 	 * other: Invalid.
16601b6e0dbaSJack F Vogel 	 */
16611b6e0dbaSJack F Vogel 	switch (hw->fc.current_mode) {
16621b6e0dbaSJack F Vogel 	case ixgbe_fc_none:
16630ac6dfecSJack F Vogel 		/* Flow control is disabled by software override or autoneg.
16640ac6dfecSJack F Vogel 		 * The code below will actually disable it in the HW.
16650ac6dfecSJack F Vogel 		 */
16661b6e0dbaSJack F Vogel 		break;
16671b6e0dbaSJack F Vogel 	case ixgbe_fc_rx_pause:
16681b6e0dbaSJack F Vogel 		/*
16691b6e0dbaSJack F Vogel 		 * Rx Flow control is enabled and Tx Flow control is
16701b6e0dbaSJack F Vogel 		 * disabled by software override. Since there really
16711b6e0dbaSJack F Vogel 		 * isn't a way to advertise that we are capable of RX
16721b6e0dbaSJack F Vogel 		 * Pause ONLY, we will advertise that we support both
16731b6e0dbaSJack F Vogel 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
16741b6e0dbaSJack F Vogel 		 * disable the adapter's ability to send PAUSE frames.
16751b6e0dbaSJack F Vogel 		 */
16760ac6dfecSJack F Vogel 		mflcn_reg |= IXGBE_MFLCN_RFCE;
16771b6e0dbaSJack F Vogel 		break;
16781b6e0dbaSJack F Vogel 	case ixgbe_fc_tx_pause:
16791b6e0dbaSJack F Vogel 		/*
16801b6e0dbaSJack F Vogel 		 * Tx Flow control is enabled, and Rx Flow control is
16811b6e0dbaSJack F Vogel 		 * disabled by software override.
16821b6e0dbaSJack F Vogel 		 */
16830ac6dfecSJack F Vogel 		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
16841b6e0dbaSJack F Vogel 		break;
16851b6e0dbaSJack F Vogel 	case ixgbe_fc_full:
16861b6e0dbaSJack F Vogel 		/* Flow control (both Rx and Tx) is enabled by SW override. */
16870ac6dfecSJack F Vogel 		mflcn_reg |= IXGBE_MFLCN_RFCE;
16880ac6dfecSJack F Vogel 		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
16891b6e0dbaSJack F Vogel 		break;
16901b6e0dbaSJack F Vogel 	default:
16911b6e0dbaSJack F Vogel 		DEBUGOUT("Flow control param set incorrectly\n");
16921b6e0dbaSJack F Vogel 		ret_val = -IXGBE_ERR_CONFIG;
16931b6e0dbaSJack F Vogel 		goto out;
16941b6e0dbaSJack F Vogel 		break;
16951b6e0dbaSJack F Vogel 	}
16961b6e0dbaSJack F Vogel 
16970ac6dfecSJack F Vogel 	/* Set 802.3x based flow control settings. */
16980ac6dfecSJack F Vogel 	mflcn_reg |= IXGBE_MFLCN_DPF;
16990ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
17000ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
17011b6e0dbaSJack F Vogel 
17020ac6dfecSJack F Vogel 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
17030ac6dfecSJack F Vogel 	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
17040ac6dfecSJack F Vogel 		if (hw->fc.send_xon) {
17050ac6dfecSJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
17060ac6dfecSJack F Vogel 			                (hw->fc.low_water | IXGBE_FCRTL_XONE));
17070ac6dfecSJack F Vogel 		} else {
17080ac6dfecSJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
17090ac6dfecSJack F Vogel 			                hw->fc.low_water);
17101b6e0dbaSJack F Vogel 		}
17111b6e0dbaSJack F Vogel 
17120ac6dfecSJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
17130ac6dfecSJack F Vogel 		                (hw->fc.high_water | IXGBE_FCRTH_FCEN));
17140ac6dfecSJack F Vogel 	}
17150ac6dfecSJack F Vogel 
17160ac6dfecSJack F Vogel 	/* Configure pause time (2 TCs per register) */
17170ac6dfecSJack F Vogel 	reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
17180ac6dfecSJack F Vogel 	if ((packetbuf_num & 1) == 0)
17190ac6dfecSJack F Vogel 		reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
17200ac6dfecSJack F Vogel 	else
17210ac6dfecSJack F Vogel 		reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
17220ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
17230ac6dfecSJack F Vogel 
17240ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
17250ac6dfecSJack F Vogel 
17260ac6dfecSJack F Vogel out:
17270ac6dfecSJack F Vogel 	return ret_val;
17280ac6dfecSJack F Vogel }
17290ac6dfecSJack F Vogel 
17300ac6dfecSJack F Vogel /**
17310ac6dfecSJack F Vogel  *  ixgbe_fc_autoneg - Configure flow control
17320ac6dfecSJack F Vogel  *  @hw: pointer to hardware structure
17330ac6dfecSJack F Vogel  *
17340ac6dfecSJack F Vogel  *  Compares our advertised flow control capabilities to those advertised by
17350ac6dfecSJack F Vogel  *  our link partner, and determines the proper flow control mode to use.
17360ac6dfecSJack F Vogel  **/
17370ac6dfecSJack F Vogel s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
17380ac6dfecSJack F Vogel {
17390ac6dfecSJack F Vogel 	s32 ret_val = IXGBE_SUCCESS;
17400ac6dfecSJack F Vogel 	ixgbe_link_speed speed;
17410ac6dfecSJack F Vogel 	u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
17420ac6dfecSJack F Vogel 	bool link_up;
17430ac6dfecSJack F Vogel 
17440ac6dfecSJack F Vogel 	DEBUGFUNC("ixgbe_fc_autoneg");
17450ac6dfecSJack F Vogel 
17460ac6dfecSJack F Vogel 	/*
17470ac6dfecSJack F Vogel 	 * AN should have completed when the cable was plugged in.
17480ac6dfecSJack F Vogel 	 * Look for reasons to bail out.  Bail out if:
17490ac6dfecSJack F Vogel 	 * - FC autoneg is disabled, or if
17500ac6dfecSJack F Vogel 	 * - we don't have multispeed fiber, or if
17510ac6dfecSJack F Vogel 	 * - we're not running at 1G, or if
17520ac6dfecSJack F Vogel 	 * - link is not up, or if
17530ac6dfecSJack F Vogel 	 * - link is up but AN did not complete, or if
17540ac6dfecSJack F Vogel 	 * - link is up and AN completed but timed out
17550ac6dfecSJack F Vogel 	 *
17560ac6dfecSJack F Vogel 	 * Since we're being called from an LSC, link is already know to be up.
17570ac6dfecSJack F Vogel 	 * So use link_up_wait_to_complete=FALSE.
17580ac6dfecSJack F Vogel 	 */
17590ac6dfecSJack F Vogel 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
17600ac6dfecSJack F Vogel 	linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
17610ac6dfecSJack F Vogel 
17620ac6dfecSJack F Vogel 	if (hw->fc.disable_fc_autoneg ||
17630ac6dfecSJack F Vogel 	    !hw->phy.multispeed_fiber ||
17640ac6dfecSJack F Vogel 	    (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
17650ac6dfecSJack F Vogel 	    !link_up ||
17660ac6dfecSJack F Vogel 	    ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
17670ac6dfecSJack F Vogel 	    ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
17680ac6dfecSJack F Vogel 		hw->fc.fc_was_autonegged = FALSE;
17690ac6dfecSJack F Vogel 		hw->fc.current_mode = hw->fc.requested_mode;
17700ac6dfecSJack F Vogel 		DEBUGOUT("Autoneg FC was skipped.\n");
17711b6e0dbaSJack F Vogel 		goto out;
17721b6e0dbaSJack F Vogel 	}
17731b6e0dbaSJack F Vogel 
17741b6e0dbaSJack F Vogel 	/*
17751b6e0dbaSJack F Vogel 	 * Read the AN advertisement and LP ability registers and resolve
17761b6e0dbaSJack F Vogel 	 * local flow control settings accordingly
17771b6e0dbaSJack F Vogel 	 */
17781b6e0dbaSJack F Vogel 	pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
17791b6e0dbaSJack F Vogel 	pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
17801b6e0dbaSJack F Vogel 	if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
17811b6e0dbaSJack F Vogel 		(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
17821b6e0dbaSJack F Vogel 		/*
17831b6e0dbaSJack F Vogel 		 * Now we need to check if the user selected Rx ONLY
17841b6e0dbaSJack F Vogel 		 * of pause frames.  In this case, we had to advertise
17851b6e0dbaSJack F Vogel 		 * FULL flow control because we could not advertise RX
17861b6e0dbaSJack F Vogel 		 * ONLY. Hence, we must now check to see if we need to
17871b6e0dbaSJack F Vogel 		 * turn OFF the TRANSMISSION of PAUSE frames.
17881b6e0dbaSJack F Vogel 		 */
17891b6e0dbaSJack F Vogel 		if (hw->fc.requested_mode == ixgbe_fc_full) {
17901b6e0dbaSJack F Vogel 			hw->fc.current_mode = ixgbe_fc_full;
17911b6e0dbaSJack F Vogel 			DEBUGOUT("Flow Control = FULL.\n");
17921b6e0dbaSJack F Vogel 		} else {
17931b6e0dbaSJack F Vogel 			hw->fc.current_mode = ixgbe_fc_rx_pause;
17941b6e0dbaSJack F Vogel 			DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
17951b6e0dbaSJack F Vogel 		}
17961b6e0dbaSJack F Vogel 	} else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
17971b6e0dbaSJack F Vogel 		   (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
17981b6e0dbaSJack F Vogel 		   (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
17991b6e0dbaSJack F Vogel 		   (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
18001b6e0dbaSJack F Vogel 		hw->fc.current_mode = ixgbe_fc_tx_pause;
18011b6e0dbaSJack F Vogel 		DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
18021b6e0dbaSJack F Vogel 	} else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
18031b6e0dbaSJack F Vogel 		   (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
18041b6e0dbaSJack F Vogel 		   !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
18051b6e0dbaSJack F Vogel 		   (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
18061b6e0dbaSJack F Vogel 		hw->fc.current_mode = ixgbe_fc_rx_pause;
18071b6e0dbaSJack F Vogel 		DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
18081b6e0dbaSJack F Vogel 	} else {
18091b6e0dbaSJack F Vogel 		hw->fc.current_mode = ixgbe_fc_none;
18101b6e0dbaSJack F Vogel 		DEBUGOUT("Flow Control = NONE.\n");
18111b6e0dbaSJack F Vogel 	}
18121b6e0dbaSJack F Vogel 
18130ac6dfecSJack F Vogel 	/* Record that current_mode is the result of a successful autoneg */
18140ac6dfecSJack F Vogel 	hw->fc.fc_was_autonegged = TRUE;
18150ac6dfecSJack F Vogel 
18161b6e0dbaSJack F Vogel out:
18171b6e0dbaSJack F Vogel 	return ret_val;
18181b6e0dbaSJack F Vogel }
18191b6e0dbaSJack F Vogel 
18200ac6dfecSJack F Vogel /**
18210ac6dfecSJack F Vogel  *  ixgbe_setup_fc - Set up flow control
18220ac6dfecSJack F Vogel  *  @hw: pointer to hardware structure
18230ac6dfecSJack F Vogel  *
18240ac6dfecSJack F Vogel  *  Called at init time to set up flow control.
18250ac6dfecSJack F Vogel  **/
18260ac6dfecSJack F Vogel s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
18270ac6dfecSJack F Vogel {
18280ac6dfecSJack F Vogel 	s32 ret_val = IXGBE_SUCCESS;
18290ac6dfecSJack F Vogel 	u32 reg;
18300ac6dfecSJack F Vogel 
18310ac6dfecSJack F Vogel 
18320ac6dfecSJack F Vogel 	/* Validate the packetbuf configuration */
18330ac6dfecSJack F Vogel 	if (packetbuf_num < 0 || packetbuf_num > 7) {
18340ac6dfecSJack F Vogel 		DEBUGOUT1("Invalid packet buffer number [%d], expected range is"
18350ac6dfecSJack F Vogel 		          " 0-7\n", packetbuf_num);
18360ac6dfecSJack F Vogel 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
18370ac6dfecSJack F Vogel 		goto out;
18380ac6dfecSJack F Vogel 	}
18390ac6dfecSJack F Vogel 
18400ac6dfecSJack F Vogel 	/*
18410ac6dfecSJack F Vogel 	 * Validate the water mark configuration.  Zero water marks are invalid
18420ac6dfecSJack F Vogel 	 * because it causes the controller to just blast out fc packets.
18430ac6dfecSJack F Vogel 	 */
18440ac6dfecSJack F Vogel 	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
18450ac6dfecSJack F Vogel 		DEBUGOUT("Invalid water mark configuration\n");
18460ac6dfecSJack F Vogel 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
18470ac6dfecSJack F Vogel 		goto out;
18480ac6dfecSJack F Vogel 	}
18490ac6dfecSJack F Vogel 
18500ac6dfecSJack F Vogel 	/*
18510ac6dfecSJack F Vogel 	 * Validate the requested mode.  Strict IEEE mode does not allow
18520ac6dfecSJack F Vogel 	 * ixgbe_fc_rx_pause because it will cause us to fail at UNH.
18530ac6dfecSJack F Vogel 	 */
18540ac6dfecSJack F Vogel 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
18550ac6dfecSJack F Vogel 		DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
18560ac6dfecSJack F Vogel 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
18570ac6dfecSJack F Vogel 		goto out;
18580ac6dfecSJack F Vogel 	}
18590ac6dfecSJack F Vogel 
18600ac6dfecSJack F Vogel 	/*
18610ac6dfecSJack F Vogel 	 * 10gig parts do not have a word in the EEPROM to determine the
18620ac6dfecSJack F Vogel 	 * default flow control setting, so we explicitly set it to full.
18630ac6dfecSJack F Vogel 	 */
18640ac6dfecSJack F Vogel 	if (hw->fc.requested_mode == ixgbe_fc_default)
18650ac6dfecSJack F Vogel 		hw->fc.requested_mode = ixgbe_fc_full;
18660ac6dfecSJack F Vogel 
18670ac6dfecSJack F Vogel 	/*
18680ac6dfecSJack F Vogel 	 * Set up the 1G flow control advertisement registers so the HW will be
18690ac6dfecSJack F Vogel 	 * able to do fc autoneg once the cable is plugged in.  If we end up
18700ac6dfecSJack F Vogel 	 * using 10g instead, this is harmless.
18710ac6dfecSJack F Vogel 	 */
18720ac6dfecSJack F Vogel 	reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
18730ac6dfecSJack F Vogel 
18740ac6dfecSJack F Vogel 	/*
18750ac6dfecSJack F Vogel 	 * The possible values of fc.requested_mode are:
18760ac6dfecSJack F Vogel 	 * 0: Flow control is completely disabled
18770ac6dfecSJack F Vogel 	 * 1: Rx flow control is enabled (we can receive pause frames,
18780ac6dfecSJack F Vogel 	 *    but not send pause frames).
18790ac6dfecSJack F Vogel 	 * 2: Tx flow control is enabled (we can send pause frames but
18800ac6dfecSJack F Vogel 	 *    we do not support receiving pause frames).
18810ac6dfecSJack F Vogel 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
18820ac6dfecSJack F Vogel 	 * other: Invalid.
18830ac6dfecSJack F Vogel 	 */
18840ac6dfecSJack F Vogel 	switch (hw->fc.requested_mode) {
18850ac6dfecSJack F Vogel 	case ixgbe_fc_none:
18860ac6dfecSJack F Vogel 		/* Flow control completely disabled by software override. */
18870ac6dfecSJack F Vogel 		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
18880ac6dfecSJack F Vogel 		break;
18890ac6dfecSJack F Vogel 	case ixgbe_fc_rx_pause:
18900ac6dfecSJack F Vogel 		/*
18910ac6dfecSJack F Vogel 		 * Rx Flow control is enabled and Tx Flow control is
18920ac6dfecSJack F Vogel 		 * disabled by software override. Since there really
18930ac6dfecSJack F Vogel 		 * isn't a way to advertise that we are capable of RX
18940ac6dfecSJack F Vogel 		 * Pause ONLY, we will advertise that we support both
18950ac6dfecSJack F Vogel 		 * symmetric and asymmetric Rx PAUSE.  Later, we will
18960ac6dfecSJack F Vogel 		 * disable the adapter's ability to send PAUSE frames.
18970ac6dfecSJack F Vogel 		 */
18980ac6dfecSJack F Vogel 		reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
18990ac6dfecSJack F Vogel 		break;
19000ac6dfecSJack F Vogel 	case ixgbe_fc_tx_pause:
19010ac6dfecSJack F Vogel 		/*
19020ac6dfecSJack F Vogel 		 * Tx Flow control is enabled, and Rx Flow control is
19030ac6dfecSJack F Vogel 		 * disabled by software override.
19040ac6dfecSJack F Vogel 		 */
19050ac6dfecSJack F Vogel 		reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
19060ac6dfecSJack F Vogel 		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
19070ac6dfecSJack F Vogel 		break;
19080ac6dfecSJack F Vogel 	case ixgbe_fc_full:
19090ac6dfecSJack F Vogel 		/* Flow control (both Rx and Tx) is enabled by SW override. */
19100ac6dfecSJack F Vogel 		reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
19110ac6dfecSJack F Vogel 		break;
19120ac6dfecSJack F Vogel 	default:
19130ac6dfecSJack F Vogel 		DEBUGOUT("Flow control param set incorrectly\n");
19140ac6dfecSJack F Vogel 		ret_val = -IXGBE_ERR_CONFIG;
19150ac6dfecSJack F Vogel 		goto out;
19160ac6dfecSJack F Vogel 		break;
19170ac6dfecSJack F Vogel 	}
19180ac6dfecSJack F Vogel 
19190ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
19200ac6dfecSJack F Vogel 	reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
19210ac6dfecSJack F Vogel 
19220ac6dfecSJack F Vogel 	/* Enable and restart autoneg to inform the link partner */
19230ac6dfecSJack F Vogel 	reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
19240ac6dfecSJack F Vogel 
19250ac6dfecSJack F Vogel 	/* Disable AN timeout */
19260ac6dfecSJack F Vogel 	if (hw->fc.strict_ieee)
19270ac6dfecSJack F Vogel 		reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
19280ac6dfecSJack F Vogel 
19290ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
19300ac6dfecSJack F Vogel 	DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
19310ac6dfecSJack F Vogel 
19320ac6dfecSJack F Vogel out:
19330ac6dfecSJack F Vogel 	return ret_val;
19340ac6dfecSJack F Vogel }
19351b6e0dbaSJack F Vogel 
193613705f88SJack F Vogel /**
193713705f88SJack F Vogel  *  ixgbe_disable_pcie_master - Disable PCI-express master access
193813705f88SJack F Vogel  *  @hw: pointer to hardware structure
193913705f88SJack F Vogel  *
194013705f88SJack F Vogel  *  Disables PCI-Express master access and verifies there are no pending
194113705f88SJack F Vogel  *  requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable
194213705f88SJack F Vogel  *  bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS
194313705f88SJack F Vogel  *  is returned signifying master requests disabled.
194413705f88SJack F Vogel  **/
194513705f88SJack F Vogel s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
194613705f88SJack F Vogel {
19475b7f4cedSJack F Vogel 	u32 i;
19485b7f4cedSJack F Vogel 	u32 reg_val;
19495b7f4cedSJack F Vogel 	u32 number_of_queues;
195013705f88SJack F Vogel 	s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
195113705f88SJack F Vogel 
19525b7f4cedSJack F Vogel 	/* Disable the receive unit by stopping each queue */
19535b7f4cedSJack F Vogel 	number_of_queues = hw->mac.max_rx_queues;
19545b7f4cedSJack F Vogel 	for (i = 0; i < number_of_queues; i++) {
19555b7f4cedSJack F Vogel 		reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
19565b7f4cedSJack F Vogel 		if (reg_val & IXGBE_RXDCTL_ENABLE) {
19575b7f4cedSJack F Vogel 			reg_val &= ~IXGBE_RXDCTL_ENABLE;
19585b7f4cedSJack F Vogel 			IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
19595b7f4cedSJack F Vogel 		}
19605b7f4cedSJack F Vogel 	}
19615b7f4cedSJack F Vogel 
19625b7f4cedSJack F Vogel 	reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL);
19635b7f4cedSJack F Vogel 	reg_val |= IXGBE_CTRL_GIO_DIS;
19645b7f4cedSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
196513705f88SJack F Vogel 
196613705f88SJack F Vogel 	for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
196713705f88SJack F Vogel 		if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
196813705f88SJack F Vogel 			status = IXGBE_SUCCESS;
196913705f88SJack F Vogel 			break;
197013705f88SJack F Vogel 		}
197113705f88SJack F Vogel 		usec_delay(100);
197213705f88SJack F Vogel 	}
197313705f88SJack F Vogel 
197413705f88SJack F Vogel 	return status;
197513705f88SJack F Vogel }
197613705f88SJack F Vogel 
197713705f88SJack F Vogel 
197813705f88SJack F Vogel /**
19799ca4041bSJack F Vogel  *  ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
198013705f88SJack F Vogel  *  @hw: pointer to hardware structure
19819ca4041bSJack F Vogel  *  @mask: Mask to specify which semaphore to acquire
198213705f88SJack F Vogel  *
19839ca4041bSJack F Vogel  *  Acquires the SWFW semaphore thought the GSSR register for the specified
198413705f88SJack F Vogel  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
198513705f88SJack F Vogel  **/
198613705f88SJack F Vogel s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
198713705f88SJack F Vogel {
198813705f88SJack F Vogel 	u32 gssr;
198913705f88SJack F Vogel 	u32 swmask = mask;
199013705f88SJack F Vogel 	u32 fwmask = mask << 5;
199113705f88SJack F Vogel 	s32 timeout = 200;
199213705f88SJack F Vogel 
199313705f88SJack F Vogel 	while (timeout) {
19940ac6dfecSJack F Vogel 		/*
19950ac6dfecSJack F Vogel 		 * SW EEPROM semaphore bit is used for access to all
19960ac6dfecSJack F Vogel 		 * SW_FW_SYNC/GSSR bits (not just EEPROM)
19970ac6dfecSJack F Vogel 		 */
199813705f88SJack F Vogel 		if (ixgbe_get_eeprom_semaphore(hw))
199913705f88SJack F Vogel 			return -IXGBE_ERR_SWFW_SYNC;
200013705f88SJack F Vogel 
200113705f88SJack F Vogel 		gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
200213705f88SJack F Vogel 		if (!(gssr & (fwmask | swmask)))
200313705f88SJack F Vogel 			break;
200413705f88SJack F Vogel 
200513705f88SJack F Vogel 		/*
200613705f88SJack F Vogel 		 * Firmware currently using resource (fwmask) or other software
200713705f88SJack F Vogel 		 * thread currently using resource (swmask)
200813705f88SJack F Vogel 		 */
200913705f88SJack F Vogel 		ixgbe_release_eeprom_semaphore(hw);
201013705f88SJack F Vogel 		msec_delay(5);
201113705f88SJack F Vogel 		timeout--;
201213705f88SJack F Vogel 	}
201313705f88SJack F Vogel 
201413705f88SJack F Vogel 	if (!timeout) {
20150ac6dfecSJack F Vogel 		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
201613705f88SJack F Vogel 		return -IXGBE_ERR_SWFW_SYNC;
201713705f88SJack F Vogel 	}
201813705f88SJack F Vogel 
201913705f88SJack F Vogel 	gssr |= swmask;
202013705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
202113705f88SJack F Vogel 
202213705f88SJack F Vogel 	ixgbe_release_eeprom_semaphore(hw);
202313705f88SJack F Vogel 	return IXGBE_SUCCESS;
202413705f88SJack F Vogel }
202513705f88SJack F Vogel 
202613705f88SJack F Vogel /**
202713705f88SJack F Vogel  *  ixgbe_release_swfw_sync - Release SWFW semaphore
202813705f88SJack F Vogel  *  @hw: pointer to hardware structure
20299ca4041bSJack F Vogel  *  @mask: Mask to specify which semaphore to release
203013705f88SJack F Vogel  *
20319ca4041bSJack F Vogel  *  Releases the SWFW semaphore thought the GSSR register for the specified
203213705f88SJack F Vogel  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
203313705f88SJack F Vogel  **/
203413705f88SJack F Vogel void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
203513705f88SJack F Vogel {
203613705f88SJack F Vogel 	u32 gssr;
203713705f88SJack F Vogel 	u32 swmask = mask;
203813705f88SJack F Vogel 
203913705f88SJack F Vogel 	ixgbe_get_eeprom_semaphore(hw);
204013705f88SJack F Vogel 
204113705f88SJack F Vogel 	gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
204213705f88SJack F Vogel 	gssr &= ~swmask;
204313705f88SJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
204413705f88SJack F Vogel 
204513705f88SJack F Vogel 	ixgbe_release_eeprom_semaphore(hw);
20460ac6dfecSJack F Vogel 
20470ac6dfecSJack F Vogel 	/* Delay before attempt to obtain semaphore again to allow FW access */
20480ac6dfecSJack F Vogel 	msec_delay(hw->eeprom.semaphore_delay);
20490ac6dfecSJack F Vogel }
20500ac6dfecSJack F Vogel 
20510ac6dfecSJack F Vogel /**
20520ac6dfecSJack F Vogel  *  ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
20530ac6dfecSJack F Vogel  *  @hw: pointer to hardware structure
20540ac6dfecSJack F Vogel  *  @regval: register value to write to RXCTRL
20550ac6dfecSJack F Vogel  *
20560ac6dfecSJack F Vogel  *  Enables the Rx DMA unit
20570ac6dfecSJack F Vogel  **/
20580ac6dfecSJack F Vogel s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
20590ac6dfecSJack F Vogel {
20600ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
20610ac6dfecSJack F Vogel 
20620ac6dfecSJack F Vogel 	return IXGBE_SUCCESS;
20630ac6dfecSJack F Vogel }
20640ac6dfecSJack F Vogel 
20650ac6dfecSJack F Vogel /**
20660ac6dfecSJack F Vogel  *  ixgbe_blink_led_start_generic - Blink LED based on index.
20670ac6dfecSJack F Vogel  *  @hw: pointer to hardware structure
20680ac6dfecSJack F Vogel  *  @index: led number to blink
20690ac6dfecSJack F Vogel  **/
20700ac6dfecSJack F Vogel s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
20710ac6dfecSJack F Vogel {
20720ac6dfecSJack F Vogel 	ixgbe_link_speed speed = 0;
20730ac6dfecSJack F Vogel 	bool link_up = 0;
20740ac6dfecSJack F Vogel 	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
20750ac6dfecSJack F Vogel 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
20760ac6dfecSJack F Vogel 
20770ac6dfecSJack F Vogel 	/*
20780ac6dfecSJack F Vogel 	 * Link must be up to auto-blink the LEDs;
20790ac6dfecSJack F Vogel 	 * Force it if link is down.
20800ac6dfecSJack F Vogel 	 */
20810ac6dfecSJack F Vogel 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
20820ac6dfecSJack F Vogel 
20830ac6dfecSJack F Vogel 	if (!link_up) {
20840ac6dfecSJack F Vogel 		autoc_reg |= IXGBE_AUTOC_FLU;
20850ac6dfecSJack F Vogel 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
20860ac6dfecSJack F Vogel 		msec_delay(10);
20870ac6dfecSJack F Vogel 	}
20880ac6dfecSJack F Vogel 
20890ac6dfecSJack F Vogel 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
20900ac6dfecSJack F Vogel 	led_reg |= IXGBE_LED_BLINK(index);
20910ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
20920ac6dfecSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
20930ac6dfecSJack F Vogel 
20940ac6dfecSJack F Vogel 	return IXGBE_SUCCESS;
20950ac6dfecSJack F Vogel }
20960ac6dfecSJack F Vogel 
20970ac6dfecSJack F Vogel /**
20980ac6dfecSJack F Vogel  *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
20990ac6dfecSJack F Vogel  *  @hw: pointer to hardware structure
21000ac6dfecSJack F Vogel  *  @index: led number to stop blinking
21010ac6dfecSJack F Vogel  **/
21020ac6dfecSJack F Vogel s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
21030ac6dfecSJack F Vogel {
21040ac6dfecSJack F Vogel 	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
21050ac6dfecSJack F Vogel 	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
21060ac6dfecSJack F Vogel 
21070ac6dfecSJack F Vogel 	autoc_reg &= ~IXGBE_AUTOC_FLU;
21080ac6dfecSJack F Vogel 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
21090ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
21100ac6dfecSJack F Vogel 
21110ac6dfecSJack F Vogel 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
21120ac6dfecSJack F Vogel 	led_reg &= ~IXGBE_LED_BLINK(index);
21130ac6dfecSJack F Vogel 	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
21140ac6dfecSJack F Vogel 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
21150ac6dfecSJack F Vogel 	IXGBE_WRITE_FLUSH(hw);
21160ac6dfecSJack F Vogel 
21170ac6dfecSJack F Vogel 	return IXGBE_SUCCESS;
211813705f88SJack F Vogel }
211913705f88SJack F Vogel 
2120