Intel Ethernet Connection I219-V not working under Linux on an ASUSPRO B laptop, e1000e driver reports: "The NVM Checksum Is Not Valid"
The e1000e
driver is the one that can run the I2xx
intel Ethernet Controllers. And the latest e1000e driver (as of this writing) is capable of running the I219
chip.
The The NVM Checksum Is Not Valid
message during boot is what was preventing the older drivers from being loaded. On other OSes (notably MS windows) that error is ignored. But Linux appears to be stricter.
NVM is a ROM (read only memory) in the chip, which undergoes a checksum, and the older version of the e1000
driver was not aware of the NVM contents of the newer chips. Since the card works on other OSes that ignore the error another possibility could have been to force the driver to ignore the error.
The checksum is performed inside nvm.c
, although other several models present their own fix_checksum
functions that run before e1000e_validate_nvm_checksum_generic
.
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
checksum += nvm_data;
}
if (checksum != (u16)NVM_SUM) {
e_dbg("NVM Checksum Invalid\n");
return -E1000_ERR_NVM;
}
return 0;
}
NVM_SUM
is defined inside define.h
#define NVM_SUM 0xBABA
If you are confident that the card runs (and only fails because of the NVM checksum) you can try to edit the checksum function to:
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
return 0;
}
And it will force the checksum to be always successful.
Extra (more-or-less) trustworthy references:
- Apparently MS windows do simply ignore this error
- RedHat do fix NVM checksum errors by commenting out the error from the code
I managed to fix the checksum. Now Ethernet works fine under Linux. I explained the details in my answer to my SuperUser.SE question.
Basically, I first patched e1000e
to skip the NVM checksum validation
for (i = 0;; i++) {
if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
break;
if (i == 2) {
dev_err(pci_dev_to_dev(pdev),
"The NVM Checksum Is Not Valid\n");
err = -EIO;
goto err_eeprom;
}
}
in src/netdev.c
, and after I had access to the Ethernet chip, I wrote to its NVM with ethtool
, which automatically fixed the checksum.