forked from Minki/linux
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>
This commit is contained in:
parent
8b32e63d48
commit
67b3c27c8a
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user