problem probing network interfaces

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I haven't heard anything in response to my earlier message, so I'm
trying again.  I don't like being a pest, but I'm stuck with a problem
I don't understand, and that I haven't been able to figure out from
the code.

Can anyone give me some suggestions?  Any idea why the sis900 driver
is acting so strangely?  If not, any clues about how to figure it out?

Chris


----------------------------------------------------------------------
Date: Mon, 19 May 2003 14:47:36 -0400
From: Chris Hanson <cph@zurich.ai.mit.edu>

   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

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux