aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-11-26 17:31:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-05 09:32:58 -0500
commite60c7744f8aa77bcbcb0b294596d6c87445d1200 (patch)
tree7039c0906d825b035595a826cd117fd08242d0ad
parentfee52678dbda2099a25243e79da98dc390e1939a (diff)
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>
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/wext.c76
-rw-r--r--net/wireless/wext-compat.c79
4 files changed, 89 insertions, 74 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c97eac34ec01..a0c0bf19496c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -530,5 +530,9 @@ struct cfg80211_ops {
530int cfg80211_wext_giwname(struct net_device *dev, 530int cfg80211_wext_giwname(struct net_device *dev,
531 struct iw_request_info *info, 531 struct iw_request_info *info,
532 char *name, char *extra); 532 char *name, char *extra);
533int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
534 u32 *mode, char *extra);
535int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
536 u32 *mode, char *extra);
533 537
534#endif /* __NET_CFG80211_H */ 538#endif /* __NET_CFG80211_H */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 9ab772ac74ae..5abbc3f07dd6 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -698,6 +698,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
698 if (type == sdata->vif.type) 698 if (type == sdata->vif.type)
699 return 0; 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 * We could, here, on changes between IBSS/STA/MESH modes, 706 * We could, here, on changes between IBSS/STA/MESH modes,
703 * invoke an MLME function instead that disassociates etc. 707 * invoke an MLME function instead that disassociates etc.
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index b9eee3c903de..4e1fdcfacb0c 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -224,78 +224,6 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
224} 224}
225 225
226 226
227static 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
266static 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
299static int ieee80211_ioctl_siwfreq(struct net_device *dev, 227static int ieee80211_ioctl_siwfreq(struct net_device *dev,
300 struct iw_request_info *info, 228 struct iw_request_info *info,
301 struct iw_freq *freq, char *extra) 229 struct iw_freq *freq, char *extra)
@@ -1109,8 +1037,8 @@ static const iw_handler ieee80211_handler[] =
1109 (iw_handler) NULL, /* SIOCGIWNWID */ 1037 (iw_handler) NULL, /* SIOCGIWNWID */
1110 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ 1038 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
1111 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ 1039 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
1112 (iw_handler) ieee80211_ioctl_siwmode, /* SIOCSIWMODE */ 1040 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
1113 (iw_handler) ieee80211_ioctl_giwmode, /* SIOCGIWMODE */ 1041 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
1114 (iw_handler) NULL, /* SIOCSIWSENS */ 1042 (iw_handler) NULL, /* SIOCSIWSENS */
1115 (iw_handler) NULL, /* SIOCGIWSENS */ 1043 (iw_handler) NULL, /* SIOCGIWSENS */
1116 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ 1044 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index a5db4551a31a..58e489fd4aed 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -58,3 +58,82 @@ int cfg80211_wext_giwname(struct net_device *dev,
58 return 0; 58 return 0;
59} 59}
60EXPORT_SYMBOL(cfg80211_wext_giwname); 60EXPORT_SYMBOL(cfg80211_wext_giwname);
61
62int 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}
104EXPORT_SYMBOL(cfg80211_wext_siwmode);
105
106int 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}
139EXPORT_SYMBOL(cfg80211_wext_giwmode);