diff -Nuarp linux-2.5.25/drivers/net/e100/e100.h linux-2.5.25-e100/drivers/net/e100/e100.h
--- linux-2.5.25/drivers/net/e100/e100.h	Fri Jul  5 16:42:19 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100.h	Sat Jul  6 10:39:22 2002
@@ -91,6 +91,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #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
 #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 */
 
diff -Nuarp linux-2.5.25/drivers/net/e100/e100_config.c linux-2.5.25-e100/drivers/net/e100/e100_config.c
--- linux-2.5.25/drivers/net/e100/e100_config.c	Fri Jul  5 16:42:20 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100_config.c	Sat Jul  6 10:39:22 2002
@@ -308,85 +308,58 @@ exit:
 
 /**
  * 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;
 }
 
 /**
diff -Nuarp linux-2.5.25/drivers/net/e100/e100_config.h linux-2.5.25-e100/drivers/net/e100/e100_config.h
--- linux-2.5.25/drivers/net/e100/e100_config.h	Fri Jul  5 16:42:14 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100_config.h	Sat Jul  6 10:39:22 2002
@@ -198,7 +198,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 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,
diff -Nuarp linux-2.5.25/drivers/net/e100/e100_main.c linux-2.5.25-e100/drivers/net/e100/e100_main.c
--- linux-2.5.25/drivers/net/e100/e100_main.c	Fri Jul  5 16:42:23 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100_main.c	Sun Jul  7 20:39:17 2002
@@ -93,6 +93,30 @@ Portions (C) 2002 Red Hat, Inc. under th
 *                                                                     *
 **********************************************************************/
 
+/* 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__
 
 #include <linux/config.h>
@@ -184,23 +208,24 @@ static void e100_non_tx_background(unsig
 
 /* Global Data structures and variables */
 char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
-
-#define E100_VERSION  "2.0.30-k1"
-
-#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";
+char e100_driver_version[]="2.1.6-k1";
+const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
+char e100_short_driver_name[] = "e100";
 static int e100nics = 0;
 
 #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_enable_wake(struct pci_dev *pcid, u32 state, int enable);
 static int e100_resume(struct pci_dev *pcid);
+struct notifier_block e100_notifier = {
+        notifier_call:  e100_notify_reboot,
+        next:           NULL,
+        priority:       0
+};
 #endif
 
