2009-02-27 15:44:30 +00:00
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
2014-02-27 20:32:43 -08:00
Copyright ( c ) 1999 - 2014 Intel Corporation .
2009-02-27 15:44:30 +00: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>
# include "ixgbe.h"
# include "ixgbe_phy.h"
2010-01-09 02:26:26 +00:00
# include "ixgbe_mbx.h"
2009-02-27 15:44:30 +00:00
# define IXGBE_82599_MAX_TX_QUEUES 128
# define IXGBE_82599_MAX_RX_QUEUES 128
# define IXGBE_82599_RAR_ENTRIES 128
# define IXGBE_82599_MC_TBL_SIZE 128
# define IXGBE_82599_VFT_TBL_SIZE 128
2011-04-04 04:29:41 +00:00
# define IXGBE_82599_RX_PB_SIZE 512
2009-02-27 15:44:30 +00:00
2010-10-12 22:20:59 +00:00
static void ixgbe_disable_tx_laser_multispeed_fiber ( struct ixgbe_hw * hw ) ;
static void ixgbe_enable_tx_laser_multispeed_fiber ( struct ixgbe_hw * hw ) ;
static void ixgbe_flap_tx_laser_multispeed_fiber ( struct ixgbe_hw * hw ) ;
static s32 ixgbe_setup_mac_link_multispeed_fiber ( struct ixgbe_hw * hw ,
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete ) ;
2009-10-08 15:36:22 +00:00
static s32 ixgbe_setup_mac_link_smartspeed ( struct ixgbe_hw * hw ,
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete ) ;
2013-06-25 07:59:23 +00:00
static void ixgbe_stop_mac_link_on_d3_82599 ( struct ixgbe_hw * hw ) ;
2010-10-12 22:20:59 +00:00
static s32 ixgbe_start_mac_link_82599 ( struct ixgbe_hw * hw ,
bool autoneg_wait_to_complete ) ;
static s32 ixgbe_setup_mac_link_82599 ( struct ixgbe_hw * hw ,
2009-09-01 13:49:35 +00:00
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete ) ;
static s32 ixgbe_setup_copper_link_82599 ( struct ixgbe_hw * hw ,
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete ) ;
2009-06-04 16:02:24 +00:00
static s32 ixgbe_verify_fw_version_82599 ( struct ixgbe_hw * hw ) ;
2013-07-27 06:25:38 +00:00
static s32 ixgbe_read_i2c_byte_82599 ( struct ixgbe_hw * hw , u8 byte_offset ,
u8 dev_addr , u8 * data ) ;
static s32 ixgbe_write_i2c_byte_82599 ( struct ixgbe_hw * hw , u8 byte_offset ,
u8 dev_addr , u8 data ) ;
2014-02-27 20:32:41 -08:00
static s32 ixgbe_reset_pipeline_82599 ( struct ixgbe_hw * hw ) ;
static bool ixgbe_verify_lesm_fw_enabled_82599 ( struct ixgbe_hw * hw ) ;
2009-02-27 15:44:30 +00:00
2013-02-21 03:00:04 +00:00
static bool ixgbe_mng_enabled ( struct ixgbe_hw * hw )
{
u32 fwsm , manc , factps ;
fwsm = IXGBE_READ_REG ( hw , IXGBE_FWSM ) ;
if ( ( fwsm & IXGBE_FWSM_MODE_MASK ) ! = IXGBE_FWSM_FW_MODE_PT )
return false ;
manc = IXGBE_READ_REG ( hw , IXGBE_MANC ) ;
if ( ! ( manc & IXGBE_MANC_RCV_TCO_EN ) )
return false ;
factps = IXGBE_READ_REG ( hw , IXGBE_FACTPS ) ;
if ( factps & IXGBE_FACTPS_MNGCG )
return false ;
return true ;
}
2009-08-25 04:47:32 +00:00
static void ixgbe_init_mac_link_ops_82599 ( struct ixgbe_hw * hw )
2009-02-27 15:44:30 +00:00
{
struct ixgbe_mac_info * mac = & hw - > mac ;
2010-12-03 03:31:51 +00:00
2013-02-21 03:00:04 +00:00
/* enable the laser control functions for SFP+ fiber
* and MNG not enabled
*/
if ( ( mac - > ops . get_media_type ( hw ) = = ixgbe_media_type_fiber ) & &
! hw - > mng_fw_enabled ) {
2010-04-27 00:38:15 +00:00
mac - > ops . disable_tx_laser =
& ixgbe_disable_tx_laser_multispeed_fiber ;
mac - > ops . enable_tx_laser =
& ixgbe_enable_tx_laser_multispeed_fiber ;
2010-03-18 14:34:52 +00:00
mac - > ops . flap_tx_laser = & ixgbe_flap_tx_laser_multispeed_fiber ;
2009-02-27 15:44:30 +00:00
} else {
2010-04-27 00:38:15 +00:00
mac - > ops . disable_tx_laser = NULL ;
mac - > ops . enable_tx_laser = NULL ;
2010-03-18 14:34:52 +00:00
mac - > ops . flap_tx_laser = NULL ;
2010-12-03 03:31:51 +00:00
}
if ( hw - > phy . multispeed_fiber ) {
/* Set up dual speed SFP+ support */
mac - > ops . setup_link = & ixgbe_setup_mac_link_multispeed_fiber ;
} else {
2009-10-08 15:36:22 +00:00
if ( ( mac - > ops . get_media_type ( hw ) = =
ixgbe_media_type_backplane ) & &
( hw - > phy . smart_speed = = ixgbe_smart_speed_auto | |
2011-03-18 08:18:32 +00:00
hw - > phy . smart_speed = = ixgbe_smart_speed_on ) & &
! ixgbe_verify_lesm_fw_enabled_82599 ( hw ) )
2009-10-08 15:36:22 +00:00
mac - > ops . setup_link = & ixgbe_setup_mac_link_smartspeed ;
else
mac - > ops . setup_link = & ixgbe_setup_mac_link_82599 ;
2009-02-27 15:44:30 +00:00
}
}
2009-08-25 04:47:32 +00:00
static s32 ixgbe_setup_sfp_modules_82599 ( struct ixgbe_hw * hw )
2009-02-27 15:44:30 +00:00
{
s32 ret_val = 0 ;
u16 list_offset , data_offset , data_value ;
if ( hw - > phy . sfp_type ! = ixgbe_sfp_type_unknown ) {
ixgbe_init_mac_link_ops_82599 ( hw ) ;
2009-04-09 22:28:15 +00:00
hw - > phy . ops . reset = NULL ;
2009-02-27 15:44:30 +00:00
ret_val = ixgbe_get_sfp_init_sequence_offsets ( hw , & list_offset ,
& data_offset ) ;
if ( ret_val ! = 0 )
goto setup_sfp_out ;
2009-05-19 09:18:34 +00:00
/* PHY config will finish before releasing the semaphore */
2011-02-25 01:58:04 +00:00
ret_val = hw - > mac . ops . acquire_swfw_sync ( hw ,
IXGBE_GSSR_MAC_CSR_SM ) ;
2009-05-19 09:18:34 +00:00
if ( ret_val ! = 0 ) {
ret_val = IXGBE_ERR_SWFW_SYNC ;
goto setup_sfp_out ;
}
2013-05-24 07:31:09 +00:00
if ( hw - > eeprom . ops . read ( hw , + + data_offset , & data_value ) )
goto setup_sfp_err ;
2009-02-27 15:44:30 +00:00
while ( data_value ! = 0xffff ) {
IXGBE_WRITE_REG ( hw , IXGBE_CORECTL , data_value ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
2013-05-24 07:31:09 +00:00
if ( hw - > eeprom . ops . read ( hw , + + data_offset , & data_value ) )
goto setup_sfp_err ;
2009-02-27 15:44:30 +00:00
}
2009-05-19 09:18:34 +00:00
/* Release the semaphore */
2011-04-13 04:56:15 +00:00
hw - > mac . ops . release_swfw_sync ( hw , IXGBE_GSSR_MAC_CSR_SM ) ;
2011-03-18 09:32:53 +00:00
/*
* Delay obtaining semaphore again to allow FW access ,
* semaphore_delay is in ms usleep_range needs us .
*/
usleep_range ( hw - > eeprom . semaphore_delay * 1000 ,
hw - > eeprom . semaphore_delay * 2000 ) ;
2010-12-03 13:23:30 +00:00
2012-10-24 06:19:01 +00:00
/* Restart DSP and set SFI mode */
2014-02-27 20:32:41 -08:00
ret_val = hw - > mac . ops . prot_autoc_write ( hw ,
hw - > mac . orig_autoc | IXGBE_AUTOC_LMS_10G_SERIAL ,
false ) ;
2012-10-24 06:19:01 +00:00
if ( ret_val ) {
hw_dbg ( hw , " sfp module setup not complete \n " ) ;
2010-12-03 13:23:30 +00:00
ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE ;
goto setup_sfp_out ;
}
2009-02-27 15:44:30 +00:00
}
setup_sfp_out :
return ret_val ;
2013-05-24 07:31:09 +00:00
setup_sfp_err :
/* Release the semaphore */
hw - > mac . ops . release_swfw_sync ( hw , IXGBE_GSSR_MAC_CSR_SM ) ;
/* Delay obtaining semaphore again to allow FW access,
* semaphore_delay is in ms usleep_range needs us .
*/
usleep_range ( hw - > eeprom . semaphore_delay * 1000 ,
hw - > eeprom . semaphore_delay * 2000 ) ;
hw_err ( hw , " eeprom read at offset %d failed \n " , data_offset ) ;
return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE ;
2009-02-27 15:44:30 +00:00
}
2014-02-27 20:32:41 -08:00
/**
* prot_autoc_read_82599 - Hides MAC differences needed for AUTOC read
* @ hw : pointer to hardware structure
* @ locked : Return the if we locked for this read .
* @ reg_val : Value we read from AUTOC
*
* For this part ( 82599 ) we need to wrap read - modify - writes with a possible
* FW / SW lock . It is assumed this lock will be freed with the next
* prot_autoc_write_82599 ( ) . Note , that locked can only be true in cases
* where this function doesn ' t return an error .
* */
static s32 prot_autoc_read_82599 ( struct ixgbe_hw * hw , bool * locked ,
u32 * reg_val )
{
s32 ret_val ;
* locked = false ;
/* If LESM is on then we need to hold the SW/FW semaphore. */
if ( ixgbe_verify_lesm_fw_enabled_82599 ( hw ) ) {
ret_val = hw - > mac . ops . acquire_swfw_sync ( hw ,
IXGBE_GSSR_MAC_CSR_SM ) ;
if ( ! ret_val )
return IXGBE_ERR_SWFW_SYNC ;
* locked = true ;
}
* reg_val = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
return 0 ;
}
/**
* prot_autoc_write_82599 - Hides MAC differences needed for AUTOC write
* @ hw : pointer to hardware structure
* @ reg_val : value to write to AUTOC
* @ locked : bool to indicate whether the SW / FW lock was already taken by
* previous proc_autoc_read_82599 .
*
* This part ( 82599 ) may need to hold a the SW / FW lock around all writes to
* AUTOC . Likewise after a write we need to do a pipeline reset .
* */
static s32 prot_autoc_write_82599 ( struct ixgbe_hw * hw , u32 autoc , bool locked )
{
s32 ret_val = 0 ;
2014-02-27 20:32:43 -08:00
/* Blocked by MNG FW so bail */
if ( ixgbe_check_reset_blocked ( hw ) )
goto out ;
2014-02-27 20:32:41 -08:00
/* We only need to get the lock if:
* - We didn ' t do it already ( in the read part of a read - modify - write )
* - LESM is enabled .
*/
if ( ! locked & & ixgbe_verify_lesm_fw_enabled_82599 ( hw ) ) {
ret_val = hw - > mac . ops . acquire_swfw_sync ( hw ,
IXGBE_GSSR_MAC_CSR_SM ) ;
if ( ! ret_val )
return IXGBE_ERR_SWFW_SYNC ;
}
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC , autoc ) ;
ret_val = ixgbe_reset_pipeline_82599 ( hw ) ;
2014-02-27 20:32:43 -08:00
out :
2014-02-27 20:32:41 -08:00
/* Free the SW/FW semaphore as we either grabbed it here or
* already had it when this function was called .
*/
if ( locked )
hw - > mac . ops . release_swfw_sync ( hw , IXGBE_GSSR_MAC_CSR_SM ) ;
return ret_val ;
}
2009-02-27 15:44:30 +00:00
static s32 ixgbe_get_invariants_82599 ( struct ixgbe_hw * hw )
{
struct ixgbe_mac_info * mac = & hw - > mac ;
2009-04-09 22:27:57 +00:00
ixgbe_init_mac_link_ops_82599 ( hw ) ;
2009-02-27 15:44:30 +00:00
2009-04-09 22:27:57 +00:00
mac - > mcft_size = IXGBE_82599_MC_TBL_SIZE ;
mac - > vft_size = IXGBE_82599_VFT_TBL_SIZE ;
mac - > num_rar_entries = IXGBE_82599_RAR_ENTRIES ;
mac - > max_rx_queues = IXGBE_82599_MAX_RX_QUEUES ;
mac - > max_tx_queues = IXGBE_82599_MAX_TX_QUEUES ;
2010-05-13 17:33:41 +00:00
mac - > max_msix_vectors = ixgbe_get_pcie_msix_count_generic ( hw ) ;
2009-02-27 15:44:30 +00:00
2009-04-09 22:27:57 +00:00
return 0 ;
}
2009-02-27 15:44:30 +00:00
2009-04-09 22:27:57 +00:00
/**
* ixgbe_init_phy_ops_82599 - 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_82599 ( struct ixgbe_hw * hw )
2009-04-09 22:27:57 +00:00
{
struct ixgbe_mac_info * mac = & hw - > mac ;
struct ixgbe_phy_info * phy = & hw - > phy ;
s32 ret_val = 0 ;
2013-07-27 06:25:38 +00:00
u32 esdp ;
if ( hw - > device_id = = IXGBE_DEV_ID_82599_QSFP_SF_QP ) {
/* Store flag indicating I2C bus access control unit. */
hw - > phy . qsfp_shared_i2c_bus = true ;
/* Initialize access to QSFP+ I2C bus */
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
esdp | = IXGBE_ESDP_SDP0_DIR ;
esdp & = ~ IXGBE_ESDP_SDP1_DIR ;
esdp & = ~ IXGBE_ESDP_SDP0 ;
esdp & = ~ IXGBE_ESDP_SDP0_NATIVE ;
esdp & = ~ IXGBE_ESDP_SDP1_NATIVE ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
phy - > ops . read_i2c_byte = & ixgbe_read_i2c_byte_82599 ;
phy - > ops . write_i2c_byte = & ixgbe_write_i2c_byte_82599 ;
}
2009-02-27 15:44:30 +00:00
2009-04-09 22:27:57 +00:00
/* Identify the PHY or SFP module */
ret_val = phy - > ops . identify ( hw ) ;
/* Setup function pointers based on detected SFP module and speeds */
ixgbe_init_mac_link_ops_82599 ( hw ) ;
2009-02-27 15:44:30 +00:00
/* If copper media, overwrite with copper function pointers */
if ( mac - > ops . get_media_type ( hw ) = = ixgbe_media_type_copper ) {
mac - > ops . setup_link = & ixgbe_setup_copper_link_82599 ;
mac - > ops . get_link_capabilities =
2010-11-16 19:27:15 -08:00
& ixgbe_get_copper_link_capabilities_generic ;
2009-02-27 15:44:30 +00:00
}
2009-04-09 22:27:57 +00:00
/* Set necessary function pointers based on phy type */
2009-02-27 15:44:30 +00:00
switch ( hw - > phy . type ) {
case ixgbe_phy_tn :
phy - > ops . check_link = & ixgbe_check_phy_link_tnx ;
2011-07-28 06:17:04 +00:00
phy - > ops . setup_link = & ixgbe_setup_phy_link_tnx ;
2009-02-27 15:44:30 +00:00
phy - > ops . get_firmware_version =
2009-04-09 22:27:57 +00:00
& ixgbe_get_phy_firmware_version_tnx ;
2009-02-27 15:44:30 +00:00
break ;
default :
break ;
}
return ret_val ;
}
/**
* ixgbe_get_link_capabilities_82599 - Determines link capabilities
* @ hw : pointer to hardware structure
* @ speed : pointer to link speed
2012-12-15 03:28:19 +00:00
* @ autoneg : true when autoneg or autotry is enabled
2009-02-27 15:44:30 +00:00
*
* Determines the link capabilities by reading the AUTOC register .
* */
2009-08-25 04:47:32 +00:00
static s32 ixgbe_get_link_capabilities_82599 ( struct ixgbe_hw * hw ,
ixgbe_link_speed * speed ,
2012-12-15 03:28:19 +00:00
bool * autoneg )
2009-02-27 15:44:30 +00:00
{
s32 status = 0 ;
2009-04-09 22:28:33 +00:00
u32 autoc = 0 ;
2009-02-27 15:44:30 +00:00
2010-06-29 18:30:59 +00:00
/* Determine 1G link capabilities off of SFP+ type */
if ( hw - > phy . sfp_type = = ixgbe_sfp_type_1g_cu_core0 | |
2012-06-08 06:59:09 +00:00
hw - > phy . sfp_type = = ixgbe_sfp_type_1g_cu_core1 | |
2013-04-11 06:23:34 +00:00
hw - > phy . sfp_type = = ixgbe_sfp_type_1g_lx_core0 | |
hw - > phy . sfp_type = = ixgbe_sfp_type_1g_lx_core1 | |
2012-06-08 06:59:09 +00:00
hw - > phy . sfp_type = = ixgbe_sfp_type_1g_sx_core0 | |
hw - > phy . sfp_type = = ixgbe_sfp_type_1g_sx_core1 ) {
2010-06-29 18:30:59 +00:00
* speed = IXGBE_LINK_SPEED_1GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = true ;
2010-06-29 18:30:59 +00:00
goto out ;
}
2009-04-09 22:28:33 +00:00
/*
* Determine link capabilities based on the stored value of AUTOC ,
* which represents EEPROM defaults . If AUTOC value has not been
* stored , use the current register value .
*/
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 ) {
2009-02-27 15:44:30 +00:00
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN :
* speed = IXGBE_LINK_SPEED_1GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = false ;
2009-02-27 15:44:30 +00:00
break ;
case IXGBE_AUTOC_LMS_10G_LINK_NO_AN :
* speed = IXGBE_LINK_SPEED_10GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = false ;
2009-02-27 15:44:30 +00:00
break ;
case IXGBE_AUTOC_LMS_1G_AN :
* speed = IXGBE_LINK_SPEED_1GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = true ;
2009-02-27 15:44:30 +00:00
break ;
case IXGBE_AUTOC_LMS_10G_SERIAL :
* speed = IXGBE_LINK_SPEED_10GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = false ;
2009-02-27 15:44:30 +00:00
break ;
case IXGBE_AUTOC_LMS_KX4_KX_KR :
case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN :
* speed = IXGBE_LINK_SPEED_UNKNOWN ;
2009-04-09 22:28:33 +00:00
if ( autoc & IXGBE_AUTOC_KR_SUPP )
2009-02-27 15:44:30 +00:00
* speed | = IXGBE_LINK_SPEED_10GB_FULL ;
2009-04-09 22:28:33 +00:00
if ( autoc & IXGBE_AUTOC_KX4_SUPP )
2009-02-27 15:44:30 +00:00
* speed | = IXGBE_LINK_SPEED_10GB_FULL ;
2009-04-09 22:28:33 +00:00
if ( autoc & IXGBE_AUTOC_KX_SUPP )
2009-02-27 15:44:30 +00:00
* speed | = IXGBE_LINK_SPEED_1GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = true ;
2009-02-27 15:44:30 +00:00
break ;
case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII :
* speed = IXGBE_LINK_SPEED_100_FULL ;
2009-04-09 22:28:33 +00:00
if ( autoc & IXGBE_AUTOC_KR_SUPP )
2009-02-27 15:44:30 +00:00
* speed | = IXGBE_LINK_SPEED_10GB_FULL ;
2009-04-09 22:28:33 +00:00
if ( autoc & IXGBE_AUTOC_KX4_SUPP )
2009-02-27 15:44:30 +00:00
* speed | = IXGBE_LINK_SPEED_10GB_FULL ;
2009-04-09 22:28:33 +00:00
if ( autoc & IXGBE_AUTOC_KX_SUPP )
2009-02-27 15:44:30 +00:00
* speed | = IXGBE_LINK_SPEED_1GB_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = true ;
2009-02-27 15:44:30 +00:00
break ;
case IXGBE_AUTOC_LMS_SGMII_1G_100M :
* speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL ;
2012-12-15 03:28:19 +00:00
* autoneg = false ;
2009-02-27 15:44:30 +00:00
break ;
default :
status = IXGBE_ERR_LINK_SETUP ;
goto out ;
break ;
}
if ( hw - > phy . multispeed_fiber ) {
* speed | = IXGBE_LINK_SPEED_10GB_FULL |
2013-08-13 07:22:16 +00:00
IXGBE_LINK_SPEED_1GB_FULL ;
/* QSFP must not enable auto-negotiation */
if ( hw - > phy . media_type = = ixgbe_media_type_fiber_qsfp )
* autoneg = false ;
else
* autoneg = true ;
2009-02-27 15:44:30 +00:00
}
out :
return status ;
}
/**
* ixgbe_get_media_type_82599 - Get media type
* @ hw : pointer to hardware structure
*
* Returns the media type ( fiber , copper , backplane )
* */
2009-08-25 04:47:32 +00:00
static enum ixgbe_media_type ixgbe_get_media_type_82599 ( struct ixgbe_hw * hw )
2009-02-27 15:44:30 +00:00
{
enum ixgbe_media_type media_type ;
/* Detect if there is a copper PHY attached. */
2011-02-12 10:52:07 +00:00
switch ( hw - > phy . type ) {
case ixgbe_phy_cu_unknown :
case ixgbe_phy_tn :
2009-02-27 15:44:30 +00:00
media_type = ixgbe_media_type_copper ;
goto out ;
2011-02-12 10:52:07 +00:00
default :
break ;
2009-02-27 15:44:30 +00:00
}
switch ( hw - > device_id ) {
case IXGBE_DEV_ID_82599_KX4 :
2009-10-02 08:58:25 +00:00
case IXGBE_DEV_ID_82599_KX4_MEZZ :
2009-10-02 08:58:04 +00:00
case IXGBE_DEV_ID_82599_COMBO_BACKPLANE :
2009-12-08 07:22:23 +00:00
case IXGBE_DEV_ID_82599_KR :
2010-12-03 03:32:34 +00:00
case IXGBE_DEV_ID_82599_BACKPLANE_FCOE :
2009-05-17 20:58:04 +00:00
case IXGBE_DEV_ID_82599_XAUI_LOM :
2009-02-27 15:44:30 +00:00
/* Default device ID is mezzanine card KX/KX4 */
media_type = ixgbe_media_type_backplane ;
break ;
case IXGBE_DEV_ID_82599_SFP :
2010-12-03 03:32:34 +00:00
case IXGBE_DEV_ID_82599_SFP_FCOE :
2009-10-08 15:35:58 +00:00
case IXGBE_DEV_ID_82599_SFP_EM :
2011-03-24 07:06:02 +00:00
case IXGBE_DEV_ID_82599_SFP_SF2 :
2011-11-04 06:43:29 +00:00
case IXGBE_DEV_ID_82599_SFP_SF_QP :
2011-09-08 08:30:14 +00:00
case IXGBE_DEV_ID_82599EN_SFP :
2009-02-27 15:44:30 +00:00
media_type = ixgbe_media_type_fiber ;
break ;
2009-09-14 07:47:49 +00:00
case IXGBE_DEV_ID_82599_CX4 :
2009-09-14 07:48:10 +00:00
media_type = ixgbe_media_type_cx4 ;
2009-09-14 07:47:49 +00:00
break ;
2011-02-12 10:52:07 +00:00
case IXGBE_DEV_ID_82599_T3_LOM :
media_type = ixgbe_media_type_copper ;
break ;
2011-05-14 06:36:35 +00:00
case IXGBE_DEV_ID_82599_LS :
media_type = ixgbe_media_type_fiber_lco ;
break ;
2013-07-27 06:25:38 +00:00
case IXGBE_DEV_ID_82599_QSFP_SF_QP :
media_type = ixgbe_media_type_fiber_qsfp ;
break ;
2009-02-27 15:44:30 +00:00
default :
media_type = ixgbe_media_type_unknown ;
break ;
}
out :
return media_type ;
}
2013-06-25 07:59:23 +00:00
/**
* ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3
* @ hw : pointer to hardware structure
*
* Disables link , should be called during D3 power down sequence .
*
*/
static void ixgbe_stop_mac_link_on_d3_82599 ( struct ixgbe_hw * hw )
{
u32 autoc2_reg ;
if ( ! hw - > mng_fw_enabled & & ! hw - > wol_enabled ) {
autoc2_reg = IXGBE_READ_REG ( hw , IXGBE_AUTOC2 ) ;
autoc2_reg | = IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK ;
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC2 , autoc2_reg ) ;
}
}
2009-02-27 15:44:30 +00:00
/**
2009-09-01 13:49:35 +00:00
* ixgbe_start_mac_link_82599 - Setup MAC link settings
2009-02-27 15:44:30 +00:00
* @ hw : pointer to hardware structure
2009-09-01 13:49:35 +00:00
* @ autoneg_wait_to_complete : true when waiting for completion is needed
2009-02-27 15:44:30 +00:00
*
* Configures link settings based on values in the ixgbe_hw struct .
* Restarts the link . Performs autonegotiation if needed .
* */
2010-10-12 22:20:59 +00:00
static s32 ixgbe_start_mac_link_82599 ( struct ixgbe_hw * hw ,
2009-09-01 13:49:35 +00:00
bool autoneg_wait_to_complete )
2009-02-27 15:44:30 +00:00
{
u32 autoc_reg ;
u32 links_reg ;
u32 i ;
s32 status = 0 ;
2012-10-24 06:19:01 +00:00
bool got_lock = false ;
if ( ixgbe_verify_lesm_fw_enabled_82599 ( hw ) ) {
status = hw - > mac . ops . acquire_swfw_sync ( hw ,
IXGBE_GSSR_MAC_CSR_SM ) ;
if ( status )
goto out ;
got_lock = true ;
}
2009-02-27 15:44:30 +00:00
/* Restart link */
2012-10-24 06:19:01 +00:00
ixgbe_reset_pipeline_82599 ( hw ) ;
if ( got_lock )
hw - > mac . ops . release_swfw_sync ( hw , IXGBE_GSSR_MAC_CSR_SM ) ;
2009-02-27 15:44:30 +00:00
/* Only poll for autoneg to complete if specified to do so */
2009-09-01 13:49:35 +00:00
if ( autoneg_wait_to_complete ) {
2012-10-24 06:19:01 +00:00
autoc_reg = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
2009-02-27 15:44:30 +00:00
if ( ( autoc_reg & IXGBE_AUTOC_LMS_MASK ) = =
IXGBE_AUTOC_LMS_KX4_KX_KR | |
( autoc_reg & IXGBE_AUTOC_LMS_MASK ) = =
IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN | |
( autoc_reg & IXGBE_AUTOC_LMS_MASK ) = =
IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII ) {
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 ;
hw_dbg ( hw , " Autoneg did not complete. \n " ) ;
}
}
}
/* Add delay to filter out noises during initial link setup */
msleep ( 50 ) ;
2012-10-24 06:19:01 +00:00
out :
2009-02-27 15:44:30 +00:00
return status ;
}
2011-02-19 08:43:44 +00:00
/**
* ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
* @ hw : pointer to hardware structure
*
* The base drivers may require better control over SFP + module
* PHY states . This includes selectively shutting down the Tx
* laser on the PHY , effectively halting physical link .
* */
2010-10-12 22:20:59 +00:00
static void ixgbe_disable_tx_laser_multispeed_fiber ( struct ixgbe_hw * hw )
2010-04-27 00:38:15 +00:00
{
u32 esdp_reg = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
2014-02-27 20:32:43 -08:00
/* Blocked by MNG FW so bail */
if ( ixgbe_check_reset_blocked ( hw ) )
return ;
2010-04-27 00:38:15 +00:00
/* Disable tx laser; allow 100us to go dark per spec */
esdp_reg | = IXGBE_ESDP_SDP3 ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp_reg ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
udelay ( 100 ) ;
}
/**
* ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
* @ hw : pointer to hardware structure
*
* The base drivers may require better control over SFP + module
* PHY states . This includes selectively turning on the Tx
* laser on the PHY , effectively starting physical link .
* */
2010-10-12 22:20:59 +00:00
static void ixgbe_enable_tx_laser_multispeed_fiber ( struct ixgbe_hw * hw )
2010-04-27 00:38:15 +00:00
{
u32 esdp_reg = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
/* Enable tx laser; allow 100ms to light up */
esdp_reg & = ~ IXGBE_ESDP_SDP3 ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp_reg ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
msleep ( 100 ) ;
}
2010-03-18 14:34:52 +00:00
/**
* ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
* @ hw : pointer to hardware structure
*
* When the driver changes the link speeds that it can support ,
* it sets autotry_restart to true to indicate that we need to
* initiate a new autotry session with the link partner . To do
* so , we set the speed then disable and re - enable the tx laser , to
* alert the link partner that it also needs to restart autotry on its
* end . This is consistent with true clause 37 autoneg , which also
* involves a loss of signal .
* */
2010-10-12 22:20:59 +00:00
static void ixgbe_flap_tx_laser_multispeed_fiber ( struct ixgbe_hw * hw )
2010-03-18 14:34:52 +00:00
{
2014-02-27 20:32:43 -08:00
/* Blocked by MNG FW so bail */
if ( ixgbe_check_reset_blocked ( hw ) )
return ;
2010-03-18 14:34:52 +00:00
if ( hw - > mac . autotry_restart ) {
2010-04-27 00:38:15 +00:00
ixgbe_disable_tx_laser_multispeed_fiber ( hw ) ;
ixgbe_enable_tx_laser_multispeed_fiber ( hw ) ;
2010-03-18 14:34:52 +00:00
hw - > mac . autotry_restart = false ;
}
}
2013-07-31 02:17:40 +00:00
/**
* ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
* @ hw : pointer to hardware structure
* @ speed : link speed to set
*
* We set the module speed differently for fixed fiber . For other
* multi - speed devices we don ' t have an error value so here if we
* detect an error we just log it and exit .
*/
static void ixgbe_set_fiber_fixed_speed ( struct ixgbe_hw * hw ,
ixgbe_link_speed speed )
{
s32 status ;
u8 rs , eeprom_data ;
switch ( speed ) {
case IXGBE_LINK_SPEED_10GB_FULL :
/* one bit mask same as setting on */
rs = IXGBE_SFF_SOFT_RS_SELECT_10G ;
break ;
case IXGBE_LINK_SPEED_1GB_FULL :
rs = IXGBE_SFF_SOFT_RS_SELECT_1G ;
break ;
default :
hw_dbg ( hw , " Invalid fixed module speed \n " ) ;
return ;
}
/* Set RS0 */
status = hw - > phy . ops . read_i2c_byte ( hw , IXGBE_SFF_SFF_8472_OSCB ,
IXGBE_I2C_EEPROM_DEV_ADDR2 ,
& eeprom_data ) ;
if ( status ) {
hw_dbg ( hw , " Failed to read Rx Rate Select RS0 \n " ) ;
goto out ;
}
2014-01-16 02:30:10 -08:00
eeprom_data = ( eeprom_data & ~ IXGBE_SFF_SOFT_RS_SELECT_MASK ) | rs ;
2013-07-31 02:17:40 +00:00
status = hw - > phy . ops . write_i2c_byte ( hw , IXGBE_SFF_SFF_8472_OSCB ,
IXGBE_I2C_EEPROM_DEV_ADDR2 ,
eeprom_data ) ;
if ( status ) {
hw_dbg ( hw , " Failed to write Rx Rate Select RS0 \n " ) ;
goto out ;
}
/* Set RS1 */
status = hw - > phy . ops . read_i2c_byte ( hw , IXGBE_SFF_SFF_8472_ESCB ,
IXGBE_I2C_EEPROM_DEV_ADDR2 ,
& eeprom_data ) ;
if ( status ) {
hw_dbg ( hw , " Failed to read Rx Rate Select RS1 \n " ) ;
goto out ;
}
eeprom_data = ( eeprom_data & ~ IXGBE_SFF_SOFT_RS_SELECT_MASK ) & rs ;
status = hw - > phy . ops . write_i2c_byte ( hw , IXGBE_SFF_SFF_8472_ESCB ,
IXGBE_I2C_EEPROM_DEV_ADDR2 ,
eeprom_data ) ;
if ( status ) {
hw_dbg ( hw , " Failed to write Rx Rate Select RS1 \n " ) ;
goto out ;
}
out :
return ;
}
2009-02-27 15:44:30 +00:00
/**
2009-09-01 13:49:35 +00:00
* ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
2009-02-27 15:44:30 +00:00
* @ hw : pointer to hardware structure
* @ speed : new link speed
* @ autoneg_wait_to_complete : true when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link .
* */
2011-04-12 02:44:55 +00:00
static s32 ixgbe_setup_mac_link_multispeed_fiber ( struct ixgbe_hw * hw ,
2009-09-01 13:49:35 +00:00
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete )
2009-02-27 15:44:30 +00:00
{
s32 status = 0 ;
2011-02-25 07:49:39 +00:00
ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN ;
2009-02-27 15:44:30 +00:00
ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN ;
u32 speedcnt = 0 ;
u32 esdp_reg = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
2011-02-25 07:49:39 +00:00
u32 i = 0 ;
2009-02-27 15:44:30 +00:00
bool link_up = false ;
2012-12-15 03:28:30 +00:00
bool autoneg = false ;
2009-02-27 15:44:30 +00:00
/* Mask off requested but non-supported speeds */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . get_link_capabilities ( hw , & link_speed ,
2012-12-15 03:28:19 +00:00
& autoneg ) ;
2011-02-25 07:49:39 +00:00
if ( status ! = 0 )
return status ;
speed & = link_speed ;
2009-02-27 15:44:30 +00:00
/*
* Try each speed one by one , highest priority first . We do this in
* software because 10 gb fiber doesn ' t support speed autonegotiation .
*/
if ( speed & IXGBE_LINK_SPEED_10GB_FULL ) {
speedcnt + + ;
highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL ;
2009-06-04 11:10:53 +00:00
/* If we already have link at this speed, just jump out */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . check_link ( hw , & link_speed , & link_up ,
false ) ;
if ( status ! = 0 )
return status ;
2009-06-04 11:10:53 +00:00
2011-02-25 07:49:39 +00:00
if ( ( link_speed = = IXGBE_LINK_SPEED_10GB_FULL ) & & link_up )
2009-06-04 11:10:53 +00:00
goto out ;
/* Set the module link speed */
2013-08-13 07:22:16 +00:00
switch ( hw - > phy . media_type ) {
case ixgbe_media_type_fiber :
2013-07-31 02:17:40 +00:00
esdp_reg | = ( IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5 ) ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp_reg ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
2013-08-13 07:22:16 +00:00
break ;
case ixgbe_media_type_fiber_qsfp :
/* QSFP module automatically detects MAC link speed */
break ;
default :
hw_dbg ( hw , " Unexpected media type. \n " ) ;
break ;
2013-07-31 02:17:40 +00:00
}
2009-02-27 15:44:30 +00:00
2009-06-04 11:10:53 +00:00
/* Allow module to change analog characteristics (1G->10G) */
msleep ( 40 ) ;
2009-02-27 15:44:30 +00:00
2009-09-01 13:49:35 +00:00
status = ixgbe_setup_mac_link_82599 ( hw ,
2011-02-25 07:49:39 +00:00
IXGBE_LINK_SPEED_10GB_FULL ,
autoneg_wait_to_complete ) ;
2009-06-04 11:10:53 +00:00
if ( status ! = 0 )
2009-09-01 13:50:14 +00:00
return status ;
2009-06-04 11:10:53 +00:00
/* Flap the tx laser if it has not already been done */
2013-02-21 03:00:04 +00:00
if ( hw - > mac . ops . flap_tx_laser )
hw - > mac . ops . flap_tx_laser ( hw ) ;
2009-06-04 11:10:53 +00:00
2009-10-08 15:36:22 +00:00
/*
* Wait for the controller to acquire link . Per IEEE 802.3 ap ,
* Section 73.10 .2 , we may have to wait up to 500 ms if KR is
* attempted . 82599 uses the same timing for 10 g SFI .
*/
2009-06-04 11:10:53 +00:00
for ( i = 0 ; i < 5 ; i + + ) {
/* Wait for the link partner to also set speed */
msleep ( 100 ) ;
/* If we have link, just jump out */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . check_link ( hw , & link_speed ,
& link_up , false ) ;
if ( status ! = 0 )
return status ;
2009-06-04 11:10:53 +00:00
if ( link_up )
goto out ;
}
2009-02-27 15:44:30 +00:00
}
if ( speed & IXGBE_LINK_SPEED_1GB_FULL ) {
speedcnt + + ;
if ( highest_link_speed = = IXGBE_LINK_SPEED_UNKNOWN )
highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL ;
2009-06-04 11:10:53 +00:00
/* If we already have link at this speed, just jump out */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . check_link ( hw , & link_speed , & link_up ,
false ) ;
if ( status ! = 0 )
return status ;
2009-06-04 11:10:53 +00:00
2011-02-25 07:49:39 +00:00
if ( ( link_speed = = IXGBE_LINK_SPEED_1GB_FULL ) & & link_up )
2009-06-04 11:10:53 +00:00
goto out ;
/* Set the module link speed */
2013-08-13 07:22:16 +00:00
switch ( hw - > phy . media_type ) {
case ixgbe_media_type_fiber_fixed :
2013-07-31 02:17:40 +00:00
ixgbe_set_fiber_fixed_speed ( hw ,
IXGBE_LINK_SPEED_1GB_FULL ) ;
2013-08-13 07:22:16 +00:00
break ;
case ixgbe_media_type_fiber :
2013-07-31 02:17:40 +00:00
esdp_reg & = ~ IXGBE_ESDP_SDP5 ;
esdp_reg | = IXGBE_ESDP_SDP5_DIR ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp_reg ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
2013-08-13 07:22:16 +00:00
break ;
case ixgbe_media_type_fiber_qsfp :
/* QSFP module automatically detects MAC link speed */
break ;
default :
hw_dbg ( hw , " Unexpected media type. \n " ) ;
break ;
2013-07-31 02:17:40 +00:00
}
2009-02-27 15:44:30 +00:00
2009-06-04 11:10:53 +00:00
/* Allow module to change analog characteristics (10G->1G) */
msleep ( 40 ) ;
2009-02-27 15:44:30 +00:00
2009-09-01 13:49:35 +00:00
status = ixgbe_setup_mac_link_82599 ( hw ,
2011-02-25 07:49:39 +00:00
IXGBE_LINK_SPEED_1GB_FULL ,
autoneg_wait_to_complete ) ;
2009-06-04 11:10:53 +00:00
if ( status ! = 0 )
2009-09-01 13:50:14 +00:00
return status ;
2009-06-04 11:10:53 +00:00
/* Flap the tx laser if it has not already been done */
2013-02-21 03:00:04 +00:00
if ( hw - > mac . ops . flap_tx_laser )
hw - > mac . ops . flap_tx_laser ( hw ) ;
2009-06-04 11:10:53 +00:00
/* Wait for the link partner to also set speed */
msleep ( 100 ) ;
2009-02-27 15:44:30 +00:00
/* If we have link, just jump out */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . check_link ( hw , & link_speed , & link_up ,
false ) ;
if ( status ! = 0 )
return status ;
2009-02-27 15:44:30 +00:00
if ( link_up )
goto out ;
}
/*
* We didn ' t get link . Configure back to the highest speed we tried ,
* ( if there was more than one ) . We call ourselves back with just the
* single highest speed that the user requested .
*/
if ( speedcnt > 1 )
2009-09-01 13:49:35 +00:00
status = ixgbe_setup_mac_link_multispeed_fiber ( hw ,
highest_link_speed ,
autoneg_wait_to_complete ) ;
2009-02-27 15:44:30 +00:00
out :
2009-09-01 13:50:14 +00:00
/* Set autoneg_advertised value based on input link speed */
hw - > phy . autoneg_advertised = 0 ;
if ( speed & IXGBE_LINK_SPEED_10GB_FULL )
hw - > phy . autoneg_advertised | = IXGBE_LINK_SPEED_10GB_FULL ;
if ( speed & IXGBE_LINK_SPEED_1GB_FULL )
hw - > phy . autoneg_advertised | = IXGBE_LINK_SPEED_1GB_FULL ;
2009-02-27 15:44:30 +00:00
return status ;
}
2009-10-08 15:36:22 +00:00
/**
* ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
* @ hw : pointer to hardware structure
* @ speed : new link speed
* @ autoneg_wait_to_complete : true when waiting for completion is needed
*
* Implements the Intel SmartSpeed algorithm .
* */
static s32 ixgbe_setup_mac_link_smartspeed ( struct ixgbe_hw * hw ,
2012-12-15 03:28:30 +00:00
ixgbe_link_speed speed ,
2009-10-08 15:36:22 +00:00
bool autoneg_wait_to_complete )
{
s32 status = 0 ;
2011-02-25 07:49:39 +00:00
ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN ;
2009-10-08 15:36:22 +00:00
s32 i , j ;
bool link_up = false ;
u32 autoc_reg = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
/* Set autoneg_advertised value based on input link speed */
hw - > phy . autoneg_advertised = 0 ;
if ( speed & IXGBE_LINK_SPEED_10GB_FULL )
hw - > phy . autoneg_advertised | = IXGBE_LINK_SPEED_10GB_FULL ;
if ( speed & IXGBE_LINK_SPEED_1GB_FULL )
hw - > phy . autoneg_advertised | = IXGBE_LINK_SPEED_1GB_FULL ;
if ( speed & IXGBE_LINK_SPEED_100_FULL )
hw - > phy . autoneg_advertised | = IXGBE_LINK_SPEED_100_FULL ;
/*
* Implement Intel SmartSpeed algorithm . SmartSpeed will reduce the
* autoneg advertisement if link is unable to be established at the
* highest negotiated rate . This can sometimes happen due to integrity
* issues with the physical media connection .
*/
/* First, try to get link with full advertisement */
hw - > phy . smart_speed_active = false ;
for ( j = 0 ; j < IXGBE_SMARTSPEED_MAX_RETRIES ; j + + ) {
2012-12-15 03:28:30 +00:00
status = ixgbe_setup_mac_link_82599 ( hw , speed ,
2009-10-08 15:36:22 +00:00
autoneg_wait_to_complete ) ;
2011-02-25 07:49:39 +00:00
if ( status ! = 0 )
2009-10-08 15:36:22 +00:00
goto out ;
/*
* Wait for the controller to acquire link . Per IEEE 802.3 ap ,
* Section 73.10 .2 , we may have to wait up to 500 ms if KR is
* attempted , or 200 ms if KX / KX4 / BX / BX4 is attempted , per
* Table 9 in the AN MAS .
*/
for ( i = 0 ; i < 5 ; i + + ) {
mdelay ( 100 ) ;
/* If we have link, just jump out */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . check_link ( hw , & link_speed ,
& link_up , false ) ;
if ( status ! = 0 )
goto out ;
2009-10-08 15:36:22 +00:00
if ( link_up )
goto out ;
}
}
/*
* We didn ' t get link . If we advertised KR plus one of KX4 / KX
* ( or BX4 / BX ) , then disable KR and try again .
*/
if ( ( ( autoc_reg & IXGBE_AUTOC_KR_SUPP ) = = 0 ) | |
( ( autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK ) = = 0 ) )
goto out ;
/* Turn SmartSpeed on to disable KR support */
hw - > phy . smart_speed_active = true ;
2012-12-15 03:28:30 +00:00
status = ixgbe_setup_mac_link_82599 ( hw , speed ,
2009-10-08 15:36:22 +00:00
autoneg_wait_to_complete ) ;
2011-02-25 07:49:39 +00:00
if ( status ! = 0 )
2009-10-08 15:36:22 +00:00
goto out ;
/*
* Wait for the controller to acquire link . 600 ms will allow for
* the AN link_fail_inhibit_timer as well for multiple cycles of
* parallel detect , both 10 g and 1 g . This allows for the maximum
* connect attempts as defined in the AN MAS table 73 - 7.
*/
for ( i = 0 ; i < 6 ; i + + ) {
mdelay ( 100 ) ;
/* If we have link, just jump out */
2011-02-25 07:49:39 +00:00
status = hw - > mac . ops . check_link ( hw , & link_speed ,
& link_up , false ) ;
if ( status ! = 0 )
goto out ;
2009-10-08 15:36:22 +00:00
if ( link_up )
goto out ;
}
/* We didn't get link. Turn SmartSpeed back off. */
hw - > phy . smart_speed_active = false ;
2012-12-15 03:28:30 +00:00
status = ixgbe_setup_mac_link_82599 ( hw , speed ,
2009-10-08 15:36:22 +00:00
autoneg_wait_to_complete ) ;
out :
2010-04-27 11:31:25 +00:00
if ( link_up & & ( link_speed = = IXGBE_LINK_SPEED_1GB_FULL ) )
2011-02-25 07:49:39 +00:00
hw_dbg ( hw , " Smartspeed has downgraded the link speed from "
2010-06-03 16:53:41 +00:00
" the maximum advertised \n " ) ;
2009-10-08 15:36:22 +00:00
return status ;
}
2009-02-27 15:44:30 +00:00
/**
2009-09-01 13:49:35 +00:00
* ixgbe_setup_mac_link_82599 - Set MAC link speed
2009-02-27 15:44:30 +00:00
* @ hw : pointer to hardware structure
* @ speed : new link speed
* @ autoneg_wait_to_complete : true when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link .
* */
2010-10-12 22:20:59 +00:00
static s32 ixgbe_setup_mac_link_82599 ( struct ixgbe_hw * hw ,
2012-12-15 03:28:30 +00:00
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete )
2009-02-27 15:44:30 +00:00
{
s32 status = 0 ;
2013-04-12 08:36:42 +00:00
u32 autoc , pma_pmd_1g , link_mode , start_autoc ;
2009-02-27 15:44:30 +00:00
u32 autoc2 = IXGBE_READ_REG ( hw , IXGBE_AUTOC2 ) ;
2009-04-09 22:28:33 +00:00
u32 orig_autoc = 0 ;
2009-02-27 15:44:30 +00:00
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK ;
u32 links_reg ;
u32 i ;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN ;
2012-12-15 03:28:30 +00:00
bool autoneg = false ;
2009-02-27 15:44:30 +00:00
/* Check to see if speed passed in is supported. */
2012-02-17 07:38:13 +00:00
status = hw - > mac . ops . get_link_capabilities ( hw , & link_capabilities ,
& autoneg ) ;
2011-02-26 06:40:16 +00:00
if ( status ! = 0 )
goto out ;
2009-02-27 15:44:30 +00:00
speed & = link_capabilities ;
2009-06-04 11:10:53 +00:00
if ( speed = = IXGBE_LINK_SPEED_UNKNOWN ) {
status = IXGBE_ERR_LINK_SETUP ;
goto out ;
}
2009-04-09 22:28:33 +00:00
/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
if ( hw - > mac . orig_link_settings_stored )
2013-04-12 08:36:42 +00:00
autoc = hw - > mac . orig_autoc ;
2009-04-09 22:28:33 +00:00
else
2013-04-12 08:36:42 +00:00
autoc = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
orig_autoc = autoc ;
2014-02-27 20:32:41 -08:00
start_autoc = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
2013-04-12 08:36:42 +00:00
link_mode = autoc & IXGBE_AUTOC_LMS_MASK ;
pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK ;
2009-04-09 22:28:33 +00:00
2009-06-04 11:10:53 +00:00
if ( link_mode = = IXGBE_AUTOC_LMS_KX4_KX_KR | |
link_mode = = IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN | |
link_mode = = IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII ) {
2009-02-27 15:44:30 +00:00
/* Set KX4/KX/KR support according to speed requested */
autoc & = ~ ( IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP ) ;
2012-08-10 07:35:14 +00:00
if ( speed & IXGBE_LINK_SPEED_10GB_FULL ) {
2009-04-09 22:28:33 +00:00
if ( orig_autoc & IXGBE_AUTOC_KX4_SUPP )
2009-02-27 15:44:30 +00:00
autoc | = IXGBE_AUTOC_KX4_SUPP ;
2009-10-08 15:36:22 +00:00
if ( ( orig_autoc & IXGBE_AUTOC_KR_SUPP ) & &
( hw - > phy . smart_speed_active = = false ) )
2009-02-27 15:44:30 +00:00
autoc | = IXGBE_AUTOC_KR_SUPP ;
2012-08-10 07:35:14 +00:00
}
2009-02-27 15:44:30 +00:00
if ( speed & IXGBE_LINK_SPEED_1GB_FULL )
autoc | = IXGBE_AUTOC_KX_SUPP ;
} else if ( ( pma_pmd_1g = = IXGBE_AUTOC_1G_SFI ) & &
( link_mode = = IXGBE_AUTOC_LMS_1G_LINK_NO_AN | |
link_mode = = IXGBE_AUTOC_LMS_1G_AN ) ) {
/* Switch from 1G SFI to 10G SFI if requested */
if ( ( speed = = IXGBE_LINK_SPEED_10GB_FULL ) & &
( pma_pmd_10g_serial = = IXGBE_AUTOC2_10G_SFI ) ) {
autoc & = ~ IXGBE_AUTOC_LMS_MASK ;
autoc | = IXGBE_AUTOC_LMS_10G_SERIAL ;
}
} else if ( ( pma_pmd_10g_serial = = IXGBE_AUTOC2_10G_SFI ) & &
( link_mode = = IXGBE_AUTOC_LMS_10G_SERIAL ) ) {
/* Switch from 10G SFI to 1G SFI if requested */
if ( ( speed = = IXGBE_LINK_SPEED_1GB_FULL ) & &
( pma_pmd_1g = = IXGBE_AUTOC_1G_SFI ) ) {
autoc & = ~ IXGBE_AUTOC_LMS_MASK ;
if ( autoneg )
autoc | = IXGBE_AUTOC_LMS_1G_AN ;
else
autoc | = IXGBE_AUTOC_LMS_1G_LINK_NO_AN ;
}
}
2009-06-04 11:10:53 +00:00
if ( autoc ! = start_autoc ) {
2009-02-27 15:44:30 +00:00
/* Restart link */
2014-02-27 20:32:41 -08:00
status = hw - > mac . ops . prot_autoc_write ( hw , autoc , false ) ;
if ( ! status )
goto out ;
2009-02-27 15:44:30 +00:00
/* Only poll for autoneg to complete if specified to do so */
if ( autoneg_wait_to_complete ) {
if ( link_mode = = IXGBE_AUTOC_LMS_KX4_KX_KR | |
link_mode = = IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN | |
link_mode = = IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII ) {
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 ;
hw_dbg ( hw , " Autoneg did not "
" complete. \n " ) ;
}
}
}
/* Add delay to filter out noises during initial link setup */
msleep ( 50 ) ;
}
2009-06-04 11:10:53 +00:00
out :
2009-02-27 15:44:30 +00:00
return status ;
}
/**
2009-09-01 13:49:35 +00:00
* ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
2009-02-27 15:44:30 +00:00
* @ hw : pointer to hardware structure
* @ speed : new link speed
* @ autoneg_wait_to_complete : true if waiting is needed to complete
*
* Restarts link on PHY and MAC based on settings passed in .
* */
2009-09-01 13:49:35 +00:00
static s32 ixgbe_setup_copper_link_82599 ( struct ixgbe_hw * hw ,
ixgbe_link_speed speed ,
bool autoneg_wait_to_complete )
2009-02-27 15:44:30 +00:00
{
s32 status ;
/* Setup the PHY according to input speed */
2012-12-15 03:28:24 +00:00
status = hw - > phy . ops . setup_link_speed ( hw , speed ,
2009-02-27 15:44:30 +00:00
autoneg_wait_to_complete ) ;
/* Set up MAC */
2009-09-01 13:49:35 +00:00
ixgbe_start_mac_link_82599 ( hw , autoneg_wait_to_complete ) ;
2009-02-27 15:44:30 +00:00
return status ;
}
/**
* ixgbe_reset_hw_82599 - Perform hardware reset
* @ hw : pointer to hardware structure
*
* Resets the hardware by resetting the transmit and receive units , masks
* and clears all interrupts , perform a PHY reset , and perform a link ( MAC )
* reset .
* */
2009-08-25 04:47:32 +00:00
static s32 ixgbe_reset_hw_82599 ( struct ixgbe_hw * hw )
2009-02-27 15:44:30 +00:00
{
2011-07-15 07:29:44 +00:00
ixgbe_link_speed link_speed ;
s32 status ;
2014-02-27 20:32:41 -08:00
u32 ctrl , i , autoc , autoc2 ;
2013-02-21 03:00:04 +00:00
u32 curr_lms ;
2011-07-15 07:29:44 +00:00
bool link_up = false ;
2009-02-27 15:44:30 +00:00
/* 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 ;
/* flush pending Tx transactions */
ixgbe_clear_tx_pending ( hw ) ;
2009-02-27 15:44:30 +00:00
2009-04-09 22:28:15 +00:00
/* PHY ops must be identified and initialized prior to reset */
2009-04-09 22:27:57 +00:00
2011-02-25 07:49:39 +00:00
/* Identify PHY and related function pointers */
2009-04-09 22:28:15 +00:00
status = hw - > phy . ops . init ( hw ) ;
2009-04-09 22:27:57 +00:00
2009-04-09 22:28:15 +00:00
if ( status = = IXGBE_ERR_SFP_NOT_SUPPORTED )
goto reset_hw_out ;
2009-04-09 22:27:57 +00:00
2009-04-09 22:28:15 +00:00
/* Setup SFP module if there is one present. */
if ( hw - > phy . sfp_setup_needed ) {
status = hw - > mac . ops . setup_sfp ( hw ) ;
hw - > phy . sfp_setup_needed = false ;
2009-04-09 22:27:57 +00:00
}
2009-02-27 15:44:30 +00:00
2011-02-25 07:49:39 +00:00
if ( status = = IXGBE_ERR_SFP_NOT_SUPPORTED )
goto reset_hw_out ;
2009-04-09 22:28:15 +00:00
/* Reset PHY */
if ( hw - > phy . reset_disable = = false & & hw - > phy . ops . reset ! = NULL )
hw - > phy . ops . reset ( hw ) ;
2013-04-12 08:36:42 +00:00
/* remember AUTOC from before we reset */
2014-02-27 20:32:41 -08:00
curr_lms = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) & IXGBE_AUTOC_LMS_MASK ;
2013-02-21 03:00:04 +00:00
2011-02-14 08:45:13 +00:00
mac_reset_top :
2009-02-27 15:44:30 +00:00
/*
2011-07-15 07:29:44 +00:00
* Issue global reset to the MAC . Needs to be SW reset if link is up .
* If link reset is used when link is up , it might reset the PHY when
* mng is using it . If link is down or the flag to force full link
* reset is set , then perform link reset .
2009-02-27 15:44:30 +00:00
*/
2011-07-15 07:29:44 +00:00
ctrl = IXGBE_CTRL_LNK_RST ;
if ( ! hw - > force_full_reset ) {
hw - > mac . ops . check_link ( hw , & link_speed , & link_up , false ) ;
if ( link_up )
ctrl = IXGBE_CTRL_RST ;
}
ctrl | = IXGBE_READ_REG ( hw , IXGBE_CTRL ) ;
IXGBE_WRITE_REG ( hw , IXGBE_CTRL , ctrl ) ;
2009-02-27 15:44:30 +00: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 ) ;
2011-07-15 07:29:44 +00:00
if ( ! ( ctrl & IXGBE_CTRL_RST_MASK ) )
2009-02-27 15:44:30 +00:00
break ;
}
2011-07-15 07:29:44 +00:00
if ( ctrl & IXGBE_CTRL_RST_MASK ) {
2009-02-27 15:44:30 +00:00
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 ;
}
2009-02-27 15:44:30 +00:00
/*
* Store the original AUTOC / AUTOC2 values if they have not been
* stored off yet . Otherwise restore the stored original
* values since the reset operation sets back to defaults .
*/
2014-02-27 20:32:41 -08:00
autoc = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
2009-02-27 15:44:30 +00:00
autoc2 = IXGBE_READ_REG ( hw , IXGBE_AUTOC2 ) ;
2013-04-12 08:36:47 +00:00
/* Enable link if disabled in NVM */
if ( autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK ) {
autoc2 & = ~ IXGBE_AUTOC2_LINK_DISABLE_MASK ;
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC2 , autoc2 ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
}
2009-02-27 15:44:30 +00:00
if ( hw - > mac . orig_link_settings_stored = = false ) {
2014-02-27 20:32:41 -08:00
hw - > mac . orig_autoc = autoc ;
2009-02-27 15:44:30 +00:00
hw - > mac . orig_autoc2 = autoc2 ;
hw - > mac . orig_link_settings_stored = true ;
2009-03-13 22:15:31 +00:00
} else {
2013-02-21 03:00:04 +00:00
/* If MNG FW is running on a multi-speed device that
* doesn ' t autoneg with out driver support we need to
* leave LMS in the state it was before we MAC reset .
2013-02-28 08:08:44 +00:00
* Likewise if we support WoL we don ' t want change the
* LMS state either .
2013-02-21 03:00:04 +00:00
*/
2013-02-28 08:08:44 +00:00
if ( ( hw - > phy . multispeed_fiber & & hw - > mng_fw_enabled ) | |
2013-04-13 05:40:37 +00:00
hw - > wol_enabled )
2013-02-21 03:00:04 +00:00
hw - > mac . orig_autoc =
( hw - > mac . orig_autoc & ~ IXGBE_AUTOC_LMS_MASK ) |
curr_lms ;
2014-02-27 20:32:41 -08:00
if ( autoc ! = hw - > mac . orig_autoc ) {
status = hw - > mac . ops . prot_autoc_write ( hw ,
hw - > mac . orig_autoc ,
false ) ;
if ( ! status )
goto reset_hw_out ;
2012-10-24 06:19:01 +00:00
}
2009-02-27 15:44:30 +00:00
if ( ( autoc2 & IXGBE_AUTOC2_UPPER_MASK ) ! =
( hw - > mac . orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK ) ) {
autoc2 & = ~ IXGBE_AUTOC2_UPPER_MASK ;
autoc2 | = ( hw - > mac . orig_autoc2 &
IXGBE_AUTOC2_UPPER_MASK ) ;
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC2 , autoc2 ) ;
}
}
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 . Also reset num_rar_entries to 128 ,
* since we modify this value when programming the SAN MAC address .
*/
hw - > mac . num_rar_entries = 128 ;
hw - > mac . ops . init_rx_addrs ( hw ) ;
2009-05-17 12:32:25 +00:00
/* Store the permanent SAN mac address */
hw - > mac . ops . get_san_mac_addr ( hw , hw - > mac . san_addr ) ;
2009-05-17 12:32:48 +00:00
/* Add the SAN MAC address to the RAR only if it's a valid address */
2012-10-24 17:19:02 +00:00
if ( is_valid_ether_addr ( hw - > mac . san_addr ) ) {
2009-05-17 12:32:48 +00:00
hw - > mac . ops . set_rar ( hw , hw - > mac . num_rar_entries - 1 ,
hw - > mac . san_addr , 0 , IXGBE_RAH_AV ) ;
2012-05-05 05:32:52 +00:00
/* Save the SAN MAC RAR index */
hw - > mac . san_mac_rar_index = hw - > mac . num_rar_entries - 1 ;
2009-05-17 12:32:48 +00:00
/* Reserve the last RAR for the SAN MAC address */
hw - > mac . num_rar_entries - - ;
}
2009-10-28 18:23:57 +00:00
/* Store the alternative WWNN/WWPN prefix */
hw - > mac . ops . get_wwn_prefix ( hw , & hw - > mac . wwnn_prefix ,
& hw - > mac . wwpn_prefix ) ;
2009-04-09 22:27:57 +00:00
reset_hw_out :
2009-02-27 15:44:30 +00:00
return status ;
}
2009-06-04 16:01:25 +00:00
/**
* ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables .
* @ hw : pointer to hardware structure
* */
s32 ixgbe_reinit_fdir_tables_82599 ( struct ixgbe_hw * hw )
{
int i ;
u32 fdirctrl = IXGBE_READ_REG ( hw , IXGBE_FDIRCTRL ) ;
fdirctrl & = ~ IXGBE_FDIRCTRL_INIT_DONE ;
/*
* Before starting reinitialization process ,
* FDIRCMD . CMD must be zero .
*/
for ( i = 0 ; i < IXGBE_FDIRCMD_CMD_POLL ; i + + ) {
if ( ! ( IXGBE_READ_REG ( hw , IXGBE_FDIRCMD ) &
IXGBE_FDIRCMD_CMD_MASK ) )
break ;
udelay ( 10 ) ;
}
if ( i > = IXGBE_FDIRCMD_CMD_POLL ) {
2011-01-06 14:29:57 +00:00
hw_dbg ( hw , " Flow Director previous command isn't complete, "
2010-03-24 07:57:35 +00:00
" aborting table re-initialization. \n " ) ;
2009-06-04 16:01:25 +00:00
return IXGBE_ERR_FDIR_REINIT_FAILED ;
}
IXGBE_WRITE_REG ( hw , IXGBE_FDIRFREE , 0 ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
/*
* 82599 adapters flow director init flow cannot be restarted ,
* Workaround 82599 silicon errata by performing the following steps
* before re - writing the FDIRCTRL control register with the same value .
* - write 1 to bit 8 of FDIRCMD register &
* - write 0 to bit 8 of FDIRCMD register
*/
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCMD ,
( IXGBE_READ_REG ( hw , IXGBE_FDIRCMD ) |
IXGBE_FDIRCMD_CLEARHT ) ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCMD ,
( IXGBE_READ_REG ( hw , IXGBE_FDIRCMD ) &
~ IXGBE_FDIRCMD_CLEARHT ) ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
/*
* Clear FDIR Hash register to clear any leftover hashes
* waiting to be programmed .
*/
IXGBE_WRITE_REG ( hw , IXGBE_FDIRHASH , 0x00 ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCTRL , fdirctrl ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
/* Poll init-done after we write FDIRCTRL register */
for ( i = 0 ; i < IXGBE_FDIR_INIT_DONE_POLL ; i + + ) {
if ( IXGBE_READ_REG ( hw , IXGBE_FDIRCTRL ) &
IXGBE_FDIRCTRL_INIT_DONE )
break ;
2012-09-20 03:33:51 +00:00
usleep_range ( 1000 , 2000 ) ;
2009-06-04 16:01:25 +00:00
}
if ( i > = IXGBE_FDIR_INIT_DONE_POLL ) {
hw_dbg ( hw , " Flow Director Signature poll time exceeded! \n " ) ;
return IXGBE_ERR_FDIR_REINIT_FAILED ;
}
/* Clear FDIR statistics registers (read to clear) */
IXGBE_READ_REG ( hw , IXGBE_FDIRUSTAT ) ;
IXGBE_READ_REG ( hw , IXGBE_FDIRFSTAT ) ;
IXGBE_READ_REG ( hw , IXGBE_FDIRMATCH ) ;
IXGBE_READ_REG ( hw , IXGBE_FDIRMISS ) ;
IXGBE_READ_REG ( hw , IXGBE_FDIRLEN ) ;
return 0 ;
}
/**
2011-05-11 07:18:36 +00:00
* ixgbe_fdir_enable_82599 - Initialize Flow Director control registers
2009-06-04 16:01:25 +00:00
* @ hw : pointer to hardware structure
2011-05-11 07:18:36 +00:00
* @ fdirctrl : value to write to flow director control register
2009-06-04 16:01:25 +00:00
* */
2011-05-11 07:18:36 +00:00
static void ixgbe_fdir_enable_82599 ( struct ixgbe_hw * hw , u32 fdirctrl )
2009-06-04 16:01:25 +00:00
{
int i ;
/* Prime the keys for hashing */
2011-01-06 14:29:57 +00:00
IXGBE_WRITE_REG ( hw , IXGBE_FDIRHKEY , IXGBE_ATR_BUCKET_HASH_KEY ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRSKEY , IXGBE_ATR_SIGNATURE_HASH_KEY ) ;
2009-06-04 16:01:25 +00:00
/*
* Poll init - done after we write the register . Estimated times :
* 10 G : PBALLOC = 11 b , timing is 60u s
* 1 G : PBALLOC = 11 b , timing is 600u s
* 100 M : PBALLOC = 11 b , timing is 6 ms
*
* Multiple these timings by 4 if under full Rx load
*
* So we ' ll poll for IXGBE_FDIR_INIT_DONE_POLL times , sleeping for
* 1 msec per poll time . If we ' re at line rate and drop to 100 M , then
* this might not finish in our poll time , but we can live with that
* for now .
*/
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCTRL , fdirctrl ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
for ( i = 0 ; i < IXGBE_FDIR_INIT_DONE_POLL ; i + + ) {
if ( IXGBE_READ_REG ( hw , IXGBE_FDIRCTRL ) &
IXGBE_FDIRCTRL_INIT_DONE )
break ;
2011-03-18 09:32:53 +00:00
usleep_range ( 1000 , 2000 ) ;
2009-06-04 16:01:25 +00:00
}
2011-05-11 07:18:36 +00:00
if ( i > = IXGBE_FDIR_INIT_DONE_POLL )
hw_dbg ( hw , " Flow Director poll time exceeded! \n " ) ;
2009-06-04 16:01:25 +00:00
}
/**
2011-05-11 07:18:36 +00:00
* ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
* @ hw : pointer to hardware structure
* @ fdirctrl : value to write to flow director control register , initially
* contains just the value of the Rx packet buffer allocation
2009-06-04 16:01:25 +00:00
* */
2011-05-11 07:18:36 +00:00
s32 ixgbe_init_fdir_signature_82599 ( struct ixgbe_hw * hw , u32 fdirctrl )
2009-06-04 16:01:25 +00:00
{
2011-05-11 07:18:36 +00:00
/*
* Continue setup of fdirctrl register bits :
* Move the flexible bytes to use the ethertype - shift 6 words
* Set the maximum length per hash bucket to 0xA filters
* Send interrupt when 64 filters are left
*/
fdirctrl | = ( 0x6 < < IXGBE_FDIRCTRL_FLEX_SHIFT ) |
( 0xA < < IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT ) |
( 4 < < IXGBE_FDIRCTRL_FULL_THRESH_SHIFT ) ;
2009-06-04 16:01:25 +00:00
2011-05-11 07:18:36 +00:00
/* write hashes and fdirctrl register, poll for completion */
ixgbe_fdir_enable_82599 ( hw , fdirctrl ) ;
2009-06-04 16:01:25 +00:00
2011-05-11 07:18:36 +00:00
return 0 ;
}
2009-06-04 16:01:25 +00:00
2011-05-11 07:18:36 +00:00
/**
* ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
* @ hw : pointer to hardware structure
* @ fdirctrl : value to write to flow director control register , initially
* contains just the value of the Rx packet buffer allocation
* */
s32 ixgbe_init_fdir_perfect_82599 ( struct ixgbe_hw * hw , u32 fdirctrl )
{
2009-06-04 16:01:25 +00:00
/*
2011-05-11 07:18:36 +00:00
* Continue setup of fdirctrl register bits :
* Turn perfect match filtering on
* Report hash in RSS field of Rx wb descriptor
* Initialize the drop queue
* Move the flexible bytes to use the ethertype - shift 6 words
* Set the maximum length per hash bucket to 0xA filters
* Send interrupt when 64 ( 0x4 * 16 ) filters are left
2009-06-04 16:01:25 +00:00
*/
2011-05-11 07:18:36 +00:00
fdirctrl | = IXGBE_FDIRCTRL_PERFECT_MATCH |
IXGBE_FDIRCTRL_REPORT_STATUS |
( IXGBE_FDIR_DROP_QUEUE < < IXGBE_FDIRCTRL_DROP_Q_SHIFT ) |
( 0x6 < < IXGBE_FDIRCTRL_FLEX_SHIFT ) |
( 0xA < < IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT ) |
( 4 < < IXGBE_FDIRCTRL_FULL_THRESH_SHIFT ) ;
2009-06-04 16:01:25 +00:00
2011-05-11 07:18:36 +00:00
/* write hashes and fdirctrl register, poll for completion */
ixgbe_fdir_enable_82599 ( hw , fdirctrl ) ;
2011-01-06 14:29:57 +00:00
2011-05-11 07:18:36 +00:00
return 0 ;
2009-06-04 16:01:25 +00:00
}
2011-01-06 14:29:58 +00:00
/*
* These defines allow us to quickly generate all of the necessary instructions
* in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION
* for values 0 through 15
*/
# define IXGBE_ATR_COMMON_HASH_KEY \
( IXGBE_ATR_BUCKET_HASH_KEY & IXGBE_ATR_SIGNATURE_HASH_KEY )
# define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \
do { \
u32 n = ( _n ) ; \
if ( IXGBE_ATR_COMMON_HASH_KEY & ( 0x01 < < n ) ) \
common_hash ^ = lo_hash_dword > > n ; \
else if ( IXGBE_ATR_BUCKET_HASH_KEY & ( 0x01 < < n ) ) \
bucket_hash ^ = lo_hash_dword > > n ; \
else if ( IXGBE_ATR_SIGNATURE_HASH_KEY & ( 0x01 < < n ) ) \
sig_hash ^ = lo_hash_dword < < ( 16 - n ) ; \
if ( IXGBE_ATR_COMMON_HASH_KEY & ( 0x01 < < ( n + 16 ) ) ) \
common_hash ^ = hi_hash_dword > > n ; \
else if ( IXGBE_ATR_BUCKET_HASH_KEY & ( 0x01 < < ( n + 16 ) ) ) \
bucket_hash ^ = hi_hash_dword > > n ; \
else if ( IXGBE_ATR_SIGNATURE_HASH_KEY & ( 0x01 < < ( n + 16 ) ) ) \
sig_hash ^ = hi_hash_dword < < ( 16 - n ) ; \
} while ( 0 ) ;
/**
* ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash
* @ stream : input bitstream to compute the hash on
*
* This function is almost identical to the function above but contains
* several optomizations such as unwinding all of the loops , letting the
* compiler work out all of the conditional ifs since the keys are static
* defines , and computing two keys at once since the hashed dword stream
* will be the same for both keys .
* */
static u32 ixgbe_atr_compute_sig_hash_82599 ( union ixgbe_atr_hash_dword input ,
union ixgbe_atr_hash_dword common )
{
u32 hi_hash_dword , lo_hash_dword , flow_vm_vlan ;
u32 sig_hash = 0 , bucket_hash = 0 , common_hash = 0 ;
/* record the flow_vm_vlan bits as they are a key part to the hash */
flow_vm_vlan = ntohl ( input . dword ) ;
/* generate common hash dword */
hi_hash_dword = ntohl ( common . dword ) ;
/* low dword is word swapped version of common */
lo_hash_dword = ( hi_hash_dword > > 16 ) | ( hi_hash_dword < < 16 ) ;
/* apply flow ID/VM pool/VLAN ID bits to hash words */
hi_hash_dword ^ = flow_vm_vlan ^ ( flow_vm_vlan > > 16 ) ;
/* Process bits 0 and 16 */
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 0 ) ;
/*
* apply flow ID / VM pool / VLAN ID bits to lo hash dword , we had to
* delay this because bit 0 of the stream should not be processed
* so we do not add the vlan until after bit 0 was processed
*/
lo_hash_dword ^ = flow_vm_vlan ^ ( flow_vm_vlan < < 16 ) ;
/* Process remaining 30 bit of the key */
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 1 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 2 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 3 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 4 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 5 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 6 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 7 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 8 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 9 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 10 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 11 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 12 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 13 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 14 ) ;
IXGBE_COMPUTE_SIG_HASH_ITERATION ( 15 ) ;
/* combine common_hash result with signature and bucket hashes */
bucket_hash ^ = common_hash ;
bucket_hash & = IXGBE_ATR_HASH_MASK ;
sig_hash ^ = common_hash < < 16 ;
sig_hash & = IXGBE_ATR_HASH_MASK < < 16 ;
/* return completed signature hash */
return sig_hash ^ bucket_hash ;
}
2009-06-04 16:01:25 +00:00
/**
* ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
* @ hw : pointer to hardware structure
2011-01-06 14:29:58 +00:00
* @ input : unique input dword
* @ common : compressed common input dword
2009-06-04 16:01:25 +00:00
* @ queue : queue index to direct traffic to
* */
s32 ixgbe_fdir_add_signature_filter_82599 ( struct ixgbe_hw * hw ,
2011-01-06 14:29:58 +00:00
union ixgbe_atr_hash_dword input ,
union ixgbe_atr_hash_dword common ,
2009-06-04 16:01:25 +00:00
u8 queue )
{
u64 fdirhashcmd ;
2011-01-06 14:29:57 +00:00
u32 fdircmd ;
2009-06-04 16:01:25 +00:00
/*
2011-01-06 14:29:57 +00:00
* Get the flow_type in order to program FDIRCMD properly
* lowest 2 bits are FDIRCMD . L4TYPE , third lowest bit is FDIRCMD . IPV6
2009-06-04 16:01:25 +00:00
*/
2011-01-06 14:29:58 +00:00
switch ( input . formatted . flow_type ) {
2011-01-06 14:29:57 +00:00
case IXGBE_ATR_FLOW_TYPE_TCPV4 :
case IXGBE_ATR_FLOW_TYPE_UDPV4 :
case IXGBE_ATR_FLOW_TYPE_SCTPV4 :
case IXGBE_ATR_FLOW_TYPE_TCPV6 :
case IXGBE_ATR_FLOW_TYPE_UDPV6 :
case IXGBE_ATR_FLOW_TYPE_SCTPV6 :
2009-06-04 16:01:25 +00:00
break ;
default :
2011-01-06 14:29:57 +00:00
hw_dbg ( hw , " Error on flow type input \n " ) ;
2009-06-04 16:01:25 +00:00
return IXGBE_ERR_CONFIG ;
}
2011-01-06 14:29:57 +00:00
/* configure FDIRCMD register */
fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN ;
2011-01-06 14:29:58 +00:00
fdircmd | = input . formatted . flow_type < < IXGBE_FDIRCMD_FLOW_TYPE_SHIFT ;
2011-01-06 14:29:57 +00:00
fdircmd | = ( u32 ) queue < < IXGBE_FDIRCMD_RX_QUEUE_SHIFT ;
/*
* The lower 32 - bits of fdirhashcmd is for FDIRHASH , the upper 32 - bits
* is for FDIRCMD . Then do a 64 - bit register write from FDIRHASH .
*/
fdirhashcmd = ( u64 ) fdircmd < < 32 ;
2011-01-06 14:29:58 +00:00
fdirhashcmd | = ixgbe_atr_compute_sig_hash_82599 ( input , common ) ;
2009-06-04 16:01:25 +00:00
IXGBE_WRITE_REG64 ( hw , IXGBE_FDIRHASH , fdirhashcmd ) ;
2011-01-06 14:29:58 +00:00
hw_dbg ( hw , " Tx Queue=%x hash=%x \n " , queue , ( u32 ) fdirhashcmd ) ;
2009-06-04 16:01:25 +00:00
return 0 ;
}
2011-05-11 07:18:36 +00:00
# define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \
do { \
u32 n = ( _n ) ; \
if ( IXGBE_ATR_BUCKET_HASH_KEY & ( 0x01 < < n ) ) \
bucket_hash ^ = lo_hash_dword > > n ; \
if ( IXGBE_ATR_BUCKET_HASH_KEY & ( 0x01 < < ( n + 16 ) ) ) \
bucket_hash ^ = hi_hash_dword > > n ; \
} while ( 0 ) ;
/**
* ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash
* @ atr_input : input bitstream to compute the hash on
* @ input_mask : mask for the input bitstream
*
* This function serves two main purposes . First it applys the input_mask
* to the atr_input resulting in a cleaned up atr_input data stream .
* Secondly it computes the hash and stores it in the bkt_hash field at
* the end of the input byte stream . This way it will be available for
* future use without needing to recompute the hash .
* */
void ixgbe_atr_compute_perfect_hash_82599 ( union ixgbe_atr_input * input ,
union ixgbe_atr_input * input_mask )
{
u32 hi_hash_dword , lo_hash_dword , flow_vm_vlan ;
u32 bucket_hash = 0 ;
/* Apply masks to input data */
input - > dword_stream [ 0 ] & = input_mask - > dword_stream [ 0 ] ;
input - > dword_stream [ 1 ] & = input_mask - > dword_stream [ 1 ] ;
input - > dword_stream [ 2 ] & = input_mask - > dword_stream [ 2 ] ;
input - > dword_stream [ 3 ] & = input_mask - > dword_stream [ 3 ] ;
input - > dword_stream [ 4 ] & = input_mask - > dword_stream [ 4 ] ;
input - > dword_stream [ 5 ] & = input_mask - > dword_stream [ 5 ] ;
input - > dword_stream [ 6 ] & = input_mask - > dword_stream [ 6 ] ;
input - > dword_stream [ 7 ] & = input_mask - > dword_stream [ 7 ] ;
input - > dword_stream [ 8 ] & = input_mask - > dword_stream [ 8 ] ;
input - > dword_stream [ 9 ] & = input_mask - > dword_stream [ 9 ] ;
input - > dword_stream [ 10 ] & = input_mask - > dword_stream [ 10 ] ;
/* record the flow_vm_vlan bits as they are a key part to the hash */
flow_vm_vlan = ntohl ( input - > dword_stream [ 0 ] ) ;
/* generate common hash dword */
hi_hash_dword = ntohl ( input - > dword_stream [ 1 ] ^
input - > dword_stream [ 2 ] ^
input - > dword_stream [ 3 ] ^
input - > dword_stream [ 4 ] ^
input - > dword_stream [ 5 ] ^
input - > dword_stream [ 6 ] ^
input - > dword_stream [ 7 ] ^
input - > dword_stream [ 8 ] ^
input - > dword_stream [ 9 ] ^
input - > dword_stream [ 10 ] ) ;
/* low dword is word swapped version of common */
lo_hash_dword = ( hi_hash_dword > > 16 ) | ( hi_hash_dword < < 16 ) ;
/* apply flow ID/VM pool/VLAN ID bits to hash words */
hi_hash_dword ^ = flow_vm_vlan ^ ( flow_vm_vlan > > 16 ) ;
/* Process bits 0 and 16 */
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 0 ) ;
/*
* apply flow ID / VM pool / VLAN ID bits to lo hash dword , we had to
* delay this because bit 0 of the stream should not be processed
* so we do not add the vlan until after bit 0 was processed
*/
lo_hash_dword ^ = flow_vm_vlan ^ ( flow_vm_vlan < < 16 ) ;
/* Process remaining 30 bit of the key */
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 1 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 2 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 3 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 4 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 5 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 6 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 7 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 8 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 9 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 10 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 11 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 12 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 13 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 14 ) ;
IXGBE_COMPUTE_BKT_HASH_ITERATION ( 15 ) ;
/*
* Limit hash to 13 bits since max bucket count is 8 K .
* Store result at the end of the input stream .
*/
input - > formatted . bkt_hash = bucket_hash & 0x1FFF ;
}
2011-01-06 14:29:59 +00:00
/**
* ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks
* @ input_mask : mask to be bit swapped
*
* The source and destination port masks for flow director are bit swapped
* in that bit 15 effects bit 0 , 14 effects 1 , 13 , 2 etc . In order to
* generate a correctly swapped value we need to bit swap the mask and that
* is what is accomplished by this function .
* */
2011-05-11 07:18:36 +00:00
static u32 ixgbe_get_fdirtcpm_82599 ( union ixgbe_atr_input * input_mask )
2011-01-06 14:29:59 +00:00
{
2011-05-11 07:18:36 +00:00
u32 mask = ntohs ( input_mask - > formatted . dst_port ) ;
2011-01-06 14:29:59 +00:00
mask < < = IXGBE_FDIRTCPM_DPORTM_SHIFT ;
2011-05-11 07:18:36 +00:00
mask | = ntohs ( input_mask - > formatted . src_port ) ;
2011-01-06 14:29:59 +00:00
mask = ( ( mask & 0x55555555 ) < < 1 ) | ( ( mask & 0xAAAAAAAA ) > > 1 ) ;
mask = ( ( mask & 0x33333333 ) < < 2 ) | ( ( mask & 0xCCCCCCCC ) > > 2 ) ;
mask = ( ( mask & 0x0F0F0F0F ) < < 4 ) | ( ( mask & 0xF0F0F0F0 ) > > 4 ) ;
return ( ( mask & 0x00FF00FF ) < < 8 ) | ( ( mask & 0xFF00FF00 ) > > 8 ) ;
}
/*
* These two macros are meant to address the fact that we have registers
* that are either all or in part big - endian . As a result on big - endian
* systems we will end up byte swapping the value to little - endian before
* it is byte swapped again and written to the hardware in the original
* big - endian format .
*/
# define IXGBE_STORE_AS_BE32(_value) \
( ( ( u32 ) ( _value ) > > 24 ) | ( ( ( u32 ) ( _value ) & 0x00FF0000 ) > > 8 ) | \
( ( ( u32 ) ( _value ) & 0x0000FF00 ) < < 8 ) | ( ( u32 ) ( _value ) < < 24 ) )
# define IXGBE_WRITE_REG_BE32(a, reg, value) \
IXGBE_WRITE_REG ( ( a ) , ( reg ) , IXGBE_STORE_AS_BE32 ( ntohl ( value ) ) )
# define IXGBE_STORE_AS_BE16(_value) \
2011-05-11 07:18:36 +00:00
ntohs ( ( ( u16 ) ( _value ) > > 8 ) | ( ( u16 ) ( _value ) < < 8 ) )
2011-01-06 14:29:59 +00:00
2011-05-11 07:18:36 +00:00
s32 ixgbe_fdir_set_input_mask_82599 ( struct ixgbe_hw * hw ,
union ixgbe_atr_input * input_mask )
2009-06-04 16:01:25 +00:00
{
2011-05-11 07:18:36 +00:00
/* mask IPv6 since it is currently not supported */
u32 fdirm = IXGBE_FDIRM_DIPv6 ;
u32 fdirtcpm ;
2009-06-04 16:01:25 +00:00
2010-02-10 16:07:54 +00:00
/*
2011-01-06 14:29:59 +00:00
* Program the relevant mask registers . If src / dst_port or src / dst_addr
* are zero , then assume a full mask for that field . Also assume that
* a VLAN of 0 is unspecified , so mask that out as well . L4type
* cannot be masked out in this implementation .
2010-02-10 16:07:54 +00:00
*
* This also assumes IPv4 only . IPv6 masking isn ' t supported at this
* point in time .
*/
2011-01-06 14:29:59 +00:00
2011-05-11 07:18:36 +00:00
/* verify bucket hash is cleared on hash generation */
if ( input_mask - > formatted . bkt_hash )
hw_dbg ( hw , " bucket hash should always be 0 in mask \n " ) ;
/* Program FDIRM and verify partial masks */
switch ( input_mask - > formatted . vm_pool & 0x7F ) {
case 0x0 :
fdirm | = IXGBE_FDIRM_POOL ;
case 0x7F :
2010-02-10 16:07:54 +00:00
break ;
2011-05-11 07:18:36 +00:00
default :
hw_dbg ( hw , " Error on vm pool mask \n " ) ;
return IXGBE_ERR_CONFIG ;
}
switch ( input_mask - > formatted . flow_type & IXGBE_ATR_L4TYPE_MASK ) {
case 0x0 :
fdirm | = IXGBE_FDIRM_L4P ;
if ( input_mask - > formatted . dst_port | |
input_mask - > formatted . src_port ) {
hw_dbg ( hw , " Error on src/dst port mask \n " ) ;
return IXGBE_ERR_CONFIG ;
}
case IXGBE_ATR_L4TYPE_MASK :
2010-02-10 16:07:54 +00:00
break ;
2011-05-11 07:18:36 +00:00
default :
hw_dbg ( hw , " Error on flow type mask \n " ) ;
return IXGBE_ERR_CONFIG ;
}
switch ( ntohs ( input_mask - > formatted . vlan_id ) & 0xEFFF ) {
2011-01-06 14:29:59 +00:00
case 0x0000 :
2011-05-11 07:18:36 +00:00
/* mask VLAN ID, fall through to mask VLAN priority */
fdirm | = IXGBE_FDIRM_VLANID ;
case 0x0FFF :
/* mask VLAN priority */
fdirm | = IXGBE_FDIRM_VLANP ;
break ;
case 0xE000 :
/* mask VLAN ID only, fall through */
fdirm | = IXGBE_FDIRM_VLANID ;
case 0xEFFF :
/* no VLAN fields masked */
2010-02-10 16:07:54 +00:00
break ;
2011-01-06 14:29:59 +00:00
default :
hw_dbg ( hw , " Error on VLAN mask \n " ) ;
return IXGBE_ERR_CONFIG ;
2010-02-10 16:07:54 +00:00
}
2011-05-11 07:18:36 +00:00
switch ( input_mask - > formatted . flex_bytes & 0xFFFF ) {
case 0x0000 :
/* Mask Flex Bytes, fall through */
fdirm | = IXGBE_FDIRM_FLEX ;
case 0xFFFF :
break ;
default :
hw_dbg ( hw , " Error on flexible byte mask \n " ) ;
return IXGBE_ERR_CONFIG ;
2011-01-06 14:29:59 +00:00
}
2010-02-10 16:07:54 +00:00
/* Now mask VM pool and destination IPv6 - bits 5 and 2 */
IXGBE_WRITE_REG ( hw , IXGBE_FDIRM , fdirm ) ;
2009-06-04 16:01:25 +00:00
2011-01-06 14:29:59 +00:00
/* store the TCP/UDP port masks, bit reversed from port layout */
2011-05-11 07:18:36 +00:00
fdirtcpm = ixgbe_get_fdirtcpm_82599 ( input_mask ) ;
2011-01-06 14:29:59 +00:00
/* write both the same so that UDP and TCP use the same mask */
IXGBE_WRITE_REG ( hw , IXGBE_FDIRTCPM , ~ fdirtcpm ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRUDPM , ~ fdirtcpm ) ;
/* store source and destination IP masks (big-enian) */
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRSIP4M ,
2011-05-11 07:18:36 +00:00
~ input_mask - > formatted . src_ip [ 0 ] ) ;
2011-01-06 14:29:59 +00:00
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRDIP4M ,
2011-05-11 07:18:36 +00:00
~ input_mask - > formatted . dst_ip [ 0 ] ) ;
2011-01-06 14:29:59 +00:00
2011-05-11 07:18:36 +00:00
return 0 ;
}
2011-01-06 14:29:59 +00:00
2011-05-11 07:18:36 +00:00
s32 ixgbe_fdir_write_perfect_filter_82599 ( struct ixgbe_hw * hw ,
union ixgbe_atr_input * input ,
u16 soft_id , u8 queue )
{
u32 fdirport , fdirvlan , fdirhash , fdircmd ;
/* currently IPv6 is not supported, must be programmed with 0 */
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRSIPv6 ( 0 ) ,
input - > formatted . src_ip [ 0 ] ) ;
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRSIPv6 ( 1 ) ,
input - > formatted . src_ip [ 1 ] ) ;
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRSIPv6 ( 2 ) ,
input - > formatted . src_ip [ 2 ] ) ;
/* record the source address (big-endian) */
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRIPSA , input - > formatted . src_ip [ 0 ] ) ;
/* record the first 32 bits of the destination address (big-endian) */
IXGBE_WRITE_REG_BE32 ( hw , IXGBE_FDIRIPDA , input - > formatted . dst_ip [ 0 ] ) ;
2011-01-06 14:29:59 +00:00
/* record source and destination port (little-endian)*/
fdirport = ntohs ( input - > formatted . dst_port ) ;
fdirport < < = IXGBE_FDIRPORT_DESTINATION_SHIFT ;
fdirport | = ntohs ( input - > formatted . src_port ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRPORT , fdirport ) ;
2011-05-11 07:18:36 +00:00
/* record vlan (little-endian) and flex_bytes(big-endian) */
fdirvlan = IXGBE_STORE_AS_BE16 ( input - > formatted . flex_bytes ) ;
fdirvlan < < = IXGBE_FDIRVLAN_FLEX_SHIFT ;
fdirvlan | = ntohs ( input - > formatted . vlan_id ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRVLAN , fdirvlan ) ;
2011-01-06 14:29:59 +00:00
2011-05-11 07:18:36 +00:00
/* configure FDIRHASH register */
fdirhash = input - > formatted . bkt_hash ;
fdirhash | = soft_id < < IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRHASH , fdirhash ) ;
/*
* flush all previous writes to make certain registers are
* programmed prior to issuing the command
*/
IXGBE_WRITE_FLUSH ( hw ) ;
2011-01-06 14:29:59 +00:00
/* configure FDIRCMD register */
fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN ;
2011-05-11 07:18:36 +00:00
if ( queue = = IXGBE_FDIR_DROP_QUEUE )
fdircmd | = IXGBE_FDIRCMD_DROP ;
2011-01-06 14:29:59 +00:00
fdircmd | = input - > formatted . flow_type < < IXGBE_FDIRCMD_FLOW_TYPE_SHIFT ;
fdircmd | = ( u32 ) queue < < IXGBE_FDIRCMD_RX_QUEUE_SHIFT ;
2011-05-11 07:18:36 +00:00
fdircmd | = ( u32 ) input - > formatted . vm_pool < < IXGBE_FDIRCMD_VT_POOL_SHIFT ;
2011-01-06 14:29:59 +00:00
2009-06-04 16:01:25 +00:00
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCMD , fdircmd ) ;
return 0 ;
}
2011-01-06 14:29:59 +00:00
2011-05-11 07:18:36 +00:00
s32 ixgbe_fdir_erase_perfect_filter_82599 ( struct ixgbe_hw * hw ,
union ixgbe_atr_input * input ,
u16 soft_id )
{
u32 fdirhash ;
u32 fdircmd = 0 ;
u32 retry_count ;
s32 err = 0 ;
/* configure FDIRHASH register */
fdirhash = input - > formatted . bkt_hash ;
fdirhash | = soft_id < < IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRHASH , fdirhash ) ;
/* flush hash to HW */
IXGBE_WRITE_FLUSH ( hw ) ;
/* Query if filter is present */
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCMD , IXGBE_FDIRCMD_CMD_QUERY_REM_FILT ) ;
for ( retry_count = 10 ; retry_count ; retry_count - - ) {
/* allow 10us for query to process */
udelay ( 10 ) ;
/* verify query completed successfully */
fdircmd = IXGBE_READ_REG ( hw , IXGBE_FDIRCMD ) ;
if ( ! ( fdircmd & IXGBE_FDIRCMD_CMD_MASK ) )
break ;
}
if ( ! retry_count )
err = IXGBE_ERR_FDIR_REINIT_FAILED ;
/* if filter exists in hardware then remove it */
if ( fdircmd & IXGBE_FDIRCMD_FILTER_VALID ) {
IXGBE_WRITE_REG ( hw , IXGBE_FDIRHASH , fdirhash ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
IXGBE_WRITE_REG ( hw , IXGBE_FDIRCMD ,
IXGBE_FDIRCMD_CMD_REMOVE_FLOW ) ;
}
return err ;
}
2009-02-27 15:44:30 +00:00
/**
* ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
* @ hw : pointer to hardware structure
* @ reg : analog register to read
* @ val : read value
*
* Performs read operation to Omer analog register specified .
* */
2009-08-25 04:47:32 +00:00
static s32 ixgbe_read_analog_reg8_82599 ( struct ixgbe_hw * hw , u32 reg , u8 * val )
2009-02-27 15:44:30 +00:00
{
u32 core_ctl ;
IXGBE_WRITE_REG ( hw , IXGBE_CORECTL , IXGBE_CORECTL_WRITE_CMD |
( reg < < 8 ) ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
udelay ( 10 ) ;
core_ctl = IXGBE_READ_REG ( hw , IXGBE_CORECTL ) ;
* val = ( u8 ) core_ctl ;
return 0 ;
}
/**
* ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
* @ hw : pointer to hardware structure
* @ reg : atlas register to write
* @ val : value to write
*
* Performs write operation to Omer analog register specified .
* */
2009-08-25 04:47:32 +00:00
static s32 ixgbe_write_analog_reg8_82599 ( struct ixgbe_hw * hw , u32 reg , u8 val )
2009-02-27 15:44:30 +00:00
{
u32 core_ctl ;
core_ctl = ( reg < < 8 ) | val ;
IXGBE_WRITE_REG ( hw , IXGBE_CORECTL , core_ctl ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
udelay ( 10 ) ;
return 0 ;
}
/**
* ixgbe_start_hw_82599 - Prepare hardware for Tx / Rx
* @ hw : pointer to hardware structure
*
2011-03-18 08:18:22 +00:00
* Starts the hardware using the generic start_hw function
* and the generation start_hw function .
* Then performs revision - specific operations , if any .
2009-02-27 15:44:30 +00:00
* */
2009-08-25 04:47:32 +00:00
static s32 ixgbe_start_hw_82599 ( struct ixgbe_hw * hw )
2009-02-27 15:44:30 +00:00
{
2011-03-18 08:18:22 +00:00
s32 ret_val = 0 ;
2009-02-27 15:44:30 +00:00
2009-06-04 16:02:24 +00:00
ret_val = ixgbe_start_hw_generic ( hw ) ;
2011-03-18 08:18:22 +00:00
if ( ret_val ! = 0 )
goto out ;
2009-02-27 15:44:30 +00:00
2011-03-18 08:18:22 +00:00
ret_val = ixgbe_start_hw_gen2 ( hw ) ;
if ( ret_val ! = 0 )
goto out ;
2009-02-27 15:44:30 +00:00
2009-06-04 11:10:53 +00:00
/* We need to run link autotry after the driver loads */
hw - > mac . autotry_restart = true ;
2011-04-04 04:29:41 +00:00
hw - > mac . rx_pb_size = IXGBE_82599_RX_PB_SIZE ;
2009-06-04 11:10:53 +00:00
2009-06-04 16:02:24 +00:00
if ( ret_val = = 0 )
ret_val = ixgbe_verify_fw_version_82599 ( hw ) ;
2011-03-18 08:18:22 +00:00
out :
2009-06-04 16:02:24 +00:00
return ret_val ;
2009-02-27 15:44:30 +00:00
}
/**
* ixgbe_identify_phy_82599 - Get physical layer module
* @ hw : pointer to hardware structure
*
* Determines the physical layer module found on the current adapter .
2011-02-12 10:52:07 +00:00
* If PHY already detected , maintains current PHY type in hw struct ,
* otherwise executes the PHY detection routine .
2009-02-27 15:44:30 +00:00
* */
2011-03-16 01:58:20 +00:00
static s32 ixgbe_identify_phy_82599 ( struct ixgbe_hw * hw )
2009-02-27 15:44:30 +00:00
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID ;
2011-02-12 10:52:07 +00:00
/* Detect PHY if not unknown - returns success if already detected. */
2009-02-27 15:44:30 +00:00
status = ixgbe_identify_phy_generic ( hw ) ;
2011-02-12 10:52:07 +00:00
if ( status ! = 0 ) {
/* 82599 10GBASE-T requires an external PHY */
if ( hw - > mac . ops . get_media_type ( hw ) = = ixgbe_media_type_copper )
goto out ;
else
2013-07-27 06:25:38 +00:00
status = ixgbe_identify_module_generic ( hw ) ;
2011-02-12 10:52:07 +00:00
}
/* Set PHY type none if no PHY detected */
if ( hw - > phy . type = = ixgbe_phy_unknown ) {
hw - > phy . type = ixgbe_phy_none ;
status = 0 ;
}
/* Return error if SFP module has been detected but is not supported */
if ( hw - > phy . type = = ixgbe_phy_sfp_unsupported )
status = IXGBE_ERR_SFP_NOT_SUPPORTED ;
out :
2009-02-27 15:44:30 +00:00
return status ;
}
/**
* ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
* @ hw : pointer to hardware structure
*
* Determines physical layer capabilities of the current configuration .
* */
2009-08-25 04:47:32 +00:00
static u32 ixgbe_get_supported_physical_layer_82599 ( struct ixgbe_hw * hw )
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 autoc2 = IXGBE_READ_REG ( hw , IXGBE_AUTOC2 ) ;
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK ;
u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK ;
u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK ;
u16 ext_ability = 0 ;
2009-03-13 22:12:29 +00:00
u8 comp_codes_10g = 0 ;
2010-06-29 18:30:59 +00:00
u8 comp_codes_1g = 0 ;
2009-02-27 15:44:30 +00:00
2009-04-09 22:28:50 +00:00
hw - > phy . ops . identify ( hw ) ;
2011-02-12 10:52:07 +00:00
switch ( hw - > phy . type ) {
case ixgbe_phy_tn :
case ixgbe_phy_cu_unknown :
2009-04-29 08:08:58 +00:00
hw - > phy . ops . read_reg ( hw , MDIO_PMA_EXTABLE , MDIO_MMD_PMAPMD ,
2011-02-12 10:52:07 +00:00
& 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-12 10:52:07 +00:00
default :
break ;
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_BX ) {
physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
IXGBE_PHYSICAL_LAYER_1000BASE_BX ;
goto out ;
} else
/* SFI mode so read SFP module */
goto sfp_check ;
2009-02-27 15:44:30 +00:00
break ;
2009-04-09 22:28:50 +00:00
case IXGBE_AUTOC_LMS_10G_LINK_NO_AN :
if ( pma_pmd_10g_parallel = = IXGBE_AUTOC_10G_CX4 )
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4 ;
else if ( pma_pmd_10g_parallel = = IXGBE_AUTOC_10G_KX4 )
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 ;
2009-05-17 20:58:04 +00:00
else if ( pma_pmd_10g_parallel = = IXGBE_AUTOC_10G_XAUI )
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI ;
2009-04-09 22:28:50 +00:00
goto out ;
break ;
case IXGBE_AUTOC_LMS_10G_SERIAL :
if ( pma_pmd_10g_serial = = IXGBE_AUTOC2_10G_KR ) {
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR ;
goto out ;
} else if ( pma_pmd_10g_serial = = IXGBE_AUTOC2_10G_SFI )
goto sfp_check ;
break ;
case IXGBE_AUTOC_LMS_KX4_KX_KR :
case IXGBE_AUTOC_LMS_KX4_KX_KR_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 ;
if ( autoc & IXGBE_AUTOC_KR_SUPP )
physical_layer | = IXGBE_PHYSICAL_LAYER_10GBASE_KR ;
goto out ;
break ;
default :
goto out ;
break ;
}
2009-02-27 15:44:30 +00:00
2009-04-09 22:28:50 +00:00
sfp_check :
/* SFP check must be done last since DA modules are sometimes used to
* test KR mode - we need to id KR mode correctly before SFP module .
* Call identify_sfp because the pluggable module may have changed */
hw - > phy . ops . identify_sfp ( hw ) ;
if ( hw - > phy . sfp_type = = ixgbe_sfp_type_not_present )
goto out ;
switch ( hw - > phy . type ) {
2010-05-18 16:00:13 +00:00
case ixgbe_phy_sfp_passive_tyco :
case ixgbe_phy_sfp_passive_unknown :
2013-07-27 06:25:38 +00:00
case ixgbe_phy_qsfp_passive_unknown :
2009-04-09 22:28:50 +00:00
physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU ;
break ;
2010-05-18 16:00:13 +00:00
case ixgbe_phy_sfp_ftl_active :
case ixgbe_phy_sfp_active_unknown :
2013-07-27 06:25:38 +00:00
case ixgbe_phy_qsfp_active_unknown :
2010-05-18 16:00:13 +00:00
physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA ;
break ;
2009-04-09 22:28:50 +00:00
case ixgbe_phy_sfp_avago :
case ixgbe_phy_sfp_ftl :
case ixgbe_phy_sfp_intel :
case ixgbe_phy_sfp_unknown :
2010-06-29 18:30:59 +00:00
hw - > phy . ops . read_i2c_eeprom ( hw ,
IXGBE_SFF_1GBE_COMP_CODES , & comp_codes_1g ) ;
2009-04-09 22:28:50 +00:00
hw - > phy . ops . read_i2c_eeprom ( hw ,
IXGBE_SFF_10GBE_COMP_CODES , & comp_codes_10g ) ;
if ( comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE )
2009-02-27 15:44:30 +00:00
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR ;
2009-04-09 22:28:50 +00:00
else if ( comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE )
2009-02-27 15:44:30 +00:00
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR ;
2010-06-29 18:30:59 +00:00
else if ( comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE )
physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T ;
2009-02-27 15:44:30 +00:00
break ;
2013-07-27 06:25:38 +00:00
case ixgbe_phy_qsfp_intel :
case ixgbe_phy_qsfp_unknown :
hw - > phy . ops . read_i2c_eeprom ( hw ,
IXGBE_SFF_QSFP_10GBE_COMP , & comp_codes_10g ) ;
if ( comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE )
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR ;
else if ( comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE )
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR ;
break ;
2009-02-27 15:44:30 +00:00
default :
break ;
}
2009-04-09 22:28:50 +00:00
out :
2009-02-27 15:44:30 +00:00
return physical_layer ;
}
/**
* ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
* @ hw : pointer to hardware structure
* @ regval : register value to write to RXCTRL
*
* Enables the Rx DMA unit for 82599
* */
2009-08-25 04:47:32 +00:00
static s32 ixgbe_enable_rx_dma_82599 ( struct ixgbe_hw * hw , u32 regval )
2009-02-27 15:44:30 +00:00
{
/*
* Workaround for 82599 silicon errata when enabling the Rx datapath .
* If traffic is incoming before we enable the Rx unit , it could hang
* the Rx DMA unit . Therefore , make sure the security engine is
* completely disabled prior to enabling the Rx unit .
*/
2012-02-18 02:58:58 +00:00
hw - > mac . ops . disable_rx_buff ( hw ) ;
2009-02-27 15:44:30 +00:00
IXGBE_WRITE_REG ( hw , IXGBE_RXCTRL , regval ) ;
2012-02-18 02:58:58 +00:00
hw - > mac . ops . enable_rx_buff ( hw ) ;
2009-02-27 15:44:30 +00:00
return 0 ;
}
2009-06-04 16:02:24 +00:00
/**
* ixgbe_verify_fw_version_82599 - verify fw version for 82599
* @ hw : pointer to hardware structure
*
* Verifies that installed the firmware version is 0.6 or higher
* for SFI devices . All 82599 SFI devices should have version 0.6 or higher .
*
* Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
* if the FW version is not supported .
* */
static s32 ixgbe_verify_fw_version_82599 ( struct ixgbe_hw * hw )
{
s32 status = IXGBE_ERR_EEPROM_VERSION ;
u16 fw_offset , fw_ptp_cfg_offset ;
2013-05-24 07:31:09 +00:00
u16 offset ;
2009-06-04 16:02:24 +00:00
u16 fw_version = 0 ;
/* firmware check is only necessary for SFI devices */
if ( hw - > phy . media_type ! = ixgbe_media_type_fiber ) {
status = 0 ;
goto fw_version_out ;
}
/* get the offset to the Firmware Module block */
2013-05-24 07:31:09 +00:00
offset = IXGBE_FW_PTR ;
if ( hw - > eeprom . ops . read ( hw , offset , & fw_offset ) )
goto fw_version_err ;
2009-06-04 16:02:24 +00:00
if ( ( fw_offset = = 0 ) | | ( fw_offset = = 0xFFFF ) )
goto fw_version_out ;
/* get the offset to the Pass Through Patch Configuration block */
2013-05-24 07:31:09 +00:00
offset = fw_offset + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR ;
if ( hw - > eeprom . ops . read ( hw , offset , & fw_ptp_cfg_offset ) )
goto fw_version_err ;
2009-06-04 16:02:24 +00:00
if ( ( fw_ptp_cfg_offset = = 0 ) | | ( fw_ptp_cfg_offset = = 0xFFFF ) )
goto fw_version_out ;
/* get the firmware version */
2013-05-24 07:31:09 +00:00
offset = fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4 ;
if ( hw - > eeprom . ops . read ( hw , offset , & fw_version ) )
goto fw_version_err ;
2009-06-04 16:02:24 +00:00
if ( fw_version > 0x5 )
status = 0 ;
fw_version_out :
return status ;
2013-05-24 07:31:09 +00:00
fw_version_err :
hw_err ( hw , " eeprom read at offset %d failed \n " , offset ) ;
return IXGBE_ERR_EEPROM_VERSION ;
2009-06-04 16:02:24 +00:00
}
2011-03-18 08:18:32 +00:00
/**
* ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state .
* @ hw : pointer to hardware structure
*
* Returns true if the LESM FW module is present and enabled . Otherwise
* returns false . Smart Speed must be disabled if LESM FW module is enabled .
* */
2014-02-27 20:32:41 -08:00
static bool ixgbe_verify_lesm_fw_enabled_82599 ( struct ixgbe_hw * hw )
2011-03-18 08:18:32 +00:00
{
bool lesm_enabled = false ;
u16 fw_offset , fw_lesm_param_offset , fw_lesm_state ;
s32 status ;
/* get the offset to the Firmware Module block */
status = hw - > eeprom . ops . read ( hw , IXGBE_FW_PTR , & fw_offset ) ;
if ( ( status ! = 0 ) | |
( fw_offset = = 0 ) | | ( fw_offset = = 0xFFFF ) )
goto out ;
/* get the offset to the LESM Parameters block */
status = hw - > eeprom . ops . read ( hw , ( fw_offset +
IXGBE_FW_LESM_PARAMETERS_PTR ) ,
& fw_lesm_param_offset ) ;
if ( ( status ! = 0 ) | |
( fw_lesm_param_offset = = 0 ) | | ( fw_lesm_param_offset = = 0xFFFF ) )
goto out ;
/* get the lesm state word */
status = hw - > eeprom . ops . read ( hw , ( fw_lesm_param_offset +
IXGBE_FW_LESM_STATE_1 ) ,
& fw_lesm_state ) ;
if ( ( status = = 0 ) & &
( fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED ) )
lesm_enabled = true ;
out :
return lesm_enabled ;
}
2011-04-20 08:49:06 +00:00
/**
* ixgbe_read_eeprom_buffer_82599 - Read EEPROM word ( s ) using
* fastest available method
*
* @ hw : pointer to hardware structure
* @ offset : offset of word in EEPROM to read
* @ words : number of words
* @ data : word ( s ) read from the EEPROM
*
* Retrieves 16 bit word ( s ) read from EEPROM
* */
static s32 ixgbe_read_eeprom_buffer_82599 ( struct ixgbe_hw * hw , u16 offset ,
u16 words , u16 * data )
{
struct ixgbe_eeprom_info * eeprom = & hw - > eeprom ;
s32 ret_val = IXGBE_ERR_CONFIG ;
/*
* If EEPROM is detected and can be addressed using 14 bits ,
* use EERD otherwise use bit bang
*/
if ( ( eeprom - > type = = ixgbe_eeprom_spi ) & &
( offset + ( words - 1 ) < = IXGBE_EERD_MAX_ADDR ) )
ret_val = ixgbe_read_eerd_buffer_generic ( hw , offset , words ,
data ) ;
else
ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic ( hw , offset ,
words ,
data ) ;
return ret_val ;
}
2011-04-01 08:17:19 +00:00
/**
* ixgbe_read_eeprom_82599 - Read EEPROM word using
* fastest available method
*
* @ hw : pointer to hardware structure
* @ offset : offset of word in the EEPROM to read
* @ data : word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM
* */
static s32 ixgbe_read_eeprom_82599 ( struct ixgbe_hw * hw ,
u16 offset , u16 * data )
{
struct ixgbe_eeprom_info * eeprom = & hw - > eeprom ;
s32 ret_val = IXGBE_ERR_CONFIG ;
/*
* If EEPROM is detected and can be addressed using 14 bits ,
* use EERD otherwise use bit bang
*/
if ( ( eeprom - > type = = ixgbe_eeprom_spi ) & &
( offset < = IXGBE_EERD_MAX_ADDR ) )
ret_val = ixgbe_read_eerd_generic ( hw , offset , data ) ;
else
ret_val = ixgbe_read_eeprom_bit_bang_generic ( hw , offset , data ) ;
return ret_val ;
}
2012-09-11 06:58:19 +00:00
/**
* ixgbe_reset_pipeline_82599 - perform pipeline reset
*
* @ hw : pointer to hardware structure
*
* Reset pipeline by asserting Restart_AN together with LMS change to ensure
* full pipeline reset . Note - We must hold the SW / FW semaphore before writing
* to AUTOC , so this function assumes the semaphore is held .
* */
2014-02-27 20:32:41 -08:00
static s32 ixgbe_reset_pipeline_82599 ( struct ixgbe_hw * hw )
2012-09-11 06:58:19 +00:00
{
2013-04-12 08:36:47 +00:00
s32 ret_val ;
u32 anlp1_reg = 0 ;
u32 i , autoc_reg , autoc2_reg ;
/* Enable link if disabled in NVM */
autoc2_reg = IXGBE_READ_REG ( hw , IXGBE_AUTOC2 ) ;
if ( autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK ) {
autoc2_reg & = ~ IXGBE_AUTOC2_LINK_DISABLE_MASK ;
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC2 , autoc2_reg ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
}
2012-09-11 06:58:19 +00:00
2014-02-27 20:32:41 -08:00
autoc_reg = IXGBE_READ_REG ( hw , IXGBE_AUTOC ) ;
2012-09-11 06:58:19 +00:00
autoc_reg | = IXGBE_AUTOC_AN_RESTART ;
/* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
2014-02-27 20:32:42 -08:00
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC ,
autoc_reg ^ ( 0x4 < < IXGBE_AUTOC_LMS_SHIFT ) ) ;
2012-09-11 06:58:19 +00:00
/* Wait for AN to leave state 0 */
for ( i = 0 ; i < 10 ; i + + ) {
usleep_range ( 4000 , 8000 ) ;
anlp1_reg = IXGBE_READ_REG ( hw , IXGBE_ANLP1 ) ;
if ( anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK )
break ;
}
if ( ! ( anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK ) ) {
hw_dbg ( hw , " auto negotiation not completed \n " ) ;
ret_val = IXGBE_ERR_RESET_FAILED ;
goto reset_pipeline_out ;
}
ret_val = 0 ;
reset_pipeline_out :
/* Write AUTOC register with original LMS field and Restart_AN */
IXGBE_WRITE_REG ( hw , IXGBE_AUTOC , autoc_reg ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
return ret_val ;
}
2013-07-27 06:25:38 +00:00
/**
* ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C
* @ hw : pointer to hardware structure
* @ byte_offset : byte offset to read
* @ data : value read
*
* Performs byte read operation to SFP module ' s EEPROM over I2C interface at
* a specified device address .
* */
static s32 ixgbe_read_i2c_byte_82599 ( struct ixgbe_hw * hw , u8 byte_offset ,
u8 dev_addr , u8 * data )
{
u32 esdp ;
s32 status ;
s32 timeout = 200 ;
if ( hw - > phy . qsfp_shared_i2c_bus = = true ) {
/* Acquire I2C bus ownership. */
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
esdp | = IXGBE_ESDP_SDP0 ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
while ( timeout ) {
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
if ( esdp & IXGBE_ESDP_SDP1 )
break ;
usleep_range ( 5000 , 10000 ) ;
timeout - - ;
}
if ( ! timeout ) {
hw_dbg ( hw , " Driver can't access resource, acquiring I2C bus timeout. \n " ) ;
status = IXGBE_ERR_I2C ;
goto release_i2c_access ;
}
}
status = ixgbe_read_i2c_byte_generic ( hw , byte_offset , dev_addr , data ) ;
release_i2c_access :
if ( hw - > phy . qsfp_shared_i2c_bus = = true ) {
/* Release I2C bus ownership. */
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
esdp & = ~ IXGBE_ESDP_SDP0 ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
}
return status ;
}
/**
* ixgbe_write_i2c_byte_82599 - Writes 8 bit word over I2C
* @ hw : pointer to hardware structure
* @ byte_offset : byte offset to write
* @ data : value to write
*
* Performs byte write operation to SFP module ' s EEPROM over I2C interface at
* a specified device address .
* */
static s32 ixgbe_write_i2c_byte_82599 ( struct ixgbe_hw * hw , u8 byte_offset ,
u8 dev_addr , u8 data )
{
u32 esdp ;
s32 status ;
s32 timeout = 200 ;
if ( hw - > phy . qsfp_shared_i2c_bus = = true ) {
/* Acquire I2C bus ownership. */
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
esdp | = IXGBE_ESDP_SDP0 ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
while ( timeout ) {
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
if ( esdp & IXGBE_ESDP_SDP1 )
break ;
usleep_range ( 5000 , 10000 ) ;
timeout - - ;
}
if ( ! timeout ) {
hw_dbg ( hw , " Driver can't access resource, acquiring I2C bus timeout. \n " ) ;
status = IXGBE_ERR_I2C ;
goto release_i2c_access ;
}
}
status = ixgbe_write_i2c_byte_generic ( hw , byte_offset , dev_addr , data ) ;
release_i2c_access :
if ( hw - > phy . qsfp_shared_i2c_bus = = true ) {
/* Release I2C bus ownership. */
esdp = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ;
esdp & = ~ IXGBE_ESDP_SDP0 ;
IXGBE_WRITE_REG ( hw , IXGBE_ESDP , esdp ) ;
IXGBE_WRITE_FLUSH ( hw ) ;
}
return status ;
}
2009-02-27 15:44:30 +00:00
static struct ixgbe_mac_operations mac_ops_82599 = {
. init_hw = & ixgbe_init_hw_generic ,
. reset_hw = & ixgbe_reset_hw_82599 ,
. start_hw = & ixgbe_start_hw_82599 ,
. clear_hw_cntrs = & ixgbe_clear_hw_cntrs_generic ,
. get_media_type = & ixgbe_get_media_type_82599 ,
. get_supported_physical_layer = & ixgbe_get_supported_physical_layer_82599 ,
. enable_rx_dma = & ixgbe_enable_rx_dma_82599 ,
2012-02-18 02:58:58 +00:00
. disable_rx_buff = & ixgbe_disable_rx_buff_generic ,
. enable_rx_buff = & ixgbe_enable_rx_buff_generic ,
2009-02-27 15:44:30 +00:00
. get_mac_addr = & ixgbe_get_mac_addr_generic ,
2010-05-13 17:33:41 +00:00
. get_san_mac_addr = & ixgbe_get_san_mac_addr_generic ,
2011-03-31 09:36:18 +00:00
. get_device_caps = & ixgbe_get_device_caps_generic ,
2010-11-16 19:27:15 -08:00
. get_wwn_prefix = & ixgbe_get_wwn_prefix_generic ,
2009-02-27 15:44:30 +00:00
. stop_adapter = & ixgbe_stop_adapter_generic ,
. get_bus_info = & ixgbe_get_bus_info_generic ,
. set_lan_id = & ixgbe_set_lan_id_multi_port_pcie ,
. read_analog_reg8 = & ixgbe_read_analog_reg8_82599 ,
. write_analog_reg8 = & ixgbe_write_analog_reg8_82599 ,
2013-06-25 07:59:23 +00:00
. stop_link_on_d3 = & ixgbe_stop_mac_link_on_d3_82599 ,
2009-02-27 15:44:30 +00:00
. setup_link = & ixgbe_setup_mac_link_82599 ,
2011-05-02 12:34:10 +00:00
. set_rxpba = & ixgbe_set_rxpba_generic ,
2010-05-13 17:33:41 +00:00
. check_link = & ixgbe_check_mac_link_generic ,
2009-02-27 15:44:30 +00:00
. get_link_capabilities = & ixgbe_get_link_capabilities_82599 ,
. 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 ,
2009-02-27 15:44:30 +00:00
. set_rar = & ixgbe_set_rar_generic ,
. clear_rar = & ixgbe_clear_rar_generic ,
2010-05-13 17:33:41 +00:00
. set_vmdq = & ixgbe_set_vmdq_generic ,
2012-05-05 05:32:52 +00:00
. set_vmdq_san_mac = & ixgbe_set_vmdq_san_mac_generic ,
2010-05-13 17:33:41 +00:00
. clear_vmdq = & ixgbe_clear_vmdq_generic ,
2009-02-27 15:44:30 +00:00
. 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 ,
2010-05-13 17:33:41 +00:00
. clear_vfta = & ixgbe_clear_vfta_generic ,
. set_vfta = & ixgbe_set_vfta_generic ,
. fc_enable = & ixgbe_fc_enable_generic ,
2011-05-07 07:40:20 +00:00
. set_fw_drv_ver = & ixgbe_set_fw_drv_ver_generic ,
2010-05-13 17:33:41 +00:00
. init_uta_tables = & ixgbe_init_uta_tables_generic ,
2009-02-27 15:44:30 +00:00
. setup_sfp = & ixgbe_setup_sfp_modules_82599 ,
2010-11-18 03:02:52 +00:00
. set_mac_anti_spoofing = & ixgbe_set_mac_anti_spoofing ,
. set_vlan_anti_spoofing = & ixgbe_set_vlan_anti_spoofing ,
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 = & ixgbe_get_thermal_sensor_data_generic ,
. init_thermal_sensor_thresh = & ixgbe_init_thermal_sensor_thresh_generic ,
2013-02-21 03:00:04 +00:00
. mng_fw_enabled = & ixgbe_mng_enabled ,
2014-02-27 20:32:41 -08:00
. prot_autoc_read = & prot_autoc_read_82599 ,
. prot_autoc_write = & prot_autoc_write_82599 ,
2009-02-27 15:44:30 +00:00
} ;
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
2011-02-25 07:49:39 +00:00
. init_params = & ixgbe_init_eeprom_params_generic ,
2011-04-01 08:17:19 +00:00
. read = & ixgbe_read_eeprom_82599 ,
2011-04-20 08:49:06 +00:00
. read_buffer = & ixgbe_read_eeprom_buffer_82599 ,
2011-02-25 07:49:39 +00:00
. write = & ixgbe_write_eeprom_generic ,
2011-04-20 08:49:06 +00:00
. write_buffer = & ixgbe_write_eeprom_buffer_bit_bang_generic ,
2011-02-25 07:49:39 +00:00
. calc_checksum = & ixgbe_calc_eeprom_checksum_generic ,
. validate_checksum = & ixgbe_validate_eeprom_checksum_generic ,
. update_checksum = & ixgbe_update_eeprom_checksum_generic ,
2009-02-27 15:44:30 +00:00
} ;
static struct ixgbe_phy_operations phy_ops_82599 = {
2011-02-25 07:49:39 +00:00
. identify = & ixgbe_identify_phy_82599 ,
2013-07-27 06:25:38 +00:00
. identify_sfp = & ixgbe_identify_module_generic ,
2011-02-25 07:49:39 +00:00
. init = & ixgbe_init_phy_ops_82599 ,
. reset = & ixgbe_reset_phy_generic ,
. read_reg = & ixgbe_read_phy_reg_generic ,
. write_reg = & ixgbe_write_phy_reg_generic ,
. setup_link = & ixgbe_setup_phy_link_generic ,
. setup_link_speed = & ixgbe_setup_phy_link_speed_generic ,
. read_i2c_byte = & ixgbe_read_i2c_byte_generic ,
. write_i2c_byte = & ixgbe_write_i2c_byte_generic ,
2012-12-19 07:14:17 +00:00
. read_i2c_sff8472 = & ixgbe_read_i2c_sff8472_generic ,
2011-02-25 07:49:39 +00:00
. read_i2c_eeprom = & ixgbe_read_i2c_eeprom_generic ,
. write_i2c_eeprom = & ixgbe_write_i2c_eeprom_generic ,
. check_overtemp = & ixgbe_tn_check_overtemp ,
2009-02-27 15:44:30 +00:00
} ;
struct ixgbe_info ixgbe_82599_info = {
. mac = ixgbe_mac_82599EB ,
. get_invariants = & ixgbe_get_invariants_82599 ,
. mac_ops = & mac_ops_82599 ,
. eeprom_ops = & eeprom_ops_82599 ,
. phy_ops = & phy_ops_82599 ,
2010-11-16 19:27:15 -08:00
. mbx_ops = & mbx_ops_generic ,
2009-02-27 15:44:30 +00:00
} ;