blob: d4e61dc903e897501aca428423879c68f2df0b61 [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
Samuel Ortiz49292d52008-07-04 10:49:31 +0200258static int ieee80211_ioctl_siwpower(struct net_device *dev,
259 struct iw_request_info *info,
260 struct iw_param *wrq,
261 char *extra)
262{
Kalle Valoe0cb6862008-12-18 23:35:13 +0200263 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Samuel Ortiz49292d52008-07-04 10:49:31 +0200264 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
265 struct ieee80211_conf *conf = &local->hw.conf;
Johannes Berg965beda2009-04-16 13:17:24 +0200266 int timeout = 0;
Kalle Valoe0cb6862008-12-18 23:35:13 +0200267 bool ps;
268
Johannes Berg4be8c382009-01-07 18:28:20 +0100269 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
270 return -EOPNOTSUPP;
271
Kalle Valoe0cb6862008-12-18 23:35:13 +0200272 if (sdata->vif.type != NL80211_IFTYPE_STATION)
273 return -EINVAL;
Samuel Ortiz49292d52008-07-04 10:49:31 +0200274
275 if (wrq->disabled) {
Kalle Valoe0cb6862008-12-18 23:35:13 +0200276 ps = false;
Kalle Valo520eb822008-12-18 23:35:27 +0200277 timeout = 0;
Kalle Valoe0cb6862008-12-18 23:35:13 +0200278 goto set;
Samuel Ortiz49292d52008-07-04 10:49:31 +0200279 }
280
281 switch (wrq->flags & IW_POWER_MODE) {
282 case IW_POWER_ON: /* If not specified */
283 case IW_POWER_MODE: /* If set all mask */
284 case IW_POWER_ALL_R: /* If explicitely state all */
Kalle Valoe0cb6862008-12-18 23:35:13 +0200285 ps = true;
Samuel Ortiz49292d52008-07-04 10:49:31 +0200286 break;
Kalle Valo520eb822008-12-18 23:35:27 +0200287 default: /* Otherwise we ignore */
Johannes Berge9aeaba2009-01-06 18:12:35 +0100288 return -EINVAL;
Samuel Ortiz49292d52008-07-04 10:49:31 +0200289 }
290
Johannes Berge9aeaba2009-01-06 18:12:35 +0100291 if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
292 return -EINVAL;
293
Kalle Valo520eb822008-12-18 23:35:27 +0200294 if (wrq->flags & IW_POWER_TIMEOUT)
295 timeout = wrq->value / 1000;
Kalle Valoe0cb6862008-12-18 23:35:13 +0200296
Johannes Berg4be8c382009-01-07 18:28:20 +0100297 set:
Johannes Berg965beda2009-04-16 13:17:24 +0200298 if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
299 return 0;
Kalle Valo520eb822008-12-18 23:35:27 +0200300
Johannes Berg965beda2009-04-16 13:17:24 +0200301 sdata->u.mgd.powersave = ps;
Johannes Berg46f2c4b2009-01-06 18:13:18 +0100302 conf->dynamic_ps_timeout = timeout;
Kalle Valoe0cb6862008-12-18 23:35:13 +0200303
Johannes Berg4be8c382009-01-07 18:28:20 +0100304 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
Johannes Berge255d5e2009-04-22 12:40:07 +0200305 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
Johannes Berg4be8c382009-01-07 18:28:20 +0100306
Johannes Berg10f644a2009-04-16 13:17:25 +0200307 ieee80211_recalc_ps(local, -1);
Johannes Berg4be8c382009-01-07 18:28:20 +0100308
Johannes Berg965beda2009-04-16 13:17:24 +0200309 return 0;
Samuel Ortiz49292d52008-07-04 10:49:31 +0200310}
311
312static int ieee80211_ioctl_giwpower(struct net_device *dev,
313 struct iw_request_info *info,
314 union iwreq_data *wrqu,
315 char *extra)
316{
Johannes Berg965beda2009-04-16 13:17:24 +0200317 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Samuel Ortiz49292d52008-07-04 10:49:31 +0200318
Johannes Berg965beda2009-04-16 13:17:24 +0200319 wrqu->power.disabled = !sdata->u.mgd.powersave;
Samuel Ortiz49292d52008-07-04 10:49:31 +0200320
321 return 0;
322}
323
Jiri Bencf0706e82007-05-05 11:45:53 -0700324/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
325static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
326{
327 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
328 struct iw_statistics *wstats = &local->wstats;
329 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
330 struct sta_info *sta = NULL;
331
Johannes Berg98dd6a52008-04-10 15:36:09 +0200332 rcu_read_lock();
333
Johannes Berg46900292009-02-15 12:44:28 +0100334 if (sdata->vif.type == NL80211_IFTYPE_STATION)
335 sta = sta_info_get(local, sdata->u.mgd.bssid);
336
Jiri Bencf0706e82007-05-05 11:45:53 -0700337 if (!sta) {
338 wstats->discard.fragment = 0;
339 wstats->discard.misc = 0;
340 wstats->qual.qual = 0;
341 wstats->qual.level = 0;
342 wstats->qual.noise = 0;
343 wstats->qual.updated = IW_QUAL_ALL_INVALID;
344 } else {
Johannes Berg24776cf2009-02-27 16:33:55 -0600345 wstats->qual.updated = 0;
346 /*
347 * mirror what cfg80211 does for iwrange/scan results,
348 * otherwise userspace gets confused.
349 */
350 if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
351 IEEE80211_HW_SIGNAL_DBM)) {
352 wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
353 wstats->qual.updated |= IW_QUAL_QUAL_UPDATED;
354 } else {
355 wstats->qual.updated |= IW_QUAL_LEVEL_INVALID;
356 wstats->qual.updated |= IW_QUAL_QUAL_INVALID;
357 }
358
359 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
360 wstats->qual.level = sta->last_signal;
361 wstats->qual.qual = sta->last_signal;
362 } else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
363 int sig = sta->last_signal;
364
365 wstats->qual.updated |= IW_QUAL_DBM;
366 wstats->qual.level = sig;
367 if (sig < -110)
368 sig = -110;
369 else if (sig > -40)
370 sig = -40;
371 wstats->qual.qual = sig + 110;
372 }
373
374 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
375 /*
376 * This assumes that if driver reports noise, it also
377 * reports signal in dBm.
378 */
379 wstats->qual.noise = sta->last_noise;
380 wstats->qual.updated |= IW_QUAL_NOISE_UPDATED;
381 } else {
382 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
383 }
Jiri Bencf0706e82007-05-05 11:45:53 -0700384 }
Johannes Berg98dd6a52008-04-10 15:36:09 +0200385
386 rcu_read_unlock();
387
Jiri Bencf0706e82007-05-05 11:45:53 -0700388 return wstats;
389}
390
Jiri Bencf0706e82007-05-05 11:45:53 -0700391/* Structures to export the Wireless Handlers */
392
393static const iw_handler ieee80211_handler[] =
394{
395 (iw_handler) NULL, /* SIOCSIWCOMMIT */
Johannes Bergfee52672008-11-26 22:36:31 +0100396 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
Jiri Bencf0706e82007-05-05 11:45:53 -0700397 (iw_handler) NULL, /* SIOCSIWNWID */
398 (iw_handler) NULL, /* SIOCGIWNWID */
399 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
400 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
Johannes Berge60c7742008-11-26 23:31:40 +0100401 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
402 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700403 (iw_handler) NULL, /* SIOCSIWSENS */
404 (iw_handler) NULL, /* SIOCGIWSENS */
405 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
Johannes Berg4aa188e2009-02-18 19:32:08 +0100406 (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700407 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
408 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
409 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
410 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
Johannes Berg5d4ecd92007-09-14 11:10:24 -0400411 (iw_handler) NULL, /* SIOCSIWSPY */
412 (iw_handler) NULL, /* SIOCGIWSPY */
413 (iw_handler) NULL, /* SIOCSIWTHRSPY */
414 (iw_handler) NULL, /* SIOCGIWTHRSPY */
Jiri Bencf0706e82007-05-05 11:45:53 -0700415 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
416 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
Johannes Berg691597c2009-04-19 19:57:45 +0200417 (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
Jiri Bencf0706e82007-05-05 11:45:53 -0700418 (iw_handler) NULL, /* SIOCGIWAPLIST */
Johannes Berg2a519312009-02-10 21:25:55 +0100419 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
420 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
Jiri Bencf0706e82007-05-05 11:45:53 -0700421 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
422 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
423 (iw_handler) NULL, /* SIOCSIWNICKN */
424 (iw_handler) NULL, /* SIOCGIWNICKN */
425 (iw_handler) NULL, /* -- hole -- */
426 (iw_handler) NULL, /* -- hole -- */
Larry Finger1fd5e582007-07-10 19:32:10 +0200427 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700428 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
Jouni Malinenb9a5f8ca2009-04-20 18:39:05 +0200429 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
430 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
431 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
432 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
Johannes Berg7643a2c2009-06-02 13:01:39 +0200433 (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */
434 (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */
Jouni Malinenb9a5f8ca2009-04-20 18:39:05 +0200435 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
436 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
Johannes Berg08645122009-05-11 13:54:58 +0200437 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
438 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
Samuel Ortiz49292d52008-07-04 10:49:31 +0200439 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
440 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
Jiri Bencf0706e82007-05-05 11:45:53 -0700441 (iw_handler) NULL, /* -- hole -- */
442 (iw_handler) NULL, /* -- hole -- */
Johannes Bergf2129352009-07-01 21:26:56 +0200443 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700444 (iw_handler) NULL, /* SIOCGIWGENIE */
Johannes Bergf2129352009-07-01 21:26:56 +0200445 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
446 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
Johannes Berg08645122009-05-11 13:54:58 +0200447 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
Jiri Bencf0706e82007-05-05 11:45:53 -0700448 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
449 (iw_handler) NULL, /* SIOCSIWPMKSA */
450 (iw_handler) NULL, /* -- hole -- */
451};
452
Jiri Bencf0706e82007-05-05 11:45:53 -0700453const struct iw_handler_def ieee80211_iw_handler_def =
454{
455 .num_standard = ARRAY_SIZE(ieee80211_handler),
Jiri Bencf0706e82007-05-05 11:45:53 -0700456 .standard = (iw_handler *) ieee80211_handler,
Jiri Bencf0706e82007-05-05 11:45:53 -0700457 .get_wireless_stats = ieee80211_get_wireless_stats,
458};