+static void e100_get_mdix_status(struct e100_private *bdp);
+
 /*********************************************************************/
 /*! This is a GCC extension to ANSI C.
  *  See the item "Labeled Elements in Initializers" in the section
@@ -250,6 +275,7 @@ static void e100_rd_pwa_no(struct e100_p
 extern u16 e100_eeprom_read(struct e100_private *, u16);
 extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16);
 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_load_microcode(struct e100_private *);
@@ -391,6 +417,8 @@ u32 e100_rx_srv(struct e100_private *, u
 void e100_polling_tasklet(unsigned long);
 
 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_manage_adaptive_ifs(struct e100_private *);
 void e100_clear_pools(struct e100_private *);
@@ -400,7 +428,7 @@ static inline tcb_t *e100_prepare_xmit_b
 static void e100_set_multi_exec(struct net_device *dev);
 
 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");
 
 E100_PARAM(TxDescriptors, "Number of transmit descriptors");
@@ -580,6 +608,7 @@ e100_found1(struct pci_dev *pcid, const 
 	struct net_device *dev = NULL;
 	struct e100_private *bdp = NULL;
 	int rc = 0;
+	u16 cal_checksum, read_checksum;
 
 	dev = alloc_etherdev(sizeof (struct e100_private));
 	if (dev == NULL) {
@@ -592,7 +621,8 @@ e100_found1(struct pci_dev *pcid, const 
 
 	if (first_time) {
 		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 "\n");
 	}
@@ -622,6 +652,10 @@ e100_found1(struct pci_dev *pcid, const 
 	bdp->watchdog_timer.data = (unsigned long) dev;
 	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) {
 		goto err_dealloc;
 	}
@@ -657,6 +691,16 @@ e100_found1(struct pci_dev *pcid, const 
 		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->open = &e100_open;
 	dev->hard_start_xmit = &e100_xmit_frame;
@@ -685,6 +729,17 @@ e100_found1(struct pci_dev *pcid, const 
 	printk(KERN_NOTICE
 	       "%s: %s\n", bdp->device->name, e100_get_brand_msg(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) {
 		printk(KERN_ERR "Failed to create proc directory for %s\n",
@@ -786,27 +841,33 @@ static struct pci_driver e100_driver = {
 	id_table:       e100_id_table,
 	probe:          e100_found1,
 	remove:         __devexit_p(e100_remove1),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM			
 	suspend:        e100_suspend,
 	resume:         e100_resume,
-	save_state:     e100_save_state,
-	enable_wake:    e100_enable_wake,
-#else
-	suspend:        NULL,
-	resume:         NULL,
 #endif
 };
 
 static int __init
 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
 e100_cleanup_module(void)
 {
+#ifdef CONFIG_PM	
+	unregister_reboot_notifier(&e100_notifier);
+#endif	
+
 	pci_unregister_driver(&e100_driver);
 }
 
@@ -1665,7 +1726,7 @@ e100_watchdog(struct net_device *dev)
 	if (!netif_running(dev)) {
 		goto exit;
 	}
-	spin_lock_bh(&(bdp->mdi_access_lock));
+	e100_get_mdix_status(bdp);
 
 	/* check if link state has changed */
 	if (e100_phy_check(bdp)) {
@@ -1677,11 +1738,38 @@ e100_watchdog(struct net_device *dev)
 			       "Half" : "Full");
 
 			e100_config_fc(bdp);
