[PATCH] wext: handle mode switches correctly for mac80211
Dan Williams
dcbw
Tue Jun 3 18:30:56 PDT 2008
Since mac80211 requires that the device be !IFF_UP to change the mode
(and I think the old prism54 fullmac driver does too), do that. This
shouldn't harm fullmac devices since they can handle mode switches on
the fly and usually don't care about up/down that much.
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index efa88a8..8c4bac2 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -2152,17 +2152,37 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
{
struct wpa_driver_wext_data *drv = priv;
struct iwreq iwr;
- int ret = 0;
+ int ret = 0, bring_up = 0, flags;
+ int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
os_memset(&iwr, 0, sizeof(iwr));
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
- iwr.u.mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
+ /* mac80211 doesn't allow mode changes while the device is up, so if
+ * the device isn't in the mode we're about to change to, take device
+ * down, set the the mode, and bring it back up.
+ */
+ if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) == 0) {
+ if (iwr.u.mode != new_mode) {
+ if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
+ (void) wpa_driver_wext_set_ifflags(drv,
+ flags & ~IFF_UP);
+ bring_up = 1;
+ }
+ }
+ }
+
+ iwr.u.mode = new_mode;
if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
perror("ioctl[SIOCSIWMODE]");
ret = -1;
}
+ if (bring_up) {
+ if (wpa_driver_wext_get_ifflags(drv, &flags) == 0)
+ (void) wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
+ }
+
return ret;
}
More information about the Hostap
mailing list