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 */  | 
