0

I have just installed FreeBSD (11.0-RELEASE-p1) on a system with the Intel I219-V network adapter. This version of FreeBSD has em v7.6.1, which (I believe...maybe it's just the EEPROM checksum error? Read on...) doesn't support this network chipset, so I sought out the updated version, v7.6.2, from Intel's website.

Following the readme, I installed like so:

  1. Untar/unzip
  2. make
  3. make install
  4. Add if_em_load="YES" to /boot/loader.conf
  5. Add ifconfig_em0="DHCP" to /etc/rc.conf

After rebooting, I still receive the following messages in dmesg.boot:

module_register: cannot register pci/em from kernel; already loaded from if_em.ko
Module pci/em failed to register: 17
...
em0: <Intel (R) PRO/1000 Network Connection 7.6.1-k> mem 0xdf300000-0xdf31ffff irq 16 at device 31.6 on pci0
em0: Using an MSI interrupt
em0: The EEPROM Checksum Is Not Valid
device_attach: em0 attach returned 5

And the adapter is not recognized by the system.

There are two things to notice here--the bad checksum, which I will return to later, and the fact that v.7.6.1 is loading, even though I've just installed v7.6.2!

I tried to find out where each version is living:

$ strings /boot/kernel/if_em.ko
...
7.6.1-k
...
$ strings /boot/modules/if_em.ko
...
7.6.2
...

So, the if_em_load="YES" is loading the old em driver found in /boot/kernel. I suppose this isn't surprising since man kldload says it looks there, but /boot/defaults/loader.conf contains module_path="/boot/modules".

Manually loading v7.6.2 via kldload /boot/modules/if_em.ko gives this output:

em0: <Intel (R) PRO/1000 Network Connection 7.6.1-k> mem 0xdf300000-0xdf31ffff irq 16 at device 31.6 on pci0
em0: Using an MSI interrupt
em0: The EEPROM Checksum Is Not Valid
device_attach: em0 attach returned 5
em0: <Intel (R) PRO/1000 Network Connection 7.6.2> mem 0xdf300000-0xdf31ffff irq 16 at device 31.6 on pci0
em0: Using an MSI interrupt
em0: The EEPROM Checksum Is Not Valid
device_attach: em0 attach returned 5

So, still having the EEPROM Checksum issue, but another question is why does the kldload attempt to load v7.6.1 before v7.6.2, which is the file it is explicitly pointed to?

Finally, I decided to see what happens if I ignore the checksum check, which required patching if_em.c and if_lem.c, the two places the string "The EEPROM Checksum Is Not Valid" exist in the driver code.

Like so

--- if_em.c 2017-05-16 01:44:07.189792000 -0700
+++ if_em_patch.c   2017-05-16 01:44:28.885779000 -0700
@@ -730,10 +730,10 @@
        ** if it fails a second time its a real issue.
        */
        if (e1000_validate_nvm_checksum(hw) < 0) {
-           device_printf(dev,
+           /*device_printf(dev,
                "The EEPROM Checksum Is Not Valid\n");
            error = EIO;
-           goto err_late;
+           goto err_late;*/
        }
    }

and like so

--- if_lem.c    2017-05-16 01:39:27.605399000 -0700
+++ if_lem_patch.c  2017-05-16 01:44:47.661294000 -0700
@@ -641,10 +641,10 @@
        ** if it fails a second time its a real issue.
        */
        if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
-           device_printf(dev,
+           /*device_printf(dev,
                "The EEPROM Checksum Is Not Valid\n");
            error = EIO;
-           goto err_hw_init;
+           goto err_hw_init;*/
        }
    }

Now, a make; make install; restart still gives me v7.6.1 in dmesg.boot, but running kldunload if_em; kldload /boot/modules/if_em.ko gives output like:

em0: <Intel (R) PRO/1000 Network Connection 7.6.1-k> mem 0xdf300000-0xdf31ffff irq 16 at device 31.6 on pci0
em0: Using an MSI interrupt
em0: The EEPROM Checksum Is Not Valid
device_attach: em0 attach returned 5
em0: <Intel (R) PRO/1000 Network Connection 7.6.2> mem 0xdf300000-0xdf31ffff irq 16 at device 31.6 on pci0
em0: Using an MSI interrupt
em0: Ethernet address: xx:xx:xx:xx:xx:xx

It works! And I can get an IP via dhclient em0 and ping 8.8.8.8 goes fine.

So, here are my questions:

  1. Why is my EEPROM checksum wrong? I haven't done anything that could mess with the firmware or whatever this is. What can I do that fixes this (that isn't prefaced with a disclaimer à la "this shouldn't work for integrated adapters," like all the answers I've found--e.g. this one)?
  2. Why is the kernel still loading v7.6.1 when I explicitly tell it to load v7.6.2 with kldload /boot/modules/if_em.ko?
  3. Why is the kernel loading v7.6.1 at boot when module_path="/boot/modules" in /boot/defaults/loader.conf? What can I do to only load v7.6.2? Do I have to delete /boot/kernel/if_em.ko? That seems slightly wrong.

I understand that I get to enjoy the "fun" (and really, it is fun) of getting all my hardware and software to work correctly when I choose to run FreeBSD, but this seems like a little much.

EDIT: After updating to 11.0-RELEASE-p9 now that network connectivity existed, the same problems remain with no change.

1

em0: The EEPROM Checksum Is Not Valid

As you write the EEPROM checksum is related to the firmware. I believe that you have found the fix yourself. The disclaimers seems to date back from the old ibautil days. This one reports success with Supermicro boards with builtin NICs and someone with an Intel D975XBX2.

I would download the latest version and make sure that I was able to list my adapter. If so - I would not be so scared to try to reset the PXE configuration. But YMMV.

The suggested fix for wrong checksum is to reset the PXE default configuration using:

bootutil -nic=1 -defcfg

-- or --

bootutil -all -defcfg

The options can be found in bootutil.txt

module_path

You should verify how module_path is actually set on your system. You can do this with kenv.

# kenv module_path
/boot/kernel;/boot/modules

You can also verify it using kldconfig which even hints the solution:

# kldconfig -r
/boot/kernel;/boot/modules

It is module_path which determines the order and where to look for .ko files. The default is set in sys/boot/common/module.c. This would have been easier to understand if module_path was removed from /boot/defaults/loader.conf or conf/73535 was implemented. I have been confused by this as well.

You can change it using kldconfig.

As /boot/kernel is updated by the system and part of the FreeBSD base system it may be wise not to touch it. On the other hand changing the path order might give surprises as well. I have seen other people suggest making a softlink from /boot/kernel.

  • This worked, using BOOTUTILW64E.EXE from Windows on the same computer and the options you mentioned. I'm still a bit confused why kldload /path/to/module.ko still looks through module_path before going to the absolute path provided, but that can be a problem for another time. After reflashing the firmware, the v7.6.1-k driver works fine on boot. – Scott Colby May 18 '17 at 0:07
  • Great! If you specify a valid absolute path and module_path is searched first - then I would consider it a bug. But if you get an error such as "module already loaded" then it makes more sense. The loading code is in module.c – Claus Andersen May 18 '17 at 11:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.