|
@@ -817,6 +817,64 @@ e1000_reset(struct e1000_adapter *adapter)
|
|
|
e1000_release_manageability(adapter);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Dump the eeprom for users having checksum issues
|
|
|
+ **/
|
|
|
+void e1000_dump_eeprom(struct e1000_adapter *adapter)
|
|
|
+{
|
|
|
+ struct net_device *netdev = adapter->netdev;
|
|
|
+ struct ethtool_eeprom eeprom;
|
|
|
+ const struct ethtool_ops *ops = netdev->ethtool_ops;
|
|
|
+ u8 *data;
|
|
|
+ int i;
|
|
|
+ u16 csum_old, csum_new = 0;
|
|
|
+
|
|
|
+ eeprom.len = ops->get_eeprom_len(netdev);
|
|
|
+ eeprom.offset = 0;
|
|
|
+
|
|
|
+ data = kmalloc(eeprom.len, GFP_KERNEL);
|
|
|
+ if (!data) {
|
|
|
+ printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
|
|
|
+ " data\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ ops->get_eeprom(netdev, &eeprom, data);
|
|
|
+
|
|
|
+ csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
|
|
|
+ (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
|
|
|
+ for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
|
|
|
+ csum_new += data[i] + (data[i + 1] << 8);
|
|
|
+ csum_new = EEPROM_SUM - csum_new;
|
|
|
+
|
|
|
+ printk(KERN_ERR "/*********************/\n");
|
|
|
+ printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
|
|
|
+ printk(KERN_ERR "Calculated : 0x%04x\n", csum_new);
|
|
|
+
|
|
|
+ printk(KERN_ERR "Offset Values\n");
|
|
|
+ printk(KERN_ERR "======== ======\n");
|
|
|
+ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
|
|
|
+
|
|
|
+ printk(KERN_ERR "Include this output when contacting your support "
|
|
|
+ "provider.\n");
|
|
|
+ printk(KERN_ERR "This is not a software error! Something bad "
|
|
|
+ "happened to your hardware or\n");
|
|
|
+ printk(KERN_ERR "EEPROM image. Ignoring this "
|
|
|
+ "problem could result in further problems,\n");
|
|
|
+ printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
|
|
|
+ printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
|
|
|
+ "which is invalid\n");
|
|
|
+ printk(KERN_ERR "and requires you to set the proper MAC "
|
|
|
+ "address manually before continuing\n");
|
|
|
+ printk(KERN_ERR "to enable this network device.\n");
|
|
|
+ printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
|
|
|
+ "to your hardware vendor\n");
|
|
|
+ printk(KERN_ERR "or Intel Customer Support: linux-nics@intel.com\n");
|
|
|
+ printk(KERN_ERR "/*********************/\n");
|
|
|
+
|
|
|
+ kfree(data);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* e1000_probe - Device Initialization Routine
|
|
|
* @pdev: PCI device information struct
|
|
@@ -968,7 +1026,6 @@ e1000_probe(struct pci_dev *pdev,
|
|
|
adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
|
|
|
|
|
|
/* initialize eeprom parameters */
|
|
|
-
|
|
|
if (e1000_init_eeprom_params(&adapter->hw)) {
|
|
|
E1000_ERR("EEPROM initialization failed\n");
|
|
|
goto err_eeprom;
|
|
@@ -980,23 +1037,29 @@ e1000_probe(struct pci_dev *pdev,
|
|
|
e1000_reset_hw(&adapter->hw);
|
|
|
|
|
|
/* make sure the EEPROM is good */
|
|
|
-
|
|
|
if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
|
|
|
DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
|
|
|
- goto err_eeprom;
|
|
|
+ e1000_dump_eeprom(adapter);
|
|
|
+ /*
|
|
|
+ * set MAC address to all zeroes to invalidate and temporary
|
|
|
+ * disable this device for the user. This blocks regular
|
|
|
+ * traffic while still permitting ethtool ioctls from reaching
|
|
|
+ * the hardware as well as allowing the user to run the
|
|
|
+ * interface after manually setting a hw addr using
|
|
|
+ * `ip set address`
|
|
|
+ */
|
|
|
+ memset(adapter->hw.mac_addr, 0, netdev->addr_len);
|
|
|
+ } else {
|
|
|
+ /* copy the MAC address out of the EEPROM */
|
|
|
+ if (e1000_read_mac_addr(&adapter->hw))
|
|
|
+ DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
|
|
|
}
|
|
|
-
|
|
|
- /* copy the MAC address out of the EEPROM */
|
|
|
-
|
|
|
- if (e1000_read_mac_addr(&adapter->hw))
|
|
|
- DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
|
|
|
+ /* don't block initalization here due to bad MAC address */
|
|
|
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
|
|
|
memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
|
|
|
|
|
|
- if (!is_valid_ether_addr(netdev->perm_addr)) {
|
|
|
+ if (!is_valid_ether_addr(netdev->perm_addr))
|
|
|
DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
|
|
|
- goto err_eeprom;
|
|
|
- }
|
|
|
|
|
|
e1000_get_bus_info(&adapter->hw);
|
|
|
|