Commit c0e1c9e4 authored by Scott Feldman's avatar Scott Feldman Committed by David Mosberger

Update e100 net driver:

o Added device ID support for Dell LOM.
o Added device ID support for 82511QM mobile nics.
o Bug fix: ethtool get/set EEPROM routines modified to use byte
  addressing rather than word addressing.
o Feature: added MDIX mode support for 82550 and up.
o Bug fix: added reboot notifier to setup WOL settings when
  shutting system down.
o Cleanup: removed yield() redefinition (Andrew Morton,
  akpm@zip.com.au).
o Bug fix: flow control now working when link partner is
  autoneg capable but not flow control capable.
o Bug fix: added check for corrupted EEPROM
o Bug fix: don't report checksum offloading for the older
  controllers that don't support the feature.
o Bug fix: calculate cable diagnostics when link goes down
  rather than when queuering /proc file.
o Cleanup: move mdi_access_lock to local get/set mdi routines.
parent f54cb1a1
......@@ -91,6 +91,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <linux/version.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/reboot.h>
#include <asm/io.h>
#include <asm/unaligned.h>
#include <asm/processor.h>
......@@ -147,6 +148,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define E100_MAX_SCB_WAIT 100 /* Max udelays in wait_scb */
#define E100_MAX_CU_IDLE_WAIT 50 /* Max udelays in wait_cus_idle */
/* HWI feature related constant */
#define HWI_MAX_LOOP 100
#define MAX_SAME_RESULTS 3
#define HWI_REGISTER_GRANULARITY 80 /* register granularity = 80 Cm */
#define HWI_NEAR_END_BOUNDARY 1000 /* Near end is defined as < 10 meters */
/* CPUSAVER_BUNDLE_MAX: Sets the maximum number of frames that will be bundled.
* In some situations, such as the TCP windowing algorithm, it may be
* better to limit the growth of the bundle size than let it go as
......@@ -504,6 +511,7 @@ enum led_state_e {
#define IS_ICH 0x00000020
#define DF_SPEED_FORCED 0x00000040 /* set if speed is forced */
#define LED_IS_ON 0x00000080 /* LED is turned ON by the driver */
#define DF_LINK_FC_TX_ONLY 0x00000100 /* Received PAUSE frames are honored*/
typedef struct net_device_stats net_dev_stats_t;
......@@ -987,6 +995,18 @@ struct e100_private {
rwlock_t isolate_lock;
int driver_isolated;
char *id_string;
char *cable_status;
char *mdix_status;
/* Variables for HWI */
int saved_open_circut;
int saved_short_circut;
int saved_distance;
int saved_i;
int saved_same;
unsigned char hwi_started;
struct timer_list hwi_timer; /* hwi timer id */
u32 speed_duplex_caps; /* adapter's speed/duplex capabilities */
......
......@@ -86,10 +86,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* operating system. *
* *
**********************************************************************/
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#endif
#include "e100_config.h"
static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
......@@ -308,85 +304,58 @@ e100_config(struct e100_private *bdp)
/**
* e100_config_fc - config flow-control state
* @bdp: atapter's private data struct
* @bdp: adapter's private data struct
*
* This routine will enable or disable flow control support in the adapter's
* config block. Flow control will be enable only if requested using the command
* line option, and if the link is flow-contorl capable (both us and the link
* partner).
*
* Returns:
* true: if then option was indeed changed
* false: if no change was needed
* partner). But, if link partner is capable of autoneg, but not capable of
* flow control, received PAUSE frames are still honored.
*/
unsigned char
void
e100_config_fc(struct e100_private *bdp)
{
unsigned char enable = false;
unsigned char changed = false;
/* 82557 doesn't support fc. Don't touch this option */
if (!(bdp->flags & IS_BACHELOR))
return false;
return;
/* Enable fc if requested and if the link supports it */
if ((bdp->params.b_params & PRM_FC) && (bdp->flags & DF_LINK_FC_CAP)) {
if ((bdp->params.b_params & PRM_FC) && (bdp->flags &
(DF_LINK_FC_CAP | DF_LINK_FC_TX_ONLY))) {
enable = true;
}
spin_lock_bh(&(bdp->config_lock));
if (enable) {
if (bdp->config[16] != DFLT_FC_DELAY_LSB) {
if (bdp->flags & DF_LINK_FC_TX_ONLY) {
/* If link partner is capable of autoneg, but */
/* not capable of flow control, Received PAUSE */
/* frames are still honored, i.e., */
/* transmitted frames would be paused by */
/* incoming PAUSE frames */
bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
bdp->config[19] &= ~(CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART);
bdp->config[19] |= CB_CFIG_FC_REJECT;
bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
} else {
bdp->config[16] = DFLT_FC_DELAY_LSB;
E100_CONFIG(bdp, 16);
changed = true;
}
if (bdp->config[17] != DFLT_FC_DELAY_LSB) {
bdp->config[17] = DFLT_FC_DELAY_MSB;
E100_CONFIG(bdp, 17);
changed = true;
}
/* check if *all* fc config options were already set */
if (((bdp->config[19] & CB_CFIG_FC_OPTS) != CB_CFIG_FC_OPTS) ||
(bdp->config[19] & CB_CFIG_TX_FC_DIS)) {
bdp->config[19] |= CB_CFIG_FC_OPTS;
bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
E100_CONFIG(bdp, 19);
changed = true;
}
} else {
if (bdp->config[16] != DFLT_NO_FC_DELAY_LSB) {
bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
E100_CONFIG(bdp, 16);
changed = true;
}
if (bdp->config[17] != DFLT_NO_FC_DELAY_MSB) {
bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
E100_CONFIG(bdp, 17);
changed = true;
}
/* check if *any* fc config options was already set */
if ((bdp->config[19] & CB_CFIG_FC_OPTS) ||
!(bdp->config[19] & CB_CFIG_TX_FC_DIS)) {
bdp->config[19] &= ~CB_CFIG_FC_OPTS;
bdp->config[19] |= CB_CFIG_TX_FC_DIS;
E100_CONFIG(bdp, 19);
changed = true;
}
bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
bdp->config[19] &= ~CB_CFIG_FC_OPTS;
bdp->config[19] |= CB_CFIG_TX_FC_DIS;
}
E100_CONFIG(bdp, 19);
spin_unlock_bh(&(bdp->config_lock));
return changed;
return;
}
/**
......
......@@ -198,7 +198,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern void e100_config_init(struct e100_private *bdp);
extern unsigned char e100_force_config(struct e100_private *bdp);
extern unsigned char e100_config(struct e100_private *bdp);
extern unsigned char e100_config_fc(struct e100_private *bdp);
extern void e100_config_fc(struct e100_private *bdp);
extern void e100_config_promisc(struct e100_private *bdp, unsigned char enable);
extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
extern void e100_config_mulcast_enbl(struct e100_private *bdp,
......
This diff is collapsed.
......@@ -96,6 +96,7 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
int e100_retry;
u32 temp_val;
spin_lock_bh(&bdp->mdi_access_lock);
temp_val = (((u32) data) | (reg_addr << 16) |
(phy_addr << 21) | (MDI_WRITE << 26));
writel(temp_val, &bdp->scb->scb_mdi_cntrl);
......@@ -111,6 +112,7 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
udelay(20);
e100_retry--;
}
spin_unlock_bh(&bdp->mdi_access_lock);
}
/*
......@@ -138,6 +140,7 @@ e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
int e100_retry;
u32 temp_val;
spin_lock_bh(&bdp->mdi_access_lock);
/* Issue the read command to the MDI control register. */
temp_val = ((reg_addr << 16) | (phy_addr << 21) | (MDI_READ << 26));
writel(temp_val, &bdp->scb->scb_mdi_cntrl);
......@@ -156,6 +159,7 @@ e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
// return the lower word
*data = (u16) readl(&bdp->scb->scb_mdi_cntrl);
spin_unlock_bh(&bdp->mdi_access_lock);
}
static unsigned char __devinit
......@@ -657,8 +661,6 @@ e100_force_speed_duplex(struct e100_private *bdp)
bdp->flags |= DF_SPEED_FORCED;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
control &= ~BMCR_ANENABLE;
......@@ -702,14 +704,10 @@ e100_force_speed_duplex(struct e100_private *bdp)
time_after(jiffies, expires)) {
break;
} else {
spin_unlock_bh(&(bdp->mdi_access_lock));
yield();
spin_lock_bh(&(bdp->mdi_access_lock));
}
} while (true);
spin_unlock_bh(&(bdp->mdi_access_lock));
}
/*
......@@ -753,7 +751,12 @@ e100_set_fc(struct e100_private *bdp)
if (ad_reg & NWAY_AD_FC_SUPPORTED)
bdp->flags |= DF_LINK_FC_CAP;
else
bdp->flags &= ~DF_LINK_FC_CAP;
/* If link partner is capable of autoneg, but */
/* not capable of flow control, Received PAUSE */
/* frames are still honored, i.e., */
/* transmitted frames would be paused */
/* by incoming PAUSE frames */
bdp->flags |= DF_LINK_FC_TX_ONLY;
} else {
bdp->flags &= ~DF_LINK_FC_CAP;
......@@ -821,8 +824,6 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
bdp->flags &= ~DF_SPEED_FORCED;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
......@@ -848,25 +849,30 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
time_after(jiffies, expires) ) {
goto exit;
} else {
spin_unlock_bh(&(bdp->mdi_access_lock));
yield();
spin_lock_bh(&(bdp->mdi_access_lock));
}
} while (true);
}
exit:
e100_find_speed_duplex(bdp);
spin_unlock_bh(&(bdp->mdi_access_lock));
}
void
e100_phy_set_speed_duplex(struct e100_private *bdp, unsigned char force_restart)
{
if (bdp->params.e100_speed_duplex == E100_AUTONEG) {
if (bdp->rev_id >= D102_REV_ID)
/* Enable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_AUTO_SWITCH_ENABLE);
e100_auto_neg(bdp, force_restart);
} else {
if (bdp->rev_id >= D102_REV_ID)
/* Disable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_RESET_ALL_MASK);
e100_force_speed_duplex(bdp);
}
......
......@@ -124,6 +124,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define NSC_CONG_CONTROL_REG 0x17 /* National (TX) congestion control */
#define NSC_SPEED_IND_REG 0x19 /* National (TX) speed indication */
#define HWI_CONTROL_REG 0x1D /* HWI Control register */
/* MDI/MDI-X Control Register bit definitions */
#define MDI_MDIX_RES_TIMER BIT_0_3 /* minimum slot time for resolution timer */
#define MDI_MDIX_CONFIG_IS_OK BIT_4 /* 1 = resolution algorithm completes OK */
#define MDI_MDIX_STATUS BIT_5 /* 1 = MDIX (croos over), 0 = MDI (straight through) */
#define MDI_MDIX_SWITCH BIT_6 /* 1 = Forces to MDIX, 0 = Forces to MDI */
#define MDI_MDIX_AUTO_SWITCH_ENABLE BIT_7 /* 1 = MDI/MDI-X feature enabled */
#define MDI_MDIX_CONCT_CONFIG BIT_8 /* Sets the MDI/MDI-X connectivity configuration (test prupose only) */
#define MDI_MDIX_CONCT_TEST_ENABLE BIT_9 /* 1 = Enables connectivity testing */
#define MDI_MDIX_RESET_ALL_MASK 0x0000
/* HWI Control Register bit definitions */
#define HWI_TEST_DISTANCE BIT_0_8 /* distance to cable problem */
#define HWI_TEST_HIGHZ_PROBLEM BIT_9 /* 1 = Open Circuit */
#define HWI_TEST_LOWZ_PROBLEM BIT_10 /* 1 = Short Circuit */
#define HWI_TEST_RESERVED (BIT_11 | BIT_12) /* reserved */
#define HWI_TEST_EXECUTE BIT_13 /* 1 = Execute the HWI test on the PHY */
#define HWI_TEST_ABILITY BIT_14 /* 1 = test passed */
#define HWI_TEST_ENABLE BIT_15 /* 1 = Enables the HWI feature */
#define HWI_RESET_ALL_MASK 0x0000
/* ############Start of 82555 specific defines################## */
/* Intel 82555 specific registers */
......
......@@ -106,8 +106,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static struct proc_dir_entry *adapters_proc_dir = 0;
/* externs from e100_main.c */
extern const char *e100_short_driver_name;
extern const char *e100_version;
extern char e100_short_driver_name[];
extern char e100_driver_version[];
extern struct net_device_stats *e100_get_stats(struct net_device *dev);
extern char *e100_get_brand_msg(struct e100_private *bdp);
extern void e100_mdi_write(struct e100_private *, u32, u32, u16);
......@@ -191,7 +191,7 @@ read_descr(char *page, char **start, off_t off, int count, int *eof, void *data)
struct e100_private *bdp = data;
int len;
len = sprintf(page, "%s\n", e100_get_brand_msg(bdp));
len = sprintf(page, "%s\n", bdp->id_string);
return generic_read(page, start, off, count, eof, len);
}
......@@ -223,23 +223,15 @@ read_part_number(char *page, char **start, off_t off,
static void
set_led(struct e100_private *bdp, u16 led_mdi_op)
{
spin_lock_bh(&bdp->mdi_access_lock);
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, led_mdi_op);
spin_unlock_bh(&bdp->mdi_access_lock);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(MDI_SLEEP_TIME);
spin_lock_bh(&bdp->mdi_access_lock);
/* turn led ownership to the chip */
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL);
spin_unlock_bh(&bdp->mdi_access_lock);
}
static int
......@@ -351,6 +343,7 @@ read_info(char *page, char **start, off_t off, int count, int *eof, void *data)
}
#ifdef E100_EOU
#ifdef MODULE
/**********************
* parameter entries
**********************/
......@@ -677,6 +670,7 @@ static e100_proc_entry e100_proc_params[] = {
{"PollingMaxWork.val", read_gen_prm, 0, bdp_prm_off(PollingMaxWork)},
{"", 0, 0, 0}
};
#endif /* MODULE */
#endif /* E100_EOU */
static struct proc_dir_entry * __devinit
......@@ -706,6 +700,7 @@ create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,
}
#ifdef E100_EOU
#ifdef MODULE
static int __devinit
create_proc_param_subdir(struct e100_private *bdp,
struct proc_dir_entry *dev_dir)
......@@ -755,7 +750,8 @@ remove_proc_param_subdir(struct proc_dir_entry *parent)
remove_proc_entry("LoadParameters", parent);
}
#endif /* E100_EOU */
#endif /* MODULE */
#endif
void
e100_remove_proc_subdir(struct e100_private *bdp)
......@@ -781,9 +777,11 @@ e100_remove_proc_subdir(struct e100_private *bdp)
remove_proc_entry(pe->name, bdp->proc_parent);
}
#ifdef E100_EOU
#ifdef E100_EOU
#ifdef MODULE
remove_proc_param_subdir(bdp->proc_parent);
#endif
#endif
remove_proc_entry(bdp->device->name, adapters_proc_dir);
bdp->proc_parent = NULL;
}
......@@ -844,12 +842,14 @@ e100_create_proc_subdir(struct e100_private *bdp)
}
}
#ifdef E100_EOU
#ifdef E100_EOU
#ifdef MODULE
if (create_proc_param_subdir(bdp, dev_dir)) {
e100_remove_proc_subdir(bdp);
return -ENOMEM;
}
#endif
#endif
return 0;
}
......
......@@ -125,6 +125,7 @@ enum e100_device_type {
E100_82559_LOM,
E100_82559_LOM_AOL,
E100_82559_LOM_AOL2,
E100_82559_LOM_DELL,
E100_IBM_MDS,
E100_CMPQ_S,
E100_PROVE_DA,
......@@ -132,7 +133,8 @@ enum e100_device_type {
E100_PROVE_LOM,
E100_PROVE_NET,
E100_82562,
E100_ALL_BOARDS,
E100_82551QM,
E100_ALL_BOARDS
};
struct e100_vendor_info e100_vendor_info_array[] = {
......@@ -147,6 +149,7 @@ struct e100_vendor_info e100_vendor_info_array[] = {
{ E100_BRD_100, "Intel(R) PRO/100+ PCI Adapter"},
{ E100_BRD_100M, "Intel(R) PRO/100+ Management Adapter"},
{ E100_BRD_AOL2, "Intel(R) PRO/100+ Alert on LAN* 2 Management Adapter"},
{ E100_82559_LOM_DELL, "Intel(R) 8255x Based Network Connection"},
{ E100_BRD_AOL, "Intel(R) PRO/100+ Alert on LAN* Management Adapter"},
{ E100_PROS_M, "Intel(R) PRO/100 S Management Adapter"},
{ E100_PROS_AM, "Intel(R) PRO/100 S Advanced Management Adapter"},
......@@ -186,6 +189,7 @@ struct e100_vendor_info e100_vendor_info_array[] = {
{ E100_PROVE_LOM, "Intel(R) PRO/100 VE Network ConnectionPLC LOM" },
{ E100_PROVE_NET, "Intel(R) PRO/100 VE Network Connection"},
{ E100_82562, "Intel(R)82562 based Fast Ethernet Connection"},
{ E100_82551QM, "Intel(R) PRO/100 M Mobile Connection"},
{ E100_ALL_BOARDS, "Intel(R) 8255x-based Ethernet Adapter"},
{0,NULL}
};
......@@ -309,6 +313,7 @@ static struct pci_device_id e100_id_table[] __devinitdata = {
{0x8086, 0x1229, 0x0E11, 0xB144, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x0E11, 0xB163, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x0E11, 0xB164, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x1028, PCI_ANY_ID, 0, 0, E100_82559_LOM_DELL},
{0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x2449, 0x1014, 0x0265, 0, 0, E100_PROVE_D},
......@@ -324,7 +329,11 @@ static struct pci_device_id e100_id_table[] __devinitdata = {
{0x8086, 0x2449, 0x0E11, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
{0x8086, 0x2449, 0x1014, PCI_ANY_ID, 0, 0, E100_PROVE_D},
{0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x1059, 0x1179, 0x0005, 0, 0, E100_82551QM},
{0x8086, 0x1059, 0x1033, 0x8191, 0, 0, E100_82551QM},
{0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82551QM},
{0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
......
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