2 * Intel Wireless Multicomm 3200 WiFi driver
4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
5 * Samuel Ortiz <samuel.ortiz@intel.com>
6 * Zhu Yi <yi.zhu@intel.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include <linux/kernel.h>
25 #include <linux/netdevice.h>
26 #include <linux/wireless.h>
27 #include <linux/if_arp.h>
28 #include <linux/etherdevice.h>
29 #include <net/cfg80211.h>
30 #include <net/iw_handler.h>
37 static struct iw_statistics
*iwm_get_wireless_stats(struct net_device
*dev
)
39 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
40 struct iw_statistics
*wstats
= &iwm
->wstats
;
42 if (!test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
43 memset(wstats
, 0, sizeof(struct iw_statistics
));
44 wstats
->qual
.updated
= IW_QUAL_ALL_INVALID
;
50 static int iwm_wext_siwfreq(struct net_device
*dev
,
51 struct iw_request_info
*info
,
52 struct iw_freq
*freq
, char *extra
)
54 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
56 if (freq
->flags
== IW_FREQ_AUTO
)
59 /* frequency/channel can only be set in IBSS mode */
60 if (iwm
->conf
.mode
!= UMAC_MODE_IBSS
)
63 return cfg80211_ibss_wext_siwfreq(dev
, info
, freq
, extra
);
66 static int iwm_wext_giwfreq(struct net_device
*dev
,
67 struct iw_request_info
*info
,
68 struct iw_freq
*freq
, char *extra
)
70 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
72 if (iwm
->conf
.mode
== UMAC_MODE_IBSS
)
73 return cfg80211_ibss_wext_giwfreq(dev
, info
, freq
, extra
);
76 freq
->m
= iwm
->channel
;
81 static int iwm_wext_siwap(struct net_device
*dev
, struct iw_request_info
*info
,
82 struct sockaddr
*ap_addr
, char *extra
)
84 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
86 if (iwm
->conf
.mode
== UMAC_MODE_IBSS
)
87 return cfg80211_ibss_wext_siwap(dev
, info
, ap_addr
, extra
);
89 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
92 if (is_zero_ether_addr(ap_addr
->sa_data
) ||
93 is_broadcast_ether_addr(ap_addr
->sa_data
)) {
94 IWM_DBG_WEXT(iwm
, DBG
, "clear mandatory bssid %pM\n",
95 iwm
->umac_profile
->bssid
[0]);
96 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
97 iwm
->umac_profile
->bss_num
= 0;
99 IWM_DBG_WEXT(iwm
, DBG
, "add mandatory bssid %pM\n",
101 memcpy(&iwm
->umac_profile
->bssid
[0], ap_addr
->sa_data
,
103 iwm
->umac_profile
->bss_num
= 1;
106 if (iwm
->umac_profile_active
) {
107 if (!memcmp(&iwm
->umac_profile
->bssid
[0], iwm
->bssid
, ETH_ALEN
))
110 iwm_invalidate_mlme_profile(iwm
);
113 if (iwm
->umac_profile
->ssid
.ssid_len
)
114 return iwm_send_mlme_profile(iwm
);
119 static int iwm_wext_giwap(struct net_device
*dev
, struct iw_request_info
*info
,
120 struct sockaddr
*ap_addr
, char *extra
)
122 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
124 switch (iwm
->conf
.mode
) {
126 return cfg80211_ibss_wext_giwap(dev
, info
, ap_addr
, extra
);
128 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
129 ap_addr
->sa_family
= ARPHRD_ETHER
;
130 memcpy(&ap_addr
->sa_data
, iwm
->bssid
, ETH_ALEN
);
132 memset(&ap_addr
->sa_data
, 0, ETH_ALEN
);
141 static int iwm_wext_siwessid(struct net_device
*dev
,
142 struct iw_request_info
*info
,
143 struct iw_point
*data
, char *ssid
)
145 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
146 size_t len
= data
->length
;
149 if (iwm
->conf
.mode
== UMAC_MODE_IBSS
)
150 return cfg80211_ibss_wext_siwessid(dev
, info
, data
, ssid
);
152 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
155 if (len
> 0 && ssid
[len
- 1] == '\0')
158 if (iwm
->umac_profile_active
) {
159 if (iwm
->umac_profile
->ssid
.ssid_len
== len
&&
160 !memcmp(iwm
->umac_profile
->ssid
.ssid
, ssid
, len
))
163 ret
= iwm_invalidate_mlme_profile(iwm
);
165 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
170 iwm
->umac_profile
->ssid
.ssid_len
= len
;
171 memcpy(iwm
->umac_profile
->ssid
.ssid
, ssid
, len
);
173 return iwm_send_mlme_profile(iwm
);
176 static int iwm_wext_giwessid(struct net_device
*dev
,
177 struct iw_request_info
*info
,
178 struct iw_point
*data
, char *ssid
)
180 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
182 if (iwm
->conf
.mode
== UMAC_MODE_IBSS
)
183 return cfg80211_ibss_wext_giwessid(dev
, info
, data
, ssid
);
185 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
188 data
->length
= iwm
->umac_profile
->ssid
.ssid_len
;
190 memcpy(ssid
, iwm
->umac_profile
->ssid
.ssid
, data
->length
);
198 static struct iwm_key
*
199 iwm_key_init(struct iwm_priv
*iwm
, u8 key_idx
, bool in_use
,
200 struct iw_encode_ext
*ext
, u8 alg
)
202 struct iwm_key
*key
= &iwm
->keys
[key_idx
];
204 memset(key
, 0, sizeof(struct iwm_key
));
205 memcpy(key
->hdr
.mac
, ext
->addr
.sa_data
, ETH_ALEN
);
206 key
->hdr
.key_idx
= key_idx
;
207 if (is_broadcast_ether_addr(ext
->addr
.sa_data
))
208 key
->hdr
.multicast
= 1;
210 key
->in_use
= in_use
;
211 key
->flags
= ext
->ext_flags
;
213 key
->key_len
= ext
->key_len
;
214 memcpy(key
->key
, ext
->key
, ext
->key_len
);
219 static int iwm_wext_giwrate(struct net_device
*dev
,
220 struct iw_request_info
*info
,
221 struct iw_param
*rate
, char *extra
)
223 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
225 rate
->value
= iwm
->rate
* 1000000;
230 static int iwm_wext_siwencode(struct net_device
*dev
,
231 struct iw_request_info
*info
,
232 struct iw_point
*erq
, char *key_buf
)
234 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
235 struct iwm_key
*uninitialized_var(key
);
236 int idx
, i
, uninitialized_var(alg
), remove
= 0, ret
;
238 IWM_DBG_WEXT(iwm
, DBG
, "key len: %d\n", erq
->length
);
239 IWM_DBG_WEXT(iwm
, DBG
, "flags: 0x%x\n", erq
->flags
);
241 if (!iwm
->umac_profile
) {
242 IWM_ERR(iwm
, "UMAC profile not allocated yet\n");
246 if (erq
->length
== WLAN_KEY_LEN_WEP40
) {
247 alg
= UMAC_CIPHER_TYPE_WEP_40
;
248 iwm
->umac_profile
->sec
.ucast_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
249 iwm
->umac_profile
->sec
.mcast_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
250 } else if (erq
->length
== WLAN_KEY_LEN_WEP104
) {
251 alg
= UMAC_CIPHER_TYPE_WEP_104
;
252 iwm
->umac_profile
->sec
.ucast_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
253 iwm
->umac_profile
->sec
.mcast_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
256 if (erq
->flags
& IW_ENCODE_RESTRICTED
)
257 iwm
->umac_profile
->sec
.auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
259 iwm
->umac_profile
->sec
.auth_type
= UMAC_AUTH_TYPE_OPEN
;
261 idx
= erq
->flags
& IW_ENCODE_INDEX
;
263 if (iwm
->default_key
)
264 for (i
= 0; i
< IWM_NUM_KEYS
; i
++) {
265 if (iwm
->default_key
== &iwm
->keys
[i
]) {
271 iwm
->default_key
= &iwm
->keys
[idx
];
272 } else if (idx
< 1 || idx
> 4) {
277 if (erq
->flags
& IW_ENCODE_DISABLED
)
279 else if (erq
->length
== 0) {
280 if (!iwm
->keys
[idx
].in_use
)
282 iwm
->default_key
= &iwm
->keys
[idx
];
286 key
= &iwm
->keys
[idx
];
287 memset(key
, 0, sizeof(struct iwm_key
));
288 memset(key
->hdr
.mac
, 0xff, ETH_ALEN
);
289 key
->hdr
.key_idx
= idx
;
290 key
->hdr
.multicast
= 1;
291 key
->in_use
= !remove
;
293 key
->key_len
= erq
->length
;
294 memcpy(key
->key
, key_buf
, erq
->length
);
296 IWM_DBG_WEXT(iwm
, DBG
, "Setting key %d, default: %d\n",
297 idx
, !!iwm
->default_key
);
301 if ((erq
->flags
& IW_ENCODE_NOKEY
) || (erq
->length
== 0)) {
303 for (j
= 0; j
< IWM_NUM_KEYS
; j
++)
304 if (iwm
->keys
[j
].in_use
) {
305 struct iwm_key
*k
= &iwm
->keys
[j
];
308 ret
= iwm_set_key(iwm
, remove
, 0, k
);
313 iwm
->umac_profile
->sec
.ucast_cipher
=
314 UMAC_CIPHER_TYPE_NONE
;
315 iwm
->umac_profile
->sec
.mcast_cipher
=
316 UMAC_CIPHER_TYPE_NONE
;
317 iwm
->umac_profile
->sec
.auth_type
=
323 return iwm_set_key(iwm
, remove
, 0, key
);
328 * If we havent set a profile yet, we cant set keys.
329 * Keys will be pushed after we're associated.
331 if (!iwm
->umac_profile_active
)
335 * If there is a current active profile, but no
336 * default key, it's not worth trying to associate again.
338 if (!iwm
->default_key
)
342 * Here we have an active profile, but a key setting changed.
343 * We thus have to invalidate the current profile, and push the
344 * new one. Keys will be pushed when association takes place.
346 ret
= iwm_invalidate_mlme_profile(iwm
);
348 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
352 return iwm_send_mlme_profile(iwm
);
355 static int iwm_wext_giwencode(struct net_device
*dev
,
356 struct iw_request_info
*info
,
357 struct iw_point
*erq
, char *key
)
359 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
362 idx
= erq
->flags
& IW_ENCODE_INDEX
;
363 if (idx
< 1 || idx
> 4) {
365 if (!iwm
->default_key
) {
367 erq
->flags
|= IW_ENCODE_NOKEY
;
370 for (i
= 0; i
< IWM_NUM_KEYS
; i
++) {
371 if (iwm
->default_key
== &iwm
->keys
[i
]) {
381 erq
->flags
= idx
+ 1;
383 if (!iwm
->keys
[idx
].in_use
) {
385 erq
->flags
|= IW_ENCODE_DISABLED
;
389 memcpy(key
, iwm
->keys
[idx
].key
,
390 min_t(int, erq
->length
, iwm
->keys
[idx
].key_len
));
391 erq
->length
= iwm
->keys
[idx
].key_len
;
392 erq
->flags
|= IW_ENCODE_ENABLED
;
394 if (iwm
->umac_profile
->mode
== UMAC_MODE_BSS
) {
395 switch (iwm
->umac_profile
->sec
.auth_type
) {
396 case UMAC_AUTH_TYPE_OPEN
:
397 erq
->flags
|= IW_ENCODE_OPEN
;
400 erq
->flags
|= IW_ENCODE_RESTRICTED
;
408 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u8 wpa_version
)
410 if (wpa_version
& IW_AUTH_WPA_VERSION_WPA2
)
411 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
412 else if (wpa_version
& IW_AUTH_WPA_VERSION_WPA
)
413 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WPA_ON_MSK
;
415 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
420 static int iwm_wext_siwpower(struct net_device
*dev
,
421 struct iw_request_info
*info
,
422 struct iw_param
*wrq
, char *extra
)
424 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
428 power_index
= IWM_POWER_INDEX_MIN
;
431 power_index
= IWM_POWER_INDEX_DEFAULT
;
433 switch (wrq
->flags
& IW_POWER_MODE
) {
443 if (power_index
== iwm
->conf
.power_index
)
446 iwm
->conf
.power_index
= power_index
;
448 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
449 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
452 static int iwm_wext_giwpower(struct net_device
*dev
,
453 struct iw_request_info
*info
,
454 union iwreq_data
*wrqu
, char *extra
)
456 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
458 wrqu
->power
.disabled
= (iwm
->conf
.power_index
== IWM_POWER_INDEX_MIN
);
463 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u8 key_mgt
)
465 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
467 if (key_mgt
== IW_AUTH_KEY_MGMT_802_1X
)
468 *auth_type
= UMAC_AUTH_TYPE_8021X
;
469 else if (key_mgt
== IW_AUTH_KEY_MGMT_PSK
) {
470 if (iwm
->umac_profile
->sec
.flags
&
471 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
472 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
474 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
476 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
483 static int iwm_set_cipher(struct iwm_priv
*iwm
, u8 cipher
, u8 ucast
)
485 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
486 &iwm
->umac_profile
->sec
.mcast_cipher
;
489 case IW_AUTH_CIPHER_NONE
:
490 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
492 case IW_AUTH_CIPHER_WEP40
:
493 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
495 case IW_AUTH_CIPHER_TKIP
:
496 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
498 case IW_AUTH_CIPHER_CCMP
:
499 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
501 case IW_AUTH_CIPHER_WEP104
:
502 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
505 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
512 static int iwm_set_auth_alg(struct iwm_priv
*iwm
, u8 auth_alg
)
514 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
517 case IW_AUTH_ALG_OPEN_SYSTEM
:
518 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
520 case IW_AUTH_ALG_SHARED_KEY
:
521 if (iwm
->umac_profile
->sec
.flags
&
522 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
523 if (*auth_type
== UMAC_AUTH_TYPE_8021X
)
525 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
527 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
530 case IW_AUTH_ALG_LEAP
:
532 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", auth_alg
);
539 static int iwm_wext_siwauth(struct net_device
*dev
,
540 struct iw_request_info
*info
,
541 struct iw_param
*data
, char *extra
)
543 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
547 (IW_AUTH_WPA_VERSION
| IW_AUTH_KEY_MGMT
|
548 IW_AUTH_WPA_ENABLED
| IW_AUTH_80211_AUTH_ALG
)) {
549 /* We need to invalidate the current profile */
550 if (iwm
->umac_profile_active
) {
551 ret
= iwm_invalidate_mlme_profile(iwm
);
553 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
559 switch (data
->flags
& IW_AUTH_INDEX
) {
560 case IW_AUTH_WPA_VERSION
:
561 return iwm_set_wpa_version(iwm
, data
->value
);
563 case IW_AUTH_CIPHER_PAIRWISE
:
564 return iwm_set_cipher(iwm
, data
->value
, 1);
566 case IW_AUTH_CIPHER_GROUP
:
567 return iwm_set_cipher(iwm
, data
->value
, 0);
569 case IW_AUTH_KEY_MGMT
:
570 return iwm_set_key_mgt(iwm
, data
->value
);
572 case IW_AUTH_80211_AUTH_ALG
:
573 return iwm_set_auth_alg(iwm
, data
->value
);
582 static int iwm_wext_giwauth(struct net_device
*dev
,
583 struct iw_request_info
*info
,
584 struct iw_param
*data
, char *extra
)
589 static int iwm_wext_siwencodeext(struct net_device
*dev
,
590 struct iw_request_info
*info
,
591 struct iw_point
*erq
, char *extra
)
593 struct iwm_priv
*iwm
= ndev_to_iwm(dev
);
595 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*) extra
;
596 int uninitialized_var(alg
), idx
, i
, remove
= 0;
598 IWM_DBG_WEXT(iwm
, DBG
, "alg: 0x%x\n", ext
->alg
);
599 IWM_DBG_WEXT(iwm
, DBG
, "key len: %d\n", ext
->key_len
);
600 IWM_DBG_WEXT(iwm
, DBG
, "ext_flags: 0x%x\n", ext
->ext_flags
);
601 IWM_DBG_WEXT(iwm
, DBG
, "flags: 0x%x\n", erq
->flags
);
602 IWM_DBG_WEXT(iwm
, DBG
, "length: 0x%x\n", erq
->length
);
605 case IW_ENCODE_ALG_NONE
:
608 case IW_ENCODE_ALG_WEP
:
609 if (ext
->key_len
== WLAN_KEY_LEN_WEP40
)
610 alg
= UMAC_CIPHER_TYPE_WEP_40
;
611 else if (ext
->key_len
== WLAN_KEY_LEN_WEP104
)
612 alg
= UMAC_CIPHER_TYPE_WEP_104
;
614 IWM_ERR(iwm
, "Invalid key length: %d\n", ext
->key_len
);
619 case IW_ENCODE_ALG_TKIP
:
620 alg
= UMAC_CIPHER_TYPE_TKIP
;
622 case IW_ENCODE_ALG_CCMP
:
623 alg
= UMAC_CIPHER_TYPE_CCMP
;
629 idx
= erq
->flags
& IW_ENCODE_INDEX
;
632 if (iwm
->default_key
)
633 for (i
= 0; i
< IWM_NUM_KEYS
; i
++) {
634 if (iwm
->default_key
== &iwm
->keys
[i
]) {
639 } else if (idx
< 1 || idx
> 4) {
644 if (erq
->flags
& IW_ENCODE_DISABLED
)
646 else if ((erq
->length
== 0) ||
647 (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
)) {
648 iwm
->default_key
= &iwm
->keys
[idx
];
649 if (iwm
->umac_profile_active
&& ext
->alg
== IW_ENCODE_ALG_WEP
)
650 return iwm_set_tx_key(iwm
, idx
);
653 key
= iwm_key_init(iwm
, idx
, !remove
, ext
, alg
);
655 return iwm_set_key(iwm
, remove
, !iwm
->default_key
, key
);
658 static const iw_handler iwm_handlers
[] =
660 (iw_handler
) NULL
, /* SIOCSIWCOMMIT */
661 (iw_handler
) cfg80211_wext_giwname
, /* SIOCGIWNAME */
662 (iw_handler
) NULL
, /* SIOCSIWNWID */
663 (iw_handler
) NULL
, /* SIOCGIWNWID */
664 (iw_handler
) iwm_wext_siwfreq
, /* SIOCSIWFREQ */
665 (iw_handler
) iwm_wext_giwfreq
, /* SIOCGIWFREQ */
666 (iw_handler
) cfg80211_wext_siwmode
, /* SIOCSIWMODE */
667 (iw_handler
) cfg80211_wext_giwmode
, /* SIOCGIWMODE */
668 (iw_handler
) NULL
, /* SIOCSIWSENS */
669 (iw_handler
) NULL
, /* SIOCGIWSENS */
670 (iw_handler
) NULL
/* not used */, /* SIOCSIWRANGE */
671 (iw_handler
) cfg80211_wext_giwrange
, /* SIOCGIWRANGE */
672 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
673 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
674 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
675 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
676 (iw_handler
) NULL
, /* SIOCSIWSPY */
677 (iw_handler
) NULL
, /* SIOCGIWSPY */
678 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
679 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
680 (iw_handler
) iwm_wext_siwap
, /* SIOCSIWAP */
681 (iw_handler
) iwm_wext_giwap
, /* SIOCGIWAP */
682 (iw_handler
) NULL
, /* SIOCSIWMLME */
683 (iw_handler
) NULL
, /* SIOCGIWAPLIST */
684 (iw_handler
) cfg80211_wext_siwscan
, /* SIOCSIWSCAN */
685 (iw_handler
) cfg80211_wext_giwscan
, /* SIOCGIWSCAN */
686 (iw_handler
) iwm_wext_siwessid
, /* SIOCSIWESSID */
687 (iw_handler
) iwm_wext_giwessid
, /* SIOCGIWESSID */
688 (iw_handler
) NULL
, /* SIOCSIWNICKN */
689 (iw_handler
) NULL
, /* SIOCGIWNICKN */
690 (iw_handler
) NULL
, /* -- hole -- */
691 (iw_handler
) NULL
, /* -- hole -- */
692 (iw_handler
) NULL
, /* SIOCSIWRATE */
693 (iw_handler
) iwm_wext_giwrate
, /* SIOCGIWRATE */
694 (iw_handler
) cfg80211_wext_siwrts
, /* SIOCSIWRTS */
695 (iw_handler
) cfg80211_wext_giwrts
, /* SIOCGIWRTS */
696 (iw_handler
) cfg80211_wext_siwfrag
, /* SIOCSIWFRAG */
697 (iw_handler
) cfg80211_wext_giwfrag
, /* SIOCGIWFRAG */
698 (iw_handler
) NULL
, /* SIOCSIWTXPOW */
699 (iw_handler
) NULL
, /* SIOCGIWTXPOW */
700 (iw_handler
) NULL
, /* SIOCSIWRETRY */
701 (iw_handler
) NULL
, /* SIOCGIWRETRY */
702 (iw_handler
) iwm_wext_siwencode
, /* SIOCSIWENCODE */
703 (iw_handler
) iwm_wext_giwencode
, /* SIOCGIWENCODE */
704 (iw_handler
) iwm_wext_siwpower
, /* SIOCSIWPOWER */
705 (iw_handler
) iwm_wext_giwpower
, /* SIOCGIWPOWER */
706 (iw_handler
) NULL
, /* -- hole -- */
707 (iw_handler
) NULL
, /* -- hole -- */
708 (iw_handler
) NULL
, /* SIOCSIWGENIE */
709 (iw_handler
) NULL
, /* SIOCGIWGENIE */
710 (iw_handler
) iwm_wext_siwauth
, /* SIOCSIWAUTH */
711 (iw_handler
) iwm_wext_giwauth
, /* SIOCGIWAUTH */
712 (iw_handler
) iwm_wext_siwencodeext
, /* SIOCSIWENCODEEXT */
713 (iw_handler
) NULL
, /* SIOCGIWENCODEEXT */
714 (iw_handler
) NULL
, /* SIOCSIWPMKSA */
715 (iw_handler
) NULL
, /* -- hole -- */
718 const struct iw_handler_def iwm_iw_handler_def
= {
719 .num_standard
= ARRAY_SIZE(iwm_handlers
),
720 .standard
= (iw_handler
*) iwm_handlers
,
721 .get_wireless_stats
= iwm_get_wireless_stats
,