summaryrefslogtreecommitdiffstats
path: root/contrib/wpa
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2013-08-07 01:01:58 +0000
committerrpaulo <rpaulo@FreeBSD.org>2013-08-07 01:01:58 +0000
commit336da2273ba2b400b1d7d7f60376058eeea1dfbd (patch)
treed604ec7ccbb632e6f8ab842d1563264693463b5f /contrib/wpa
parenta11192f9a00b2b646f39c8c79e968df269688606 (diff)
downloadFreeBSD-src-336da2273ba2b400b1d7d7f60376058eeea1dfbd.zip
FreeBSD-src-336da2273ba2b400b1d7d7f60376058eeea1dfbd.tar.gz
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
Diffstat (limited to 'contrib/wpa')
-rw-r--r--contrib/wpa/src/drivers/driver_wired.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/contrib/wpa/src/drivers/driver_wired.c b/contrib/wpa/src/drivers/driver_wired.c
index e0f0f22..95dcea9 100644
--- a/contrib/wpa/src/drivers/driver_wired.c
+++ b/contrib/wpa/src/drivers/driver_wired.c
@@ -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(const char *ifname, int flags)
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 char *ifname, const u8 *addr, int add)
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 *ctx, const char *ifname)
__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;
}
OpenPOWER on IntegriCloud