- 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:
parent
ef5def596d
commit
1d966d27b1
@ -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
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user