blob: 4053d766af2d7d0e9ade0da15cce2e444382a7aa [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 Bergab737a42009-07-01 21:26:58 +0200143 if (sdata->vif.type == NL80211_IFTYPE_WDS)
144 return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
Jiri Bencf0706e82007-05-05 11:45:53 -0700145 return -EOPNOTSUPP;
146}
147
148
149static int ieee80211_ioctl_giwap(struct net_device *dev,
150 struct iw_request_info *info,
151 struct sockaddr *ap_addr, char *extra)
152{
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200153 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Jiri Bencf0706e82007-05-05 11:45:53 -0700154
Johannes Bergaf8cdcd2009-04-19 21:25:43 +0200155 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
156 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
157
Johannes Bergf2129352009-07-01 21:26:56 +0200158 if (sdata->vif.type == NL80211_IFTYPE_STATION)
159 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
160
Johannes Bergab737a42009-07-01 21:26:58 +0200161 if (sdata->vif.type == NL80211_IFTYPE_WDS)
162 return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
Jiri Bencf0706e82007-05-05 11:45:53 -0700163
164 return -EOPNOTSUPP;
165}
166
167
Larry Finger1fd5e582007-07-10 19:32:10 +0200168static int ieee80211_ioctl_siwrate(struct net_device *dev,
169 struct iw_request_info *info,
170 struct iw_param *rate, char *extra)
171{
172 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
Johannes Berg8318d782008-01-24 19:38:38 +0100173 int i, err = -EINVAL;
Larry Finger1fd5e582007-07-10 19:32:10 +0200174 u32 target_rate = rate->value / 100000;
175 struct ieee80211_sub_if_data *sdata;
Johannes Berg8318d782008-01-24 19:38:38 +0100176 struct ieee80211_supported_band *sband;
Larry Finger1fd5e582007-07-10 19:32:10 +0200177
178 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Johannes Berg8318d782008-01-24 19:38:38 +0100179
180 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
181
Larry Finger1fd5e582007-07-10 19:32:10 +0200182 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
183 * target_rate = X, rate->fixed = 1 means only rate X
184 * target_rate = X, rate->fixed = 0 means all rates <= X */
Johannes Berg3e122be2008-07-09 14:40:34 +0200185 sdata->max_ratectrl_rateidx = -1;
186 sdata->force_unicast_rateidx = -1;
Larry Finger1fd5e582007-07-10 19:32:10 +0200187 if (rate->value < 0)
188 return 0;
Johannes Berg8318d782008-01-24 19:38:38 +0100189
190 for (i=0; i< sband->n_bitrates; i++) {
191 struct ieee80211_rate *brate = &sband->bitrates[i];
192 int this_rate = brate->bitrate;
Larry Finger1fd5e582007-07-10 19:32:10 +0200193
Larry Finger1fd5e582007-07-10 19:32:10 +0200194 if (target_rate == this_rate) {
Johannes Berg3e122be2008-07-09 14:40:34 +0200195 sdata->max_ratectrl_rateidx = i;
Larry Finger1fd5e582007-07-10 19:32:10 +0200196 if (rate->fixed)
Johannes Berg3e122be2008-07-09 14:40:34 +0200197 sdata->force_unicast_rateidx = i;
Johannes Berg8318d782008-01-24 19:38:38 +0100198 err = 0;
199 break;
Larry Finger1fd5e582007-07-10 19:32:10 +0200200 }
201 }
Johannes Berg8318d782008-01-24 19:38:38 +0100202 return err;
Larry Finger1fd5e582007-07-10 19:32:10 +0200203}
204
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700205static int ieee80211_ioctl_giwrate(struct net_device *dev,
206 struct iw_request_info *info,
207 struct iw_param *rate, char *extra)
208{
209 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
210 struct sta_info *sta;
211 struct ieee80211_sub_if_data *sdata;
Johannes Berg8318d782008-01-24 19:38:38 +0100212 struct ieee80211_supported_band *sband;
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700213
214 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
Johannes Berg8318d782008-01-24 19:38:38 +0100215
Johannes Berg05c914f2008-09-11 00:01:58 +0200216 if (sdata->vif.type != NL80211_IFTYPE_STATION)
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700217 return -EOPNOTSUPP;
Johannes Berg8318d782008-01-24 19:38:38 +0100218
219 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
220
Johannes Berg380a9422008-04-04 23:40:35 +0200221 rcu_read_lock();
222
Johannes Berg46900292009-02-15 12:44:28 +0100223 sta = sta_info_get(local, sdata->u.mgd.bssid);
Johannes Berg380a9422008-04-04 23:40:35 +0200224
Johannes Berge6a98542008-10-21 12:40:02 +0200225 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
226 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700227 else
228 rate->value = 0;
Johannes Berg380a9422008-04-04 23:40:35 +0200229
230 rcu_read_unlock();
231
232 if (!sta)
233 return -ENODEV;
234
Johannes Berg8318d782008-01-24 19:38:38 +0100235 rate->value *= 100000;
Johannes Bergd0709a62008-02-25 16:27:46 +0100236
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700237 return 0;
238}
239
Jiri Bencf0706e82007-05-05 11:45:53 -0700240/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
241static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
242{
243 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
244 struct iw_statistics *wstats = &local->wstats;
245 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
246 struct sta_info *sta = NULL;
247
Johannes Berg98dd6a52008-04-10 15:36:09 +0200248 rcu_read_lock();
249
Johannes Berg46900292009-02-15 12:44:28 +0100250 if (sdata->vif.type == NL80211_IFTYPE_STATION)
251 sta = sta_info_get(local, sdata->u.mgd.bssid);
252
Jiri Bencf0706e82007-05-05 11:45:53 -0700253 if (!sta) {
254 wstats->discard.fragment = 0;
255 wstats->discard.misc = 0;
256 wstats->qual.qual = 0;
257 wstats->qual.level = 0;
258 wstats->qual.noise = 0;
259 wstats->qual.updated = IW_QUAL_ALL_INVALID;
260 } else {
Johannes Berg24776cf2009-02-27 16:33:55 -0600261 wstats->qual.updated = 0;
262 /*
263 * mirror what cfg80211 does for iwrange/scan results,
264 * otherwise userspace gets confused.
265 */
266 if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
267 IEEE80211_HW_SIGNAL_DBM)) {
268 wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
269 wstats->qual.updated |= IW_QUAL_QUAL_UPDATED;
270 } else {
271 wstats->qual.updated |= IW_QUAL_LEVEL_INVALID;
272 wstats->qual.updated |= IW_QUAL_QUAL_INVALID;
273 }
274
275 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
276 wstats->qual.level = sta->last_signal;
277 wstats->qual.qual = sta->last_signal;
278 } else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
279 int sig = sta->last_signal;
280
281 wstats->qual.updated |= IW_QUAL_DBM;
282 wstats->qual.level = sig;
283 if (sig < -110)
284 sig = -110;
285 else if (sig > -40)
286 sig = -40;
287 wstats->qual.qual = sig + 110;
288 }
289
290 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
291 /*
292 * This assumes that if driver reports noise, it also
293 * reports signal in dBm.
294 */
295 wstats->qual.noise = sta->last_noise;
296 wstats->qual.updated |= IW_QUAL_NOISE_UPDATED;
297 } else {
298 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
299 }
Jiri Bencf0706e82007-05-05 11:45:53 -0700300 }
Johannes Berg98dd6a52008-04-10 15:36:09 +0200301
302 rcu_read_unlock();
303
Jiri Bencf0706e82007-05-05 11:45:53 -0700304 return wstats;
305}
306
Jiri Bencf0706e82007-05-05 11:45:53 -0700307/* Structures to export the Wireless Handlers */
308
309static const iw_handler ieee80211_handler[] =
310{
311 (iw_handler) NULL, /* SIOCSIWCOMMIT */
Johannes Bergfee52672008-11-26 22:36:31 +0100312 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
Jiri Bencf0706e82007-05-05 11:45:53 -0700313 (iw_handler) NULL, /* SIOCSIWNWID */
314 (iw_handler) NULL, /* SIOCGIWNWID */
315 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
316 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
Johannes Berge60c7742008-11-26 23:31:40 +0100317 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
318 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700319 (iw_handler) NULL, /* SIOCSIWSENS */
320 (iw_handler) NULL, /* SIOCGIWSENS */
321 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
Johannes Berg4aa188e2009-02-18 19:32:08 +0100322 (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700323 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
324 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
325 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
326 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
Johannes Berg5d4ecd92007-09-14 11:10:24 -0400327 (iw_handler) NULL, /* SIOCSIWSPY */
328 (iw_handler) NULL, /* SIOCGIWSPY */
329 (iw_handler) NULL, /* SIOCSIWTHRSPY */
330 (iw_handler) NULL, /* SIOCGIWTHRSPY */
Jiri Bencf0706e82007-05-05 11:45:53 -0700331 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
332 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
Johannes Berg691597c2009-04-19 19:57:45 +0200333 (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
Jiri Bencf0706e82007-05-05 11:45:53 -0700334 (iw_handler) NULL, /* SIOCGIWAPLIST */
Johannes Berg2a519312009-02-10 21:25:55 +0100335 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
336 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
Jiri Bencf0706e82007-05-05 11:45:53 -0700337 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
338 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
339 (iw_handler) NULL, /* SIOCSIWNICKN */
340 (iw_handler) NULL, /* SIOCGIWNICKN */
341 (iw_handler) NULL, /* -- hole -- */
342 (iw_handler) NULL, /* -- hole -- */
Larry Finger1fd5e582007-07-10 19:32:10 +0200343 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
Larry Fingerb3d88ad2007-06-10 17:57:33 -0700344 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
Jouni Malinenb9a5f8ca2009-04-20 18:39:05 +0200345 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
346 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
347 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
348 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
Johannes Berg7643a2c2009-06-02 13:01:39 +0200349 (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */
350 (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */
Jouni Malinenb9a5f8ca2009-04-20 18:39:05 +0200351 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
352 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
Johannes Berg08645122009-05-11 13:54:58 +0200353 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
354 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
Johannes Bergbc92afd2009-07-01 21:26:57 +0200355 (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */
356 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */
Jiri Bencf0706e82007-05-05 11:45:53 -0700357 (iw_handler) NULL, /* -- hole -- */
358 (iw_handler) NULL, /* -- hole -- */
Johannes Bergf2129352009-07-01 21:26:56 +0200359 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
Jiri Bencf0706e82007-05-05 11:45:53 -0700360 (iw_handler) NULL, /* SIOCGIWGENIE */
Johannes Bergf2129352009-07-01 21:26:56 +0200361 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
362 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
Johannes Berg08645122009-05-11 13:54:58 +0200363 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
Jiri Bencf0706e82007-05-05 11:45:53 -0700364 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
365 (iw_handler) NULL, /* SIOCSIWPMKSA */
366 (iw_handler) NULL, /* -- hole -- */
367};
368
Jiri Bencf0706e82007-05-05 11:45:53 -0700369const struct iw_handler_def ieee80211_iw_handler_def =
370{
371 .num_standard = ARRAY_SIZE(ieee80211_handler),
Jiri Bencf0706e82007-05-05 11:45:53 -0700372 .standard = (iw_handler *) ieee80211_handler,
Jiri Bencf0706e82007-05-05 11:45:53 -0700373 .get_wireless_stats = ieee80211_get_wireless_stats,
374};