]> git.neil.brown.name Git - history.git/commitdiff
Update e100 net driver:
authorScott Feldman <scott.feldman@intel.com>
Sat, 3 Aug 2002 05:37:05 +0000 (01:37 -0400)
committerDavid Mosberger <davidm@tiger.hpl.hp.com>
Sat, 3 Aug 2002 05:37:05 +0000 (01:37 -0400)
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.

drivers/net/e100/e100.h
drivers/net/e100/e100_config.c
drivers/net/e100/e100_config.h
drivers/net/e100/e100_main.c
drivers/net/e100/e100_phy.c
drivers/net/e100/e100_phy.h
drivers/net/e100/e100_proc.c
drivers/net/e100/e100_vendor.h

index 9e6b5d3d4e26efecf8b6cb44c3ada24ceed7db78..a0446258dbc7d24268eb0b160d96ae29d9196b38 100644 (file)
@@ -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 */
 
index cce55296ebb1fcfeb0e034117751b610fca5c2c9..cb5d372c1cd7de12628d96f424ea04b428311e68 100644 (file)
@@ -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 @@ 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;
 }
 
 /**
index 6172ce27ef4b5495ff982ac5b05fbb21af3a3615..e114a6cc99178a852ba0c0fe561c25cc0117cddf 100644 (file)
@@ -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,
index d58486f305bfd21b09fecb8fe79781c0e08ed703..4f0c0ae2185658a2620f4c64ad0953fa1da0a35d 100644 (file)
@@ -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__
 
 #include <linux/config.h>
@@ -184,23 +208,24 @@ static void e100_non_tx_background(unsigned long);
 
 /* 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_private *);
 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 *, u32, int *);
 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_buff(struct e100_private *,
 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 pci_device_id *ent)
        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 struct pci_device_id *ent)
 
        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 struct pci_device_id *ent)
        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 struct pci_device_id *ent)
                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 struct pci_device_id *ent)
        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 *bdp)
        /* 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 *bdp)
 
        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_device *dev, struct ifreq *ifr)
        }
 
        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 *dev, struct ifreq *ifr)
        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_device *dev, struct ifreq *ifr)
        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 *dev, struct ifreq *ifr)
        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 *dev, struct ifreq *ifr)
        usr_eeprom_ptr =
                (u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data));
 
-       word_offset = (ecmd.offset >> 1);
-       if (word_offset >= bdp->eeprom_size)
-               return -EFAULT;
+        max_len = bdp->eeprom_size * 2;
+       if ((ecmd.offset + ecmd.len) > max_len)
+               ecmd.len = (max_len - ecmd.offset);
 
-       word_length =
-               min_t(u32, (ecmd.len >> 1), (bdp->eeprom_size - word_offset));
+       first_word = ecmd.offset >> 1;
+       last_word = (ecmd.offset + ecmd.len - 1) >> 1;
+               
+       if (first_word >= bdp->eeprom_size)
+               return -EFAULT;
 
        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 *dev, struct ifreq *ifr)
 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, struct ifreq *ifr, int cmd)
        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, struct ifreq *ifr, int cmd)
                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 state)
        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 */
index 3bd2f620d19a6d1489ce7404b75957ec4f80fba8..4fccffb3035e988992a772dcf31549ea4482980c 100644 (file)
@@ -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);
        }
 
index 1a8166e264fa0cd149c16081ea5dff364855ddcf..4d05de89b4e7a67f28ca7eb63866c72bcbbbe435 100644 (file)
@@ -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 */
index a589557b6a4e5b5858ee3ce1d8fd510a277d6f90..82540446a12e0b39c5ced418ba5a791d7602352d 100644 (file)
@@ -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;
 }
index c8f65af939141a2cbebddbfb99774ecc3de1c546..21580737b8658350e8a57dcd4b7e53bc3fdc436e 100644 (file)
@@ -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},