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