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.29-rc7 2819 lines 76 kB view raw
1/* 2 * Driver for RNDIS based wireless USB devices. 3 * 4 * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net> 5 * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 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. 16 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 * Portions of this file are based on NDISwrapper project, 22 * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani 23 * http://ndiswrapper.sourceforge.net/ 24 */ 25 26// #define DEBUG // error path messages, extra info 27// #define VERBOSE // more; success messages 28 29#include <linux/module.h> 30#include <linux/init.h> 31#include <linux/netdevice.h> 32#include <linux/etherdevice.h> 33#include <linux/ethtool.h> 34#include <linux/workqueue.h> 35#include <linux/mutex.h> 36#include <linux/mii.h> 37#include <linux/usb.h> 38#include <linux/usb/cdc.h> 39#include <linux/wireless.h> 40#include <linux/ieee80211.h> 41#include <linux/if_arp.h> 42#include <linux/ctype.h> 43#include <linux/spinlock.h> 44#include <net/iw_handler.h> 45#include <linux/usb/usbnet.h> 46#include <linux/usb/rndis_host.h> 47 48 49/* NOTE: All these are settings for Broadcom chipset */ 50static char modparam_country[4] = "EU"; 51module_param_string(country, modparam_country, 4, 0444); 52MODULE_PARM_DESC(country, "Country code (ISO 3166-1 alpha-2), default: EU"); 53 54static int modparam_frameburst = 1; 55module_param_named(frameburst, modparam_frameburst, int, 0444); 56MODULE_PARM_DESC(frameburst, "enable frame bursting (default: on)"); 57 58static int modparam_afterburner = 0; 59module_param_named(afterburner, modparam_afterburner, int, 0444); 60MODULE_PARM_DESC(afterburner, 61 "enable afterburner aka '125 High Speed Mode' (default: off)"); 62 63static int modparam_power_save = 0; 64module_param_named(power_save, modparam_power_save, int, 0444); 65MODULE_PARM_DESC(power_save, 66 "set power save mode: 0=off, 1=on, 2=fast (default: off)"); 67 68static int modparam_power_output = 3; 69module_param_named(power_output, modparam_power_output, int, 0444); 70MODULE_PARM_DESC(power_output, 71 "set power output: 0=25%, 1=50%, 2=75%, 3=100% (default: 100%)"); 72 73static int modparam_roamtrigger = -70; 74module_param_named(roamtrigger, modparam_roamtrigger, int, 0444); 75MODULE_PARM_DESC(roamtrigger, 76 "set roaming dBm trigger: -80=optimize for distance, " 77 "-60=bandwidth (default: -70)"); 78 79static int modparam_roamdelta = 1; 80module_param_named(roamdelta, modparam_roamdelta, int, 0444); 81MODULE_PARM_DESC(roamdelta, 82 "set roaming tendency: 0=aggressive, 1=moderate, " 83 "2=conservative (default: moderate)"); 84 85static int modparam_workaround_interval = 500; 86module_param_named(workaround_interval, modparam_workaround_interval, 87 int, 0444); 88MODULE_PARM_DESC(workaround_interval, 89 "set stall workaround interval in msecs (default: 500)"); 90 91 92/* various RNDIS OID defs */ 93#define OID_GEN_LINK_SPEED ccpu2(0x00010107) 94#define OID_GEN_RNDIS_CONFIG_PARAMETER ccpu2(0x0001021b) 95 96#define OID_GEN_XMIT_OK ccpu2(0x00020101) 97#define OID_GEN_RCV_OK ccpu2(0x00020102) 98#define OID_GEN_XMIT_ERROR ccpu2(0x00020103) 99#define OID_GEN_RCV_ERROR ccpu2(0x00020104) 100#define OID_GEN_RCV_NO_BUFFER ccpu2(0x00020105) 101 102#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101) 103#define OID_802_3_CURRENT_ADDRESS ccpu2(0x01010102) 104#define OID_802_3_MULTICAST_LIST ccpu2(0x01010103) 105#define OID_802_3_MAXIMUM_LIST_SIZE ccpu2(0x01010104) 106 107#define OID_802_11_BSSID ccpu2(0x0d010101) 108#define OID_802_11_SSID ccpu2(0x0d010102) 109#define OID_802_11_INFRASTRUCTURE_MODE ccpu2(0x0d010108) 110#define OID_802_11_ADD_WEP ccpu2(0x0d010113) 111#define OID_802_11_REMOVE_WEP ccpu2(0x0d010114) 112#define OID_802_11_DISASSOCIATE ccpu2(0x0d010115) 113#define OID_802_11_AUTHENTICATION_MODE ccpu2(0x0d010118) 114#define OID_802_11_PRIVACY_FILTER ccpu2(0x0d010119) 115#define OID_802_11_BSSID_LIST_SCAN ccpu2(0x0d01011a) 116#define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) 117#define OID_802_11_ADD_KEY ccpu2(0x0d01011d) 118#define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) 119#define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f) 120#define OID_802_11_PMKID ccpu2(0x0d010123) 121#define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) 122#define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) 123#define OID_802_11_TX_POWER_LEVEL ccpu2(0x0d010205) 124#define OID_802_11_RSSI ccpu2(0x0d010206) 125#define OID_802_11_RSSI_TRIGGER ccpu2(0x0d010207) 126#define OID_802_11_FRAGMENTATION_THRESHOLD ccpu2(0x0d010209) 127#define OID_802_11_RTS_THRESHOLD ccpu2(0x0d01020a) 128#define OID_802_11_SUPPORTED_RATES ccpu2(0x0d01020e) 129#define OID_802_11_CONFIGURATION ccpu2(0x0d010211) 130#define OID_802_11_BSSID_LIST ccpu2(0x0d010217) 131 132 133/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */ 134#define WL_NOISE -96 /* typical noise level in dBm */ 135#define WL_SIGMAX -32 /* typical maximum signal level in dBm */ 136 137 138/* Assume that Broadcom 4320 (only chipset at time of writing known to be 139 * based on wireless rndis) has default txpower of 13dBm. 140 * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications. 141 * 13dBm == 19.9mW 142 */ 143#define BCM4320_DEFAULT_TXPOWER 20 144 145 146/* codes for "status" field of completion messages */ 147#define RNDIS_STATUS_ADAPTER_NOT_READY ccpu2(0xc0010011) 148#define RNDIS_STATUS_ADAPTER_NOT_OPEN ccpu2(0xc0010012) 149 150 151/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c 152 * slightly modified for datatype endianess, etc 153 */ 154#define NDIS_802_11_LENGTH_SSID 32 155#define NDIS_802_11_LENGTH_RATES 8 156#define NDIS_802_11_LENGTH_RATES_EX 16 157 158enum ndis_80211_net_type { 159 ndis_80211_type_freq_hop, 160 ndis_80211_type_direct_seq, 161 ndis_80211_type_ofdm_a, 162 ndis_80211_type_ofdm_g 163}; 164 165enum ndis_80211_net_infra { 166 ndis_80211_infra_adhoc, 167 ndis_80211_infra_infra, 168 ndis_80211_infra_auto_unknown 169}; 170 171enum ndis_80211_auth_mode { 172 ndis_80211_auth_open, 173 ndis_80211_auth_shared, 174 ndis_80211_auth_auto_switch, 175 ndis_80211_auth_wpa, 176 ndis_80211_auth_wpa_psk, 177 ndis_80211_auth_wpa_none, 178 ndis_80211_auth_wpa2, 179 ndis_80211_auth_wpa2_psk 180}; 181 182enum ndis_80211_encr_status { 183 ndis_80211_encr_wep_enabled, 184 ndis_80211_encr_disabled, 185 ndis_80211_encr_wep_key_absent, 186 ndis_80211_encr_not_supported, 187 ndis_80211_encr_tkip_enabled, 188 ndis_80211_encr_tkip_key_absent, 189 ndis_80211_encr_ccmp_enabled, 190 ndis_80211_encr_ccmp_key_absent 191}; 192 193enum ndis_80211_priv_filter { 194 ndis_80211_priv_accept_all, 195 ndis_80211_priv_8021x_wep 196}; 197 198struct ndis_80211_ssid { 199 __le32 length; 200 u8 essid[NDIS_802_11_LENGTH_SSID]; 201} __attribute__((packed)); 202 203struct ndis_80211_conf_freq_hop { 204 __le32 length; 205 __le32 hop_pattern; 206 __le32 hop_set; 207 __le32 dwell_time; 208} __attribute__((packed)); 209 210struct ndis_80211_conf { 211 __le32 length; 212 __le32 beacon_period; 213 __le32 atim_window; 214 __le32 ds_config; 215 struct ndis_80211_conf_freq_hop fh_config; 216} __attribute__((packed)); 217 218struct ndis_80211_bssid_ex { 219 __le32 length; 220 u8 mac[6]; 221 u8 padding[2]; 222 struct ndis_80211_ssid ssid; 223 __le32 privacy; 224 __le32 rssi; 225 __le32 net_type; 226 struct ndis_80211_conf config; 227 __le32 net_infra; 228 u8 rates[NDIS_802_11_LENGTH_RATES_EX]; 229 __le32 ie_length; 230 u8 ies[0]; 231} __attribute__((packed)); 232 233struct ndis_80211_bssid_list_ex { 234 __le32 num_items; 235 struct ndis_80211_bssid_ex bssid[0]; 236} __attribute__((packed)); 237 238struct ndis_80211_fixed_ies { 239 u8 timestamp[8]; 240 __le16 beacon_interval; 241 __le16 capabilities; 242} __attribute__((packed)); 243 244struct ndis_80211_wep_key { 245 __le32 size; 246 __le32 index; 247 __le32 length; 248 u8 material[32]; 249} __attribute__((packed)); 250 251struct ndis_80211_key { 252 __le32 size; 253 __le32 index; 254 __le32 length; 255 u8 bssid[6]; 256 u8 padding[6]; 257 u8 rsc[8]; 258 u8 material[32]; 259} __attribute__((packed)); 260 261struct ndis_80211_remove_key { 262 __le32 size; 263 __le32 index; 264 u8 bssid[6]; 265} __attribute__((packed)); 266 267struct ndis_config_param { 268 __le32 name_offs; 269 __le32 name_length; 270 __le32 type; 271 __le32 value_offs; 272 __le32 value_length; 273} __attribute__((packed)); 274 275struct ndis_80211_assoc_info { 276 __le32 length; 277 __le16 req_ies; 278 struct req_ie { 279 __le16 capa; 280 __le16 listen_interval; 281 u8 cur_ap_address[6]; 282 } req_ie; 283 __le32 req_ie_length; 284 __le32 offset_req_ies; 285 __le16 resp_ies; 286 struct resp_ie { 287 __le16 capa; 288 __le16 status_code; 289 __le16 assoc_id; 290 } resp_ie; 291 __le32 resp_ie_length; 292 __le32 offset_resp_ies; 293} __attribute__((packed)); 294 295/* these have to match what is in wpa_supplicant */ 296enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; 297enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, 298 CIPHER_WEP104 }; 299enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, 300 KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE }; 301 302/* 303 * private data 304 */ 305#define NET_TYPE_11FB 0 306 307#define CAP_MODE_80211A 1 308#define CAP_MODE_80211B 2 309#define CAP_MODE_80211G 4 310#define CAP_MODE_MASK 7 311#define CAP_SUPPORT_TXPOWER 8 312 313#define WORK_LINK_UP (1<<0) 314#define WORK_LINK_DOWN (1<<1) 315#define WORK_SET_MULTICAST_LIST (1<<2) 316 317#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) 318 319/* RNDIS device private data */ 320struct rndis_wext_private { 321 char name[32]; 322 323 struct usbnet *usbdev; 324 325 struct workqueue_struct *workqueue; 326 struct delayed_work stats_work; 327 struct work_struct work; 328 struct mutex command_lock; 329 spinlock_t stats_lock; 330 unsigned long work_pending; 331 332 struct iw_statistics iwstats; 333 struct iw_statistics privstats; 334 335 int nick_len; 336 char nick[32]; 337 338 int caps; 339 int multicast_size; 340 341 /* module parameters */ 342 char param_country[4]; 343 int param_frameburst; 344 int param_afterburner; 345 int param_power_save; 346 int param_power_output; 347 int param_roamtrigger; 348 int param_roamdelta; 349 u32 param_workaround_interval; 350 351 /* hardware state */ 352 int radio_on; 353 int infra_mode; 354 struct ndis_80211_ssid essid; 355 356 /* encryption stuff */ 357 int encr_tx_key_index; 358 char encr_keys[4][32]; 359 int encr_key_len[4]; 360 int wpa_version; 361 int wpa_keymgmt; 362 int wpa_authalg; 363 int wpa_ie_len; 364 u8 *wpa_ie; 365 int wpa_cipher_pair; 366 int wpa_cipher_group; 367 368 u8 command_buffer[COMMAND_BUFFER_SIZE]; 369}; 370 371 372static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 373 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; 374 375static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 }; 376 377static const int bcm4320_power_output[4] = { 25, 50, 75, 100 }; 378 379static const unsigned char zero_bssid[ETH_ALEN] = {0,}; 380static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 381 0xff, 0xff, 0xff }; 382 383 384static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev) 385{ 386 return (struct rndis_wext_private *)dev->driver_priv; 387} 388 389 390static u32 get_bcm4320_power(struct rndis_wext_private *priv) 391{ 392 return BCM4320_DEFAULT_TXPOWER * 393 bcm4320_power_output[priv->param_power_output] / 100; 394} 395 396 397/* translate error code */ 398static int rndis_error_status(__le32 rndis_status) 399{ 400 int ret = -EINVAL; 401 switch (rndis_status) { 402 case RNDIS_STATUS_SUCCESS: 403 ret = 0; 404 break; 405 case RNDIS_STATUS_FAILURE: 406 case RNDIS_STATUS_INVALID_DATA: 407 ret = -EINVAL; 408 break; 409 case RNDIS_STATUS_NOT_SUPPORTED: 410 ret = -EOPNOTSUPP; 411 break; 412 case RNDIS_STATUS_ADAPTER_NOT_READY: 413 case RNDIS_STATUS_ADAPTER_NOT_OPEN: 414 ret = -EBUSY; 415 break; 416 } 417 return ret; 418} 419 420 421static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) 422{ 423 struct rndis_wext_private *priv = get_rndis_wext_priv(dev); 424 union { 425 void *buf; 426 struct rndis_msg_hdr *header; 427 struct rndis_query *get; 428 struct rndis_query_c *get_c; 429 } u; 430 int ret, buflen; 431 432 buflen = *len + sizeof(*u.get); 433 if (buflen < CONTROL_BUFFER_SIZE) 434 buflen = CONTROL_BUFFER_SIZE; 435 436 if (buflen > COMMAND_BUFFER_SIZE) { 437 u.buf = kmalloc(buflen, GFP_KERNEL); 438 if (!u.buf) 439 return -ENOMEM; 440 } else { 441 u.buf = priv->command_buffer; 442 } 443 444 mutex_lock(&priv->command_lock); 445 446 memset(u.get, 0, sizeof *u.get); 447 u.get->msg_type = RNDIS_MSG_QUERY; 448 u.get->msg_len = ccpu2(sizeof *u.get); 449 u.get->oid = oid; 450 451 ret = rndis_command(dev, u.header, buflen); 452 if (ret == 0) { 453 ret = le32_to_cpu(u.get_c->len); 454 *len = (*len > ret) ? ret : *len; 455 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); 456 ret = rndis_error_status(u.get_c->status); 457 } 458 459 mutex_unlock(&priv->command_lock); 460 461 if (u.buf != priv->command_buffer) 462 kfree(u.buf); 463 return ret; 464} 465 466 467static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) 468{ 469 struct rndis_wext_private *priv = get_rndis_wext_priv(dev); 470 union { 471 void *buf; 472 struct rndis_msg_hdr *header; 473 struct rndis_set *set; 474 struct rndis_set_c *set_c; 475 } u; 476 int ret, buflen; 477 478 buflen = len + sizeof(*u.set); 479 if (buflen < CONTROL_BUFFER_SIZE) 480 buflen = CONTROL_BUFFER_SIZE; 481 482 if (buflen > COMMAND_BUFFER_SIZE) { 483 u.buf = kmalloc(buflen, GFP_KERNEL); 484 if (!u.buf) 485 return -ENOMEM; 486 } else { 487 u.buf = priv->command_buffer; 488 } 489 490 mutex_lock(&priv->command_lock); 491 492 memset(u.set, 0, sizeof *u.set); 493 u.set->msg_type = RNDIS_MSG_SET; 494 u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len); 495 u.set->oid = oid; 496 u.set->len = cpu_to_le32(len); 497 u.set->offset = ccpu2(sizeof(*u.set) - 8); 498 u.set->handle = ccpu2(0); 499 memcpy(u.buf + sizeof(*u.set), data, len); 500 501 ret = rndis_command(dev, u.header, buflen); 502 if (ret == 0) 503 ret = rndis_error_status(u.set_c->status); 504 505 mutex_unlock(&priv->command_lock); 506 507 if (u.buf != priv->command_buffer) 508 kfree(u.buf); 509 return ret; 510} 511 512 513/* 514 * Specs say that we can only set config parameters only soon after device 515 * initialization. 516 * value_type: 0 = u32, 2 = unicode string 517 */ 518static int rndis_set_config_parameter(struct usbnet *dev, char *param, 519 int value_type, void *value) 520{ 521 struct ndis_config_param *infobuf; 522 int value_len, info_len, param_len, ret, i; 523 __le16 *unibuf; 524 __le32 *dst_value; 525 526 if (value_type == 0) 527 value_len = sizeof(__le32); 528 else if (value_type == 2) 529 value_len = strlen(value) * sizeof(__le16); 530 else 531 return -EINVAL; 532 533 param_len = strlen(param) * sizeof(__le16); 534 info_len = sizeof(*infobuf) + param_len + value_len; 535 536#ifdef DEBUG 537 info_len += 12; 538#endif 539 infobuf = kmalloc(info_len, GFP_KERNEL); 540 if (!infobuf) 541 return -ENOMEM; 542 543#ifdef DEBUG 544 info_len -= 12; 545 /* extra 12 bytes are for padding (debug output) */ 546 memset(infobuf, 0xCC, info_len + 12); 547#endif 548 549 if (value_type == 2) 550 devdbg(dev, "setting config parameter: %s, value: %s", 551 param, (u8 *)value); 552 else 553 devdbg(dev, "setting config parameter: %s, value: %d", 554 param, *(u32 *)value); 555 556 infobuf->name_offs = cpu_to_le32(sizeof(*infobuf)); 557 infobuf->name_length = cpu_to_le32(param_len); 558 infobuf->type = cpu_to_le32(value_type); 559 infobuf->value_offs = cpu_to_le32(sizeof(*infobuf) + param_len); 560 infobuf->value_length = cpu_to_le32(value_len); 561 562 /* simple string to unicode string conversion */ 563 unibuf = (void *)infobuf + sizeof(*infobuf); 564 for (i = 0; i < param_len / sizeof(__le16); i++) 565 unibuf[i] = cpu_to_le16(param[i]); 566 567 if (value_type == 2) { 568 unibuf = (void *)infobuf + sizeof(*infobuf) + param_len; 569 for (i = 0; i < value_len / sizeof(__le16); i++) 570 unibuf[i] = cpu_to_le16(((u8 *)value)[i]); 571 } else { 572 dst_value = (void *)infobuf + sizeof(*infobuf) + param_len; 573 *dst_value = cpu_to_le32(*(u32 *)value); 574 } 575 576#ifdef DEBUG 577 devdbg(dev, "info buffer (len: %d):", info_len); 578 for (i = 0; i < info_len; i += 12) { 579 u32 *tmp = (u32 *)((u8 *)infobuf + i); 580 devdbg(dev, "%08X:%08X:%08X", 581 cpu_to_be32(tmp[0]), 582 cpu_to_be32(tmp[1]), 583 cpu_to_be32(tmp[2])); 584 } 585#endif 586 587 ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER, 588 infobuf, info_len); 589 if (ret != 0) 590 devdbg(dev, "setting rndis config paramater failed, %d.", ret); 591 592 kfree(infobuf); 593 return ret; 594} 595 596static int rndis_set_config_parameter_str(struct usbnet *dev, 597 char *param, char *value) 598{ 599 return(rndis_set_config_parameter(dev, param, 2, value)); 600} 601 602/*static int rndis_set_config_parameter_u32(struct usbnet *dev, 603 char *param, u32 value) 604{ 605 return(rndis_set_config_parameter(dev, param, 0, &value)); 606}*/ 607 608 609/* 610 * data conversion functions 611 */ 612static int level_to_qual(int level) 613{ 614 int qual = 100 * (level - WL_NOISE) / (WL_SIGMAX - WL_NOISE); 615 return qual >= 0 ? (qual <= 100 ? qual : 100) : 0; 616} 617 618 619static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq) 620{ 621 freq->e = 0; 622 freq->i = 0; 623 freq->flags = 0; 624 625 /* see comment in wireless.h above the "struct iw_freq" 626 * definition for an explanation of this if 627 * NOTE: 1000000 is due to the kHz 628 */ 629 if (dsconfig > 1000000) { 630 freq->m = dsconfig / 10; 631 freq->e = 1; 632 } else 633 freq->m = dsconfig; 634 635 /* convert from kHz to Hz */ 636 freq->e += 3; 637} 638 639 640static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) 641{ 642 if (freq->m < 1000 && freq->e == 0) { 643 if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan)) 644 *dsconfig = freq_chan[freq->m - 1] * 1000; 645 else 646 return -1; 647 } else { 648 int i; 649 *dsconfig = freq->m; 650 for (i = freq->e; i > 0; i--) 651 *dsconfig *= 10; 652 *dsconfig /= 1000; 653 } 654 655 return 0; 656} 657 658 659/* 660 * common functions 661 */ 662static int 663add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index); 664 665static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) 666{ 667 int ret, len; 668 669 len = sizeof(*ssid); 670 ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len); 671 672 if (ret != 0) 673 ssid->length = 0; 674 675#ifdef DEBUG 676 { 677 unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1]; 678 679 memcpy(tmp, ssid->essid, le32_to_cpu(ssid->length)); 680 tmp[le32_to_cpu(ssid->length)] = 0; 681 devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret); 682 } 683#endif 684 return ret; 685} 686 687 688static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) 689{ 690 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 691 int ret; 692 693 ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); 694 if (ret == 0) { 695 memcpy(&priv->essid, ssid, sizeof(priv->essid)); 696 priv->radio_on = 1; 697 devdbg(usbdev, "set_essid: radio_on = 1"); 698 } 699 700 return ret; 701} 702 703 704static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) 705{ 706 int ret, len; 707 708 len = ETH_ALEN; 709 ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len); 710 711 if (ret != 0) 712 memset(bssid, 0, ETH_ALEN); 713 714 return ret; 715} 716 717static int get_association_info(struct usbnet *usbdev, 718 struct ndis_80211_assoc_info *info, int len) 719{ 720 return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, 721 info, &len); 722} 723 724static int is_associated(struct usbnet *usbdev) 725{ 726 u8 bssid[ETH_ALEN]; 727 int ret; 728 729 ret = get_bssid(usbdev, bssid); 730 731 return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0); 732} 733 734 735static int disassociate(struct usbnet *usbdev, int reset_ssid) 736{ 737 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 738 struct ndis_80211_ssid ssid; 739 int i, ret = 0; 740 741 if (priv->radio_on) { 742 ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0); 743 if (ret == 0) { 744 priv->radio_on = 0; 745 devdbg(usbdev, "disassociate: radio_on = 0"); 746 747 if (reset_ssid) 748 msleep(100); 749 } 750 } 751 752 /* disassociate causes radio to be turned off; if reset_ssid 753 * is given, set random ssid to enable radio */ 754 if (reset_ssid) { 755 ssid.length = cpu_to_le32(sizeof(ssid.essid)); 756 get_random_bytes(&ssid.essid[2], sizeof(ssid.essid)-2); 757 ssid.essid[0] = 0x1; 758 ssid.essid[1] = 0xff; 759 for (i = 2; i < sizeof(ssid.essid); i++) 760 ssid.essid[i] = 0x1 + (ssid.essid[i] * 0xfe / 0xff); 761 ret = set_essid(usbdev, &ssid); 762 } 763 return ret; 764} 765 766 767static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) 768{ 769 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 770 __le32 tmp; 771 int auth_mode, ret; 772 773 devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x " 774 "keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt); 775 776 if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { 777 if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) 778 auth_mode = ndis_80211_auth_wpa2; 779 else 780 auth_mode = ndis_80211_auth_wpa2_psk; 781 } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { 782 if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) 783 auth_mode = ndis_80211_auth_wpa; 784 else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) 785 auth_mode = ndis_80211_auth_wpa_psk; 786 else 787 auth_mode = ndis_80211_auth_wpa_none; 788 } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { 789 if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) 790 auth_mode = ndis_80211_auth_auto_switch; 791 else 792 auth_mode = ndis_80211_auth_shared; 793 } else 794 auth_mode = ndis_80211_auth_open; 795 796 tmp = cpu_to_le32(auth_mode); 797 ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, 798 sizeof(tmp)); 799 if (ret != 0) { 800 devwarn(usbdev, "setting auth mode failed (%08X)", ret); 801 return ret; 802 } 803 804 priv->wpa_version = wpa_version; 805 priv->wpa_authalg = authalg; 806 return 0; 807} 808 809 810static int set_priv_filter(struct usbnet *usbdev) 811{ 812 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 813 __le32 tmp; 814 815 devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); 816 817 if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || 818 priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) 819 tmp = cpu_to_le32(ndis_80211_priv_8021x_wep); 820 else 821 tmp = cpu_to_le32(ndis_80211_priv_accept_all); 822 823 return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, 824 sizeof(tmp)); 825} 826 827 828static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) 829{ 830 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 831 __le32 tmp; 832 int encr_mode, ret; 833 834 devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x", 835 pairwise, 836 groupwise); 837 838 if (pairwise & IW_AUTH_CIPHER_CCMP) 839 encr_mode = ndis_80211_encr_ccmp_enabled; 840 else if (pairwise & IW_AUTH_CIPHER_TKIP) 841 encr_mode = ndis_80211_encr_tkip_enabled; 842 else if (pairwise & 843 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) 844 encr_mode = ndis_80211_encr_wep_enabled; 845 else if (groupwise & IW_AUTH_CIPHER_CCMP) 846 encr_mode = ndis_80211_encr_ccmp_enabled; 847 else if (groupwise & IW_AUTH_CIPHER_TKIP) 848 encr_mode = ndis_80211_encr_tkip_enabled; 849 else 850 encr_mode = ndis_80211_encr_disabled; 851 852 tmp = cpu_to_le32(encr_mode); 853 ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, 854 sizeof(tmp)); 855 if (ret != 0) { 856 devwarn(usbdev, "setting encr mode failed (%08X)", ret); 857 return ret; 858 } 859 860 priv->wpa_cipher_pair = pairwise; 861 priv->wpa_cipher_group = groupwise; 862 return 0; 863} 864 865 866static int set_assoc_params(struct usbnet *usbdev) 867{ 868 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 869 870 set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); 871 set_priv_filter(usbdev); 872 set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group); 873 874 return 0; 875} 876 877 878static int set_infra_mode(struct usbnet *usbdev, int mode) 879{ 880 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 881 __le32 tmp; 882 int ret, i; 883 884 devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode); 885 886 tmp = cpu_to_le32(mode); 887 ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp, 888 sizeof(tmp)); 889 if (ret != 0) { 890 devwarn(usbdev, "setting infra mode failed (%08X)", ret); 891 return ret; 892 } 893 894 /* NDIS drivers clear keys when infrastructure mode is 895 * changed. But Linux tools assume otherwise. So set the 896 * keys */ 897 if (priv->wpa_keymgmt == 0 || 898 priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) { 899 for (i = 0; i < 4; i++) { 900 if (priv->encr_key_len[i] > 0) 901 add_wep_key(usbdev, priv->encr_keys[i], 902 priv->encr_key_len[i], i); 903 } 904 } 905 906 priv->infra_mode = mode; 907 return 0; 908} 909 910 911static void set_default_iw_params(struct usbnet *usbdev) 912{ 913 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 914 915 priv->wpa_keymgmt = 0; 916 priv->wpa_version = 0; 917 918 set_infra_mode(usbdev, ndis_80211_infra_infra); 919 set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, 920 IW_AUTH_ALG_OPEN_SYSTEM); 921 set_priv_filter(usbdev); 922 set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); 923} 924 925 926static int deauthenticate(struct usbnet *usbdev) 927{ 928 int ret; 929 930 ret = disassociate(usbdev, 1); 931 set_default_iw_params(usbdev); 932 return ret; 933} 934 935 936/* index must be 0 - N, as per NDIS */ 937static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) 938{ 939 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 940 struct ndis_80211_wep_key ndis_key; 941 int ret; 942 943 if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4) 944 return -EINVAL; 945 946 memset(&ndis_key, 0, sizeof(ndis_key)); 947 948 ndis_key.size = cpu_to_le32(sizeof(ndis_key)); 949 ndis_key.length = cpu_to_le32(key_len); 950 ndis_key.index = cpu_to_le32(index); 951 memcpy(&ndis_key.material, key, key_len); 952 953 if (index == priv->encr_tx_key_index) { 954 ndis_key.index |= cpu_to_le32(1 << 31); 955 ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, 956 IW_AUTH_CIPHER_NONE); 957 if (ret) 958 devwarn(usbdev, "encryption couldn't be enabled (%08X)", 959 ret); 960 } 961 962 ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key, 963 sizeof(ndis_key)); 964 if (ret != 0) { 965 devwarn(usbdev, "adding encryption key %d failed (%08X)", 966 index+1, ret); 967 return ret; 968 } 969 970 priv->encr_key_len[index] = key_len; 971 memcpy(&priv->encr_keys[index], key, key_len); 972 973 return 0; 974} 975 976 977/* remove_key is for both wep and wpa */ 978static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) 979{ 980 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 981 struct ndis_80211_remove_key remove_key; 982 __le32 keyindex; 983 int ret; 984 985 if (priv->encr_key_len[index] == 0) 986 return 0; 987 988 priv->encr_key_len[index] = 0; 989 memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index])); 990 991 if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP || 992 priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP || 993 priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP || 994 priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) { 995 remove_key.size = cpu_to_le32(sizeof(remove_key)); 996 remove_key.index = cpu_to_le32(index); 997 if (bssid) { 998 /* pairwise key */ 999 if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) 1000 remove_key.index |= cpu_to_le32(1 << 30); 1001 memcpy(remove_key.bssid, bssid, 1002 sizeof(remove_key.bssid)); 1003 } else 1004 memset(remove_key.bssid, 0xff, 1005 sizeof(remove_key.bssid)); 1006 1007 ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key, 1008 sizeof(remove_key)); 1009 if (ret != 0) 1010 return ret; 1011 } else { 1012 keyindex = cpu_to_le32(index); 1013 ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex, 1014 sizeof(keyindex)); 1015 if (ret != 0) { 1016 devwarn(usbdev, 1017 "removing encryption key %d failed (%08X)", 1018 index, ret); 1019 return ret; 1020 } 1021 } 1022 1023 /* if it is transmit key, disable encryption */ 1024 if (index == priv->encr_tx_key_index) 1025 set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); 1026 1027 return 0; 1028} 1029 1030 1031static void set_multicast_list(struct usbnet *usbdev) 1032{ 1033 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1034 struct dev_mc_list *mclist; 1035 __le32 filter; 1036 int ret, i, size; 1037 char *buf; 1038 1039 filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; 1040 1041 if (usbdev->net->flags & IFF_PROMISC) { 1042 filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | 1043 RNDIS_PACKET_TYPE_ALL_LOCAL; 1044 } else if (usbdev->net->flags & IFF_ALLMULTI || 1045 usbdev->net->mc_count > priv->multicast_size) { 1046 filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 1047 } else if (usbdev->net->mc_count > 0) { 1048 size = min(priv->multicast_size, usbdev->net->mc_count); 1049 buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); 1050 if (!buf) { 1051 devwarn(usbdev, 1052 "couldn't alloc %d bytes of memory", 1053 size * ETH_ALEN); 1054 return; 1055 } 1056 1057 mclist = usbdev->net->mc_list; 1058 for (i = 0; i < size && mclist; mclist = mclist->next) { 1059 if (mclist->dmi_addrlen != ETH_ALEN) 1060 continue; 1061 1062 memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); 1063 i++; 1064 } 1065 1066 ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf, 1067 i * ETH_ALEN); 1068 if (ret == 0 && i > 0) 1069 filter |= RNDIS_PACKET_TYPE_MULTICAST; 1070 else 1071 filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 1072 1073 devdbg(usbdev, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d", 1074 i, priv->multicast_size, ret); 1075 1076 kfree(buf); 1077 } 1078 1079 ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, 1080 sizeof(filter)); 1081 if (ret < 0) { 1082 devwarn(usbdev, "couldn't set packet filter: %08x", 1083 le32_to_cpu(filter)); 1084 } 1085 1086 devdbg(usbdev, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d", 1087 le32_to_cpu(filter), ret); 1088} 1089 1090 1091/* 1092 * wireless extension handlers 1093 */ 1094 1095static int rndis_iw_commit(struct net_device *dev, 1096 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1097{ 1098 /* dummy op */ 1099 return 0; 1100} 1101 1102 1103static int rndis_iw_get_range(struct net_device *dev, 1104 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1105{ 1106 struct iw_range *range = (struct iw_range *)extra; 1107 struct usbnet *usbdev = netdev_priv(dev); 1108 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1109 int len, ret, i, j, num, has_80211g_rates; 1110 u8 rates[8]; 1111 __le32 tx_power; 1112 1113 devdbg(usbdev, "SIOCGIWRANGE"); 1114 1115 /* clear iw_range struct */ 1116 memset(range, 0, sizeof(*range)); 1117 wrqu->data.length = sizeof(*range); 1118 1119 range->txpower_capa = IW_TXPOW_MWATT; 1120 range->num_txpower = 1; 1121 if (priv->caps & CAP_SUPPORT_TXPOWER) { 1122 len = sizeof(tx_power); 1123 ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, 1124 &tx_power, &len); 1125 if (ret == 0 && le32_to_cpu(tx_power) != 0xFF) 1126 range->txpower[0] = le32_to_cpu(tx_power); 1127 else 1128 range->txpower[0] = get_bcm4320_power(priv); 1129 } else 1130 range->txpower[0] = get_bcm4320_power(priv); 1131 1132 len = sizeof(rates); 1133 ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates, 1134 &len); 1135 has_80211g_rates = 0; 1136 if (ret == 0) { 1137 j = 0; 1138 for (i = 0; i < len; i++) { 1139 if (rates[i] == 0) 1140 break; 1141 range->bitrate[j] = (rates[i] & 0x7f) * 500000; 1142 /* check for non 802.11b rates */ 1143 if (range->bitrate[j] == 6000000 || 1144 range->bitrate[j] == 9000000 || 1145 (range->bitrate[j] >= 12000000 && 1146 range->bitrate[j] != 22000000)) 1147 has_80211g_rates = 1; 1148 j++; 1149 } 1150 range->num_bitrates = j; 1151 } else 1152 range->num_bitrates = 0; 1153 1154 /* fill in 802.11g rates */ 1155 if (has_80211g_rates) { 1156 num = range->num_bitrates; 1157 for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) { 1158 for (j = 0; j < num; j++) { 1159 if (range->bitrate[j] == 1160 rates_80211g[i] * 1000000) 1161 break; 1162 } 1163 if (j == num) 1164 range->bitrate[range->num_bitrates++] = 1165 rates_80211g[i] * 1000000; 1166 if (range->num_bitrates == IW_MAX_BITRATES) 1167 break; 1168 } 1169 1170 /* estimated max real througput in bps */ 1171 range->throughput = 54 * 1000 * 1000 / 2; 1172 1173 /* ~35% more with afterburner */ 1174 if (priv->param_afterburner) 1175 range->throughput = range->throughput / 100 * 135; 1176 } else { 1177 /* estimated max real througput in bps */ 1178 range->throughput = 11 * 1000 * 1000 / 2; 1179 } 1180 1181 range->num_channels = ARRAY_SIZE(freq_chan); 1182 1183 for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) { 1184 range->freq[i].i = i + 1; 1185 range->freq[i].m = freq_chan[i] * 100000; 1186 range->freq[i].e = 1; 1187 } 1188 range->num_frequency = i; 1189 1190 range->min_rts = 0; 1191 range->max_rts = 2347; 1192 range->min_frag = 256; 1193 range->max_frag = 2346; 1194 1195 range->max_qual.qual = 100; 1196 range->max_qual.level = 154; 1197 range->max_qual.updated = IW_QUAL_QUAL_UPDATED 1198 | IW_QUAL_LEVEL_UPDATED 1199 | IW_QUAL_NOISE_INVALID; 1200 1201 range->we_version_compiled = WIRELESS_EXT; 1202 range->we_version_source = WIRELESS_EXT; 1203 1204 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 1205 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 1206 return 0; 1207} 1208 1209 1210static int rndis_iw_get_name(struct net_device *dev, 1211 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1212{ 1213 struct usbnet *usbdev = netdev_priv(dev); 1214 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1215 1216 strcpy(wrqu->name, priv->name); 1217 return 0; 1218} 1219 1220 1221static int rndis_iw_set_essid(struct net_device *dev, 1222 struct iw_request_info *info, union iwreq_data *wrqu, char *essid) 1223{ 1224 struct ndis_80211_ssid ssid; 1225 int length = wrqu->essid.length; 1226 struct usbnet *usbdev = netdev_priv(dev); 1227 1228 devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'", 1229 wrqu->essid.flags, wrqu->essid.length, essid); 1230 1231 if (length > NDIS_802_11_LENGTH_SSID) 1232 length = NDIS_802_11_LENGTH_SSID; 1233 1234 ssid.length = cpu_to_le32(length); 1235 if (length > 0) 1236 memcpy(ssid.essid, essid, length); 1237 else 1238 memset(ssid.essid, 0, NDIS_802_11_LENGTH_SSID); 1239 1240 set_assoc_params(usbdev); 1241 1242 if (!wrqu->essid.flags || length == 0) 1243 return disassociate(usbdev, 1); 1244 else 1245 return set_essid(usbdev, &ssid); 1246} 1247 1248 1249static int rndis_iw_get_essid(struct net_device *dev, 1250 struct iw_request_info *info, union iwreq_data *wrqu, char *essid) 1251{ 1252 struct ndis_80211_ssid ssid; 1253 struct usbnet *usbdev = netdev_priv(dev); 1254 int ret; 1255 1256 ret = get_essid(usbdev, &ssid); 1257 1258 if (ret == 0 && le32_to_cpu(ssid.length) > 0) { 1259 wrqu->essid.flags = 1; 1260 wrqu->essid.length = le32_to_cpu(ssid.length); 1261 memcpy(essid, ssid.essid, wrqu->essid.length); 1262 essid[wrqu->essid.length] = 0; 1263 } else { 1264 memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID)); 1265 wrqu->essid.flags = 0; 1266 wrqu->essid.length = 0; 1267 } 1268 devdbg(usbdev, "SIOCGIWESSID: %s", essid); 1269 return ret; 1270} 1271 1272 1273static int rndis_iw_get_bssid(struct net_device *dev, 1274 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1275{ 1276 struct usbnet *usbdev = netdev_priv(dev); 1277 unsigned char bssid[ETH_ALEN]; 1278 int ret; 1279 1280 ret = get_bssid(usbdev, bssid); 1281 1282 if (ret == 0) 1283 devdbg(usbdev, "SIOCGIWAP: %pM", bssid); 1284 else 1285 devdbg(usbdev, "SIOCGIWAP: <not associated>"); 1286 1287 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 1288 memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN); 1289 1290 return ret; 1291} 1292 1293 1294static int rndis_iw_set_bssid(struct net_device *dev, 1295 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1296{ 1297 struct usbnet *usbdev = netdev_priv(dev); 1298 u8 *bssid = (u8 *)wrqu->ap_addr.sa_data; 1299 int ret; 1300 1301 devdbg(usbdev, "SIOCSIWAP: %pM", bssid); 1302 1303 ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN); 1304 1305 /* user apps may set ap's mac address, which is not required; 1306 * they may fail to work if this function fails, so return 1307 * success */ 1308 if (ret) 1309 devwarn(usbdev, "setting AP mac address failed (%08X)", ret); 1310 1311 return 0; 1312} 1313 1314 1315static int rndis_iw_set_auth(struct net_device *dev, 1316 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1317{ 1318 struct iw_param *p = &wrqu->param; 1319 struct usbnet *usbdev = netdev_priv(dev); 1320 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1321 int ret = -ENOTSUPP; 1322 1323 switch (p->flags & IW_AUTH_INDEX) { 1324 case IW_AUTH_WPA_VERSION: 1325 devdbg(usbdev, "SIOCSIWAUTH: WPA_VERSION, %08x", p->value); 1326 priv->wpa_version = p->value; 1327 ret = 0; 1328 break; 1329 1330 case IW_AUTH_CIPHER_PAIRWISE: 1331 devdbg(usbdev, "SIOCSIWAUTH: CIPHER_PAIRWISE, %08x", p->value); 1332 priv->wpa_cipher_pair = p->value; 1333 ret = 0; 1334 break; 1335 1336 case IW_AUTH_CIPHER_GROUP: 1337 devdbg(usbdev, "SIOCSIWAUTH: CIPHER_GROUP, %08x", p->value); 1338 priv->wpa_cipher_group = p->value; 1339 ret = 0; 1340 break; 1341 1342 case IW_AUTH_KEY_MGMT: 1343 devdbg(usbdev, "SIOCSIWAUTH: KEY_MGMT, %08x", p->value); 1344 priv->wpa_keymgmt = p->value; 1345 ret = 0; 1346 break; 1347 1348 case IW_AUTH_TKIP_COUNTERMEASURES: 1349 devdbg(usbdev, "SIOCSIWAUTH: TKIP_COUNTERMEASURES, %08x", 1350 p->value); 1351 ret = 0; 1352 break; 1353 1354 case IW_AUTH_DROP_UNENCRYPTED: 1355 devdbg(usbdev, "SIOCSIWAUTH: DROP_UNENCRYPTED, %08x", p->value); 1356 ret = 0; 1357 break; 1358 1359 case IW_AUTH_80211_AUTH_ALG: 1360 devdbg(usbdev, "SIOCSIWAUTH: 80211_AUTH_ALG, %08x", p->value); 1361 priv->wpa_authalg = p->value; 1362 ret = 0; 1363 break; 1364 1365 case IW_AUTH_WPA_ENABLED: 1366 devdbg(usbdev, "SIOCSIWAUTH: WPA_ENABLED, %08x", p->value); 1367 if (wrqu->param.value) 1368 deauthenticate(usbdev); 1369 ret = 0; 1370 break; 1371 1372 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1373 devdbg(usbdev, "SIOCSIWAUTH: RX_UNENCRYPTED_EAPOL, %08x", 1374 p->value); 1375 ret = 0; 1376 break; 1377 1378 case IW_AUTH_ROAMING_CONTROL: 1379 devdbg(usbdev, "SIOCSIWAUTH: ROAMING_CONTROL, %08x", p->value); 1380 ret = 0; 1381 break; 1382 1383 case IW_AUTH_PRIVACY_INVOKED: 1384 devdbg(usbdev, "SIOCSIWAUTH: invalid cmd %d", 1385 wrqu->param.flags & IW_AUTH_INDEX); 1386 return -EOPNOTSUPP; 1387 1388 default: 1389 devdbg(usbdev, "SIOCSIWAUTH: UNKNOWN %08x, %08x", 1390 p->flags & IW_AUTH_INDEX, p->value); 1391 } 1392 return ret; 1393} 1394 1395 1396static int rndis_iw_get_auth(struct net_device *dev, 1397 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1398{ 1399 struct iw_param *p = &wrqu->param; 1400 struct usbnet *usbdev = netdev_priv(dev); 1401 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1402 1403 switch (p->flags & IW_AUTH_INDEX) { 1404 case IW_AUTH_WPA_VERSION: 1405 p->value = priv->wpa_version; 1406 break; 1407 case IW_AUTH_CIPHER_PAIRWISE: 1408 p->value = priv->wpa_cipher_pair; 1409 break; 1410 case IW_AUTH_CIPHER_GROUP: 1411 p->value = priv->wpa_cipher_group; 1412 break; 1413 case IW_AUTH_KEY_MGMT: 1414 p->value = priv->wpa_keymgmt; 1415 break; 1416 case IW_AUTH_80211_AUTH_ALG: 1417 p->value = priv->wpa_authalg; 1418 break; 1419 default: 1420 devdbg(usbdev, "SIOCGIWAUTH: invalid cmd %d", 1421 wrqu->param.flags & IW_AUTH_INDEX); 1422 return -EOPNOTSUPP; 1423 } 1424 return 0; 1425} 1426 1427 1428static int rndis_iw_get_mode(struct net_device *dev, 1429 struct iw_request_info *info, 1430 union iwreq_data *wrqu, char *extra) 1431{ 1432 struct usbnet *usbdev = netdev_priv(dev); 1433 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1434 1435 switch (priv->infra_mode) { 1436 case ndis_80211_infra_adhoc: 1437 wrqu->mode = IW_MODE_ADHOC; 1438 break; 1439 case ndis_80211_infra_infra: 1440 wrqu->mode = IW_MODE_INFRA; 1441 break; 1442 /*case ndis_80211_infra_auto_unknown:*/ 1443 default: 1444 wrqu->mode = IW_MODE_AUTO; 1445 break; 1446 } 1447 devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode); 1448 return 0; 1449} 1450 1451 1452static int rndis_iw_set_mode(struct net_device *dev, 1453 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1454{ 1455 struct usbnet *usbdev = netdev_priv(dev); 1456 int mode; 1457 1458 devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode); 1459 1460 switch (wrqu->mode) { 1461 case IW_MODE_ADHOC: 1462 mode = ndis_80211_infra_adhoc; 1463 break; 1464 case IW_MODE_INFRA: 1465 mode = ndis_80211_infra_infra; 1466 break; 1467 /*case IW_MODE_AUTO:*/ 1468 default: 1469 mode = ndis_80211_infra_auto_unknown; 1470 break; 1471 } 1472 1473 return set_infra_mode(usbdev, mode); 1474} 1475 1476 1477static int rndis_iw_set_encode(struct net_device *dev, 1478 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1479{ 1480 struct usbnet *usbdev = netdev_priv(dev); 1481 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1482 int ret, index, key_len; 1483 u8 *key; 1484 1485 index = (wrqu->encoding.flags & IW_ENCODE_INDEX); 1486 1487 /* iwconfig gives index as 1 - N */ 1488 if (index > 0) 1489 index--; 1490 else 1491 index = priv->encr_tx_key_index; 1492 1493 if (index < 0 || index >= 4) { 1494 devwarn(usbdev, "encryption index out of range (%u)", index); 1495 return -EINVAL; 1496 } 1497 1498 /* remove key if disabled */ 1499 if (wrqu->data.flags & IW_ENCODE_DISABLED) { 1500 if (remove_key(usbdev, index, NULL)) 1501 return -EINVAL; 1502 else 1503 return 0; 1504 } 1505 1506 /* global encryption state (for all keys) */ 1507 if (wrqu->data.flags & IW_ENCODE_OPEN) 1508 ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, 1509 IW_AUTH_ALG_OPEN_SYSTEM); 1510 else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/ 1511 ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, 1512 IW_AUTH_ALG_SHARED_KEY); 1513 if (ret != 0) 1514 return ret; 1515 1516 if (wrqu->data.length > 0) { 1517 key_len = wrqu->data.length; 1518 key = extra; 1519 } else { 1520 /* must be set as tx key */ 1521 if (priv->encr_key_len[index] == 0) 1522 return -EINVAL; 1523 key_len = priv->encr_key_len[index]; 1524 key = priv->encr_keys[index]; 1525 priv->encr_tx_key_index = index; 1526 } 1527 1528 if (add_wep_key(usbdev, key, key_len, index) != 0) 1529 return -EINVAL; 1530 1531 if (index == priv->encr_tx_key_index) 1532 /* ndis drivers want essid to be set after setting encr */ 1533 set_essid(usbdev, &priv->essid); 1534 1535 return 0; 1536} 1537 1538 1539static int rndis_iw_set_encode_ext(struct net_device *dev, 1540 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1541{ 1542 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 1543 struct usbnet *usbdev = netdev_priv(dev); 1544 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1545 struct ndis_80211_key ndis_key; 1546 int keyidx, ret; 1547 u8 *addr; 1548 1549 keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; 1550 1551 /* iwconfig gives index as 1 - N */ 1552 if (keyidx) 1553 keyidx--; 1554 else 1555 keyidx = priv->encr_tx_key_index; 1556 1557 if (keyidx < 0 || keyidx >= 4) 1558 return -EINVAL; 1559 1560 if (ext->alg == WPA_ALG_WEP) { 1561 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1562 priv->encr_tx_key_index = keyidx; 1563 return add_wep_key(usbdev, ext->key, ext->key_len, keyidx); 1564 } 1565 1566 if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || 1567 ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) 1568 return remove_key(usbdev, keyidx, NULL); 1569 1570 if (ext->key_len > sizeof(ndis_key.material)) 1571 return -1; 1572 1573 memset(&ndis_key, 0, sizeof(ndis_key)); 1574 1575 ndis_key.size = cpu_to_le32(sizeof(ndis_key) - 1576 sizeof(ndis_key.material) + ext->key_len); 1577 ndis_key.length = cpu_to_le32(ext->key_len); 1578 ndis_key.index = cpu_to_le32(keyidx); 1579 1580 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { 1581 memcpy(ndis_key.rsc, ext->rx_seq, 6); 1582 ndis_key.index |= cpu_to_le32(1 << 29); 1583 } 1584 1585 addr = ext->addr.sa_data; 1586 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { 1587 /* group key */ 1588 if (priv->infra_mode == ndis_80211_infra_adhoc) 1589 memset(ndis_key.bssid, 0xff, ETH_ALEN); 1590 else 1591 get_bssid(usbdev, ndis_key.bssid); 1592 } else { 1593 /* pairwise key */ 1594 ndis_key.index |= cpu_to_le32(1 << 30); 1595 memcpy(ndis_key.bssid, addr, ETH_ALEN); 1596 } 1597 1598 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1599 ndis_key.index |= cpu_to_le32(1 << 31); 1600 1601 if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) { 1602 /* wpa_supplicant gives us the Michael MIC RX/TX keys in 1603 * different order than NDIS spec, so swap the order here. */ 1604 memcpy(ndis_key.material, ext->key, 16); 1605 memcpy(ndis_key.material + 16, ext->key + 24, 8); 1606 memcpy(ndis_key.material + 24, ext->key + 16, 8); 1607 } else 1608 memcpy(ndis_key.material, ext->key, ext->key_len); 1609 1610 ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key, 1611 le32_to_cpu(ndis_key.size)); 1612 devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret); 1613 if (ret != 0) 1614 return ret; 1615 1616 priv->encr_key_len[keyidx] = ext->key_len; 1617 memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len); 1618 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1619 priv->encr_tx_key_index = keyidx; 1620 1621 return 0; 1622} 1623 1624 1625static int rndis_iw_set_scan(struct net_device *dev, 1626 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1627{ 1628 struct usbnet *usbdev = netdev_priv(dev); 1629 union iwreq_data evt; 1630 int ret = -EINVAL; 1631 __le32 tmp; 1632 1633 devdbg(usbdev, "SIOCSIWSCAN"); 1634 1635 if (wrqu->data.flags == 0) { 1636 tmp = ccpu2(1); 1637 ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, 1638 sizeof(tmp)); 1639 evt.data.flags = 0; 1640 evt.data.length = 0; 1641 wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL); 1642 } 1643 return ret; 1644} 1645 1646 1647static char *rndis_translate_scan(struct net_device *dev, 1648 struct iw_request_info *info, char *cev, 1649 char *end_buf, 1650 struct ndis_80211_bssid_ex *bssid) 1651{ 1652 struct usbnet *usbdev = netdev_priv(dev); 1653 u8 *ie; 1654 char *current_val; 1655 int bssid_len, ie_len, i; 1656 u32 beacon, atim; 1657 struct iw_event iwe; 1658 unsigned char sbuf[32]; 1659 1660 bssid_len = le32_to_cpu(bssid->length); 1661 1662 devdbg(usbdev, "BSSID %pM", bssid->mac); 1663 iwe.cmd = SIOCGIWAP; 1664 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1665 memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); 1666 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN); 1667 1668 devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), 1669 bssid->ssid.essid); 1670 iwe.cmd = SIOCGIWESSID; 1671 iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); 1672 iwe.u.essid.flags = 1; 1673 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid); 1674 1675 devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); 1676 iwe.cmd = SIOCGIWMODE; 1677 switch (le32_to_cpu(bssid->net_infra)) { 1678 case ndis_80211_infra_adhoc: 1679 iwe.u.mode = IW_MODE_ADHOC; 1680 break; 1681 case ndis_80211_infra_infra: 1682 iwe.u.mode = IW_MODE_INFRA; 1683 break; 1684 /*case ndis_80211_infra_auto_unknown:*/ 1685 default: 1686 iwe.u.mode = IW_MODE_AUTO; 1687 break; 1688 } 1689 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN); 1690 1691 devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); 1692 iwe.cmd = SIOCGIWFREQ; 1693 dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); 1694 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN); 1695 1696 devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); 1697 iwe.cmd = IWEVQUAL; 1698 iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi)); 1699 iwe.u.qual.level = le32_to_cpu(bssid->rssi); 1700 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED 1701 | IW_QUAL_LEVEL_UPDATED 1702 | IW_QUAL_NOISE_INVALID; 1703 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN); 1704 1705 devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); 1706 iwe.cmd = SIOCGIWENCODE; 1707 iwe.u.data.length = 0; 1708 if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all) 1709 iwe.u.data.flags = IW_ENCODE_DISABLED; 1710 else 1711 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 1712 1713 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL); 1714 1715 devdbg(usbdev, "RATES:"); 1716 current_val = cev + iwe_stream_lcp_len(info); 1717 iwe.cmd = SIOCGIWRATE; 1718 for (i = 0; i < sizeof(bssid->rates); i++) { 1719 if (bssid->rates[i] & 0x7f) { 1720 iwe.u.bitrate.value = 1721 ((bssid->rates[i] & 0x7f) * 1722 500000); 1723 devdbg(usbdev, " %d", iwe.u.bitrate.value); 1724 current_val = iwe_stream_add_value(info, cev, 1725 current_val, end_buf, &iwe, 1726 IW_EV_PARAM_LEN); 1727 } 1728 } 1729 1730 if ((current_val - cev) > iwe_stream_lcp_len(info)) 1731 cev = current_val; 1732 1733 beacon = le32_to_cpu(bssid->config.beacon_period); 1734 devdbg(usbdev, "BCN_INT %d", beacon); 1735 iwe.cmd = IWEVCUSTOM; 1736 snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); 1737 iwe.u.data.length = strlen(sbuf); 1738 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); 1739 1740 atim = le32_to_cpu(bssid->config.atim_window); 1741 devdbg(usbdev, "ATIM %d", atim); 1742 iwe.cmd = IWEVCUSTOM; 1743 snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); 1744 iwe.u.data.length = strlen(sbuf); 1745 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); 1746 1747 ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); 1748 ie_len = min(bssid_len - (int)sizeof(*bssid), 1749 (int)le32_to_cpu(bssid->ie_length)); 1750 ie_len -= sizeof(struct ndis_80211_fixed_ies); 1751 while (ie_len >= 2 && 2 + ie[1] <= ie_len) { 1752 if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 && 1753 memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) || 1754 ie[0] == WLAN_EID_RSN) { 1755 devdbg(usbdev, "IE: WPA%d", 1756 (ie[0] == WLAN_EID_RSN) ? 2 : 1); 1757 iwe.cmd = IWEVGENIE; 1758 /* arbitrary cut-off at 64 */ 1759 iwe.u.data.length = min(ie[1] + 2, 64); 1760 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie); 1761 } 1762 1763 ie_len -= 2 + ie[1]; 1764 ie += 2 + ie[1]; 1765 } 1766 1767 return cev; 1768} 1769 1770 1771static int rndis_iw_get_scan(struct net_device *dev, 1772 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1773{ 1774 struct usbnet *usbdev = netdev_priv(dev); 1775 void *buf = NULL; 1776 char *cev = extra; 1777 struct ndis_80211_bssid_list_ex *bssid_list; 1778 struct ndis_80211_bssid_ex *bssid; 1779 int ret = -EINVAL, len, count, bssid_len; 1780 1781 devdbg(usbdev, "SIOCGIWSCAN"); 1782 1783 len = CONTROL_BUFFER_SIZE; 1784 buf = kmalloc(len, GFP_KERNEL); 1785 if (!buf) { 1786 ret = -ENOMEM; 1787 goto out; 1788 } 1789 1790 ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); 1791 1792 if (ret != 0) 1793 goto out; 1794 1795 bssid_list = buf; 1796 bssid = bssid_list->bssid; 1797 bssid_len = le32_to_cpu(bssid->length); 1798 count = le32_to_cpu(bssid_list->num_items); 1799 devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); 1800 1801 while (count && ((void *)bssid + bssid_len) <= (buf + len)) { 1802 cev = rndis_translate_scan(dev, info, cev, 1803 extra + IW_SCAN_MAX_DATA, bssid); 1804 bssid = (void *)bssid + bssid_len; 1805 bssid_len = le32_to_cpu(bssid->length); 1806 count--; 1807 } 1808 1809out: 1810 wrqu->data.length = cev - extra; 1811 wrqu->data.flags = 0; 1812 kfree(buf); 1813 return ret; 1814} 1815 1816 1817static int rndis_iw_set_genie(struct net_device *dev, 1818 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1819{ 1820 struct usbnet *usbdev = netdev_priv(dev); 1821 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1822 int ret = 0; 1823 1824#ifdef DEBUG 1825 int j; 1826 u8 *gie = extra; 1827 for (j = 0; j < wrqu->data.length; j += 8) 1828 devdbg(usbdev, 1829 "SIOCSIWGENIE %04x - " 1830 "%02x %02x %02x %02x %02x %02x %02x %02x", j, 1831 gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3], 1832 gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]); 1833#endif 1834 /* clear existing IEs */ 1835 if (priv->wpa_ie_len) { 1836 kfree(priv->wpa_ie); 1837 priv->wpa_ie_len = 0; 1838 } 1839 1840 /* set new IEs */ 1841 priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL); 1842 if (priv->wpa_ie) { 1843 priv->wpa_ie_len = wrqu->data.length; 1844 memcpy(priv->wpa_ie, extra, priv->wpa_ie_len); 1845 } else 1846 ret = -ENOMEM; 1847 return ret; 1848} 1849 1850 1851static int rndis_iw_get_genie(struct net_device *dev, 1852 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1853{ 1854 struct usbnet *usbdev = netdev_priv(dev); 1855 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1856 1857 devdbg(usbdev, "SIOCGIWGENIE"); 1858 1859 if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) { 1860 wrqu->data.length = 0; 1861 return 0; 1862 } 1863 1864 if (wrqu->data.length < priv->wpa_ie_len) 1865 return -E2BIG; 1866 1867 wrqu->data.length = priv->wpa_ie_len; 1868 memcpy(extra, priv->wpa_ie, priv->wpa_ie_len); 1869 1870 return 0; 1871} 1872 1873 1874static int rndis_iw_set_rts(struct net_device *dev, 1875 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1876{ 1877 struct usbnet *usbdev = netdev_priv(dev); 1878 __le32 tmp; 1879 devdbg(usbdev, "SIOCSIWRTS"); 1880 1881 tmp = cpu_to_le32(wrqu->rts.value); 1882 return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, 1883 sizeof(tmp)); 1884} 1885 1886 1887static int rndis_iw_get_rts(struct net_device *dev, 1888 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1889{ 1890 struct usbnet *usbdev = netdev_priv(dev); 1891 __le32 tmp; 1892 int len, ret; 1893 1894 len = sizeof(tmp); 1895 ret = rndis_query_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, &len); 1896 if (ret == 0) { 1897 wrqu->rts.value = le32_to_cpu(tmp); 1898 wrqu->rts.flags = 1; 1899 wrqu->rts.disabled = 0; 1900 } 1901 1902 devdbg(usbdev, "SIOCGIWRTS: %d", wrqu->rts.value); 1903 1904 return ret; 1905} 1906 1907 1908static int rndis_iw_set_frag(struct net_device *dev, 1909 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1910{ 1911 struct usbnet *usbdev = netdev_priv(dev); 1912 __le32 tmp; 1913 1914 devdbg(usbdev, "SIOCSIWFRAG"); 1915 1916 tmp = cpu_to_le32(wrqu->frag.value); 1917 return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp, 1918 sizeof(tmp)); 1919} 1920 1921 1922static int rndis_iw_get_frag(struct net_device *dev, 1923 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1924{ 1925 struct usbnet *usbdev = netdev_priv(dev); 1926 __le32 tmp; 1927 int len, ret; 1928 1929 len = sizeof(tmp); 1930 ret = rndis_query_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp, 1931 &len); 1932 if (ret == 0) { 1933 wrqu->frag.value = le32_to_cpu(tmp); 1934 wrqu->frag.flags = 1; 1935 wrqu->frag.disabled = 0; 1936 } 1937 devdbg(usbdev, "SIOCGIWFRAG: %d", wrqu->frag.value); 1938 return ret; 1939} 1940 1941 1942static int rndis_iw_set_nick(struct net_device *dev, 1943 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1944{ 1945 struct usbnet *usbdev = netdev_priv(dev); 1946 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1947 1948 devdbg(usbdev, "SIOCSIWNICK"); 1949 1950 priv->nick_len = wrqu->data.length; 1951 if (priv->nick_len > 32) 1952 priv->nick_len = 32; 1953 1954 memcpy(priv->nick, extra, priv->nick_len); 1955 return 0; 1956} 1957 1958 1959static int rndis_iw_get_nick(struct net_device *dev, 1960 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1961{ 1962 struct usbnet *usbdev = netdev_priv(dev); 1963 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 1964 1965 wrqu->data.flags = 1; 1966 wrqu->data.length = priv->nick_len; 1967 memcpy(extra, priv->nick, priv->nick_len); 1968 1969 devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick); 1970 1971 return 0; 1972} 1973 1974 1975static int rndis_iw_set_freq(struct net_device *dev, 1976 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 1977{ 1978 struct usbnet *usbdev = netdev_priv(dev); 1979 struct ndis_80211_conf config; 1980 unsigned int dsconfig; 1981 int len, ret; 1982 1983 /* this OID is valid only when not associated */ 1984 if (is_associated(usbdev)) 1985 return 0; 1986 1987 dsconfig = 0; 1988 if (freq_to_dsconfig(&wrqu->freq, &dsconfig)) 1989 return -EINVAL; 1990 1991 len = sizeof(config); 1992 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); 1993 if (ret != 0) { 1994 devdbg(usbdev, "SIOCSIWFREQ: querying configuration failed"); 1995 return 0; 1996 } 1997 1998 config.ds_config = cpu_to_le32(dsconfig); 1999 2000 devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e); 2001 return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config, 2002 sizeof(config)); 2003} 2004 2005 2006static int rndis_iw_get_freq(struct net_device *dev, 2007 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 2008{ 2009 struct usbnet *usbdev = netdev_priv(dev); 2010 struct ndis_80211_conf config; 2011 int len, ret; 2012 2013 len = sizeof(config); 2014 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); 2015 if (ret == 0) 2016 dsconfig_to_freq(le32_to_cpu(config.ds_config), &wrqu->freq); 2017 2018 devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m); 2019 return ret; 2020} 2021 2022 2023static int rndis_iw_get_txpower(struct net_device *dev, 2024 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 2025{ 2026 struct usbnet *usbdev = netdev_priv(dev); 2027 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2028 __le32 tx_power; 2029 int ret = 0, len; 2030 2031 if (priv->radio_on) { 2032 if (priv->caps & CAP_SUPPORT_TXPOWER) { 2033 len = sizeof(tx_power); 2034 ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, 2035 &tx_power, &len); 2036 if (ret != 0) 2037 return ret; 2038 } else 2039 /* fake incase not supported */ 2040 tx_power = cpu_to_le32(get_bcm4320_power(priv)); 2041 2042 wrqu->txpower.flags = IW_TXPOW_MWATT; 2043 wrqu->txpower.value = le32_to_cpu(tx_power); 2044 wrqu->txpower.disabled = 0; 2045 } else { 2046 wrqu->txpower.flags = IW_TXPOW_MWATT; 2047 wrqu->txpower.value = 0; 2048 wrqu->txpower.disabled = 1; 2049 } 2050 2051 devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value); 2052 2053 return ret; 2054} 2055 2056 2057static int rndis_iw_set_txpower(struct net_device *dev, 2058 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 2059{ 2060 struct usbnet *usbdev = netdev_priv(dev); 2061 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2062 __le32 tx_power = 0; 2063 int ret = 0; 2064 2065 if (!wrqu->txpower.disabled) { 2066 if (wrqu->txpower.flags == IW_TXPOW_MWATT) 2067 tx_power = cpu_to_le32(wrqu->txpower.value); 2068 else { /* wrqu->txpower.flags == IW_TXPOW_DBM */ 2069 if (wrqu->txpower.value > 20) 2070 tx_power = cpu_to_le32(128); 2071 else if (wrqu->txpower.value < -43) 2072 tx_power = cpu_to_le32(127); 2073 else { 2074 signed char tmp; 2075 tmp = wrqu->txpower.value; 2076 tmp = -12 - tmp; 2077 tmp <<= 2; 2078 tx_power = cpu_to_le32((unsigned char)tmp); 2079 } 2080 } 2081 } 2082 2083 devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power)); 2084 2085 if (le32_to_cpu(tx_power) != 0) { 2086 if (priv->caps & CAP_SUPPORT_TXPOWER) { 2087 /* turn radio on first */ 2088 if (!priv->radio_on) 2089 disassociate(usbdev, 1); 2090 2091 ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL, 2092 &tx_power, sizeof(tx_power)); 2093 if (ret != 0) 2094 ret = -EOPNOTSUPP; 2095 return ret; 2096 } else { 2097 /* txpower unsupported, just turn radio on */ 2098 if (!priv->radio_on) 2099 return disassociate(usbdev, 1); 2100 return 0; /* all ready on */ 2101 } 2102 } 2103 2104 /* tx_power == 0, turn off radio */ 2105 return disassociate(usbdev, 0); 2106} 2107 2108 2109static int rndis_iw_get_rate(struct net_device *dev, 2110 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 2111{ 2112 struct usbnet *usbdev = netdev_priv(dev); 2113 __le32 tmp; 2114 int ret, len; 2115 2116 len = sizeof(tmp); 2117 ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len); 2118 if (ret == 0) { 2119 wrqu->bitrate.value = le32_to_cpu(tmp) * 100; 2120 wrqu->bitrate.disabled = 0; 2121 wrqu->bitrate.flags = 1; 2122 } 2123 return ret; 2124} 2125 2126 2127static int rndis_iw_set_mlme(struct net_device *dev, 2128 struct iw_request_info *info, union iwreq_data *wrqu, char *extra) 2129{ 2130 struct usbnet *usbdev = netdev_priv(dev); 2131 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2132 struct iw_mlme *mlme = (struct iw_mlme *)extra; 2133 unsigned char bssid[ETH_ALEN]; 2134 2135 get_bssid(usbdev, bssid); 2136 2137 if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN)) 2138 return -EINVAL; 2139 2140 switch (mlme->cmd) { 2141 case IW_MLME_DEAUTH: 2142 return deauthenticate(usbdev); 2143 case IW_MLME_DISASSOC: 2144 return disassociate(usbdev, priv->radio_on); 2145 default: 2146 return -EOPNOTSUPP; 2147 } 2148 2149 return 0; 2150} 2151 2152 2153static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) 2154{ 2155 struct usbnet *usbdev = netdev_priv(dev); 2156 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2157 unsigned long flags; 2158 2159 spin_lock_irqsave(&priv->stats_lock, flags); 2160 memcpy(&priv->iwstats, &priv->privstats, sizeof(priv->iwstats)); 2161 spin_unlock_irqrestore(&priv->stats_lock, flags); 2162 2163 return &priv->iwstats; 2164} 2165 2166 2167#define IW_IOCTL(x) [(x) - SIOCSIWCOMMIT] 2168static const iw_handler rndis_iw_handler[] = 2169{ 2170 IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit, 2171 IW_IOCTL(SIOCGIWNAME) = rndis_iw_get_name, 2172 IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq, 2173 IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq, 2174 IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode, 2175 IW_IOCTL(SIOCGIWMODE) = rndis_iw_get_mode, 2176 IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range, 2177 IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid, 2178 IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid, 2179 IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan, 2180 IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan, 2181 IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid, 2182 IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid, 2183 IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick, 2184 IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick, 2185 IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate, 2186 IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts, 2187 IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts, 2188 IW_IOCTL(SIOCSIWFRAG) = rndis_iw_set_frag, 2189 IW_IOCTL(SIOCGIWFRAG) = rndis_iw_get_frag, 2190 IW_IOCTL(SIOCSIWTXPOW) = rndis_iw_set_txpower, 2191 IW_IOCTL(SIOCGIWTXPOW) = rndis_iw_get_txpower, 2192 IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode, 2193 IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext, 2194 IW_IOCTL(SIOCSIWAUTH) = rndis_iw_set_auth, 2195 IW_IOCTL(SIOCGIWAUTH) = rndis_iw_get_auth, 2196 IW_IOCTL(SIOCSIWGENIE) = rndis_iw_set_genie, 2197 IW_IOCTL(SIOCGIWGENIE) = rndis_iw_get_genie, 2198 IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, 2199}; 2200 2201static const iw_handler rndis_wext_private_handler[] = { 2202}; 2203 2204static const struct iw_priv_args rndis_wext_private_args[] = { 2205}; 2206 2207 2208static const struct iw_handler_def rndis_iw_handlers = { 2209 .num_standard = ARRAY_SIZE(rndis_iw_handler), 2210 .num_private = ARRAY_SIZE(rndis_wext_private_handler), 2211 .num_private_args = ARRAY_SIZE(rndis_wext_private_args), 2212 .standard = (iw_handler *)rndis_iw_handler, 2213 .private = (iw_handler *)rndis_wext_private_handler, 2214 .private_args = (struct iw_priv_args *)rndis_wext_private_args, 2215 .get_wireless_stats = rndis_get_wireless_stats, 2216}; 2217 2218 2219static void rndis_wext_worker(struct work_struct *work) 2220{ 2221 struct rndis_wext_private *priv = 2222 container_of(work, struct rndis_wext_private, work); 2223 struct usbnet *usbdev = priv->usbdev; 2224 union iwreq_data evt; 2225 unsigned char bssid[ETH_ALEN]; 2226 struct ndis_80211_assoc_info *info; 2227 int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; 2228 int ret, offset; 2229 2230 if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) { 2231 netif_carrier_on(usbdev->net); 2232 2233 info = kzalloc(assoc_size, GFP_KERNEL); 2234 if (!info) 2235 goto get_bssid; 2236 2237 /* Get association info IEs from device and send them back to 2238 * userspace. */ 2239 ret = get_association_info(usbdev, info, assoc_size); 2240 if (!ret) { 2241 evt.data.length = le32_to_cpu(info->req_ie_length); 2242 if (evt.data.length > 0) { 2243 offset = le32_to_cpu(info->offset_req_ies); 2244 wireless_send_event(usbdev->net, 2245 IWEVASSOCREQIE, &evt, 2246 (char *)info + offset); 2247 } 2248 2249 evt.data.length = le32_to_cpu(info->resp_ie_length); 2250 if (evt.data.length > 0) { 2251 offset = le32_to_cpu(info->offset_resp_ies); 2252 wireless_send_event(usbdev->net, 2253 IWEVASSOCRESPIE, &evt, 2254 (char *)info + offset); 2255 } 2256 } 2257 2258 kfree(info); 2259 2260get_bssid: 2261 ret = get_bssid(usbdev, bssid); 2262 if (!ret) { 2263 evt.data.flags = 0; 2264 evt.data.length = 0; 2265 memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN); 2266 wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL); 2267 } 2268 } 2269 2270 if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) { 2271 netif_carrier_off(usbdev->net); 2272 2273 evt.data.flags = 0; 2274 evt.data.length = 0; 2275 memset(evt.ap_addr.sa_data, 0, ETH_ALEN); 2276 wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL); 2277 } 2278 2279 if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) 2280 set_multicast_list(usbdev); 2281} 2282 2283static void rndis_wext_set_multicast_list(struct net_device *dev) 2284{ 2285 struct usbnet *usbdev = netdev_priv(dev); 2286 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2287 2288 if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) 2289 return; 2290 2291 set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending); 2292 queue_work(priv->workqueue, &priv->work); 2293} 2294 2295static void rndis_wext_link_change(struct usbnet *usbdev, int state) 2296{ 2297 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2298 2299 /* queue work to avoid recursive calls into rndis_command */ 2300 set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); 2301 queue_work(priv->workqueue, &priv->work); 2302} 2303 2304 2305static int rndis_wext_get_caps(struct usbnet *usbdev) 2306{ 2307 struct { 2308 __le32 num_items; 2309 __le32 items[8]; 2310 } networks_supported; 2311 int len, retval, i, n; 2312 __le32 tx_power; 2313 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2314 2315 /* determine if supports setting txpower */ 2316 len = sizeof(tx_power); 2317 retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power, 2318 &len); 2319 if (retval == 0 && le32_to_cpu(tx_power) != 0xFF) 2320 priv->caps |= CAP_SUPPORT_TXPOWER; 2321 2322 /* determine supported modes */ 2323 len = sizeof(networks_supported); 2324 retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED, 2325 &networks_supported, &len); 2326 if (retval >= 0) { 2327 n = le32_to_cpu(networks_supported.num_items); 2328 if (n > 8) 2329 n = 8; 2330 for (i = 0; i < n; i++) { 2331 switch (le32_to_cpu(networks_supported.items[i])) { 2332 case ndis_80211_type_freq_hop: 2333 case ndis_80211_type_direct_seq: 2334 priv->caps |= CAP_MODE_80211B; 2335 break; 2336 case ndis_80211_type_ofdm_a: 2337 priv->caps |= CAP_MODE_80211A; 2338 break; 2339 case ndis_80211_type_ofdm_g: 2340 priv->caps |= CAP_MODE_80211G; 2341 break; 2342 } 2343 } 2344 if (priv->caps & CAP_MODE_80211A) 2345 strcat(priv->name, "a"); 2346 if (priv->caps & CAP_MODE_80211B) 2347 strcat(priv->name, "b"); 2348 if (priv->caps & CAP_MODE_80211G) 2349 strcat(priv->name, "g"); 2350 } 2351 2352 return retval; 2353} 2354 2355 2356#define STATS_UPDATE_JIFFIES (HZ) 2357static void rndis_update_wireless_stats(struct work_struct *work) 2358{ 2359 struct rndis_wext_private *priv = 2360 container_of(work, struct rndis_wext_private, stats_work.work); 2361 struct usbnet *usbdev = priv->usbdev; 2362 struct iw_statistics iwstats; 2363 __le32 rssi, tmp; 2364 int len, ret, j; 2365 unsigned long flags; 2366 int update_jiffies = STATS_UPDATE_JIFFIES; 2367 void *buf; 2368 2369 spin_lock_irqsave(&priv->stats_lock, flags); 2370 memcpy(&iwstats, &priv->privstats, sizeof(iwstats)); 2371 spin_unlock_irqrestore(&priv->stats_lock, flags); 2372 2373 /* only update stats when connected */ 2374 if (!is_associated(usbdev)) { 2375 iwstats.qual.qual = 0; 2376 iwstats.qual.level = 0; 2377 iwstats.qual.updated = IW_QUAL_QUAL_UPDATED 2378 | IW_QUAL_LEVEL_UPDATED 2379 | IW_QUAL_NOISE_INVALID 2380 | IW_QUAL_QUAL_INVALID 2381 | IW_QUAL_LEVEL_INVALID; 2382 goto end; 2383 } 2384 2385 len = sizeof(rssi); 2386 ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); 2387 2388 devdbg(usbdev, "stats: OID_802_11_RSSI -> %d, rssi:%d", ret, 2389 le32_to_cpu(rssi)); 2390 if (ret == 0) { 2391 memset(&iwstats.qual, 0, sizeof(iwstats.qual)); 2392 iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi)); 2393 iwstats.qual.level = le32_to_cpu(rssi); 2394 iwstats.qual.updated = IW_QUAL_QUAL_UPDATED 2395 | IW_QUAL_LEVEL_UPDATED 2396 | IW_QUAL_NOISE_INVALID; 2397 } 2398 2399 memset(&iwstats.discard, 0, sizeof(iwstats.discard)); 2400 2401 len = sizeof(tmp); 2402 ret = rndis_query_oid(usbdev, OID_GEN_XMIT_ERROR, &tmp, &len); 2403 if (ret == 0) 2404 iwstats.discard.misc += le32_to_cpu(tmp); 2405 2406 len = sizeof(tmp); 2407 ret = rndis_query_oid(usbdev, OID_GEN_RCV_ERROR, &tmp, &len); 2408 if (ret == 0) 2409 iwstats.discard.misc += le32_to_cpu(tmp); 2410 2411 len = sizeof(tmp); 2412 ret = rndis_query_oid(usbdev, OID_GEN_RCV_NO_BUFFER, &tmp, &len); 2413 if (ret == 0) 2414 iwstats.discard.misc += le32_to_cpu(tmp); 2415 2416 /* Workaround transfer stalls on poor quality links. 2417 * TODO: find right way to fix these stalls (as stalls do not happen 2418 * with ndiswrapper/windows driver). */ 2419 if (iwstats.qual.qual <= 25) { 2420 /* Decrease stats worker interval to catch stalls. 2421 * faster. Faster than 400-500ms causes packet loss, 2422 * Slower doesn't catch stalls fast enough. 2423 */ 2424 j = msecs_to_jiffies(priv->param_workaround_interval); 2425 if (j > STATS_UPDATE_JIFFIES) 2426 j = STATS_UPDATE_JIFFIES; 2427 else if (j <= 0) 2428 j = 1; 2429 update_jiffies = j; 2430 2431 /* Send scan OID. Use of both OIDs is required to get device 2432 * working. 2433 */ 2434 tmp = ccpu2(1); 2435 rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, 2436 sizeof(tmp)); 2437 2438 len = CONTROL_BUFFER_SIZE; 2439 buf = kmalloc(len, GFP_KERNEL); 2440 if (!buf) 2441 goto end; 2442 2443 rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); 2444 kfree(buf); 2445 } 2446end: 2447 spin_lock_irqsave(&priv->stats_lock, flags); 2448 memcpy(&priv->privstats, &iwstats, sizeof(iwstats)); 2449 spin_unlock_irqrestore(&priv->stats_lock, flags); 2450 2451 if (update_jiffies >= HZ) 2452 update_jiffies = round_jiffies_relative(update_jiffies); 2453 else { 2454 j = round_jiffies_relative(update_jiffies); 2455 if (abs(j - update_jiffies) <= 10) 2456 update_jiffies = j; 2457 } 2458 2459 queue_delayed_work(priv->workqueue, &priv->stats_work, update_jiffies); 2460} 2461 2462 2463static int bcm4320_early_init(struct usbnet *usbdev) 2464{ 2465 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2466 char buf[8]; 2467 2468 /* Early initialization settings, setting these won't have effect 2469 * if called after generic_rndis_bind(). 2470 */ 2471 2472 priv->param_country[0] = modparam_country[0]; 2473 priv->param_country[1] = modparam_country[1]; 2474 priv->param_country[2] = 0; 2475 priv->param_frameburst = modparam_frameburst; 2476 priv->param_afterburner = modparam_afterburner; 2477 priv->param_power_save = modparam_power_save; 2478 priv->param_power_output = modparam_power_output; 2479 priv->param_roamtrigger = modparam_roamtrigger; 2480 priv->param_roamdelta = modparam_roamdelta; 2481 2482 priv->param_country[0] = toupper(priv->param_country[0]); 2483 priv->param_country[1] = toupper(priv->param_country[1]); 2484 /* doesn't support EU as country code, use FI instead */ 2485 if (!strcmp(priv->param_country, "EU")) 2486 strcpy(priv->param_country, "FI"); 2487 2488 if (priv->param_power_save < 0) 2489 priv->param_power_save = 0; 2490 else if (priv->param_power_save > 2) 2491 priv->param_power_save = 2; 2492 2493 if (priv->param_power_output < 0) 2494 priv->param_power_output = 0; 2495 else if (priv->param_power_output > 3) 2496 priv->param_power_output = 3; 2497 2498 if (priv->param_roamtrigger < -80) 2499 priv->param_roamtrigger = -80; 2500 else if (priv->param_roamtrigger > -60) 2501 priv->param_roamtrigger = -60; 2502 2503 if (priv->param_roamdelta < 0) 2504 priv->param_roamdelta = 0; 2505 else if (priv->param_roamdelta > 2) 2506 priv->param_roamdelta = 2; 2507 2508 if (modparam_workaround_interval < 0) 2509 priv->param_workaround_interval = 500; 2510 else 2511 priv->param_workaround_interval = modparam_workaround_interval; 2512 2513 rndis_set_config_parameter_str(usbdev, "Country", priv->param_country); 2514 rndis_set_config_parameter_str(usbdev, "FrameBursting", 2515 priv->param_frameburst ? "1" : "0"); 2516 rndis_set_config_parameter_str(usbdev, "Afterburner", 2517 priv->param_afterburner ? "1" : "0"); 2518 sprintf(buf, "%d", priv->param_power_save); 2519 rndis_set_config_parameter_str(usbdev, "PowerSaveMode", buf); 2520 sprintf(buf, "%d", priv->param_power_output); 2521 rndis_set_config_parameter_str(usbdev, "PwrOut", buf); 2522 sprintf(buf, "%d", priv->param_roamtrigger); 2523 rndis_set_config_parameter_str(usbdev, "RoamTrigger", buf); 2524 sprintf(buf, "%d", priv->param_roamdelta); 2525 rndis_set_config_parameter_str(usbdev, "RoamDelta", buf); 2526 2527 return 0; 2528} 2529 2530 2531static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) 2532{ 2533 struct rndis_wext_private *priv; 2534 int retval, len; 2535 __le32 tmp; 2536 2537 /* allocate rndis private data */ 2538 priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); 2539 if (!priv) 2540 return -ENOMEM; 2541 2542 /* These have to be initialized before calling generic_rndis_bind(). 2543 * Otherwise we'll be in big trouble in rndis_wext_early_init(). 2544 */ 2545 usbdev->driver_priv = priv; 2546 strcpy(priv->name, "IEEE802.11"); 2547 usbdev->net->wireless_handlers = &rndis_iw_handlers; 2548 priv->usbdev = usbdev; 2549 2550 mutex_init(&priv->command_lock); 2551 spin_lock_init(&priv->stats_lock); 2552 2553 /* try bind rndis_host */ 2554 retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); 2555 if (retval < 0) 2556 goto fail; 2557 2558 /* generic_rndis_bind set packet filter to multicast_all+ 2559 * promisc mode which doesn't work well for our devices (device 2560 * picks up rssi to closest station instead of to access point). 2561 * 2562 * rndis_host wants to avoid all OID as much as possible 2563 * so do promisc/multicast handling in rndis_wext. 2564 */ 2565 usbdev->net->set_multicast_list = rndis_wext_set_multicast_list; 2566 tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; 2567 retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, 2568 sizeof(tmp)); 2569 2570 len = sizeof(tmp); 2571 retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, 2572 &len); 2573 priv->multicast_size = le32_to_cpu(tmp); 2574 if (retval < 0 || priv->multicast_size < 0) 2575 priv->multicast_size = 0; 2576 if (priv->multicast_size > 0) 2577 usbdev->net->flags |= IFF_MULTICAST; 2578 else 2579 usbdev->net->flags &= ~IFF_MULTICAST; 2580 2581 priv->iwstats.qual.qual = 0; 2582 priv->iwstats.qual.level = 0; 2583 priv->iwstats.qual.updated = IW_QUAL_QUAL_UPDATED 2584 | IW_QUAL_LEVEL_UPDATED 2585 | IW_QUAL_NOISE_INVALID 2586 | IW_QUAL_QUAL_INVALID 2587 | IW_QUAL_LEVEL_INVALID; 2588 2589 rndis_wext_get_caps(usbdev); 2590 set_default_iw_params(usbdev); 2591 2592 /* turn radio on */ 2593 priv->radio_on = 1; 2594 disassociate(usbdev, 1); 2595 netif_carrier_off(usbdev->net); 2596 2597 /* because rndis_command() sleeps we need to use workqueue */ 2598 priv->workqueue = create_singlethread_workqueue("rndis_wlan"); 2599 INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); 2600 queue_delayed_work(priv->workqueue, &priv->stats_work, 2601 round_jiffies_relative(STATS_UPDATE_JIFFIES)); 2602 INIT_WORK(&priv->work, rndis_wext_worker); 2603 2604 return 0; 2605 2606fail: 2607 kfree(priv); 2608 return retval; 2609} 2610 2611 2612static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) 2613{ 2614 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); 2615 2616 /* turn radio off */ 2617 disassociate(usbdev, 0); 2618 2619 cancel_delayed_work_sync(&priv->stats_work); 2620 cancel_work_sync(&priv->work); 2621 flush_workqueue(priv->workqueue); 2622 destroy_workqueue(priv->workqueue); 2623 2624 if (priv && priv->wpa_ie_len) 2625 kfree(priv->wpa_ie); 2626 kfree(priv); 2627 2628 rndis_unbind(usbdev, intf); 2629} 2630 2631 2632static int rndis_wext_reset(struct usbnet *usbdev) 2633{ 2634 return deauthenticate(usbdev); 2635} 2636 2637 2638static const struct driver_info bcm4320b_info = { 2639 .description = "Wireless RNDIS device, BCM4320b based", 2640 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, 2641 .bind = rndis_wext_bind, 2642 .unbind = rndis_wext_unbind, 2643 .status = rndis_status, 2644 .rx_fixup = rndis_rx_fixup, 2645 .tx_fixup = rndis_tx_fixup, 2646 .reset = rndis_wext_reset, 2647 .early_init = bcm4320_early_init, 2648 .link_change = rndis_wext_link_change, 2649}; 2650 2651static const struct driver_info bcm4320a_info = { 2652 .description = "Wireless RNDIS device, BCM4320a based", 2653 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, 2654 .bind = rndis_wext_bind, 2655 .unbind = rndis_wext_unbind, 2656 .status = rndis_status, 2657 .rx_fixup = rndis_rx_fixup, 2658 .tx_fixup = rndis_tx_fixup, 2659 .reset = rndis_wext_reset, 2660 .early_init = bcm4320_early_init, 2661 .link_change = rndis_wext_link_change, 2662}; 2663 2664static const struct driver_info rndis_wext_info = { 2665 .description = "Wireless RNDIS device", 2666 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, 2667 .bind = rndis_wext_bind, 2668 .unbind = rndis_wext_unbind, 2669 .status = rndis_status, 2670 .rx_fixup = rndis_rx_fixup, 2671 .tx_fixup = rndis_tx_fixup, 2672 .reset = rndis_wext_reset, 2673 .early_init = bcm4320_early_init, 2674 .link_change = rndis_wext_link_change, 2675}; 2676 2677/*-------------------------------------------------------------------------*/ 2678 2679static const struct usb_device_id products [] = { 2680#define RNDIS_MASTER_INTERFACE \ 2681 .bInterfaceClass = USB_CLASS_COMM, \ 2682 .bInterfaceSubClass = 2 /* ACM */, \ 2683 .bInterfaceProtocol = 0x0ff 2684 2685/* INF driver for these devices have DriverVer >= 4.xx.xx.xx and many custom 2686 * parameters available. Chipset marked as 'BCM4320SKFBG' in NDISwrapper-wiki. 2687 */ 2688{ 2689 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2690 | USB_DEVICE_ID_MATCH_DEVICE, 2691 .idVendor = 0x0411, 2692 .idProduct = 0x00bc, /* Buffalo WLI-U2-KG125S */ 2693 RNDIS_MASTER_INTERFACE, 2694 .driver_info = (unsigned long) &bcm4320b_info, 2695}, { 2696 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2697 | USB_DEVICE_ID_MATCH_DEVICE, 2698 .idVendor = 0x0baf, 2699 .idProduct = 0x011b, /* U.S. Robotics USR5421 */ 2700 RNDIS_MASTER_INTERFACE, 2701 .driver_info = (unsigned long) &bcm4320b_info, 2702}, { 2703 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2704 | USB_DEVICE_ID_MATCH_DEVICE, 2705 .idVendor = 0x050d, 2706 .idProduct = 0x011b, /* Belkin F5D7051 */ 2707 RNDIS_MASTER_INTERFACE, 2708 .driver_info = (unsigned long) &bcm4320b_info, 2709}, { 2710 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2711 | USB_DEVICE_ID_MATCH_DEVICE, 2712 .idVendor = 0x1799, /* Belkin has two vendor ids */ 2713 .idProduct = 0x011b, /* Belkin F5D7051 */ 2714 RNDIS_MASTER_INTERFACE, 2715 .driver_info = (unsigned long) &bcm4320b_info, 2716}, { 2717 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2718 | USB_DEVICE_ID_MATCH_DEVICE, 2719 .idVendor = 0x13b1, 2720 .idProduct = 0x0014, /* Linksys WUSB54GSv2 */ 2721 RNDIS_MASTER_INTERFACE, 2722 .driver_info = (unsigned long) &bcm4320b_info, 2723}, { 2724 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2725 | USB_DEVICE_ID_MATCH_DEVICE, 2726 .idVendor = 0x13b1, 2727 .idProduct = 0x0026, /* Linksys WUSB54GSC */ 2728 RNDIS_MASTER_INTERFACE, 2729 .driver_info = (unsigned long) &bcm4320b_info, 2730}, { 2731 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2732 | USB_DEVICE_ID_MATCH_DEVICE, 2733 .idVendor = 0x0b05, 2734 .idProduct = 0x1717, /* Asus WL169gE */ 2735 RNDIS_MASTER_INTERFACE, 2736 .driver_info = (unsigned long) &bcm4320b_info, 2737}, { 2738 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2739 | USB_DEVICE_ID_MATCH_DEVICE, 2740 .idVendor = 0x0a5c, 2741 .idProduct = 0xd11b, /* Eminent EM4045 */ 2742 RNDIS_MASTER_INTERFACE, 2743 .driver_info = (unsigned long) &bcm4320b_info, 2744}, { 2745 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2746 | USB_DEVICE_ID_MATCH_DEVICE, 2747 .idVendor = 0x1690, 2748 .idProduct = 0x0715, /* BT Voyager 1055 */ 2749 RNDIS_MASTER_INTERFACE, 2750 .driver_info = (unsigned long) &bcm4320b_info, 2751}, 2752/* These devices have DriverVer < 4.xx.xx.xx and do not have any custom 2753 * parameters available, hardware probably contain older firmware version with 2754 * no way of updating. Chipset marked as 'BCM4320????' in NDISwrapper-wiki. 2755 */ 2756{ 2757 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2758 | USB_DEVICE_ID_MATCH_DEVICE, 2759 .idVendor = 0x13b1, 2760 .idProduct = 0x000e, /* Linksys WUSB54GSv1 */ 2761 RNDIS_MASTER_INTERFACE, 2762 .driver_info = (unsigned long) &bcm4320a_info, 2763}, { 2764 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2765 | USB_DEVICE_ID_MATCH_DEVICE, 2766 .idVendor = 0x0baf, 2767 .idProduct = 0x0111, /* U.S. Robotics USR5420 */ 2768 RNDIS_MASTER_INTERFACE, 2769 .driver_info = (unsigned long) &bcm4320a_info, 2770}, { 2771 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO 2772 | USB_DEVICE_ID_MATCH_DEVICE, 2773 .idVendor = 0x0411, 2774 .idProduct = 0x004b, /* BUFFALO WLI-USB-G54 */ 2775 RNDIS_MASTER_INTERFACE, 2776 .driver_info = (unsigned long) &bcm4320a_info, 2777}, 2778/* Generic Wireless RNDIS devices that we don't have exact 2779 * idVendor/idProduct/chip yet. 2780 */ 2781{ 2782 /* RNDIS is MSFT's un-official variant of CDC ACM */ 2783 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), 2784 .driver_info = (unsigned long) &rndis_wext_info, 2785}, { 2786 /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ 2787 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), 2788 .driver_info = (unsigned long) &rndis_wext_info, 2789}, 2790 { }, // END 2791}; 2792MODULE_DEVICE_TABLE(usb, products); 2793 2794static struct usb_driver rndis_wlan_driver = { 2795 .name = "rndis_wlan", 2796 .id_table = products, 2797 .probe = usbnet_probe, 2798 .disconnect = usbnet_disconnect, 2799 .suspend = usbnet_suspend, 2800 .resume = usbnet_resume, 2801}; 2802 2803static int __init rndis_wlan_init(void) 2804{ 2805 return usb_register(&rndis_wlan_driver); 2806} 2807module_init(rndis_wlan_init); 2808 2809static void __exit rndis_wlan_exit(void) 2810{ 2811 usb_deregister(&rndis_wlan_driver); 2812} 2813module_exit(rndis_wlan_exit); 2814 2815MODULE_AUTHOR("Bjorge Dijkstra"); 2816MODULE_AUTHOR("Jussi Kivilinna"); 2817MODULE_DESCRIPTION("Driver for RNDIS based USB Wireless adapters"); 2818MODULE_LICENSE("GPL"); 2819