Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Apr 2004 03:27:48 +0200
From:      Andre Oppermann <andre@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        wpaul@freebsd.org
Subject:   Re: events when (de)associating or when cable is (un)plugged
Message-ID:  <40887114.7000700@freebsd.org>
In-Reply-To: <200403271918.18032.vjardin@free.fr>
References:  <39FE23FA-7F75-11D8-8F99-000A95CDA38A@webweaving.org> <BA068B86-7F97-11D8-8F99-000A95CDA38A@asemantics.com> <20040327175645.GC90316@empiric.dek.spc.org> <200403271918.18032.vjardin@free.fr>

next in thread | previous in thread | raw e-mail | index | archive | help

Ok, I tried to implement this tonight but it doesn't work in FreeBSD.  I don't
get any notification when the cable is unplugged or plugged.  I don't get it,
maybe someone else sees it, I don't.

miibus_linkchg gets called pretty frequently but the detection logic seems to
be flawed.  For some reason it doesn't detect cable changes.  When I change the
media with ifconfig from auto to 100BaseTX and back it reports correctly.
Tested with fxp and bge interfaces.

In OpenBSD it works perfectly (fxp interface).  Unplug cable, message comes
up, plug cable, message comes up.  I can't see any logical difference between
OpenBSD/NetBSD and or MII variant.

-- 
Andre


Index: dev/mii/mii.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/mii/mii.c,v
retrieving revision 1.17
diff -u -p -r1.17 mii.c
--- dev/mii/mii.c	24 Aug 2003 17:54:10 -0000	1.17
+++ dev/mii/mii.c	23 Apr 2004 01:16:06 -0000
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD: src/sys/dev/mii/mii.

  #include <net/if.h>
  #include <net/if_media.h>
+#include <net/route.h>

  #include <dev/mii/mii.h>
  #include <dev/mii/miivar.h>
@@ -237,7 +238,7 @@ miibus_linkchg(dev)
  	struct mii_data *mii;
  	struct ifnet *ifp;
  	device_t parent;
-	int link;
+	int link, link_state;

  	parent = device_get_parent(dev);
  	MIIBUS_LINKCHG(parent);
@@ -249,15 +250,25 @@ miibus_linkchg(dev)
  	ifp = device_get_softc(parent);
  	
  	if (mii->mii_media_status & IFM_AVALID) {
-		if (mii->mii_media_status & IFM_ACTIVE)
+		if (mii->mii_media_status & IFM_ACTIVE) {
  			link = NOTE_LINKUP;
-		else
+			link_state = LINK_STATE_UP;
+		} else {
  			link = NOTE_LINKDOWN;
+			link_state = LINK_STATE_DOWN;
+		}
  	} else {
  		link = NOTE_LINKINV;
+		link_state = LINK_STATE_UNKNOWN;
  	}

  	KNOTE(&ifp->if_klist, link);
+
+	/* Notify protocols that the link state has changed */
+	if (link_state != ifp->if_link_state) {
+		ifp->if_link_state = link_state;
+		rt_ifmsg(ifp);
+	}
  }

  static void
Index: net/if.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if.h,v
retrieving revision 1.85
diff -u -p -r1.85 if.h
--- net/if.h	11 Apr 2004 13:36:52 -0000	1.85
+++ net/if.h	23 Apr 2004 01:16:06 -0000
@@ -104,6 +104,7 @@ struct if_data {
  	u_char	ifi_physical;		/* e.g., AUI, Thinnet, 10base-T, etc */
  	u_char	ifi_addrlen;		/* media address length */
  	u_char	ifi_hdrlen;		/* media header length */
+	u_char	ifi_link_state;		/* current link state */
  	u_char	ifi_recvquota;		/* polling quota for receive intrs */
  	u_char	ifi_xmitquota;		/* polling quota for xmit intrs */
  	u_long	ifi_mtu;		/* maximum transmission unit */
@@ -153,6 +154,13 @@ struct if_data {
  	(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
  	    IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART|IFF_PROMISC|\
  	    IFF_POLLING)
+
+/*
+ * Values for if_link_state.
+ */
+#define LINK_STATE_UNKNOWN	0	/* link invalid/unknown */
+#define LINK_STATE_DOWN		1	/* link is down */
+#define LINK_STATE_UP		2	/* link is up */

  /*
   * Some convenience macros used for setting ifi_baudrate.
Index: net/if_var.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_var.h,v
retrieving revision 1.73
diff -u -p -r1.73 if_var.h
--- net/if_var.h	18 Apr 2004 18:59:44 -0000	1.73
+++ net/if_var.h	23 Apr 2004 01:16:06 -0000
@@ -197,6 +197,7 @@ typedef void if_init_f_t(void *);
  #define	if_addrlen	if_data.ifi_addrlen
  #define	if_hdrlen	if_data.ifi_hdrlen
  #define	if_metric	if_data.ifi_metric
+#define	if_link_state	if_data.ifi_link_state
  #define	if_baudrate	if_data.ifi_baudrate
  #define	if_hwassist	if_data.ifi_hwassist
  #define	if_ipackets	if_data.ifi_ipackets



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?40887114.7000700>