- Set RS (Report Status) bit on all descriptors of a packet instead of just the last one.

- Set RDTR to zero by default instead of 28.
- Fixed a problem with TX hangs with jumbo frames when number of fragments in the mbuf chain
is large.
- Added support for 82540EP based cards.

MFC after:	3 days
This commit is contained in:
Prafulla Deuskar 2002-11-08 18:14:17 +00:00
parent ef5def596d
commit 1d966d27b1
6 changed files with 765 additions and 517 deletions

View File

@ -2,7 +2,7 @@ $FreeBSD$
FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters
============================================================
July 2, 2002
September 11, 2002
Contents
@ -21,7 +21,7 @@ Contents
In This Release
===============
This file describes the FreeBSD* driver, version 1.3.x, for the Intel(R)
This file describes the FreeBSD* driver, version 1.4.x, for the Intel(R)
PRO/1000 Family of Adapters. This driver has been developed for use with
FreeBSD, version 4.6. As a new feature for this release, the driver is now
compiled by default into the FreeBSD 4.6 kernel.
@ -155,7 +155,7 @@ NOTE: You must have kernel sources installed in order to compile the driver
Remove the following lines from the /usr/src/sys/conf/files.i386 file, if
they exist:
/dev/em/if_em_fxhw.c optional em
/dev/em/if_em_fx_hw.c optional em
/dev/em/if_em_phy.c optional em
Compile and install the kernel.

File diff suppressed because it is too large Load Diff

View File

