| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | /*******************************************************************************
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Intel 10 Gigabit PCI Express Linux driver | 
					
						
							| 
									
										
										
										
											2013-01-08 05:02:28 +00:00
										 |  |  |   Copyright(c) 1999 - 2013 Intel Corporation. | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   This program is free software; you can redistribute it and/or modify it | 
					
						
							|  |  |  |   under the terms and conditions of the GNU General Public License, | 
					
						
							|  |  |  |   version 2, as published by the Free Software Foundation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   This program is distributed in the hope it will be useful, but WITHOUT | 
					
						
							|  |  |  |   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
					
						
							|  |  |  |   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
					
						
							|  |  |  |   more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   You should have received a copy of the GNU General Public License along with | 
					
						
							|  |  |  |   this program; if not, write to the Free Software Foundation, Inc., | 
					
						
							|  |  |  |   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   The full GNU General Public License is included in this distribution in | 
					
						
							|  |  |  |   the file called "COPYING". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Contact Information: | 
					
						
							|  |  |  |   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | 
					
						
							|  |  |  |   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | *******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/pci.h>
 | 
					
						
							|  |  |  | #include <linux/delay.h>
 | 
					
						
							|  |  |  | #include <linux/sched.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-29 10:46:24 -07:00
										 |  |  | #include "ixgbe.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | #include "ixgbe_phy.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define IXGBE_82598_MAX_TX_QUEUES 32
 | 
					
						
							|  |  |  | #define IXGBE_82598_MAX_RX_QUEUES 64
 | 
					
						
							|  |  |  | #define IXGBE_82598_RAR_ENTRIES   16
 | 
					
						
							| 
									
										
										
										
											2008-08-26 04:27:02 -07:00
										 |  |  | #define IXGBE_82598_MC_TBL_SIZE  128
 | 
					
						
							|  |  |  | #define IXGBE_82598_VFT_TBL_SIZE 128
 | 
					
						
							| 
									
										
										
										
											2011-04-04 04:29:41 +00:00
										 |  |  | #define IXGBE_82598_RX_PB_SIZE	 512
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  | static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, | 
					
						
							| 
									
										
										
										
											2010-05-13 17:33:41 +00:00
										 |  |  |                                          ixgbe_link_speed speed, | 
					
						
							|  |  |  |                                          bool autoneg_wait_to_complete); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, | 
					
						
							|  |  |  |                                        u8 *eeprom_data); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_set_pcie_completion_timeout - set pci-e completion timeout | 
					
						
							|  |  |  |  *  @hw: pointer to the HW structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  The defaults for 82598 should be in the range of 50us to 50ms, | 
					
						
							|  |  |  |  *  however the hardware default for these parts is 500us to 1ms which is less | 
					
						
							|  |  |  |  *  than the 10ms recommended by the pci-e spec.  To address this we need to | 
					
						
							|  |  |  |  *  increase the value to either 10ms to 250ms for capability version 1 config, | 
					
						
							|  |  |  |  *  or 16ms to 55ms for version 2. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-08-25 04:47:32 +00:00
										 |  |  | static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw) | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ixgbe_adapter *adapter = hw->back; | 
					
						
							|  |  |  | 	u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR); | 
					
						
							|  |  |  | 	u16 pcie_devctl2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* only take action if timeout value is defaulted to 0 */ | 
					
						
							|  |  |  | 	if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK) | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * if capababilities version is type 1 we can write the | 
					
						
							|  |  |  | 	 * timeout of 10ms to 250ms through the GCR register | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (!(gcr & IXGBE_GCR_CAP_VER2)) { | 
					
						
							|  |  |  | 		gcr |= IXGBE_GCR_CMPL_TMOUT_10ms; | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * for version 2 capabilities we need to write the config space | 
					
						
							|  |  |  | 	 * directly in order to set the completion timeout value for | 
					
						
							|  |  |  | 	 * 16ms to 55ms | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	pci_read_config_word(adapter->pdev, | 
					
						
							|  |  |  | 	                     IXGBE_PCI_DEVICE_CONTROL2, &pcie_devctl2); | 
					
						
							|  |  |  | 	pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms; | 
					
						
							|  |  |  | 	pci_write_config_word(adapter->pdev, | 
					
						
							|  |  |  | 	                      IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2); | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	/* disable completion timeout resend */ | 
					
						
							|  |  |  | 	gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND; | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ixgbe_mac_info *mac = &hw->mac; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Call PHY identify routine to get the phy type */ | 
					
						
							|  |  |  | 	ixgbe_identify_phy_generic(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mac->mcft_size = IXGBE_82598_MC_TBL_SIZE; | 
					
						
							|  |  |  | 	mac->vft_size = IXGBE_82598_VFT_TBL_SIZE; | 
					
						
							|  |  |  | 	mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES; | 
					
						
							|  |  |  | 	mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES; | 
					
						
							|  |  |  | 	mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES; | 
					
						
							| 
									
										
										
										
											2012-03-22 03:00:29 +00:00
										 |  |  | 	mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Initialize any function pointers that were not able to be | 
					
						
							|  |  |  |  *  set during get_invariants because the PHY/SFP type was | 
					
						
							|  |  |  |  *  not known.  Perform the SFP init if necessary. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-08-25 04:47:32 +00:00
										 |  |  | static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	struct ixgbe_mac_info *mac = &hw->mac; | 
					
						
							|  |  |  | 	struct ixgbe_phy_info *phy = &hw->phy; | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	s32 ret_val = 0; | 
					
						
							|  |  |  | 	u16 list_offset, data_offset; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	/* Identify the PHY */ | 
					
						
							|  |  |  | 	phy->ops.identify(hw); | 
					
						
							| 
									
										
										
										
											2009-03-19 01:23:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	/* Overwrite the link function pointers if copper PHY */ | 
					
						
							|  |  |  | 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { | 
					
						
							|  |  |  | 		mac->ops.setup_link = &ixgbe_setup_copper_link_82598; | 
					
						
							|  |  |  | 		mac->ops.get_link_capabilities = | 
					
						
							| 
									
										
										
										
											2010-11-16 19:27:15 -08:00
										 |  |  | 			&ixgbe_get_copper_link_capabilities_generic; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	switch (hw->phy.type) { | 
					
						
							| 
									
										
										
										
											2008-10-31 00:46:40 -07:00
										 |  |  | 	case ixgbe_phy_tn: | 
					
						
							| 
									
										
										
										
											2011-03-05 01:28:07 +00:00
										 |  |  | 		phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; | 
					
						
							| 
									
										
										
										
											2008-10-31 00:46:40 -07:00
										 |  |  | 		phy->ops.check_link = &ixgbe_check_phy_link_tnx; | 
					
						
							|  |  |  | 		phy->ops.get_firmware_version = | 
					
						
							|  |  |  | 		             &ixgbe_get_phy_firmware_version_tnx; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	case ixgbe_phy_nl: | 
					
						
							|  |  |  | 		phy->ops.reset = &ixgbe_reset_phy_nl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Call SFP+ identify routine to get the SFP+ module type */ | 
					
						
							|  |  |  | 		ret_val = phy->ops.identify_sfp(hw); | 
					
						
							|  |  |  | 		if (ret_val != 0) | 
					
						
							|  |  |  | 			goto out; | 
					
						
							|  |  |  | 		else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) { | 
					
						
							|  |  |  | 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; | 
					
						
							|  |  |  | 			goto out; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Check to see if SFP+ module is supported */ | 
					
						
							|  |  |  | 		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 		                                            &list_offset, | 
					
						
							|  |  |  | 		                                            &data_offset); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 		if (ret_val != 0) { | 
					
						
							|  |  |  | 			ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; | 
					
						
							|  |  |  | 			goto out; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | out: | 
					
						
							|  |  |  | 	return ret_val; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Starts the hardware using the generic start_hw function. | 
					
						
							| 
									
										
										
										
											2011-03-19 01:32:46 +00:00
										 |  |  |  *  Disables relaxed ordering Then set pcie completion timeout | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-08-25 04:47:32 +00:00
										 |  |  | static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-19 01:32:46 +00:00
										 |  |  | 	u32 regval; | 
					
						
							|  |  |  | 	u32 i; | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | 	s32 ret_val = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret_val = ixgbe_start_hw_generic(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-19 01:32:46 +00:00
										 |  |  | 	/* Disable relaxed ordering */ | 
					
						
							|  |  |  | 	for (i = 0; ((i < hw->mac.max_tx_queues) && | 
					
						
							|  |  |  | 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { | 
					
						
							|  |  |  | 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); | 
					
						
							| 
									
										
										
										
											2012-02-08 07:50:14 +00:00
										 |  |  | 		regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; | 
					
						
							| 
									
										
										
										
											2011-03-19 01:32:46 +00:00
										 |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; ((i < hw->mac.max_rx_queues) && | 
					
						
							|  |  |  | 	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { | 
					
						
							|  |  |  | 		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); | 
					
						
							| 
									
										
										
										
											2012-02-08 07:50:14 +00:00
										 |  |  | 		regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | | 
					
						
							|  |  |  | 			    IXGBE_DCA_RXCTRL_HEAD_WRO_EN); | 
					
						
							| 
									
										
										
										
											2011-03-19 01:32:46 +00:00
										 |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-04 04:29:41 +00:00
										 |  |  | 	hw->mac.rx_pb_size = IXGBE_82598_RX_PB_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | 	/* set the completion timeout for interface */ | 
					
						
							|  |  |  | 	if (ret_val == 0) | 
					
						
							|  |  |  | 		ixgbe_set_pcie_completion_timeout(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret_val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  |  *  ixgbe_get_link_capabilities_82598 - Determines link capabilities | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @speed: pointer to link speed | 
					
						
							|  |  |  |  *  @autoneg: boolean auto-negotiation value | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  |  *  Determines the link capabilities by reading the AUTOC register. | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, | 
					
						
							| 
									
										
										
										
											2008-09-11 20:04:46 -07:00
										 |  |  |                                              ixgbe_link_speed *speed, | 
					
						
							|  |  |  |                                              bool *autoneg) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	s32 status = 0; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:33 +00:00
										 |  |  | 	u32 autoc = 0; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Determine link capabilities based on the stored value of AUTOC, | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:33 +00:00
										 |  |  | 	 * which represents EEPROM defaults.  If AUTOC value has not been | 
					
						
							|  |  |  | 	 * stored, use the current register value. | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:33 +00:00
										 |  |  | 	if (hw->mac.orig_link_settings_stored) | 
					
						
							|  |  |  | 		autoc = hw->mac.orig_autoc; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (autoc & IXGBE_AUTOC_LMS_MASK) { | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: | 
					
						
							|  |  |  | 		*speed = IXGBE_LINK_SPEED_1GB_FULL; | 
					
						
							|  |  |  | 		*autoneg = false; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: | 
					
						
							|  |  |  | 		*speed = IXGBE_LINK_SPEED_10GB_FULL; | 
					
						
							|  |  |  | 		*autoneg = false; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_1G_AN: | 
					
						
							|  |  |  | 		*speed = IXGBE_LINK_SPEED_1GB_FULL; | 
					
						
							|  |  |  | 		*autoneg = true; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_KX4_AN: | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: | 
					
						
							|  |  |  | 		*speed = IXGBE_LINK_SPEED_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:33 +00:00
										 |  |  | 		if (autoc & IXGBE_AUTOC_KX4_SUPP) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 			*speed |= IXGBE_LINK_SPEED_10GB_FULL; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:33 +00:00
										 |  |  | 		if (autoc & IXGBE_AUTOC_KX_SUPP) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 			*speed |= IXGBE_LINK_SPEED_1GB_FULL; | 
					
						
							|  |  |  | 		*autoneg = true; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		status = IXGBE_ERR_LINK_SETUP; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_get_media_type_82598 - Determines media type | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Returns the media type (fiber, copper, backplane) | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	enum ixgbe_media_type media_type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  | 	/* Detect if there is a copper PHY attached. */ | 
					
						
							|  |  |  | 	switch (hw->phy.type) { | 
					
						
							|  |  |  | 	case ixgbe_phy_cu_unknown: | 
					
						
							|  |  |  | 	case ixgbe_phy_tn: | 
					
						
							|  |  |  | 		media_type = ixgbe_media_type_copper; | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	/* Media type for I82598 is based on device ID */ | 
					
						
							|  |  |  | 	switch (hw->device_id) { | 
					
						
							| 
									
										
										
										
											2009-01-26 20:57:51 -08:00
										 |  |  | 	case IXGBE_DEV_ID_82598: | 
					
						
							| 
									
										
										
										
											2009-02-01 01:18:23 -08:00
										 |  |  | 	case IXGBE_DEV_ID_82598_BX: | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  | 		/* Default device ID is mezzanine card KX/KX4 */ | 
					
						
							| 
									
										
										
										
											2009-01-26 20:57:51 -08:00
										 |  |  | 		media_type = ixgbe_media_type_backplane; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	case IXGBE_DEV_ID_82598AF_DUAL_PORT: | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT: | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT: | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: | 
					
						
							| 
									
										
										
										
											2008-09-11 19:58:59 -07:00
										 |  |  | 	case IXGBE_DEV_ID_82598EB_XF_LR: | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	case IXGBE_DEV_ID_82598EB_SFP_LOM: | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 		media_type = ixgbe_media_type_fiber; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-09-14 07:48:10 +00:00
										 |  |  | 	case IXGBE_DEV_ID_82598EB_CX4: | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: | 
					
						
							|  |  |  | 		media_type = ixgbe_media_type_cx4; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2008-10-31 00:46:40 -07:00
										 |  |  | 	case IXGBE_DEV_ID_82598AT: | 
					
						
							| 
									
										
										
										
											2009-07-16 15:50:52 +00:00
										 |  |  | 	case IXGBE_DEV_ID_82598AT2: | 
					
						
							| 
									
										
										
										
											2008-10-31 00:46:40 -07:00
										 |  |  | 		media_type = ixgbe_media_type_copper; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		media_type = ixgbe_media_type_unknown; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  | out: | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	return media_type; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  |  *  ixgbe_fc_enable_82598 - Enable flow control | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  |  *  Enable flow control according to the current settings. | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw) | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	s32 ret_val = 0; | 
					
						
							|  |  |  | 	u32 fctrl_reg; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	u32 rmcs_reg; | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	u32 reg; | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	u32 fcrtl, fcrth; | 
					
						
							| 
									
										
										
										
											2010-02-11 04:13:49 +00:00
										 |  |  | 	u32 link_speed = 0; | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2010-02-11 04:13:49 +00:00
										 |  |  | 	bool link_up; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Validate the water mark configuration for packet buffer 0.  Zero | 
					
						
							|  |  |  | 	 * water marks indicate that the packet buffer was not configured | 
					
						
							|  |  |  | 	 * and the watermarks for packet buffer 0 should always be configured. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (!hw->fc.low_water || | 
					
						
							|  |  |  | 	    !hw->fc.high_water[0] || | 
					
						
							|  |  |  | 	    !hw->fc.pause_time) { | 
					
						
							|  |  |  | 		hw_dbg(hw, "Invalid water mark configuration\n"); | 
					
						
							|  |  |  | 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 		goto out; | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-11 04:13:49 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * On 82598 having Rx FC on causes resets while doing 1G | 
					
						
							|  |  |  | 	 * so if it's on turn it off once we know link_speed. For | 
					
						
							|  |  |  | 	 * more details see 82598 Specification update. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false); | 
					
						
							|  |  |  | 	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) { | 
					
						
							|  |  |  | 		switch (hw->fc.requested_mode) { | 
					
						
							|  |  |  | 		case ixgbe_fc_full: | 
					
						
							|  |  |  | 			hw->fc.requested_mode = ixgbe_fc_tx_pause; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case ixgbe_fc_rx_pause: | 
					
						
							|  |  |  | 			hw->fc.requested_mode = ixgbe_fc_none; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			/* no change */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 	/* Negotiate the fc mode to use */ | 
					
						
							| 
									
										
										
										
											2012-03-28 08:03:48 +00:00
										 |  |  | 	ixgbe_fc_autoneg(hw); | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Disable any previous flow control settings */ | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | 
					
						
							|  |  |  | 	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | 
					
						
							|  |  |  | 	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	 * The possible values of fc.current_mode are: | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	 * 0: Flow control is completely disabled | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	 * 1: Rx flow control is enabled (we can receive pause frames, | 
					
						
							|  |  |  | 	 *    but not send pause frames). | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 	 * 2: Tx flow control is enabled (we can send pause frames but | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	 *     we do not support receiving pause frames). | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	 * 3: Both Rx and Tx flow control (symmetric) are enabled. | 
					
						
							| 
									
										
										
										
											2011-02-26 06:40:16 +00:00
										 |  |  | 	 * other: Invalid. | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	switch (hw->fc.current_mode) { | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	case ixgbe_fc_none: | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Flow control is disabled by software override or autoneg. | 
					
						
							|  |  |  | 		 * The code below will actually disable it in the HW. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case ixgbe_fc_rx_pause: | 
					
						
							|  |  |  | 		/*
 | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 		 * Rx Flow control is enabled and Tx Flow control is | 
					
						
							|  |  |  | 		 * disabled by software override. Since there really | 
					
						
							|  |  |  | 		 * isn't a way to advertise that we are capable of RX | 
					
						
							|  |  |  | 		 * Pause ONLY, we will advertise that we support both | 
					
						
							|  |  |  | 		 * symmetric and asymmetric Rx PAUSE.  Later, we will | 
					
						
							|  |  |  | 		 * disable the adapter's ability to send PAUSE frames. | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 		fctrl_reg |= IXGBE_FCTRL_RFCE; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case ixgbe_fc_tx_pause: | 
					
						
							|  |  |  | 		/*
 | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 		 * Tx Flow control is enabled, and Rx Flow control is | 
					
						
							|  |  |  | 		 * disabled by software override. | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		 */ | 
					
						
							|  |  |  | 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ixgbe_fc_full: | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 		/* Flow control (both Rx and Tx) is enabled by SW override. */ | 
					
						
							|  |  |  | 		fctrl_reg |= IXGBE_FCTRL_RFCE; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		hw_dbg(hw, "Flow control param set incorrectly\n"); | 
					
						
							| 
									
										
										
										
											2009-09-30 12:07:38 +00:00
										 |  |  | 		ret_val = IXGBE_ERR_CONFIG; | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 		goto out; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 	/* Set 802.3x based flow control settings. */ | 
					
						
							| 
									
										
										
										
											2009-04-09 22:26:21 +00:00
										 |  |  | 	fctrl_reg |= IXGBE_FCTRL_DPF; | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE; | 
					
						
							| 
									
										
										
										
											2010-11-16 19:26:44 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */ | 
					
						
							|  |  |  | 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 
					
						
							|  |  |  | 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && | 
					
						
							|  |  |  | 		    hw->fc.high_water[i]) { | 
					
						
							|  |  |  | 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 	/* Configure pause time (2 TCs per register) */ | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	reg = hw->fc.pause_time * 0x00010001; | 
					
						
							|  |  |  | 	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) | 
					
						
							|  |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 17:48:48 +00:00
										 |  |  | 	/* Configure flow control refresh threshold value */ | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-06 21:46:54 -08:00
										 |  |  | out: | 
					
						
							|  |  |  | 	return ret_val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  |  *  ixgbe_start_mac_link_82598 - Configures MAC link settings | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Configures link settings based on values in the ixgbe_hw struct. | 
					
						
							|  |  |  |  *  Restarts the link.  Performs autonegotiation if needed. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  | static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, | 
					
						
							|  |  |  |                                       bool autoneg_wait_to_complete) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32 autoc_reg; | 
					
						
							|  |  |  | 	u32 links_reg; | 
					
						
							|  |  |  | 	u32 i; | 
					
						
							|  |  |  | 	s32 status = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Restart link */ | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Only poll for autoneg to complete if specified to do so */ | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  | 	if (autoneg_wait_to_complete) { | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == | 
					
						
							|  |  |  | 		     IXGBE_AUTOC_LMS_KX4_AN || | 
					
						
							|  |  |  | 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) == | 
					
						
							|  |  |  | 		     IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 			links_reg = 0; /* Just in case Autoneg time = 0 */ | 
					
						
							|  |  |  | 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { | 
					
						
							|  |  |  | 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
					
						
							|  |  |  | 				if (links_reg & IXGBE_LINKS_KX_AN_COMP) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				msleep(100); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { | 
					
						
							|  |  |  | 				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 				hw_dbg(hw, "Autonegotiation did not complete.\n"); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Add delay to filter out noises during initial link setup */ | 
					
						
							|  |  |  | 	msleep(50); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 11:57:20 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_validate_link_ready - Function looks for phy link | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Function indicates success when phy link is available. If phy is not ready | 
					
						
							|  |  |  |  *  within 5 seconds of MAC indicating link, the function returns error. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 timeout; | 
					
						
							|  |  |  | 	u16 an_reg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hw->device_id != IXGBE_DEV_ID_82598AT2) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (timeout = 0; | 
					
						
							|  |  |  | 	     timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) { | 
					
						
							|  |  |  | 		hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, &an_reg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((an_reg & MDIO_AN_STAT1_COMPLETE) && | 
					
						
							|  |  |  | 		    (an_reg & MDIO_STAT1_LSTATUS)) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		msleep(100); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) { | 
					
						
							|  |  |  | 		hw_dbg(hw, "Link was indicated but link is down\n"); | 
					
						
							|  |  |  | 		return IXGBE_ERR_LINK_SETUP; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_check_mac_link_82598 - Get link/speed status | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @speed: pointer to link speed | 
					
						
							|  |  |  |  *  @link_up: true is link is up, false otherwise | 
					
						
							| 
									
										
										
										
											2008-09-11 19:55:32 -07:00
										 |  |  |  *  @link_up_wait_to_complete: bool used to wait for link up or not | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  Reads the links register to determine if link is up and the current speed | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2008-09-11 20:04:46 -07:00
										 |  |  | static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, | 
					
						
							|  |  |  |                                       ixgbe_link_speed *speed, bool *link_up, | 
					
						
							|  |  |  |                                       bool link_up_wait_to_complete) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32 links_reg; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:55:32 -07:00
										 |  |  | 	u32 i; | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	u16 link_reg, adapt_comp_reg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * SERDES PHY requires us to read link status from register 0xC79F. | 
					
						
							|  |  |  | 	 * Bit 0 set indicates link is up/ready; clear indicates link down. | 
					
						
							|  |  |  | 	 * 0xC00C is read to check that the XAUI lanes are active.  Bit 0 | 
					
						
							|  |  |  | 	 * clear indicates active; set indicates inactive. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (hw->phy.type == ixgbe_phy_nl) { | 
					
						
							| 
									
										
										
										
											2009-04-29 08:08:58 +00:00
										 |  |  | 		hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); | 
					
						
							|  |  |  | 		hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); | 
					
						
							|  |  |  | 		hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD, | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 		                     &adapt_comp_reg); | 
					
						
							|  |  |  | 		if (link_up_wait_to_complete) { | 
					
						
							|  |  |  | 			for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { | 
					
						
							|  |  |  | 				if ((link_reg & 1) && | 
					
						
							|  |  |  | 				    ((adapt_comp_reg & 1) == 0)) { | 
					
						
							|  |  |  | 					*link_up = true; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					*link_up = false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				msleep(100); | 
					
						
							|  |  |  | 				hw->phy.ops.read_reg(hw, 0xC79F, | 
					
						
							| 
									
										
										
										
											2009-04-29 08:08:58 +00:00
										 |  |  | 				                     MDIO_MMD_PMAPMD, | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 				                     &link_reg); | 
					
						
							|  |  |  | 				hw->phy.ops.read_reg(hw, 0xC00C, | 
					
						
							| 
									
										
										
										
											2009-04-29 08:08:58 +00:00
										 |  |  | 				                     MDIO_MMD_PMAPMD, | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 				                     &adapt_comp_reg); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0)) | 
					
						
							|  |  |  | 				*link_up = true; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				*link_up = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 11:17:23 +00:00
										 |  |  | 		if (!*link_up) | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 			goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
					
						
							| 
									
										
										
										
											2008-09-11 19:55:32 -07:00
										 |  |  | 	if (link_up_wait_to_complete) { | 
					
						
							|  |  |  | 		for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { | 
					
						
							|  |  |  | 			if (links_reg & IXGBE_LINKS_UP) { | 
					
						
							|  |  |  | 				*link_up = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				*link_up = false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			msleep(100); | 
					
						
							|  |  |  | 			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (links_reg & IXGBE_LINKS_UP) | 
					
						
							|  |  |  | 			*link_up = true; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			*link_up = false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (links_reg & IXGBE_LINKS_SPEED) | 
					
						
							|  |  |  | 		*speed = IXGBE_LINK_SPEED_10GB_FULL; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		*speed = IXGBE_LINK_SPEED_1GB_FULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 11:17:23 +00:00
										 |  |  | 	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && *link_up && | 
					
						
							| 
									
										
										
										
											2009-12-15 11:57:20 +00:00
										 |  |  | 	    (ixgbe_validate_link_ready(hw) != 0)) | 
					
						
							|  |  |  | 		*link_up = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | out: | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  |  *  ixgbe_setup_mac_link_82598 - Set MAC link speed | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @speed: new link speed | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  |  *  @autoneg_wait_to_complete: true when waiting for completion is needed | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  Set the link speed in the AUTOC register and restarts link. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  | static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, | 
					
						
							| 
									
										
										
										
											2012-12-15 03:28:30 +00:00
										 |  |  | 				      ixgbe_link_speed speed, | 
					
						
							|  |  |  | 				      bool autoneg_wait_to_complete) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-15 03:28:30 +00:00
										 |  |  | 	bool		 autoneg	   = false; | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	s32              status            = 0; | 
					
						
							|  |  |  | 	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; | 
					
						
							|  |  |  | 	u32              curr_autoc        = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
					
						
							|  |  |  | 	u32              autoc             = curr_autoc; | 
					
						
							|  |  |  | 	u32              link_mode         = autoc & IXGBE_AUTOC_LMS_MASK; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	/* Check to see if speed passed in is supported. */ | 
					
						
							|  |  |  | 	ixgbe_get_link_capabilities_82598(hw, &link_capabilities, &autoneg); | 
					
						
							|  |  |  | 	speed &= link_capabilities; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (speed == IXGBE_LINK_SPEED_UNKNOWN) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 		status = IXGBE_ERR_LINK_SETUP; | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Set KX4/KX support according to speed requested */ | 
					
						
							|  |  |  | 	else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || | 
					
						
							|  |  |  | 	         link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | 
					
						
							|  |  |  | 		autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK; | 
					
						
							|  |  |  | 		if (speed & IXGBE_LINK_SPEED_10GB_FULL) | 
					
						
							|  |  |  | 			autoc |= IXGBE_AUTOC_KX4_SUPP; | 
					
						
							|  |  |  | 		if (speed & IXGBE_LINK_SPEED_1GB_FULL) | 
					
						
							|  |  |  | 			autoc |= IXGBE_AUTOC_KX_SUPP; | 
					
						
							|  |  |  | 		if (autoc != curr_autoc) | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (status == 0) { | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Setup and restart the link based on the new values in | 
					
						
							|  |  |  | 		 * ixgbe_hw This will write the AUTOC register based on the new | 
					
						
							|  |  |  | 		 * stored values | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  | 		status = ixgbe_start_mac_link_82598(hw, | 
					
						
							|  |  |  | 						    autoneg_wait_to_complete); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  |  *  ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @speed: new link speed | 
					
						
							|  |  |  |  *  @autoneg_wait_to_complete: true if waiting is needed to complete | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Sets the link speed in the AUTOC register in the MAC and restarts link. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  | static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, | 
					
						
							| 
									
										
										
										
											2008-09-11 20:04:46 -07:00
										 |  |  |                                                ixgbe_link_speed speed, | 
					
						
							|  |  |  |                                                bool autoneg_wait_to_complete) | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	s32 status; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup the PHY according to input speed */ | 
					
						
							| 
									
										
										
										
											2012-12-15 03:28:24 +00:00
										 |  |  | 	status = hw->phy.ops.setup_link_speed(hw, speed, | 
					
						
							| 
									
										
										
										
											2008-09-11 20:04:46 -07:00
										 |  |  | 	                                      autoneg_wait_to_complete); | 
					
						
							| 
									
										
										
										
											2007-10-31 15:22:10 -07:00
										 |  |  | 	/* Set up MAC */ | 
					
						
							| 
									
										
										
										
											2009-09-01 13:49:35 +00:00
										 |  |  | 	ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_reset_hw_82598 - Performs hardware reset | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  |  *  Resets the hardware by resetting the transmit and receive units, masks and | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  |  *  clears all interrupts, performing a PHY reset, and performing a link (MAC) | 
					
						
							|  |  |  |  *  reset. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	s32 status = 0; | 
					
						
							| 
									
										
										
										
											2009-05-26 20:40:47 -07:00
										 |  |  | 	s32 phy_status = 0; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	u32 ctrl; | 
					
						
							|  |  |  | 	u32 gheccr; | 
					
						
							|  |  |  | 	u32 i; | 
					
						
							|  |  |  | 	u32 autoc; | 
					
						
							|  |  |  | 	u8  analog_val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Call adapter stop to disable tx/rx and clear interrupts */ | 
					
						
							| 
									
										
										
										
											2011-08-16 04:35:11 +00:00
										 |  |  | 	status = hw->mac.ops.stop_adapter(hw); | 
					
						
							|  |  |  | 	if (status != 0) | 
					
						
							|  |  |  | 		goto reset_hw_out; | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	 * Power up the Atlas Tx lanes if they are currently powered down. | 
					
						
							|  |  |  | 	 * Atlas Tx lanes are powered down for MAC loopback tests, but | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	 * they are not automatically restored on reset. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) { | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		/* Enable Tx Atlas so packets can be transmitted again */ | 
					
						
							|  |  |  | 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, | 
					
						
							|  |  |  | 		                             &analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 		analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, | 
					
						
							|  |  |  | 		                              analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, | 
					
						
							|  |  |  | 		                             &analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 		analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, | 
					
						
							|  |  |  | 		                              analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, | 
					
						
							|  |  |  | 		                             &analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 		analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, | 
					
						
							|  |  |  | 		                              analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, | 
					
						
							|  |  |  | 		                             &analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 		analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, | 
					
						
							|  |  |  | 		                              analog_val); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Reset PHY */ | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	if (hw->phy.reset_disable == false) { | 
					
						
							|  |  |  | 		/* PHY ops must be identified and initialized prior to reset */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Init PHY and function pointers, perform SFP setup */ | 
					
						
							| 
									
										
										
										
											2009-05-26 20:40:47 -07:00
										 |  |  | 		phy_status = hw->phy.ops.init(hw); | 
					
						
							|  |  |  | 		if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 			goto reset_hw_out; | 
					
						
							| 
									
										
										
										
											2011-08-16 04:35:11 +00:00
										 |  |  | 		if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) | 
					
						
							|  |  |  | 			goto mac_reset_top; | 
					
						
							| 
									
										
										
										
											2009-05-26 20:40:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw->phy.ops.reset(hw); | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 08:45:13 +00:00
										 |  |  | mac_reset_top: | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Issue global reset to the MAC.  This needs to be a SW reset. | 
					
						
							|  |  |  | 	 * If link reset is used, it might reset the MAC when mng is using it | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2011-07-15 07:29:44 +00:00
										 |  |  | 	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST; | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	IXGBE_WRITE_FLUSH(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Poll for reset bit to self-clear indicating reset is complete */ | 
					
						
							|  |  |  | 	for (i = 0; i < 10; i++) { | 
					
						
							|  |  |  | 		udelay(1); | 
					
						
							|  |  |  | 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 
					
						
							|  |  |  | 		if (!(ctrl & IXGBE_CTRL_RST)) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ctrl & IXGBE_CTRL_RST) { | 
					
						
							|  |  |  | 		status = IXGBE_ERR_RESET_FAILED; | 
					
						
							|  |  |  | 		hw_dbg(hw, "Reset polling failed to complete.\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-15 07:29:44 +00:00
										 |  |  | 	msleep(50); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 08:45:13 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Double resets are required for recovery from certain error | 
					
						
							|  |  |  | 	 * conditions.  Between resets, it is necessary to stall to allow time | 
					
						
							| 
									
										
										
										
											2011-07-15 07:29:44 +00:00
										 |  |  | 	 * for any pending HW events to complete. | 
					
						
							| 
									
										
										
										
											2011-02-14 08:45:13 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { | 
					
						
							|  |  |  | 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; | 
					
						
							|  |  |  | 		goto mac_reset_top; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); | 
					
						
							|  |  |  | 	gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6)); | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	 * Store the original AUTOC value if it has not been | 
					
						
							|  |  |  | 	 * stored off yet.  Otherwise restore the stored original | 
					
						
							|  |  |  | 	 * AUTOC value since the reset operation sets back to deaults. | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
					
						
							| 
									
										
										
										
											2009-02-05 23:54:21 -08:00
										 |  |  | 	if (hw->mac.orig_link_settings_stored == false) { | 
					
						
							|  |  |  | 		hw->mac.orig_autoc = autoc; | 
					
						
							|  |  |  | 		hw->mac.orig_link_settings_stored = true; | 
					
						
							|  |  |  | 	} else if (autoc != hw->mac.orig_autoc) { | 
					
						
							|  |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-19 08:43:49 +00:00
										 |  |  | 	/* Store the permanent mac address */ | 
					
						
							|  |  |  | 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-17 12:32:48 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Store MAC address from RAR0, clear receive address registers, and | 
					
						
							|  |  |  | 	 * clear the multicast table | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	hw->mac.ops.init_rx_addrs(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | reset_hw_out: | 
					
						
							| 
									
										
										
										
											2009-05-26 20:40:47 -07:00
										 |  |  | 	if (phy_status) | 
					
						
							|  |  |  | 		status = phy_status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address | 
					
						
							|  |  |  |  *  @hw: pointer to hardware struct | 
					
						
							|  |  |  |  *  @rar: receive address register index to associate with a VMDq index | 
					
						
							|  |  |  |  *  @vmdq: VMDq set index | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2008-12-26 00:03:59 -08:00
										 |  |  | static s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32 rar_high; | 
					
						
							| 
									
										
										
										
											2011-02-17 11:34:58 +00:00
										 |  |  | 	u32 rar_entries = hw->mac.num_rar_entries; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Make sure we are using a valid rar index range */ | 
					
						
							|  |  |  | 	if (rar >= rar_entries) { | 
					
						
							|  |  |  | 		hw_dbg(hw, "RAR index %d is out of range.\n", rar); | 
					
						
							|  |  |  | 		return IXGBE_ERR_INVALID_ARGUMENT; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); | 
					
						
							|  |  |  | 	rar_high &= ~IXGBE_RAH_VIND_MASK; | 
					
						
							|  |  |  | 	rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK); | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address | 
					
						
							|  |  |  |  *  @hw: pointer to hardware struct | 
					
						
							|  |  |  |  *  @rar: receive address register index to associate with a VMDq index | 
					
						
							|  |  |  |  *  @vmdq: VMDq clear index (not used in 82598, but elsewhere) | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 rar_high; | 
					
						
							|  |  |  | 	u32 rar_entries = hw->mac.num_rar_entries; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-17 11:34:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Make sure we are using a valid rar index range */ | 
					
						
							|  |  |  | 	if (rar >= rar_entries) { | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		hw_dbg(hw, "RAR index %d is out of range.\n", rar); | 
					
						
							| 
									
										
										
										
											2011-02-17 11:34:58 +00:00
										 |  |  | 		return IXGBE_ERR_INVALID_ARGUMENT; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); | 
					
						
							|  |  |  | 	if (rar_high & IXGBE_RAH_VIND_MASK) { | 
					
						
							|  |  |  | 		rar_high &= ~IXGBE_RAH_VIND_MASK; | 
					
						
							|  |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_set_vfta_82598 - Set VLAN filter table | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @vlan: VLAN id to write to VLAN filter | 
					
						
							|  |  |  |  *  @vind: VMDq output index that maps queue to VLAN id in VFTA | 
					
						
							|  |  |  |  *  @vlan_on: boolean flag to turn on/off VLAN in VFTA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Turn on/off specified VLAN in the VLAN filter table. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2008-12-26 00:03:59 -08:00
										 |  |  | static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, | 
					
						
							|  |  |  | 				bool vlan_on) | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32 regindex; | 
					
						
							|  |  |  | 	u32 bitindex; | 
					
						
							|  |  |  | 	u32 bits; | 
					
						
							|  |  |  | 	u32 vftabyte; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (vlan > 4095) | 
					
						
							|  |  |  | 		return IXGBE_ERR_PARAM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Determine 32-bit word position in array */ | 
					
						
							|  |  |  | 	regindex = (vlan >> 5) & 0x7F;   /* upper seven bits */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Determine the location of the (VMD) queue index */ | 
					
						
							|  |  |  | 	vftabyte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */ | 
					
						
							|  |  |  | 	bitindex = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set the nibble for VMD queue index */ | 
					
						
							|  |  |  | 	bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex)); | 
					
						
							|  |  |  | 	bits &= (~(0x0F << bitindex)); | 
					
						
							|  |  |  | 	bits |= (vind << bitindex); | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Determine the location of the bit for this VLAN id */ | 
					
						
							|  |  |  | 	bitindex = vlan & 0x1F;   /* lower five bits */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); | 
					
						
							|  |  |  | 	if (vlan_on) | 
					
						
							|  |  |  | 		/* Turn on this VLAN id */ | 
					
						
							|  |  |  | 		bits |= (1 << bitindex); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		/* Turn off this VLAN id */ | 
					
						
							|  |  |  | 		bits &= ~(1 << bitindex); | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_clear_vfta_82598 - Clear VLAN filter table | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Clears the VLAN filer table, and the VMDq index associated with the filter | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 offset; | 
					
						
							|  |  |  | 	u32 vlanbyte; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (offset = 0; offset < hw->mac.vft_size; offset++) | 
					
						
							|  |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) | 
					
						
							|  |  |  | 		for (offset = 0; offset < hw->mac.vft_size; offset++) | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), | 
					
						
							| 
									
										
										
										
											2008-09-11 20:04:46 -07:00
										 |  |  | 			                0); | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @reg: analog register to read | 
					
						
							|  |  |  |  *  @val: read value | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Performs read operation to Atlas analog register specified. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2008-12-26 00:03:59 -08:00
										 |  |  | static s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val) | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32  atlas_ctl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, | 
					
						
							|  |  |  | 	                IXGBE_ATLASCTL_WRITE_CMD | (reg << 8)); | 
					
						
							|  |  |  | 	IXGBE_WRITE_FLUSH(hw); | 
					
						
							|  |  |  | 	udelay(10); | 
					
						
							|  |  |  | 	atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL); | 
					
						
							|  |  |  | 	*val = (u8)atlas_ctl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @reg: atlas register to write | 
					
						
							|  |  |  |  *  @val: value to write | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Performs write operation to Atlas analog register specified. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2008-12-26 00:03:59 -08:00
										 |  |  | static s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	u32  atlas_ctl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	atlas_ctl = (reg << 8) | val; | 
					
						
							|  |  |  | 	IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl); | 
					
						
							|  |  |  | 	IXGBE_WRITE_FLUSH(hw); | 
					
						
							|  |  |  | 	udelay(10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  |  *  ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface. | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  |  *  @hw: pointer to hardware structure | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  |  *  @dev_addr: address to read from | 
					
						
							|  |  |  |  *  @byte_offset: byte offset to read from dev_addr | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  |  *  @eeprom_data: value read | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  |  *  Performs 8 byte read operation to SFP module's data over I2C interface. | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  | static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr, | 
					
						
							|  |  |  | 				    u8 byte_offset, u8 *eeprom_data) | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	s32 status = 0; | 
					
						
							|  |  |  | 	u16 sfp_addr = 0; | 
					
						
							|  |  |  | 	u16 sfp_data = 0; | 
					
						
							|  |  |  | 	u16 sfp_stat = 0; | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 	u16 gssr; | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	u32 i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 	if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) | 
					
						
							|  |  |  | 		gssr = IXGBE_GSSR_PHY1_SM; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		gssr = IXGBE_GSSR_PHY0_SM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0) | 
					
						
							|  |  |  | 		return IXGBE_ERR_SWFW_SYNC; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	if (hw->phy.type == ixgbe_phy_nl) { | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * phy SDA/SCL registers are at addresses 0xC30A to | 
					
						
							|  |  |  | 		 * 0xC30D.  These registers are used to talk to the SFP+ | 
					
						
							|  |  |  | 		 * module's EEPROM through the SDA/SCL (I2C) interface. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  | 		sfp_addr = (dev_addr << 8) + byte_offset; | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK); | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 		hw->phy.ops.write_reg_mdi(hw, | 
					
						
							|  |  |  | 					  IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, | 
					
						
							|  |  |  | 					  MDIO_MMD_PMAPMD, | 
					
						
							|  |  |  | 					  sfp_addr); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* Poll status */ | 
					
						
							|  |  |  | 		for (i = 0; i < 100; i++) { | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 			hw->phy.ops.read_reg_mdi(hw, | 
					
						
							|  |  |  | 						IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT, | 
					
						
							|  |  |  | 						MDIO_MMD_PMAPMD, | 
					
						
							|  |  |  | 						&sfp_stat); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; | 
					
						
							|  |  |  | 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2011-03-18 09:32:53 +00:00
										 |  |  | 			usleep_range(10000, 20000); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { | 
					
						
							|  |  |  | 			hw_dbg(hw, "EEPROM read did not pass.\n"); | 
					
						
							|  |  |  | 			status = IXGBE_ERR_SFP_NOT_PRESENT; | 
					
						
							|  |  |  | 			goto out; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Read data */ | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 		hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA, | 
					
						
							|  |  |  | 					MDIO_MMD_PMAPMD, &sfp_data); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		*eeprom_data = (u8)(sfp_data >> 8); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		status = IXGBE_ERR_PHY; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 	hw->mac.ops.release_swfw_sync(hw, gssr); | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	return status; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface. | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @byte_offset: EEPROM byte offset to read | 
					
						
							|  |  |  |  *  @eeprom_data: value read | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, | 
					
						
							|  |  |  | 				       u8 *eeprom_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR, | 
					
						
							|  |  |  | 					byte_offset, eeprom_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface. | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  *  @byte_offset: byte offset at address 0xA2 | 
					
						
							|  |  |  |  *  @eeprom_data: value read | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Performs 8 byte read operation to SFP module's SFF-8472 data over I2C | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset, | 
					
						
							|  |  |  | 				       u8 *sff8472_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2, | 
					
						
							|  |  |  | 					byte_offset, sff8472_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type | 
					
						
							|  |  |  |  *  @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Determines physical layer capabilities of the current configuration. | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2009-02-27 15:44:30 +00:00
										 |  |  | static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-27 15:44:30 +00:00
										 |  |  | 	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 
					
						
							|  |  |  | 	u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; | 
					
						
							|  |  |  | 	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; | 
					
						
							|  |  |  | 	u16 ext_ability = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hw->phy.ops.identify(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Copper PHY must be checked before AUTOC LMS to determine correct
 | 
					
						
							|  |  |  | 	 * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  | 	switch (hw->phy.type) { | 
					
						
							|  |  |  | 	case ixgbe_phy_tn: | 
					
						
							|  |  |  | 	case ixgbe_phy_cu_unknown: | 
					
						
							|  |  |  | 		hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, | 
					
						
							|  |  |  | 		MDIO_MMD_PMAPMD, &ext_ability); | 
					
						
							| 
									
										
										
										
											2009-04-29 08:08:58 +00:00
										 |  |  | 		if (ext_ability & MDIO_PMA_EXTABLE_10GBT) | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; | 
					
						
							| 
									
										
										
										
											2009-04-29 08:08:58 +00:00
										 |  |  | 		if (ext_ability & MDIO_PMA_EXTABLE_1000BT) | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; | 
					
						
							| 
									
										
										
										
											2009-04-29 08:08:58 +00:00
										 |  |  | 		if (ext_ability & MDIO_PMA_EXTABLE_100BTX) | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; | 
					
						
							|  |  |  | 		goto out; | 
					
						
							| 
									
										
										
										
											2011-02-25 07:49:39 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	switch (autoc & IXGBE_AUTOC_LMS_MASK) { | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_1G_AN: | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: | 
					
						
							|  |  |  | 		if (pma_pmd_1g == IXGBE_AUTOC_1G_KX) | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX; | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: | 
					
						
							|  |  |  | 		if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4) | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; | 
					
						
							|  |  |  | 		else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4) | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; | 
					
						
							|  |  |  | 		else /* XAUI */ | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	case IXGBE_AUTOC_LMS_KX4_AN: | 
					
						
							|  |  |  | 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: | 
					
						
							|  |  |  | 		if (autoc & IXGBE_AUTOC_KX_SUPP) | 
					
						
							|  |  |  | 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; | 
					
						
							|  |  |  | 		if (autoc & IXGBE_AUTOC_KX4_SUPP) | 
					
						
							|  |  |  | 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2008-10-31 00:46:40 -07:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (hw->phy.type == ixgbe_phy_nl) { | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 		hw->phy.ops.identify_sfp(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch (hw->phy.sfp_type) { | 
					
						
							|  |  |  | 		case ixgbe_sfp_type_da_cu: | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case ixgbe_sfp_type_sr: | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case ixgbe_sfp_type_lr: | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | 	switch (hw->device_id) { | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT: | 
					
						
							|  |  |  | 		physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598AF_DUAL_PORT: | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT: | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: | 
					
						
							|  |  |  | 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case IXGBE_DEV_ID_82598EB_XF_LR: | 
					
						
							|  |  |  | 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-09 22:28:50 +00:00
										 |  |  | out: | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	return physical_layer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-16 01:55:55 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  *  ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple | 
					
						
							|  |  |  |  *  port devices. | 
					
						
							|  |  |  |  *  @hw: pointer to the HW structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Calls common function and corrects issue with some single port devices | 
					
						
							|  |  |  |  *  that enable LAN1 but not LAN0. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ixgbe_bus_info *bus = &hw->bus; | 
					
						
							|  |  |  | 	u16 pci_gen = 0; | 
					
						
							|  |  |  | 	u16 pci_ctrl2 = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ixgbe_set_lan_id_multi_port_pcie(hw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* check if LAN0 is disabled */ | 
					
						
							|  |  |  | 	hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen); | 
					
						
							|  |  |  | 	if ((pci_gen != 0) && (pci_gen != 0xFFFF)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* if LAN0 is completely disabled force function to 0 */ | 
					
						
							|  |  |  | 		if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) && | 
					
						
							|  |  |  | 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) && | 
					
						
							|  |  |  | 		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bus->func = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 12:34:10 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * ixgbe_set_rxpba_82598 - Configure packet buffers | 
					
						
							|  |  |  |  * @hw: pointer to hardware structure | 
					
						
							|  |  |  |  * @dcb_config: pointer to ixgbe_dcb_config structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Configure packet buffers. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb, u32 headroom, | 
					
						
							|  |  |  | 				  int strategy) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 rxpktsize = IXGBE_RXPBSIZE_64KB; | 
					
						
							|  |  |  | 	u8  i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!num_pb) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup Rx packet buffer sizes */ | 
					
						
							|  |  |  | 	switch (strategy) { | 
					
						
							|  |  |  | 	case PBA_STRATEGY_WEIGHTED: | 
					
						
							|  |  |  | 		/* Setup the first four at 80KB */ | 
					
						
							|  |  |  | 		rxpktsize = IXGBE_RXPBSIZE_80KB; | 
					
						
							|  |  |  | 		for (; i < 4; i++) | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); | 
					
						
							|  |  |  | 		/* Setup the last four at 48KB...don't re-init i */ | 
					
						
							|  |  |  | 		rxpktsize = IXGBE_RXPBSIZE_48KB; | 
					
						
							|  |  |  | 		/* Fall Through */ | 
					
						
							|  |  |  | 	case PBA_STRATEGY_EQUAL: | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		/* Divide the remaining Rx packet buffer evenly among the TCs */ | 
					
						
							|  |  |  | 		for (; i < IXGBE_MAX_PACKET_BUFFERS; i++) | 
					
						
							|  |  |  | 			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Setup Tx packet buffer sizes */ | 
					
						
							|  |  |  | 	for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) | 
					
						
							|  |  |  | 		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | static struct ixgbe_mac_operations mac_ops_82598 = { | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.init_hw		= &ixgbe_init_hw_generic, | 
					
						
							|  |  |  | 	.reset_hw		= &ixgbe_reset_hw_82598, | 
					
						
							| 
									
										
										
										
											2009-08-03 07:20:38 +00:00
										 |  |  | 	.start_hw		= &ixgbe_start_hw_82598, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.clear_hw_cntrs		= &ixgbe_clear_hw_cntrs_generic, | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	.get_media_type		= &ixgbe_get_media_type_82598, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598, | 
					
						
							| 
									
										
										
										
											2009-02-27 15:44:30 +00:00
										 |  |  | 	.enable_rx_dma          = &ixgbe_enable_rx_dma_generic, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.get_mac_addr		= &ixgbe_get_mac_addr_generic, | 
					
						
							|  |  |  | 	.stop_adapter		= &ixgbe_stop_adapter_generic, | 
					
						
							| 
									
										
										
										
											2009-02-27 15:44:30 +00:00
										 |  |  | 	.get_bus_info           = &ixgbe_get_bus_info_generic, | 
					
						
							| 
									
										
										
										
											2011-03-16 01:55:55 +00:00
										 |  |  | 	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie_82598, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.read_analog_reg8	= &ixgbe_read_analog_reg8_82598, | 
					
						
							|  |  |  | 	.write_analog_reg8	= &ixgbe_write_analog_reg8_82598, | 
					
						
							| 
									
										
										
										
											2007-10-31 15:22:10 -07:00
										 |  |  | 	.setup_link		= &ixgbe_setup_mac_link_82598, | 
					
						
							| 
									
										
										
										
											2011-05-02 12:34:10 +00:00
										 |  |  | 	.set_rxpba		= &ixgbe_set_rxpba_82598, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.check_link		= &ixgbe_check_mac_link_82598, | 
					
						
							|  |  |  | 	.get_link_capabilities	= &ixgbe_get_link_capabilities_82598, | 
					
						
							|  |  |  | 	.led_on			= &ixgbe_led_on_generic, | 
					
						
							|  |  |  | 	.led_off		= &ixgbe_led_off_generic, | 
					
						
							| 
									
										
										
										
											2009-04-08 13:20:31 +00:00
										 |  |  | 	.blink_led_start	= &ixgbe_blink_led_start_generic, | 
					
						
							|  |  |  | 	.blink_led_stop		= &ixgbe_blink_led_stop_generic, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.set_rar		= &ixgbe_set_rar_generic, | 
					
						
							|  |  |  | 	.clear_rar		= &ixgbe_clear_rar_generic, | 
					
						
							|  |  |  | 	.set_vmdq		= &ixgbe_set_vmdq_82598, | 
					
						
							|  |  |  | 	.clear_vmdq		= &ixgbe_clear_vmdq_82598, | 
					
						
							|  |  |  | 	.init_rx_addrs		= &ixgbe_init_rx_addrs_generic, | 
					
						
							|  |  |  | 	.update_mc_addr_list	= &ixgbe_update_mc_addr_list_generic, | 
					
						
							|  |  |  | 	.enable_mc		= &ixgbe_enable_mc_generic, | 
					
						
							|  |  |  | 	.disable_mc		= &ixgbe_disable_mc_generic, | 
					
						
							|  |  |  | 	.clear_vfta		= &ixgbe_clear_vfta_82598, | 
					
						
							|  |  |  | 	.set_vfta		= &ixgbe_set_vfta_82598, | 
					
						
							| 
									
										
										
										
											2009-06-04 11:11:13 +00:00
										 |  |  | 	.fc_enable		= &ixgbe_fc_enable_82598, | 
					
						
							| 
									
										
										
										
											2011-05-07 07:40:20 +00:00
										 |  |  | 	.set_fw_drv_ver         = NULL, | 
					
						
							| 
									
										
										
										
											2011-02-25 01:58:04 +00:00
										 |  |  | 	.acquire_swfw_sync      = &ixgbe_acquire_swfw_sync, | 
					
						
							|  |  |  | 	.release_swfw_sync      = &ixgbe_release_swfw_sync, | 
					
						
							| 
									
										
										
										
											2012-04-12 00:33:31 +00:00
										 |  |  | 	.get_thermal_sensor_data = NULL, | 
					
						
							|  |  |  | 	.init_thermal_sensor_thresh = NULL, | 
					
						
							| 
									
										
										
										
											2013-02-21 03:00:04 +00:00
										 |  |  | 	.mng_fw_enabled		= NULL, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ixgbe_eeprom_operations eeprom_ops_82598 = { | 
					
						
							|  |  |  | 	.init_params		= &ixgbe_init_eeprom_params_generic, | 
					
						
							| 
									
										
										
										
											2010-05-13 17:33:41 +00:00
										 |  |  | 	.read			= &ixgbe_read_eerd_generic, | 
					
						
							| 
									
										
										
										
											2011-10-06 08:57:04 +00:00
										 |  |  | 	.write			= &ixgbe_write_eeprom_generic, | 
					
						
							|  |  |  | 	.write_buffer		= &ixgbe_write_eeprom_buffer_bit_bang_generic, | 
					
						
							| 
									
										
										
										
											2011-04-20 08:49:06 +00:00
										 |  |  | 	.read_buffer		= &ixgbe_read_eerd_buffer_generic, | 
					
						
							| 
									
										
										
										
											2010-11-16 19:27:15 -08:00
										 |  |  | 	.calc_checksum          = &ixgbe_calc_eeprom_checksum_generic, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.validate_checksum	= &ixgbe_validate_eeprom_checksum_generic, | 
					
						
							|  |  |  | 	.update_checksum	= &ixgbe_update_eeprom_checksum_generic, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ixgbe_phy_operations phy_ops_82598 = { | 
					
						
							|  |  |  | 	.identify		= &ixgbe_identify_phy_generic, | 
					
						
							| 
									
										
										
										
											2013-07-27 06:25:38 +00:00
										 |  |  | 	.identify_sfp		= &ixgbe_identify_module_generic, | 
					
						
							| 
									
										
										
										
											2009-04-09 22:27:57 +00:00
										 |  |  | 	.init			= &ixgbe_init_phy_ops_82598, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.reset			= &ixgbe_reset_phy_generic, | 
					
						
							|  |  |  | 	.read_reg		= &ixgbe_read_phy_reg_generic, | 
					
						
							|  |  |  | 	.write_reg		= &ixgbe_write_phy_reg_generic, | 
					
						
							| 
									
										
										
										
											2013-05-29 06:23:05 +00:00
										 |  |  | 	.read_reg_mdi		= &ixgbe_read_phy_reg_mdi, | 
					
						
							|  |  |  | 	.write_reg_mdi		= &ixgbe_write_phy_reg_mdi, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.setup_link		= &ixgbe_setup_phy_link_generic, | 
					
						
							|  |  |  | 	.setup_link_speed	= &ixgbe_setup_phy_link_speed_generic, | 
					
						
							| 
									
										
										
										
											2012-12-19 07:14:17 +00:00
										 |  |  | 	.read_i2c_sff8472	= &ixgbe_read_i2c_sff8472_82598, | 
					
						
							| 
									
										
										
										
											2008-11-20 21:11:42 -08:00
										 |  |  | 	.read_i2c_eeprom	= &ixgbe_read_i2c_eeprom_82598, | 
					
						
							| 
									
										
										
										
											2010-05-20 23:07:06 -07:00
										 |  |  | 	.check_overtemp   = &ixgbe_tn_check_overtemp, | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-31 15:22:10 -07:00
										 |  |  | struct ixgbe_info ixgbe_82598_info = { | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | 	.mac			= ixgbe_mac_82598EB, | 
					
						
							|  |  |  | 	.get_invariants		= &ixgbe_get_invariants_82598, | 
					
						
							|  |  |  | 	.mac_ops		= &mac_ops_82598, | 
					
						
							| 
									
										
										
										
											2008-09-11 19:59:59 -07:00
										 |  |  | 	.eeprom_ops		= &eeprom_ops_82598, | 
					
						
							|  |  |  | 	.phy_ops		= &phy_ops_82598, | 
					
						
							| 
									
										
										
										
											2007-09-15 14:07:45 -07:00
										 |  |  | }; |