mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
cfg80211: handle SIOCGIWMODE/SIOCSIWMODE
further reducing wext code in mac80211. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
fee52678db
commit
e60c7744f8
@ -530,5 +530,9 @@ struct cfg80211_ops {
|
|||||||
int cfg80211_wext_giwname(struct net_device *dev,
|
int cfg80211_wext_giwname(struct net_device *dev,
|
||||||
struct iw_request_info *info,
|
struct iw_request_info *info,
|
||||||
char *name, char *extra);
|
char *name, char *extra);
|
||||||
|
int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
||||||
|
u32 *mode, char *extra);
|
||||||
|
int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
|
||||||
|
u32 *mode, char *extra);
|
||||||
|
|
||||||
#endif /* __NET_CFG80211_H */
|
#endif /* __NET_CFG80211_H */
|
||||||
|
@ -698,6 +698,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
|
|||||||
if (type == sdata->vif.type)
|
if (type == sdata->vif.type)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Setting ad-hoc mode on non-IBSS channel is not supported. */
|
||||||
|
if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We could, here, on changes between IBSS/STA/MESH modes,
|
* We could, here, on changes between IBSS/STA/MESH modes,
|
||||||
* invoke an MLME function instead that disassociates etc.
|
* invoke an MLME function instead that disassociates etc.
|
||||||
|
@ -224,78 +224,6 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ieee80211_ioctl_siwmode(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
__u32 *mode, char *extra)
|
|
||||||
{
|
|
||||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
||||||
struct ieee80211_local *local = sdata->local;
|
|
||||||
int type;
|
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
switch (*mode) {
|
|
||||||
case IW_MODE_INFRA:
|
|
||||||
type = NL80211_IFTYPE_STATION;
|
|
||||||
break;
|
|
||||||
case IW_MODE_ADHOC:
|
|
||||||
/* Setting ad-hoc mode on non ibss channel is not
|
|
||||||
* supported.
|
|
||||||
*/
|
|
||||||
if (local->oper_channel &&
|
|
||||||
(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS))
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
type = NL80211_IFTYPE_ADHOC;
|
|
||||||
break;
|
|
||||||
case IW_MODE_REPEAT:
|
|
||||||
type = NL80211_IFTYPE_WDS;
|
|
||||||
break;
|
|
||||||
case IW_MODE_MONITOR:
|
|
||||||
type = NL80211_IFTYPE_MONITOR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ieee80211_if_change_type(sdata, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int ieee80211_ioctl_giwmode(struct net_device *dev,
|
|
||||||
struct iw_request_info *info,
|
|
||||||
__u32 *mode, char *extra)
|
|
||||||
{
|
|
||||||
struct ieee80211_sub_if_data *sdata;
|
|
||||||
|
|
||||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
||||||
switch (sdata->vif.type) {
|
|
||||||
case NL80211_IFTYPE_AP:
|
|
||||||
*mode = IW_MODE_MASTER;
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_STATION:
|
|
||||||
*mode = IW_MODE_INFRA;
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_ADHOC:
|
|
||||||
*mode = IW_MODE_ADHOC;
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_MONITOR:
|
|
||||||
*mode = IW_MODE_MONITOR;
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_WDS:
|
|
||||||
*mode = IW_MODE_REPEAT;
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_AP_VLAN:
|
|
||||||
*mode = IW_MODE_SECOND; /* FIXME */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*mode = IW_MODE_AUTO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ieee80211_ioctl_siwfreq(struct net_device *dev,
|
static int ieee80211_ioctl_siwfreq(struct net_device *dev,
|
||||||
struct iw_request_info *info,
|
struct iw_request_info *info,
|
||||||
struct iw_freq *freq, char *extra)
|
struct iw_freq *freq, char *extra)
|
||||||
@ -1109,8 +1037,8 @@ static const iw_handler ieee80211_handler[] =
|
|||||||
(iw_handler) NULL, /* SIOCGIWNWID */
|
(iw_handler) NULL, /* SIOCGIWNWID */
|
||||||
(iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
|
(iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
|
||||||
(iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
|
(iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
|
||||||
(iw_handler) ieee80211_ioctl_siwmode, /* SIOCSIWMODE */
|
(iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
|
||||||
(iw_handler) ieee80211_ioctl_giwmode, /* SIOCGIWMODE */
|
(iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
|
||||||
(iw_handler) NULL, /* SIOCSIWSENS */
|
(iw_handler) NULL, /* SIOCSIWSENS */
|
||||||
(iw_handler) NULL, /* SIOCGIWSENS */
|
(iw_handler) NULL, /* SIOCGIWSENS */
|
||||||
(iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
|
(iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
|
||||||
|
@ -58,3 +58,82 @@ int cfg80211_wext_giwname(struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cfg80211_wext_giwname);
|
EXPORT_SYMBOL(cfg80211_wext_giwname);
|
||||||
|
|
||||||
|
int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
||||||
|
u32 *mode, char *extra)
|
||||||
|
{
|
||||||
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
struct cfg80211_registered_device *rdev;
|
||||||
|
struct vif_params vifparams;
|
||||||
|
enum nl80211_iftype type;
|
||||||
|
|
||||||
|
if (!wdev)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
rdev = wiphy_to_dev(wdev->wiphy);
|
||||||
|
|
||||||
|
if (!rdev->ops->change_virtual_intf)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* don't support changing VLANs, you just re-create them */
|
||||||
|
if (wdev->iftype == NL80211_IFTYPE_AP_VLAN)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
switch (*mode) {
|
||||||
|
case IW_MODE_INFRA:
|
||||||
|
type = NL80211_IFTYPE_STATION;
|
||||||
|
break;
|
||||||
|
case IW_MODE_ADHOC:
|
||||||
|
type = NL80211_IFTYPE_ADHOC;
|
||||||
|
break;
|
||||||
|
case IW_MODE_REPEAT:
|
||||||
|
type = NL80211_IFTYPE_WDS;
|
||||||
|
break;
|
||||||
|
case IW_MODE_MONITOR:
|
||||||
|
type = NL80211_IFTYPE_MONITOR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&vifparams, 0, sizeof(vifparams));
|
||||||
|
|
||||||
|
return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
|
||||||
|
NULL, &vifparams);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cfg80211_wext_siwmode);
|
||||||
|
|
||||||
|
int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
|
||||||
|
u32 *mode, char *extra)
|
||||||
|
{
|
||||||
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
|
||||||
|
if (!wdev)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
switch (wdev->iftype) {
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
*mode = IW_MODE_MASTER;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
*mode = IW_MODE_INFRA;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_ADHOC:
|
||||||
|
*mode = IW_MODE_ADHOC;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
*mode = IW_MODE_MONITOR;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_WDS:
|
||||||
|
*mode = IW_MODE_REPEAT;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
*mode = IW_MODE_SECOND; /* FIXME */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*mode = IW_MODE_AUTO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cfg80211_wext_giwmode);
|
||||||
|
Loading…
Reference in New Issue
Block a user