Commit 9beae32e authored by Scott Feldman's avatar Scott Feldman Committed by David Mosberger

Update e1000 gige net driver:

o Bug fix: fixed jumbo frames sized from 1514 to 2048.
o ASF support: disable ARP when driver is loaded or resumed; enable when 
  driver is removed or suspended.
o Bug fix: changed default setting for RxIntDelay to 0 for 82542/3/4
  controllers to workaround h/w errata where controller will hang when
  RxIntDelay <> 0 under certian network conditions.
o Bug fix: perform controller reset using I/O rather than mmio because
  some chipsets try to perform a 64-bit write, but the controller ignores
  the upper 32-bit write once the reset is intiated by the lower 32-bit
  write, causing a master abort.
o Clean up: removed unused and undocumented user-settable settings for
  PHY.
o Bug fix: ethtool GEEPROM was using byte address rather than word
  addressing.
o Feature: added support for ethtool SEEPROM.
o Feature: added support for entropy pool.
parent 7dbdd525
Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
=============================================================== ===============================================================
April 23, 2002 June 11, 2002
Contents Contents
...@@ -95,8 +95,8 @@ For the latest Intel network drivers for Linux, go to: ...@@ -95,8 +95,8 @@ For the latest Intel network drivers for Linux, go to:
Command Line Parameters Command Line Parameters
======================= =======================
If the driver is built as a module, the following parameters are used by If the driver is built as a module, the following optional parameters are
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.
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
...@@ -141,7 +141,7 @@ Default Value: 80 ...@@ -141,7 +141,7 @@ Default Value: 80
RxIntDelay RxIntDelay
Valid Range: 0-65535 (0=off) Valid Range: 0-65535 (0=off)
Default Value: 64 (82542, 82543, and 82544-based adapters) Default Value: 0 (82542, 82543, and 82544-based adapters)
128 (82540, 82545, and 82546-based adapters) 128 (82540, 82545, and 82546-based adapters)
This value delays the generation of receive interrupts in units of 1.024 This value delays the generation of receive interrupts in units of 1.024
microseconds. Receive interrupt reduction can improve CPU efficiency if microseconds. Receive interrupt reduction can improve CPU efficiency if
...@@ -151,6 +151,14 @@ Default Value: 64 (82542, 82543, and 82544-based adapters) ...@@ -151,6 +151,14 @@ Default Value: 64 (82542, 82543, and 82544-based adapters)
may be set too high, causing the driver to run out of available receive may be set too high, causing the driver to run out of available receive
descriptors. descriptors.
CAUTION: When setting RxIntDelay to a value other than 0, adapters based
on the Intel 82543 and 82544 LAN controllers may hang (stop
transmitting) under certain network conditions. If this occurs a
message is logged in the system event log. In addition, the
controller is automatically reset, restoring the network
connection. To eliminate the potential for the hang ensure that
RxIntDelay is set to 0.
Speed (adapters using copper connections only) Speed (adapters using copper connections only)
Valid Settings: 0, 10, 100, 1000 Valid Settings: 0, 10, 100, 1000
Default Value: 0 (auto-negotiate at all supported speeds) Default Value: 0 (auto-negotiate at all supported speeds)
...@@ -229,16 +237,6 @@ Additional Configurations ...@@ -229,16 +237,6 @@ Additional Configurations
Known Issues Known Issues
============ ============
Inconsistent Driver Behavior Under Heavy Traffic Loads
------------------------------------------------------
Adapters based on the Intel 82543 and 82544 LAN controllers may hang (stop
transmitting) under certain network conditions. If this occurs a message
is logged in the system event log. In addition, the controller is
automatically reset, restoring the network connection. To eliminate the
potential for the hang change the RxIntDelay parameter to zero. For details
on the RxIntDelay parameter see the Command Line Parameters section.
Jumbo Frames System Requirement Jumbo Frames System Requirement
------------------------------- -------------------------------
......
...@@ -114,6 +114,8 @@ ...@@ -114,6 +114,8 @@
#endif #endif
#define BAR_0 0 #define BAR_0 0
#define BAR_1 1
#define BAR_5 5
#define PCI_DMA_64BIT 0xffffffffffffffffULL #define PCI_DMA_64BIT 0xffffffffffffffffULL
#define PCI_DMA_32BIT 0x00000000ffffffffULL #define PCI_DMA_32BIT 0x00000000ffffffffULL
...@@ -150,6 +152,8 @@ struct e1000_adapter; ...@@ -150,6 +152,8 @@ struct e1000_adapter;
#define E1000_JUMBO_PBA 0x00000028 #define E1000_JUMBO_PBA 0x00000028
#define E1000_DEFAULT_PBA 0x00000030 #define E1000_DEFAULT_PBA 0x00000030
#define AUTO_ALL_MODES 0
/* only works for sizes that are powers of 2 */ /* only works for sizes that are powers of 2 */
#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
......
...@@ -249,17 +249,70 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter, ...@@ -249,17 +249,70 @@ 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 i, max_len; int i, max_len, first_word, last_word;
if(eeprom->len == 0) return;
eeprom->magic = hw->vendor_id | (hw->device_id << 16); eeprom->magic = hw->vendor_id | (hw->device_id << 16);
max_len = e1000_eeprom_size(hw); max_len = e1000_eeprom_size(hw);
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);
for(i = 0; i < (max_len >> 1); i++) first_word = eeprom->offset >> 1;
e1000_read_eeprom(&adapter->hw, i, &eeprom_buff[i]); last_word = (eeprom->offset + eeprom->len - 1) >> 1;
for(i = 0; i <= (last_word - first_word); i++)
e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]);
}
static int
e1000_ethtool_seeprom(struct e1000_adapter *adapter,
struct ethtool_eeprom *eeprom, void *user_data)
{
struct e1000_hw *hw = &adapter->hw;
uint16_t eeprom_buff[256];
int i, max_len, first_word, last_word;
void *ptr;
if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
if(eeprom->len == 0) return 0;
max_len = e1000_eeprom_size(hw);
if((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
ptr = (void *)eeprom_buff;
if(eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
e1000_read_eeprom(hw, first_word, &eeprom_buff[0]);
ptr++;
}
if((eeprom->offset + eeprom->len) & 1) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
e1000_read_eeprom(hw, last_word,
&eeprom_buff[last_word - first_word]);
}
if(copy_from_user(ptr, user_data, eeprom->len))
return -EFAULT;
for(i = 0; i <= (last_word - first_word); i++)
e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]);
/* Update the checksum over the first part of the EEPROM if needed */
if(first_word <= EEPROM_CHECKSUM_REG)
e1000_update_eeprom_checksum(hw);
return 0;
} }
static void static void
...@@ -339,7 +392,7 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) ...@@ -339,7 +392,7 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82545EM_FIBER: case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82546EB_COPPER: case E1000_DEV_ID_82546EB_COPPER:
if(wol->wolopts & WAKE_ARP) if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP; return -EOPNOTSUPP;
adapter->wol = 0; adapter->wol = 0;
...@@ -496,6 +549,7 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -496,6 +549,7 @@ 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};
uint16_t eeprom_buff[256]; uint16_t eeprom_buff[256];
void *ptr;
if(copy_from_user(&eeprom, addr, sizeof(eeprom))) if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
return -EFAULT; return -EFAULT;
...@@ -506,11 +560,24 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr) ...@@ -506,11 +560,24 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
return -EFAULT; return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data); addr += offsetof(struct ethtool_eeprom, data);
ptr = ((void *)eeprom_buff) + (eeprom.offset & 1);
if(copy_to_user(addr, eeprom_buff + eeprom.offset, eeprom.len)) if(copy_to_user(addr, ptr, eeprom.len))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
case ETHTOOL_SEEPROM: {
struct ethtool_eeprom eeprom;
if(!capable(CAP_NET_ADMIN))
return -EPERM;
if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
return -EFAULT;
addr += offsetof(struct ethtool_eeprom, data);
return e1000_ethtool_seeprom(adapter, &eeprom, addr);
}
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -146,6 +146,10 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -146,6 +146,10 @@ e1000_reset_hw(struct e1000_hw *hw)
*/ */
DEBUGOUT("Issuing a global reset to MAC\n"); DEBUGOUT("Issuing a global reset to MAC\n");
ctrl = E1000_READ_REG(hw, CTRL); ctrl = E1000_READ_REG(hw, CTRL);
if(hw->mac_type > e1000_82543)
E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
else
E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
/* Force a reload from the EEPROM if necessary */ /* Force a reload from the EEPROM if necessary */
...@@ -2393,6 +2397,47 @@ e1000_standby_eeprom(struct e1000_hw *hw) ...@@ -2393,6 +2397,47 @@ e1000_standby_eeprom(struct e1000_hw *hw)
usec_delay(50); usec_delay(50);
} }
/******************************************************************************
* Raises then lowers the EEPROM's clock pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
e1000_clock_eeprom(struct e1000_hw *hw)
{
uint32_t eecd;
eecd = E1000_READ_REG(hw, EECD);
/* Rising edge of clock */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
usec_delay(50);
/* Falling edge of clock */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
usec_delay(50);
}
/******************************************************************************
* Terminates a command by lowering the EEPROM's chip select pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static void
e1000_cleanup_eeprom(struct e1000_hw *hw)
{
uint32_t eecd;
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, EECD, eecd);
e1000_clock_eeprom(hw);
}
/****************************************************************************** /******************************************************************************
* Reads a 16 bit word from the EEPROM. * Reads a 16 bit word from the EEPROM.
...@@ -2494,6 +2539,152 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw) ...@@ -2494,6 +2539,152 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
} }
} }
/******************************************************************************
* Calculates the EEPROM checksum and writes it to the EEPROM
*
* hw - Struct containing variables accessed by shared code
*
* Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
* Writes the difference to word offset 63 of the EEPROM.
*****************************************************************************/
int32_t
e1000_update_eeprom_checksum(struct e1000_hw *hw)
{
uint16_t checksum = 0;
uint16_t i, eeprom_data;
DEBUGFUNC("e1000_update_eeprom_checksum");
for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
checksum += eeprom_data;
}
checksum = (uint16_t) EEPROM_SUM - checksum;
if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum) < 0) {
DEBUGOUT("EEPROM Write Error\n");
return -E1000_ERR_EEPROM;
}
return 0;
}
/******************************************************************************
* Writes a 16 bit word to a given offset in the EEPROM.
*
* hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to
* data - 16 bit word to be writen to the EEPROM
*
* If e1000_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum.
*****************************************************************************/
int32_t
e1000_write_eeprom(struct e1000_hw *hw,
uint16_t offset,
uint16_t data)
{
uint32_t eecd;
uint32_t i = 0;
int32_t status = 0;
boolean_t large_eeprom = FALSE;
DEBUGFUNC("e1000_write_eeprom");
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
eecd = E1000_READ_REG(hw, EECD);
while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
i++;
usec_delay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
return -E1000_ERR_EEPROM;
}
}
/* Prepare the EEPROM for writing */
e1000_setup_eeprom(hw);
/* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM
* into write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
/* Prepare the EEPROM */
e1000_standby_eeprom(hw);
/* Send the Write command (3-bit opcode + addr) */
e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3);
if(large_eeprom)
/* If we have a 256 word EEPROM, there are 8 address bits */
e1000_shift_out_ee_bits(hw, offset, 8);
else
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits(hw, offset, 6);
/* Send the data */
e1000_shift_out_ee_bits(hw, data, 16);
/* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question.
*/
e1000_standby_eeprom(hw);
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
for(i = 0; i < 200; i++) {
eecd = E1000_READ_REG(hw, EECD);
if(eecd & E1000_EECD_DO) break;
usec_delay(50);
}
if(i == 200) {
DEBUGOUT("EEPROM Write did not complete\n");
status = -E1000_ERR_EEPROM;
}
/* Recover from write */
e1000_standby_eeprom(hw);
/* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
* out of write/erase mode.
*/
e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
if(large_eeprom)
e1000_shift_out_ee_bits(hw, 0, 6);
else
e1000_shift_out_ee_bits(hw, 0, 4);
/* Done with writing */
e1000_cleanup_eeprom(hw);
/* Stop requesting EEPROM access */
if(hw->mac_type > e1000_82544) {
eecd = E1000_READ_REG(hw, EECD);
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
}
return status;
}
/****************************************************************************** /******************************************************************************
* Reads the adapter's part number from the EEPROM * Reads the adapter's part number from the EEPROM
* *
...@@ -3334,4 +3525,41 @@ e1000_get_bus_info(struct e1000_hw *hw) ...@@ -3334,4 +3525,41 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_width = (status & E1000_STATUS_BUS64) ? hw->bus_width = (status & E1000_STATUS_BUS64) ?
e1000_bus_width_64 : e1000_bus_width_32; e1000_bus_width_64 : e1000_bus_width_32;
} }
/******************************************************************************
* Reads a value from one of the devices registers using port I/O (as opposed
* memory mapped I/O). Only 82544 and newer devices support port I/O.
*
* hw - Struct containing variables accessed by shared code
* offset - offset to read from
*****************************************************************************/
uint32_t
e1000_read_reg_io(struct e1000_hw *hw,
uint32_t offset)
{
uint32_t io_addr = hw->io_base;
uint32_t io_data = hw->io_base + 4;
e1000_io_write(hw, io_addr, offset);
return e1000_io_read(hw, io_data);
}
/******************************************************************************
* Writes a value to one of the devices registers using port I/O (as opposed to
* memory mapped I/O). Only 82544 and newer devices support port I/O.
*
* hw - Struct containing variables accessed by shared code
* offset - offset to write to
* value - value to write
*****************************************************************************/
void
e1000_write_reg_io(struct e1000_hw *hw,
uint32_t offset,
uint32_t value)
{
uint32_t io_addr = hw->io_base;
uint32_t io_data = hw->io_base + 4;
e1000_io_write(hw, io_addr, offset);
e1000_io_write(hw, io_data, value);
}
...@@ -236,6 +236,8 @@ int32_t e1000_validate_mdi_setting(struct e1000_hw *hw); ...@@ -236,6 +236,8 @@ int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
/* EEPROM Functions */ /* EEPROM Functions */
int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t *data); int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t *data);
int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw); int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t data);
int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num); int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
int32_t e1000_read_mac_addr(struct e1000_hw * hw); int32_t e1000_read_mac_addr(struct e1000_hw * hw);
...@@ -264,6 +266,15 @@ void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, u ...@@ -264,6 +266,15 @@ void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, u
void e1000_get_bus_info(struct e1000_hw *hw); void e1000_get_bus_info(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
/* Port I/O is only supported on 82544 and newer */
uint32_t e1000_io_read(struct e1000_hw *hw, uint32_t port);
uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
#define E1000_READ_REG_IO(a, reg) \
e1000_read_reg_io((a), E1000_##reg)
#define E1000_WRITE_REG_IO(a, reg, val) \
e1000_write_reg_io((a), E1000_##reg, val)
/* PCI Device IDs */ /* PCI Device IDs */
#define E1000_DEV_ID_82542 0x1000 #define E1000_DEV_ID_82542 0x1000
...@@ -878,6 +889,7 @@ struct e1000_hw { ...@@ -878,6 +889,7 @@ struct e1000_hw {
e1000_bus_speed bus_speed; e1000_bus_speed bus_speed;
e1000_bus_width bus_width; e1000_bus_width bus_width;
e1000_bus_type bus_type; e1000_bus_type bus_type;
uint32_t io_base;
uint32_t phy_id; uint32_t phy_id;
uint32_t phy_addr; uint32_t phy_addr;
uint32_t original_fc; uint32_t original_fc;
...@@ -1333,6 +1345,7 @@ struct e1000_hw { ...@@ -1333,6 +1345,7 @@ struct e1000_hw {
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */ #define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
/* EEPROM Word Offsets */ /* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004 #define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_INIT_CONTROL1_REG 0x000A #define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_INIT_CONTROL2_REG 0x000F #define EEPROM_INIT_CONTROL2_REG 0x000F
...@@ -1356,6 +1369,10 @@ struct e1000_hw { ...@@ -1356,6 +1369,10 @@ struct e1000_hw {
#define ID_LED_OFF1_ON2 0x8 #define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9 #define ID_LED_OFF1_OFF2 0x9
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define EEPROM_COMPAT_SERVER 0x0400
#define EEPROM_COMPAT_CLIENT 0x0200
/* Mask bits for fields in Word 0x0a of the EEPROM */ /* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS 0x0010 #define EEPROM_WORD0A_ILOS 0x0010
#define EEPROM_WORD0A_SWDPIO 0x01E0 #define EEPROM_WORD0A_SWDPIO 0x01E0
......
...@@ -70,13 +70,35 @@ ...@@ -70,13 +70,35 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/ *******************************************************************************/
#define __E1000_MAIN__ #define __E1000_MAIN__
#include "e1000.h" #include "e1000.h"
/* Change Log
*
* 4.3.2 7/5/02
* o Bug fix: perform controller reset using I/O rather than mmio because
* some chipsets try to perform a 64-bit write, but the controller ignores
* the upper 32-bit write once the reset is intiated by the lower 32-bit
* write, causing a master abort.
* o Bug fix: fixed jumbo frames sized from 1514 to 2048.
* o ASF support: disable ARP when driver is loaded or resumed; enable when
* driver is removed or suspended.
* o Bug fix: changed default setting for RxIntDelay to 0 for 82542/3/4
* controllers to workaround h/w errata where controller will hang when
* RxIntDelay <> 0 under certian network conditions.
* o Clean up: removed unused and undocumented user-settable settings for
* PHY.
* o Bug fix: ethtool GEEPROM was using byte address rather than word
* addressing.
* o Feature: added support for ethtool SEEPROM.
* o Feature: added support for entropy pool.
*
* 4.2.17 5/30/02
*/
char e1000_driver_name[] = "e1000"; char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
char e1000_driver_version[] = "4.2.17-k1"; char e1000_driver_version[] = "4.3.2-k1";
char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation."; char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table /* e1000_pci_tbl - PCI Device ID Table
...@@ -156,7 +178,6 @@ static void e1000_set_multi(struct net_device *netdev); ...@@ -156,7 +178,6 @@ static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data); static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data); static void e1000_watchdog(unsigned long data);
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
static void e1000_tx_timeout(struct net_device *dev);
static struct net_device_stats * e1000_get_stats(struct net_device *netdev); static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
static int e1000_change_mtu(struct net_device *netdev, int new_mtu); static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
static int e1000_set_mac(struct net_device *netdev, void *p); static int e1000_set_mac(struct net_device *netdev, void *p);
...@@ -173,6 +194,8 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter); ...@@ -173,6 +194,8 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
static inline void e1000_rx_checksum(struct e1000_adapter *adapter, static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
struct e1000_rx_desc *rx_desc, struct e1000_rx_desc *rx_desc,
struct sk_buff *skb); struct sk_buff *skb);
static void e1000_tx_timeout(struct net_device *dev);
#ifdef NETIF_F_HW_VLAN_TX #ifdef NETIF_F_HW_VLAN_TX
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
...@@ -260,7 +283,7 @@ e1000_up(struct e1000_adapter *adapter) ...@@ -260,7 +283,7 @@ e1000_up(struct e1000_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ, if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
netdev->name, netdev)) netdev->name, netdev))
return -1; return -1;
...@@ -380,6 +403,15 @@ e1000_probe(struct pci_dev *pdev, ...@@ -380,6 +403,15 @@ e1000_probe(struct pci_dev *pdev,
if(!adapter->hw.hw_addr) if(!adapter->hw.hw_addr)
goto err_ioremap; goto err_ioremap;
for(i = BAR_1; i <= BAR_5; i++) {
if(pci_resource_len(pdev, i) == 0)
continue;
if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
adapter->hw.io_base = pci_resource_start(pdev, i);
break;
}
}
netdev->open = &e1000_open; netdev->open = &e1000_open;
netdev->stop = &e1000_close; netdev->stop = &e1000_close;
netdev->hard_start_xmit = &e1000_xmit_frame; netdev->hard_start_xmit = &e1000_xmit_frame;
...@@ -397,7 +429,8 @@ e1000_probe(struct pci_dev *pdev, ...@@ -397,7 +429,8 @@ e1000_probe(struct pci_dev *pdev,
#endif #endif
netdev->irq = pdev->irq; netdev->irq = pdev->irq;
netdev->base_addr = mmio_start; netdev->mem_start = mmio_start;
netdev->base_addr = adapter->hw.io_base;
adapter->bd_number = cards_found; adapter->bd_number = cards_found;
adapter->id_string = e1000_strings[ent->driver_data]; adapter->id_string = e1000_strings[ent->driver_data];
...@@ -509,6 +542,15 @@ e1000_remove(struct pci_dev *pdev) ...@@ -509,6 +542,15 @@ e1000_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t manc;
if(adapter->hw.mac_type >= e1000_82540) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if(manc & E1000_MANC_SMBUS_EN) {
manc |= E1000_MANC_ARP_EN;
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
}
unregister_netdev(netdev); unregister_netdev(netdev);
...@@ -630,6 +672,13 @@ e1000_sw_init(struct e1000_adapter *adapter) ...@@ -630,6 +672,13 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw->tbi_compatibility_en = TRUE; hw->tbi_compatibility_en = TRUE;
hw->adaptive_ifs = TRUE; hw->adaptive_ifs = TRUE;
/* Copper options */
if(hw->media_type == e1000_media_type_copper) {
hw->mdix = AUTO_ALL_MODES;
hw->disable_polarity_correction = FALSE;
}
atomic_set(&adapter->irq_sem, 1); atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->stats_lock); spin_lock_init(&adapter->stats_lock);
} }
...@@ -1525,7 +1574,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -1525,7 +1574,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL; return -EINVAL;
} }
if(max_frame <= E1000_RXBUFFER_2048) { if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) {
adapter->rx_buffer_len = E1000_RXBUFFER_2048; adapter->rx_buffer_len = E1000_RXBUFFER_2048;
} else if(adapter->hw.mac_type < e1000_82543) { } else if(adapter->hw.mac_type < e1000_82543) {
...@@ -2033,6 +2082,18 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) ...@@ -2033,6 +2082,18 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
pci_write_config_word(adapter->pdev, reg, *value); pci_write_config_word(adapter->pdev, reg, *value);
} }
uint32_t
e1000_io_read(struct e1000_hw *hw, uint32_t port)
{
return inl(port);
}
void
e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value)
{
outl(value, port);
}
#ifdef NETIF_F_HW_VLAN_TX #ifdef NETIF_F_HW_VLAN_TX
static void static void
e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
...@@ -2133,7 +2194,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -2133,7 +2194,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t ctrl, ctrl_ext, rctl; uint32_t ctrl, ctrl_ext, rctl, manc;
netif_device_detach(netdev); netif_device_detach(netdev);
...@@ -2171,6 +2232,14 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) ...@@ -2171,6 +2232,14 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
} }
pci_save_state(pdev, adapter->pci_state); pci_save_state(pdev, adapter->pci_state);
if(adapter->hw.mac_type >= e1000_82540) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if(manc & E1000_MANC_SMBUS_EN) {
manc |= E1000_MANC_ARP_EN;
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
} else
pci_set_power_state(pdev, 3); pci_set_power_state(pdev, 3);
return 0; return 0;
...@@ -2182,6 +2251,7 @@ e1000_resume(struct pci_dev *pdev) ...@@ -2182,6 +2251,7 @@ e1000_resume(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev->priv;
uint32_t manc;
pci_set_power_state(pdev, 0); pci_set_power_state(pdev, 0);
pci_restore_state(pdev, adapter->pci_state); pci_restore_state(pdev, adapter->pci_state);
...@@ -2196,6 +2266,12 @@ e1000_resume(struct pci_dev *pdev) ...@@ -2196,6 +2266,12 @@ e1000_resume(struct pci_dev *pdev)
netif_device_attach(netdev); netif_device_attach(netdev);
if(adapter->hw.mac_type >= e1000_82540) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc &= ~(E1000_MANC_ARP_EN);
E1000_WRITE_REG(&adapter->hw, MANC, manc);
}
return 0; return 0;
} }
#endif #endif
......
...@@ -196,38 +196,11 @@ E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); ...@@ -196,38 +196,11 @@ E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
* *
* Valid Range: 0-65535 * Valid Range: 0-65535
* *
* Default Value: 64/128 * Default Value: 0/128
*/ */
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
/* MDI-X Support Enable/Disable - Applies only to Copper PHY
*
* Valid Range: 0, 3
* - 0 - Auto in all modes
* - 1 - MDI
* - 2 - MDI-X
* - 3 - Auto in 1000 Base-T mode (MDI in 10 Base-T and 100 Base-T)
*
* Default Value: 0 (Auto)
*/
E1000_PARAM(MdiX, "Set MDI/MDI-X Mode");
/* Automatic Correction of Reversed Cable Polarity Enable/Disable
* This setting applies only to Copper PHY
*
* Valid Range: 0, 1
* - 0 - Disabled
* - 1 - Enabled
*
* Default Value: 1 (Enabled)
*/
E1000_PARAM(DisablePolarityCorrection,
"Disable or enable Automatic Correction for Reversed Cable Polarity");
#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
...@@ -242,16 +215,11 @@ E1000_PARAM(DisablePolarityCorrection, ...@@ -242,16 +215,11 @@ E1000_PARAM(DisablePolarityCorrection,
#define MIN_RXD 80 #define MIN_RXD 80
#define MAX_82544_RXD 4096 #define MAX_82544_RXD 4096
#define DEFAULT_RDTR 64 #define DEFAULT_RDTR 0
#define DEFAULT_RADV 128 #define DEFAULT_RADV 128
#define MAX_RXDELAY 0xFFFF #define MAX_RXDELAY 0xFFFF
#define MIN_RXDELAY 0 #define MIN_RXDELAY 0
#define DEFAULT_MDIX 0
#define MAX_MDIX 3
#define MIN_MDIX 0
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;
...@@ -646,36 +614,6 @@ e1000_check_copper_options(struct e1000_adapter *adapter) ...@@ -646,36 +614,6 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
BUG(); BUG();
} }
/* a few other copper only options */
{ /* MDI/MDI-X */
struct e1000_option opt = {
type: range_option,
name: "MDI/MDI-X",
err: "using default of " __MODULE_STRING(DEFAULT_MDIX),
def: DEFAULT_MDIX,
arg: { r: { min: MIN_MDIX, max: MAX_MDIX }}
};
int mdix = MdiX[bd];
e1000_validate_option(&mdix, &opt);
adapter->hw.mdix = mdix;
}
{ /* Automatic Correction for Reverse Cable Polarity */
/* option is actually to disable polarity correction,
* so setting to OPTION_ENABLED turns the hardware feature off */
struct e1000_option opt = {
type: enable_option,
name: "Disable Polarity Correction",
err: "defaulting to Disabled",
def: OPTION_DISABLED,
};
int dpc = DisablePolarityCorrection[bd];
e1000_validate_option(&dpc, &opt);
adapter->hw.disable_polarity_correction = dpc;
}
/* Speed, AutoNeg and MDI/MDI-X must all play nice */ /* Speed, AutoNeg and MDI/MDI-X must all play nice */
if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) { if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) {
printk(KERN_INFO "Speed, AutoNeg and MDI-X specifications are " printk(KERN_INFO "Speed, AutoNeg and MDI-X specifications are "
......
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