Date: Thu, 08 May 2003 10:29:06 -0700 (PDT) From: "David S. Miller" <davem@redhat.com> From: Chris Hanson <cph@zurich.ai.mit.edu> Date: Thu, 08 May 2003 14:34:21 -0400 For example, is it sufficient to just set IFF_UP and leave the other flags off? Setting this interface flag from userspace should work. OK, but... (I bet you thought this conversation was finished :) This seems to work most of the time, except for one of my users. He's using the sis900 driver in kernel 2.4.21-rc1. When I don't force the interface up, my code is able to detect link beat with no trouble. When I _do_ force the interface up, it doesn't. Any ideas why this would be true? I've tried a number of different things and have failed to come up with a working configuration, other than to leave the interface down when it is already down. I did notice that the sis900 doesn't seem to immediately detect link-beat when it is up, instead deferring to a timer event, but sleeping for a full second after bringing the interface up didn't change anything. FYI, here is my current detection code. Perhaps there's something wrong with it, although it's quite similar to mii-diag. Chris static unsigned int get_link_status (int fd, const char * if_name, unsigned int * result_r) { struct ifreq ifr; u16 * data = ((u16 *) (& (ifr . ifr_data))); unsigned int if_flags; int up_p; int run_p; int conn_p; unsigned int retval; strncpy ((ifr . ifr_name), if_name, IFNAMSIZ); if ((ioctl (fd, SIOCGIFFLAGS, (&ifr))) < 0) return (errno); if_flags = (ifr . ifr_flags); up_p = ((if_flags & IFF_UP) != 0); run_p = ((if_flags & IFF_RUNNING) != 0); /* As of 2.4.20, interfaces must be up in order to be interrogated. */ if (!up_p) { strncpy ((ifr . ifr_name), if_name, IFNAMSIZ); (ifr . ifr_flags) = IFF_UP; ioctl (fd, SIOCSIFFLAGS, (&ifr)); } strncpy ((ifr . ifr_name), if_name, IFNAMSIZ); (data[1]) = 1; /* read Basic Mode Status Register */ if ((ioctl (fd, SIOCGMIIPHY, (&ifr))) < 0) retval = errno; else if ((data[3]) == 0xFFFF) /* Interface no longer available. */ retval = ENODEV; else { /* Check for: 0x0002 clear = no jabber 0x0004 set = link up 0x0010 clear = no remote fault */ conn_p = (((data[3]) & 0x0016) == 0x0004); retval = 0; } /* Restore original interface flags. */ if (!up_p) { strncpy ((ifr . ifr_name), if_name, IFNAMSIZ); (ifr . ifr_flags) = if_flags; ioctl (fd, SIOCSIFFLAGS, (&ifr)); } if (retval == 0) (*result_r) = ((up_p ? STATUS_UP : 0) | (run_p ? STATUS_RUNNING : 0) | (conn_p ? STATUS_CONNECTED : 0)); return (retval); } - : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html