Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.31-rc7 633 lines 18 kB view raw
1/* 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" 24#include "led.h" 25#include "rate.h" 26#include "wpa.h" 27#include "aes_ccm.h" 28 29 30static int ieee80211_ioctl_siwgenie(struct net_device *dev, 31 struct iw_request_info *info, 32 struct iw_point *data, char *extra) 33{ 34 struct ieee80211_sub_if_data *sdata; 35 36 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 37 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) 41 return ret; 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; 45 if (ret != -EALREADY) 46 ieee80211_sta_req_auth(sdata); 47 return 0; 48 } 49 50 return -EOPNOTSUPP; 51} 52 53static int ieee80211_ioctl_siwfreq(struct net_device *dev, 54 struct iw_request_info *info, 55 struct iw_freq *freq, char *extra) 56{ 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; 60 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; 65 66 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 67 if (freq->e == 0) { 68 if (freq->m < 0) { 69 if (sdata->vif.type == NL80211_IFTYPE_STATION) 70 sdata->u.mgd.flags |= 71 IEEE80211_STA_AUTO_CHANNEL_SEL; 72 return 0; 73 } else 74 chan = ieee80211_get_channel(local->hw.wiphy, 75 ieee80211_channel_to_frequency(freq->m)); 76 } else { 77 int i, div = 1000000; 78 for (i = 0; i < freq->e; i++) 79 div /= 10; 80 if (div <= 0) 81 return -EINVAL; 82 chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div); 83 } 84 85 if (!chan) 86 return -EINVAL; 87 88 if (chan->flags & IEEE80211_CHAN_DISABLED) 89 return -EINVAL; 90 91 /* 92 * no change except maybe auto -> fixed, ignore the HT 93 * setting so you can fix a channel you're on already 94 */ 95 if (local->oper_channel == chan) 96 return 0; 97 98 if (sdata->vif.type == NL80211_IFTYPE_STATION) 99 ieee80211_sta_req_auth(sdata); 100 101 local->oper_channel = chan; 102 local->oper_channel_type = NL80211_CHAN_NO_HT; 103 ieee80211_hw_config(local, 0); 104 105 return 0; 106} 107 108 109static int ieee80211_ioctl_giwfreq(struct net_device *dev, 110 struct iw_request_info *info, 111 struct iw_freq *freq, char *extra) 112{ 113 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 114 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 115 116 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 117 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); 118 119 freq->m = local->oper_channel->center_freq; 120 freq->e = 6; 121 122 return 0; 123} 124 125 126static int ieee80211_ioctl_siwessid(struct net_device *dev, 127 struct iw_request_info *info, 128 struct iw_point *data, char *ssid) 129{ 130 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 131 size_t len = data->length; 132 int ret; 133 134 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 135 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); 136 137 /* iwconfig uses nul termination in SSID.. */ 138 if (len > 0 && ssid[len - 1] == '\0') 139 len--; 140 141 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 142 if (data->flags) 143 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 144 else 145 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL; 146 147 ret = ieee80211_sta_set_ssid(sdata, ssid, len); 148 if (ret) 149 return ret; 150 151 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 152 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT; 153 ieee80211_sta_req_auth(sdata); 154 return 0; 155 } 156 157 return -EOPNOTSUPP; 158} 159 160 161static int ieee80211_ioctl_giwessid(struct net_device *dev, 162 struct iw_request_info *info, 163 struct iw_point *data, char *ssid) 164{ 165 size_t len; 166 struct ieee80211_sub_if_data *sdata; 167 168 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 169 170 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 171 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); 172 173 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 174 int res = ieee80211_sta_get_ssid(sdata, ssid, &len); 175 if (res == 0) { 176 data->length = len; 177 data->flags = 1; 178 } else 179 data->flags = 0; 180 return res; 181 } 182 183 return -EOPNOTSUPP; 184} 185 186 187static int ieee80211_ioctl_siwap(struct net_device *dev, 188 struct iw_request_info *info, 189 struct sockaddr *ap_addr, char *extra) 190{ 191 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 192 193 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 194 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); 195 196 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 197 int ret; 198 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; 204 else 205 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 206 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data); 207 if (ret) 208 return ret; 209 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 210 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT; 211 ieee80211_sta_req_auth(sdata); 212 return 0; 213 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 214 /* 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(). 220 */ 221 if (netif_running(dev)) 222 return -EBUSY; 223 224 memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data, 225 ETH_ALEN); 226 227 return 0; 228 } 229 230 return -EOPNOTSUPP; 231} 232 233 234static int ieee80211_ioctl_giwap(struct net_device *dev, 235 struct iw_request_info *info, 236 struct sockaddr *ap_addr, char *extra) 237{ 238 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 239 240 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 241 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); 242 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); 247 } else 248 memset(&ap_addr->sa_data, 0, ETH_ALEN); 249 return 0; 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); 253 return 0; 254 } 255 256 return -EOPNOTSUPP; 257} 258 259 260static int ieee80211_ioctl_siwrate(struct net_device *dev, 261 struct iw_request_info *info, 262 struct iw_param *rate, char *extra) 263{ 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; 269 270 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 271 272 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 273 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; 279 if (rate->value < 0) 280 return 0; 281 282 for (i=0; i< sband->n_bitrates; i++) { 283 struct ieee80211_rate *brate = &sband->bitrates[i]; 284 int this_rate = brate->bitrate; 285 286 if (target_rate == this_rate) { 287 sdata->max_ratectrl_rateidx = i; 288 if (rate->fixed) 289 sdata->force_unicast_rateidx = i; 290 err = 0; 291 break; 292 } 293 } 294 return err; 295} 296 297static int ieee80211_ioctl_giwrate(struct net_device *dev, 298 struct iw_request_info *info, 299 struct iw_param *rate, char *extra) 300{ 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; 305 306 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 307 308 if (sdata->vif.type != NL80211_IFTYPE_STATION) 309 return -EOPNOTSUPP; 310 311 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 312 313 rcu_read_lock(); 314 315 sta = sta_info_get(local, sdata->u.mgd.bssid); 316 317 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) 318 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; 319 else 320 rate->value = 0; 321 322 rcu_read_unlock(); 323 324 if (!sta) 325 return -ENODEV; 326 327 rate->value *= 100000; 328 329 return 0; 330} 331 332static int ieee80211_ioctl_siwpower(struct net_device *dev, 333 struct iw_request_info *info, 334 struct iw_param *wrq, 335 char *extra) 336{ 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; 340 int timeout = 0; 341 bool ps; 342 343 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) 344 return -EOPNOTSUPP; 345 346 if (sdata->vif.type != NL80211_IFTYPE_STATION) 347 return -EINVAL; 348 349 if (wrq->disabled) { 350 ps = false; 351 timeout = 0; 352 goto set; 353 } 354 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 */ 359 ps = true; 360 break; 361 default: /* Otherwise we ignore */ 362 return -EINVAL; 363 } 364 365 if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT)) 366 return -EINVAL; 367 368 if (wrq->flags & IW_POWER_TIMEOUT) 369 timeout = wrq->value / 1000; 370 371 set: 372 if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout) 373 return 0; 374 375 sdata->u.mgd.powersave = ps; 376 conf->dynamic_ps_timeout = timeout; 377 378 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 379 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 380 381 ieee80211_recalc_ps(local, -1); 382 383 return 0; 384} 385 386static int ieee80211_ioctl_giwpower(struct net_device *dev, 387 struct iw_request_info *info, 388 union iwreq_data *wrqu, 389 char *extra) 390{ 391 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 392 393 wrqu->power.disabled = !sdata->u.mgd.powersave; 394 395 return 0; 396} 397 398static int ieee80211_ioctl_siwauth(struct net_device *dev, 399 struct iw_request_info *info, 400 struct iw_param *data, char *extra) 401{ 402 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 403 int ret = 0; 404 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: 412 break; 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; 419 else 420 sdata->u.mgd.flags &= 421 ~IEEE80211_STA_TKIP_WEP_USED; 422 } 423 break; 424 case IW_AUTH_DROP_UNENCRYPTED: 425 sdata->drop_unencrypted = !!data->value; 426 break; 427 case IW_AUTH_PRIVACY_INVOKED: 428 if (sdata->vif.type != NL80211_IFTYPE_STATION) 429 ret = -EINVAL; 430 else { 431 sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; 432 /* 433 * Privacy invoked by wpa_supplicant, store the 434 * value and allow associating to a protected 435 * network without having a key up front. 436 */ 437 if (data->value) 438 sdata->u.mgd.flags |= 439 IEEE80211_STA_PRIVACY_INVOKED; 440 } 441 break; 442 case IW_AUTH_80211_AUTH_ALG: 443 if (sdata->vif.type == NL80211_IFTYPE_STATION) 444 sdata->u.mgd.auth_algs = data->value; 445 else 446 ret = -EOPNOTSUPP; 447 break; 448 case IW_AUTH_MFP: 449 if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) { 450 ret = -EOPNOTSUPP; 451 break; 452 } 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; 457 break; 458 case IW_AUTH_MFP_OPTIONAL: 459 sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL; 460 break; 461 case IW_AUTH_MFP_REQUIRED: 462 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED; 463 break; 464 default: 465 ret = -EINVAL; 466 } 467 } else 468 ret = -EOPNOTSUPP; 469 break; 470 default: 471 ret = -EOPNOTSUPP; 472 break; 473 } 474 return ret; 475} 476 477/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 478static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) 479{ 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; 484 485 rcu_read_lock(); 486 487 if (sdata->vif.type == NL80211_IFTYPE_STATION) 488 sta = sta_info_get(local, sdata->u.mgd.bssid); 489 490 if (!sta) { 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; 497 } else { 498 wstats->qual.updated = 0; 499 /* 500 * mirror what cfg80211 does for iwrange/scan results, 501 * otherwise userspace gets confused. 502 */ 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; 507 } else { 508 wstats->qual.updated |= IW_QUAL_LEVEL_INVALID; 509 wstats->qual.updated |= IW_QUAL_QUAL_INVALID; 510 } 511 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; 517 518 wstats->qual.updated |= IW_QUAL_DBM; 519 wstats->qual.level = sig; 520 if (sig < -110) 521 sig = -110; 522 else if (sig > -40) 523 sig = -40; 524 wstats->qual.qual = sig + 110; 525 } 526 527 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { 528 /* 529 * This assumes that if driver reports noise, it also 530 * reports signal in dBm. 531 */ 532 wstats->qual.noise = sta->last_noise; 533 wstats->qual.updated |= IW_QUAL_NOISE_UPDATED; 534 } else { 535 wstats->qual.updated |= IW_QUAL_NOISE_INVALID; 536 } 537 } 538 539 rcu_read_unlock(); 540 541 return wstats; 542} 543 544static int ieee80211_ioctl_giwauth(struct net_device *dev, 545 struct iw_request_info *info, 546 struct iw_param *data, char *extra) 547{ 548 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 549 int ret = 0; 550 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; 555 else 556 ret = -EOPNOTSUPP; 557 break; 558 default: 559 ret = -EOPNOTSUPP; 560 break; 561 } 562 return ret; 563} 564 565 566/* Structures to export the Wireless Handlers */ 567 568static const iw_handler ieee80211_handler[] = 569{ 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 -- */ 626}; 627 628const struct iw_handler_def ieee80211_iw_handler_def = 629{ 630 .num_standard = ARRAY_SIZE(ieee80211_handler), 631 .standard = (iw_handler *) ieee80211_handler, 632 .get_wireless_stats = ieee80211_get_wireless_stats, 633};