From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080203 SUSE/2.0.0.12-0.2 Firefox/2.0.0.12 Description of problem: I'm seeing what I consider a problem with getting link status via SIOCETHTOOL and the e1000e driver. According to all the data I have and based on how the e1000/e100/tg3 and any broadcom driver works if I issue something like the following: edata.cmd = ETHTOOL_GLINK; ifr.ifr_data = (caddr_t)&edata; if (ioctl(mii_socket, SIOCETHTOOL, &ifr) != 0 ){ printf("errno: %d, %s\n", errno, strerror(errno)); } else { printf("status for %s: 0x%x\n", if_name, edata.data); } I would/should get an edata.data value of 1 for link up and 0 for link down. Here is an example on an interface that uses the tg3 driver: [root@ ~]# ./test eth0 mii_socket: 3 Proper MII ioctl for eth0 is SIOCETHTOOL. status for eth0: 0x1 The link is up and I get a 1. Same test on a nic with the e1000e driver shows: [root@ ~]# ./test eth4 mii_socket: 3 Proper MII ioctl for eth4 is SIOCETHTOOL. status for eth4: 0x2 The link is definately up and connected but instead of showing a status of 1 it give me 2. If I unplug the link it does give me a 0 (as expected). Information I received when I reported this to the e1000 alias: Yup, it's known and already fixed in-house. Essentially, the return from e1000_get_link() should be something like: return ((status & E1000_STATUS_LU) ? 1 : 0); According to other information, this fix will be included in an aug 15 submittal to kernel.org. This fix needs to be in 5.3 and 5.2 if possible. Version-Release number of selected component (if applicable): kernel-2.6.18-92.el5 How reproducible: Always Steps to Reproduce: 1. setup an nic that uses the e1000e driver (actually I don't even believe the interface needs to be up, just connected to a network). 2. Run the test program included in the additional information section. 3. Actual Results: With a cable connected to the NIC it returns 2. Expected Results: It should return 1. Additional info: Sample program to see behavior: #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <netdb.h> #include <sys/uio.h> #include <arpa/inet.h> #include <fcntl.h> #include <net/route.h> #include <net/if_arp.h> #include <linux/if.h> #include <linux/if_ether.h> #include <linux/if_packet.h> #include <linux/if_bonding.h> #include <linux/sockios.h> #include <endian.h> #ifndef SIOCETHTOOL #define SIOCETHTOOL (0x8946) #endif #ifndef SIOCGMIIPHY #define SIOCGMIIPHY (0x8947) #endif #ifndef SIOCGMIIREG #define SIOCGMIIREG (0x8948) #endif #define ETHTOOL_GSET 0x00000001 /* Get settings. */ #define ETHTOOL_SSET 0x00000002 /* Set settings, privileged. */ #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ #define ETHTOOL_GREGS 0x00000004 /* Get NIC registers, privileged. */ #define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */ #define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options, priv. */ #define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ #define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */ #define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv. */ #define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */ #define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ #define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data, priv. */ #define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ #define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config, priv. */ #define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ #define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ #define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ #define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters, priv. */ #define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ #define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ /* for passing single values */ struct ethtool_value { unsigned int cmd; unsigned int data; }; extern int errno; main(int argc, char ** argv) { int mii_socket; int mii_ioctl; char if_name[10]; struct ifreq ifr; struct ethtool_value edata; unsigned short *data = (unsigned short *) &ifr.ifr_data; if (argc == 1) { printf("usage: %s <ethX>\n", argv[0]); exit(1); } strcpy(if_name ,argv[1]); sprintf(ifr.ifr_name, "%s", if_name); edata.cmd = ETHTOOL_GLINK; ifr.ifr_data = (caddr_t)&edata; mii_socket = socket(AF_INET, SOCK_DGRAM, 0); if (mii_socket < 0 ) { printf ("MII link status socket open failed: %s\n", strerror(errno)); exit(1); } printf("mii_socket: %d\n", mii_socket); mii_ioctl = ioctl(mii_socket, SIOCETHTOOL, &ifr); if (mii_ioctl == 0 ) { printf("Proper MII ioctl for %s is SIOCETHTOOL.\n", if_name); } else { printf ("error, mii_ioctl: %u\n", mii_ioctl); exit (1); } edata.cmd = ETHTOOL_GLINK; ifr.ifr_data = (caddr_t)&edata; if (ioctl(mii_socket, SIOCETHTOOL, &ifr) != 0 ){ printf("errno: %d, %s\n", errno, strerror(errno)); } else { printf("status for %s: 0x%x\n", if_name, edata.data); } }
Andy, I see that this change was submitted by Intel upstream and Dave Miller has taken it into his tree: http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=56e1f82968af79f70902008098a4687198142ce7. Are these changes that you have pulled into the 5.3 kernel already? Can it still make 5.3? Bill
Bill, that patch will get included.
Andy, Thanks. Let us know if you have a test kernel to try.
Adding myself to cc list.
My test kernels have been updated to include a patch for this bugzilla. http://people.redhat.com/agospoda/#rhel5 Please test them and report back your results.
I will download the kernel and give it a try. It may take a day or two to gain access to the system. Will let you know the results.
I have tested with this new kernel. Results are good. The postfix results show: fixed kernel for e1000e driver [root@pltest12 ~]# uname -a Linux pltest12.cup.hp.com 2.6.18-106.el5.gtest.54 #1 SMP Wed Aug 27 17:12:29 EDT 2008 i686 athlon i386 GNU/Linux [root@pltest12 ~]# ./test eth0 mii_socket: 3 Proper MII ioctl for eth0 is SIOCETHTOOL. status for eth0: 0x0 [root@pltest12 ~]# ./test eth1 mii_socket: 3 Proper MII ioctl for eth1 is SIOCETHTOOL. status for eth1: 0x1 [root@pltest12 ~]# ./test eth2 mii_socket: 3 Proper MII ioctl for eth2 is SIOCETHTOOL. status for eth2: 0x0 [root@pltest12 ~]# ./test eth3 mii_socket: 3 Proper MII ioctl for eth3 is SIOCETHTOOL. status for eth3: 0x0 eth0-3: e1000e, eth0,2, 3 are not connected, eth1 is connected. In the above eth0-3 are all using the e1000e driver. eth1 is the nic that is connected the others are not. Running my test program (included in the original bugzilla submittal) shows that for eth0,2 and 3 the status is 0x0 and for eth1 its 0x1 which is correct. Previous results would show this as 0x2.
This is in 5.3 kernels. Closing.