Jump to content
hnak

AppleIntelE1000e.kext for 10.8/10.7/10.6/10.5

768 posts in this topic

Recommended Posts

Yes, WoL is enabled.

 

For the windows driver to enable WoL after a shutdown (from windows), we have to set some settings in device. If you tick "Wake on network access" on mac os, nothing seems to happend in the driver.

 

should it be passed another way than "IOReturn AppleIntelE1000e::setWakeOnMagicPacket(bool active)" to the driver ?

You can try by modifying code to set adapter->wol = 1 before calling __e1000_shutdown().

I found the WOL works with i217v, but not with 82579.  I found "phy wakup / mac wakeup" comment by the Linux driver author in  __e1000_shutdown, which may be related to the behavior.

Share this post


Link to post
Share on other sites
Advertisement

You can try by modifying code to set adapter->wol = 1 before calling __e1000_shutdown().

I found the WOL works with i217v, but not with 82579.  I found "phy wakup / mac wakeup" comment by the Linux driver author in  __e1000_shutdown, which may be related to the behavior.

 

As OS X doesn't support WoL from S5 officially, it doesn't call setWakeOnMagicPacket() on shutdown so that there is no clean solution. You have to resort to "some dirty trick" in order to get it working, i.e. enable WoL in systemWillShutdown().

 

Mieze

Share this post


Link to post
Share on other sites
I have 3 MBs with onboard Intel NIC.

 

The following MBs wake up from power-off (even with the previous driver) :

Gigabyte GA-Z97X-UD7 TH (i217)

Asrock H97M Pro4 (i218v2)

 


The following MB does not wake up:

Intel DH68DB (82579)

 


It seems whether WOL works or not depends on BIOS/UEFI/Hardware.

I have not investigated the differences of the settings among the MBs, but WOL is enabled.

Share this post


Link to post
Share on other sites

You can try by modifying code to set adapter->wol = 1 before calling __e1000_shutdown().

I found the WOL works with i217v, but not with 82579.  I found "phy wakup / mac wakeup" comment by the Linux driver author in  __e1000_shutdown, which may be related to the behavior.

 

I will investigate that.

 

As OS X doesn't support WoL from S5 officially, it doesn't call setWakeOnMagicPacket() on shutdown so that there is no clean solution. You have to resort to "some dirty trick" in order to get it working, i.e. enable WoL in systemWillShutdown().

 

Mieze

 

It's not realy an OS issue, I think. To me, it's more like put the NIC in the previous state that bios setup before the driver drives it.

 

