This source file includes following definitions.
- indicate_wx_scan_complete_event
- rtw_indicate_wx_assoc_event
- rtw_indicate_wx_disassoc_event
- translate_scan
- wpa_set_auth_algs
- wpa_set_encryption
- rtw_set_wpa_ie
- rtw_wx_get_name
- rtw_wx_set_freq
- rtw_wx_get_freq
- rtw_wx_set_mode
- rtw_wx_get_mode
- rtw_wx_set_pmkid
- rtw_wx_get_sens
- rtw_wx_get_range
- rtw_wx_set_wap
- rtw_wx_get_wap
- rtw_wx_set_mlme
- rtw_wx_set_scan
- rtw_wx_get_scan
- rtw_wx_set_essid
- rtw_wx_get_essid
- rtw_wx_set_rate
- rtw_wx_get_rate
- rtw_wx_set_rts
- rtw_wx_get_rts
- rtw_wx_set_frag
- rtw_wx_get_frag
- rtw_wx_get_retry
- rtw_wx_set_enc
- rtw_wx_get_enc
- rtw_wx_get_power
- rtw_wx_set_gen_ie
- rtw_wx_set_auth
- rtw_wx_set_enc_ext
- rtw_wx_get_nick
- rtw_wx_read32
- rtw_wx_write32
- rtw_wx_read_rf
- rtw_wx_write_rf
- rtw_wx_priv_null
- dummy
- rtw_wx_set_channel_plan
- rtw_wx_set_mtk_wps_probe_ie
- rtw_wx_get_sensitivity
- rtw_wx_set_mtk_wps_ie
- rtw_drvext_hdl
- rtw_mp_ioctl_hdl
- rtw_get_ap_info
- rtw_set_pid
- rtw_wps_start
- rtw_p2p_set
- rtw_p2p_get
- rtw_p2p_get2
- rtw_rereg_nd_name
- rtw_dbg_port
- wpa_set_param
- wpa_mlme
- wpa_supplicant_ioctl
- rtw_set_encryption
- rtw_set_beacon
- rtw_hostapd_sta_flush
- rtw_add_sta
- rtw_del_sta
- rtw_ioctl_get_sta_data
- rtw_get_sta_wpaie
- rtw_set_wps_beacon
- rtw_set_wps_probe_resp
- rtw_set_wps_assoc_resp
- rtw_set_hidden_ssid
- rtw_ioctl_acl_remove_sta
- rtw_ioctl_acl_add_sta
- rtw_ioctl_set_macaddr_acl
- rtw_hostapd_ioctl
- rtw_wx_set_priv
- rtw_pm_set
- rtw_mp_efuse_get
- rtw_mp_efuse_set
- rtw_tdls
- rtw_tdls_get
- rtw_test
- rtw_get_wireless_stats
- get_priv_size
- rtw_ioctl_wext_private
- rtw_ioctl
1
2
3
4
5
6
7 #define _IOCTL_LINUX_C_
8
9 #include <linux/etherdevice.h>
10 #include <drv_types.h>
11 #include <rtw_debug.h>
12 #include <rtw_mp.h>
13 #include <hal_btcoex.h>
14 #include <linux/jiffies.h>
15 #include <linux/kernel.h>
16
17 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)
18
19 #define SCAN_ITEM_SIZE 768
20 #define MAX_CUSTOM_LEN 64
21 #define RATE_COUNT 4
22
23
24 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
25 #define WEXT_CSCAN_HEADER_SIZE 12
26 #define WEXT_CSCAN_SSID_SECTION 'S'
27 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
28 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
29 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
30 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
31 #define WEXT_CSCAN_TYPE_SECTION 'T'
32
33 static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
34 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
35
36 static const char * const iw_operation_mode[] = {
37 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor"
38 };
39
40 void indicate_wx_scan_complete_event(struct adapter *padapter)
41 {
42 union iwreq_data wrqu;
43
44 memset(&wrqu, 0, sizeof(union iwreq_data));
45
46
47 }
48
49
50 void rtw_indicate_wx_assoc_event(struct adapter *padapter)
51 {
52 union iwreq_data wrqu;
53 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
54 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
55 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
56 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
57
58 memset(&wrqu, 0, sizeof(union iwreq_data));
59
60 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
61
62 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ==true)
63 memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
64 else
65 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
66
67 DBG_871X_LEVEL(_drv_always_, "assoc success\n");
68 }
69
70 void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
71 {
72 union iwreq_data wrqu;
73
74 memset(&wrqu, 0, sizeof(union iwreq_data));
75
76 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
77 eth_zero_addr(wrqu.ap_addr.sa_data);
78 }
79
80 static char *translate_scan(struct adapter *padapter,
81 struct iw_request_info* info, struct wlan_network *pnetwork,
82 char *start, char *stop)
83 {
84 struct iw_event iwe;
85 u16 cap;
86 u32 ht_ielen = 0;
87 char *custom = NULL;
88 char *p;
89 u16 max_rate = 0, rate, ht_cap =false, vht_cap = false;
90 u32 i = 0;
91 u8 bw_40MHz = 0, short_GI = 0;
92 u16 mcs_rate = 0, vht_data_rate = 0;
93 u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
94 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
95 u8 ss, sq;
96
97
98 iwe.cmd = SIOCGIWAP;
99 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
100
101 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
102 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
103
104
105 iwe.cmd = SIOCGIWESSID;
106 iwe.u.data.flags = 1;
107 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
108 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
109
110
111 if (pnetwork->network.Reserved[0] == 2) {
112 p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength);
113 } else {
114 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
115 }
116 if (p && ht_ielen>0) {
117 struct rtw_ieee80211_ht_cap *pht_capie;
118 ht_cap = true;
119 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
120 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
121 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
122 short_GI = (le16_to_cpu(pht_capie->cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
123 }
124
125
126 iwe.cmd = SIOCGIWNAME;
127 if (rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) {
128 if (ht_cap)
129 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
130 else
131 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
132 } else if (rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) {
133 if (ht_cap)
134 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
135 else
136 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
137 } else {
138 if (pnetwork->network.Configuration.DSConfig > 14) {
139 if (vht_cap)
140 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
141 else if (ht_cap)
142 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
143 else
144 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
145 } else {
146 if (ht_cap)
147 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
148 else
149 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
150 }
151 }
152
153 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
154
155
156 if (pnetwork->network.Reserved[0] == 2) {
157 cap = 0;
158 } else {
159 __le16 le_tmp;
160
161 iwe.cmd = SIOCGIWMODE;
162 memcpy((u8 *)&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
163 cap = le16_to_cpu(le_tmp);
164 }
165
166 if (cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)) {
167 if (cap & WLAN_CAPABILITY_BSS)
168 iwe.u.mode = IW_MODE_MASTER;
169 else
170 iwe.u.mode = IW_MODE_ADHOC;
171
172 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
173 }
174
175 if (pnetwork->network.Configuration.DSConfig<1 )
176 pnetwork->network.Configuration.DSConfig = 1;
177
178
179 iwe.cmd = SIOCGIWFREQ;
180 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
181 iwe.u.freq.e = 1;
182 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
183 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
184
185
186 iwe.cmd = SIOCGIWENCODE;
187 if (cap & WLAN_CAPABILITY_PRIVACY)
188 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
189 else
190 iwe.u.data.flags = IW_ENCODE_DISABLED;
191 iwe.u.data.length = 0;
192 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
193
194
195 max_rate = 0;
196 custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC);
197 if (!custom)
198 return start;
199 p = custom;
200 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
201 while (pnetwork->network.SupportedRates[i]!= 0) {
202 rate = pnetwork->network.SupportedRates[i]&0x7F;
203 if (rate > max_rate)
204 max_rate = rate;
205 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
206 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
207 i++;
208 }
209
210 if (vht_cap) {
211 max_rate = vht_data_rate;
212 } else if (ht_cap) {
213 if (mcs_rate&0x8000) {
214 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
215 } else {
216
217 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
218 }
219
220 max_rate = max_rate*2;
221 }
222
223 iwe.cmd = SIOCGIWRATE;
224 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
225 iwe.u.bitrate.value = max_rate * 500000;
226 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
227
228
229 if (pnetwork->network.Reserved[0] != 2) {
230 u8 *buf;
231 u8 wpa_ie[255], rsn_ie[255];
232 u16 wpa_len = 0, rsn_len = 0;
233 u8 *p;
234 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
235 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.Ssid.Ssid));
236 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len));
237
238 buf = kzalloc(MAX_WPA_IE_LEN*2, GFP_ATOMIC);
239 if (!buf)
240 return start;
241 if (wpa_len > 0) {
242 p =buf;
243 p += sprintf(p, "wpa_ie =");
244 for (i = 0; i < wpa_len; i++)
245 p += sprintf(p, "%02x", wpa_ie[i]);
246
247 if (wpa_len > 100) {
248 printk("-----------------Len %d----------------\n", wpa_len);
249 for (i = 0; i < wpa_len; i++)
250 printk("%02x ", wpa_ie[i]);
251 printk("\n");
252 printk("-----------------Len %d----------------\n", wpa_len);
253 }
254
255 memset(&iwe, 0, sizeof(iwe));
256 iwe.cmd = IWEVCUSTOM;
257 iwe.u.data.length = strlen(buf);
258 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
259
260 memset(&iwe, 0, sizeof(iwe));
261 iwe.cmd =IWEVGENIE;
262 iwe.u.data.length = wpa_len;
263 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
264 }
265 if (rsn_len > 0) {
266 p = buf;
267 memset(buf, 0, MAX_WPA_IE_LEN*2);
268 p += sprintf(p, "rsn_ie =");
269 for (i = 0; i < rsn_len; i++)
270 p += sprintf(p, "%02x", rsn_ie[i]);
271 memset(&iwe, 0, sizeof(iwe));
272 iwe.cmd = IWEVCUSTOM;
273 iwe.u.data.length = strlen(buf);
274 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
275
276 memset(&iwe, 0, sizeof(iwe));
277 iwe.cmd =IWEVGENIE;
278 iwe.u.data.length = rsn_len;
279 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
280 }
281 kfree(buf);
282 }
283
284 {
285 uint cnt = 0, total_ielen;
286 u8 *wpsie_ptr = NULL;
287 uint wps_ielen = 0;
288
289 u8 *ie_ptr;
290 total_ielen = pnetwork->network.IELength - ie_offset;
291
292 if (pnetwork->network.Reserved[0] == 2) {
293 ie_ptr = pnetwork->network.IEs;
294 total_ielen = pnetwork->network.IELength;
295 } else {
296 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
297 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
298 }
299
300 while (cnt < total_ielen) {
301 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2)) {
302 wpsie_ptr = &ie_ptr[cnt];
303 iwe.cmd =IWEVGENIE;
304 iwe.u.data.length = (u16)wps_ielen;
305 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
306 }
307 cnt+=ie_ptr[cnt+1]+2;
308 }
309 }
310
311
312 iwe.cmd = IWEVQUAL;
313 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
314 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
315 | IW_QUAL_NOISE_UPDATED
316 #else
317 | IW_QUAL_NOISE_INVALID
318 #endif
319 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
320 | IW_QUAL_DBM
321 #endif
322 ;
323
324 if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
325 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
326 ss = padapter->recvpriv.signal_strength;
327 sq = padapter->recvpriv.signal_qual;
328 } else {
329 ss = pnetwork->network.PhyInfo.SignalStrength;
330 sq = pnetwork->network.PhyInfo.SignalQuality;
331 }
332
333
334 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
335 iwe.u.qual.level = (u8)translate_percentage_to_dbm(ss);
336 #else
337 #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
338 {
339
340
341 struct hal_com_data *pHal = GET_HAL_DATA(padapter);
342
343 iwe.u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
344 }
345 #else
346 iwe.u.qual.level = (u8)ss;
347 #endif
348 #endif
349
350 iwe.u.qual.qual = (u8)sq;
351
352 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
353 {
354 s16 tmp_noise = 0;
355 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
356 iwe.u.qual.noise = tmp_noise ;
357 }
358 #else
359 iwe.u.qual.noise = 0;
360 #endif
361
362
363
364 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
365
366 {
367 u8 *buf;
368 u8 *p, *pos;
369
370 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
371 if (!buf)
372 goto exit;
373 p = buf;
374 pos = pnetwork->network.Reserved;
375 p += sprintf(p, "fm =%02X%02X", pos[1], pos[0]);
376 memset(&iwe, 0, sizeof(iwe));
377 iwe.cmd = IWEVCUSTOM;
378 iwe.u.data.length = strlen(buf);
379 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
380 kfree(buf);
381 }
382 exit:
383 kfree(custom);
384
385 return start;
386 }
387
388 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
389 {
390 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
391 int ret = 0;
392
393 if ((value & WLAN_AUTH_SHARED_KEY) && (value & WLAN_AUTH_OPEN)) {
394 DBG_871X("wpa_set_auth_algs, WLAN_AUTH_SHARED_KEY and WLAN_AUTH_OPEN [value:0x%x]\n", value);
395 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
396 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
397 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
398 } else if (value & WLAN_AUTH_SHARED_KEY) {
399 DBG_871X("wpa_set_auth_algs, WLAN_AUTH_SHARED_KEY [value:0x%x]\n", value);
400 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
401
402 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
403 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
404 } else if (value & WLAN_AUTH_OPEN) {
405 DBG_871X("wpa_set_auth_algs, WLAN_AUTH_OPEN\n");
406
407 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
408 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
409 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
410 }
411 } else if (value & WLAN_AUTH_LEAP) {
412 DBG_871X("wpa_set_auth_algs, WLAN_AUTH_LEAP\n");
413 } else {
414 DBG_871X("wpa_set_auth_algs, error!\n");
415 ret = -EINVAL;
416 }
417
418 return ret;
419
420 }
421
422 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
423 {
424 int ret = 0;
425 u32 wep_key_idx, wep_key_len, wep_total_len;
426 struct ndis_802_11_wep *pwep = NULL;
427 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
428 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
429 struct security_priv *psecuritypriv = &padapter->securitypriv;
430
431 param->u.crypt.err = 0;
432 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
433
434 if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
435 ret = -EINVAL;
436 goto exit;
437 }
438
439 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
440 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
441 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
442 if (param->u.crypt.idx >= WEP_KEYS ||
443 param->u.crypt.idx >= BIP_MAX_KEYID) {
444 ret = -EINVAL;
445 goto exit;
446 }
447 } else {
448 {
449 ret = -EINVAL;
450 goto exit;
451 }
452 }
453
454 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
455 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
456 DBG_871X("wpa_set_encryption, crypt.alg = WEP\n");
457
458 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
459 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
460 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
461
462 wep_key_idx = param->u.crypt.idx;
463 wep_key_len = param->u.crypt.key_len;
464
465 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(1)wep_key_idx =%d\n", wep_key_idx));
466 DBG_871X("(1)wep_key_idx =%d\n", wep_key_idx);
467
468 if (wep_key_idx > WEP_KEYS)
469 return -EINVAL;
470
471 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(2)wep_key_idx =%d\n", wep_key_idx));
472
473 if (wep_key_len > 0) {
474 wep_key_len = wep_key_len <= 5 ? 5 : 13;
475 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
476 pwep = kzalloc(wep_total_len, GFP_KERNEL);
477 if (pwep == NULL) {
478 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n"));
479 goto exit;
480 }
481
482 pwep->KeyLength = wep_key_len;
483 pwep->Length = wep_total_len;
484
485 if (wep_key_len == 13) {
486 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
487 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
488 }
489 } else {
490 ret = -EINVAL;
491 goto exit;
492 }
493
494 pwep->KeyIndex = wep_key_idx;
495 pwep->KeyIndex |= 0x80000000;
496
497 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
498
499 if (param->u.crypt.set_tx) {
500 DBG_871X("wep, set_tx = 1\n");
501
502 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
503 ret = -EOPNOTSUPP ;
504 } else {
505 DBG_871X("wep, set_tx = 0\n");
506
507
508
509
510 if (wep_key_idx >= WEP_KEYS) {
511 ret = -EOPNOTSUPP ;
512 goto exit;
513 }
514
515 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
516 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
517 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true);
518 }
519
520 goto exit;
521 }
522
523 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
524 struct sta_info *psta, *pbcmc_sta;
525 struct sta_priv *pstapriv = &padapter->stapriv;
526
527 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) {
528 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
529 if (psta == NULL) {
530
531 } else {
532
533 if (strcmp(param->u.crypt.alg, "none") != 0)
534 psta->ieee8021x_blocked = false;
535
536 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
537 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
538 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
539 }
540
541 if (param->u.crypt.set_tx == 1) {
542 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
543
544 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
545
546 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
547 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
548
549 padapter->securitypriv.busetkipkey =false;
550
551 }
552
553
554 DBG_871X(" ~~~~set sta key:unicastkey\n");
555
556 rtw_setstakey_cmd(padapter, psta, true, true);
557 } else {
558 if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
559 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));
560
561 if (param->u.crypt.key_len > 16) {
562 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]), 8);
563 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]), 8);
564 }
565 padapter->securitypriv.binstallGrpkey = true;
566
567 DBG_871X(" ~~~~set sta key:groupkey\n");
568
569 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
570
571 rtw_set_key(padapter,&padapter->securitypriv, param->u.crypt.idx, 1, true);
572 } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
573
574
575 memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
576
577
578
579
580 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
581 padapter->securitypriv.binstallBIPkey = true;
582 DBG_871X(" ~~~~set sta key:IGKT\n");
583 }
584 }
585 }
586
587 pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
588 if (pbcmc_sta == NULL) {
589
590 } else {
591
592 if (strcmp(param->u.crypt.alg, "none") != 0)
593 pbcmc_sta->ieee8021x_blocked = false;
594
595 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
596 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
597 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
598 }
599 }
600 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
601
602 }
603 }
604
605 exit:
606
607 kfree(pwep);
608 return ret;
609 }
610
611 static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
612 {
613 u8 *buf = NULL;
614 int group_cipher = 0, pairwise_cipher = 0;
615 int ret = 0;
616 u8 null_addr[]= {0, 0, 0, 0, 0, 0};
617
618 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
619 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
620 if (pie == NULL)
621 return ret;
622 else
623 return -EINVAL;
624 }
625
626 if (ielen) {
627 buf = rtw_zmalloc(ielen);
628 if (buf == NULL) {
629 ret = -ENOMEM;
630 goto exit;
631 }
632
633 memcpy(buf, pie , ielen);
634
635
636 {
637 int i;
638 DBG_871X("\n wpa_ie(length:%d):\n", ielen);
639 for (i = 0;i<ielen;i =i+8)
640 DBG_871X("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]);
641 }
642
643 if (ielen < RSN_HEADER_LEN) {
644 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
645 ret = -1;
646 goto exit;
647 }
648
649 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
650 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
651 padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPAPSK;
652 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
653 }
654
655 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
656 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
657 padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPA2PSK;
658 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
659 }
660
661 if (group_cipher == 0)
662 group_cipher = WPA_CIPHER_NONE;
663 if (pairwise_cipher == 0)
664 pairwise_cipher = WPA_CIPHER_NONE;
665
666 switch (group_cipher) {
667 case WPA_CIPHER_NONE:
668 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
669 padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
670 break;
671 case WPA_CIPHER_WEP40:
672 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
673 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
674 break;
675 case WPA_CIPHER_TKIP:
676 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
677 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
678 break;
679 case WPA_CIPHER_CCMP:
680 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
681 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
682 break;
683 case WPA_CIPHER_WEP104:
684 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
685 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
686 break;
687 }
688
689 switch (pairwise_cipher) {
690 case WPA_CIPHER_NONE:
691 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
692 padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
693 break;
694 case WPA_CIPHER_WEP40:
695 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
696 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
697 break;
698 case WPA_CIPHER_TKIP:
699 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
700 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
701 break;
702 case WPA_CIPHER_CCMP:
703 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
704 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
705 break;
706 case WPA_CIPHER_WEP104:
707 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
708 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
709 break;
710 }
711
712 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
713 {
714 u16 cnt = 0;
715 u8 eid, wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
716
717 while (cnt < ielen) {
718 eid = buf[cnt];
719
720 if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4))) {
721 DBG_871X("SET WPS_IE\n");
722
723 padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
724
725 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
726
727 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
728
729 cnt += buf[cnt+1]+2;
730
731 break;
732 } else {
733 cnt += buf[cnt+1]+2;
734 }
735 }
736 }
737 }
738
739
740 if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
741 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
742 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
743
744
745 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
746
747 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
748 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
749 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
750
751 exit:
752
753 kfree(buf);
754
755 return ret;
756 }
757
758 static int rtw_wx_get_name(struct net_device *dev,
759 struct iw_request_info *info,
760 union iwreq_data *wrqu, char *extra)
761 {
762 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
763 u32 ht_ielen = 0;
764 char *p;
765 u8 ht_cap =false, vht_cap =false;
766 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
767 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
768 NDIS_802_11_RATES_EX* prates = NULL;
769
770 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("cmd_code =%x\n", info->cmd));
771
772 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
773
774 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
775 if (p && ht_ielen>0)
776 ht_cap = true;
777
778 prates = &pcur_bss->SupportedRates;
779
780 if (rtw_is_cckratesonly_included((u8 *)prates)) {
781 if (ht_cap)
782 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
783 else
784 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
785 } else if (rtw_is_cckrates_included((u8 *)prates)) {
786 if (ht_cap)
787 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
788 else
789 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
790 } else {
791 if (pcur_bss->Configuration.DSConfig > 14) {
792 if (vht_cap)
793 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
794 else if (ht_cap)
795 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
796 else
797 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
798 } else {
799 if (ht_cap)
800 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
801 else
802 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
803 }
804 }
805 } else {
806
807
808 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
809 }
810 return 0;
811 }
812
813 static int rtw_wx_set_freq(struct net_device *dev,
814 struct iw_request_info *info,
815 union iwreq_data *wrqu, char *extra)
816 {
817 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
818
819 return 0;
820 }
821
822 static int rtw_wx_get_freq(struct net_device *dev,
823 struct iw_request_info *info,
824 union iwreq_data *wrqu, char *extra)
825 {
826 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
827 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
828 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
829
830 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
831
832 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
833 wrqu->freq.e = 1;
834 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
835
836 } else {
837 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
838 wrqu->freq.e = 1;
839 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
840 }
841
842 return 0;
843 }
844
845 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
846 union iwreq_data *wrqu, char *b)
847 {
848 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
849 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
850 int ret = 0;
851
852 if (_FAIL == rtw_pwr_wakeup(padapter)) {
853 ret = -EPERM;
854 goto exit;
855 }
856
857 if (!padapter->hw_init_completed) {
858 ret = -EPERM;
859 goto exit;
860 }
861
862 switch (wrqu->mode) {
863 case IW_MODE_AUTO:
864 networkType = Ndis802_11AutoUnknown;
865 DBG_871X("set_mode = IW_MODE_AUTO\n");
866 break;
867 case IW_MODE_ADHOC:
868 networkType = Ndis802_11IBSS;
869 DBG_871X("set_mode = IW_MODE_ADHOC\n");
870 break;
871 case IW_MODE_MASTER:
872 networkType = Ndis802_11APMode;
873 DBG_871X("set_mode = IW_MODE_MASTER\n");
874
875 break;
876 case IW_MODE_INFRA:
877 networkType = Ndis802_11Infrastructure;
878 DBG_871X("set_mode = IW_MODE_INFRA\n");
879 break;
880
881 default :
882 ret = -EINVAL;
883 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode]));
884 goto exit;
885 }
886
887
888
889
890
891
892
893
894
895
896
897
898 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==false) {
899
900 ret = -EPERM;
901 goto exit;
902
903 }
904
905 rtw_setopmode_cmd(padapter, networkType, true);
906
907 exit:
908 return ret;
909 }
910
911 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
912 union iwreq_data *wrqu, char *b)
913 {
914 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
915 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
916
917 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
918
919 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
920 wrqu->mode = IW_MODE_INFRA;
921 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
922 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
923 wrqu->mode = IW_MODE_ADHOC;
924 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
925 wrqu->mode = IW_MODE_MASTER;
926 } else {
927 wrqu->mode = IW_MODE_AUTO;
928 }
929 return 0;
930 }
931
932
933 static int rtw_wx_set_pmkid(struct net_device *dev,
934 struct iw_request_info *a,
935 union iwreq_data *wrqu, char *extra)
936 {
937 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
938 u8 j, blInserted = false;
939 int intReturn = false;
940 struct security_priv *psecuritypriv = &padapter->securitypriv;
941 struct iw_pmksa* pPMK = (struct iw_pmksa *)extra;
942 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
943 u8 strIssueBssid[ ETH_ALEN ] = { 0x00 };
944
945
946
947
948
949
950
951
952 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
953 if (pPMK->cmd == IW_PMKSA_ADD) {
954 DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
955 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
956 return intReturn;
957 else
958 intReturn = true;
959
960 blInserted = false;
961
962
963 for (j = 0 ; j<NUM_PMKID_CACHE; j++) {
964 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
965
966 DBG_871X("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
967
968 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
969 psecuritypriv->PMKIDList[ j ].bUsed = true;
970 psecuritypriv->PMKIDIndex = j+1;
971 blInserted = true;
972 break;
973 }
974 }
975
976 if (!blInserted) {
977
978 DBG_871X("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
979 psecuritypriv->PMKIDIndex);
980
981 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
982 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
983
984 psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = true;
985 psecuritypriv->PMKIDIndex++ ;
986 if (psecuritypriv->PMKIDIndex == 16)
987 psecuritypriv->PMKIDIndex = 0;
988 }
989 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
990 DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
991 intReturn = true;
992 for (j = 0 ; j<NUM_PMKID_CACHE; j++) {
993 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
994
995 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
996 psecuritypriv->PMKIDList[ j ].bUsed = false;
997 break;
998 }
999 }
1000 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
1001 DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
1002 memset(&psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
1003 psecuritypriv->PMKIDIndex = 0;
1004 intReturn = true;
1005 }
1006 return intReturn;
1007 }
1008
1009 static int rtw_wx_get_sens(struct net_device *dev,
1010 struct iw_request_info *info,
1011 union iwreq_data *wrqu, char *extra)
1012 {
1013 {
1014 wrqu->sens.value = 0;
1015 wrqu->sens.fixed = 0;
1016 wrqu->sens.disabled = 1;
1017 }
1018 return 0;
1019 }
1020
1021 static int rtw_wx_get_range(struct net_device *dev,
1022 struct iw_request_info *info,
1023 union iwreq_data *wrqu, char *extra)
1024 {
1025 struct iw_range *range = (struct iw_range *)extra;
1026 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1027 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1028
1029 u16 val;
1030 int i;
1031
1032 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd));
1033
1034 wrqu->data.length = sizeof(*range);
1035 memset(range, 0, sizeof(*range));
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 range->throughput = 5 * 1000 * 1000;
1047
1048
1049
1050
1051 range->max_qual.qual = 100;
1052 range->max_qual.level = 100;
1053 range->max_qual.noise = 100;
1054 range->max_qual.updated = 7;
1055
1056
1057 range->avg_qual.qual = 92;
1058
1059 range->avg_qual.level = 256 - 78;
1060 range->avg_qual.noise = 0;
1061 range->avg_qual.updated = 7;
1062
1063 range->num_bitrates = RATE_COUNT;
1064
1065 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
1066 range->bitrate[i] = rtw_rates[i];
1067
1068 range->min_frag = MIN_FRAG_THRESHOLD;
1069 range->max_frag = MAX_FRAG_THRESHOLD;
1070
1071 range->pm_capa = 0;
1072
1073 range->we_version_compiled = WIRELESS_EXT;
1074 range->we_version_source = 16;
1075
1076 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
1077
1078
1079 if (pmlmeext->channel_set[i].ChannelNum != 0) {
1080 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
1081 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
1082 range->freq[val].e = 1;
1083 val++;
1084 }
1085
1086 if (val == IW_MAX_FREQUENCIES)
1087 break;
1088 }
1089
1090 range->num_channels = val;
1091 range->num_frequency = val;
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
1110 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
1111
1112 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
1113 IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
1114
1115 return 0;
1116 }
1117
1118
1119
1120
1121
1122
1123 static int rtw_wx_set_wap(struct net_device *dev,
1124 struct iw_request_info *info,
1125 union iwreq_data *awrq,
1126 char *extra)
1127 {
1128 uint ret = 0;
1129 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1130 struct sockaddr *temp = (struct sockaddr *)awrq;
1131 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1132 struct list_head *phead;
1133 u8 *dst_bssid, *src_bssid;
1134 struct __queue *queue = &(pmlmepriv->scanned_queue);
1135 struct wlan_network *pnetwork = NULL;
1136 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1137
1138 rtw_ps_deny(padapter, PS_DENY_JOIN);
1139 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1140 ret = -1;
1141 goto exit;
1142 }
1143
1144 if (!padapter->bup) {
1145 ret = -1;
1146 goto exit;
1147 }
1148
1149
1150 if (temp->sa_family != ARPHRD_ETHER) {
1151 ret = -EINVAL;
1152 goto exit;
1153 }
1154
1155 authmode = padapter->securitypriv.ndisauthtype;
1156 spin_lock_bh(&queue->lock);
1157 phead = get_list_head(queue);
1158 pmlmepriv->pscanned = get_next(phead);
1159
1160 while (1) {
1161 if (phead == pmlmepriv->pscanned)
1162 break;
1163
1164 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1165
1166 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1167
1168 dst_bssid = pnetwork->network.MacAddress;
1169
1170 src_bssid = temp->sa_data;
1171
1172 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
1173 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1174 ret = -1;
1175 spin_unlock_bh(&queue->lock);
1176 goto exit;
1177 }
1178 break;
1179 }
1180
1181 }
1182 spin_unlock_bh(&queue->lock);
1183
1184 rtw_set_802_11_authentication_mode(padapter, authmode);
1185
1186 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) {
1187 ret = -1;
1188 goto exit;
1189 }
1190
1191 exit:
1192
1193 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1194
1195 return ret;
1196 }
1197
1198 static int rtw_wx_get_wap(struct net_device *dev,
1199 struct iw_request_info *info,
1200 union iwreq_data *wrqu, char *extra)
1201 {
1202
1203 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1204 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1205 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1206
1207 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1208
1209 eth_zero_addr(wrqu->ap_addr.sa_data);
1210
1211 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n"));
1212
1213 if (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) ||
1214 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) ||
1215 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) {
1216 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1217 } else {
1218 eth_zero_addr(wrqu->ap_addr.sa_data);
1219 }
1220
1221 return 0;
1222 }
1223
1224 static int rtw_wx_set_mlme(struct net_device *dev,
1225 struct iw_request_info *info,
1226 union iwreq_data *wrqu, char *extra)
1227 {
1228 int ret = 0;
1229 u16 reason;
1230 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1231 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1232
1233
1234 if (mlme == NULL)
1235 return -1;
1236
1237 DBG_871X("%s\n", __func__);
1238
1239 reason = mlme->reason_code;
1240
1241 DBG_871X("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
1242
1243 switch (mlme->cmd) {
1244 case IW_MLME_DEAUTH:
1245 if (!rtw_set_802_11_disassociate(padapter))
1246 ret = -1;
1247 break;
1248 case IW_MLME_DISASSOC:
1249 if (!rtw_set_802_11_disassociate(padapter))
1250 ret = -1;
1251 break;
1252 default:
1253 return -EOPNOTSUPP;
1254 }
1255
1256 return ret;
1257 }
1258
1259 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1260 union iwreq_data *wrqu, char *extra)
1261 {
1262 u8 _status = false;
1263 int ret = 0;
1264 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1265 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1266 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1267 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
1268
1269 #ifdef DBG_IOCTL
1270 DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
1271 #endif
1272
1273 rtw_ps_deny(padapter, PS_DENY_SCAN);
1274 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1275 ret = -1;
1276 goto exit;
1277 }
1278
1279 if (padapter->bDriverStopped) {
1280 DBG_871X("bDriverStopped =%d\n", padapter->bDriverStopped);
1281 ret = -1;
1282 goto exit;
1283 }
1284
1285 if (!padapter->bup) {
1286 ret = -1;
1287 goto exit;
1288 }
1289
1290 if (!padapter->hw_init_completed ) {
1291 ret = -1;
1292 goto exit;
1293 }
1294
1295
1296
1297
1298 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1299 indicate_wx_scan_complete_event(padapter);
1300 goto exit;
1301 }
1302
1303 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) {
1304 indicate_wx_scan_complete_event(padapter);
1305 goto exit;
1306 }
1307
1308 memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
1309
1310 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1311 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1312
1313 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1314 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1315
1316 memcpy(ssid[0].Ssid, req->essid, len);
1317 ssid[0].SsidLength = len;
1318
1319 DBG_871X("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len);
1320
1321 spin_lock_bh(&pmlmepriv->lock);
1322
1323 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1324
1325 spin_unlock_bh(&pmlmepriv->lock);
1326
1327 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
1328 DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1329 }
1330
1331 } else if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
1332 && !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1333 int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
1334 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
1335 char section;
1336 char sec_len;
1337 int ssid_index = 0;
1338
1339
1340
1341 while (len >= 1) {
1342 section = *(pos++); len-= 1;
1343
1344 switch (section) {
1345 case WEXT_CSCAN_SSID_SECTION:
1346
1347 if (len < 1) {
1348 len = 0;
1349 break;
1350 }
1351
1352 sec_len = *(pos++); len-= 1;
1353
1354 if (sec_len>0 && sec_len<=len) {
1355 ssid[ssid_index].SsidLength = sec_len;
1356 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1357
1358
1359 ssid_index++;
1360 }
1361
1362 pos+=sec_len; len-=sec_len;
1363 break;
1364
1365
1366 case WEXT_CSCAN_CHANNEL_SECTION:
1367
1368 pos+= 1; len-= 1;
1369 break;
1370 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1371
1372 pos+=2; len-=2;
1373 break;
1374 case WEXT_CSCAN_PASV_DWELL_SECTION:
1375
1376 pos+=2; len-=2;
1377 break;
1378 case WEXT_CSCAN_HOME_DWELL_SECTION:
1379
1380 pos+=2; len-=2;
1381 break;
1382 case WEXT_CSCAN_TYPE_SECTION:
1383
1384 pos+= 1; len-= 1;
1385 break;
1386 default:
1387
1388 len = 0;
1389 }
1390
1391
1392 }
1393
1394
1395 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1396
1397 } else {
1398 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1399 }
1400
1401 if (_status == false)
1402 ret = -1;
1403
1404 exit:
1405
1406 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
1407
1408 #ifdef DBG_IOCTL
1409 DBG_871X("DBG_IOCTL %s:%d return %d\n", __func__, __LINE__, ret);
1410 #endif
1411
1412 return ret;
1413 }
1414
1415 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1416 union iwreq_data *wrqu, char *extra)
1417 {
1418 struct list_head *plist, *phead;
1419 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1420 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1421 struct __queue *queue = &(pmlmepriv->scanned_queue);
1422 struct wlan_network *pnetwork = NULL;
1423 char *ev = extra;
1424 char *stop = ev + wrqu->data.length;
1425 u32 ret = 0;
1426 sint wait_status;
1427
1428 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
1429 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
1430
1431 #ifdef DBG_IOCTL
1432 DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
1433 #endif
1434
1435 if (adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped) {
1436 ret = -EINVAL;
1437 goto exit;
1438 }
1439
1440 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1441
1442 if (check_fwstate(pmlmepriv, wait_status))
1443 return -EAGAIN;
1444
1445 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1446
1447 phead = get_list_head(queue);
1448 plist = get_next(phead);
1449
1450 while (1) {
1451 if (phead == plist)
1452 break;
1453
1454 if ((stop - ev) < SCAN_ITEM_SIZE) {
1455 ret = -E2BIG;
1456 break;
1457 }
1458
1459 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1460
1461
1462 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1463 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
1464 && true == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
1465
1466 ev =translate_scan(padapter, a, pnetwork, ev, stop);
1467 }
1468
1469 plist = get_next(plist);
1470
1471 }
1472
1473 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1474
1475 wrqu->data.length = ev-extra;
1476 wrqu->data.flags = 0;
1477
1478 exit:
1479
1480 #ifdef DBG_IOCTL
1481 DBG_871X("DBG_IOCTL %s:%d return %d\n", __func__, __LINE__, ret);
1482 #endif
1483
1484 return ret ;
1485
1486 }
1487
1488
1489
1490
1491
1492
1493 static int rtw_wx_set_essid(struct net_device *dev,
1494 struct iw_request_info *a,
1495 union iwreq_data *wrqu, char *extra)
1496 {
1497 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1498 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1499 struct __queue *queue = &pmlmepriv->scanned_queue;
1500 struct list_head *phead;
1501 struct wlan_network *pnetwork = NULL;
1502 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1503 struct ndis_802_11_ssid ndis_ssid;
1504 u8 *dst_ssid, *src_ssid;
1505
1506 uint ret = 0, len;
1507
1508 #ifdef DBG_IOCTL
1509 DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
1510 #endif
1511
1512 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1513 ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv)));
1514
1515 rtw_ps_deny(padapter, PS_DENY_JOIN);
1516 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1517 ret = -1;
1518 goto exit;
1519 }
1520
1521 if (!padapter->bup) {
1522 ret = -1;
1523 goto exit;
1524 }
1525
1526 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1527 ret = -E2BIG;
1528 goto exit;
1529 }
1530
1531 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1532 ret = -1;
1533 goto exit;
1534 }
1535
1536 authmode = padapter->securitypriv.ndisauthtype;
1537 DBG_871X("=>%s\n", __func__);
1538 if (wrqu->essid.flags && wrqu->essid.length) {
1539 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
1540
1541 if (wrqu->essid.length != 33)
1542 DBG_871X("ssid =%s, len =%d\n", extra, wrqu->essid.length);
1543
1544 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1545 ndis_ssid.SsidLength = len;
1546 memcpy(ndis_ssid.Ssid, extra, len);
1547 src_ssid = ndis_ssid.Ssid;
1548
1549 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid));
1550 spin_lock_bh(&queue->lock);
1551 phead = get_list_head(queue);
1552 pmlmepriv->pscanned = get_next(phead);
1553
1554 while (1) {
1555 if (phead == pmlmepriv->pscanned) {
1556 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
1557 ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
1558
1559 break;
1560 }
1561
1562 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1563
1564 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1565
1566 dst_ssid = pnetwork->network.Ssid.Ssid;
1567
1568 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1569 ("rtw_wx_set_essid: dst_ssid =%s\n",
1570 pnetwork->network.Ssid.Ssid));
1571
1572 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
1573 (pnetwork->network.Ssid.SsidLength ==ndis_ssid.SsidLength)) {
1574 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1575 ("rtw_wx_set_essid: find match, set infra mode\n"));
1576
1577 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
1578 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1579 continue;
1580 }
1581
1582 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == false) {
1583 ret = -1;
1584 spin_unlock_bh(&queue->lock);
1585 goto exit;
1586 }
1587
1588 break;
1589 }
1590 }
1591 spin_unlock_bh(&queue->lock);
1592 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1593 ("set ssid: set_802_11_auth. mode =%d\n", authmode));
1594 rtw_set_802_11_authentication_mode(padapter, authmode);
1595
1596 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) {
1597 ret = -1;
1598 goto exit;
1599 }
1600 }
1601
1602 exit:
1603
1604 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1605
1606 DBG_871X("<=%s, ret %d\n", __func__, ret);
1607
1608 #ifdef DBG_IOCTL
1609 DBG_871X("DBG_IOCTL %s:%d return %d\n", __func__, __LINE__, ret);
1610 #endif
1611
1612 return ret;
1613 }
1614
1615 static int rtw_wx_get_essid(struct net_device *dev,
1616 struct iw_request_info *a,
1617 union iwreq_data *wrqu, char *extra)
1618 {
1619 u32 len, ret = 0;
1620 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1621 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1622 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1623
1624 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
1625
1626 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
1627 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
1628 len = pcur_bss->Ssid.SsidLength;
1629
1630 wrqu->essid.length = len;
1631
1632 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1633
1634 wrqu->essid.flags = 1;
1635 } else {
1636 ret = -1;
1637 goto exit;
1638 }
1639
1640 exit:
1641 return ret;
1642 }
1643
1644 static int rtw_wx_set_rate(struct net_device *dev,
1645 struct iw_request_info *a,
1646 union iwreq_data *wrqu, char *extra)
1647 {
1648 int i, ret = 0;
1649 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1650 u8 datarates[NumRates];
1651 u32 target_rate = wrqu->bitrate.value;
1652 u32 fixed = wrqu->bitrate.fixed;
1653 u32 ratevalue = 0;
1654 u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1655
1656 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n"));
1657 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed));
1658
1659 if (target_rate == -1) {
1660 ratevalue = 11;
1661 goto set_rate;
1662 }
1663 target_rate = target_rate/100000;
1664
1665 switch (target_rate) {
1666 case 10:
1667 ratevalue = 0;
1668 break;
1669 case 20:
1670 ratevalue = 1;
1671 break;
1672 case 55:
1673 ratevalue = 2;
1674 break;
1675 case 60:
1676 ratevalue = 3;
1677 break;
1678 case 90:
1679 ratevalue = 4;
1680 break;
1681 case 110:
1682 ratevalue = 5;
1683 break;
1684 case 120:
1685 ratevalue = 6;
1686 break;
1687 case 180:
1688 ratevalue = 7;
1689 break;
1690 case 240:
1691 ratevalue = 8;
1692 break;
1693 case 360:
1694 ratevalue = 9;
1695 break;
1696 case 480:
1697 ratevalue = 10;
1698 break;
1699 case 540:
1700 ratevalue = 11;
1701 break;
1702 default:
1703 ratevalue = 11;
1704 break;
1705 }
1706
1707 set_rate:
1708
1709 for (i = 0; i<NumRates; i++) {
1710 if (ratevalue ==mpdatarate[i]) {
1711 datarates[i] = mpdatarate[i];
1712 if (fixed == 0)
1713 break;
1714 } else {
1715 datarates[i] = 0xff;
1716 }
1717
1718 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i]));
1719 }
1720
1721 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
1722 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("rtw_wx_set_rate Fail!!!\n"));
1723 ret = -1;
1724 }
1725 return ret;
1726 }
1727
1728 static int rtw_wx_get_rate(struct net_device *dev,
1729 struct iw_request_info *info,
1730 union iwreq_data *wrqu, char *extra)
1731 {
1732 u16 max_rate = 0;
1733
1734 max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
1735
1736 if (max_rate == 0)
1737 return -EPERM;
1738
1739 wrqu->bitrate.fixed = 0;
1740 wrqu->bitrate.value = max_rate * 100000;
1741
1742 return 0;
1743 }
1744
1745 static int rtw_wx_set_rts(struct net_device *dev,
1746 struct iw_request_info *info,
1747 union iwreq_data *wrqu, char *extra)
1748 {
1749 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1750
1751 if (wrqu->rts.disabled)
1752 padapter->registrypriv.rts_thresh = 2347;
1753 else {
1754 if (wrqu->rts.value < 0 ||
1755 wrqu->rts.value > 2347)
1756 return -EINVAL;
1757
1758 padapter->registrypriv.rts_thresh = wrqu->rts.value;
1759 }
1760
1761 DBG_871X("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1762
1763 return 0;
1764 }
1765
1766 static int rtw_wx_get_rts(struct net_device *dev,
1767 struct iw_request_info *info,
1768 union iwreq_data *wrqu, char *extra)
1769 {
1770 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1771
1772 DBG_871X("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1773
1774 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1775 wrqu->rts.fixed = 0;
1776
1777
1778 return 0;
1779 }
1780
1781 static int rtw_wx_set_frag(struct net_device *dev,
1782 struct iw_request_info *info,
1783 union iwreq_data *wrqu, char *extra)
1784 {
1785 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1786
1787 if (wrqu->frag.disabled)
1788 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1789 else {
1790 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1791 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1792 return -EINVAL;
1793
1794 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1795 }
1796
1797 DBG_871X("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1798
1799 return 0;
1800
1801 }
1802
1803 static int rtw_wx_get_frag(struct net_device *dev,
1804 struct iw_request_info *info,
1805 union iwreq_data *wrqu, char *extra)
1806 {
1807 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1808
1809 DBG_871X("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1810
1811 wrqu->frag.value = padapter->xmitpriv.frag_len;
1812 wrqu->frag.fixed = 0;
1813
1814
1815 return 0;
1816 }
1817
1818 static int rtw_wx_get_retry(struct net_device *dev,
1819 struct iw_request_info *info,
1820 union iwreq_data *wrqu, char *extra)
1821 {
1822
1823
1824
1825 wrqu->retry.value = 7;
1826 wrqu->retry.fixed = 0;
1827 wrqu->retry.disabled = 1;
1828
1829 return 0;
1830
1831 }
1832
1833 static int rtw_wx_set_enc(struct net_device *dev,
1834 struct iw_request_info *info,
1835 union iwreq_data *wrqu, char *keybuf)
1836 {
1837 u32 key, ret = 0;
1838 u32 keyindex_provided;
1839 struct ndis_802_11_wep wep;
1840 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1841
1842 struct iw_point *erq = &(wrqu->encoding);
1843 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1844 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1845 DBG_871X("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
1846
1847 memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1848
1849 key = erq->flags & IW_ENCODE_INDEX;
1850
1851 if (erq->flags & IW_ENCODE_DISABLED) {
1852 DBG_871X("EncryptionDisabled\n");
1853 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1854 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1855 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1856 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1857 authmode = Ndis802_11AuthModeOpen;
1858 padapter->securitypriv.ndisauthtype =authmode;
1859
1860 goto exit;
1861 }
1862
1863 if (key) {
1864 if (key > WEP_KEYS)
1865 return -EINVAL;
1866 key--;
1867 keyindex_provided = 1;
1868 } else {
1869 keyindex_provided = 0;
1870 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1871 DBG_871X("rtw_wx_set_enc, key =%d\n", key);
1872 }
1873
1874
1875 if (erq->flags & IW_ENCODE_OPEN) {
1876 DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1877 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1878
1879 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1880
1881 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1882 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1883 authmode = Ndis802_11AuthModeOpen;
1884 padapter->securitypriv.ndisauthtype =authmode;
1885 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1886 DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1887 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1888
1889 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1890
1891 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1892 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1893 authmode = Ndis802_11AuthModeShared;
1894 padapter->securitypriv.ndisauthtype =authmode;
1895 } else {
1896 DBG_871X("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
1897
1898 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1899 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1900 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1901 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1902 authmode = Ndis802_11AuthModeOpen;
1903 padapter->securitypriv.ndisauthtype =authmode;
1904 }
1905
1906 wep.KeyIndex = key;
1907 if (erq->length > 0) {
1908 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1909
1910 wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
1911 } else {
1912 wep.KeyLength = 0 ;
1913
1914 if (keyindex_provided == 1) {
1915 padapter->securitypriv.dot11PrivacyKeyIndex = key;
1916
1917 DBG_871X("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
1918
1919 switch (padapter->securitypriv.dot11DefKeylen[key]) {
1920 case 5:
1921 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1922 break;
1923 case 13:
1924 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1925 break;
1926 default:
1927 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1928 break;
1929 }
1930
1931 goto exit;
1932
1933 }
1934
1935 }
1936
1937 wep.KeyIndex |= 0x80000000;
1938
1939 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1940
1941 if (rtw_set_802_11_add_wep(padapter, &wep) == false) {
1942 if (rf_on == pwrpriv->rf_pwrstate)
1943 ret = -EOPNOTSUPP;
1944 goto exit;
1945 }
1946
1947 exit:
1948 return ret;
1949 }
1950
1951 static int rtw_wx_get_enc(struct net_device *dev,
1952 struct iw_request_info *info,
1953 union iwreq_data *wrqu, char *keybuf)
1954 {
1955 uint key, ret = 0;
1956 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1957 struct iw_point *erq = &(wrqu->encoding);
1958 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1959
1960 if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
1961 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true) {
1962 erq->length = 0;
1963 erq->flags |= IW_ENCODE_DISABLED;
1964 return 0;
1965 }
1966 }
1967
1968
1969 key = erq->flags & IW_ENCODE_INDEX;
1970
1971 if (key) {
1972 if (key > WEP_KEYS)
1973 return -EINVAL;
1974 key--;
1975 } else {
1976 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1977 }
1978
1979 erq->flags = key + 1;
1980
1981
1982
1983
1984
1985
1986 switch (padapter->securitypriv.ndisencryptstatus) {
1987 case Ndis802_11EncryptionNotSupported:
1988 case Ndis802_11EncryptionDisabled:
1989 erq->length = 0;
1990 erq->flags |= IW_ENCODE_DISABLED;
1991 break;
1992 case Ndis802_11Encryption1Enabled:
1993 erq->length = padapter->securitypriv.dot11DefKeylen[key];
1994
1995 if (erq->length) {
1996 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1997
1998 erq->flags |= IW_ENCODE_ENABLED;
1999
2000 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2001 erq->flags |= IW_ENCODE_OPEN;
2002 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
2003 erq->flags |= IW_ENCODE_RESTRICTED;
2004 } else {
2005 erq->length = 0;
2006 erq->flags |= IW_ENCODE_DISABLED;
2007 }
2008 break;
2009 case Ndis802_11Encryption2Enabled:
2010 case Ndis802_11Encryption3Enabled:
2011 erq->length = 16;
2012 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
2013 break;
2014 default:
2015 erq->length = 0;
2016 erq->flags |= IW_ENCODE_DISABLED;
2017 break;
2018 }
2019 return ret;
2020 }
2021
2022 static int rtw_wx_get_power(struct net_device *dev,
2023 struct iw_request_info *info,
2024 union iwreq_data *wrqu, char *extra)
2025 {
2026
2027
2028 wrqu->power.value = 0;
2029 wrqu->power.fixed = 0;
2030 wrqu->power.disabled = 1;
2031
2032 return 0;
2033 }
2034
2035 static int rtw_wx_set_gen_ie(struct net_device *dev,
2036 struct iw_request_info *info,
2037 union iwreq_data *wrqu, char *extra)
2038 {
2039 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2040
2041 return rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
2042 }
2043
2044 static int rtw_wx_set_auth(struct net_device *dev,
2045 struct iw_request_info *info,
2046 union iwreq_data *wrqu, char *extra)
2047 {
2048 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2049 struct iw_param *param = (struct iw_param *)&(wrqu->param);
2050 int ret = 0;
2051
2052 switch (param->flags & IW_AUTH_INDEX) {
2053 case IW_AUTH_WPA_VERSION:
2054 break;
2055 case IW_AUTH_CIPHER_PAIRWISE:
2056 break;
2057 case IW_AUTH_CIPHER_GROUP:
2058 break;
2059 case IW_AUTH_KEY_MGMT:
2060
2061
2062
2063 break;
2064 case IW_AUTH_TKIP_COUNTERMEASURES:
2065
2066 if (param->value)
2067 padapter->securitypriv.btkip_countermeasure = true;
2068 else
2069 padapter->securitypriv.btkip_countermeasure = false;
2070 break;
2071 case IW_AUTH_DROP_UNENCRYPTED:
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
2089 break;
2090
2091 if (param->value) {
2092 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2093 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2094 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2095 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2096 padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeOpen;
2097 }
2098
2099 break;
2100 case IW_AUTH_80211_AUTH_ALG:
2101
2102
2103
2104 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2105 LeaveAllPowerSaveMode(padapter);
2106 rtw_disassoc_cmd(padapter, 500, false);
2107 DBG_871X("%s...call rtw_indicate_disconnect\n ", __func__);
2108 rtw_indicate_disconnect(padapter);
2109 rtw_free_assoc_resources(padapter, 1);
2110 }
2111
2112 ret = wpa_set_auth_algs(dev, (u32)param->value);
2113 break;
2114 case IW_AUTH_WPA_ENABLED:
2115 break;
2116 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2117 break;
2118 case IW_AUTH_PRIVACY_INVOKED:
2119 break;
2120 default:
2121 return -EOPNOTSUPP;
2122 }
2123
2124 return ret;
2125 }
2126
2127 static int rtw_wx_set_enc_ext(struct net_device *dev,
2128 struct iw_request_info *info,
2129 union iwreq_data *wrqu, char *extra)
2130 {
2131 char *alg_name;
2132 u32 param_len;
2133 struct ieee_param *param = NULL;
2134 struct iw_point *pencoding = &wrqu->encoding;
2135 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
2136 int ret = 0;
2137
2138 param_len = sizeof(struct ieee_param) + pext->key_len;
2139 param = kzalloc(param_len, GFP_KERNEL);
2140 if (param == NULL)
2141 return -1;
2142
2143 param->cmd = IEEE_CMD_SET_ENCRYPTION;
2144 memset(param->sta_addr, 0xff, ETH_ALEN);
2145
2146
2147 switch (pext->alg) {
2148 case IW_ENCODE_ALG_NONE:
2149
2150
2151 alg_name = "none";
2152 break;
2153 case IW_ENCODE_ALG_WEP:
2154 alg_name = "WEP";
2155 break;
2156 case IW_ENCODE_ALG_TKIP:
2157 alg_name = "TKIP";
2158 break;
2159 case IW_ENCODE_ALG_CCMP:
2160 alg_name = "CCMP";
2161 break;
2162 case IW_ENCODE_ALG_AES_CMAC:
2163 alg_name = "BIP";
2164 break;
2165 default:
2166 ret = -1;
2167 goto exit;
2168 }
2169
2170 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
2171
2172 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2173 param->u.crypt.set_tx = 1;
2174
2175
2176
2177
2178 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
2179 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2180 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC))) {
2181 param->u.crypt.set_tx = 0;
2182 }
2183
2184 param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
2185
2186 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
2187 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
2188
2189 if (pext->key_len) {
2190 param->u.crypt.key_len = pext->key_len;
2191
2192 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
2193 }
2194
2195 if (pencoding->flags & IW_ENCODE_DISABLED) {
2196
2197
2198 }
2199
2200 ret = wpa_set_encryption(dev, param, param_len);
2201
2202 exit:
2203 kfree(param);
2204
2205 return ret;
2206 }
2207
2208
2209 static int rtw_wx_get_nick(struct net_device *dev,
2210 struct iw_request_info *info,
2211 union iwreq_data *wrqu, char *extra)
2212 {
2213
2214
2215
2216
2217 if (extra) {
2218 wrqu->data.length = 14;
2219 wrqu->data.flags = 1;
2220 memcpy(extra, "<WIFI@REALTEK>", 14);
2221 }
2222 return 0;
2223 }
2224
2225 static int rtw_wx_read32(struct net_device *dev,
2226 struct iw_request_info *info,
2227 union iwreq_data *wrqu, char *extra)
2228 {
2229 struct adapter *padapter;
2230 struct iw_point *p;
2231 u16 len;
2232 u32 addr;
2233 u32 data32;
2234 u32 bytes;
2235 u8 *ptmp;
2236 int ret;
2237
2238
2239 ret = 0;
2240 padapter = (struct adapter *)rtw_netdev_priv(dev);
2241 p = &wrqu->data;
2242 len = p->length;
2243 if (0 == len)
2244 return -EINVAL;
2245
2246 ptmp = rtw_malloc(len);
2247 if (NULL == ptmp)
2248 return -ENOMEM;
2249
2250 if (copy_from_user(ptmp, p->pointer, len)) {
2251 ret = -EFAULT;
2252 goto exit;
2253 }
2254
2255 bytes = 0;
2256 addr = 0;
2257 sscanf(ptmp, "%d,%x", &bytes, &addr);
2258
2259 switch (bytes) {
2260 case 1:
2261 data32 = rtw_read8(padapter, addr);
2262 sprintf(extra, "0x%02X", data32);
2263 break;
2264 case 2:
2265 data32 = rtw_read16(padapter, addr);
2266 sprintf(extra, "0x%04X", data32);
2267 break;
2268 case 4:
2269 data32 = rtw_read32(padapter, addr);
2270 sprintf(extra, "0x%08X", data32);
2271 break;
2272 default:
2273 DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
2274 ret = -EINVAL;
2275 goto exit;
2276 }
2277 DBG_871X(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
2278
2279 exit:
2280 kfree(ptmp);
2281
2282 return ret;
2283 }
2284
2285 static int rtw_wx_write32(struct net_device *dev,
2286 struct iw_request_info *info,
2287 union iwreq_data *wrqu, char *extra)
2288 {
2289 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2290
2291 u32 addr;
2292 u32 data32;
2293 u32 bytes;
2294
2295
2296 bytes = 0;
2297 addr = 0;
2298 data32 = 0;
2299 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
2300
2301 switch (bytes) {
2302 case 1:
2303 rtw_write8(padapter, addr, (u8)data32);
2304 DBG_871X(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32);
2305 break;
2306 case 2:
2307 rtw_write16(padapter, addr, (u16)data32);
2308 DBG_871X(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32);
2309 break;
2310 case 4:
2311 rtw_write32(padapter, addr, data32);
2312 DBG_871X(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32);
2313 break;
2314 default:
2315 DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
2316 return -EINVAL;
2317 }
2318
2319 return 0;
2320 }
2321
2322 static int rtw_wx_read_rf(struct net_device *dev,
2323 struct iw_request_info *info,
2324 union iwreq_data *wrqu, char *extra)
2325 {
2326 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2327 u32 path, addr, data32;
2328
2329
2330 path = *(u32 *)extra;
2331 addr = *((u32 *)extra + 1);
2332 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
2333
2334
2335
2336
2337
2338 sprintf(extra, "0x%05x", data32);
2339
2340 return 0;
2341 }
2342
2343 static int rtw_wx_write_rf(struct net_device *dev,
2344 struct iw_request_info *info,
2345 union iwreq_data *wrqu, char *extra)
2346 {
2347 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2348 u32 path, addr, data32;
2349
2350
2351 path = *(u32 *)extra;
2352 addr = *((u32 *)extra + 1);
2353 data32 = *((u32 *)extra + 2);
2354
2355 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
2356
2357 return 0;
2358 }
2359
2360 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
2361 union iwreq_data *wrqu, char *b)
2362 {
2363 return -1;
2364 }
2365
2366 static int dummy(struct net_device *dev, struct iw_request_info *a,
2367 union iwreq_data *wrqu, char *b)
2368 {
2369
2370
2371
2372
2373
2374 return -1;
2375
2376 }
2377
2378 static int rtw_wx_set_channel_plan(struct net_device *dev,
2379 struct iw_request_info *info,
2380 union iwreq_data *wrqu, char *extra)
2381 {
2382 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2383 u8 channel_plan_req = (u8)(*((int *)wrqu));
2384
2385 if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1))
2386 DBG_871X("%s set channel_plan = 0x%02X\n", __func__, channel_plan_req);
2387 else
2388 return -EPERM;
2389
2390 return 0;
2391 }
2392
2393 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
2394 struct iw_request_info *a,
2395 union iwreq_data *wrqu, char *b)
2396 {
2397 return 0;
2398 }
2399
2400 static int rtw_wx_get_sensitivity(struct net_device *dev,
2401 struct iw_request_info *info,
2402 union iwreq_data *wrqu, char *buf)
2403 {
2404 return 0;
2405 }
2406
2407 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
2408 struct iw_request_info *info,
2409 union iwreq_data *wrqu, char *extra)
2410 {
2411 return 0;
2412 }
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422 static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
2423 union iwreq_data *wrqu, char *extra)
2424 {
2425 return 0;
2426 }
2427
2428 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
2429 union iwreq_data *wrqu, char *extra)
2430 {
2431 int ret = 0;
2432 return ret;
2433 }
2434
2435 static int rtw_get_ap_info(struct net_device *dev,
2436 struct iw_request_info *info,
2437 union iwreq_data *wrqu, char *extra)
2438 {
2439 int ret = 0;
2440 u32 cnt = 0, wpa_ielen;
2441 struct list_head *plist, *phead;
2442 unsigned char *pbuf;
2443 u8 bssid[ETH_ALEN];
2444 char data[32];
2445 struct wlan_network *pnetwork = NULL;
2446 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2447 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2448 struct __queue *queue = &(pmlmepriv->scanned_queue);
2449 struct iw_point *pdata = &wrqu->data;
2450
2451 DBG_871X("+rtw_get_aplist_info\n");
2452
2453 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2454 ret = -EINVAL;
2455 goto exit;
2456 }
2457
2458 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true) {
2459 msleep(30);
2460 cnt++;
2461 if (cnt > 100)
2462 break;
2463 }
2464
2465
2466
2467 pdata->flags = 0;
2468 if (pdata->length>=32) {
2469 if (copy_from_user(data, pdata->pointer, 32)) {
2470 ret = -EINVAL;
2471 goto exit;
2472 }
2473 } else {
2474 ret = -EINVAL;
2475 goto exit;
2476 }
2477
2478 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2479
2480 phead = get_list_head(queue);
2481 plist = get_next(phead);
2482
2483 while (1) {
2484 if (phead == plist)
2485 break;
2486
2487
2488 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2489
2490 if (!mac_pton(data, bssid)) {
2491 DBG_871X("Invalid BSSID '%s'.\n", (u8 *)data);
2492 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2493 return -EINVAL;
2494 }
2495
2496
2497 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2498 DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
2499
2500 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
2501 if (pbuf && (wpa_ielen>0)) {
2502 pdata->flags = 1;
2503 break;
2504 }
2505
2506 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
2507 if (pbuf && (wpa_ielen>0)) {
2508 pdata->flags = 2;
2509 break;
2510 }
2511 }
2512
2513 plist = get_next(plist);
2514
2515 }
2516
2517 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2518
2519 if (pdata->length>=34) {
2520 if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1)) {
2521 ret = -EINVAL;
2522 goto exit;
2523 }
2524 }
2525
2526 exit:
2527
2528 return ret;
2529
2530 }
2531
2532 static int rtw_set_pid(struct net_device *dev,
2533 struct iw_request_info *info,
2534 union iwreq_data *wrqu, char *extra)
2535 {
2536
2537 int ret = 0;
2538 struct adapter *padapter = rtw_netdev_priv(dev);
2539 int *pdata = (int *)wrqu;
2540 int selector;
2541
2542 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2543 ret = -EINVAL;
2544 goto exit;
2545 }
2546
2547 selector = *pdata;
2548 if (selector < 3 && selector >= 0) {
2549 padapter->pid[selector] = *(pdata+1);
2550 DBG_871X("%s set pid[%d]=%d\n", __func__, selector , padapter->pid[selector]);
2551 }
2552 else
2553 DBG_871X("%s selector %d error\n", __func__, selector);
2554
2555 exit:
2556
2557 return ret;
2558
2559 }
2560
2561 static int rtw_wps_start(struct net_device *dev,
2562 struct iw_request_info *info,
2563 union iwreq_data *wrqu, char *extra)
2564 {
2565
2566 int ret = 0;
2567 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2568 struct iw_point *pdata = &wrqu->data;
2569 u32 u32wps_start = 0;
2570 unsigned int uintRet = 0;
2571
2572 if ((true == padapter->bDriverStopped) ||(true ==padapter->bSurpriseRemoved) || (NULL == pdata)) {
2573 ret = -EINVAL;
2574 goto exit;
2575 }
2576
2577 uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
2578 if (u32wps_start == 0)
2579 u32wps_start = *extra;
2580
2581 DBG_871X("[%s] wps_start = %d\n", __func__, u32wps_start);
2582
2583 exit:
2584
2585 return ret;
2586
2587 }
2588
2589 static int rtw_p2p_set(struct net_device *dev,
2590 struct iw_request_info *info,
2591 union iwreq_data *wrqu, char *extra)
2592 {
2593
2594 return 0;
2595
2596 }
2597
2598 static int rtw_p2p_get(struct net_device *dev,
2599 struct iw_request_info *info,
2600 union iwreq_data *wrqu, char *extra)
2601 {
2602
2603 return 0;
2604
2605 }
2606
2607 static int rtw_p2p_get2(struct net_device *dev,
2608 struct iw_request_info *info,
2609 union iwreq_data *wrqu, char *extra)
2610 {
2611
2612 return 0;
2613
2614 }
2615
2616 static int rtw_rereg_nd_name(struct net_device *dev,
2617 struct iw_request_info *info,
2618 union iwreq_data *wrqu, char *extra)
2619 {
2620 int ret = 0;
2621 struct adapter *padapter = rtw_netdev_priv(dev);
2622 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
2623 char new_ifname[IFNAMSIZ];
2624
2625 if (rereg_priv->old_ifname[0] == 0) {
2626 char *reg_ifname;
2627 reg_ifname = padapter->registrypriv.ifname;
2628
2629 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
2630 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
2631 }
2632
2633
2634 if (wrqu->data.length > IFNAMSIZ)
2635 return -EFAULT;
2636
2637 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
2638 return -EFAULT;
2639
2640 if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
2641 return ret;
2642
2643 DBG_871X("%s new_ifname:%s\n", __func__, new_ifname);
2644 if (0 != (ret = rtw_change_ifname(padapter, new_ifname)))
2645 goto exit;
2646
2647 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
2648 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
2649
2650 if (!memcmp(new_ifname, "disable%d", 9)) {
2651
2652 DBG_871X("%s disable\n", __func__);
2653
2654 rtw_free_network_queue(padapter, true);
2655
2656
2657
2658
2659 }
2660 exit:
2661 return ret;
2662
2663 }
2664
2665 static int rtw_dbg_port(struct net_device *dev,
2666 struct iw_request_info *info,
2667 union iwreq_data *wrqu, char *extra)
2668 {
2669 u8 major_cmd, minor_cmd;
2670 u16 arg;
2671 u32 extra_arg, *pdata, val32;
2672 struct sta_info *psta;
2673 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2674 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2675 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2676 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2677 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2678 struct sta_priv *pstapriv = &padapter->stapriv;
2679
2680
2681 pdata = (u32 *)&wrqu->data;
2682
2683 val32 = *pdata;
2684 arg = (u16)(val32&0x0000ffff);
2685 major_cmd = (u8)(val32>>24);
2686 minor_cmd = (u8)((val32>>16)&0x00ff);
2687
2688 extra_arg = *(pdata+1);
2689
2690 switch (major_cmd) {
2691 case 0x70:
2692 switch (minor_cmd) {
2693 case 1:
2694 DBG_871X("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
2695 break;
2696 case 2:
2697 DBG_871X("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
2698 break;
2699 case 4:
2700 DBG_871X("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
2701 break;
2702 }
2703 break;
2704 case 0x71:
2705 switch (minor_cmd) {
2706 case 1:
2707 rtw_write8(padapter, arg, extra_arg);
2708 DBG_871X("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
2709 break;
2710 case 2:
2711 rtw_write16(padapter, arg, extra_arg);
2712 DBG_871X("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
2713 break;
2714 case 4:
2715 rtw_write32(padapter, arg, extra_arg);
2716 DBG_871X("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
2717 break;
2718 }
2719 break;
2720 case 0x72:
2721 DBG_871X("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
2722 break;
2723 case 0x73:
2724 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
2725 DBG_871X("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
2726 break;
2727 case 0x74:
2728 DBG_871X("read RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
2729 break;
2730 case 0x75:
2731 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
2732 DBG_871X("write RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
2733 break;
2734
2735 case 0x76:
2736 switch (minor_cmd) {
2737 case 0x00:
2738 padapter->recvpriv.is_signal_dbg = 0;
2739 break;
2740 case 0x01:
2741 padapter->recvpriv.is_signal_dbg = 1;
2742 extra_arg = extra_arg>100?100:extra_arg;
2743 padapter->recvpriv.signal_strength_dbg =extra_arg;
2744 break;
2745 }
2746 break;
2747 case 0x78:
2748 break;
2749 case 0x79:
2750 {
2751
2752
2753
2754
2755 u8 value = extra_arg & 0x0f;
2756 u8 sign = minor_cmd;
2757 u16 write_value = 0;
2758
2759 DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
2760
2761 if (sign)
2762 value = value | 0x10;
2763
2764 write_value = value | (value << 5);
2765 rtw_write16(padapter, 0x6d9, write_value);
2766 }
2767 break;
2768 case 0x7a:
2769 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
2770 , WLAN_REASON_EXPIRATION_CHK);
2771 break;
2772 case 0x7F:
2773 switch (minor_cmd) {
2774 case 0x0:
2775 DBG_871X("fwstate = 0x%x\n", get_fwstate(pmlmepriv));
2776 break;
2777 case 0x01:
2778 DBG_871X("minor_cmd 0x%x\n", minor_cmd);
2779 break;
2780 case 0x02:
2781 DBG_871X("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state);
2782 DBG_871X("DrvBcnEarly =%d\n", pmlmeext->DrvBcnEarly);
2783 DBG_871X("DrvBcnTimeOut =%d\n", pmlmeext->DrvBcnTimeOut);
2784 break;
2785 case 0x03:
2786 DBG_871X("qos_option =%d\n", pmlmepriv->qospriv.qos_option);
2787 DBG_871X("ht_option =%d\n", pmlmepriv->htpriv.ht_option);
2788 break;
2789 case 0x04:
2790 DBG_871X("cur_ch =%d\n", pmlmeext->cur_channel);
2791 DBG_871X("cur_bw =%d\n", pmlmeext->cur_bwmode);
2792 DBG_871X("cur_ch_off =%d\n", pmlmeext->cur_ch_offset);
2793
2794 DBG_871X("oper_ch =%d\n", rtw_get_oper_ch(padapter));
2795 DBG_871X("oper_bw =%d\n", rtw_get_oper_bw(padapter));
2796 DBG_871X("oper_ch_offet =%d\n", rtw_get_oper_choffset(padapter));
2797
2798 break;
2799 case 0x05:
2800 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
2801 if (psta) {
2802 int i;
2803 struct recv_reorder_ctrl *preorder_ctrl;
2804
2805 DBG_871X("SSID =%s\n", cur_network->network.Ssid.Ssid);
2806 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
2807 DBG_871X("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
2808 DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
2809 DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
2810 DBG_871X("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
2811 DBG_871X("bwmode =%d, ch_offset =%d, sgi_20m =%d, sgi_40m =%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
2812 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
2813 DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
2814
2815 for (i = 0;i<16;i++) {
2816 preorder_ctrl = &psta->recvreorder_ctrl[i];
2817 if (preorder_ctrl->enable)
2818 DBG_871X("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq);
2819 }
2820
2821 } else {
2822 DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
2823 }
2824 break;
2825 case 0x06:
2826 {
2827 u32 ODMFlag;
2828 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
2829 DBG_871X("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg);
2830 ODMFlag = (u32)(0x0f&arg);
2831 DBG_871X("(A)DMFlag = 0x%x\n", ODMFlag);
2832 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
2833 }
2834 break;
2835 case 0x07:
2836 DBG_871X("bSurpriseRemoved =%d, bDriverStopped =%d\n",
2837 padapter->bSurpriseRemoved, padapter->bDriverStopped);
2838 break;
2839 case 0x08:
2840 {
2841 DBG_871X("minor_cmd 0x%x\n", minor_cmd);
2842 }
2843 break;
2844 case 0x09:
2845 {
2846 int i, j;
2847 struct list_head *plist, *phead;
2848 struct recv_reorder_ctrl *preorder_ctrl;
2849
2850 DBG_871X("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
2851
2852 spin_lock_bh(&pstapriv->sta_hash_lock);
2853
2854 for (i = 0; i< NUM_STA; i++) {
2855 phead = &(pstapriv->sta_hash[i]);
2856 plist = get_next(phead);
2857
2858 while (phead != plist) {
2859 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
2860
2861 plist = get_next(plist);
2862
2863 if (extra_arg == psta->aid) {
2864 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
2865 DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
2866 DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
2867 DBG_871X("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
2868 DBG_871X("bwmode =%d, ch_offset =%d, sgi_20m =%d, sgi_40m =%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
2869 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
2870 DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
2871 DBG_871X("capability = 0x%x\n", psta->capability);
2872 DBG_871X("flags = 0x%x\n", psta->flags);
2873 DBG_871X("wpa_psk = 0x%x\n", psta->wpa_psk);
2874 DBG_871X("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher);
2875 DBG_871X("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher);
2876 DBG_871X("qos_info = 0x%x\n", psta->qos_info);
2877 DBG_871X("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy);
2878
2879
2880
2881 for (j = 0;j<16;j++) {
2882 preorder_ctrl = &psta->recvreorder_ctrl[j];
2883 if (preorder_ctrl->enable)
2884 DBG_871X("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq);
2885 }
2886 }
2887 }
2888 }
2889
2890 spin_unlock_bh(&pstapriv->sta_hash_lock);
2891
2892 }
2893 break;
2894 case 0x0a:
2895 {
2896 int max_mac_id = 0;
2897 max_mac_id = rtw_search_max_mac_id(padapter);
2898 printk("%s ==> max_mac_id = %d\n", __func__, max_mac_id);
2899 }
2900 break;
2901 case 0x0b:
2902 if (arg == 0) {
2903 DBG_871X("disable driver ctrl vcs\n");
2904 padapter->driver_vcs_en = 0;
2905 } else if (arg == 1) {
2906 DBG_871X("enable driver ctrl vcs = %d\n", extra_arg);
2907 padapter->driver_vcs_en = 1;
2908
2909 if (extra_arg>2)
2910 padapter->driver_vcs_type = 1;
2911 else
2912 padapter->driver_vcs_type = extra_arg;
2913 }
2914 break;
2915 case 0x0c:
2916 {
2917 if (arg == 0) {
2918 DBG_871X("dump rx packet (%d)\n", extra_arg);
2919
2920 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
2921 } else if (arg == 1) {
2922 DBG_871X("dump tx packet (%d)\n", extra_arg);
2923 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
2924 }
2925 }
2926 break;
2927 case 0x0e:
2928 {
2929 if (arg == 0) {
2930 DBG_871X("disable driver ctrl rx_ampdu_factor\n");
2931 padapter->driver_rx_ampdu_factor = 0xFF;
2932 } else if (arg == 1) {
2933
2934 DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
2935
2936 if ((extra_arg & 0x03) > 0x03)
2937 padapter->driver_rx_ampdu_factor = 0xFF;
2938 else
2939 padapter->driver_rx_ampdu_factor = extra_arg;
2940 }
2941 }
2942 break;
2943
2944 case 0x10:
2945 dump_drv_version(RTW_DBGDUMP);
2946 break;
2947 case 0x11:
2948 {
2949 linked_info_dump(padapter, extra_arg);
2950 }
2951 break;
2952 case 0x12:
2953 {
2954 struct registry_priv *pregpriv = &padapter->registrypriv;
2955
2956
2957 if (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3) {
2958 pregpriv->rx_stbc = extra_arg;
2959 DBG_871X("set rx_stbc =%d\n", pregpriv->rx_stbc);
2960 } else
2961 DBG_871X("get rx_stbc =%d\n", pregpriv->rx_stbc);
2962
2963 }
2964 break;
2965 case 0x13:
2966 {
2967 struct registry_priv *pregpriv = &padapter->registrypriv;
2968
2969 if (extra_arg < 3) {
2970 pregpriv->ampdu_enable = extra_arg;
2971 DBG_871X("set ampdu_enable =%d\n", pregpriv->ampdu_enable);
2972 } else
2973 DBG_871X("get ampdu_enable =%d\n", pregpriv->ampdu_enable);
2974
2975 }
2976 break;
2977 case 0x14:
2978 {
2979 DBG_871X("minor_cmd 0x%x\n", minor_cmd);
2980 }
2981 break;
2982 case 0x16:
2983 {
2984 if (arg == 0xff) {
2985 rtw_odm_dbg_comp_msg(RTW_DBGDUMP, padapter);
2986 } else {
2987 u64 dbg_comp = (u64)extra_arg;
2988 rtw_odm_dbg_comp_set(padapter, dbg_comp);
2989 }
2990 }
2991 break;
2992 #ifdef DBG_FIXED_CHAN
2993 case 0x17:
2994 {
2995 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2996 printk("===> Fixed channel to %d\n", extra_arg);
2997 pmlmeext->fixed_chan = extra_arg;
2998
2999 }
3000 break;
3001 #endif
3002 case 0x18:
3003 {
3004 printk("===> Switch USB Mode %d\n", extra_arg);
3005 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
3006 }
3007 break;
3008 case 0x19:
3009 {
3010 struct registry_priv *pregistrypriv = &padapter->registrypriv;
3011
3012
3013
3014 if (arg == 0) {
3015 DBG_871X("driver disable LDPC\n");
3016 pregistrypriv->ldpc_cap = 0x00;
3017 } else if (arg == 1) {
3018 DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg);
3019 pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33);
3020 }
3021 }
3022 break;
3023 case 0x1a:
3024 {
3025 struct registry_priv *pregistrypriv = &padapter->registrypriv;
3026
3027
3028
3029 if (arg == 0) {
3030 DBG_871X("driver disable STBC\n");
3031 pregistrypriv->stbc_cap = 0x00;
3032 } else if (arg == 1) {
3033 DBG_871X("driver set STBC cap = 0x%x\n", extra_arg);
3034 pregistrypriv->stbc_cap = (u8)(extra_arg&0x33);
3035 }
3036 }
3037 break;
3038 case 0x1b:
3039 {
3040 struct registry_priv *pregistrypriv = &padapter->registrypriv;
3041
3042 if (arg == 0) {
3043 DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
3044 init_mlme_default_rate_set(padapter);
3045 pregistrypriv->ht_enable = (u8)rtw_ht_enable;
3046 } else if (arg == 1) {
3047
3048 int i;
3049 u8 max_rx_rate;
3050
3051 DBG_871X("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
3052
3053 max_rx_rate = (u8)extra_arg;
3054
3055 if (max_rx_rate < 0xc) {
3056 pregistrypriv->ht_enable = 0;
3057 for (i = 0; i<NumRates; i++) {
3058 if (pmlmeext->datarate[i] > max_rx_rate)
3059 pmlmeext->datarate[i] = 0xff;
3060 }
3061
3062 }
3063 else if (max_rx_rate < 0x1c) {
3064 u32 mcs_bitmap = 0x0;
3065
3066 for (i = 0; i<((max_rx_rate+1)-0xc); i++)
3067 mcs_bitmap |= BIT(i);
3068
3069 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
3070 }
3071 }
3072 }
3073 break;
3074 case 0x1c:
3075 {
3076 if (arg == 0) {
3077 DBG_871X("disable driver ctrl ampdu density\n");
3078 padapter->driver_ampdu_spacing = 0xFF;
3079 } else if (arg == 1) {
3080
3081 DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg);
3082
3083 if (extra_arg > 0x07)
3084 padapter->driver_ampdu_spacing = 0xFF;
3085 else
3086 padapter->driver_ampdu_spacing = extra_arg;
3087 }
3088 }
3089 break;
3090 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
3091 case 0x1e:
3092 {
3093 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
3094 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
3095 u8 chan = rtw_get_oper_ch(padapter);
3096 DBG_871X("===========================================\n");
3097 ODM_InbandNoise_Monitor(pDM_Odm, true, 0x1e, 100);
3098 DBG_871X("channel(%d), noise_a = %d, noise_b = %d , noise_all:%d\n",
3099 chan, pDM_Odm->noise_level.noise[ODM_RF_PATH_A],
3100 pDM_Odm->noise_level.noise[ODM_RF_PATH_B],
3101 pDM_Odm->noise_level.noise_all);
3102 DBG_871X("===========================================\n");
3103
3104 }
3105 break;
3106 #endif
3107 case 0x23:
3108 {
3109 DBG_871X("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1)?"on":"off");
3110 padapter->bNotifyChannelChange = extra_arg;
3111 break;
3112 }
3113 case 0x24:
3114 {
3115 break;
3116 }
3117 #ifdef CONFIG_GPIO_API
3118 case 0x25:
3119 {
3120
3121
3122
3123
3124 int value;
3125 DBG_871X("Read GPIO Value extra_arg = %d\n", extra_arg);
3126 value = rtw_get_gpio(dev, extra_arg);
3127 DBG_871X("Read GPIO Value = %d\n", value);
3128 break;
3129 }
3130 case 0x26:
3131 {
3132
3133
3134
3135
3136
3137 int value;
3138 DBG_871X("Set GPIO Direction! arg = %d , extra_arg =%d\n", arg , extra_arg);
3139 value = rtw_config_gpio(dev, arg, extra_arg);
3140 DBG_871X("Set GPIO Direction %s\n", (value ==-1)?"Fail!!!":"Success");
3141 break;
3142 }
3143 case 0x27:
3144 {
3145
3146
3147
3148
3149
3150 int value;
3151 DBG_871X("Set GPIO Value! arg = %d , extra_arg =%d\n", arg , extra_arg);
3152 value = rtw_set_gpio_output_value(dev, arg, extra_arg);
3153 DBG_871X("Set GPIO Value %s\n", (value ==-1)?"Fail!!!":"Success");
3154 break;
3155 }
3156 #endif
3157 case 0xaa:
3158 {
3159 if ((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF;
3160 DBG_871X("chang data rate to :0x%02x\n", extra_arg);
3161 padapter->fix_rate = extra_arg;
3162 }
3163 break;
3164 case 0xdd:
3165 {
3166 if (extra_arg == 0)
3167 mac_reg_dump(RTW_DBGDUMP, padapter);
3168 else if (extra_arg == 1)
3169 bb_reg_dump(RTW_DBGDUMP, padapter);
3170 else if (extra_arg ==2)
3171 rf_reg_dump(RTW_DBGDUMP, padapter);
3172 }
3173 break;
3174
3175 case 0xee:
3176 {
3177 u32 odm_flag;
3178
3179 if (0xf ==extra_arg) {
3180 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
3181 DBG_871X(" === DMFlag(0x%08x) ===\n", odm_flag);
3182 DBG_871X("extra_arg = 0 - disable all dynamic func\n");
3183 DBG_871X("extra_arg = 1 - disable DIG- BIT(0)\n");
3184 DBG_871X("extra_arg = 2 - disable High power - BIT(1)\n");
3185 DBG_871X("extra_arg = 3 - disable tx power tracking - BIT(2)\n");
3186 DBG_871X("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
3187 DBG_871X("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
3188 DBG_871X("extra_arg = 6 - enable all dynamic func\n");
3189 } else {
3190
3191
3192
3193
3194
3195 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
3196 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
3197 DBG_871X(" === DMFlag(0x%08x) ===\n", odm_flag);
3198 }
3199 }
3200 break;
3201
3202 case 0xfd:
3203 rtw_write8(padapter, 0xc50, arg);
3204 DBG_871X("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
3205 rtw_write8(padapter, 0xc58, arg);
3206 DBG_871X("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
3207 break;
3208 case 0xfe:
3209 DBG_871X("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
3210 DBG_871X("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
3211 break;
3212 case 0xff:
3213 {
3214 DBG_871X("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
3215 DBG_871X("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
3216 DBG_871X("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
3217 DBG_871X("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
3218 DBG_871X("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
3219
3220 DBG_871X("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
3221
3222
3223 DBG_871X("\n");
3224
3225 DBG_871X("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
3226 DBG_871X("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
3227
3228 DBG_871X("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
3229
3230 DBG_871X("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
3231
3232 DBG_871X("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
3233 DBG_871X("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
3234
3235 DBG_871X("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
3236 DBG_871X("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
3237 DBG_871X("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
3238 DBG_871X("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
3239 }
3240 break;
3241 }
3242 break;
3243 default:
3244 DBG_871X("error dbg cmd!\n");
3245 break;
3246 }
3247
3248
3249 return 0;
3250
3251 }
3252
3253 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
3254 {
3255 uint ret = 0;
3256 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3257
3258 switch (name) {
3259 case IEEE_PARAM_WPA_ENABLED:
3260
3261 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3262
3263
3264
3265 switch ((value)&0xff) {
3266 case 1 :
3267 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
3268 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
3269 break;
3270 case 2:
3271 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
3272 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
3273 break;
3274 }
3275
3276 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype));
3277
3278 break;
3279
3280 case IEEE_PARAM_TKIP_COUNTERMEASURES:
3281
3282 break;
3283
3284 case IEEE_PARAM_DROP_UNENCRYPTED:
3285 {
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297 break;
3298
3299 }
3300 case IEEE_PARAM_PRIVACY_INVOKED:
3301
3302
3303
3304 break;
3305
3306 case IEEE_PARAM_AUTH_ALGS:
3307
3308 ret = wpa_set_auth_algs(dev, value);
3309
3310 break;
3311
3312 case IEEE_PARAM_IEEE_802_1X:
3313
3314
3315
3316 break;
3317
3318 case IEEE_PARAM_WPAX_SELECT:
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329 break;
3330
3331 default:
3332
3333
3334
3335 ret = -EOPNOTSUPP;
3336
3337
3338 break;
3339
3340 }
3341
3342 return ret;
3343
3344 }
3345
3346 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
3347 {
3348 int ret = 0;
3349 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3350
3351 switch (command) {
3352 case IEEE_MLME_STA_DEAUTH:
3353
3354 if (!rtw_set_802_11_disassociate(padapter))
3355 ret = -1;
3356
3357 break;
3358
3359 case IEEE_MLME_STA_DISASSOC:
3360
3361 if (!rtw_set_802_11_disassociate(padapter))
3362 ret = -1;
3363
3364 break;
3365
3366 default:
3367 ret = -EOPNOTSUPP;
3368 break;
3369 }
3370
3371 return ret;
3372
3373 }
3374
3375 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
3376 {
3377 struct ieee_param *param;
3378 uint ret = 0;
3379
3380
3381
3382 if (!p->pointer || p->length != sizeof(struct ieee_param)) {
3383 ret = -EINVAL;
3384 goto out;
3385 }
3386
3387 param = rtw_malloc(p->length);
3388 if (param == NULL) {
3389 ret = -ENOMEM;
3390 goto out;
3391 }
3392
3393 if (copy_from_user(param, p->pointer, p->length)) {
3394 kfree(param);
3395 ret = -EFAULT;
3396 goto out;
3397 }
3398
3399 switch (param->cmd) {
3400
3401 case IEEE_CMD_SET_WPA_PARAM:
3402 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
3403 break;
3404
3405 case IEEE_CMD_SET_WPA_IE:
3406
3407 ret = rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
3408 break;
3409
3410 case IEEE_CMD_SET_ENCRYPTION:
3411 ret = wpa_set_encryption(dev, param, p->length);
3412 break;
3413
3414 case IEEE_CMD_MLME:
3415 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
3416 break;
3417
3418 default:
3419 DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd);
3420 ret = -EOPNOTSUPP;
3421 break;
3422
3423 }
3424
3425 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3426 ret = -EFAULT;
3427
3428 kfree(param);
3429
3430 out:
3431
3432
3433
3434 return ret;
3435
3436 }
3437
3438 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
3439 {
3440 int ret = 0;
3441 u32 wep_key_idx, wep_key_len, wep_total_len;
3442 struct ndis_802_11_wep *pwep = NULL;
3443 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
3444 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3445 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3446 struct security_priv* psecuritypriv =&(padapter->securitypriv);
3447 struct sta_priv *pstapriv = &padapter->stapriv;
3448
3449 DBG_871X("%s\n", __func__);
3450
3451 param->u.crypt.err = 0;
3452 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3453
3454
3455
3456 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
3457 ret = -EINVAL;
3458 goto exit;
3459 }
3460
3461 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3462 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3463 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3464 if (param->u.crypt.idx >= WEP_KEYS) {
3465 ret = -EINVAL;
3466 goto exit;
3467 }
3468 } else {
3469 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3470 if (!psta) {
3471
3472 DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
3473 goto exit;
3474 }
3475 }
3476
3477 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
3478
3479
3480 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3481 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
3482 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
3483 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3484
3485 DBG_871X("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
3486
3487 goto exit;
3488 }
3489
3490
3491 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
3492 DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
3493
3494 wep_key_idx = param->u.crypt.idx;
3495 wep_key_len = param->u.crypt.key_len;
3496
3497 DBG_871X("r871x_set_encryption, wep_key_idx =%d, len =%d\n", wep_key_idx, wep_key_len);
3498
3499 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0)) {
3500 ret = -EINVAL;
3501 goto exit;
3502 }
3503
3504
3505 if (wep_key_len > 0) {
3506 wep_key_len = wep_key_len <= 5 ? 5 : 13;
3507 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
3508 pwep = kzalloc(wep_total_len, GFP_KERNEL);
3509 if (pwep == NULL) {
3510 DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n");
3511 goto exit;
3512 }
3513
3514 pwep->KeyLength = wep_key_len;
3515 pwep->Length = wep_total_len;
3516
3517 }
3518
3519 pwep->KeyIndex = wep_key_idx;
3520
3521 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
3522
3523 if (param->u.crypt.set_tx) {
3524 DBG_871X("wep, set_tx = 1\n");
3525
3526 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3527 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
3528 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
3529 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3530
3531 if (pwep->KeyLength == 13) {
3532 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
3533 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3534 }
3535
3536
3537 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
3538
3539 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
3540
3541 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
3542
3543 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
3544 } else {
3545 DBG_871X("wep, set_tx = 0\n");
3546
3547
3548
3549
3550 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
3551
3552 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
3553
3554 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
3555 }
3556
3557 goto exit;
3558
3559 }
3560
3561
3562 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3563 if (param->u.crypt.set_tx == 1) {
3564 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3565 DBG_871X("%s, set group_key, WEP\n", __func__);
3566
3567 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3568
3569 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3570 if (param->u.crypt.key_len == 13)
3571 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3572
3573 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3574 DBG_871X("%s, set group_key, TKIP\n", __func__);
3575
3576 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
3577
3578 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3579
3580
3581
3582 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
3583 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
3584
3585 psecuritypriv->busetkipkey = true;
3586
3587 }
3588 else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3589 DBG_871X("%s, set group_key, CCMP\n", __func__);
3590
3591 psecuritypriv->dot118021XGrpPrivacy = _AES_;
3592
3593 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3594 } else {
3595 DBG_871X("%s, set group_key, none\n", __func__);
3596
3597 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3598 }
3599
3600 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
3601
3602 psecuritypriv->binstallGrpkey = true;
3603
3604 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
3605
3606 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
3607
3608 pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
3609 if (pbcmc_sta) {
3610 pbcmc_sta->ieee8021x_blocked = false;
3611 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
3612 }
3613 }
3614
3615 goto exit;
3616
3617 }
3618
3619 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) {
3620 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3621 if (param->u.crypt.set_tx == 1) {
3622 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3623
3624 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3625 DBG_871X("%s, set pairwise key, WEP\n", __func__);
3626
3627 psta->dot118021XPrivacy = _WEP40_;
3628 if (param->u.crypt.key_len == 13)
3629 psta->dot118021XPrivacy = _WEP104_;
3630 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3631 DBG_871X("%s, set pairwise key, TKIP\n", __func__);
3632
3633 psta->dot118021XPrivacy = _TKIP_;
3634
3635
3636
3637 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
3638 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
3639
3640 psecuritypriv->busetkipkey = true;
3641
3642 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3643
3644 DBG_871X("%s, set pairwise key, CCMP\n", __func__);
3645
3646 psta->dot118021XPrivacy = _AES_;
3647 } else {
3648 DBG_871X("%s, set pairwise key, none\n", __func__);
3649
3650 psta->dot118021XPrivacy = _NO_PRIVACY_;
3651 }
3652
3653 rtw_ap_set_pairwise_key(padapter, psta);
3654
3655 psta->ieee8021x_blocked = false;
3656
3657 } else {
3658 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3659 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3660
3661 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3662 if (param->u.crypt.key_len == 13)
3663 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3664 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3665 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
3666
3667 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3668
3669
3670
3671 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
3672 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
3673
3674 psecuritypriv->busetkipkey = true;
3675
3676 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3677 psecuritypriv->dot118021XGrpPrivacy = _AES_;
3678
3679 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3680 } else {
3681 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3682 }
3683
3684 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
3685
3686 psecuritypriv->binstallGrpkey = true;
3687
3688 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
3689
3690 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
3691
3692 pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
3693 if (pbcmc_sta) {
3694 pbcmc_sta->ieee8021x_blocked = false;
3695 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
3696 }
3697 }
3698 }
3699 }
3700
3701 exit:
3702 kfree(pwep);
3703
3704 return ret;
3705
3706 }
3707
3708 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
3709 {
3710 int ret = 0;
3711 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3712 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3713 struct sta_priv *pstapriv = &padapter->stapriv;
3714 unsigned char *pbuf = param->u.bcn_ie.buf;
3715
3716
3717 DBG_871X("%s, len =%d\n", __func__, len);
3718
3719 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3720 return -EINVAL;
3721
3722 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3723
3724 if ((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<= 0))
3725 pstapriv->max_num_sta = NUM_STA;
3726
3727
3728 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)
3729 ret = 0;
3730 else
3731 ret = -EINVAL;
3732
3733
3734 return ret;
3735
3736 }
3737
3738 static void rtw_hostapd_sta_flush(struct net_device *dev)
3739 {
3740
3741
3742
3743 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3744
3745
3746 DBG_871X("%s\n", __func__);
3747
3748 flush_all_cam_entry(padapter);
3749
3750 rtw_sta_flush(padapter);
3751 }
3752
3753 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
3754 {
3755 int ret = 0;
3756 struct sta_info *psta = NULL;
3757 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3758 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3759 struct sta_priv *pstapriv = &padapter->stapriv;
3760
3761 DBG_871X("rtw_add_sta(aid =%d) =" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
3762
3763 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3764 return -EINVAL;
3765
3766 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3767 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3768 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3769 return -EINVAL;
3770 }
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3786 if (psta) {
3787 int flags = param->u.add_sta.flags;
3788
3789
3790
3791 psta->aid = param->u.add_sta.aid;
3792
3793 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
3794
3795
3796
3797 if (WLAN_STA_WME&flags)
3798 psta->qos_option = 1;
3799 else
3800 psta->qos_option = 0;
3801
3802 if (pmlmepriv->qospriv.qos_option == 0)
3803 psta->qos_option = 0;
3804
3805
3806 if (WLAN_STA_HT&flags) {
3807 psta->htpriv.ht_option = true;
3808 psta->qos_option = 1;
3809 memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
3810 } else {
3811 psta->htpriv.ht_option = false;
3812 }
3813
3814 if (pmlmepriv->htpriv.ht_option == false)
3815 psta->htpriv.ht_option = false;
3816
3817 update_sta_info_apmode(padapter, psta);
3818
3819
3820 } else {
3821 ret = -ENOMEM;
3822 }
3823
3824 return ret;
3825
3826 }
3827
3828 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
3829 {
3830 int ret = 0;
3831 struct sta_info *psta = NULL;
3832 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3833 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3834 struct sta_priv *pstapriv = &padapter->stapriv;
3835
3836 DBG_871X("rtw_del_sta =" MAC_FMT "\n", MAC_ARG(param->sta_addr));
3837
3838 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3839 return -EINVAL;
3840
3841 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3842 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3843 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3844 return -EINVAL;
3845 }
3846
3847 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3848 if (psta) {
3849 u8 updated =false;
3850
3851
3852
3853 spin_lock_bh(&pstapriv->asoc_list_lock);
3854 if (list_empty(&psta->asoc_list) ==false) {
3855 list_del_init(&psta->asoc_list);
3856 pstapriv->asoc_list_cnt--;
3857 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
3858
3859 }
3860 spin_unlock_bh(&pstapriv->asoc_list_lock);
3861
3862 associated_clients_update(padapter, updated);
3863
3864 psta = NULL;
3865
3866 } else {
3867 DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
3868
3869
3870 }
3871
3872
3873 return ret;
3874
3875 }
3876
3877 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
3878 {
3879 int ret = 0;
3880 struct sta_info *psta = NULL;
3881 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3882 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3883 struct sta_priv *pstapriv = &padapter->stapriv;
3884 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
3885 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
3886
3887 DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
3888
3889 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3890 return -EINVAL;
3891
3892 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
3893 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
3894 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
3895 return -EINVAL;
3896 }
3897
3898 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
3899 if (psta) {
3900 psta_data->aid = (u16)psta->aid;
3901 psta_data->capability = psta->capability;
3902 psta_data->flags = psta->flags;
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913 psta_data->sta_set =((psta->nonerp_set) |
3914 (psta->no_short_slot_time_set <<1) |
3915 (psta->no_short_preamble_set <<2) |
3916 (psta->no_ht_gf_set <<3) |
3917 (psta->no_ht_set <<4) |
3918 (psta->ht_20mhz_set <<5));
3919
3920 psta_data->tx_supp_rates_len = psta->bssratelen;
3921 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
3922 memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
3923 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
3924 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
3925 psta_data->rx_drops = psta->sta_stats.rx_drops;
3926
3927 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
3928 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
3929 psta_data->tx_drops = psta->sta_stats.tx_drops;
3930
3931
3932 } else {
3933 ret = -1;
3934 }
3935
3936 return ret;
3937
3938 }
3939
3940 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
3941 {
3942 int ret = 0;
3943 struct sta_info *psta = NULL;
3944 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3945 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3946 struct sta_priv *pstapriv = &padapter->stapriv;
3947
3948 DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
3949
3950 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3951 return -EINVAL;
3952
3953 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3954 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3955 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3956 return -EINVAL;
3957 }
3958
3959 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3960 if (psta) {
3961 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
3962 int wpa_ie_len;
3963 int copy_len;
3964
3965 wpa_ie_len = psta->wpa_ie[1];
3966
3967 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
3968
3969 param->u.wpa_ie.len = copy_len;
3970
3971 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
3972 } else {
3973
3974 DBG_871X("sta's wpa_ie is NONE\n");
3975 }
3976 } else {
3977 ret = -1;
3978 }
3979
3980 return ret;
3981
3982 }
3983
3984 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
3985 {
3986 int ret = 0;
3987 unsigned char wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
3988 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3989 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3990 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3991 int ie_len;
3992
3993 DBG_871X("%s, len =%d\n", __func__, len);
3994
3995 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3996 return -EINVAL;
3997
3998 ie_len = len-12-2;
3999
4000
4001 kfree(pmlmepriv->wps_beacon_ie);
4002 pmlmepriv->wps_beacon_ie = NULL;
4003
4004 if (ie_len>0) {
4005 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
4006 pmlmepriv->wps_beacon_ie_len = ie_len;
4007 if (pmlmepriv->wps_beacon_ie == NULL) {
4008 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4009 return -EINVAL;
4010 }
4011
4012 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
4013
4014 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
4015
4016 pmlmeext->bstart_bss = true;
4017 }
4018
4019
4020 return ret;
4021
4022 }
4023
4024 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
4025 {
4026 int ret = 0;
4027 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4028 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4029 int ie_len;
4030
4031 DBG_871X("%s, len =%d\n", __func__, len);
4032
4033 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4034 return -EINVAL;
4035
4036 ie_len = len-12-2;
4037
4038
4039 kfree(pmlmepriv->wps_probe_resp_ie);
4040 pmlmepriv->wps_probe_resp_ie = NULL;
4041
4042 if (ie_len>0) {
4043 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
4044 pmlmepriv->wps_probe_resp_ie_len = ie_len;
4045 if (pmlmepriv->wps_probe_resp_ie == NULL) {
4046 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4047 return -EINVAL;
4048 }
4049 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
4050 }
4051
4052
4053 return ret;
4054
4055 }
4056
4057 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
4058 {
4059 int ret = 0;
4060 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4061 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4062 int ie_len;
4063
4064 DBG_871X("%s, len =%d\n", __func__, len);
4065
4066 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4067 return -EINVAL;
4068
4069 ie_len = len-12-2;
4070
4071
4072 kfree(pmlmepriv->wps_assoc_resp_ie);
4073 pmlmepriv->wps_assoc_resp_ie = NULL;
4074
4075 if (ie_len>0) {
4076 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
4077 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
4078 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
4079 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4080 return -EINVAL;
4081 }
4082
4083 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
4084 }
4085
4086
4087 return ret;
4088
4089 }
4090
4091 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
4092 {
4093 int ret = 0;
4094 struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev);
4095 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
4096 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
4097 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
4098 int ie_len;
4099 u8 *ssid_ie;
4100 char ssid[NDIS_802_11_LENGTH_SSID + 1];
4101 sint ssid_len;
4102 u8 ignore_broadcast_ssid;
4103
4104 if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true)
4105 return -EPERM;
4106
4107 if (param->u.bcn_ie.reserved[0] != 0xea)
4108 return -EINVAL;
4109
4110 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
4111
4112 ie_len = len-12-2;
4113 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
4114
4115 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
4116 struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network;
4117 struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network;
4118
4119 memcpy(ssid, ssid_ie+2, ssid_len);
4120 ssid[ssid_len] = 0x0;
4121
4122 if (0)
4123 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
4124 ssid, ssid_len,
4125 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
4126 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
4127
4128 memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
4129 pbss_network->Ssid.SsidLength = ssid_len;
4130 memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
4131 pbss_network_ext->Ssid.SsidLength = ssid_len;
4132
4133 if (0)
4134 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
4135 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
4136 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
4137 }
4138
4139 DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
4140 ignore_broadcast_ssid, ssid, ssid_len);
4141
4142 return ret;
4143 }
4144
4145 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
4146 {
4147 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4148 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4149
4150 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4151 return -EINVAL;
4152
4153 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
4154 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
4155 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
4156 return -EINVAL;
4157 }
4158
4159 rtw_acl_remove_sta(padapter, param->sta_addr);
4160 return 0;
4161
4162 }
4163
4164 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
4165 {
4166 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4167 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4168
4169 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4170 return -EINVAL;
4171
4172 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
4173 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
4174 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
4175 return -EINVAL;
4176 }
4177
4178 return rtw_acl_add_sta(padapter, param->sta_addr);
4179
4180 }
4181
4182 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
4183 {
4184 int ret = 0;
4185 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4186 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4187
4188 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4189 return -EINVAL;
4190
4191 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
4192
4193 return ret;
4194 }
4195
4196 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
4197 {
4198 struct ieee_param *param;
4199 int ret = 0;
4200 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4201
4202
4203
4204
4205
4206
4207
4208
4209 if (!padapter->hw_init_completed) {
4210 ret = -EPERM;
4211 goto out;
4212 }
4213
4214
4215
4216 if (!p->pointer || p->length != sizeof(*param)) {
4217 ret = -EINVAL;
4218 goto out;
4219 }
4220
4221 param = rtw_malloc(p->length);
4222 if (param == NULL) {
4223 ret = -ENOMEM;
4224 goto out;
4225 }
4226
4227 if (copy_from_user(param, p->pointer, p->length)) {
4228 kfree(param);
4229 ret = -EFAULT;
4230 goto out;
4231 }
4232
4233
4234
4235 switch (param->cmd) {
4236 case RTL871X_HOSTAPD_FLUSH:
4237
4238 rtw_hostapd_sta_flush(dev);
4239
4240 break;
4241
4242 case RTL871X_HOSTAPD_ADD_STA:
4243
4244 ret = rtw_add_sta(dev, param);
4245
4246 break;
4247
4248 case RTL871X_HOSTAPD_REMOVE_STA:
4249
4250 ret = rtw_del_sta(dev, param);
4251
4252 break;
4253
4254 case RTL871X_HOSTAPD_SET_BEACON:
4255
4256 ret = rtw_set_beacon(dev, param, p->length);
4257
4258 break;
4259
4260 case RTL871X_SET_ENCRYPTION:
4261
4262 ret = rtw_set_encryption(dev, param, p->length);
4263
4264 break;
4265
4266 case RTL871X_HOSTAPD_GET_WPAIE_STA:
4267
4268 ret = rtw_get_sta_wpaie(dev, param);
4269
4270 break;
4271
4272 case RTL871X_HOSTAPD_SET_WPS_BEACON:
4273
4274 ret = rtw_set_wps_beacon(dev, param, p->length);
4275
4276 break;
4277
4278 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
4279
4280 ret = rtw_set_wps_probe_resp(dev, param, p->length);
4281
4282 break;
4283
4284 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
4285
4286 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
4287
4288 break;
4289
4290 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
4291
4292 ret = rtw_set_hidden_ssid(dev, param, p->length);
4293
4294 break;
4295
4296 case RTL871X_HOSTAPD_GET_INFO_STA:
4297
4298 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
4299
4300 break;
4301
4302 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
4303
4304 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
4305
4306 break;
4307
4308 case RTL871X_HOSTAPD_ACL_ADD_STA:
4309
4310 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
4311
4312 break;
4313
4314 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
4315
4316 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
4317
4318 break;
4319
4320 default:
4321 DBG_871X("Unknown hostapd request: %d\n", param->cmd);
4322 ret = -EOPNOTSUPP;
4323 break;
4324
4325 }
4326
4327 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
4328 ret = -EFAULT;
4329
4330
4331 kfree(param);
4332
4333 out:
4334
4335 return ret;
4336
4337 }
4338
4339 static int rtw_wx_set_priv(struct net_device *dev,
4340 struct iw_request_info *info,
4341 union iwreq_data *awrq,
4342 char *extra)
4343 {
4344
4345 #ifdef DEBUG_RTW_WX_SET_PRIV
4346 char *ext_dbg;
4347 #endif
4348
4349 int ret = 0;
4350 int len = 0;
4351 char *ext;
4352
4353 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4354 struct iw_point *dwrq = (struct iw_point *)awrq;
4355
4356
4357 if (dwrq->length == 0)
4358 return -EFAULT;
4359
4360 len = dwrq->length;
4361 if (!(ext = vmalloc(len)))
4362 return -ENOMEM;
4363
4364 if (copy_from_user(ext, dwrq->pointer, len)) {
4365 vfree(ext);
4366 return -EFAULT;
4367 }
4368
4369
4370
4371
4372
4373
4374 #ifdef DEBUG_RTW_WX_SET_PRIV
4375 if (!(ext_dbg = vmalloc(len))) {
4376 vfree(ext, len);
4377 return -ENOMEM;
4378 }
4379
4380 memcpy(ext_dbg, ext, len);
4381 #endif
4382
4383
4384 if (dwrq->flags == 0x8766 && len > 8) {
4385 u32 cp_sz;
4386 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4387 u8 *probereq_wpsie = ext;
4388 int probereq_wpsie_len = len;
4389 u8 wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
4390
4391 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
4392 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
4393 cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
4394
4395 if (pmlmepriv->wps_probe_req_ie) {
4396 pmlmepriv->wps_probe_req_ie_len = 0;
4397 kfree(pmlmepriv->wps_probe_req_ie);
4398 pmlmepriv->wps_probe_req_ie = NULL;
4399 }
4400
4401 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
4402 if (pmlmepriv->wps_probe_req_ie == NULL) {
4403 printk("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4404 ret = -EINVAL;
4405 goto FREE_EXT;
4406
4407 }
4408
4409 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
4410 pmlmepriv->wps_probe_req_ie_len = cp_sz;
4411
4412 }
4413
4414 goto FREE_EXT;
4415
4416 }
4417
4418 if (len >= WEXT_CSCAN_HEADER_SIZE
4419 && !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
4420 ret = rtw_wx_set_scan(dev, info, awrq, ext);
4421 goto FREE_EXT;
4422 }
4423
4424 FREE_EXT:
4425
4426 vfree(ext);
4427 #ifdef DEBUG_RTW_WX_SET_PRIV
4428 vfree(ext_dbg);
4429 #endif
4430
4431
4432
4433
4434 return ret;
4435
4436 }
4437
4438 static int rtw_pm_set(struct net_device *dev,
4439 struct iw_request_info *info,
4440 union iwreq_data *wrqu, char *extra)
4441 {
4442 int ret = 0;
4443 unsigned mode = 0;
4444 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4445
4446 DBG_871X("[%s] extra = %s\n", __func__, extra);
4447
4448 if (!memcmp(extra, "lps =", 4)) {
4449 sscanf(extra+4, "%u", &mode);
4450 ret = rtw_pm_set_lps(padapter, mode);
4451 } else if (!memcmp(extra, "ips =", 4)) {
4452 sscanf(extra+4, "%u", &mode);
4453 ret = rtw_pm_set_ips(padapter, mode);
4454 } else {
4455 ret = -EINVAL;
4456 }
4457
4458 return ret;
4459 }
4460
4461 static int rtw_mp_efuse_get(struct net_device *dev,
4462 struct iw_request_info *info,
4463 union iwreq_data *wdata, char *extra)
4464 {
4465 int err = 0;
4466 return err;
4467 }
4468
4469 static int rtw_mp_efuse_set(struct net_device *dev,
4470 struct iw_request_info *info,
4471 union iwreq_data *wdata, char *extra)
4472 {
4473 int err = 0;
4474 return err;
4475 }
4476
4477 static int rtw_tdls(struct net_device *dev,
4478 struct iw_request_info *info,
4479 union iwreq_data *wrqu, char *extra)
4480 {
4481 int ret = 0;
4482 return ret;
4483 }
4484
4485
4486 static int rtw_tdls_get(struct net_device *dev,
4487 struct iw_request_info *info,
4488 union iwreq_data *wrqu, char *extra)
4489 {
4490 int ret = 0;
4491 return ret;
4492 }
4493
4494
4495
4496
4497
4498 static int rtw_test(
4499 struct net_device *dev,
4500 struct iw_request_info *info,
4501 union iwreq_data *wrqu, char *extra)
4502 {
4503 u32 len;
4504 u8 *pbuf, *pch;
4505 char *ptmp;
4506 u8 *delim = ",";
4507 struct adapter *padapter = rtw_netdev_priv(dev);
4508
4509
4510 DBG_871X("+%s\n", __func__);
4511 len = wrqu->data.length;
4512
4513 pbuf = rtw_zmalloc(len);
4514 if (pbuf == NULL) {
4515 DBG_871X("%s: no memory!\n", __func__);
4516 return -ENOMEM;
4517 }
4518
4519 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
4520 kfree(pbuf);
4521 DBG_871X("%s: copy from user fail!\n", __func__);
4522 return -EFAULT;
4523 }
4524 DBG_871X("%s: string =\"%s\"\n", __func__, pbuf);
4525
4526 ptmp = (char *)pbuf;
4527 pch = strsep(&ptmp, delim);
4528 if ((pch == NULL) || (strlen(pch) == 0)) {
4529 kfree(pbuf);
4530 DBG_871X("%s: parameter error(level 1)!\n", __func__);
4531 return -EFAULT;
4532 }
4533
4534 if (strcmp(pch, "bton") == 0)
4535 hal_btcoex_SetManualControl(padapter, false);
4536
4537 if (strcmp(pch, "btoff") == 0)
4538 hal_btcoex_SetManualControl(padapter, true);
4539
4540 if (strcmp(pch, "h2c") == 0) {
4541 u8 param[8];
4542 u8 count = 0;
4543 u32 tmp;
4544 u8 i;
4545 u32 pos;
4546 s32 ret;
4547
4548
4549 do {
4550 pch = strsep(&ptmp, delim);
4551 if ((pch == NULL) || (strlen(pch) == 0))
4552 break;
4553
4554 sscanf(pch, "%x", &tmp);
4555 param[count++] = (u8)tmp;
4556 } while (count < 8);
4557
4558 if (count == 0) {
4559 kfree(pbuf);
4560 DBG_871X("%s: parameter error(level 2)!\n", __func__);
4561 return -EFAULT;
4562 }
4563
4564 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]);
4565
4566 pos = sprintf(extra, "H2C ID = 0x%02x content =", param[0]);
4567 for (i = 1; i<count; i++)
4568 pos += sprintf(extra+pos, "%02x,", param[i]);
4569 extra[pos] = 0;
4570 pos--;
4571 pos += sprintf(extra+pos, " %s", ret == _FAIL?"FAIL":"OK");
4572
4573 wrqu->data.length = strlen(extra) + 1;
4574 }
4575
4576 kfree(pbuf);
4577 return 0;
4578 }
4579
4580 static iw_handler rtw_handlers[] = {
4581 NULL,
4582 rtw_wx_get_name,
4583 dummy,
4584 dummy,
4585 rtw_wx_set_freq,
4586 rtw_wx_get_freq,
4587 rtw_wx_set_mode,
4588 rtw_wx_get_mode,
4589 dummy,
4590 rtw_wx_get_sens,
4591 NULL,
4592 rtw_wx_get_range,
4593 rtw_wx_set_priv,
4594 NULL,
4595 NULL,
4596 NULL,
4597 dummy,
4598 dummy,
4599 NULL,
4600 NULL,
4601 rtw_wx_set_wap,
4602 rtw_wx_get_wap,
4603 rtw_wx_set_mlme,
4604 dummy,
4605 rtw_wx_set_scan,
4606 rtw_wx_get_scan,
4607 rtw_wx_set_essid,
4608 rtw_wx_get_essid,
4609 dummy,
4610 rtw_wx_get_nick,
4611 NULL,
4612 NULL,
4613 rtw_wx_set_rate,
4614 rtw_wx_get_rate,
4615 rtw_wx_set_rts,
4616 rtw_wx_get_rts,
4617 rtw_wx_set_frag,
4618 rtw_wx_get_frag,
4619 dummy,
4620 dummy,
4621 dummy,
4622 rtw_wx_get_retry,
4623 rtw_wx_set_enc,
4624 rtw_wx_get_enc,
4625 dummy,
4626 rtw_wx_get_power,
4627 NULL,
4628 NULL,
4629 rtw_wx_set_gen_ie,
4630 NULL,
4631 rtw_wx_set_auth,
4632 NULL,
4633 rtw_wx_set_enc_ext,
4634 NULL,
4635 rtw_wx_set_pmkid,
4636 NULL,
4637 };
4638
4639 static const struct iw_priv_args rtw_private_args[] = {
4640 {
4641 SIOCIWFIRSTPRIV + 0x0,
4642 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
4643 },
4644 {
4645 SIOCIWFIRSTPRIV + 0x1,
4646 IW_PRIV_TYPE_CHAR | 0x7FF,
4647 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
4648 },
4649 {
4650 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
4651 },
4652 {
4653 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
4654 },
4655 {
4656 SIOCIWFIRSTPRIV + 0x4,
4657 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
4658 },
4659 {
4660 SIOCIWFIRSTPRIV + 0x5,
4661 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
4662 },
4663 {
4664 SIOCIWFIRSTPRIV + 0x6,
4665 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
4666 },
4667
4668 {
4669 SIOCIWFIRSTPRIV + 0x7,
4670 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
4671 },
4672 {
4673 SIOCIWFIRSTPRIV + 0x8,
4674 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
4675 },
4676 {
4677 SIOCIWFIRSTPRIV + 0x9,
4678 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
4679 },
4680
4681
4682 {
4683 SIOCIWFIRSTPRIV + 0xA,
4684 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
4685 },
4686
4687 {
4688 SIOCIWFIRSTPRIV + 0xB,
4689 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
4690 },
4691 {
4692 SIOCIWFIRSTPRIV + 0xC,
4693 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
4694 },
4695 {
4696 SIOCIWFIRSTPRIV + 0xD,
4697 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
4698 },
4699 {
4700 SIOCIWFIRSTPRIV + 0x10,
4701 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
4702 },
4703 {
4704 SIOCIWFIRSTPRIV + 0x11,
4705 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
4706 },
4707 {
4708 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
4709 },
4710 {
4711 SIOCIWFIRSTPRIV + 0x13,
4712 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
4713 },
4714 {
4715 SIOCIWFIRSTPRIV + 0x14,
4716 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
4717 },
4718 {
4719 SIOCIWFIRSTPRIV + 0x15,
4720 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
4721 },
4722 {
4723 SIOCIWFIRSTPRIV + 0x16,
4724 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
4725 },
4726
4727 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
4728 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
4729 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
4730 {
4731 SIOCIWFIRSTPRIV + 0x1D,
4732 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
4733 },
4734
4735 #ifdef CONFIG_WOWLAN
4736 { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
4737 #endif
4738 #ifdef CONFIG_AP_WOWLAN
4739 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" },
4740 #endif
4741 };
4742
4743 static iw_handler rtw_private_handler[] = {
4744 rtw_wx_write32,
4745 rtw_wx_read32,
4746 rtw_drvext_hdl,
4747 rtw_mp_ioctl_hdl,
4748
4749
4750 rtw_get_ap_info,
4751
4752 rtw_set_pid,
4753 rtw_wps_start,
4754
4755
4756 rtw_wx_get_sensitivity,
4757 rtw_wx_set_mtk_wps_probe_ie,
4758 rtw_wx_set_mtk_wps_ie,
4759
4760
4761
4762 rtw_wx_set_channel_plan,
4763
4764 rtw_dbg_port,
4765 rtw_wx_write_rf,
4766 rtw_wx_read_rf,
4767 rtw_wx_priv_null,
4768 rtw_wx_priv_null,
4769 rtw_p2p_set,
4770 rtw_p2p_get,
4771 NULL,
4772 rtw_p2p_get2,
4773
4774 rtw_tdls,
4775 rtw_tdls_get,
4776
4777 rtw_pm_set,
4778 rtw_wx_priv_null,
4779 rtw_rereg_nd_name,
4780 rtw_wx_priv_null,
4781 rtw_mp_efuse_set,
4782 rtw_mp_efuse_get,
4783 NULL,
4784 rtw_test,
4785 };
4786
4787 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
4788 {
4789 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4790 struct iw_statistics *piwstats =&padapter->iwstats;
4791 int tmp_level = 0;
4792 int tmp_qual = 0;
4793 int tmp_noise = 0;
4794
4795 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
4796 piwstats->qual.qual = 0;
4797 piwstats->qual.level = 0;
4798 piwstats->qual.noise = 0;
4799
4800 } else {
4801 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
4802 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
4803 #else
4804 #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
4805 {
4806
4807
4808 struct hal_com_data *pHal = GET_HAL_DATA(padapter);
4809
4810 tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength);
4811 }
4812 #else
4813 tmp_level = padapter->recvpriv.signal_strength;
4814 #endif
4815 #endif
4816
4817 tmp_qual = padapter->recvpriv.signal_qual;
4818 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
4819 if (rtw_linked_check(padapter)) {
4820 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4821 struct noise_info info;
4822 info.bPauseDIG = true;
4823 info.IGIValue = 0x1e;
4824 info.max_time = 100;
4825 info.chan = pmlmeext->cur_channel ;
4826 rtw_ps_deny(padapter, PS_DENY_IOCTL);
4827 LeaveAllPowerSaveModeDirect(padapter);
4828
4829 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, false);
4830
4831 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
4832 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(info.chan), &(padapter->recvpriv.noise));
4833 DBG_871X("chan:%d, noise_level:%d\n", info.chan, padapter->recvpriv.noise);
4834 }
4835 #endif
4836 tmp_noise = padapter->recvpriv.noise;
4837 DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise, padapter->recvpriv.rssi);
4838
4839 piwstats->qual.level = tmp_level;
4840 piwstats->qual.qual = tmp_qual;
4841 piwstats->qual.noise = tmp_noise;
4842 }
4843 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;
4844
4845 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
4846 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
4847 #endif
4848
4849 return &padapter->iwstats;
4850 }
4851
4852 struct iw_handler_def rtw_handlers_def = {
4853 .standard = rtw_handlers,
4854 .num_standard = ARRAY_SIZE(rtw_handlers),
4855 #if defined(CONFIG_WEXT_PRIV)
4856 .private = rtw_private_handler,
4857 .private_args = (struct iw_priv_args *)rtw_private_args,
4858 .num_private = ARRAY_SIZE(rtw_private_handler),
4859 .num_private_args = ARRAY_SIZE(rtw_private_args),
4860 #endif
4861 .get_wireless_stats = rtw_get_wireless_stats,
4862 };
4863
4864
4865
4866
4867
4868
4869 static const char iw_priv_type_size[] = {
4870 0,
4871 1,
4872 1,
4873 0,
4874 sizeof(__u32),
4875 sizeof(struct iw_freq),
4876 sizeof(struct sockaddr),
4877 0,
4878 };
4879
4880 static int get_priv_size(__u16 args)
4881 {
4882 int num = args & IW_PRIV_SIZE_MASK;
4883 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
4884
4885 return num * iw_priv_type_size[type];
4886 }
4887
4888
4889 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
4890 {
4891 int err = 0;
4892 u8 *input = NULL;
4893 u32 input_len = 0;
4894 const char delim[] = " ";
4895 u8 *output = NULL;
4896 u32 output_len = 0;
4897 u32 count = 0;
4898 u8 *buffer = NULL;
4899 u32 buffer_len = 0;
4900 char *ptr = NULL;
4901 u8 cmdname[17] = {0};
4902 u32 cmdlen;
4903 s32 len;
4904 u8 *extra = NULL;
4905 u32 extra_size = 0;
4906
4907 s32 k;
4908 const iw_handler *priv;
4909 const struct iw_priv_args *priv_args;
4910 u32 num_priv_args;
4911 iw_handler handler;
4912 int temp;
4913 int subcmd = 0;
4914 int offset = 0;
4915
4916 union iwreq_data wdata;
4917
4918
4919 memcpy(&wdata, wrq_data, sizeof(wdata));
4920
4921 input_len = 2048;
4922 input = rtw_zmalloc(input_len);
4923 if (NULL == input)
4924 return -ENOMEM;
4925 if (copy_from_user(input, wdata.data.pointer, input_len)) {
4926 err = -EFAULT;
4927 goto exit;
4928 }
4929 ptr = input;
4930 len = strlen(input);
4931
4932 sscanf(ptr, "%16s", cmdname);
4933 cmdlen = strlen(cmdname);
4934 DBG_8192C("%s: cmd =%s\n", __func__, cmdname);
4935
4936
4937 if (cmdlen > 0)
4938 cmdlen += 1;
4939 ptr += cmdlen;
4940 len -= cmdlen;
4941 DBG_8192C("%s: parameters =%s\n", __func__, ptr);
4942
4943 priv = rtw_private_handler;
4944 priv_args = rtw_private_args;
4945 num_priv_args = ARRAY_SIZE(rtw_private_args);
4946
4947 if (num_priv_args == 0) {
4948 err = -EOPNOTSUPP;
4949 goto exit;
4950 }
4951
4952
4953 k = -1;
4954 while ((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
4955
4956
4957 if (k == num_priv_args) {
4958 err = -EOPNOTSUPP;
4959 goto exit;
4960 }
4961
4962
4963 if (priv_args[k].cmd < SIOCDEVPRIVATE) {
4964 int j = -1;
4965
4966
4967 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
4968 (priv_args[j].set_args != priv_args[k].set_args) ||
4969 (priv_args[j].get_args != priv_args[k].get_args)));
4970
4971
4972 if (j == num_priv_args) {
4973 err = -EINVAL;
4974 goto exit;
4975 }
4976
4977
4978 subcmd = priv_args[k].cmd;
4979
4980 offset = sizeof(__u32);
4981
4982 k = j;
4983 }
4984
4985 buffer = rtw_zmalloc(4096);
4986 if (NULL == buffer) {
4987 err = -ENOMEM;
4988 goto exit;
4989 }
4990
4991
4992 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
4993 (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
4994 u8 *str;
4995
4996 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
4997 case IW_PRIV_TYPE_BYTE:
4998
4999 count = 0;
5000 do {
5001 str = strsep(&ptr, delim);
5002 if (NULL == str) break;
5003 sscanf(str, "%i", &temp);
5004 buffer[count++] = (u8)temp;
5005 } while (1);
5006 buffer_len = count;
5007
5008
5009 wdata.data.length = count;
5010 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
5011 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
5012
5013 break;
5014
5015 case IW_PRIV_TYPE_INT:
5016
5017 count = 0;
5018 do {
5019 str = strsep(&ptr, delim);
5020 if (NULL == str) break;
5021 sscanf(str, "%i", &temp);
5022 ((s32 *)buffer)[count++] = (s32)temp;
5023 } while (1);
5024 buffer_len = count * sizeof(s32);
5025
5026
5027 wdata.data.length = count;
5028 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
5029 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
5030
5031 break;
5032
5033 case IW_PRIV_TYPE_CHAR:
5034 if (len > 0) {
5035
5036 wdata.data.length = len;
5037 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
5038 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
5039
5040
5041 memcpy(buffer, ptr, wdata.data.length);
5042 } else {
5043 wdata.data.length = 1;
5044 buffer[0] = '\0';
5045 }
5046 buffer_len = wdata.data.length;
5047 break;
5048
5049 default:
5050 DBG_8192C("%s: Not yet implemented...\n", __func__);
5051 err = -1;
5052 goto exit;
5053 }
5054
5055 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
5056 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
5057 DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
5058 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
5059 err = -EINVAL;
5060 goto exit;
5061 }
5062 } else {
5063 wdata.data.length = 0L;
5064 }
5065
5066
5067
5068 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
5069 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
5070
5071 if (offset)
5072 wdata.mode = subcmd;
5073 memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
5074 } else {
5075 if ((priv_args[k].set_args == 0) &&
5076 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
5077 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
5078
5079 if (offset)
5080 wdata.mode = subcmd;
5081 } else {
5082
5083 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
5084 err = -EFAULT;
5085 goto exit;
5086 }
5087 wdata.data.flags = subcmd;
5088 }
5089 }
5090
5091 kfree(input);
5092 input = NULL;
5093
5094 extra_size = 0;
5095 if (IW_IS_SET(priv_args[k].cmd)) {
5096
5097 extra_size = get_priv_size(priv_args[k].set_args);
5098
5099
5100 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
5101 ((extra_size + offset) <= IFNAMSIZ))
5102 extra_size = 0;
5103 } else {
5104
5105 extra_size = get_priv_size(priv_args[k].get_args);
5106
5107
5108 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
5109 (extra_size <= IFNAMSIZ))
5110 extra_size = 0;
5111 }
5112
5113 if (extra_size == 0) {
5114 extra = (u8 *)&wdata;
5115 kfree(buffer);
5116 buffer = NULL;
5117 } else
5118 extra = buffer;
5119
5120 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
5121 err = handler(dev, NULL, &wdata, extra);
5122
5123
5124 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
5125 (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
5126 int j;
5127 int n = 0;
5128 u8 str[20] = {0};
5129
5130
5131 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
5132 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
5133 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
5134 else
5135 n = wdata.data.length;
5136
5137 output = rtw_zmalloc(4096);
5138 if (NULL == output) {
5139 err = -ENOMEM;
5140 goto exit;
5141 }
5142
5143 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
5144 case IW_PRIV_TYPE_BYTE:
5145
5146 for (j = 0; j < n; j++) {
5147 sprintf(str, "%d ", extra[j]);
5148 len = strlen(str);
5149 output_len = strlen(output);
5150 if ((output_len + len + 1) > 4096) {
5151 err = -E2BIG;
5152 goto exit;
5153 }
5154 memcpy(output+output_len, str, len);
5155 }
5156 break;
5157
5158 case IW_PRIV_TYPE_INT:
5159
5160 for (j = 0; j < n; j++) {
5161 sprintf(str, "%d ", ((__s32 *)extra)[j]);
5162 len = strlen(str);
5163 output_len = strlen(output);
5164 if ((output_len + len + 1) > 4096) {
5165 err = -E2BIG;
5166 goto exit;
5167 }
5168 memcpy(output+output_len, str, len);
5169 }
5170 break;
5171
5172 case IW_PRIV_TYPE_CHAR:
5173
5174 memcpy(output, extra, n);
5175 break;
5176
5177 default:
5178 DBG_8192C("%s: Not yet implemented...\n", __func__);
5179 err = -1;
5180 goto exit;
5181 }
5182
5183 output_len = strlen(output) + 1;
5184 wrq_data->data.length = output_len;
5185 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
5186 err = -EFAULT;
5187 goto exit;
5188 }
5189 } else {
5190 wrq_data->data.length = 0;
5191 }
5192
5193 exit:
5194 kfree(input);
5195 kfree(buffer);
5196 kfree(output);
5197
5198 return err;
5199 }
5200
5201 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5202 {
5203 struct iwreq *wrq = (struct iwreq *)rq;
5204 int ret = 0;
5205
5206 switch (cmd) {
5207 case RTL_IOCTL_WPA_SUPPLICANT:
5208 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
5209 break;
5210 case RTL_IOCTL_HOSTAPD:
5211 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
5212 break;
5213 case SIOCDEVPRIVATE:
5214 ret = rtw_ioctl_wext_private(dev, &wrq->u);
5215 break;
5216 default:
5217 ret = -EOPNOTSUPP;
5218 break;
5219 }
5220
5221 return ret;
5222 }