diff options
-rw-r--r-- | package/openwrt/wlcompat.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/package/openwrt/wlcompat.c b/package/openwrt/wlcompat.c index 52af95a9a..ebed8c365 100644 --- a/package/openwrt/wlcompat.c +++ b/package/openwrt/wlcompat.c @@ -201,6 +201,75 @@ static int wlcompat_ioctl(struct net_device *dev, return wlcompat_ioctl_getiwrange(dev, extra); break; } + case SIOCSIWMODE: + { + int ap = -1, infra = -1, passive = -1; + + switch (wrqu->mode) { + case IW_MODE_MONITOR: + passive = 1; + break; + case IW_MODE_ADHOC: + passive = 0; + infra = 0; + ap = 0; + break; + case IW_MODE_MASTER: + passive = 0; + infra = 1; + ap = 1; + break; + case IW_MODE_INFRA: + passive = 0; + infra = 1; + ap = 0; + break; + default: + return -EINVAL; + } + + if (passive >= 0) { + if (wl_ioctl(dev, WLC_SET_PASSIVE, &passive, sizeof(passive)) < 0) + return -EINVAL; + if (wl_ioctl(dev, WLC_SET_MONITOR, &passive, sizeof(passive)) < 0) + return -EINVAL; + } + if (ap >= 0) + if (wl_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)) < 0) + return -EINVAL; + if (infra >= 0) + if (wl_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra)) < 0) + return -EINVAL; + + break; + + } + case SIOCGIWMODE: + { + int ap, infra, passive; + + if (wl_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)) < 0) + return -EINVAL; + + if (wl_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)) < 0) + return -EINVAL; + + if (wl_ioctl(dev, WLC_GET_PASSIVE, &passive, sizeof(passive)) < 0) + return -EINVAL; + + if (passive) { + wrqu->mode = IW_MODE_MONITOR; + } else if (!infra) { + wrqu->mode = IW_MODE_ADHOC; + } else { + if (ap) { + wrqu->mode = IW_MODE_MASTER; + } else { + wrqu->mode = IW_MODE_INFRA; + } + } + break; + } default: { return -EINVAL; @@ -217,8 +286,8 @@ static const iw_handler wlcompat_handler[] = { NULL, /* SIOCGIWNWID */ wlcompat_ioctl, /* SIOCSIWFREQ */ wlcompat_ioctl, /* SIOCGIWFREQ */ - NULL, /* SIOCSIWMODE */ - NULL, /* SIOCGIWMODE */ + wlcompat_ioctl, /* SIOCSIWMODE */ + wlcompat_ioctl, /* SIOCGIWMODE */ NULL, /* SIOCSIWSENS */ NULL, /* SIOCGIWSENS */ NULL, /* SIOCSIWRANGE */ |