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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <linux/netdevice.h>
2008-08-04 17:20:41 -07:00
# include <linux/pci.h>
2007-09-17 12:30:59 -07:00
# include "e1000.h"
2008-03-28 09:15:03 -07:00
/*
* This is the only thing that needs to be changed to adjust the
2007-09-17 12:30:59 -07:00
* maximum number of ports that the driver can manage .
*/
# define E1000_MAX_NIC 32
# define OPTION_UNSET -1
# define OPTION_DISABLED 0
# define OPTION_ENABLED 1
# define COPYBREAK_DEFAULT 256
unsigned int copybreak = COPYBREAK_DEFAULT ;
module_param ( copybreak , uint , 0644 ) ;
MODULE_PARM_DESC ( copybreak ,
" Maximum size of packet that is copied to a new buffer on receive " ) ;
2008-03-28 09:15:03 -07:00
/*
* All parameters are treated the same , as an integer array of values .
2007-09-17 12:30:59 -07:00
* This macro just reduces the need to repeat the same declaration code
* over and over ( plus this helps to avoid typo bugs ) .
*/
# define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
2007-10-29 10:46:05 -07:00
# define E1000_PARAM(X, desc) \
static int __devinitdata X [ E1000_MAX_NIC + 1 ] \
= E1000_PARAM_INIT ; \
static unsigned int num_ # # X ; \
module_param_array_named ( X , X , int , & num_ # # X , 0 ) ; \
2007-09-17 12:30:59 -07:00
MODULE_PARM_DESC ( X , desc ) ;
2008-03-28 09:15:03 -07:00
/*
* Transmit Interrupt Delay in units of 1.024 microseconds
* Tx interrupt delay needs to typically be set to something non zero
2007-09-17 12:30:59 -07:00
*
* Valid Range : 0 - 65535
*/
E1000_PARAM ( TxIntDelay , " Transmit Interrupt Delay " ) ;
# define DEFAULT_TIDV 8
# define MAX_TXDELAY 0xFFFF
# define MIN_TXDELAY 0
2008-03-28 09:15:03 -07:00
/*
* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
2007-09-17 12:30:59 -07:00
*
* Valid Range : 0 - 65535
*/
E1000_PARAM ( TxAbsIntDelay , " Transmit Absolute Interrupt Delay " ) ;
# define DEFAULT_TADV 32
# define MAX_TXABSDELAY 0xFFFF
# define MIN_TXABSDELAY 0
2008-03-28 09:15:03 -07:00
/*
* Receive Interrupt Delay in units of 1.024 microseconds
* hardware will likely hang if you set this to anything but zero .
2007-09-17 12:30:59 -07:00
*
* Valid Range : 0 - 65535
*/
E1000_PARAM ( RxIntDelay , " Receive Interrupt Delay " ) ;
# define DEFAULT_RDTR 0
# define MAX_RXDELAY 0xFFFF
# define MIN_RXDELAY 0
2008-03-28 09:15:03 -07:00
/*
* Receive Absolute Interrupt Delay in units of 1.024 microseconds
2007-09-17 12:30:59 -07:00
*
* Valid Range : 0 - 65535
*/
E1000_PARAM ( RxAbsIntDelay , " Receive Absolute Interrupt Delay " ) ;
# define DEFAULT_RADV 8
# define MAX_RXABSDELAY 0xFFFF
# define MIN_RXABSDELAY 0
2008-03-28 09:15:03 -07:00
/*
* Interrupt Throttle Rate ( interrupts / sec )
2007-09-17 12:30:59 -07:00
*
* Valid Range : 100 - 100000 ( 0 = off , 1 = dynamic , 3 = dynamic conservative )
*/
E1000_PARAM ( InterruptThrottleRate , " Interrupt Throttling Rate " ) ;
# define DEFAULT_ITR 3
# define MAX_ITR 100000
# define MIN_ITR 100
2008-08-26 18:37:06 -07:00
/* IntMode (Interrupt Mode)
*
* Valid Range : 0 - 2
*
* Default Value : 2 ( MSI - X )
*/
E1000_PARAM ( IntMode , " Interrupt Mode " ) ;
# define MAX_INTMODE 2
# define MIN_INTMODE 0
2007-09-17 12:30:59 -07:00
2008-03-28 09:15:03 -07:00
/*
* Enable Smart Power Down of the PHY
2007-09-17 12:30:59 -07:00
*
* Valid Range : 0 , 1
*
* Default Value : 0 ( disabled )
*/
E1000_PARAM ( SmartPowerDownEnable , " Enable PHY smart power down " ) ;
2008-03-28 09:15:03 -07:00
/*
* Enable Kumeran Lock Loss workaround
2007-09-17 12:30:59 -07:00
*
* Valid Range : 0 , 1
*
* Default Value : 1 ( enabled )
*/
E1000_PARAM ( KumeranLockLoss , " Enable Kumeran lock loss workaround " ) ;
2008-10-01 17:18:35 -07:00
/*
* Write Protect NVM
*
* Valid Range : 0 , 1
*
* Default Value : 1 ( enabled )
*/
E1000_PARAM ( WriteProtectNVM , " Write-protect NVM [WARNING: disabling this can lead to corrupted NVM] " ) ;
2008-11-14 06:45:23 +00:00
/*
* Enable CRC Stripping
*
* Valid Range : 0 , 1
*
* Default Value : 1 ( enabled )
*/
E1000_PARAM ( CrcStripping , " Enable CRC Stripping, disable if your BMC needs " \
" the CRC " ) ;
2007-09-17 12:30:59 -07:00
struct e1000_option {
enum { enable_option , range_option , list_option } type ;
2007-10-29 10:46:05 -07:00
const char * name ;
const char * err ;
int def ;
2007-09-17 12:30:59 -07:00
union {
struct { /* range_option info */
int min ;
int max ;
} r ;
struct { /* list_option info */
int nr ;
struct e1000_opt_list { int i ; char * str ; } * p ;
} l ;
} arg ;
} ;
2007-10-29 10:46:05 -07:00
static int __devinit e1000_validate_option ( unsigned int * value ,
const struct e1000_option * opt ,
2007-09-17 12:30:59 -07:00
struct e1000_adapter * adapter )
{
if ( * value = = OPTION_UNSET ) {
* value = opt - > def ;
return 0 ;
}
switch ( opt - > type ) {
case enable_option :
switch ( * value ) {
case OPTION_ENABLED :
2008-08-04 17:20:41 -07:00
e_info ( " %s Enabled \n " , opt - > name ) ;
2007-09-17 12:30:59 -07:00
return 0 ;
case OPTION_DISABLED :
2008-08-04 17:20:41 -07:00
e_info ( " %s Disabled \n " , opt - > name ) ;
2007-09-17 12:30:59 -07:00
return 0 ;
}
break ;
case range_option :
if ( * value > = opt - > arg . r . min & & * value < = opt - > arg . r . max ) {
2008-08-04 17:20:41 -07:00
e_info ( " %s set to %i \n " , opt - > name , * value ) ;
2007-09-17 12:30:59 -07:00
return 0 ;
}
break ;
case list_option : {
int i ;
struct e1000_opt_list * ent ;
for ( i = 0 ; i < opt - > arg . l . nr ; i + + ) {
ent = & opt - > arg . l . p [ i ] ;
if ( * value = = ent - > i ) {
if ( ent - > str [ 0 ] ! = ' \0 ' )
2008-08-04 17:20:41 -07:00
e_info ( " %s \n " , ent - > str ) ;
2007-09-17 12:30:59 -07:00
return 0 ;
}
}
}
break ;
default :
BUG ( ) ;
}
2008-08-04 17:20:41 -07:00
e_info ( " Invalid %s value specified (%i) %s \n " , opt - > name , * value ,
opt - > err ) ;
2007-09-17 12:30:59 -07:00
* value = opt - > def ;
return - 1 ;
}
/**
* e1000e_check_options - Range Checking for Command Line Parameters
* @ adapter : board private structure
*
* This routine checks all command line parameters for valid user
* input . If an invalid value is given , or if no user specified
* value exists , a default value is used . The final value is stored
* in a variable in the adapter structure .
* */
void __devinit e1000e_check_options ( struct e1000_adapter * adapter )
{
struct e1000_hw * hw = & adapter - > hw ;
int bd = adapter - > bd_number ;
if ( bd > = E1000_MAX_NIC ) {
2008-08-04 17:20:41 -07:00
e_notice ( " Warning: no configuration for board #%i \n " , bd ) ;
e_notice ( " Using defaults for all values \n " ) ;
2007-09-17 12:30:59 -07:00
}
{ /* Transmit Interrupt Delay */
2007-10-29 10:46:05 -07:00
const struct e1000_option opt = {
2007-09-17 12:30:59 -07:00
. type = range_option ,
. name = " Transmit Interrupt Delay " ,
. err = " using default of "
__MODULE_STRING ( DEFAULT_TIDV ) ,
. def = DEFAULT_TIDV ,
. arg = { . r = { . min = MIN_TXDELAY ,
. max = MAX_TXDELAY } }
} ;
if ( num_TxIntDelay > bd ) {
adapter - > tx_int_delay = TxIntDelay [ bd ] ;
e1000_validate_option ( & adapter - > tx_int_delay , & opt ,
adapter ) ;
} else {
adapter - > tx_int_delay = opt . def ;
}
}
{ /* Transmit Absolute Interrupt Delay */
2007-10-29 10:46:05 -07:00
const struct e1000_option opt = {
2007-09-17 12:30:59 -07:00
. type = range_option ,
. name = " Transmit Absolute Interrupt Delay " ,
. err = " using default of "
__MODULE_STRING ( DEFAULT_TADV ) ,
. def = DEFAULT_TADV ,
. arg = { . r = { . min = MIN_TXABSDELAY ,
. max = MAX_TXABSDELAY } }
} ;
if ( num_TxAbsIntDelay > bd ) {
adapter - > tx_abs_int_delay = TxAbsIntDelay [ bd ] ;
e1000_validate_option ( & adapter - > tx_abs_int_delay , & opt ,
adapter ) ;
} else {
adapter - > tx_abs_int_delay = opt . def ;
}
}
{ /* Receive Interrupt Delay */
struct e1000_option opt = {
. type = range_option ,
. name = " Receive Interrupt Delay " ,
. err = " using default of "
__MODULE_STRING ( DEFAULT_RDTR ) ,
. def = DEFAULT_RDTR ,
. arg = { . r = { . min = MIN_RXDELAY ,
. max = MAX_RXDELAY } }
} ;
if ( num_RxIntDelay > bd ) {
adapter - > rx_int_delay = RxIntDelay [ bd ] ;
e1000_validate_option ( & adapter - > rx_int_delay , & opt ,
adapter ) ;
} else {
adapter - > rx_int_delay = opt . def ;
}
}
{ /* Receive Absolute Interrupt Delay */
2007-10-29 10:46:05 -07:00
const struct e1000_option opt = {
2007-09-17 12:30:59 -07:00
. type = range_option ,
. name = " Receive Absolute Interrupt Delay " ,
. err = " using default of "
__MODULE_STRING ( DEFAULT_RADV ) ,
. def = DEFAULT_RADV ,
. arg = { . r = { . min = MIN_RXABSDELAY ,
. max = MAX_RXABSDELAY } }
} ;
if ( num_RxAbsIntDelay > bd ) {
adapter - > rx_abs_int_delay = RxAbsIntDelay [ bd ] ;
e1000_validate_option ( & adapter - > rx_abs_int_delay , & opt ,
adapter ) ;
} else {
adapter - > rx_abs_int_delay = opt . def ;
}
}
{ /* Interrupt Throttling Rate */
2007-10-29 10:46:05 -07:00
const struct e1000_option opt = {
2007-09-17 12:30:59 -07:00
. type = range_option ,
. name = " Interrupt Throttling Rate (ints/sec) " ,
. err = " using default of "
__MODULE_STRING ( DEFAULT_ITR ) ,
. def = DEFAULT_ITR ,
. arg = { . r = { . min = MIN_ITR ,
. max = MAX_ITR } }
} ;
if ( num_InterruptThrottleRate > bd ) {
adapter - > itr = InterruptThrottleRate [ bd ] ;
switch ( adapter - > itr ) {
case 0 :
2008-08-04 17:20:41 -07:00
e_info ( " %s turned off \n " , opt . name ) ;
2007-09-17 12:30:59 -07:00
break ;
case 1 :
2008-08-04 17:20:41 -07:00
e_info ( " %s set to dynamic mode \n " , opt . name ) ;
2007-09-17 12:30:59 -07:00
adapter - > itr_setting = adapter - > itr ;
adapter - > itr = 20000 ;
break ;
case 3 :
2008-08-04 17:20:41 -07:00
e_info ( " %s set to dynamic conservative mode \n " ,
2007-09-17 12:30:59 -07:00
opt . name ) ;
adapter - > itr_setting = adapter - > itr ;
adapter - > itr = 20000 ;
break ;
default :
/*
2008-08-08 18:35:51 -07:00
* Save the setting , because the dynamic bits
* change itr .
2007-09-17 12:30:59 -07:00
*/
2008-08-08 18:35:51 -07:00
if ( e1000_validate_option ( & adapter - > itr , & opt ,
adapter ) & &
( adapter - > itr = = 3 ) ) {
/*
* In case of invalid user value ,
* default to conservative mode .
*/
adapter - > itr_setting = adapter - > itr ;
adapter - > itr = 20000 ;
} else {
/*
* Clear the lower two bits because
* they are used as control .
*/
adapter - > itr_setting =
adapter - > itr & ~ 3 ;
}
2007-09-17 12:30:59 -07:00
break ;
}
} else {
adapter - > itr_setting = opt . def ;
adapter - > itr = 20000 ;
}
}
2008-08-26 18:37:06 -07:00
{ /* Interrupt Mode */
struct e1000_option opt = {
. type = range_option ,
. name = " Interrupt Mode " ,
. err = " defaulting to 2 (MSI-X) " ,
. def = E1000E_INT_MODE_MSIX ,
. arg = { . r = { . min = MIN_INTMODE ,
. max = MAX_INTMODE } }
} ;
if ( num_IntMode > bd ) {
unsigned int int_mode = IntMode [ bd ] ;
e1000_validate_option ( & int_mode , & opt , adapter ) ;
adapter - > int_mode = int_mode ;
} else {
adapter - > int_mode = opt . def ;
}
}
2007-09-17 12:30:59 -07:00
{ /* Smart Power Down */
2007-10-29 10:46:05 -07:00
const struct e1000_option opt = {
2007-09-17 12:30:59 -07:00
. type = enable_option ,
. name = " PHY Smart Power Down " ,
. err = " defaulting to Disabled " ,
. def = OPTION_DISABLED
} ;
if ( num_SmartPowerDownEnable > bd ) {
2007-10-29 10:46:05 -07:00
unsigned int spd = SmartPowerDownEnable [ bd ] ;
2007-09-17 12:30:59 -07:00
e1000_validate_option ( & spd , & opt , adapter ) ;
if ( ( adapter - > flags & FLAG_HAS_SMART_POWER_DOWN )
& & spd )
adapter - > flags | = FLAG_SMART_POWER_DOWN ;
}
}
2008-11-14 06:45:23 +00:00
{ /* CRC Stripping */
const struct e1000_option opt = {
. type = enable_option ,
. name = " CRC Stripping " ,
. err = " defaulting to enabled " ,
. def = OPTION_ENABLED
} ;
if ( num_CrcStripping > bd ) {
unsigned int crc_stripping = CrcStripping [ bd ] ;
e1000_validate_option ( & crc_stripping , & opt , adapter ) ;
if ( crc_stripping = = OPTION_ENABLED )
adapter - > flags2 | = FLAG2_CRC_STRIPPING ;
2009-06-02 11:28:01 +00:00
} else {
adapter - > flags2 | = FLAG2_CRC_STRIPPING ;
2008-11-14 06:45:23 +00:00
}
}
2007-09-17 12:30:59 -07:00
{ /* Kumeran Lock Loss Workaround */
2007-10-29 10:46:05 -07:00
const struct e1000_option opt = {
2007-09-17 12:30:59 -07:00
. type = enable_option ,
. name = " Kumeran Lock Loss Workaround " ,
. err = " defaulting to Enabled " ,
. def = OPTION_ENABLED
} ;
if ( num_KumeranLockLoss > bd ) {
2007-10-29 10:46:05 -07:00
unsigned int kmrn_lock_loss = KumeranLockLoss [ bd ] ;
2007-09-17 12:30:59 -07:00
e1000_validate_option ( & kmrn_lock_loss , & opt , adapter ) ;
if ( hw - > mac . type = = e1000_ich8lan )
e1000e_set_kmrn_lock_loss_workaround_ich8lan ( hw ,
kmrn_lock_loss ) ;
} else {
if ( hw - > mac . type = = e1000_ich8lan )
e1000e_set_kmrn_lock_loss_workaround_ich8lan ( hw ,
opt . def ) ;
}
}
2008-10-01 17:18:35 -07:00
{ /* Write-protect NVM */
const struct e1000_option opt = {
. type = enable_option ,
. name = " Write-protect NVM " ,
. err = " defaulting to Enabled " ,
. def = OPTION_ENABLED
} ;
if ( adapter - > flags & FLAG_IS_ICH ) {
if ( num_WriteProtectNVM > bd ) {
unsigned int write_protect_nvm = WriteProtectNVM [ bd ] ;
e1000_validate_option ( & write_protect_nvm , & opt ,
adapter ) ;
if ( write_protect_nvm )
adapter - > flags | = FLAG_READ_ONLY_NVM ;
} else {
if ( opt . def )
adapter - > flags | = FLAG_READ_ONLY_NVM ;
}
}
}
2007-09-17 12:30:59 -07:00
}