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. ...@@ -91,6 +91,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <linux/version.h> #include <linux/version.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/reboot.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -147,6 +148,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -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_SCB_WAIT 100 /* Max udelays in wait_scb */
#define E100_MAX_CU_IDLE_WAIT 50 /* Max udelays in wait_cus_idle */ #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. /* 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 * 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 * better to limit the growth of the bundle size than let it go as
...@@ -504,6 +511,7 @@ enum led_state_e { ...@@ -504,6 +511,7 @@ enum led_state_e {
#define IS_ICH 0x00000020 #define IS_ICH 0x00000020
#define DF_SPEED_FORCED 0x00000040 /* set if speed is forced */ #define DF_SPEED_FORCED 0x00000040 /* set if speed is forced */
#define LED_IS_ON 0x00000080 /* LED is turned ON by the driver */ #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; typedef struct net_device_stats net_dev_stats_t;
...@@ -987,6 +995,18 @@ struct e100_private { ...@@ -987,6 +995,18 @@ struct e100_private {
rwlock_t isolate_lock; rwlock_t isolate_lock;
int driver_isolated; 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 */ 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. ...@@ -86,10 +86,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* operating system. * * operating system. *
* * * *
**********************************************************************/ **********************************************************************/
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#endif
#include "e100_config.h" #include "e100_config.h"
static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable); static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
...@@ -308,85 +304,58 @@ e100_config(struct e100_private *bdp) ...@@ -308,85 +304,58 @@ e100_config(struct e100_private *bdp)
/** /**
* e100_config_fc - config flow-control state * 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 * 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 * 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 * line option, and if the link is flow-contorl capable (both us and the link
* partner). * partner). But, if link partner is capable of autoneg, but not capable of
* * flow control, received PAUSE frames are still honored.
* Returns:
* true: if then option was indeed changed
* false: if no change was needed
*/ */
unsigned char void
e100_config_fc(struct e100_private *bdp) e100_config_fc(struct e100_private *bdp)
{ {
unsigned char enable = false; unsigned char enable = false;
unsigned char changed = false;
/* 82557 doesn't support fc. Don't touch this option */ /* 82557 doesn't support fc. Don't touch this option */
if (!(bdp->flags & IS_BACHELOR)) if (!(bdp->flags & IS_BACHELOR))
return false; return;
/* Enable fc if requested and if the link supports it */ /* 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; enable = true;
} }
spin_lock_bh(&(bdp->config_lock)); spin_lock_bh(&(bdp->config_lock));
if (enable) { if (enable) {
if (bdp->flags & DF_LINK_FC_TX_ONLY) {
if (bdp->config[16] != DFLT_FC_DELAY_LSB) { /* 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; 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; 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_FC_OPTS;
bdp->config[19] &= ~CB_CFIG_TX_FC_DIS; bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
E100_CONFIG(bdp, 19);
changed = true;
} }
} else { } else {
if (bdp->config[16] != DFLT_NO_FC_DELAY_LSB) { bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
bdp->config[16] = DFLT_NO_FC_DELAY_LSB; bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
E100_CONFIG(bdp, 16); bdp->config[19] &= ~CB_CFIG_FC_OPTS;
changed = true; bdp->config[19] |= CB_CFIG_TX_FC_DIS;
}
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;
}
} }
E100_CONFIG(bdp, 19);
spin_unlock_bh(&(bdp->config_lock)); 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. ...@@ -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 void e100_config_init(struct e100_private *bdp);
extern unsigned char e100_force_config(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(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_promisc(struct e100_private *bdp, unsigned char enable);
extern void e100_config_brdcast_dsbl(struct e100_private *bdp); extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
extern void e100_config_mulcast_enbl(struct e100_private *bdp, extern void e100_config_mulcast_enbl(struct e100_private *bdp,
......
...@@ -93,6 +93,30 @@ Portions (C) 2002 Red Hat, Inc. under the terms of the GNU GPL v2. ...@@ -93,6 +93,30 @@ Portions (C) 2002 Red Hat, Inc. under the terms of the GNU GPL v2.
* * * *
**********************************************************************/ **********************************************************************/
/* Change Log
*
* 2.1.6 7/5/02
* 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 notifer 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.
*
* 2.0.30 5/30/02
*/
#undef __NO_VERSION__ #undef __NO_VERSION__
#include <linux/config.h> #include <linux/config.h>
...@@ -184,23 +208,24 @@ static void e100_non_tx_background(unsigned long); ...@@ -184,23 +208,24 @@ static void e100_non_tx_background(unsigned long);
/* Global Data structures and variables */ /* Global Data structures and variables */
char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation"; char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
char e100_driver_version[]="2.1.6-k1";
#define E100_VERSION "2.0.30-k1" const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
char e100_short_driver_name[] = "e100";
#define E100_FULL_DRIVER_NAME "Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver "
const char *e100_version = E100_VERSION;
const char *e100_full_driver_name = E100_FULL_DRIVER_NAME E100_VERSION;
char *e100_short_driver_name = "e100";
static int e100nics = 0; static int e100nics = 0;
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int e100_save_state(struct pci_dev *pcid, u32 state); static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
static int e100_suspend(struct pci_dev *pcid, u32 state); static int e100_suspend(struct pci_dev *pcid, u32 state);
static int e100_enable_wake(struct pci_dev *pcid, u32 state, int enable);
static int e100_resume(struct pci_dev *pcid); static int e100_resume(struct pci_dev *pcid);
struct notifier_block e100_notifier = {
notifier_call: e100_notify_reboot,
next: NULL,
priority: 0
};
#endif #endif
static void e100_get_mdix_status(struct e100_private *bdp);
/*********************************************************************/ /*********************************************************************/
/*! This is a GCC extension to ANSI C. /*! This is a GCC extension to ANSI C.
* See the item "Labeled Elements in Initializers" in the section * See the item "Labeled Elements in Initializers" in the section
...@@ -250,6 +275,7 @@ static void e100_rd_pwa_no(struct e100_private *); ...@@ -250,6 +275,7 @@ static void e100_rd_pwa_no(struct e100_private *);
extern u16 e100_eeprom_read(struct e100_private *, u16); extern u16 e100_eeprom_read(struct e100_private *, u16);
extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16); extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16);
extern u16 e100_eeprom_size(struct e100_private *); extern u16 e100_eeprom_size(struct e100_private *);
u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
static unsigned char e100_clr_cntrs(struct e100_private *); static unsigned char e100_clr_cntrs(struct e100_private *);
static unsigned char e100_load_microcode(struct e100_private *); static unsigned char e100_load_microcode(struct e100_private *);
...@@ -391,6 +417,8 @@ u32 e100_rx_srv(struct e100_private *, u32, int *); ...@@ -391,6 +417,8 @@ u32 e100_rx_srv(struct e100_private *, u32, int *);
void e100_polling_tasklet(unsigned long); void e100_polling_tasklet(unsigned long);
void e100_watchdog(struct net_device *); void e100_watchdog(struct net_device *);
static void e100_do_hwi(struct net_device *);
static void e100_hwi_restore(struct e100_private *);
void e100_refresh_txthld(struct e100_private *); void e100_refresh_txthld(struct e100_private *);
void e100_manage_adaptive_ifs(struct e100_private *); void e100_manage_adaptive_ifs(struct e100_private *);
void e100_clear_pools(struct e100_private *); void e100_clear_pools(struct e100_private *);
...@@ -400,7 +428,7 @@ static inline tcb_t *e100_prepare_xmit_buff(struct e100_private *, ...@@ -400,7 +428,7 @@ static inline tcb_t *e100_prepare_xmit_buff(struct e100_private *,
static void e100_set_multi_exec(struct net_device *dev); static void e100_set_multi_exec(struct net_device *dev);
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION(E100_FULL_DRIVER_NAME E100_VERSION); MODULE_DESCRIPTION("Intel(R) PRO/100 Network Driver");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
E100_PARAM(TxDescriptors, "Number of transmit descriptors"); E100_PARAM(TxDescriptors, "Number of transmit descriptors");
...@@ -580,6 +608,7 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent) ...@@ -580,6 +608,7 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct e100_private *bdp = NULL; struct e100_private *bdp = NULL;
int rc = 0; int rc = 0;
u16 cal_checksum, read_checksum;
dev = alloc_etherdev(sizeof (struct e100_private)); dev = alloc_etherdev(sizeof (struct e100_private));
if (dev == NULL) { if (dev == NULL) {
...@@ -592,7 +621,8 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent) ...@@ -592,7 +621,8 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
if (first_time) { if (first_time) {
first_time = false; first_time = false;
printk(KERN_NOTICE "%s\n", e100_full_driver_name); printk(KERN_NOTICE "%s - version %s\n",
e100_full_driver_name, e100_driver_version);
printk(KERN_NOTICE "%s\n", e100_copyright); printk(KERN_NOTICE "%s\n", e100_copyright);
printk(KERN_NOTICE "\n"); printk(KERN_NOTICE "\n");
} }
...@@ -622,6 +652,10 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent) ...@@ -622,6 +652,10 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
bdp->watchdog_timer.data = (unsigned long) dev; bdp->watchdog_timer.data = (unsigned long) dev;
bdp->watchdog_timer.function = (void *) &e100_watchdog; bdp->watchdog_timer.function = (void *) &e100_watchdog;
init_timer(&bdp->hwi_timer);
bdp->hwi_timer.data = (unsigned long) dev;
bdp->hwi_timer.function = (void *) &e100_do_hwi;
if ((rc = e100_pci_setup(pcid, bdp)) != 0) { if ((rc = e100_pci_setup(pcid, bdp)) != 0) {
goto err_dealloc; goto err_dealloc;
} }
...@@ -657,6 +691,16 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent) ...@@ -657,6 +691,16 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
goto err_pci; goto err_pci;
} }
/* Check if checksum is valid */
cal_checksum = e100_eeprom_calculate_chksum(bdp);
read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1));
if (cal_checksum != read_checksum) {
printk(KERN_ERR "e100: Corrupted EERPROM on instance #%d\n",
e100nics);
rc = -ENODEV;
goto err_pci;
}
dev->irq = pcid->irq; dev->irq = pcid->irq;
dev->open = &e100_open; dev->open = &e100_open;
dev->hard_start_xmit = &e100_xmit_frame; dev->hard_start_xmit = &e100_xmit_frame;
...@@ -685,6 +729,17 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent) ...@@ -685,6 +729,17 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
printk(KERN_NOTICE printk(KERN_NOTICE
"%s: %s\n", bdp->device->name, e100_get_brand_msg(bdp)); "%s: %s\n", bdp->device->name, e100_get_brand_msg(bdp));
e100_print_brd_conf(bdp); e100_print_brd_conf(bdp);
bdp->id_string = e100_get_brand_msg(bdp);
e100_get_mdix_status(bdp);
if (netif_carrier_ok(bdp->device))
bdp->cable_status = "Cable OK";
else {
if (bdp->rev_id < D102_REV_ID)
bdp->cable_status = "Not supported";
else
bdp->cable_status = "Not available";
}
if (e100_create_proc_subdir(bdp) < 0) { if (e100_create_proc_subdir(bdp) < 0) {
printk(KERN_ERR "Failed to create proc directory for %s\n", printk(KERN_ERR "Failed to create proc directory for %s\n",
...@@ -786,27 +841,33 @@ static struct pci_driver e100_driver = { ...@@ -786,27 +841,33 @@ static struct pci_driver e100_driver = {
id_table: e100_id_table, id_table: e100_id_table,
probe: e100_found1, probe: e100_found1,
remove: __devexit_p(e100_remove1), remove: __devexit_p(e100_remove1),
#ifdef CONFIG_PM #ifdef CONFIG_PM
suspend: e100_suspend, suspend: e100_suspend,
resume: e100_resume, resume: e100_resume,
save_state: e100_save_state,
enable_wake: e100_enable_wake,
#else
suspend: NULL,
resume: NULL,
#endif #endif
}; };
static int __init static int __init
e100_init_module(void) e100_init_module(void)
{ {
return pci_module_init(&e100_driver); int ret;
ret = pci_module_init(&e100_driver);
#ifdef CONFIG_PM
if(ret >= 0)
register_reboot_notifier(&e100_notifier);
#endif
return ret;
} }
static void __exit static void __exit
e100_cleanup_module(void) e100_cleanup_module(void)
{ {
#ifdef CONFIG_PM
unregister_reboot_notifier(&e100_notifier);
#endif
pci_unregister_driver(&e100_driver); pci_unregister_driver(&e100_driver);
} }
...@@ -1665,7 +1726,7 @@ e100_watchdog(struct net_device *dev) ...@@ -1665,7 +1726,7 @@ e100_watchdog(struct net_device *dev)
if (!netif_running(dev)) { if (!netif_running(dev)) {
goto exit; goto exit;
} }
spin_lock_bh(&(bdp->mdi_access_lock)); e100_get_mdix_status(bdp);
/* check if link state has changed */ /* check if link state has changed */
if (e100_phy_check(bdp)) { if (e100_phy_check(bdp)) {
...@@ -1677,11 +1738,38 @@ e100_watchdog(struct net_device *dev) ...@@ -1677,11 +1738,38 @@ e100_watchdog(struct net_device *dev)
"Half" : "Full"); "Half" : "Full");
e100_config_fc(bdp); e100_config_fc(bdp);
e100_config(bdp); e100_config(bdp);
bdp->cable_status = "Cable OK";
} else { } else {
printk(KERN_ERR "e100: %s NIC Link is Down\n", printk(KERN_ERR "e100: %s NIC Link is Down\n",
bdp->device->name); bdp->device->name);
if (bdp->rev_id < D102_REV_ID)
bdp->cable_status = "Not supported";
else {
/* Initiate hwi, ie, cable diagnostic */
bdp->saved_open_circut = 0xffff;
bdp->saved_short_circut = 0xffff;
bdp->saved_distance = 0xffff;
bdp->saved_i = 0;
bdp->saved_same = 0;
bdp->hwi_started = 1;
/* Disable MDI/MDI-X auto switching */
e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
MDI_MDIX_RESET_ALL_MASK);
/* Set to 100 Full as required by hwi test */
e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
BMCR_SPEED100 | BMCR_FULLDPLX);
/* Enable and execute HWI test */
e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
(HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
/* Launch hwi timer in 1 msec */
mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
}
} }
} }
...@@ -1722,8 +1810,6 @@ e100_watchdog(struct net_device *dev) ...@@ -1722,8 +1810,6 @@ e100_watchdog(struct net_device *dev)
wmb(); wmb();
spin_unlock_bh(&(bdp->mdi_access_lock));
/* relaunch watchdog timer in 2 sec */ /* relaunch watchdog timer in 2 sec */
mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ)); mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
...@@ -3051,8 +3137,10 @@ e100_print_brd_conf(struct e100_private *bdp) ...@@ -3051,8 +3137,10 @@ e100_print_brd_conf(struct e100_private *bdp)
/* Print the string if checksum Offloading was enabled */ /* Print the string if checksum Offloading was enabled */
if (bdp->flags & DF_CSUM_OFFLOAD) if (bdp->flags & DF_CSUM_OFFLOAD)
printk(KERN_NOTICE " Hardware receive checksums enabled\n"); printk(KERN_NOTICE " Hardware receive checksums enabled\n");
else else {
printk(KERN_NOTICE " Hardware receive checksums disabled\n"); if (bdp->rev_id >= D101MA_REV_ID)
printk(KERN_NOTICE " Hardware receive checksums disabled\n");
}
if ((bdp->flags & DF_UCODE_LOADED)) if ((bdp->flags & DF_UCODE_LOADED))
printk(KERN_NOTICE " cpu cycle saver enabled\n"); printk(KERN_NOTICE " cpu cycle saver enabled\n");
...@@ -3151,6 +3239,13 @@ e100_isolate_driver(struct e100_private *bdp) ...@@ -3151,6 +3239,13 @@ e100_isolate_driver(struct e100_private *bdp)
del_timer_sync(&bdp->watchdog_timer); del_timer_sync(&bdp->watchdog_timer);
del_timer_sync(&bdp->hwi_timer);
/* If in middle of cable diag, */
if (bdp->hwi_started) {
bdp->hwi_started = 0;
e100_hwi_restore(bdp);
}
if (netif_running(bdp->device)) if (netif_running(bdp->device))
netif_stop_queue(bdp->device); netif_stop_queue(bdp->device);
...@@ -3382,9 +3477,7 @@ e100_ethtool_get_settings(struct net_device *dev, struct ifreq *ifr) ...@@ -3382,9 +3477,7 @@ e100_ethtool_get_settings(struct net_device *dev, struct ifreq *ifr)
} }
if (bdp->speed_duplex_caps & SUPPORTED_MII) { if (bdp->speed_duplex_caps & SUPPORTED_MII) {
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &advert); e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &advert);
spin_unlock_bh(&(bdp->mdi_access_lock));
if (advert & ADVERTISE_10HALF) if (advert & ADVERTISE_10HALF)
ecmd.advertising |= ADVERTISED_10baseT_Half; ecmd.advertising |= ADVERTISED_10baseT_Half;
...@@ -3495,9 +3588,7 @@ e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr) ...@@ -3495,9 +3588,7 @@ e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr)
bdp = dev->priv; bdp = dev->priv;
info.cmd = ETHTOOL_GLINK; info.cmd = ETHTOOL_GLINK;
spin_lock_bh(&(bdp->mdi_access_lock));
info.data = e100_get_link_state(bdp); info.data = e100_get_link_state(bdp);
spin_unlock_bh(&(bdp->mdi_access_lock));
if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
return -EFAULT; return -EFAULT;
...@@ -3569,7 +3660,7 @@ e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr) ...@@ -3569,7 +3660,7 @@ e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
bdp = dev->priv; bdp = dev->priv;
strncpy(info.driver, e100_short_driver_name, sizeof (info.driver) - 1); strncpy(info.driver, e100_short_driver_name, sizeof (info.driver) - 1);
strncpy(info.version, e100_version, sizeof (info.version) - 1); strncpy(info.version, e100_driver_version, sizeof (info.version) - 1);
strncpy(info.fw_version, e100_get_brand_msg(bdp), strncpy(info.fw_version, e100_get_brand_msg(bdp),
sizeof (info.fw_version) - 1); sizeof (info.fw_version) - 1);
strncpy(info.bus_info, bdp->pdev->slot_name, strncpy(info.bus_info, bdp->pdev->slot_name,
...@@ -3595,8 +3686,9 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr) ...@@ -3595,8 +3686,9 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
struct ethtool_eeprom ecmd; struct ethtool_eeprom ecmd;
u16 eeprom_data[256]; u16 eeprom_data[256];
u16 *usr_eeprom_ptr; u16 *usr_eeprom_ptr;
u16 word_length, word_offset; u16 first_word, last_word;
int i; int i, max_len;
void *ptr;
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
...@@ -3609,39 +3701,49 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr) ...@@ -3609,39 +3701,49 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
usr_eeprom_ptr = usr_eeprom_ptr =
(u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data)); (u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data));
word_offset = (ecmd.offset >> 1); max_len = bdp->eeprom_size * 2;
if (word_offset >= bdp->eeprom_size) if ((ecmd.offset + ecmd.len) > max_len)
return -EFAULT; ecmd.len = (max_len - ecmd.offset);
word_length = first_word = ecmd.offset >> 1;
min_t(u32, (ecmd.len >> 1), (bdp->eeprom_size - word_offset)); last_word = (ecmd.offset + ecmd.len - 1) >> 1;
if (first_word >= bdp->eeprom_size)
return -EFAULT;
if (ecmd.cmd == ETHTOOL_GEEPROM) { if (ecmd.cmd == ETHTOOL_GEEPROM) {
for (i = word_offset; i < (word_length + word_offset); i++) for(i = 0; i <= (last_word - first_word); i++)
eeprom_data[i] = e100_eeprom_read(bdp, i); eeprom_data[i] = e100_eeprom_read(bdp, first_word + i);
ecmd.len = (word_length << 1);
ecmd.magic = E100_EEPROM_MAGIC; ecmd.magic = E100_EEPROM_MAGIC;
if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
return -EFAULT; return -EFAULT;
if (copy_to_user(usr_eeprom_ptr, &(eeprom_data[word_offset]), if (copy_to_user(usr_eeprom_ptr, eeprom_data, ecmd.len))
(ecmd.len << 1)))
return -EFAULT; return -EFAULT;
} else { } else {
if (ecmd.magic != E100_EEPROM_MAGIC) if (ecmd.magic != E100_EEPROM_MAGIC)
return -EFAULT; return -EFAULT;
if (copy_from_user(&(eeprom_data[word_offset]), usr_eeprom_ptr, ptr = (void *)eeprom_data;
(ecmd.len << 1))) if(ecmd.offset & 1) {
return -EFAULT; /* need modification of first changed EEPROM word */
/* only the second byte of the word is being modified */
e100_eeprom_write_block(bdp, word_offset, eeprom_data[0] = e100_eeprom_read(bdp, first_word);
&(eeprom_data[word_offset]), ptr++;
word_length); }
if((ecmd.offset + ecmd.len) & 1) {
/* need modification of last changed EEPROM word */
/* only the first byte of the word is being modified */
eeprom_data[last_word - first_word] =
e100_eeprom_read(bdp, last_word);
}
if(copy_from_user(ptr, usr_eeprom_ptr, ecmd.len))
return -EFAULT;
ecmd.len = (word_length << 1); e100_eeprom_write_block(bdp, first_word, eeprom_data,
last_word - first_word + 1);
if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
return -EFAULT; return -EFAULT;
...@@ -3663,12 +3765,9 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr) ...@@ -3663,12 +3765,9 @@ e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
static void static void
e100_led_control(struct e100_private *bdp, u16 led_mdi_op) e100_led_control(struct e100_private *bdp, u16 led_mdi_op)
{ {
spin_lock_bh(&bdp->mdi_access_lock);
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL, e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, led_mdi_op); bdp->phy_addr, led_mdi_op);
spin_unlock_bh(&bdp->mdi_access_lock);
} }
/** /**
* e100_led_blink_callback * e100_led_blink_callback
...@@ -3965,10 +4064,8 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -3965,10 +4064,8 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case SIOCGMIIREG: case SIOCGMIIREG:
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr, e100_mdi_read(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
&(data_ptr->val_out)); &(data_ptr->val_out));
spin_unlock_bh(&(bdp->mdi_access_lock));
break; break;
case SIOCSMIIREG: case SIOCSMIIREG:
...@@ -3977,10 +4074,8 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -3977,10 +4074,8 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (netif_running(dev)) { if (netif_running(dev)) {
return -EBUSY; return -EBUSY;
} }
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_write(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr, e100_mdi_write(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
data_ptr->val_in); data_ptr->val_in);
spin_unlock_bh(&(bdp->mdi_access_lock));
break; break;
default: default:
...@@ -4149,17 +4244,22 @@ e100_non_tx_background(unsigned long ptr) ...@@ -4149,17 +4244,22 @@ e100_non_tx_background(unsigned long ptr)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int static int
e100_save_state(struct pci_dev *pcid, u32 state) e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
{ {
struct net_device *dev; struct pci_dev *pdev = NULL;
struct e100_private *bdp; switch(event) {
case SYS_DOWN:
/* Actually, PCI PM does NOT call this entry */ case SYS_HALT:
if (!(dev = (struct net_device *) pci_get_drvdata(pcid))) case SYS_POWER_OFF:
return -1; pci_for_each_dev(pdev) {
bdp = dev->priv; if(pci_dev_driver(pdev) == &e100_driver) {
pci_save_state(pcid, bdp->pci_state); /* If net_device struct is allocated? */
return 0; if (pci_get_drvdata(pdev))
e100_suspend(pdev, 3);
}
}
}
return NOTIFY_DONE;
} }
static int static int
...@@ -4169,7 +4269,7 @@ e100_suspend(struct pci_dev *pcid, u32 state) ...@@ -4169,7 +4269,7 @@ e100_suspend(struct pci_dev *pcid, u32 state)
struct e100_private *bdp = netdev->priv; struct e100_private *bdp = netdev->priv;
e100_isolate_driver(bdp); e100_isolate_driver(bdp);
e100_save_state(pcid, state); pci_save_state(pcid, bdp->pci_state);
/* If wol is enabled */ /* If wol is enabled */
#ifdef ETHTOOL_GWOL #ifdef ETHTOOL_GWOL
...@@ -4218,12 +4318,126 @@ e100_resume(struct pci_dev *pcid) ...@@ -4218,12 +4318,126 @@ e100_resume(struct pci_dev *pcid)
return 0; return 0;
} }
static int #endif /* CONFIG_PM */
e100_enable_wake(struct pci_dev *pcid, u32 state, int enable)
static void
e100_get_mdix_status(struct e100_private *bdp)
{
if (bdp->rev_id < D102_REV_ID) {
if (netif_carrier_ok(bdp->device))
bdp->mdix_status = "MDI";
else
bdp->mdix_status = "None";
} else {
u16 ctrl_reg;
/* Read the MDIX control register */
e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &ctrl_reg);
if (ctrl_reg & MDI_MDIX_CONFIG_IS_OK) {
if (ctrl_reg & MDI_MDIX_STATUS)
bdp->mdix_status = "MDI-X";
else
bdp->mdix_status = "MDI";
} else
bdp->mdix_status = "None";
}
}
static void
e100_do_hwi(struct net_device *dev)
{ {
/* Driver doesn't need to do anything because it will enable */ struct e100_private *bdp = dev->priv;
/* wol when suspended. */ u16 ctrl_reg;
/* Actually, PCI PM does NOT call this entry. */ int distance, open_circut, short_circut;
return 0;
e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg);
distance = ctrl_reg & HWI_TEST_DISTANCE;
open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM;
short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM;
if ((distance == bdp->saved_distance) &&
(open_circut == bdp->saved_open_circut) &&
(short_circut == bdp->saved_short_circut))
bdp->saved_same++;
else {
bdp->saved_same = 0;
bdp->saved_distance = distance;
bdp->saved_open_circut = open_circut;
bdp->saved_short_circut = short_circut;
}
if (bdp->saved_same == MAX_SAME_RESULTS) {
if ((open_circut && !(short_circut)) ||
(!(open_circut) && short_circut)) {
u8 near_end = ((distance * HWI_REGISTER_GRANULARITY) <
HWI_NEAR_END_BOUNDARY);
if (open_circut) {
if (near_end)
bdp->cable_status = "Open Circut Near End";
else
bdp->cable_status = "Open Circut Far End";
} else {
if (near_end)
bdp->cable_status = "Short Circut Near End";
else
bdp->cable_status = "Short Circut Far End";
}
goto done;
}
}
else if (bdp->saved_i == HWI_MAX_LOOP) {
bdp->cable_status = "Test failed";
goto done;
}
/* Do another hwi test */
e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
(HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
bdp->saved_i++;
/* relaunch hwi timer in 1 msec */
mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
return;
done:
e100_hwi_restore(bdp);
bdp->hwi_started = 0;
return;
}
static void e100_hwi_restore(struct e100_private *bdp)
{
u16 control = 0;
/* Restore speed, duplex and autoneg before */
/* hwi test, i.e., cable diagnostic */
/* Reset hwi test */
e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, HWI_RESET_ALL_MASK);
if ((bdp->params.e100_speed_duplex == E100_AUTONEG) &&
(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);
switch (bdp->params.e100_speed_duplex) {
case E100_SPEED_10_HALF:
break;
case E100_SPEED_10_FULL:
control = BMCR_FULLDPLX;
break;
case E100_SPEED_100_HALF:
control = BMCR_SPEED100;
break;
case E100_SPEED_100_FULL:
control = BMCR_SPEED100 | BMCR_FULLDPLX;
break;
case E100_AUTONEG:
control = BMCR_ANENABLE | BMCR_ANRESTART;
break;
}
/* Restore original speed/duplex */
e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
return;
} }
#endif /* CONFIG_PM */
...@@ -96,6 +96,7 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data) ...@@ -96,6 +96,7 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
int e100_retry; int e100_retry;
u32 temp_val; u32 temp_val;
spin_lock_bh(&bdp->mdi_access_lock);
temp_val = (((u32) data) | (reg_addr << 16) | temp_val = (((u32) data) | (reg_addr << 16) |
(phy_addr << 21) | (MDI_WRITE << 26)); (phy_addr << 21) | (MDI_WRITE << 26));
writel(temp_val, &bdp->scb->scb_mdi_cntrl); 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) ...@@ -111,6 +112,7 @@ e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
udelay(20); udelay(20);
e100_retry--; 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) ...@@ -138,6 +140,7 @@ e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
int e100_retry; int e100_retry;
u32 temp_val; u32 temp_val;
spin_lock_bh(&bdp->mdi_access_lock);
/* Issue the read command to the MDI control register. */ /* Issue the read command to the MDI control register. */
temp_val = ((reg_addr << 16) | (phy_addr << 21) | (MDI_READ << 26)); temp_val = ((reg_addr << 16) | (phy_addr << 21) | (MDI_READ << 26));
writel(temp_val, &bdp->scb->scb_mdi_cntrl); 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) ...@@ -156,6 +159,7 @@ e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
// return the lower word // return the lower word
*data = (u16) readl(&bdp->scb->scb_mdi_cntrl); *data = (u16) readl(&bdp->scb->scb_mdi_cntrl);
spin_unlock_bh(&bdp->mdi_access_lock);
} }
static unsigned char __devinit static unsigned char __devinit
...@@ -657,8 +661,6 @@ e100_force_speed_duplex(struct e100_private *bdp) ...@@ -657,8 +661,6 @@ e100_force_speed_duplex(struct e100_private *bdp)
bdp->flags |= DF_SPEED_FORCED; bdp->flags |= DF_SPEED_FORCED;
spin_lock_bh(&(bdp->mdi_access_lock));
e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control); e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
control &= ~BMCR_ANENABLE; control &= ~BMCR_ANENABLE;
...@@ -702,14 +704,10 @@ e100_force_speed_duplex(struct e100_private *bdp) ...@@ -702,14 +704,10 @@ e100_force_speed_duplex(struct e100_private *bdp)
time_after(jiffies, expires)) { time_after(jiffies, expires)) {
break; break;
} else { } else {
spin_unlock_bh(&(bdp->mdi_access_lock));
yield(); yield();
spin_lock_bh(&(bdp->mdi_access_lock));
} }
} while (true); } while (true);
spin_unlock_bh(&(bdp->mdi_access_lock));
} }
/* /*
...@@ -753,7 +751,12 @@ e100_set_fc(struct e100_private *bdp) ...@@ -753,7 +751,12 @@ e100_set_fc(struct e100_private *bdp)
if (ad_reg & NWAY_AD_FC_SUPPORTED) if (ad_reg & NWAY_AD_FC_SUPPORTED)
bdp->flags |= DF_LINK_FC_CAP; bdp->flags |= DF_LINK_FC_CAP;
else 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 { } else {
bdp->flags &= ~DF_LINK_FC_CAP; bdp->flags &= ~DF_LINK_FC_CAP;
...@@ -821,8 +824,6 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart) ...@@ -821,8 +824,6 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
bdp->flags &= ~DF_SPEED_FORCED; 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);
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) ...@@ -848,25 +849,30 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
time_after(jiffies, expires) ) { time_after(jiffies, expires) ) {
goto exit; goto exit;
} else { } else {
spin_unlock_bh(&(bdp->mdi_access_lock));
yield(); yield();
spin_lock_bh(&(bdp->mdi_access_lock));
} }
} while (true); } while (true);
} }
exit: exit:
e100_find_speed_duplex(bdp); e100_find_speed_duplex(bdp);
spin_unlock_bh(&(bdp->mdi_access_lock));
} }
void void
e100_phy_set_speed_duplex(struct e100_private *bdp, unsigned char force_restart) e100_phy_set_speed_duplex(struct e100_private *bdp, unsigned char force_restart)
{ {
if (bdp->params.e100_speed_duplex == E100_AUTONEG) { 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); e100_auto_neg(bdp, force_restart);
} else { } 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); e100_force_speed_duplex(bdp);
} }
......
...@@ -124,6 +124,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -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_CONG_CONTROL_REG 0x17 /* National (TX) congestion control */
#define NSC_SPEED_IND_REG 0x19 /* National (TX) speed indication */ #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################## */ /* ############Start of 82555 specific defines################## */
/* Intel 82555 specific registers */ /* Intel 82555 specific registers */
......
...@@ -106,8 +106,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -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; static struct proc_dir_entry *adapters_proc_dir = 0;
/* externs from e100_main.c */ /* externs from e100_main.c */
extern const char *e100_short_driver_name; extern char e100_short_driver_name[];
extern const char *e100_version; extern char e100_driver_version[];
extern struct net_device_stats *e100_get_stats(struct net_device *dev); extern struct net_device_stats *e100_get_stats(struct net_device *dev);
extern char *e100_get_brand_msg(struct e100_private *bdp); extern char *e100_get_brand_msg(struct e100_private *bdp);
extern void e100_mdi_write(struct e100_private *, u32, u32, u16); 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) ...@@ -191,7 +191,7 @@ read_descr(char *page, char **start, off_t off, int count, int *eof, void *data)
struct e100_private *bdp = data; struct e100_private *bdp = data;
int len; 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); return generic_read(page, start, off, count, eof, len);
} }
...@@ -223,23 +223,15 @@ read_part_number(char *page, char **start, off_t off, ...@@ -223,23 +223,15 @@ read_part_number(char *page, char **start, off_t off,
static void static void
set_led(struct e100_private *bdp, u16 led_mdi_op) 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, e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, led_mdi_op); bdp->phy_addr, led_mdi_op);
spin_unlock_bh(&bdp->mdi_access_lock);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(MDI_SLEEP_TIME); schedule_timeout(MDI_SLEEP_TIME);
spin_lock_bh(&bdp->mdi_access_lock);
/* turn led ownership to the chip */ /* turn led ownership to the chip */
e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL, e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL); bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL);
spin_unlock_bh(&bdp->mdi_access_lock);
} }
static int static int
...@@ -351,6 +343,7 @@ read_info(char *page, char **start, off_t off, int count, int *eof, void *data) ...@@ -351,6 +343,7 @@ read_info(char *page, char **start, off_t off, int count, int *eof, void *data)
} }
#ifdef E100_EOU #ifdef E100_EOU
#ifdef MODULE
/********************** /**********************
* parameter entries * parameter entries
**********************/ **********************/
...@@ -677,6 +670,7 @@ static e100_proc_entry e100_proc_params[] = { ...@@ -677,6 +670,7 @@ static e100_proc_entry e100_proc_params[] = {
{"PollingMaxWork.val", read_gen_prm, 0, bdp_prm_off(PollingMaxWork)}, {"PollingMaxWork.val", read_gen_prm, 0, bdp_prm_off(PollingMaxWork)},
{"", 0, 0, 0} {"", 0, 0, 0}
}; };
#endif /* MODULE */
#endif /* E100_EOU */ #endif /* E100_EOU */
static struct proc_dir_entry * __devinit static struct proc_dir_entry * __devinit
...@@ -706,6 +700,7 @@ create_proc_rw(char *name, void *data, struct proc_dir_entry *parent, ...@@ -706,6 +700,7 @@ create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,
} }
#ifdef E100_EOU #ifdef E100_EOU
#ifdef MODULE
static int __devinit static int __devinit
create_proc_param_subdir(struct e100_private *bdp, create_proc_param_subdir(struct e100_private *bdp,
struct proc_dir_entry *dev_dir) struct proc_dir_entry *dev_dir)
...@@ -755,7 +750,8 @@ remove_proc_param_subdir(struct proc_dir_entry *parent) ...@@ -755,7 +750,8 @@ remove_proc_param_subdir(struct proc_dir_entry *parent)
remove_proc_entry("LoadParameters", parent); remove_proc_entry("LoadParameters", parent);
} }
#endif /* E100_EOU */ #endif /* MODULE */
#endif
void void
e100_remove_proc_subdir(struct e100_private *bdp) e100_remove_proc_subdir(struct e100_private *bdp)
...@@ -781,9 +777,11 @@ 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); remove_proc_entry(pe->name, bdp->proc_parent);
} }
#ifdef E100_EOU #ifdef E100_EOU
#ifdef MODULE
remove_proc_param_subdir(bdp->proc_parent); remove_proc_param_subdir(bdp->proc_parent);
#endif #endif
#endif
remove_proc_entry(bdp->device->name, adapters_proc_dir); remove_proc_entry(bdp->device->name, adapters_proc_dir);
bdp->proc_parent = NULL; bdp->proc_parent = NULL;
} }
...@@ -844,12 +842,14 @@ e100_create_proc_subdir(struct e100_private *bdp) ...@@ -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)) { if (create_proc_param_subdir(bdp, dev_dir)) {
e100_remove_proc_subdir(bdp); e100_remove_proc_subdir(bdp);
return -ENOMEM; return -ENOMEM;
} }
#endif #endif
#endif
return 0; return 0;
} }
......
...@@ -125,6 +125,7 @@ enum e100_device_type { ...@@ -125,6 +125,7 @@ enum e100_device_type {
E100_82559_LOM, E100_82559_LOM,
E100_82559_LOM_AOL, E100_82559_LOM_AOL,
E100_82559_LOM_AOL2, E100_82559_LOM_AOL2,
E100_82559_LOM_DELL,
E100_IBM_MDS, E100_IBM_MDS,
E100_CMPQ_S, E100_CMPQ_S,
E100_PROVE_DA, E100_PROVE_DA,
...@@ -132,7 +133,8 @@ enum e100_device_type { ...@@ -132,7 +133,8 @@ enum e100_device_type {
E100_PROVE_LOM, E100_PROVE_LOM,
E100_PROVE_NET, E100_PROVE_NET,
E100_82562, E100_82562,
E100_ALL_BOARDS, E100_82551QM,
E100_ALL_BOARDS
}; };
struct e100_vendor_info e100_vendor_info_array[] = { struct e100_vendor_info e100_vendor_info_array[] = {
...@@ -147,6 +149,7 @@ 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_100, "Intel(R) PRO/100+ PCI Adapter"},
{ E100_BRD_100M, "Intel(R) PRO/100+ Management Adapter"}, { E100_BRD_100M, "Intel(R) PRO/100+ Management Adapter"},
{ E100_BRD_AOL2, "Intel(R) PRO/100+ Alert on LAN* 2 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_BRD_AOL, "Intel(R) PRO/100+ Alert on LAN* Management Adapter"},
{ E100_PROS_M, "Intel(R) PRO/100 S Management Adapter"}, { E100_PROS_M, "Intel(R) PRO/100 S Management Adapter"},
{ E100_PROS_AM, "Intel(R) PRO/100 S Advanced 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[] = { ...@@ -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_LOM, "Intel(R) PRO/100 VE Network ConnectionPLC LOM" },
{ E100_PROVE_NET, "Intel(R) PRO/100 VE Network Connection"}, { E100_PROVE_NET, "Intel(R) PRO/100 VE Network Connection"},
{ E100_82562, "Intel(R)82562 based Fast Ethernet 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"}, { E100_ALL_BOARDS, "Intel(R) 8255x-based Ethernet Adapter"},
{0,NULL} {0,NULL}
}; };
...@@ -309,6 +313,7 @@ static struct pci_device_id e100_id_table[] __devinitdata = { ...@@ -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, 0xB144, 0, 0, E100_CMPQ_S},
{0x8086, 0x1229, 0x0E11, 0xB163, 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, 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, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
{0x8086, 0x2449, 0x1014, 0x0265, 0, 0, E100_PROVE_D}, {0x8086, 0x2449, 0x1014, 0x0265, 0, 0, E100_PROVE_D},
...@@ -324,7 +329,11 @@ static struct pci_device_id e100_id_table[] __devinitdata = { ...@@ -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, 0x0E11, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
{0x8086, 0x2449, 0x1014, PCI_ANY_ID, 0, 0, E100_PROVE_D}, {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, 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, 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, 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}, {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