aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2007-12-17 16:50:23 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:07:18 -0500
commit67b3c27c8a8d8f81ffc3fe0afc0d805d66744d18 (patch)
treed202c7fd4e723f63ab43c3be9b9935d48d1dc9b9 /drivers/net
parent8b32e63d48d43f3843222ca66fecd45ff2a74147 (diff)
e1000: Dump the eeprom when a user encounters a bad checksum
To help supporting users with a bad eeprom checksum, dump the eeprom info when such a situation is encountered by a user. Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/e1000/e1000_main.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 5b129964e832..7f5b2ae70d5d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -818,6 +818,64 @@ e1000_reset(struct e1000_adapter *adapter)
818} 818}
819 819
820/** 820/**
821 * Dump the eeprom for users having checksum issues
822 **/
823void e1000_dump_eeprom(struct e1000_adapter *adapter)
824{
825 struct net_device *netdev = adapter->netdev;
826 struct ethtool_eeprom eeprom;
827 const struct ethtool_ops *ops = netdev->ethtool_ops;
828 u8 *data;
829 int i;
830 u16 csum_old, csum_new = 0;
831
832 eeprom.len = ops->get_eeprom_len(netdev);
833 eeprom.offset = 0;
834
835 data = kmalloc(eeprom.len, GFP_KERNEL);
836 if (!data) {
837 printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
838 " data\n");
839 return;
840 }
841
842 ops->get_eeprom(netdev, &eeprom, data);
843
844 csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
845 (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
846 for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
847 csum_new += data[i] + (data[i + 1] << 8);
848 csum_new = EEPROM_SUM - csum_new;
849
850 printk(KERN_ERR "/*********************/\n");
851 printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
852 printk(KERN_ERR "Calculated : 0x%04x\n", csum_new);
853
854 printk(KERN_ERR "Offset Values\n");
855 printk(KERN_ERR "======== ======\n");
856 print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
857
858 printk(KERN_ERR "Include this output when contacting your support "
859 "provider.\n");
860 printk(KERN_ERR "This is not a software error! Something bad "
861 "happened to your hardware or\n");
862 printk(KERN_ERR "EEPROM image. Ignoring this "
863 "problem could result in further problems,\n");
864 printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
865 printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
866 "which is invalid\n");
867 printk(KERN_ERR "and requires you to set the proper MAC "
868 "address manually before continuing\n");
869 printk(KERN_ERR "to enable this network device.\n");
870 printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
871 "to your hardware vendor\n");
872 printk(KERN_ERR "or Intel Customer Support: linux-nics@intel.com\n");
873 printk(KERN_ERR "/*********************/\n");
874
875 kfree(data);
876}
877
878/**
821 * e1000_probe - Device Initialization Routine 879 * e1000_probe - Device Initialization Routine
822 * @pdev: PCI device information struct 880 * @pdev: PCI device information struct
823 * @ent: entry in e1000_pci_tbl 881 * @ent: entry in e1000_pci_tbl
@@ -968,7 +1026,6 @@ e1000_probe(struct pci_dev *pdev,
968 adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw); 1026 adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
969 1027
970 /* initialize eeprom parameters */ 1028 /* initialize eeprom parameters */
971
972 if (e1000_init_eeprom_params(&adapter->hw)) { 1029 if (e1000_init_eeprom_params(&adapter->hw)) {
973 E1000_ERR("EEPROM initialization failed\n"); 1030 E1000_ERR("EEPROM initialization failed\n");
974 goto err_eeprom; 1031 goto err_eeprom;
@@ -980,23 +1037,29 @@ e1000_probe(struct pci_dev *pdev,
980 e1000_reset_hw(&adapter->hw); 1037 e1000_reset_hw(&adapter->hw);
981 1038
982 /* make sure the EEPROM is good */ 1039 /* make sure the EEPROM is good */
983
984 if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) { 1040 if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
985 DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n"); 1041 DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
986 goto err_eeprom; 1042 e1000_dump_eeprom(adapter);
1043 /*
1044 * set MAC address to all zeroes to invalidate and temporary
1045 * disable this device for the user. This blocks regular
1046 * traffic while still permitting ethtool ioctls from reaching
1047 * the hardware as well as allowing the user to run the
1048 * interface after manually setting a hw addr using
1049 * `ip set address`
1050 */
1051 memset(adapter->hw.mac_addr, 0, netdev->addr_len);
1052 } else {
1053 /* copy the MAC address out of the EEPROM */
1054 if (e1000_read_mac_addr(&adapter->hw))
1055 DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
987 } 1056 }
988 1057 /* don't block initalization here due to bad MAC address */
989 /* copy the MAC address out of the EEPROM */
990
991 if (e1000_read_mac_addr(&adapter->hw))
992 DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
993 memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); 1058 memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
994 memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); 1059 memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
995 1060
996 if (!is_valid_ether_addr(netdev->perm_addr)) { 1061 if (!is_valid_ether_addr(netdev->perm_addr))
997 DPRINTK(PROBE, ERR, "Invalid MAC Address\n"); 1062 DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
998 goto err_eeprom;
999 }
1000 1063
1001 e1000_get_bus_info(&adapter->hw); 1064 e1000_get_bus_info(&adapter->hw);
1002 1065