Hello,
I currently ran into this problem and had a fix for it. It will be great if
someone can tell me if there is anything wrong with this fix?
Both the interfaces are up on the local machine and switch. Ethool returns Link
detected yes, speed and duplex.
Settings for lan2_0:
Supported ports: [ FIBRE ]
Supported link modes: 1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Port: FIBRE
PHYAD: 0
Transceiver: external
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000001 (1)
Link detected: yes
Shutdown the interface on the switch. Ethool returns Link detected no and
mistakenly print out speed and duplex.
Settings for lan2_0:
Supported ports: [ FIBRE ]
Supported link modes: 1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Speed: 1000Mb/s <---------- should be Unknown!
Duplex: Full <------------ should be Unknown!
Port: FIBRE
PHYAD: 0
Transceiver: external
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000001 (1)
Link detected: no <----------- Link is down
Added some printk statements and I have tracked it down to the following code
e1000_get_settings()
if (netif_running(netdev)) {
if (netif_carrier_ok(netdev)) {
ecmd->speed = adapter->link_speed;
ecmd->duplex = adapter->link_duplex - 1;
}
} else {
u32 status = er32(STATUS);
if (status & E1000_STATUS_LU) { <----------
The code checks bit-2 of STATUS register to determine if there the link is up
or not.
if (status & E1000_STATUS_SPEED_1000)
ecmd->speed = 1000;
else if (status & E1000_STATUS_SPEED_100)
ecmd->speed = 100;
else
ecmd->speed = 10;
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
}
}
Checked the Intel 82574 Gbe Controller Family datasheet, section 10.2.2.2 has
the following information about this bit.
"Link Up
0b = No link establish
1b = Link establish. For this to be valid, the Set Link Up bit of the Device
Control (CTRL.SU) register must be set."
So, it looks like just checking this bit may not be a reliable way to determine
if link is up and that's why this problem don't show up on some other machines.
Next, I change the code to call netif_carrier_ok() (the way ethtool detects
link up/down). The speed and duplex printed as "Unknown!" which is the expected
result.
if (netif_running(netdev)) {
if (netif_carrier_ok(netdev)) {
ecmd->speed = adapter->link_speed;
ecmd->duplex = adapter->link_duplex - 1;
}
} else {
if (netif_carrier_ok(netdev)) {
<--------- Change is made here.
u32 status = er32(STATUS);
if (status & E1000_STATUS_SPEED_1000)
ecmd->speed = 1000;
else if (status & E1000_STATUS_SPEED_100)
ecmd->speed = 100;
else
ecmd->speed = 10;
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
}
}
Thanks and Regards,
--Steven
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit
http://communities.intel.com/community/wired