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