-			e100_config(bdp);	
+			e100_config(bdp);  
+			bdp->cable_status = "Cable OK";
 
 		} else {
 			printk(KERN_ERR "e100: %s NIC Link is Down\n",
 			       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)
 
 	wmb();
 
-	spin_unlock_bh(&(bdp->mdi_access_lock));
-
 	/* relaunch watchdog timer in 2 sec */
 	mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
 
@@ -3051,8 +3137,10 @@ e100_print_brd_conf(struct e100_private 
 	/* Print the string if checksum Offloading was enabled */
 	if (bdp->flags & DF_CSUM_OFFLOAD)
 		printk(KERN_NOTICE "  Hardware receive checksums enabled\n");
-	else
-		printk(KERN_NOTICE "  Hardware receive checksums disabled\n");
+	else {
+		if (bdp->rev_id >= D101MA_REV_ID) 
+			printk(KERN_NOTICE "  Hardware receive checksums disabled\n");
+	}
 
 	if ((bdp->flags & DF_UCODE_LOADED))
 		printk(KERN_NOTICE "  cpu cycle saver enabled\n");
@@ -3151,6 +3239,13 @@ e100_isolate_driver(struct e100_private 
 
 	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))
 		netif_stop_queue(bdp->device);
 
@@ -3382,9 +3477,7 @@ e100_ethtool_get_settings(struct net_dev
 	}
 
 	if (bdp->speed_duplex_caps & SUPPORTED_MII) {
-		spin_lock_bh(&(bdp->mdi_access_lock));
 		e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &advert);
-		spin_unlock_bh(&(bdp->mdi_access_lock));
 
 		if (advert & ADVERTISE_10HALF)
 			ecmd.advertising |= ADVERTISED_10baseT_Half;
@@ -3495,9 +3588,7 @@ e100_ethtool_glink(struct net_device *de
 	bdp = dev->priv;
 	info.cmd = ETHTOOL_GLINK;
 
-	spin_lock_bh(&(bdp->mdi_access_lock));
 	info.data = e100_get_link_state(bdp);
-	spin_unlock_bh(&(bdp->mdi_access_lock));
 
 	if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
 		return -EFAULT;
@@ -3569,7 +3660,7 @@ e100_ethtool_get_drvinfo(struct net_devi
 	bdp = dev->priv;
 
 	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),
 		sizeof (info.fw_version) - 1);
 	strncpy(info.bus_info, bdp->pdev->slot_name,
@@ -3595,8 +3686,9 @@ e100_ethtool_eeprom(struct net_device *d
 	struct ethtool_eeprom ecmd;
 	u16 eeprom_data[256];
 	u16 *usr_eeprom_ptr;
-	u16 word_length, word_offset;
-	int i;
+	u16 first_word, last_word;
+	int i, max_len;
+	void *ptr;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -3609,39 +3701,49 @@ e100_ethtool_eeprom(struct net_device *d
 	usr_eeprom_ptr =
 		(u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data));
 
-	word_offset = (ecmd.offset >> 1);
-	if (word_offset >= bdp->eeprom_size)
+        max_len = bdp->eeprom_size * 2;
+	if ((ecmd.offset + ecmd.len) > max_len)
+		ecmd.len = (max_len - ecmd.offset);
+
+	first_word = ecmd.offset >> 1;
+	last_word = (ecmd.offset + ecmd.len - 1) >> 1;
+		
+	if (first_word >= bdp->eeprom_size)
 		return -EFAULT;
 
-	word_length =
-		min_t(u32, (ecmd.len >> 1), (bdp->eeprom_size - word_offset));
-
 	if (ecmd.cmd == ETHTOOL_GEEPROM) {
-		for (i = word_offset; i < (word_length + word_offset); i++)
-			eeprom_data[i] = e100_eeprom_read(bdp, i);
+        	for(i = 0; i <= (last_word - first_word); i++)
+			eeprom_data[i] = e100_eeprom_read(bdp, first_word + i);
 
-		ecmd.len = (word_length << 1);
 		ecmd.magic = E100_EEPROM_MAGIC;
 
 		if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
 			return -EFAULT;
 
-		if (copy_to_user(usr_eeprom_ptr, &(eeprom_data[word_offset]),
-				 (ecmd.len << 1)))
+		if (copy_to_user(usr_eeprom_ptr, eeprom_data, ecmd.len))
 			return -EFAULT;
 	} else {
 		if (ecmd.magic != E100_EEPROM_MAGIC)
 			return -EFAULT;
 
-		if (copy_from_user(&(eeprom_data[word_offset]), usr_eeprom_ptr,
-				   (ecmd.len << 1)))
-			return -EFAULT;
-
-		e100_eeprom_write_block(bdp, word_offset,
-					&(eeprom_data[word_offset]),
-					word_length);
+		ptr = (void *)eeprom_data;
+        	if(ecmd.offset & 1) {
+                	/* need modification of first changed EEPROM word */
+                	/* only the second byte of the word is being modified */
+			eeprom_data[0] = e100_eeprom_read(bdp, first_word);
+                	ptr++;
+        	}
+        	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)))
 			return -EFAULT;
@@ -3663,12 +3765,9 @@ e100_ethtool_eeprom(struct net_device *d
 static void
 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,
 		       bdp->phy_addr, led_mdi_op);
 
-	spin_unlock_bh(&bdp->mdi_access_lock);
 }
 /**
  * e100_led_blink_callback
@@ -3965,10 +4064,8 @@ e100_mii_ioctl(struct net_device *dev, s
 	case SIOCGMIIREG:
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		spin_lock_bh(&(bdp->mdi_access_lock));
 		e100_mdi_read(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
 			      &(data_ptr->val_out));
-		spin_unlock_bh(&(bdp->mdi_access_lock));
 		break;
 
 	case SIOCSMIIREG:
@@ -3977,10 +4074,8 @@ e100_mii_ioctl(struct net_device *dev, s
 		if (netif_running(dev)) {
 			return -EBUSY;
 		}
-		spin_lock_bh(&(bdp->mdi_access_lock));
 		e100_mdi_write(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
 			       data_ptr->val_in);
-		spin_unlock_bh(&(bdp->mdi_access_lock));
 		break;
 
 	default:
@@ -4149,17 +4244,22 @@ exit:
 
 #ifdef CONFIG_PM
 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 e100_private *bdp;
-
-	/* Actually, PCI PM does NOT call this entry */
-	if (!(dev = (struct net_device *) pci_get_drvdata(pcid)))
-		return -1;
-	bdp = dev->priv;
-	pci_save_state(pcid, bdp->pci_state);
-	return 0;
+        struct pci_dev *pdev = NULL;
+        switch(event) {
+        case SYS_DOWN:
+        case SYS_HALT:
+        case SYS_POWER_OFF:
+                pci_for_each_dev(pdev) {
+                        if(pci_dev_driver(pdev) == &e100_driver) {
+				/* If net_device struct is allocated? */
+                                if (pci_get_drvdata(pdev))
+					e100_suspend(pdev, 3);
+                	}
+		}
+        }
+        return NOTIFY_DONE;
 }
 
 static int
