blob: f77929802c7ad1b9b3b8deec1a4981fb07949a32 [file] [log] [blame]
Jiri Bencf0706e82007-05-05 11:45:53 -07001/*
2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/netdevice.h>
13#include <linux/types.h>
14#include <linux/slab.h>
15#include <linux/skbuff.h>
16#include <linux/etherdevice.h>
17#include <linux/if_arp.h>
18#include <linux/wireless.h>
19#include <net/iw_handler.h>
20#include <asm/uaccess.h>
21
22#include <net/mac80211.h>
23#include "ieee80211_i.h"
Johannes Berg2c8dccc2008-04-08 15:14:40 -040024#include "led.h"
25#include "rate.h"
Jiri Bencf0706e82007-05-05 11:45:53 -070026#include "wpa.h"
27#include "aes_ccm.h"
Jiri Bencf0706e82007-05-05 11:45:53 -070028
Johannes Bergb708e612007-09-14 11:10:25 -040029
Jiri Bencf0706e82007-05-05 11:45:53 -070030static int ieee80211_ioctl_siwfreq(struct net_device *dev,
31 struct iw_request_info *info,
32 struct iw_freq *freq, char *extra)
33{
Jiri Bencf0706e82007-05-05 11:45:53 -070034 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Johannes Berg7e9debe2009-06-15 13:42:25 +020035 struct ieee80211_local *local = sdata->local;
36 struct ieee80211_channel *chan;
Jiri Bencf0706e82007-05-05 11:45:53 -070037
Johannes Berg46900292009-02-15 12:44:28 +010038 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
Johannes Bergaf8cdcd2009-04-19 21:25:43 +020039 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
Johannes Berg46900292009-02-15 12:44:28 +010040 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
Johannes Bergf2129352009-07-01 21:26:56 +020041 return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
Jiri Bencf0706e82007-05-05 11:45:53 -070042
43 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
44 if (freq->e == 0) {
Johannes Bergf2129352009-07-01 21:26:56 +020045 if (freq->m < 0)
46 return -EINVAL;
47 else
Johannes Berg7e9debe2009-06-15 13:42:25 +020048 chan = ieee80211_get_channel(local->hw.wiphy,
Johannes Berg8318d782008-01-24 19:38:38 +010049 ieee80211_channel_to_frequency(freq->m));
Jiri Bencf0706e82007-05-05 11:45:53 -070050 } else {
51 int i, div = 1000000;
52 for (i = 0; i < freq->e; i++)
53 div /= 10;
Johannes Berg7e9debe2009-06-15 13:42:25 +020054 if (div <= 0)
Jiri Bencf0706e82007-05-05 11:45:53 -070055 return -EINVAL;
Johannes Berg7e9debe2009-06-15 13:42:25 +020056 chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div);
Jiri Bencf0706e82007-05-05 11:45:53 -070057 }
Johannes Berg7e9debe2009-06-15 13:42:25 +020058
59 if (!chan)
60 return -EINVAL;
61
62 if (chan->flags & IEEE80211_CHAN_DISABLED)
63 return -EINVAL;
64
65 /*
66 * no change except maybe auto -> fixed, ignore the HT
67 * setting so you can fix a channel you're on already
68 */
69 if (local->oper_channel == chan)
70 return 0;
71
Johannes Berg7e9debe2009-06-15 13:42:25 +020072 local->oper_channel = chan;
73 local->oper_channel_type = NL80211_CHAN_NO_HT;
74 ieee80211_hw_config(local, 0);
75
76 return 0;
Jiri Bencf0706e82007-05-05 11:45:53 -070077}
78
79
80static int ieee80211_ioctl_giwfreq(struct net_device *dev,
81 struct iw_request_info *info,
82 struct iw_freq *freq, char *extra)
83{
84 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
Johannes Bergaf8cdcd2009-04-19 21:25:43 +020085 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
86
87 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
88 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
Johannes Bergf2129352009-07-01 21:26:56 +020089 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
90 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
Jiri Bencf0706e82007-05-05 11:45:53 -070091
Johannes Berg77382312009-05-04 17:52:10 +020092 freq->m = local->oper_channel->center_freq;
Jiri Bencf0706e82007-05-05 11:45:53 -070093 freq->e = 6;
94
95 return 0;
96}
97
98
99static int ieee80211_ioctl_siwessid(struct net_device *dev,
100 struct iw_request_info *info,
101 struct iw_point *data, char *ssid)
102{
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200103 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Jiri Bencf0706e82007-05-05 11:45:53 -0700104
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200105 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
106 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
Johannes Bergf2129352009-07-01 21:26:56 +0200107 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
108 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
Jiri Bencf0706e82007-05-05 11:45:53 -0700109
Jiri Bencf0706e82007-05-05 11:45:53 -0700110 return -EOPNOTSUPP;
111}
112
113
114static int ieee80211_ioctl_giwessid(struct net_device *dev,
115 struct iw_request_info *info,
116 struct iw_point *data, char *ssid)
117{
Jiri Bencf0706e82007-05-05 11:45:53 -0700118 struct ieee80211_sub_if_data *sdata;
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200119
Jiri Bencf0706e82007-05-05 11:45:53 -0700120 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200121
122 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
123 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
Johannes Bergf2129352009-07-01 21:26:56 +0200124 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
125 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
Jiri Bencf0706e82007-05-05 11:45:53 -0700126
Jiri Bencf0706e82007-05-05 11:45:53 -0700127 return -EOPNOTSUPP;
128}
129
130
131static int ieee80211_ioctl_siwap(struct net_device *dev,
132 struct iw_request_info *info,
133 struct sockaddr *ap_addr, char *extra)
134{
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200135 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Jiri Bencf0706e82007-05-05 11:45:53 -0700136
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200137 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
138 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
139
Johannes Bergf2129352009-07-01 21:26:56 +0200140 if (sdata->vif.type == NL80211_IFTYPE_STATION)
141 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
Johannes Berg7986cf92009-03-21 17:08:43 +0100142
Johannes Bergf2129352009-07-01 21:26:56 +0200143 if (sdata->vif.type == NL80211_IFTYPE_WDS) {
Johannes Berg44213b52008-02-25 16:27:49 +0100144 /*
145 * If it is necessary to update the WDS peer address
146 * while the interface is running, then we need to do
147 * more work here, namely if it is running we need to
148 * add a new and remove the old STA entry, this is
149 * normally handled by _open() and _stop().
150 */
151 if (netif_running(dev))
152 return -EBUSY;
153
154 memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
155 ETH_ALEN);
156
157 return 0;
Jiri Bencf0706e82007-05-05 11:45:53 -0700158 }
159
160 return -EOPNOTSUPP;
161}
162
163
164static int ieee80211_ioctl_giwap(struct net_device *dev,
165 struct iw_request_info *info,
166 struct sockaddr *ap_addr, char *extra)
167{
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200168 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Jiri Bencf0706e82007-05-05 11:45:53 -0700169
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200170 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
171 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
172
Johannes Bergf2129352009-07-01 21:26:56 +0200173 if (sdata->vif.type == NL80211_IFTYPE_STATION)
174 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
175
176 if (sdata->vif.type == NL80211_IFTYPE_WDS) {
Jiri Bencf0706e82007-05-05 11:45:53 -0700177 ap_addr->sa_family = ARPHRD_ETHER;
178 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
179 return 0;
180 }
181
182 return -EOPNOTSUPP;
183}
184
185
Larry Finger1fd5e582007-07-10 19:32:10 +0200186static int ieee80211_ioctl_siwrate(struct net_device *dev,
187 struct iw_request_info *info,
188 struct iw_param *rate, char *extra)
189{
190 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
Johannes Berg8318d782008-01-24 19:38:38 +0100191 int i, err = -EINVAL;
Larry Finger1fd5e582007-07-10 19:32:10 +0200192 u32 target_rate = rate->value / 100000;
193 struct ieee80211_sub_if_data *sdata;
Johannes Berg8318d782008-01-24 19:38:38 +0100194 struct ieee80211_supported_band *sband;
Larry Finger1fd5e582007-07-10 19:32:10 +0200195
196 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Johannes Berg8318d782008-01-24 19:38:38 +0100197
198 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
199
Larry Finger1fd5e582007-07-10 19:32:10 +0200200 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
201 * target_rate = X, rate->fixed = 1 means only rate X
202 * target_rate = X, rate->fixed = 0 means all rates <= X */
Johannes Berg3e122be2008-07-09 14:40:34 +0200203 sdata->max_ratectrl_rateidx = -1;
204 sdata->force_unicast_rateidx = -1;
Larry Finger1fd5e582007-07-10 19:32:10 +0200205 if (rate->value < 0)
206 return 0;
Johannes Berg8318d782008-01-24 19:38:38 +0100207
208 for (i=0; i< sband->n_bitrates; i++) {
209 struct ieee80211_rate *brate = &sband->bitrates[i];
210 int this_rate = brate->bitrate;
Larry Finger1fd5e582007-07-10 19:32:10 +0200211
Larry Finger1fd5e582007-07-10 19:32:10 +0200212 if (target_rate == this_rate) {
Johannes Berg3e122be2008-07-09 14:40:34 +0200213 sdata->max_ratectrl_rateidx = i;
Larry Finger1fd5e582007-07-10 19:32:10 +0200214 if (rate->fixed)
Johannes Berg3e122be2008-07-09 14:40:34 +0200215 sdata->force_unicast_rateidx = i;
Johannes Berg8318d782008-01-24 19:38:38 +0100216 err = 0;
217 break;
Larry Finger1fd5e582007-07-10 19:32:10 +0200218 }
219 }
Johannes Berg8318d782008-01-24 19:38:38 +0100220 return err;
Larry Finger1fd5e582007-07-10 19:32:10 +0200221}
222
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700223static int ieee80211_ioctl_giwrate(struct net_device *dev,
224 struct iw_request_info *info,
225 struct iw_param *rate, char *extra)
226{
227 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
228 struct sta_info *sta;
229 struct ieee80211_sub_if_data *sdata;
Johannes Berg8318d782008-01-24 19:38:38 +0100230 struct ieee80211_supported_band *sband;
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700231
232 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Johannes Berg8318d782008-01-24 19:38:38 +0100233
Johannes Berg05c914f2008-09-11 00:01:58 +0200234 if (sdata->vif.type != NL80211_IFTYPE_STATION)
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700235 return -EOPNOTSUPP;
Johannes Berg8318d782008-01-24 19:38:38 +0100236
237 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
238
Johannes Berg380a9422008-04-04 23:40:35 +0200239 rcu_read_lock();
240
Johannes Berg46900292009-02-15 12:44:28 +0100241 sta = sta_info_get(local, sdata->u.mgd.bssid);
Johannes Berg380a9422008-04-04 23:40:35 +0200242
Johannes Berge6a98542008-10-21 12:40:02 +0200243 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
244 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700245 else
246 rate->value = 0;
Johannes Berg380a9422008-04-04 23:40:35 +0200247
248 rcu_read_unlock();
249
250 if (!sta)
251 return -ENODEV;
252
Johannes Berg8318d782008-01-24 19:38:38 +0100253 rate->value *= 100000;
Johannes Bergd0709a62008-02-25 16:27:46 +0100254
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700255 return 0;
256}
257
Jiri Bencf0706e82007-05-05 11:45:53 -0700258/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
259static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
260{
261 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
262 struct iw_statistics *wstats = &local->wstats;
263 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
264 struct sta_info *sta = NULL;
265
Johannes Berg98dd6a52008-04-10 15:36:09 +0200266 rcu_read_lock();
267
Johannes Berg46900292009-02-15 12:44:28 +0100268 if (sdata->vif.type == NL80211_IFTYPE_STATION)
269 sta = sta_info_get(local, sdata->u.mgd.bssid);
270
Jiri Bencf0706e82007-05-05 11:45:53 -0700271 if (!sta) {
272 wstats->discard.fragment = 0;
273 wstats->discard.misc = 0;
274 wstats->qual.qual = 0;
275 wstats->qual.level = 0;
276 wstats->qual.noise = 0;
277 wstats->qual.updated = IW_QUAL_ALL_INVALID;
278 } else {
Johannes Berg24776cf2009-02-27 16:33:55 -0600279 wstats->qual.updated = 0;
280 /*
281 * mirror what cfg80211 does for iwrange/scan results,
282 * otherwise userspace gets confused.
283 */
284 if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
285 IEEE80211_HW_SIGNAL_DBM)) {
286 wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
287 wstats->qual.updated |= IW_QUAL_QUAL_UPDATED;
288 } else {
289 wstats->qual.updated |= IW_QUAL_LEVEL_INVALID;
290 wstats->qual.updated |= IW_QUAL_QUAL_INVALID;
291 }
292
293 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
294 wstats->qual.level = sta->last_signal;
295 wstats->qual.qual = sta->last_signal;
296 } else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
297 int sig = sta->last_signal;
298
299 wstats->qual.updated |= IW_QUAL_DBM;
300 wstats->qual.level = sig;
301 if (sig < -110)
302 sig = -110;
303 else if (sig > -40)
304 sig = -40;
305 wstats->qual.qual = sig + 110;
306 }
307
308 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
309 /*
310 * This assumes that if driver reports noise, it also
311 * reports signal in dBm.
312 */
313 wstats->qual.noise = sta->last_noise;
314 wstats->qual.updated |= IW_QUAL_NOISE_UPDATED;
315 } else {
316 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
317 }
Jiri Bencf0706e82007-05-05 11:45:53 -0700318 }
Johannes Berg98dd6a52008-04-10 15:36:09 +0200319
320 rcu_read_unlock();
321
Jiri Bencf0706e82007-05-05 11:45:53 -0700322 return wstats;
323}
324
Jiri Bencf0706e82007-05-05 11:45:53 -0700325/* Structures to export the Wireless Handlers */
326
327static const iw_handler ieee80211_handler[] =
328{
329 (iw_handler) NULL, /* SIOCSIWCOMMIT */
Johannes Bergfee52672008-11-26 22:36:31 +0100330 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
Jiri Bencf0706e82007-05-05 11:45:53 -0700331 (iw_handler) NULL, /* SIOCSIWNWID */
332 (iw_handler) NULL, /* SIOCGIWNWID */
333 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
334 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
Johannes Berge60c7742008-11-26 23:31:40 +0100335 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
336 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700337 (iw_handler) NULL, /* SIOCSIWSENS */
338 (iw_handler) NULL, /* SIOCGIWSENS */
339 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
Johannes Berg4aa188e2009-02-18 19:32:08 +0100340 (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700341 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
342 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
343 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
344 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
Johannes Berg5d4ecd92007-09-14 11:10:24 -0400345 (iw_handler) NULL, /* SIOCSIWSPY */
346 (iw_handler) NULL, /* SIOCGIWSPY */
347 (iw_handler) NULL, /* SIOCSIWTHRSPY */
348 (iw_handler) NULL, /* SIOCGIWTHRSPY */
Jiri Bencf0706e82007-05-05 11:45:53 -0700349 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
350 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
Johannes Berg691597c2009-04-19 19:57:45 +0200351 (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
Jiri Bencf0706e82007-05-05 11:45:53 -0700352 (iw_handler) NULL, /* SIOCGIWAPLIST */
Johannes Berg2a519312009-02-10 21:25:55 +0100353 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
354 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
Jiri Bencf0706e82007-05-05 11:45:53 -0700355 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
356 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
357 (iw_handler) NULL, /* SIOCSIWNICKN */
358 (iw_handler) NULL, /* SIOCGIWNICKN */
359 (iw_handler) NULL, /* -- hole -- */
360 (iw_handler) NULL, /* -- hole -- */
Larry Finger1fd5e582007-07-10 19:32:10 +0200361 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700362 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
Jouni Malinenb9a5f8ca2009-04-20 18:39:05 +0200363 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
364 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
365 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
366 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
Johannes Berg7643a2c2009-06-02 13:01:39 +0200367 (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */
368 (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */
Jouni Malinenb9a5f8ca2009-04-20 18:39:05 +0200369 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
370 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
Johannes Berg08645122009-05-11 13:54:58 +0200371 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
372 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
Johannes Bergbc92afd2009-07-01 21:26:57 +0200373 (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */
374 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */
Jiri Bencf0706e82007-05-05 11:45:53 -0700375 (iw_handler) NULL, /* -- hole -- */
376 (iw_handler) NULL, /* -- hole -- */
Johannes Bergf2129352009-07-01 21:26:56 +0200377 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700378 (iw_handler) NULL, /* SIOCGIWGENIE */
Johannes Bergf2129352009-07-01 21:26:56 +0200379 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
380 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
Johannes Berg08645122009-05-11 13:54:58 +0200381 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
Jiri Bencf0706e82007-05-05 11:45:53 -0700382 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
383 (iw_handler) NULL, /* SIOCSIWPMKSA */
384 (iw_handler) NULL, /* -- hole -- */
385};
386
Jiri Bencf0706e82007-05-05 11:45:53 -0700387const struct iw_handler_def ieee80211_iw_handler_def =
388{
389 .num_standard = ARRAY_SIZE(ieee80211_handler),
Jiri Bencf0706e82007-05-05 11:45:53 -0700390 .standard = (iw_handler *) ieee80211_handler,
Jiri Bencf0706e82007-05-05 11:45:53 -0700391 .get_wireless_stats = ieee80211_get_wireless_stats,
392};