ipsec: update MAX_AH_AUTH_LEN to support sha512
[deliverable/linux.git] / drivers / staging / rtl8712 / rtl871x_ioctl_linux.c
1 /******************************************************************************
2 * rtl871x_ioctl_linux.c
3 *
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
22 *
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
26 *
27 ******************************************************************************/
28
29 #define _RTL871X_IOCTL_LINUX_C_
30
31 #include "osdep_service.h"
32 #include "drv_types.h"
33 #include "wlan_bssdef.h"
34 #include "rtl871x_debug.h"
35 #include "wifi.h"
36 #include "rtl871x_mlme.h"
37 #include "rtl871x_ioctl.h"
38 #include "rtl871x_ioctl_set.h"
39 #include "rtl871x_mp_ioctl.h"
40 #include "mlme_osdep.h"
41
42 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
43
44 #define SCAN_ITEM_SIZE 768
45 #define MAX_CUSTOM_LEN 64
46 #define RATE_COUNT 4
47
48
49 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
50 6000000, 9000000, 12000000, 18000000,
51 24000000, 36000000, 48000000, 54000000};
52
53 static const long ieee80211_wlan_frequencies[] = {
54 2412, 2417, 2422, 2427,
55 2432, 2437, 2442, 2447,
56 2452, 2457, 2462, 2467,
57 2472, 2484
58 };
59
60 static const char * const iw_operation_mode[] = {
61 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
62 "Monitor"
63 };
64
65 /**
66 * hwaddr_aton - Convert ASCII string to MAC address
67 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
68 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
69 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
70 */
71 static int hwaddr_aton_i(const char *txt, u8 *addr)
72 {
73 int i;
74
75 for (i = 0; i < 6; i++) {
76 int a, b;
77
78 a = hex_to_bin(*txt++);
79 if (a < 0)
80 return -1;
81 b = hex_to_bin(*txt++);
82 if (b < 0)
83 return -1;
84 *addr++ = (a << 4) | b;
85 if (i < 5 && *txt++ != ':')
86 return -1;
87 }
88 return 0;
89 }
90
91 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
92 {
93 union iwreq_data wrqu;
94 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
95
96 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
97 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
98 ETH_ALEN);
99 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
100 }
101
102 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
103 {
104 union iwreq_data wrqu;
105
106 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
107 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
108 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
109 }
110
111 static inline void handle_pairwise_key(struct sta_info *psta,
112 struct ieee_param *param,
113 struct _adapter *padapter)
114 {
115 /* pairwise key */
116 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
117 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
118 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
119 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
120 key[16]), 8);
121 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
122 key[24]), 8);
123 padapter->securitypriv. busetkipkey = false;
124 _set_timer(&padapter->securitypriv.tkip_timer, 50);
125 }
126 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
127 }
128
129 static inline void handle_group_key(struct ieee_param *param,
130 struct _adapter *padapter)
131 {
132 if (0 < param->u.crypt.idx &&
133 param->u.crypt.idx < 3) {
134 /* group key idx is 1 or 2 */
135 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
136 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
137 > 16 ? 16 : param->u.crypt.key_len));
138 memcpy(padapter->securitypriv.XGrptxmickey[param->
139 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
140 memcpy(padapter->securitypriv. XGrprxmickey[param->
141 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
142 padapter->securitypriv.binstallGrpkey = true;
143 r8712_set_key(padapter, &padapter->securitypriv,
144 param->u.crypt.idx);
145 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
146 if (padapter->registrypriv.power_mgnt != padapter->
147 pwrctrlpriv.pwr_mode)
148 _set_timer(&(padapter->mlmepriv.dhcp_timer),
149 60000);
150 }
151 }
152 }
153
154 static inline char *translate_scan(struct _adapter *padapter,
155 struct iw_request_info *info,
156 struct wlan_network *pnetwork,
157 char *start, char *stop)
158 {
159 struct iw_event iwe;
160 struct ieee80211_ht_cap *pht_capie;
161 char *current_val;
162 u8 *buf = (u8 *)_malloc(pnetwork->network.IELength * 2);
163 u8 *wpa_ie = (u8 *)_malloc(255);
164 u8 *rsn_ie = (u8 *)_malloc(255);
165 u8 *wps_ie = (u8 *)_malloc(MAX_WPS_IE_LEN);
166 s8 *p;
167 u32 i = 0, ht_ielen = 0;
168 u16 cap, ht_cap = false, mcs_rate;
169 u8 rssi, bw_40MHz = 0, short_GI = 0;
170
171 if ((pnetwork->network.Configuration.DSConfig < 1) ||
172 (pnetwork->network.Configuration.DSConfig > 14)) {
173 if (pnetwork->network.Configuration.DSConfig < 1)
174 pnetwork->network.Configuration.DSConfig = 1;
175 else
176 pnetwork->network.Configuration.DSConfig = 14;
177 }
178 /* AP MAC address */
179 iwe.cmd = SIOCGIWAP;
180 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
181 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
182 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
183 /* Add the ESSID */
184 iwe.cmd = SIOCGIWESSID;
185 iwe.u.data.flags = 1;
186 iwe.u.data.length = (u16)min((u16)pnetwork->network.Ssid.SsidLength,
187 (u16)32);
188 start = iwe_stream_add_point(info, start, stop, &iwe,
189 pnetwork->network.Ssid.Ssid);
190 /* parsing HT_CAP_IE */
191 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
192 &ht_ielen, pnetwork->network.IELength - 12);
193 if (p && ht_ielen > 0) {
194 ht_cap = true;
195 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
196 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
197 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH)
198 ? 1 : 0;
199 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 |
200 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
201 }
202 /* Add the protocol name */
203 iwe.cmd = SIOCGIWNAME;
204 if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
205 SupportedRates)) == true) {
206 if (ht_cap == true)
207 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
208 else
209 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
210 } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
211 SupportedRates)) == true) {
212 if (ht_cap == true)
213 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
214 else
215 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
216 } else {
217 if (ht_cap == true)
218 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
219 else
220 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
221 }
222 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
223 /* Add mode */
224 iwe.cmd = SIOCGIWMODE;
225 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
226 2);
227 cap = le16_to_cpu(cap);
228 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
229 if (cap & WLAN_CAPABILITY_BSS)
230 iwe.u.mode = (u32)IW_MODE_MASTER;
231 else
232 iwe.u.mode = (u32)IW_MODE_ADHOC;
233 start = iwe_stream_add_event(info, start, stop, &iwe,
234 IW_EV_UINT_LEN);
235 }
236 /* Add frequency/channel */
237 iwe.cmd = SIOCGIWFREQ;
238 {
239 /* check legel index */
240 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
241 if (dsconfig >= 1 && dsconfig <= sizeof(
242 ieee80211_wlan_frequencies) / sizeof(long))
243 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
244 pnetwork->network.Configuration.
245 DSConfig - 1] * 100000);
246 else
247 iwe.u.freq.m = 0;
248 }
249 iwe.u.freq.e = (s16)1;
250 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
251 start = iwe_stream_add_event(info, start, stop, &iwe,
252 IW_EV_FREQ_LEN);
253 /* Add encryption capability */
254 iwe.cmd = SIOCGIWENCODE;
255 if (cap & WLAN_CAPABILITY_PRIVACY)
256 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
257 IW_ENCODE_NOKEY);
258 else
259 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
260 iwe.u.data.length = (u16)0;
261 start = iwe_stream_add_point(info, start, stop, &iwe,
262 pnetwork->network.Ssid.Ssid);
263 /*Add basic and extended rates */
264 current_val = start + iwe_stream_lcp_len(info);
265 iwe.cmd = SIOCGIWRATE;
266 iwe.u.bitrate.fixed = 0;
267 iwe.u.bitrate.disabled = 0;
268 iwe.u.bitrate.value = 0;
269 i = 0;
270 while (pnetwork->network.SupportedRates[i] != 0) {
271 /* Bit rate given in 500 kb/s units */
272 iwe.u.bitrate.value = (pnetwork->network.SupportedRates[i++] &
273 0x7F) * 500000;
274 current_val = iwe_stream_add_value(info, start, current_val,
275 stop, &iwe, IW_EV_PARAM_LEN);
276 }
277 /* Check if we added any event */
278 if ((current_val - start) > iwe_stream_lcp_len(info))
279 start = current_val;
280 /* parsing WPA/WPA2 IE */
281 {
282 u16 wpa_len = 0, rsn_len = 0;
283 u8 *p;
284 sint out_len = 0;
285 out_len = r8712_get_sec_ie(pnetwork->network.IEs,
286 pnetwork->network.
287 IELength, rsn_ie, &rsn_len,
288 wpa_ie, &wpa_len);
289 if (wpa_len > 0) {
290 p = buf;
291 memset(buf, 0, MAX_WPA_IE_LEN);
292 p += snprintf(p, 7, "wpa_ie=");
293 for (i = 0; i < wpa_len; i++)
294 p += snprintf(p, 2, "%02x", wpa_ie[i]);
295 memset(&iwe, 0, sizeof(iwe));
296 iwe.cmd = IWEVCUSTOM;
297 iwe.u.data.length = (u16)strlen(buf);
298 start = iwe_stream_add_point(info, start, stop,
299 &iwe, buf);
300 memset(&iwe, 0, sizeof(iwe));
301 iwe.cmd = IWEVGENIE;
302 iwe.u.data.length = (u16)wpa_len;
303 start = iwe_stream_add_point(info, start, stop,
304 &iwe, wpa_ie);
305 }
306 if (rsn_len > 0) {
307 p = buf;
308 memset(buf, 0, MAX_WPA_IE_LEN);
309 p += snprintf(p, 7, "rsn_ie=");
310 for (i = 0; i < rsn_len; i++)
311 p += snprintf(p, 2, "%02x", rsn_ie[i]);
312 memset(&iwe, 0, sizeof(iwe));
313 iwe.cmd = IWEVCUSTOM;
314 iwe.u.data.length = strlen(buf);
315 start = iwe_stream_add_point(info, start, stop,
316 &iwe, buf);
317 memset(&iwe, 0, sizeof(iwe));
318 iwe.cmd = IWEVGENIE;
319 iwe.u.data.length = rsn_len;
320 start = iwe_stream_add_point(info, start, stop, &iwe,
321 rsn_ie);
322 }
323 }
324
325 { /* parsing WPS IE */
326 uint wps_ielen;
327
328 if (r8712_get_wps_ie(pnetwork->network.IEs,
329 pnetwork->network.IELength,
330 wps_ie, &wps_ielen) == true) {
331 if (wps_ielen > 2) {
332 iwe.cmd = IWEVGENIE;
333 iwe.u.data.length = (u16)wps_ielen;
334 start = iwe_stream_add_point(info, start, stop,
335 &iwe, wps_ie);
336 }
337 }
338 }
339 /* Add quality statistics */
340 iwe.cmd = IWEVQUAL;
341 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
342 /* we only update signal_level (signal strength) that is rssi. */
343 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
344 IW_QUAL_NOISE_INVALID);
345 iwe.u.qual.level = rssi; /* signal strength */
346 iwe.u.qual.qual = 0; /* signal quality */
347 iwe.u.qual.noise = 0; /* noise level */
348 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
349 /* how to translate rssi to ?% */
350 kfree(buf);
351 kfree(wpa_ie);
352 kfree(rsn_ie);
353 kfree(wps_ie);
354 return start;
355 }
356
357 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
358 {
359 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
360 int ret = 0;
361
362 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
363 padapter->securitypriv.ndisencryptstatus =
364 Ndis802_11Encryption1Enabled;
365 padapter->securitypriv.ndisauthtype =
366 Ndis802_11AuthModeAutoSwitch;
367 padapter->securitypriv.AuthAlgrthm = 3;
368 } else if (value & AUTH_ALG_SHARED_KEY) {
369 padapter->securitypriv.ndisencryptstatus =
370 Ndis802_11Encryption1Enabled;
371 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
372 padapter->securitypriv.AuthAlgrthm = 1;
373 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
374 if (padapter->securitypriv.ndisauthtype <
375 Ndis802_11AuthModeWPAPSK) {
376 padapter->securitypriv.ndisauthtype =
377 Ndis802_11AuthModeOpen;
378 padapter->securitypriv.AuthAlgrthm = 0;
379 }
380 } else
381 ret = -EINVAL;
382 return ret;
383 }
384
385 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
386 u32 param_len)
387 {
388 int ret = 0;
389 u32 wep_key_idx, wep_key_len = 0;
390 struct NDIS_802_11_WEP *pwep = NULL;
391 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
392 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
393 struct security_priv *psecuritypriv = &padapter->securitypriv;
394
395 param->u.crypt.err = 0;
396 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
397 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
398 param->u.crypt.key_len)
399 return -EINVAL;
400 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
401 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
402 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
403 if (param->u.crypt.idx >= WEP_KEYS) {
404 /* for large key indices, set the default (0) */
405 param->u.crypt.idx = 0;
406 }
407 } else
408 return -EINVAL;
409 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
410 printk(KERN_INFO "r8712u: wpa_set_encryption, crypt.alg ="
411 " WEP\n");
412 padapter->securitypriv.ndisencryptstatus =
413 Ndis802_11Encryption1Enabled;
414 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
415 padapter->securitypriv.XGrpPrivacy = _WEP40_;
416 wep_key_idx = param->u.crypt.idx;
417 wep_key_len = param->u.crypt.key_len;
418 if (wep_key_idx >= WEP_KEYS)
419 wep_key_idx = 0;
420 if (wep_key_len > 0) {
421 wep_key_len = wep_key_len <= 5 ? 5 : 13;
422 pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
423 (wep_key_len +
424 FIELD_OFFSET(struct NDIS_802_11_WEP,
425 KeyMaterial)));
426 if (pwep == NULL)
427 return -ENOMEM;
428 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
429 pwep->KeyLength = wep_key_len;
430 pwep->Length = wep_key_len +
431 FIELD_OFFSET(struct NDIS_802_11_WEP,
432 KeyMaterial);
433 if (wep_key_len == 13) {
434 padapter->securitypriv.PrivacyAlgrthm =
435 _WEP104_;
436 padapter->securitypriv.XGrpPrivacy =
437 _WEP104_;
438 }
439 } else
440 return -EINVAL;
441 pwep->KeyIndex = wep_key_idx;
442 pwep->KeyIndex |= 0x80000000;
443 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
444 if (param->u.crypt.set_tx) {
445 if (r8712_set_802_11_add_wep(padapter, pwep) ==
446 (u8)_FAIL)
447 ret = -EOPNOTSUPP;
448 } else {
449 /* don't update "psecuritypriv->PrivacyAlgrthm" and
450 * "psecuritypriv->PrivacyKeyIndex=keyid", but can
451 * r8712_set_key to fw/cam
452 */
453 if (wep_key_idx >= WEP_KEYS) {
454 ret = -EOPNOTSUPP;
455 goto exit;
456 }
457 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
458 skey[0]), pwep->KeyMaterial,
459 pwep->KeyLength);
460 psecuritypriv->DefKeylen[wep_key_idx] =
461 pwep->KeyLength;
462 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
463 }
464 goto exit;
465 }
466 if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
467 struct sta_info *psta, *pbcmc_sta;
468 struct sta_priv *pstapriv = &padapter->stapriv;
469
470 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
471 WIFI_MP_STATE) == true) { /* sta mode */
472 psta = r8712_get_stainfo(pstapriv,
473 get_bssid(pmlmepriv));
474 if (psta) {
475 psta->ieee8021x_blocked = false;
476 if ((padapter->securitypriv.ndisencryptstatus ==
477 Ndis802_11Encryption2Enabled) ||
478 (padapter->securitypriv.ndisencryptstatus ==
479 Ndis802_11Encryption3Enabled))
480 psta->XPrivacy = padapter->
481 securitypriv.PrivacyAlgrthm;
482 if (param->u.crypt.set_tx == 1)
483 handle_pairwise_key(psta, param,
484 padapter);
485 else /* group key */
486 handle_group_key(param, padapter);
487 }
488 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
489 if (pbcmc_sta) {
490 pbcmc_sta->ieee8021x_blocked = false;
491 if ((padapter->securitypriv.ndisencryptstatus ==
492 Ndis802_11Encryption2Enabled) ||
493 (padapter->securitypriv.ndisencryptstatus ==
494 Ndis802_11Encryption3Enabled))
495 pbcmc_sta->XPrivacy =
496 padapter->securitypriv.
497 PrivacyAlgrthm;
498 }
499 }
500 }
501 exit:
502 kfree((u8 *)pwep);
503 return ret;
504 }
505
506 static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
507 unsigned short ielen)
508 {
509 u8 *buf = NULL, *pos = NULL;
510 int group_cipher = 0, pairwise_cipher = 0;
511 int ret = 0;
512
513 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
514 return -EINVAL;
515 if (ielen) {
516 buf = _malloc(ielen);
517 if (buf == NULL)
518 return -ENOMEM;
519 memcpy(buf, pie , ielen);
520 pos = buf;
521 if (ielen < RSN_HEADER_LEN) {
522 ret = -1;
523 goto exit;
524 }
525 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
526 &pairwise_cipher) == _SUCCESS) {
527 padapter->securitypriv.AuthAlgrthm = 2;
528 padapter->securitypriv.ndisauthtype =
529 Ndis802_11AuthModeWPAPSK;
530 }
531 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
532 &pairwise_cipher) == _SUCCESS) {
533 padapter->securitypriv.AuthAlgrthm = 2;
534 padapter->securitypriv.ndisauthtype =
535 Ndis802_11AuthModeWPA2PSK;
536 }
537 switch (group_cipher) {
538 case WPA_CIPHER_NONE:
539 padapter->securitypriv.XGrpPrivacy =
540 _NO_PRIVACY_;
541 padapter->securitypriv.ndisencryptstatus =
542 Ndis802_11EncryptionDisabled;
543 break;
544 case WPA_CIPHER_WEP40:
545 padapter->securitypriv.XGrpPrivacy = _WEP40_;
546 padapter->securitypriv.ndisencryptstatus =
547 Ndis802_11Encryption1Enabled;
548 break;
549 case WPA_CIPHER_TKIP:
550 padapter->securitypriv.XGrpPrivacy = _TKIP_;
551 padapter->securitypriv.ndisencryptstatus =
552 Ndis802_11Encryption2Enabled;
553 break;
554 case WPA_CIPHER_CCMP:
555 padapter->securitypriv.XGrpPrivacy = _AES_;
556 padapter->securitypriv.ndisencryptstatus =
557 Ndis802_11Encryption3Enabled;
558 break;
559 case WPA_CIPHER_WEP104:
560 padapter->securitypriv.XGrpPrivacy = _WEP104_;
561 padapter->securitypriv.ndisencryptstatus =
562 Ndis802_11Encryption1Enabled;
563 break;
564 }
565 switch (pairwise_cipher) {
566 case WPA_CIPHER_NONE:
567 padapter->securitypriv.PrivacyAlgrthm =
568 _NO_PRIVACY_;
569 padapter->securitypriv.ndisencryptstatus =
570 Ndis802_11EncryptionDisabled;
571 break;
572 case WPA_CIPHER_WEP40:
573 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
574 padapter->securitypriv.ndisencryptstatus =
575 Ndis802_11Encryption1Enabled;
576 break;
577 case WPA_CIPHER_TKIP:
578 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
579 padapter->securitypriv.ndisencryptstatus =
580 Ndis802_11Encryption2Enabled;
581 break;
582 case WPA_CIPHER_CCMP:
583 padapter->securitypriv.PrivacyAlgrthm = _AES_;
584 padapter->securitypriv.ndisencryptstatus =
585 Ndis802_11Encryption3Enabled;
586 break;
587 case WPA_CIPHER_WEP104:
588 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
589 padapter->securitypriv.ndisencryptstatus =
590 Ndis802_11Encryption1Enabled;
591 break;
592 }
593 padapter->securitypriv.wps_phase = false;
594 {/* set wps_ie */
595 u16 cnt = 0;
596 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
597
598 while (cnt < ielen) {
599 eid = buf[cnt];
600
601 if ((eid == _VENDOR_SPECIFIC_IE_) &&
602 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
603 printk(KERN_INFO "r8712u: "
604 "SET WPS_IE\n");
605 padapter->securitypriv.wps_ie_len =
606 ((buf[cnt+1] + 2) <
607 (MAX_WPA_IE_LEN << 2)) ?
608 (buf[cnt + 1] + 2) :
609 (MAX_WPA_IE_LEN << 2);
610 memcpy(padapter->securitypriv.wps_ie,
611 &buf[cnt],
612 padapter->securitypriv.wps_ie_len);
613 padapter->securitypriv.wps_phase =
614 true;
615 printk(KERN_INFO "r8712u: SET WPS_IE,"
616 " wps_phase==true\n");
617 cnt += buf[cnt+1]+2;
618 break;
619 } else
620 cnt += buf[cnt + 1] + 2;
621 }
622 }
623 }
624 exit:
625 kfree(buf);
626 return ret;
627 }
628
629 static int r8711_wx_get_name(struct net_device *dev,
630 struct iw_request_info *info,
631 union iwreq_data *wrqu, char *extra)
632 {
633 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
634 u32 ht_ielen = 0;
635 char *p;
636 u8 ht_cap = false;
637 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
638 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
639 NDIS_802_11_RATES_EX *prates = NULL;
640
641 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
642 true) {
643 /* parsing HT_CAP_IE */
644 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
645 &ht_ielen, pcur_bss->IELength - 12);
646 if (p && ht_ielen > 0)
647 ht_cap = true;
648 prates = &pcur_bss->SupportedRates;
649 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
650 if (ht_cap == true)
651 snprintf(wrqu->name, IFNAMSIZ,
652 "IEEE 802.11bn");
653 else
654 snprintf(wrqu->name, IFNAMSIZ,
655 "IEEE 802.11b");
656 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
657 if (ht_cap == true)
658 snprintf(wrqu->name, IFNAMSIZ,
659 "IEEE 802.11bgn");
660 else
661 snprintf(wrqu->name, IFNAMSIZ,
662 "IEEE 802.11bg");
663 } else {
664 if (ht_cap == true)
665 snprintf(wrqu->name, IFNAMSIZ,
666 "IEEE 802.11gn");
667 else
668 snprintf(wrqu->name, IFNAMSIZ,
669 "IEEE 802.11g");
670 }
671 } else
672 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
673 return 0;
674 }
675
676 static const long frequency_list[] = {
677 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
678 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
679 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
680 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
681 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
682 5825
683 };
684
685 static int r8711_wx_set_freq(struct net_device *dev,
686 struct iw_request_info *info,
687 union iwreq_data *wrqu, char *extra)
688 {
689 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
690 struct iw_freq *fwrq = &wrqu->freq;
691 int rc = 0;
692
693 /* If setting by frequency, convert to a channel */
694 if ((fwrq->e == 1) &&
695 (fwrq->m >= (int) 2.412e8) &&
696 (fwrq->m <= (int) 2.487e8)) {
697 int f = fwrq->m / 100000;
698 int c = 0;
699 while ((c < 14) && (f != frequency_list[c]))
700 c++;
701 fwrq->e = 0;
702 fwrq->m = c + 1;
703 }
704 /* Setting by channel number */
705 if ((fwrq->m > 14) || (fwrq->e > 0))
706 rc = -EOPNOTSUPP;
707 else {
708 int channel = fwrq->m;
709 if ((channel < 1) || (channel > 14))
710 rc = -EINVAL;
711 else {
712 /* Yes ! We can set it !!! */
713 padapter->registrypriv.channel = channel;
714 }
715 }
716 return rc;
717 }
718
719 static int r8711_wx_get_freq(struct net_device *dev,
720 struct iw_request_info *info,
721 union iwreq_data *wrqu, char *extra)
722 {
723 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
724 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
725 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
726
727 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
728 wrqu->freq.m = ieee80211_wlan_frequencies[
729 pcur_bss->Configuration.DSConfig-1] * 100000;
730 wrqu->freq.e = 1;
731 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
732 } else
733 return -1;
734 return 0;
735 }
736
737 static int r8711_wx_set_mode(struct net_device *dev,
738 struct iw_request_info *a,
739 union iwreq_data *wrqu, char *b)
740 {
741 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
742 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
743
744 switch (wrqu->mode) {
745 case IW_MODE_AUTO:
746 networkType = Ndis802_11AutoUnknown;
747 break;
748 case IW_MODE_ADHOC:
749 networkType = Ndis802_11IBSS;
750 break;
751 case IW_MODE_MASTER:
752 networkType = Ndis802_11APMode;
753 break;
754 case IW_MODE_INFRA:
755 networkType = Ndis802_11Infrastructure;
756 break;
757 default:
758 return -EINVAL;
759 }
760 if (Ndis802_11APMode == networkType)
761 r8712_setopmode_cmd(padapter, networkType);
762 else
763 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
764 if (!r8712_set_802_11_infrastructure_mode(padapter, networkType))
765 return -1;
766 return 0;
767 }
768
769 static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
770 union iwreq_data *wrqu, char *b)
771 {
772 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
773 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
774
775 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
776 wrqu->mode = IW_MODE_INFRA;
777 else if (check_fwstate(pmlmepriv,
778 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
779 wrqu->mode = IW_MODE_ADHOC;
780 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
781 wrqu->mode = IW_MODE_MASTER;
782 else
783 wrqu->mode = IW_MODE_AUTO;
784 return 0;
785 }
786
787 static int r871x_wx_set_pmkid(struct net_device *dev,
788 struct iw_request_info *a,
789 union iwreq_data *wrqu, char *extra)
790 {
791 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
792 struct security_priv *psecuritypriv = &padapter->securitypriv;
793 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
794 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
795 u8 strIssueBssid[ETH_ALEN] = {0x00};
796 u8 j, blInserted = false;
797 int intReturn = false;
798
799 /*
800 There are the BSSID information in the bssid.sa_data array.
801 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear
802 all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
803 wpa_supplicant wants to add a PMKID/BSSID to driver.
804 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
805 remove a PMKID/BSSID from driver.
806 */
807 if (pPMK == NULL)
808 return -EINVAL;
809 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
810 switch (pPMK->cmd) {
811 case IW_PMKSA_ADD:
812 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
813 return intReturn;
814 else
815 intReturn = true;
816 blInserted = false;
817 /* overwrite PMKID */
818 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
819 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
820 strIssueBssid, ETH_ALEN)) {
821 /* BSSID is matched, the same AP => rewrite
822 * with new PMKID. */
823 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid:"
824 " BSSID exists in the PMKList.\n");
825 memcpy(psecuritypriv->PMKIDList[j].PMKID,
826 pPMK->pmkid, IW_PMKID_LEN);
827 psecuritypriv->PMKIDList[j].bUsed = true;
828 psecuritypriv->PMKIDIndex = j + 1;
829 blInserted = true;
830 break;
831 }
832 }
833 if (!blInserted) {
834 /* Find a new entry */
835 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: Use the"
836 " new entry index = %d for this PMKID.\n",
837 psecuritypriv->PMKIDIndex);
838 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
839 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
840 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
841 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
842 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
843 bUsed = true;
844 psecuritypriv->PMKIDIndex++ ;
845 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
846 psecuritypriv->PMKIDIndex = 0;
847 }
848 break;
849 case IW_PMKSA_REMOVE:
850 intReturn = true;
851 for (j = 0; j < NUM_PMKID_CACHE; j++) {
852 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
853 strIssueBssid, ETH_ALEN)) {
854 /* BSSID is matched, the same AP => Remove
855 * this PMKID information and reset it. */
856 memset(psecuritypriv->PMKIDList[j].Bssid,
857 0x00, ETH_ALEN);
858 psecuritypriv->PMKIDList[j].bUsed = false;
859 break;
860 }
861 }
862 break;
863 case IW_PMKSA_FLUSH:
864 memset(psecuritypriv->PMKIDList, 0,
865 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
866 psecuritypriv->PMKIDIndex = 0;
867 intReturn = true;
868 break;
869 default:
870 printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: "
871 "unknown Command\n");
872 intReturn = false;
873 break;
874 }
875 return intReturn;
876 }
877
878 static int r8711_wx_get_sens(struct net_device *dev,
879 struct iw_request_info *info,
880 union iwreq_data *wrqu, char *extra)
881 {
882 wrqu->sens.value = 0;
883 wrqu->sens.fixed = 0; /* no auto select */
884 wrqu->sens.disabled = 1;
885 return 0;
886 }
887
888 static int r8711_wx_get_range(struct net_device *dev,
889 struct iw_request_info *info,
890 union iwreq_data *wrqu, char *extra)
891 {
892 struct iw_range *range = (struct iw_range *)extra;
893 u16 val;
894 int i;
895
896 wrqu->data.length = sizeof(*range);
897 memset(range, 0, sizeof(*range));
898 /* Let's try to keep this struct in the same order as in
899 * linux/include/wireless.h
900 */
901
902 /* TODO: See what values we can set, and remove the ones we can't
903 * set, or fill them with some default data.
904 */
905 /* ~5 Mb/s real (802.11b) */
906 range->throughput = 5 * 1000 * 1000;
907 /* TODO: 8711 sensitivity ? */
908 /* signal level threshold range */
909 /* percent values between 0 and 100. */
910 range->max_qual.qual = 100;
911 range->max_qual.level = 100;
912 range->max_qual.noise = 100;
913 range->max_qual.updated = 7; /* Updated all three */
914 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
915 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
916 range->avg_qual.level = 20 + -98;
917 range->avg_qual.noise = 0;
918 range->avg_qual.updated = 7; /* Updated all three */
919 range->num_bitrates = RATE_COUNT;
920 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
921 range->bitrate[i] = rtl8180_rates[i];
922 range->min_frag = MIN_FRAG_THRESHOLD;
923 range->max_frag = MAX_FRAG_THRESHOLD;
924 range->pm_capa = 0;
925 range->we_version_compiled = WIRELESS_EXT;
926 range->we_version_source = 16;
927 range->num_channels = 14;
928 for (i = 0, val = 0; i < 14; i++) {
929 /* Include only legal frequencies for some countries */
930 range->freq[val].i = i + 1;
931 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
932 range->freq[val].e = 1;
933 val++;
934 if (val == IW_MAX_FREQUENCIES)
935 break;
936 }
937 range->num_frequency = val;
938 range->enc_capa = IW_ENC_CAPA_WPA |
939 IW_ENC_CAPA_WPA2 |
940 IW_ENC_CAPA_CIPHER_TKIP |
941 IW_ENC_CAPA_CIPHER_CCMP;
942 return 0;
943 }
944
945 static int r871x_wx_set_priv(struct net_device *dev,
946 struct iw_request_info *info,
947 union iwreq_data *awrq,
948 char *extra)
949 {
950 int ret = 0, len = 0;
951 char *ext;
952 struct iw_point *dwrq = (struct iw_point *)awrq;
953
954 len = dwrq->length;
955 ext = _malloc(len);
956 if (!_malloc(len))
957 return -ENOMEM;
958 if (copy_from_user(ext, dwrq->pointer, len)) {
959 kfree(ext);
960 return -EFAULT;
961 }
962 kfree(ext);
963 return ret;
964 }
965
966 /* set bssid flow
967 * s1. set_802_11_infrastructure_mode()
968 * s2. set_802_11_authentication_mode()
969 * s3. set_802_11_encryption_mode()
970 * s4. set_802_11_bssid()
971 */
972 static int r8711_wx_set_wap(struct net_device *dev,
973 struct iw_request_info *info,
974 union iwreq_data *awrq,
975 char *extra)
976 {
977 int ret = -EINPROGRESS;
978 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
980 struct __queue *queue = &pmlmepriv->scanned_queue;
981 struct sockaddr *temp = (struct sockaddr *)awrq;
982 unsigned long irqL;
983 struct list_head *phead;
984 u8 *dst_bssid;
985 struct wlan_network *pnetwork = NULL;
986 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
987
988 if (padapter->bup == false)
989 return -1;
990 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
991 return -1;
992 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
993 return ret;
994 if (temp->sa_family != ARPHRD_ETHER)
995 return -EINVAL;
996 authmode = padapter->securitypriv.ndisauthtype;
997 spin_lock_irqsave(&queue->lock, irqL);
998 phead = get_list_head(queue);
999 pmlmepriv->pscanned = get_next(phead);
1000 while (1) {
1001 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1002 break;
1003 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1004 struct wlan_network, list);
1005 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1006 dst_bssid = pnetwork->network.MacAddress;
1007 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1008 if (r8712_set_802_11_infrastructure_mode(padapter,
1009 pnetwork->network.InfrastructureMode) == false)
1010 ret = -1;
1011 break;
1012 }
1013 }
1014 spin_unlock_irqrestore(&queue->lock, irqL);
1015 if (!ret) {
1016 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1017 ret = -1;
1018 else {
1019 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1020 ret = -1;
1021 }
1022 }
1023 return ret;
1024 }
1025
1026 static int r8711_wx_get_wap(struct net_device *dev,
1027 struct iw_request_info *info,
1028 union iwreq_data *wrqu, char *extra)
1029 {
1030 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1031 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1032 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1033
1034 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1035 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1036 if (check_fwstate(pmlmepriv, _FW_LINKED |
1037 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
1038 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1039 }
1040 return 0;
1041 }
1042
1043 static int r871x_wx_set_mlme(struct net_device *dev,
1044 struct iw_request_info *info,
1045 union iwreq_data *wrqu, char *extra)
1046 {
1047 int ret = 0;
1048 u16 reason;
1049 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1050 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1051
1052 if (mlme == NULL)
1053 return -1;
1054 reason = cpu_to_le16(mlme->reason_code);
1055 switch (mlme->cmd) {
1056 case IW_MLME_DEAUTH:
1057 if (!r8712_set_802_11_disassociate(padapter))
1058 ret = -1;
1059 break;
1060 case IW_MLME_DISASSOC:
1061 if (!r8712_set_802_11_disassociate(padapter))
1062 ret = -1;
1063 break;
1064 default:
1065 return -EOPNOTSUPP;
1066 }
1067 return ret;
1068 }
1069
1070 static int r8711_wx_set_scan(struct net_device *dev,
1071 struct iw_request_info *a,
1072 union iwreq_data *wrqu, char *extra)
1073 {
1074 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1075 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1076 u8 status = true;
1077
1078 if (padapter->bDriverStopped == true) {
1079 printk(KERN_WARNING "r8712u: in r8711_wx_set_scan: "
1080 "bDriverStopped=%d\n", padapter->bDriverStopped);
1081 return -1;
1082 }
1083 if (padapter->bup == false)
1084 return -1;
1085 if (padapter->hw_init_completed == false)
1086 return -1;
1087 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1088 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1089 return 0;
1090 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1091 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1092 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1093 struct ndis_802_11_ssid ssid;
1094 unsigned long irqL;
1095 u32 len = (u32) min((u8)req->essid_len,
1096 (u8)IW_ESSID_MAX_SIZE);
1097 memset((unsigned char *)&ssid, 0,
1098 sizeof(struct ndis_802_11_ssid));
1099 memcpy(ssid.Ssid, req->essid, len);
1100 ssid.SsidLength = len;
1101 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1102 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1103 _FW_UNDER_LINKING)) ||
1104 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1105 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1106 status = false;
1107 } else
1108 status = r8712_sitesurvey_cmd(padapter, &ssid);
1109 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1110 }
1111 } else
1112 status = r8712_set_802_11_bssid_list_scan(padapter);
1113 if (status == false)
1114 return -1;
1115 return 0;
1116 }
1117
1118 static int r8711_wx_get_scan(struct net_device *dev,
1119 struct iw_request_info *a,
1120 union iwreq_data *wrqu, char *extra)
1121 {
1122 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1123 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1124 struct __queue *queue = &pmlmepriv->scanned_queue;
1125 struct wlan_network *pnetwork = NULL;
1126 unsigned long irqL;
1127 struct list_head *plist, *phead;
1128 char *ev = extra;
1129 char *stop = ev + wrqu->data.length;
1130 u32 ret = 0, cnt = 0;
1131
1132 if (padapter->bDriverStopped)
1133 return -EINVAL;
1134 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1135 msleep(30);
1136 cnt++;
1137 if (cnt > 1000)
1138 break;
1139 }
1140 spin_lock_irqsave(&queue->lock, irqL);
1141 phead = get_list_head(queue);
1142 plist = get_next(phead);
1143 while (1) {
1144 if (end_of_queue_search(phead, plist) == true)
1145 break;
1146 if ((stop - ev) < SCAN_ITEM_SIZE) {
1147 ret = -E2BIG;
1148 break;
1149 }
1150 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1151 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1152 plist = get_next(plist);
1153 }
1154 spin_unlock_irqrestore(&queue->lock, irqL);
1155 wrqu->data.length = ev - extra;
1156 wrqu->data.flags = 0;
1157 return ret;
1158 }
1159
1160 /* set ssid flow
1161 * s1. set_802_11_infrastructure_mode()
1162 * s2. set_802_11_authenticaion_mode()
1163 * s3. set_802_11_encryption_mode()
1164 * s4. set_802_11_ssid()
1165 */
1166 static int r8711_wx_set_essid(struct net_device *dev,
1167 struct iw_request_info *a,
1168 union iwreq_data *wrqu, char *extra)
1169 {
1170 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1171 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1172 struct __queue *queue = &pmlmepriv->scanned_queue;
1173 struct wlan_network *pnetwork = NULL;
1174 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1175 struct ndis_802_11_ssid ndis_ssid;
1176 u8 *dst_ssid, *src_ssid;
1177 struct list_head *phead;
1178 u32 len;
1179
1180 if (padapter->bup == false)
1181 return -1;
1182 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1183 return -1;
1184 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1185 return 0;
1186 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1187 return -E2BIG;
1188 authmode = padapter->securitypriv.ndisauthtype;
1189 if (wrqu->essid.flags && wrqu->essid.length) {
1190 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1191 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1192 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1193 ndis_ssid.SsidLength = len;
1194 memcpy(ndis_ssid.Ssid, extra, len);
1195 src_ssid = ndis_ssid.Ssid;
1196 phead = get_list_head(queue);
1197 pmlmepriv->pscanned = get_next(phead);
1198 while (1) {
1199 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1200 break;
1201 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1202 struct wlan_network, list);
1203 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1204 dst_ssid = pnetwork->network.Ssid.Ssid;
1205 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1206 && (pnetwork->network.Ssid.SsidLength ==
1207 ndis_ssid.SsidLength)) {
1208 if (!r8712_set_802_11_infrastructure_mode(
1209 padapter,
1210 pnetwork->network.InfrastructureMode))
1211 return -1;
1212 break;
1213 }
1214 }
1215 r8712_set_802_11_authentication_mode(padapter, authmode);
1216 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1217 }
1218 return -EINPROGRESS;
1219 }
1220
1221 static int r8711_wx_get_essid(struct net_device *dev,
1222 struct iw_request_info *a,
1223 union iwreq_data *wrqu, char *extra)
1224 {
1225 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1226 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1227 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1228 u32 len, ret = 0;
1229
1230 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1231 len = pcur_bss->Ssid.SsidLength;
1232 wrqu->essid.length = len;
1233 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1234 wrqu->essid.flags = 1;
1235 } else
1236 ret = -1;
1237 return ret;
1238 }
1239
1240 static int r8711_wx_set_rate(struct net_device *dev,
1241 struct iw_request_info *a,
1242 union iwreq_data *wrqu, char *extra)
1243 {
1244 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1245 u32 target_rate = wrqu->bitrate.value;
1246 u32 fixed = wrqu->bitrate.fixed;
1247 u32 ratevalue = 0;
1248 u8 datarates[NumRates];
1249 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1250 int i, ret = 0;
1251
1252 if (target_rate == -1) {
1253 ratevalue = 11;
1254 goto set_rate;
1255 }
1256 target_rate = target_rate / 100000;
1257 switch (target_rate) {
1258 case 10:
1259 ratevalue = 0;
1260 break;
1261 case 20:
1262 ratevalue = 1;
1263 break;
1264 case 55:
1265 ratevalue = 2;
1266 break;
1267 case 60:
1268 ratevalue = 3;
1269 break;
1270 case 90:
1271 ratevalue = 4;
1272 break;
1273 case 110:
1274 ratevalue = 5;
1275 break;
1276 case 120:
1277 ratevalue = 6;
1278 break;
1279 case 180:
1280 ratevalue = 7;
1281 break;
1282 case 240:
1283 ratevalue = 8;
1284 break;
1285 case 360:
1286 ratevalue = 9;
1287 break;
1288 case 480:
1289 ratevalue = 10;
1290 break;
1291 case 540:
1292 ratevalue = 11;
1293 break;
1294 default:
1295 ratevalue = 11;
1296 break;
1297 }
1298 set_rate:
1299 for (i = 0; i < NumRates; i++) {
1300 if (ratevalue == mpdatarate[i]) {
1301 datarates[i] = mpdatarate[i];
1302 if (fixed == 0)
1303 break;
1304 } else
1305 datarates[i] = 0xff;
1306 }
1307 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1308 ret = -1;
1309 return ret;
1310 }
1311
1312 static int r8711_wx_get_rate(struct net_device *dev,
1313 struct iw_request_info *info,
1314 union iwreq_data *wrqu, char *extra)
1315 {
1316 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1317 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1318 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1319 struct ieee80211_ht_cap *pht_capie;
1320 int i;
1321 u8 *p;
1322 u16 rate, max_rate = 0, ht_cap = false;
1323 u32 ht_ielen = 0;
1324 u8 bw_40MHz = 0, short_GI = 0;
1325 u16 mcs_rate = 0;
1326
1327 i = 0;
1328 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1329 p = r8712_get_ie(&pcur_bss->IEs[12],
1330 _HT_CAPABILITY_IE_, &ht_ielen,
1331 pcur_bss->IELength - 12);
1332 if (p && ht_ielen > 0) {
1333 ht_cap = true;
1334 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1335 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1336 bw_40MHz = (pht_capie->cap_info &
1337 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1338 short_GI = (pht_capie->cap_info &
1339 (IEEE80211_HT_CAP_SGI_20 |
1340 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1341 }
1342 while ((pcur_bss->SupportedRates[i] != 0) &&
1343 (pcur_bss->SupportedRates[i] != 0xFF)) {
1344 rate = pcur_bss->SupportedRates[i] & 0x7F;
1345 if (rate > max_rate)
1346 max_rate = rate;
1347 wrqu->bitrate.fixed = 0; /* no auto select */
1348 wrqu->bitrate.value = rate*500000;
1349 i++;
1350 }
1351 if (ht_cap == true) {
1352 if (mcs_rate & 0x8000) /* MCS15 */
1353 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1354 270) : ((short_GI) ? 144 : 130);
1355 else if (mcs_rate & 0x0080) /* MCS7 */
1356 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1357 135) : ((short_GI) ? 72 : 65);
1358 else /* default MCS7 */
1359 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1360 135) : ((short_GI) ? 72 : 65);
1361 max_rate *= 2; /* Mbps/2 */
1362 wrqu->bitrate.value = max_rate * 500000;
1363 } else {
1364 wrqu->bitrate.value = max_rate * 500000;
1365 }
1366 } else
1367 return -1;
1368 return 0;
1369 }
1370
1371 static int r8711_wx_get_rts(struct net_device *dev,
1372 struct iw_request_info *info,
1373 union iwreq_data *wrqu, char *extra)
1374 {
1375 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1376
1377 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1378 wrqu->rts.fixed = 0; /* no auto select */
1379 return 0;
1380 }
1381
1382 static int r8711_wx_set_frag(struct net_device *dev,
1383 struct iw_request_info *info,
1384 union iwreq_data *wrqu, char *extra)
1385 {
1386 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1387
1388 if (wrqu->frag.disabled)
1389 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1390 else {
1391 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1392 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1393 return -EINVAL;
1394 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1395 }
1396 return 0;
1397 }
1398
1399 static int r8711_wx_get_frag(struct net_device *dev,
1400 struct iw_request_info *info,
1401 union iwreq_data *wrqu, char *extra)
1402 {
1403 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1404
1405 wrqu->frag.value = padapter->xmitpriv.frag_len;
1406 wrqu->frag.fixed = 0; /* no auto select */
1407 return 0;
1408 }
1409
1410 static int r8711_wx_get_retry(struct net_device *dev,
1411 struct iw_request_info *info,
1412 union iwreq_data *wrqu, char *extra)
1413 {
1414 wrqu->retry.value = 7;
1415 wrqu->retry.fixed = 0; /* no auto select */
1416 wrqu->retry.disabled = 1;
1417 return 0;
1418 }
1419
1420 static int r8711_wx_set_enc(struct net_device *dev,
1421 struct iw_request_info *info,
1422 union iwreq_data *wrqu, char *keybuf)
1423 {
1424 u32 key;
1425 u32 keyindex_provided;
1426 struct NDIS_802_11_WEP wep;
1427 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1428 struct iw_point *erq = &(wrqu->encoding);
1429 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1430
1431 key = erq->flags & IW_ENCODE_INDEX;
1432 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1433 if (erq->flags & IW_ENCODE_DISABLED) {
1434 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1435 "EncryptionDisabled\n");
1436 padapter->securitypriv.ndisencryptstatus =
1437 Ndis802_11EncryptionDisabled;
1438 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1439 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1440 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1441 authmode = Ndis802_11AuthModeOpen;
1442 padapter->securitypriv.ndisauthtype = authmode;
1443 return 0;
1444 }
1445 if (key) {
1446 if (key > WEP_KEYS)
1447 return -EINVAL;
1448 key--;
1449 keyindex_provided = 1;
1450 } else {
1451 keyindex_provided = 0;
1452 key = padapter->securitypriv.PrivacyKeyIndex;
1453 }
1454 /* set authentication mode */
1455 if (erq->flags & IW_ENCODE_OPEN) {
1456 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1457 "IW_ENCODE_OPEN\n");
1458 padapter->securitypriv.ndisencryptstatus =
1459 Ndis802_11Encryption1Enabled;
1460 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1461 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1462 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1463 authmode = Ndis802_11AuthModeOpen;
1464 padapter->securitypriv.ndisauthtype = authmode;
1465 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1466 printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
1467 "IW_ENCODE_RESTRICTED\n");
1468 padapter->securitypriv.ndisencryptstatus =
1469 Ndis802_11Encryption1Enabled;
1470 padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
1471 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1472 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1473 authmode = Ndis802_11AuthModeShared;
1474 padapter->securitypriv.ndisauthtype = authmode;
1475 } else {
1476 padapter->securitypriv.ndisencryptstatus =
1477 Ndis802_11Encryption1Enabled;
1478 padapter->securitypriv.AuthAlgrthm = 0; /* open system */
1479 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1480 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1481 authmode = Ndis802_11AuthModeOpen;
1482 padapter->securitypriv.ndisauthtype = authmode;
1483 }
1484 wep.KeyIndex = key;
1485 if (erq->length > 0) {
1486 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1487 wep.Length = wep.KeyLength +
1488 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1489 } else {
1490 wep.KeyLength = 0 ;
1491 if (keyindex_provided == 1) { /* set key_id only, no given
1492 * KeyMaterial(erq->length==0).*/
1493 padapter->securitypriv.PrivacyKeyIndex = key;
1494 switch (padapter->securitypriv.DefKeylen[key]) {
1495 case 5:
1496 padapter->securitypriv.PrivacyAlgrthm =
1497 _WEP40_;
1498 break;
1499 case 13:
1500 padapter->securitypriv.PrivacyAlgrthm =
1501 _WEP104_;
1502 break;
1503 default:
1504 padapter->securitypriv.PrivacyAlgrthm =
1505 _NO_PRIVACY_;
1506 break;
1507 }
1508 return 0;
1509 }
1510 }
1511 wep.KeyIndex |= 0x80000000; /* transmit key */
1512 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1513 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1514 return -EOPNOTSUPP;
1515 return 0;
1516 }
1517
1518 static int r8711_wx_get_enc(struct net_device *dev,
1519 struct iw_request_info *info,
1520 union iwreq_data *wrqu, char *keybuf)
1521 {
1522 uint key, ret = 0;
1523 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1524 struct iw_point *erq = &(wrqu->encoding);
1525 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1526
1527 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1528 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1529 erq->length = 0;
1530 erq->flags |= IW_ENCODE_DISABLED;
1531 return 0;
1532 }
1533 }
1534 key = erq->flags & IW_ENCODE_INDEX;
1535 if (key) {
1536 if (key > WEP_KEYS)
1537 return -EINVAL;
1538 key--;
1539 } else {
1540 key = padapter->securitypriv.PrivacyKeyIndex;
1541 }
1542 erq->flags = key + 1;
1543 switch (padapter->securitypriv.ndisencryptstatus) {
1544 case Ndis802_11EncryptionNotSupported:
1545 case Ndis802_11EncryptionDisabled:
1546 erq->length = 0;
1547 erq->flags |= IW_ENCODE_DISABLED;
1548 break;
1549 case Ndis802_11Encryption1Enabled:
1550 erq->length = padapter->securitypriv.DefKeylen[key];
1551 if (erq->length) {
1552 memcpy(keybuf, padapter->securitypriv.DefKey[
1553 key].skey, padapter->securitypriv.
1554 DefKeylen[key]);
1555 erq->flags |= IW_ENCODE_ENABLED;
1556 if (padapter->securitypriv.ndisauthtype ==
1557 Ndis802_11AuthModeOpen)
1558 erq->flags |= IW_ENCODE_OPEN;
1559 else if (padapter->securitypriv.ndisauthtype ==
1560 Ndis802_11AuthModeShared)
1561 erq->flags |= IW_ENCODE_RESTRICTED;
1562 } else {
1563 erq->length = 0;
1564 erq->flags |= IW_ENCODE_DISABLED;
1565 }
1566 break;
1567 case Ndis802_11Encryption2Enabled:
1568 case Ndis802_11Encryption3Enabled:
1569 erq->length = 16;
1570 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1571 IW_ENCODE_NOKEY);
1572 break;
1573 default:
1574 erq->length = 0;
1575 erq->flags |= IW_ENCODE_DISABLED;
1576 break;
1577 }
1578 return ret;
1579 }
1580
1581 static int r8711_wx_get_power(struct net_device *dev,
1582 struct iw_request_info *info,
1583 union iwreq_data *wrqu, char *extra)
1584 {
1585 wrqu->power.value = 0;
1586 wrqu->power.fixed = 0; /* no auto select */
1587 wrqu->power.disabled = 1;
1588 return 0;
1589 }
1590
1591 static int r871x_wx_set_gen_ie(struct net_device *dev,
1592 struct iw_request_info *info,
1593 union iwreq_data *wrqu, char *extra)
1594 {
1595 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1596
1597 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1598 }
1599
1600 static int r871x_wx_set_auth(struct net_device *dev,
1601 struct iw_request_info *info,
1602 union iwreq_data *wrqu, char *extra)
1603 {
1604 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1605 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1606 int paramid;
1607 int paramval;
1608 int ret = 0;
1609
1610 paramid = param->flags & IW_AUTH_INDEX;
1611 paramval = param->value;
1612 switch (paramid) {
1613 case IW_AUTH_WPA_VERSION:
1614 break;
1615 case IW_AUTH_CIPHER_PAIRWISE:
1616 break;
1617 case IW_AUTH_CIPHER_GROUP:
1618 break;
1619 case IW_AUTH_KEY_MGMT:
1620 /*
1621 * ??? does not use these parameters
1622 */
1623 break;
1624 case IW_AUTH_TKIP_COUNTERMEASURES:
1625 if (paramval) {
1626 /* wpa_supplicant is enabling tkip countermeasure. */
1627 padapter->securitypriv.btkip_countermeasure = true;
1628 } else {
1629 /* wpa_supplicant is disabling tkip countermeasure. */
1630 padapter->securitypriv.btkip_countermeasure = false;
1631 }
1632 break;
1633 case IW_AUTH_DROP_UNENCRYPTED:
1634 /* HACK:
1635 *
1636 * wpa_supplicant calls set_wpa_enabled when the driver
1637 * is loaded and unloaded, regardless of if WPA is being
1638 * used. No other calls are made which can be used to
1639 * determine if encryption will be used or not prior to
1640 * association being expected. If encryption is not being
1641 * used, drop_unencrypted is set to false, else true -- we
1642 * can use this to determine if the CAP_PRIVACY_ON bit should
1643 * be set.
1644 */
1645 if (padapter->securitypriv.ndisencryptstatus ==
1646 Ndis802_11Encryption1Enabled) {
1647 /* it means init value, or using wep,
1648 * ndisencryptstatus =
1649 * Ndis802_11Encryption1Enabled,
1650 * then it needn't reset it;
1651 */
1652 break;
1653 }
1654
1655 if (paramval) {
1656 padapter->securitypriv.ndisencryptstatus =
1657 Ndis802_11EncryptionDisabled;
1658 padapter->securitypriv.PrivacyAlgrthm =
1659 _NO_PRIVACY_;
1660 padapter->securitypriv.XGrpPrivacy =
1661 _NO_PRIVACY_;
1662 padapter->securitypriv.AuthAlgrthm = 0;
1663 padapter->securitypriv.ndisauthtype =
1664 Ndis802_11AuthModeOpen;
1665 }
1666 break;
1667 case IW_AUTH_80211_AUTH_ALG:
1668 ret = wpa_set_auth_algs(dev, (u32)paramval);
1669 break;
1670 case IW_AUTH_WPA_ENABLED:
1671 break;
1672 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1673 break;
1674 case IW_AUTH_PRIVACY_INVOKED:
1675 break;
1676 default:
1677 return -EOPNOTSUPP;
1678 }
1679
1680 return ret;
1681 }
1682
1683 static int r871x_wx_set_enc_ext(struct net_device *dev,
1684 struct iw_request_info *info,
1685 union iwreq_data *wrqu, char *extra)
1686 {
1687 struct iw_point *pencoding = &wrqu->encoding;
1688 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1689 struct ieee_param *param = NULL;
1690 char *alg_name;
1691 u32 param_len;
1692 int ret = 0;
1693
1694 param_len = sizeof(struct ieee_param) + pext->key_len;
1695 param = (struct ieee_param *)_malloc(param_len);
1696 if (param == NULL)
1697 return -1;
1698 memset(param, 0, param_len);
1699 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1700 memset(param->sta_addr, 0xff, ETH_ALEN);
1701 switch (pext->alg) {
1702 case IW_ENCODE_ALG_NONE:
1703 alg_name = "none";
1704 break;
1705 case IW_ENCODE_ALG_WEP:
1706 alg_name = "WEP";
1707 break;
1708 case IW_ENCODE_ALG_TKIP:
1709 alg_name = "TKIP";
1710 break;
1711 case IW_ENCODE_ALG_CCMP:
1712 alg_name = "CCMP";
1713 break;
1714 default:
1715 return -1;
1716 }
1717 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1718 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1719 param->u.crypt.set_tx = 0;
1720 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1721 param->u.crypt.set_tx = 1;
1722 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1723 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1724 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1725 if (pext->key_len) {
1726 param->u.crypt.key_len = pext->key_len;
1727 memcpy(param + 1, pext + 1, pext->key_len);
1728 }
1729 ret = wpa_set_encryption(dev, param, param_len);
1730 if (param)
1731 kfree((u8 *)param);
1732 return ret;
1733 }
1734
1735 static int r871x_wx_get_nick(struct net_device *dev,
1736 struct iw_request_info *info,
1737 union iwreq_data *wrqu, char *extra)
1738 {
1739 if (extra) {
1740 wrqu->data.length = 8;
1741 wrqu->data.flags = 1;
1742 memcpy(extra, "rtl_wifi", 8);
1743 }
1744 return 0;
1745 }
1746
1747 static int r8711_wx_read32(struct net_device *dev,
1748 struct iw_request_info *info,
1749 union iwreq_data *wrqu, char *keybuf)
1750 {
1751 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1752 u32 addr;
1753 u32 data32;
1754
1755 get_user(addr, (u32 __user *)wrqu->data.pointer);
1756 data32 = r8712_read32(padapter, addr);
1757 put_user(data32, (u32 __user *)wrqu->data.pointer);
1758 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1759 wrqu->data.flags = data32 & 0xffff;
1760 get_user(addr, (u32 __user *)wrqu->data.pointer);
1761 return 0;
1762 }
1763
1764 static int r8711_wx_write32(struct net_device *dev,
1765 struct iw_request_info *info,
1766 union iwreq_data *wrqu, char *keybuf)
1767 {
1768 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1769 u32 addr;
1770 u32 data32;
1771
1772 get_user(addr, (u32 __user *)wrqu->data.pointer);
1773 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
1774 r8712_write32(padapter, addr, data32);
1775 return 0;
1776 }
1777
1778 static int dummy(struct net_device *dev,
1779 struct iw_request_info *a,
1780 union iwreq_data *wrqu, char *b)
1781 {
1782 return -1;
1783 }
1784
1785 static int r8711_drvext_hdl(struct net_device *dev,
1786 struct iw_request_info *info,
1787 union iwreq_data *wrqu, char *extra)
1788 {
1789 return 0;
1790 }
1791
1792 static int r871x_mp_ioctl_hdl(struct net_device *dev,
1793 struct iw_request_info *info,
1794 union iwreq_data *wrqu, char *extra)
1795 {
1796 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1797 struct iw_point *p = &wrqu->data;
1798 struct oid_par_priv oid_par;
1799 struct mp_ioctl_handler *phandler;
1800 struct mp_ioctl_param *poidparam;
1801 unsigned long BytesRead, BytesWritten, BytesNeeded;
1802 u8 *pparmbuf = NULL, bset;
1803 u16 len;
1804 uint status;
1805 int ret = 0;
1806
1807 if ((!p->length) || (!p->pointer)) {
1808 ret = -EINVAL;
1809 goto _r871x_mp_ioctl_hdl_exit;
1810 }
1811 bset = (u8)(p->flags & 0xFFFF);
1812 len = p->length;
1813 pparmbuf = NULL;
1814 pparmbuf = (u8 *)_malloc(len);
1815 if (pparmbuf == NULL) {
1816 ret = -ENOMEM;
1817 goto _r871x_mp_ioctl_hdl_exit;
1818 }
1819 if (copy_from_user(pparmbuf, p->pointer, len)) {
1820 ret = -EFAULT;
1821 goto _r871x_mp_ioctl_hdl_exit;
1822 }
1823 poidparam = (struct mp_ioctl_param *)pparmbuf;
1824 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1825 ret = -EINVAL;
1826 goto _r871x_mp_ioctl_hdl_exit;
1827 }
1828 phandler = mp_ioctl_hdl + poidparam->subcode;
1829 if ((phandler->paramsize != 0) &&
1830 (poidparam->len < phandler->paramsize)) {
1831 ret = -EINVAL;
1832 goto _r871x_mp_ioctl_hdl_exit;
1833 }
1834 if (phandler->oid == 0 && phandler->handler)
1835 status = phandler->handler(&oid_par);
1836 else if (phandler->handler) {
1837 oid_par.adapter_context = padapter;
1838 oid_par.oid = phandler->oid;
1839 oid_par.information_buf = poidparam->data;
1840 oid_par.information_buf_len = poidparam->len;
1841 oid_par.dbg = 0;
1842 BytesWritten = 0;
1843 BytesNeeded = 0;
1844 if (bset) {
1845 oid_par.bytes_rw = &BytesRead;
1846 oid_par.bytes_needed = &BytesNeeded;
1847 oid_par.type_of_oid = SET_OID;
1848 } else {
1849 oid_par.bytes_rw = &BytesWritten;
1850 oid_par.bytes_needed = &BytesNeeded;
1851 oid_par.type_of_oid = QUERY_OID;
1852 }
1853 status = phandler->handler(&oid_par);
1854 /* todo:check status, BytesNeeded, etc. */
1855 } else {
1856 printk(KERN_INFO "r8712u: r871x_mp_ioctl_hdl(): err!,"
1857 " subcode=%d, oid=%d, handler=%p\n",
1858 poidparam->subcode, phandler->oid, phandler->handler);
1859 ret = -EFAULT;
1860 goto _r871x_mp_ioctl_hdl_exit;
1861 }
1862 if (bset == 0x00) { /* query info */
1863 if (copy_to_user(p->pointer, pparmbuf, len))
1864 ret = -EFAULT;
1865 }
1866 if (status) {
1867 ret = -EFAULT;
1868 goto _r871x_mp_ioctl_hdl_exit;
1869 }
1870 _r871x_mp_ioctl_hdl_exit:
1871 if (pparmbuf != NULL)
1872 kfree(pparmbuf);
1873 return ret;
1874 }
1875
1876 static int r871x_get_ap_info(struct net_device *dev,
1877 struct iw_request_info *info,
1878 union iwreq_data *wrqu, char *extra)
1879 {
1880 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1881 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1882 struct __queue *queue = &pmlmepriv->scanned_queue;
1883 struct iw_point *pdata = &wrqu->data;
1884 struct wlan_network *pnetwork = NULL;
1885 u32 cnt = 0, wpa_ielen;
1886 unsigned long irqL;
1887 struct list_head *plist, *phead;
1888 unsigned char *pbuf;
1889 u8 bssid[ETH_ALEN];
1890 char data[32];
1891
1892 if (padapter->bDriverStopped || (pdata == NULL))
1893 return -EINVAL;
1894 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1895 msleep(30);
1896 cnt++;
1897 if (cnt > 100)
1898 break;
1899 }
1900 pdata->flags = 0;
1901 if (pdata->length >= 32) {
1902 if (copy_from_user(data, pdata->pointer, 32))
1903 return -EINVAL;
1904 } else
1905 return -EINVAL;
1906 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
1907 phead = get_list_head(queue);
1908 plist = get_next(phead);
1909 while (1) {
1910 if (end_of_queue_search(phead, plist) == true)
1911 break;
1912 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1913 if (hwaddr_aton_i(data, bssid)) {
1914 printk(KERN_INFO "r8712u: Invalid BSSID '%s'.\n",
1915 (u8 *)data);
1916 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
1917 irqL);
1918 return -EINVAL;
1919 }
1920 printk(KERN_INFO "r8712u: BSSID:%pM\n", bssid);
1921 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
1922 /* BSSID match, then check if supporting wpa/wpa2 */
1923 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
1924 &wpa_ielen, pnetwork->network.IELength-12);
1925 if (pbuf && (wpa_ielen > 0)) {
1926 pdata->flags = 1;
1927 break;
1928 }
1929 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
1930 &wpa_ielen, pnetwork->network.IELength-12);
1931 if (pbuf && (wpa_ielen > 0)) {
1932 pdata->flags = 2;
1933 break;
1934 }
1935 }
1936 plist = get_next(plist);
1937 }
1938 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
1939 if (pdata->length >= 34) {
1940 if (copy_to_user((u8 __user *)pdata->pointer + 32,
1941 (u8 *)&pdata->flags, 1))
1942 return -EINVAL;
1943 }
1944 return 0;
1945 }
1946
1947 static int r871x_set_pid(struct net_device *dev,
1948 struct iw_request_info *info,
1949 union iwreq_data *wrqu, char *extra)
1950 {
1951 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1952 struct iw_point *pdata = &wrqu->data;
1953
1954 if ((padapter->bDriverStopped) || (pdata == NULL))
1955 return -EINVAL;
1956 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
1957 return -EINVAL;
1958 return 0;
1959 }
1960
1961 static int r871x_wps_start(struct net_device *dev,
1962 struct iw_request_info *info,
1963 union iwreq_data *wrqu, char *extra)
1964 {
1965 struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
1966 struct iw_point *pdata = &wrqu->data;
1967 u32 u32wps_start = 0;
1968 unsigned int uintRet = 0;
1969
1970 uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
1971 if ((padapter->bDriverStopped) || (pdata == NULL))
1972 return -EINVAL;
1973 if (u32wps_start == 0)
1974 u32wps_start = *extra;
1975 if (u32wps_start == 1) /* WPS Start */
1976 padapter->ledpriv.LedControlHandler(padapter,
1977 LED_CTL_START_WPS);
1978 else if (u32wps_start == 2) /* WPS Stop because of wps success */
1979 padapter->ledpriv.LedControlHandler(padapter,
1980 LED_CTL_STOP_WPS);
1981 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
1982 padapter->ledpriv.LedControlHandler(padapter,
1983 LED_CTL_STOP_WPS_FAIL);
1984 return 0;
1985 }
1986
1987 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1988 {
1989 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
1990
1991 switch (name) {
1992 case IEEE_PARAM_WPA_ENABLED:
1993 padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
1994 switch ((value)&0xff) {
1995 case 1: /* WPA */
1996 padapter->securitypriv.ndisauthtype =
1997 Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
1998 padapter->securitypriv.ndisencryptstatus =
1999 Ndis802_11Encryption2Enabled;
2000 break;
2001 case 2: /* WPA2 */
2002 padapter->securitypriv.ndisauthtype =
2003 Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
2004 padapter->securitypriv.ndisencryptstatus =
2005 Ndis802_11Encryption3Enabled;
2006 break;
2007 }
2008 break;
2009 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2010 break;
2011 case IEEE_PARAM_DROP_UNENCRYPTED:
2012 /* HACK:
2013 *
2014 * wpa_supplicant calls set_wpa_enabled when the driver
2015 * is loaded and unloaded, regardless of if WPA is being
2016 * used. No other calls are made which can be used to
2017 * determine if encryption will be used or not prior to
2018 * association being expected. If encryption is not being
2019 * used, drop_unencrypted is set to false, else true -- we
2020 * can use this to determine if the CAP_PRIVACY_ON bit should
2021 * be set.
2022 */
2023 break;
2024 case IEEE_PARAM_PRIVACY_INVOKED:
2025 break;
2026 case IEEE_PARAM_AUTH_ALGS:
2027 return wpa_set_auth_algs(dev, value);
2028 break;
2029 case IEEE_PARAM_IEEE_802_1X:
2030 break;
2031 case IEEE_PARAM_WPAX_SELECT:
2032 /* added for WPA2 mixed mode */
2033 break;
2034 default:
2035 return -EOPNOTSUPP;
2036 }
2037 return 0;
2038 }
2039
2040 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2041 {
2042 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2043
2044 switch (command) {
2045 case IEEE_MLME_STA_DEAUTH:
2046 if (!r8712_set_802_11_disassociate(padapter))
2047 return -1;
2048 break;
2049 case IEEE_MLME_STA_DISASSOC:
2050 if (!r8712_set_802_11_disassociate(padapter))
2051 return -1;
2052 break;
2053 default:
2054 return -EOPNOTSUPP;
2055 }
2056 return 0;
2057 }
2058
2059 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2060 {
2061 struct ieee_param *param;
2062 int ret = 0;
2063 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2064
2065 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2066 return -EINVAL;
2067 param = (struct ieee_param *)_malloc(p->length);
2068 if (param == NULL)
2069 return -ENOMEM;
2070 if (copy_from_user(param, p->pointer, p->length))
2071 kfree((u8 *)param);
2072 return -EFAULT;
2073 switch (param->cmd) {
2074 case IEEE_CMD_SET_WPA_PARAM:
2075 ret = wpa_set_param(dev, param->u.wpa_param.name,
2076 param->u.wpa_param.value);
2077 break;
2078 case IEEE_CMD_SET_WPA_IE:
2079 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2080 (u16)param->u.wpa_ie.len);
2081 break;
2082 case IEEE_CMD_SET_ENCRYPTION:
2083 ret = wpa_set_encryption(dev, param, p->length);
2084 break;
2085 case IEEE_CMD_MLME:
2086 ret = wpa_mlme(dev, param->u.mlme.command,
2087 param->u.mlme.reason_code);
2088 break;
2089 default:
2090 ret = -EOPNOTSUPP;
2091 break;
2092 }
2093 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2094 ret = -EFAULT;
2095 kfree((u8 *)param);
2096 return ret;
2097 }
2098
2099 /* based on "driver_ipw" and for hostapd */
2100 int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2101 {
2102 struct iwreq *wrq = (struct iwreq *)rq;
2103
2104 switch (cmd) {
2105 case RTL_IOCTL_WPA_SUPPLICANT:
2106 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2107 default:
2108 return -EOPNOTSUPP;
2109 }
2110 return 0;
2111 }
2112
2113 static iw_handler r8711_handlers[] = {
2114 NULL, /* SIOCSIWCOMMIT */
2115 r8711_wx_get_name, /* SIOCGIWNAME */
2116 dummy, /* SIOCSIWNWID */
2117 dummy, /* SIOCGIWNWID */
2118 r8711_wx_set_freq, /* SIOCSIWFREQ */
2119 r8711_wx_get_freq, /* SIOCGIWFREQ */
2120 r8711_wx_set_mode, /* SIOCSIWMODE */
2121 r8711_wx_get_mode, /* SIOCGIWMODE */
2122 dummy, /* SIOCSIWSENS */
2123 r8711_wx_get_sens, /* SIOCGIWSENS */
2124 NULL, /* SIOCSIWRANGE */
2125 r8711_wx_get_range, /* SIOCGIWRANGE */
2126 r871x_wx_set_priv, /* SIOCSIWPRIV */
2127 NULL, /* SIOCGIWPRIV */
2128 NULL, /* SIOCSIWSTATS */
2129 NULL, /* SIOCGIWSTATS */
2130 dummy, /* SIOCSIWSPY */
2131 dummy, /* SIOCGIWSPY */
2132 NULL, /* SIOCGIWTHRSPY */
2133 NULL, /* SIOCWIWTHRSPY */
2134 r8711_wx_set_wap, /* SIOCSIWAP */
2135 r8711_wx_get_wap, /* SIOCGIWAP */
2136 r871x_wx_set_mlme, /* request MLME operation;
2137 * uses struct iw_mlme */
2138 dummy, /* SIOCGIWAPLIST -- deprecated */
2139 r8711_wx_set_scan, /* SIOCSIWSCAN */
2140 r8711_wx_get_scan, /* SIOCGIWSCAN */
2141 r8711_wx_set_essid, /* SIOCSIWESSID */
2142 r8711_wx_get_essid, /* SIOCGIWESSID */
2143 dummy, /* SIOCSIWNICKN */
2144 r871x_wx_get_nick, /* SIOCGIWNICKN */
2145 NULL, /* -- hole -- */
2146 NULL, /* -- hole -- */
2147 r8711_wx_set_rate, /* SIOCSIWRATE */
2148 r8711_wx_get_rate, /* SIOCGIWRATE */
2149 dummy, /* SIOCSIWRTS */
2150 r8711_wx_get_rts, /* SIOCGIWRTS */
2151 r8711_wx_set_frag, /* SIOCSIWFRAG */
2152 r8711_wx_get_frag, /* SIOCGIWFRAG */
2153 dummy, /* SIOCSIWTXPOW */
2154 dummy, /* SIOCGIWTXPOW */
2155 dummy, /* SIOCSIWRETRY */
2156 r8711_wx_get_retry, /* SIOCGIWRETRY */
2157 r8711_wx_set_enc, /* SIOCSIWENCODE */
2158 r8711_wx_get_enc, /* SIOCGIWENCODE */
2159 dummy, /* SIOCSIWPOWER */
2160 r8711_wx_get_power, /* SIOCGIWPOWER */
2161 NULL, /*---hole---*/
2162 NULL, /*---hole---*/
2163 r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
2164 NULL, /* SIOCGIWGENIE */
2165 r871x_wx_set_auth, /* SIOCSIWAUTH */
2166 NULL, /* SIOCGIWAUTH */
2167 r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
2168 NULL, /* SIOCGIWENCODEEXT */
2169 r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
2170 NULL, /*---hole---*/
2171 };
2172
2173 static const struct iw_priv_args r8711_private_args[] = {
2174 {
2175 SIOCIWFIRSTPRIV + 0x0,
2176 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2177 },
2178 {
2179 SIOCIWFIRSTPRIV + 0x1,
2180 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2181 },
2182 {
2183 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2184 },
2185 {
2186 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2187 },
2188 {
2189 SIOCIWFIRSTPRIV + 0x4,
2190 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2191 },
2192 {
2193 SIOCIWFIRSTPRIV + 0x5,
2194 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2195 },
2196 {
2197 SIOCIWFIRSTPRIV + 0x6,
2198 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2199 }
2200 };
2201
2202 static iw_handler r8711_private_handler[] = {
2203 r8711_wx_read32,
2204 r8711_wx_write32,
2205 r8711_drvext_hdl,
2206 r871x_mp_ioctl_hdl,
2207 r871x_get_ap_info, /*for MM DTV platform*/
2208 r871x_set_pid,
2209 r871x_wps_start,
2210 };
2211
2212 static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2213 {
2214 struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
2215 struct iw_statistics *piwstats = &padapter->iwstats;
2216 int tmp_level = 0;
2217 int tmp_qual = 0;
2218 int tmp_noise = 0;
2219
2220 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2221 piwstats->qual.qual = 0;
2222 piwstats->qual.level = 0;
2223 piwstats->qual.noise = 0;
2224 } else {
2225 /* show percentage, we need transfer dbm to orignal value. */
2226 tmp_level = padapter->recvpriv.fw_rssi;
2227 tmp_qual = padapter->recvpriv.signal;
2228 tmp_noise = padapter->recvpriv.noise;
2229 piwstats->qual.level = tmp_level;
2230 piwstats->qual.qual = tmp_qual;
2231 piwstats->qual.noise = tmp_noise;
2232 }
2233 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2234 return &padapter->iwstats;
2235 }
2236
2237 struct iw_handler_def r871x_handlers_def = {
2238 .standard = r8711_handlers,
2239 .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler),
2240 .private = r8711_private_handler,
2241 .private_args = (struct iw_priv_args *)r8711_private_args,
2242 .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
2243 .num_private_args = sizeof(r8711_private_args) /
2244 sizeof(struct iw_priv_args),
2245 .get_wireless_stats = r871x_get_wireless_stats,
2246 };
This page took 0.089119 seconds and 5 git commands to generate.