Commit e60c7744f8aa77bcbcb0b294596d6c87445d1200
Committed by
John W. Linville
1 parent
fee52678db
Exists in
master
and in
39 other branches
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>
Showing 4 changed files with 89 additions and 74 deletions Side-by-side Diff
include/net/cfg80211.h
... | ... | @@ -530,6 +530,10 @@ |
530 | 530 | int cfg80211_wext_giwname(struct net_device *dev, |
531 | 531 | struct iw_request_info *info, |
532 | 532 | char *name, char *extra); |
533 | +int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | |
534 | + u32 *mode, char *extra); | |
535 | +int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, | |
536 | + u32 *mode, char *extra); | |
533 | 537 | |
534 | 538 | #endif /* __NET_CFG80211_H */ |
net/mac80211/iface.c
... | ... | @@ -698,6 +698,10 @@ |
698 | 698 | if (type == sdata->vif.type) |
699 | 699 | return 0; |
700 | 700 | |
701 | + /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | |
702 | + if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) | |
703 | + return -EOPNOTSUPP; | |
704 | + | |
701 | 705 | /* |
702 | 706 | * We could, here, on changes between IBSS/STA/MESH modes, |
703 | 707 | * invoke an MLME function instead that disassociates etc. |
net/mac80211/wext.c
... | ... | @@ -224,78 +224,6 @@ |
224 | 224 | } |
225 | 225 | |
226 | 226 | |
227 | -static int ieee80211_ioctl_siwmode(struct net_device *dev, | |
228 | - struct iw_request_info *info, | |
229 | - __u32 *mode, char *extra) | |
230 | -{ | |
231 | - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | |
232 | - struct ieee80211_local *local = sdata->local; | |
233 | - int type; | |
234 | - | |
235 | - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | |
236 | - return -EOPNOTSUPP; | |
237 | - | |
238 | - switch (*mode) { | |
239 | - case IW_MODE_INFRA: | |
240 | - type = NL80211_IFTYPE_STATION; | |
241 | - break; | |
242 | - case IW_MODE_ADHOC: | |
243 | - /* Setting ad-hoc mode on non ibss channel is not | |
244 | - * supported. | |
245 | - */ | |
246 | - if (local->oper_channel && | |
247 | - (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) | |
248 | - return -EOPNOTSUPP; | |
249 | - | |
250 | - type = NL80211_IFTYPE_ADHOC; | |
251 | - break; | |
252 | - case IW_MODE_REPEAT: | |
253 | - type = NL80211_IFTYPE_WDS; | |
254 | - break; | |
255 | - case IW_MODE_MONITOR: | |
256 | - type = NL80211_IFTYPE_MONITOR; | |
257 | - break; | |
258 | - default: | |
259 | - return -EINVAL; | |
260 | - } | |
261 | - | |
262 | - return ieee80211_if_change_type(sdata, type); | |
263 | -} | |
264 | - | |
265 | - | |
266 | -static int ieee80211_ioctl_giwmode(struct net_device *dev, | |
267 | - struct iw_request_info *info, | |
268 | - __u32 *mode, char *extra) | |
269 | -{ | |
270 | - struct ieee80211_sub_if_data *sdata; | |
271 | - | |
272 | - sdata = IEEE80211_DEV_TO_SUB_IF(dev); | |
273 | - switch (sdata->vif.type) { | |
274 | - case NL80211_IFTYPE_AP: | |
275 | - *mode = IW_MODE_MASTER; | |
276 | - break; | |
277 | - case NL80211_IFTYPE_STATION: | |
278 | - *mode = IW_MODE_INFRA; | |
279 | - break; | |
280 | - case NL80211_IFTYPE_ADHOC: | |
281 | - *mode = IW_MODE_ADHOC; | |
282 | - break; | |
283 | - case NL80211_IFTYPE_MONITOR: | |
284 | - *mode = IW_MODE_MONITOR; | |
285 | - break; | |
286 | - case NL80211_IFTYPE_WDS: | |
287 | - *mode = IW_MODE_REPEAT; | |
288 | - break; | |
289 | - case NL80211_IFTYPE_AP_VLAN: | |
290 | - *mode = IW_MODE_SECOND; /* FIXME */ | |
291 | - break; | |
292 | - default: | |
293 | - *mode = IW_MODE_AUTO; | |
294 | - break; | |
295 | - } | |
296 | - return 0; | |
297 | -} | |
298 | - | |
299 | 227 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, |
300 | 228 | struct iw_request_info *info, |
301 | 229 | struct iw_freq *freq, char *extra) |
... | ... | @@ -1109,8 +1037,8 @@ |
1109 | 1037 | (iw_handler) NULL, /* SIOCGIWNWID */ |
1110 | 1038 | (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ |
1111 | 1039 | (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ |
1112 | - (iw_handler) ieee80211_ioctl_siwmode, /* SIOCSIWMODE */ | |
1113 | - (iw_handler) ieee80211_ioctl_giwmode, /* SIOCGIWMODE */ | |
1040 | + (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ | |
1041 | + (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ | |
1114 | 1042 | (iw_handler) NULL, /* SIOCSIWSENS */ |
1115 | 1043 | (iw_handler) NULL, /* SIOCGIWSENS */ |
1116 | 1044 | (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ |
net/wireless/wext-compat.c
... | ... | @@ -58,4 +58,83 @@ |
58 | 58 | return 0; |
59 | 59 | } |
60 | 60 | EXPORT_SYMBOL(cfg80211_wext_giwname); |
61 | + | |
62 | +int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | |
63 | + u32 *mode, char *extra) | |
64 | +{ | |
65 | + struct wireless_dev *wdev = dev->ieee80211_ptr; | |
66 | + struct cfg80211_registered_device *rdev; | |
67 | + struct vif_params vifparams; | |
68 | + enum nl80211_iftype type; | |
69 | + | |
70 | + if (!wdev) | |
71 | + return -EOPNOTSUPP; | |
72 | + | |
73 | + rdev = wiphy_to_dev(wdev->wiphy); | |
74 | + | |
75 | + if (!rdev->ops->change_virtual_intf) | |
76 | + return -EOPNOTSUPP; | |
77 | + | |
78 | + /* don't support changing VLANs, you just re-create them */ | |
79 | + if (wdev->iftype == NL80211_IFTYPE_AP_VLAN) | |
80 | + return -EOPNOTSUPP; | |
81 | + | |
82 | + switch (*mode) { | |
83 | + case IW_MODE_INFRA: | |
84 | + type = NL80211_IFTYPE_STATION; | |
85 | + break; | |
86 | + case IW_MODE_ADHOC: | |
87 | + type = NL80211_IFTYPE_ADHOC; | |
88 | + break; | |
89 | + case IW_MODE_REPEAT: | |
90 | + type = NL80211_IFTYPE_WDS; | |
91 | + break; | |
92 | + case IW_MODE_MONITOR: | |
93 | + type = NL80211_IFTYPE_MONITOR; | |
94 | + break; | |
95 | + default: | |
96 | + return -EINVAL; | |
97 | + } | |
98 | + | |
99 | + memset(&vifparams, 0, sizeof(vifparams)); | |
100 | + | |
101 | + return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type, | |
102 | + NULL, &vifparams); | |
103 | +} | |
104 | +EXPORT_SYMBOL(cfg80211_wext_siwmode); | |
105 | + | |
106 | +int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, | |
107 | + u32 *mode, char *extra) | |
108 | +{ | |
109 | + struct wireless_dev *wdev = dev->ieee80211_ptr; | |
110 | + | |
111 | + if (!wdev) | |
112 | + return -EOPNOTSUPP; | |
113 | + | |
114 | + switch (wdev->iftype) { | |
115 | + case NL80211_IFTYPE_AP: | |
116 | + *mode = IW_MODE_MASTER; | |
117 | + break; | |
118 | + case NL80211_IFTYPE_STATION: | |
119 | + *mode = IW_MODE_INFRA; | |
120 | + break; | |
121 | + case NL80211_IFTYPE_ADHOC: | |
122 | + *mode = IW_MODE_ADHOC; | |
123 | + break; | |
124 | + case NL80211_IFTYPE_MONITOR: | |
125 | + *mode = IW_MODE_MONITOR; | |
126 | + break; | |
127 | + case NL80211_IFTYPE_WDS: | |
128 | + *mode = IW_MODE_REPEAT; | |
129 | + break; | |
130 | + case NL80211_IFTYPE_AP_VLAN: | |
131 | + *mode = IW_MODE_SECOND; /* FIXME */ | |
132 | + break; | |
133 | + default: | |
134 | + *mode = IW_MODE_AUTO; | |
135 | + break; | |
136 | + } | |
137 | + return 0; | |
138 | +} | |
139 | +EXPORT_SYMBOL(cfg80211_wext_giwmode); |