Commit e5c136c0 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/garz/repo/e1000-2.5

into redhat.com:/garz/repo/net-drivers-2.5
parents 605cafbe 3cddbbc6
Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
=============================================================== ===============================================================
October 12, 2002 January 8, 2003
Contents Contents
...@@ -20,27 +20,11 @@ In This Release ...@@ -20,27 +20,11 @@ In This Release
=============== ===============
This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
of Adapters, version 4.4.x. This driver includes support for of Adapters, version 5.0.x. This driver includes support for
Itanium(TM)-based systems. Itanium(TM)-based systems.
This release version includes the following:
- Support for the ethtool 1.6 interface. A third-party application can use
the ethtool interface to get and set driver parameters.
- Zero copy. This feature provides faster data throughput. Enabled by
default in supporting kernels. It is not supported on the Intel(R)
PRO/1000 Gigabit Server Adapter.
Features include:
- Support for the 82545 and 82546-based adapters listed below
- Wake on LAN* support via ethtool for 82540, 82544, 82545, and 82546-
based adapters
- Adaptive IFS for increased performance at half duplex
Native VLANs are now available with supported kernels.
Supported Adapters Supported Adapters
...@@ -65,6 +49,7 @@ release: ...@@ -65,6 +49,7 @@ release:
82544 PRO/1000 T Desktop Adapter A62947-xxx 82544 PRO/1000 T Desktop Adapter A62947-xxx
82540 PRO/1000 MT Desktop Adapter A78408-xxx 82540 PRO/1000 MT Desktop Adapter A78408-xxx
82541 C91016-xxx
82545 PRO/1000 MT Server Adapter A92165-xxx 82545 PRO/1000 MT Server Adapter A92165-xxx
...@@ -77,26 +62,32 @@ release: ...@@ -77,26 +62,32 @@ release:
82546 PRO/1000 MF Dual Port Server Adapter A91620-xxx 82546 PRO/1000 MF Dual Port Server Adapter A91620-xxx
To verify your Intel adapter is supported, find the board ID number on the To verify your Intel adapter is supported, find the board ID number on the
adapter. Look for a label that has a barcode and a number in the format of adapter. Look for a label that has a barcode and a number in the format
123456-001 (six digits hyphen three digits). Match this to the list of A12345-001. Match this to the list of numbers above.
numbers above.
For more information on how to identify your adapter, go to the Adapter & For more information on how to identify your adapter, go to the Adapter &
Driver ID Guide at: Driver ID Guide at:
http://support.intel.com/support/network/adapter/pro100/21397.htm http://support.intel.com/support/network/adapter/pro100/21397.htm
For the latest Intel network drivers for Linux, go to: For the latest Intel network drivers for Linux, refer to the following
http://appsr.intel.com/scripts-df/support_intel.asp http://downloadfinder.intel.com/scripts-df/support_intel.asp
Command Line Parameters Command Line Parameters
======================= =======================
If the driver is built as a module, the following optional parameters are If the driver is built as a module, the following optional parameters are
used by entering them on the command line with the modprobe or insmod command. used by entering them on the command line with the modprobe or insmod command
using this syntax:
modprobe e1000 [<option>=<VAL1>,<VAL2>,...]
insmod e1000 [<option>=<VAL1>,<VAL2>,...]
For example, with two PRO/1000 PCI adapters, entering: For example, with two PRO/1000 PCI adapters, entering:
insmod e1000 TxDescriptors=80,128 insmod e1000 TxDescriptors=80,128
...@@ -104,6 +95,9 @@ For example, with two PRO/1000 PCI adapters, entering: ...@@ -104,6 +95,9 @@ For example, with two PRO/1000 PCI adapters, entering:
loads the e1000 driver with 80 TX resources for the first adapter and 128 TX loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
resources for the second adapter. resources for the second adapter.
The default value for each parameter is generally the recommended setting,
unless otherwise noted.
For more information about the AutoNeg, Duplex, and Speed parameters, see the For more information about the AutoNeg, Duplex, and Speed parameters, see the
"Speed and Duplex Configuration" section in this document. "Speed and Duplex Configuration" section in this document.
...@@ -129,6 +123,20 @@ Default: Read flow control settings from the EEPROM ...@@ -129,6 +123,20 @@ Default: Read flow control settings from the EEPROM
This parameter controls the automatic generation(Tx) and response(Rx) to This parameter controls the automatic generation(Tx) and response(Rx) to
Ethernet PAUSE frames. Ethernet PAUSE frames.
InterruptThrottleRate
Valid Range: 100-100000 (0=off, 1=dynamic)
Default Value: 1
This value represents the maximum number of interrupts per second the
controller generates. InterruptThrottleRate is another setting used in
interrupt moderation. Dynamic mode uses a heuristic algorithm to adjust
InterruptThrottleRate based on the current traffic load.
NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and
RxAbsIntDelay parameters. In other words, minimizing the receive
and/or transmit absolute delays does not force the controller to
generate more interrupts than what the Interrupt Throttle Rate
allows.
RxDescriptors RxDescriptors
Valid Range: 80-256 for 82542 and 82543-based adapters Valid Range: 80-256 for 82542 and 82543-based adapters
80-4096 for 82540, 82544, 82545, and 82546-based adapters 80-4096 for 82540, 82544, 82545, and 82546-based adapters
...@@ -176,7 +184,7 @@ Default Value: 0 (auto-negotiate at all supported speeds) ...@@ -176,7 +184,7 @@ Default Value: 0 (auto-negotiate at all supported speeds)
Speed forces the line speed to the specified value in megabits per second Speed forces the line speed to the specified value in megabits per second
(Mbps). If this parameter is not specified or is set to 0 and the link (Mbps). If this parameter is not specified or is set to 0 and the link
partner is set to auto-negotiate, the board will auto-detect the correct partner is set to auto-negotiate, the board will auto-detect the correct
speed. Duplex must also be set when Speed is set to either 10 or 100. speed. Duplex should also be set when Speed is set to either 10 or 100.
TxDescriptors TxDescriptors
Valid Range: 80-256 for 82542 and 82543-based adapters Valid Range: 80-256 for 82542 and 82543-based adapters
...@@ -205,7 +213,7 @@ Default Value: 64 ...@@ -205,7 +213,7 @@ Default Value: 64
along with TxIntDelay, may improve traffic throughput in specific along with TxIntDelay, may improve traffic throughput in specific
network conditions. network conditions.
XsumRX (not available on the PRO/1000 Gigabit Server Adapter) XsumRX (not available on the 82542-based adapter)
Valid Range: 0-1 Valid Range: 0-1
Default Value: 1 Default Value: 1
A value of '1' indicates that the driver should enable IP checksum A value of '1' indicates that the driver should enable IP checksum
...@@ -230,8 +238,8 @@ For copper-based boards, the keywords interact as follows: ...@@ -230,8 +238,8 @@ For copper-based boards, the keywords interact as follows:
If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
advertised (The 1000BaseT spec requires auto-negotiation.) advertised (The 1000BaseT spec requires auto-negotiation.)
If Speed = 10 or 100, then both Speed and Duplex must be set. Auto- If Speed = 10 or 100, then both Speed and Duplex should be set. Auto-
negotiation is disabled, and the AutoNeg parameter is ignored. Partner MUST negotiation is disabled, and the AutoNeg parameter is ignored. Partner SHOULD
also be forced. also be forced.
The AutoNeg parameter is used when more control is required over the auto- The AutoNeg parameter is used when more control is required over the auto-
...@@ -263,6 +271,12 @@ Additional Configurations ...@@ -263,6 +271,12 @@ Additional Configurations
ifconfig ethx mtu 9000 up ifconfig ethx mtu 9000 up
The maximum MTU setting for Jumbo Frames is 16110. This value coincides
with the maximum Jumbo Frames size of 16128.
NOTE: Jumbo Frames are supported at 1000 Mbps only. Using Jumbo Frames at
10 or 100 Mbps may result in poor performance or loss of link.
Known Issues Known Issues
============ ============
...@@ -279,7 +293,7 @@ Known Issues ...@@ -279,7 +293,7 @@ Known Issues
Support Support
======= =======
For general information and support, go to the Intel support website at: For general information, go to the Intel support website at:
http://support.intel.com http://support.intel.com
......
...@@ -923,10 +923,11 @@ M: scott.feldman@intel.com ...@@ -923,10 +923,11 @@ M: scott.feldman@intel.com
S: Supported S: Supported
INTEL PRO/1000 GIGABIT ETHERNET SUPPORT INTEL PRO/1000 GIGABIT ETHERNET SUPPORT
P: Chris Leech P: Jeb Cramer
M: christopher.leech@intel.com M: cramerj@intel.com
P: Scott Feldman P: Scott Feldman
M: scott.feldman@intel.com M: scott.feldman@intel.com
W: http://sourceforge.net/projects/e1000/
S: Supported S: Supported
INTERMEZZO FILE SYSTEM INTERMEZZO FILE SYSTEM
......
...@@ -1953,6 +1953,7 @@ config E1000 ...@@ -1953,6 +1953,7 @@ config E1000
82544 PRO/1000 XF Server Adapter A50484-xxx 82544 PRO/1000 XF Server Adapter A50484-xxx
82544 PRO/1000 T Desktop Adapter A62947-xxx 82544 PRO/1000 T Desktop Adapter A62947-xxx
82540 PRO/1000 MT Desktop Adapter A78408-xxx 82540 PRO/1000 MT Desktop Adapter A78408-xxx
82541 PRO/1000 MT Desktop Adapter C91016-xxx
82545 PRO/1000 MT Server Adapter A92165-xxx 82545 PRO/1000 MT Server Adapter A92165-xxx
82546 PRO/1000 MT Dual Port Server Adapter A92111-xxx 82546 PRO/1000 MT Dual Port Server Adapter A92111-xxx
82545 PRO/1000 MF Server Adapter A91622-xxx 82545 PRO/1000 MF Server Adapter A91622-xxx
......
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <net/checksum.h> #include <net/checksum.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
...@@ -95,6 +96,15 @@ struct e1000_adapter; ...@@ -95,6 +96,15 @@ struct e1000_adapter;
#define E1000_RXBUFFER_8192 8192 #define E1000_RXBUFFER_8192 8192
#define E1000_RXBUFFER_16384 16384 #define E1000_RXBUFFER_16384 16384
/* SmartSpeed delimiters */
#define E1000_SMARTSPEED_DOWNSHIFT 3
#define E1000_SMARTSPEED_MAX 15
/* Packet Buffer allocations */
#define E1000_TX_FIFO_SIZE_SHIFT 0xA
#define E1000_TX_HEAD_ADDR_SHIFT 7
#define E1000_PBA_TX_MASK 0xFFFF0000
/* Flow Control High-Watermark: 43464 bytes */ /* Flow Control High-Watermark: 43464 bytes */
#define E1000_FC_HIGH_THRESH 0xA9C8 #define E1000_FC_HIGH_THRESH 0xA9C8
...@@ -107,10 +117,7 @@ struct e1000_adapter; ...@@ -107,10 +117,7 @@ struct e1000_adapter;
/* How many Tx Descriptors do we need to call netif_wake_queue ? */ /* How many Tx Descriptors do we need to call netif_wake_queue ? */
#define E1000_TX_QUEUE_WAKE 16 #define E1000_TX_QUEUE_WAKE 16
/* How many Rx Buffers do we bundle into one write to the hardware ? */ /* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE 16 #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define E1000_JUMBO_PBA 0x00000028
#define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0 #define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 4 #define E1000_EEPROM_APME 4
...@@ -145,7 +152,8 @@ struct e1000_desc_ring { ...@@ -145,7 +152,8 @@ struct e1000_desc_ring {
}; };
#define E1000_DESC_UNUSED(R) \ #define E1000_DESC_UNUSED(R) \
((((R)->next_to_clean + (R)->count) - ((R)->next_to_use + 1)) % ((R)->count)) ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
(R)->next_to_clean - (R)->next_to_use - 1)
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
...@@ -155,6 +163,7 @@ struct e1000_desc_ring { ...@@ -155,6 +163,7 @@ struct e1000_desc_ring {
/* board specific private data structure */ /* board specific private data structure */
struct e1000_adapter { struct e1000_adapter {
struct timer_list tx_fifo_stall_timer;
struct timer_list watchdog_timer; struct timer_list watchdog_timer;
struct timer_list phy_info_timer; struct timer_list phy_info_timer;
struct vlan_group *vlgrp; struct vlan_group *vlgrp;
...@@ -163,6 +172,7 @@ struct e1000_adapter { ...@@ -163,6 +172,7 @@ struct e1000_adapter {
uint32_t rx_buffer_len; uint32_t rx_buffer_len;
uint32_t part_num; uint32_t part_num;
uint32_t wol; uint32_t wol;
uint32_t smartspeed;
uint16_t link_speed; uint16_t link_speed;
uint16_t link_duplex; uint16_t link_duplex;
spinlock_t stats_lock; spinlock_t stats_lock;
...@@ -177,7 +187,11 @@ struct e1000_adapter { ...@@ -177,7 +187,11 @@ struct e1000_adapter {
uint32_t txd_cmd; uint32_t txd_cmd;
uint32_t tx_int_delay; uint32_t tx_int_delay;
uint32_t tx_abs_int_delay; uint32_t tx_abs_int_delay;
int max_data_per_txd; uint32_t gotcl;
uint32_t tx_fifo_head;
uint32_t tx_head_addr;
uint32_t tx_fifo_size;
atomic_t tx_fifo_stall;
/* RX */ /* RX */
struct e1000_desc_ring rx_ring; struct e1000_desc_ring rx_ring;
...@@ -186,6 +200,10 @@ struct e1000_adapter { ...@@ -186,6 +200,10 @@ struct e1000_adapter {
uint32_t rx_int_delay; uint32_t rx_int_delay;
uint32_t rx_abs_int_delay; uint32_t rx_abs_int_delay;
boolean_t rx_csum; boolean_t rx_csum;
uint32_t gorcl;
/* Interrupt Throttle Rate */
uint32_t itr;
/* OS defined structs */ /* OS defined structs */
struct net_device *netdev; struct net_device *netdev;
......
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -38,6 +38,7 @@ extern char e1000_driver_version[]; ...@@ -38,6 +38,7 @@ extern char e1000_driver_version[];
extern int e1000_up(struct e1000_adapter *adapter); extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter); extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter); extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
static char e1000_gstrings_stats[][ETH_GSTRING_LEN] = { static char e1000_gstrings_stats[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
...@@ -129,30 +130,9 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) ...@@ -129,30 +130,9 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
hw->autoneg = 1; hw->autoneg = 1;
hw->autoneg_advertised = 0x002F; hw->autoneg_advertised = 0x002F;
ecmd->advertising = 0x002F; ecmd->advertising = 0x002F;
} else { } else
hw->autoneg = 0; if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
switch(ecmd->speed + ecmd->duplex) {
case SPEED_10 + DUPLEX_HALF:
hw->forced_speed_duplex = e1000_10_half;
break;
case SPEED_10 + DUPLEX_FULL:
hw->forced_speed_duplex = e1000_10_full;
break;
case SPEED_100 + DUPLEX_HALF:
hw->forced_speed_duplex = e1000_100_half;
break;
case SPEED_100 + DUPLEX_FULL:
hw->forced_speed_duplex = e1000_100_full;
break;
case SPEED_1000 + DUPLEX_FULL:
hw->autoneg = 1;
hw->autoneg_advertised = ADVERTISE_1000_FULL;
break;
case SPEED_1000 + DUPLEX_HALF: /* not supported */
default:
return -EINVAL; return -EINVAL;
}
}
/* reset the link */ /* reset the link */
...@@ -165,16 +145,6 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) ...@@ -165,16 +145,6 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
return 0; return 0;
} }
static inline int
e1000_eeprom_size(struct e1000_hw *hw)
{
if((hw->mac_type > e1000_82544) &&
(E1000_READ_REG(hw, EECD) & E1000_EECD_SIZE))
return 512;
else
return 128;
}
static void static void
e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter, e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
...@@ -186,7 +156,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter, ...@@ -186,7 +156,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
drvinfo->n_stats = E1000_STATS_LEN; drvinfo->n_stats = E1000_STATS_LEN;
#define E1000_REGS_LEN 32 #define E1000_REGS_LEN 32
drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t); drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t);
drvinfo->eedump_len = e1000_eeprom_size(&adapter->hw); drvinfo->eedump_len = adapter->hw.eeprom.word_size * 2;
} }
static void static void
...@@ -220,9 +190,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter, ...@@ -220,9 +190,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff) struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int max_len, first_word, last_word; int first_word, last_word;
int ret_val = 0; int ret_val = 0;
int i;
if(eeprom->len == 0) { if(eeprom->len == 0) {
ret_val = -EINVAL; ret_val = -EINVAL;
...@@ -231,22 +200,28 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter, ...@@ -231,22 +200,28 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
eeprom->magic = hw->vendor_id | (hw->device_id << 16); eeprom->magic = hw->vendor_id | (hw->device_id << 16);
max_len = e1000_eeprom_size(hw);
if(eeprom->offset > eeprom->offset + eeprom->len) { if(eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL; ret_val = -EINVAL;
goto geeprom_error; goto geeprom_error;
} }
if((eeprom->offset + eeprom->len) > max_len) if((eeprom->offset + eeprom->len) > (hw->eeprom.word_size * 2))
eeprom->len = (max_len - eeprom->offset); eeprom->len = ((hw->eeprom.word_size * 2) - eeprom->offset);
first_word = eeprom->offset >> 1; first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1;
for(i = 0; i <= (last_word - first_word); i++) if(hw->eeprom.type == e1000_eeprom_spi)
e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]); ret_val = e1000_read_eeprom(hw, first_word,
last_word - first_word + 1,
eeprom_buff);
else {
uint16_t i;
for (i = 0; i < last_word - first_word + 1; i++)
if((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
&eeprom_buff[i])))
break;
}
geeprom_error: geeprom_error:
return ret_val; return ret_val;
} }
...@@ -257,9 +232,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter, ...@@ -257,9 +232,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff; uint16_t *eeprom_buff;
int max_len, first_word, last_word;
void *ptr; void *ptr;
int i; int max_len, first_word, last_word, ret_val = 0;
if(eeprom->len == 0) if(eeprom->len == 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -267,7 +241,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter, ...@@ -267,7 +241,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT; return -EFAULT;
max_len = e1000_eeprom_size(hw); max_len = hw->eeprom.word_size * 2;
if((eeprom->offset + eeprom->len) > max_len) if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset); eeprom->len = (max_len - eeprom->offset);
...@@ -283,30 +257,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter, ...@@ -283,30 +257,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if(eeprom->offset & 1) { if(eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */ /* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */ /* only the second byte of the word is being modified */
e1000_read_eeprom(hw, first_word, &eeprom_buff[0]); ret_val = e1000_read_eeprom(hw, first_word, 1,
&eeprom_buff[0]);
ptr++; ptr++;
} }
if((eeprom->offset + eeprom->len) & 1) { if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
/* need read/modify/write of last changed EEPROM word */ /* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */ /* only the first byte of the word is being modified */
e1000_read_eeprom(hw, last_word, ret_val = e1000_read_eeprom(hw, last_word, 1,
&eeprom_buff[last_word - first_word]); &eeprom_buff[last_word - first_word]);
} }
if(copy_from_user(ptr, user_data, eeprom->len)) { if((ret_val != 0) || copy_from_user(ptr, user_data, eeprom->len)) {
kfree(eeprom_buff); ret_val = -EFAULT;
return -EFAULT; goto seeprom_error;
} }
for(i = 0; i <= (last_word - first_word); i++) ret_val = e1000_write_eeprom(hw, first_word,
e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]); last_word - first_word + 1, eeprom_buff);
/* Update the checksum over the first part of the EEPROM if needed */ /* Update the checksum over the first part of the EEPROM if needed */
if(first_word <= EEPROM_CHECKSUM_REG) if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
e1000_update_eeprom_checksum(hw); e1000_update_eeprom_checksum(hw);
seeprom_error:
kfree(eeprom_buff); kfree(eeprom_buff);
return ret_val;
return 0;
} }
static void static void
...@@ -333,8 +308,8 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -333,8 +308,8 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */ /* Fall Through */
default: default:
wol->supported = WAKE_UCAST | WAKE_MCAST wol->supported = WAKE_UCAST | WAKE_MCAST |
| WAKE_BCAST | WAKE_MAGIC; WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0; wol->wolopts = 0;
if(adapter->wol & E1000_WUFC_EX) if(adapter->wol & E1000_WUFC_EX)
...@@ -368,7 +343,7 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -368,7 +343,7 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */ /* Fall Through */
default: default:
if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY)) if(wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP; return -EOPNOTSUPP;
adapter->wol = 0; adapter->wol = 0;
...@@ -542,13 +517,12 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -542,13 +517,12 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
} }
case ETHTOOL_GEEPROM: { case ETHTOOL_GEEPROM: {
struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM}; struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff; uint16_t *eeprom_buff;
void *ptr; void *ptr;
int max_len, err = 0; int err = 0;
max_len = e1000_eeprom_size(&adapter->hw);
eeprom_buff = kmalloc(max_len, GFP_KERNEL); eeprom_buff = kmalloc(hw->eeprom.word_size * 2, GFP_KERNEL);
if(eeprom_buff == NULL) if(eeprom_buff == NULL)
return -ENOMEM; return -ENOMEM;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -77,24 +77,22 @@ typedef enum { ...@@ -77,24 +77,22 @@ typedef enum {
#define E1000_WRITE_REG(a, reg, value) ( \ #define E1000_WRITE_REG(a, reg, value) ( \
((a)->mac_type >= e1000_82543) ? \ writel((value), ((a)->hw_addr + \
(writel((value), ((a)->hw_addr + E1000_##reg))) : \ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))))
(writel((value), ((a)->hw_addr + E1000_82542_##reg))))
#define E1000_READ_REG(a, reg) ( \ #define E1000_READ_REG(a, reg) ( \
((a)->mac_type >= e1000_82543) ? \ readl((a)->hw_addr + \
readl((a)->hw_addr + E1000_##reg) : \ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))
readl((a)->hw_addr + E1000_82542_##reg))
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \ #define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
((a)->mac_type >= e1000_82543) ? \ writel((value), ((a)->hw_addr + \
writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) : \ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
writel((value), ((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))) ((offset) << 2))))
#define E1000_READ_REG_ARRAY(a, reg, offset) ( \ #define E1000_READ_REG_ARRAY(a, reg, offset) ( \
((a)->mac_type >= e1000_82543) ? \ readl((a)->hw_addr + \
readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2))) ((offset) << 2)))
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS) #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
......
/******************************************************************************* /*******************************************************************************
Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
...@@ -169,7 +169,7 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); ...@@ -169,7 +169,7 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
* *
* Valid Range: 0-65535 * Valid Range: 0-65535
* *
* Default Value: 0/128 * Default Value: 0
*/ */
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
...@@ -183,6 +183,15 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); ...@@ -183,6 +183,15 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
/* Interrupt Throttle Rate (interrupts/sec)
*
* Valid Range: 100-100000 (0=off, 1=dynamic)
*
* Default Value: 1
*/
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
#define AUTONEG_ADV_DEFAULT 0x2F #define AUTONEG_ADV_DEFAULT 0x2F
#define AUTONEG_ADV_MASK 0x2F #define AUTONEG_ADV_MASK 0x2F
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
...@@ -213,6 +222,10 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); ...@@ -213,6 +222,10 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
#define MAX_TXABSDELAY 0xFFFF #define MAX_TXABSDELAY 0xFFFF
#define MIN_TXABSDELAY 0 #define MIN_TXABSDELAY 0
#define DEFAULT_ITR 1
#define MAX_ITR 100000
#define MIN_ITR 100
struct e1000_option { struct e1000_option {
enum { enable_option, range_option, list_option } type; enum { enable_option, range_option, list_option } type;
char *name; char *name;
...@@ -309,7 +322,7 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -309,7 +322,7 @@ e1000_check_options(struct e1000_adapter *adapter)
.name = "Transmit Descriptors", .name = "Transmit Descriptors",
.err = "using default of " __MODULE_STRING(DEFAULT_TXD), .err = "using default of " __MODULE_STRING(DEFAULT_TXD),
.def = DEFAULT_TXD, .def = DEFAULT_TXD,
.arg = { .r = { .min = MIN_TXD }} .arg = { .r { .min = MIN_TXD }}
}; };
struct e1000_desc_ring *tx_ring = &adapter->tx_ring; struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
e1000_mac_type mac_type = adapter->hw.mac_type; e1000_mac_type mac_type = adapter->hw.mac_type;
...@@ -362,7 +375,8 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -362,7 +375,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.name = "Flow Control", .name = "Flow Control",
.err = "reading default settings from EEPROM", .err = "reading default settings from EEPROM",
.def = e1000_fc_default, .def = e1000_fc_default,
.arg = { .l = { .nr = ARRAY_SIZE(fc_list), .p = fc_list }} .arg = { .l = { .nr = ARRAY_SIZE(fc_list),
.p = fc_list }}
}; };
int fc = FlowControl[bd]; int fc = FlowControl[bd];
...@@ -370,57 +384,77 @@ e1000_check_options(struct e1000_adapter *adapter) ...@@ -370,57 +384,77 @@ e1000_check_options(struct e1000_adapter *adapter)
adapter->hw.fc = adapter->hw.original_fc = fc; adapter->hw.fc = adapter->hw.original_fc = fc;
} }
{ /* Transmit Interrupt Delay */ { /* Transmit Interrupt Delay */
char *tidv = "using default of " __MODULE_STRING(DEFAULT_TIDV);
struct e1000_option opt = { struct e1000_option opt = {
.type = range_option, .type = range_option,
.name = "Transmit Interrupt Delay", .name = "Transmit Interrupt Delay",
.arg = { .r = { .min = MIN_TXDELAY, .max = MAX_TXDELAY }} .err = "using default of " __MODULE_STRING(DEFAULT_TIDV),
.def = DEFAULT_TIDV,
.arg = { .r = { .min = MIN_TXDELAY,
.max = MAX_TXDELAY }}
}; };
opt.def = DEFAULT_TIDV;
opt.err = tidv;
adapter->tx_int_delay = TxIntDelay[bd]; adapter->tx_int_delay = TxIntDelay[bd];
e1000_validate_option(&adapter->tx_int_delay, &opt); e1000_validate_option(&adapter->tx_int_delay, &opt);
} }
{ /* Transmit Absolute Interrupt Delay */ { /* Transmit Absolute Interrupt Delay */
char *tadv = "using default of " __MODULE_STRING(DEFAULT_TADV);
struct e1000_option opt = { struct e1000_option opt = {
.type = range_option, .type = range_option,
.name = "Transmit Absolute Interrupt Delay", .name = "Transmit Absolute Interrupt Delay",
.arg = { .r = { .min = MIN_TXABSDELAY, .max = MAX_TXABSDELAY }} .err = "using default of " __MODULE_STRING(DEFAULT_TADV),
.def = DEFAULT_TADV,
.arg = { .r = { .min = MIN_TXABSDELAY,
.max = MAX_TXABSDELAY }}
}; };
opt.def = DEFAULT_TADV;
opt.err = tadv;
adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
e1000_validate_option(&adapter->tx_abs_int_delay, &opt); e1000_validate_option(&adapter->tx_abs_int_delay, &opt);
} }
{ /* Receive Interrupt Delay */ { /* Receive Interrupt Delay */
char *rdtr = "using default of " __MODULE_STRING(DEFAULT_RDTR);
struct e1000_option opt = { struct e1000_option opt = {
.type = range_option, .type = range_option,
.name = "Receive Interrupt Delay", .name = "Receive Interrupt Delay",
.arg = { .r = { .min = MIN_RXDELAY, .max = MAX_RXDELAY }} .err = "using default of " __MODULE_STRING(DEFAULT_RDTR),
.def = DEFAULT_RDTR,
.arg = { .r = { .min = MIN_RXDELAY,
.max = MAX_RXDELAY }}
}; };
opt.def = DEFAULT_RDTR;
opt.err = rdtr;
adapter->rx_int_delay = RxIntDelay[bd]; adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt); e1000_validate_option(&adapter->rx_int_delay, &opt);
} }
{ /* Receive Absolute Interrupt Delay */ { /* Receive Absolute Interrupt Delay */
char *radv = "using default of " __MODULE_STRING(DEFAULT_RADV);
struct e1000_option opt = { struct e1000_option opt = {
.type = range_option, .type = range_option,
.name = "Receive Absolute Interrupt Delay", .name = "Receive Absolute Interrupt Delay",
.arg = { .r = { .min = MIN_RXABSDELAY, .max = MAX_RXABSDELAY }} .err = "using default of " __MODULE_STRING(DEFAULT_RADV),
.def = DEFAULT_RADV,
.arg = { .r = { .min = MIN_RXABSDELAY,
.max = MAX_RXABSDELAY }}
}; };
opt.def = DEFAULT_RADV;
opt.err = radv;
adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
e1000_validate_option(&adapter->rx_abs_int_delay, &opt); e1000_validate_option(&adapter->rx_abs_int_delay, &opt);
} }
{ /* Interrupt Throttling Rate */
struct e1000_option opt = {
.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 }}
};
adapter->itr = InterruptThrottleRate[bd];
if(adapter->itr == 0) {
printk(KERN_INFO "%s turned off\n", opt.name);
} else if(adapter->itr == 1 || adapter->itr == -1) {
/* Dynamic mode */
adapter->itr = 1;
} else {
e1000_validate_option(&adapter->itr, &opt);
}
}
switch(adapter->hw.media_type) { switch(adapter->hw.media_type) {
case e1000_media_type_fiber: case e1000_media_type_fiber:
...@@ -486,7 +520,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -486,7 +520,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.name = "Speed", .name = "Speed",
.err = "parameter ignored", .err = "parameter ignored",
.def = 0, .def = 0,
.arg = { .l = { .nr = ARRAY_SIZE(speed_list), .p = speed_list }} .arg = { .l = { .nr = ARRAY_SIZE(speed_list),
.p = speed_list }}
}; };
speed = Speed[bd]; speed = Speed[bd];
...@@ -502,7 +537,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -502,7 +537,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.name = "Duplex", .name = "Duplex",
.err = "parameter ignored", .err = "parameter ignored",
.def = 0, .def = 0,
.arg = { .l = { .nr = ARRAY_SIZE(dplx_list), .p = dplx_list }} .arg = { .l = { .nr = ARRAY_SIZE(dplx_list),
.p = dplx_list }}
}; };
dplx = Duplex[bd]; dplx = Duplex[bd];
...@@ -554,7 +590,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -554,7 +590,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.name = "AutoNeg", .name = "AutoNeg",
.err = "parameter ignored", .err = "parameter ignored",
.def = AUTONEG_ADV_DEFAULT, .def = AUTONEG_ADV_DEFAULT,
.arg = { .l = { .nr = ARRAY_SIZE(an_list), .p = an_list }} .arg = { .l = { .nr = ARRAY_SIZE(an_list),
.p = an_list }}
}; };
int an = AutoNeg[bd]; int an = AutoNeg[bd];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment