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
;
1398 memcpy(extra
, pcur_bss
->Ssid
.Ssid
, len
);
1403 wrqu
->essid
.length
= len
;
1404 wrqu
->essid
.flags
= 1;
1409 static int rtw_wx_set_rate(struct net_device
*dev
,
1410 struct iw_request_info
*a
,
1411 union iwreq_data
*wrqu
, char *extra
)
1414 u8 datarates
[NumRates
];
1415 u32 target_rate
= wrqu
->bitrate
.value
;
1416 u32 fixed
= wrqu
->bitrate
.fixed
;
1418 u8 mpdatarate
[NumRates
] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1421 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, (" rtw_wx_set_rate\n"));
1422 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("target_rate = %d, fixed = %d\n", target_rate
, fixed
));
1424 if (target_rate
== -1) {
1428 target_rate
= target_rate
/100000;
1430 switch (target_rate
) {
1474 for (i
= 0; i
< NumRates
; i
++) {
1475 if (ratevalue
== mpdatarate
[i
]) {
1476 datarates
[i
] = mpdatarate
[i
];
1480 datarates
[i
] = 0xff;
1483 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("datarate_inx =%d\n", datarates
[i
]));
1489 static int rtw_wx_get_rate(struct net_device
*dev
,
1490 struct iw_request_info
*info
,
1491 union iwreq_data
*wrqu
, char *extra
)
1495 max_rate
= rtw_get_cur_max_rate((struct adapter
*)rtw_netdev_priv(dev
));
1500 wrqu
->bitrate
.fixed
= 0; /* no auto select */
1501 wrqu
->bitrate
.value
= max_rate
* 100000;
1506 static int rtw_wx_set_rts(struct net_device
*dev
,
1507 struct iw_request_info
*info
,
1508 union iwreq_data
*wrqu
, char *extra
)
1510 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1513 if (wrqu
->rts
.disabled
) {
1514 padapter
->registrypriv
.rts_thresh
= 2347;
1516 if (wrqu
->rts
.value
< 0 ||
1517 wrqu
->rts
.value
> 2347)
1520 padapter
->registrypriv
.rts_thresh
= wrqu
->rts
.value
;
1523 DBG_88E("%s, rts_thresh =%d\n", __func__
, padapter
->registrypriv
.rts_thresh
);
1529 static int rtw_wx_get_rts(struct net_device
*dev
,
1530 struct iw_request_info
*info
,
1531 union iwreq_data
*wrqu
, char *extra
)
1533 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1536 DBG_88E("%s, rts_thresh =%d\n", __func__
, padapter
->registrypriv
.rts_thresh
);
1538 wrqu
->rts
.value
= padapter
->registrypriv
.rts_thresh
;
1539 wrqu
->rts
.fixed
= 0; /* no auto select */
1540 /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
1546 static int rtw_wx_set_frag(struct net_device
*dev
,
1547 struct iw_request_info
*info
,
1548 union iwreq_data
*wrqu
, char *extra
)
1550 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1553 if (wrqu
->frag
.disabled
) {
1554 padapter
->xmitpriv
.frag_len
= MAX_FRAG_THRESHOLD
;
1556 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
1557 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
1560 padapter
->xmitpriv
.frag_len
= wrqu
->frag
.value
& ~0x1;
1563 DBG_88E("%s, frag_len =%d\n", __func__
, padapter
->xmitpriv
.frag_len
);
1569 static int rtw_wx_get_frag(struct net_device
*dev
,
1570 struct iw_request_info
*info
,
1571 union iwreq_data
*wrqu
, char *extra
)
1573 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1576 DBG_88E("%s, frag_len =%d\n", __func__
, padapter
->xmitpriv
.frag_len
);
1578 wrqu
->frag
.value
= padapter
->xmitpriv
.frag_len
;
1579 wrqu
->frag
.fixed
= 0; /* no auto select */
1585 static int rtw_wx_get_retry(struct net_device
*dev
,
1586 struct iw_request_info
*info
,
1587 union iwreq_data
*wrqu
, char *extra
)
1589 wrqu
->retry
.value
= 7;
1590 wrqu
->retry
.fixed
= 0; /* no auto select */
1591 wrqu
->retry
.disabled
= 1;
1596 static int rtw_wx_set_enc(struct net_device
*dev
,
1597 struct iw_request_info
*info
,
1598 union iwreq_data
*wrqu
, char *keybuf
)
1601 u32 keyindex_provided
;
1602 struct ndis_802_11_wep wep
;
1603 enum ndis_802_11_auth_mode authmode
;
1605 struct iw_point
*erq
= &(wrqu
->encoding
);
1606 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1607 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
1609 DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq
->flags
);
1611 memset(&wep
, 0, sizeof(struct ndis_802_11_wep
));
1613 key
= erq
->flags
& IW_ENCODE_INDEX
;
1616 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1617 DBG_88E("EncryptionDisabled\n");
1618 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
1619 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1620 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1621 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1622 authmode
= Ndis802_11AuthModeOpen
;
1623 padapter
->securitypriv
.ndisauthtype
= authmode
;
1632 keyindex_provided
= 1;
1634 keyindex_provided
= 0;
1635 key
= padapter
->securitypriv
.dot11PrivacyKeyIndex
;
1636 DBG_88E("rtw_wx_set_enc, key =%d\n", key
);
1639 /* set authentication mode */
1640 if (erq
->flags
& IW_ENCODE_OPEN
) {
1641 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1642 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;/* Ndis802_11EncryptionDisabled; */
1643 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1644 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1645 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1646 authmode
= Ndis802_11AuthModeOpen
;
1647 padapter
->securitypriv
.ndisauthtype
= authmode
;
1648 } else if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
1649 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1650 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
1651 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Shared
;
1652 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
1653 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
1654 authmode
= Ndis802_11AuthModeShared
;
1655 padapter
->securitypriv
.ndisauthtype
= authmode
;
1657 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq
->flags
);
1659 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;/* Ndis802_11EncryptionDisabled; */
1660 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1661 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1662 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1663 authmode
= Ndis802_11AuthModeOpen
;
1664 padapter
->securitypriv
.ndisauthtype
= authmode
;
1668 if (erq
->length
> 0) {
1669 wep
.KeyLength
= erq
->length
<= 5 ? 5 : 13;
1671 wep
.Length
= wep
.KeyLength
+ offsetof(struct ndis_802_11_wep
, KeyMaterial
);
1675 if (keyindex_provided
== 1) {
1676 /* set key_id only, no given KeyMaterial(erq->length == 0). */
1677 padapter
->securitypriv
.dot11PrivacyKeyIndex
= key
;
1679 DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key
, padapter
->securitypriv
.dot11DefKeylen
[key
]);
1681 switch (padapter
->securitypriv
.dot11DefKeylen
[key
]) {
1683 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
1686 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
1689 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1697 wep
.KeyIndex
|= 0x80000000;
1699 memcpy(wep
.KeyMaterial
, keybuf
, wep
.KeyLength
);
1701 if (rtw_set_802_11_add_wep(padapter
, &wep
) == false) {
1702 if (rf_on
== pwrpriv
->rf_pwrstate
)
1713 static int rtw_wx_get_enc(struct net_device
*dev
,
1714 struct iw_request_info
*info
,
1715 union iwreq_data
*wrqu
, char *keybuf
)
1718 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1719 struct iw_point
*erq
= &(wrqu
->encoding
);
1720 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1723 if (check_fwstate(pmlmepriv
, _FW_LINKED
) != true) {
1724 if (!check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
1726 erq
->flags
|= IW_ENCODE_DISABLED
;
1731 key
= erq
->flags
& IW_ENCODE_INDEX
;
1738 key
= padapter
->securitypriv
.dot11PrivacyKeyIndex
;
1741 erq
->flags
= key
+ 1;
1743 switch (padapter
->securitypriv
.ndisencryptstatus
) {
1744 case Ndis802_11EncryptionNotSupported
:
1745 case Ndis802_11EncryptionDisabled
:
1747 erq
->flags
|= IW_ENCODE_DISABLED
;
1749 case Ndis802_11Encryption1Enabled
:
1750 erq
->length
= padapter
->securitypriv
.dot11DefKeylen
[key
];
1752 memcpy(keybuf
, padapter
->securitypriv
.dot11DefKey
[key
].skey
, padapter
->securitypriv
.dot11DefKeylen
[key
]);
1754 erq
->flags
|= IW_ENCODE_ENABLED
;
1756 if (padapter
->securitypriv
.ndisauthtype
== Ndis802_11AuthModeOpen
)
1757 erq
->flags
|= IW_ENCODE_OPEN
;
1758 else if (padapter
->securitypriv
.ndisauthtype
== Ndis802_11AuthModeShared
)
1759 erq
->flags
|= IW_ENCODE_RESTRICTED
;
1762 erq
->flags
|= IW_ENCODE_DISABLED
;
1765 case Ndis802_11Encryption2Enabled
:
1766 case Ndis802_11Encryption3Enabled
:
1768 erq
->flags
|= (IW_ENCODE_ENABLED
| IW_ENCODE_OPEN
| IW_ENCODE_NOKEY
);
1772 erq
->flags
|= IW_ENCODE_DISABLED
;
1779 static int rtw_wx_get_power(struct net_device
*dev
,
1780 struct iw_request_info
*info
,
1781 union iwreq_data
*wrqu
, char *extra
)
1783 wrqu
->power
.value
= 0;
1784 wrqu
->power
.fixed
= 0; /* no auto select */
1785 wrqu
->power
.disabled
= 1;
1790 static int rtw_wx_set_gen_ie(struct net_device
*dev
,
1791 struct iw_request_info
*info
,
1792 union iwreq_data
*wrqu
, char *extra
)
1794 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1796 return rtw_set_wpa_ie(padapter
, extra
, wrqu
->data
.length
);
1799 static int rtw_wx_set_auth(struct net_device
*dev
,
1800 struct iw_request_info
*info
,
1801 union iwreq_data
*wrqu
, char *extra
)
1803 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1804 struct iw_param
*param
= (struct iw_param
*)&(wrqu
->param
);
1807 switch (param
->flags
& IW_AUTH_INDEX
) {
1808 case IW_AUTH_WPA_VERSION
:
1810 case IW_AUTH_CIPHER_PAIRWISE
:
1813 case IW_AUTH_CIPHER_GROUP
:
1816 case IW_AUTH_KEY_MGMT
:
1818 * ??? does not use these parameters
1821 case IW_AUTH_TKIP_COUNTERMEASURES
:
1823 /* wpa_supplicant is enabling the tkip countermeasure. */
1824 padapter
->securitypriv
.btkip_countermeasure
= true;
1826 /* wpa_supplicant is disabling the tkip countermeasure. */
1827 padapter
->securitypriv
.btkip_countermeasure
= false;
1830 case IW_AUTH_DROP_UNENCRYPTED
:
1833 * wpa_supplicant calls set_wpa_enabled when the driver
1834 * is loaded and unloaded, regardless of if WPA is being
1835 * used. No other calls are made which can be used to
1836 * determine if encryption will be used or not prior to
1837 * association being expected. If encryption is not being
1838 * used, drop_unencrypted is set to false, else true -- we
1839 * can use this to determine if the CAP_PRIVACY_ON bit should
1843 if (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption1Enabled
)
1844 break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
1845 /* then it needn't reset it; */
1848 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
1849 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1850 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1851 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1852 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeOpen
;
1856 case IW_AUTH_80211_AUTH_ALG
:
1858 * It's the starting point of a link layer connection using wpa_supplicant
1860 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
1861 LeaveAllPowerSaveMode(padapter
);
1862 rtw_disassoc_cmd(padapter
, 500, false);
1863 DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__
);
1864 rtw_indicate_disconnect(padapter
);
1865 rtw_free_assoc_resources(padapter
);
1867 ret
= wpa_set_auth_algs(dev
, (u32
)param
->value
);
1869 case IW_AUTH_WPA_ENABLED
:
1871 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1873 case IW_AUTH_PRIVACY_INVOKED
:
1882 static int rtw_wx_set_enc_ext(struct net_device
*dev
,
1883 struct iw_request_info
*info
,
1884 union iwreq_data
*wrqu
, char *extra
)
1888 struct ieee_param
*param
= NULL
;
1889 struct iw_point
*pencoding
= &wrqu
->encoding
;
1890 struct iw_encode_ext
*pext
= (struct iw_encode_ext
*)extra
;
1893 param_len
= sizeof(struct ieee_param
) + pext
->key_len
;
1894 param
= (struct ieee_param
*)rtw_malloc(param_len
);
1898 memset(param
, 0, param_len
);
1900 param
->cmd
= IEEE_CMD_SET_ENCRYPTION
;
1901 eth_broadcast_addr(param
->sta_addr
);
1903 switch (pext
->alg
) {
1904 case IW_ENCODE_ALG_NONE
:
1905 /* todo: remove key */
1909 case IW_ENCODE_ALG_WEP
:
1912 case IW_ENCODE_ALG_TKIP
:
1915 case IW_ENCODE_ALG_CCMP
:
1923 strncpy((char *)param
->u
.crypt
.alg
, alg_name
, IEEE_CRYPT_ALG_NAME_LEN
);
1925 if (pext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
)
1926 param
->u
.crypt
.set_tx
= 1;
1928 /* cliW: WEP does not have group key
1929 * just not checking GROUP key setting
1931 if ((pext
->alg
!= IW_ENCODE_ALG_WEP
) &&
1932 (pext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
))
1933 param
->u
.crypt
.set_tx
= 0;
1935 param
->u
.crypt
.idx
= (pencoding
->flags
&0x00FF) - 1;
1937 if (pext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
)
1938 memcpy(param
->u
.crypt
.seq
, pext
->rx_seq
, 8);
1940 if (pext
->key_len
) {
1941 param
->u
.crypt
.key_len
= pext
->key_len
;
1942 memcpy(param
->u
.crypt
.key
, pext
+ 1, pext
->key_len
);
1945 ret
= wpa_set_encryption(dev
, param
, param_len
);
1952 static int rtw_wx_get_nick(struct net_device
*dev
,
1953 struct iw_request_info
*info
,
1954 union iwreq_data
*wrqu
, char *extra
)
1957 wrqu
->data
.length
= 14;
1958 wrqu
->data
.flags
= 1;
1959 memcpy(extra
, "<WIFI@REALTEK>", 14);
1962 /* dump debug info here */
1966 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1967 union iwreq_data
*wrqu
, char *b
)
1972 static int wpa_set_param(struct net_device
*dev
, u8 name
, u32 value
)
1975 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1978 case IEEE_PARAM_WPA_ENABLED
:
1979 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
; /* 802.1x */
1980 switch ((value
)&0xff) {
1982 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPAPSK
; /* WPA_PSK */
1983 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
1986 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPA2PSK
; /* WPA2_PSK */
1987 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
1990 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1991 ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter
->securitypriv
.ndisauthtype
));
1993 case IEEE_PARAM_TKIP_COUNTERMEASURES
:
1995 case IEEE_PARAM_DROP_UNENCRYPTED
: {
1998 * wpa_supplicant calls set_wpa_enabled when the driver
1999 * is loaded and unloaded, regardless of if WPA is being
2000 * used. No other calls are made which can be used to
2001 * determine if encryption will be used or not prior to
2002 * association being expected. If encryption is not being
2003 * used, drop_unencrypted is set to false, else true -- we
2004 * can use this to determine if the CAP_PRIVACY_ON bit should
2010 case IEEE_PARAM_PRIVACY_INVOKED
:
2013 case IEEE_PARAM_AUTH_ALGS
:
2014 ret
= wpa_set_auth_algs(dev
, value
);
2016 case IEEE_PARAM_IEEE_802_1X
:
2018 case IEEE_PARAM_WPAX_SELECT
:
2027 static int wpa_mlme(struct net_device
*dev
, u32 command
, u32 reason
)
2030 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2033 case IEEE_MLME_STA_DEAUTH
:
2034 if (!rtw_set_802_11_disassociate(padapter
))
2037 case IEEE_MLME_STA_DISASSOC
:
2038 if (!rtw_set_802_11_disassociate(padapter
))
2049 static int wpa_supplicant_ioctl(struct net_device
*dev
, struct iw_point
*p
)
2051 struct ieee_param
*param
;
2054 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
) {
2059 param
= (struct ieee_param
*)rtw_malloc(p
->length
);
2065 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
2071 switch (param
->cmd
) {
2072 case IEEE_CMD_SET_WPA_PARAM
:
2073 ret
= wpa_set_param(dev
, param
->u
.wpa_param
.name
, param
->u
.wpa_param
.value
);
2076 case IEEE_CMD_SET_WPA_IE
:
2077 ret
= rtw_set_wpa_ie((struct adapter
*)rtw_netdev_priv(dev
),
2078 (char *)param
->u
.wpa_ie
.data
, (u16
)param
->u
.wpa_ie
.len
);
2081 case IEEE_CMD_SET_ENCRYPTION
:
2082 ret
= wpa_set_encryption(dev
, param
, p
->length
);
2086 ret
= wpa_mlme(dev
, param
->u
.mlme
.command
, param
->u
.mlme
.reason_code
);
2090 DBG_88E("Unknown WPA supplicant request: %d\n", param
->cmd
);
2095 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
2105 #ifdef CONFIG_88EU_AP_MODE
2106 static u8
set_pairwise_key(struct adapter
*padapter
, struct sta_info
*psta
)
2108 struct cmd_obj
*ph2c
;
2109 struct set_stakey_parm
*psetstakey_para
;
2110 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
2113 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
2119 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_KERNEL
);
2120 if (!psetstakey_para
) {
2126 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
2128 psetstakey_para
->algorithm
= (u8
)psta
->dot118021XPrivacy
;
2130 memcpy(psetstakey_para
->addr
, psta
->hwaddr
, ETH_ALEN
);
2132 memcpy(psetstakey_para
->key
, &psta
->dot118021x_UncstKey
, 16);
2134 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
2141 static int set_group_key(struct adapter
*padapter
, u8
*key
, u8 alg
, int keyid
)
2144 struct cmd_obj
*pcmd
;
2145 struct setkey_parm
*psetkeyparm
;
2146 struct cmd_priv
*pcmdpriv
= &(padapter
->cmdpriv
);
2149 DBG_88E("%s\n", __func__
);
2151 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
2156 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
2163 psetkeyparm
->keyid
= (u8
)keyid
;
2165 psetkeyparm
->algorithm
= alg
;
2167 psetkeyparm
->set_tx
= 1;
2183 memcpy(&(psetkeyparm
->key
[0]), key
, keylen
);
2185 pcmd
->cmdcode
= _SetKey_CMD_
;
2186 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
2187 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
2191 INIT_LIST_HEAD(&pcmd
->list
);
2193 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
2200 static int set_wep_key(struct adapter
*padapter
, u8
*key
, u8 keylen
, int keyid
)
2215 return set_group_key(padapter
, key
, alg
, keyid
);
2218 static int rtw_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
2221 u32 wep_key_idx
, wep_key_len
, wep_total_len
;
2222 struct ndis_802_11_wep
*pwep
= NULL
;
2223 struct sta_info
*psta
= NULL
, *pbcmc_sta
= NULL
;
2224 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2225 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2226 struct security_priv
*psecuritypriv
= &(padapter
->securitypriv
);
2227 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2229 DBG_88E("%s\n", __func__
);
2230 param
->u
.crypt
.err
= 0;
2231 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
2232 if (param_len
!= sizeof(struct ieee_param
) + param
->u
.crypt
.key_len
) {
2236 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2237 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2238 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff) {
2239 if (param
->u
.crypt
.idx
>= WEP_KEYS
) {
2244 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2246 DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
2251 if (strcmp(param
->u
.crypt
.alg
, "none") == 0 && (!psta
)) {
2252 /* todo:clear default encryption keys */
2254 DBG_88E("clear default encryption keys, keyid =%d\n", param
->u
.crypt
.idx
);
2257 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0 && (!psta
)) {
2258 DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
2259 wep_key_idx
= param
->u
.crypt
.idx
;
2260 wep_key_len
= param
->u
.crypt
.key_len
;
2261 DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx
, wep_key_len
);
2262 if ((wep_key_idx
>= WEP_KEYS
) || (wep_key_len
<= 0)) {
2267 if (wep_key_len
> 0) {
2268 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
2269 wep_total_len
= wep_key_len
+ offsetof(struct ndis_802_11_wep
, KeyMaterial
);
2270 pwep
= (struct ndis_802_11_wep
*)rtw_malloc(wep_total_len
);
2272 DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
2276 memset(pwep
, 0, wep_total_len
);
2278 pwep
->KeyLength
= wep_key_len
;
2279 pwep
->Length
= wep_total_len
;
2282 pwep
->KeyIndex
= wep_key_idx
;
2284 memcpy(pwep
->KeyMaterial
, param
->u
.crypt
.key
, pwep
->KeyLength
);
2286 if (param
->u
.crypt
.set_tx
) {
2287 DBG_88E("wep, set_tx = 1\n");
2289 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2290 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP40_
;
2291 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2293 if (pwep
->KeyLength
== 13) {
2294 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP104_
;
2295 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2298 psecuritypriv
->dot11PrivacyKeyIndex
= wep_key_idx
;
2300 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
2302 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
2304 set_wep_key(padapter
, pwep
->KeyMaterial
, pwep
->KeyLength
, wep_key_idx
);
2306 DBG_88E("wep, set_tx = 0\n");
2308 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
2309 /* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
2311 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
2313 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
2315 set_wep_key(padapter
, pwep
->KeyMaterial
, pwep
->KeyLength
, wep_key_idx
);
2321 if (!psta
&& check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) { /* group key */
2322 if (param
->u
.crypt
.set_tx
== 1) {
2323 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2324 DBG_88E("%s, set group_key, WEP\n", __func__
);
2326 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2327 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2329 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2330 if (param
->u
.crypt
.key_len
== 13)
2331 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2332 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2333 DBG_88E("%s, set group_key, TKIP\n", __func__
);
2334 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
2335 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2336 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2338 memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
2339 memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
2341 psecuritypriv
->busetkipkey
= true;
2342 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2343 DBG_88E("%s, set group_key, CCMP\n", __func__
);
2344 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
2345 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2346 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2348 DBG_88E("%s, set group_key, none\n", __func__
);
2349 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2351 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
2352 psecuritypriv
->binstallGrpkey
= true;
2353 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;/* */
2354 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
2355 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
2357 pbcmc_sta
->ieee8021x_blocked
= false;
2358 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;/* rx will use bmc_sta's dot118021XPrivacy */
2364 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
&& psta
) { /* psk/802_1x */
2365 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
2366 if (param
->u
.crypt
.set_tx
== 1) {
2367 memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2369 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2370 DBG_88E("%s, set pairwise key, WEP\n", __func__
);
2372 psta
->dot118021XPrivacy
= _WEP40_
;
2373 if (param
->u
.crypt
.key_len
== 13)
2374 psta
->dot118021XPrivacy
= _WEP104_
;
2375 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2376 DBG_88E("%s, set pairwise key, TKIP\n", __func__
);
2378 psta
->dot118021XPrivacy
= _TKIP_
;
2381 memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
2382 memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
2384 psecuritypriv
->busetkipkey
= true;
2385 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2386 DBG_88E("%s, set pairwise key, CCMP\n", __func__
);
2388 psta
->dot118021XPrivacy
= _AES_
;
2390 DBG_88E("%s, set pairwise key, none\n", __func__
);
2392 psta
->dot118021XPrivacy
= _NO_PRIVACY_
;
2395 set_pairwise_key(padapter
, psta
);
2397 psta
->ieee8021x_blocked
= false;
2398 } else { /* group key??? */
2399 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2400 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2401 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2402 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2403 if (param
->u
.crypt
.key_len
== 13)
2404 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2405 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2406 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
2408 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2409 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2412 memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
2413 memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
2415 psecuritypriv
->busetkipkey
= true;
2416 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2417 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
2419 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2420 param
->u
.crypt
.key
, min_t(u16
, param
->u
.crypt
.key_len
, 16));
2422 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2425 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
2427 psecuritypriv
->binstallGrpkey
= true;
2429 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;/* */
2431 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
2433 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
2435 pbcmc_sta
->ieee8021x_blocked
= false;
2436 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;/* rx will use bmc_sta's dot118021XPrivacy */
2449 static int rtw_set_beacon(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2452 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2453 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2454 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2455 unsigned char *pbuf
= param
->u
.bcn_ie
.buf
;
2457 DBG_88E("%s, len =%d\n", __func__
, len
);
2459 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2462 memcpy(&pstapriv
->max_num_sta
, param
->u
.bcn_ie
.reserved
, 2);
2464 if ((pstapriv
->max_num_sta
> NUM_STA
) || (pstapriv
->max_num_sta
<= 0))
2465 pstapriv
->max_num_sta
= NUM_STA
;
2467 if (rtw_check_beacon_data(padapter
, pbuf
, (len
-12-2)) == _SUCCESS
)/* 12 = param header, 2:no packed */
2475 static int rtw_hostapd_sta_flush(struct net_device
*dev
)
2477 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2479 DBG_88E("%s\n", __func__
);
2481 flush_all_cam_entry(padapter
); /* clear CAM */
2483 return rtw_sta_flush(padapter
);
2486 static int rtw_add_sta(struct net_device
*dev
, struct ieee_param
*param
)
2489 struct sta_info
*psta
= NULL
;
2490 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2491 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2492 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2494 DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param
->u
.add_sta
.aid
, (param
->sta_addr
));
2496 if (!check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)))
2499 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2500 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2501 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2504 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2506 int flags
= param
->u
.add_sta
.flags
;
2508 psta
->aid
= param
->u
.add_sta
.aid
;/* aid = 1~2007 */
2510 memcpy(psta
->bssrateset
, param
->u
.add_sta
.tx_supp_rates
, 16);
2512 /* check wmm cap. */
2513 if (WLAN_STA_WME
&flags
)
2514 psta
->qos_option
= 1;
2516 psta
->qos_option
= 0;
2518 if (pmlmepriv
->qospriv
.qos_option
== 0)
2519 psta
->qos_option
= 0;
2521 /* chec 802.11n ht cap. */
2522 if (WLAN_STA_HT
&flags
) {
2523 psta
->htpriv
.ht_option
= true;
2524 psta
->qos_option
= 1;
2525 memcpy(&psta
->htpriv
.ht_cap
, ¶m
->u
.add_sta
.ht_cap
,
2526 sizeof(struct ieee80211_ht_cap
));
2528 psta
->htpriv
.ht_option
= false;
2531 if (pmlmepriv
->htpriv
.ht_option
== false)
2532 psta
->htpriv
.ht_option
= false;
2534 update_sta_info_apmode(padapter
, psta
);
2542 static int rtw_del_sta(struct net_device
*dev
, struct ieee_param
*param
)
2545 struct sta_info
*psta
= NULL
;
2546 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2547 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2548 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2551 DBG_88E("rtw_del_sta =%pM\n", (param
->sta_addr
));
2553 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2556 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2557 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2558 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2561 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2563 spin_lock_bh(&pstapriv
->asoc_list_lock
);
2564 if (!list_empty(&psta
->asoc_list
)) {
2565 list_del_init(&psta
->asoc_list
);
2566 pstapriv
->asoc_list_cnt
--;
2567 updated
= ap_free_sta(padapter
, psta
, true, WLAN_REASON_DEAUTH_LEAVING
);
2569 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
2570 associated_clients_update(padapter
, updated
);
2573 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
2579 static int rtw_ioctl_get_sta_data(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2582 struct sta_info
*psta
= NULL
;
2583 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2584 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2585 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2586 struct ieee_param_ex
*param_ex
= (struct ieee_param_ex
*)param
;
2587 struct sta_data
*psta_data
= (struct sta_data
*)param_ex
->data
;
2589 DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex
->sta_addr
));
2591 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2594 if (param_ex
->sta_addr
[0] == 0xff && param_ex
->sta_addr
[1] == 0xff &&
2595 param_ex
->sta_addr
[2] == 0xff && param_ex
->sta_addr
[3] == 0xff &&
2596 param_ex
->sta_addr
[4] == 0xff && param_ex
->sta_addr
[5] == 0xff)
2599 psta
= rtw_get_stainfo(pstapriv
, param_ex
->sta_addr
);
2601 psta_data
->aid
= (u16
)psta
->aid
;
2602 psta_data
->capability
= psta
->capability
;
2603 psta_data
->flags
= psta
->flags
;
2607 no_short_slot_time_set : BIT(1)
2608 no_short_preamble_set : BIT(2)
2609 no_ht_gf_set : BIT(3)
2611 ht_20mhz_set : BIT(5)
2614 psta_data
->sta_set
= ((psta
->nonerp_set
) |
2615 (psta
->no_short_slot_time_set
<< 1) |
2616 (psta
->no_short_preamble_set
<< 2) |
2617 (psta
->no_ht_gf_set
<< 3) |
2618 (psta
->no_ht_set
<< 4) |
2619 (psta
->ht_20mhz_set
<< 5));
2620 psta_data
->tx_supp_rates_len
= psta
->bssratelen
;
2621 memcpy(psta_data
->tx_supp_rates
, psta
->bssrateset
, psta
->bssratelen
);
2622 memcpy(&psta_data
->ht_cap
,
2623 &psta
->htpriv
.ht_cap
, sizeof(struct ieee80211_ht_cap
));
2624 psta_data
->rx_pkts
= psta
->sta_stats
.rx_data_pkts
;
2625 psta_data
->rx_bytes
= psta
->sta_stats
.rx_bytes
;
2626 psta_data
->rx_drops
= psta
->sta_stats
.rx_drops
;
2627 psta_data
->tx_pkts
= psta
->sta_stats
.tx_pkts
;
2628 psta_data
->tx_bytes
= psta
->sta_stats
.tx_bytes
;
2629 psta_data
->tx_drops
= psta
->sta_stats
.tx_drops
;
2637 static int rtw_get_sta_wpaie(struct net_device
*dev
, struct ieee_param
*param
)
2640 struct sta_info
*psta
= NULL
;
2641 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2642 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2643 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2645 DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param
->sta_addr
));
2647 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2650 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2651 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2652 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2655 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2657 if (psta
->wpa_ie
[0] == WLAN_EID_RSN
||
2658 psta
->wpa_ie
[0] == WLAN_EID_VENDOR_SPECIFIC
) {
2662 wpa_ie_len
= psta
->wpa_ie
[1];
2663 copy_len
= min_t(int, wpa_ie_len
+ 2, sizeof(psta
->wpa_ie
));
2664 param
->u
.wpa_ie
.len
= copy_len
;
2665 memcpy(param
->u
.wpa_ie
.reserved
, psta
->wpa_ie
, copy_len
);
2667 DBG_88E("sta's wpa_ie is NONE\n");
2676 static int rtw_set_wps_beacon(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2679 unsigned char wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
2680 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2681 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2682 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
2685 DBG_88E("%s, len =%d\n", __func__
, len
);
2687 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2690 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2692 kfree(pmlmepriv
->wps_beacon_ie
);
2693 pmlmepriv
->wps_beacon_ie
= NULL
;
2696 pmlmepriv
->wps_beacon_ie
= rtw_malloc(ie_len
);
2697 pmlmepriv
->wps_beacon_ie_len
= ie_len
;
2698 if (!pmlmepriv
->wps_beacon_ie
) {
2699 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2703 memcpy(pmlmepriv
->wps_beacon_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2705 update_beacon(padapter
, _VENDOR_SPECIFIC_IE_
, wps_oui
, true);
2707 pmlmeext
->bstart_bss
= true;
2713 static int rtw_set_wps_probe_resp(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2716 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2717 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2720 DBG_88E("%s, len =%d\n", __func__
, len
);
2722 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2725 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2727 kfree(pmlmepriv
->wps_probe_resp_ie
);
2728 pmlmepriv
->wps_probe_resp_ie
= NULL
;
2731 pmlmepriv
->wps_probe_resp_ie
= rtw_malloc(ie_len
);
2732 pmlmepriv
->wps_probe_resp_ie_len
= ie_len
;
2733 if (!pmlmepriv
->wps_probe_resp_ie
) {
2734 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2737 memcpy(pmlmepriv
->wps_probe_resp_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2743 static int rtw_set_wps_assoc_resp(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2746 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2747 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2750 DBG_88E("%s, len =%d\n", __func__
, len
);
2752 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2755 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2757 kfree(pmlmepriv
->wps_assoc_resp_ie
);
2758 pmlmepriv
->wps_assoc_resp_ie
= NULL
;
2761 pmlmepriv
->wps_assoc_resp_ie
= rtw_malloc(ie_len
);
2762 pmlmepriv
->wps_assoc_resp_ie_len
= ie_len
;
2763 if (!pmlmepriv
->wps_assoc_resp_ie
) {
2764 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2768 memcpy(pmlmepriv
->wps_assoc_resp_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2774 static int rtw_set_hidden_ssid(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2777 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2778 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2779 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
2780 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2784 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2787 if (param
->u
.wpa_param
.name
!= 0) /* dummy test... */
2788 DBG_88E("%s name(%u) != 0\n", __func__
, param
->u
.wpa_param
.name
);
2789 value
= param
->u
.wpa_param
.value
;
2791 /* use the same definition of hostapd's ignore_broadcast_ssid */
2792 if (value
!= 1 && value
!= 2)
2794 DBG_88E("%s value(%u)\n", __func__
, value
);
2795 pmlmeinfo
->hidden_ssid_mode
= value
;
2799 static int rtw_ioctl_acl_remove_sta(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2801 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2802 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2804 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2807 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2808 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2809 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2811 return rtw_acl_remove_sta(padapter
, param
->sta_addr
);
2814 static int rtw_ioctl_acl_add_sta(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2816 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2817 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2819 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2822 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2823 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2824 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2826 return rtw_acl_add_sta(padapter
, param
->sta_addr
);
2829 static int rtw_ioctl_set_macaddr_acl(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2832 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2833 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2835 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2838 rtw_set_macaddr_acl(padapter
, param
->u
.mlme
.command
);
2843 static int rtw_hostapd_ioctl(struct net_device
*dev
, struct iw_point
*p
)
2845 struct ieee_param
*param
;
2847 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2850 * this function is expect to call in master mode, which allows no power saving
2851 * so, we just check hw_init_completed
2854 if (!padapter
->hw_init_completed
) {
2864 param
= (struct ieee_param
*)rtw_malloc(p
->length
);
2870 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
2876 switch (param
->cmd
) {
2877 case RTL871X_HOSTAPD_FLUSH
:
2878 ret
= rtw_hostapd_sta_flush(dev
);
2880 case RTL871X_HOSTAPD_ADD_STA
:
2881 ret
= rtw_add_sta(dev
, param
);
2883 case RTL871X_HOSTAPD_REMOVE_STA
:
2884 ret
= rtw_del_sta(dev
, param
);
2886 case RTL871X_HOSTAPD_SET_BEACON
:
2887 ret
= rtw_set_beacon(dev
, param
, p
->length
);
2889 case RTL871X_SET_ENCRYPTION
:
2890 ret
= rtw_set_encryption(dev
, param
, p
->length
);
2892 case RTL871X_HOSTAPD_GET_WPAIE_STA
:
2893 ret
= rtw_get_sta_wpaie(dev
, param
);
2895 case RTL871X_HOSTAPD_SET_WPS_BEACON
:
2896 ret
= rtw_set_wps_beacon(dev
, param
, p
->length
);
2898 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP
:
2899 ret
= rtw_set_wps_probe_resp(dev
, param
, p
->length
);
2901 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP
:
2902 ret
= rtw_set_wps_assoc_resp(dev
, param
, p
->length
);
2904 case RTL871X_HOSTAPD_SET_HIDDEN_SSID
:
2905 ret
= rtw_set_hidden_ssid(dev
, param
, p
->length
);
2907 case RTL871X_HOSTAPD_GET_INFO_STA
:
2908 ret
= rtw_ioctl_get_sta_data(dev
, param
, p
->length
);
2910 case RTL871X_HOSTAPD_SET_MACADDR_ACL
:
2911 ret
= rtw_ioctl_set_macaddr_acl(dev
, param
, p
->length
);
2913 case RTL871X_HOSTAPD_ACL_ADD_STA
:
2914 ret
= rtw_ioctl_acl_add_sta(dev
, param
, p
->length
);
2916 case RTL871X_HOSTAPD_ACL_REMOVE_STA
:
2917 ret
= rtw_ioctl_acl_remove_sta(dev
, param
, p
->length
);
2920 DBG_88E("Unknown hostapd request: %d\n", param
->cmd
);
2925 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
2933 #include <rtw_android.h>
2934 static int rtw_wx_set_priv(struct net_device
*dev
,
2935 struct iw_request_info
*info
,
2936 union iwreq_data
*awrq
,
2942 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2943 struct iw_point
*dwrq
= (struct iw_point
*)awrq
;
2945 if (dwrq
->length
== 0)
2953 if (copy_from_user(ext
, dwrq
->pointer
, len
)) {
2958 /* added for wps2.0 @20110524 */
2959 if (dwrq
->flags
== 0x8766 && len
> 8) {
2961 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2962 u8
*probereq_wpsie
= ext
;
2963 int probereq_wpsie_len
= len
;
2964 u8 wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
2966 if ((_VENDOR_SPECIFIC_IE_
== probereq_wpsie
[0]) &&
2967 (!memcmp(&probereq_wpsie
[2], wps_oui
, 4))) {
2968 cp_sz
= min(probereq_wpsie_len
, MAX_WPS_IE_LEN
);
2970 pmlmepriv
->wps_probe_req_ie_len
= 0;
2971 kfree(pmlmepriv
->wps_probe_req_ie
);
2972 pmlmepriv
->wps_probe_req_ie
= NULL
;
2974 pmlmepriv
->wps_probe_req_ie
= rtw_malloc(cp_sz
);
2975 if (!pmlmepriv
->wps_probe_req_ie
) {
2976 pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2980 memcpy(pmlmepriv
->wps_probe_req_ie
, probereq_wpsie
, cp_sz
);
2981 pmlmepriv
->wps_probe_req_ie_len
= cp_sz
;
2986 if (len
>= WEXT_CSCAN_HEADER_SIZE
&&
2987 !memcmp(ext
, WEXT_CSCAN_HEADER
, WEXT_CSCAN_HEADER_SIZE
)) {
2988 ret
= rtw_wx_set_scan(dev
, info
, awrq
, ext
);
2999 static iw_handler rtw_handlers
[] = {
3000 NULL
, /* SIOCSIWCOMMIT */
3001 rtw_wx_get_name
, /* SIOCGIWNAME */
3002 dummy
, /* SIOCSIWNWID */
3003 dummy
, /* SIOCGIWNWID */
3004 rtw_wx_set_freq
, /* SIOCSIWFREQ */
3005 rtw_wx_get_freq
, /* SIOCGIWFREQ */
3006 rtw_wx_set_mode
, /* SIOCSIWMODE */
3007 rtw_wx_get_mode
, /* SIOCGIWMODE */
3008 dummy
, /* SIOCSIWSENS */
3009 rtw_wx_get_sens
, /* SIOCGIWSENS */
3010 NULL
, /* SIOCSIWRANGE */
3011 rtw_wx_get_range
, /* SIOCGIWRANGE */
3012 rtw_wx_set_priv
, /* SIOCSIWPRIV */
3013 NULL
, /* SIOCGIWPRIV */
3014 NULL
, /* SIOCSIWSTATS */
3015 NULL
, /* SIOCGIWSTATS */
3016 dummy
, /* SIOCSIWSPY */
3017 dummy
, /* SIOCGIWSPY */
3018 NULL
, /* SIOCGIWTHRSPY */
3019 NULL
, /* SIOCWIWTHRSPY */
3020 rtw_wx_set_wap
, /* SIOCSIWAP */
3021 rtw_wx_get_wap
, /* SIOCGIWAP */
3022 rtw_wx_set_mlme
, /* request MLME operation; uses struct iw_mlme */
3023 dummy
, /* SIOCGIWAPLIST -- depricated */
3024 rtw_wx_set_scan
, /* SIOCSIWSCAN */
3025 rtw_wx_get_scan
, /* SIOCGIWSCAN */
3026 rtw_wx_set_essid
, /* SIOCSIWESSID */
3027 rtw_wx_get_essid
, /* SIOCGIWESSID */
3028 dummy
, /* SIOCSIWNICKN */
3029 rtw_wx_get_nick
, /* SIOCGIWNICKN */
3030 NULL
, /* -- hole -- */
3031 NULL
, /* -- hole -- */
3032 rtw_wx_set_rate
, /* SIOCSIWRATE */
3033 rtw_wx_get_rate
, /* SIOCGIWRATE */
3034 rtw_wx_set_rts
, /* SIOCSIWRTS */
3035 rtw_wx_get_rts
, /* SIOCGIWRTS */
3036 rtw_wx_set_frag
, /* SIOCSIWFRAG */
3037 rtw_wx_get_frag
, /* SIOCGIWFRAG */
3038 dummy
, /* SIOCSIWTXPOW */
3039 dummy
, /* SIOCGIWTXPOW */
3040 dummy
, /* SIOCSIWRETRY */
3041 rtw_wx_get_retry
, /* SIOCGIWRETRY */
3042 rtw_wx_set_enc
, /* SIOCSIWENCODE */
3043 rtw_wx_get_enc
, /* SIOCGIWENCODE */
3044 dummy
, /* SIOCSIWPOWER */
3045 rtw_wx_get_power
, /* SIOCGIWPOWER */
3046 NULL
, /*---hole---*/
3047 NULL
, /*---hole---*/
3048 rtw_wx_set_gen_ie
, /* SIOCSIWGENIE */
3049 NULL
, /* SIOCGWGENIE */
3050 rtw_wx_set_auth
, /* SIOCSIWAUTH */
3051 NULL
, /* SIOCGIWAUTH */
3052 rtw_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
3053 NULL
, /* SIOCGIWENCODEEXT */
3054 rtw_wx_set_pmkid
, /* SIOCSIWPMKSA */
3055 NULL
, /*---hole---*/
3058 static struct iw_statistics
*rtw_get_wireless_stats(struct net_device
*dev
)
3060 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
3061 struct iw_statistics
*piwstats
= &padapter
->iwstats
;
3066 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
3067 piwstats
->qual
.qual
= 0;
3068 piwstats
->qual
.level
= 0;
3069 piwstats
->qual
.noise
= 0;
3071 tmp_level
= padapter
->recvpriv
.signal_strength
;
3072 tmp_qual
= padapter
->recvpriv
.signal_qual
;
3073 tmp_noise
= padapter
->recvpriv
.noise
;
3075 piwstats
->qual
.level
= tmp_level
;
3076 piwstats
->qual
.qual
= tmp_qual
;
3077 piwstats
->qual
.noise
= tmp_noise
;
3079 piwstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
;/* IW_QUAL_DBM; */
3080 return &padapter
->iwstats
;
3083 struct iw_handler_def rtw_handlers_def
= {
3084 .standard
= rtw_handlers
,
3085 .num_standard
= ARRAY_SIZE(rtw_handlers
),
3086 .get_wireless_stats
= rtw_get_wireless_stats
,
3089 int rtw_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
3091 struct iwreq
*wrq
= (struct iwreq
*)rq
;
3095 case RTL_IOCTL_WPA_SUPPLICANT
:
3096 ret
= wpa_supplicant_ioctl(dev
, &wrq
->u
.data
);
3098 #ifdef CONFIG_88EU_AP_MODE
3099 case RTL_IOCTL_HOSTAPD
:
3100 ret
= rtw_hostapd_ioctl(dev
, &wrq
->u
.data
);
3102 #endif /* CONFIG_88EU_AP_MODE */
3103 case (SIOCDEVPRIVATE
+1):
3104 ret
= rtw_android_priv_cmd(dev
, rq
, cmd
);