@ -75,23 +75,129 @@ POSSIBILITY OF SUCH DAMAGE.
#include <dev/em/if_em_hw.h>
/* Tunables */
#define MAX_TXD 256
#define MAX_RXD 256
#define TX_CLEANUP_THRESHOLD MAX_TXD / 8
#define TIDV 128
#define RIDV 28
#define DO_AUTO_NEG 1
#define WAIT_FOR_AUTO_NEG_DEFAULT 1
/* Tunables -- Begin */
/*
* FlowControl
* Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
* Default: Read flow control settings from the EEPROM
* This parameter controls the automatic generation(Tx) and response(Rx) to
* Ethernet PAUSE frames.
*/
/*
* TxDescriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
* 80-4096 for 82540, 82544, 82545, and 82546-based adapters
* Default Value: 256
* This value is the number of transmit descriptors allocated by the driver.
* Increasing this value allows the driver to queue more transmits. Each
* descriptor is 16 bytes.
*/
#define EM_MAX_TXD 256
/*
* RxDescriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
* 80-4096 for 82540, 82544, 82545, and 82546-based adapters
* Default Value: 256
* This value is the number of receive descriptors allocated by the driver.
* Increasing this value allows the driver to buffer more incoming packets.
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
* descriptor. The maximum MTU size is 16110.
*
*/
#define EM_MAX_RXD 256
/*
* TxIntDelay
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value delays the generation of transmit interrupts in units of
* 1.024 microseconds. Transmit interrupt reduction can improve CPU
* efficiency if properly tuned for specific network traffic. If the
* system is reporting dropped transmits, this value may be set too high
* causing the driver to run out of available transmit descriptors.
*/
#define EM_TIDV 128
/*
* RxIntDelay
* Valid Range: 0-65535 (0=off)
* Default Value: 0
* This value delays the generation of receive interrupts in units of 1.024
* microseconds. Receive interrupt reduction can improve CPU efficiency if
* properly tuned for specific network traffic. Increasing this value adds
* extra latency to frame reception and can end up decreasing the throughput
* of TCP traffic. If the system is reporting dropped receives, this value
* may be set too high, causing the driver to run out of available receive
* descriptors.
*
* CAUTION: When setting RxIntDelay to a value other than 0, adapters
* may hang (stop transmitting) under certain network conditions.
* If this occurs a WATCHDOG 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.
*/
#define EM_RDTR 0
/*
* This parameter controls the maximum no of times the driver will loop
* in the isr.
* Minimum Value = 1
*/
#define EM_MAX_INTR 3
/*
* This parameter determines when the hardware will report that it is
* done with the packet.
* 0 - "Done" is reported when the packet has been sent on the wire
* 1 - "Done" is reported when the packet has been DMA'ed and is on chip.
* 2 - Determine the best method.
*/
#define EM_REPORT_TX_EARLY 2
/*
* Inform the stack about transmit checksum offload capabilities.
*/
#define EM_CHECKSUM_FEATURES (CSUM_TCP | CSUM_UDP)
/*
* This parameter controls the duration of transmit watchdog timer.
*/
#define EM_TX_TIMEOUT 5 /* set to 5 seconds */
/*
* This parameter controls when the driver calls the routine to reclaim
* transmit descriptors.
*/
#define EM_TX_CLEANUP_THRESHOLD EM_MAX_TXD / 8
/*
* This parameter controls whether or not autonegotation is enabled.
* 0 - Disable autonegotiation
* 1 - Enable autonegotiation
*/
#define DO_AUTO_NEG 1
/*
* This parameter control whether or not the driver will wait for
* autonegotiation to complete.
* 1 - Wait for autonegotiation to complete
* 0 - Don't wait for autonegotiation to complete
*/
#define WAIT_FOR_AUTO_NEG_DEFAULT 1
/* Tunables -- End */
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define EM_REPORT_TX_EARLY 2
#define EM_CHECKSUM_FEATURES (CSUM_TCP | CSUM_UDP)
#define EM_MAX_INTR 3
#define EM_TX_TIMEOUT 5 /* set to 5 seconds */
#define EM_VENDOR_ID 0x8086
#define EM_MMBA 0x0010 /* Mem base address */
#define EM_ROUNDUP(size, unit) (((size) + (unit) - 1) & ~((unit) - 1))
@ -138,8 +244,7 @@ POSSIBILITY OF SUCH DAMAGE.
* should load.
*
* ******************************************************************************/
typedef struct _em_vendor_info_t
{
typedef struct _em_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
unsigned int subvendor_id;
@ -151,10 +256,9 @@ typedef struct _em_vendor_info_t
struct em_tx_buffer {
STAILQ_ENTRY(em_tx_buffer) em_tx_entry;
struct mbuf *m_head;
u_int32_t num_tx_desc_used;
struct em_tx_desc *used_tx_desc;
};
/* ******************************************************************************
* This structure stores information about the 2k aligned receive buffer
* into which the E1000 DMA's frames.
@ -204,7 +308,6 @@ struct adapter {
struct em_tx_desc *first_tx_desc;
struct em_tx_desc *last_tx_desc;
struct em_tx_desc *next_avail_tx_desc;
struct em_tx_desc *oldest_used_tx_desc;
struct em_tx_desc *tx_desc_base;
volatile u_int16_t num_tx_desc_avail;
u_int16_t num_tx_desc;
@ -232,8 +335,8 @@ struct adapter {
unsigned long dropped_pkts;
unsigned long mbuf_alloc_failed;
unsigned long mbuf_cluster_failed;
unsigned long xmit_pullup;
unsigned long no_tx_desc_avail;
unsigned long no_tx_desc_avail1;
unsigned long no_tx_desc_avail2;
unsigned long no_tx_buffer_avail1;
unsigned long no_tx_buffer_avail2;
#ifdef DBG_STATS

View File

@ -53,9 +53,71 @@ static void em_lower_ee_clk(struct em_hw *hw, uint32_t *eecd);
static void em_shift_out_ee_bits(struct em_hw *hw, uint16_t data, uint16_t count);
static uint16_t em_shift_in_ee_bits(struct em_hw *hw);
static void em_setup_eeprom(struct em_hw *hw);
static void em_clock_eeprom(struct em_hw *hw);
static void em_cleanup_eeprom(struct em_hw *hw);
static void em_standby_eeprom(struct em_hw *hw);
static int32_t em_id_led_init(struct em_hw * hw);
/******************************************************************************
* Set the mac type member in the hw struct.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
int32_t
em_set_mac_type(struct em_hw *hw)
{
DEBUGFUNC("em_set_mac_type");
switch (hw->device_id) {
case E1000_DEV_ID_82542:
switch (hw->revision_id) {
case E1000_82542_2_0_REV_ID:
hw->mac_type = em_82542_rev2_0;
break;
case E1000_82542_2_1_REV_ID:
hw->mac_type = em_82542_rev2_1;
break;
default:
/* Invalid 82542 revision ID */
return -E1000_ERR_MAC_TYPE;
}
break;
case E1000_DEV_ID_82543GC_FIBER:
case E1000_DEV_ID_82543GC_COPPER:
hw->mac_type = em_82543;
break;
case E1000_DEV_ID_82544EI_COPPER:
case E1000_DEV_ID_82544EI_FIBER:
case E1000_DEV_ID_82544GC_COPPER:
case E1000_DEV_ID_82544GC_LOM:
hw->mac_type = em_82544;
break;
case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82540EP:
case E1000_DEV_ID_82540EP_LOM:
case E1000_DEV_ID_82540EP_LP:
hw->mac_type = em_82540;
break;
case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82545EM_FIBER:
hw->mac_type = em_82545;
break;
case E1000_DEV_ID_82546EB_COPPER:
case E1000_DEV_ID_82546EB_FIBER:
hw->mac_type = em_82546;
break;
default:
/* Should never have loaded on this device */
return -E1000_ERR_MAC_TYPE;
}
return E1000_SUCCESS;
}
/******************************************************************************
* Reset the transmit and receive units; mask and clear all interrupts.
*
@ -68,17 +130,13 @@ em_reset_hw(struct em_hw *hw)
uint32_t ctrl_ext;
uint32_t icr;
uint32_t manc;
uint16_t pci_cmd_word;
DEBUGFUNC("em_reset_hw");
/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
if(hw->mac_type == em_82542_rev2_0) {
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
em_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);
}
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
em_pci_clear_mwi(hw);
}
/* Clear interrupt mask to stop board from generating interrupts */
@ -91,6 +149,7 @@ em_reset_hw(struct em_hw *hw)
*/
E1000_WRITE_REG(hw, RCTL, 0);
E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw);
/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
hw->tbi_compatibility_on = FALSE;
@ -120,6 +179,7 @@ em_reset_hw(struct em_hw *hw)
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
/* Wait for EEPROM reload */
msec_delay(2);
} else {
@ -141,7 +201,7 @@ em_reset_hw(struct em_hw *hw)
/* If MWI was previously enabled, reenable it. */
if(hw->mac_type == em_82542_rev2_0) {
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
em_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);
em_pci_set_mwi(hw);
}
}
@ -162,7 +222,6 @@ em_init_hw(struct em_hw *hw)
uint32_t ctrl, status;
uint32_t i;
int32_t ret_val;
uint16_t pci_cmd_word;
uint16_t pcix_cmd_word;
uint16_t pcix_stat_hi_word;
uint16_t cmd_mmrbc;
@ -205,12 +264,10 @@ em_init_hw(struct em_hw *hw)
/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
if(hw->mac_type == em_82542_rev2_0) {
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
em_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);
}
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
em_pci_clear_mwi(hw);
E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
E1000_WRITE_FLUSH(hw);
msec_delay(5);
}
@ -222,9 +279,10 @@ em_init_hw(struct em_hw *hw)
/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
if(hw->mac_type == em_82542_rev2_0) {
E1000_WRITE_REG(hw, RCTL, 0);
E1000_WRITE_FLUSH(hw);
msec_delay(1);
if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
em_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);
em_pci_set_mwi(hw);
}
/* Zero out the Multicast HASH table */
@ -249,6 +307,8 @@ em_init_hw(struct em_hw *hw)
PCIX_COMMAND_MMRBC_SHIFT;
stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
PCIX_STATUS_HI_MMRBC_SHIFT;
if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
if(cmd_mmrbc > stat_mmrbc) {
pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
@ -259,6 +319,13 @@ em_init_hw(struct em_hw *hw)
/* Call a subroutine to configure the link and setup flow control. */
ret_val = em_setup_link(hw);
/* Set the transmit descriptor write-back policy */
if(hw->mac_type > em_82544) {
ctrl = E1000_READ_REG(hw, TXDCTL);
ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
E1000_WRITE_REG(hw, TXDCTL, ctrl);
}
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
@ -384,7 +451,6 @@ em_setup_link(struct em_hw *hw)
* Sets up link for a fiber based adapter
*
* hw - Struct containing variables accessed by shared code
* ctrl - Current value of the device control register
*
* Manipulates Physical Coding Sublayer functions in order to configure
* link. Assumes the hardware has been previously reset and the transmitter
@ -470,6 +536,7 @@ em_setup_fiber_link(struct em_hw *hw)
E1000_WRITE_REG(hw, TXCW, txcw);
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
hw->txcw = txcw;
msec_delay(1);
@ -514,7 +581,6 @@ em_setup_fiber_link(struct em_hw *hw)
* Detects which PHY is present and the speed and duplex
*
* hw - Struct containing variables accessed by shared code
* ctrl - current value of the device control register
******************************************************************************/
static int32_t
em_setup_copper_link(struct em_hw *hw)
@ -603,14 +669,17 @@ em_setup_copper_link(struct em_hw *hw)
return -E1000_ERR_PHY;
}
phy_data |= M88E1000_EPSCR_TX_CLK_25;
/* Configure Master and Slave downshift values */
phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
if(em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
if (hw->phy_revision < M88E1011_I_REV_4) {
/* Configure Master and Slave downshift values */
phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
if(em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
}
}
/* SW Reset the PHY so all changes take effect */
@ -956,7 +1025,6 @@ em_phy_force_speed_duplex(struct em_hw *hw)
/* Write the configured values back to the Device Control Reg. */
E1000_WRITE_REG(hw, CTRL, ctrl);
/* Write the MII Control Register with the new PHY configuration. */
if(em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
@ -971,9 +1039,11 @@ em_phy_force_speed_duplex(struct em_hw *hw)
return -E1000_ERR_PHY;
}
DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
/* Need to reset the PHY or these changes will be ignored */
mii_ctrl_reg |= MII_CR_RESET;
/* Write back the modified PHY MII control register. */
if(em_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
DEBUGOUT("PHY Write Error\n");
return -E1000_ERR_PHY;
@ -1083,6 +1153,7 @@ em_config_collision_dist(struct em_hw *hw)
tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
E1000_WRITE_REG(hw, TCTL, tctl);
E1000_WRITE_FLUSH(hw);
}
/******************************************************************************
@ -1680,6 +1751,7 @@ em_raise_mdi_clk(struct em_hw *hw,
* bit), and then delay 2 microseconds.
*/
E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
E1000_WRITE_FLUSH(hw);
usec_delay(2);
}
@ -1697,6 +1769,7 @@ em_lower_mdi_clk(struct em_hw *hw,
* bit), and then delay 2 microseconds.
*/
E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
E1000_WRITE_FLUSH(hw);
usec_delay(2);
}
@ -1739,6 +1812,7 @@ em_shift_out_mdi_bits(struct em_hw *hw,
else ctrl &= ~E1000_CTRL_MDIO;
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
usec_delay(2);
@ -1747,9 +1821,6 @@ em_shift_out_mdi_bits(struct em_hw *hw,
mask = mask >> 1;
}
/* Clear the data bit just before leaving this routine. */
ctrl &= ~E1000_CTRL_MDIO;
}
/******************************************************************************
@ -1780,6 +1851,7 @@ em_shift_in_mdi_bits(struct em_hw *hw)
ctrl &= ~E1000_CTRL_MDIO;
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
/* Raise and Lower the clock before reading in the data. This accounts for
* the turnaround bits. The first clock occurred when we clocked out the
@ -1800,9 +1872,6 @@ em_shift_in_mdi_bits(struct em_hw *hw)
em_raise_mdi_clk(hw, &ctrl);
em_lower_mdi_clk(hw, &ctrl);
/* Clear the MDIO bit just before leaving this routine. */
ctrl &= ~E1000_CTRL_MDIO;
return data;
}
@ -1976,8 +2045,10 @@ em_phy_hw_reset(struct em_hw *hw)
*/
ctrl = E1000_READ_REG(hw, CTRL);
E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
E1000_WRITE_FLUSH(hw);
msec_delay(10);
E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
} else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
* bit to put the PHY into reset. Then, take it out of reset.
@ -1986,9 +2057,11 @@ em_phy_hw_reset(struct em_hw *hw)
ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
msec_delay(10);
ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
}
usec_delay(150);
}
@ -2045,7 +2118,8 @@ em_detect_gig_phy(struct em_hw *hw)
return -E1000_ERR_PHY;
}
hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
switch(hw->mac_type) {
case em_82543:
if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
@ -2176,6 +2250,8 @@ em_validate_mdi_setting(struct em_hw *hw)
return 0;
}
/******************************************************************************
* Raises the EEPROM's clock input.
*
@ -2187,10 +2263,11 @@ em_raise_ee_clk(struct em_hw *hw,
uint32_t *eecd)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait 50 microseconds.
* wait <delay> microseconds.
*/
*eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
@ -2209,6 +2286,7 @@ em_lower_ee_clk(struct em_hw *hw,
*/
*eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
@ -2246,6 +2324,7 @@ em_shift_out_ee_bits(struct em_hw *hw,
eecd |= E1000_EECD_DI;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
@ -2273,11 +2352,11 @@ em_shift_in_ee_bits(struct em_hw *hw)
uint32_t i;
uint16_t data;
/* In order to read a register from the EEPROM, we need to shift 16 bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the "DO"
* bit. During this "shifting in" process the "DI" bit should always be
* clear..
/* In order to read a register from the EEPROM, we need to shift 'count'
* bits in from the EEPROM. Bits are "shifted in" by raising the clock
* input to the EEPROM (setting the SK bit), and then reading the value of
* the "DO" bit. During this "shifting in" process the "DI" bit should
* always be clear.
*/
eecd = E1000_READ_REG(hw, EECD);
@ -2340,21 +2419,25 @@ em_standby_eeprom(struct em_hw *hw)
/* Deselct EEPROM */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Clock high */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Select EEPROM */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Clock low */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
@ -2373,11 +2456,13 @@ em_clock_eeprom(struct em_hw *hw)
/* Rising edge of clock */
eecd |= E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
/* Falling edge of clock */
eecd &= ~E1000_EECD_SK;
E1000_WRITE_REG(hw, EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(50);
}
@ -3076,6 +3161,9 @@ em_setup_led(struct em_hw *hw)
ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT);
E1000_WRITE_REG(hw, LEDCTL, ledctl);
break;
case E1000_DEV_ID_82540EP:
case E1000_DEV_ID_82540EP_LOM:
case E1000_DEV_ID_82540EP_LP:
case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER:
@ -3109,6 +3197,9 @@ em_cleanup_led(struct em_hw *hw)
case E1000_DEV_ID_82544GC_LOM:
/* No cleanup necessary */
break;
case E1000_DEV_ID_82540EP:
case E1000_DEV_ID_82540EP_LOM:
case E1000_DEV_ID_82540EP_LP:
case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER:
@ -3159,6 +3250,9 @@ em_led_on(struct em_hw *hw)
ctrl |= E1000_CTRL_SWDPIO0;
E1000_WRITE_REG(hw, CTRL, ctrl);
break;
case E1000_DEV_ID_82540EP:
case E1000_DEV_ID_82540EP_LOM:
case E1000_DEV_ID_82540EP_LP:
case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER:
@ -3206,6 +3300,9 @@ em_led_off(struct em_hw *hw)
ctrl |= E1000_CTRL_SWDPIO0;
E1000_WRITE_REG(hw, CTRL, ctrl);
break;
case E1000_DEV_ID_82540EP:
case E1000_DEV_ID_82540EP_LOM:
case E1000_DEV_ID_82540EP_LP:
case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82540EM_LOM:
case E1000_DEV_ID_82545EM_COPPER:

View File

@ -48,7 +48,8 @@ struct em_hw_stats;
/* Enumerated types specific to the e1000 hardware */
/* Media Access Controlers */
typedef enum {
em_82542_rev2_0 = 0,
em_undefined = 0,
em_82542_rev2_0,
em_82542_rev2_1,
em_82543,
em_82544,
@ -58,6 +59,7 @@ typedef enum {
em_num_macs
} em_mac_type;
/* Media Types */
typedef enum {
em_media_type_copper = 0,
@ -127,6 +129,7 @@ typedef enum {
em_rev_polarity_undefined = 0xFF
} em_rev_polarity;
typedef enum {
em_polarity_reversal_enabled = 0,
em_polarity_reversal_disabled,
@ -147,6 +150,7 @@ typedef enum {
em_1000t_rx_status_undefined = 0xFF
} em_1000t_rx_status;
struct em_phy_info {
em_cable_length cable_length;
em_10bt_ext_dist_enable extended_10bt_distance;
@ -165,16 +169,18 @@ struct em_phy_stats {
/* Error Codes */
#define E1000_SUCCESS 0
#define E1000_ERR_EEPROM 1
#define E1000_ERR_PHY 2
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_SUCCESS 0
#define E1000_ERR_EEPROM 1
#define E1000_ERR_PHY 2
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_TYPE 5
/* Function prototypes */
/* Initialization */
void em_reset_hw(struct em_hw *hw);
int32_t em_init_hw(struct em_hw *hw);
int32_t em_set_mac_type(struct em_hw *hw);
/* Link Configuration */
int32_t em_setup_link(struct em_hw *hw);
@ -225,6 +231,8 @@ void em_reset_adaptive(struct em_hw *hw);
void em_update_adaptive(struct em_hw *hw);
void em_tbi_adjust_stats(struct em_hw *hw, struct em_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
void em_get_bus_info(struct em_hw *hw);
void em_pci_set_mwi(struct em_hw *hw);
void em_pci_clear_mwi(struct em_hw *hw);
void em_read_pci_cfg(struct em_hw *hw, uint32_t reg, uint16_t * value);
void em_write_pci_cfg(struct em_hw *hw, uint32_t reg, uint16_t * value);
/* Port I/O is only supported on 82544 and newer */
@ -232,26 +240,30 @@ uint32_t em_io_read(struct em_hw *hw, uint32_t port);
uint32_t em_read_reg_io(struct em_hw *hw, uint32_t offset);
void em_io_write(struct em_hw *hw, uint32_t port, uint32_t value);
void em_write_reg_io(struct em_hw *hw, uint32_t offset, uint32_t value);
#define E1000_READ_REG_IO(a, reg) \
em_read_reg_io((a), E1000_##reg)
#define E1000_WRITE_REG_IO(a, reg, val) \
em_write_reg_io((a), E1000_##reg, val)
/* PCI Device IDs */
#define E1000_DEV_ID_82542 0x1000
#define E1000_DEV_ID_82543GC_FIBER 0x1001
#define E1000_DEV_ID_82543GC_COPPER 0x1004
#define E1000_DEV_ID_82544EI_COPPER 0x1008
#define E1000_DEV_ID_82544EI_FIBER 0x1009
#define E1000_DEV_ID_82544GC_COPPER 0x100C
#define E1000_DEV_ID_82544GC_LOM 0x100D
#define E1000_DEV_ID_82540EM 0x100E
#define E1000_DEV_ID_82540EM_LOM 0x1015
#define E1000_DEV_ID_82545EM_COPPER 0x100F
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define NUM_DEV_IDS 13
#define E1000_DEV_ID_82542 0x1000
#define E1000_DEV_ID_82543GC_FIBER 0x1001
#define E1000_DEV_ID_82543GC_COPPER 0x1004
#define E1000_DEV_ID_82544EI_COPPER 0x1008
#define E1000_DEV_ID_82544EI_FIBER 0x1009
#define E1000_DEV_ID_82544GC_COPPER 0x100C
#define E1000_DEV_ID_82544GC_LOM 0x100D
#define E1000_DEV_ID_82540EM 0x100E
#define E1000_DEV_ID_82540EM_LOM 0x1015
#define E1000_DEV_ID_82540EP_LOM 0x1016
#define E1000_DEV_ID_82540EP 0x1017
#define E1000_DEV_ID_82540EP_LP 0x101E
#define E1000_DEV_ID_82545EM_COPPER 0x100F
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define NUM_DEV_IDS 16
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
@ -852,6 +864,7 @@ struct em_hw {
em_bus_type bus_type;
uint32_t io_base;
uint32_t phy_id;
uint32_t phy_revision;
uint32_t phy_addr;
uint32_t original_fc;
uint32_t txcw;
@ -981,6 +994,7 @@ struct em_hw {
#define E1000_EERD_DATA_SHIFT 16
#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */
/* Extended Device Control */
#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
@ -1189,6 +1203,7 @@ struct em_hw {
#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */
#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
/* Transmit Configuration Word */
#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
@ -1428,6 +1443,8 @@ struct em_hw {
#define PCIX_COMMAND_MMRBC_SHIFT 0x2
#define PCIX_STATUS_HI_MMRBC_MASK 0x0060
#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5
#define PCIX_STATUS_HI_MMRBC_4K 0x3
#define PCIX_STATUS_HI_MMRBC_2K 0x2
/* The number of bits that we need to shift right to move the "pause"
@ -1541,6 +1558,7 @@ struct em_hw {
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
/* PHY Control Register */
@ -1747,12 +1765,14 @@ struct em_hw {
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
/* Bit definitions for valid PHY IDs. */
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
#define M88E1011_I_REV_4 0x04
/* Miscellaneous PHY bit definitions. */
#define PHY_PREAMBLE 0xFFFFFFFF

View File

@ -89,6 +89,8 @@ struct em_osdep
struct device *dev;
};
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
#define E1000_READ_REG(a, reg) (\
((a)->mac_type >= em_82543) ? \
bus_space_read_4( ((struct em_osdep *)(a)->back)->mem_bus_space_tag, \