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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _IOCTL_LINUX_C_
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <wlan_bssdef.h>
25 #include <rtw_debug.h>
28 #include <rtw_mlme_ext.h>
29 #include <rtw_ioctl.h>
30 #include <rtw_ioctl_set.h>
31 #include <rtl8188e_hal.h>
34 #include <linux/vmalloc.h>
35 #include "osdep_intf.h"
37 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
39 #define SCAN_ITEM_SIZE 768
40 #define MAX_CUSTOM_LEN 64
44 #define WEXT_CSCAN_AMOUNT 9
45 #define WEXT_CSCAN_BUF_LEN 360
46 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
47 #define WEXT_CSCAN_HEADER_SIZE 12
48 #define WEXT_CSCAN_SSID_SECTION 'S'
49 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
50 #define WEXT_CSCAN_NPROBE_SECTION 'N'
51 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
52 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
53 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
54 #define WEXT_CSCAN_TYPE_SECTION 'T'
56 static u32 rtw_rates
[] = {1000000, 2000000, 5500000, 11000000,
57 6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
60 static const char * const iw_operation_mode
[] = {
61 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater",
62 "Secondary", "Monitor"
65 void indicate_wx_scan_complete_event(struct adapter
*padapter
)
67 union iwreq_data wrqu
;
69 memset(&wrqu
, 0, sizeof(union iwreq_data
));
70 wireless_send_event(padapter
->pnetdev
, SIOCGIWSCAN
, &wrqu
, NULL
);
73 void rtw_indicate_wx_assoc_event(struct adapter
*padapter
)
75 union iwreq_data wrqu
;
76 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
78 memset(&wrqu
, 0, sizeof(union iwreq_data
));
80 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
82 memcpy(wrqu
.ap_addr
.sa_data
, pmlmepriv
->cur_network
.network
.MacAddress
, ETH_ALEN
);
84 DBG_88E_LEVEL(_drv_always_
, "assoc success\n");
85 wireless_send_event(padapter
->pnetdev
, SIOCGIWAP
, &wrqu
, NULL
);
88 void rtw_indicate_wx_disassoc_event(struct adapter
*padapter
)
90 union iwreq_data wrqu
;
92 memset(&wrqu
, 0, sizeof(union iwreq_data
));
94 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
95 memset(wrqu
.ap_addr
.sa_data
, 0, ETH_ALEN
);
97 DBG_88E_LEVEL(_drv_always_
, "indicate disassoc\n");
98 wireless_send_event(padapter
->pnetdev
, SIOCGIWAP
, &wrqu
, NULL
);
101 static char *translate_scan(struct adapter
*padapter
,
102 struct iw_request_info
*info
,
103 struct wlan_network
*pnetwork
,
104 char *start
, char *stop
)
106 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
111 char custom
[MAX_CUSTOM_LEN
];
113 u16 max_rate
= 0, rate
, ht_cap
= false;
115 u8 bw_40MHz
= 0, short_GI
= 0;
121 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
123 memcpy(iwe
.u
.ap_addr
.sa_data
, pnetwork
->network
.MacAddress
, ETH_ALEN
);
124 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_ADDR_LEN
);
127 iwe
.cmd
= SIOCGIWESSID
;
128 iwe
.u
.data
.flags
= 1;
129 iwe
.u
.data
.length
= min_t(u16
, pnetwork
->network
.Ssid
.SsidLength
, 32);
130 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, pnetwork
->network
.Ssid
.Ssid
);
132 /* parsing HT_CAP_IE */
133 p
= rtw_get_ie(&pnetwork
->network
.IEs
[12], _HT_CAPABILITY_IE_
, &ht_ielen
, pnetwork
->network
.IELength
-12);
135 if (p
&& ht_ielen
> 0) {
136 struct rtw_ieee80211_ht_cap
*pht_capie
;
138 pht_capie
= (struct rtw_ieee80211_ht_cap
*)(p
+2);
139 memcpy(&mcs_rate
, pht_capie
->supp_mcs_set
, 2);
140 bw_40MHz
= (pht_capie
->cap_info
&IEEE80211_HT_CAP_SUP_WIDTH
) ? 1 : 0;
141 short_GI
= (pht_capie
->cap_info
&(IEEE80211_HT_CAP_SGI_20
|IEEE80211_HT_CAP_SGI_40
)) ? 1 : 0;
144 /* Add the protocol name */
145 iwe
.cmd
= SIOCGIWNAME
;
146 if ((rtw_is_cckratesonly_included((u8
*)&pnetwork
->network
.SupportedRates
))) {
148 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11bn");
150 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11b");
151 } else if ((rtw_is_cckrates_included((u8
*)&pnetwork
->network
.SupportedRates
))) {
153 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11bgn");
155 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11bg");
157 if (pnetwork
->network
.Configuration
.DSConfig
> 14) {
159 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11an");
161 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11a");
164 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11gn");
166 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11g");
170 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_CHAR_LEN
);
173 iwe
.cmd
= SIOCGIWMODE
;
174 memcpy(&le_tmp
, rtw_get_capability_from_ie(pnetwork
->network
.IEs
), 2);
176 cap
= le16_to_cpu(le_tmp
);
178 if (cap
& (WLAN_CAPABILITY_IBSS
| WLAN_CAPABILITY_BSS
)) {
179 if (cap
& WLAN_CAPABILITY_BSS
)
180 iwe
.u
.mode
= IW_MODE_MASTER
;
182 iwe
.u
.mode
= IW_MODE_ADHOC
;
184 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_UINT_LEN
);
187 if (pnetwork
->network
.Configuration
.DSConfig
< 1)
188 pnetwork
->network
.Configuration
.DSConfig
= 1;
190 /* Add frequency/channel */
191 iwe
.cmd
= SIOCGIWFREQ
;
192 iwe
.u
.freq
.m
= rtw_ch2freq(pnetwork
->network
.Configuration
.DSConfig
) * 100000;
194 iwe
.u
.freq
.i
= pnetwork
->network
.Configuration
.DSConfig
;
195 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_FREQ_LEN
);
197 /* Add encryption capability */
198 iwe
.cmd
= SIOCGIWENCODE
;
199 if (cap
& WLAN_CAPABILITY_PRIVACY
)
200 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
202 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
203 iwe
.u
.data
.length
= 0;
204 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, pnetwork
->network
.Ssid
.Ssid
);
206 /*Add basic and extended rates */
209 p
+= snprintf(p
, MAX_CUSTOM_LEN
- (p
- custom
), " Rates (Mb/s): ");
210 while (pnetwork
->network
.SupportedRates
[i
] != 0) {
211 rate
= pnetwork
->network
.SupportedRates
[i
]&0x7F;
214 p
+= snprintf(p
, MAX_CUSTOM_LEN
- (p
- custom
),
215 "%d%s ", rate
>> 1, (rate
& 1) ? ".5" : "");
220 if (mcs_rate
&0x8000)/* MCS15 */
221 max_rate
= (bw_40MHz
) ? ((short_GI
) ? 300 : 270) : ((short_GI
) ? 144 : 130);
222 else if (mcs_rate
&0x0080)/* MCS7 */
224 else/* default MCS7 */
225 max_rate
= (bw_40MHz
) ? ((short_GI
) ? 150 : 135) : ((short_GI
) ? 72 : 65);
227 max_rate
= max_rate
*2;/* Mbps/2; */
230 iwe
.cmd
= SIOCGIWRATE
;
231 iwe
.u
.bitrate
.fixed
= 0;
232 iwe
.u
.bitrate
.disabled
= 0;
233 iwe
.u
.bitrate
.value
= max_rate
* 500000;
234 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_PARAM_LEN
);
236 /* parsing WPA/WPA2 IE */
238 u8 buf
[MAX_WPA_IE_LEN
];
239 u8 wpa_ie
[255], rsn_ie
[255];
240 u16 wpa_len
= 0, rsn_len
= 0;
243 rtw_get_sec_ie(pnetwork
->network
.IEs
, pnetwork
->network
.IELength
, rsn_ie
, &rsn_len
, wpa_ie
, &wpa_len
);
244 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_scan: ssid =%s\n", pnetwork
->network
.Ssid
.Ssid
));
245 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len
, rsn_len
));
249 memset(buf
, 0, MAX_WPA_IE_LEN
);
250 p
+= sprintf(p
, "wpa_ie=");
251 for (i
= 0; i
< wpa_len
; i
++)
252 p
+= sprintf(p
, "%02x", wpa_ie
[i
]);
254 memset(&iwe
, 0, sizeof(iwe
));
255 iwe
.cmd
= IWEVCUSTOM
;
256 iwe
.u
.data
.length
= strlen(buf
);
257 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, buf
);
259 memset(&iwe
, 0, sizeof(iwe
));
261 iwe
.u
.data
.length
= wpa_len
;
262 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, wpa_ie
);
266 memset(buf
, 0, MAX_WPA_IE_LEN
);
267 p
+= sprintf(p
, "rsn_ie=");
268 for (i
= 0; i
< rsn_len
; i
++)
269 p
+= sprintf(p
, "%02x", rsn_ie
[i
]);
270 memset(&iwe
, 0, sizeof(iwe
));
271 iwe
.cmd
= IWEVCUSTOM
;
272 iwe
.u
.data
.length
= strlen(buf
);
273 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, buf
);
275 memset(&iwe
, 0, sizeof(iwe
));
277 iwe
.u
.data
.length
= rsn_len
;
278 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, rsn_ie
);
282 {/* parsing WPS IE */
283 uint cnt
= 0, total_ielen
;
284 u8
*wpsie_ptr
= NULL
;
287 u8
*ie_ptr
= pnetwork
->network
.IEs
+ _FIXED_IE_LENGTH_
;
288 total_ielen
= pnetwork
->network
.IELength
- _FIXED_IE_LENGTH_
;
290 while (cnt
< total_ielen
) {
291 if (rtw_is_wps_ie(&ie_ptr
[cnt
], &wps_ielen
) && (wps_ielen
> 2)) {
292 wpsie_ptr
= &ie_ptr
[cnt
];
294 iwe
.u
.data
.length
= (u16
)wps_ielen
;
295 start
= iwe_stream_add_point(info
, start
, stop
, &iwe
, wpsie_ptr
);
297 cnt
+= ie_ptr
[cnt
+1]+2; /* goto next */
301 /* Add quality statistics */
303 iwe
.u
.qual
.updated
= IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID
;
305 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true &&
306 is_same_network(&pmlmepriv
->cur_network
.network
, &pnetwork
->network
)) {
307 ss
= padapter
->recvpriv
.signal_strength
;
308 sq
= padapter
->recvpriv
.signal_qual
;
310 ss
= pnetwork
->network
.PhyInfo
.SignalStrength
;
311 sq
= pnetwork
->network
.PhyInfo
.SignalQuality
;
314 iwe
.u
.qual
.level
= (u8
)ss
;
315 iwe
.u
.qual
.qual
= (u8
)sq
; /* signal quality */
316 iwe
.u
.qual
.noise
= 0; /* noise level */
317 start
= iwe_stream_add_event(info
, start
, stop
, &iwe
, IW_EV_QUAL_LEN
);
321 static int wpa_set_auth_algs(struct net_device
*dev
, u32 value
)
323 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
326 if ((value
& AUTH_ALG_SHARED_KEY
) && (value
& AUTH_ALG_OPEN_SYSTEM
)) {
327 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value
);
328 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
329 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeAutoSwitch
;
330 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Auto
;
331 } else if (value
& AUTH_ALG_SHARED_KEY
) {
332 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value
);
333 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
335 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeShared
;
336 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Shared
;
337 } else if (value
& AUTH_ALG_OPEN_SYSTEM
) {
338 DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
339 if (padapter
->securitypriv
.ndisauthtype
< Ndis802_11AuthModeWPAPSK
) {
340 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeOpen
;
341 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
343 } else if (value
& AUTH_ALG_LEAP
) {
344 DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
346 DBG_88E("wpa_set_auth_algs, error!\n");
352 static int wpa_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
355 u32 wep_key_idx
, wep_key_len
, wep_total_len
;
356 struct ndis_802_11_wep
*pwep
= NULL
;
357 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
358 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
359 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
361 param
->u
.crypt
.err
= 0;
362 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
364 if (param_len
< (u32
)((u8
*)param
->u
.crypt
.key
- (u8
*)param
) + param
->u
.crypt
.key_len
) {
369 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
370 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
371 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff) {
372 if (param
->u
.crypt
.idx
>= WEP_KEYS
) {
381 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
382 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, ("wpa_set_encryption, crypt.alg = WEP\n"));
383 DBG_88E("wpa_set_encryption, crypt.alg = WEP\n");
385 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
386 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
387 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
389 wep_key_idx
= param
->u
.crypt
.idx
;
390 wep_key_len
= param
->u
.crypt
.key_len
;
392 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("(1)wep_key_idx =%d\n", wep_key_idx
));
393 DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx
);
395 if (wep_key_idx
> WEP_KEYS
)
398 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
, ("(2)wep_key_idx =%d\n", wep_key_idx
));
400 if (wep_key_len
> 0) {
401 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
402 wep_total_len
= wep_key_len
+ FIELD_OFFSET(struct ndis_802_11_wep
, KeyMaterial
);
403 pwep
= (struct ndis_802_11_wep
*)rtw_malloc(wep_total_len
);
405 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, (" wpa_set_encryption: pwep allocate fail !!!\n"));
408 memset(pwep
, 0, wep_total_len
);
409 pwep
->KeyLength
= wep_key_len
;
410 pwep
->Length
= wep_total_len
;
411 if (wep_key_len
== 13) {
412 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
413 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP104_
;
419 pwep
->KeyIndex
= wep_key_idx
;
420 pwep
->KeyIndex
|= 0x80000000;
421 memcpy(pwep
->KeyMaterial
, param
->u
.crypt
.key
, pwep
->KeyLength
);
422 if (param
->u
.crypt
.set_tx
) {
423 DBG_88E("wep, set_tx = 1\n");
424 if (rtw_set_802_11_add_wep(padapter
, pwep
) == (u8
)_FAIL
)
427 DBG_88E("wep, set_tx = 0\n");
428 if (wep_key_idx
>= WEP_KEYS
) {
432 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
433 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
434 rtw_set_key(padapter
, psecuritypriv
, wep_key_idx
, 0);
439 if (padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) { /* 802_1x */
440 struct sta_info
*psta
, *pbcmc_sta
;
441 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
443 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_MP_STATE
)) { /* sta mode */
444 psta
= rtw_get_stainfo(pstapriv
, get_bssid(pmlmepriv
));
448 if (strcmp(param
->u
.crypt
.alg
, "none") != 0)
449 psta
->ieee8021x_blocked
= false;
451 if ((padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption2Enabled
) ||
452 (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption3Enabled
))
453 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
455 if (param
->u
.crypt
.set_tx
== 1) { /* pairwise key */
456 memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
458 if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) { /* set mic key */
459 memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
460 memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
461 padapter
->securitypriv
.busetkipkey
= false;
464 DBG_88E(" ~~~~set sta key:unicastkey\n");
466 rtw_setstakey_cmd(padapter
, (unsigned char *)psta
, true);
467 } else { /* group key */
468 memcpy(padapter
->securitypriv
.dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
, param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
469 memcpy(padapter
->securitypriv
.dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
470 memcpy(padapter
->securitypriv
.dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
471 padapter
->securitypriv
.binstallGrpkey
= true;
472 DBG_88E(" ~~~~set sta key:groupkey\n");
474 padapter
->securitypriv
.dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
476 rtw_set_key(padapter
, &padapter
->securitypriv
, param
->u
.crypt
.idx
, 1);
479 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
480 if (pbcmc_sta
== NULL
) {
483 /* Jeff: don't disable ieee8021x_blocked while clearing key */
484 if (strcmp(param
->u
.crypt
.alg
, "none") != 0)
485 pbcmc_sta
->ieee8021x_blocked
= false;
487 if ((padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption2Enabled
) ||
488 (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption3Enabled
))
489 pbcmc_sta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
500 static int rtw_set_wpa_ie(struct adapter
*padapter
, char *pie
, unsigned short ielen
)
503 int group_cipher
= 0, pairwise_cipher
= 0;
506 if ((ielen
> MAX_WPA_IE_LEN
) || (pie
== NULL
)) {
507 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
515 buf
= kmemdup(pie
, ielen
, GFP_KERNEL
);
524 DBG_88E("\n wpa_ie(length:%d):\n", ielen
);
525 for (i
= 0; i
< ielen
; i
+= 8)
526 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]);
529 if (ielen
< RSN_HEADER_LEN
) {
530 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, ("Ie len too short %d\n", ielen
));
535 if (rtw_parse_wpa_ie(buf
, ielen
, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
536 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
537 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPAPSK
;
538 memcpy(padapter
->securitypriv
.supplicant_ie
, &buf
[0], ielen
);
541 if (rtw_parse_wpa2_ie(buf
, ielen
, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
542 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
543 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPA2PSK
;
544 memcpy(padapter
->securitypriv
.supplicant_ie
, &buf
[0], ielen
);
547 switch (group_cipher
) {
548 case WPA_CIPHER_NONE
:
549 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
550 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
552 case WPA_CIPHER_WEP40
:
553 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
554 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
556 case WPA_CIPHER_TKIP
:
557 padapter
->securitypriv
.dot118021XGrpPrivacy
= _TKIP_
;
558 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
560 case WPA_CIPHER_CCMP
:
561 padapter
->securitypriv
.dot118021XGrpPrivacy
= _AES_
;
562 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
564 case WPA_CIPHER_WEP104
:
565 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP104_
;
566 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
570 switch (pairwise_cipher
) {
571 case WPA_CIPHER_NONE
:
572 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
573 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
575 case WPA_CIPHER_WEP40
:
576 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
577 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
579 case WPA_CIPHER_TKIP
:
580 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _TKIP_
;
581 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
583 case WPA_CIPHER_CCMP
:
584 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _AES_
;
585 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
587 case WPA_CIPHER_WEP104
:
588 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
589 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
593 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
596 u8 eid
, wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
598 while (cnt
< ielen
) {
600 if ((eid
== _VENDOR_SPECIFIC_IE_
) && (!memcmp(&buf
[cnt
+2], wps_oui
, 4))) {
601 DBG_88E("SET WPS_IE\n");
603 padapter
->securitypriv
.wps_ie_len
= ((buf
[cnt
+1]+2) < (MAX_WPA_IE_LEN
<<2)) ? (buf
[cnt
+1]+2) : (MAX_WPA_IE_LEN
<<2);
605 memcpy(padapter
->securitypriv
.wps_ie
, &buf
[cnt
], padapter
->securitypriv
.wps_ie_len
);
607 set_fwstate(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
611 cnt
+= buf
[cnt
+1]+2; /* goto next */
617 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
618 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
619 pairwise_cipher
, padapter
->securitypriv
.ndisencryptstatus
, padapter
->securitypriv
.ndisauthtype
));
625 typedef unsigned char NDIS_802_11_RATES_EX
[NDIS_802_11_LENGTH_RATES_EX
];
627 static int rtw_wx_get_name(struct net_device
*dev
,
628 struct iw_request_info
*info
,
629 union iwreq_data
*wrqu
, char *extra
)
631 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
635 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
636 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
637 NDIS_802_11_RATES_EX
*prates
= NULL
;
639 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("cmd_code =%x\n", info
->cmd
));
641 if (check_fwstate(pmlmepriv
, _FW_LINKED
|WIFI_ADHOC_MASTER_STATE
) == true) {
642 /* parsing HT_CAP_IE */
643 p
= rtw_get_ie(&pcur_bss
->IEs
[12], _HT_CAPABILITY_IE_
, &ht_ielen
, pcur_bss
->IELength
-12);
644 if (p
&& ht_ielen
> 0)
647 prates
= &pcur_bss
->SupportedRates
;
649 if (rtw_is_cckratesonly_included((u8
*)prates
) == true) {
651 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11bn");
653 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11b");
654 } else if ((rtw_is_cckrates_included((u8
*)prates
)) == true) {
656 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11bgn");
658 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11bg");
660 if (pcur_bss
->Configuration
.DSConfig
> 14) {
662 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11an");
664 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11a");
667 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11gn");
669 snprintf(wrqu
->name
, IFNAMSIZ
, "IEEE 802.11g");
673 snprintf(wrqu
->name
, IFNAMSIZ
, "unassociated");
678 static int rtw_wx_set_freq(struct net_device
*dev
,
679 struct iw_request_info
*info
,
680 union iwreq_data
*wrqu
, char *extra
)
682 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+rtw_wx_set_freq\n"));
686 static int rtw_wx_get_freq(struct net_device
*dev
,
687 struct iw_request_info
*info
,
688 union iwreq_data
*wrqu
, char *extra
)
690 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
691 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
692 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
694 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
695 /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
696 wrqu
->freq
.m
= rtw_ch2freq(pcur_bss
->Configuration
.DSConfig
) * 100000;
698 wrqu
->freq
.i
= pcur_bss
->Configuration
.DSConfig
;
700 wrqu
->freq
.m
= rtw_ch2freq(padapter
->mlmeextpriv
.cur_channel
) * 100000;
702 wrqu
->freq
.i
= padapter
->mlmeextpriv
.cur_channel
;
708 static int rtw_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
709 union iwreq_data
*wrqu
, char *b
)
711 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
712 enum ndis_802_11_network_infra networkType
;
715 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
720 if (!padapter
->hw_init_completed
) {
725 switch (wrqu
->mode
) {
727 networkType
= Ndis802_11AutoUnknown
;
728 DBG_88E("set_mode = IW_MODE_AUTO\n");
731 networkType
= Ndis802_11IBSS
;
732 DBG_88E("set_mode = IW_MODE_ADHOC\n");
735 networkType
= Ndis802_11APMode
;
736 DBG_88E("set_mode = IW_MODE_MASTER\n");
739 networkType
= Ndis802_11Infrastructure
;
740 DBG_88E("set_mode = IW_MODE_INFRA\n");
744 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_err_
, ("\n Mode: %s is not supported\n", iw_operation_mode
[wrqu
->mode
]));
747 if (rtw_set_802_11_infrastructure_mode(padapter
, networkType
) == false) {
751 rtw_setopmode_cmd(padapter
, networkType
);
756 static int rtw_wx_get_mode(struct net_device
*dev
, struct iw_request_info
*a
,
757 union iwreq_data
*wrqu
, char *b
)
759 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
760 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
762 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, (" rtw_wx_get_mode\n"));
764 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
765 wrqu
->mode
= IW_MODE_INFRA
;
766 else if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
767 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)))
768 wrqu
->mode
= IW_MODE_ADHOC
;
769 else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
770 wrqu
->mode
= IW_MODE_MASTER
;
772 wrqu
->mode
= IW_MODE_AUTO
;
777 static int rtw_wx_set_pmkid(struct net_device
*dev
,
778 struct iw_request_info
*a
,
779 union iwreq_data
*wrqu
, char *extra
)
781 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
782 u8 j
, blInserted
= false;
784 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
785 struct iw_pmksa
*pPMK
= (struct iw_pmksa
*)extra
;
786 u8 strZeroMacAddress
[ETH_ALEN
] = {0x00};
787 u8 strIssueBssid
[ETH_ALEN
] = {0x00};
789 memcpy(strIssueBssid
, pPMK
->bssid
.sa_data
, ETH_ALEN
);
790 if (pPMK
->cmd
== IW_PMKSA_ADD
) {
791 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
792 if (!memcmp(strIssueBssid
, strZeroMacAddress
, ETH_ALEN
))
798 /* overwrite PMKID */
799 for (j
= 0; j
< NUM_PMKID_CACHE
; j
++) {
800 if (!memcmp(psecuritypriv
->PMKIDList
[j
].Bssid
, strIssueBssid
, ETH_ALEN
)) {
801 /* BSSID is matched, the same AP => rewrite with new PMKID. */
802 DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
803 memcpy(psecuritypriv
->PMKIDList
[j
].PMKID
, pPMK
->pmkid
, IW_PMKID_LEN
);
804 psecuritypriv
->PMKIDList
[j
].bUsed
= true;
805 psecuritypriv
->PMKIDIndex
= j
+1;
812 /* Find a new entry */
813 DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
814 psecuritypriv
->PMKIDIndex
);
816 memcpy(psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].Bssid
, strIssueBssid
, ETH_ALEN
);
817 memcpy(psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].PMKID
, pPMK
->pmkid
, IW_PMKID_LEN
);
819 psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].bUsed
= true;
820 psecuritypriv
->PMKIDIndex
++;
821 if (psecuritypriv
->PMKIDIndex
== 16)
822 psecuritypriv
->PMKIDIndex
= 0;
824 } else if (pPMK
->cmd
== IW_PMKSA_REMOVE
) {
825 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
827 for (j
= 0; j
< NUM_PMKID_CACHE
; j
++) {
828 if (!memcmp(psecuritypriv
->PMKIDList
[j
].Bssid
, strIssueBssid
, ETH_ALEN
)) {
829 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
830 memset(psecuritypriv
->PMKIDList
[j
].Bssid
, 0x00, ETH_ALEN
);
831 psecuritypriv
->PMKIDList
[j
].bUsed
= false;
835 } else if (pPMK
->cmd
== IW_PMKSA_FLUSH
) {
836 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
837 memset(&psecuritypriv
->PMKIDList
[0], 0x00, sizeof(struct rt_pmkid_list
) * NUM_PMKID_CACHE
);
838 psecuritypriv
->PMKIDIndex
= 0;
844 static int rtw_wx_get_sens(struct net_device
*dev
,
845 struct iw_request_info
*info
,
846 union iwreq_data
*wrqu
, char *extra
)
848 wrqu
->sens
.value
= 0;
849 wrqu
->sens
.fixed
= 0; /* no auto select */
850 wrqu
->sens
.disabled
= 1;
854 static int rtw_wx_get_range(struct net_device
*dev
,
855 struct iw_request_info
*info
,
856 union iwreq_data
*wrqu
, char *extra
)
858 struct iw_range
*range
= (struct iw_range
*)extra
;
859 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
860 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
865 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_range. cmd_code =%x\n", info
->cmd
));
867 wrqu
->data
.length
= sizeof(*range
);
868 memset(range
, 0, sizeof(*range
));
870 /* Let's try to keep this struct in the same order as in
871 * linux/include/wireless.h
874 /* TODO: See what values we can set, and remove the ones we can't
875 * set, or fill them with some default data.
878 /* ~5 Mb/s real (802.11b) */
879 range
->throughput
= 5 * 1000 * 1000;
881 /* signal level threshold range */
883 /* percent values between 0 and 100. */
884 range
->max_qual
.qual
= 100;
885 range
->max_qual
.level
= 100;
886 range
->max_qual
.noise
= 100;
887 range
->max_qual
.updated
= 7; /* Updated all three */
889 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
890 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
891 range
->avg_qual
.level
= 178; /* -78 dBm */
892 range
->avg_qual
.noise
= 0;
893 range
->avg_qual
.updated
= 7; /* Updated all three */
895 range
->num_bitrates
= RATE_COUNT
;
897 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++)
898 range
->bitrate
[i
] = rtw_rates
[i
];
900 range
->min_frag
= MIN_FRAG_THRESHOLD
;
901 range
->max_frag
= MAX_FRAG_THRESHOLD
;
905 range
->we_version_compiled
= WIRELESS_EXT
;
906 range
->we_version_source
= 16;
908 for (i
= 0, val
= 0; i
< MAX_CHANNEL_NUM
; i
++) {
909 /* Include only legal frequencies for some countries */
910 if (pmlmeext
->channel_set
[i
].ChannelNum
!= 0) {
911 range
->freq
[val
].i
= pmlmeext
->channel_set
[i
].ChannelNum
;
912 range
->freq
[val
].m
= rtw_ch2freq(pmlmeext
->channel_set
[i
].ChannelNum
) * 100000;
913 range
->freq
[val
].e
= 1;
917 if (val
== IW_MAX_FREQUENCIES
)
921 range
->num_channels
= val
;
922 range
->num_frequency
= val
;
924 /* The following code will proivde the security capability to network manager. */
925 /* If the driver doesn't provide this capability to network manager, */
926 /* the WPA/WPA2 routers can't be chosen in the network manager. */
929 #define IW_SCAN_CAPA_NONE 0x00
930 #define IW_SCAN_CAPA_ESSID 0x01
931 #define IW_SCAN_CAPA_BSSID 0x02
932 #define IW_SCAN_CAPA_CHANNEL 0x04
933 #define IW_SCAN_CAPA_MODE 0x08
934 #define IW_SCAN_CAPA_RATE 0x10
935 #define IW_SCAN_CAPA_TYPE 0x20
936 #define IW_SCAN_CAPA_TIME 0x40
939 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
940 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
942 range
->scan_capa
= IW_SCAN_CAPA_ESSID
| IW_SCAN_CAPA_TYPE
|
943 IW_SCAN_CAPA_BSSID
| IW_SCAN_CAPA_CHANNEL
|
944 IW_SCAN_CAPA_MODE
| IW_SCAN_CAPA_RATE
;
949 /* s1. rtw_set_802_11_infrastructure_mode() */
950 /* s2. rtw_set_802_11_authentication_mode() */
951 /* s3. set_802_11_encryption_mode() */
952 /* s4. rtw_set_802_11_bssid() */
953 static int rtw_wx_set_wap(struct net_device
*dev
,
954 struct iw_request_info
*info
,
955 union iwreq_data
*awrq
,
959 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
960 struct sockaddr
*temp
= (struct sockaddr
*)awrq
;
961 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
962 struct list_head
*phead
;
963 u8
*dst_bssid
, *src_bssid
;
964 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
965 struct wlan_network
*pnetwork
= NULL
;
966 enum ndis_802_11_auth_mode authmode
;
968 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
973 if (!padapter
->bup
) {
978 if (temp
->sa_family
!= ARPHRD_ETHER
) {
983 authmode
= padapter
->securitypriv
.ndisauthtype
;
984 spin_lock_bh(&queue
->lock
);
985 phead
= get_list_head(queue
);
986 pmlmepriv
->pscanned
= phead
->next
;
988 while (phead
!= pmlmepriv
->pscanned
) {
989 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
991 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
993 dst_bssid
= pnetwork
->network
.MacAddress
;
995 src_bssid
= temp
->sa_data
;
997 if ((!memcmp(dst_bssid
, src_bssid
, ETH_ALEN
))) {
998 if (!rtw_set_802_11_infrastructure_mode(padapter
, pnetwork
->network
.InfrastructureMode
)) {
1000 spin_unlock_bh(&queue
->lock
);
1007 spin_unlock_bh(&queue
->lock
);
1009 rtw_set_802_11_authentication_mode(padapter
, authmode
);
1010 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1011 if (rtw_set_802_11_bssid(padapter
, temp
->sa_data
) == false) {
1021 static int rtw_wx_get_wap(struct net_device
*dev
,
1022 struct iw_request_info
*info
,
1023 union iwreq_data
*wrqu
, char *extra
)
1025 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1026 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1027 struct wlan_bssid_ex
*pcur_bss
= &pmlmepriv
->cur_network
.network
;
1029 wrqu
->ap_addr
.sa_family
= ARPHRD_ETHER
;
1031 memset(wrqu
->ap_addr
.sa_data
, 0, ETH_ALEN
);
1033 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_get_wap\n"));
1035 if (((check_fwstate(pmlmepriv
, _FW_LINKED
)) == true) ||
1036 ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) == true) ||
1037 ((check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) == true))
1038 memcpy(wrqu
->ap_addr
.sa_data
, pcur_bss
->MacAddress
, ETH_ALEN
);
1040 memset(wrqu
->ap_addr
.sa_data
, 0, ETH_ALEN
);
1044 static int rtw_wx_set_mlme(struct net_device
*dev
,
1045 struct iw_request_info
*info
,
1046 union iwreq_data
*wrqu
, char *extra
)
1050 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1051 struct iw_mlme
*mlme
= (struct iw_mlme
*)extra
;
1056 DBG_88E("%s\n", __func__
);
1058 reason
= mlme
->reason_code
;
1060 DBG_88E("%s, cmd =%d, reason =%d\n", __func__
, mlme
->cmd
, reason
);
1062 switch (mlme
->cmd
) {
1063 case IW_MLME_DEAUTH
:
1064 if (!rtw_set_802_11_disassociate(padapter
))
1067 case IW_MLME_DISASSOC
:
1068 if (!rtw_set_802_11_disassociate(padapter
))
1077 static int rtw_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
1078 union iwreq_data
*wrqu
, char *extra
)
1082 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1083 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1084 struct ndis_802_11_ssid ssid
[RTW_SSID_SCAN_AMOUNT
];
1085 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_wx_set_scan\n"));
1087 if (padapter
->registrypriv
.mp_mode
== 1) {
1088 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) {
1093 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
1098 if (padapter
->bDriverStopped
) {
1099 DBG_88E("bDriverStopped =%d\n", padapter
->bDriverStopped
);
1104 if (!padapter
->bup
) {
1109 if (!padapter
->hw_init_completed
) {
1114 /* When Busy Traffic, driver do not site survey. So driver return success. */
1115 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1116 /* modify by thomas 2011-02-22. */
1117 if (pmlmepriv
->LinkDetectInfo
.bBusyTraffic
) {
1118 indicate_wx_scan_complete_event(padapter
);
1122 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
|_FW_UNDER_LINKING
)) {
1123 indicate_wx_scan_complete_event(padapter
);
1127 /* For the DMP WiFi Display project, the driver won't to scan because */
1128 /* the pmlmepriv->scan_interval is always equal to 3. */
1129 /* So, the wpa_supplicant won't find out the WPS SoftAP. */
1131 memset(ssid
, 0, sizeof(struct ndis_802_11_ssid
)*RTW_SSID_SCAN_AMOUNT
);
1133 if (wrqu
->data
.length
== sizeof(struct iw_scan_req
)) {
1134 struct iw_scan_req
*req
= (struct iw_scan_req
*)extra
;
1136 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
) {
1137 int len
= min_t(int, req
->essid_len
,
1140 memcpy(ssid
[0].Ssid
, req
->essid
, len
);
1141 ssid
[0].SsidLength
= len
;
1143 DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req
->essid
, req
->essid_len
);
1145 spin_lock_bh(&pmlmepriv
->lock
);
1147 _status
= rtw_sitesurvey_cmd(padapter
, ssid
, 1, NULL
, 0);
1149 spin_unlock_bh(&pmlmepriv
->lock
);
1150 } else if (req
->scan_type
== IW_SCAN_TYPE_PASSIVE
) {
1151 DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1154 if (wrqu
->data
.length
>= WEXT_CSCAN_HEADER_SIZE
&&
1155 !memcmp(extra
, WEXT_CSCAN_HEADER
, WEXT_CSCAN_HEADER_SIZE
)) {
1156 int len
= wrqu
->data
.length
- WEXT_CSCAN_HEADER_SIZE
;
1157 char *pos
= extra
+WEXT_CSCAN_HEADER_SIZE
;
1167 case WEXT_CSCAN_SSID_SECTION
:
1172 sec_len
= *(pos
++); len
-= 1;
1173 if (sec_len
> 0 && sec_len
<= len
) {
1174 ssid
[ssid_index
].SsidLength
= sec_len
;
1175 memcpy(ssid
[ssid_index
].Ssid
, pos
, ssid
[ssid_index
].SsidLength
);
1181 case WEXT_CSCAN_TYPE_SECTION
:
1182 case WEXT_CSCAN_CHANNEL_SECTION
:
1186 case WEXT_CSCAN_PASV_DWELL_SECTION
:
1187 case WEXT_CSCAN_HOME_DWELL_SECTION
:
1188 case WEXT_CSCAN_ACTV_DWELL_SECTION
:
1193 len
= 0; /* stop parsing */
1197 /* it has still some scan parameter to parse, we only do this now... */
1198 _status
= rtw_set_802_11_bssid_list_scan(padapter
, ssid
, RTW_SSID_SCAN_AMOUNT
);
1200 _status
= rtw_set_802_11_bssid_list_scan(padapter
, NULL
, 0);
1212 static int rtw_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
1213 union iwreq_data
*wrqu
, char *extra
)
1215 struct list_head
*plist
, *phead
;
1216 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1217 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1218 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1219 struct wlan_network
*pnetwork
= NULL
;
1221 char *stop
= ev
+ wrqu
->data
.length
;
1224 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
= (wrqu
->essid
.length
< IW_ESSID_MAX_SIZE
) ? 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
;
1614 DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq
->flags
);
1616 memset(&wep
, 0, sizeof(struct ndis_802_11_wep
));
1618 key
= erq
->flags
& IW_ENCODE_INDEX
;
1621 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1622 DBG_88E("EncryptionDisabled\n");
1623 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
1624 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1625 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1626 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
; /* open system */
1627 authmode
= Ndis802_11AuthModeOpen
;
1628 padapter
->securitypriv
.ndisauthtype
= authmode
;
1637 keyindex_provided
= 1;
1639 keyindex_provided
= 0;
1640 key
= padapter
->securitypriv
.dot11PrivacyKeyIndex
;
1641 DBG_88E("rtw_wx_set_enc, key =%d\n", key
);
1644 /* set authentication mode */
1645 if (erq
->flags
& IW_ENCODE_OPEN
) {
1646 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1647 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;/* Ndis802_11EncryptionDisabled; */
1648 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
1649 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1650 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1651 authmode
= Ndis802_11AuthModeOpen
;
1652 padapter
->securitypriv
.ndisauthtype
= authmode
;
1653 } else if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
1654 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1655 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
1656 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Shared
;
1657 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
1658 padapter
->securitypriv
.dot118021XGrpPrivacy
= _WEP40_
;
1659 authmode
= Ndis802_11AuthModeShared
;
1660 padapter
->securitypriv
.ndisauthtype
= authmode
;
1662 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq
->flags
);
1664 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;/* Ndis802_11EncryptionDisabled; */
1665 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
; /* open system */
1666 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1667 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1668 authmode
= Ndis802_11AuthModeOpen
;
1669 padapter
->securitypriv
.ndisauthtype
= authmode
;
1673 if (erq
->length
> 0) {
1674 wep
.KeyLength
= erq
->length
<= 5 ? 5 : 13;
1676 wep
.Length
= wep
.KeyLength
+ FIELD_OFFSET(struct ndis_802_11_wep
, KeyMaterial
);
1680 if (keyindex_provided
== 1) {
1681 /* set key_id only, no given KeyMaterial(erq->length == 0). */
1682 padapter
->securitypriv
.dot11PrivacyKeyIndex
= key
;
1684 DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key
, padapter
->securitypriv
.dot11DefKeylen
[key
]);
1686 switch (padapter
->securitypriv
.dot11DefKeylen
[key
]) {
1688 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP40_
;
1691 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _WEP104_
;
1694 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1702 wep
.KeyIndex
|= 0x80000000;
1704 memcpy(wep
.KeyMaterial
, keybuf
, wep
.KeyLength
);
1706 if (rtw_set_802_11_add_wep(padapter
, &wep
) == false) {
1707 if (rf_on
== pwrpriv
->rf_pwrstate
)
1718 static int rtw_wx_get_enc(struct net_device
*dev
,
1719 struct iw_request_info
*info
,
1720 union iwreq_data
*wrqu
, char *keybuf
)
1723 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1724 struct iw_point
*erq
= &(wrqu
->encoding
);
1725 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1728 if (check_fwstate(pmlmepriv
, _FW_LINKED
) != true) {
1729 if (!check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
1731 erq
->flags
|= IW_ENCODE_DISABLED
;
1736 key
= erq
->flags
& IW_ENCODE_INDEX
;
1743 key
= padapter
->securitypriv
.dot11PrivacyKeyIndex
;
1746 erq
->flags
= key
+ 1;
1748 switch (padapter
->securitypriv
.ndisencryptstatus
) {
1749 case Ndis802_11EncryptionNotSupported
:
1750 case Ndis802_11EncryptionDisabled
:
1752 erq
->flags
|= IW_ENCODE_DISABLED
;
1754 case Ndis802_11Encryption1Enabled
:
1755 erq
->length
= padapter
->securitypriv
.dot11DefKeylen
[key
];
1757 memcpy(keybuf
, padapter
->securitypriv
.dot11DefKey
[key
].skey
, padapter
->securitypriv
.dot11DefKeylen
[key
]);
1759 erq
->flags
|= IW_ENCODE_ENABLED
;
1761 if (padapter
->securitypriv
.ndisauthtype
== Ndis802_11AuthModeOpen
)
1762 erq
->flags
|= IW_ENCODE_OPEN
;
1763 else if (padapter
->securitypriv
.ndisauthtype
== Ndis802_11AuthModeShared
)
1764 erq
->flags
|= IW_ENCODE_RESTRICTED
;
1767 erq
->flags
|= IW_ENCODE_DISABLED
;
1770 case Ndis802_11Encryption2Enabled
:
1771 case Ndis802_11Encryption3Enabled
:
1773 erq
->flags
|= (IW_ENCODE_ENABLED
| IW_ENCODE_OPEN
| IW_ENCODE_NOKEY
);
1777 erq
->flags
|= IW_ENCODE_DISABLED
;
1784 static int rtw_wx_get_power(struct net_device
*dev
,
1785 struct iw_request_info
*info
,
1786 union iwreq_data
*wrqu
, char *extra
)
1788 wrqu
->power
.value
= 0;
1789 wrqu
->power
.fixed
= 0; /* no auto select */
1790 wrqu
->power
.disabled
= 1;
1795 static int rtw_wx_set_gen_ie(struct net_device
*dev
,
1796 struct iw_request_info
*info
,
1797 union iwreq_data
*wrqu
, char *extra
)
1800 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1802 ret
= rtw_set_wpa_ie(padapter
, extra
, wrqu
->data
.length
);
1806 static int rtw_wx_set_auth(struct net_device
*dev
,
1807 struct iw_request_info
*info
,
1808 union iwreq_data
*wrqu
, char *extra
)
1810 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1811 struct iw_param
*param
= (struct iw_param
*)&(wrqu
->param
);
1814 switch (param
->flags
& IW_AUTH_INDEX
) {
1815 case IW_AUTH_WPA_VERSION
:
1817 case IW_AUTH_CIPHER_PAIRWISE
:
1820 case IW_AUTH_CIPHER_GROUP
:
1823 case IW_AUTH_KEY_MGMT
:
1825 * ??? does not use these parameters
1828 case IW_AUTH_TKIP_COUNTERMEASURES
:
1830 /* wpa_supplicant is enabling the tkip countermeasure. */
1831 padapter
->securitypriv
.btkip_countermeasure
= true;
1833 /* wpa_supplicant is disabling the tkip countermeasure. */
1834 padapter
->securitypriv
.btkip_countermeasure
= false;
1837 case IW_AUTH_DROP_UNENCRYPTED
:
1840 * wpa_supplicant calls set_wpa_enabled when the driver
1841 * is loaded and unloaded, regardless of if WPA is being
1842 * used. No other calls are made which can be used to
1843 * determine if encryption will be used or not prior to
1844 * association being expected. If encryption is not being
1845 * used, drop_unencrypted is set to false, else true -- we
1846 * can use this to determine if the CAP_PRIVACY_ON bit should
1850 if (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption1Enabled
)
1851 break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
1852 /* then it needn't reset it; */
1855 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
1856 padapter
->securitypriv
.dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
1857 padapter
->securitypriv
.dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1858 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
; /* open system */
1859 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeOpen
;
1863 case IW_AUTH_80211_AUTH_ALG
:
1865 * It's the starting point of a link layer connection using wpa_supplicant
1867 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
1868 LeaveAllPowerSaveMode(padapter
);
1869 rtw_disassoc_cmd(padapter
, 500, false);
1870 DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__
);
1871 rtw_indicate_disconnect(padapter
);
1872 rtw_free_assoc_resources(padapter
, 1);
1874 ret
= wpa_set_auth_algs(dev
, (u32
)param
->value
);
1876 case IW_AUTH_WPA_ENABLED
:
1878 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1880 case IW_AUTH_PRIVACY_INVOKED
:
1889 static int rtw_wx_set_enc_ext(struct net_device
*dev
,
1890 struct iw_request_info
*info
,
1891 union iwreq_data
*wrqu
, char *extra
)
1895 struct ieee_param
*param
= NULL
;
1896 struct iw_point
*pencoding
= &wrqu
->encoding
;
1897 struct iw_encode_ext
*pext
= (struct iw_encode_ext
*)extra
;
1900 param_len
= sizeof(struct ieee_param
) + pext
->key_len
;
1901 param
= (struct ieee_param
*)rtw_malloc(param_len
);
1905 memset(param
, 0, param_len
);
1907 param
->cmd
= IEEE_CMD_SET_ENCRYPTION
;
1908 memset(param
->sta_addr
, 0xff, ETH_ALEN
);
1910 switch (pext
->alg
) {
1911 case IW_ENCODE_ALG_NONE
:
1912 /* todo: remove key */
1916 case IW_ENCODE_ALG_WEP
:
1919 case IW_ENCODE_ALG_TKIP
:
1922 case IW_ENCODE_ALG_CCMP
:
1930 strncpy((char *)param
->u
.crypt
.alg
, alg_name
, IEEE_CRYPT_ALG_NAME_LEN
);
1932 if (pext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
)
1933 param
->u
.crypt
.set_tx
= 1;
1935 /* cliW: WEP does not have group key
1936 * just not checking GROUP key setting
1938 if ((pext
->alg
!= IW_ENCODE_ALG_WEP
) &&
1939 (pext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
))
1940 param
->u
.crypt
.set_tx
= 0;
1942 param
->u
.crypt
.idx
= (pencoding
->flags
&0x00FF) - 1;
1944 if (pext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
)
1945 memcpy(param
->u
.crypt
.seq
, pext
->rx_seq
, 8);
1947 if (pext
->key_len
) {
1948 param
->u
.crypt
.key_len
= pext
->key_len
;
1949 memcpy(param
->u
.crypt
.key
, pext
+ 1, pext
->key_len
);
1952 ret
= wpa_set_encryption(dev
, param
, param_len
);
1959 static int rtw_wx_get_nick(struct net_device
*dev
,
1960 struct iw_request_info
*info
,
1961 union iwreq_data
*wrqu
, char *extra
)
1964 wrqu
->data
.length
= 14;
1965 wrqu
->data
.flags
= 1;
1966 memcpy(extra
, "<WIFI@REALTEK>", 14);
1969 /* dump debug info here */
1973 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1974 union iwreq_data
*wrqu
, char *b
)
1979 static int wpa_set_param(struct net_device
*dev
, u8 name
, u32 value
)
1982 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
1985 case IEEE_PARAM_WPA_ENABLED
:
1986 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
; /* 802.1x */
1987 switch ((value
)&0xff) {
1989 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPAPSK
; /* WPA_PSK */
1990 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
1993 padapter
->securitypriv
.ndisauthtype
= Ndis802_11AuthModeWPA2PSK
; /* WPA2_PSK */
1994 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
1997 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
1998 ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter
->securitypriv
.ndisauthtype
));
2000 case IEEE_PARAM_TKIP_COUNTERMEASURES
:
2002 case IEEE_PARAM_DROP_UNENCRYPTED
: {
2005 * wpa_supplicant calls set_wpa_enabled when the driver
2006 * is loaded and unloaded, regardless of if WPA is being
2007 * used. No other calls are made which can be used to
2008 * determine if encryption will be used or not prior to
2009 * association being expected. If encryption is not being
2010 * used, drop_unencrypted is set to false, else true -- we
2011 * can use this to determine if the CAP_PRIVACY_ON bit should
2017 case IEEE_PARAM_PRIVACY_INVOKED
:
2020 case IEEE_PARAM_AUTH_ALGS
:
2021 ret
= wpa_set_auth_algs(dev
, value
);
2023 case IEEE_PARAM_IEEE_802_1X
:
2025 case IEEE_PARAM_WPAX_SELECT
:
2034 static int wpa_mlme(struct net_device
*dev
, u32 command
, u32 reason
)
2037 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2040 case IEEE_MLME_STA_DEAUTH
:
2041 if (!rtw_set_802_11_disassociate(padapter
))
2044 case IEEE_MLME_STA_DISASSOC
:
2045 if (!rtw_set_802_11_disassociate(padapter
))
2056 static int wpa_supplicant_ioctl(struct net_device
*dev
, struct iw_point
*p
)
2058 struct ieee_param
*param
;
2061 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
) {
2066 param
= (struct ieee_param
*)rtw_malloc(p
->length
);
2067 if (param
== NULL
) {
2072 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
2078 switch (param
->cmd
) {
2079 case IEEE_CMD_SET_WPA_PARAM
:
2080 ret
= wpa_set_param(dev
, param
->u
.wpa_param
.name
, param
->u
.wpa_param
.value
);
2083 case IEEE_CMD_SET_WPA_IE
:
2084 ret
= rtw_set_wpa_ie((struct adapter
*)rtw_netdev_priv(dev
),
2085 (char *)param
->u
.wpa_ie
.data
, (u16
)param
->u
.wpa_ie
.len
);
2088 case IEEE_CMD_SET_ENCRYPTION
:
2089 ret
= wpa_set_encryption(dev
, param
, p
->length
);
2093 ret
= wpa_mlme(dev
, param
->u
.mlme
.command
, param
->u
.mlme
.reason_code
);
2097 DBG_88E("Unknown WPA supplicant request: %d\n", param
->cmd
);
2102 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
2112 #ifdef CONFIG_88EU_AP_MODE
2113 static u8
set_pairwise_key(struct adapter
*padapter
, struct sta_info
*psta
)
2115 struct cmd_obj
*ph2c
;
2116 struct set_stakey_parm
*psetstakey_para
;
2117 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
2120 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
2126 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_KERNEL
);
2127 if (psetstakey_para
== NULL
) {
2133 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
2135 psetstakey_para
->algorithm
= (u8
)psta
->dot118021XPrivacy
;
2137 memcpy(psetstakey_para
->addr
, psta
->hwaddr
, ETH_ALEN
);
2139 memcpy(psetstakey_para
->key
, &psta
->dot118021x_UncstKey
, 16);
2141 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
2148 static int set_group_key(struct adapter
*padapter
, u8
*key
, u8 alg
, int keyid
)
2151 struct cmd_obj
*pcmd
;
2152 struct setkey_parm
*psetkeyparm
;
2153 struct cmd_priv
*pcmdpriv
= &(padapter
->cmdpriv
);
2156 DBG_88E("%s\n", __func__
);
2158 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
2163 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
2164 if (psetkeyparm
== NULL
) {
2170 memset(psetkeyparm
, 0, sizeof(struct setkey_parm
));
2172 psetkeyparm
->keyid
= (u8
)keyid
;
2174 psetkeyparm
->algorithm
= alg
;
2176 psetkeyparm
->set_tx
= 1;
2192 memcpy(&(psetkeyparm
->key
[0]), key
, keylen
);
2194 pcmd
->cmdcode
= _SetKey_CMD_
;
2195 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
2196 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
2200 INIT_LIST_HEAD(&pcmd
->list
);
2202 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
2209 static int set_wep_key(struct adapter
*padapter
, u8
*key
, u8 keylen
, int keyid
)
2224 return set_group_key(padapter
, key
, alg
, keyid
);
2227 static int rtw_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
2230 u32 wep_key_idx
, wep_key_len
, wep_total_len
;
2231 struct ndis_802_11_wep
*pwep
= NULL
;
2232 struct sta_info
*psta
= NULL
, *pbcmc_sta
= NULL
;
2233 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2234 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2235 struct security_priv
*psecuritypriv
= &(padapter
->securitypriv
);
2236 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2238 DBG_88E("%s\n", __func__
);
2239 param
->u
.crypt
.err
= 0;
2240 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
2241 if (param_len
!= sizeof(struct ieee_param
) + param
->u
.crypt
.key_len
) {
2245 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2246 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2247 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff) {
2248 if (param
->u
.crypt
.idx
>= WEP_KEYS
) {
2253 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2255 DBG_88E("rtw_set_encryption(), sta has already been removed or never been added\n");
2260 if (strcmp(param
->u
.crypt
.alg
, "none") == 0 && (psta
== NULL
)) {
2261 /* todo:clear default encryption keys */
2263 DBG_88E("clear default encryption keys, keyid =%d\n", param
->u
.crypt
.idx
);
2266 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0 && (psta
== NULL
)) {
2267 DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
2268 wep_key_idx
= param
->u
.crypt
.idx
;
2269 wep_key_len
= param
->u
.crypt
.key_len
;
2270 DBG_88E("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx
, wep_key_len
);
2271 if ((wep_key_idx
>= WEP_KEYS
) || (wep_key_len
<= 0)) {
2276 if (wep_key_len
> 0) {
2277 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
2278 wep_total_len
= wep_key_len
+ FIELD_OFFSET(struct ndis_802_11_wep
, KeyMaterial
);
2279 pwep
= (struct ndis_802_11_wep
*)rtw_malloc(wep_total_len
);
2281 DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
2285 memset(pwep
, 0, wep_total_len
);
2287 pwep
->KeyLength
= wep_key_len
;
2288 pwep
->Length
= wep_total_len
;
2291 pwep
->KeyIndex
= wep_key_idx
;
2293 memcpy(pwep
->KeyMaterial
, param
->u
.crypt
.key
, pwep
->KeyLength
);
2295 if (param
->u
.crypt
.set_tx
) {
2296 DBG_88E("wep, set_tx = 1\n");
2298 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2299 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP40_
;
2300 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2302 if (pwep
->KeyLength
== 13) {
2303 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP104_
;
2304 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2307 psecuritypriv
->dot11PrivacyKeyIndex
= wep_key_idx
;
2309 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
2311 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
2313 set_wep_key(padapter
, pwep
->KeyMaterial
, pwep
->KeyLength
, wep_key_idx
);
2315 DBG_88E("wep, set_tx = 0\n");
2317 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
2318 /* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
2320 memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), pwep
->KeyMaterial
, pwep
->KeyLength
);
2322 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = pwep
->KeyLength
;
2324 set_wep_key(padapter
, pwep
->KeyMaterial
, pwep
->KeyLength
, wep_key_idx
);
2330 if (!psta
&& check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) { /* group key */
2331 if (param
->u
.crypt
.set_tx
== 1) {
2332 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2333 DBG_88E("%s, set group_key, WEP\n", __func__
);
2335 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2336 param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2338 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2339 if (param
->u
.crypt
.key_len
== 13)
2340 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2341 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2342 DBG_88E("%s, set group_key, TKIP\n", __func__
);
2343 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
2344 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2345 param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2347 memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
2348 memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
2350 psecuritypriv
->busetkipkey
= true;
2351 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2352 DBG_88E("%s, set group_key, CCMP\n", __func__
);
2353 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
2354 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2355 param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2357 DBG_88E("%s, set group_key, none\n", __func__
);
2358 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2360 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
2361 psecuritypriv
->binstallGrpkey
= true;
2362 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;/* */
2363 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
2364 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
2366 pbcmc_sta
->ieee8021x_blocked
= false;
2367 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;/* rx will use bmc_sta's dot118021XPrivacy */
2373 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
&& psta
) { /* psk/802_1x */
2374 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
2375 if (param
->u
.crypt
.set_tx
== 1) {
2376 memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2378 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2379 DBG_88E("%s, set pairwise key, WEP\n", __func__
);
2381 psta
->dot118021XPrivacy
= _WEP40_
;
2382 if (param
->u
.crypt
.key_len
== 13)
2383 psta
->dot118021XPrivacy
= _WEP104_
;
2384 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2385 DBG_88E("%s, set pairwise key, TKIP\n", __func__
);
2387 psta
->dot118021XPrivacy
= _TKIP_
;
2390 memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
2391 memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
2393 psecuritypriv
->busetkipkey
= true;
2394 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2395 DBG_88E("%s, set pairwise key, CCMP\n", __func__
);
2397 psta
->dot118021XPrivacy
= _AES_
;
2399 DBG_88E("%s, set pairwise key, none\n", __func__
);
2401 psta
->dot118021XPrivacy
= _NO_PRIVACY_
;
2404 set_pairwise_key(padapter
, psta
);
2406 psta
->ieee8021x_blocked
= false;
2407 } else { /* group key??? */
2408 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2409 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2410 param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2411 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
2412 if (param
->u
.crypt
.key_len
== 13)
2413 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
2414 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2415 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
2417 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2418 param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2421 memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
2422 memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
2424 psecuritypriv
->busetkipkey
= true;
2425 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
2426 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
2428 memcpy(psecuritypriv
->dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
,
2429 param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
> 16 ? 16 : param
->u
.crypt
.key_len
));
2431 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2434 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
2436 psecuritypriv
->binstallGrpkey
= true;
2438 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;/* */
2440 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
2442 pbcmc_sta
= rtw_get_bcmc_stainfo(padapter
);
2444 pbcmc_sta
->ieee8021x_blocked
= false;
2445 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;/* rx will use bmc_sta's dot118021XPrivacy */
2458 static int rtw_set_beacon(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2461 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2462 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2463 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2464 unsigned char *pbuf
= param
->u
.bcn_ie
.buf
;
2466 DBG_88E("%s, len =%d\n", __func__
, len
);
2468 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2471 memcpy(&pstapriv
->max_num_sta
, param
->u
.bcn_ie
.reserved
, 2);
2473 if ((pstapriv
->max_num_sta
> NUM_STA
) || (pstapriv
->max_num_sta
<= 0))
2474 pstapriv
->max_num_sta
= NUM_STA
;
2476 if (rtw_check_beacon_data(padapter
, pbuf
, (len
-12-2)) == _SUCCESS
)/* 12 = param header, 2:no packed */
2484 static int rtw_hostapd_sta_flush(struct net_device
*dev
)
2487 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2489 DBG_88E("%s\n", __func__
);
2491 flush_all_cam_entry(padapter
); /* clear CAM */
2493 ret
= rtw_sta_flush(padapter
);
2498 static int rtw_add_sta(struct net_device
*dev
, struct ieee_param
*param
)
2501 struct sta_info
*psta
= NULL
;
2502 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2503 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2504 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2506 DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param
->u
.add_sta
.aid
, (param
->sta_addr
));
2508 if (!check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)))
2511 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2512 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2513 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2516 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2518 int flags
= param
->u
.add_sta
.flags
;
2520 psta
->aid
= param
->u
.add_sta
.aid
;/* aid = 1~2007 */
2522 memcpy(psta
->bssrateset
, param
->u
.add_sta
.tx_supp_rates
, 16);
2524 /* check wmm cap. */
2525 if (WLAN_STA_WME
&flags
)
2526 psta
->qos_option
= 1;
2528 psta
->qos_option
= 0;
2530 if (pmlmepriv
->qospriv
.qos_option
== 0)
2531 psta
->qos_option
= 0;
2533 /* chec 802.11n ht cap. */
2534 if (WLAN_STA_HT
&flags
) {
2535 psta
->htpriv
.ht_option
= true;
2536 psta
->qos_option
= 1;
2537 memcpy((void *)&psta
->htpriv
.ht_cap
, (void *)¶m
->u
.add_sta
.ht_cap
, sizeof(struct rtw_ieee80211_ht_cap
));
2539 psta
->htpriv
.ht_option
= false;
2542 if (pmlmepriv
->htpriv
.ht_option
== false)
2543 psta
->htpriv
.ht_option
= false;
2545 update_sta_info_apmode(padapter
, psta
);
2553 static int rtw_del_sta(struct net_device
*dev
, struct ieee_param
*param
)
2556 struct sta_info
*psta
= NULL
;
2557 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2558 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2559 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2562 DBG_88E("rtw_del_sta =%pM\n", (param
->sta_addr
));
2564 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2567 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2568 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2569 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2572 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2574 spin_lock_bh(&pstapriv
->asoc_list_lock
);
2575 if (!list_empty(&psta
->asoc_list
)) {
2576 list_del_init(&psta
->asoc_list
);
2577 pstapriv
->asoc_list_cnt
--;
2578 updated
= ap_free_sta(padapter
, psta
, true, WLAN_REASON_DEAUTH_LEAVING
);
2580 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
2581 associated_clients_update(padapter
, updated
);
2584 DBG_88E("rtw_del_sta(), sta has already been removed or never been added\n");
2590 static int rtw_ioctl_get_sta_data(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2593 struct sta_info
*psta
= NULL
;
2594 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2595 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2596 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2597 struct ieee_param_ex
*param_ex
= (struct ieee_param_ex
*)param
;
2598 struct sta_data
*psta_data
= (struct sta_data
*)param_ex
->data
;
2600 DBG_88E("rtw_ioctl_get_sta_info, sta_addr: %pM\n", (param_ex
->sta_addr
));
2602 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2605 if (param_ex
->sta_addr
[0] == 0xff && param_ex
->sta_addr
[1] == 0xff &&
2606 param_ex
->sta_addr
[2] == 0xff && param_ex
->sta_addr
[3] == 0xff &&
2607 param_ex
->sta_addr
[4] == 0xff && param_ex
->sta_addr
[5] == 0xff)
2610 psta
= rtw_get_stainfo(pstapriv
, param_ex
->sta_addr
);
2612 psta_data
->aid
= (u16
)psta
->aid
;
2613 psta_data
->capability
= psta
->capability
;
2614 psta_data
->flags
= psta
->flags
;
2618 no_short_slot_time_set : BIT(1)
2619 no_short_preamble_set : BIT(2)
2620 no_ht_gf_set : BIT(3)
2622 ht_20mhz_set : BIT(5)
2625 psta_data
->sta_set
= ((psta
->nonerp_set
) |
2626 (psta
->no_short_slot_time_set
<< 1) |
2627 (psta
->no_short_preamble_set
<< 2) |
2628 (psta
->no_ht_gf_set
<< 3) |
2629 (psta
->no_ht_set
<< 4) |
2630 (psta
->ht_20mhz_set
<< 5));
2631 psta_data
->tx_supp_rates_len
= psta
->bssratelen
;
2632 memcpy(psta_data
->tx_supp_rates
, psta
->bssrateset
, psta
->bssratelen
);
2633 memcpy(&psta_data
->ht_cap
, &psta
->htpriv
.ht_cap
, sizeof(struct rtw_ieee80211_ht_cap
));
2634 psta_data
->rx_pkts
= psta
->sta_stats
.rx_data_pkts
;
2635 psta_data
->rx_bytes
= psta
->sta_stats
.rx_bytes
;
2636 psta_data
->rx_drops
= psta
->sta_stats
.rx_drops
;
2637 psta_data
->tx_pkts
= psta
->sta_stats
.tx_pkts
;
2638 psta_data
->tx_bytes
= psta
->sta_stats
.tx_bytes
;
2639 psta_data
->tx_drops
= psta
->sta_stats
.tx_drops
;
2647 static int rtw_get_sta_wpaie(struct net_device
*dev
, struct ieee_param
*param
)
2650 struct sta_info
*psta
= NULL
;
2651 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2652 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2653 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2655 DBG_88E("rtw_get_sta_wpaie, sta_addr: %pM\n", (param
->sta_addr
));
2657 if (check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != true)
2660 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2661 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2662 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2665 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
2667 if ((psta
->wpa_ie
[0] == WLAN_EID_RSN
) || (psta
->wpa_ie
[0] == WLAN_EID_GENERIC
)) {
2671 wpa_ie_len
= psta
->wpa_ie
[1];
2672 copy_len
= ((wpa_ie_len
+2) > sizeof(psta
->wpa_ie
)) ? (sizeof(psta
->wpa_ie
)) : (wpa_ie_len
+2);
2673 param
->u
.wpa_ie
.len
= copy_len
;
2674 memcpy(param
->u
.wpa_ie
.reserved
, psta
->wpa_ie
, copy_len
);
2676 DBG_88E("sta's wpa_ie is NONE\n");
2685 static int rtw_set_wps_beacon(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2688 unsigned char wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
2689 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2690 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2691 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
2694 DBG_88E("%s, len =%d\n", __func__
, len
);
2696 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2699 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2701 kfree(pmlmepriv
->wps_beacon_ie
);
2702 pmlmepriv
->wps_beacon_ie
= NULL
;
2705 pmlmepriv
->wps_beacon_ie
= rtw_malloc(ie_len
);
2706 pmlmepriv
->wps_beacon_ie_len
= ie_len
;
2707 if (pmlmepriv
->wps_beacon_ie
== NULL
) {
2708 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2712 memcpy(pmlmepriv
->wps_beacon_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2714 update_beacon(padapter
, _VENDOR_SPECIFIC_IE_
, wps_oui
, true);
2716 pmlmeext
->bstart_bss
= true;
2722 static int rtw_set_wps_probe_resp(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2725 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2726 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2729 DBG_88E("%s, len =%d\n", __func__
, len
);
2731 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2734 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2736 kfree(pmlmepriv
->wps_probe_resp_ie
);
2737 pmlmepriv
->wps_probe_resp_ie
= NULL
;
2740 pmlmepriv
->wps_probe_resp_ie
= rtw_malloc(ie_len
);
2741 pmlmepriv
->wps_probe_resp_ie_len
= ie_len
;
2742 if (pmlmepriv
->wps_probe_resp_ie
== NULL
) {
2743 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2746 memcpy(pmlmepriv
->wps_probe_resp_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2752 static int rtw_set_wps_assoc_resp(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2755 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2756 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2759 DBG_88E("%s, len =%d\n", __func__
, len
);
2761 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2764 ie_len
= len
-12-2;/* 12 = param header, 2:no packed */
2766 kfree(pmlmepriv
->wps_assoc_resp_ie
);
2767 pmlmepriv
->wps_assoc_resp_ie
= NULL
;
2770 pmlmepriv
->wps_assoc_resp_ie
= rtw_malloc(ie_len
);
2771 pmlmepriv
->wps_assoc_resp_ie_len
= ie_len
;
2772 if (pmlmepriv
->wps_assoc_resp_ie
== NULL
) {
2773 DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2777 memcpy(pmlmepriv
->wps_assoc_resp_ie
, param
->u
.bcn_ie
.buf
, ie_len
);
2783 static int rtw_set_hidden_ssid(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2786 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2787 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2788 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
2789 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2793 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2796 if (param
->u
.wpa_param
.name
!= 0) /* dummy test... */
2797 DBG_88E("%s name(%u) != 0\n", __func__
, param
->u
.wpa_param
.name
);
2798 value
= param
->u
.wpa_param
.value
;
2800 /* use the same definition of hostapd's ignore_broadcast_ssid */
2801 if (value
!= 1 && value
!= 2)
2803 DBG_88E("%s value(%u)\n", __func__
, value
);
2804 pmlmeinfo
->hidden_ssid_mode
= value
;
2808 static int rtw_ioctl_acl_remove_sta(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2811 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2812 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2814 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2817 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2818 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2819 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2821 ret
= rtw_acl_remove_sta(padapter
, param
->sta_addr
);
2825 static int rtw_ioctl_acl_add_sta(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2828 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2829 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2831 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2834 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
2835 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
2836 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
2838 ret
= rtw_acl_add_sta(padapter
, param
->sta_addr
);
2842 static int rtw_ioctl_set_macaddr_acl(struct net_device
*dev
, struct ieee_param
*param
, int len
)
2845 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2846 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2848 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != true)
2851 rtw_set_macaddr_acl(padapter
, param
->u
.mlme
.command
);
2856 static int rtw_hostapd_ioctl(struct net_device
*dev
, struct iw_point
*p
)
2858 struct ieee_param
*param
;
2860 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2863 * this function is expect to call in master mode, which allows no power saving
2864 * so, we just check hw_init_completed
2867 if (!padapter
->hw_init_completed
) {
2877 param
= (struct ieee_param
*)rtw_malloc(p
->length
);
2878 if (param
== NULL
) {
2883 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
2889 switch (param
->cmd
) {
2890 case RTL871X_HOSTAPD_FLUSH
:
2891 ret
= rtw_hostapd_sta_flush(dev
);
2893 case RTL871X_HOSTAPD_ADD_STA
:
2894 ret
= rtw_add_sta(dev
, param
);
2896 case RTL871X_HOSTAPD_REMOVE_STA
:
2897 ret
= rtw_del_sta(dev
, param
);
2899 case RTL871X_HOSTAPD_SET_BEACON
:
2900 ret
= rtw_set_beacon(dev
, param
, p
->length
);
2902 case RTL871X_SET_ENCRYPTION
:
2903 ret
= rtw_set_encryption(dev
, param
, p
->length
);
2905 case RTL871X_HOSTAPD_GET_WPAIE_STA
:
2906 ret
= rtw_get_sta_wpaie(dev
, param
);
2908 case RTL871X_HOSTAPD_SET_WPS_BEACON
:
2909 ret
= rtw_set_wps_beacon(dev
, param
, p
->length
);
2911 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP
:
2912 ret
= rtw_set_wps_probe_resp(dev
, param
, p
->length
);
2914 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP
:
2915 ret
= rtw_set_wps_assoc_resp(dev
, param
, p
->length
);
2917 case RTL871X_HOSTAPD_SET_HIDDEN_SSID
:
2918 ret
= rtw_set_hidden_ssid(dev
, param
, p
->length
);
2920 case RTL871X_HOSTAPD_GET_INFO_STA
:
2921 ret
= rtw_ioctl_get_sta_data(dev
, param
, p
->length
);
2923 case RTL871X_HOSTAPD_SET_MACADDR_ACL
:
2924 ret
= rtw_ioctl_set_macaddr_acl(dev
, param
, p
->length
);
2926 case RTL871X_HOSTAPD_ACL_ADD_STA
:
2927 ret
= rtw_ioctl_acl_add_sta(dev
, param
, p
->length
);
2929 case RTL871X_HOSTAPD_ACL_REMOVE_STA
:
2930 ret
= rtw_ioctl_acl_remove_sta(dev
, param
, p
->length
);
2933 DBG_88E("Unknown hostapd request: %d\n", param
->cmd
);
2938 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
2946 #include <rtw_android.h>
2947 static int rtw_wx_set_priv(struct net_device
*dev
,
2948 struct iw_request_info
*info
,
2949 union iwreq_data
*awrq
,
2955 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
2956 struct iw_point
*dwrq
= (struct iw_point
*)awrq
;
2958 if (dwrq
->length
== 0)
2966 if (copy_from_user(ext
, dwrq
->pointer
, len
)) {
2971 /* added for wps2.0 @20110524 */
2972 if (dwrq
->flags
== 0x8766 && len
> 8) {
2974 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2975 u8
*probereq_wpsie
= ext
;
2976 int probereq_wpsie_len
= len
;
2977 u8 wps_oui
[4] = {0x0, 0x50, 0xf2, 0x04};
2979 if ((_VENDOR_SPECIFIC_IE_
== probereq_wpsie
[0]) &&
2980 (!memcmp(&probereq_wpsie
[2], wps_oui
, 4))) {
2981 cp_sz
= probereq_wpsie_len
> MAX_WPS_IE_LEN
? MAX_WPS_IE_LEN
: probereq_wpsie_len
;
2983 pmlmepriv
->wps_probe_req_ie_len
= 0;
2984 kfree(pmlmepriv
->wps_probe_req_ie
);
2985 pmlmepriv
->wps_probe_req_ie
= NULL
;
2987 pmlmepriv
->wps_probe_req_ie
= rtw_malloc(cp_sz
);
2988 if (pmlmepriv
->wps_probe_req_ie
== NULL
) {
2989 pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__
, __LINE__
);
2993 memcpy(pmlmepriv
->wps_probe_req_ie
, probereq_wpsie
, cp_sz
);
2994 pmlmepriv
->wps_probe_req_ie_len
= cp_sz
;
2999 if (len
>= WEXT_CSCAN_HEADER_SIZE
&&
3000 !memcmp(ext
, WEXT_CSCAN_HEADER
, WEXT_CSCAN_HEADER_SIZE
)) {
3001 ret
= rtw_wx_set_scan(dev
, info
, awrq
, ext
);
3012 static iw_handler rtw_handlers
[] = {
3013 NULL
, /* SIOCSIWCOMMIT */
3014 rtw_wx_get_name
, /* SIOCGIWNAME */
3015 dummy
, /* SIOCSIWNWID */
3016 dummy
, /* SIOCGIWNWID */
3017 rtw_wx_set_freq
, /* SIOCSIWFREQ */
3018 rtw_wx_get_freq
, /* SIOCGIWFREQ */
3019 rtw_wx_set_mode
, /* SIOCSIWMODE */
3020 rtw_wx_get_mode
, /* SIOCGIWMODE */
3021 dummy
, /* SIOCSIWSENS */
3022 rtw_wx_get_sens
, /* SIOCGIWSENS */
3023 NULL
, /* SIOCSIWRANGE */
3024 rtw_wx_get_range
, /* SIOCGIWRANGE */
3025 rtw_wx_set_priv
, /* SIOCSIWPRIV */
3026 NULL
, /* SIOCGIWPRIV */
3027 NULL
, /* SIOCSIWSTATS */
3028 NULL
, /* SIOCGIWSTATS */
3029 dummy
, /* SIOCSIWSPY */
3030 dummy
, /* SIOCGIWSPY */
3031 NULL
, /* SIOCGIWTHRSPY */
3032 NULL
, /* SIOCWIWTHRSPY */
3033 rtw_wx_set_wap
, /* SIOCSIWAP */
3034 rtw_wx_get_wap
, /* SIOCGIWAP */
3035 rtw_wx_set_mlme
, /* request MLME operation; uses struct iw_mlme */
3036 dummy
, /* SIOCGIWAPLIST -- depricated */
3037 rtw_wx_set_scan
, /* SIOCSIWSCAN */
3038 rtw_wx_get_scan
, /* SIOCGIWSCAN */
3039 rtw_wx_set_essid
, /* SIOCSIWESSID */
3040 rtw_wx_get_essid
, /* SIOCGIWESSID */
3041 dummy
, /* SIOCSIWNICKN */
3042 rtw_wx_get_nick
, /* SIOCGIWNICKN */
3043 NULL
, /* -- hole -- */
3044 NULL
, /* -- hole -- */
3045 rtw_wx_set_rate
, /* SIOCSIWRATE */
3046 rtw_wx_get_rate
, /* SIOCGIWRATE */
3047 rtw_wx_set_rts
, /* SIOCSIWRTS */
3048 rtw_wx_get_rts
, /* SIOCGIWRTS */
3049 rtw_wx_set_frag
, /* SIOCSIWFRAG */
3050 rtw_wx_get_frag
, /* SIOCGIWFRAG */
3051 dummy
, /* SIOCSIWTXPOW */
3052 dummy
, /* SIOCGIWTXPOW */
3053 dummy
, /* SIOCSIWRETRY */
3054 rtw_wx_get_retry
, /* SIOCGIWRETRY */
3055 rtw_wx_set_enc
, /* SIOCSIWENCODE */
3056 rtw_wx_get_enc
, /* SIOCGIWENCODE */
3057 dummy
, /* SIOCSIWPOWER */
3058 rtw_wx_get_power
, /* SIOCGIWPOWER */
3059 NULL
, /*---hole---*/
3060 NULL
, /*---hole---*/
3061 rtw_wx_set_gen_ie
, /* SIOCSIWGENIE */
3062 NULL
, /* SIOCGWGENIE */
3063 rtw_wx_set_auth
, /* SIOCSIWAUTH */
3064 NULL
, /* SIOCGIWAUTH */
3065 rtw_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
3066 NULL
, /* SIOCGIWENCODEEXT */
3067 rtw_wx_set_pmkid
, /* SIOCSIWPMKSA */
3068 NULL
, /*---hole---*/
3071 static struct iw_statistics
*rtw_get_wireless_stats(struct net_device
*dev
)
3073 struct adapter
*padapter
= (struct adapter
*)rtw_netdev_priv(dev
);
3074 struct iw_statistics
*piwstats
= &padapter
->iwstats
;
3079 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
3080 piwstats
->qual
.qual
= 0;
3081 piwstats
->qual
.level
= 0;
3082 piwstats
->qual
.noise
= 0;
3084 tmp_level
= padapter
->recvpriv
.signal_strength
;
3085 tmp_qual
= padapter
->recvpriv
.signal_qual
;
3086 tmp_noise
= padapter
->recvpriv
.noise
;
3088 piwstats
->qual
.level
= tmp_level
;
3089 piwstats
->qual
.qual
= tmp_qual
;
3090 piwstats
->qual
.noise
= tmp_noise
;
3092 piwstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
;/* IW_QUAL_DBM; */
3093 return &padapter
->iwstats
;
3096 struct iw_handler_def rtw_handlers_def
= {
3097 .standard
= rtw_handlers
,
3098 .num_standard
= sizeof(rtw_handlers
) / sizeof(iw_handler
),
3099 .get_wireless_stats
= rtw_get_wireless_stats
,
3102 #include <rtw_android.h>
3103 int rtw_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
3105 struct iwreq
*wrq
= (struct iwreq
*)rq
;
3109 case RTL_IOCTL_WPA_SUPPLICANT
:
3110 ret
= wpa_supplicant_ioctl(dev
, &wrq
->u
.data
);
3112 #ifdef CONFIG_88EU_AP_MODE
3113 case RTL_IOCTL_HOSTAPD
:
3114 ret
= rtw_hostapd_ioctl(dev
, &wrq
->u
.data
);
3116 #endif /* CONFIG_88EU_AP_MODE */
3117 case (SIOCDEVPRIVATE
+1):
3118 ret
= rtw_android_priv_cmd(dev
, rq
, cmd
);