@@ -4169,7 +4269,7 @@ e100_suspend(struct pci_dev *pcid, u32 s
 	struct e100_private *bdp = netdev->priv;
 
 	e100_isolate_driver(bdp);
-	e100_save_state(pcid, state);
+	pci_save_state(pcid, bdp->pci_state);
 
 	/* If wol is enabled */
 #ifdef ETHTOOL_GWOL
@@ -4218,12 +4318,126 @@ e100_resume(struct pci_dev *pcid)
 	return 0;
 }
 
-static int
-e100_enable_wake(struct pci_dev *pcid, u32 state, int enable)
+#endif /* CONFIG_PM */
+
+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 */
-	/* wol when suspended.                                       */
-	/* Actually, PCI PM does NOT call this entry.                */
-	return 0;
+	struct e100_private *bdp = dev->priv;
+	u16 ctrl_reg;
+	int distance, open_circut, short_circut;
+
+	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 */
diff -Nuarp linux-2.5.25/drivers/net/e100/e100_phy.c linux-2.5.25-e100/drivers/net/e100/e100_phy.c
--- linux-2.5.25/drivers/net/e100/e100_phy.c	Fri Jul  5 16:42:01 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100_phy.c	Sat Jul  6 10:39:22 2002
@@ -96,6 +96,7 @@ e100_mdi_write(struct e100_private *bdp,
 	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,
 		udelay(20);
 		e100_retry--;
 	}
+	spin_unlock_bh(&bdp->mdi_access_lock);
 }
 
 /* 
@@ -138,6 +140,7 @@ e100_mdi_read(struct e100_private *bdp, 
 	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, 
 
 	// 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_priv
 
 	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_priv
 		    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, 
 
 	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, 
 			    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);
 	}
 
diff -Nuarp linux-2.5.25/drivers/net/e100/e100_proc.c linux-2.5.25-e100/drivers/net/e100/e100_proc.c
--- linux-2.5.25/drivers/net/e100/e100_proc.c	Fri Jul  5 16:42:21 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100_proc.c	Sat Jul  6 10:39:23 2002
@@ -106,8 +106,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 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
 	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 **star
 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_
 }
 
 #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, s
 }
 
 #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
 
 	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_priv
 			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_priv
 		}
 	}
 
-#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;
 }
diff -Nuarp linux-2.5.25/drivers/net/e100/e100_vendor.h linux-2.5.25-e100/drivers/net/e100/e100_vendor.h
--- linux-2.5.25/drivers/net/e100/e100_vendor.h	Fri Jul  5 16:42:33 2002
+++ linux-2.5.25-e100/drivers/net/e100/e100_vendor.h	Sat Jul  6 10:39:23 2002
@@ -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
 	{ 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
 	{ 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_tabl
 	{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_tabl
 	{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},	