Without the driver, WoL works. So, the driver is setting the NIC in the "wrong" state as its (driver's) "default" behavior is to power off NIC on shutdown/sleep. A "backup/restore" state should do the trick, so, it could be clean, right ?

Share this post


Link to post
Share on other sites

It's not realy an OS issue, I think. To me, it's more like put the NIC in the previous state that bios setup before the driver drives it.

 

Without the driver, WoL works. So, the driver is setting the NIC in the "wrong" state as its (driver's) "default" behavior is to power off NIC on shutdown/sleep. A "backup/restore" state should do the trick, so, it could be clean, right ?

 

It is an OS X issue because of the lack of an interface how to enable WoL from S5.

 

Let's take a look on the sequence when the machine is going to S3 and WoL is enabled in System Preferences:

  1. The driver's setWakeOnMagicPacket() method gets called.
  2. The driver's disable() method gets called.
  3. The driver's setPowerState() method gets called.

When the system shuts down you only get one call from the OS:

  1. systemWillShutdown() where you have to take any actions required to stop the driver and put the NIC into the correct state.

The problem is that the driver doesn't get any information if it should enable WoL or not when the system is going down. You'll have to disabled it, as specified by the OS X, or enabled it regardless of the setting.

 

Mieze

Share this post


Link to post
Share on other sites

It is an OS X issue because of the lack of an interface how to enable WoL from S5.

 

Let's take a look on the sequence when the machine is going to S3 and WoL is enabled in System Preferences:

 

  • The driver's setWakeOnMagicPacket() method gets called.
  • The driver's disable() method gets called.
  • The driver's setPowerState() method gets called.
When the system shuts down you only get one call from the OS:

  • systemWillShutdown() where you have to take any actions required to stop the driver and put the NIC into the correct state.
The problem is that the driver doesn't get any information if it should enable WoL or not when the system is going down. You'll have to disabled it, as specified by the OS X, or enabled it regardless of the setting.

 

Mieze

Thanks for the information, now I have a better understanding of the OS side issue.

Maybe we could read at least the BIOS setting in the firmware ?

Share this post


Link to post
Share on other sites

Thanks for the information, now I have a better understanding of the OS side issue.

Maybe we could read at least the BIOS setting in the firmware ?

It is already acquired in the line:

adapter->eeprom_wol |= E1000_WUFC_MAG;

Share this post


Link to post
Share on other sites

I was running with version 3.0.4, which I just swapped out with a kextunload, copied in the latest, and kextload-ed it.

I'm awaiting results on this version, but with 3.0.4, when I attempted to run a Time Machine backup to my Time Capsule, or attempted to copy previous backups over my (unfortunately) 100Mbps link (spliced cable for reasons), it will eventually lose connection after about 13GB of transfer, due to the TX unit hardware hang.

This may be relevant, including the fix, which is probably impossible to do on OS X: http://serverfault.com/questions/193114/linux-e1000e-intel-networking-driver-problems-galore-where-do-i-start

Based on some feedback from a friend regarding Linux kernel drivers, how do I disable all of the "smart" features, like all the hardware offload things that are normally disabled by default in Windows? EDIT: Like Large Send Offload, which is buggy. (Ah, would that be TSO?)

 

EDIT 2: It appeared again with the latest version. Yes, it does seem I can reset the device and try again by kextunload/kextload cycling it. And I disabled TSO this time, we'll see if it fixes my issue.

 

Issue is specifically trying to copy 29 old local Time Machine backups to a newly purchased Time Capsule, totaling 130GB or 330k files, most of them mirrored throughout the set by the hard links that Finder is optimizing back into hardlinks on the target when it performs the copy.

 

Somebody remind me again why TSO is enabled by default? Because the Linux driver does it? Note how the Windows driver disables it by default, and often times, it actually slows down the connection throughput.

Share this post


Link to post
Share on other sites

 

Somebody remind me again why TSO is enabled by default? Because the Linux driver does it? Note how the Windows driver disables it by default, and often times, it actually slows down the connection throughput.

No other reason.

I will change the default to false in future releases.

Share this post


Link to post
Share on other sites

No other reason.

I will change the default to false in future releases.

 

Thank you.

 

I just thought I'd like to point out, that this feature is not broken through any fault of your own. It is likely broken in the hardware implementation, and that is why it is off by default. The fact that it can still be turned on in Windows is probably so know-it-alls can try to turn it back on, only to eventually discover why it was turned off in the first place.

 

Linux team was probably independent of the Windows team, so was not aware of the design error, or hadn't dealt with it enough.

 

I have an experienced and apparently wise Windows and Unix developer friend who even asked me about fragmentation offload when I told him about problems with my Intel NIC.

 

Then one of our other friends tried turning it on with his Windows machine, and found his gigabit line throughput decreased by 9% when he did so, and turned it back off again.

 

Incidentally, turning that off has fixed my lengthy copy operation, and I have not had any further TX unit failures since. At least experienced users may be interested to know that such a string of failures is soft recoverable, as the hardware appears to reset itself if the kext is unloaded and reloaded. Handy way to test out whether that TSO flag has any effect on things, at least.

Share this post


Link to post
Share on other sites

I just thought I'd like to point out, that this feature is not broken through any fault of your own. It is likely broken in the hardware implementation, and that is why it is off by default. The fact that it can still be turned on in Windows is probably so know-it-alls can try to turn it back on, only to eventually discover why it was turned off in the first place.

 

Linux team was probably independent of the Windows team, so was not aware of the design error, or hadn't dealt with it enough.

 

I have an experienced and apparently wise Windows and Unix developer friend who even asked me about fragmentation offload when I told him about problems with my Intel NIC.

 

Then one of our other friends tried turning it on with his Windows machine, and found his gigabit line throughput decreased by 9% when he did so, and turned it back off again.

 

Incidentally, turning that off has fixed my lengthy copy operation, and I have not had any further TX unit failures since. At least experienced users may be interested to know that such a string of failures is soft recoverable, as the hardware appears to reset itself if the kext is unloaded and reloaded. Handy way to test out whether that TSO flag has any effect on things, at least.

 

I'm sorry, but most of what you said is completely wrong:

  • Intel's Windows driver suite enables all the offload features by default, at least for recent NICs.
  • If TSO is broken it can be easily fixed with a new firmware image and this is the way it is done in the Windows world, but as parts of the Linux community reject proprietary firmware that is the point where the trouble starts.
  • Linux and OS X are different with regard to the network system making it hard to port a driver. Most of the code needs to be rewritten in order to get a stable driver. Warping some kind of compatibility layer around the linux driver is definitely the wrong approach and almost inevitably results in a broken driver. I checked the driver's code and I would be very surprised if it works properly the way it was designed. Much of the code, in particular outputPacket() needs a complete rewrite in order to get rid of the linux overhead.
  • TSO was designed to lower CPU usage, not to speed up network operation because any recent CPU is able to handle a gigabit connection at full speed without problems.
  • It is true that TSO might cause serious speed issues because it has an impact on timing, in particular on the TCP data flow. That's the reason why you experience a speedup sometimes after TSO has been disabled.

Mieze

Share this post


Link to post
Share on other sites

 Warping some kind of compatibility layer around the linux driver is definitely the wrong approach and almost inevitably results in a broken driver. I checked the driver's code and I would be very surprised if it works properly the way it was designed. Much of the code, in particular outputPacket() needs a complete rewrite in order to get rid of the linux overhead.

The decision was made to keep up with Linux update pace with minimal effort in the first place - I wanted to use Linux code without modification.

About outputPacket(), what kind of Linux overhead would you suggest to remove ?

Share this post


Link to post
Share on other sites

The decision was made to keep up with Linux update pace with minimal effort in the first place - I wanted to use Linux code without modification.

About outputPacket(), what kind of Linux overhead would you suggest to remove ?

Usually it's best to rewrite all the code involved with descriptor handling, starting from allocation, outputPacket(), rx/tx interrupt handling up to the cleanup routines when the driver gets disabled. This also allows to use IOBasicOutputQueue for concurrent tx/rx operations as both can be synchronized by starting/stoping the output queue.

 

Of course this makes updating the linux code basis much harder and would be a lot of work.

 

With regard to offload features (checksum calculation and TSO), it helps to read the Microsoft specification as OS X seems to conform widely to it. Besides that, I found out some facts which make it easier to implement the code:

  • OS X doesn't offload packets with IPv4 header options/IPv6 extension headers for checksumming and TSO, so that the level 4 protocol header offset is always fixed, but there might be TCP options!
  • For TSO there is no need to calculate the pseudo header checksum yourself because the network stack already placed it in the TCP checksum field of the TCP header when it offloads a packet. The IP header's checksum filed is zeroed too as stipulated by the MS specs.
  • Most NICs, including those from Intel, require the complete headers (L2, L3 and L4) to be found in the first buffer for TSO so that a mbuf_pullup()-operation is usually required.

Mieze

Share this post


Link to post
Share on other sites

Usually it's best to rewrite all the code involved with descriptor handling, starting from allocation, outputPacket(), rx/tx interrupt handling up to the cleanup routines when the driver gets disabled. This also allows to use IOBasicOutputQueue for concurrent tx/rx operations as both can be synchronized by starting/stoping the output queue.

 

Of course this makes updating the linux code basis much harder and would be a lot of work.

 

With regard to offload features (checksum calculation and TSO), it helps to read the Microsoft specification as OS X seems to conform widely to it. Besides that, I found out some facts which make it easier to implement the code:

  • OS X doesn't offload packets with IPv4 header options/IPv6 extension headers for checksumming and TSO, so that the level 4 protocol header offset is always fixed, but there might be TCP options!
  • For TSO there is no need to calculate the pseudo header checksum yourself because the network stack already placed it in the TCP checksum field of the TCP header when it offloads a packet. The IP header's checksum filed is zeroed too as stipulated by the MS specs.
  • Most NICs, including those from Intel, require the complete headers (L2, L3 and L4) to be found in the first buffer for TSO so that a mbuf_pullup()-operation is usually required.

Currently, the driver copies the mbuf content to a continuous memory preallocated at startup and discards it immediately in OutputQueue(). Allocation does not happen during sending packets and pullup is not necessary.

The copy is a synchronous operation and may not be efficient as regard to CPU usage.

 

By the way, what is the benefit of IOBasicOutputQueue? Is concurrent rx/tx beneficial ?

Share this post


Link to post
Share on other sites

Currently, the driver copies the mbuf content to a continuous memory preallocated at startup and discards it immediately in OutputQueue(). Allocation does not happen during sending packets and pullup is not necessary.

The copy is a synchronous operation and may not be efficient as regard to CPU usage.

 

By the way, what is the benefit of IOBasicOutputQueue? Is concurrent rx/tx beneficial ?

 

Instead of copying the mbuf content it is more efficient to use an IOMbufNaturalMemoryCursor in order to create a scatter-gather-list that can be used directly to fill out the descriptors. The mbuf needs  to be attached to the descriptors in any way so that it can be freed by the tx interrupt handler when the request is complete. For an example please see my latest Project, the Atheros driver http://www.insanelymac.com/forum/topic/300056-solution-for-qca-ar816x-ar817x-and-killer-e220x/. It is not as complex as the Realtek driver but implements the same mechanisms.

 

IOBasicOutputQueue doesn't synchronize with the driver's work loop so that outputPacket() will continue to be called while the driver is handling interrupts, e.g. is receiving packets. Besides the speedup of operation you also get rid of the CPU overhead caused by synchronization.

 

Mieze

Share this post


Link to post
Share on other sites

Instead of copying the mbuf content it is more efficient to use an IOMbufNaturalMemoryCursor in order to create a scatter-gather-list that can be used directly to fill out the descriptors. The mbuf needs to be attached to the descriptors in any way so that it can be freed by the tx interrupt handler when the request is complete. For an example please see my latest Project, the Atheros driver http://www.insanelymac.com/forum/topic/300056-solution-for-qca-ar816x-ar817x-and-killer-e220x/. It is not as complex as the Realtek driver but implements the same mechanisms.

 

IOBasicOutputQueue doesn't synchronize with the driver's work loop so that outputPacket() will continue to be called while the driver is handling interrupts, e.g. is receiving packets. Besides the speedup of operation you also get rid of the CPU overhead caused by synchronization.

 

Mieze

The code to copy mbuf is originally for jumbo frame and scatter-gather code exists for long ( I recently disabled it by a macro for simplicity ). IOBasicOutputQueue sounds easy to use. I will check it.

Share this post


Link to post
Share on other sites

The code to copy mbuf is originally for jumbo frame and scatter-gather code exists for long ( I recently disabled it by a macro for simplicity ). IOBasicOutputQueue sounds easy to use. I will check it.

The only thing you have to keep an eye on are the descriptor indices for the tx ring. I maintain 3 variables in my code, next free index, next dirty index and the number of free descriptors. The number of free descriptors is the only variable which gets modified by outputPacket() and txInterrupt() so that I use atomic operations in order modify it.

 

Provided you stop the output queue before any operation in the work loop which also affects the transmitter (chip reset, disable, etc.) there should be no problem at all.

 

Mieze

Share this post


Link to post
Share on other sites

So I've been trying to figure out what @diddl14 did to enable WOL on 2.5.4 so I can replicate it on 2.4.14. So far 2.4.14 has been the only version to be stable in large (>5gb) transfer across the network. Any pointers or help in making this happen? (if its possible)

Share this post


Link to post
Share on other sites

I am also experiencing issues with large file copies and any driver version greater than 2.4.14.  My last attempt was with the 3.1.0 driver and the TSO property set to False.  I was attempting to use Time Machine to backup to a Time Capsule.  I have approximately 300GB of data that I was trying to move.  Looking back in the syslog I started seeing the following:

Aug 12 00:10:00 --- last message repeated 33 times ---

Aug 12 00:10:13 Roberts-Mac-Pro kernel[0]: failed to getphysicalsegment in outputPacket.
 
Finally it just gave up:
Aug 12 00:43:16 Roberts-Mac-Pro kernel[0]: AppleIntelE1000e(Err): Detected Hardware Unit Hang:
 
I have tried multiple configurations and kexts and get the same error with anything over 2.4.14.  With 2.4.14 I have been able to complete my backup without error.  Am I missing out on anything staying with the older driver?  And also, is there anything else I can try to make the 3.1.0 kext work correctly?
 
Thanks

Share this post


Link to post
Share on other sites

sudo kextunload /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext

 

sudo vi /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext/Contents/Info.plist

 

Type:

 

/NETIF_F_TSO<Enter>

 

to find the relevant setting. Change the associated <true/> to <false/>, by moving the cursor to the /, pressing the i key to switch to insert mode, backspace the word, and type in false. Then press Escape, then :wq to write out the file and quit.

 

Then you can reload it with:

 

sudo kextload /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext

 
You're welcome to copy the plist out and make the change with Xcode, but I think that goes a little overboard. Nano -w is also fine, if you already know your way around search, edit, and save with that.
 
As mentioned above, this feature will probably be disabled by default in future releases.
 
Further disputing the usefulness of TSO, when it's already proven to be quite buggy. The fact that it's enabled by default on Windows for some newer chipsets does not mean that it suddenly works properly on older chipsets. Or even that it has been fully tested on newer hardware. Intel probably likes to use their install base as a testbed, then cleans up the mess with later driver releases. You're welcome to argue this, but perhaps for now, you could put a notice in the OP to disable this option if TX unit hangs are encountered, and for future versions, enable it at your own risk.
 
You may also opt to make the edit and reboot instead of using the kextunload/kextload cycle, but I've found that a reboot is not entirely necessary to fix the hardware hang issue, now that I've already had to experience it a few times from attempting to back up over 40GB of data over even just a 100Mbps link. Since making this configuration change, I have been able to back up over 1TB of data over the same link without any errors.

Share this post


Link to post
Share on other sites

sudo vi /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext/Contents/Info.plist

 

Type:

 

/NETIF_F_TSO<Enter>

 

to find the relevant setting. Change the associated <true/> to <false/>, by moving the cursor to the /, pressing the i key to switch to insert mode, backspace the word, and type in false. Then press Escape, then :wq to write out the file and quit.

 

Or this:

 

- Check the value, then set the value, then check the value again:

$sudo /usr/libexec/PlistBuddy -c "Print IOKitPersonalities:e1000e:NETIF_F_TSO" /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext/Contents/Info.plist
Password:
true

sudo /usr/libexec/PlistBuddy -c "Set IOKitPersonalities:e1000e:NETIF_F_TSO false" /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext/Contents/Info.plist

sudo /usr/libexec/PlistBuddy -c "Print IOKitPersonalities:e1000e:NETIF_F_TSO" /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/AppleIntelE1000e.kext/Contents/Info.plist
false

That way you avoid having to teach "vi" to someone, hehe  :D

Share this post


Link to post
Share on other sites

Further disputing the usefulness of TSO, when it's already proven to be quite buggy. The fact that it's enabled by default on Windows for some newer chipsets does not mean that it suddenly works properly on older chipsets. Or even that it has been fully tested on newer hardware. Intel probably likes to use their install base as a testbed, then cleans up the mess with later driver releases. You're welcome to argue this, but perhaps for now, you could put a notice in the OP to disable this option if TX unit hangs are encountered, and for future versions, enable it at your own risk.

 

Instead of complaining about a very useful feature you could just add a few lines of code which print the corresponding descriptors in case of a tx deadlock giving us a chance to find out what is wrong so that we can fix it.

 

Mieze

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×