2007-09-17 12:30:59 -07:00
/*******************************************************************************
Intel PRO / 1000 Linux driver
2008-03-28 09:15:03 -07:00
Copyright ( c ) 1999 - 2008 Intel Corporation .
2007-09-17 12:30:59 -07:00
This program is free software ; you can redistribute it and / or modify it
under the terms and conditions of the GNU General Public License ,
version 2 , as published by the Free Software Foundation .
This program is distributed in the hope it will be useful , but WITHOUT
ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
more details .
You should have received a copy of the GNU General Public License along with
this program ; if not , write to the Free Software Foundation , Inc . ,
51 Franklin St - Fifth Floor , Boston , MA 02110 - 1301 USA .
The full GNU General Public License is included in this distribution in
the file called " COPYING " .
Contact Information :
Linux NICS < linux . nics @ intel . com >
e1000 - devel Mailing List < e1000 - devel @ lists . sourceforge . net >
Intel Corporation , 5200 N . E . Elam Young Parkway , Hillsboro , OR 97124 - 6497
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* 82562 G - 2 10 / 100 Network Connection
* 82562 GT 10 / 100 Network Connection
* 82562 GT - 2 10 / 100 Network Connection
* 82562 V 10 / 100 Network Connection
* 82562 V - 2 10 / 100 Network Connection
* 82566 DC - 2 Gigabit Network Connection
* 82566 DC Gigabit Network Connection
* 82566 DM - 2 Gigabit Network Connection
* 82566 DM Gigabit Network Connection
* 82566 MC Gigabit Network Connection
* 82566 MM Gigabit Network Connection
2008-04-29 09:16:05 -07:00
* 82567L M Gigabit Network Connection
* 82567L F Gigabit Network Connection
* 82567L M - 2 Gigabit Network Connection
* 82567L F - 2 Gigabit Network Connection
* 82567 V - 2 Gigabit Network Connection
2008-08-26 18:36:50 -07:00
* 82567L F - 3 Gigabit Network Connection
* 82567L M - 3 Gigabit Network Connection
2008-08-26 18:36:36 -07:00
* 82567L M - 4 Gigabit Network Connection
2007-09-17 12:30:59 -07:00
*/
# include <linux/netdevice.h>
# include <linux/ethtool.h>
# include <linux/delay.h>
# include <linux/pci.h>
# include "e1000.h"
# define ICH_FLASH_GFPREG 0x0000
# define ICH_FLASH_HSFSTS 0x0004
# define ICH_FLASH_HSFCTL 0x0006
# define ICH_FLASH_FADDR 0x0008
# define ICH_FLASH_FDATA0 0x0010
# define ICH_FLASH_READ_COMMAND_TIMEOUT 500
# define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500
# define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000
# define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
# define ICH_FLASH_CYCLE_REPEAT_COUNT 10
# define ICH_CYCLE_READ 0
# define ICH_CYCLE_WRITE 2
# define ICH_CYCLE_ERASE 3
# define FLASH_GFPREG_BASE_MASK 0x1FFF
# define FLASH_SECTOR_ADDR_SHIFT 12
# define ICH_FLASH_SEG_SIZE_256 256
# define ICH_FLASH_SEG_SIZE_4K 4096
# define ICH_FLASH_SEG_SIZE_8K 8192
# define ICH_FLASH_SEG_SIZE_64K 65536
# define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
# define E1000_ICH_MNG_IAMT_MODE 0x2
# define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
( ID_LED_DEF1_OFF2 < < 8 ) | \
( ID_LED_DEF1_ON2 < < 4 ) | \
( ID_LED_DEF1_DEF2 ) )
# define E1000_ICH_NVM_SIG_WORD 0x13
# define E1000_ICH_NVM_SIG_MASK 0xC000
# define E1000_ICH8_LAN_INIT_TIMEOUT 1500
# define E1000_FEXTNVM_SW_CONFIG 1
# define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
# define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
# define E1000_ICH_RAR_ENTRIES 7
# define PHY_PAGE_SHIFT 5
# define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
( ( reg ) & MAX_PHY_REG_ADDRESS ) )
# define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
# define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
# define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
# define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
# define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
/* Offset 04h HSFSTS */
union ich8_hws_flash_status {
struct ich8_hsfsts {
u16 flcdone : 1 ; /* bit 0 Flash Cycle Done */
u16 flcerr : 1 ; /* bit 1 Flash Cycle Error */
u16 dael : 1 ; /* bit 2 Direct Access error Log */
u16 berasesz : 2 ; /* bit 4:3 Sector Erase Size */
u16 flcinprog : 1 ; /* bit 5 flash cycle in Progress */
u16 reserved1 : 2 ; /* bit 13:6 Reserved */
u16 reserved2 : 6 ; /* bit 13:6 Reserved */
u16 fldesvalid : 1 ; /* bit 14 Flash Descriptor Valid */
u16 flockdn : 1 ; /* bit 15 Flash Config Lock-Down */
} hsf_status ;
u16 regval ;
} ;
/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */
/* Offset 06h FLCTL */
union ich8_hws_flash_ctrl {
struct ich8_hsflctl {
u16 flcgo : 1 ; /* 0 Flash Cycle Go */
u16 flcycle : 2 ; /* 2:1 Flash Cycle */
u16 reserved : 5 ; /* 7:3 Reserved */
u16 fldbcount : 2 ; /* 9:8 Flash Data Byte Count */
u16 flockdn : 6 ; /* 15:10 Reserved */
} hsf_ctrl ;
u16 regval ;
} ;
/* ICH Flash Region Access Permissions */
union ich8_hws_flash_regacc {
struct ich8_flracc {
u32 grra : 8 ; /* 0:7 GbE region Read Access */
u32 grwa : 8 ; /* 8:15 GbE region Write Access */
u32 gmrag : 8 ; /* 23:16 GbE Master Read Access Grant */
u32 gmwag : 8 ; /* 31:24 GbE Master Write Access Grant */
} hsf_flregacc ;
u16 regval ;
} ;
static s32 e1000_setup_link_ich8lan ( struct e1000_hw * hw ) ;
static void e1000_clear_hw_cntrs_ich8lan ( struct e1000_hw * hw ) ;
static void e1000_initialize_hw_bits_ich8lan ( struct e1000_hw * hw ) ;
static s32 e1000_check_polarity_ife_ich8lan ( struct e1000_hw * hw ) ;
static s32 e1000_erase_flash_bank_ich8lan ( struct e1000_hw * hw , u32 bank ) ;
static s32 e1000_retry_write_flash_byte_ich8lan ( struct e1000_hw * hw ,
u32 offset , u8 byte ) ;
2008-08-26 18:36:50 -07:00
static s32 e1000_read_flash_byte_ich8lan ( struct e1000_hw * hw , u32 offset ,
u8 * data ) ;
2007-09-17 12:30:59 -07:00
static s32 e1000_read_flash_word_ich8lan ( struct e1000_hw * hw , u32 offset ,
u16 * data ) ;
static s32 e1000_read_flash_data_ich8lan ( struct e1000_hw * hw , u32 offset ,
u8 size , u16 * data ) ;
static s32 e1000_setup_copper_link_ich8lan ( struct e1000_hw * hw ) ;
static s32 e1000_kmrn_lock_loss_workaround_ich8lan ( struct e1000_hw * hw ) ;
2008-08-26 18:36:50 -07:00
static s32 e1000_get_cfg_done_ich8lan ( struct e1000_hw * hw ) ;
2007-09-17 12:30:59 -07:00
static inline u16 __er16flash ( struct e1000_hw * hw , unsigned long reg )
{
return readw ( hw - > flash_address + reg ) ;
}
static inline u32 __er32flash ( struct e1000_hw * hw , unsigned long reg )
{
return readl ( hw - > flash_address + reg ) ;
}
static inline void __ew16flash ( struct e1000_hw * hw , unsigned long reg , u16 val )
{
writew ( val , hw - > flash_address + reg ) ;
}
static inline void __ew32flash ( struct e1000_hw * hw , unsigned long reg , u32 val )
{
writel ( val , hw - > flash_address + reg ) ;
}
# define er16flash(reg) __er16flash(hw, (reg))
# define er32flash(reg) __er32flash(hw, (reg))
# define ew16flash(reg,val) __ew16flash(hw, (reg), (val))
# define ew32flash(reg,val) __ew32flash(hw, (reg), (val))
/**
* e1000_init_phy_params_ich8lan - Initialize PHY function pointers
* @ hw : pointer to the HW structure
*
* Initialize family - specific PHY parameters and function pointers .
* */
static s32 e1000_init_phy_params_ich8lan ( struct e1000_hw * hw )
{
struct e1000_phy_info * phy = & hw - > phy ;
s32 ret_val ;
u16 i = 0 ;
phy - > addr = 1 ;
phy - > reset_delay_us = 100 ;
2008-04-29 09:16:05 -07:00
/*
* We may need to do this twice - once for IGP and if that fails ,
* we ' ll set BM func pointers and try again
*/
ret_val = e1000e_determine_phy_address ( hw ) ;
if ( ret_val ) {
hw - > phy . ops . write_phy_reg = e1000e_write_phy_reg_bm ;
hw - > phy . ops . read_phy_reg = e1000e_read_phy_reg_bm ;
ret_val = e1000e_determine_phy_address ( hw ) ;
if ( ret_val )
return ret_val ;
}
2007-09-17 12:30:59 -07:00
phy - > id = 0 ;
while ( ( e1000_phy_unknown = = e1000e_get_phy_type_from_id ( phy - > id ) ) & &
( i + + < 100 ) ) {
msleep ( 1 ) ;
ret_val = e1000e_get_phy_id ( hw ) ;
if ( ret_val )
return ret_val ;
}
/* Verify phy id */
switch ( phy - > id ) {
case IGP03E1000_E_PHY_ID :
phy - > type = e1000_phy_igp_3 ;
phy - > autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT ;
break ;
case IFE_E_PHY_ID :
case IFE_PLUS_E_PHY_ID :
case IFE_C_E_PHY_ID :
phy - > type = e1000_phy_ife ;
phy - > autoneg_mask = E1000_ALL_NOT_GIG ;
break ;
2008-04-29 09:16:05 -07:00
case BME1000_E_PHY_ID :
phy - > type = e1000_phy_bm ;
phy - > autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT ;
hw - > phy . ops . read_phy_reg = e1000e_read_phy_reg_bm ;
hw - > phy . ops . write_phy_reg = e1000e_write_phy_reg_bm ;
hw - > phy . ops . commit_phy = e1000e_phy_sw_reset ;
break ;
2007-09-17 12:30:59 -07:00
default :
return - E1000_ERR_PHY ;
break ;
}
return 0 ;
}
/**
* e1000_init_nvm_params_ich8lan - Initialize NVM function pointers
* @ hw : pointer to the HW structure
*
* Initialize family - specific NVM parameters and function
* pointers .
* */
static s32 e1000_init_nvm_params_ich8lan ( struct e1000_hw * hw )
{
struct e1000_nvm_info * nvm = & hw - > nvm ;
struct e1000_dev_spec_ich8lan * dev_spec = & hw - > dev_spec . ich8lan ;
u32 gfpreg ;
u32 sector_base_addr ;
u32 sector_end_addr ;
u16 i ;
2008-03-28 09:15:03 -07:00
/* Can't read flash registers if the register set isn't mapped. */
2007-09-17 12:30:59 -07:00
if ( ! hw - > flash_address ) {
hw_dbg ( hw , " ERROR: Flash registers not mapped \n " ) ;
return - E1000_ERR_CONFIG ;
}
nvm - > type = e1000_nvm_flash_sw ;
gfpreg = er32flash ( ICH_FLASH_GFPREG ) ;
2008-03-28 09:15:03 -07:00
/*
* sector_X_addr is a " sector " - aligned address ( 4096 bytes )
2007-09-17 12:30:59 -07:00
* Add 1 to sector_end_addr since this sector is included in
2008-03-28 09:15:03 -07:00
* the overall size .
*/
2007-09-17 12:30:59 -07:00
sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK ;
sector_end_addr = ( ( gfpreg > > 16 ) & FLASH_GFPREG_BASE_MASK ) + 1 ;
/* flash_base_addr is byte-aligned */
nvm - > flash_base_addr = sector_base_addr < < FLASH_SECTOR_ADDR_SHIFT ;
2008-03-28 09:15:03 -07:00
/*
* find total size of the NVM , then cut in half since the total
* size represents two separate NVM banks .
*/
2007-09-17 12:30:59 -07:00
nvm - > flash_bank_size = ( sector_end_addr - sector_base_addr )
< < FLASH_SECTOR_ADDR_SHIFT ;
nvm - > flash_bank_size / = 2 ;
/* Adjust to word count */
nvm - > flash_bank_size / = sizeof ( u16 ) ;
nvm - > word_size = E1000_ICH8_SHADOW_RAM_WORDS ;
/* Clear shadow ram */
for ( i = 0 ; i < nvm - > word_size ; i + + ) {
dev_spec - > shadow_ram [ i ] . modified = 0 ;
dev_spec - > shadow_ram [ i ] . value = 0xFFFF ;
}
return 0 ;
}
/**
* e1000_init_mac_params_ich8lan - Initialize MAC function pointers
* @ hw : pointer to the HW structure
*
* Initialize family - specific MAC parameters and function
* pointers .
* */
static s32 e1000_init_mac_params_ich8lan ( struct e1000_adapter * adapter )
{
struct e1000_hw * hw = & adapter - > hw ;
struct e1000_mac_info * mac = & hw - > mac ;
/* Set media type function pointer */
2008-03-28 09:15:16 -07:00
hw - > phy . media_type = e1000_media_type_copper ;
2007-09-17 12:30:59 -07:00
/* Set mta register count */
mac - > mta_reg_count = 32 ;
/* Set rar entry count */
mac - > rar_entry_count = E1000_ICH_RAR_ENTRIES ;
if ( mac - > type = = e1000_ich8lan )
mac - > rar_entry_count - - ;
/* Set if manageability features are enabled. */
mac - > arc_subsystem_valid = 1 ;
/* Enable PCS Lock-loss workaround for ICH8 */
if ( mac - > type = = e1000_ich8lan )
e1000e_set_kmrn_lock_loss_workaround_ich8lan ( hw , 1 ) ;
return 0 ;
}
2008-04-02 13:48:18 -07:00
static s32 e1000_get_variants_ich8lan ( struct e1000_adapter * adapter )
2007-09-17 12:30:59 -07:00
{
struct e1000_hw * hw = & adapter - > hw ;
s32 rc ;
rc = e1000_init_mac_params_ich8lan ( adapter ) ;
if ( rc )
return rc ;
rc = e1000_init_nvm_params_ich8lan ( hw ) ;
if ( rc )
return rc ;
rc = e1000_init_phy_params_ich8lan ( hw ) ;
if ( rc )
return rc ;
if ( ( adapter - > hw . mac . type = = e1000_ich8lan ) & &
( adapter - > hw . phy . type = = e1000_phy_igp_3 ) )
adapter - > flags | = FLAG_LSC_GIG_SPEED_DROP ;
return 0 ;
}
/**
* e1000_acquire_swflag_ich8lan - Acquire software control flag
* @ hw : pointer to the HW structure
*
* Acquires the software control flag for performing NVM and PHY
* operations . This is a function pointer entry point only called by
* read / write routines for the PHY and NVM parts .
* */
static s32 e1000_acquire_swflag_ich8lan ( struct e1000_hw * hw )
{
u32 extcnf_ctrl ;
u32 timeout = PHY_CFG_TIMEOUT ;
while ( timeout ) {
extcnf_ctrl = er32 ( EXTCNF_CTRL ) ;
extcnf_ctrl | = E1000_EXTCNF_CTRL_SWFLAG ;
ew32 ( EXTCNF_CTRL , extcnf_ctrl ) ;
extcnf_ctrl = er32 ( EXTCNF_CTRL ) ;
if ( extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG )
break ;
mdelay ( 1 ) ;
timeout - - ;
}
if ( ! timeout ) {
hw_dbg ( hw , " FW or HW has locked the resource for too long. \n " ) ;
return - E1000_ERR_CONFIG ;
}
return 0 ;
}
/**
* e1000_release_swflag_ich8lan - Release software control flag
* @ hw : pointer to the HW structure
*
* Releases the software control flag for performing NVM and PHY operations .
* This is a function pointer entry point only called by read / write
* routines for the PHY and NVM parts .
* */
static void e1000_release_swflag_ich8lan ( struct e1000_hw * hw )
{
u32 extcnf_ctrl ;
extcnf_ctrl = er32 ( EXTCNF_CTRL ) ;
extcnf_ctrl & = ~ E1000_EXTCNF_CTRL_SWFLAG ;
ew32 ( EXTCNF_CTRL , extcnf_ctrl ) ;
}
2008-08-26 18:37:06 -07:00
/**
* e1000_check_mng_mode_ich8lan - Checks management mode
* @ hw : pointer to the HW structure
*
* This checks if the adapter has manageability enabled .
* This is a function pointer entry point only called by read / write
* routines for the PHY and NVM parts .
* */
static bool e1000_check_mng_mode_ich8lan ( struct e1000_hw * hw )
{
u32 fwsm = er32 ( FWSM ) ;
return ( fwsm & E1000_FWSM_MODE_MASK ) = =
( E1000_ICH_MNG_IAMT_MODE < < E1000_FWSM_MODE_SHIFT ) ;
}
2007-09-17 12:30:59 -07:00
/**
* e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
* @ hw : pointer to the HW structure
*
* Checks if firmware is blocking the reset of the PHY .
* This is a function pointer entry point only called by
* reset routines .
* */
static s32 e1000_check_reset_block_ich8lan ( struct e1000_hw * hw )
{
u32 fwsm ;
fwsm = er32 ( FWSM ) ;
return ( fwsm & E1000_ICH_FWSM_RSPCIPHY ) ? 0 : E1000_BLK_PHY_RESET ;
}
/**
* e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex
* @ hw : pointer to the HW structure
*
* Forces the speed and duplex settings of the PHY .
* This is a function pointer entry point only called by
* PHY setup routines .
* */
static s32 e1000_phy_force_speed_duplex_ich8lan ( struct e1000_hw * hw )
{
struct e1000_phy_info * phy = & hw - > phy ;
s32 ret_val ;
u16 data ;
bool link ;
if ( phy - > type ! = e1000_phy_ife ) {
ret_val = e1000e_phy_force_speed_duplex_igp ( hw ) ;
return ret_val ;
}
ret_val = e1e_rphy ( hw , PHY_CONTROL , & data ) ;
if ( ret_val )
return ret_val ;
e1000e_phy_force_speed_duplex_setup ( hw , & data ) ;
ret_val = e1e_wphy ( hw , PHY_CONTROL , data ) ;
if ( ret_val )
return ret_val ;
/* Disable MDI-X support for 10/100 */
ret_val = e1e_rphy ( hw , IFE_PHY_MDIX_CONTROL , & data ) ;
if ( ret_val )
return ret_val ;
data & = ~ IFE_PMC_AUTO_MDIX ;
data & = ~ IFE_PMC_FORCE_MDIX ;
ret_val = e1e_wphy ( hw , IFE_PHY_MDIX_CONTROL , data ) ;
if ( ret_val )
return ret_val ;
hw_dbg ( hw , " IFE PMC: %X \n " , data ) ;
udelay ( 1 ) ;
2008-03-28 09:15:16 -07:00
if ( phy - > autoneg_wait_to_complete ) {
2007-09-17 12:30:59 -07:00
hw_dbg ( hw , " Waiting for forced speed/duplex link on IFE phy. \n " ) ;
ret_val = e1000e_phy_has_link_generic ( hw ,
PHY_FORCE_LIMIT ,
100000 ,
& link ) ;
if ( ret_val )
return ret_val ;
if ( ! link )
hw_dbg ( hw , " Link taking longer than expected. \n " ) ;
/* Try once more */
ret_val = e1000e_phy_has_link_generic ( hw ,
PHY_FORCE_LIMIT ,
100000 ,
& link ) ;
if ( ret_val )
return ret_val ;
}
return 0 ;
}
/**
* e1000_phy_hw_reset_ich8lan - Performs a PHY reset
* @ hw : pointer to the HW structure
*
* Resets the PHY
* This is a function pointer entry point called by drivers
* or other shared routines .
* */
static s32 e1000_phy_hw_reset_ich8lan ( struct e1000_hw * hw )
{
struct e1000_phy_info * phy = & hw - > phy ;
u32 i ;
u32 data , cnf_size , cnf_base_addr , sw_cfg_mask ;
s32 ret_val ;
u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT ;
u16 word_addr , reg_data , reg_addr , phy_page = 0 ;
ret_val = e1000e_phy_hw_reset_generic ( hw ) ;
if ( ret_val )
return ret_val ;
2008-03-28 09:15:03 -07:00
/*
* Initialize the PHY from the NVM on ICH platforms . This
2007-09-17 12:30:59 -07:00
* is needed due to an issue where the NVM configuration is
* not properly autoloaded after power transitions .
* Therefore , after each PHY reset , we will load the
* configuration data out of the NVM manually .
*/
if ( hw - > mac . type = = e1000_ich8lan & & phy - > type = = e1000_phy_igp_3 ) {
struct e1000_adapter * adapter = hw - > adapter ;
/* Check if SW needs configure the PHY */
if ( ( adapter - > pdev - > device = = E1000_DEV_ID_ICH8_IGP_M_AMT ) | |
( adapter - > pdev - > device = = E1000_DEV_ID_ICH8_IGP_M ) )
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M ;
else
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG ;
data = er32 ( FEXTNVM ) ;
if ( ! ( data & sw_cfg_mask ) )
return 0 ;
/* Wait for basic configuration completes before proceeding*/
do {
data = er32 ( STATUS ) ;
data & = E1000_STATUS_LAN_INIT_DONE ;
udelay ( 100 ) ;
} while ( ( ! data ) & & - - loop ) ;
2008-03-28 09:15:03 -07:00
/*
* If basic configuration is incomplete before the above loop
2007-09-17 12:30:59 -07:00
* count reaches 0 , loading the configuration from NVM will
* leave the PHY in a bad state possibly resulting in no link .
*/
if ( loop = = 0 ) {
hw_dbg ( hw , " LAN_INIT_DONE not set, increase timeout \n " ) ;
}
/* Clear the Init Done bit for the next init event */
data = er32 ( STATUS ) ;
data & = ~ E1000_STATUS_LAN_INIT_DONE ;
ew32 ( STATUS , data ) ;
2008-03-28 09:15:03 -07:00
/*
* Make sure HW does not configure LCD from PHY
* extended configuration before SW configuration
*/
2007-09-17 12:30:59 -07:00
data = er32 ( EXTCNF_CTRL ) ;
if ( data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE )
return 0 ;
cnf_size = er32 ( EXTCNF_SIZE ) ;
cnf_size & = E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK ;
cnf_size > > = E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT ;
if ( ! cnf_size )
return 0 ;
cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK ;
cnf_base_addr > > = E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT ;
2008-03-28 09:15:03 -07:00
/* Configure LCD from extended configuration region. */
2007-09-17 12:30:59 -07:00
/* cnf_base_addr is in DWORD */
word_addr = ( u16 ) ( cnf_base_addr < < 1 ) ;
for ( i = 0 ; i < cnf_size ; i + + ) {
ret_val = e1000_read_nvm ( hw ,
( word_addr + i * 2 ) ,
1 ,
& reg_data ) ;
if ( ret_val )
return ret_val ;
ret_val = e1000_read_nvm ( hw ,
( word_addr + i * 2 + 1 ) ,
1 ,
& reg_addr ) ;
if ( ret_val )
return ret_val ;
/* Save off the PHY page for future writes. */
if ( reg_addr = = IGP01E1000_PHY_PAGE_SELECT ) {
phy_page = reg_data ;
continue ;
}
reg_addr | = phy_page ;
ret_val = e1e_wphy ( hw , ( u32 ) reg_addr , reg_data ) ;
if ( ret_val )
return ret_val ;
}
}
return 0 ;
}
/**
* e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states
* @ hw : pointer to the HW structure
*
* Populates " phy " structure with various feature states .
* This function is only called by other family - specific
* routines .
* */
static s32 e1000_get_phy_info_ife_ich8lan ( struct e1000_hw * hw )
{
struct e1000_phy_info * phy = & hw - > phy ;
s32 ret_val ;
u16 data ;
bool link ;
ret_val = e1000e_phy_has_link_generic ( hw , 1 , 0 , & link ) ;
if ( ret_val )
return ret_val ;
if ( ! link ) {
hw_dbg ( hw , " Phy info is only valid if link is up \n " ) ;
return - E1000_ERR_CONFIG ;
}
ret_val = e1e_rphy ( hw , IFE_PHY_SPECIAL_CONTROL , & data ) ;
if ( ret_val )
return ret_val ;
phy - > polarity_correction = ( ! ( data & IFE_PSC_AUTO_POLARITY_DISABLE ) ) ;
if ( phy - > polarity_correction ) {
ret_val = e1000_check_polarity_ife_ich8lan ( hw ) ;
if ( ret_val )
return ret_val ;
} else {
/* Polarity is forced */
phy - > cable_polarity = ( data & IFE_PSC_FORCE_POLARITY )
? e1000_rev_polarity_reversed
: e1000_rev_polarity_normal ;
}
ret_val = e1e_rphy ( hw , IFE_PHY_MDIX_CONTROL , & data ) ;
if ( ret_val )
return ret_val ;
phy - > is_mdix = ( data & IFE_PMC_MDIX_STATUS ) ;
/* The following parameters are undefined for 10/100 operation. */
phy - > cable_length = E1000_CABLE_LENGTH_UNDEFINED ;
phy - > local_rx = e1000_1000t_rx_status_undefined ;
phy - > remote_rx = e1000_1000t_rx_status_undefined ;
return 0 ;
}
/**
* e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info
* @ hw : pointer to the HW structure
*
* Wrapper for calling the get_phy_info routines for the appropriate phy type .
* This is a function pointer entry point called by drivers
* or other shared routines .
* */
static s32 e1000_get_phy_info_ich8lan ( struct e1000_hw * hw )
{
switch ( hw - > phy . type ) {
case e1000_phy_ife :
return e1000_get_phy_info_ife_ich8lan ( hw ) ;
break ;
case e1000_phy_igp_3 :
2008-04-29 09:16:05 -07:00
case e1000_phy_bm :
2007-09-17 12:30:59 -07:00
return e1000e_get_phy_info_igp ( hw ) ;
break ;
default :
break ;
}
return - E1000_ERR_PHY_TYPE ;
}
/**
* e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
* @ hw : pointer to the HW structure
*
2008-02-21 15:11:07 -08:00
* Polarity is determined on the polarity reversal feature being enabled .
2007-09-17 12:30:59 -07:00
* This function is only called by other family - specific
* routines .
* */
static s32 e1000_check_polarity_ife_ich8lan ( struct e1000_hw * hw )
{
struct e1000_phy_info * phy = & hw - > phy ;
s32 ret_val ;
u16 phy_data , offset , mask ;
2008-03-28 09:15:03 -07:00
/*
* Polarity is determined based on the reversal feature being enabled .
2007-09-17 12:30:59 -07:00
*/
if ( phy - > polarity_correction ) {
offset = IFE_PHY_EXTENDED_STATUS_CONTROL ;
mask = IFE_PESC_POLARITY_REVERSED ;
} else {
offset = IFE_PHY_SPECIAL_CONTROL ;
mask = IFE_PSC_FORCE_POLARITY ;
}
ret_val = e1e_rphy ( hw , offset , & phy_data ) ;
if ( ! ret_val )
phy - > cable_polarity = ( phy_data & mask )
? e1000_rev_polarity_reversed
: e1000_rev_polarity_normal ;
return ret_val ;
}
/**
* e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
* @ hw : pointer to the HW structure
* @ active : TRUE to enable LPLU , FALSE to disable
*
* Sets the LPLU D0 state according to the active flag . When
* activating LPLU this function also disables smart speed
* and vice versa . LPLU will not be activated unless the
* device autonegotiation advertisement meets standards of
* either 10 or 10 / 100 or 10 / 100 / 1000 at all duplexes .
* This is a function pointer entry point only called by
* PHY setup routines .
* */
static s32 e1000_set_d0_lplu_state_ich8lan ( struct e1000_hw * hw , bool active )
{
struct e1000_phy_info * phy = & hw - > phy ;
u32 phy_ctrl ;
s32 ret_val = 0 ;
u16 data ;
2008-04-29 09:16:05 -07:00
if ( phy - > type = = e1000_phy_ife )
2007-09-17 12:30:59 -07:00
return ret_val ;
phy_ctrl = er32 ( PHY_CTRL ) ;
if ( active ) {
phy_ctrl | = E1000_PHY_CTRL_D0A_LPLU ;
ew32 ( PHY_CTRL , phy_ctrl ) ;
2008-03-28 09:15:03 -07:00
/*
* Call gig speed drop workaround on LPLU before accessing
* any PHY registers
*/
2007-09-17 12:30:59 -07:00
if ( ( hw - > mac . type = = e1000_ich8lan ) & &
( hw - > phy . type = = e1000_phy_igp_3 ) )
e1000e_gig_downshift_workaround_ich8lan ( hw ) ;
/* When LPLU is enabled, we should disable SmartSpeed */
ret_val = e1e_rphy ( hw , IGP01E1000_PHY_PORT_CONFIG , & data ) ;
data & = ~ IGP01E1000_PSCFR_SMART_SPEED ;
ret_val = e1e_wphy ( hw , IGP01E1000_PHY_PORT_CONFIG , data ) ;
if ( ret_val )
return ret_val ;
} else {
phy_ctrl & = ~ E1000_PHY_CTRL_D0A_LPLU ;
ew32 ( PHY_CTRL , phy_ctrl ) ;
2008-03-28 09:15:03 -07:00
/*
* LPLU and SmartSpeed are mutually exclusive . LPLU is used
2007-09-17 12:30:59 -07:00
* during Dx states where the power conservation is most
* important . During driver activity we should enable
2008-03-28 09:15:03 -07:00
* SmartSpeed , so performance is maintained .
*/
2007-09-17 12:30:59 -07:00
if ( phy - > smart_speed = = e1000_smart_speed_on ) {
ret_val = e1e_rphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
2008-03-28 09:15:03 -07:00
& data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
data | = IGP01E1000_PSCFR_SMART_SPEED ;
ret_val = e1e_wphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
2008-03-28 09:15:03 -07:00
data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
} else if ( phy - > smart_speed = = e1000_smart_speed_off ) {
ret_val = e1e_rphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
2008-03-28 09:15:03 -07:00
& data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
data & = ~ IGP01E1000_PSCFR_SMART_SPEED ;
ret_val = e1e_wphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
2008-03-28 09:15:03 -07:00
data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
}
}
return 0 ;
}
/**
* e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state
* @ hw : pointer to the HW structure
* @ active : TRUE to enable LPLU , FALSE to disable
*
* Sets the LPLU D3 state according to the active flag . When
* activating LPLU this function also disables smart speed
* and vice versa . LPLU will not be activated unless the
* device autonegotiation advertisement meets standards of
* either 10 or 10 / 100 or 10 / 100 / 1000 at all duplexes .
* This is a function pointer entry point only called by
* PHY setup routines .
* */
static s32 e1000_set_d3_lplu_state_ich8lan ( struct e1000_hw * hw , bool active )
{
struct e1000_phy_info * phy = & hw - > phy ;
u32 phy_ctrl ;
s32 ret_val ;
u16 data ;
phy_ctrl = er32 ( PHY_CTRL ) ;
if ( ! active ) {
phy_ctrl & = ~ E1000_PHY_CTRL_NOND0A_LPLU ;
ew32 ( PHY_CTRL , phy_ctrl ) ;
2008-03-28 09:15:03 -07:00
/*
* LPLU and SmartSpeed are mutually exclusive . LPLU is used
2007-09-17 12:30:59 -07:00
* during Dx states where the power conservation is most
* important . During driver activity we should enable
2008-03-28 09:15:03 -07:00
* SmartSpeed , so performance is maintained .
*/
2007-09-17 12:30:59 -07:00
if ( phy - > smart_speed = = e1000_smart_speed_on ) {
2008-03-28 09:15:03 -07:00
ret_val = e1e_rphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
& data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
data | = IGP01E1000_PSCFR_SMART_SPEED ;
2008-03-28 09:15:03 -07:00
ret_val = e1e_wphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
} else if ( phy - > smart_speed = = e1000_smart_speed_off ) {
2008-03-28 09:15:03 -07:00
ret_val = e1e_rphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
& data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
data & = ~ IGP01E1000_PSCFR_SMART_SPEED ;
2008-03-28 09:15:03 -07:00
ret_val = e1e_wphy ( hw , IGP01E1000_PHY_PORT_CONFIG ,
data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
}
} else if ( ( phy - > autoneg_advertised = = E1000_ALL_SPEED_DUPLEX ) | |
( phy - > autoneg_advertised = = E1000_ALL_NOT_GIG ) | |
( phy - > autoneg_advertised = = E1000_ALL_10_SPEED ) ) {
phy_ctrl | = E1000_PHY_CTRL_NOND0A_LPLU ;
ew32 ( PHY_CTRL , phy_ctrl ) ;
2008-03-28 09:15:03 -07:00
/*
* Call gig speed drop workaround on LPLU before accessing
* any PHY registers
*/
2007-09-17 12:30:59 -07:00
if ( ( hw - > mac . type = = e1000_ich8lan ) & &
( hw - > phy . type = = e1000_phy_igp_3 ) )
e1000e_gig_downshift_workaround_ich8lan ( hw ) ;
/* When LPLU is enabled, we should disable SmartSpeed */
2008-03-28 09:15:03 -07:00
ret_val = e1e_rphy ( hw , IGP01E1000_PHY_PORT_CONFIG , & data ) ;
2007-09-17 12:30:59 -07:00
if ( ret_val )
return ret_val ;
data & = ~ IGP01E1000_PSCFR_SMART_SPEED ;
2008-03-28 09:15:03 -07:00
ret_val = e1e_wphy ( hw , IGP01E1000_PHY_PORT_CONFIG , data ) ;
2007-09-17 12:30:59 -07:00
}
return 0 ;
}
2008-08-26 18:36:50 -07:00
/**
* e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1
* @ hw : pointer to the HW structure
* @ bank : pointer to the variable that returns the active bank
*
* Reads signature byte from the NVM using the flash access registers .
* */
static s32 e1000_valid_nvm_bank_detect_ich8lan ( struct e1000_hw * hw , u32 * bank )
{
struct e1000_nvm_info * nvm = & hw - > nvm ;
/* flash bank size is in words */
u32 bank1_offset = nvm - > flash_bank_size * sizeof ( u16 ) ;
u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1 ;
u8 bank_high_byte = 0 ;
if ( hw - > mac . type ! = e1000_ich10lan ) {
if ( er32 ( EECD ) & E1000_EECD_SEC1VAL )
* bank = 1 ;
else
* bank = 0 ;
} else {
/*
* Make sure the signature for bank 0 is valid ,
* if not check for bank1
*/
e1000_read_flash_byte_ich8lan ( hw , act_offset , & bank_high_byte ) ;
if ( ( bank_high_byte & 0xC0 ) = = 0x80 ) {
* bank = 0 ;
} else {
/*
* find if segment 1 is valid by verifying
* bit 15 : 14 = 10 b in word 0x13
*/
e1000_read_flash_byte_ich8lan ( hw ,
act_offset + bank1_offset ,
& bank_high_byte ) ;
/* bank1 has a valid signature equivalent to SEC1V */
if ( ( bank_high_byte & 0xC0 ) = = 0x80 ) {
* bank = 1 ;
} else {
hw_dbg ( hw , " ERROR: EEPROM not present \n " ) ;
return - E1000_ERR_NVM ;
}
}
}
return 0 ;
}
2007-09-17 12:30:59 -07:00
/**
* e1000_read_nvm_ich8lan - Read word ( s ) from the NVM
* @ hw : pointer to the HW structure
* @ offset : The offset ( in bytes ) of the word ( s ) to read .
* @ words : Size of data to read in words
* @ data : Pointer to the word ( s ) to read at offset .
*
* Reads a word ( s ) from the NVM using the flash access registers .
* */
static s32 e1000_read_nvm_ich8lan ( struct e1000_hw * hw , u16 offset , u16 words ,
u16 * data )
{
struct e1000_nvm_info * nvm = & hw - > nvm ;
struct e1000_dev_spec_ich8lan * dev_spec = & hw - > dev_spec . ich8lan ;
u32 act_offset ;
s32 ret_val ;
2008-08-26 18:36:50 -07:00
u32 bank = 0 ;
2007-09-17 12:30:59 -07:00
u16 i , word ;
if ( ( offset > = nvm - > word_size ) | | ( words > nvm - > word_size - offset ) | |
( words = = 0 ) ) {
hw_dbg ( hw , " nvm parameter(s) out of bounds \n " ) ;
return - E1000_ERR_NVM ;
}
ret_val = e1000_acquire_swflag_ich8lan ( hw ) ;
if ( ret_val )
return ret_val ;
2008-08-26 18:36:50 -07:00
ret_val = e1000_valid_nvm_bank_detect_ich8lan ( hw , & bank ) ;
if ( ret_val )
return ret_val ;
act_offset = ( bank ) ? nvm - > flash_bank_size : 0 ;
2007-09-17 12:30:59 -07:00
act_offset + = offset ;
for ( i = 0 ; i < words ; i + + ) {
if ( ( dev_spec - > shadow_ram ) & &
( dev_spec - > shadow_ram [ offset + i ] . modified ) ) {
data [ i ] = dev_spec - > shadow_ram [ offset + i ] . value ;
} else {
ret_val = e1000_read_flash_word_ich8lan ( hw ,
act_offset + i ,
& word ) ;
if ( ret_val )
break ;
data [ i ] = word ;
}
}
e1000_release_swflag_ich8lan ( hw ) ;
return ret_val ;
}
/**
* e1000_flash_cycle_init_ich8lan - Initialize flash
* @ hw : pointer to the HW structure
*
* This function does initial flash setup so that a new read / write / erase cycle
* can be started .
* */
static s32 e1000_flash_cycle_init_ich8lan ( struct e1000_hw * hw )
{
union ich8_hws_flash_status hsfsts ;
s32 ret_val = - E1000_ERR_NVM ;
s32 i = 0 ;
hsfsts . regval = er16flash ( ICH_FLASH_HSFSTS ) ;
/* Check if the flash descriptor is valid */
if ( hsfsts . hsf_status . fldesvalid = = 0 ) {
hw_dbg ( hw , " Flash descriptor invalid. "
" SW Sequencing must be used. " ) ;
return - E1000_ERR_NVM ;
}
/* Clear FCERR and DAEL in hw status by writing 1 */
hsfsts . hsf_status . flcerr = 1 ;
hsfsts . hsf_status . dael = 1 ;
ew16flash ( ICH_FLASH_HSFSTS , hsfsts . regval ) ;
2008-03-28 09:15:03 -07:00
/*
* Either we should have a hardware SPI cycle in progress
2007-09-17 12:30:59 -07:00
* bit to check against , in order to start a new cycle or
* FDONE bit should be changed in the hardware so that it
2008-02-21 15:11:07 -08:00
* is 1 after hardware reset , which can then be used as an
2007-09-17 12:30:59 -07:00
* indication whether a cycle is in progress or has been
* completed .
*/
if ( hsfsts . hsf_status . flcinprog = = 0 ) {
2008-03-28 09:15:03 -07:00
/*
* There is no cycle running at present ,
* so we can start a cycle
* Begin by setting Flash Cycle Done .
*/
2007-09-17 12:30:59 -07:00
hsfsts . hsf_status . flcdone = 1 ;
ew16flash ( ICH_FLASH_HSFSTS , hsfsts . regval ) ;
ret_val = 0 ;
} else {
2008-03-28 09:15:03 -07:00
/*
* otherwise poll for sometime so the current
* cycle has a chance to end before giving up .
*/
2007-09-17 12:30:59 -07:00
for ( i = 0 ; i < ICH_FLASH_READ_COMMAND_TIMEOUT ; i + + ) {
hsfsts . regval = __er16flash ( hw , ICH_FLASH_HSFSTS ) ;
if ( hsfsts . hsf_status . flcinprog = = 0 ) {
ret_val = 0 ;
break ;
}
udelay ( 1 ) ;
}
if ( ret_val = = 0 ) {
2008-03-28 09:15:03 -07:00
/*
* Successful in waiting for previous cycle to timeout ,
* now set the Flash Cycle Done .
*/
2007-09-17 12:30:59 -07:00
hsfsts . hsf_status . flcdone = 1 ;
ew16flash ( ICH_FLASH_HSFSTS , hsfsts . regval ) ;
} else {
hw_dbg ( hw , " Flash controller busy, cannot get access " ) ;
}
}
return ret_val ;
}
/**
* e1000_flash_cycle_ich8lan - Starts flash cycle ( read / write / erase )
* @ hw : pointer to the HW structure
* @ timeout : maximum time to wait for completion
*
* This function starts a flash cycle and waits for its completion .
* */
static s32 e1000_flash_cycle_ich8lan ( struct e1000_hw * hw , u32 timeout )
{
union ich8_hws_flash_ctrl hsflctl ;
union ich8_hws_flash_status hsfsts ;
s32 ret_val = - E1000_ERR_NVM ;
u32 i = 0 ;
/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
hsflctl . regval = er16flash ( ICH_FLASH_HSFCTL ) ;
hsflctl . hsf_ctrl . flcgo = 1 ;
ew16flash ( ICH_FLASH_HSFCTL , hsflctl . regval ) ;
/* wait till FDONE bit is set to 1 */
do {
hsfsts . regval = er16flash ( ICH_FLASH_HSFSTS ) ;
if ( hsfsts . hsf_status . flcdone = = 1 )
break ;
udelay ( 1 ) ;
} while ( i + + < timeout ) ;
if ( hsfsts . hsf_status . flcdone = = 1 & & hsfsts . hsf_status . flcerr = = 0 )
return 0 ;
return ret_val ;
}
/**
* e1000_read_flash_word_ich8lan - Read word from flash
* @ hw : pointer to the HW structure
* @ offset : offset to data location
* @ data : pointer to the location for storing the data
*
* Reads the flash word at offset into data . Offset is converted
* to bytes before read .
* */
static s32 e1000_read_flash_word_ich8lan ( struct e1000_hw * hw , u32 offset ,
u16 * data )
{
/* Must convert offset into bytes. */
offset < < = 1 ;
return e1000_read_flash_data_ich8lan ( hw , offset , 2 , data ) ;
}
2008-08-26 18:36:50 -07:00
/**
* e1000_read_flash_byte_ich8lan - Read byte from flash
* @ hw : pointer to the HW structure
* @ offset : The offset of the byte to read .
* @ data : Pointer to a byte to store the value read .
*
* Reads a single byte from the NVM using the flash access registers .
* */
static s32 e1000_read_flash_byte_ich8lan ( struct e1000_hw * hw , u32 offset ,
u8 * data )
{
s32 ret_val ;
u16 word = 0 ;
ret_val = e1000_read_flash_data_ich8lan ( hw , offset , 1 , & word ) ;
if ( ret_val )
return ret_val ;
* data = ( u8 ) word ;
return 0 ;
}
2007-09-17 12:30:59 -07:00
/**
* e1000_read_flash_data_ich8lan - Read byte or word from NVM
* @ hw : pointer to the HW structure
* @ offset : The offset ( in bytes ) of the byte or word to read .
* @ size : Size of data to read , 1 = byte 2 = word
* @ data : Pointer to the word to store the value read .
*
* Reads a byte or word from the NVM using the flash access registers .
* */
static s32 e1000_read_flash_data_ich8lan ( struct e1000_hw * hw , u32 offset ,
u8 size , u16 * data )
{
union ich8_hws_flash_status hsfsts ;
union ich8_hws_flash_ctrl hsflctl ;
u32 flash_linear_addr ;
u32 flash_data = 0 ;
s32 ret_val = - E1000_ERR_NVM ;
u8 count = 0 ;
if ( size < 1 | | size > 2 | | offset > ICH_FLASH_LINEAR_ADDR_MASK )
return - E1000_ERR_NVM ;
flash_linear_addr = ( ICH_FLASH_LINEAR_ADDR_MASK & offset ) +
hw - > nvm . flash_base_addr ;
do {
udelay ( 1 ) ;
/* Steps */
ret_val = e1000_flash_cycle_init_ich8lan ( hw ) ;
if ( ret_val ! = 0 )
break ;
hsflctl . regval = er16flash ( ICH_FLASH_HSFCTL ) ;
/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
hsflctl . hsf_ctrl . fldbcount = size - 1 ;
hsflctl . hsf_ctrl . flcycle = ICH_CYCLE_READ ;
ew16flash ( ICH_FLASH_HSFCTL , hsflctl . regval ) ;
ew32flash ( ICH_FLASH_FADDR , flash_linear_addr ) ;
ret_val = e1000_flash_cycle_ich8lan ( hw ,
ICH_FLASH_READ_COMMAND_TIMEOUT ) ;
2008-03-28 09:15:03 -07:00
/*
* Check if FCERR is set to 1 , if set to 1 , clear it
2007-09-17 12:30:59 -07:00
* and try the whole sequence a few more times , else
* read in ( shift in ) the Flash Data0 , the order is
2008-03-28 09:15:03 -07:00
* least significant byte first msb to lsb
*/
2007-09-17 12:30:59 -07:00
if ( ret_val = = 0 ) {
flash_data = er32flash ( ICH_FLASH_FDATA0 ) ;
if ( size = = 1 ) {
* data = ( u8 ) ( flash_data & 0x000000FF ) ;
} else if ( size = = 2 ) {
* data = ( u16 ) ( flash_data & 0x0000FFFF ) ;
}
break ;
} else {
2008-03-28 09:15:03 -07:00
/*
* If we ' ve gotten here , then things are probably
2007-09-17 12:30:59 -07:00
* completely hosed , but if the error condition is
* detected , it won ' t hurt to give it another try . . .
* ICH_FLASH_CYCLE_REPEAT_COUNT times .
*/
hsfsts . regval = er16flash ( ICH_FLASH_HSFSTS ) ;
if ( hsfsts . hsf_status . flcerr = = 1 ) {
/* Repeat for some time before giving up. */
continue ;
} else if ( hsfsts . hsf_status . flcdone = = 0 ) {
hw_dbg ( hw , " Timeout error - flash cycle "
" did not complete. " ) ;
break ;
}
}
} while ( count + + < ICH_FLASH_CYCLE_REPEAT_COUNT ) ;
return ret_val ;
}
/**
* e1000_write_nvm_ich8lan - Write word ( s ) to the NVM
* @ hw : pointer to the HW structure
* @ offset : The offset ( in bytes ) of the word ( s ) to write .
* @ words : Size of data to write in words
* @ data : Pointer to the word ( s ) to write at offset .
*
* Writes a byte or word to the NVM using the flash access registers .
* */
static s32 e1000_write_nvm_ich8lan ( struct e1000_hw * hw , u16 offset , u16 words ,
u16 * data )
{
struct e1000_nvm_info * nvm = & hw - > nvm ;
struct e1000_dev_spec_ich8lan * dev_spec = & hw - > dev_spec . ich8lan ;
s32 ret_val ;
u16 i ;
if ( ( offset > = nvm - > word_size ) | | ( words > nvm - > word_size - offset ) | |
( words = = 0 ) ) {
hw_dbg ( hw , " nvm parameter(s) out of bounds \n " ) ;
return - E1000_ERR_NVM ;
}
ret_val = e1000_acquire_swflag_ich8lan ( hw ) ;
if ( ret_val )
return ret_val ;
for ( i = 0 ; i < words ; i + + ) {
dev_spec - > shadow_ram [ offset + i ] . modified = 1 ;
dev_spec - > shadow_ram [ offset + i ] . value = data [ i ] ;
}
e1000_release_swflag_ich8lan ( hw ) ;
return 0 ;
}
/**
* e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM
* @ hw : pointer to the HW structure
*
* The NVM checksum is updated by calling the generic update_nvm_checksum ,
* which writes the checksum to the shadow ram . The changes in the shadow
* ram are then committed to the EEPROM by processing each bank at a time
* checking for the modified bit and writing only the pending changes .
2008-02-21 15:11:07 -08:00
* After a successful commit , the shadow ram is cleared and is ready for
2007-09-17 12:30:59 -07:00
* future writes .
* */
static s32 e1000_update_nvm_checksum_ich8lan ( struct e1000_hw * hw )
{
struct e1000_nvm_info * nvm = & hw - > nvm ;
struct e1000_dev_spec_ich8lan * dev_spec = & hw - > dev_spec . ich8lan ;
2008-08-26 18:36:50 -07:00
u32 i , act_offset , new_bank_offset , old_bank_offset , bank ;
2007-09-17 12:30:59 -07:00
s32 ret_val ;
u16 data ;
ret_val = e1000e_update_nvm_checksum_generic ( hw ) ;
if ( ret_val )
2008-03-28 09:15:03 -07:00
return ret_val ;
2007-09-17 12:30:59 -07:00
if ( nvm - > type ! = e1000_nvm_flash_sw )
2008-03-28 09:15:03 -07:00
return ret_val ;
2007-09-17 12:30:59 -07:00
ret_val = e1000_acquire_swflag_ich8lan ( hw ) ;
if ( ret_val )
2008-03-28 09:15:03 -07:00
return ret_val ;
2007-09-17 12:30:59 -07:00
2008-03-28 09:15:03 -07:00
/*
* We ' re writing to the opposite bank so if we ' re on bank 1 ,
2007-09-17 12:30:59 -07:00
* write to bank 0 etc . We also need to erase the segment that
2008-03-28 09:15:03 -07:00
* is going to be written
*/
2008-08-26 18:36:50 -07:00
ret_val = e1000_valid_nvm_bank_detect_ich8lan ( hw , & bank ) ;
if ( ret_val )
return ret_val ;
if ( bank = = 0 ) {
2007-09-17 12:30:59 -07:00
new_bank_offset = nvm - > flash_bank_size ;
old_bank_offset = 0 ;
e1000_erase_flash_bank_ich8lan ( hw , 1 ) ;
} else {
old_bank_offset = nvm - > flash_bank_size ;
new_bank_offset = 0 ;
e1000_erase_flash_bank_ich8lan ( hw , 0 ) ;
}
for ( i = 0 ; i < E1000_ICH8_SHADOW_RAM_WORDS ; i + + ) {
2008-03-28 09:15:03 -07:00
/*
* Determine whether to write the value stored
2007-09-17 12:30:59 -07:00
* in the other NVM bank or a modified value stored
2008-03-28 09:15:03 -07:00
* in the shadow RAM
*/
2007-09-17 12:30:59 -07:00
if ( dev_spec - > shadow_ram [ i ] . modified ) {
data = dev_spec - > shadow_ram [ i ] . value ;
} else {
e1000_read_flash_word_ich8lan ( hw ,
i + old_bank_offset ,
& data ) ;
}
2008-03-28 09:15:03 -07:00
/*
* If the word is 0x13 , then make sure the signature bits
2007-09-17 12:30:59 -07:00
* ( 15 : 14 ) are 11 b until the commit has completed .
* This will allow us to write 10 b which indicates the
* signature is valid . We want to do this after the write
* has completed so that we don ' t mark the segment valid
2008-03-28 09:15:03 -07:00
* while the write is still in progress
*/
2007-09-17 12:30:59 -07:00
if ( i = = E1000_ICH_NVM_SIG_WORD )
data | = E1000_ICH_NVM_SIG_MASK ;
/* Convert offset to bytes. */
act_offset = ( i + new_bank_offset ) < < 1 ;
udelay ( 100 ) ;
/* Write the bytes to the new bank. */
ret_val = e1000_retry_write_flash_byte_ich8lan ( hw ,
act_offset ,
( u8 ) data ) ;
if ( ret_val )
break ;
udelay ( 100 ) ;
ret_val = e1000_retry_write_flash_byte_ich8lan ( hw ,
act_offset + 1 ,
( u8 ) ( data > > 8 ) ) ;
if ( ret_val )
break ;
}
2008-03-28 09:15:03 -07:00
/*
* Don ' t bother writing the segment valid bits if sector
* programming failed .
*/
2007-09-17 12:30:59 -07:00
if ( ret_val ) {
hw_dbg ( hw , " Flash commit failed. \n " ) ;
e1000_release_swflag_ich8lan ( hw ) ;
return ret_val ;
}
2008-03-28 09:15:03 -07:00
/*
* Finally validate the new segment by setting bit 15 : 14
2007-09-17 12:30:59 -07:00
* to 10 b in word 0x13 , this can be done without an
* erase as well since these bits are 11 to start with
2008-03-28 09:15:03 -07:00
* and we need to change bit 14 to 0 b
*/
2007-09-17 12:30:59 -07:00
act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD ;
e1000_read_flash_word_ich8lan ( hw , act_offset , & data ) ;
data & = 0xBFFF ;
ret_val = e1000_retry_write_flash_byte_ich8lan ( hw ,
act_offset * 2 + 1 ,
( u8 ) ( data > > 8 ) ) ;
if ( ret_val ) {
e1000_release_swflag_ich8lan ( hw ) ;
return ret_val ;
}
2008-03-28 09:15:03 -07:00
/*
* And invalidate the previously valid segment by setting
2007-09-17 12:30:59 -07:00
* its signature word ( 0x13 ) high_byte to 0 b . This can be
* done without an erase because flash erase sets all bits
2008-03-28 09:15:03 -07:00
* to 1 ' s . We can write 1 ' s to 0 ' s without an erase
*/
2007-09-17 12:30:59 -07:00
act_offset = ( old_bank_offset + E1000_ICH_NVM_SIG_WORD ) * 2 + 1 ;
ret_val = e1000_retry_write_flash_byte_ich8lan ( hw , act_offset , 0 ) ;
if ( ret_val ) {
e1000_release_swflag_ich8lan ( hw ) ;
return ret_val ;
}
/* Great! Everything worked, we can now clear the cached entries. */
for ( i = 0 ; i < E1000_ICH8_SHADOW_RAM_WORDS ; i + + ) {
dev_spec - > shadow_ram [ i ] . modified = 0 ;
dev_spec - > shadow_ram [ i ] . value = 0xFFFF ;
}
e1000_release_swflag_ich8lan ( hw ) ;
2008-03-28 09:15:03 -07:00
/*
* Reload the EEPROM , or else modifications will not appear
2007-09-17 12:30:59 -07:00
* until after the next adapter reset .
*/
e1000e_reload_nvm ( hw ) ;
msleep ( 10 ) ;
return ret_val ;
}
/**
* e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum
* @ hw : pointer to the HW structure
*
* Check to see if checksum needs to be fixed by reading bit 6 in word 0x19 .
* If the bit is 0 , that the EEPROM had been modified , but the checksum was not
* calculated , in which case we need to calculate the checksum and set bit 6.
* */
static s32 e1000_validate_nvm_checksum_ich8lan ( struct e1000_hw * hw )
{
s32 ret_val ;
u16 data ;
2008-03-28 09:15:03 -07:00
/*
* Read 0x19 and check bit 6. If this bit is 0 , the checksum
2007-09-17 12:30:59 -07:00
* needs to be fixed . This bit is an indication that the NVM
* was prepared by OEM software and did not calculate the
* checksum . . . a likely scenario .
*/
ret_val = e1000_read_nvm ( hw , 0x19 , 1 , & data ) ;
if ( ret_val )
return ret_val ;
if ( ( data & 0x40 ) = = 0 ) {
data | = 0x40 ;
ret_val = e1000_write_nvm ( hw , 0x19 , 1 , & data ) ;
if ( ret_val )
return ret_val ;
ret_val = e1000e_update_nvm_checksum ( hw ) ;
if ( ret_val )
return ret_val ;
}
return e1000e_validate_nvm_checksum_generic ( hw ) ;
}
/**
* e1000_write_flash_data_ich8lan - Writes bytes to the NVM
* @ hw : pointer to the HW structure
* @ offset : The offset ( in bytes ) of the byte / word to read .
* @ size : Size of data to read , 1 = byte 2 = word
* @ data : The byte ( s ) to write to the NVM .
*
* Writes one / two bytes to the NVM using the flash access registers .
* */
static s32 e1000_write_flash_data_ich8lan ( struct e1000_hw * hw , u32 offset ,
u8 size , u16 data )
{
union ich8_hws_flash_status hsfsts ;
union ich8_hws_flash_ctrl hsflctl ;
u32 flash_linear_addr ;
u32 flash_data = 0 ;
s32 ret_val ;
u8 count = 0 ;
if ( size < 1 | | size > 2 | | data > size * 0xff | |
offset > ICH_FLASH_LINEAR_ADDR_MASK )
return - E1000_ERR_NVM ;
flash_linear_addr = ( ICH_FLASH_LINEAR_ADDR_MASK & offset ) +
hw - > nvm . flash_base_addr ;
do {
udelay ( 1 ) ;
/* Steps */
ret_val = e1000_flash_cycle_init_ich8lan ( hw ) ;
if ( ret_val )
break ;
hsflctl . regval = er16flash ( ICH_FLASH_HSFCTL ) ;
/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
hsflctl . hsf_ctrl . fldbcount = size - 1 ;
hsflctl . hsf_ctrl . flcycle = ICH_CYCLE_WRITE ;
ew16flash ( ICH_FLASH_HSFCTL , hsflctl . regval ) ;
ew32flash ( ICH_FLASH_FADDR , flash_linear_addr ) ;
if ( size = = 1 )
flash_data = ( u32 ) data & 0x00FF ;
else
flash_data = ( u32 ) data ;
ew32flash ( ICH_FLASH_FDATA0 , flash_data ) ;
2008-03-28 09:15:03 -07:00
/*
* check if FCERR is set to 1 , if set to 1 , clear it
* and try the whole sequence a few more times else done
*/
2007-09-17 12:30:59 -07:00
ret_val = e1000_flash_cycle_ich8lan ( hw ,
ICH_FLASH_WRITE_COMMAND_TIMEOUT ) ;
if ( ! ret_val )
break ;
2008-03-28 09:15:03 -07:00
/*
* If we ' re here , then things are most likely
2007-09-17 12:30:59 -07:00
* completely hosed , but if the error condition
* is detected , it won ' t hurt to give it another
* try . . . ICH_FLASH_CYCLE_REPEAT_COUNT times .
*/
hsfsts . regval = er16flash ( ICH_FLASH_HSFSTS ) ;
if ( hsfsts . hsf_status . flcerr = = 1 )
/* Repeat for some time before giving up. */
continue ;
if ( hsfsts . hsf_status . flcdone = = 0 ) {
hw_dbg ( hw , " Timeout error - flash cycle "
" did not complete. " ) ;
break ;
}
} while ( count + + < ICH_FLASH_CYCLE_REPEAT_COUNT ) ;
return ret_val ;
}
/**
* e1000_write_flash_byte_ich8lan - Write a single byte to NVM
* @ hw : pointer to the HW structure
* @ offset : The index of the byte to read .
* @ data : The byte to write to the NVM .
*
* Writes a single byte to the NVM using the flash access registers .
* */
static s32 e1000_write_flash_byte_ich8lan ( struct e1000_hw * hw , u32 offset ,
u8 data )
{
u16 word = ( u16 ) data ;
return e1000_write_flash_data_ich8lan ( hw , offset , 1 , word ) ;
}
/**
* e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
* @ hw : pointer to the HW structure
* @ offset : The offset of the byte to write .
* @ byte : The byte to write to the NVM .
*
* Writes a single byte to the NVM using the flash access registers .
* Goes through a retry algorithm before giving up .
* */
static s32 e1000_retry_write_flash_byte_ich8lan ( struct e1000_hw * hw ,
u32 offset , u8 byte )
{
s32 ret_val ;
u16 program_retries ;
ret_val = e1000_write_flash_byte_ich8lan ( hw , offset , byte ) ;
if ( ! ret_val )
return ret_val ;
for ( program_retries = 0 ; program_retries < 100 ; program_retries + + ) {
hw_dbg ( hw , " Retrying Byte %2.2X at offset %u \n " , byte , offset ) ;
udelay ( 100 ) ;
ret_val = e1000_write_flash_byte_ich8lan ( hw , offset , byte ) ;
if ( ! ret_val )
break ;
}
if ( program_retries = = 100 )
return - E1000_ERR_NVM ;
return 0 ;
}
/**
* e1000_erase_flash_bank_ich8lan - Erase a bank ( 4 k ) from NVM
* @ hw : pointer to the HW structure
* @ bank : 0 for first bank , 1 for second bank , etc .
*
* Erases the bank specified . Each bank is a 4 k block . Banks are 0 based .
* bank N is 4096 * N + flash_reg_addr .
* */
static s32 e1000_erase_flash_bank_ich8lan ( struct e1000_hw * hw , u32 bank )
{
struct e1000_nvm_info * nvm = & hw - > nvm ;
union ich8_hws_flash_status hsfsts ;
union ich8_hws_flash_ctrl hsflctl ;
u32 flash_linear_addr ;
/* bank size is in 16bit words - adjust to bytes */
u32 flash_bank_size = nvm - > flash_bank_size * 2 ;
s32 ret_val ;
s32 count = 0 ;
s32 iteration ;
s32 sector_size ;
s32 j ;
hsfsts . regval = er16flash ( ICH_FLASH_HSFSTS ) ;
2008-03-28 09:15:03 -07:00
/*
* Determine HW Sector size : Read BERASE bits of hw flash status
* register
* 00 : The Hw sector is 256 bytes , hence we need to erase 16
2007-09-17 12:30:59 -07:00
* consecutive sectors . The start index for the nth Hw sector
* can be calculated as = bank * 4096 + n * 256
* 01 : The Hw sector is 4 K bytes , hence we need to erase 1 sector .
* The start index for the nth Hw sector can be calculated
* as = bank * 4096
* 10 : The Hw sector is 8 K bytes , nth sector = bank * 8192
* ( ich9 only , otherwise error condition )
* 11 : The Hw sector is 64 K bytes , nth sector = bank * 65536
*/
switch ( hsfsts . hsf_status . berasesz ) {
case 0 :
/* Hw sector size 256 */
sector_size = ICH_FLASH_SEG_SIZE_256 ;
iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256 ;
break ;
case 1 :
sector_size = ICH_FLASH_SEG_SIZE_4K ;
iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K ;
break ;
case 2 :
if ( hw - > mac . type = = e1000_ich9lan ) {
sector_size = ICH_FLASH_SEG_SIZE_8K ;
iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K ;
} else {
return - E1000_ERR_NVM ;
}
break ;
case 3 :
sector_size = ICH_FLASH_SEG_SIZE_64K ;
iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K ;
break ;
default :
return - E1000_ERR_NVM ;
}
/* Start with the base address, then add the sector offset. */
flash_linear_addr = hw - > nvm . flash_base_addr ;
flash_linear_addr + = ( bank ) ? ( sector_size * iteration ) : 0 ;
for ( j = 0 ; j < iteration ; j + + ) {
do {
/* Steps */
ret_val = e1000_flash_cycle_init_ich8lan ( hw ) ;
if ( ret_val )
return ret_val ;
2008-03-28 09:15:03 -07:00
/*
* Write a value 11 ( block Erase ) in Flash
* Cycle field in hw flash control
*/
2007-09-17 12:30:59 -07:00
hsflctl . regval = er16flash ( ICH_FLASH_HSFCTL ) ;
hsflctl . hsf_ctrl . flcycle = ICH_CYCLE_ERASE ;
ew16flash ( ICH_FLASH_HSFCTL , hsflctl . regval ) ;
2008-03-28 09:15:03 -07:00
/*
* Write the last 24 bits of an index within the
2007-09-17 12:30:59 -07:00
* block into Flash Linear address field in Flash
* Address .
*/
flash_linear_addr + = ( j * sector_size ) ;
ew32flash ( ICH_FLASH_FADDR , flash_linear_addr ) ;
ret_val = e1000_flash_cycle_ich8lan ( hw ,
ICH_FLASH_ERASE_COMMAND_TIMEOUT ) ;
if ( ret_val = = 0 )
break ;
2008-03-28 09:15:03 -07:00
/*
* Check if FCERR is set to 1. If 1 ,
2007-09-17 12:30:59 -07:00
* clear it and try the whole sequence
2008-03-28 09:15:03 -07:00
* a few more times else Done
*/
2007-09-17 12:30:59 -07:00
hsfsts . regval = er16flash ( ICH_FLASH_HSFSTS ) ;
if ( hsfsts . hsf_status . flcerr = = 1 )
2008-03-28 09:15:03 -07:00
/* repeat for some time before giving up */
2007-09-17 12:30:59 -07:00
continue ;
else if ( hsfsts . hsf_status . flcdone = = 0 )
return ret_val ;
} while ( + + count < ICH_FLASH_CYCLE_REPEAT_COUNT ) ;
}
return 0 ;
}
/**
* e1000_valid_led_default_ich8lan - Set the default LED settings
* @ hw : pointer to the HW structure
* @ data : Pointer to the LED settings
*
* Reads the LED default settings from the NVM to data . If the NVM LED
* settings is all 0 ' s or F ' s , set the LED default to a valid LED default
* setting .
* */
static s32 e1000_valid_led_default_ich8lan ( struct e1000_hw * hw , u16 * data )
{
s32 ret_val ;
ret_val = e1000_read_nvm ( hw , NVM_ID_LED_SETTINGS , 1 , data ) ;
if ( ret_val ) {
hw_dbg ( hw , " NVM Read Error \n " ) ;
return ret_val ;
}
if ( * data = = ID_LED_RESERVED_0000 | |
* data = = ID_LED_RESERVED_FFFF )
* data = ID_LED_DEFAULT_ICH8LAN ;
return 0 ;
}
/**
* e1000_get_bus_info_ich8lan - Get / Set the bus type and width
* @ hw : pointer to the HW structure
*
* ICH8 use the PCI Express bus , but does not contain a PCI Express Capability
* register , so the the bus width is hard coded .
* */
static s32 e1000_get_bus_info_ich8lan ( struct e1000_hw * hw )
{
struct e1000_bus_info * bus = & hw - > bus ;
s32 ret_val ;
ret_val = e1000e_get_bus_info_pcie ( hw ) ;
2008-03-28 09:15:03 -07:00
/*
* ICH devices are " PCI Express " - ish . They have
2007-09-17 12:30:59 -07:00
* a configuration space , but do not contain
* PCI Express Capability registers , so bus width
* must be hardcoded .
*/
if ( bus - > width = = e1000_bus_width_unknown )
bus - > width = e1000_bus_width_pcie_x1 ;
return ret_val ;
}
/**
* e1000_reset_hw_ich8lan - Reset the hardware
* @ hw : pointer to the HW structure
*
* Does a full reset of the hardware which includes a reset of the PHY and
* MAC .
* */
static s32 e1000_reset_hw_ich8lan ( struct e1000_hw * hw )
{
u32 ctrl , icr , kab ;
s32 ret_val ;
2008-03-28 09:15:03 -07:00
/*
* Prevent the PCI - E bus from sticking if there is no TLP connection
2007-09-17 12:30:59 -07:00
* on the last TLP read / write transaction when MAC is reset .
*/
ret_val = e1000e_disable_pcie_master ( hw ) ;
if ( ret_val ) {
hw_dbg ( hw , " PCI-E Master disable polling has failed. \n " ) ;
}
hw_dbg ( hw , " Masking off all interrupts \n " ) ;
ew32 ( IMC , 0xffffffff ) ;
2008-03-28 09:15:03 -07:00
/*
* Disable the Transmit and Receive units . Then delay to allow
2007-09-17 12:30:59 -07:00
* any pending transactions to complete before we hit the MAC
* with the global reset .
*/
ew32 ( RCTL , 0 ) ;
ew32 ( TCTL , E1000_TCTL_PSP ) ;
e1e_flush ( ) ;
msleep ( 10 ) ;
/* Workaround for ICH8 bit corruption issue in FIFO memory */
if ( hw - > mac . type = = e1000_ich8lan ) {
/* Set Tx and Rx buffer allocation to 8k apiece. */
ew32 ( PBA , E1000_PBA_8K ) ;
/* Set Packet Buffer Size to 16k. */
ew32 ( PBS , E1000_PBS_16K ) ;
}
ctrl = er32 ( CTRL ) ;
if ( ! e1000_check_reset_block ( hw ) ) {
2008-03-28 09:15:03 -07:00
/*
* PHY HW reset requires MAC CORE reset at the same
2007-09-17 12:30:59 -07:00
* time to make sure the interface between MAC and the
* external PHY is reset .
*/
ctrl | = E1000_CTRL_PHY_RST ;
}
ret_val = e1000_acquire_swflag_ich8lan ( hw ) ;
hw_dbg ( hw , " Issuing a global reset to ich8lan " ) ;
ew32 ( CTRL , ( ctrl | E1000_CTRL_RST ) ) ;
msleep ( 20 ) ;
ret_val = e1000e_get_auto_rd_done ( hw ) ;
if ( ret_val ) {
/*
* When auto config read does not complete , do not
* return with an error . This can happen in situations
* where there is no eeprom and prevents getting link .
*/
hw_dbg ( hw , " Auto Read Done did not complete \n " ) ;
}
ew32 ( IMC , 0xffffffff ) ;
icr = er32 ( ICR ) ;
kab = er32 ( KABGTXD ) ;
kab | = E1000_KABGTXD_BGSQLBIAS ;
ew32 ( KABGTXD , kab ) ;
return ret_val ;
}
/**
* e1000_init_hw_ich8lan - Initialize the hardware
* @ hw : pointer to the HW structure
*
* Prepares the hardware for transmit and receive by doing the following :
* - initialize hardware bits
* - initialize LED identification
* - setup receive address registers
* - setup flow control
2008-02-21 15:11:07 -08:00
* - setup transmit descriptors
2007-09-17 12:30:59 -07:00
* - clear statistics
* */
static s32 e1000_init_hw_ich8lan ( struct e1000_hw * hw )
{
struct e1000_mac_info * mac = & hw - > mac ;
u32 ctrl_ext , txdctl , snoop ;
s32 ret_val ;
u16 i ;
e1000_initialize_hw_bits_ich8lan ( hw ) ;
/* Initialize identification LED */
ret_val = e1000e_id_led_init ( hw ) ;
if ( ret_val ) {
hw_dbg ( hw , " Error initializing identification LED \n " ) ;
return ret_val ;
}
/* Setup the receive address. */
e1000e_init_rx_addrs ( hw , mac - > rar_entry_count ) ;
/* Zero out the Multicast HASH table */
hw_dbg ( hw , " Zeroing the MTA \n " ) ;
for ( i = 0 ; i < mac - > mta_reg_count ; i + + )
E1000_WRITE_REG_ARRAY ( hw , E1000_MTA , i , 0 ) ;
/* Setup link and flow control */
ret_val = e1000_setup_link_ich8lan ( hw ) ;
/* Set the transmit descriptor write-back policy for both queues */
2008-04-02 13:48:13 -07:00
txdctl = er32 ( TXDCTL ( 0 ) ) ;
2007-09-17 12:30:59 -07:00
txdctl = ( txdctl & ~ E1000_TXDCTL_WTHRESH ) |
E1000_TXDCTL_FULL_TX_DESC_WB ;
txdctl = ( txdctl & ~ E1000_TXDCTL_PTHRESH ) |
E1000_TXDCTL_MAX_TX_DESC_PREFETCH ;
2008-04-02 13:48:13 -07:00
ew32 ( TXDCTL ( 0 ) , txdctl ) ;
txdctl = er32 ( TXDCTL ( 1 ) ) ;
2007-09-17 12:30:59 -07:00
txdctl = ( txdctl & ~ E1000_TXDCTL_WTHRESH ) |
E1000_TXDCTL_FULL_TX_DESC_WB ;
txdctl = ( txdctl & ~ E1000_TXDCTL_PTHRESH ) |
E1000_TXDCTL_MAX_TX_DESC_PREFETCH ;
2008-04-02 13:48:13 -07:00
ew32 ( TXDCTL ( 1 ) , txdctl ) ;
2007-09-17 12:30:59 -07:00
2008-03-28 09:15:03 -07:00
/*
* ICH8 has opposite polarity of no_snoop bits .
* By default , we should use snoop behavior .
*/
2007-09-17 12:30:59 -07:00
if ( mac - > type = = e1000_ich8lan )
snoop = PCIE_ICH8_SNOOP_ALL ;
else
snoop = ( u32 ) ~ ( PCIE_NO_SNOOP_ALL ) ;
e1000e_set_pcie_no_snoop ( hw , snoop ) ;
ctrl_ext = er32 ( CTRL_EXT ) ;
ctrl_ext | = E1000_CTRL_EXT_RO_DIS ;
ew32 ( CTRL_EXT , ctrl_ext ) ;
2008-03-28 09:15:03 -07:00
/*
* Clear all of the statistics registers ( clear on read ) . It is
2007-09-17 12:30:59 -07:00
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
* is no link .
*/
e1000_clear_hw_cntrs_ich8lan ( hw ) ;
return 0 ;
}
/**
* e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits
* @ hw : pointer to the HW structure
*
* Sets / Clears required hardware bits necessary for correctly setting up the
* hardware for transmit and receive .
* */
static void e1000_initialize_hw_bits_ich8lan ( struct e1000_hw * hw )
{
u32 reg ;
/* Extended Device Control */
reg = er32 ( CTRL_EXT ) ;
reg | = ( 1 < < 22 ) ;
ew32 ( CTRL_EXT , reg ) ;
/* Transmit Descriptor Control 0 */
2008-04-02 13:48:13 -07:00
reg = er32 ( TXDCTL ( 0 ) ) ;
2007-09-17 12:30:59 -07:00
reg | = ( 1 < < 22 ) ;
2008-04-02 13:48:13 -07:00
ew32 ( TXDCTL ( 0 ) , reg ) ;
2007-09-17 12:30:59 -07:00
/* Transmit Descriptor Control 1 */
2008-04-02 13:48:13 -07:00
reg = er32 ( TXDCTL ( 1 ) ) ;
2007-09-17 12:30:59 -07:00
reg | = ( 1 < < 22 ) ;
2008-04-02 13:48:13 -07:00
ew32 ( TXDCTL ( 1 ) , reg ) ;
2007-09-17 12:30:59 -07:00
/* Transmit Arbitration Control 0 */
2008-04-02 13:48:13 -07:00
reg = er32 ( TARC ( 0 ) ) ;
2007-09-17 12:30:59 -07:00
if ( hw - > mac . type = = e1000_ich8lan )
reg | = ( 1 < < 28 ) | ( 1 < < 29 ) ;
reg | = ( 1 < < 23 ) | ( 1 < < 24 ) | ( 1 < < 26 ) | ( 1 < < 27 ) ;
2008-04-02 13:48:13 -07:00
ew32 ( TARC ( 0 ) , reg ) ;
2007-09-17 12:30:59 -07:00
/* Transmit Arbitration Control 1 */
2008-04-02 13:48:13 -07:00
reg = er32 ( TARC ( 1 ) ) ;
2007-09-17 12:30:59 -07:00
if ( er32 ( TCTL ) & E1000_TCTL_MULR )
reg & = ~ ( 1 < < 28 ) ;
else
reg | = ( 1 < < 28 ) ;
reg | = ( 1 < < 24 ) | ( 1 < < 26 ) | ( 1 < < 30 ) ;
2008-04-02 13:48:13 -07:00
ew32 ( TARC ( 1 ) , reg ) ;
2007-09-17 12:30:59 -07:00
/* Device Status */
if ( hw - > mac . type = = e1000_ich8lan ) {
reg = er32 ( STATUS ) ;
reg & = ~ ( 1 < < 31 ) ;
ew32 ( STATUS , reg ) ;
}
}
/**
* e1000_setup_link_ich8lan - Setup flow control and link settings
* @ hw : pointer to the HW structure
*
* Determines which flow control settings to use , then configures flow
* control . Calls the appropriate media - specific link configuration
* function . Assuming the adapter has a valid link partner , a valid link
* should be established . Assumes the hardware has previously been reset
* and the transmitter and receiver are not enabled .
* */
static s32 e1000_setup_link_ich8lan ( struct e1000_hw * hw )
{
s32 ret_val ;
if ( e1000_check_reset_block ( hw ) )
return 0 ;
2008-03-28 09:15:03 -07:00
/*
* ICH parts do not have a word in the NVM to determine
2007-09-17 12:30:59 -07:00
* the default flow control setting , so we explicitly
* set it to full .
*/
2008-03-28 09:15:16 -07:00
if ( hw - > fc . type = = e1000_fc_default )
hw - > fc . type = e1000_fc_full ;
2007-09-17 12:30:59 -07:00
2008-03-28 09:15:16 -07:00
hw - > fc . original_type = hw - > fc . type ;
2007-09-17 12:30:59 -07:00
2008-03-28 09:15:16 -07:00
hw_dbg ( hw , " After fix-ups FlowControl is now = %x \n " , hw - > fc . type ) ;
2007-09-17 12:30:59 -07:00
/* Continue to configure the copper link. */
ret_val = e1000_setup_copper_link_ich8lan ( hw ) ;
if ( ret_val )
return ret_val ;
2008-03-28 09:15:16 -07:00
ew32 ( FCTTV , hw - > fc . pause_time ) ;
2007-09-17 12:30:59 -07:00
return e1000e_set_fc_watermarks ( hw ) ;
}
/**
* e1000_setup_copper_link_ich8lan - Configure MAC / PHY interface
* @ hw : pointer to the HW structure
*
* Configures the kumeran interface to the PHY to wait the appropriate time
* when polling the PHY , then call the generic setup_copper_link to finish
* configuring the copper link .
* */
static s32 e1000_setup_copper_link_ich8lan ( struct e1000_hw * hw )
{
u32 ctrl ;
s32 ret_val ;
u16 reg_data ;
ctrl = er32 ( CTRL ) ;
ctrl | = E1000_CTRL_SLU ;
ctrl & = ~ ( E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX ) ;
ew32 ( CTRL , ctrl ) ;
2008-03-28 09:15:03 -07:00
/*
* Set the mac to wait the maximum time between each iteration
2007-09-17 12:30:59 -07:00
* and increase the max iterations when polling the phy ;
2008-03-28 09:15:03 -07:00
* this fixes erroneous timeouts at 10 Mbps .
*/
2007-09-17 12:30:59 -07:00
ret_val = e1000e_write_kmrn_reg ( hw , GG82563_REG ( 0x34 , 4 ) , 0xFFFF ) ;
if ( ret_val )
return ret_val ;
ret_val = e1000e_read_kmrn_reg ( hw , GG82563_REG ( 0x34 , 9 ) , & reg_data ) ;
if ( ret_val )
return ret_val ;
reg_data | = 0x3F ;
ret_val = e1000e_write_kmrn_reg ( hw , GG82563_REG ( 0x34 , 9 ) , reg_data ) ;
if ( ret_val )
return ret_val ;
if ( hw - > phy . type = = e1000_phy_igp_3 ) {
ret_val = e1000e_copper_link_setup_igp ( hw ) ;
if ( ret_val )
return ret_val ;
2008-04-29 09:16:05 -07:00
} else if ( hw - > phy . type = = e1000_phy_bm ) {
ret_val = e1000e_copper_link_setup_m88 ( hw ) ;
if ( ret_val )
return ret_val ;
2007-09-17 12:30:59 -07:00
}
2008-04-29 09:16:05 -07:00
if ( hw - > phy . type = = e1000_phy_ife ) {
ret_val = e1e_rphy ( hw , IFE_PHY_MDIX_CONTROL , & reg_data ) ;
if ( ret_val )
return ret_val ;
reg_data & = ~ IFE_PMC_AUTO_MDIX ;
switch ( hw - > phy . mdix ) {
case 1 :
reg_data & = ~ IFE_PMC_FORCE_MDIX ;
break ;
case 2 :
reg_data | = IFE_PMC_FORCE_MDIX ;
break ;
case 0 :
default :
reg_data | = IFE_PMC_AUTO_MDIX ;
break ;
}
ret_val = e1e_wphy ( hw , IFE_PHY_MDIX_CONTROL , reg_data ) ;
if ( ret_val )
return ret_val ;
}
2007-09-17 12:30:59 -07:00
return e1000e_setup_copper_link ( hw ) ;
}
/**
* e1000_get_link_up_info_ich8lan - Get current link speed and duplex
* @ hw : pointer to the HW structure
* @ speed : pointer to store current link speed
* @ duplex : pointer to store the current link duplex
*
2008-03-28 09:15:03 -07:00
* Calls the generic get_speed_and_duplex to retrieve the current link
2007-09-17 12:30:59 -07:00
* information and then calls the Kumeran lock loss workaround for links at
* gigabit speeds .
* */
static s32 e1000_get_link_up_info_ich8lan ( struct e1000_hw * hw , u16 * speed ,
u16 * duplex )
{
s32 ret_val ;
ret_val = e1000e_get_speed_and_duplex_copper ( hw , speed , duplex ) ;
if ( ret_val )
return ret_val ;
if ( ( hw - > mac . type = = e1000_ich8lan ) & &
( hw - > phy . type = = e1000_phy_igp_3 ) & &
( * speed = = SPEED_1000 ) ) {
ret_val = e1000_kmrn_lock_loss_workaround_ich8lan ( hw ) ;
}
return ret_val ;
}
/**
* e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround
* @ hw : pointer to the HW structure
*
* Work - around for 82566 Kumeran PCS lock loss :
* On link status change ( i . e . PCI reset , speed change ) and link is up and
* speed is gigabit -
* 0 ) if workaround is optionally disabled do nothing
* 1 ) wait 1 ms for Kumeran link to come up
* 2 ) check Kumeran Diagnostic register PCS lock loss bit
* 3 ) if not set the link is locked ( all is good ) , otherwise . . .
* 4 ) reset the PHY
* 5 ) repeat up to 10 times
* Note : this is only called for IGP3 copper when speed is 1 gb .
* */
static s32 e1000_kmrn_lock_loss_workaround_ich8lan ( struct e1000_hw * hw )
{
struct e1000_dev_spec_ich8lan * dev_spec = & hw - > dev_spec . ich8lan ;
u32 phy_ctrl ;
s32 ret_val ;
u16 i , data ;
bool link ;
if ( ! dev_spec - > kmrn_lock_loss_workaround_enabled )
return 0 ;
2008-03-28 09:15:03 -07:00
/*
* Make sure link is up before proceeding . If not just return .
2007-09-17 12:30:59 -07:00
* Attempting this while link is negotiating fouled up link
2008-03-28 09:15:03 -07:00
* stability
*/
2007-09-17 12:30:59 -07:00
ret_val = e1000e_phy_has_link_generic ( hw , 1 , 0 , & link ) ;
if ( ! link )
return 0 ;
for ( i = 0 ; i < 10 ; i + + ) {
/* read once to clear */
ret_val = e1e_rphy ( hw , IGP3_KMRN_DIAG , & data ) ;
if ( ret_val )
return ret_val ;
/* and again to get new status */
ret_val = e1e_rphy ( hw , IGP3_KMRN_DIAG , & data ) ;
if ( ret_val )
return ret_val ;
/* check for PCS lock */
if ( ! ( data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS ) )
return 0 ;
/* Issue PHY reset */
e1000_phy_hw_reset ( hw ) ;
mdelay ( 5 ) ;
}
/* Disable GigE link negotiation */
phy_ctrl = er32 ( PHY_CTRL ) ;
phy_ctrl | = ( E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE ) ;
ew32 ( PHY_CTRL , phy_ctrl ) ;
2008-03-28 09:15:03 -07:00
/*
* Call gig speed drop workaround on Gig disable before accessing
* any PHY registers
*/
2007-09-17 12:30:59 -07:00
e1000e_gig_downshift_workaround_ich8lan ( hw ) ;
/* unable to acquire PCS lock */
return - E1000_ERR_PHY ;
}
/**
2008-03-28 09:15:03 -07:00
* e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state
2007-09-17 12:30:59 -07:00
* @ hw : pointer to the HW structure
2008-02-21 15:11:07 -08:00
* @ state : boolean value used to set the current Kumeran workaround state
2007-09-17 12:30:59 -07:00
*
* If ICH8 , set the current Kumeran workaround state ( enabled - TRUE
* / disabled - FALSE ) .
* */
void e1000e_set_kmrn_lock_loss_workaround_ich8lan ( struct e1000_hw * hw ,
bool state )
{
struct e1000_dev_spec_ich8lan * dev_spec = & hw - > dev_spec . ich8lan ;
if ( hw - > mac . type ! = e1000_ich8lan ) {
hw_dbg ( hw , " Workaround applies to ICH8 only. \n " ) ;
return ;
}
dev_spec - > kmrn_lock_loss_workaround_enabled = state ;
}
/**
* e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3
* @ hw : pointer to the HW structure
*
* Workaround for 82566 power - down on D3 entry :
* 1 ) disable gigabit link
* 2 ) write VR power - down enable
* 3 ) read it back
* Continue if successful , else issue LCD reset and repeat
* */
void e1000e_igp3_phy_powerdown_workaround_ich8lan ( struct e1000_hw * hw )
{
u32 reg ;
u16 data ;
u8 retry = 0 ;
if ( hw - > phy . type ! = e1000_phy_igp_3 )
return ;
/* Try the workaround twice (if needed) */
do {
/* Disable link */
reg = er32 ( PHY_CTRL ) ;
reg | = ( E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE ) ;
ew32 ( PHY_CTRL , reg ) ;
2008-03-28 09:15:03 -07:00
/*
* Call gig speed drop workaround on Gig disable before
* accessing any PHY registers
*/
2007-09-17 12:30:59 -07:00
if ( hw - > mac . type = = e1000_ich8lan )
e1000e_gig_downshift_workaround_ich8lan ( hw ) ;
/* Write VR power-down enable */
e1e_rphy ( hw , IGP3_VR_CTRL , & data ) ;
data & = ~ IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK ;
e1e_wphy ( hw , IGP3_VR_CTRL , data | IGP3_VR_CTRL_MODE_SHUTDOWN ) ;
/* Read it back and test */
e1e_rphy ( hw , IGP3_VR_CTRL , & data ) ;
data & = IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK ;
if ( ( data = = IGP3_VR_CTRL_MODE_SHUTDOWN ) | | retry )
break ;
/* Issue PHY reset and repeat at most one more time */
reg = er32 ( CTRL ) ;
ew32 ( CTRL , reg | E1000_CTRL_PHY_RST ) ;
retry + + ;
} while ( retry ) ;
}
/**
* e1000e_gig_downshift_workaround_ich8lan - WoL from S5 stops working
* @ hw : pointer to the HW structure
*
* Steps to take when dropping from 1 Gb / s ( eg . link cable removal ( LSC ) ,
2008-02-21 15:11:07 -08:00
* LPLU , Gig disable , MDIC PHY reset ) :
2007-09-17 12:30:59 -07:00
* 1 ) Set Kumeran Near - end loopback
* 2 ) Clear Kumeran Near - end loopback
* Should only be called for ICH8 [ m ] devices with IGP_3 Phy .
* */
void e1000e_gig_downshift_workaround_ich8lan ( struct e1000_hw * hw )
{
s32 ret_val ;
u16 reg_data ;
if ( ( hw - > mac . type ! = e1000_ich8lan ) | |
( hw - > phy . type ! = e1000_phy_igp_3 ) )
return ;
ret_val = e1000e_read_kmrn_reg ( hw , E1000_KMRNCTRLSTA_DIAG_OFFSET ,
& reg_data ) ;
if ( ret_val )
return ;
reg_data | = E1000_KMRNCTRLSTA_DIAG_NELPBK ;
ret_val = e1000e_write_kmrn_reg ( hw , E1000_KMRNCTRLSTA_DIAG_OFFSET ,
reg_data ) ;
if ( ret_val )
return ;
reg_data & = ~ E1000_KMRNCTRLSTA_DIAG_NELPBK ;
ret_val = e1000e_write_kmrn_reg ( hw , E1000_KMRNCTRLSTA_DIAG_OFFSET ,
reg_data ) ;
}
2008-04-29 09:16:05 -07:00
/**
* e1000e_disable_gig_wol_ich8lan - disable gig during WoL
* @ hw : pointer to the HW structure
*
* During S0 to Sx transition , it is possible the link remains at gig
* instead of negotiating to a lower speed . Before going to Sx , set
* ' LPLU Enabled ' and ' Gig Disable ' to force link speed negotiation
* to a lower speed .
*
2008-08-26 18:36:50 -07:00
* Should only be called for ICH9 and ICH10 devices .
2008-04-29 09:16:05 -07:00
* */
void e1000e_disable_gig_wol_ich8lan ( struct e1000_hw * hw )
{
u32 phy_ctrl ;
2008-08-26 18:36:50 -07:00
if ( ( hw - > mac . type = = e1000_ich10lan ) | |
( hw - > mac . type = = e1000_ich9lan ) ) {
2008-04-29 09:16:05 -07:00
phy_ctrl = er32 ( PHY_CTRL ) ;
phy_ctrl | = E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_GBE_DISABLE ;
ew32 ( PHY_CTRL , phy_ctrl ) ;
}
return ;
}
2007-09-17 12:30:59 -07:00
/**
* e1000_cleanup_led_ich8lan - Restore the default LED operation
* @ hw : pointer to the HW structure
*
* Return the LED back to the default configuration .
* */
static s32 e1000_cleanup_led_ich8lan ( struct e1000_hw * hw )
{
if ( hw - > phy . type = = e1000_phy_ife )
return e1e_wphy ( hw , IFE_PHY_SPECIAL_CONTROL_LED , 0 ) ;
ew32 ( LEDCTL , hw - > mac . ledctl_default ) ;
return 0 ;
}
/**
2008-02-21 15:11:07 -08:00
* e1000_led_on_ich8lan - Turn LEDs on
2007-09-17 12:30:59 -07:00
* @ hw : pointer to the HW structure
*
2008-02-21 15:11:07 -08:00
* Turn on the LEDs .
2007-09-17 12:30:59 -07:00
* */
static s32 e1000_led_on_ich8lan ( struct e1000_hw * hw )
{
if ( hw - > phy . type = = e1000_phy_ife )
return e1e_wphy ( hw , IFE_PHY_SPECIAL_CONTROL_LED ,
( IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON ) ) ;
ew32 ( LEDCTL , hw - > mac . ledctl_mode2 ) ;
return 0 ;
}
/**
2008-02-21 15:11:07 -08:00
* e1000_led_off_ich8lan - Turn LEDs off
2007-09-17 12:30:59 -07:00
* @ hw : pointer to the HW structure
*
2008-02-21 15:11:07 -08:00
* Turn off the LEDs .
2007-09-17 12:30:59 -07:00
* */
static s32 e1000_led_off_ich8lan ( struct e1000_hw * hw )
{
if ( hw - > phy . type = = e1000_phy_ife )
return e1e_wphy ( hw , IFE_PHY_SPECIAL_CONTROL_LED ,
( IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF ) ) ;
ew32 ( LEDCTL , hw - > mac . ledctl_mode1 ) ;
return 0 ;
}
2008-08-26 18:36:50 -07:00
/**
* e1000_get_cfg_done_ich8lan - Read config done bit
* @ hw : pointer to the HW structure
*
* Read the management control register for the config done bit for
* completion status . NOTE : silicon which is EEPROM - less will fail trying
* to read the config done bit , so an error is * ONLY * logged and returns
* E1000_SUCCESS . If we were to return with error , EEPROM - less silicon
* would not be able to be reset or change link .
* */
static s32 e1000_get_cfg_done_ich8lan ( struct e1000_hw * hw )
{
u32 bank = 0 ;
e1000e_get_cfg_done ( hw ) ;
/* If EEPROM is not marked present, init the IGP 3 PHY manually */
if ( hw - > mac . type ! = e1000_ich10lan ) {
if ( ( ( er32 ( EECD ) & E1000_EECD_PRES ) = = 0 ) & &
( hw - > phy . type = = e1000_phy_igp_3 ) ) {
e1000e_phy_init_script_igp3 ( hw ) ;
}
} else {
if ( e1000_valid_nvm_bank_detect_ich8lan ( hw , & bank ) ) {
/* Maybe we should do a basic PHY config */
hw_dbg ( hw , " EEPROM not present \n " ) ;
return - E1000_ERR_CONFIG ;
}
}
return 0 ;
}
2007-09-17 12:30:59 -07:00
/**
* e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
* @ hw : pointer to the HW structure
*
* Clears hardware counters specific to the silicon family and calls
* clear_hw_cntrs_generic to clear all general purpose counters .
* */
static void e1000_clear_hw_cntrs_ich8lan ( struct e1000_hw * hw )
{
u32 temp ;
e1000e_clear_hw_cntrs_base ( hw ) ;
temp = er32 ( ALGNERRC ) ;
temp = er32 ( RXERRC ) ;
temp = er32 ( TNCRS ) ;
temp = er32 ( CEXTERR ) ;
temp = er32 ( TSCTC ) ;
temp = er32 ( TSCTFC ) ;
temp = er32 ( MGTPRC ) ;
temp = er32 ( MGTPDC ) ;
temp = er32 ( MGTPTC ) ;
temp = er32 ( IAC ) ;
temp = er32 ( ICRXOC ) ;
}
static struct e1000_mac_operations ich8_mac_ops = {
2008-08-26 18:37:06 -07:00
. check_mng_mode = e1000_check_mng_mode_ich8lan ,
2007-09-17 12:30:59 -07:00
. check_for_link = e1000e_check_for_copper_link ,
. cleanup_led = e1000_cleanup_led_ich8lan ,
. clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan ,
. get_bus_info = e1000_get_bus_info_ich8lan ,
. get_link_up_info = e1000_get_link_up_info_ich8lan ,
. led_on = e1000_led_on_ich8lan ,
. led_off = e1000_led_off_ich8lan ,
2008-03-28 09:15:11 -07:00
. update_mc_addr_list = e1000e_update_mc_addr_list_generic ,
2007-09-17 12:30:59 -07:00
. reset_hw = e1000_reset_hw_ich8lan ,
. init_hw = e1000_init_hw_ich8lan ,
. setup_link = e1000_setup_link_ich8lan ,
. setup_physical_interface = e1000_setup_copper_link_ich8lan ,
} ;
static struct e1000_phy_operations ich8_phy_ops = {
. acquire_phy = e1000_acquire_swflag_ich8lan ,
. check_reset_block = e1000_check_reset_block_ich8lan ,
. commit_phy = NULL ,
. force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan ,
2008-08-26 18:36:50 -07:00
. get_cfg_done = e1000_get_cfg_done_ich8lan ,
2007-09-17 12:30:59 -07:00
. get_cable_length = e1000e_get_cable_length_igp_2 ,
. get_phy_info = e1000_get_phy_info_ich8lan ,
. read_phy_reg = e1000e_read_phy_reg_igp ,
. release_phy = e1000_release_swflag_ich8lan ,
. reset_phy = e1000_phy_hw_reset_ich8lan ,
. set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan ,
. set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan ,
. write_phy_reg = e1000e_write_phy_reg_igp ,
} ;
static struct e1000_nvm_operations ich8_nvm_ops = {
. acquire_nvm = e1000_acquire_swflag_ich8lan ,
. read_nvm = e1000_read_nvm_ich8lan ,
. release_nvm = e1000_release_swflag_ich8lan ,
. update_nvm = e1000_update_nvm_checksum_ich8lan ,
. valid_led_default = e1000_valid_led_default_ich8lan ,
. validate_nvm = e1000_validate_nvm_checksum_ich8lan ,
. write_nvm = e1000_write_nvm_ich8lan ,
} ;
struct e1000_info e1000_ich8_info = {
. mac = e1000_ich8lan ,
. flags = FLAG_HAS_WOL
2008-04-29 09:16:05 -07:00
| FLAG_IS_ICH
2007-09-17 12:30:59 -07:00
| FLAG_RX_CSUM_ENABLED
| FLAG_HAS_CTRLEXT_ON_LOAD
| FLAG_HAS_AMT
| FLAG_HAS_FLASH
| FLAG_APME_IN_WUC ,
. pba = 8 ,
2008-04-02 13:48:18 -07:00
. get_variants = e1000_get_variants_ich8lan ,
2007-09-17 12:30:59 -07:00
. mac_ops = & ich8_mac_ops ,
. phy_ops = & ich8_phy_ops ,
. nvm_ops = & ich8_nvm_ops ,
} ;
struct e1000_info e1000_ich9_info = {
. mac = e1000_ich9lan ,
. flags = FLAG_HAS_JUMBO_FRAMES
2008-04-29 09:16:05 -07:00
| FLAG_IS_ICH
2007-09-17 12:30:59 -07:00
| FLAG_HAS_WOL
| FLAG_RX_CSUM_ENABLED
| FLAG_HAS_CTRLEXT_ON_LOAD
| FLAG_HAS_AMT
| FLAG_HAS_ERT
| FLAG_HAS_FLASH
| FLAG_APME_IN_WUC ,
. pba = 10 ,
2008-04-02 13:48:18 -07:00
. get_variants = e1000_get_variants_ich8lan ,
2007-09-17 12:30:59 -07:00
. mac_ops = & ich8_mac_ops ,
. phy_ops = & ich8_phy_ops ,
. nvm_ops = & ich8_nvm_ops ,
} ;
2008-08-26 18:36:50 -07:00
struct e1000_info e1000_ich10_info = {
. mac = e1000_ich10lan ,
. flags = FLAG_HAS_JUMBO_FRAMES
| FLAG_IS_ICH
| FLAG_HAS_WOL
| FLAG_RX_CSUM_ENABLED
| FLAG_HAS_CTRLEXT_ON_LOAD
| FLAG_HAS_AMT
| FLAG_HAS_ERT
| FLAG_HAS_FLASH
| FLAG_APME_IN_WUC ,
. pba = 10 ,
. get_variants = e1000_get_variants_ich8lan ,
. mac_ops = & ich8_mac_ops ,
. phy_ops = & ich8_phy_ops ,
. nvm_ops = & ich8_nvm_ops ,
} ;