svn commit: r254019 - head/contrib/wpa/src/drivers

Rui Paulo rpaulo at FreeBSD.org
Wed Aug 7 01:01:58 UTC 2013


Author: rpaulo
Date: Wed Aug  7 01:01:58 2013
New Revision: 254019
URL: http://svnweb.freebsd.org/changeset/base/254019

Log:
  Fix a timing issue with the wired driver.
  
  After configuring the interface, wait for the link to become active.
  Many ethernet drivers reset the chip when we set multicast filters
  (causing significant delays due to link re-negotiation) and, by the time
  we start sending packets, they are discared instead of going to the ether.
  
  Tested by:	dumbbell

Modified:
  head/contrib/wpa/src/drivers/driver_wired.c

Modified: head/contrib/wpa/src/drivers/driver_wired.c
==============================================================================
--- head/contrib/wpa/src/drivers/driver_wired.c	Wed Aug  7 00:28:17 2013	(r254018)
+++ head/contrib/wpa/src/drivers/driver_wired.c	Wed Aug  7 01:01:58 2013	(r254019)
@@ -17,6 +17,7 @@
 #endif /* __linux__ */
 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
 #include <net/if_dl.h>
+#include <net/if_media.h>
 #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */
 #ifdef __sun__
 #include <sys/sockio.h>
@@ -453,6 +454,29 @@ static int wpa_driver_wired_set_ifflags(
 	return 0;
 }
 
+static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status)
+{
+	struct ifmediareq ifmr;
+	int s;
+
+	s = socket(PF_INET, SOCK_DGRAM, 0);
+	if (s < 0) {
+		perror("socket");
+		return -1;
+	}
+
+	os_memset(&ifmr, 0, sizeof(ifmr));
+	os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ);
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) {
+		perror("ioctl[SIOCGIFMEDIA]");
+		close(s);
+		return -1;
+	}
+	close(s);
+	*status = ifmr.ifm_status & IFM_ACTIVE;
+
+	return 0;
+}
 
 static int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add)
 {
@@ -511,7 +535,7 @@ static int wpa_driver_wired_multi(const 
 static void * wpa_driver_wired_init(void *ctx, const char *ifname)
 {
 	struct wpa_driver_wired_data *drv;
-	int flags;
+	int flags, status;
 
 	drv = os_zalloc(sizeof(*drv));
 	if (drv == NULL)
@@ -562,6 +586,11 @@ static void * wpa_driver_wired_init(void
 			   __func__);
 		drv->iff_allmulti = 1;
 	}
+	wpa_printf(MSG_DEBUG, "%s: waiting for link to become active",
+	    __func__);
+	while (wpa_driver_wired_get_ifstatus(ifname, &status) == 0 && 
+	    status == 0)
+		sleep(1);
 
 	return drv;
 }


More information about the svn-src-head mailing list