2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.
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.
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>
22 #include <net/mac80211.h>
23 #include "ieee80211_i.h"
30 static int ieee80211_ioctl_siwgenie(struct net_device
*dev
,
31 struct iw_request_info
*info
,
32 struct iw_point
*data
, char *extra
)
34 struct ieee80211_sub_if_data
*sdata
;
36 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
38 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
39 int ret
= ieee80211_sta_set_extra_ie(sdata
, extra
, data
->length
);
40 if (ret
&& ret
!= -EALREADY
)
42 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_AUTO_BSSID_SEL
;
43 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_EXT_SME
;
44 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_CONTROL_PORT
;
46 ieee80211_sta_req_auth(sdata
);
53 static int ieee80211_ioctl_siwfreq(struct net_device
*dev
,
54 struct iw_request_info
*info
,
55 struct iw_freq
*freq
, char *extra
)
57 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
58 struct ieee80211_local
*local
= sdata
->local
;
59 struct ieee80211_channel
*chan
;
61 if (sdata
->vif
.type
== NL80211_IFTYPE_ADHOC
)
62 return cfg80211_ibss_wext_siwfreq(dev
, info
, freq
, extra
);
63 else if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
)
64 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_AUTO_CHANNEL_SEL
;
66 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
69 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
)
71 IEEE80211_STA_AUTO_CHANNEL_SEL
;
74 chan
= ieee80211_get_channel(local
->hw
.wiphy
,
75 ieee80211_channel_to_frequency(freq
->m
));
78 for (i
= 0; i
< freq
->e
; i
++)
82 chan
= ieee80211_get_channel(local
->hw
.wiphy
, freq
->m
/ div
);
88 if (chan
->flags
& IEEE80211_CHAN_DISABLED
)
92 * no change except maybe auto -> fixed, ignore the HT
93 * setting so you can fix a channel you're on already
95 if (local
->oper_channel
== chan
)
98 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
)
99 ieee80211_sta_req_auth(sdata
);
101 local
->oper_channel
= chan
;
102 local
->oper_channel_type
= NL80211_CHAN_NO_HT
;
103 ieee80211_hw_config(local
, 0);
109 static int ieee80211_ioctl_giwfreq(struct net_device
*dev
,
110 struct iw_request_info
*info
,
111 struct iw_freq
*freq
, char *extra
)
113 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
114 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
116 if (sdata
->vif
.type
== NL80211_IFTYPE_ADHOC
)
117 return cfg80211_ibss_wext_giwfreq(dev
, info
, freq
, extra
);
119 freq
->m
= local
->oper_channel
->center_freq
;
126 static int ieee80211_ioctl_siwessid(struct net_device
*dev
,
127 struct iw_request_info
*info
,
128 struct iw_point
*data
, char *ssid
)
130 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
131 size_t len
= data
->length
;
134 if (sdata
->vif
.type
== NL80211_IFTYPE_ADHOC
)
135 return cfg80211_ibss_wext_siwessid(dev
, info
, data
, ssid
);
137 /* iwconfig uses nul termination in SSID.. */
138 if (len
> 0 && ssid
[len
- 1] == '\0')
141 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
143 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_AUTO_SSID_SEL
;
145 sdata
->u
.mgd
.flags
|= IEEE80211_STA_AUTO_SSID_SEL
;
147 ret
= ieee80211_sta_set_ssid(sdata
, ssid
, len
);
151 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_EXT_SME
;
152 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_CONTROL_PORT
;
153 ieee80211_sta_req_auth(sdata
);
161 static int ieee80211_ioctl_giwessid(struct net_device
*dev
,
162 struct iw_request_info
*info
,
163 struct iw_point
*data
, char *ssid
)
166 struct ieee80211_sub_if_data
*sdata
;
168 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
170 if (sdata
->vif
.type
== NL80211_IFTYPE_ADHOC
)
171 return cfg80211_ibss_wext_giwessid(dev
, info
, data
, ssid
);
173 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
174 int res
= ieee80211_sta_get_ssid(sdata
, ssid
, &len
);
187 static int ieee80211_ioctl_siwap(struct net_device
*dev
,
188 struct iw_request_info
*info
,
189 struct sockaddr
*ap_addr
, char *extra
)
191 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
193 if (sdata
->vif
.type
== NL80211_IFTYPE_ADHOC
)
194 return cfg80211_ibss_wext_siwap(dev
, info
, ap_addr
, extra
);
196 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
199 if (is_zero_ether_addr((u8
*) &ap_addr
->sa_data
))
200 sdata
->u
.mgd
.flags
|= IEEE80211_STA_AUTO_BSSID_SEL
|
201 IEEE80211_STA_AUTO_CHANNEL_SEL
;
202 else if (is_broadcast_ether_addr((u8
*) &ap_addr
->sa_data
))
203 sdata
->u
.mgd
.flags
|= IEEE80211_STA_AUTO_BSSID_SEL
;
205 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_AUTO_BSSID_SEL
;
206 ret
= ieee80211_sta_set_bssid(sdata
, (u8
*) &ap_addr
->sa_data
);
209 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_EXT_SME
;
210 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_CONTROL_PORT
;
211 ieee80211_sta_req_auth(sdata
);
213 } else if (sdata
->vif
.type
== NL80211_IFTYPE_WDS
) {
215 * If it is necessary to update the WDS peer address
216 * while the interface is running, then we need to do
217 * more work here, namely if it is running we need to
218 * add a new and remove the old STA entry, this is
219 * normally handled by _open() and _stop().
221 if (netif_running(dev
))
224 memcpy(&sdata
->u
.wds
.remote_addr
, (u8
*) &ap_addr
->sa_data
,
234 static int ieee80211_ioctl_giwap(struct net_device
*dev
,
235 struct iw_request_info
*info
,
236 struct sockaddr
*ap_addr
, char *extra
)
238 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
240 if (sdata
->vif
.type
== NL80211_IFTYPE_ADHOC
)
241 return cfg80211_ibss_wext_giwap(dev
, info
, ap_addr
, extra
);
243 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
244 if (sdata
->u
.mgd
.state
== IEEE80211_STA_MLME_ASSOCIATED
) {
245 ap_addr
->sa_family
= ARPHRD_ETHER
;
246 memcpy(&ap_addr
->sa_data
, sdata
->u
.mgd
.bssid
, ETH_ALEN
);
248 memset(&ap_addr
->sa_data
, 0, ETH_ALEN
);
250 } else if (sdata
->vif
.type
== NL80211_IFTYPE_WDS
) {
251 ap_addr
->sa_family
= ARPHRD_ETHER
;
252 memcpy(&ap_addr
->sa_data
, sdata
->u
.wds
.remote_addr
, ETH_ALEN
);
260 static int ieee80211_ioctl_siwrate(struct net_device
*dev
,
261 struct iw_request_info
*info
,
262 struct iw_param
*rate
, char *extra
)
264 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
265 int i
, err
= -EINVAL
;
266 u32 target_rate
= rate
->value
/ 100000;
267 struct ieee80211_sub_if_data
*sdata
;
268 struct ieee80211_supported_band
*sband
;
270 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
272 sband
= local
->hw
.wiphy
->bands
[local
->hw
.conf
.channel
->band
];
274 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
275 * target_rate = X, rate->fixed = 1 means only rate X
276 * target_rate = X, rate->fixed = 0 means all rates <= X */
277 sdata
->max_ratectrl_rateidx
= -1;
278 sdata
->force_unicast_rateidx
= -1;
282 for (i
=0; i
< sband
->n_bitrates
; i
++) {
283 struct ieee80211_rate
*brate
= &sband
->bitrates
[i
];
284 int this_rate
= brate
->bitrate
;
286 if (target_rate
== this_rate
) {
287 sdata
->max_ratectrl_rateidx
= i
;
289 sdata
->force_unicast_rateidx
= i
;
297 static int ieee80211_ioctl_giwrate(struct net_device
*dev
,
298 struct iw_request_info
*info
,
299 struct iw_param
*rate
, char *extra
)
301 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
302 struct sta_info
*sta
;
303 struct ieee80211_sub_if_data
*sdata
;
304 struct ieee80211_supported_band
*sband
;
306 sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
308 if (sdata
->vif
.type
!= NL80211_IFTYPE_STATION
)
311 sband
= local
->hw
.wiphy
->bands
[local
->hw
.conf
.channel
->band
];
315 sta
= sta_info_get(local
, sdata
->u
.mgd
.bssid
);
317 if (sta
&& !(sta
->last_tx_rate
.flags
& IEEE80211_TX_RC_MCS
))
318 rate
->value
= sband
->bitrates
[sta
->last_tx_rate
.idx
].bitrate
;
327 rate
->value
*= 100000;
332 static int ieee80211_ioctl_siwpower(struct net_device
*dev
,
333 struct iw_request_info
*info
,
334 struct iw_param
*wrq
,
337 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
338 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
339 struct ieee80211_conf
*conf
= &local
->hw
.conf
;
343 if (!(local
->hw
.flags
& IEEE80211_HW_SUPPORTS_PS
))
346 if (sdata
->vif
.type
!= NL80211_IFTYPE_STATION
)
355 switch (wrq
->flags
& IW_POWER_MODE
) {
356 case IW_POWER_ON
: /* If not specified */
357 case IW_POWER_MODE
: /* If set all mask */
358 case IW_POWER_ALL_R
: /* If explicitely state all */
361 default: /* Otherwise we ignore */
365 if (wrq
->flags
& ~(IW_POWER_MODE
| IW_POWER_TIMEOUT
))
368 if (wrq
->flags
& IW_POWER_TIMEOUT
)
369 timeout
= wrq
->value
/ 1000;
372 if (ps
== sdata
->u
.mgd
.powersave
&& timeout
== conf
->dynamic_ps_timeout
)
375 sdata
->u
.mgd
.powersave
= ps
;
376 conf
->dynamic_ps_timeout
= timeout
;
378 if (local
->hw
.flags
& IEEE80211_HW_SUPPORTS_DYNAMIC_PS
)
379 ieee80211_hw_config(local
, IEEE80211_CONF_CHANGE_PS
);
381 ieee80211_recalc_ps(local
, -1);
386 static int ieee80211_ioctl_giwpower(struct net_device
*dev
,
387 struct iw_request_info
*info
,
388 union iwreq_data
*wrqu
,
391 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
393 wrqu
->power
.disabled
= !sdata
->u
.mgd
.powersave
;
398 static int ieee80211_ioctl_siwauth(struct net_device
*dev
,
399 struct iw_request_info
*info
,
400 struct iw_param
*data
, char *extra
)
402 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
405 switch (data
->flags
& IW_AUTH_INDEX
) {
406 case IW_AUTH_WPA_VERSION
:
407 case IW_AUTH_CIPHER_GROUP
:
408 case IW_AUTH_WPA_ENABLED
:
409 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
410 case IW_AUTH_KEY_MGMT
:
411 case IW_AUTH_CIPHER_GROUP_MGMT
:
413 case IW_AUTH_CIPHER_PAIRWISE
:
414 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
415 if (data
->value
& (IW_AUTH_CIPHER_WEP40
|
416 IW_AUTH_CIPHER_WEP104
| IW_AUTH_CIPHER_TKIP
))
417 sdata
->u
.mgd
.flags
|=
418 IEEE80211_STA_TKIP_WEP_USED
;
420 sdata
->u
.mgd
.flags
&=
421 ~IEEE80211_STA_TKIP_WEP_USED
;
424 case IW_AUTH_DROP_UNENCRYPTED
:
425 sdata
->drop_unencrypted
= !!data
->value
;
427 case IW_AUTH_PRIVACY_INVOKED
:
428 if (sdata
->vif
.type
!= NL80211_IFTYPE_STATION
)
431 sdata
->u
.mgd
.flags
&= ~IEEE80211_STA_PRIVACY_INVOKED
;
433 * Privacy invoked by wpa_supplicant, store the
434 * value and allow associating to a protected
435 * network without having a key up front.
438 sdata
->u
.mgd
.flags
|=
439 IEEE80211_STA_PRIVACY_INVOKED
;
442 case IW_AUTH_80211_AUTH_ALG
:
443 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
)
444 sdata
->u
.mgd
.auth_algs
= data
->value
;
449 if (!(sdata
->local
->hw
.flags
& IEEE80211_HW_MFP_CAPABLE
)) {
453 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
) {
454 switch (data
->value
) {
455 case IW_AUTH_MFP_DISABLED
:
456 sdata
->u
.mgd
.mfp
= IEEE80211_MFP_DISABLED
;
458 case IW_AUTH_MFP_OPTIONAL
:
459 sdata
->u
.mgd
.mfp
= IEEE80211_MFP_OPTIONAL
;
461 case IW_AUTH_MFP_REQUIRED
:
462 sdata
->u
.mgd
.mfp
= IEEE80211_MFP_REQUIRED
;
477 /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
478 static struct iw_statistics
*ieee80211_get_wireless_stats(struct net_device
*dev
)
480 struct ieee80211_local
*local
= wdev_priv(dev
->ieee80211_ptr
);
481 struct iw_statistics
*wstats
= &local
->wstats
;
482 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
483 struct sta_info
*sta
= NULL
;
487 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
)
488 sta
= sta_info_get(local
, sdata
->u
.mgd
.bssid
);
491 wstats
->discard
.fragment
= 0;
492 wstats
->discard
.misc
= 0;
493 wstats
->qual
.qual
= 0;
494 wstats
->qual
.level
= 0;
495 wstats
->qual
.noise
= 0;
496 wstats
->qual
.updated
= IW_QUAL_ALL_INVALID
;
498 wstats
->qual
.updated
= 0;
500 * mirror what cfg80211 does for iwrange/scan results,
501 * otherwise userspace gets confused.
503 if (local
->hw
.flags
& (IEEE80211_HW_SIGNAL_UNSPEC
|
504 IEEE80211_HW_SIGNAL_DBM
)) {
505 wstats
->qual
.updated
|= IW_QUAL_LEVEL_UPDATED
;
506 wstats
->qual
.updated
|= IW_QUAL_QUAL_UPDATED
;
508 wstats
->qual
.updated
|= IW_QUAL_LEVEL_INVALID
;
509 wstats
->qual
.updated
|= IW_QUAL_QUAL_INVALID
;
512 if (local
->hw
.flags
& IEEE80211_HW_SIGNAL_UNSPEC
) {
513 wstats
->qual
.level
= sta
->last_signal
;
514 wstats
->qual
.qual
= sta
->last_signal
;
515 } else if (local
->hw
.flags
& IEEE80211_HW_SIGNAL_DBM
) {
516 int sig
= sta
->last_signal
;
518 wstats
->qual
.updated
|= IW_QUAL_DBM
;
519 wstats
->qual
.level
= sig
;
524 wstats
->qual
.qual
= sig
+ 110;
527 if (local
->hw
.flags
& IEEE80211_HW_NOISE_DBM
) {
529 * This assumes that if driver reports noise, it also
530 * reports signal in dBm.
532 wstats
->qual
.noise
= sta
->last_noise
;
533 wstats
->qual
.updated
|= IW_QUAL_NOISE_UPDATED
;
535 wstats
->qual
.updated
|= IW_QUAL_NOISE_INVALID
;
544 static int ieee80211_ioctl_giwauth(struct net_device
*dev
,
545 struct iw_request_info
*info
,
546 struct iw_param
*data
, char *extra
)
548 struct ieee80211_sub_if_data
*sdata
= IEEE80211_DEV_TO_SUB_IF(dev
);
551 switch (data
->flags
& IW_AUTH_INDEX
) {
552 case IW_AUTH_80211_AUTH_ALG
:
553 if (sdata
->vif
.type
== NL80211_IFTYPE_STATION
)
554 data
->value
= sdata
->u
.mgd
.auth_algs
;
566 /* Structures to export the Wireless Handlers */
568 static const iw_handler ieee80211_handler
[] =
570 (iw_handler
) NULL
, /* SIOCSIWCOMMIT */
571 (iw_handler
) cfg80211_wext_giwname
, /* SIOCGIWNAME */
572 (iw_handler
) NULL
, /* SIOCSIWNWID */
573 (iw_handler
) NULL
, /* SIOCGIWNWID */
574 (iw_handler
) ieee80211_ioctl_siwfreq
, /* SIOCSIWFREQ */
575 (iw_handler
) ieee80211_ioctl_giwfreq
, /* SIOCGIWFREQ */
576 (iw_handler
) cfg80211_wext_siwmode
, /* SIOCSIWMODE */
577 (iw_handler
) cfg80211_wext_giwmode
, /* SIOCGIWMODE */
578 (iw_handler
) NULL
, /* SIOCSIWSENS */
579 (iw_handler
) NULL
, /* SIOCGIWSENS */
580 (iw_handler
) NULL
/* not used */, /* SIOCSIWRANGE */
581 (iw_handler
) cfg80211_wext_giwrange
, /* SIOCGIWRANGE */
582 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
583 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
584 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
585 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
586 (iw_handler
) NULL
, /* SIOCSIWSPY */
587 (iw_handler
) NULL
, /* SIOCGIWSPY */
588 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
589 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
590 (iw_handler
) ieee80211_ioctl_siwap
, /* SIOCSIWAP */
591 (iw_handler
) ieee80211_ioctl_giwap
, /* SIOCGIWAP */
592 (iw_handler
) cfg80211_wext_siwmlme
, /* SIOCSIWMLME */
593 (iw_handler
) NULL
, /* SIOCGIWAPLIST */
594 (iw_handler
) cfg80211_wext_siwscan
, /* SIOCSIWSCAN */
595 (iw_handler
) cfg80211_wext_giwscan
, /* SIOCGIWSCAN */
596 (iw_handler
) ieee80211_ioctl_siwessid
, /* SIOCSIWESSID */
597 (iw_handler
) ieee80211_ioctl_giwessid
, /* SIOCGIWESSID */
598 (iw_handler
) NULL
, /* SIOCSIWNICKN */
599 (iw_handler
) NULL
, /* SIOCGIWNICKN */
600 (iw_handler
) NULL
, /* -- hole -- */
601 (iw_handler
) NULL
, /* -- hole -- */
602 (iw_handler
) ieee80211_ioctl_siwrate
, /* SIOCSIWRATE */
603 (iw_handler
) ieee80211_ioctl_giwrate
, /* SIOCGIWRATE */
604 (iw_handler
) cfg80211_wext_siwrts
, /* SIOCSIWRTS */
605 (iw_handler
) cfg80211_wext_giwrts
, /* SIOCGIWRTS */
606 (iw_handler
) cfg80211_wext_siwfrag
, /* SIOCSIWFRAG */
607 (iw_handler
) cfg80211_wext_giwfrag
, /* SIOCGIWFRAG */
608 (iw_handler
) cfg80211_wext_siwtxpower
, /* SIOCSIWTXPOW */
609 (iw_handler
) cfg80211_wext_giwtxpower
, /* SIOCGIWTXPOW */
610 (iw_handler
) cfg80211_wext_siwretry
, /* SIOCSIWRETRY */
611 (iw_handler
) cfg80211_wext_giwretry
, /* SIOCGIWRETRY */
612 (iw_handler
) cfg80211_wext_siwencode
, /* SIOCSIWENCODE */
613 (iw_handler
) cfg80211_wext_giwencode
, /* SIOCGIWENCODE */
614 (iw_handler
) ieee80211_ioctl_siwpower
, /* SIOCSIWPOWER */
615 (iw_handler
) ieee80211_ioctl_giwpower
, /* SIOCGIWPOWER */
616 (iw_handler
) NULL
, /* -- hole -- */
617 (iw_handler
) NULL
, /* -- hole -- */
618 (iw_handler
) ieee80211_ioctl_siwgenie
, /* SIOCSIWGENIE */
619 (iw_handler
) NULL
, /* SIOCGIWGENIE */
620 (iw_handler
) ieee80211_ioctl_siwauth
, /* SIOCSIWAUTH */
621 (iw_handler
) ieee80211_ioctl_giwauth
, /* SIOCGIWAUTH */
622 (iw_handler
) cfg80211_wext_siwencodeext
, /* SIOCSIWENCODEEXT */
623 (iw_handler
) NULL
, /* SIOCGIWENCODEEXT */
624 (iw_handler
) NULL
, /* SIOCSIWPMKSA */
625 (iw_handler
) NULL
, /* -- hole -- */
628 const struct iw_handler_def ieee80211_iw_handler_def
=
630 .num_standard
= ARRAY_SIZE(ieee80211_handler
),
631 .standard
= (iw_handler
*) ieee80211_handler
,
632 .get_wireless_stats
= ieee80211_get_wireless_stats
,