1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
15 #define _IOCTL_LINUX_C_
17 #include <linux/ieee80211.h>
19 #include <osdep_service.h>
20 #include <drv_types.h>
21 #include <wlan_bssdef.h>
22 #include <rtw_debug.h>
25 #include <rtw_mlme_ext.h>
26 #include <rtw_ioctl.h>
27 #include <rtw_ioctl_set.h>
28 #include <rtl8188e_hal.h>
31 #include <linux/vmalloc.h>
32 #include <linux/etherdevice.h>
34 #include "osdep_intf.h"
36 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
38 #define SCAN_ITEM_SIZE 768
39 #define MAX_CUSTOM_LEN 64
43 #define WEXT_CSCAN_AMOUNT 9
44 #define WEXT_CSCAN_BUF_LEN 360
45 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
46 #define WEXT_CSCAN_HEADER_SIZE 12
47 #define WEXT_CSCAN_SSID_SECTION 'S'
48 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
49 #define WEXT_CSCAN_NPROBE_SECTION 'N'
50 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
51 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
52 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
53 #define WEXT_CSCAN_TYPE_SECTION 'T'
55 static u32 rtw_rates
[] = {1000000, 2000000, 5500000, 11000000,
56 6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
59 static const char * const iw_operation_mode
[] = {
60 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater",
61 "Secondary", "Monitor"
64 void indicate_wx_scan_complete_event(struct adapter
*padapter
)
66 union iwreq_data wrqu
;
68 memset(&wrqu
, 0, sizeof(union iwreq_data
));
69 wireless_send_event(padapter
->pnetdev
, SIOCGIWSCAN
, &wrqu
, NULL
);
72 void rtw_indicate_wx_assoc_event(struct adapter
*padapter
)
74 union iwreq_data wrqu
;
75 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
77 memset(&wrqu
, 0, sizeof(union iwreq_data
));
79 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
81 memcpy(wrqu
.ap_addr
.sa_data
, pmlmepriv
->cur_network
.network
.MacAddress
, ETH_ALEN
);
83 DBG_88E_LEVEL(_drv_always_
, "assoc success\n");
84 wireless_send_event(padapter
->pnetdev
, SIOCGIWAP
, &wrqu
, NULL
);
87 void rtw_indicate_wx_disassoc_event(struct adapter
*padapter
)
89 union iwreq_data wrqu
;
91 memset(&wrqu
, 0, sizeof(union iwreq_data
));
93 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
94 eth_zero_addr(wrqu
.ap_addr
.sa_data
);
96 DBG_88E_LEVEL(_drv_always_
, "indicate disassoc\n");
97 wireless_send_event(padapter
->pnetdev
, SIOCGIWAP
, &wrqu
, NULL
);
100 static char *translate_scan(struct adapter
*padapter
,
101 struct iw_request_info
*info
,
102 struct wlan_network
*pnetwork
,
103 char *start
, char *stop
)
105 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
110 char custom
[MAX_CUSTOM_LEN
];
112 u16 max_rate
= 0, rate
, ht_cap
= false;
114 u8 bw_40MHz
= 0, short_GI
= 0;
120 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
122 memcpy(iwe
.u
.ap_addr
.sa_data
, pnetwork
->network
.MacAddress
, ETH_ALEN
);
123 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_ADDR_LEN
);
126 iwe
.cmd
= SIOCGIWESSID
;
127 iwe
.u
.data
.flags
= 1;
128 iwe
.u
.data
.length
= min_t(u16
, pnetwork
->network
.Ssid
.SsidLength
, 32);
129 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, pnetwork
->network
.Ssid
.Ssid
);
131 /* parsing HT_CAP_IE */
132 p
= rtw_get_ie(&pnetwork
->network
.IEs
[12], _HT_CAPABILITY_IE_
, &ht_ielen
, pnetwork
->network
.IELength
-12);
134 if (p
&& ht_ielen
> 0) {
135 struct ieee80211_ht_cap
*pht_capie
;
138 pht_capie
= (struct ieee80211_ht_cap
*)(p
+ 2);
139 memcpy(&mcs_rate
, pht_capie
->mcs
.rx_mask
, 2);
140 bw_40MHz
= !!(le16_to_cpu(pht_capie
->cap_info
) &
141 IEEE80211_HT_CAP_SUP_WIDTH
);
142 short_GI
= !!(le16_to_cpu(pht_capie
->cap_info
) &
143 (IEEE80211_HT_CAP_SGI_20
|
144 IEEE80211_HT_CAP_SGI_40
));
147 /* Add the protocol name */
148 iwe
.cmd
= SIOCGIWNAME
;
149 if ((rtw_is_cckratesonly_included((u8
*)&pnetwork
->network
.SupportedRates
))) {
151 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11bn");
153 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11b");
154 } else if ((rtw_is_cckrates_included((u8
*)&pnetwork
->network
.SupportedRates
))) {
156 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11bgn");
158 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11bg");
160 if (pnetwork
->network
.Configuration
.DSConfig
> 14) {
162 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11an");
164 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11a");
167 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11gn");
169 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11g");
173 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_CHAR_LEN
);
176 iwe
.cmd
= SIOCGIWMODE
;
177 memcpy(&le_tmp
, rtw_get_capability_from_ie(pnetwork
->network
.IEs
), 2);
179 cap
= le16_to_cpu(le_tmp
);
181 if (!WLAN_CAPABILITY_IS_STA_BSS(cap
)) {
182 if (cap
& WLAN_CAPABILITY_ESS
)
183 iwe
.u
.mode
= IW_MODE_MASTER
;
185 iwe
.u
.mode
= IW_MODE_ADHOC
;
187 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_UINT_LEN
);
190 if (pnetwork
->network
.Configuration
.DSConfig
< 1)
191 pnetwork
->network
.Configuration
.DSConfig
= 1;
193 /* Add frequency/channel */
194 iwe
.cmd
= SIOCGIWFREQ
;
195 iwe
.u
.freq
.m
= rtw_ch2freq(pnetwork
->network
.Configuration
.DSConfig
) * 100000;
197 iwe
.u
.freq
.i
= pnetwork
->network
.Configuration
.DSConfig
;
198 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_FREQ_LEN
);
200 /* Add encryption capability */
201 iwe
.cmd
= SIOCGIWENCODE
;
202 if (cap
& WLAN_CAPABILITY_PRIVACY
)
203 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
205 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
206 iwe
.u
.data
.length
= 0;
207 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, pnetwork
->network
.Ssid
.Ssid
);
209 /*Add basic and extended rates */
212 p
+= snprintf(p
, MAX_CUSTOM_LEN
- (p
- custom
), " Rates (Mb/s): ");
213 while (pnetwork
->network
.SupportedRates
[i
] != 0) {
214 rate
= pnetwork
->network
.SupportedRates
[i
]&0x7F;
217 p
+= snprintf(p
, MAX_CUSTOM_LEN
- (p
- custom
),
218 "%d%s ", rate
>> 1, (rate
& 1) ? ".5" : "");
223 if (mcs_rate
&0x8000)/* MCS15 */
224 max_rate
= (bw_40MHz
) ? ((short_GI
) ? 300 : 270) : ((short_GI
) ? 144 : 130);
225 else if (mcs_rate
&0x0080)/* MCS7 */
227 else/* default MCS7 */
228 max_rate
= (bw_40MHz
) ? ((short_GI
) ? 150 : 135) : ((short_GI
) ? 72 : 65);
230 max_rate
= max_rate
*2;/* Mbps/2; */
233 iwe
.cmd
= SIOCGIWRATE
;
234 iwe
.u
.bitrate
.fixed
= 0;
235 iwe
.u
.bitrate
.disabled
= 0;
236 iwe
.u
.bitrate
.value
= max_rate
* 500000;
237 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_PARAM_LEN
);
239 /* parsing WPA/WPA2 IE */
241 u8 buf
[MAX_WPA_IE_LEN
];
242 u8 wpa_ie
[255], rsn_ie
[255];
243 u16 wpa_len
= 0, rsn_len
= 0;
246 rtw_get_sec_ie(pnetwork
->network
.IEs
, pnetwork
->network
.IELength
, rsn_ie
, &rsn_len
, wpa_ie
, &wpa_len
);
247 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_scan: ssid =%s\n", pnetwork
->network
.Ssid
.Ssid
));
248 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len
, rsn_len
));
252 memset(buf
, 0, MAX_WPA_IE_LEN
);
253 p
+= sprintf(p
, "wpa_ie=");
254 for (i
= 0; i
< wpa_len
; i
++)
255 p
+= sprintf(p
, "%02x", wpa_ie
[i
]);
257 memset(&iwe
, 0, sizeof(iwe
));
258 iwe
.cmd
= IWEVCUSTOM
;
259 iwe
.u
.data
.length
= strlen(buf
);
260 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, buf
);
262 memset(&iwe
, 0, sizeof(iwe
));
264 iwe
.u
.data
.length
= wpa_len
;
265 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, wpa_ie
);
269 memset(buf
, 0, MAX_WPA_IE_LEN
);
270 p
+= sprintf(p
, "rsn_ie=");
271 for (i
= 0; i
< rsn_len
; i
++)
272 p
+= sprintf(p
, "%02x", rsn_ie
[i
]);
273 memset(&iwe
, 0, sizeof(iwe
));
274 iwe
.cmd
= IWEVCUSTOM
;
275 iwe
.u
.data
.length
= strlen(buf
);
276 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, buf
);
278 memset(&iwe
, 0, sizeof(iwe
));
280 iwe
.u
.data
.length
= rsn_len
;
281 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, rsn_ie
);
285 {/* parsing WPS IE */
286 uint cnt
= 0, total_ielen
;
287 u8
*wpsie_ptr
= NULL
;
289 u8
*ie_ptr
= pnetwork
->network
.IEs
+ _FIXED_IE_LENGTH_
;
291 total_ielen
= pnetwork
->network
.IELength
- _FIXED_IE_LENGTH_
;
293 while (cnt
< total_ielen
) {
294 if (rtw_is_wps_ie(&ie_ptr
[cnt
], &wps_ielen
) && (wps_ielen
> 2)) {
295 wpsie_ptr
= &ie_ptr
[cnt
];
297 iwe
.u
.data
.length
= (u16
)wps_ielen
;
298 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, wpsie_ptr
);
300 cnt
+= ie_ptr
[cnt
+1]+2; /* goto next */
304 /* Add quality statistics */
306 iwe
.u
.qual
.updated
= IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID
;
308 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true &&
309 is_same_network(&pmlmepriv
->cur_network
.network
, &pnetwork
->network
)) {
310 ss
= padapter
->recvpriv
.signal_strength
;
311 sq
= padapter
->recvpriv
.signal_qual
;
313 ss
= pnetwork
->network
.PhyInfo
.SignalStrength
;
314 sq
= pnetwork
->network
.PhyInfo
.SignalQuality
;
317 iwe
.u
.qual
.level
= (u8
)ss
;
318 iwe
.u
.qual
.qual
= (u8
)sq
; /* signal quality */
319 iwe
.u
.qual
.noise
= 0; /* noise level */
320 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_QUAL_LEN
);
324 static int wpa_set_auth_algs(struct net_device
*dev
, u32 value
)
326 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
329 if ((value
& AUTH_ALG_SHARED_KEY
) && (value
& AUTH_ALG_OPEN_SYSTEM
)) {
330 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value
);
331 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
332 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeAutoSwitch
;
333 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Auto
;
334 } else if (value
& AUTH_ALG_SHARED_KEY
) {
335 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value
);
336 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
338 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeShared
;
339 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Shared
;
340 } else if (value
& AUTH_ALG_OPEN_SYSTEM
) {
341 DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
342 if (padapter
->securitypriv
.ndisauthtype
< Ndis802_11AuthModeWPAPSK
) {
343 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeOpen
;
344 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
346 } else if (value
& AUTH_ALG_LEAP
) {
347 DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
349 DBG_88E("wpa_set_auth_algs, error!\n");
355 static int wpa_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
358 u32 wep_key_idx
, wep_key_len
, wep_total_len
;
359 struct ndis_802_11_wep
*pwep
= NULL
;
360 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
361 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
362 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
364 param
->u
.crypt
.err
= 0;
365 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
367 if (param_len
< (u32
)((u8
*)param
->u
.crypt
.key
- (u8
*)param
) + param
->u
.crypt
.key_len
) {
372 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
373 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
374 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff) {
375 if (param
->u
.crypt
.idx
>= WEP_KEYS
) {
384 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
385 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, ("wpa_set_encryption, crypt.alg = WEP\n"));
386 DBG_88E("wpa_set_encryption, crypt.alg = WEP\n");
388 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
389 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
390 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
392 wep_key_idx
= param
->u
.crypt
.idx
;
393 wep_key_len
= param
->u
.crypt
.key_len
;
395 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("(1)wep_key_idx =%d\n", wep_key_idx
));
396 DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx
);
398 if (wep_key_idx
> WEP_KEYS
)
401 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("(2)wep_key_idx =%d\n", wep_key_idx
));
403 if (wep_key_len
> 0) {
404 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
405 wep_total_len
= wep_key_len
+ offsetof(struct ndis_802_11_wep
, KeyMaterial
);
406 pwep
= (struct ndis_802_11_wep
*)rtw_malloc(wep_total_len
);
408 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, (" wpa_set_encryption: pwep allocate fail !!!\n"));
411 memset(pwep
, 0, wep_total_len
);
412 pwep
->KeyLength
= wep_key_len
;
413 pwep
->Length
= wep_total_len
;
414 if (wep_key_len
== 13) {
415 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
416 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP104_
;
422 pwep
->KeyIndex
= wep_key_idx
;
423 pwep
->KeyIndex
|= 0x80000000;
424 memcpy(pwep
->KeyMaterial
, param
->u
.crypt
.key
, pwep
->KeyLength
);
425 if (param
->u
.crypt
.set_tx
) {
426 DBG_88E("wep, set_tx = 1\n");
427 if (rtw_set_802_11_add_wep(padapter
, pwep
) == (u8
)_FAIL
)
430 DBG_88E("wep, set_tx = 0\n");
431 if (wep_key_idx
>= WEP_KEYS
) {
435 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
436 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
437 rtw_set_key(padapter
, psecuritypriv
, wep_key_idx
, 0);
442 if (padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) { /* 802_1x */
443 struct sta_info
*psta
, *pbcmc_sta
;
444 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
446 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) { /* sta mode */
447 psta
= rtw_get_stainfo(pstapriv
, get_bssid(pmlmepriv
));
451 if (strcmp(param
->u
.crypt
.alg
, "none") != 0)
452 psta
->ieee8021x_blocked
= false;
454 if ((padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption2Enabled
) ||
455 (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption3Enabled
))
456 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
458 if (param
->u
.crypt
.set_tx
== 1) { /* pairwise key */
459 memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
461 if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) { /* set mic key */
462 memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
463 memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
464 padapter
->securitypriv
.busetkipkey
= false;
467 DBG_88E(" ~~~~set sta key:unicastkey\n");
469 rtw_setstakey_cmd(padapter
, (unsigned char *)psta
, true);
470 } else { /* group key */
471 memcpy(padapter
->securitypriv
.dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
, param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16 ));
472 memcpy(padapter
->securitypriv
.dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
473 memcpy(padapter
->securitypriv
.dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
474 padapter
->securitypriv
.binstallGrpkey
= true;
475 DBG_88E(" ~~~~set sta key:groupkey\n");
477 padapter
->securitypriv
.dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
479 rtw_set_key(padapter
, &padapter
->securitypriv
, param
->u
.crypt
.idx
, 1);
482 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
486 /* Jeff: don't disable ieee8021x_blocked while clearing key */
487 if (strcmp(param
->u
.crypt
.alg
, "none") != 0)
488 pbcmc_sta
->ieee8021x_blocked
= false;
490 if ((padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption2Enabled
) ||
491 (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption3Enabled
))
492 pbcmc_sta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
503 static int rtw_set_wpa_ie(struct adapter
*padapter
, char *pie
, unsigned short ielen
)
506 int group_cipher
= 0, pairwise_cipher
= 0;
509 if ((ielen
> MAX_WPA_IE_LEN
) || (!pie
)) {
510 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
518 buf
= kmemdup(pie
, ielen
, GFP_KERNEL
);
528 DBG_88E("\n wpa_ie(length:%d):\n", ielen
);
529 for (i
= 0; i
< ielen
; i
+= 8)
530 DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf
[i
], buf
[i
+1], buf
[i
+2], buf
[i
+3], buf
[i
+4], buf
[i
+5], buf
[i
+6], buf
[i
+7]);
533 if (ielen
< RSN_HEADER_LEN
) {
534 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, ("Ie len too short %d\n", ielen
));
539 if (rtw_parse_wpa_ie(buf
, ielen
, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
540 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
541 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPAPSK
;
542 memcpy(padapter
->securitypriv
.supplicant_ie
, &buf
[0], ielen
);
545 if (rtw_parse_wpa2_ie(buf
, ielen
, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
546 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
547 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPA2PSK
;
548 memcpy(padapter
->securitypriv
.supplicant_ie
, &buf
[0], ielen
);
551 switch (group_cipher
) {
552 case WPA_CIPHER_NONE
:
553 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
554 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
556 case WPA_CIPHER_WEP40
:
557 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
558 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
560 case WPA_CIPHER_TKIP
:
561 padapter
->securitypriv
.dot118021XGrpPrivacy
= _TKIP_
;
562 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
564 case WPA_CIPHER_CCMP
:
565 padapter
->securitypriv
.dot118021XGrpPrivacy
= _AES_
;
566 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
568 case WPA_CIPHER_WEP104
:
569 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP104_
;
570 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
574 switch (pairwise_cipher
) {
575 case WPA_CIPHER_NONE
:
576 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
577 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
579 case WPA_CIPHER_WEP40
:
580 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
581 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
583 case WPA_CIPHER_TKIP
:
584 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _TKIP_
;
585 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
587 case WPA_CIPHER_CCMP
:
588 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _AES_
;
589 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
591 case WPA_CIPHER_WEP104
:
592 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
593 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
597 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
600 u8 eid
, wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
602 while (cnt
< ielen
) {
604 if ((eid
== _VENDOR_SPECIFIC_IE_
) && (!memcmp(&buf
[cnt
+2], wps_oui
, 4))) {
605 DBG_88E("SET WPS_IE\n");
607 padapter
->securitypriv
.wps_ie_len
= min(buf
[cnt
+ 1] + 2, MAX_WPA_IE_LEN
<< 2);
609 memcpy(padapter
->securitypriv
.wps_ie
, &buf
[cnt
], padapter
->securitypriv
.wps_ie_len
);
611 set_fwstate(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
615 cnt
+= buf
[cnt
+1]+2; /* goto next */
621 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
622 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
623 pairwise_cipher
, padapter
->securitypriv
.ndisencryptstatus
, padapter
->securitypriv
.ndisauthtype
));
629 typedef unsigned char NDIS_802_11_RATES_EX
[NDIS_802_11_LENGTH_RATES_EX
];
631 static int rtw_wx_get_name(struct net_device
*dev
,
632 struct iw_request_info
*info
,
633 union iwreq_data
*wrqu
, char *extra
)
635 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
639 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
640 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
641 NDIS_802_11_RATES_EX
*prates
= NULL
;
643 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("cmd_code =%x\n", info
->cmd
));
645 if (check_fwstate(pmlmepriv
, _FW_LINKED
|WIFI_ADHOC_MASTER_STATE
) == true) {
646 /* parsing HT_CAP_IE */
647 p
= rtw_get_ie(&pcur_bss
->IEs
[12], _HT_CAPABILITY_IE_
, &ht_ielen
, pcur_bss
->IELength
-12);
648 if (p
&& ht_ielen
> 0)
651 prates
= &pcur_bss
->SupportedRates
;
653 if (rtw_is_cckratesonly_included((u8
*)prates
) == true) {
655 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11bn");
657 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11b");
658 } else if ((rtw_is_cckrates_included((u8
*)prates
)) == true) {
660 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11bgn");
662 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11bg");
664 if (pcur_bss
->Configuration
.DSConfig
> 14) {
666 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11an");
668 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11a");
671 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11gn");
673 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11g");
677 snprintf(wrqu
->name
, IFNAMSIZ
, "unassociated");
682 static int rtw_wx_set_freq(struct net_device
*dev
,
683 struct iw_request_info
*info
,
684 union iwreq_data
*wrqu
, char *extra
)
686 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+rtw_wx_set_freq\n"));
690 static int rtw_wx_get_freq(struct net_device
*dev
,
691 struct iw_request_info
*info
,
692 union iwreq_data
*wrqu
, char *extra
)
694 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
695 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
696 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
698 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
699 /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
700 wrqu
->freq
.m
= rtw_ch2freq(pcur_bss
->Configuration
.DSConfig
) * 100000;
702 wrqu
->freq
.i
= pcur_bss
->Configuration
.DSConfig
;
704 wrqu
->freq
.m
= rtw_ch2freq(padapter
->mlmeextpriv
.cur_channel
) * 100000;
706 wrqu
->freq
.i
= padapter
->mlmeextpriv
.cur_channel
;
712 static int rtw_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
713 union iwreq_data
*wrqu
, char *b
)
715 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
716 enum ndis_802_11_network_infra networkType
;
719 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
724 if (!padapter
->hw_init_completed
) {
729 switch (wrqu
->mode
) {
731 networkType
= Ndis802_11AutoUnknown
;
732 DBG_88E("set_mode = IW_MODE_AUTO\n");
735 networkType
= Ndis802_11IBSS
;
736 DBG_88E("set_mode = IW_MODE_ADHOC\n");
739 networkType
= Ndis802_11APMode
;
740 DBG_88E("set_mode = IW_MODE_MASTER\n");
743 networkType
= Ndis802_11Infrastructure
;
744 DBG_88E("set_mode = IW_MODE_INFRA\n");
748 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, ("\n Mode: %s is not supported\n", iw_operation_mode
[wrqu
->mode
]));
751 if (rtw_set_802_11_infrastructure_mode(padapter
, networkType
) == false) {
755 rtw_setopmode_cmd(padapter
, networkType
);
760 static int rtw_wx_get_mode(struct net_device
*dev
, struct iw_request_info
*a
,
761 union iwreq_data
*wrqu
, char *b
)
763 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
764 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
766 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, (" rtw_wx_get_mode\n"));
768 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
769 wrqu
->mode
= IW_MODE_INFRA
;
770 else if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
771 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)))
772 wrqu
->mode
= IW_MODE_ADHOC
;
773 else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
774 wrqu
->mode
= IW_MODE_MASTER
;
776 wrqu
->mode
= IW_MODE_AUTO
;
781 static int rtw_wx_set_pmkid(struct net_device
*dev
,
782 struct iw_request_info
*a
,
783 union iwreq_data
*wrqu
, char *extra
)
785 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
786 u8 j
, blInserted
= false;
788 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
789 struct iw_pmksa
*pPMK
= (struct iw_pmksa
*)extra
;
790 u8 strZeroMacAddress
[ETH_ALEN
] = {0x00};
791 u8 strIssueBssid
[ETH_ALEN
] = {0x00};
793 memcpy(strIssueBssid
, pPMK
->bssid
.sa_data
, ETH_ALEN
);
794 if (pPMK
->cmd
== IW_PMKSA_ADD
) {
795 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
796 if (!memcmp(strIssueBssid
, strZeroMacAddress
, ETH_ALEN
))
802 /* overwrite PMKID */
803 for (j
= 0; j
< NUM_PMKID_CACHE
; j
++) {
804 if (!memcmp(psecuritypriv
->PMKIDList
[j
].Bssid
, strIssueBssid
, ETH_ALEN
)) {
805 /* BSSID is matched, the same AP => rewrite with new PMKID. */
806 DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
807 memcpy(psecuritypriv
->PMKIDList
[j
].PMKID
, pPMK
->pmkid
, IW_PMKID_LEN
);
808 psecuritypriv
->PMKIDList
[j
].bUsed
= true;
809 psecuritypriv
->PMKIDIndex
= j
+1;
816 /* Find a new entry */
817 DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
818 psecuritypriv
->PMKIDIndex
);
820 memcpy(psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].Bssid
, strIssueBssid
, ETH_ALEN
);
821 memcpy(psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].PMKID
, pPMK
->pmkid
, IW_PMKID_LEN
);
823 psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].bUsed
= true;
824 psecuritypriv
->PMKIDIndex
++;
825 if (psecuritypriv
->PMKIDIndex
== 16)
826 psecuritypriv
->PMKIDIndex
= 0;
828 } else if (pPMK
->cmd
== IW_PMKSA_REMOVE
) {
829 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
831 for (j
= 0; j
< NUM_PMKID_CACHE
; j
++) {
832 if (!memcmp(psecuritypriv
->PMKIDList
[j
].Bssid
, strIssueBssid
, ETH_ALEN
)) {
833 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
834 eth_zero_addr(psecuritypriv
->PMKIDList
[j
].Bssid
);
835 psecuritypriv
->PMKIDList
[j
].bUsed
= false;
839 } else if (pPMK
->cmd
== IW_PMKSA_FLUSH
) {
840 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
841 memset(&psecuritypriv
->PMKIDList
[0], 0x00, sizeof(struct rt_pmkid_list
) * NUM_PMKID_CACHE
);
842 psecuritypriv
->PMKIDIndex
= 0;
848 static int rtw_wx_get_sens(struct net_device
*dev
,
849 struct iw_request_info
*info
,
850 union iwreq_data
*wrqu
, char *extra
)
852 wrqu
->sens
.value
= 0;
853 wrqu
->sens
.fixed
= 0; /* no auto select */
854 wrqu
->sens
.disabled
= 1;
858 static int rtw_wx_get_range(struct net_device
*dev
,
859 struct iw_request_info
*info
,
860 union iwreq_data
*wrqu
, char *extra
)
862 struct iw_range
*range
= (struct iw_range
*)extra
;
863 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
864 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
869 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_range. cmd_code =%x\n", info
->cmd
));
871 wrqu
->data
.length
= sizeof(*range
);
872 memset(range
, 0, sizeof(*range
));
874 /* Let's try to keep this struct in the same order as in
875 * linux/include/wireless.h
878 /* TODO: See what values we can set, and remove the ones we can't
879 * set, or fill them with some default data.
882 /* ~5 Mb/s real (802.11b) */
883 range
->throughput
= 5 * 1000 * 1000;
885 /* signal level threshold range */
887 /* percent values between 0 and 100. */
888 range
->max_qual
.qual
= 100;
889 range
->max_qual
.level
= 100;
890 range
->max_qual
.noise
= 100;
891 range
->max_qual
.updated
= 7; /* Updated all three */
893 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
894 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
895 range
->avg_qual
.level
= 178; /* -78 dBm */
896 range
->avg_qual
.noise
= 0;
897 range
->avg_qual
.updated
= 7; /* Updated all three */
899 range
->num_bitrates
= RATE_COUNT
;
901 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++)
902 range
->bitrate
[i
] = rtw_rates
[i
];
904 range
->min_frag
= MIN_FRAG_THRESHOLD
;
905 range
->max_frag
= MAX_FRAG_THRESHOLD
;
909 range
->we_version_compiled
= WIRELESS_EXT
;
910 range
->we_version_source
= 16;
912 for (i
= 0, val
= 0; i
< MAX_CHANNEL_NUM
; i
++) {
913 /* Include only legal frequencies for some countries */
914 if (pmlmeext
->channel_set
[i
].ChannelNum
!= 0) {
915 range
->freq
[val
].i
= pmlmeext
->channel_set
[i
].ChannelNum
;
916 range
->freq
[val
].m
= rtw_ch2freq(pmlmeext
->channel_set
[i
].ChannelNum
) * 100000;
917 range
->freq
[val
].e
= 1;
921 if (val
== IW_MAX_FREQUENCIES
)
925 range
->num_channels
= val
;
926 range
->num_frequency
= val
;
928 /* The following code will proivde the security capability to network manager. */
929 /* If the driver doesn't provide this capability to network manager, */
930 /* the WPA/WPA2 routers can't be chosen in the network manager. */
933 #define IW_SCAN_CAPA_NONE 0x00
934 #define IW_SCAN_CAPA_ESSID 0x01
935 #define IW_SCAN_CAPA_BSSID 0x02
936 #define IW_SCAN_CAPA_CHANNEL 0x04
937 #define IW_SCAN_CAPA_MODE 0x08
938 #define IW_SCAN_CAPA_RATE 0x10
939 #define IW_SCAN_CAPA_TYPE 0x20
940 #define IW_SCAN_CAPA_TIME 0x40
943 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
944 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
946 range
->scan_capa
= IW_SCAN_CAPA_ESSID
| IW_SCAN_CAPA_TYPE
|
947 IW_SCAN_CAPA_BSSID
| IW_SCAN_CAPA_CHANNEL
|
948 IW_SCAN_CAPA_MODE
| IW_SCAN_CAPA_RATE
;
953 /* s1. rtw_set_802_11_infrastructure_mode() */
954 /* s2. rtw_set_802_11_authentication_mode() */
955 /* s3. set_802_11_encryption_mode() */
956 /* s4. rtw_set_802_11_bssid() */
957 static int rtw_wx_set_wap(struct net_device
*dev
,
958 struct iw_request_info
*info
,
959 union iwreq_data
*awrq
,
963 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
964 struct sockaddr
*temp
= (struct sockaddr
*)awrq
;
965 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
966 struct list_head
*phead
;
967 u8
*dst_bssid
, *src_bssid
;
968 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
969 struct wlan_network
*pnetwork
= NULL
;
970 enum ndis_802_11_auth_mode authmode
;
972 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
977 if (!padapter
->bup
) {
982 if (temp
->sa_family
!= ARPHRD_ETHER
) {
987 authmode
= padapter
->securitypriv
.ndisauthtype
;
988 spin_lock_bh(&queue
->lock
);
989 phead
= get_list_head(queue
);
990 pmlmepriv
->pscanned
= phead
->next
;
992 while (phead
!= pmlmepriv
->pscanned
) {
993 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
995 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
997 dst_bssid
= pnetwork
->network
.MacAddress
;
999 src_bssid
= temp
->sa_data
;
1001 if ((!memcmp(dst_bssid
, src_bssid
, ETH_ALEN
))) {
1002 if (!rtw_set_802_11_infrastructure_mode(padapter
, pnetwork
->network
.InfrastructureMode
)) {
1004 spin_unlock_bh(&queue
->lock
);
1011 spin_unlock_bh(&queue
->lock
);
1013 rtw_set_802_11_authentication_mode(padapter
, authmode
);
1014 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1015 if (rtw_set_802_11_bssid(padapter
, temp
->sa_data
) == false) {
1025 static int rtw_wx_get_wap(struct net_device
*dev
,
1026 struct iw_request_info
*info
,
1027 union iwreq_data
*wrqu
, char *extra
)
1029 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1030 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1031 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
1033 wrqu
->ap_addr
.sa_family
= ARPHRD_ETHER
;
1035 eth_zero_addr(wrqu
->ap_addr
.sa_data
);
1037 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_wap\n"));
1039 if (((check_fwstate(pmlmepriv
, _FW_LINKED
)) == true) ||
1040 ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) == true) ||
1041 ((check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) == true))
1042 memcpy(wrqu
->ap_addr
.sa_data
, pcur_bss
->MacAddress
, ETH_ALEN
);
1044 eth_zero_addr(wrqu
->ap_addr
.sa_data
);
1048 static int rtw_wx_set_mlme(struct net_device
*dev
,
1049 struct iw_request_info
*info
,
1050 union iwreq_data
*wrqu
, char *extra
)
1054 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1055 struct iw_mlme
*mlme
= (struct iw_mlme
*)extra
;
1060 DBG_88E("%s\n", __func__
);
1062 reason
= mlme
->reason_code
;
1064 DBG_88E("%s, cmd =%d, reason =%d\n", __func__
, mlme
->cmd
, reason
);
1066 switch (mlme
->cmd
) {
1067 case IW_MLME_DEAUTH
:
1068 if (!rtw_set_802_11_disassociate(padapter
))
1071 case IW_MLME_DISASSOC
:
1072 if (!rtw_set_802_11_disassociate(padapter
))
1081 static int rtw_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
1082 union iwreq_data
*wrqu
, char *extra
)
1086 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1087 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1088 struct ndis_802_11_ssid ssid
[RTW_SSID_SCAN_AMOUNT
];
1090 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_set_scan\n"));
1092 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
1097 if (padapter
->bDriverStopped
) {
1098 DBG_88E("bDriverStopped =%d\n", padapter
->bDriverStopped
);
1103 if (!padapter
->bup
) {
1108 if (!padapter
->hw_init_completed
) {
1113 /* When Busy Traffic, driver do not site survey. So driver return success. */
1114 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1115 /* modify by thomas 2011-02-22. */
1116 if (pmlmepriv
->LinkDetectInfo
.bBusyTraffic
) {
1117 indicate_wx_scan_complete_event(padapter
);
1121 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
|_FW_UNDER_LINKING
)) {
1122 indicate_wx_scan_complete_event(padapter
);
1126 /* For the DMP WiFi Display project, the driver won't to scan because */
1127 /* the pmlmepriv->scan_interval is always equal to 3. */
1128 /* So, the wpa_supplicant won't find out the WPS SoftAP. */
1130 memset(ssid
, 0, sizeof(struct ndis_802_11_ssid
)*RTW_SSID_SCAN_AMOUNT
);
1132 if (wrqu
->data
.length
== sizeof(struct iw_scan_req
)) {
1133 struct iw_scan_req
*req
= (struct iw_scan_req
*)extra
;
1135 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
) {
1136 int len
= min_t(int, req
->essid_len
,
1139 memcpy(ssid
[0].Ssid
, req
->essid
, len
);
1140 ssid
[0].SsidLength
= len
;
1142 DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req
->essid
, req
->essid_len
);
1144 spin_lock_bh(&pmlmepriv
->lock
);
1146 _status
= rtw_sitesurvey_cmd(padapter
, ssid
, 1, NULL
, 0);
1148 spin_unlock_bh(&pmlmepriv
->lock
);
1149 } else if (req
->scan_type
== IW_SCAN_TYPE_PASSIVE
) {
1150 DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1153 if (wrqu
->data
.length
>= WEXT_CSCAN_HEADER_SIZE
&&
1154 !memcmp(extra
, WEXT_CSCAN_HEADER
, WEXT_CSCAN_HEADER_SIZE
)) {
1155 int len
= wrqu
->data
.length
- WEXT_CSCAN_HEADER_SIZE
;
1156 char *pos
= extra
+WEXT_CSCAN_HEADER_SIZE
;
1166 case WEXT_CSCAN_SSID_SECTION
:
1171 sec_len
= *(pos
++); len
-= 1;
1172 if (sec_len
> 0 && sec_len
<= len
) {
1173 ssid
[ssid_index
].SsidLength
= sec_len
;
1174 memcpy(ssid
[ssid_index
].Ssid
, pos
, ssid
[ssid_index
].SsidLength
);
1180 case WEXT_CSCAN_TYPE_SECTION
:
1181 case WEXT_CSCAN_CHANNEL_SECTION
:
1185 case WEXT_CSCAN_PASV_DWELL_SECTION
:
1186 case WEXT_CSCAN_HOME_DWELL_SECTION
:
1187 case WEXT_CSCAN_ACTV_DWELL_SECTION
:
1192 len
= 0; /* stop parsing */
1196 /* it has still some scan parameter to parse, we only do this now... */
1197 _status
= rtw_set_802_11_bssid_list_scan(padapter
, ssid
, RTW_SSID_SCAN_AMOUNT
);
1199 _status
= rtw_set_802_11_bssid_list_scan(padapter
, NULL
, 0);
1211 static int rtw_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
1212 union iwreq_data
*wrqu
, char *extra
)
1214 struct list_head
*plist
, *phead
;
1215 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1216 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1217 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1218 struct wlan_network
*pnetwork
= NULL
;
1220 char *stop
= ev
+ wrqu
->data
.length
;
1223 u32 wait_for_surveydone
;
1226 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_scan\n"));
1227 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, (" Start of Query SIOCGIWSCAN .\n"));
1229 if (padapter
->pwrctrlpriv
.brfoffbyhw
&& padapter
->bDriverStopped
) {
1234 wait_for_surveydone
= 100;
1236 wait_status
= _FW_UNDER_SURVEY
| _FW_UNDER_LINKING
;
1238 while (check_fwstate(pmlmepriv
, wait_status
)) {
1241 if (cnt
> wait_for_surveydone
)
1245 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1247 phead
= get_list_head(queue
);
1248 plist
= phead
->next
;
1250 while (phead
!= plist
) {
1251 if ((stop
- ev
) < SCAN_ITEM_SIZE
) {
1256 pnetwork
= container_of(plist
, struct wlan_network
, list
);
1258 /* report network only if the current channel set contains the channel to which this network belongs */
1259 if (rtw_ch_set_search_ch(padapter
->mlmeextpriv
.channel_set
, pnetwork
->network
.Configuration
.DSConfig
) >= 0)
1260 ev
= translate_scan(padapter
, a
, pnetwork
, ev
, stop
);
1262 plist
= plist
->next
;
1265 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1267 wrqu
->data
.length
= ev
-extra
;
1268 wrqu
->data
.flags
= 0;
1275 /* s1. rtw_set_802_11_infrastructure_mode() */
1276 /* s2. set_802_11_authenticaion_mode() */
1277 /* s3. set_802_11_encryption_mode() */
1278 /* s4. rtw_set_802_11_ssid() */
1279 static int rtw_wx_set_essid(struct net_device
*dev
,
1280 struct iw_request_info
*a
,
1281 union iwreq_data
*wrqu
, char *extra
)
1283 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1284 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1285 struct __queue
*queue
= &pmlmepriv
->scanned_queue
;
1286 struct list_head
*phead
;
1287 struct wlan_network
*pnetwork
= NULL
;
1288 enum ndis_802_11_auth_mode authmode
;
1289 struct ndis_802_11_ssid ndis_ssid
;
1290 u8
*dst_ssid
, *src_ssid
;
1295 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1296 ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv
)));
1297 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
1302 if (!padapter
->bup
) {
1307 if (wrqu
->essid
.length
> IW_ESSID_MAX_SIZE
) {
1312 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1317 authmode
= padapter
->securitypriv
.ndisauthtype
;
1318 DBG_88E("=>%s\n", __func__
);
1319 if (wrqu
->essid
.flags
&& wrqu
->essid
.length
) {
1320 len
= min_t(uint
, wrqu
->essid
.length
, IW_ESSID_MAX_SIZE
);
1322 if (wrqu
->essid
.length
!= 33)
1323 DBG_88E("ssid =%s, len =%d\n", extra
, wrqu
->essid
.length
);
1325 memset(&ndis_ssid
, 0, sizeof(struct ndis_802_11_ssid
));
1326 ndis_ssid
.SsidLength
= len
;
1327 memcpy(ndis_ssid
.Ssid
, extra
, len
);
1328 src_ssid
= ndis_ssid
.Ssid
;
1330 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid
));
1331 spin_lock_bh(&queue
->lock
);
1332 phead
= get_list_head(queue
);
1333 pmlmepriv
->pscanned
= phead
->next
;
1335 while (phead
!= pmlmepriv
->pscanned
) {
1336 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
1338 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
1340 dst_ssid
= pnetwork
->network
.Ssid
.Ssid
;
1342 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1343 ("rtw_wx_set_essid: dst_ssid =%s\n",
1344 pnetwork
->network
.Ssid
.Ssid
));
1346 if ((!memcmp(dst_ssid
, src_ssid
, ndis_ssid
.SsidLength
)) &&
1347 (pnetwork
->network
.Ssid
.SsidLength
== ndis_ssid
.SsidLength
)) {
1348 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1349 ("rtw_wx_set_essid: find match, set infra mode\n"));
1351 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true) {
1352 if (pnetwork
->network
.InfrastructureMode
!= pmlmepriv
->cur_network
.network
.InfrastructureMode
)
1356 if (!rtw_set_802_11_infrastructure_mode(padapter
, pnetwork
->network
.InfrastructureMode
)) {
1358 spin_unlock_bh(&queue
->lock
);
1365 spin_unlock_bh(&queue
->lock
);
1366 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1367 ("set ssid: set_802_11_auth. mode =%d\n", authmode
));
1368 rtw_set_802_11_authentication_mode(padapter
, authmode
);
1369 if (rtw_set_802_11_ssid(padapter
, &ndis_ssid
) == false) {
1377 DBG_88E("<=%s, ret %d\n", __func__
, ret
);
1383 static int rtw_wx_get_essid(struct net_device
*dev
,
1384 struct iw_request_info
*a
,
1385 union iwreq_data
*wrqu
, char *extra
)
1388 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1389 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1390 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
1392 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_essid\n"));
1395 if ((check_fwstate(pmlmepriv
, _FW_LINKED
)) ||
1396 (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
))) {
1397 len
= pcur_bss
->Ssid
.SsidLength
;
1399 wrqu
->essid
.length
= len
;
1401 memcpy(extra
, pcur_bss
->Ssid
.Ssid
, len
);
1403 wrqu
->essid
.flags
= 1;
1415 static int rtw_wx_set_rate(struct net_device
*dev
,
1416 struct iw_request_info
*a
,
1417 union iwreq_data
*wrqu
, char *extra
)
1420 u8 datarates
[NumRates
];
1421 u32 target_rate
= wrqu
->bitrate
.value
;
1422 u32 fixed
= wrqu
->bitrate
.fixed
;
1424 u8 mpdatarate
[NumRates
] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1427 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, (" rtw_wx_set_rate\n"));
1428 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("target_rate = %d, fixed = %d\n", target_rate
, fixed
));
1430 if (target_rate
== -1) {
1434 target_rate
= target_rate
/100000;
1436 switch (target_rate
) {
1480 for (i
= 0; i
< NumRates
; i
++) {
1481 if (ratevalue
== mpdatarate
[i
]) {
1482 datarates
[i
] = mpdatarate
[i
];
1486 datarates
[i
] = 0xff;
1489 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("datarate_inx =%d\n", datarates
[i
]));
1495 static int rtw_wx_get_rate(struct net_device
*dev
,
1496 struct iw_request_info
*info
,
1497 union iwreq_data
*wrqu
, char *extra
)
1501 max_rate
= rtw_get_cur_max_rate((struct adapter
*)rtw_netdev_priv(dev
));
1506 wrqu
->bitrate
.fixed
= 0; /* no auto select */
1507 wrqu
->bitrate
.value
= max_rate
* 100000;
1512 static int rtw_wx_set_rts(struct net_device
*dev
,
1513 struct iw_request_info
*info
,
1514 union iwreq_data
*wrqu
, char *extra
)
1516 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1519 if (wrqu
->rts
.disabled
) {
1520 padapter
->registrypriv
.rts_thresh
= 2347;
1522 if (wrqu
->rts
.value
< 0 ||
1523 wrqu
->rts
.value
> 2347)
1526 padapter
->registrypriv
.rts_thresh
= wrqu
->rts
.value
;
1529 DBG_88E("%s, rts_thresh =%d\n", __func__
, padapter
->registrypriv
.rts_thresh
);
1535 static int rtw_wx_get_rts(struct net_device
*dev
,
1536 struct iw_request_info
*info
,
1537 union iwreq_data
*wrqu
, char *extra
)
1539 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1542 DBG_88E("%s, rts_thresh =%d\n", __func__
, padapter
->registrypriv
.rts_thresh
);
1544 wrqu
->rts
.value
= padapter
->registrypriv
.rts_thresh
;
1545 wrqu
->rts
.fixed
= 0; /* no auto select */
1546 /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
1552 static int rtw_wx_set_frag(struct net_device
*dev
,
1553 struct iw_request_info
*info
,
1554 union iwreq_data
*wrqu
, char *extra
)
1556 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1559 if (wrqu
->frag
.disabled
) {
1560 padapter
->xmitpriv
.frag_len
= MAX_FRAG_THRESHOLD
;
1562 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
1563 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
1566 padapter
->xmitpriv
.frag_len
= wrqu
->frag
.value
& ~0x1;
1569 DBG_88E("%s, frag_len =%d\n", __func__
, padapter
->xmitpriv
.frag_len
);
1575 static int rtw_wx_get_frag(struct net_device
*dev
,
1576 struct iw_request_info
*info
,
1577 union iwreq_data
*wrqu
, char *extra
)
1579 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1582 DBG_88E("%s, frag_len =%d\n", __func__
, padapter
->xmitpriv
.frag_len
);
1584 wrqu
->frag
.value
= padapter
->xmitpriv
.frag_len
;
1585 wrqu
->frag
.fixed
= 0; /* no auto select */
1591 static int rtw_wx_get_retry(struct net_device
*dev
,
1592 struct iw_request_info
*info
,
1593 union iwreq_data
*wrqu
, char *extra
)
1595 wrqu
->retry
.value
= 7;
1596 wrqu
->retry
.fixed
= 0; /* no auto select */
1597 wrqu
->retry
.disabled
= 1;
1602 static int rtw_wx_set_enc(struct net_device
*dev
,
1603 struct iw_request_info
*info
,
1604 union iwreq_data
*wrqu
, char *keybuf
)
1607 u32 keyindex_provided
;
1608 struct ndis_802_11_wep wep
;
1609 enum ndis_802_11_auth_mode authmode
;
1611 struct iw_point
*erq
= &(wrqu
->encoding
);
1612 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1613 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
1615 DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq
->flags
);
1617 memset(&wep
, 0, sizeof(struct ndis_802_11_wep
));
1619 key
= erq
->flags
& IW_ENCODE_INDEX
;
1622 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1623 DBG_88E("EncryptionDisabled\n");
1624 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
1625 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1626 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1627 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1628 authmode
= Ndis802_11AuthModeOpen
;
1629 padapter
->securitypriv
.ndisauthtype
= authmode
;
1638 keyindex_provided
= 1;
1640 keyindex_provided
= 0;
1641 key
= padapter
->securitypriv
.dot11PrivacyKeyIndex
;
1642 DBG_88E("rtw_wx_set_enc, key =%d\n", key
);
1645 /* set authentication mode */
1646 if (erq
->flags
& IW_ENCODE_OPEN
) {
1647 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1648 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;/* Ndis802_11EncryptionDisabled; */
1649 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1650 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1651 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1652 authmode
= Ndis802_11AuthModeOpen
;
1653 padapter
->securitypriv
.ndisauthtype
= authmode
;
1654 } else if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
1655 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1656 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
1657 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Shared
;
1658 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
1659 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
1660 authmode
= Ndis802_11AuthModeShared
;
1661 padapter
->securitypriv
.ndisauthtype
= authmode
;
1663 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq
->flags
);
1665 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;/* Ndis802_11EncryptionDisabled; */
1666 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1667 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1668 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1669 authmode
= Ndis802_11AuthModeOpen
;
1670 padapter
->securitypriv
.ndisauthtype
= authmode
;
1674 if (erq
->length
> 0) {
1675 wep
.KeyLength
= erq
->length
<= 5 ? 5 : 13;
1677 wep
.Length
= wep
.KeyLength
+ offsetof(struct ndis_802_11_wep
, KeyMaterial
);
1681 if (keyindex_provided
== 1) {
1682 /* set key_id only, no given KeyMaterial(erq->length == 0). */
1683 padapter
->securitypriv
.dot11PrivacyKeyIndex
= key
;
1685 DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key
, padapter
->securitypriv
.dot11DefKeylen
[key
]);
1687 switch (padapter
->securitypriv
.dot11DefKeylen
[key
]) {
1689 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
1692 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
1695 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1703 wep
.KeyIndex
|= 0x80000000;
1705 memcpy(wep
.KeyMaterial
, keybuf
, wep
.KeyLength
);
1707 if (rtw_set_802_11_add_wep(padapter
, &wep
) == false) {
1708 if (rf_on
== pwrpriv
->rf_pwrstate
)
1719 static int rtw_wx_get_enc(struct net_device
*dev
,
1720 struct iw_request_info
*info
,
1721 union iwreq_data
*wrqu
, char *keybuf
)
1724 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1725 struct iw_point
*erq
= &(wrqu
->encoding
);
1726 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1729 if (check_fwstate(pmlmepriv
, _FW_LINKED
) != true) {
1730 if (!check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
1732 erq
->flags
|= IW_ENCODE_DISABLED
;
1737 key
= erq
->flags
& IW_ENCODE_INDEX
;
1744 key
= padapter
->securitypriv
.dot11PrivacyKeyIndex
;
1747 erq
->flags
= key
+ 1;
1749 switch (padapter
->securitypriv
.ndisencryptstatus
) {
1750 case Ndis802_11EncryptionNotSupported
:
1751 case Ndis802_11EncryptionDisabled
:
1753 erq
->flags
|= IW_ENCODE_DISABLED
;
1755 case Ndis802_11Encryption1Enabled
:
1756 erq
->length
= padapter
->securitypriv
.dot11DefKeylen
[key
];
1758 memcpy(keybuf
, padapter
->securitypriv
.dot11DefKey
[key
].skey
, padapter
->securitypriv
.dot11DefKeylen
[key
]);
1760 erq
->flags
|= IW_ENCODE_ENABLED
;
1762 if (padapter
->securitypriv
.ndisauthtype
== Ndis802_11AuthModeOpen
)
1763 erq
->flags
|= IW_ENCODE_OPEN
;
1764 else if (padapter
->securitypriv
.ndisauthtype
== Ndis802_11AuthModeShared
)
1765 erq
->flags
|= IW_ENCODE_RESTRICTED
;
1768 erq
->flags
|= IW_ENCODE_DISABLED
;
1771 case Ndis802_11Encryption2Enabled
:
1772 case Ndis802_11Encryption3Enabled
:
1774 erq
->flags
|= (IW_ENCODE_ENABLED
| IW_ENCODE_OPEN
| IW_ENCODE_NOKEY
);
1778 erq
->flags
|= IW_ENCODE_DISABLED
;
1785 static int rtw_wx_get_power(struct net_device
*dev
,
1786 struct iw_request_info
*info
,
1787 union iwreq_data
*wrqu
, char *extra
)
1789 wrqu
->power
.value
= 0;
1790 wrqu
->power
.fixed
= 0; /* no auto select */
1791 wrqu
->power
.disabled
= 1;
1796 static int rtw_wx_set_gen_ie(struct net_device
*dev
,
1797 struct iw_request_info
*info
,
1798 union iwreq_data
*wrqu
, char *extra
)
1800 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1802 return rtw_set_wpa_ie(padapter
, extra
, wrqu
->data
.length
);
1805 static int rtw_wx_set_auth(struct net_device
*dev
,
1806 struct iw_request_info
*info
,
1807 union iwreq_data
*wrqu
, char *extra
)
1809 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1810 struct iw_param
*param
= (struct iw_param
*)&(wrqu
->param
);
1813 switch (param
->flags
& IW_AUTH_INDEX
) {
1814 case IW_AUTH_WPA_VERSION
:
1816 case IW_AUTH_CIPHER_PAIRWISE
:
1819 case IW_AUTH_CIPHER_GROUP
:
1822 case IW_AUTH_KEY_MGMT
:
1824 * ??? does not use these parameters
1827 case IW_AUTH_TKIP_COUNTERMEASURES
:
1829 /* wpa_supplicant is enabling the tkip countermeasure. */
1830 padapter
->securitypriv
.btkip_countermeasure
= true;
1832 /* wpa_supplicant is disabling the tkip countermeasure. */
1833 padapter
->securitypriv
.btkip_countermeasure
= false;
1836 case IW_AUTH_DROP_UNENCRYPTED
:
1839 * wpa_supplicant calls set_wpa_enabled when the driver
1840 * is loaded and unloaded, regardless of if WPA is being
1841 * used. No other calls are made which can be used to
1842 * determine if encryption will be used or not prior to
1843 * association being expected. If encryption is not being
1844 * used, drop_unencrypted is set to false, else true -- we
1845 * can use this to determine if the CAP_PRIVACY_ON bit should
1849 if (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption1Enabled
)
1850 break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
1851 /* then it needn't reset it; */
1854 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
1855 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1856 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1857 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1858 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeOpen
;
1862 case IW_AUTH_80211_AUTH_ALG
:
1864 * It's the starting point of a link layer connection using wpa_supplicant
1866 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
1867 LeaveAllPowerSaveMode(padapter
);
1868 rtw_disassoc_cmd(padapter
, 500, false);
1869 DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__
);
1870 rtw_indicate_disconnect(padapter
);
1871 rtw_free_assoc_resources(padapter
);
1873 ret
= wpa_set_auth_algs(dev
, (u32
)param
->value
);
1875 case IW_AUTH_WPA_ENABLED
:
1877 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1879 case IW_AUTH_PRIVACY_INVOKED
:
1888 static int rtw_wx_set_enc_ext(struct net_device
*dev
,
1889 struct iw_request_info
*info
,
1890 union iwreq_data
*wrqu
, char *extra
)
1894 struct ieee_param
*param
= NULL
;
1895 struct iw_point
*pencoding
= &wrqu
->encoding
;
1896 struct iw_encode_ext
*pext
= (struct iw_encode_ext
*)extra
;
1899 param_len
= sizeof(struct ieee_param
) + pext
->key_len
;
1900 param
= (struct ieee_param
*)rtw_malloc(param_len
);
1904 memset(param
, 0, param_len
);
1906 param
->cmd
= IEEE_CMD_SET_ENCRYPTION
;
1907 eth_broadcast_addr(param
->sta_addr
);
1909 switch (pext
->alg
) {
1910 case IW_ENCODE_ALG_NONE
:
1911 /* todo: remove key */
1915 case IW_ENCODE_ALG_WEP
:
1918 case IW_ENCODE_ALG_TKIP
:
1921 case IW_ENCODE_ALG_CCMP
:
1929 strncpy((char *)param
->u
.crypt
.alg
, alg_name
, IEEE_CRYPT_ALG_NAME_LEN
);
1931 if (pext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
)
1932 param
->u
.crypt
.set_tx
= 1;
1934 /* cliW: WEP does not have group key
1935 * just not checking GROUP key setting
1937 if ((pext
->alg
!= IW_ENCODE_ALG_WEP
) &&
1938 (pext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
))
1939 param
->u
.crypt
.set_tx
= 0;
1941 param
->u
.crypt
.idx
= (pencoding
->flags
&0x00FF) - 1;
1943 if (pext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
)
1944 memcpy(param
->u
.crypt
.seq
, pext
->rx_seq
, 8);
1946 if (pext
->key_len
) {
1947 param
->u
.crypt
.key_len
= pext
->key_len
;
1948 memcpy(param
->u
.crypt
.key
, pext
+ 1, pext
->key_len
);
1951 ret
= wpa_set_encryption(dev
, param
, param_len
);
1958 static int rtw_wx_get_nick(struct net_device
*dev
,
1959 struct iw_request_info
*info
,
1960 union iwreq_data
*wrqu
, char *extra
)
1963 wrqu
->data
.length
= 14;
1964 wrqu
->data
.flags
= 1;
1965 memcpy(extra
, "<WIFI@REALTEK>", 14);
1968 /* dump debug info here */
1972 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1973 union iwreq_data
*wrqu
, char *b
)
1978 static int wpa_set_param(struct net_device
*dev
, u8 name
, u32 value
)
1981 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1984 case IEEE_PARAM_WPA_ENABLED
:
1985 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
; /* 802.1x */
1986 switch ((value
)&0xff) {
1988 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPAPSK
; /* WPA_PSK */
1989 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
1992 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPA2PSK
; /* WPA2_PSK */
1993 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
1996 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1997 ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter
->securitypriv
.ndisauthtype
));
1999 case IEEE_PARAM_TKIP_COUNTERMEASURES
:
2001 case IEEE_PARAM_DROP_UNENCRYPTED
: {
2004 * wpa_supplicant calls set_wpa_enabled when the driver
2005 * is loaded and unloaded, regardless of if WPA is being
2006 * used. No other calls are made which can be used to
2007 * determine if encryption will be used or not prior to
2008 * association being expected. If encryption is not being
2009 * used, drop_unencrypted is set to false, else true -- we
2010 * can use this to determine if the CAP_PRIVACY_ON bit should
2016 case IEEE_PARAM_PRIVACY_INVOKED
:
2019 case IEEE_PARAM_AUTH_ALGS
:
2020 ret
= wpa_set_auth_algs(dev
, value
);
2022 case IEEE_PARAM_IEEE_802_1X
:
2024 case IEEE_PARAM_WPAX_SELECT
:
2033 static int wpa_mlme(struct net_device
*dev
, u32 command
, u32 reason
)
2036 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2039 case IEEE_MLME_STA_DEAUTH
:
2040 if (!rtw_set_802_11_disassociate(padapter
))
2043 case IEEE_MLME_STA_DISASSOC
:
2044 if (!rtw_set_802_11_disassociate(padapter
))
2055 static int wpa_supplicant_ioctl(struct net_device
*dev
, struct iw_point
*p
)
2057 struct ieee_param
*param
;
2060 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
) {
2065 param
= (struct ieee_param
*)rtw_malloc(p
->length
);
2071 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
2077 switch (param
->cmd
) {
2078 case IEEE_CMD_SET_WPA_PARAM
:
2079 ret
= wpa_set_param(dev
, param
->u
.wpa_param
.name
, param
->u
.wpa_param
.value
);
2082 case IEEE_CMD_SET_WPA_IE
:
2083 ret
= rtw_set_wpa_ie((struct adapter
*)rtw_netdev_priv(dev
),
2084 (char *)param
->u
.wpa_ie
.data
, (u16
)param
->u
.wpa_ie
.len
);
2087 case IEEE_CMD_SET_ENCRYPTION
:
2088 ret
= wpa_set_encryption(dev
, param
, p
->length
);
2092 ret
= wpa_mlme(dev
, param
->u
.mlme
.command
, param
->u
.mlme
.reason_code
);
2096 DBG_88E("Unknown WPA supplicant request: %d\n", param
->cmd
);
2101 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
2111 #ifdef CONFIG_88EU_AP_MODE
2112 static u8
set_pairwise_key(struct adapter
*padapter
, struct sta_info
*psta
)
2114 struct cmd_obj
*ph2c
;
2115 struct set_stakey_parm
*psetstakey_para
;
2116 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
2119 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
2125 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_KERNEL
);
2126 if (!psetstakey_para
) {
2132 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
2134 psetstakey_para
->algorithm
= (u8
)psta
->dot118021XPrivacy
;
2136 memcpy(psetstakey_para
->addr
, psta
->hwaddr
, ETH_ALEN
);
2138 memcpy(psetstakey_para
->key
, &psta
->dot118021x_UncstKey
, 16);
2140 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
2147 static int set_group_key(struct adapter
*padapter
, u8
*key
, u8 alg
, int keyid
)
2150 struct cmd_obj
*pcmd
;
2151 struct setkey_parm
*psetkeyparm
;
2152 struct cmd_priv
*pcmdpriv
= &(padapter
->cmdpriv
);
2155 DBG_88E("%s\n", __func__
);
2157 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
2162 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
2169 psetkeyparm
->keyid
= (u8
)keyid
;
2171 psetkeyparm
->algorithm
= alg
;
2173 psetkeyparm
->set_tx
= 1;
2189 memcpy(&(psetkeyparm
->key
[0]), key
, keylen
);
2191 pcmd
->cmdcode
= _SetKey_CMD_
;
2192 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
2193 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
2197 INIT_LIST_HEAD(&pcmd
->list
);
2199 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
2206 static int set_wep_key(struct adapter
*padapter
, u8
*key
, u8 keylen
, int keyid
)
2221 return set_group_key(padapter
, key
, alg
, keyid
);
2224 static int rtw_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
2227 u32 wep_key_idx
, wep_key_len
, wep_total_len
;
2228 struct ndis_802_11_wep
*pwep
= NULL
;
2229 struct sta_info
*psta
= NULL
, *pbcmc_sta
= NULL
;
2230 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2231 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2232 struct security_priv
*psecuritypriv
= &(padapter
->securitypriv
);
2233 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2235 DBG_88E("%s\n", __func__
);
2236 param
->u
.crypt
.err
= 0;
2237 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
2238 if (param_len
!= sizeof(struct ieee_param
) + param
->u
.crypt
.key_len
) {
2242 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2243 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2244 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff) {
2245 if (param
->u
.crypt
.idx
>= WEP_KEYS
) {
2250 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2252 DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
2257 if (strcmp(param
->u
.crypt
.alg
, "none") == 0 && (!psta
)) {
2258 /* todo:clear default encryption keys */
2260 DBG_88E("clear default encryption keys, keyid =%d\n", param
->u
.crypt
.idx
);
2263 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0 && (!psta
)) {
2264 DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
2265 wep_key_idx
= param
->u
.crypt
.idx
;
2266 wep_key_len
= param
->u
.crypt
.key_len
;
2267 DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx
, wep_key_len
);
2268 if ((wep_key_idx
>= WEP_KEYS
) || (wep_key_len
<= 0)) {
2273 if (wep_key_len
> 0) {
2274 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
2275 wep_total_len
= wep_key_len
+ offsetof(struct ndis_802_11_wep
, KeyMaterial
);
2276 pwep
= (struct ndis_802_11_wep
*)rtw_malloc(wep_total_len
);
2278 DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
2282 memset(pwep
, 0, wep_total_len
);
2284 pwep
->KeyLength
= wep_key_len
;
2285 pwep
->Length
= wep_total_len
;
2288 pwep
->KeyIndex
= wep_key_idx
;
2290 memcpy(pwep
->KeyMaterial
, param
->u
.crypt
.key
, pwep
->KeyLength
);
2292 if (param
->u
.crypt
.set_tx
) {
2293 DBG_88E("wep, set_tx = 1\n");
2295 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2296 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP40_
;
2297 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2299 if (pwep
->KeyLength
== 13) {
2300 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP104_
;
2301 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2304 psecuritypriv
->dot11PrivacyKeyIndex
= wep_key_idx
;
2306 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
2308 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
2310 set_wep_key(padapter
, pwep
->KeyMaterial
, pwep
->KeyLength
, wep_key_idx
);
2312 DBG_88E("wep, set_tx = 0\n");
2314 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
2315 /* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
2317 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
2319 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
2321 set_wep_key(padapter
, pwep
->KeyMaterial
, pwep
->KeyLength
, wep_key_idx
);
2327 if (!psta
&& check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) { /* group key */
2328 if (param
->u
.crypt
.set_tx
== 1) {
2329 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2330 DBG_88E("%s, set group_key, WEP\n", __func__
);
2332 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2333 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2335 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2336 if (param
->u
.crypt
.key_len
== 13)
2337 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2338 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2339 DBG_88E("%s, set group_key, TKIP\n", __func__
);
2340 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
2341 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2342 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2344 memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
2345 memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
2347 psecuritypriv
->busetkipkey
= true;
2348 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2349 DBG_88E("%s, set group_key, CCMP\n", __func__
);
2350 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
2351 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2352 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2354 DBG_88E("%s, set group_key, none\n", __func__
);
2355 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2357 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
2358 psecuritypriv
->binstallGrpkey
= true;
2359 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;/* */
2360 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
2361 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
2363 pbcmc_sta
->ieee8021x_blocked
= false;
2364 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;/* rx will use bmc_sta's dot118021XPrivacy */
2370 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
&& psta
) { /* psk/802_1x */
2371 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
2372 if (param
->u
.crypt
.set_tx
== 1) {
2373 memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2375 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2376 DBG_88E("%s, set pairwise key, WEP\n", __func__
);
2378 psta
->dot118021XPrivacy
= _WEP40_
;
2379 if (param
->u
.crypt
.key_len
== 13)
2380 psta
->dot118021XPrivacy
= _WEP104_
;
2381 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2382 DBG_88E("%s, set pairwise key, TKIP\n", __func__
);
2384 psta
->dot118021XPrivacy
= _TKIP_
;
2387 memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
2388 memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
2390 psecuritypriv
->busetkipkey
= true;
2391 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2392 DBG_88E("%s, set pairwise key, CCMP\n", __func__
);
2394 psta
->dot118021XPrivacy
= _AES_
;
2396 DBG_88E("%s, set pairwise key, none\n", __func__
);
2398 psta
->dot118021XPrivacy
= _NO_PRIVACY_
;
2401 set_pairwise_key(padapter
, psta
);
2403 psta
->ieee8021x_blocked
= false;
2404 } else { /* group key??? */
2405 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2406 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2407 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2408 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2409 if (param
->u
.crypt
.key_len
== 13)
2410 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2411 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2412 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
2414 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2415 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2418 memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
2419 memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
2421 psecuritypriv
->busetkipkey
= true;
2422 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2423 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
2425 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2426 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2428 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2431 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
2433 psecuritypriv
->binstallGrpkey
= true;
2435 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;/* */
2437 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
2439 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
2441 pbcmc_sta
->ieee8021x_blocked
= false;
2442 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;/* rx will use bmc_sta's dot118021XPrivacy */
2455 static int rtw_set_beacon(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2458 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2459 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2460 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2461 unsigned char *pbuf
= param
->u
.bcn_ie
.buf
;
2463 DBG_88E("%s, len =%d\n", __func__
, len
);
2465 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2468 memcpy(&pstapriv
->max_num_sta
, param
->u
.bcn_ie
.reserved
, 2);
2470 if ((pstapriv
->max_num_sta
> NUM_STA
) || (pstapriv
->max_num_sta
<= 0))
2471 pstapriv
->max_num_sta
= NUM_STA
;
2473 if (rtw_check_beacon_data(padapter
, pbuf
, (len
-12-2)) == _SUCCESS
)/* 12 = param header, 2:no packed */
2481 static int rtw_hostapd_sta_flush(struct net_device
*dev
)
2483 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2485 DBG_88E("%s\n", __func__
);
2487 flush_all_cam_entry(padapter
); /* clear CAM */
2489 return rtw_sta_flush(padapter
);
2492 static int rtw_add_sta(struct net_device
*dev
, struct ieee_param
*param
)
2495 struct sta_info
*psta
= NULL
;
2496 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2497 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2498 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2500 DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param
->u
.add_sta
.aid
, (param
->sta_addr
));
2502 if (!check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)))
2505 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2506 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2507 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2510 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2512 int flags
= param
->u
.add_sta
.flags
;
2514 psta
->aid
= param
->u
.add_sta
.aid
;/* aid = 1~2007 */
2516 memcpy(psta
->bssrateset
, param
->u
.add_sta
.tx_supp_rates
, 16);
2518 /* check wmm cap. */
2519 if (WLAN_STA_WME
&flags
)
2520 psta
->qos_option
= 1;
2522 psta
->qos_option
= 0;
2524 if (pmlmepriv
->qospriv
.qos_option
== 0)
2525 psta
->qos_option
= 0;
2527 /* chec 802.11n ht cap. */
2528 if (WLAN_STA_HT
&flags
) {
2529 psta
->htpriv
.ht_option
= true;
2530 psta
->qos_option
= 1;
2531 memcpy(&psta
->htpriv
.ht_cap
, ¶m
->u
.add_sta
.ht_cap
,
2532 sizeof(struct ieee80211_ht_cap
));
2534 psta
->htpriv
.ht_option
= false;
2537 if (pmlmepriv
->htpriv
.ht_option
== false)
2538 psta
->htpriv
.ht_option
= false;
2540 update_sta_info_apmode(padapter
, psta
);
2548 static int rtw_del_sta(struct net_device
*dev
, struct ieee_param
*param
)
2551 struct sta_info
*psta
= NULL
;
2552 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2553 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2554 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2557 DBG_88E("rtw_del_sta =%pM\n", (param
->sta_addr
));
2559 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2562 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2563 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2564 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2567 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2569 spin_lock_bh(&pstapriv
->asoc_list_lock
);
2570 if (!list_empty(&psta
->asoc_list
)) {
2571 list_del_init(&psta
->asoc_list
);
2572 pstapriv
->asoc_list_cnt
--;
2573 updated
= ap_free_sta(padapter
, psta
, true, WLAN_REASON_DEAUTH_LEAVING
);
2575 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
2576 associated_clients_update(padapter
, updated
);
2579 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
2585 static int rtw_ioctl_get_sta_data(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2588 struct sta_info
*psta
= NULL
;
2589 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2590 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2591 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2592 struct ieee_param_ex
*param_ex
= (struct ieee_param_ex
*)param
;
2593 struct sta_data
*psta_data
= (struct sta_data
*)param_ex
->data
;
2595 DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex
->sta_addr
));
2597 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2600 if (param_ex
->sta_addr
[0] == 0xff && param_ex
->sta_addr
[1] == 0xff &&
2601 param_ex
->sta_addr
[2] == 0xff && param_ex
->sta_addr
[3] == 0xff &&
2602 param_ex
->sta_addr
[4] == 0xff && param_ex
->sta_addr
[5] == 0xff)
2605 psta
= rtw_get_stainfo(pstapriv
, param_ex
->sta_addr
);
2607 psta_data
->aid
= (u16
)psta
->aid
;
2608 psta_data
->capability
= psta
->capability
;
2609 psta_data
->flags
= psta
->flags
;
2613 no_short_slot_time_set : BIT(1)
2614 no_short_preamble_set : BIT(2)
2615 no_ht_gf_set : BIT(3)
2617 ht_20mhz_set : BIT(5)
2620 psta_data
->sta_set
= ((psta
->nonerp_set
) |
2621 (psta
->no_short_slot_time_set
<< 1) |
2622 (psta
->no_short_preamble_set
<< 2) |
2623 (psta
->no_ht_gf_set
<< 3) |
2624 (psta
->no_ht_set
<< 4) |
2625 (psta
->ht_20mhz_set
<< 5));
2626 psta_data
->tx_supp_rates_len
= psta
->bssratelen
;
2627 memcpy(psta_data
->tx_supp_rates
, psta
->bssrateset
, psta
->bssratelen
);
2628 memcpy(&psta_data
->ht_cap
,
2629 &psta
->htpriv
.ht_cap
, sizeof(struct ieee80211_ht_cap
));
2630 psta_data
->rx_pkts
= psta
->sta_stats
.rx_data_pkts
;
2631 psta_data
->rx_bytes
= psta
->sta_stats
.rx_bytes
;
2632 psta_data
->rx_drops
= psta
->sta_stats
.rx_drops
;
2633 psta_data
->tx_pkts
= psta
->sta_stats
.tx_pkts
;
2634 psta_data
->tx_bytes
= psta
->sta_stats
.tx_bytes
;
2635 psta_data
->tx_drops
= psta
->sta_stats
.tx_drops
;
2643 static int rtw_get_sta_wpaie(struct net_device
*dev
, struct ieee_param
*param
)
2646 struct sta_info
*psta
= NULL
;
2647 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2648 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2649 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2651 DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param
->sta_addr
));
2653 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2656 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2657 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2658 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2661 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2663 if (psta
->wpa_ie
[0] == WLAN_EID_RSN
||
2664 psta
->wpa_ie
[0] == WLAN_EID_VENDOR_SPECIFIC
) {
2668 wpa_ie_len
= psta
->wpa_ie
[1];
2669 copy_len
= min_t(int, wpa_ie_len
+ 2, sizeof(psta
->wpa_ie
));
2670 param
->u
.wpa_ie
.len
= copy_len
;
2671 memcpy(param
->u
.wpa_ie
.reserved
, psta
->wpa_ie
, copy_len
);
2673 DBG_88E("sta's wpa_ie is NONE\n");
2682 static int rtw_set_wps_beacon(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2685 unsigned char wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
2686 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2687 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2688 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
2691 DBG_88E("%s, len =%d\n", __func__
, len
);
2693 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2696 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2698 kfree(pmlmepriv
->wps_beacon_ie
);
2699 pmlmepriv
->wps_beacon_ie
= NULL
;
2702 pmlmepriv
->wps_beacon_ie
= rtw_malloc(ie_len
);
2703 pmlmepriv
->wps_beacon_ie_len
= ie_len
;
2704 if (!pmlmepriv
->wps_beacon_ie
) {
2705 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2709 memcpy(pmlmepriv
->wps_beacon_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2711 update_beacon(padapter
, _VENDOR_SPECIFIC_IE_
, wps_oui
, true);
2713 pmlmeext
->bstart_bss
= true;
2719 static int rtw_set_wps_probe_resp(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2722 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2723 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2726 DBG_88E("%s, len =%d\n", __func__
, len
);
2728 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2731 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2733 kfree(pmlmepriv
->wps_probe_resp_ie
);
2734 pmlmepriv
->wps_probe_resp_ie
= NULL
;
2737 pmlmepriv
->wps_probe_resp_ie
= rtw_malloc(ie_len
);
2738 pmlmepriv
->wps_probe_resp_ie_len
= ie_len
;
2739 if (!pmlmepriv
->wps_probe_resp_ie
) {
2740 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2743 memcpy(pmlmepriv
->wps_probe_resp_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2749 static int rtw_set_wps_assoc_resp(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2752 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2753 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2756 DBG_88E("%s, len =%d\n", __func__
, len
);
2758 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2761 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2763 kfree(pmlmepriv
->wps_assoc_resp_ie
);
2764 pmlmepriv
->wps_assoc_resp_ie
= NULL
;
2767 pmlmepriv
->wps_assoc_resp_ie
= rtw_malloc(ie_len
);
2768 pmlmepriv
->wps_assoc_resp_ie_len
= ie_len
;
2769 if (!pmlmepriv
->wps_assoc_resp_ie
) {
2770 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2774 memcpy(pmlmepriv
->wps_assoc_resp_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2780 static int rtw_set_hidden_ssid(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2783 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2784 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2785 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
2786 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2790 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2793 if (param
->u
.wpa_param
.name
!= 0) /* dummy test... */
2794 DBG_88E("%s name(%u) != 0\n", __func__
, param
->u
.wpa_param
.name
);
2795 value
= param
->u
.wpa_param
.value
;
2797 /* use the same definition of hostapd's ignore_broadcast_ssid */
2798 if (value
!= 1 && value
!= 2)
2800 DBG_88E("%s value(%u)\n", __func__
, value
);
2801 pmlmeinfo
->hidden_ssid_mode
= value
;
2805 static int rtw_ioctl_acl_remove_sta(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2807 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2808 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2810 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2813 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2814 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2815 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2817 return rtw_acl_remove_sta(padapter
, param
->sta_addr
);
2820 static int rtw_ioctl_acl_add_sta(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2822 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2823 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2825 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2828 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2829 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2830 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2832 return rtw_acl_add_sta(padapter
, param
->sta_addr
);
2835 static int rtw_ioctl_set_macaddr_acl(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2838 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2839 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2841 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2844 rtw_set_macaddr_acl(padapter
, param
->u
.mlme
.command
);
2849 static int rtw_hostapd_ioctl(struct net_device
*dev
, struct iw_point
*p
)
2851 struct ieee_param
*param
;
2853 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2856 * this function is expect to call in master mode, which allows no power saving
2857 * so, we just check hw_init_completed
2860 if (!padapter
->hw_init_completed
) {
2870 param
= (struct ieee_param
*)rtw_malloc(p
->length
);
2876 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
2882 switch (param
->cmd
) {
2883 case RTL871X_HOSTAPD_FLUSH
:
2884 ret
= rtw_hostapd_sta_flush(dev
);
2886 case RTL871X_HOSTAPD_ADD_STA
:
2887 ret
= rtw_add_sta(dev
, param
);
2889 case RTL871X_HOSTAPD_REMOVE_STA
:
2890 ret
= rtw_del_sta(dev
, param
);
2892 case RTL871X_HOSTAPD_SET_BEACON
:
2893 ret
= rtw_set_beacon(dev
, param
, p
->length
);
2895 case RTL871X_SET_ENCRYPTION
:
2896 ret
= rtw_set_encryption(dev
, param
, p
->length
);
2898 case RTL871X_HOSTAPD_GET_WPAIE_STA
:
2899 ret
= rtw_get_sta_wpaie(dev
, param
);
2901 case RTL871X_HOSTAPD_SET_WPS_BEACON
:
2902 ret
= rtw_set_wps_beacon(dev
, param
, p
->length
);
2904 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP
:
2905 ret
= rtw_set_wps_probe_resp(dev
, param
, p
->length
);
2907 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP
:
2908 ret
= rtw_set_wps_assoc_resp(dev
, param
, p
->length
);
2910 case RTL871X_HOSTAPD_SET_HIDDEN_SSID
:
2911 ret
= rtw_set_hidden_ssid(dev
, param
, p
->length
);
2913 case RTL871X_HOSTAPD_GET_INFO_STA
:
2914 ret
= rtw_ioctl_get_sta_data(dev
, param
, p
->length
);
2916 case RTL871X_HOSTAPD_SET_MACADDR_ACL
:
2917 ret
= rtw_ioctl_set_macaddr_acl(dev
, param
, p
->length
);
2919 case RTL871X_HOSTAPD_ACL_ADD_STA
:
2920 ret
= rtw_ioctl_acl_add_sta(dev
, param
, p
->length
);
2922 case RTL871X_HOSTAPD_ACL_REMOVE_STA
:
2923 ret
= rtw_ioctl_acl_remove_sta(dev
, param
, p
->length
);
2926 DBG_88E("Unknown hostapd request: %d\n", param
->cmd
);
2931 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
2939 #include <rtw_android.h>
2940 static int rtw_wx_set_priv(struct net_device
*dev
,
2941 struct iw_request_info
*info
,
2942 union iwreq_data
*awrq
,
2948 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2949 struct iw_point
*dwrq
= (struct iw_point
*)awrq
;
2951 if (dwrq
->length
== 0)
2959 if (copy_from_user(ext
, dwrq
->pointer
, len
)) {
2964 /* added for wps2.0 @20110524 */
2965 if (dwrq
->flags
== 0x8766 && len
> 8) {
2967 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2968 u8
*probereq_wpsie
= ext
;
2969 int probereq_wpsie_len
= len
;
2970 u8 wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
2972 if ((_VENDOR_SPECIFIC_IE_
== probereq_wpsie
[0]) &&
2973 (!memcmp(&probereq_wpsie
[2], wps_oui
, 4))) {
2974 cp_sz
= min(probereq_wpsie_len
, MAX_WPS_IE_LEN
);
2976 pmlmepriv
->wps_probe_req_ie_len
= 0;
2977 kfree(pmlmepriv
->wps_probe_req_ie
);
2978 pmlmepriv
->wps_probe_req_ie
= NULL
;
2980 pmlmepriv
->wps_probe_req_ie
= rtw_malloc(cp_sz
);
2981 if (!pmlmepriv
->wps_probe_req_ie
) {
2982 pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2986 memcpy(pmlmepriv
->wps_probe_req_ie
, probereq_wpsie
, cp_sz
);
2987 pmlmepriv
->wps_probe_req_ie_len
= cp_sz
;
2992 if (len
>= WEXT_CSCAN_HEADER_SIZE
&&
2993 !memcmp(ext
, WEXT_CSCAN_HEADER
, WEXT_CSCAN_HEADER_SIZE
)) {
2994 ret
= rtw_wx_set_scan(dev
, info
, awrq
, ext
);
3005 static iw_handler rtw_handlers
[] = {
3006 NULL
, /* SIOCSIWCOMMIT */
3007 rtw_wx_get_name
, /* SIOCGIWNAME */
3008 dummy
, /* SIOCSIWNWID */
3009 dummy
, /* SIOCGIWNWID */
3010 rtw_wx_set_freq
, /* SIOCSIWFREQ */
3011 rtw_wx_get_freq
, /* SIOCGIWFREQ */
3012 rtw_wx_set_mode
, /* SIOCSIWMODE */
3013 rtw_wx_get_mode
, /* SIOCGIWMODE */
3014 dummy
, /* SIOCSIWSENS */
3015 rtw_wx_get_sens
, /* SIOCGIWSENS */
3016 NULL
, /* SIOCSIWRANGE */
3017 rtw_wx_get_range
, /* SIOCGIWRANGE */
3018 rtw_wx_set_priv
, /* SIOCSIWPRIV */
3019 NULL
, /* SIOCGIWPRIV */
3020 NULL
, /* SIOCSIWSTATS */
3021 NULL
, /* SIOCGIWSTATS */
3022 dummy
, /* SIOCSIWSPY */
3023 dummy
, /* SIOCGIWSPY */
3024 NULL
, /* SIOCGIWTHRSPY */
3025 NULL
, /* SIOCWIWTHRSPY */
3026 rtw_wx_set_wap
, /* SIOCSIWAP */
3027 rtw_wx_get_wap
, /* SIOCGIWAP */
3028 rtw_wx_set_mlme
, /* request MLME operation; uses struct iw_mlme */
3029 dummy
, /* SIOCGIWAPLIST -- depricated */
3030 rtw_wx_set_scan
, /* SIOCSIWSCAN */
3031 rtw_wx_get_scan
, /* SIOCGIWSCAN */
3032 rtw_wx_set_essid
, /* SIOCSIWESSID */
3033 rtw_wx_get_essid
, /* SIOCGIWESSID */
3034 dummy
, /* SIOCSIWNICKN */
3035 rtw_wx_get_nick
, /* SIOCGIWNICKN */
3036 NULL
, /* -- hole -- */
3037 NULL
, /* -- hole -- */
3038 rtw_wx_set_rate
, /* SIOCSIWRATE */
3039 rtw_wx_get_rate
, /* SIOCGIWRATE */
3040 rtw_wx_set_rts
, /* SIOCSIWRTS */
3041 rtw_wx_get_rts
, /* SIOCGIWRTS */
3042 rtw_wx_set_frag
, /* SIOCSIWFRAG */
3043 rtw_wx_get_frag
, /* SIOCGIWFRAG */
3044 dummy
, /* SIOCSIWTXPOW */
3045 dummy
, /* SIOCGIWTXPOW */
3046 dummy
, /* SIOCSIWRETRY */
3047 rtw_wx_get_retry
, /* SIOCGIWRETRY */
3048 rtw_wx_set_enc
, /* SIOCSIWENCODE */
3049 rtw_wx_get_enc
, /* SIOCGIWENCODE */
3050 dummy
, /* SIOCSIWPOWER */
3051 rtw_wx_get_power
, /* SIOCGIWPOWER */
3052 NULL
, /*---hole---*/
3053 NULL
, /*---hole---*/
3054 rtw_wx_set_gen_ie
, /* SIOCSIWGENIE */
3055 NULL
, /* SIOCGWGENIE */
3056 rtw_wx_set_auth
, /* SIOCSIWAUTH */
3057 NULL
, /* SIOCGIWAUTH */
3058 rtw_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
3059 NULL
, /* SIOCGIWENCODEEXT */
3060 rtw_wx_set_pmkid
, /* SIOCSIWPMKSA */
3061 NULL
, /*---hole---*/
3064 static struct iw_statistics
*rtw_get_wireless_stats(struct net_device
*dev
)
3066 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
3067 struct iw_statistics
*piwstats
= &padapter
->iwstats
;
3072 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
3073 piwstats
->qual
.qual
= 0;
3074 piwstats
->qual
.level
= 0;
3075 piwstats
->qual
.noise
= 0;
3077 tmp_level
= padapter
->recvpriv
.signal_strength
;
3078 tmp_qual
= padapter
->recvpriv
.signal_qual
;
3079 tmp_noise
= padapter
->recvpriv
.noise
;
3081 piwstats
->qual
.level
= tmp_level
;
3082 piwstats
->qual
.qual
= tmp_qual
;
3083 piwstats
->qual
.noise
= tmp_noise
;
3085 piwstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
;/* IW_QUAL_DBM; */
3086 return &padapter
->iwstats
;
3089 struct iw_handler_def rtw_handlers_def
= {
3090 .standard
= rtw_handlers
,
3091 .num_standard
= ARRAY_SIZE(rtw_handlers
),
3092 .get_wireless_stats
= rtw_get_wireless_stats
,
3095 int rtw_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
3097 struct iwreq
*wrq
= (struct iwreq
*)rq
;
3101 case RTL_IOCTL_WPA_SUPPLICANT
:
3102 ret
= wpa_supplicant_ioctl(dev
, &wrq
->u
.data
);
3104 #ifdef CONFIG_88EU_AP_MODE
3105 case RTL_IOCTL_HOSTAPD
:
3106 ret
= rtw_hostapd_ioctl(dev
, &wrq
->u
.data
);
3108 #endif /* CONFIG_88EU_AP_MODE */
3109 case (SIOCDEVPRIVATE
+1):
3110 ret
= rtw_android_priv_cmd(dev
, rq
, cmd
);