2013-09-11 08:40:12 +00:00
/*******************************************************************************
*
* Intel Ethernet Controller XL710 Family Linux Driver
2013-12-18 13:45:51 +00:00
* Copyright ( c ) 2013 - 2014 Intel Corporation .
2013-09-11 08:40:12 +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 .
*
2013-12-18 13:45:51 +00:00
* You should have received a copy of the GNU General Public License along
* with this program . If not , see < http : //www.gnu.org/licenses/>.
2013-09-11 08:40:12 +00:00
*
* 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 "i40e_diag.h"
# include "i40e_prototype.h"
/**
* i40e_diag_reg_pattern_test
* @ hw : pointer to the hw struct
* @ reg : reg to be tested
* @ mask : bits to be touched
* */
static i40e_status i40e_diag_reg_pattern_test ( struct i40e_hw * hw ,
u32 reg , u32 mask )
{
const u32 patterns [ ] = { 0x5A5A5A5A , 0xA5A5A5A5 , 0x00000000 , 0xFFFFFFFF } ;
u32 pat , val , orig_val ;
int i ;
orig_val = rd32 ( hw , reg ) ;
for ( i = 0 ; i < ARRAY_SIZE ( patterns ) ; i + + ) {
pat = patterns [ i ] ;
wr32 ( hw , reg , ( pat & mask ) ) ;
val = rd32 ( hw , reg ) ;
if ( ( val & mask ) ! = ( pat & mask ) ) {
i40e_debug ( hw , I40E_DEBUG_DIAG ,
" %s: reg pattern test failed - reg 0x%08x pat 0x%08x val 0x%08x \n " ,
__func__ , reg , pat , val ) ;
return I40E_ERR_DIAG_TEST_FAILED ;
}
}
wr32 ( hw , reg , orig_val ) ;
val = rd32 ( hw , reg ) ;
if ( val ! = orig_val ) {
i40e_debug ( hw , I40E_DEBUG_DIAG ,
" %s: reg restore test failed - reg 0x%08x orig_val 0x%08x val 0x%08x \n " ,
__func__ , reg , orig_val , val ) ;
return I40E_ERR_DIAG_TEST_FAILED ;
}
return 0 ;
}
struct i40e_diag_reg_test_info i40e_reg_list [ ] = {
/* offset mask elements stride */
2014-04-23 04:49:56 +00:00
{ I40E_QTX_CTL ( 0 ) , 0x0000FFBF , 1 ,
I40E_QTX_CTL ( 1 ) - I40E_QTX_CTL ( 0 ) } ,
{ I40E_PFINT_ITR0 ( 0 ) , 0x00000FFF , 3 ,
I40E_PFINT_ITR0 ( 1 ) - I40E_PFINT_ITR0 ( 0 ) } ,
{ I40E_PFINT_ITRN ( 0 , 0 ) , 0x00000FFF , 1 ,
I40E_PFINT_ITRN ( 0 , 1 ) - I40E_PFINT_ITRN ( 0 , 0 ) } ,
{ I40E_PFINT_ITRN ( 1 , 0 ) , 0x00000FFF , 1 ,
I40E_PFINT_ITRN ( 1 , 1 ) - I40E_PFINT_ITRN ( 1 , 0 ) } ,
{ I40E_PFINT_ITRN ( 2 , 0 ) , 0x00000FFF , 1 ,
I40E_PFINT_ITRN ( 2 , 1 ) - I40E_PFINT_ITRN ( 2 , 0 ) } ,
{ I40E_PFINT_STAT_CTL0 , 0x0000000C , 1 , 0 } ,
{ I40E_PFINT_LNKLST0 , 0x00001FFF , 1 , 0 } ,
{ I40E_PFINT_LNKLSTN ( 0 ) , 0x000007FF , 1 ,
I40E_PFINT_LNKLSTN ( 1 ) - I40E_PFINT_LNKLSTN ( 0 ) } ,
{ I40E_QINT_TQCTL ( 0 ) , 0x000000FF , 1 ,
I40E_QINT_TQCTL ( 1 ) - I40E_QINT_TQCTL ( 0 ) } ,
{ I40E_QINT_RQCTL ( 0 ) , 0x000000FF , 1 ,
I40E_QINT_RQCTL ( 1 ) - I40E_QINT_RQCTL ( 0 ) } ,
{ I40E_PFINT_ICR0_ENA , 0xF7F20000 , 1 , 0 } ,
2013-09-11 08:40:12 +00:00
{ 0 }
} ;
/**
* i40e_diag_reg_test
* @ hw : pointer to the hw struct
*
* Perform registers diagnostic test
* */
i40e_status i40e_diag_reg_test ( struct i40e_hw * hw )
{
i40e_status ret_code = 0 ;
u32 reg , mask ;
u32 i , j ;
2014-04-23 04:49:56 +00:00
for ( i = 0 ; i40e_reg_list [ i ] . offset ! = 0 & &
! ret_code ; i + + ) {
/* set actual reg range for dynamically allocated resources */
if ( i40e_reg_list [ i ] . offset = = I40E_QTX_CTL ( 0 ) & &
hw - > func_caps . num_tx_qp ! = 0 )
i40e_reg_list [ i ] . elements = hw - > func_caps . num_tx_qp ;
if ( ( i40e_reg_list [ i ] . offset = = I40E_PFINT_ITRN ( 0 , 0 ) | |
i40e_reg_list [ i ] . offset = = I40E_PFINT_ITRN ( 1 , 0 ) | |
i40e_reg_list [ i ] . offset = = I40E_PFINT_ITRN ( 2 , 0 ) | |
i40e_reg_list [ i ] . offset = = I40E_QINT_TQCTL ( 0 ) | |
i40e_reg_list [ i ] . offset = = I40E_QINT_RQCTL ( 0 ) ) & &
hw - > func_caps . num_msix_vectors ! = 0 )
i40e_reg_list [ i ] . elements =
hw - > func_caps . num_msix_vectors - 1 ;
/* test register access */
2013-09-11 08:40:12 +00:00
mask = i40e_reg_list [ i ] . mask ;
2014-04-23 04:49:56 +00:00
for ( j = 0 ; j < i40e_reg_list [ i ] . elements & & ! ret_code ; j + + ) {
2013-09-11 08:40:12 +00:00
reg = i40e_reg_list [ i ] . offset +
( j * i40e_reg_list [ i ] . stride ) ;
ret_code = i40e_diag_reg_pattern_test ( hw , reg , mask ) ;
}
}
return ret_code ;
}
/**
* i40e_diag_eeprom_test
* @ hw : pointer to the hw struct
*
* Perform EEPROM diagnostic test
* */
i40e_status i40e_diag_eeprom_test ( struct i40e_hw * hw )
{
i40e_status ret_code ;
u16 reg_val ;
/* read NVM control word and if NVM valid, validate EEPROM checksum*/
ret_code = i40e_read_nvm_word ( hw , I40E_SR_NVM_CONTROL_WORD , & reg_val ) ;
2013-11-26 10:49:16 +00:00
if ( ! ret_code & &
2013-09-11 08:40:12 +00:00
( ( reg_val & I40E_SR_CONTROL_WORD_1_MASK ) = =
2015-06-04 16:24:02 -04:00
BIT ( I40E_SR_CONTROL_WORD_1_SHIFT ) ) )
return i40e_validate_nvm_checksum ( hw , NULL ) ;
else
return I40E_ERR_DIAG_TEST_FAILED ;
2013-09-11 08:40:12 +00:00
}